about summary refs log tree commit diff
path: root/sysdeps
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@gmail.com>2011-09-14 12:58:43 -0400
committerUlrich Drepper <drepper@gmail.com>2011-09-14 12:58:43 -0400
commitcd20565401bfb2abc41203667aba681c44a96697 (patch)
tree0759570d4388ef57d29f3075cbb9dc69cc04b3dd /sysdeps
parent48b67d71ec677d1b3168e52a68b644784cead604 (diff)
downloadglibc-cd20565401bfb2abc41203667aba681c44a96697.tar.gz
glibc-cd20565401bfb2abc41203667aba681c44a96697.tar.xz
glibc-cd20565401bfb2abc41203667aba681c44a96697.zip
Optimized lrint and llrint for x86-64
Diffstat (limited to 'sysdeps')
-rw-r--r--sysdeps/x86_64/fpu/bits/mathinline.h56
1 files changed, 46 insertions, 10 deletions
diff --git a/sysdeps/x86_64/fpu/bits/mathinline.h b/sysdeps/x86_64/fpu/bits/mathinline.h
index dc58f67d6c..9f2c4d9689 100644
--- a/sysdeps/x86_64/fpu/bits/mathinline.h
+++ b/sysdeps/x86_64/fpu/bits/mathinline.h
@@ -1,7 +1,6 @@
 /* Inline math functions for x86-64.
-   Copyright (C) 2002, 2003, 2004, 2007, 2009 Free Software Foundation, Inc.
+   Copyright (C) 2002-2004, 2007, 2009, 2011 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
-   Contributed by Andreas Jaeger <aj@suse.de>, 2002.
 
    The GNU C Library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
@@ -24,10 +23,10 @@
 
 #include <bits/wordsize.h>
 
-#ifndef __extern_inline
+#ifndef __extern_always_inline
 # define __MATH_INLINE __inline
 #else
-# define __MATH_INLINE __extern_inline
+# define __MATH_INLINE __extern_always_inline
 #endif
 
 
@@ -37,26 +36,26 @@
 __MATH_INLINE int
 __NTH (__signbitf (float __x))
 {
-#if __WORDSIZE == 32
+# if __WORDSIZE == 32
   __extension__ union { float __f; int __i; } __u = { __f: __x };
   return __u.__i < 0;
-#else
+# else
   int __m;
   __asm ("pmovmskb %1, %0" : "=r" (__m) : "x" (__x));
   return __m & 0x8;
-#endif
+# endif
 }
 __MATH_INLINE int
 __NTH (__signbit (double __x))
 {
-#if __WORDSIZE == 32
+# if __WORDSIZE == 32
   __extension__ union { double __d; int __i[2]; } __u = { __d: __x };
   return __u.__i[1] < 0;
-#else
+# else
   int __m;
   __asm ("pmovmskb %1, %0" : "=r" (__m) : "x" (__x));
   return __m & 0x80;
-#endif
+# endif
 }
 __MATH_INLINE int
 __NTH (__signbitl (long double __x))
@@ -64,4 +63,41 @@ __NTH (__signbitl (long double __x))
   __extension__ union { long double __l; int __i[3]; } __u = { __l: __x };
   return (__u.__i[2] & 0x8000) != 0;
 }
+
+/* Round to nearest integer.  */
+# if __WORDSIZE == 64 || defined __SSE_MATH__
+__MATH_INLINE long int
+__NTH (lrintf (float __x))
+{
+  long int __res;
+  asm ("cvtss2si %1, %0" : "=r" (__res) : "xm" (__x));
+  return __res;
+}
+# endif
+# if __WORDSIZE == 64 || defined __SSE2_MATH__
+__MATH_INLINE long int
+__NTH (lrint (double __x))
+{
+  long int __res;
+  asm ("cvtsd2si %1, %0" : "=r" (__res) : "xm" (__x));
+  return __res;
+}
+# endif
+# if __WORDSIZE == 64
+__MATH_INLINE long long int
+__NTH (llrintf (float __x))
+{
+  long long int __res;
+  asm ("cvtss2si %1, %0" : "=r" (__res) : "xm" (__x));
+  return __res;
+}
+__MATH_INLINE long long int
+__NTH (llrint (double __x))
+{
+  long long int __res;
+  asm ("cvtsd2si %1, %0" : "=r" (__res) : "xm" (__x));
+  return __res;
+}
+# endif
+
 #endif