# --- T2-COPYRIGHT-NOTE-BEGIN --- # T2 SDE: package/*/glibc/math-fpu-error-partial-fix.patch.ia64 # Copyright (C) 2023 The T2 SDE Project # # This Copyright note is generated by scripts/Create-CopyPatch, # more information can be found in the files COPYING and README. # # This patch file is dual-licensed. It is available under the license the # patched project is licensed under, as long as it is an OpenSource license # as defined at http://www.opensource.org/ (e.g. BSD, X11) or under the terms # of the GNU General Public License version 2 as used by the T2 SDE. # --- T2-COPYRIGHT-NOTE-END --- # # This patch is adopted from an attachment to # https://sourceware.org/bugzilla/show_bug.cgi?id=10163 by Aurelien Jarno # # Development is happening at https://github.com/lenticularis39/glibc-ia64-fpu-patches/tree/ia64-fpu-patch # diff --git a/sysdeps/ia64/fpu/e_fmod.S b/sysdeps/ia64/fpu/e_fmod.S index 23de4a6c4e..33aaaf6314 100644 --- a/sysdeps/ia64/fpu/e_fmod.S +++ b/sysdeps/ia64/fpu/e_fmod.S @@ -74,8 +74,8 @@ // // Special cases //==================================================================== -// b=+/-0: return NaN, call libm_error_support -// a=+/-Inf, a=NaN or b=NaN: return NaN +// a=+/-Inf or b=+/-0: return NaN, call libm_error_support +// a=NaN or b=NaN: return NaN // // Registers used //==================================================================== @@ -406,13 +406,13 @@ FMOD_X_NAN_INF: nop.m 999 // also set Denormal flag if necessary (p8) fma.s0 f9=f9,f1,f0 - nop.i 999 ;; +(p8) mov GR_Parameter_TAG=274 ;; } { .mfb nop.m 999 (p8) fma.d.s0 f8=f8,f1,f0 - nop.b 999 ;; +(p8) br.spnt __libm_error_region;; } { .mfb diff --git a/sysdeps/ia64/fpu/e_fmodf.S b/sysdeps/ia64/fpu/e_fmodf.S index 60613a781c..06e3cc4180 100644 --- a/sysdeps/ia64/fpu/e_fmodf.S +++ b/sysdeps/ia64/fpu/e_fmodf.S @@ -74,8 +74,8 @@ // Special cases //==================================================================== -// b=+/-0: return NaN, call libm_error_support -// a=+/-Inf, a=NaN or b=NaN: return NaN +// a=+/-Inf or b=+/-0: return NaN, call libm_error_support +// a=NaN or b=NaN: return NaN // Registers used //==================================================================== @@ -412,13 +412,13 @@ FMOD_X_NAN_INF: nop.m 999 // also set Denormal flag if necessary (p8) fma.s0 f9=f9,f1,f0 - nop.i 999 ;; +(p8) mov GR_Parameter_TAG=275 ;; } { .mfb nop.m 999 (p8) fma.s.s0 f8=f8,f1,f0 - nop.b 999 ;; +(p8) br.spnt __libm_error_region;; } { .mfb diff --git a/sysdeps/ia64/fpu/e_fmodl.S b/sysdeps/ia64/fpu/e_fmodl.S index bbe1060872..c493a93400 100644 --- a/sysdeps/ia64/fpu/e_fmodl.S +++ b/sysdeps/ia64/fpu/e_fmodl.S @@ -483,6 +483,11 @@ FMOD_A_NAN_INF: (p8) cmp.ne p7, p0 = GR_SIG_B, r0 nop.i 0 } +{ .mfi + nop.m 0 + fmerge.s FR_X = f8, f8 + nop.i 0 +} ;; { .mfi @@ -508,7 +513,12 @@ FMOD_A_NAN_INF: { .mfb nop.m 0 (p9) frcpa.s0 f8, p7 = f8, f9 - br.ret.sptk b0 + (p9) br.ret.sptk b0 +} +{ .mmb + alloc GR_ARPFS = ar.pfs, 1, 4, 4, 0 + mov GR_Parameter_TAG = 273 + br.sptk __libm_error_region } ;; diff --git a/sysdeps/ia64/fpu/libm_error.c b/sysdeps/ia64/fpu/libm_error.c index 519c3ab493..35a4e8a998 100644 --- a/sysdeps/ia64/fpu/libm_error.c +++ b/sysdeps/ia64/fpu/libm_error.c @@ -439,6 +439,9 @@ else if(_LIB_VERSIONIMF==_ISOC_) case powl_overflow: case pow_overflow: case powf_overflow: + case powl_zero_to_negative: + case pow_zero_to_negative: + case powf_zero_to_negative: case expl_overflow: case exp_overflow: case expf_overflow: @@ -610,11 +613,8 @@ else if(_LIB_VERSIONIMF==_ISOC_) case atan2l_zero: case atan2_zero: case atan2f_zero: - case powl_zero_to_negative: case powl_neg_to_non_integer: - case pow_zero_to_negative: case pow_neg_to_non_integer: - case powf_zero_to_negative: case powf_neg_to_non_integer: case fmodl_by_zero: case fmod_by_zero: @@ -717,6 +717,9 @@ switch(input_tag) case lgammal_negative: case lgamma_negative: case lgammaf_negative: + { + ERRNO_RANGE; break; + } case tgammal_negative: case tgamma_negative: case tgammaf_negative: @@ -769,23 +772,35 @@ switch(input_tag) ERRNO_RANGE; break; } case atanhl_gt_one: - case atanhl_eq_one: - /* atanhl(|x| >= 1) */ + /* atanhl(|x| > 1) */ { ERRNO_DOMAIN; break; } + case atanhl_eq_one: + /* atanhl(|x| == 1) */ + { + ERRNO_RANGE; break; + } case atanh_gt_one: - case atanh_eq_one: - /* atanh(|x| >= 1) */ + /* atanh(|x| > 1) */ { ERRNO_DOMAIN; break; } + case atanh_eq_one: + /* atanh(|x| == 1) */ + { + ERRNO_RANGE; break; + } case atanhf_gt_one: - case atanhf_eq_one: - /* atanhf(|x| >= 1) */ + /* atanhf(|x| > 1) */ { ERRNO_DOMAIN; break; } + case atanhf_eq_one: + /* atanhf(|x| == 1) */ + { + ERRNO_RANGE; break; + } case sqrtl_negative: /* sqrtl(x < 0) */ { @@ -1007,17 +1022,9 @@ switch(input_tag) RETVAL_ZEROF; ERRNO_RANGE; break; } case powl_zero_to_zero: - /* powl 0**0 */ - { - break; - } case pow_zero_to_zero: - /* pow 0**0 */ - { - break; - } case powf_zero_to_zero: - /* powf 0**0 */ + /* 0**0 */ { break; } @@ -1085,31 +1092,15 @@ switch(input_tag) ERRNO_DOMAIN; break; } case powl_zero_to_negative: - /* 0**neg */ - { - ERRNO_DOMAIN; break; - } case pow_zero_to_negative: + case powf_zero_to_negative: /* 0**neg */ { - ERRNO_DOMAIN; break; - } - case powf_zero_to_negative: - /* 0**neg */ - { - ERRNO_DOMAIN; break; + ERRNO_RANGE; break; } case powl_neg_to_non_integer: - /* neg**non_integral */ - { - ERRNO_DOMAIN; break; - } case pow_neg_to_non_integer: - /* neg**non_integral */ - { - ERRNO_DOMAIN; break; - } - case powf_neg_to_non_integer: + case powf_neg_to_non_integer: /* neg**non-integral */ { ERRNO_DOMAIN; break; @@ -1313,6 +1304,21 @@ switch(input_tag) { ERRNO_DOMAIN; break; } + case fmodl_infinity: + /* fmodl(inf,y) */ + { + ERRNO_DOMAIN; break; + } + case fmod_infinity: + /* fmod(inf,y) */ + { + ERRNO_DOMAIN; break; + } + case fmodf_infinity: + /* fmodf(inf,y) */ + { + ERRNO_DOMAIN; break; + } case coshl_overflow: /* coshl overflows */ { @@ -1379,6 +1385,51 @@ switch(input_tag) { ERRNO_RANGE; break; } + case cosl_infinity: + /* cosl(inf) */ + { + ERRNO_DOMAIN; break; + } + case cos_infinity: + /* cos(inf) */ + { + ERRNO_DOMAIN; break; + } + case cosf_infinity: + /* cosf(inf) */ + { + ERRNO_DOMAIN; break; + } + case sinl_infinity: + /* sinl(inf) */ + { + ERRNO_DOMAIN; break; + } + case sin_infinity: + /* sin(inf) */ + { + ERRNO_DOMAIN; break; + } + case sinf_infinity: + /* sinf(inf) */ + { + ERRNO_DOMAIN; break; + } + case tanl_infinity: + /* tanl(inf) */ + { + ERRNO_DOMAIN; break; + } + case tan_infinity: + /* tan(inf) */ + { + ERRNO_DOMAIN; break; + } + case tanf_infinity: + /* tanf(inf) */ + { + ERRNO_DOMAIN; break; + } default: break; } @@ -2227,7 +2278,7 @@ else NOT_MATHERRL { WRITEL_POW_ZERO_TO_NEGATIVE; - ERRNO_DOMAIN; + ERRNO_RANGE; } } else @@ -2248,7 +2299,7 @@ else NOT_MATHERRD { WRITED_POW_ZERO_TO_NEGATIVE; - ERRNO_DOMAIN; + ERRNO_RANGE; } } else @@ -2269,7 +2320,7 @@ else NOT_MATHERRF { WRITEF_POW_ZERO_TO_NEGATIVE; - ERRNO_DOMAIN; + ERRNO_RANGE; } } else @@ -2310,7 +2361,7 @@ else NOT_MATHERRD { WRITED_POW_NEG_TO_NON_INTEGER; - ERRNO_DOMAIN; + ERRNO_RANGE; } } else @@ -2330,7 +2381,7 @@ else NOT_MATHERRF { WRITEF_POW_NEG_TO_NON_INTEGER; - ERRNO_DOMAIN; + ERRNO_RANGE; } } else @@ -3064,12 +3115,12 @@ else NOT_MATHERRL { WRITEL_ATANH_EQ_ONE; - ERRNO_DOMAIN; + ERRNO_RANGE; } } else { - NOT_MATHERRL {ERRNO_DOMAIN;} + NOT_MATHERRL {ERRNO_RANGE;} } break; } @@ -3082,12 +3133,12 @@ else NOT_MATHERRD { WRITED_ATANH_EQ_ONE; - ERRNO_DOMAIN; + ERRNO_RANGE; } } else { - NOT_MATHERRD {ERRNO_DOMAIN;} + NOT_MATHERRD {ERRNO_RANGE;} } break; } @@ -3100,12 +3151,12 @@ else NOT_MATHERRF { WRITEF_ATANH_EQ_ONE; - ERRNO_DOMAIN; + ERRNO_RANGE; } } else { - NOT_MATHERRF {ERRNO_DOMAIN;} + NOT_MATHERRF {ERRNO_RANGE;} } break; } @@ -3167,13 +3218,13 @@ else NOT_MATHERRL { WRITEL_GAMMA_NEGATIVE; - ERRNO_DOMAIN; + ERRNO_RANGE; } } else { RETVAL_HUGE_VALL; - NOT_MATHERRL {ERRNO_DOMAIN;} + NOT_MATHERRL {ERRNO_RANGE;} } *(long double *)retval = excl.retval; break; @@ -3188,13 +3239,13 @@ else NOT_MATHERRD { WRITED_GAMMA_NEGATIVE; - ERRNO_DOMAIN; + ERRNO_RANGE; } } else { RETVAL_HUGE_VALD; - NOT_MATHERRD {ERRNO_DOMAIN;} + NOT_MATHERRD {ERRNO_RANGE;} } *(double *)retval = exc.retval; break; @@ -3209,13 +3260,13 @@ else NOT_MATHERRF { WRITEF_GAMMA_NEGATIVE; - ERRNO_DOMAIN; + ERRNO_RANGE; } } else { RETVAL_HUGE_VALF; - NOT_MATHERRF {ERRNO_DOMAIN;} + NOT_MATHERRF {ERRNO_RANGE;} } *(float *)retval = excf.retval; break; @@ -3278,13 +3329,13 @@ else NOT_MATHERRL { WRITEL_LGAMMA_NEGATIVE; - ERRNO_DOMAIN; + ERRNO_RANGE; } } else { RETVAL_HUGE_VALL; - NOT_MATHERRL {ERRNO_DOMAIN;} + NOT_MATHERRL {ERRNO_RANGE;} } *(long double *)retval = excl.retval; break; @@ -3299,13 +3350,13 @@ else NOT_MATHERRD { WRITED_LGAMMA_NEGATIVE; - ERRNO_DOMAIN; + ERRNO_RANGE; } } else { RETVAL_HUGE_VALD; - NOT_MATHERRD {ERRNO_DOMAIN;} + NOT_MATHERRD {ERRNO_RANGE;} } *(double *)retval = exc.retval; break; @@ -3320,13 +3371,13 @@ else NOT_MATHERRF { WRITEF_LGAMMA_NEGATIVE; - ERRNO_DOMAIN; + ERRNO_RANGE; } } else { RETVAL_HUGE_VALF; - NOT_MATHERRF {ERRNO_DOMAIN;} + NOT_MATHERRF {ERRNO_RANGE;} } *(float *)retval = excf.retval; break; diff --git a/sysdeps/ia64/fpu/libm_error_codes.h b/sysdeps/ia64/fpu/libm_error_codes.h index fbf38004a6..a66194aad9 100644 --- a/sysdeps/ia64/fpu/libm_error_codes.h +++ b/sysdeps/ia64/fpu/libm_error_codes.h @@ -194,7 +194,11 @@ typedef enum nextafterl_underflow, nextafter_underflow, nextafterf_underflow, /* 267, 268, 269 */ nexttowardl_underflow, nexttoward_underflow, - nexttowardf_underflow /* 270, 271, 272 */ + nexttowardf_underflow, /* 270, 271, 272 */ + fmodl_infinity, fmod_infinity, fmodf_infinity, /* 273, 274, 275 */ + cosl_infinity, cos_infinity, cosf_infinity, /* 276, 277, 278 */ + sinl_infinity, sin_infinity, sinf_infinity, /* 279, 280, 281 */ + tanl_infinity, tan_infinity, tanf_infinity, /* 282, 283, 284 */ } error_types; #define LIBM_ERROR __libm_error_support diff --git a/sysdeps/ia64/fpu/s_cos.S b/sysdeps/ia64/fpu/s_cos.S index cc79aca17e..fb21a9f7d5 100644 --- a/sysdeps/ia64/fpu/s_cos.S +++ b/sysdeps/ia64/fpu/s_cos.S @@ -173,7 +173,7 @@ //============================================================== // general input registers: // r14 -> r26 -// r32 -> r35 +// r32 -> r36 // predicate registers used: // p6 -> p11 @@ -259,6 +259,10 @@ GR_SAVE_B0 = r34 GR_SAVE_GP = r35 GR_SAVE_r_sincos = r36 +GR_Parameter_X = r37 +GR_Parameter_Y = r38 +GR_Parameter_RESULT = r39 +GR_Parameter_TAG = r40 RODATA @@ -474,7 +478,7 @@ _SINCOS_COMMON: // 0x1001a is register_bias + 27. // So if f8 >= 2^27, go to large argument routines { .mfi - alloc r32 = ar.pfs, 1, 4, 0, 0 + alloc r32 = ar.pfs, 1, 4, 4, 0 fclass.m p11,p0 = f8, 0x0b // Test for x=unorm mov sincos_GR_all_ones = -1 // For "inexect" constant create } @@ -681,20 +685,39 @@ _SINCOS_COMMON2: ////////// x = 0/Inf/NaN path ////////////////// _SINCOS_SPECIAL_ARGS: .pred.rel "mutex",p8,p9 + +{ .mfi + nop.m 999 + fclass.m.unc p7,p0 = f8, 0x23 // is x +/- inf? + nop.i 999;; +} + +{ .mfi + nop.m 999 +(p7) fmerge.s f9 = f8,f8 + nop.i 999 +} + // sin(+/-0) = +/-0 // sin(Inf) = NaN // sin(NaN) = NaN { .mfi nop.m 999 (p8) fma.d.s0 f8 = f8, f0, f0 // sin(+/-0,NaN,Inf) - nop.i 999 +(p8) mov GR_Parameter_TAG = 280 } // cos(+/-0) = 1.0 // cos(Inf) = NaN // cos(NaN) = NaN -{ .mfb +{ .mfi nop.m 999 (p9) fma.d.s0 f8 = f8, f0, f1 // cos(+/-0,NaN,Inf) +(p9) mov GR_Parameter_TAG = 277 +} + +{ .mbb + nop.m 999 +(p7) br.cond.spnt __libm_error_region br.ret.sptk b0 // Exit for x = 0/Inf/NaN path };; @@ -766,3 +789,55 @@ LOCAL_LIBM_END(__libm_callout_sincos) .global __libm_sin_large# .type __libm_cos_large#,@function .global __libm_cos_large# + +LOCAL_LIBM_ENTRY(__libm_error_region) +.prologue +{ .mfi + add GR_Parameter_Y=-32,sp // Parameter 2 value + nop.f 0 +.save ar.pfs,GR_SAVE_PFS + mov GR_SAVE_PFS=ar.pfs // Save ar.pfs +} +{ .mfi +.fframe 64 + add sp=-64,sp // Create new stack + nop.f 0 + mov GR_SAVE_GP=gp // Save gp +};; +{ .mmi + stfd [GR_Parameter_Y] = f1,16 // STORE Parameter 2 on stack + add GR_Parameter_X = 16,sp // Parameter 1 address +.save b0, GR_SAVE_B0 + mov GR_SAVE_B0=b0 // Save b0 +};; +.body +{ .mib + stfd [GR_Parameter_X] = f9 // STORE Parameter 1 on stack + add GR_Parameter_RESULT = 0,GR_Parameter_Y // Parameter 3 address + nop.b 0 +} +{ .mib + stfd [GR_Parameter_Y] = f8 // STORE Parameter 3 on stack + add GR_Parameter_Y = -16,GR_Parameter_Y + br.call.sptk b0=__libm_error_support# // Call error handling function +};; +{ .mmi + add GR_Parameter_RESULT = 48,sp + nop.m 0 + nop.i 0 +};; +{ .mmi + ldfd f8 = [GR_Parameter_RESULT] // Get return result off stack +.restore sp + add sp = 64,sp // Restore stack pointer + mov b0 = GR_SAVE_B0 // Restore return address +};; +{ .mib + mov gp = GR_SAVE_GP // Restore gp + mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs + br.ret.sptk b0 // Return +};; + +LOCAL_LIBM_END(__libm_error_region) +.type __libm_error_support#,@function +.global __libm_error_support# diff --git a/sysdeps/ia64/fpu/s_cosf.S b/sysdeps/ia64/fpu/s_cosf.S index f793e61fd3..f98df85dbf 100644 --- a/sysdeps/ia64/fpu/s_cosf.S +++ b/sysdeps/ia64/fpu/s_cosf.S @@ -170,7 +170,7 @@ //============================================================== // general input registers: // r14 -> r19 -// r32 -> r45 +// r32 -> r43 // predicate registers used: // p6 -> p14 @@ -259,6 +259,11 @@ GR_SAVE_PFS = r41 GR_SAVE_B0 = r42 GR_SAVE_GP = r43 +GR_Parameter_X = r44 +GR_Parameter_Y = r45 +GR_Parameter_RESULT = r46 +GR_Parameter_TAG = r47 + RODATA .align 16 @@ -388,7 +393,7 @@ LOCAL_OBJECT_END(double_sin_cos_beta_k4) GLOBAL_IEEE754_ENTRY(sinf) { .mlx - alloc r32 = ar.pfs,1,13,0,0 + alloc r32 = ar.pfs,1,11,4,0 movl sincosf_GR_sig_inv_pi_by_16 = 0xA2F9836E4E44152A //signd of 16/pi } { .mlx @@ -413,7 +418,7 @@ libm_alias_float_other (__sin, sin) GLOBAL_IEEE754_ENTRY(cosf) { .mlx - alloc r32 = ar.pfs,1,13,0,0 + alloc r32 = ar.pfs,1,11,4,0 movl sincosf_GR_sig_inv_pi_by_16 = 0xA2F9836E4E44152A //signd of 16/pi } { .mlx @@ -641,20 +646,39 @@ _SINCOSF_COMMON: ////////// x = 0/Inf/NaN path ////////////////// _SINCOSF_SPECIAL_ARGS: .pred.rel "mutex",p8,p9 + +{ .mfi + nop.m 999 + fclass.m.unc p7,p0 = f8, 0x23 // is x +/- inf? + nop.i 999;; +} + +{ .mfi + nop.m 999 +(p7) fmerge.s f9 = f8,f8 + nop.i 999 +} + // sinf(+/-0) = +/-0 // sinf(Inf) = NaN // sinf(NaN) = NaN { .mfi nop.m 999 (p8) fma.s.s0 f8 = f8, f0, f0 // sinf(+/-0,NaN,Inf) - nop.i 999 +(p8) mov GR_Parameter_TAG = 281 } // cosf(+/-0) = 1.0 // cosf(Inf) = NaN // cosf(NaN) = NaN -{ .mfb +{ .mfi nop.m 999 (p9) fma.s.s0 f8 = f8, f0, f1 // cosf(+/-0,NaN,Inf) +(p9) mov GR_Parameter_TAG = 278 +};; + +{ .mbb + nop.m 999 +(p7) br.cond.spnt __libm_error_region br.ret.sptk b0 // Exit for x = 0/Inf/NaN path };; @@ -715,3 +739,55 @@ LOCAL_LIBM_END(__libm_callout_sincosf) .global __libm_sin_large# .type __libm_cos_large#, @function .global __libm_cos_large# + +LOCAL_LIBM_ENTRY(__libm_error_region) +.prologue +{ .mfi + add GR_Parameter_Y=-32,sp // Parameter 2 value + nop.f 0 +.save ar.pfs,GR_SAVE_PFS + mov GR_SAVE_PFS=ar.pfs // Save ar.pfs +} +{ .mfi +.fframe 64 + add sp=-64,sp // Create new stack + nop.f 0 + mov GR_SAVE_GP=gp // Save gp +};; +{ .mmi + stfd [GR_Parameter_Y] = f1,16 // STORE Parameter 2 on stack + add GR_Parameter_X = 16,sp // Parameter 1 address +.save b0, GR_SAVE_B0 + mov GR_SAVE_B0=b0 // Save b0 +};; +.body +{ .mib + stfd [GR_Parameter_X] = f9 // STORE Parameter 1 on stack + add GR_Parameter_RESULT = 0,GR_Parameter_Y // Parameter 3 address + nop.b 0 +} +{ .mib + stfd [GR_Parameter_Y] = f8 // STORE Parameter 3 on stack + add GR_Parameter_Y = -16,GR_Parameter_Y + br.call.sptk b0=__libm_error_support# // Call error handling function +};; +{ .mmi + add GR_Parameter_RESULT = 48,sp + nop.m 0 + nop.i 0 +};; +{ .mmi + ldfd f8 = [GR_Parameter_RESULT] // Get return result off stack +.restore sp + add sp = 64,sp // Restore stack pointer + mov b0 = GR_SAVE_B0 // Restore return address +};; +{ .mib + mov gp = GR_SAVE_GP // Restore gp + mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs + br.ret.sptk b0 // Return +};; + +LOCAL_LIBM_END(__libm_error_region) +.type __libm_error_support#,@function +.global __libm_error_support# diff --git a/sysdeps/ia64/fpu/s_cosl.S b/sysdeps/ia64/fpu/s_cosl.S index 559cdb6607..876a280e15 100644 --- a/sysdeps/ia64/fpu/s_cosl.S +++ b/sysdeps/ia64/fpu/s_cosl.S @@ -746,12 +746,16 @@ GR_SAVE_B0 = r39 GR_SAVE_GP = r40 GR_SAVE_PFS = r41 +GR_Parameter_X = r59 +GR_Parameter_Y = r60 +GR_Parameter_RESULT = r61 +GR_Parameter_TAG = r62 .section .text GLOBAL_IEEE754_ENTRY(sinl) { .mlx - alloc r32 = ar.pfs,0,27,2,0 + alloc r32 = ar.pfs,1,26,4,0 movl GR_sig_inv_pi = 0xa2f9836e4e44152a // significand of 1/pi } { .mlx @@ -777,7 +781,7 @@ libm_alias_ldouble_other (__sin, sin) GLOBAL_IEEE754_ENTRY(cosl) { .mlx - alloc r32 = ar.pfs,0,27,2,0 + alloc r32 = ar.pfs,1,26,4,0 movl GR_sig_inv_pi = 0xa2f9836e4e44152a // significand of 1/pi } { .mlx @@ -2278,13 +2282,31 @@ SINCOSL_DENORMAL: SINCOSL_SPECIAL: { .mfb nop.m 999 + fclass.m.unc p6,p0 = f8, 0x23 // is x +/- inf? + nop.b 999;; +} + +{ .mfi + nop.m 999 +(p6) fmerge.s f9 = f8,f8 +(p6) cmp.eq.unc p7, p8 = 0x1, GR_Sin_or_Cos;; +} + +{ .mmf +(p7) mov GR_Parameter_TAG = 276 // (cosl) +(p8) mov GR_Parameter_TAG = 279 // (sinl) // // Path for Arg = +/- QNaN, SNaN, Inf // Invalid can be raised. SNaNs // become QNaNs // fmpy.s0 FR_Result = FR_Input_X, f0 - br.ret.sptk b0 ;; +} + +{ .mbb + nop.m 999 +(p6) br.cond.spnt __libm_error_region + br.ret.sptk b0 ;; } GLOBAL_IEEE754_END(cosl) @@ -2364,3 +2386,55 @@ SINCOSL_ARG_TOO_LARGE: LOCAL_LIBM_END(__libm_callout) .type __libm_pi_by_2_reduce#,@function .global __libm_pi_by_2_reduce# + +LOCAL_LIBM_ENTRY(__libm_error_region) +.prologue +{ .mfi + add GR_Parameter_Y=-32,sp // Parameter 2 value + nop.f 0 +.save ar.pfs,GR_SAVE_PFS + mov GR_SAVE_PFS=ar.pfs // Save ar.pfs +} +{ .mfi +.fframe 64 + add sp=-64,sp // Create new stack + nop.f 0 + mov GR_SAVE_GP=gp // Save gp +};; +{ .mmi + stfd [GR_Parameter_Y] = f1,16 // STORE Parameter 2 on stack + add GR_Parameter_X = 16,sp // Parameter 1 address +.save b0, GR_SAVE_B0 + mov GR_SAVE_B0=b0 // Save b0 +};; +.body +{ .mib + stfd [GR_Parameter_X] = f9 // STORE Parameter 1 on stack + add GR_Parameter_RESULT = 0,GR_Parameter_Y // Parameter 3 address + nop.b 0 +} +{ .mib + stfd [GR_Parameter_Y] = f8 // STORE Parameter 3 on stack + add GR_Parameter_Y = -16,GR_Parameter_Y + br.call.sptk b0=__libm_error_support# // Call error handling function +};; +{ .mmi + add GR_Parameter_RESULT = 48,sp + nop.m 0 + nop.i 0 +};; +{ .mmi + ldfd f8 = [GR_Parameter_RESULT] // Get return result off stack +.restore sp + add sp = 64,sp // Restore stack pointer + mov b0 = GR_SAVE_B0 // Restore return address +};; +{ .mib + mov gp = GR_SAVE_GP // Restore gp + mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs + br.ret.sptk b0 // Return +};; + +LOCAL_LIBM_END(__libm_error_region) +.type __libm_error_support#,@function +.global __libm_error_support# diff --git a/sysdeps/ia64/fpu/s_tan.S b/sysdeps/ia64/fpu/s_tan.S index d3b511f226..052cd975a1 100644 --- a/sysdeps/ia64/fpu/s_tan.S +++ b/sysdeps/ia64/fpu/s_tan.S @@ -347,15 +347,10 @@ COMMON_PATH: (p6) br.ret.spnt b0 ;; // Exit for x=0 (tan only) } -{ .mfi +{ .mmi ldfpd tan_P14,tan_P15 = [tan_AD],16 -(p7) frcpa.s0 f8,p9=f0,f0 // Set qnan indef if x=inf - mov tan_GR_10009 = 0x10009 -} -{ .mib ldfpd tan_Q8,tan_Q9 = [tan_ADQ],16 - nop.i 999 -(p7) br.ret.spnt b0 ;; // Exit for x=inf + mov tan_GR_10009 = 0x10009;; } { .mfi @@ -383,6 +378,12 @@ COMMON_PATH: fma.s1 TAN_W_2TO64_RSH = tan_NORM_f8,TAN_INV_PI_BY_2_2TO64,TAN_RSHF_2TO64 };; +{ .mfb +(p7) mov GR_Parameter_Tag = 283 // (tan) +(p7) frcpa.s0 f8,p9=f0,f0 // Set qnan indef if x=inf +(p7) br.cond.spnt __libm_error_region ;; // call error support if tan(+-inf) +} + { .mmf ldfpd tan_P10,tan_P11 = [tan_AD],16 and tan_exp = tan_GR_17_ones, tan_signexp diff --git a/sysdeps/ia64/fpu/s_tanf.S b/sysdeps/ia64/fpu/s_tanf.S index 30d11a6f88..77390791c4 100644 --- a/sysdeps/ia64/fpu/s_tanf.S +++ b/sysdeps/ia64/fpu/s_tanf.S @@ -300,11 +300,11 @@ Common_Path: { .mfi cmp.ge p6, p0 = rSignMask, rExpCut // p6 = (E => 0x10009) (p8) frcpa.s0 f8, p0 = f0, f0 // Set qnan indef if x=inf - mov GR_Parameter_Tag = 227 // (cotf) + mov GR_Parameter_Tag = 284 // (tanf) } { .mbb ldfe fPiby2 = [rCoeffB], 16 -(p8) br.ret.spnt b0 // Exit for x=inf +(p8) br.cond.spnt __libm_error_region // call error support if tanf(+-0) (p6) br.cond.spnt Huge_Argument // Branch if |x|>=2^10 } ;; @@ -312,7 +312,7 @@ Common_Path: { .mfi nop.m 0 (p11) fclass.m.unc p6, p0 = f8, 0x07 // Test for x=0 (for cotf) - nop.i 0 + mov GR_Parameter_Tag = 227 // (cotf) } { .mfb nop.m 0 diff --git a/sysdeps/ia64/fpu/s_tanl.S b/sysdeps/ia64/fpu/s_tanl.S index c28658e24e..2edc3a38e5 100644 --- a/sysdeps/ia64/fpu/s_tanl.S +++ b/sysdeps/ia64/fpu/s_tanl.S @@ -3071,21 +3071,32 @@ TANL_UNSUPPORTED: { .mfi nop.m 999 -(p6) fclass.m p6, p7 = f8, 0x7 // Test for zero (cotl only) +(p6) fclass.m.unc p6, p0 = f8, 0x7 // Test for zero (cotl only) + nop.i 999 +} +;; +{ .mfi + nop.m 999 +(p7) fclass.m.unc p7, p0 = f8, 0x23 // Test for inf (tanl only) nop.i 999 } ;; .pred.rel "mutex", p6, p7 -{ .mfi +{ .mfb (p6) mov GR_Parameter_Tag = 225 // (cotl) (p6) frcpa.s0 f8, p0 = f1, f8 // cotl(+-0) = +-Inf - nop.i 999 +(p6) br.cond.spnt __libm_error_region;; +} +{ .mfb +(p7) mov GR_Parameter_Tag = 282 // (tanl) + fmpy.s0 f8 = f8, f0 +(p7) br.cond.spnt __libm_error_region;; } { .mfb nop.m 999 -(p7) fmpy.s0 f8 = f8, f0 -(p7) br.ret.sptk b0 + nop.f 999 + br.ret.sptk b0 } ;;