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
