📄 e_powl.s
字号:
//// S0 user supplied status// S2 user supplied status + WRE + TD (Overflows)// S2 user supplied status + FZ + TD (Underflows)////// If (Safe) is true, then// Compute result using user supplied status field.// No overflow or underflow here, but perhaps inexact.// Return// Else// Determine if overflow or underflow was raised.// Fetch +/- overflow threshold for IEEE double extended{ .mfi nop.m 999 fsetc.s2 0x7F,0x41 // For underflow test, set S2=User+TD+FTZ nop.i 999};;{ .mfi nop.m 999 fma.s2 FR_Result_small = FR_TMP1, FR_TMP2, FR_TMP3 nop.i 999};;{ .mfi nop.m 999 fsetc.s2 0x7F,0x42 // For overflow test, set S2=User+TD+WRE nop.i 999};;{ .mfi nop.m 999 fma.s2 FR_Result_big = FR_TMP1, FR_TMP2,FR_TMP3 nop.i 999};;{ .mfi nop.m 999 fsetc.s2 0x7F,0x40 // Reset S2=User nop.i 999};;{ .mfi nop.m 999 fclass.m p11, p0 = FR_Result_small, 0x00F // Test small result unorm/zero nop.i 999};;{ .mfi nop.m 999 fcmp.ge.s1 p8, p0 = FR_Result_big , FR_Big // Test >= + oflow threshold nop.i 999};;{ .mfb(p11) mov GR_Parameter_TAG = 19 // Set tag for underflow fcmp.le.s1 p9, p0 = FR_Result_big, FR_NBig // Test <= - oflow threshold(p11) br.cond.spnt __libm_error_region // Branch if pow underflowed};;{ .mfb(p8) mov GR_Parameter_TAG = 18 // Set tag for overflow nop.f 999(p8) br.cond.spnt __libm_error_region // Branch if pow +overflow};;{ .mbb(p9) mov GR_Parameter_TAG = 18 // Set tag for overflow(p9) br.cond.spnt __libm_error_region // Branch if pow -overflow br.ret.sptk b0 // Branch if result really ok};;POWL_64_SPECIAL:// Here if x or y is NatVal, nan, inf, or zero{ .mfi nop.m 999 fcmp.eq.s1 p15, p0 = FR_Input_X, f1 // Test x=+1 nop.i 999};;{ .mfi nop.m 999 fclass.m p8, p0 = FR_Input_X, 0x143 // Test x natval, snan nop.i 999};;{ .mfi nop.m 999(p15) fcmp.eq.unc.s0 p6,p0 = FR_Input_Y, f0 // If x=1, flag invalid if y=SNaN nop.i 999}{ .mfb nop.m 999(p15) fmpy.s0 FR_Result = f1,f1 // If x=1, result=1(p15) br.ret.spnt b0 // Exit if x=1};;{ .mfi nop.m 999 fclass.m p6, p0 = FR_Input_Y, 0x007 // Test y zero nop.i 999};;{ .mfi nop.m 999 fclass.m p9, p0 = FR_Input_Y, 0x143 // Test y natval, snan nop.i 999};;{ .mfi nop.m 999 fclass.m p10, p0 = FR_Input_X, 0x083 // Test x qnan nop.i 999}{ .mfi nop.m 999(p8) fmpy.s0 FR_Result = FR_Input_Y, FR_Input_X // If x=snan, result=qnan(p6) cmp.ne p8,p0 = r0,r0 // Don't exit if x=snan, y=0 ==> result=+1};;{ .mfi nop.m 999(p6) fclass.m.unc p15, p0 = FR_Input_X,0x007 // Test x=0, y=0 nop.i 999}{ .mfb nop.m 999(p9) fmpy.s0 FR_Result = FR_Input_Y, FR_Input_X // If y=snan, result=qnan(p8) br.ret.spnt b0 // Exit if x=snan, y not 0, // result=qnan};;{ .mfi nop.m 999 fcmp.eq.s1 p7, p0 = FR_Input_Y, f1 // Test y +1.0 nop.i 999}{ .mfb nop.m 999(p10) fmpy.s0 FR_Result = FR_Input_X, f0 // If x=qnan, result=qnan(p9) br.ret.spnt b0 // Exit if y=snan, result=qnan};;{ .mfi nop.m 999(p6) fclass.m.unc p8, p0 = FR_Input_X,0x0C3 // Test x=nan, y=0 nop.i 999};;{ .mfi nop.m 999(p6) fcmp.eq.s0 p9,p0 = FR_Input_X, f0 // If y=0, flag if x denormal nop.i 999}{ .mfi nop.m 999(p6) fadd.s0 FR_Result = f1, f0 // If y=0, result=1 nop.i 999};;{ .mfi nop.m 999 fclass.m p11, p0 = FR_Input_Y, 0x083 // Test y qnan nop.i 999}{ .mfb(p15) mov GR_Parameter_TAG = 20 // Error tag for x=0, y=0(p7) fmpy.s0 FR_Result = FR_Input_X,f1 // If y=1, result=x(p15) br.cond.spnt __libm_error_region // Branch if x=0, y=0, result=1};;{ .mfb(p8) mov GR_Parameter_TAG = 23 // Error tag for x=nan, y=0 fclass.m p14, p0 = FR_Input_Y, 0x023 // Test y inf(p8) br.cond.spnt __libm_error_region // Branch if x=snan, y=0, // result=1};;{ .mfb nop.m 999 fclass.m p13, p0 = FR_Input_X, 0x023 // Test x inf(p6) br.ret.spnt b0 // Exit y=0, x not nan or 0, // result=1};;{ .mfb nop.m 999(p14) fcmp.eq.unc.s1 p0,p14 = FR_Input_X,f0 // Test x not 0, y=inf(p7) br.ret.spnt b0 // Exit y=1, x not snan, // result=x};;{ .mfb nop.m 999(p10) fmpy.s0 FR_Result = FR_Input_Y,FR_Input_X // If x=qnan, y not snan, // result=qnan(p10) br.ret.spnt b0 // Exit x=qnan, y not snan, // result=qnan};;{ .mfb nop.m 999(p11) fmpy.s0 FR_Result = FR_Input_Y,FR_Input_X // If y=qnan, x not nan or 1, // result=qnan(p11) br.ret.spnt b0 // Exit y=qnan, x not nan or 1, // result=qnan};;{ .mbb nop.m 999(p14) br.cond.spnt POWL_64_Y_IS_INF // Branch if y=inf, x not 1 or nan(p13) br.cond.spnt POWL_64_X_IS_INF // Branch if x=inf, y not 1 or nan};;POWL_64_X_IS_ZERO:// Here if x=0, y not nan or 1 or inf or 0// There is logic starting here to determine if y is an integer when x = 0.// If 0 < |y| < 1 then clearly y is not an integer.// If |y| > 1, then the significand of y is shifted left by the size of// the exponent of y. This preserves the lsb of the integer part + the// fractional bits. The lsb of the integer can be tested to determine if// the integer is even or odd. The fractional bits can be tested. If zero,// then y is an integer.//{ .mfi and GR_exp_y = GR_exp_mask,GR_signexp_y // Get biased exponent of y nop.f 999 and GR_y_sign = GR_sign_mask,GR_signexp_y // Get sign of y};;//// Maybe y is < 1 already, so// can never be an integer.//{ .mfi cmp.lt p9, p8 = GR_exp_y,GR_exp_bias // Test 0 < |y| < 1 nop.f 999 sub GR_exp_y = GR_exp_y,GR_exp_bias // Get true exponent of y};;//// Shift significand of y looking for nonzero bits// For y > 1, shift signif_y exp_y bits to the left// For y < 1, turn on 4 low order bits of significand of y// so that the fraction will always be non-zero//{ .mmi(p9) or GR_exp_y= 0xF,GR_signif_y // Force nonzero fraction if y<1;; nop.m 999(p8) shl GR_exp_y= GR_signif_y,GR_exp_y // Get lsb of int + fraction // Wait 4 cycles to use result};;{ .mmi nop.m 999;; nop.m 999 nop.i 999};;{ .mmi nop.m 999;; nop.m 999 shl GR_fraction_y= GR_exp_y,1 // Shift left 1 to get fraction};;//// Integer part of y shifted off.// Get y's low even or odd bit - y might not be an int.//{ .mii cmp.eq p13,p0 = GR_fraction_y, r0 // Test for y integer cmp.eq p8,p0 = GR_y_sign, r0 // Test for y > 0;;(p13) tbit.nz.unc p13,p0 = GR_exp_y, 63 // Test if y an odd integer};;{ .mfi(p13) cmp.eq.unc p13,p14 = GR_y_sign, r0 // Test y pos odd integer(p8) fcmp.eq.s0 p12,p0 = FR_Input_Y, f0 // If x=0 and y>0 flag if y denormal nop.i 999};;//// Return +/-0 when x=+/-0 and y is positive odd integer//{ .mfb nop.m 999(p13) mov FR_Result = FR_Input_X // If x=0, y pos odd int, result=x(p13) br.ret.spnt b0 // Exit x=0, y pos odd int, result=x};;//// Return +/-inf when x=+/-0 and y is negative odd int//{ .mfb(p14) mov GR_Parameter_TAG = 21(p14) frcpa.s0 FR_Result, p0 = f1, FR_Input_X // Result +-inf, set Z flag(p14) br.cond.spnt __libm_error_region};;//// Return +0 when x=+/-0 and y positive and not an odd integer//{ .mfb nop.m 999(p8) mov FR_Result = f0 // If x=0, y>0 and not odd integer, result=+0(p8) br.ret.sptk b0 // Exit x=0, y>0 and not odd integer, result=+0};;//// Return +inf when x=+/-0 and y is negative and not odd int//{ .mfb mov GR_Parameter_TAG = 21 frcpa.s0 FR_Result, p10 = f1,f0 // Result +inf, raise Z flag br.cond.sptk __libm_error_region};;POWL_64_X_IS_INF://// Here if x=inf, y not 1 or nan//{ .mfi and GR_exp_y = GR_exp_mask,GR_signexp_y // Get biased exponent y fclass.m p13, p0 = FR_Input_X,0x022 // Test x=-inf nop.i 999};;{ .mfi and GR_y_sign = GR_sign_mask,GR_signexp_y // Get sign of y fcmp.eq.s0 p9,p0 = FR_Input_Y, f0 // Dummy to set flag if y denorm nop.i 999};;//// Maybe y is < 1 already, so// isn't an int.//{ .mfi(p13) cmp.lt.unc p9, p8 = GR_exp_y,GR_exp_bias // Test 0 < |y| < 1 if x=-inf fclass.m p11, p0 = FR_Input_X,0x021 // Test x=+inf sub GR_exp_y = GR_exp_y,GR_exp_bias // Get true exponent y};;//// Shift significand of y looking for nonzero bits// For y > 1, shift signif_y exp_y bits to the left// For y < 1, turn on 4 low order bits of significand of y// so that the fraction will always be non-zero//{ .mmi(p9) or GR_exp_y= 0xF,GR_signif_y // Force nonzero fraction if y<1;;(p11) cmp.eq.unc p14,p12 = GR_y_sign, r0 // Test x=+inf, y>0(p8) shl GR_exp_y= GR_signif_y,GR_exp_y // Get lsb of int + fraction // Wait 4 cycles to use result};;//// Return +inf for x=+inf, y > 0// Return +0 for x=+inf, y < 0//{ .mfi nop.m 999(p12) mov FR_Result = f0 // If x=+inf, y<0, result=+0 nop.i 999}{ .mfb nop.m 999(p14) fma.s0 FR_Result = FR_Input_X,f1,f0 // If x=+inf, y>0, result=+inf(p11) br.ret.sptk b0 // Exit x=+inf};;//// Here only if x=-inf. Wait until can use result of shl...//{ .mmi nop.m 999;; nop.m 999 nop.i 999};;{ .mfi cmp.eq p8,p9 = GR_y_sign, r0 // Test y pos nop.f 999 shl GR_fraction_y = GR_exp_y,1 // Shift left 1 to get fraction};;{ .mmi cmp.eq p13,p0 = GR_fraction_y, r0 // Test y integer;; nop.m 999(p13) tbit.nz.unc p13,p0 = GR_exp_y, 63 // Test y odd integer};;//// Is y even or odd?//{ .mii(p13) cmp.eq.unc p14,p10 = GR_y_sign, r0 // Test x=-inf, y pos odd int(p13) cmp.ne.and p8,p9 = r0,r0 // If y odd int, turn off p8,p9 nop.i 999};;//// Return -0 for x = -inf and y < 0 and odd int.// Return -Inf for x = -inf and y > 0 and odd int.//{ .mfi nop.m 999(p10) fmerge.ns FR_Result = f0, f0 // If x=-inf, y neg odd int, result=-0 nop.i 999}{ .mfi nop.m 999(p14) fmpy.s0 FR_Result = FR_Input_X,f1 // If x=-inf, y pos odd int, result=-inf nop.i 999};;//// Return Inf for x = -inf and y > 0 not an odd int.// Return +0 for x = -inf and y < 0 not an odd int.//.pred.rel "mutex",p8,p9{ .mfi nop.m 999(p8) fmerge.ns FR_Result = FR_Input_X, FR_Input_X // If x=-inf, y>0 not odd int // result=+inf nop.i 999}{ .mfb nop.m 999(p9) fmpy.s0 FR_Result = f0,f0 // If x=-inf, y<0 not odd int // result=+0 br.ret.sptk b0 // Exit for x=-inf};;POWL_64_Y_IS_INF:// Here if y=in
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -