how do you bit mask and shift the left most values in mips32? - mips

lets say I have a word in binary: 0111
I know that you can mask the right most value and shift right like this:
andi $10, $9, 1 # bit mask for $9, set mask to $10
bne $10, 1, outer_loop
srl $9, $9, 1
this with one iteration would turn the binary example to 0011 with $10 = 1
is there a way to do this but with the left most bit instead?
for example 0111 would turn to 1110 by shifting left but how do you get the mask equal to left most bit?
sorry for broken English, this is my second language.

Related

mips extract certain bits from register and set them to a different register in the same place without changing the rest

I'm trying to pull bits 15 to 31 from register $t0 and set them to the same positions in register $t1.
How can I do this in the least possible instructions?
At a basic level, you can get the values of certain bits from a register by ANDing the register with 0s where you want to ignore the old value and 1s where you want to respect it.
If you want to then combine that with bits from another input, do that same technique on the second input with the opposite 1s and 0s on the value you AND them with. Then, add the two resultant values together.
So for example (pseudoy, with values instead of registers):
AND 0001010101 0000001111 = 0000000101
AND 1101101101 1111110000 = 1101100000
ADD 1101100000 0000000101 = 1101100101
First of all, lets define $t0 as being equal to a 16 bits value (because its easier), let's say 1010 1100 0101 1000.
Then lets say $t1 have the value of 1100 0101 1011 1110.
And we want to put the first 5 bits of $t0 into the same fields of $t1. Then we need to follow these steps :
Make an and operation between $t0 and another register. Notice that the "other register" need to have all the bits different from the ones we want extract as being equal to zero, meanwhile all the bits that have the same "index" of the bits we want to extract need to be equal to one. Example :
1010 1100 0101 1000
0000 0000 0001 1111
-------------------
0000 0000 0001 1000
let's put this result in the register $s0
Make the same thing with $t2, but now all the fields of $t2 that we want to substitute (the 5 first bits) need to perform an and operation between a register that has just zeros in the matching indexes, meanwhile all the others bits need to be equal to 1. Example :
1100 0101 1011 1110
1111 1111 1110 0000
-------------------
1100 0101 1010 0000
lets put this result on $s1
In order to substitute the first 5 bits of $t1 by the first bits of $t0, you just need to do :
xor $t1, $s0, $s1
OBSs :
1.When I said "the first 5 bits of the register $t0" on the third paragraph, I was make reference to the LSB's

MIPS 'nor' usage in code

In my textbook, there are these lines of code:
addu $t0, $t1, $t2
nor $t3, $t1, $zero
sltu $t3, $t3, $t2
bne $t3, $zero, Overflow
I understand the addu function, but when I get to the nor function and everything afterward, I don't understand what it does. The textbook just says t3 = the 2's complement of t1 - 1 for the 2nd line, but I don't understand how that works in binary. Would it just switch out all 0's for 1's and vice versa and then interpret that as 2's complement, resulting in a negative number? The book's explanation doesn't make sense to me.
Yes nor-ing a value with $zero simply inverts all the bits. For example binary 101011 nor-ed with 0 results in binary 010100. This is also a way the assembler psuedo-op not can be implemented.
Your question refers to:
nor $t3, $t1, $zero # t3 = the 2's complement of t1 - 1
Let me explain.... appying twos complement to a binary number is a way of converting that number between positive and negative. So for example if you have 0111 which is a +7, then you apply twos complement you get 1001 which represents -7. The method used is to flip all the bits, then add 1. So in our example of +7 0111 flipping the bits gives 1000 then adding 1 gives 1001, which is a twos complement representation of -7. If you start with 1001 which is -7 in twos complement, and you want the positive version, you apply the SAME method, flip the bits gives 0110 then add 1 gives 0111. So this same operation applies both ways.
Now, let's look at what NOR does with a small truth table:
t1
0
or
nor
1
0
1
0
0
0
0
1
So NOR gives us a flipped t1, whatever t1 is, NORing with 0 produces the opposite. With this information we know that if we do t1 NOR 0 we get ~t1, and that is basically flipping all the bits in t1.
Now, can you think of a method that involves flipping bits? That's right, twos complement. Oh but twos complement flips them but also adds 1, so if we just want to flip them only, we can do the twos complement and then minus 1 to cancel out that add 1.
So this is why the textbook said this, because NORing with 0 essentially flips t1's bits, and another way of saying that is twos complement minus 1.

MIPS: Calculating Displacement

Working through some problems and I am confused by calculating the displacement.
Some examples are:
top:
addi $s2, $s2, -1
addi $s1, $s1, 1
bne $s2, $0, top
Assume top has the value of 0x1000 0008.
top: bne $s1, $s2, end
addi $s1, $s1, 1
end: j top
Assume top has the value of 0x1000 0008.
What is the displacement in the bne instructions?
Can anyone explain how to calculate these? Thanks.
The absolute address doesn't matter. What matters is the distance between the jump and its target.
To calculate the offset, calculate the distance between jump target and the instruction following the bne. In your first example the distance would be 12 bytes because there are 3 instructions between the target label and the instruction following the bne, and each instruction is 4 bytes in size. And since this is a backwards jump it has to be a negative offset, i.e. -12.
Since instructions need to be word aligned (4 bytes), the offset stored in the instruction word is shifted 2 bits to the right (since the two least significant bits always will be 00 anyway). This is an arithmetic shift, meaning the sign bit is preserved. So we need to take -12 and do an arithmetic right shift by 2 bits to get the actual offset that gets stored in the instruction word. This gets easier if we view -12 in hexadecimal form, which would be 0xFFF4. Shifting 0xFFF4 gives us 0xFFFD, which is what we'd put in the instruction word.
In your second example the offset will be positive, but apart from that the way you calculate it is exactly the same.

Adding 64 bit IEEE 754 numbers in MIPS w/o FPU

I'm supposed to describe how I would implement the addition of two doubles in MIPS without using the floating point unit. I know how to do it with single precision IEEE 754, but somehow cannot figure out how to do the whole shifting business in two registers(when normalizing etc.).
Is there any other way than shifting the first register, saving the number of bits shifted, and then applying the same number of shifts to the second register?
If you need to shift a 64-bit value on a MIPS32 processor you can do something like this:
# Left shift
# $t1:$t0 contains a 64-bit number
slt $t2,$t0,$0 # $t2 = ($t0 & 0x80000000) ? 1 : 0
sll $t0,$t0,1 # shift the low word left 1 bit
sll $t1,$t1,1 # shift the high word left 1 bit
or $t1,$t1,$t2 # add the carry from the low word to the high word
# Right shift
# $t1:$t0 contains a 64-bit number
sll $t2,$t1,31 # save the lsb of $t1 in the msb of $t2
srl $t1,$t1,1 # shift the high word right 1 bit
srl $t0,$t0,1 # shift the low word right 1 bit
or $t0,$t0,$t2 # add the carry from the high word to the low word
Repeat in a loop as many times as necessary.

Showing a BEQ MIPS instruction in binary

beq $s1, $s2, endif(assume endif is 22 instructions after the branch)
The answer to the following question is
000100 10001 10010 0000000000001111
Can someone explain what "assume endif is 22 instructions after the branch" means?
Helpful data:
opcode for beq is 000100
$s1 is 10010
$s2 is 10001
I just need help understanding how we get the last part, which is the endif.
You want to jump to the 22th instruction after the beq, that is skip the next 21 instructions.
Now, that would be 10101 binary which is 21 decimal (the number of instructions to skip).
The instruction for such a jump would be 0001 0010 0011 0010 0000 0000 0001 0101 and not what you have written (your branch offset is wrong).
You have to take into account that in MIPS every instruction is the same size (4 bytes), thus the branches count the number of words (4 bytes each) to jump.
As a note aside, these values are encoded in two's complement so when you skip forward you just have to read that number in binary and if it were backwards you would have to apply two's complement to "see" were it will jump.