aboutsummaryrefslogtreecommitdiffstats
path: root/runtime/powerpc64
diff options
context:
space:
mode:
authorXavier Leroy <xavier.leroy@college-de-france.fr>2020-03-29 11:20:01 +0200
committerXavier Leroy <xavierleroy@users.noreply.github.com>2020-03-30 17:26:17 +0200
commitf1abe04e503f1c54c5a50f7b3f3906beca15a760 (patch)
treec348b8cd5f6683d03eda0bfb8b528e9a12a76b18 /runtime/powerpc64
parentf2de2518509f198c5ce958ec06c18e78e896f814 (diff)
downloadcompcert-kvx-f1abe04e503f1c54c5a50f7b3f3906beca15a760.tar.gz
compcert-kvx-f1abe04e503f1c54c5a50f7b3f3906beca15a760.zip
Double rounding error in int64->float32 conversions on PowerPC and ARM
The "stof" and "utof" runtime functions contain a round-to-odd step that avoids double rounding. However, this step was incorrectly coded on PowerPC (stof and utof), PowerPC64 (utof), and ARM (stof), making round-to-odd ineffective and causing double rounding. Closes: #343
Diffstat (limited to 'runtime/powerpc64')
-rw-r--r--runtime/powerpc64/i64_utof.s10
1 files changed, 5 insertions, 5 deletions
diff --git a/runtime/powerpc64/i64_utof.s b/runtime/powerpc64/i64_utof.s
index cdb2f867..4a2a172b 100644
--- a/runtime/powerpc64/i64_utof.s
+++ b/runtime/powerpc64/i64_utof.s
@@ -48,11 +48,11 @@ __compcert_i64_utof:
# X is large enough that double rounding can occur.
# Avoid it by nudging X away from the points where double rounding
# occurs (the "round to odd" technique)
- rlwinm r0, r4, 0, 21, 31 # extract bits 0 to 11 of X
- addi r0, r0, 0x7FF # r0 = (X & 0x7FF) + 0x7FF
- # bit 12 of r0 is 0 if all low 12 bits of X are 0, 1 otherwise
- # bits 13-31 of r0 are 0
- or r4, r4, r0 # correct bit number 12 of X
+ rlwinm r5, r4, 0, 21, 31 # extract bits 0 to 11 of X
+ addi r5, r5, 0x7FF # r5 = (X & 0x7FF) + 0x7FF
+ # bit 12 of r5 is 0 if all low 12 bits of X are 0, 1 otherwise
+ # bits 13-31 of r5 are 0
+ or r4, r4, r5 # correct bit number 12 of X
rlwinm r4, r4, 0, 0, 20 # set to 0 bits 0 to 11 of X
# Convert to double, then round to single
1: bl __compcert_i64_utod