about summary refs log tree commit diff
path: root/sysdeps/ia64/fpu/s_ceil.S
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/ia64/fpu/s_ceil.S')
-rw-r--r--sysdeps/ia64/fpu/s_ceil.S274
1 files changed, 156 insertions, 118 deletions
diff --git a/sysdeps/ia64/fpu/s_ceil.S b/sysdeps/ia64/fpu/s_ceil.S
index d1d2980618..f7e6d2cfa6 100644
--- a/sysdeps/ia64/fpu/s_ceil.S
+++ b/sysdeps/ia64/fpu/s_ceil.S
@@ -1,10 +1,10 @@
 .file "ceil.s"
 
-
-// Copyright (c) 2000 - 2003, Intel Corporation
+// Copyright (C) 2000, 2001, Intel Corporation
 // All rights reserved.
-//
-// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+// 
+// 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.
 //
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
@@ -20,67 +20,90 @@
 // * 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://www.intel.com/software/products/opensource/libraries/num.htm.
+// problem reports or change requests be submitted to it directly at 
+// http://developer.intel.com/opensource.
 //
+
+#include "libm_support.h"
+
+.align 32
+.global ceil#
+
+.section .text
+.proc  ceil#
+.align 32
+
 // History
 //==============================================================
-// 02/02/00 Initial version
-// 06/13/00 Improved speed
-// 06/27/00 Eliminated incorrect invalid flag setting
-// 05/20/02 Cleaned up namespace and sf0 syntax
-// 01/28/03 Improved performance
-//==============================================================
+// 2/02/00: Initial version
+// 6/13/00: Improved speed
+// 6/27/00: Eliminated incorrect invalid flag setting
 
 // API
 //==============================================================
 // double ceil(double x)
-//==============================================================
 
-// general input registers:
-// r14 - r19
+// general input registers:  
+
+ceil_GR_FFFF      = r14
+ceil_GR_signexp   = r15
+ceil_GR_exponent  = r16
+ceil_GR_expmask   = r17
+ceil_GR_bigexp    = r18
+
 
-rSignexp   = r14
-rExp       = r15
-rExpMask   = r16
-rBigexp    = r17
-rM1        = r18
-rSignexpM1 = r19
+// predicate registers used: 
 
-// floating-point registers:
-// f8 - f13
+// 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
+// p14 ==> Input is between -1 and 0, so result will be -0 and inexact
 
-fXInt      = f9
-fNormX     = f10
-fTmp       = f11
-fAdj       = f12
-fPreResult = f13
 
-// predicate registers used:
-// p6 - p10
+// floating-point registers used: 
+
+CEIL_SIGNED_ZERO  = f7
+CEIL_NORM_f8      = f9                        
+CEIL_FFFF         = f10 
+CEIL_INEXACT      = f11 
+CEIL_FLOAT_INT_f8 = f12
+CEIL_INT_f8       = f13
+CEIL_adj          = f14
+CEIL_MINUS_ONE    = f15
 
 // Overview of operation
 //==============================================================
+
 // double ceil(double x)
-// Return an integer value (represented as a double) that is the smallest
+// Return an integer value (represented as a double) that is the smallest 
 // value not less than x
 // This is x rounded toward +infinity to an integral value.
 // Inexact is set if x != ceil(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)
@@ -101,124 +124,139 @@ fPreResult = f13
 // 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
 
-.section .text
-GLOBAL_LIBM_ENTRY(ceil)
+
+ceil:
 
 { .mfi
-      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
+      getf.exp ceil_GR_signexp  = f8
+      fcvt.fx.trunc.s1     CEIL_INT_f8  = f8
+      addl        ceil_GR_bigexp = 0x10033, r0
 }
 { .mfi
-      mov              rM1 = -1              // Set all ones
-      fcvt.fx.trunc.s1 fXInt  = f8           // Convert to int in significand
-      mov              rExpMask    = 0x1FFFF // Form exponent mask
+      addl        ceil_GR_FFFF      = -1,r0
+      fcmp.lt.s1  p8,p9 = f8,f0
+      mov         ceil_GR_expmask    = 0x1FFFF ;;
 }
-;;
 
+// p7 ==> denorm
 { .mfi
-      mov              rSignexpM1  = 0x2FFFF // Form signexp of -1
-      fcmp.lt.s1       p8,p9 = f8, f0        // Test x < 0
-      nop.i            0
+      setf.sig    CEIL_FFFF  = ceil_GR_FFFF
+      fclass.m    p7,p0 = f8, 0x0b
+      nop.i 999
 }
-{ .mfb
-      setf.sig         fTmp = rM1            // Make const for setting inexact
-      fnorm.s1         fNormX  = f8          // Normalize input
-(p7)  br.cond.spnt     CEIL_UNORM            // Branch if x unorm
+{ .mfi
+      nop.m 999
+      fnorm           CEIL_NORM_f8  = f8
+      nop.i 999 ;;
 }
-;;
 
-CEIL_COMMON:
-// Return here from CEIL_UNORM
+// Form 0 with sign of input in case negative zero is needed
+{ .mfi
+      nop.m 999
+      fmerge.s           CEIL_SIGNED_ZERO = f8, f0
+      nop.i 999
+}
 { .mfi
-      nop.m            0
-      fclass.m         p6,p0 = f8, 0x1e7     // Test x natval, nan, inf, 0
-      nop.i            0
+      nop.m 999
+      fsub.s1           CEIL_MINUS_ONE = f0, f1
+      nop.i 999 ;;
+}
+
+// p6 ==> NAN, INF, ZERO
+{ .mfb
+      nop.m 999
+      fclass.m      p6,p10 = f8, 0xe7
+(p7)  br.cond.spnt  L(CEIL_DENORM) ;;
 }
-;;
 
+L(CEIL_COMMON):
 .pred.rel "mutex",p8,p9
+// Set adjustment to add to trunc(x) for result
+//   If x>0,  adjustment is 1.0
+//   If x<=0, adjustment is 0.0
 { .mfi
-      nop.m            0
-(p8)  fma.s1           fAdj = f0, f0, f0     // If x < 0, adjustment is 0
-      nop.i            0
+      and      ceil_GR_exponent = ceil_GR_signexp, ceil_GR_expmask
+(p9)  fadd.s1  CEIL_adj = f1,f0
+      nop.i 999
 }
 { .mfi
-      nop.m            0
-(p9)  fma.s1           fAdj = f1, f1, f0     // If x > 0, adjustment is +1
-      nop.i            0
+      nop.m 999
+(p8)  fadd.s1  CEIL_adj = f0,f0
+      nop.i 999 ;;
 }
-;;
 
 { .mfi
-      nop.m            0
-      fcvt.xf          fPreResult = fXInt    // trunc(x)
-      nop.i            0
+(p10) cmp.ge.unc    p10,p11 = ceil_GR_exponent, ceil_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         CEIL_FLOAT_INT_f8   = CEIL_INT_f8
+      nop.i 999 ;;
 }
-;;
 
-{ .mmi
-      and              rExp = rSignexp, rExpMask // Get biased exponent
-;;
-      cmp.ge           p7,p6 = rExp, rBigexp  // Is |x| >= 2^52?
-(p8)  cmp.lt.unc       p10,p0 = rSignexp, rSignexpM1 // Is -1 < x < 0?
+{ .mfi
+      nop.m 999
+(p10) fnorm.d f8 = CEIL_NORM_f8
+      nop.i 999 ;;
 }
-;;
 
-// If -1 < x < 0, we turn off p6 and compute result as -0
+// Is -1 < x < 0?  If so, result will be -0.  Special case it with p14 set.
 { .mfi
-(p10) cmp.ne           p6,p0 = r0,r0
-(p10) fmerge.s         f8 = fNormX, f0
-      nop.i            0
+      nop.m 999
+(p8)  fcmp.gt.unc.s1 p14,p0 = CEIL_NORM_f8, CEIL_MINUS_ONE
+      nop.i 999 ;;
 }
-;;
 
-.pred.rel "mutex",p6,p7
 { .mfi
-      nop.m            0
-(p6)  fma.d.s0         f8 = fPreResult, f1, fAdj // Result if !int, |x| < 2^52
-      nop.i            0
+(p14) cmp.ne  p11,p0 = r0,r0
+(p14) fnorm.d f8 = CEIL_SIGNED_ZERO
+      nop.i 999
 }
 { .mfi
-      nop.m            0
-(p7)  fma.d.s0         f8 = fNormX, f1, f0    // Result, if |x| >= 2^52
-(p10) cmp.eq           p6,p0 = r0,r0          // If -1 < x < 0, turn on p6 again
+      nop.m 999
+(p14) fmpy.s0     CEIL_INEXACT = CEIL_FFFF,CEIL_FFFF
+      nop.i 999 ;;
 }
-;;
 
 { .mfi
-      nop.m            0
-(p6)  fcmp.eq.unc.s1   p8, p9 = fPreResult, fNormX // Is trunc(x) = x ?
-      nop.i            0
+      nop.m 999
+(p11) fadd.d   f8 = CEIL_FLOAT_INT_f8,CEIL_adj
+      nop.i 999 ;;
+}
+{ .mfi
+      nop.m 999
+(p11) fcmp.eq.unc.s1  p12,p13  = CEIL_FLOAT_INT_f8, CEIL_NORM_f8
+      nop.i 999 ;;
 }
-;;
 
+// Set inexact if result not equal to input
 { .mfi
-      nop.m            0
-(p9)  fmpy.s0          fTmp = fTmp, fTmp      // Dummy to set inexact
-      nop.i            0
+      nop.m 999
+(p13) fmpy.s0     CEIL_INEXACT = CEIL_FFFF,CEIL_FFFF
+      nop.i 999
 }
+// Set result to input if integer
 { .mfb
-      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
+      nop.m 999
+(p12) fnorm.d f8 = CEIL_NORM_f8
+      br.ret.sptk    b0 ;;
 }
-;;
-
 
-CEIL_UNORM:
-// Here if x unorm
+// Here if input denorm
+L(CEIL_DENORM):
 { .mfb
-      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     CEIL_COMMON            // Return to main path
+      getf.exp ceil_GR_signexp  = CEIL_NORM_f8
+      fcvt.fx.trunc.s1     CEIL_INT_f8  = CEIL_NORM_f8
+      br.cond.sptk  L(CEIL_COMMON) ;;
 }
-;;
 
-GLOBAL_LIBM_END(ceil)
+.endp ceil
+ASM_SIZE_DIRECTIVE(ceil)