Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding PowerPC rlwinm instruction

Tags:

c

powerpc

So I finally convinced myself to try and learn/use PowerPC (PPC). Everything is going well and most information was found online. However, when looking at some examples I came across this:

rlwinm    r3, r3, 0,1,1

How would I do this in C? I tried doing some research, but couldn't find anything that helped me out. Thanks in advance!

like image 365
user3829771 Avatar asked Jun 17 '15 15:06

user3829771


2 Answers

rlwinm stands for "Rotate Left Word Immediate then aNd with Mask, and it's correct usage is

rlwinm  RA, RS, SH, MB, ME

As per the description page:

  • RA Specifies target general-purpose register where result of operation is stored.
  • RS Specifies source general-purpose register for operation.
  • SH Specifies shift value for operation.
  • MB Specifies begin value of mask for operation.
  • ME Specifies end value of mask for operation.
  • BM Specifies value of 32-bit mask.

And

  • If the MB value is less than the ME value + 1, then the mask bits between and including the starting point and the end point are set to ones. All other bits are set to zeros.
  • If the MB value is the same as the ME value + 1, then all 32 mask bits are set to ones.
  • If the MB value is greater than the ME value + 1, then all of the mask bits between and including the ME value +1 and the MB value -1 are set to zeros. All other bits are set to ones.

So in your example the source and target are the same. Shift amount is 0, so no shift. And MB=ME=1, so the first case applies, such that the mask becomes all zeros with bit number 1 as 1, while numbering from MSB=0: 0x40000000.

In C we can write it as simple as

a &= 0x40000000;

assuming a is 32-bit variable.

like image 74
Eugene Sh. Avatar answered Sep 18 '22 13:09

Eugene Sh.


rlwinm rotates the value of a register left by the specified number, performs an AND and stores the result in a register.

Example: rlwinm r3, r4, 5, 0, 31

r4 is the source register which is rotated by 5 and before the rotated result is placed in r3, it is also ANDed with a bit mask of only 1s since the interval between 0 and 31 is the entire 32-bit value.

Example taken from here.

For a C implementation you may want to take a look at how to rotate left and how to AND which should be trivial to build together now. Something like the following should work:

int rotateLeft(int input, int shift) {
    return (input << shift) | ((input >> (32 - shift)) & ~(-1 << shift));
}

int rlwinm(int input, int shift, int mask) {
    return rotateLeft(input, shift) & mask;
}
like image 34
BullyWiiPlaza Avatar answered Sep 19 '22 13:09

BullyWiiPlaza