summaryrefslogtreecommitdiff
path: root/runtime/arm/i64_shr.s
diff options
context:
space:
mode:
authorGravatar xleroy <xleroy@fca1b0fc-160b-0410-b1d3-a4f43f01ea2e>2013-05-05 16:29:20 +0000
committerGravatar xleroy <xleroy@fca1b0fc-160b-0410-b1d3-a4f43f01ea2e>2013-05-05 16:29:20 +0000
commitb257a6d283f6f5784cb351856b5dbe8c645a1f6f (patch)
tree3e134e46c53a5e75a3b6c78878d07a554b396367 /runtime/arm/i64_shr.s
parentbc24cf49659f91245d8f42ca06fbe7d21a5c06cd (diff)
ia32/i64_dtou: wrong play on rounding mode
arm, powerpc: expand shifts inline in dtos and dtou arm: branchless code for shl and shr test: more tests for double -> long long conversions. git-svn-id: https://yquem.inria.fr/compcert/svn/compcert/trunk@2234 fca1b0fc-160b-0410-b1d3-a4f43f01ea2e
Diffstat (limited to 'runtime/arm/i64_shr.s')
-rw-r--r--runtime/arm/i64_shr.s31
1 files changed, 23 insertions, 8 deletions
diff --git a/runtime/arm/i64_shr.s b/runtime/arm/i64_shr.s
index f10b770..9d60441 100644
--- a/runtime/arm/i64_shr.s
+++ b/runtime/arm/i64_shr.s
@@ -38,20 +38,35 @@
@@@ Shift right unsigned
+@ Note on ARM shifts: the shift amount is taken modulo 256.
+@ If shift amount mod 256 >= 32, the shift produces 0.
+
+@ Algorithm:
+@ RL = (XL >> N) | (XH << (32-N) | (XH >> (N-32))
+@ RH = XH >> N
+@ If N = 0:
+@ RL = XL | 0 | 0
+@ RH = XH
+@ If 1 <= N <= 31: 1 <= 32-N <= 31 and 255 <= N-32 mod 256 <= 255
+@ RL = (XL >> N) | (XH >> (32-N) | 0
+@ RH = XH >> N
+@ If N = 32:
+@ RL = 0 | XH | 0
+@ RH = 0
+@ If 33 <= N <= 63: 255 <= 32-N mod 256 <= 255 and 1 <= N-32 <= 31
+@ RL = 0 | 0 | (XH >> (N-32))
+@ RH = 0
+
.global __i64_shr
__i64_shr:
and r2, r2, #63 @ normalize amount to 0...63
- rsbs r3, r2, #32 @ r3 = 32 - amount
- ble 1f @ branch if <= 0, namely if amount >= 32
+ rsb r3, r2, #32 @ r3 = 32 - amount
mov r0, r0, lsr r2
- orr r0, r1, lsl r3
+ orr r0, r0, r1, lsl r3
+ sub r3, r2, #32 @ r3 = amount - 32
+ orr r0, r0, r1, lsr r3
mov r1, r1, lsr r2
bx lr
-1:
- sub r2, r2, #32
- mov r0, r1, lsr r2
- mov r1, #0
- bx lr
.type __i64_shr, %function
.size __i64_shr, . - __i64_shr