summaryrefslogtreecommitdiff
path: root/runtime/powerpc
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/powerpc
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/powerpc')
-rw-r--r--runtime/powerpc/i64_dtos.s25
-rw-r--r--runtime/powerpc/i64_dtou.s21
2 files changed, 36 insertions, 10 deletions
diff --git a/runtime/powerpc/i64_dtos.s b/runtime/powerpc/i64_dtos.s
index 56c6e4b..9b1288f 100644
--- a/runtime/powerpc/i64_dtos.s
+++ b/runtime/powerpc/i64_dtos.s
@@ -58,16 +58,27 @@ __i64_dtos:
rlwinm r3, r3, 0, 12, 31 # HI &= ~0xFFF00000
oris r3, r3, 0x10 # HI |= 0x00100000
# shift it appropriately
- mflr r9 # save retaddr in r9
cmpwi r5, 0
blt 3f
- bl __i64_shl # if EXP >= 0, shift left by EXP
+ # if EXP >= 0, shift left by EXP. Note that EXP < 11.
+ subfic r6, r5, 32 # r6 = 32 - EXP
+ slw r3, r3, r5
+ srw r0, r4, r6
+ or r3, r3, r0
+ slw r4, r4, r5
b 4f
-3: subfic r5, r5, 0
- bl __i64_shr # if EXP < 0, shift right by -EXP
+ # if EXP < 0, shift right by -EXP. Note that -EXP <= 52 but can be >= 32.
+3: subfic r5, r5, 0 # r5 = -EXP = shift amount
+ subfic r6, r5, 32 # r6 = 32 - amount
+ addi r7, r5, -32 # r7 = amount - 32 (see i64_shr.s)
+ srw r4, r4, r5
+ slw r0, r3, r6
+ or r4, r4, r0
+ srw r0, r3, r7
+ or r4, r4, r0
+ srw r3, r3, r5
# apply sign to result
-4: mtlr r9
- xor r4, r4, r10
+4: xor r4, r4, r10
xor r3, r3, r10
subfc r4, r10, r4
subfe r3, r10, r3
@@ -76,7 +87,7 @@ __i64_dtos:
1: li r3, 0 # result is 0
li r4, 0
blr
-2: cmpwi r10, 0 # result is MAX_SINT or MIN_SINT
+2: li r4, -1 # result is MAX_SINT or MIN_SINT
bge 5f # depending on sign
li r4, -1 # result is MAX_SINT = 0x7FFF_FFFF
srwi r3, r4, 1
diff --git a/runtime/powerpc/i64_dtou.s b/runtime/powerpc/i64_dtou.s
index d9638e6..78cd08b 100644
--- a/runtime/powerpc/i64_dtou.s
+++ b/runtime/powerpc/i64_dtou.s
@@ -61,9 +61,24 @@ __i64_dtou:
# shift it appropriately
cmpwi r5, 0
blt 3f
- b __i64_shl # if EXP >= 0, shift left by EXP
-3: subfic r5, r5, 0
- b __i64_shr # if EXP < 0, shift right by -EXP
+ # if EXP >= 0, shift left by EXP. Note that EXP < 12.
+ subfic r6, r5, 32 # r6 = 32 - EXP
+ slw r3, r3, r5
+ srw r0, r4, r6
+ or r3, r3, r0
+ slw r4, r4, r5
+ blr
+ # if EXP < 0, shift right by -EXP. Note that -EXP <= 52 but can be >= 32.
+3: subfic r5, r5, 0 # r5 = -EXP = shift amount
+ subfic r6, r5, 32 # r6 = 32 - amount
+ addi r7, r5, -32 # r7 = amount - 32 (see i64_shr.s)
+ srw r4, r4, r5
+ slw r0, r3, r6
+ or r4, r4, r0
+ srw r0, r3, r7
+ or r4, r4, r0
+ srw r3, r3, r5
+ blr
# Special cases
1: li r3, 0 # result is 0
li r4, 0