diff options
author | xleroy <xleroy@fca1b0fc-160b-0410-b1d3-a4f43f01ea2e> | 2013-05-05 16:29:20 +0000 |
---|---|---|
committer | xleroy <xleroy@fca1b0fc-160b-0410-b1d3-a4f43f01ea2e> | 2013-05-05 16:29:20 +0000 |
commit | b257a6d283f6f5784cb351856b5dbe8c645a1f6f (patch) | |
tree | 3e134e46c53a5e75a3b6c78878d07a554b396367 /runtime/powerpc | |
parent | bc24cf49659f91245d8f42ca06fbe7d21a5c06cd (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.s | 25 | ||||
-rw-r--r-- | runtime/powerpc/i64_dtou.s | 21 |
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 |