Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- Generic Quad-FP.
- Should also support generic C (not depending entirely on __int128).
- */
- #ifndef _BGBCC
- // #if 1
- typedef struct tk_sqfp_val128_s tk_sqfp_val128;
- struct tk_sqfp_val128_s {
- u64 lo;
- u64 hi;
- };
- tk_sqfp_val128 tk_sqfp_get_f128(u64 *rv)
- {
- tk_sqfp_val128 vc;
- vc.lo=rv[0];
- vc.hi=rv[1];
- return(vc);
- }
- void tk_sqfp_set_f128(u64 *rv, tk_sqfp_val128 va)
- {
- rv[0]=va.lo;
- rv[1]=va.hi;
- }
- tk_sqfp_val128 tk_sqfp_get_frac(tk_sqfp_val128 va)
- {
- tk_sqfp_val128 vc;
- vc.lo=va.lo;
- vc.hi=(va.hi&0x0000FFFFFFFFFFFFULL);
- if((va.hi>>48)&32767)
- vc.hi|=0x0001000000000000ULL;
- return(vc);
- }
- int tk_sqfp_get_exp(tk_sqfp_val128 va)
- {
- return((va.hi>>48)&32767);
- }
- int tk_sqfp_get_sgn(tk_sqfp_val128 va)
- {
- return((va.hi>>63)&1);
- }
- tk_sqfp_val128 tk_sqfp_shlr(tk_sqfp_val128 va, int shr)
- {
- tk_sqfp_val128 vc;
- if(!shr)
- return(va);
- if(shr>=64)
- {
- if(shr==64)
- {
- vc.lo=va.hi;
- vc.hi=0;
- return(vc);
- }
- vc.lo=va.hi>>(shr-64);
- vc.hi=0;
- return(vc);
- }
- vc.lo=(va.lo>>shr)|(va.hi<<(64-shr));
- vc.hi=va.hi>>shr;
- return(vc);
- }
- tk_sqfp_val128 tk_sqfp_shll(tk_sqfp_val128 va, int shr)
- {
- tk_sqfp_val128 vc;
- if(!shr)
- return(va);
- if(shr>=64)
- {
- if(shr==64)
- {
- vc.hi=va.lo;
- vc.lo=0;
- return(vc);
- }
- vc.hi=va.lo<<(shr-64);
- vc.lo=0;
- return(vc);
- }
- vc.hi=(va.hi<<shr)|(va.lo>>(64-shr));
- vc.lo=va.lo<<shr;
- return(vc);
- }
- tk_sqfp_val128 tk_sqfp_shlr1(tk_sqfp_val128 va)
- {
- tk_sqfp_val128 vc;
- vc.lo=(va.lo>>1)|(va.hi<<63);
- vc.hi=va.hi>>1;
- return(vc);
- }
- tk_sqfp_val128 tk_sqfp_shll1(tk_sqfp_val128 va)
- {
- tk_sqfp_val128 vc;
- vc.hi=(va.hi<<1)|(va.lo>>63);
- vc.lo=va.lo<<1;
- return(vc);
- }
- tk_sqfp_val128 tk_sqfp_shlr8(tk_sqfp_val128 va)
- {
- tk_sqfp_val128 vc;
- vc.lo=(va.lo>>8)|(va.hi<<56);
- vc.hi=va.hi>>8;
- return(vc);
- }
- tk_sqfp_val128 tk_sqfp_shll8(tk_sqfp_val128 va)
- {
- tk_sqfp_val128 vc;
- vc.hi=(va.hi<<8)|(va.lo>>56);
- vc.lo=va.lo<<8;
- return(vc);
- }
- tk_sqfp_val128 tk_sqfp_shlr32(tk_sqfp_val128 va)
- {
- tk_sqfp_val128 vc;
- vc.lo=(va.lo>>32)|(va.hi<<32);
- vc.hi=va.hi>>32;
- return(vc);
- }
- tk_sqfp_val128 tk_sqfp_shll32(tk_sqfp_val128 va)
- {
- tk_sqfp_val128 vc;
- vc.hi=(va.hi<<32)|(va.lo>>32);
- vc.lo=va.lo<<32;
- return(vc);
- }
- tk_sqfp_val128 tk_sqfp_add_i128(tk_sqfp_val128 va, tk_sqfp_val128 vb)
- {
- tk_sqfp_val128 vc;
- int cf;
- vc.lo=va.lo+vb.lo;
- cf=vc.lo<va.lo;
- vc.hi=va.hi+vb.hi+cf;
- return(vc);
- }
- tk_sqfp_val128 tk_sqfp_neg_i128(tk_sqfp_val128 va)
- {
- tk_sqfp_val128 vc;
- u64 vlo, vlop1;
- int cf;
- vlo=(~va.lo);
- vlop1=vlo+1;
- cf=vlo>vlop1;
- vc.lo=vlop1;
- vc.hi=(~va.hi)+cf;
- return(vc);
- }
- tk_sqfp_val128 tk_sqfp_wrapu64lo_i128(u64 va)
- {
- tk_sqfp_val128 vc;
- vc.lo=va;
- vc.hi=0;
- return(vc);
- }
- tk_sqfp_val128 tk_sqfp_wrapu64hi_i128(u64 va)
- {
- tk_sqfp_val128 vc;
- vc.lo=0;
- vc.hi=va;
- return(vc);
- }
- tk_sqfp_val128 tk_sqfp_wrapu64mi_i128(u64 va)
- {
- tk_sqfp_val128 vc;
- vc.lo=va<<32;
- vc.hi=va>>32;
- return(vc);
- }
- tk_sqfp_val128 tk_sqfp_mulhi_i128(tk_sqfp_val128 va, tk_sqfp_val128 vb)
- {
- tk_sqfp_val128 vc;
- u64 v_aa, v_ab, v_ac, v_ad;
- u64 v_ba, v_bb, v_bc;
- u64 v_ca, v_cb, v_da;
- u64 va_a, va_b, va_c, va_d;
- u64 vb_a, vb_b, vb_c, vb_d;
- va_a=(u32)(va.hi>>32); va_b=(u32)(va.hi>> 0);
- va_c=(u32)(va.lo>>32); va_d=(u32)(va.lo>> 0);
- vb_a=(u32)(vb.hi>>32); vb_b=(u32)(vb.hi>> 0);
- vb_c=(u32)(vb.lo>>32); vb_d=(u32)(vb.lo>> 0);
- v_aa=va_a*vb_a;
- v_ab=va_a*vb_b;
- v_ac=va_a*vb_c;
- v_ad=va_a*vb_d;
- v_ba=va_b*vb_a;
- v_bb=va_b*vb_b;
- v_bc=va_b*vb_c;
- v_ca=va_c*vb_a;
- v_cb=va_c*vb_b;
- v_da=va_d*vb_a;
- vc=
- tk_sqfp_add_i128(
- tk_sqfp_add_i128(
- tk_sqfp_add_i128(
- tk_sqfp_wrapu64hi_i128(v_aa),
- tk_sqfp_wrapu64lo_i128(v_bb)),
- tk_sqfp_add_i128(
- tk_sqfp_add_i128(
- tk_sqfp_wrapu64mi_i128(v_ab),
- tk_sqfp_wrapu64mi_i128(v_ba)),
- tk_sqfp_add_i128(
- tk_sqfp_wrapu64lo_i128(v_ac),
- tk_sqfp_wrapu64lo_i128(v_ca)))),
- tk_sqfp_add_i128(
- tk_sqfp_add_i128(
- tk_sqfp_wrapu64lo_i128(v_ad>>32),
- tk_sqfp_wrapu64lo_i128(v_da>>32)),
- tk_sqfp_add_i128(
- tk_sqfp_wrapu64lo_i128(v_bc>>32),
- tk_sqfp_wrapu64lo_i128(v_cb>>32))));
- return(vc);
- }
- static const tk_sqfp_val128 tk_sqfp_f128_const_0 =
- { 0x0000000000000000ULL, 0x0000000000000000ULL };
- static const tk_sqfp_val128 tk_sqfp_f128_const_1 =
- { 0x0000000000000000ULL, 0x3FFF000000000000ULL };
- static const tk_sqfp_val128 tk_sqfp_f128_const_2 =
- { 0x0000000000000000ULL, 0x4000000000000000ULL };
- #define tk_sqfp_i128_iszero(va) (((va.hi)==0) && ((va.lo)==0))
- #define tk_sqfp_hi16(va) ((int)((va.hi)>>48))
- #define tk_sqfp_hi24(va) ((int)((va.hi)>>40))
- #define tk_sqfp_hi32(va) ((u32)((va.hi)>>32))
- #define tk_sqfp_hi48(va) ((u32)((va.hi)>>16))
- int tk_sqfp_i128_isgt(tk_sqfp_val128 va, tk_sqfp_val128 vb)
- {
- if(va.hi>vb.hi)
- return(1);
- if(va.hi!=vb.hi)
- return(0);
- if(va.lo>vb.lo)
- return(1);
- return(0);
- }
- int tk_sqfp_i128_iseq(tk_sqfp_val128 va, tk_sqfp_val128 vb)
- {
- if(va.hi!=vb.hi)
- return(0);
- if(va.lo!=vb.lo)
- return(0);
- return(1);
- }
- #else
- #define SQFP_ISINT128
- typedef unsigned __int128 tk_sqfp_val128;
- // #define tk_sqfp_get_f128(rv) (*(unsigned __int128 **)(rv))
- // #define tk_sqfp_set_f128(rv, va) (*(unsigned __int128 **)(rv)=(va))
- tk_sqfp_val128 tk_sqfp_get_f128(u64 *rv)
- {
- tk_sqfp_val128 vc;
- vc=0;
- memcpy(&vc, rv, 16);
- return(vc);
- }
- void tk_sqfp_set_f128(u64 *rv, tk_sqfp_val128 va)
- { memcpy(rv, &va, 16); }
- #define tk_sqfp_get_sgn(va) (((int)((va)>>127))&1)
- #define tk_sqfp_get_exp(va) (((int)((va)>>112))&32767)
- #define tk_sqfp_shlr(va, shr) ((va)>>(shr))
- #define tk_sqfp_shll(va, shr) ((va)<<(shr))
- #define tk_sqfp_shlr1(va) ((va)>>1)
- #define tk_sqfp_shll1(va) ((va)<<1)
- #define tk_sqfp_shlr8(va) ((va)>>8)
- #define tk_sqfp_shll8(va) ((va)<<8)
- #define tk_sqfp_shlr32(va) ((va)>>32)
- #define tk_sqfp_shll32(va) ((va)<<32)
- tk_sqfp_val128 tk_sqfp_get_frac(tk_sqfp_val128 va)
- {
- tk_sqfp_val128 vc;
- vc=(va&0x0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFUI128);
- if(tk_sqfp_get_exp(va))
- vc|=0x00010000000000000000000000000000UI128;
- return(vc);
- }
- #define tk_sqfp_add_i128(va, vb) ((va)+(vb))
- #define tk_sqfp_sub_i128(va, vb) ((va)-(vb))
- #define tk_sqfp_neg_i128(va) (0UI128-(va))
- #define tk_sqfp_wrapu64lo_i128(va) ((tk_sqfp_val128)(va))
- #define tk_sqfp_wrapu64hi_i128(va) (((tk_sqfp_val128)(va))<<64)
- #define tk_sqfp_wrapu64mi_i128(va) (((tk_sqfp_val128)(va))<<32)
- tk_sqfp_val128 tk_sqfp_mulhi_i128(tk_sqfp_val128 va, tk_sqfp_val128 vb)
- {
- tk_sqfp_val128 vc;
- u64 v_aa, v_ab, v_ac, v_ad;
- u64 v_ba, v_bb, v_bc;
- u64 v_ca, v_cb, v_da;
- u64 va_a, va_b, va_c, va_d;
- u64 vb_a, vb_b, vb_c, vb_d;
- va_a=(u32)(va>>96); va_b=(u32)(va>>64);
- va_c=(u32)(va>>32); va_d=(u32)(va>> 0);
- vb_a=(u32)(vb>>96); vb_b=(u32)(vb>>64);
- vb_c=(u32)(vb>>32); vb_d=(u32)(vb>> 0);
- #ifdef __BJX2__
- v_aa=__int32_dmulu(va_a, vb_a);
- v_ab=__int32_dmulu(va_a, vb_b);
- v_ac=__int32_dmulu(va_a, vb_c);
- v_ad=__int32_dmulu(va_a, vb_d);
- v_ba=__int32_dmulu(va_b, vb_a);
- v_bb=__int32_dmulu(va_b, vb_b);
- v_bc=__int32_dmulu(va_b, vb_c);
- v_ca=__int32_dmulu(va_c, vb_a);
- v_cb=__int32_dmulu(va_c, vb_b);
- v_da=__int32_dmulu(va_d, vb_a);
- #else
- v_aa=va_a*vb_a;
- v_ab=va_a*vb_b;
- v_ac=va_a*vb_c;
- v_ad=va_a*vb_d;
- v_ba=va_b*vb_a;
- v_bb=va_b*vb_b;
- v_bc=va_b*vb_c;
- v_ca=va_c*vb_a;
- v_cb=va_c*vb_b;
- v_da=va_d*vb_a;
- #endif
- vc=
- (((tk_sqfp_val128)v_aa)<<64)+
- (((tk_sqfp_val128)v_ab)<<32)+
- (((tk_sqfp_val128)v_ba)<<32)+
- v_bb+
- v_ac+
- v_ca+
- (v_ad>>32)+
- (v_da>>32)+
- (v_bc>>32)+
- (v_cb>>32);
- return(vc);
- }
- #define tk_sqfp_f128_const_0 0x00000000000000000000000000000000UI128
- #define tk_sqfp_f128_const_1 0x3FFF0000000000000000000000000000UI128
- #define tk_sqfp_f128_const_2 0x40000000000000000000000000000000UI128
- #define tk_sqfp_f128_const_inf 0x7FFF0000000000000000000000000000UI128
- #define tk_sqfp_i128_iszero(va) ((va)==0)
- #define tk_sqfp_hi16(va) ((int)((va)>>112))
- #define tk_sqfp_hi24(va) ((int)((va)>>104))
- #define tk_sqfp_hi32(va) ((u32)((va)>> 96))
- #define tk_sqfp_hi48(va) ((u64)((va)>> 80))
- #define tk_sqfp_i128_isgt(va, vb) ((va)>(vb))
- #define tk_sqfp_i128_iseq(va, vb) ((va)==(vb))
- #endif
- tk_sqfp_val128 tk_sqfp_repack_f128(tk_sqfp_val128 frc, int exc, int sgc)
- {
- tk_sqfp_val128 vc;
- if(tk_sqfp_i128_iszero(frc))
- return(tk_sqfp_f128_const_0);
- if(tk_sqfp_get_sgn(frc))
- {
- sgc=!sgc;
- frc=tk_sqfp_neg_i128(frc);
- }
- while(tk_sqfp_hi16(frc)>1)
- { exc++; frc=tk_sqfp_shlr1(frc); }
- while(!tk_sqfp_hi48(frc))
- { exc-=32; frc=tk_sqfp_shll32(frc); }
- while(!tk_sqfp_hi24(frc))
- { exc-=8; frc=tk_sqfp_shll8(frc); }
- while(!tk_sqfp_hi16(frc))
- { exc--; frc=tk_sqfp_shll1(frc); }
- if(exc>=32767)
- {
- #ifdef SQFP_ISINT128
- vc=tk_sqfp_f128_const_inf|(((tk_sqfp_val128)sgc)<<127);
- #else
- vc.hi=(32767ULL<<48)|(((u64)sgc)<<63);
- vc.lo=0;
- #endif
- return(vc);
- }
- if(exc<=0)
- {
- if(exc<=(-111))
- return(tk_sqfp_f128_const_0);
- frc=tk_sqfp_shlr(frc, -exc);
- #ifdef SQFP_ISINT128
- vc=frc|(((tk_sqfp_val128)sgc)<<127);
- #else
- vc.lo=frc.lo;
- vc.hi=(frc.hi&0x0000FFFFFFFFFFFFULL)|
- (((u64)sgc)<<63);
- #endif
- return(vc);
- }
- #ifdef SQFP_ISINT128
- vc=frc |
- (((tk_sqfp_val128)exc)<<112) |
- (((tk_sqfp_val128)sgc)<<127) ;
- #else
- vc.lo=frc.lo;
- vc.hi=(frc.hi&0x0000FFFFFFFFFFFFULL)|
- (((u64)exc)<<48)|(((u64)sgc)<<63);
- #endif
- return(vc);
- }
- tk_sqfp_val128 tk_sqfp_fadd_f128(tk_sqfp_val128 va, tk_sqfp_val128 vb)
- {
- tk_sqfp_val128 vc, fra, frb, frc;
- int exa, exb, exc, sga, sgb, sgc;
- int exd;
- fra=tk_sqfp_get_frac(va);
- frb=tk_sqfp_get_frac(vb);
- exa=tk_sqfp_get_exp(va);
- exb=tk_sqfp_get_exp(vb);
- sga=tk_sqfp_get_sgn(va);
- sgb=tk_sqfp_get_sgn(vb);
- if((exb>exa) || ((exb==exa) && tk_sqfp_i128_isgt(frb, fra)))
- {
- vc=va; va=vb; vb=vc;
- frc=fra; fra=frb; frb=frc;
- exc=exa; exa=exb; exb=exc;
- sgc=sga; sga=sgb; sgb=sgc;
- }
- exd=exa-exb;
- if(exd>=112)
- return(va);
- frb=tk_sqfp_shlr(frb, exd);
- if(sga!=sgb)
- { frb=tk_sqfp_neg_i128(frb); }
- exc=exa; sgc=sga;
- frc=tk_sqfp_add_i128(fra, frb);
- vc=tk_sqfp_repack_f128(frc, exc, sgc);
- return(vc);
- }
- tk_sqfp_val128 tk_sqfp_fsub_f128(tk_sqfp_val128 va, tk_sqfp_val128 vb)
- {
- tk_sqfp_val128 vc, vb1;
- vb1=vb;
- #ifdef SQFP_ISINT128
- vb1^=1UI128<<127;
- #else
- vb1.hi^=1ULL<<63;
- #endif
- vc=tk_sqfp_fadd_f128(va, vb1);
- }
- tk_sqfp_val128 tk_sqfp_fmul_f128(tk_sqfp_val128 va, tk_sqfp_val128 vb)
- {
- tk_sqfp_val128 vc, fra, frb, frc;
- int exa, exb, exc, sga, sgb, sgc;
- int exd;
- fra=tk_sqfp_get_frac(va);
- frb=tk_sqfp_get_frac(vb);
- exa=tk_sqfp_get_exp(va);
- exb=tk_sqfp_get_exp(vb);
- sga=tk_sqfp_get_sgn(va);
- sgb=tk_sqfp_get_sgn(vb);
- sgc=sga^sgb;
- exc=(exa+exb)-16383;
- fra=tk_sqfp_shll8(fra);
- frb=tk_sqfp_shll8(frb);
- frc=tk_sqfp_mulhi_i128(fra, frb);
- vc=tk_sqfp_repack_f128(frc, exc, sgc);
- return(vc);
- }
- tk_sqfp_val128 tk_sqfp_frcpa_f128(tk_sqfp_val128 va)
- {
- tk_sqfp_val128 vc;
- int sga;
- sga=tk_sqfp_get_sgn(va);
- #ifdef SQFP_ISINT128
- vc=~va;
- vc+=0x7FFE0000000000000000000000000000UI128;
- vc&=0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFUI128;
- vc|=((tk_sqfp_val128)sga)<<127;
- #else
- vc.hi=~va.hi;
- vc.lo=~va.lo;
- vc.hi+=0x7FFE000000000000ULL;
- vc.hi&=0x7FFFFFFFFFFFFFFFULL;
- vc.hi|=((u64)sga)<<63;
- #endif
- return(vc);
- }
- tk_sqfp_val128 tk_sqfp_fsqrta_f128(tk_sqfp_val128 va)
- {
- tk_sqfp_val128 vc;
- int sga;
- sga=tk_sqfp_get_sgn(va);
- #ifdef SQFP_ISINT128
- vc=va&0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFUI128;
- vc=vc>>1;
- vc+=0x1FFF8000000000000000000000000000UI128;
- vc|=((tk_sqfp_val128)sga)<<127;
- #else
- vc.hi=va.hi&0x7FFFFFFFFFFFFFFFULL;
- vc.lo=va.lo;
- // vc=tk_sqfp_shlr(vc, 1);
- vc=tk_sqfp_shlr1(vc);
- vc.hi+=0x1FFF800000000000ULL;
- vc.hi|=((u64)sga)<<63;
- #endif
- return(vc);
- }
- tk_sqfp_val128 tk_sqfp_frcp_f128(tk_sqfp_val128 va)
- {
- tk_sqfp_val128 vq, vt, vd, vk1, vk2;
- int i;
- vk2=tk_sqfp_f128_const_2;
- vq=tk_sqfp_frcpa_f128(va);
- for(i=0; i<8; i++)
- {
- vt=tk_sqfp_fmul_f128(vq, va);
- vd=tk_sqfp_fsub_f128(vk2, vt);
- vq=tk_sqfp_fmul_f128(vq, vd);
- }
- return(vq);
- }
- tk_sqfp_val128 tk_sqfp_fdiv_f128(tk_sqfp_val128 va, tk_sqfp_val128 vb)
- {
- tk_sqfp_val128 vq, vr;
- vr=tk_sqfp_frcp_f128(vb);
- vq=tk_sqfp_fmul_f128(va, vr);
- return(vq);
- }
- tk_sqfp_val128 tk_sqfp_fsqrt_f128(tk_sqfp_val128 va)
- {
- tk_sqfp_val128 vq, vt, vd, vk;
- int i;
- vk=tk_sqfp_fadd_f128(va, tk_sqfp_f128_const_1);
- vq=tk_sqfp_fsqrta_f128(va);
- for(i=0; i<8; i++)
- {
- vt=tk_sqfp_fmul_f128(vq, vq);
- vd=tk_sqfp_fsub_f128(vk, vt);
- vq=tk_sqfp_fmul_f128(vq, vd);
- }
- return(vq);
- }
- int tk_sqfp_fcmp_f128(tk_sqfp_val128 va, tk_sqfp_val128 vb)
- {
- int gt, lt, eq, sga, sgb, rv;
- sga=tk_sqfp_get_sgn(va);
- sgb=tk_sqfp_get_sgn(vb);
- if(sga==sgb)
- {
- gt=tk_sqfp_i128_isgt(va, vb);
- eq=tk_sqfp_i128_iseq(va, vb);
- lt=!gt && !eq;
- if(eq)
- {
- if(tk_sqfp_get_exp(va)==32767)
- return(2);
- }
- }else
- {
- gt=0; eq=0; lt=0;
- }
- rv=0;
- if(sga)
- {
- if(sgb)
- {
- if(gt) rv=-1;
- if(lt) rv= 1;
- }else
- { rv=-1; }
- }else
- {
- if(!sgb)
- {
- if(gt) rv=-1;
- if(lt) rv= 1;
- }
- else
- { rv=1; }
- }
- return(rv);
- }
- tk_sqfp_val128 tk_sqfp_fcvt_f64_to_f128(u64 va)
- {
- tk_sqfp_val128 vc;
- int sga, exa;
- sga=va>>63;
- exa=(va>>52)&2047;
- if(!exa)
- return(tk_sqfp_f128_const_0);
- #ifdef SQFP_ISINT128
- vc= ((va&0x7FFFFFFFFFFFFFFFUI128)<<60)+
- (((tk_sqfp_val128)(16383-1023))<<112);
- vc|=((tk_sqfp_val128)sga)<<127;
- #else
- vc.hi=(va>>4)+((16383LL-1023LL)<<48)+(((u64)sga)<<63);
- vc.lo=va<<60;
- #endif
- return(vc);
- }
- u64 tk_sqfp_fcvt_f128_to_f64(tk_sqfp_val128 va)
- {
- u64 vc;
- int sga, exa, exa1;
- sga=tk_sqfp_get_sgn(va);
- exa=tk_sqfp_get_exp(va);
- exa1=exa-(16383-1023);
- if(exa1<=0)
- return(0);
- if(exa1>=2047)
- {
- vc=0x7FF0000000000000ULL|(((u64)sga)<<63);
- return(vc);
- }
- #ifdef SQFP_ISINT128
- vc=(va>>60)-((16383UI128-1023UI128)<<52);
- vc|=((u64)sga)<<63;
- #else
- vc=(va.hi-((16383ULL-1023ULL)<<48))<<4;
- vc|=va.lo>>60;
- #endif
- return(vc);
- }
- tk_sqfp_val128 tk_sqfp_fcvt_i64_to_f128(u64 va, int issg)
- {
- tk_sqfp_val128 vc, frc;
- int sga, exa;
- if(!va)
- return(tk_sqfp_f128_const_0);
- #ifdef SQFP_ISINT128
- exa=16383+112;
- frc=va; sga=0;
- if(issg && (va>>63))
- { frc=(~va)+1; sga=1; }
- #else
- sga=0; exa=16383+112;
- frc.hi=0; frc.lo=va;
- if(issg && (va>>63))
- { frc.lo=(~va)+1; sga=1; }
- #endif
- vc=tk_sqfp_repack_f128(frc, exa, sga);
- return(vc);
- }
- u64 tk_sqfp_fcvt_f128_to_i64(tk_sqfp_val128 va)
- {
- tk_sqfp_val128 fra;
- u64 vc;
- int sga, exa, exa1;
- sga=tk_sqfp_get_sgn(va);
- exa=tk_sqfp_get_exp(va);
- fra=tk_sqfp_get_frac(va);
- exa1=exa-16383;
- if(exa1<=0)
- {
- vc=1;
- if(exa1<0) vc=0;
- if(sga) vc=(~vc)+1;
- return(vc);
- }
- if(exa1>=64)
- {
- vc=0x8000000000000000ULL;
- return(vc);
- }
- #ifdef SQFP_ISINT128
- vc=fra>>(112-exa1);
- #else
- fra=tk_sqfp_shlr(fra, 112-exa1);
- vc=fra.lo;
- #endif
- if(sga)
- vc=(~vc)+1;
- return(vc);
- }
- tk_sqfp_val128 tk_sqfp_fcvt_i128_to_f128(tk_sqfp_val128 va, int issg)
- {
- tk_sqfp_val128 vc, frc;
- int sga, exa;
- if(tk_sqfp_int128_iszero(va))
- return(tk_sqfp_f128_const_0);
- #ifdef SQFP_ISINT128
- exa=16383+112;
- frc=va; sga=0;
- if(issg && ((va>>127)!=0))
- { frc=(~va)+1; sga=1; }
- #else
- sga=0; exa=16383+112;
- frc.hi=va.hi; frc.lo=va.lo;
- if(issg && (va.hi>>63))
- { frc=tk_sqfp_neg_i128(frc); sga=1; }
- #endif
- while(tk_sqfp_hi16(frc)>1)
- { exa++; frc=tk_sqfp_shlr1(frc); }
- vc=tk_sqfp_repack_f128(frc, exa, sga);
- return(vc);
- }
- tk_sqfp_val128 tk_sqfp_fcvt_f128_to_i128(tk_sqfp_val128 va)
- {
- tk_sqfp_val128 fra;
- tk_sqfp_val128 vc;
- int sga, exa, exa1;
- sga=tk_sqfp_get_sgn(va);
- exa=tk_sqfp_get_exp(va);
- fra=tk_sqfp_get_frac(va);
- exa1=exa-16383;
- if(exa1<=0)
- {
- vc=tk_sqfp_wrapu64lo_i128(1);
- if(exa1<0) vc=tk_sqfp_wrapu64lo_i128(0);
- if(sga) vc=tk_sqfp_neg_i128(vc);
- return(vc);
- }
- if(exa1>=128)
- {
- vc=tk_sqfp_wrapu64hi_i128(0x8000000000000000ULL);
- return(vc);
- }
- #ifdef SQFP_ISINT128
- vc=fra>>(112-exa1);
- #else
- fra=tk_sqfp_shlr(fra, 112-exa1);
- vc=fra.lo;
- #endif
- if(sga) vc=tk_sqfp_neg_i128(vc);
- return(vc);
- }
- void __sqfp_fadd_f128fv(u64 *rf0, u64 *rf1, u64 *rf2)
- {
- tk_sqfp_val128 va, vb, vc;
- va=tk_sqfp_get_f128(rf0);
- vb=tk_sqfp_get_f128(rf1);
- vc=tk_sqfp_fadd_f128(va, vb);
- tk_sqfp_set_f128(rf2, vc);
- }
- void __sqfp_fsub_f128fv(u64 *rf0, u64 *rf1, u64 *rf2)
- {
- tk_sqfp_val128 va, vb, vc;
- va=tk_sqfp_get_f128(rf0);
- vb=tk_sqfp_get_f128(rf1);
- vc=tk_sqfp_fsub_f128(va, vb);
- tk_sqfp_set_f128(rf2, vc);
- }
- void __sqfp_fmul_f128fv(u64 *rf0, u64 *rf1, u64 *rf2)
- {
- tk_sqfp_val128 va, vb, vc;
- va=tk_sqfp_get_f128(rf0);
- vb=tk_sqfp_get_f128(rf1);
- vc=tk_sqfp_fmul_f128(va, vb);
- tk_sqfp_set_f128(rf2, vc);
- }
- void __sqfp_fdiv_f128fv(u64 *rf0, u64 *rf1, u64 *rf2)
- {
- tk_sqfp_val128 va, vb, vc;
- va=tk_sqfp_get_f128(rf0);
- vb=tk_sqfp_get_f128(rf1);
- vc=tk_sqfp_fdiv_f128(va, vb);
- tk_sqfp_set_f128(rf2, vc);
- }
- void __sqfp_fsqrt_f128fv(u64 *rf0, u64 *rf2)
- {
- tk_sqfp_val128 va, vb, vc;
- va=tk_sqfp_get_f128(rf0);
- vc=tk_sqfp_fsqrt_f128(va);
- tk_sqfp_set_f128(rf2, vc);
- }
- int __sqfp_fcmp_f128fv(u64 *rf0, u64 *rf1)
- {
- tk_sqfp_val128 va, vb, vc;
- int vi;
- va=tk_sqfp_get_f128(rf0);
- vb=tk_sqfp_get_f128(rf1);
- vi=tk_sqfp_fcmp_f128(va, vb);
- return(vi);
- }
- void __sqfp_fcvt_d2q(u64 *rf0, u64 *rf2)
- {
- tk_sqfp_val128 vc;
- vc=tk_sqfp_fcvt_f64_to_f128(rf0[0]);
- tk_sqfp_set_f128(rf2, vc);
- }
- void __sqfp_fcvt_q2d(u64 *rf0, u64 *rf2)
- {
- tk_sqfp_val128 va;
- va=tk_sqfp_get_f128(rf0);
- rf2[0]=tk_sqfp_fcvt_f128_to_f64(va);
- }
- void __sqfp_fcvt_s2q(u64 *rf0, u64 *rf2)
- {
- tk_sqfp_val128 vc;
- u64 va;
- va=__sfp_fcnvsd(rf0[0]);
- vc=tk_sqfp_fcvt_f64_to_f128(va);
- tk_sqfp_set_f128(rf2, vc);
- }
- void __sqfp_fcvt_q2s(u64 *rf0, u64 *rf2)
- {
- tk_sqfp_val128 va;
- u64 vc;
- va=tk_sqfp_get_f128(rf0);
- vc=tk_sqfp_fcvt_f128_to_f64(va);
- vc=__sfp_fcnvds(vc);
- rf2[0]=vc;
- }
- void __sqfp_fcvt_i2q(u64 *rf0, u64 *rf2)
- {
- tk_sqfp_val128 vc;
- vc=tk_sqfp_fcvt_i64_to_f128(rf0[0], 1);
- tk_sqfp_set_f128(rf2, vc);
- }
- void __sqfp_fcvt_ui2q(u64 *rf0, u64 *rf2)
- {
- tk_sqfp_val128 vc;
- vc=tk_sqfp_fcvt_i64_to_f128(rf0[0], 0);
- tk_sqfp_set_f128(rf2, vc);
- }
- void __sqfp_fcvt_q2i(u64 *rf0, u64 *rf2)
- {
- tk_sqfp_val128 va;
- va=tk_sqfp_get_f128(rf0);
- rf2[0]=tk_sqfp_fcvt_f128_to_i64(va);
- }
- void __sqfp_fcvt_xi2q(u64 *rf0, u64 *rf2)
- {
- tk_sqfp_val128 va, vc;
- va=tk_sqfp_get_f128(rf0);
- vc=tk_sqfp_fcvt_i128_to_f128(vc, 1);
- tk_sqfp_set_f128(rf2, vc);
- }
- void __sqfp_fcvt_xiu2q(u64 *rf0, u64 *rf2)
- {
- tk_sqfp_val128 va, vc;
- va=tk_sqfp_get_f128(rf0);
- vc=tk_sqfp_fcvt_i128_to_f128(vc, 0);
- tk_sqfp_set_f128(rf2, vc);
- }
- void __sqfp_fcvt_q2xi(u64 *rf0, u64 *rf2)
- {
- tk_sqfp_val128 va, vc;
- va=tk_sqfp_get_f128(rf0);
- vc=tk_sqfp_fcvt_f128_to_i128(va);
- tk_sqfp_set_f128(rf2, vc);
- }
Advertisement
Add Comment
Please, Sign In to add comment