A couple of assembly command queries

Started by Almas, February 05, 2009, 06:33:55 PM

Previous topic - Next topic

Almas

Okay, I've checked my lists but it's somewhat hard to check what I'm getting at.

The main plan for my code is to load a 32 bit value into a register, then read some specific data from it.

For example, say my 32 bit value is 25ABCDEF. I want a way to read the top 8 bits (25), then also attain one of the other digits depending on the value stored in another register.

For the first part, I believe I could use a bitshift (Is srw the correct command, with the number of bits being 0x18?).

For the second, I'm lead to think the most effective method is a nor 0xFFFFF0FF (saying I would want the D in this example), followed by a bitshift. However, I'm not sure if this is wholly line efficient (I'd have to load that value into another register beforehand) - which is somewhat important, as the line restriction is looming for this project. I'd appreciate any input on what I could do to optimise the code.

Thanks in advance.

brkirch

#1
It sounds like you need to use the rlwinm and rlwimi instructions.  In case the documentation for it is too confusing here are some examples:

Extract first bit from r3, put result in r4
rlwinm r4,r3,0,0,0
If r3 = F0000000 then the result will be
r4 = 80000000

Do 31 left rotations (the same as 1 right rotation), extract last bit, put result in r4
rlwinm r4,r3,31,31,31
If r3 = 0000000E then the result will be
r4 = 00000001

Extract bits 2 through 4 from r3, put result in r4
rlwinm r4,r3,0,2,4
If r3 = A9FFFFFF then the result will be
r4 = 28000000
Note that the first bit is bit 0, second is bit 1, etc.

Extract bits 2 through 4 from r3, insert result in bits 2 through 4 of r4
rlwimi r4,r3,0,2,4
If r3 = A9FFFFFF and r4 = 10CCBBAA then the result will be
r4 = 38CCBBAA

Almas

#2
Oh my. Those sound like my idea of perfection.

Maybe I should get out more.

But seriously, thanks so much for telling me of the existance of those thingies. I'm sure I'll figure out their functonality soon enough.

One question, though: what is the significance of left rotations? How many left rotations would I need to make the value stay in the same location (assuming I didn't use 0, of course).

brkirch

#3
Quote from: Almas on February 05, 2009, 08:41:21 PMOne question, though: what is the significance of left rotations? How many left rotations would I need to make the value stay in the same location (assuming I didn't use 0, of course).
Each left rotation just rotates the bits left by 1, moving the first bit to the last bit location.

For example:
E8F00000 = 11101000111100000000000000000000
One bitwise left rotation would result in
11010001111000000000000000000001 = D1E00001

32 left rotations (or right rotations) will result in the same value.

Almas

Do 31 left rotations, extract last bit, put result in r4
rlwinm r4,r3,31,31,31
If r3 = F0000000 then the result will be
r4 = 00000001

F0000000 =

11110000000000000000000000000000

31 left shifts = 1 right shift

01111000000000000000000000000000

last bit = 0

so rlwinm r4,r3,31,31,31 should produce 00000000?

I think I've got the general idea but I'm just missing a point. Does the bit rotation come before or after the copying of bits across?

Oh, and in your last point, did you mean D1E0001?

brkirch

Quote from: Almas on February 06, 2009, 12:00:15 AM
Do 31 left rotations, extract last bit, put result in r4
rlwinm r4,r3,31,31,31
If r3 = F0000000 then the result will be
r4 = 00000001

F0000000 =

11110000000000000000000000000000

31 left shifts = 1 right shift

01111000000000000000000000000000

last bit = 0

so rlwinm r4,r3,31,31,31 should produce 00000000?
Yeah that's right, I made a mistake there and did a left rotation when I should have done a right, I corrected my post with an example that is hopefully correct.

Quote from: Almas on February 06, 2009, 12:00:15 AMI think I've got the general idea but I'm just missing a point. Does the bit rotation come before or after the copying of bits across?
Before.

Another thing I didn't mention is that you can easily use "rlwinm." for testing a bit.  For example, if you want to jump to label "endofcode" if bit 0 of r3 is NOT set, then you would use these instructions (assuming that r4 is not being used):
rlwinm. r4,r3,1,31,31
beq- endofcode


This uses the instruction "rlwinm." instead of "rlwinm" because the "." means that the resulting value will be compared against 0 (it is equivalent  to having a cmpwi rN,0 instruction after a rlwinm instruction, with rN being the destination register of the rlwinm instruction).


Quote from: Almas on February 06, 2009, 12:00:15 AMOh, and in your last point, did you mean D1E0001?

This one?
Quote from: brkirch on February 05, 2009, 08:25:35 PMExtract bits 2 through 4 from r3, insert result in bits 2 through 4 of r4
rlwimi r4,r3,0,2,4
If r3 = A9FFFFFF and r4 = 10CCBBAA then the result will be
r4 = 38CCBBAA
It should be correct, the bits 2 through 4 in r4 are replacing the bits 2 through 4 in r3 (if there was a non-zero value for the number of rotations then the rotations would be done first, and bits 2 through 4 would be copied from the result).

Almas

#6
Nono:

Quote from: brkirchFor example:
E8F00000 = 11101000111100000000000000000000
One bitwise left rotation would result in
11010001111000000000000000000001 = D1E00000

What is the difference between rlwinm and rlwimi? I'm assuming it's that rlwinm overwrites the bits in the destination register, whilst rlwimi ands it? Except the documentation here seems to disagree. If I'm intepreting that correctly, though, then:

Quote from: brkirchExtract bits 2 through 4 from r3, insert result in bits 2 through 4 of r4
rlwimi r4,r3,0,2,4
If r3 = A9FFFFFF and r4 = 10CCBBAA then the result will be
r4 = 38CCBBAA

Should return 28CCBBAA instead, then

I didn't know the . thing, that should actually come in really useful for some stuff.

Thanks loads for your help =). I'm sure I'll get the hang of it eventually.

brkirch

#7
Quote from: Almas on February 06, 2009, 03:57:38 AMNono:

Quote from: brkirchFor example:
E8F00000 = 11101000111100000000000000000000
One bitwise left rotation would result in
11010001111000000000000000000001 = D1E00000
Yeah that was also a mistake.  Sorry about all the mistakes, I was in a bit of a hurry when I posted the first and second posts.

Quote from: Almas on February 06, 2009, 03:57:38 AMWhat is the difference between rlwinm and rlwimi? I'm assuming it's that rlwinm overwrites the bits in the destination register, whilst rlwimi ands it? Except the documentation here seems to disagree. If I'm intepreting that correctly, though, then:

Quote from: brkirchExtract bits 2 through 4 from r3, insert result in bits 2 through 4 of r4
rlwimi r4,r3,0,2,4
If r3 = A9FFFFFF and r4 = 10CCBBAA then the result will be
r4 = 38CCBBAA

Should return 28CCBBAA instead, then
The instruction rlwinm completely overwrites the destination register regardless of what it contains (it sets everything outside the bit range you specify to 0).  As for rlwimi, it only overwrites the bit range that you specify in the destination register (the result I have there should be correct).

BTW, I would recommend this documentation, it contains a LOT of useful information about PowerPC processors and PowerPC assembly:
http://www.freescale.com/files/product/doc/MPCFPE32B.pdf

Quote from: Almas on February 06, 2009, 03:57:38 AMI didn't know the . thing, that should actually come in really useful for some stuff.
It is very useful, and it doesn't just work on these instructions either; most integer operations have the option to save a comparison against 0 to CR0.

James0x57

Dude, thank you brkirch. Seriously- I had no idea what that one was doing.
Much appreciated. =)