diff options
author | Ulrich Drepper <drepper@redhat.com> | 2005-03-31 10:02:53 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2005-03-31 10:02:53 +0000 |
commit | ee6189855aab3a9be8f3c2d95ce2b2cd17db4ec2 (patch) | |
tree | cf3e2fe1f9be5b358033fd927a0bd922542e04a1 /sysdeps/ia64/fpu/s_nextafterl.S | |
parent | 4d6302cf51b16a129addf7687c91490c40a7225c (diff) | |
download | glibc-ee6189855aab3a9be8f3c2d95ce2b2cd17db4ec2.tar.gz glibc-ee6189855aab3a9be8f3c2d95ce2b2cd17db4ec2.tar.xz glibc-ee6189855aab3a9be8f3c2d95ce2b2cd17db4ec2.zip |
* sysdeps/unix/sysv/linux/x86_64/getcontext.S: Use functionally
equivalent, but shorter instructions. * sysdeps/unix/sysv/linux/x86_64/sysdep.h: Likewise. * sysdeps/unix/sysv/linux/x86_64/setcontext.S: Likewise. * sysdeps/unix/sysv/linux/x86_64/clone.S: Likewise. * sysdeps/unix/sysv/linux/x86_64/swapcontext.S: Likewise. * sysdeps/unix/x86_64/sysdep.S: Likewise. * sysdeps/x86_64/strchr.S: Likewise. * sysdeps/x86_64/memset.S: Likewise. * sysdeps/x86_64/strcspn.S: Likewise. * sysdeps/x86_64/strcmp.S: Likewise. * sysdeps/x86_64/elf/start.S: Likewise. * sysdeps/x86_64/strspn.S: Likewise. * sysdeps/x86_64/dl-machine.h: Likewise. * sysdeps/x86_64/bsd-_setjmp.S: Likewise. * sysdeps/x86_64/bsd-setjmp.S: Likewise. * sysdeps/x86_64/strtok.S: Likewise.
Diffstat (limited to 'sysdeps/ia64/fpu/s_nextafterl.S')
-rw-r--r-- | sysdeps/ia64/fpu/s_nextafterl.S | 266 |
1 files changed, 134 insertions, 132 deletions
diff --git a/sysdeps/ia64/fpu/s_nextafterl.S b/sysdeps/ia64/fpu/s_nextafterl.S index 05bdd9c17a..20c927b1cc 100644 --- a/sysdeps/ia64/fpu/s_nextafterl.S +++ b/sysdeps/ia64/fpu/s_nextafterl.S @@ -1,7 +1,7 @@ .file "nextafterl.s" -// Copyright (c) 2000 - 2003, Intel Corporation +// Copyright (c) 2000 - 2004, Intel Corporation // All rights reserved. // // Contributed 2000 by the Intel Numerics Group, Intel Corporation @@ -52,6 +52,7 @@ // for several cases // 05/20/02 Cleaned up namespace and sf0 syntax // 02/10/03 Reordered header: .section, .global, .proc, .align +// 12/14/04 Added error handling on underflow. // // API //============================================================== @@ -61,20 +62,20 @@ // // Registers used //============================================================== -nextafter_GR_max_pexp = r14 -nextafter_GR_min_pexp = r15 -nextafter_GR_exp = r16 -nextafter_GR_sig = r17 -nextafter_GR_lnorm_sig = r18 -nextafter_GR_sign_mask = r19 -nextafter_GR_exp_mask = r20 -nextafter_GR_sden_sig = r21 -nextafter_GR_new_sig = r22 -nextafter_GR_new_exp = r23 -nextafter_GR_lden_sig = r24 -nextafter_GR_snorm_sig = r25 -nextafter_GR_exp1 = r26 -nextafter_GR_x_exp = r27 +GR_max_pexp = r14 +GR_min_pexp = r15 +GR_exp = r16 +GR_sig = r17 +GR_lnorm_sig = r18 +GR_sign_mask = r19 +GR_exp_mask = r20 +GR_sden_sig = r21 +GR_new_sig = r22 +GR_new_exp = r23 +GR_lden_sig = r24 +GR_snorm_sig = r25 +GR_exp1 = r26 +GR_x_exp = r27 // r36-39 parameters for libm_error_support GR_SAVE_B0 = r34 @@ -84,21 +85,22 @@ GR_SAVE_PFS = r32 GR_Parameter_X = r36 GR_Parameter_Y = r37 GR_Parameter_RESULT = r38 - -NEXTAFTER_lnorm_sig = f10 -NEXTAFTER_lnorm_exp = f11 -NEXTAFTER_lnorm = f12 -NEXTAFTER_sden_sig = f13 -NEXTAFTER_den_exp = f14 -NEXTAFTER_sden = f15 -NEXTAFTER_snorm_exp = f32 -NEXTAFTER_save_f8 = f33 -NEXTAFTER_new_exp = f34 -NEXTAFTER_new_sig = f35 -NEXTAFTER_lden_sig = f36 -NEXTAFTER_snorm_sig = f37 -NEXTAFTER_exp1 = f38 -NEXTAFTER_tmp = f39 +GR_Parameter_TAG = r39 + +FR_lnorm_sig = f10 +FR_lnorm_exp = f11 +FR_lnorm = f12 +FR_sden_sig = f13 +FR_den_exp = f14 +FR_sden = f15 +FR_snorm_exp = f32 +FR_save_f8 = f33 +FR_new_exp = f34 +FR_new_sig = f35 +FR_lden_sig = f36 +FR_snorm_sig = f37 +FR_exp1 = f38 +FR_tmp = f39 // // Overview of operation @@ -114,31 +116,31 @@ GLOBAL_LIBM_ENTRY(nextafterl) // Is x < y ? p10 if yes, p11 if no // Form smallest denormal significand = ulp size { .mfi - getf.exp nextafter_GR_exp = f8 + getf.exp GR_exp = f8 fcmp.lt.s1 p10,p11 = f8, f9 - addl nextafter_GR_sden_sig = 0x1, r0 + addl GR_sden_sig = 0x1, r0 } // Form largest normal significand 0xffffffffffffffff // Form smallest normal exponent { .mfi - addl nextafter_GR_lnorm_sig = -0x1,r0 + addl GR_lnorm_sig = -0x1,r0 nop.f 999 - addl nextafter_GR_min_pexp = 0x0c001, r0 ;; + addl GR_min_pexp = 0x0c001, r0 ;; } // Extract significand from x // Is x=y? This fcmp also sets Invalid and Denormal if required // Form largest normal exponent { .mfi - getf.sig nextafter_GR_sig = f8 + getf.sig GR_sig = f8 fcmp.eq.s0 p6,p0 = f8, f9 - addl nextafter_GR_max_pexp = 0x13ffe, r0 + addl GR_max_pexp = 0x13ffe, r0 } // Move largest normal significand to fp reg for special cases { .mfi - setf.sig NEXTAFTER_lnorm_sig = nextafter_GR_lnorm_sig + setf.sig FR_lnorm_sig = GR_lnorm_sig nop.f 999 - addl nextafter_GR_sign_mask = 0x20000, r0 ;; + addl GR_sign_mask = 0x20000, r0 ;; } // Move smallest denormal significand and exp to fp regs @@ -147,15 +149,15 @@ GLOBAL_LIBM_ENTRY(nextafterl) // It increases (p12 set) if x<y and x>=0 or if x>y and x<0 // It decreases (p13 set) if x<y and x<0 or if x>y and x>=0 { .mfi - setf.sig NEXTAFTER_sden_sig = nextafter_GR_sden_sig + setf.sig FR_sden_sig = GR_sden_sig fclass.m p8,p0 = f8, 0xc3 -(p10) cmp.lt p12,p13 = nextafter_GR_exp, nextafter_GR_sign_mask +(p10) cmp.lt p12,p13 = GR_exp, GR_sign_mask } // Move smallest normal exp to fp regs { .mfi - setf.exp NEXTAFTER_snorm_exp = nextafter_GR_min_pexp + setf.exp FR_snorm_exp = GR_min_pexp nop.f 999 -(p11) cmp.ge p12,p13 = nextafter_GR_exp, nextafter_GR_sign_mask ;; +(p11) cmp.ge p12,p13 = GR_exp, GR_sign_mask ;; } .pred.rel "mutex",p12,p13 @@ -164,38 +166,38 @@ GLOBAL_LIBM_ENTRY(nextafterl) // If x=y set result to y // Form smallest normal significand and largest denormal significand { .mfi -(p12) add nextafter_GR_new_sig = nextafter_GR_sig, nextafter_GR_sden_sig +(p12) add GR_new_sig = GR_sig, GR_sden_sig (p6) fmerge.s f8=f9,f9 - dep.z nextafter_GR_snorm_sig = 1,63,1 // 0x8000000000000000 + dep.z GR_snorm_sig = 1,63,1 // 0x8000000000000000 } { .mlx -(p13) sub nextafter_GR_new_sig = nextafter_GR_sig, nextafter_GR_sden_sig - movl nextafter_GR_lden_sig = 0x7fffffffffffffff ;; +(p13) sub GR_new_sig = GR_sig, GR_sden_sig + movl GR_lden_sig = 0x7fffffffffffffff ;; } // Move expected result significand and signexp to fp regs // Is y=nan? // Form new exponent in case result exponent needs incrementing or decrementing { .mfi - setf.exp NEXTAFTER_new_exp = nextafter_GR_exp + setf.exp FR_new_exp = GR_exp fclass.m p9,p0 = f9, 0xc3 -(p12) add nextafter_GR_exp1 = 1, nextafter_GR_exp +(p12) add GR_exp1 = 1, GR_exp } { .mib - setf.sig NEXTAFTER_new_sig = nextafter_GR_new_sig -(p13) add nextafter_GR_exp1 = -1, nextafter_GR_exp + setf.sig FR_new_sig = GR_new_sig +(p13) add GR_exp1 = -1, GR_exp (p6) br.ret.spnt b0 ;; // Exit if x=y } // Move largest normal signexp to fp reg for special cases // Is x=zero? { .mfi - setf.exp NEXTAFTER_lnorm_exp = nextafter_GR_max_pexp + setf.exp FR_lnorm_exp = GR_max_pexp fclass.m p7,p0 = f8, 0x7 nop.i 999 } { .mfb - setf.exp NEXTAFTER_den_exp = nextafter_GR_min_pexp + setf.exp FR_den_exp = GR_min_pexp (p8) fma.s0 f8 = f8,f1,f9 (p8) br.ret.spnt b0 ;; // Exit if x=nan } @@ -203,12 +205,12 @@ GLOBAL_LIBM_ENTRY(nextafterl) // Move exp+-1 and smallest normal significand to fp regs for special cases // Is x=inf? { .mfi - setf.exp NEXTAFTER_exp1 = nextafter_GR_exp1 + setf.exp FR_exp1 = GR_exp1 fclass.m p6,p0 = f8, 0x23 - addl nextafter_GR_exp_mask = 0x1ffff, r0 + addl GR_exp_mask = 0x1ffff, r0 } { .mfb - setf.sig NEXTAFTER_snorm_sig = nextafter_GR_snorm_sig + setf.sig FR_snorm_sig = GR_snorm_sig (p9) fma.s0 f8 = f8,f1,f9 (p9) br.ret.spnt b0 ;; // Exit if y=nan } @@ -216,16 +218,16 @@ GLOBAL_LIBM_ENTRY(nextafterl) // Move largest denormal significand to fp regs for special cases // Save x { .mfb - setf.sig NEXTAFTER_lden_sig = nextafter_GR_lden_sig - mov NEXTAFTER_save_f8 = f8 -(p7) br.cond.spnt NEXTAFTER_ZERO ;; // Exit if x=0 + setf.sig FR_lden_sig = GR_lden_sig + mov FR_save_f8 = f8 +(p7) br.cond.spnt NEXT_ZERO ;; // Exit if x=0 } // Mask off the sign to get x_exp { .mfb - and nextafter_GR_x_exp = nextafter_GR_exp_mask, nextafter_GR_exp + and GR_x_exp = GR_exp_mask, GR_exp nop.f 999 -(p6) br.cond.spnt NEXTAFTER_INF ;; // Exit if x=inf +(p6) br.cond.spnt NEXT_INF ;; // Exit if x=inf } // Check 5 special cases when significand rolls over: @@ -241,37 +243,37 @@ GLOBAL_LIBM_ENTRY(nextafterl) // Set p10, result is zero, sign of x, signal underflow and inexact // { .mmi -(p12) cmp.eq.unc p6,p0 = nextafter_GR_new_sig, r0 -(p13) cmp.eq.unc p9,p10 = nextafter_GR_new_sig, nextafter_GR_lden_sig +(p12) cmp.eq.unc p6,p0 = GR_new_sig, r0 +(p13) cmp.eq.unc p9,p10 = GR_new_sig, GR_lden_sig nop.i 999 ;; } { .mmi -(p6) cmp.lt.unc p6,p7 = nextafter_GR_x_exp, nextafter_GR_max_pexp -(p10) cmp.eq.unc p10,p0 = nextafter_GR_new_sig, r0 -(p9) cmp.le.unc p9,p8 = nextafter_GR_x_exp, nextafter_GR_min_pexp +(p6) cmp.lt.unc p6,p7 = GR_x_exp, GR_max_pexp +(p10) cmp.eq.unc p10,p0 = GR_new_sig, r0 +(p9) cmp.le.unc p9,p8 = GR_x_exp, GR_min_pexp ;; } // Create small normal in case need to generate underflow flag { .mfi nop.m 999 - fmerge.se NEXTAFTER_tmp = NEXTAFTER_snorm_exp, NEXTAFTER_lnorm_sig + fmerge.se FR_tmp = FR_snorm_exp, FR_lnorm_sig nop.i 999 } // Branch if cases 1, 2, 3 { .bbb -(p6) br.cond.spnt NEXTAFTER_EXPUP -(p7) br.cond.spnt NEXTAFTER_OVERFLOW -(p8) br.cond.spnt NEXTAFTER_EXPDOWN ;; +(p6) br.cond.spnt NEXT_EXPUP +(p7) br.cond.spnt NEXT_OVERFLOW +(p8) br.cond.spnt NEXT_EXPDOWN ;; } // Branch if cases 4, 5 { .mbb nop.m 999 -(p9) br.cond.spnt NEXTAFTER_NORM_TO_DENORM -(p10) br.cond.spnt NEXTAFTER_UNDERFLOW_TO_ZERO +(p9) br.cond.spnt NEXT_NORM_TO_DENORM +(p10) br.cond.spnt NEXT_UNDERFLOW_TO_ZERO ;; } @@ -280,68 +282,72 @@ GLOBAL_LIBM_ENTRY(nextafterl) // Case 1: x_exp=min_exp, x_sig=unnormalized // Case 2: x_exp<min_exp { .mfi - cmp.lt p6,p7 = nextafter_GR_x_exp, nextafter_GR_min_pexp - fmerge.se f8 = NEXTAFTER_new_exp, NEXTAFTER_new_sig + cmp.lt p6,p7 = GR_x_exp, GR_min_pexp + fmerge.se f8 = FR_new_exp, FR_new_sig nop.i 999 ;; } { .mfi nop.m 999 nop.f 999 -(p6) tbit.z p6,p0 = nextafter_GR_new_sig, 63 ;; +(p6) tbit.z p6,p0 = GR_new_sig, 63 ;; } -NEXTAFTER_COMMON_FINISH: +NEXT_COMMON_FINISH: // Force underflow and inexact if denormal result { .mfi nop.m 999 -(p6) fma.s0 NEXTAFTER_tmp = NEXTAFTER_tmp,NEXTAFTER_tmp,f0 - nop.i 999 ;; +(p6) fma.s0 FR_tmp = FR_tmp,FR_tmp,f0 + nop.i 999 +} +{ .mfb + nop.m 999 + fnorm.s0 f8 = f8 // Final normalization to result precision +(p6) br.cond.spnt NEXT_UNDERFLOW ;; } -// Final normalization to result precision and exit { .mfb nop.m 999 - fnorm.s0 f8 = f8 + nop.f 999 br.ret.sptk b0;; } //Special cases -NEXTAFTER_EXPUP: +NEXT_EXPUP: { .mfb - cmp.lt p6,p7 = nextafter_GR_x_exp, nextafter_GR_min_pexp - fmerge.se f8 = NEXTAFTER_exp1, NEXTAFTER_snorm_sig - br.cond.sptk NEXTAFTER_COMMON_FINISH ;; + cmp.lt p6,p7 = GR_x_exp, GR_min_pexp + fmerge.se f8 = FR_exp1, FR_snorm_sig + br.cond.sptk NEXT_COMMON_FINISH ;; } -NEXTAFTER_EXPDOWN: +NEXT_EXPDOWN: { .mfb - cmp.lt p6,p7 = nextafter_GR_x_exp, nextafter_GR_min_pexp - fmerge.se f8 = NEXTAFTER_exp1, NEXTAFTER_lnorm_sig - br.cond.sptk NEXTAFTER_COMMON_FINISH ;; + cmp.lt p6,p7 = GR_x_exp, GR_min_pexp + fmerge.se f8 = FR_exp1, FR_lnorm_sig + br.cond.sptk NEXT_COMMON_FINISH ;; } -NEXTAFTER_NORM_TO_DENORM: +NEXT_NORM_TO_DENORM: { .mfi nop.m 999 - fmerge.se f8 = NEXTAFTER_exp1, NEXTAFTER_lden_sig + fmerge.se f8 = FR_exp1, FR_lden_sig nop.i 999 } // Force underflow and inexact { .mfb nop.m 999 - fma.s0 NEXTAFTER_tmp = NEXTAFTER_tmp,NEXTAFTER_tmp,f0 - br.ret.sptk b0 ;; + fma.s0 FR_tmp = FR_tmp,FR_tmp,f0 + br.cond.sptk NEXT_UNDERFLOW ;; } -NEXTAFTER_UNDERFLOW_TO_ZERO: +NEXT_UNDERFLOW_TO_ZERO: { .mfb cmp.eq p6,p0 = r0,r0 - fmerge.s f8 = NEXTAFTER_save_f8,f0 - br.cond.sptk NEXTAFTER_COMMON_FINISH ;; + fmerge.s f8 = FR_save_f8,f0 + br.cond.sptk NEXT_COMMON_FINISH ;; } -NEXTAFTER_INF: +NEXT_INF: // Here if f8 is +- infinity // INF // if f8 is +inf, no matter what y is return largest long double @@ -350,17 +356,17 @@ NEXTAFTER_INF: // Create largest long double { .mfi nop.m 999 - fmerge.se NEXTAFTER_lnorm = NEXTAFTER_lnorm_exp,NEXTAFTER_lnorm_sig + fmerge.se FR_lnorm = FR_lnorm_exp,FR_lnorm_sig nop.i 999 ;; } { .mfb nop.m 999 - fmerge.s f8 = f8,NEXTAFTER_lnorm + fmerge.s f8 = f8,FR_lnorm br.ret.sptk b0 ;; } -NEXTAFTER_ZERO: +NEXT_ZERO: // Here if f8 is +- zero // ZERO @@ -369,76 +375,72 @@ NEXTAFTER_ZERO: { .mfi nop.m 999 - fmerge.se NEXTAFTER_sden = f0,NEXTAFTER_sden_sig + fmerge.se FR_sden = f0,FR_sden_sig nop.i 999 ;; } // Create small normal to generate underflow flag { .mfi nop.m 999 - fmerge.se NEXTAFTER_tmp = NEXTAFTER_snorm_exp, NEXTAFTER_lnorm_sig + fmerge.se FR_tmp = FR_snorm_exp, FR_lnorm_sig nop.i 999 ;; } // Add correct sign from direction arg { .mfi nop.m 999 - fmerge.s f8 = f9,NEXTAFTER_sden + fmerge.s f8 = f9,FR_sden nop.i 999 ;; } // Force underflow and inexact flags { .mfb nop.m 999 - fma.s0 NEXTAFTER_tmp = NEXTAFTER_tmp,NEXTAFTER_tmp,f0 - br.ret.sptk b0 ;; + fma.s0 FR_tmp = FR_tmp,FR_tmp,f0 + br.cond.sptk NEXT_UNDERFLOW ;; } -GLOBAL_LIBM_END(nextafterl) -// Stack operations when calling error support. -// (1) (2) (3) (call) (4) -// sp -> + psp -> + psp -> + sp -> + -// | | | | -// | | <- GR_Y R3 ->| <- GR_RESULT | -> f8 -// | | | | -// | <-GR_Y Y2->| Y2 ->| <- GR_Y | -// | | | | -// | | <- GR_X X1 ->| | -// | | | | -// sp-64 -> + sp -> + sp -> + + -// save ar.pfs save b0 restore gp -// save gp restore ar.pfs - - +NEXT_UNDERFLOW: +// Here if result is a denorm, or input is finite and result is zero +// Call error support to report possible range error +{ .mib + alloc r32=ar.pfs,2,2,4,0 + mov GR_Parameter_TAG = 267 // Error code + br.cond.sptk __libm_error_region // Branch to error call +} +;; -LOCAL_LIBM_ENTRY(__libm_error_region) -NEXTAFTER_OVERFLOW: -// Here if f8 is finite, but result will be infinite +NEXT_OVERFLOW: +// Here if input is finite, but result will be infinite // Use frcpa to generate infinity of correct sign // Call error support to report possible range error -.prologue - { .mfi alloc r32=ar.pfs,2,2,4,0 - frcpa.s1 f8,p6 = NEXTAFTER_save_f8, f0 + frcpa.s1 f8,p6 = FR_save_f8, f0 nop.i 999 ;; } -// Create largest long double +// Create largest double { .mfi nop.m 999 - fmerge.se NEXTAFTER_lnorm = NEXTAFTER_lnorm_exp,NEXTAFTER_lnorm_sig + fmerge.se FR_lnorm = FR_lnorm_exp,FR_lnorm_sig nop.i 999 ;; } // Force overflow and inexact flags to be set -{ .mfi - mov r39 = 153 // Error code - fma.s0 NEXTAFTER_tmp = NEXTAFTER_lnorm,NEXTAFTER_lnorm,f0 - nop.i 999 +{ .mfb + mov GR_Parameter_TAG = 153 // Error code + fma.s0 FR_tmp = FR_lnorm,FR_lnorm,f0 + br.cond.sptk __libm_error_region // Branch to error call } ;; +GLOBAL_LIBM_END(nextafterl) + + +LOCAL_LIBM_ENTRY(__libm_error_region) +.prologue + // (1) { .mfi add GR_Parameter_Y=-32,sp // Parameter 2 value @@ -465,7 +467,7 @@ NEXTAFTER_OVERFLOW: .body // (3) { .mib - stfe [GR_Parameter_X] = NEXTAFTER_save_f8 // STORE Parameter 1 on stack + stfe [GR_Parameter_X] = FR_save_f8 // STORE Parameter 1 on stack add GR_Parameter_RESULT = 0,GR_Parameter_Y // Parameter 3 address nop.b 0 } |