cr88192

TestKern new Binary128 SoftFP code

Sep 28th, 2025
146
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 18.88 KB | Source Code | 0 0
  1. /*
  2. Generic Quad-FP.
  3. Should also support generic C (not depending entirely on __int128).
  4.  
  5.  */
  6.  
  7. #ifndef _BGBCC
  8.  
  9. // #if 1
  10.  
  11. typedef struct tk_sqfp_val128_s tk_sqfp_val128;
  12.  
  13. struct tk_sqfp_val128_s {
  14. u64 lo;
  15. u64 hi;
  16. };
  17.  
  18. tk_sqfp_val128 tk_sqfp_get_f128(u64 *rv)
  19. {
  20.     tk_sqfp_val128 vc;
  21.     vc.lo=rv[0];
  22.     vc.hi=rv[1];
  23.     return(vc);
  24. }
  25.  
  26. void tk_sqfp_set_f128(u64 *rv, tk_sqfp_val128 va)
  27. {
  28.     rv[0]=va.lo;
  29.     rv[1]=va.hi;
  30. }
  31.  
  32. tk_sqfp_val128 tk_sqfp_get_frac(tk_sqfp_val128 va)
  33. {
  34.     tk_sqfp_val128 vc;
  35.     vc.lo=va.lo;
  36.     vc.hi=(va.hi&0x0000FFFFFFFFFFFFULL);
  37.     if((va.hi>>48)&32767)
  38.         vc.hi|=0x0001000000000000ULL;
  39.     return(vc);
  40. }
  41.  
  42. int tk_sqfp_get_exp(tk_sqfp_val128 va)
  43. {
  44.     return((va.hi>>48)&32767);
  45. }
  46.  
  47. int tk_sqfp_get_sgn(tk_sqfp_val128 va)
  48. {
  49.     return((va.hi>>63)&1);
  50. }
  51.  
  52. tk_sqfp_val128 tk_sqfp_shlr(tk_sqfp_val128 va, int shr)
  53. {
  54.     tk_sqfp_val128 vc;
  55.    
  56.     if(!shr)
  57.         return(va);
  58.    
  59.     if(shr>=64)
  60.     {
  61.         if(shr==64)
  62.         {
  63.             vc.lo=va.hi;
  64.             vc.hi=0;
  65.             return(vc);
  66.         }
  67.         vc.lo=va.hi>>(shr-64);
  68.         vc.hi=0;
  69.         return(vc);
  70.     }
  71.    
  72.     vc.lo=(va.lo>>shr)|(va.hi<<(64-shr));
  73.     vc.hi=va.hi>>shr;
  74.     return(vc);
  75. }
  76.  
  77. tk_sqfp_val128 tk_sqfp_shll(tk_sqfp_val128 va, int shr)
  78. {
  79.     tk_sqfp_val128 vc;
  80.    
  81.     if(!shr)
  82.         return(va);
  83.    
  84.     if(shr>=64)
  85.     {
  86.         if(shr==64)
  87.         {
  88.             vc.hi=va.lo;
  89.             vc.lo=0;
  90.             return(vc);
  91.         }
  92.         vc.hi=va.lo<<(shr-64);
  93.         vc.lo=0;
  94.         return(vc);
  95.     }
  96.    
  97.     vc.hi=(va.hi<<shr)|(va.lo>>(64-shr));
  98.     vc.lo=va.lo<<shr;
  99.     return(vc);
  100. }
  101.  
  102.  
  103. tk_sqfp_val128 tk_sqfp_shlr1(tk_sqfp_val128 va)
  104. {
  105.     tk_sqfp_val128 vc;
  106.     vc.lo=(va.lo>>1)|(va.hi<<63);
  107.     vc.hi=va.hi>>1;
  108.     return(vc);
  109. }
  110.  
  111. tk_sqfp_val128 tk_sqfp_shll1(tk_sqfp_val128 va)
  112. {
  113.     tk_sqfp_val128 vc;
  114.     vc.hi=(va.hi<<1)|(va.lo>>63);
  115.     vc.lo=va.lo<<1;
  116.     return(vc);
  117. }
  118.  
  119. tk_sqfp_val128 tk_sqfp_shlr8(tk_sqfp_val128 va)
  120. {
  121.     tk_sqfp_val128 vc;
  122.     vc.lo=(va.lo>>8)|(va.hi<<56);
  123.     vc.hi=va.hi>>8;
  124.     return(vc);
  125. }
  126.  
  127. tk_sqfp_val128 tk_sqfp_shll8(tk_sqfp_val128 va)
  128. {
  129.     tk_sqfp_val128 vc;
  130.     vc.hi=(va.hi<<8)|(va.lo>>56);
  131.     vc.lo=va.lo<<8;
  132.     return(vc);
  133. }
  134.  
  135. tk_sqfp_val128 tk_sqfp_shlr32(tk_sqfp_val128 va)
  136. {
  137.     tk_sqfp_val128 vc;
  138.     vc.lo=(va.lo>>32)|(va.hi<<32);
  139.     vc.hi=va.hi>>32;
  140.     return(vc);
  141. }
  142.  
  143. tk_sqfp_val128 tk_sqfp_shll32(tk_sqfp_val128 va)
  144. {
  145.     tk_sqfp_val128 vc;
  146.     vc.hi=(va.hi<<32)|(va.lo>>32);
  147.     vc.lo=va.lo<<32;
  148.     return(vc);
  149. }
  150.  
  151.  
  152. tk_sqfp_val128 tk_sqfp_add_i128(tk_sqfp_val128 va, tk_sqfp_val128 vb)
  153. {
  154.     tk_sqfp_val128 vc;
  155.     int cf;
  156.    
  157.     vc.lo=va.lo+vb.lo;
  158.     cf=vc.lo<va.lo;
  159.     vc.hi=va.hi+vb.hi+cf;
  160.     return(vc);
  161. }
  162.  
  163. tk_sqfp_val128 tk_sqfp_neg_i128(tk_sqfp_val128 va)
  164. {
  165.     tk_sqfp_val128 vc;
  166.     u64 vlo, vlop1;
  167.     int cf;
  168.  
  169.     vlo=(~va.lo);
  170.     vlop1=vlo+1;
  171.     cf=vlo>vlop1;
  172.     vc.lo=vlop1;
  173.     vc.hi=(~va.hi)+cf;
  174.     return(vc);
  175. }
  176.  
  177. tk_sqfp_val128 tk_sqfp_wrapu64lo_i128(u64 va)
  178. {
  179.     tk_sqfp_val128 vc;
  180.     vc.lo=va;
  181.     vc.hi=0;
  182.     return(vc);
  183. }
  184.  
  185. tk_sqfp_val128 tk_sqfp_wrapu64hi_i128(u64 va)
  186. {
  187.     tk_sqfp_val128 vc;
  188.     vc.lo=0;
  189.     vc.hi=va;
  190.     return(vc);
  191. }
  192.  
  193. tk_sqfp_val128 tk_sqfp_wrapu64mi_i128(u64 va)
  194. {
  195.     tk_sqfp_val128 vc;
  196.     vc.lo=va<<32;
  197.     vc.hi=va>>32;
  198.     return(vc);
  199. }
  200.  
  201. tk_sqfp_val128 tk_sqfp_mulhi_i128(tk_sqfp_val128 va, tk_sqfp_val128 vb)
  202. {
  203.     tk_sqfp_val128 vc;
  204.     u64 v_aa, v_ab, v_ac, v_ad;
  205.     u64 v_ba, v_bb, v_bc;
  206.     u64 v_ca, v_cb, v_da;
  207.     u64 va_a, va_b, va_c, va_d;
  208.     u64 vb_a, vb_b, vb_c, vb_d;
  209.  
  210.     va_a=(u32)(va.hi>>32);  va_b=(u32)(va.hi>> 0);
  211.     va_c=(u32)(va.lo>>32);  va_d=(u32)(va.lo>> 0);
  212.     vb_a=(u32)(vb.hi>>32);  vb_b=(u32)(vb.hi>> 0);
  213.     vb_c=(u32)(vb.lo>>32);  vb_d=(u32)(vb.lo>> 0);
  214.  
  215.     v_aa=va_a*vb_a;
  216.     v_ab=va_a*vb_b;
  217.     v_ac=va_a*vb_c;
  218.     v_ad=va_a*vb_d;
  219.  
  220.     v_ba=va_b*vb_a;
  221.     v_bb=va_b*vb_b;
  222.     v_bc=va_b*vb_c;
  223.  
  224.     v_ca=va_c*vb_a;
  225.     v_cb=va_c*vb_b;
  226.  
  227.     v_da=va_d*vb_a;
  228.  
  229.     vc=
  230.         tk_sqfp_add_i128(
  231.             tk_sqfp_add_i128(
  232.                 tk_sqfp_add_i128(
  233.                     tk_sqfp_wrapu64hi_i128(v_aa),
  234.                     tk_sqfp_wrapu64lo_i128(v_bb)),
  235.                 tk_sqfp_add_i128(
  236.                     tk_sqfp_add_i128(
  237.                         tk_sqfp_wrapu64mi_i128(v_ab),
  238.                         tk_sqfp_wrapu64mi_i128(v_ba)),
  239.                     tk_sqfp_add_i128(
  240.                         tk_sqfp_wrapu64lo_i128(v_ac),
  241.                         tk_sqfp_wrapu64lo_i128(v_ca)))),
  242.             tk_sqfp_add_i128(
  243.                 tk_sqfp_add_i128(
  244.                     tk_sqfp_wrapu64lo_i128(v_ad>>32),
  245.                     tk_sqfp_wrapu64lo_i128(v_da>>32)),
  246.                 tk_sqfp_add_i128(
  247.                     tk_sqfp_wrapu64lo_i128(v_bc>>32),
  248.                     tk_sqfp_wrapu64lo_i128(v_cb>>32))));
  249.    
  250.     return(vc);
  251. }
  252.  
  253. static const tk_sqfp_val128 tk_sqfp_f128_const_0 =
  254.     { 0x0000000000000000ULL, 0x0000000000000000ULL };
  255. static const tk_sqfp_val128 tk_sqfp_f128_const_1 =
  256.     { 0x0000000000000000ULL, 0x3FFF000000000000ULL };
  257. static const tk_sqfp_val128 tk_sqfp_f128_const_2 =
  258.     { 0x0000000000000000ULL, 0x4000000000000000ULL };
  259.  
  260. #define tk_sqfp_i128_iszero(va) (((va.hi)==0) && ((va.lo)==0))
  261.  
  262. #define tk_sqfp_hi16(va)        ((int)((va.hi)>>48))
  263. #define tk_sqfp_hi24(va)        ((int)((va.hi)>>40))
  264. #define tk_sqfp_hi32(va)        ((u32)((va.hi)>>32))
  265. #define tk_sqfp_hi48(va)        ((u32)((va.hi)>>16))
  266.  
  267. int tk_sqfp_i128_isgt(tk_sqfp_val128 va, tk_sqfp_val128 vb)
  268. {
  269.     if(va.hi>vb.hi)
  270.         return(1);
  271.     if(va.hi!=vb.hi)
  272.         return(0);
  273.     if(va.lo>vb.lo)
  274.         return(1);
  275.     return(0);
  276. }
  277.  
  278. int tk_sqfp_i128_iseq(tk_sqfp_val128 va, tk_sqfp_val128 vb)
  279. {
  280.     if(va.hi!=vb.hi)
  281.         return(0);
  282.     if(va.lo!=vb.lo)
  283.         return(0);
  284.     return(1);
  285. }
  286.  
  287. #else
  288.  
  289. #define SQFP_ISINT128
  290.  
  291. typedef unsigned __int128 tk_sqfp_val128;
  292.  
  293. // #define tk_sqfp_get_f128(rv)     (*(unsigned __int128 **)(rv))
  294. // #define tk_sqfp_set_f128(rv, va) (*(unsigned __int128 **)(rv)=(va))
  295.  
  296. tk_sqfp_val128 tk_sqfp_get_f128(u64 *rv)
  297. {
  298.     tk_sqfp_val128 vc;
  299.     vc=0;
  300.     memcpy(&vc, rv, 16);
  301.     return(vc);
  302. }
  303.  
  304. void tk_sqfp_set_f128(u64 *rv, tk_sqfp_val128 va)
  305.     { memcpy(rv, &va, 16); }
  306.  
  307. #define tk_sqfp_get_sgn(va)     (((int)((va)>>127))&1)
  308. #define tk_sqfp_get_exp(va)     (((int)((va)>>112))&32767)
  309.  
  310. #define tk_sqfp_shlr(va, shr)   ((va)>>(shr))
  311. #define tk_sqfp_shll(va, shr)   ((va)<<(shr))
  312. #define tk_sqfp_shlr1(va)       ((va)>>1)
  313. #define tk_sqfp_shll1(va)       ((va)<<1)
  314. #define tk_sqfp_shlr8(va)       ((va)>>8)
  315. #define tk_sqfp_shll8(va)       ((va)<<8)
  316. #define tk_sqfp_shlr32(va)      ((va)>>32)
  317. #define tk_sqfp_shll32(va)      ((va)<<32)
  318.  
  319. tk_sqfp_val128 tk_sqfp_get_frac(tk_sqfp_val128 va)
  320. {
  321.     tk_sqfp_val128 vc;
  322.     vc=(va&0x0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFUI128);
  323.     if(tk_sqfp_get_exp(va))
  324.         vc|=0x00010000000000000000000000000000UI128;
  325.     return(vc);
  326. }
  327.  
  328. #define tk_sqfp_add_i128(va, vb)    ((va)+(vb))
  329. #define tk_sqfp_sub_i128(va, vb)    ((va)-(vb))
  330. #define tk_sqfp_neg_i128(va)        (0UI128-(va))
  331.  
  332. #define tk_sqfp_wrapu64lo_i128(va)  ((tk_sqfp_val128)(va))
  333. #define tk_sqfp_wrapu64hi_i128(va)  (((tk_sqfp_val128)(va))<<64)
  334. #define tk_sqfp_wrapu64mi_i128(va)  (((tk_sqfp_val128)(va))<<32)
  335.  
  336. tk_sqfp_val128 tk_sqfp_mulhi_i128(tk_sqfp_val128 va, tk_sqfp_val128 vb)
  337. {
  338.     tk_sqfp_val128 vc;
  339.     u64 v_aa, v_ab, v_ac, v_ad;
  340.     u64 v_ba, v_bb, v_bc;
  341.     u64 v_ca, v_cb, v_da;
  342.     u64 va_a, va_b, va_c, va_d;
  343.     u64 vb_a, vb_b, vb_c, vb_d;
  344.    
  345.     va_a=(u32)(va>>96); va_b=(u32)(va>>64);
  346.     va_c=(u32)(va>>32); va_d=(u32)(va>> 0);
  347.     vb_a=(u32)(vb>>96); vb_b=(u32)(vb>>64);
  348.     vb_c=(u32)(vb>>32); vb_d=(u32)(vb>> 0);
  349.  
  350. #ifdef __BJX2__
  351.     v_aa=__int32_dmulu(va_a, vb_a);
  352.     v_ab=__int32_dmulu(va_a, vb_b);
  353.     v_ac=__int32_dmulu(va_a, vb_c);
  354.     v_ad=__int32_dmulu(va_a, vb_d);
  355.  
  356.     v_ba=__int32_dmulu(va_b, vb_a);
  357.     v_bb=__int32_dmulu(va_b, vb_b);
  358.     v_bc=__int32_dmulu(va_b, vb_c);
  359.  
  360.     v_ca=__int32_dmulu(va_c, vb_a);
  361.     v_cb=__int32_dmulu(va_c, vb_b);
  362.  
  363.     v_da=__int32_dmulu(va_d, vb_a);
  364. #else
  365.     v_aa=va_a*vb_a;
  366.     v_ab=va_a*vb_b;
  367.     v_ac=va_a*vb_c;
  368.     v_ad=va_a*vb_d;
  369.  
  370.     v_ba=va_b*vb_a;
  371.     v_bb=va_b*vb_b;
  372.     v_bc=va_b*vb_c;
  373.  
  374.     v_ca=va_c*vb_a;
  375.     v_cb=va_c*vb_b;
  376.  
  377.     v_da=va_d*vb_a;
  378. #endif
  379.  
  380.     vc=
  381.         (((tk_sqfp_val128)v_aa)<<64)+
  382.         (((tk_sqfp_val128)v_ab)<<32)+
  383.         (((tk_sqfp_val128)v_ba)<<32)+
  384.         v_bb+
  385.         v_ac+
  386.         v_ca+
  387.         (v_ad>>32)+
  388.         (v_da>>32)+
  389.         (v_bc>>32)+
  390.         (v_cb>>32);
  391.    
  392.     return(vc);
  393. }
  394.  
  395.  
  396. #define tk_sqfp_f128_const_0        0x00000000000000000000000000000000UI128
  397. #define tk_sqfp_f128_const_1        0x3FFF0000000000000000000000000000UI128
  398. #define tk_sqfp_f128_const_2        0x40000000000000000000000000000000UI128
  399. #define tk_sqfp_f128_const_inf      0x7FFF0000000000000000000000000000UI128
  400.  
  401. #define tk_sqfp_i128_iszero(va) ((va)==0)
  402.  
  403. #define tk_sqfp_hi16(va)        ((int)((va)>>112))
  404. #define tk_sqfp_hi24(va)        ((int)((va)>>104))
  405. #define tk_sqfp_hi32(va)        ((u32)((va)>> 96))
  406. #define tk_sqfp_hi48(va)        ((u64)((va)>> 80))
  407.  
  408. #define tk_sqfp_i128_isgt(va, vb)   ((va)>(vb))
  409. #define tk_sqfp_i128_iseq(va, vb)   ((va)==(vb))
  410.  
  411.  
  412. #endif
  413.  
  414. tk_sqfp_val128 tk_sqfp_repack_f128(tk_sqfp_val128 frc, int exc, int sgc)
  415. {
  416.     tk_sqfp_val128 vc;
  417.  
  418.     if(tk_sqfp_i128_iszero(frc))
  419.         return(tk_sqfp_f128_const_0);
  420.  
  421.     if(tk_sqfp_get_sgn(frc))
  422.     {
  423.         sgc=!sgc;
  424.         frc=tk_sqfp_neg_i128(frc);
  425.     }
  426.    
  427.     while(tk_sqfp_hi16(frc)>1)
  428.         { exc++; frc=tk_sqfp_shlr1(frc); }
  429.  
  430.     while(!tk_sqfp_hi48(frc))
  431.         { exc-=32; frc=tk_sqfp_shll32(frc); }
  432.     while(!tk_sqfp_hi24(frc))
  433.         { exc-=8; frc=tk_sqfp_shll8(frc); }
  434.     while(!tk_sqfp_hi16(frc))
  435.         { exc--; frc=tk_sqfp_shll1(frc); }
  436.    
  437.     if(exc>=32767)
  438.     {
  439. #ifdef SQFP_ISINT128
  440.         vc=tk_sqfp_f128_const_inf|(((tk_sqfp_val128)sgc)<<127);
  441. #else
  442.         vc.hi=(32767ULL<<48)|(((u64)sgc)<<63);
  443.         vc.lo=0;
  444. #endif
  445.         return(vc);
  446.     }
  447.  
  448.     if(exc<=0)
  449.     {
  450.         if(exc<=(-111))
  451.             return(tk_sqfp_f128_const_0);
  452.        
  453.         frc=tk_sqfp_shlr(frc, -exc);
  454.  
  455. #ifdef SQFP_ISINT128
  456.         vc=frc|(((tk_sqfp_val128)sgc)<<127);
  457. #else
  458.         vc.lo=frc.lo;
  459.         vc.hi=(frc.hi&0x0000FFFFFFFFFFFFULL)|
  460.             (((u64)sgc)<<63);
  461. #endif
  462.         return(vc);
  463.     }
  464.    
  465. #ifdef SQFP_ISINT128
  466.     vc=frc |
  467.         (((tk_sqfp_val128)exc)<<112) |
  468.         (((tk_sqfp_val128)sgc)<<127) ;
  469. #else
  470.     vc.lo=frc.lo;
  471.     vc.hi=(frc.hi&0x0000FFFFFFFFFFFFULL)|
  472.         (((u64)exc)<<48)|(((u64)sgc)<<63);
  473. #endif
  474.     return(vc);
  475. }
  476.  
  477. tk_sqfp_val128 tk_sqfp_fadd_f128(tk_sqfp_val128 va, tk_sqfp_val128 vb)
  478. {
  479.     tk_sqfp_val128 vc, fra, frb, frc;
  480.     int exa, exb, exc, sga, sgb, sgc;
  481.     int exd;
  482.  
  483.     fra=tk_sqfp_get_frac(va);
  484.     frb=tk_sqfp_get_frac(vb);
  485.     exa=tk_sqfp_get_exp(va);
  486.     exb=tk_sqfp_get_exp(vb);
  487.     sga=tk_sqfp_get_sgn(va);
  488.     sgb=tk_sqfp_get_sgn(vb);
  489.    
  490.     if((exb>exa) || ((exb==exa) && tk_sqfp_i128_isgt(frb, fra)))
  491.     {
  492.         vc=va; va=vb; vb=vc;
  493.         frc=fra; fra=frb; frb=frc;
  494.         exc=exa; exa=exb; exb=exc;
  495.         sgc=sga; sga=sgb; sgb=sgc;
  496.     }
  497.    
  498.     exd=exa-exb;
  499.     if(exd>=112)
  500.         return(va);
  501.    
  502.     frb=tk_sqfp_shlr(frb, exd);
  503.    
  504.     if(sga!=sgb)
  505.         { frb=tk_sqfp_neg_i128(frb); }
  506.    
  507.     exc=exa; sgc=sga;
  508.     frc=tk_sqfp_add_i128(fra, frb);
  509.  
  510.     vc=tk_sqfp_repack_f128(frc, exc, sgc);
  511.     return(vc);
  512. }
  513.  
  514. tk_sqfp_val128 tk_sqfp_fsub_f128(tk_sqfp_val128 va, tk_sqfp_val128 vb)
  515. {
  516.     tk_sqfp_val128 vc, vb1;
  517.     vb1=vb;
  518. #ifdef SQFP_ISINT128
  519.     vb1^=1UI128<<127;
  520. #else
  521.     vb1.hi^=1ULL<<63;
  522. #endif
  523.     vc=tk_sqfp_fadd_f128(va, vb1);
  524. }
  525.  
  526. tk_sqfp_val128 tk_sqfp_fmul_f128(tk_sqfp_val128 va, tk_sqfp_val128 vb)
  527. {
  528.     tk_sqfp_val128 vc, fra, frb, frc;
  529.     int exa, exb, exc, sga, sgb, sgc;
  530.     int exd;
  531.  
  532.     fra=tk_sqfp_get_frac(va);
  533.     frb=tk_sqfp_get_frac(vb);
  534.     exa=tk_sqfp_get_exp(va);
  535.     exb=tk_sqfp_get_exp(vb);
  536.     sga=tk_sqfp_get_sgn(va);
  537.     sgb=tk_sqfp_get_sgn(vb);
  538.  
  539.     sgc=sga^sgb;
  540.     exc=(exa+exb)-16383;
  541.  
  542.     fra=tk_sqfp_shll8(fra);
  543.     frb=tk_sqfp_shll8(frb);
  544.     frc=tk_sqfp_mulhi_i128(fra, frb);
  545.  
  546.     vc=tk_sqfp_repack_f128(frc, exc, sgc);
  547.     return(vc);
  548. }
  549.  
  550. tk_sqfp_val128 tk_sqfp_frcpa_f128(tk_sqfp_val128 va)
  551. {
  552.     tk_sqfp_val128 vc;
  553.     int sga;
  554.  
  555.     sga=tk_sqfp_get_sgn(va);
  556.  
  557. #ifdef SQFP_ISINT128
  558.     vc=~va;
  559.     vc+=0x7FFE0000000000000000000000000000UI128;
  560.     vc&=0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFUI128;
  561.     vc|=((tk_sqfp_val128)sga)<<127;
  562. #else
  563.     vc.hi=~va.hi;
  564.     vc.lo=~va.lo;
  565.     vc.hi+=0x7FFE000000000000ULL;
  566.     vc.hi&=0x7FFFFFFFFFFFFFFFULL;
  567.     vc.hi|=((u64)sga)<<63;
  568. #endif
  569.  
  570.     return(vc);
  571. }
  572.  
  573. tk_sqfp_val128 tk_sqfp_fsqrta_f128(tk_sqfp_val128 va)
  574. {
  575.     tk_sqfp_val128 vc;
  576.     int sga;
  577.  
  578.     sga=tk_sqfp_get_sgn(va);
  579.    
  580. #ifdef SQFP_ISINT128
  581.     vc=va&0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFUI128;
  582.     vc=vc>>1;
  583.     vc+=0x1FFF8000000000000000000000000000UI128;
  584.     vc|=((tk_sqfp_val128)sga)<<127;
  585. #else
  586.     vc.hi=va.hi&0x7FFFFFFFFFFFFFFFULL;
  587.     vc.lo=va.lo;
  588. //  vc=tk_sqfp_shlr(vc, 1);
  589.     vc=tk_sqfp_shlr1(vc);
  590.     vc.hi+=0x1FFF800000000000ULL;
  591.     vc.hi|=((u64)sga)<<63;
  592. #endif
  593.  
  594.     return(vc);
  595. }
  596.  
  597. tk_sqfp_val128 tk_sqfp_frcp_f128(tk_sqfp_val128 va)
  598. {
  599.     tk_sqfp_val128 vq, vt, vd, vk1, vk2;
  600.     int i;
  601.    
  602.     vk2=tk_sqfp_f128_const_2;
  603.  
  604.     vq=tk_sqfp_frcpa_f128(va);
  605.     for(i=0; i<8; i++)
  606.     {
  607.         vt=tk_sqfp_fmul_f128(vq, va);
  608.         vd=tk_sqfp_fsub_f128(vk2, vt);
  609.         vq=tk_sqfp_fmul_f128(vq, vd);
  610.     }
  611.     return(vq);
  612. }
  613.  
  614. tk_sqfp_val128 tk_sqfp_fdiv_f128(tk_sqfp_val128 va, tk_sqfp_val128 vb)
  615. {
  616.     tk_sqfp_val128 vq, vr;
  617.     vr=tk_sqfp_frcp_f128(vb);
  618.     vq=tk_sqfp_fmul_f128(va, vr);
  619.     return(vq);
  620. }
  621.  
  622. tk_sqfp_val128 tk_sqfp_fsqrt_f128(tk_sqfp_val128 va)
  623. {
  624.     tk_sqfp_val128 vq, vt, vd, vk;
  625.     int i;
  626.  
  627.     vk=tk_sqfp_fadd_f128(va, tk_sqfp_f128_const_1);
  628.     vq=tk_sqfp_fsqrta_f128(va);
  629.     for(i=0; i<8; i++)
  630.     {
  631.         vt=tk_sqfp_fmul_f128(vq, vq);
  632.         vd=tk_sqfp_fsub_f128(vk, vt);
  633.         vq=tk_sqfp_fmul_f128(vq, vd);
  634.     }
  635.     return(vq);
  636. }
  637.  
  638. int tk_sqfp_fcmp_f128(tk_sqfp_val128 va, tk_sqfp_val128 vb)
  639. {
  640.     int gt, lt, eq, sga, sgb, rv;
  641.  
  642.     sga=tk_sqfp_get_sgn(va);
  643.     sgb=tk_sqfp_get_sgn(vb);
  644.    
  645.     if(sga==sgb)
  646.     {
  647.         gt=tk_sqfp_i128_isgt(va, vb);
  648.         eq=tk_sqfp_i128_iseq(va, vb);
  649.         lt=!gt && !eq;
  650.        
  651.         if(eq)
  652.         {
  653.             if(tk_sqfp_get_exp(va)==32767)
  654.                 return(2);
  655.         }
  656.     }else
  657.     {
  658.         gt=0; eq=0; lt=0;
  659.     }
  660.    
  661.     rv=0;
  662.     if(sga)
  663.     {
  664.         if(sgb)
  665.         {
  666.             if(gt)  rv=-1;
  667.             if(lt)  rv= 1;
  668.         }else
  669.             { rv=-1; }
  670.     }else
  671.     {
  672.         if(!sgb)
  673.         {
  674.             if(gt)  rv=-1;
  675.             if(lt)  rv= 1;
  676.         }
  677.         else
  678.             { rv=1; }
  679.     }
  680.     return(rv);
  681. }
  682.  
  683. tk_sqfp_val128 tk_sqfp_fcvt_f64_to_f128(u64 va)
  684. {
  685.     tk_sqfp_val128 vc;
  686.     int sga, exa;
  687.  
  688.     sga=va>>63;
  689.     exa=(va>>52)&2047;
  690.     if(!exa)
  691.         return(tk_sqfp_f128_const_0);
  692.  
  693. #ifdef SQFP_ISINT128
  694.     vc= ((va&0x7FFFFFFFFFFFFFFFUI128)<<60)+
  695.         (((tk_sqfp_val128)(16383-1023))<<112);
  696.     vc|=((tk_sqfp_val128)sga)<<127;
  697. #else
  698.     vc.hi=(va>>4)+((16383LL-1023LL)<<48)+(((u64)sga)<<63);
  699.     vc.lo=va<<60;
  700. #endif
  701.     return(vc);
  702. }
  703.  
  704. u64 tk_sqfp_fcvt_f128_to_f64(tk_sqfp_val128 va)
  705. {
  706.     u64 vc;
  707.     int sga, exa, exa1;
  708.  
  709.     sga=tk_sqfp_get_sgn(va);
  710.     exa=tk_sqfp_get_exp(va);
  711.     exa1=exa-(16383-1023);
  712.     if(exa1<=0)
  713.         return(0);
  714.     if(exa1>=2047)
  715.     {
  716.         vc=0x7FF0000000000000ULL|(((u64)sga)<<63);
  717.         return(vc);
  718.     }
  719.  
  720. #ifdef SQFP_ISINT128
  721.     vc=(va>>60)-((16383UI128-1023UI128)<<52);
  722.     vc|=((u64)sga)<<63;
  723. #else
  724.     vc=(va.hi-((16383ULL-1023ULL)<<48))<<4;
  725.     vc|=va.lo>>60;
  726. #endif
  727.     return(vc);
  728. }
  729.  
  730. tk_sqfp_val128 tk_sqfp_fcvt_i64_to_f128(u64 va, int issg)
  731. {
  732.     tk_sqfp_val128 vc, frc;
  733.     int sga, exa;
  734.  
  735.     if(!va)
  736.         return(tk_sqfp_f128_const_0);
  737.  
  738. #ifdef SQFP_ISINT128
  739.     exa=16383+112;
  740.     frc=va; sga=0;
  741.     if(issg && (va>>63))
  742.         { frc=(~va)+1; sga=1; }
  743. #else
  744.     sga=0; exa=16383+112;
  745.     frc.hi=0;   frc.lo=va;
  746.     if(issg && (va>>63))
  747.         { frc.lo=(~va)+1; sga=1; }
  748. #endif
  749.  
  750.     vc=tk_sqfp_repack_f128(frc, exa, sga);
  751.     return(vc);
  752. }
  753.  
  754. u64 tk_sqfp_fcvt_f128_to_i64(tk_sqfp_val128 va)
  755. {
  756.     tk_sqfp_val128 fra;
  757.     u64 vc;
  758.     int sga, exa, exa1;
  759.  
  760.     sga=tk_sqfp_get_sgn(va);
  761.     exa=tk_sqfp_get_exp(va);
  762.     fra=tk_sqfp_get_frac(va);
  763.     exa1=exa-16383;
  764.  
  765.     if(exa1<=0)
  766.     {
  767.         vc=1;
  768.         if(exa1<0)  vc=0;
  769.         if(sga)     vc=(~vc)+1;
  770.         return(vc);
  771.     }
  772.  
  773.     if(exa1>=64)
  774.     {
  775.         vc=0x8000000000000000ULL;
  776.         return(vc);
  777.     }
  778.  
  779. #ifdef SQFP_ISINT128
  780.     vc=fra>>(112-exa1);
  781. #else
  782.     fra=tk_sqfp_shlr(fra, 112-exa1);
  783.     vc=fra.lo;
  784. #endif
  785.  
  786.     if(sga)
  787.         vc=(~vc)+1;
  788.     return(vc);
  789. }
  790.  
  791.  
  792.  
  793. tk_sqfp_val128 tk_sqfp_fcvt_i128_to_f128(tk_sqfp_val128 va, int issg)
  794. {
  795.     tk_sqfp_val128 vc, frc;
  796.     int sga, exa;
  797.  
  798.     if(tk_sqfp_int128_iszero(va))
  799.         return(tk_sqfp_f128_const_0);
  800.  
  801. #ifdef SQFP_ISINT128
  802.     exa=16383+112;
  803.     frc=va; sga=0;
  804.     if(issg && ((va>>127)!=0))
  805.         { frc=(~va)+1; sga=1; }
  806. #else
  807.     sga=0; exa=16383+112;
  808.     frc.hi=va.hi;   frc.lo=va.lo;
  809.     if(issg && (va.hi>>63))
  810.         { frc=tk_sqfp_neg_i128(frc); sga=1; }
  811. #endif
  812.  
  813.     while(tk_sqfp_hi16(frc)>1)
  814.         { exa++; frc=tk_sqfp_shlr1(frc); }
  815.  
  816.     vc=tk_sqfp_repack_f128(frc, exa, sga);
  817.     return(vc);
  818. }
  819.  
  820. tk_sqfp_val128 tk_sqfp_fcvt_f128_to_i128(tk_sqfp_val128 va)
  821. {
  822.     tk_sqfp_val128 fra;
  823.     tk_sqfp_val128 vc;
  824.     int sga, exa, exa1;
  825.  
  826.     sga=tk_sqfp_get_sgn(va);
  827.     exa=tk_sqfp_get_exp(va);
  828.     fra=tk_sqfp_get_frac(va);
  829.     exa1=exa-16383;
  830.  
  831.     if(exa1<=0)
  832.     {
  833.         vc=tk_sqfp_wrapu64lo_i128(1);
  834.         if(exa1<0)  vc=tk_sqfp_wrapu64lo_i128(0);
  835.         if(sga)     vc=tk_sqfp_neg_i128(vc);
  836.         return(vc);
  837.     }
  838.  
  839.     if(exa1>=128)
  840.     {
  841.         vc=tk_sqfp_wrapu64hi_i128(0x8000000000000000ULL);
  842.         return(vc);
  843.     }
  844.  
  845. #ifdef SQFP_ISINT128
  846.     vc=fra>>(112-exa1);
  847. #else
  848.     fra=tk_sqfp_shlr(fra, 112-exa1);
  849.     vc=fra.lo;
  850. #endif
  851.  
  852.     if(sga)     vc=tk_sqfp_neg_i128(vc);
  853.     return(vc);
  854. }
  855.  
  856.  
  857. void __sqfp_fadd_f128fv(u64 *rf0, u64 *rf1, u64 *rf2)
  858. {
  859.     tk_sqfp_val128 va, vb, vc;
  860.     va=tk_sqfp_get_f128(rf0);
  861.     vb=tk_sqfp_get_f128(rf1);
  862.     vc=tk_sqfp_fadd_f128(va, vb);
  863.     tk_sqfp_set_f128(rf2, vc);
  864. }
  865.  
  866. void __sqfp_fsub_f128fv(u64 *rf0, u64 *rf1, u64 *rf2)
  867. {
  868.     tk_sqfp_val128 va, vb, vc;
  869.     va=tk_sqfp_get_f128(rf0);
  870.     vb=tk_sqfp_get_f128(rf1);
  871.     vc=tk_sqfp_fsub_f128(va, vb);
  872.     tk_sqfp_set_f128(rf2, vc);
  873. }
  874.  
  875. void __sqfp_fmul_f128fv(u64 *rf0, u64 *rf1, u64 *rf2)
  876. {
  877.     tk_sqfp_val128 va, vb, vc;
  878.     va=tk_sqfp_get_f128(rf0);
  879.     vb=tk_sqfp_get_f128(rf1);
  880.     vc=tk_sqfp_fmul_f128(va, vb);
  881.     tk_sqfp_set_f128(rf2, vc);
  882. }
  883.  
  884. void __sqfp_fdiv_f128fv(u64 *rf0, u64 *rf1, u64 *rf2)
  885. {
  886.     tk_sqfp_val128 va, vb, vc;
  887.     va=tk_sqfp_get_f128(rf0);
  888.     vb=tk_sqfp_get_f128(rf1);
  889.     vc=tk_sqfp_fdiv_f128(va, vb);
  890.     tk_sqfp_set_f128(rf2, vc);
  891. }
  892.  
  893. void __sqfp_fsqrt_f128fv(u64 *rf0, u64 *rf2)
  894. {
  895.     tk_sqfp_val128 va, vb, vc;
  896.     va=tk_sqfp_get_f128(rf0);
  897.     vc=tk_sqfp_fsqrt_f128(va);
  898.     tk_sqfp_set_f128(rf2, vc);
  899. }
  900.  
  901.  
  902. int __sqfp_fcmp_f128fv(u64 *rf0, u64 *rf1)
  903. {
  904.     tk_sqfp_val128 va, vb, vc;
  905.     int vi;
  906.     va=tk_sqfp_get_f128(rf0);
  907.     vb=tk_sqfp_get_f128(rf1);
  908.     vi=tk_sqfp_fcmp_f128(va, vb);
  909.     return(vi);
  910. }
  911.  
  912. void __sqfp_fcvt_d2q(u64 *rf0, u64 *rf2)
  913. {
  914.     tk_sqfp_val128 vc;
  915.     vc=tk_sqfp_fcvt_f64_to_f128(rf0[0]);
  916.     tk_sqfp_set_f128(rf2, vc);
  917. }
  918.  
  919. void __sqfp_fcvt_q2d(u64 *rf0, u64 *rf2)
  920. {
  921.     tk_sqfp_val128 va;
  922.     va=tk_sqfp_get_f128(rf0);
  923.     rf2[0]=tk_sqfp_fcvt_f128_to_f64(va);
  924. }
  925.  
  926.  
  927. void __sqfp_fcvt_s2q(u64 *rf0, u64 *rf2)
  928. {
  929.     tk_sqfp_val128 vc;
  930.     u64 va;
  931.    
  932.     va=__sfp_fcnvsd(rf0[0]);
  933.     vc=tk_sqfp_fcvt_f64_to_f128(va);
  934.     tk_sqfp_set_f128(rf2, vc);
  935. }
  936.  
  937. void __sqfp_fcvt_q2s(u64 *rf0, u64 *rf2)
  938. {
  939.     tk_sqfp_val128 va;
  940.     u64 vc;
  941.     va=tk_sqfp_get_f128(rf0);
  942.     vc=tk_sqfp_fcvt_f128_to_f64(va);
  943.     vc=__sfp_fcnvds(vc);
  944.     rf2[0]=vc;
  945. }
  946.  
  947.  
  948. void __sqfp_fcvt_i2q(u64 *rf0, u64 *rf2)
  949. {
  950.     tk_sqfp_val128 vc;
  951.     vc=tk_sqfp_fcvt_i64_to_f128(rf0[0], 1);
  952.     tk_sqfp_set_f128(rf2, vc);
  953. }
  954.  
  955. void __sqfp_fcvt_ui2q(u64 *rf0, u64 *rf2)
  956. {
  957.     tk_sqfp_val128 vc;
  958.     vc=tk_sqfp_fcvt_i64_to_f128(rf0[0], 0);
  959.     tk_sqfp_set_f128(rf2, vc);
  960. }
  961.  
  962. void __sqfp_fcvt_q2i(u64 *rf0, u64 *rf2)
  963. {
  964.     tk_sqfp_val128 va;
  965.     va=tk_sqfp_get_f128(rf0);
  966.     rf2[0]=tk_sqfp_fcvt_f128_to_i64(va);
  967. }
  968.  
  969.  
  970. void __sqfp_fcvt_xi2q(u64 *rf0, u64 *rf2)
  971. {
  972.     tk_sqfp_val128 va, vc;
  973.     va=tk_sqfp_get_f128(rf0);
  974.     vc=tk_sqfp_fcvt_i128_to_f128(vc, 1);
  975.     tk_sqfp_set_f128(rf2, vc);
  976. }
  977.  
  978. void __sqfp_fcvt_xiu2q(u64 *rf0, u64 *rf2)
  979. {
  980.     tk_sqfp_val128 va, vc;
  981.     va=tk_sqfp_get_f128(rf0);
  982.     vc=tk_sqfp_fcvt_i128_to_f128(vc, 0);
  983.     tk_sqfp_set_f128(rf2, vc);
  984. }
  985.  
  986. void __sqfp_fcvt_q2xi(u64 *rf0, u64 *rf2)
  987. {
  988.     tk_sqfp_val128 va, vc;
  989.     va=tk_sqfp_get_f128(rf0);
  990.     vc=tk_sqfp_fcvt_f128_to_i128(va);
  991.     tk_sqfp_set_f128(rf2, vc);
  992. }
  993.  
Advertisement
Add Comment
Please, Sign In to add comment