diff options
Diffstat (limited to 'sysdeps/ia64/fpu/s_floorl.S')
-rw-r--r-- | sysdeps/ia64/fpu/s_floorl.S | 250 |
1 files changed, 114 insertions, 136 deletions
diff --git a/sysdeps/ia64/fpu/s_floorl.S b/sysdeps/ia64/fpu/s_floorl.S index 294578e1a7..345c4f30dd 100644 --- a/sysdeps/ia64/fpu/s_floorl.S +++ b/sysdeps/ia64/fpu/s_floorl.S @@ -1,10 +1,10 @@ .file "floorl.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,85 +20,67 @@ // * 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 floorl# - -.section .text -.proc floorl# -.align 32 - // History //============================================================== -// 2/02/00: Initial version -// 6/13/00: Improved speed -// 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 +// 06/13/00 Improved speed +// 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 //============================================================== // long double floorl(long 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 //============================================================== - // long double floorl(long double x) -// Return an integer value (represented as a long double) that is the largest +// Return an integer value (represented as a long 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 != floorl(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) @@ -119,119 +101,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" -floorl: -#ifdef _LIBC -.global __floorl -__floorl: -#endif +.section .text +GLOBAL_IEEE754_ENTRY(floorl) { .mfi - getf.exp floor_GR_signexp = f8 - fcvt.fx.trunc.s1 FLOOR_INT_f8 = f8 - addl floor_GR_bigexp = 0x1003e, r0 + getf.exp rSignexp = f8 // Get signexp, recompute if unorm + fclass.m p7,p0 = f8, 0x0b // Test x unorm + addl rBigexp = 0x1003e, 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 f8 = f8 - nop.i 999 ;; +{ .mfb + nop.m 0 +(p6) fma.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^63? + nop.i 0 } +;; { .mfi - nop.m 999 -(p10) fnorm f8 = FLOOR_NORM_f8 - nop.i 999 ;; + nop.m 0 +(p6) fma.s0 f8 = fPreResult, f1, fAdj // Result if !int, |x| < 2^63 + nop.i 0 } - { .mfi - nop.m 999 -(p11) fadd f8 = FLOOR_FLOAT_INT_f8,FLOOR_adj - nop.i 999 ;; + nop.m 0 +(p7) fma.s0 f8 = fNormX, f1, f0 // Result, if |x| >= 2^63 + 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 f8 = FLOOR_NORM_f8 - br.ret.sptk b0 ;; + nop.m 0 +(p8) fma.s0 f8 = fNormX, f1, f0 // If x int, result normalized x + br.ret.sptk b0 // Exit main path, 0 < |x| < 2^63 } +;; + -// 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 floorl -ASM_SIZE_DIRECTIVE(floorl) +GLOBAL_IEEE754_END(floorl) |