162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Linux/PA-RISC Project (http://www.parisc-linux.org/) 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Floating-point emulation code 662306a36Sopenharmony_ci * Copyright (C) 2001 Hewlett-Packard (Paul Bame) <bame@debian.org> 762306a36Sopenharmony_ci */ 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#ifdef __NO_PA_HDRS 1062306a36Sopenharmony_ci PA header file -- do not include this header file for non-PA builds. 1162306a36Sopenharmony_ci#endif 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci/* 32-bit word grabbing functions */ 1462306a36Sopenharmony_ci#define Sgl_firstword(value) Sall(value) 1562306a36Sopenharmony_ci#define Sgl_secondword(value) dummy_location 1662306a36Sopenharmony_ci#define Sgl_thirdword(value) dummy_location 1762306a36Sopenharmony_ci#define Sgl_fourthword(value) dummy_location 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci#define Sgl_sign(object) Ssign(object) 2062306a36Sopenharmony_ci#define Sgl_exponent(object) Sexponent(object) 2162306a36Sopenharmony_ci#define Sgl_signexponent(object) Ssignexponent(object) 2262306a36Sopenharmony_ci#define Sgl_mantissa(object) Smantissa(object) 2362306a36Sopenharmony_ci#define Sgl_exponentmantissa(object) Sexponentmantissa(object) 2462306a36Sopenharmony_ci#define Sgl_all(object) Sall(object) 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_ci/* sgl_and_signs ANDs the sign bits of each argument and puts the result 2762306a36Sopenharmony_ci * into the first argument. sgl_or_signs ors those same sign bits */ 2862306a36Sopenharmony_ci#define Sgl_and_signs( src1dst, src2) \ 2962306a36Sopenharmony_ci Sall(src1dst) = (Sall(src2)|~((unsigned int)1<<31)) & Sall(src1dst) 3062306a36Sopenharmony_ci#define Sgl_or_signs( src1dst, src2) \ 3162306a36Sopenharmony_ci Sall(src1dst) = (Sall(src2)&((unsigned int)1<<31)) | Sall(src1dst) 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci/* The hidden bit is always the low bit of the exponent */ 3462306a36Sopenharmony_ci#define Sgl_clear_exponent_set_hidden(srcdst) Deposit_sexponent(srcdst,1) 3562306a36Sopenharmony_ci#define Sgl_clear_signexponent_set_hidden(srcdst) \ 3662306a36Sopenharmony_ci Deposit_ssignexponent(srcdst,1) 3762306a36Sopenharmony_ci#define Sgl_clear_sign(srcdst) Sall(srcdst) &= ~((unsigned int)1<<31) 3862306a36Sopenharmony_ci#define Sgl_clear_signexponent(srcdst) Sall(srcdst) &= 0x007fffff 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci/* varamount must be less than 32 for the next three functions */ 4162306a36Sopenharmony_ci#define Sgl_rightshift(srcdst, varamount) \ 4262306a36Sopenharmony_ci Sall(srcdst) >>= varamount 4362306a36Sopenharmony_ci#define Sgl_leftshift(srcdst, varamount) \ 4462306a36Sopenharmony_ci Sall(srcdst) <<= varamount 4562306a36Sopenharmony_ci#define Sgl_rightshift_exponentmantissa(srcdst, varamount) \ 4662306a36Sopenharmony_ci Sall(srcdst) = \ 4762306a36Sopenharmony_ci (Sexponentmantissa(srcdst) >> varamount) | \ 4862306a36Sopenharmony_ci (Sall(srcdst) & ((unsigned int)1<<31)) 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ci#define Sgl_leftshiftby1_withextent(left,right,result) \ 5162306a36Sopenharmony_ci Shiftdouble(Sall(left),Extall(right),31,Sall(result)) 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci#define Sgl_rightshiftby1_withextent(left,right,dst) \ 5462306a36Sopenharmony_ci Shiftdouble(Sall(left),Extall(right),1,Extall(right)) 5562306a36Sopenharmony_ci#define Sgl_arithrightshiftby1(srcdst) \ 5662306a36Sopenharmony_ci Sall(srcdst) = (int)Sall(srcdst) >> 1 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_ci/* Sign extend the sign bit with an integer destination */ 5962306a36Sopenharmony_ci#define Sgl_signextendedsign(value) Ssignedsign(value) 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci#define Sgl_isone_hidden(sgl_value) (Shidden(sgl_value)) 6262306a36Sopenharmony_ci#define Sgl_increment(sgl_value) Sall(sgl_value) += 1 6362306a36Sopenharmony_ci#define Sgl_increment_mantissa(sgl_value) \ 6462306a36Sopenharmony_ci Deposit_smantissa(sgl_value,sgl_value+1) 6562306a36Sopenharmony_ci#define Sgl_decrement(sgl_value) Sall(sgl_value) -= 1 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_ci#define Sgl_isone_sign(sgl_value) (Is_ssign(sgl_value)!=0) 6862306a36Sopenharmony_ci#define Sgl_isone_hiddenoverflow(sgl_value) \ 6962306a36Sopenharmony_ci (Is_shiddenoverflow(sgl_value)!=0) 7062306a36Sopenharmony_ci#define Sgl_isone_lowmantissa(sgl_value) (Is_slow(sgl_value)!=0) 7162306a36Sopenharmony_ci#define Sgl_isone_signaling(sgl_value) (Is_ssignaling(sgl_value)!=0) 7262306a36Sopenharmony_ci#define Sgl_is_signalingnan(sgl_value) (Ssignalingnan(sgl_value)==0x1ff) 7362306a36Sopenharmony_ci#define Sgl_isnotzero(sgl_value) (Sall(sgl_value)!=0) 7462306a36Sopenharmony_ci#define Sgl_isnotzero_hiddenhigh7mantissa(sgl_value) \ 7562306a36Sopenharmony_ci (Shiddenhigh7mantissa(sgl_value)!=0) 7662306a36Sopenharmony_ci#define Sgl_isnotzero_low4(sgl_value) (Slow4(sgl_value)!=0) 7762306a36Sopenharmony_ci#define Sgl_isnotzero_exponent(sgl_value) (Sexponent(sgl_value)!=0) 7862306a36Sopenharmony_ci#define Sgl_isnotzero_mantissa(sgl_value) (Smantissa(sgl_value)!=0) 7962306a36Sopenharmony_ci#define Sgl_isnotzero_exponentmantissa(sgl_value) \ 8062306a36Sopenharmony_ci (Sexponentmantissa(sgl_value)!=0) 8162306a36Sopenharmony_ci#define Sgl_iszero(sgl_value) (Sall(sgl_value)==0) 8262306a36Sopenharmony_ci#define Sgl_iszero_signaling(sgl_value) (Is_ssignaling(sgl_value)==0) 8362306a36Sopenharmony_ci#define Sgl_iszero_hidden(sgl_value) (Is_shidden(sgl_value)==0) 8462306a36Sopenharmony_ci#define Sgl_iszero_hiddenoverflow(sgl_value) \ 8562306a36Sopenharmony_ci (Is_shiddenoverflow(sgl_value)==0) 8662306a36Sopenharmony_ci#define Sgl_iszero_hiddenhigh3mantissa(sgl_value) \ 8762306a36Sopenharmony_ci (Shiddenhigh3mantissa(sgl_value)==0) 8862306a36Sopenharmony_ci#define Sgl_iszero_hiddenhigh7mantissa(sgl_value) \ 8962306a36Sopenharmony_ci (Shiddenhigh7mantissa(sgl_value)==0) 9062306a36Sopenharmony_ci#define Sgl_iszero_sign(sgl_value) (Is_ssign(sgl_value)==0) 9162306a36Sopenharmony_ci#define Sgl_iszero_exponent(sgl_value) (Sexponent(sgl_value)==0) 9262306a36Sopenharmony_ci#define Sgl_iszero_mantissa(sgl_value) (Smantissa(sgl_value)==0) 9362306a36Sopenharmony_ci#define Sgl_iszero_exponentmantissa(sgl_value) \ 9462306a36Sopenharmony_ci (Sexponentmantissa(sgl_value)==0) 9562306a36Sopenharmony_ci#define Sgl_isinfinity_exponent(sgl_value) \ 9662306a36Sopenharmony_ci (Sgl_exponent(sgl_value)==SGL_INFINITY_EXPONENT) 9762306a36Sopenharmony_ci#define Sgl_isnotinfinity_exponent(sgl_value) \ 9862306a36Sopenharmony_ci (Sgl_exponent(sgl_value)!=SGL_INFINITY_EXPONENT) 9962306a36Sopenharmony_ci#define Sgl_isinfinity(sgl_value) \ 10062306a36Sopenharmony_ci (Sgl_exponent(sgl_value)==SGL_INFINITY_EXPONENT && \ 10162306a36Sopenharmony_ci Sgl_mantissa(sgl_value)==0) 10262306a36Sopenharmony_ci#define Sgl_isnan(sgl_value) \ 10362306a36Sopenharmony_ci (Sgl_exponent(sgl_value)==SGL_INFINITY_EXPONENT && \ 10462306a36Sopenharmony_ci Sgl_mantissa(sgl_value)!=0) 10562306a36Sopenharmony_ci#define Sgl_isnotnan(sgl_value) \ 10662306a36Sopenharmony_ci (Sgl_exponent(sgl_value)!=SGL_INFINITY_EXPONENT || \ 10762306a36Sopenharmony_ci Sgl_mantissa(sgl_value)==0) 10862306a36Sopenharmony_ci#define Sgl_islessthan(sgl_op1,sgl_op2) \ 10962306a36Sopenharmony_ci (Sall(sgl_op1) < Sall(sgl_op2)) 11062306a36Sopenharmony_ci#define Sgl_isgreaterthan(sgl_op1,sgl_op2) \ 11162306a36Sopenharmony_ci (Sall(sgl_op1) > Sall(sgl_op2)) 11262306a36Sopenharmony_ci#define Sgl_isnotlessthan(sgl_op1,sgl_op2) \ 11362306a36Sopenharmony_ci (Sall(sgl_op1) >= Sall(sgl_op2)) 11462306a36Sopenharmony_ci#define Sgl_isequal(sgl_op1,sgl_op2) \ 11562306a36Sopenharmony_ci (Sall(sgl_op1) == Sall(sgl_op2)) 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_ci#define Sgl_leftshiftby8(sgl_value) \ 11862306a36Sopenharmony_ci Sall(sgl_value) <<= 8 11962306a36Sopenharmony_ci#define Sgl_leftshiftby4(sgl_value) \ 12062306a36Sopenharmony_ci Sall(sgl_value) <<= 4 12162306a36Sopenharmony_ci#define Sgl_leftshiftby3(sgl_value) \ 12262306a36Sopenharmony_ci Sall(sgl_value) <<= 3 12362306a36Sopenharmony_ci#define Sgl_leftshiftby2(sgl_value) \ 12462306a36Sopenharmony_ci Sall(sgl_value) <<= 2 12562306a36Sopenharmony_ci#define Sgl_leftshiftby1(sgl_value) \ 12662306a36Sopenharmony_ci Sall(sgl_value) <<= 1 12762306a36Sopenharmony_ci#define Sgl_rightshiftby1(sgl_value) \ 12862306a36Sopenharmony_ci Sall(sgl_value) >>= 1 12962306a36Sopenharmony_ci#define Sgl_rightshiftby4(sgl_value) \ 13062306a36Sopenharmony_ci Sall(sgl_value) >>= 4 13162306a36Sopenharmony_ci#define Sgl_rightshiftby8(sgl_value) \ 13262306a36Sopenharmony_ci Sall(sgl_value) >>= 8 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_ci#define Sgl_ismagnitudeless(signlessleft,signlessright) \ 13562306a36Sopenharmony_ci/* unsigned int signlessleft, signlessright; */ \ 13662306a36Sopenharmony_ci (signlessleft < signlessright) 13762306a36Sopenharmony_ci 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_ci#define Sgl_copytoint_exponentmantissa(source,dest) \ 14062306a36Sopenharmony_ci dest = Sexponentmantissa(source) 14162306a36Sopenharmony_ci 14262306a36Sopenharmony_ci/* A quiet NaN has the high mantissa bit clear and at least on other (in this 14362306a36Sopenharmony_ci * case the adjacent bit) bit set. */ 14462306a36Sopenharmony_ci#define Sgl_set_quiet(sgl_value) Deposit_shigh2mantissa(sgl_value,1) 14562306a36Sopenharmony_ci#define Sgl_set_exponent(sgl_value,exp) Deposit_sexponent(sgl_value,exp) 14662306a36Sopenharmony_ci 14762306a36Sopenharmony_ci#define Sgl_set_mantissa(dest,value) Deposit_smantissa(dest,value) 14862306a36Sopenharmony_ci#define Sgl_set_exponentmantissa(dest,value) \ 14962306a36Sopenharmony_ci Deposit_sexponentmantissa(dest,value) 15062306a36Sopenharmony_ci 15162306a36Sopenharmony_ci/* An infinity is represented with the max exponent and a zero mantissa */ 15262306a36Sopenharmony_ci#define Sgl_setinfinity_exponent(sgl_value) \ 15362306a36Sopenharmony_ci Deposit_sexponent(sgl_value,SGL_INFINITY_EXPONENT) 15462306a36Sopenharmony_ci#define Sgl_setinfinity_exponentmantissa(sgl_value) \ 15562306a36Sopenharmony_ci Deposit_sexponentmantissa(sgl_value, \ 15662306a36Sopenharmony_ci (SGL_INFINITY_EXPONENT << (32-(1+SGL_EXP_LENGTH)))) 15762306a36Sopenharmony_ci#define Sgl_setinfinitypositive(sgl_value) \ 15862306a36Sopenharmony_ci Sall(sgl_value) = (SGL_INFINITY_EXPONENT << (32-(1+SGL_EXP_LENGTH))) 15962306a36Sopenharmony_ci#define Sgl_setinfinitynegative(sgl_value) \ 16062306a36Sopenharmony_ci Sall(sgl_value) = (SGL_INFINITY_EXPONENT << (32-(1+SGL_EXP_LENGTH))) \ 16162306a36Sopenharmony_ci | ((unsigned int)1<<31) 16262306a36Sopenharmony_ci#define Sgl_setinfinity(sgl_value,sign) \ 16362306a36Sopenharmony_ci Sall(sgl_value) = (SGL_INFINITY_EXPONENT << (32-(1+SGL_EXP_LENGTH))) | \ 16462306a36Sopenharmony_ci ((unsigned int)sign << 31) 16562306a36Sopenharmony_ci#define Sgl_sethigh4bits(sgl_value, extsign) \ 16662306a36Sopenharmony_ci Deposit_shigh4(sgl_value,extsign) 16762306a36Sopenharmony_ci#define Sgl_set_sign(sgl_value,sign) Deposit_ssign(sgl_value,sign) 16862306a36Sopenharmony_ci#define Sgl_invert_sign(sgl_value) \ 16962306a36Sopenharmony_ci Deposit_ssign(sgl_value,~Ssign(sgl_value)) 17062306a36Sopenharmony_ci#define Sgl_setone_sign(sgl_value) Deposit_ssign(sgl_value,1) 17162306a36Sopenharmony_ci#define Sgl_setone_lowmantissa(sgl_value) Deposit_slow(sgl_value,1) 17262306a36Sopenharmony_ci#define Sgl_setzero_sign(sgl_value) Sall(sgl_value) &= 0x7fffffff 17362306a36Sopenharmony_ci#define Sgl_setzero_exponent(sgl_value) Sall(sgl_value) &= 0x807fffff 17462306a36Sopenharmony_ci#define Sgl_setzero_mantissa(sgl_value) Sall(sgl_value) &= 0xff800000 17562306a36Sopenharmony_ci#define Sgl_setzero_exponentmantissa(sgl_value) Sall(sgl_value) &= 0x80000000 17662306a36Sopenharmony_ci#define Sgl_setzero(sgl_value) Sall(sgl_value) = 0 17762306a36Sopenharmony_ci#define Sgl_setnegativezero(sgl_value) Sall(sgl_value) = (unsigned int)1 << 31 17862306a36Sopenharmony_ci 17962306a36Sopenharmony_ci/* Use following macro for both overflow & underflow conditions */ 18062306a36Sopenharmony_ci#define ovfl - 18162306a36Sopenharmony_ci#define unfl + 18262306a36Sopenharmony_ci#define Sgl_setwrapped_exponent(sgl_value,exponent,op) \ 18362306a36Sopenharmony_ci Deposit_sexponent(sgl_value,(exponent op SGL_WRAP)) 18462306a36Sopenharmony_ci 18562306a36Sopenharmony_ci#define Sgl_setlargestpositive(sgl_value) \ 18662306a36Sopenharmony_ci Sall(sgl_value) = ((SGL_EMAX+SGL_BIAS) << (32-(1+SGL_EXP_LENGTH))) \ 18762306a36Sopenharmony_ci | ((1<<(32-(1+SGL_EXP_LENGTH))) - 1 ) 18862306a36Sopenharmony_ci#define Sgl_setlargestnegative(sgl_value) \ 18962306a36Sopenharmony_ci Sall(sgl_value) = ((SGL_EMAX+SGL_BIAS) << (32-(1+SGL_EXP_LENGTH))) \ 19062306a36Sopenharmony_ci | ((1<<(32-(1+SGL_EXP_LENGTH))) - 1 ) \ 19162306a36Sopenharmony_ci | ((unsigned int)1<<31) 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_ci#define Sgl_setnegativeinfinity(sgl_value) \ 19462306a36Sopenharmony_ci Sall(sgl_value) = \ 19562306a36Sopenharmony_ci ((1<<SGL_EXP_LENGTH) | SGL_INFINITY_EXPONENT) << (32-(1+SGL_EXP_LENGTH)) 19662306a36Sopenharmony_ci#define Sgl_setlargest(sgl_value,sign) \ 19762306a36Sopenharmony_ci Sall(sgl_value) = (unsigned int)sign << 31 | \ 19862306a36Sopenharmony_ci (((SGL_EMAX+SGL_BIAS) << (32-(1+SGL_EXP_LENGTH))) \ 19962306a36Sopenharmony_ci | ((1 << (32-(1+SGL_EXP_LENGTH))) - 1 )) 20062306a36Sopenharmony_ci#define Sgl_setlargest_exponentmantissa(sgl_value) \ 20162306a36Sopenharmony_ci Sall(sgl_value) = Sall(sgl_value) & ((unsigned int)1<<31) | \ 20262306a36Sopenharmony_ci (((SGL_EMAX+SGL_BIAS) << (32-(1+SGL_EXP_LENGTH))) \ 20362306a36Sopenharmony_ci | ((1 << (32-(1+SGL_EXP_LENGTH))) - 1 )) 20462306a36Sopenharmony_ci 20562306a36Sopenharmony_ci/* The high bit is always zero so arithmetic or logical shifts will work. */ 20662306a36Sopenharmony_ci#define Sgl_right_align(srcdst,shift,extent) \ 20762306a36Sopenharmony_ci /* sgl_floating_point srcdst; int shift; extension extent */ \ 20862306a36Sopenharmony_ci if (shift < 32) { \ 20962306a36Sopenharmony_ci Extall(extent) = Sall(srcdst) << (32-(shift)); \ 21062306a36Sopenharmony_ci Sall(srcdst) >>= shift; \ 21162306a36Sopenharmony_ci } \ 21262306a36Sopenharmony_ci else { \ 21362306a36Sopenharmony_ci Extall(extent) = Sall(srcdst); \ 21462306a36Sopenharmony_ci Sall(srcdst) = 0; \ 21562306a36Sopenharmony_ci } 21662306a36Sopenharmony_ci#define Sgl_hiddenhigh3mantissa(sgl_value) Shiddenhigh3mantissa(sgl_value) 21762306a36Sopenharmony_ci#define Sgl_hidden(sgl_value) Shidden(sgl_value) 21862306a36Sopenharmony_ci#define Sgl_lowmantissa(sgl_value) Slow(sgl_value) 21962306a36Sopenharmony_ci 22062306a36Sopenharmony_ci/* The left argument is never smaller than the right argument */ 22162306a36Sopenharmony_ci#define Sgl_subtract(sgl_left,sgl_right,sgl_result) \ 22262306a36Sopenharmony_ci Sall(sgl_result) = Sall(sgl_left) - Sall(sgl_right) 22362306a36Sopenharmony_ci 22462306a36Sopenharmony_ci/* Subtract right augmented with extension from left augmented with zeros and 22562306a36Sopenharmony_ci * store into result and extension. */ 22662306a36Sopenharmony_ci#define Sgl_subtract_withextension(left,right,extent,result) \ 22762306a36Sopenharmony_ci /* sgl_floating_point left,right,result; extension extent */ \ 22862306a36Sopenharmony_ci Sgl_subtract(left,right,result); \ 22962306a36Sopenharmony_ci if((Extall(extent) = 0-Extall(extent))) \ 23062306a36Sopenharmony_ci Sall(result) = Sall(result)-1 23162306a36Sopenharmony_ci 23262306a36Sopenharmony_ci#define Sgl_addition(sgl_left,sgl_right,sgl_result) \ 23362306a36Sopenharmony_ci Sall(sgl_result) = Sall(sgl_left) + Sall(sgl_right) 23462306a36Sopenharmony_ci 23562306a36Sopenharmony_ci#define Sgl_xortointp1(left,right,result) \ 23662306a36Sopenharmony_ci result = Sall(left) XOR Sall(right); 23762306a36Sopenharmony_ci 23862306a36Sopenharmony_ci#define Sgl_xorfromintp1(left,right,result) \ 23962306a36Sopenharmony_ci Sall(result) = left XOR Sall(right) 24062306a36Sopenharmony_ci 24162306a36Sopenharmony_ci/* Need to Initialize */ 24262306a36Sopenharmony_ci#define Sgl_makequietnan(dest) \ 24362306a36Sopenharmony_ci Sall(dest) = ((SGL_EMAX+SGL_BIAS)+1)<< (32-(1+SGL_EXP_LENGTH)) \ 24462306a36Sopenharmony_ci | (1<<(32-(1+SGL_EXP_LENGTH+2))) 24562306a36Sopenharmony_ci#define Sgl_makesignalingnan(dest) \ 24662306a36Sopenharmony_ci Sall(dest) = ((SGL_EMAX+SGL_BIAS)+1)<< (32-(1+SGL_EXP_LENGTH)) \ 24762306a36Sopenharmony_ci | (1<<(32-(1+SGL_EXP_LENGTH+1))) 24862306a36Sopenharmony_ci 24962306a36Sopenharmony_ci#define Sgl_normalize(sgl_opnd,exponent) \ 25062306a36Sopenharmony_ci while(Sgl_iszero_hiddenhigh7mantissa(sgl_opnd)) { \ 25162306a36Sopenharmony_ci Sgl_leftshiftby8(sgl_opnd); \ 25262306a36Sopenharmony_ci exponent -= 8; \ 25362306a36Sopenharmony_ci } \ 25462306a36Sopenharmony_ci if(Sgl_iszero_hiddenhigh3mantissa(sgl_opnd)) { \ 25562306a36Sopenharmony_ci Sgl_leftshiftby4(sgl_opnd); \ 25662306a36Sopenharmony_ci exponent -= 4; \ 25762306a36Sopenharmony_ci } \ 25862306a36Sopenharmony_ci while(Sgl_iszero_hidden(sgl_opnd)) { \ 25962306a36Sopenharmony_ci Sgl_leftshiftby1(sgl_opnd); \ 26062306a36Sopenharmony_ci exponent -= 1; \ 26162306a36Sopenharmony_ci } 26262306a36Sopenharmony_ci 26362306a36Sopenharmony_ci#define Sgl_setoverflow(sgl_opnd) \ 26462306a36Sopenharmony_ci /* set result to infinity or largest number */ \ 26562306a36Sopenharmony_ci switch (Rounding_mode()) { \ 26662306a36Sopenharmony_ci case ROUNDPLUS: \ 26762306a36Sopenharmony_ci if (Sgl_isone_sign(sgl_opnd)) { \ 26862306a36Sopenharmony_ci Sgl_setlargestnegative(sgl_opnd); \ 26962306a36Sopenharmony_ci } \ 27062306a36Sopenharmony_ci else { \ 27162306a36Sopenharmony_ci Sgl_setinfinitypositive(sgl_opnd); \ 27262306a36Sopenharmony_ci } \ 27362306a36Sopenharmony_ci break; \ 27462306a36Sopenharmony_ci case ROUNDMINUS: \ 27562306a36Sopenharmony_ci if (Sgl_iszero_sign(sgl_opnd)) { \ 27662306a36Sopenharmony_ci Sgl_setlargestpositive(sgl_opnd); \ 27762306a36Sopenharmony_ci } \ 27862306a36Sopenharmony_ci else { \ 27962306a36Sopenharmony_ci Sgl_setinfinitynegative(sgl_opnd); \ 28062306a36Sopenharmony_ci } \ 28162306a36Sopenharmony_ci break; \ 28262306a36Sopenharmony_ci case ROUNDNEAREST: \ 28362306a36Sopenharmony_ci Sgl_setinfinity_exponentmantissa(sgl_opnd); \ 28462306a36Sopenharmony_ci break; \ 28562306a36Sopenharmony_ci case ROUNDZERO: \ 28662306a36Sopenharmony_ci Sgl_setlargest_exponentmantissa(sgl_opnd); \ 28762306a36Sopenharmony_ci } 28862306a36Sopenharmony_ci 28962306a36Sopenharmony_ci#define Sgl_denormalize(opnd,exponent,guard,sticky,inexact) \ 29062306a36Sopenharmony_ci Sgl_clear_signexponent_set_hidden(opnd); \ 29162306a36Sopenharmony_ci if (exponent >= (1 - SGL_P)) { \ 29262306a36Sopenharmony_ci guard = (Sall(opnd) >> -exponent) & 1; \ 29362306a36Sopenharmony_ci if (exponent < 0) sticky |= Sall(opnd) << (32+exponent); \ 29462306a36Sopenharmony_ci inexact = guard | sticky; \ 29562306a36Sopenharmony_ci Sall(opnd) >>= (1-exponent); \ 29662306a36Sopenharmony_ci } \ 29762306a36Sopenharmony_ci else { \ 29862306a36Sopenharmony_ci guard = 0; \ 29962306a36Sopenharmony_ci sticky |= Sall(opnd); \ 30062306a36Sopenharmony_ci inexact = sticky; \ 30162306a36Sopenharmony_ci Sgl_setzero(opnd); \ 30262306a36Sopenharmony_ci } 30362306a36Sopenharmony_ci 30462306a36Sopenharmony_ci/* 30562306a36Sopenharmony_ci * The fused multiply add instructions requires a single extended format, 30662306a36Sopenharmony_ci * with 48 bits of mantissa. 30762306a36Sopenharmony_ci */ 30862306a36Sopenharmony_ci#define SGLEXT_THRESHOLD 48 30962306a36Sopenharmony_ci 31062306a36Sopenharmony_ci#define Sglext_setzero(valA,valB) \ 31162306a36Sopenharmony_ci Sextallp1(valA) = 0; Sextallp2(valB) = 0 31262306a36Sopenharmony_ci 31362306a36Sopenharmony_ci#define Sglext_isnotzero_mantissap2(valB) (Sextallp2(valB)!=0) 31462306a36Sopenharmony_ci#define Sglext_isone_lowp1(val) (Sextlowp1(val)!=0) 31562306a36Sopenharmony_ci#define Sglext_isone_highp2(val) (Sexthighp2(val)!=0) 31662306a36Sopenharmony_ci#define Sglext_isnotzero_low31p2(val) (Sextlow31p2(val)!=0) 31762306a36Sopenharmony_ci#define Sglext_iszero(valA,valB) (Sextallp1(valA)==0 && Sextallp2(valB)==0) 31862306a36Sopenharmony_ci 31962306a36Sopenharmony_ci#define Sgl_copytoptr(src,destptr) *destptr = src 32062306a36Sopenharmony_ci#define Sgl_copyfromptr(srcptr,dest) dest = *srcptr 32162306a36Sopenharmony_ci#define Sglext_copy(srca,srcb,desta,destb) \ 32262306a36Sopenharmony_ci Sextallp1(desta) = Sextallp1(srca); \ 32362306a36Sopenharmony_ci Sextallp2(destb) = Sextallp2(srcb) 32462306a36Sopenharmony_ci#define Sgl_copyto_sglext(src1,dest1,dest2) \ 32562306a36Sopenharmony_ci Sextallp1(dest1) = Sall(src1); Sextallp2(dest2) = 0 32662306a36Sopenharmony_ci 32762306a36Sopenharmony_ci#define Sglext_swap_lower(leftp2,rightp2) \ 32862306a36Sopenharmony_ci Sextallp2(leftp2) = Sextallp2(leftp2) XOR Sextallp2(rightp2); \ 32962306a36Sopenharmony_ci Sextallp2(rightp2) = Sextallp2(leftp2) XOR Sextallp2(rightp2); \ 33062306a36Sopenharmony_ci Sextallp2(leftp2) = Sextallp2(leftp2) XOR Sextallp2(rightp2) 33162306a36Sopenharmony_ci 33262306a36Sopenharmony_ci#define Sglext_setone_lowmantissap2(value) Deposit_dlowp2(value,1) 33362306a36Sopenharmony_ci 33462306a36Sopenharmony_ci/* The high bit is always zero so arithmetic or logical shifts will work. */ 33562306a36Sopenharmony_ci#define Sglext_right_align(srcdstA,srcdstB,shift) \ 33662306a36Sopenharmony_ci {int shiftamt, sticky; \ 33762306a36Sopenharmony_ci shiftamt = shift % 32; \ 33862306a36Sopenharmony_ci sticky = 0; \ 33962306a36Sopenharmony_ci switch (shift/32) { \ 34062306a36Sopenharmony_ci case 0: if (shiftamt > 0) { \ 34162306a36Sopenharmony_ci sticky = Sextallp2(srcdstB) << 32 - (shiftamt); \ 34262306a36Sopenharmony_ci Variable_shift_double(Sextallp1(srcdstA), \ 34362306a36Sopenharmony_ci Sextallp2(srcdstB),shiftamt,Sextallp2(srcdstB)); \ 34462306a36Sopenharmony_ci Sextallp1(srcdstA) >>= shiftamt; \ 34562306a36Sopenharmony_ci } \ 34662306a36Sopenharmony_ci break; \ 34762306a36Sopenharmony_ci case 1: if (shiftamt > 0) { \ 34862306a36Sopenharmony_ci sticky = (Sextallp1(srcdstA) << 32 - (shiftamt)) | \ 34962306a36Sopenharmony_ci Sextallp2(srcdstB); \ 35062306a36Sopenharmony_ci } \ 35162306a36Sopenharmony_ci else { \ 35262306a36Sopenharmony_ci sticky = Sextallp2(srcdstB); \ 35362306a36Sopenharmony_ci } \ 35462306a36Sopenharmony_ci Sextallp2(srcdstB) = Sextallp1(srcdstA) >> shiftamt; \ 35562306a36Sopenharmony_ci Sextallp1(srcdstA) = 0; \ 35662306a36Sopenharmony_ci break; \ 35762306a36Sopenharmony_ci } \ 35862306a36Sopenharmony_ci if (sticky) Sglext_setone_lowmantissap2(srcdstB); \ 35962306a36Sopenharmony_ci } 36062306a36Sopenharmony_ci 36162306a36Sopenharmony_ci/* The left argument is never smaller than the right argument */ 36262306a36Sopenharmony_ci#define Sglext_subtract(lefta,leftb,righta,rightb,resulta,resultb) \ 36362306a36Sopenharmony_ci if( Sextallp2(rightb) > Sextallp2(leftb) ) Sextallp1(lefta)--; \ 36462306a36Sopenharmony_ci Sextallp2(resultb) = Sextallp2(leftb) - Sextallp2(rightb); \ 36562306a36Sopenharmony_ci Sextallp1(resulta) = Sextallp1(lefta) - Sextallp1(righta) 36662306a36Sopenharmony_ci 36762306a36Sopenharmony_ci#define Sglext_addition(lefta,leftb,righta,rightb,resulta,resultb) \ 36862306a36Sopenharmony_ci /* If the sum of the low words is less than either source, then \ 36962306a36Sopenharmony_ci * an overflow into the next word occurred. */ \ 37062306a36Sopenharmony_ci if ((Sextallp2(resultb) = Sextallp2(leftb)+Sextallp2(rightb)) < \ 37162306a36Sopenharmony_ci Sextallp2(rightb)) \ 37262306a36Sopenharmony_ci Sextallp1(resulta) = Sextallp1(lefta)+Sextallp1(righta)+1; \ 37362306a36Sopenharmony_ci else Sextallp1(resulta) = Sextallp1(lefta)+Sextallp1(righta) 37462306a36Sopenharmony_ci 37562306a36Sopenharmony_ci 37662306a36Sopenharmony_ci#define Sglext_arithrightshiftby1(srcdstA,srcdstB) \ 37762306a36Sopenharmony_ci Shiftdouble(Sextallp1(srcdstA),Sextallp2(srcdstB),1,Sextallp2(srcdstB)); \ 37862306a36Sopenharmony_ci Sextallp1(srcdstA) = (int)Sextallp1(srcdstA) >> 1 37962306a36Sopenharmony_ci 38062306a36Sopenharmony_ci#define Sglext_leftshiftby8(valA,valB) \ 38162306a36Sopenharmony_ci Shiftdouble(Sextallp1(valA),Sextallp2(valB),24,Sextallp1(valA)); \ 38262306a36Sopenharmony_ci Sextallp2(valB) <<= 8 38362306a36Sopenharmony_ci#define Sglext_leftshiftby4(valA,valB) \ 38462306a36Sopenharmony_ci Shiftdouble(Sextallp1(valA),Sextallp2(valB),28,Sextallp1(valA)); \ 38562306a36Sopenharmony_ci Sextallp2(valB) <<= 4 38662306a36Sopenharmony_ci#define Sglext_leftshiftby3(valA,valB) \ 38762306a36Sopenharmony_ci Shiftdouble(Sextallp1(valA),Sextallp2(valB),29,Sextallp1(valA)); \ 38862306a36Sopenharmony_ci Sextallp2(valB) <<= 3 38962306a36Sopenharmony_ci#define Sglext_leftshiftby2(valA,valB) \ 39062306a36Sopenharmony_ci Shiftdouble(Sextallp1(valA),Sextallp2(valB),30,Sextallp1(valA)); \ 39162306a36Sopenharmony_ci Sextallp2(valB) <<= 2 39262306a36Sopenharmony_ci#define Sglext_leftshiftby1(valA,valB) \ 39362306a36Sopenharmony_ci Shiftdouble(Sextallp1(valA),Sextallp2(valB),31,Sextallp1(valA)); \ 39462306a36Sopenharmony_ci Sextallp2(valB) <<= 1 39562306a36Sopenharmony_ci 39662306a36Sopenharmony_ci#define Sglext_rightshiftby4(valueA,valueB) \ 39762306a36Sopenharmony_ci Shiftdouble(Sextallp1(valueA),Sextallp2(valueB),4,Sextallp2(valueB)); \ 39862306a36Sopenharmony_ci Sextallp1(valueA) >>= 4 39962306a36Sopenharmony_ci#define Sglext_rightshiftby3(valueA,valueB) \ 40062306a36Sopenharmony_ci Shiftdouble(Sextallp1(valueA),Sextallp2(valueB),3,Sextallp2(valueB)); \ 40162306a36Sopenharmony_ci Sextallp1(valueA) >>= 3 40262306a36Sopenharmony_ci#define Sglext_rightshiftby1(valueA,valueB) \ 40362306a36Sopenharmony_ci Shiftdouble(Sextallp1(valueA),Sextallp2(valueB),1,Sextallp2(valueB)); \ 40462306a36Sopenharmony_ci Sextallp1(valueA) >>= 1 40562306a36Sopenharmony_ci 40662306a36Sopenharmony_ci#define Sglext_xortointp1(left,right,result) Sgl_xortointp1(left,right,result) 40762306a36Sopenharmony_ci#define Sglext_xorfromintp1(left,right,result) \ 40862306a36Sopenharmony_ci Sgl_xorfromintp1(left,right,result) 40962306a36Sopenharmony_ci#define Sglext_copytoint_exponentmantissa(src,dest) \ 41062306a36Sopenharmony_ci Sgl_copytoint_exponentmantissa(src,dest) 41162306a36Sopenharmony_ci#define Sglext_ismagnitudeless(signlessleft,signlessright) \ 41262306a36Sopenharmony_ci Sgl_ismagnitudeless(signlessleft,signlessright) 41362306a36Sopenharmony_ci 41462306a36Sopenharmony_ci#define Sglext_set_sign(dbl_value,sign) Sgl_set_sign(dbl_value,sign) 41562306a36Sopenharmony_ci#define Sglext_clear_signexponent_set_hidden(srcdst) \ 41662306a36Sopenharmony_ci Sgl_clear_signexponent_set_hidden(srcdst) 41762306a36Sopenharmony_ci#define Sglext_clear_signexponent(srcdst) Sgl_clear_signexponent(srcdst) 41862306a36Sopenharmony_ci#define Sglext_clear_sign(srcdst) Sgl_clear_sign(srcdst) 41962306a36Sopenharmony_ci#define Sglext_isone_hidden(dbl_value) Sgl_isone_hidden(dbl_value) 42062306a36Sopenharmony_ci 42162306a36Sopenharmony_ci#define Sglext_denormalize(opndp1,opndp2,exponent,is_tiny) \ 42262306a36Sopenharmony_ci {int sticky; \ 42362306a36Sopenharmony_ci is_tiny = TRUE; \ 42462306a36Sopenharmony_ci if (exponent == 0 && Sextallp2(opndp2)) { \ 42562306a36Sopenharmony_ci switch (Rounding_mode()) { \ 42662306a36Sopenharmony_ci case ROUNDPLUS: \ 42762306a36Sopenharmony_ci if (Sgl_iszero_sign(opndp1)) \ 42862306a36Sopenharmony_ci if (Sgl_isone_hiddenoverflow(opndp1 + 1)) \ 42962306a36Sopenharmony_ci is_tiny = FALSE; \ 43062306a36Sopenharmony_ci break; \ 43162306a36Sopenharmony_ci case ROUNDMINUS: \ 43262306a36Sopenharmony_ci if (Sgl_isone_sign(opndp1)) { \ 43362306a36Sopenharmony_ci if (Sgl_isone_hiddenoverflow(opndp1 + 1)) \ 43462306a36Sopenharmony_ci is_tiny = FALSE; \ 43562306a36Sopenharmony_ci } \ 43662306a36Sopenharmony_ci break; \ 43762306a36Sopenharmony_ci case ROUNDNEAREST: \ 43862306a36Sopenharmony_ci if (Sglext_isone_highp2(opndp2) && \ 43962306a36Sopenharmony_ci (Sglext_isone_lowp1(opndp1) || \ 44062306a36Sopenharmony_ci Sglext_isnotzero_low31p2(opndp2))) \ 44162306a36Sopenharmony_ci if (Sgl_isone_hiddenoverflow(opndp1 + 1)) \ 44262306a36Sopenharmony_ci is_tiny = FALSE; \ 44362306a36Sopenharmony_ci break; \ 44462306a36Sopenharmony_ci } \ 44562306a36Sopenharmony_ci } \ 44662306a36Sopenharmony_ci Sglext_clear_signexponent_set_hidden(opndp1); \ 44762306a36Sopenharmony_ci if (exponent >= (1-DBL_P)) { \ 44862306a36Sopenharmony_ci if (exponent >= -31) { \ 44962306a36Sopenharmony_ci if (exponent > -31) { \ 45062306a36Sopenharmony_ci sticky = Sextallp2(opndp2) << 31+exponent; \ 45162306a36Sopenharmony_ci Variable_shift_double(opndp1,opndp2,1-exponent,opndp2); \ 45262306a36Sopenharmony_ci Sextallp1(opndp1) >>= 1-exponent; \ 45362306a36Sopenharmony_ci } \ 45462306a36Sopenharmony_ci else { \ 45562306a36Sopenharmony_ci sticky = Sextallp2(opndp2); \ 45662306a36Sopenharmony_ci Sextallp2(opndp2) = Sextallp1(opndp1); \ 45762306a36Sopenharmony_ci Sextallp1(opndp1) = 0; \ 45862306a36Sopenharmony_ci } \ 45962306a36Sopenharmony_ci } \ 46062306a36Sopenharmony_ci else { \ 46162306a36Sopenharmony_ci sticky = (Sextallp1(opndp1) << 31+exponent) | \ 46262306a36Sopenharmony_ci Sextallp2(opndp2); \ 46362306a36Sopenharmony_ci Sextallp2(opndp2) = Sextallp1(opndp1) >> -31-exponent; \ 46462306a36Sopenharmony_ci Sextallp1(opndp1) = 0; \ 46562306a36Sopenharmony_ci } \ 46662306a36Sopenharmony_ci } \ 46762306a36Sopenharmony_ci else { \ 46862306a36Sopenharmony_ci sticky = Sextallp1(opndp1) | Sextallp2(opndp2); \ 46962306a36Sopenharmony_ci Sglext_setzero(opndp1,opndp2); \ 47062306a36Sopenharmony_ci } \ 47162306a36Sopenharmony_ci if (sticky) Sglext_setone_lowmantissap2(opndp2); \ 47262306a36Sopenharmony_ci exponent = 0; \ 47362306a36Sopenharmony_ci } 474