summary refs log tree commit diff
path: root/sysdeps/ia64/fpu/s_truncf.S
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/ia64/fpu/s_truncf.S')
-rw-r--r--sysdeps/ia64/fpu/s_truncf.S207
1 files changed, 86 insertions, 121 deletions
diff --git a/sysdeps/ia64/fpu/s_truncf.S b/sysdeps/ia64/fpu/s_truncf.S
index 0ac4181209..ff40bc7101 100644
--- a/sysdeps/ia64/fpu/s_truncf.S
+++ b/sysdeps/ia64/fpu/s_truncf.S
@@ -1,11 +1,10 @@
 .file "truncf.s"
 
-// Copyright (C) 2000, 2001, Intel Corporation
+
+// Copyright (c) 2000 - 2003, Intel Corporation
 // All rights reserved.
-// 
-// Contributed 7/7/2000 by John Harrison, Cristina Iordache, 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
@@ -21,33 +20,28 @@
 // * 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 truncf#
-
-.section .text
-.proc  truncf#
-.align 32
-
 // History
 //==============================================================
-// 7/7/00: Created 
+// 07/07/00 Created
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 01/20/03 Improved performance and reduced code size
 //==============================================================
 
 // API
@@ -55,25 +49,28 @@
 // float truncf(float x)
 //==============================================================
 
-#include "libm_support.h"
+// general input registers:
+// r14 - r18
 
-// general input registers:  
-TRUNC_GR_FFFF      = r14
-TRUNC_GR_signexp   = r15
-TRUNC_GR_exponent  = r16
-TRUNC_GR_expmask   = r17
-TRUNC_GR_bigexp    = r18
+rExpBias   = r14
+rSignexp   = r15
+rExp       = r16
+rExpMask   = r17
+rBigexp    = r18
 
 // floating-point registers:
-// f8, f9, f11, f12
+// f8 - f10
+
+fXtruncInt = f9
+fNormX     = f10
 
-// predicate registers used: 
-// p6, p7, p8, p9, p10, p11
+// predicate registers used:
+// p6, p7
 
 // Overview of operation
 //==============================================================
 // float truncf(float x)
-// Return an integer value (represented as a float) less than or 
+// Return an integer value (represented as a float) less than or
 // equal to x in magnitude.
 // This is x rounded toward zero to an integral value.
 //==============================================================
@@ -97,105 +94,73 @@ TRUNC_GR_bigexp    = r18
 // If we multiply by 2^23, we no longer have a fractional part
 // So input is an integer value already.
 
-truncf:
+.section .text
+GLOBAL_LIBM_ENTRY(truncf)
 
 { .mfi
-      getf.exp         TRUNC_GR_signexp  = f8
-      fcvt.fx.trunc.s1 f9  = f8
-      addl             TRUNC_GR_bigexp = 0x10016, r0
+      getf.exp         rSignexp  = f8        // Get signexp, recompute if unorm
+      fcvt.fx.trunc.s1 fXtruncInt  = f8      // Convert to int in significand
+      addl             rBigexp = 0x10016, r0 // Set exponent at which is integer
 }
 { .mfi
-      mov              TRUNC_GR_FFFF    = 0x0FFFF
-      fnorm.s          f11  = f8
-      mov              TRUNC_GR_expmask    = 0x1FFFF 
-};;
-//    get the exponent of x
-//    convert x to integer in signficand of f9 
-//    Normalize x - this will raise invalid on SNaNs, the
-//    denormal operand flag - and possibly a spurious U flag
-//    get exponent only mask (will exclude sign bit)
+      mov              rExpBias    = 0x0FFFF // Form exponent bias
+      fnorm.s1         fNormX  = f8          // Normalize input
+      mov              rExpMask    = 0x1FFFF // Form exponent mask
+}
+;;
 
 { .mfi
       nop.m            0
-      fclass.m         p7,p8 = f8, 0x0b  
+      fclass.m         p7,p0 = f8, 0x0b      // Test x unorm
       nop.i            0
 }
-{ .mfi
-      nop.m            0
-      fcmp.eq.unc.s1   p9,p0 = f8,f0
-      nop.i      0       
-};;
-//    fclass to set p7 if unnorm 
-{ .mmi
-      and              TRUNC_GR_exponent = TRUNC_GR_signexp, TRUNC_GR_expmask ;;
-(p8)  cmp.ge.unc       p10,p11 = TRUNC_GR_exponent, TRUNC_GR_bigexp
-(p8)  cmp.ne.unc       p6,p0 = TRUNC_GR_exponent, TRUNC_GR_signexp
-};;
-//    Get the exponent of x
-//    Test if exponent such that result already an integer
-//    Test if x < 0
-{ .mmi
-(p9)  cmp.eq.andcm     p10,p11 = r0, r0 
-(p6)  cmp.lt.unc       p6,p0 = TRUNC_GR_exponent, TRUNC_GR_FFFF
-      nop.i 0 
-};;
-//    If -1 < x < 0, set p6, turn off p10 and p11, and set result to -0.0
-{ .mfb
-(p6)  cmp.eq.andcm     p10,p11 = r0, r0 
-(p6)  fmerge.s         f8 = f8, f0
-      nop.b 0
-};;
-//    If not a unnorm, set p10 if x already is a big int, nan, or inf?
-//    If not a unnorm, set p10 if x already is a big int, nan, or inf?
-.pred.rel "mutex",p10,p11    
+;;
+
 { .mfb
       nop.m            0
-(p11) fcvt.xf          f8   = f9 
-      nop.b            0 
+      fclass.m         p6,p0 = f8, 0x1e3     // Test x natval, nan, inf
+(p7)  br.cond.spnt     TRUNC_UNORM           // Branch if x unorm
 }
+;;
+
+TRUNC_COMMON:
+// Return here from TRUNC_UNORM
 { .mfb
+      and              rExp = rSignexp, rExpMask // Get biased exponent
+(p6)  fma.s.s0         f8 = f8, f1, f0       // Result if x natval, nan, inf
+(p6)  br.ret.spnt      b0                    // Exit if x natval, nan, inf
+}
+;;
+
+{ .mfi
+      cmp.lt           p6,p0 = rExp, rExpBias // Is |x| < 1?
+      fcvt.xf          f8 = fXtruncInt        // Result, assume 1 <= |x| < 2^23
+      cmp.ge           p7,p0 = rExp, rBigexp  // Is |x| >= 2^23?
+}
+;;
+
+// We must correct result if |x| < 1, or |x| >= 2^23
+.pred.rel "mutex",p6,p7
+{ .mfi
       nop.m            0
-(p10) fma.s.s1         f8   = f11,f1,f0 
-(p8)  br.ret.sptk      b0 
-};;
-//    If not a unnorm and not an big int, nan,or +/-inf convert signficand
-//    back to f8.
-//    If not a unorm  and a big int, nan, or +/-inf, return fnorm'd x 
-//    If not a unorm, Return
-//    If unnorm, get the exponent again - perhaps it wasn't a denorm. 
-{ .mfb
-(p7)  getf.exp         TRUNC_GR_signexp  = f11
-(p7)  fcvt.fx.trunc.s1 f12   = f11 
-      nop.b 0
-};;
-{ .mfb
-      and              TRUNC_GR_exponent = TRUNC_GR_signexp, TRUNC_GR_expmask
-      fcmp.lt.unc.s1   p9,p0 = f8,f0
-      nop.b            0
-};;
-{ .mfb
-      cmp.ge.unc       p10,p11 = TRUNC_GR_exponent, TRUNC_GR_bigexp
-      nop.f            0
-      nop.b            0
-};;
-// If a unnorm, check to see if value is already a big int. 
+(p6)  fmerge.s         f8 = fNormX, f0        // If |x| < 1, result sgn(x)*0
+      nop.i            0
+}
 { .mfb
-      nop.m 0
-(p11) fcvt.xf          f8   = f12 
-      nop.b 0
+      nop.m            0
+(p7)  fma.s.s0         f8 = fNormX, f1, f0    // If |x| >= 2^23, result x
+      br.ret.sptk      b0                     // Exit main path
 }
-{ .mfi
-      nop.m 0
-(p10) fma.s.s1         f8   = f11,f1,f0 
-      nop.i 0
-};;
+;;
+
+
+TRUNC_UNORM:
+// Here if x unorm
 { .mfb
-      nop.m 0
-(p9)  fmerge.ns        f8   = f1,f8 
-      br.ret.sptk      b0 
-};;
-// If so return it. Otherwise, return (fcvt.xf(fcvt.fx.trunc(x)))
-// Make sure the result is negative if it should be - that is
-// negative(denormal) -> -0.
-.endp truncf
-ASM_SIZE_DIRECTIVE(truncf)
+      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     TRUNC_COMMON           // Return to main path
+}
+;;
+
+GLOBAL_LIBM_END(truncf)