Reputation: 9
I have a 64-bit quantity with the most significant 32 bits in R2 and the least significant 32 bits in R3.
How can I do a 64-bit logical and arithmetic right shift by 4-bit?
Also, how can I 64-bit right rotate these by 2-bit.
How can I do this with minimum count of instructions on 32-bit ARM?
Upvotes: 0
Views: 1812
Reputation: 71506
unsigned long long fun ( unsigned long long x, unsigned int y)
{
return(x<<y);
}
Disassembly of section .text:
00000000 <fun>:
0: f1a2 0c20 sub.w r12, r2, #32
4: fa00 fc0c lsl.w r12, r0, r12
8: f1c2 0320 rsb r3, r2, #32
c: 4091 lsls r1, r2
e: fa20 f303 lsr.w r3, r0, r3
12: ea41 010c orr.w r1, r1, r12
16: 4090 lsls r0, r2
18: 4319 orrs r1, r3
1a: 4770 bx lr
If I have two 4 bit registers that are holding an 8 bit value abcd efgh and I want to shift that left 3 bits, then both parts will need to shift left three
abcd -> d000
efgh -> h000
But also the lower has to shift right one bit (4-3 = 1)
efgh -> 0efg
Then add/or d000 and 0efg giving the result
defg h000
Instruction set or programming language are often irrelevant here, you can do the above with many languages and instruction sets.
Some instruction sets only have a single bit shift but also many will have a single bit rotate through carry, so one shift would be done with
clear carry
rotate lower through carry one bit
rotate upper through carry one bit
And you repeat that in a loop or unrolled as many bits as you need.
Naturally you are not limited on how many bits you can shift, with 32 bit registers and enough memory you can shift a 123456 byte number by n bits.
Shift right, shift left, rotate its all the same concept, just implement it.
Another example.
unsigned long long fun ( unsigned long long x)
{
return(x<<3);
}
0: 4603 mov r3, r0
2: 00c9 lsls r1, r1, #3
4: 00c0 lsls r0, r0, #3
6: ea41 7153 orr.w r1, r1, r3, lsr #29
a: 4770 bx lr
32 - 3 = 29.
Upvotes: 2