I have the following two registers that were read using lha from two different words in memory. The data that I need has 2 bytes in one word and the last two bytes in the next word.
r4=000001234
r5=000005678
I would like to know how I can combine the two registers into r6 as 12345678. Update: I believe that I would do ori r6,r4,r5, right?
If it's easier, how could I use one register to read the half words and combine them?
ori is not going to do what you want it to do. It would generate 0x567C.
0x1234 = 001001000110100
0x5678 = 101011001111000
OR ____________________
0x567C = 101011001111100
You need to shift r4 to the left by 16 bits first, then you can ori them together.
I think this is what you want to do. rlwinm rD, rS, A, B, C = Rotate Left Word Immediate then aNd with Mask. The contents of rS will be rotated to the left by A bits. Values that "fall off" the left will appear on the right side of the word (hence "rotate"). After the rotation, a bit mask of 1's, starting with the bit specified by B and ending with the bit specified by C (inclusive) will be ANDed with the result, which we can use to get rid of the bits that we don't want. PowerPC is big endian so the bits start counting from 0 on the left.
So let's take 0x12345678. Rotate it to the left by 16-bits; 0x56781234 (see the rotation? fall off the left, appear on the right)). Now mask off the first 16 bits; 0x56780000.
Therefore, the following will take the contents of r4, rotate it 16 bits to the left so the lower half word is now in the upper half word, and then mask off the bits from 0 to 15 (i.e. the upper half word) so that the lower half word is all 0. Then you can or the value from r5 into r6. You may or may not want to be careful about masking off the upper 16 bits of r5 before or'ing; if r5 contains a negative 16-bit number and it becomes sign-extended then there will be all 1's in the upper half word and your or will get pwned.
rlwinm r6,r4,16,0,15
or r6,r6,r5
EDIT: ACK! Not ori! It should be just or. ori is when you have an Immediate you want to OR with (i.e. third operand is a number). Plain old or is what you use when you have a register to OR with (i.e. third operand is a register)
Quote from: dcx2 on September 18, 2010, 09:32:20 PMrlwinm r6,r4,16,0,15
or r6,r6,r5
It is also possible to combine the registers with a single instruction. Like this:
rlwimi r5,r4,16,0,15
That instruction will take r4 and rotate its value left by 16 bits, and insert the first 16 bits of the result into r5. So if r4 = 00001234 and r5 = 00005678 then the result after the instruction will be r5 = 12345678.
Are you sure? Wouldn't that over-write r5 with 12340000?
Actually the rlwimi instruction only overwrites the specified bit range of the destination register. Unlike most other instructions it does not simply overwrite the destination register.
doh, I saw rlwin* and my mind filled in the m, and I didn't realize that you're using Mask Insert. That's a cool instruction...but he may need a second line anyway if the contents of r5 must be preserved.
Still, that's a cool trick...thanks. The rlw* instructions never cease to amaze me with their possibilities.
Thank you both. I really appreciate it.