about summary refs log tree commit diff
path: root/sysdeps/ia64/fpu/s_floor.S
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/ia64/fpu/s_floor.S')
-rw-r--r--sysdeps/ia64/fpu/s_floor.S252
1 files changed, 114 insertions, 138 deletions
diff --git a/sysdeps/ia64/fpu/s_floor.S b/sysdeps/ia64/fpu/s_floor.S
index 438b0fa867..9ed9d6dcdb 100644
--- a/sysdeps/ia64/fpu/s_floor.S
+++ b/sysdeps/ia64/fpu/s_floor.S
@@ -1,10 +1,10 @@
 .file "floor.s"
 
-// Copyright (C) 2000, 2001, Intel Corporation
+
+// Copyright (c) 2000 - 2003, Intel Corporation
 // All rights reserved.
-// 
-// Contributed 2/2/2000 by John Harrison, Ted Kubaska, Bob Norin, Shane Story,
-// and Ping Tak Peter Tang of the Computational Software Lab, Intel Corporation.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
 //
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
@@ -20,86 +20,68 @@
 // * The name of Intel Corporation may not be used to endorse or promote
 // products derived from this software without specific prior written
 // permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS 
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 // OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
-// 
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
 // Intel Corporation is the author of this code, and requests that all
-// problem reports or change requests be submitted to it directly at 
-// http://developer.intel.com/opensource.
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
 //
-.align 32
-.global floor#
-
-.section .text
-.proc  floor#
-.align 32
-
 // History
 //==============================================================
-// 2/02/00: Initial version
-// 3/22/00: Updated to improve performance 
-// 6/13/00: Improved speed, fixed setting of inexact flag
-// 6/27/00: Eliminated incorrect invalid flag setting
-// 2/07/01: Corrected sign of zero result in round to -inf mode
+// 02/02/00 Initial version
+// 03/22/00 Updated to improve performance
+// 06/13/00 Improved speed, fixed setting of inexact flag
+// 06/27/00 Eliminated incorrect invalid flag setting
+// 02/07/01 Corrected sign of zero result in round to -inf mode
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 01/28/03 Improved performance
+//==============================================================
 
 // API
 //==============================================================
 // double floor(double x)
+//==============================================================
 
-// general input registers:  
-
-floor_GR_FFFF      = r14
-floor_GR_signexp   = r15
-floor_GR_exponent  = r16
-floor_GR_expmask   = r17
-floor_GR_bigexp    = r18
-
-
-// predicate registers used: 
+// general input registers:
+// r14 - r18
 
-// p6  ==> Input is NaN, infinity, zero
-// p7  ==> Input is denormal
-// p8  ==> Input is <0
-// p9  ==> Input is >=0
-// p10 ==> Input is already an integer (bigger than largest integer)
-// p11 ==> Input is not a large integer
-// p12 ==> Input is a smaller integer
-// p13 ==> Input is not an even integer, so inexact must be set
+rSignexp   = r14
+rExp       = r15
+rExpMask   = r16
+rBigexp    = r17
+rM1        = r18
 
+// floating-point registers:
+// f8 - f13
 
-// floating-point registers used: 
+fXInt      = f9
+fNormX     = f10
+fTmp       = f11
+fAdj       = f12
+fPreResult = f13
 
-FLOOR_NORM_f8      = f9                        
-FLOOR_FFFF         = f10 
-FLOOR_INEXACT      = f11 
-FLOOR_FLOAT_INT_f8 = f12
-FLOOR_INT_f8       = f13
-FLOOR_adj          = f14
+// predicate registers used:
+// p6 - p9
 
 // Overview of operation
 //==============================================================
-
 // double floor(double x)
-// Return an integer value (represented as a double) that is the largest 
+// Return an integer value (represented as a double) that is the largest
 // value not greater than x
 // This is x rounded toward -infinity to an integral value.
 // Inexact is set if x != floor(x)
-// **************************************************************************
-
-// Set denormal flag for denormal input and
-// and take denormal fault if necessary.
-
-// Is the input an integer value already?
+//==============================================================
 
 // double_extended
 // if the exponent is > 1003e => 3F(true) = 63(decimal)
@@ -120,121 +102,115 @@ FLOOR_adj          = f14
 // If we multiply by 2^23, we no longer have a fractional part
 // So input is an integer value already.
 
-// If x is NAN, ZERO, or INFINITY, then  return
-
-// qnan snan inf norm     unorm 0 -+
-// 1    1    1   0        0     1 11     0xe7
-
-#include "libm_support.h"
 
-floor:
-#ifdef _LIBC
-.global __floor
-__floor:
-#endif
+.section .text
+GLOBAL_IEEE754_ENTRY(floor)
 
 { .mfi
-      getf.exp floor_GR_signexp  = f8
-      fcvt.fx.trunc.s1     FLOOR_INT_f8  = f8
-      addl        floor_GR_bigexp = 0x10033, r0
+      getf.exp         rSignexp  = f8        // Get signexp, recompute if unorm
+      fclass.m         p7,p0 = f8, 0x0b      // Test x unorm
+      addl             rBigexp = 0x10033, r0 // Set exponent at which is integer
 }
 { .mfi
-      addl        floor_GR_FFFF      = -1,r0
-      fcmp.lt.s1  p8,p9 = f8,f0
-      mov         floor_GR_expmask    = 0x1FFFF ;;
+      mov              rM1 = -1              // Set all ones
+      fcvt.fx.trunc.s1 fXInt  = f8           // Convert to int in significand
+      mov              rExpMask    = 0x1FFFF // Form exponent mask
 }
+;;
 
-// p7 ==> denorm
 { .mfi
-      setf.sig    FLOOR_FFFF  = floor_GR_FFFF
-      fclass.m    p7,p0 = f8, 0x0b
-      nop.i 999
+      nop.m            0
+      fcmp.lt.s1       p8,p9 = f8, f0        // Test x < 0
+      nop.i            0
 }
-{ .mfi
-      nop.m 999
-      fnorm.s1           FLOOR_NORM_f8  = f8
-      nop.i 999 ;;
+{ .mfb
+      setf.sig         fTmp = rM1            // Make const for setting inexact
+      fnorm.s1         fNormX  = f8          // Normalize input
+(p7)  br.cond.spnt     FLOOR_UNORM           // Branch if x unorm
 }
+;;
 
-// p6 ==> NAN, INF, ZERO
-{ .mfb
-      nop.m 999
-      fclass.m      p6,p10 = f8, 0xe7
-(p7)  br.cond.spnt  L(FLOOR_DENORM) ;;
+FLOOR_COMMON:
+// Return here from FLOOR_UNORM
+{ .mfi
+      nop.m            0
+      fclass.m         p6,p0 = f8, 0x1e7     // Test x natval, nan, inf, 0
+      nop.i            0
 }
+;;
 
-L(FLOOR_COMMON):
 .pred.rel "mutex",p8,p9
-// Set adjustment to subtract from trunc(x) for result
-//   If x<0,  adjustment is -1.0
-//   If x>=0, adjustment is 0.0
 { .mfi
-      and      floor_GR_exponent = floor_GR_signexp, floor_GR_expmask
-(p8)  fnma.s1  FLOOR_adj = f1,f1,f0
-      nop.i 999
+      nop.m            0
+(p8)  fnma.s1          fAdj = f1, f1, f0     // If x < 0, adjustment is -1
+      nop.i            0
 }
 { .mfi
-      nop.m 999
-(p9)  fadd.s1  FLOOR_adj = f0,f0
-      nop.i 999 ;;
+      nop.m            0
+(p9)  fma.s1           fAdj = f0, f0, f0     // If x > 0, adjustment is 0
+      nop.i            0
 }
+;;
 
 { .mfi
-      nop.m 999
-      fcmp.eq.s0  p12,p0 = f8,f0 // Dummy op to set denormal and invalid flag
-      nop.i 999
+      nop.m            0
+      fcvt.xf          fPreResult = fXInt    // trunc(x)
+      nop.i            0
 }
-{ .mfi
-(p10) cmp.ge.unc    p10,p11 = floor_GR_exponent, floor_GR_bigexp
-(p6)  fnorm.d f8 = f8
-      nop.i 999 ;;
+{ .mfb
+      nop.m            0
+(p6)  fma.d.s0         f8 = f8, f1, f0       // Result if x natval, nan, inf, 0
+(p6)  br.ret.spnt      b0                    // Exit if x natval, nan, inf, 0
 }
+;;
 
-{ .mfi
-      nop.m 999
-(p11) fcvt.xf         FLOOR_FLOAT_INT_f8   = FLOOR_INT_f8
-      nop.i 999 ;;
+{ .mmi
+      and              rExp = rSignexp, rExpMask // Get biased exponent
+;;
+      cmp.ge           p7,p6 = rExp, rBigexp  // Is |x| >= 2^52?
+      nop.i            0
 }
+;;
 
 { .mfi
-      nop.m 999
-(p10) fnorm.d f8 = FLOOR_NORM_f8
-      nop.i 999 ;;
+      nop.m            0
+(p6)  fma.d.s0         f8 = fPreResult, f1, fAdj // Result if !int, |x| < 2^52
+      nop.i            0
 }
-
-
 { .mfi
-      nop.m 999
-(p11) fadd.d   f8 = FLOOR_FLOAT_INT_f8,FLOOR_adj
-      nop.i 999 ;;
+      nop.m            0
+(p7)  fma.d.s0         f8 = fNormX, f1, f0    // Result, if |x| >= 2^52
+      nop.i            0
 }
+;;
 
 { .mfi
-      nop.m 999
-(p11) fcmp.eq.unc.s1  p12,p13  = FLOOR_FLOAT_INT_f8, FLOOR_NORM_f8
-      nop.i 999 ;;
+      nop.m            0
+(p6)  fcmp.eq.unc.s1   p8, p9 = fPreResult, fNormX // Is trunc(x) = x ?
+      nop.i            0
 }
+;;
 
-// Set inexact if result not equal to input
 { .mfi
-      nop.m 999
-(p13) fmpy.s0     FLOOR_INEXACT = FLOOR_FFFF,FLOOR_FFFF
-      nop.i 999
+      nop.m            0
+(p9)  fmpy.s0          fTmp = fTmp, fTmp      // Dummy to set inexact
+      nop.i            0
 }
-// Set result to input if integer
 { .mfb
-      nop.m 999
-(p12) fnorm.d f8 = FLOOR_NORM_f8
-      br.ret.sptk    b0 ;;
+      nop.m            0
+(p8)  fma.d.s0         f8 = fNormX, f1, f0    // If x int, result normalized x
+      br.ret.sptk      b0                     // Exit main path, 0 < |x| < 2^52
 }
+;;
+
 
-// Here if input denorm
-L(FLOOR_DENORM):
+FLOOR_UNORM:
+// Here if x unorm
 { .mfb
-      getf.exp floor_GR_signexp  = FLOOR_NORM_f8
-      fcvt.fx.trunc.s1     FLOOR_INT_f8  = FLOOR_NORM_f8
-      br.cond.sptk  L(FLOOR_COMMON) ;;
+      getf.exp         rSignexp  = fNormX     // Get signexp, recompute if unorm
+      fcmp.eq.s0       p7,p0 = f8, f0         // Dummy op to set denormal flag
+      br.cond.sptk     FLOOR_COMMON           // Return to main path
 }
+;;
 
-.endp floor
-ASM_SIZE_DIRECTIVE(floor)
+GLOBAL_IEEE754_END(floor)