Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

arithmetic right shift with sign extension

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.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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:

  1. I added and shamt to skip the mask logic if shamt is zero. This is becuase, in C, shifting a 32-bit integer by 32 produces an unspecified result.

  2. For the Python version only, the mask value needs to be and-ed with 0xffffffff to force it back to a 32-bit value. In C, this won’t be necessary with 32-bit integers (but you should use an unsigned integer for the value being shifted).

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading