This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: Fix lrint, llrint missing exceptions close to overflow threshold (bug 19094) [committed]
- From: "H.J. Lu" <hjl dot tools at gmail dot com>
- To: Joseph Myers <joseph at codesourcery dot com>
- Cc: GNU C Library <libc-alpha at sourceware dot org>
- Date: Fri, 9 Oct 2015 11:44:08 -0700
- Subject: Re: Fix lrint, llrint missing exceptions close to overflow threshold (bug 19094) [committed]
- Authentication-results: sourceware.org; auth=none
On Fri, Oct 9, 2015 at 10:27 AM, Joseph Myers <joseph@codesourcery.com> wrote:
> On Fri, 9 Oct 2015, H.J. Lu wrote:
>
>> testing double (without inline functions)
>> Failure: lrint (0x1p31): Exception "Invalid operation" not set
> [...]
>>
>> on x32. Do you know why?
>
> The x86_64 versions of lrint / lrintf / lrintl are aliases for the long
> long versions. This isn't correct for x32, where exceptions must respect
> overflow for 32-bit long. I think you need to write separate versions of
> the long functions for x32 that convert to 32-bit long and raise the right
> exceptions for that conversion, while keeping the aliases in the non-x32
> case.
>
This is what I checked in.
Thanks.
--
H.J.
From 4b71ce6c1a50c14c758f1dd7a2943f2ab9760e85 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Fri, 9 Oct 2015 11:33:30 -0700
Subject: [PATCH] Update lrint/lrintf/lrintl for x32
The x86_64 versions of lrint/lrintf/ lrintl are aliases for the long
long versions which isn't correct for x32, where exceptions must respect
overflow for 32-bit long. Separate versions of the long functions for
x32 that convert to 32-bit long and raise the right exceptions for that
conversion, while keeping the aliases in the non-x32 case.
Tested on x86_64 and x32. There are no code changes in libm.so on
x86_64.
* sysdeps/x86_64/fpu/s_llrint.S (__lrint): Add alias only if
__ILP32__ isn't defined.
(lrint): Likewise.
* sysdeps/x86_64/fpu/s_llrintf.S (__lrintf): Likewise.
(lrintf): Likewise.
* sysdeps/x86_64/fpu/s_llrintl.S (__lrintl): Likewise.
(lrintl): Likewise.
* sysdeps/x86_64/x32/fpu/s_lrint.S: New file.
* sysdeps/x86_64/x32/fpu/s_lrintf.S: Likewise.
* sysdeps/x86_64/x32/fpu/s_lrintl.S: Likewise.
---
ChangeLog | 13 +++++++++++++
sysdeps/x86_64/fpu/s_llrint.S | 2 ++
sysdeps/x86_64/fpu/s_llrintf.S | 2 ++
sysdeps/x86_64/fpu/s_llrintl.S | 3 ++-
sysdeps/x86_64/x32/fpu/s_lrint.S | 27 +++++++++++++++++++++++++++
sysdeps/x86_64/x32/fpu/s_lrintf.S | 27 +++++++++++++++++++++++++++
sysdeps/x86_64/x32/fpu/s_lrintl.S | 30 ++++++++++++++++++++++++++++++
7 files changed, 103 insertions(+), 1 deletion(-)
create mode 100644 sysdeps/x86_64/x32/fpu/s_lrint.S
create mode 100644 sysdeps/x86_64/x32/fpu/s_lrintf.S
create mode 100644 sysdeps/x86_64/x32/fpu/s_lrintl.S
diff --git a/ChangeLog b/ChangeLog
index 025a3d8..cf987c6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2015-10-09 H.J. Lu <hongjiu.lu@intel.com>
+
+ * sysdeps/x86_64/fpu/s_llrint.S (__lrint): Add alias only if
+ __ILP32__ isn't defined.
+ (lrint): Likewise.
+ * sysdeps/x86_64/fpu/s_llrintf.S (__lrintf): Likewise.
+ (lrintf): Likewise.
+ * sysdeps/x86_64/fpu/s_llrintl.S (__lrintl): Likewise.
+ (lrintl): Likewise.
+ * sysdeps/x86_64/x32/fpu/s_lrint.S: New file.
+ * sysdeps/x86_64/x32/fpu/s_lrintf.S: Likewise.
+ * sysdeps/x86_64/x32/fpu/s_lrintl.S: Likewise.
+
2015-10-09 Adhemerval Zanella <adhemerval.zanella@linaro.org>
* sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
diff --git a/sysdeps/x86_64/fpu/s_llrint.S b/sysdeps/x86_64/fpu/s_llrint.S
index e822c06..07061a7 100644
--- a/sysdeps/x86_64/fpu/s_llrint.S
+++ b/sysdeps/x86_64/fpu/s_llrint.S
@@ -26,5 +26,7 @@ ENTRY(__llrint)
ret
END(__llrint)
weak_alias (__llrint, llrint)
+#ifndef __ILP32__
strong_alias (__llrint, __lrint)
weak_alias (__llrint, lrint)
+#endif
diff --git a/sysdeps/x86_64/fpu/s_llrintf.S b/sysdeps/x86_64/fpu/s_llrintf.S
index 6825511..a2e763c 100644
--- a/sysdeps/x86_64/fpu/s_llrintf.S
+++ b/sysdeps/x86_64/fpu/s_llrintf.S
@@ -26,5 +26,7 @@ ENTRY(__llrintf)
ret
END(__llrintf)
weak_alias (__llrintf, llrintf)
+#ifndef __ILP32__
strong_alias (__llrintf, __lrintf)
weak_alias (__llrintf, lrintf)
+#endif
diff --git a/sysdeps/x86_64/fpu/s_llrintl.S b/sysdeps/x86_64/fpu/s_llrintl.S
index abe3a5b..2b6c6f3 100644
--- a/sysdeps/x86_64/fpu/s_llrintl.S
+++ b/sysdeps/x86_64/fpu/s_llrintl.S
@@ -28,6 +28,7 @@ ENTRY(__llrintl)
ret
END(__llrintl)
weak_alias (__llrintl, llrintl)
+#ifndef __ILP32__
strong_alias (__llrintl, __lrintl)
weak_alias (__llrintl, lrintl)
-
+#endif
diff --git a/sysdeps/x86_64/x32/fpu/s_lrint.S b/sysdeps/x86_64/x32/fpu/s_lrint.S
new file mode 100644
index 0000000..4d183d1
--- /dev/null
+++ b/sysdeps/x86_64/x32/fpu/s_lrint.S
@@ -0,0 +1,27 @@
+/* Round argument to nearest integral value according to current rounding
+ direction.
+ Copyright (C) 2015 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+
+ .text
+ENTRY(__lrint)
+ cvtsd2si %xmm0,%eax
+ ret
+END(__lrint)
+weak_alias (__lrint, lrint)
diff --git a/sysdeps/x86_64/x32/fpu/s_lrintf.S b/sysdeps/x86_64/x32/fpu/s_lrintf.S
new file mode 100644
index 0000000..4b3a54e
--- /dev/null
+++ b/sysdeps/x86_64/x32/fpu/s_lrintf.S
@@ -0,0 +1,27 @@
+/* Round argument to nearest integral value according to current rounding
+ direction.
+ Copyright (C) 2015 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+
+ .text
+ENTRY(__lrintf)
+ cvtss2si %xmm0,%eax
+ ret
+END(__lrintf)
+weak_alias (__lrintf, lrintf)
diff --git a/sysdeps/x86_64/x32/fpu/s_lrintl.S b/sysdeps/x86_64/x32/fpu/s_lrintl.S
new file mode 100644
index 0000000..b10bf34
--- /dev/null
+++ b/sysdeps/x86_64/x32/fpu/s_lrintl.S
@@ -0,0 +1,30 @@
+/* Round argument to nearest integral value according to current rounding
+ direction.
+ Copyright (C) 1997-2015 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+
+ .text
+ENTRY(__lrintl)
+ fldt 8(%rsp)
+ fistpl -4(%rsp)
+ fwait
+ movl -4(%rsp),%eax
+ ret
+END(__lrintl)
+weak_alias (__lrintl, lrintl)
--
2.4.3