I am trying to write a function (in C) the does an arithmetic right shift with sign extension.
The result will be held in R[rd]
.
the source is R[rs]
the shift amount is R[rt]
In order to simplify my task, I’m trying to write this function in python.
dest
functions as R[rd]
source
functions as R[rs]
shamt
functions as shamt
my try:
dest = 0
source = 0xF5042352
print("source = ", hex(source))
shamt = 1
print(f"shifting {shamt}")
sign_bit = source & 0x80000000
shifted = source >> shamt
if(sign_bit):
mask = (1 << (32  shamt))  1 # create a mask with 1s from the 32 bit to the 32  shamt bit
print("mask = ", hex(mask))
shifted = (mask << shamt) # sign extend the number
dest = shifted
print("dest = ", hex(dest))
I added some prints just to view the variable contents mid.
The way I went about solving my problem is keeping note on the sign of the number source
.
if the number was negative before the shift, then I should create a mask with 1’s from the rightmost 1 to the 32′ bit.
However this doesn’t work.
When I shift the number 0xf5042352
by just 1, the resulting dest is:
0xffffffff
My algorithm is wrong, I couldn’t figure out how to fix my implementation, tips would be appreciated
>Solution :
This should work:
dest = 0
source = 0xF5042352
print("source = ", hex(source))
shamt = 1
print(f"shifting {shamt}")
sign_bit = source & 0x80000000
shifted = source >> shamt
if sign_bit and shamt:
mask = 0xffffffff << (32  shamt)
mask &= 0xffffffff # only needed in python, to force back to 32 bits
print("mask = ", hex(mask))
shifted = mask # sign extend the number
dest = shifted
print("dest = ", hex(dest))
This computes the shifted mask value, which can then be used directly without shifting. Note that:

I added
and shamt
to skip the mask logic ifshamt
is zero. This is becuase, in C, shifting a 32bit integer by 32 produces an unspecified result. 
For the Python version only, the mask value needs to be anded with
0xffffffff
to force it back to a 32bit value. In C, this won’t be necessary with 32bit integers (but you should use an unsigned integer for the value being shifted).