aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog8
-rw-r--r--NEWS2
-rw-r--r--sysdeps/powerpc/powerpc32/fpu/s_lround.S43
3 files changed, 50 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index 8a308891ea..997ad1381f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2015-10-14 Joseph Myers <joseph@codesourcery.com>
+
+ [BZ #19134]
+ * sysdeps/powerpc/powerpc32/fpu/s_lround.S (.LC1): New object.
+ (.LC2): Likewise.
+ (.LC3): Likewise.
+ (__lround): Do not add 0.5 to integer or out-of-range arguments.
+
2015-10-14 Szabolcs Nagy <szabolcs.nagy@arm.com>
[BZ #19129]
diff --git a/NEWS b/NEWS
index fd33e079f6..d4e8b4adf2 100644
--- a/NEWS
+++ b/NEWS
@@ -20,7 +20,7 @@ Version 2.23
18966, 18967, 18969, 18970, 18977, 18980, 18981, 18985, 19003, 19007,
19012, 19016, 19018, 19032, 19046, 19049, 19050, 19059, 19071, 19074,
19076, 19077, 19078, 19079, 19085, 19086, 19088, 19094, 19095, 19124,
- 19125, 19129
+ 19125, 19129, 19134
* The obsolete header <regexp.h> has been removed. Programs that require
this header must be updated to use <regex.h> instead.
diff --git a/sysdeps/powerpc/powerpc32/fpu/s_lround.S b/sysdeps/powerpc/powerpc32/fpu/s_lround.S
index 231d5e4f45..5dd3618524 100644
--- a/sysdeps/powerpc/powerpc32/fpu/s_lround.S
+++ b/sysdeps/powerpc/powerpc32/fpu/s_lround.S
@@ -23,6 +23,16 @@
.align 2
.LC0: /* 0.5 */
.long 0x3f000000
+.LC1: /* 2^52. */
+ .long 0x59800000
+ .section .rodata.cst8,"aM",@progbits,8
+ .align 3
+.LC2: /* 0x7fffffff.8p0. */
+ .long 0x41dfffff
+ .long 0xffe00000
+.LC3: /* -0x80000000.8p0. */
+ .long 0xc1e00000
+ .long 0x00100000
.section ".text"
/* long [r3] lround (float x [fp1])
@@ -45,19 +55,40 @@ ENTRY (__lround)
mflr r11
cfi_register(lr,r11)
SETUP_GOT_ACCESS(r9,got_label)
- addis r9,r9,.LC0-got_label@ha
- lfs fp10,.LC0-got_label@l(r9)
+ addis r10,r9,.LC0-got_label@ha
+ lfs fp10,.LC0-got_label@l(r10)
+ addis r10,r9,.LC1-got_label@ha
+ lfs fp11,.LC1-got_label@l(r10)
+ addis r10,r9,.LC2-got_label@ha
+ lfd fp9,.LC2-got_label@l(r10)
+ addis r10,r9,.LC3-got_label@ha
+ lfd fp8,.LC3-got_label@l(r10)
mtlr r11
cfi_same_value (lr)
#else
lis r9,.LC0@ha
lfs fp10,.LC0@l(r9)
+ lis r9,.LC1@ha
+ lfs fp11,.LC1@l(r9)
+ lis r9,.LC2@ha
+ lfd fp9,.LC2@l(r9)
+ lis r9,.LC3@ha
+ lfd fp8,.LC3@l(r9)
#endif
fabs fp2, fp1 /* Get the absolute value of x. */
fsub fp12,fp10,fp10 /* Compute 0.0. */
fcmpu cr6, fp2, fp10 /* if |x| < 0.5 */
+ fcmpu cr5, fp1, fp9 /* if x >= 0x7fffffff.8p0 */
+ fcmpu cr1, fp1, fp8 /* if x <= -0x80000000.8p0 */
fcmpu cr7, fp1, fp12 /* x is negative? x < 0.0 */
blt- cr6,.Lretzero
+ bge- cr5,.Loflow
+ ble- cr1,.Loflow
+ /* Test whether an integer to avoid spurious "inexact". */
+ fadd fp3,fp2,fp11
+ fsub fp3,fp3,fp11
+ fcmpu cr5, fp2, fp3
+ beq cr5,.Lnobias
fadd fp3,fp2,fp10 /* |x|+=0.5 bias to prepare to round. */
bge cr7,.Lconvert /* x is positive so don't negate x. */
fnabs fp3,fp3 /* -(|x|+=0.5) */
@@ -74,6 +105,14 @@ ENTRY (__lround)
.Lretzero: /* when 0.5 > x > -0.5 */
li r3,0 /* return 0. */
b .Lout
+.Lnobias:
+ fmr fp3,fp1
+ b .Lconvert
+.Loflow:
+ fmr fp3,fp11
+ bge cr7,.Lconvert
+ fnabs fp3,fp3
+ b .Lconvert
END (__lround)
weak_alias (__lround, lround)