Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. #include "math64.h"
  2.  
  3. #ifndef COMPILER_SUPPORTS_LONG_LONG
  4.  
  5.  
  6.  
  7. UInt64 u64_from_halves(UInt32 hi, UInt32 lo){
  8.        
  9.         UInt64 r;
  10.        
  11.         r.lo = lo;
  12.         r.hi = hi;
  13.        
  14.         return r;      
  15. }
  16.  
  17.  
  18. UInt64 u64_32_to_64(UInt32 v){
  19.        
  20.         UInt64 r;
  21.        
  22.         r.hi = 0;
  23.         r.lo = v;
  24.        
  25.         return r;      
  26. }
  27.  
  28. UInt32 u64_64_to_32(UInt64 v){
  29.        
  30.         return v.lo;   
  31. }
  32.  
  33. UInt32 u64_get_hi(UInt64 v){
  34.        
  35.         return v.hi;   
  36. }
  37.  
  38. UInt64 u64_add(UInt64 a, UInt64 b){
  39.        
  40.         UInt64 r;
  41.        
  42.         r.lo = a.lo + b.lo;
  43.         r.hi = a.hi + b.hi;
  44.         if(r.lo < a.lo) r.hi++;
  45.        
  46.         return r;
  47. }
  48.  
  49. UInt64 u64_add32(UInt64 a, UInt32 b){
  50.        
  51.         UInt64 r;
  52.        
  53.         r.lo = a.lo + b;
  54.         r.hi = a.hi;
  55.         if(r.lo < a.lo) r.hi++;
  56.        
  57.         return r;      
  58. }
  59.  
  60. UInt64 u64_umul3232(UInt32 a, UInt32 b){
  61.        
  62.         UInt64 r;
  63.         UInt32 ah, al, bh, bl;
  64.        
  65.         ah = a >> 16;
  66.         al = a & 0xFFFFUL;
  67.         bh = b >> 16;
  68.         bl = b & 0xFFFFUL;
  69.        
  70.         r = u64_shl(u64_32_to_64(ah * bh), 16);
  71.         r = u64_add32(r, ah * bl);
  72.         r = u64_add32(r, al * bh);
  73.         r = u64_add32(u64_shl(r, 16), al * bl);
  74.        
  75.         return r;
  76. }
  77.  
  78. UInt64 u64_smul3232(Int32 a, Int32 b){
  79.        
  80.         Boolean negative = false;
  81.         UInt64 r;
  82.        
  83.         if(a < 0){
  84.                 a = -a;
  85.                 negative = !negative;
  86.         }
  87.        
  88.         if(b < 0){
  89.                 b = -b;
  90.                 negative = !negative;
  91.         }
  92.        
  93.         r = u64_umul3232(a, b);
  94.        
  95.         if(negative){
  96.                
  97.                 r.hi = ~r.hi;                   //negate r
  98.                 r.lo = ~r.lo;
  99.                 r = u64_inc(r);
  100.         }
  101.        
  102.         return r;
  103. }
  104.  
  105. UInt64 u64_shr(UInt64 v, unsigned bits){
  106.        
  107.         UInt64 a = v;
  108.        
  109.         while(bits >= 32){
  110.                 a.lo = a.hi;
  111.                 a.hi = 0;
  112.                 bits -= 32;
  113.         }
  114.        
  115.         a.lo = (a.lo >> bits) + (a.hi << (32 - bits));
  116.         a.hi >>= bits;
  117.        
  118.         return a;
  119. }
  120.  
  121. UInt64 u64_shl(UInt64 v, unsigned bits){
  122.        
  123.         UInt64 a = v;
  124.        
  125.         while(bits >= 32){
  126.                 a.hi = a.lo;
  127.                 a.lo = 0;
  128.                 bits -= 32;
  129.         }
  130.        
  131.         a.hi = (a.hi << bits) + (a.lo >> (32 - bits));
  132.         a.lo <<= bits;
  133.        
  134.         return a;
  135. }
  136.  
  137. UInt64 u64_xtnd32(UInt64 v){
  138.        
  139.         UInt64 a = v;
  140.        
  141.         if(a.lo & 0x80000000UL) a.hi = 0xFFFFFFFFUL;
  142.        
  143.         return a;
  144. }
  145.  
  146. Boolean u64_isZero(UInt64 a){
  147.        
  148.         return a.lo == 0 && a.hi == 0;
  149. }
  150.  
  151. UInt64 u64_inc(UInt64 v){
  152.        
  153.         UInt64 a = v;
  154.        
  155.         if(!++a.lo) a.hi++;
  156.        
  157.         return a;
  158. }
  159.  
  160. UInt64 u64_and(UInt64 a, UInt64 b){
  161.        
  162.         UInt64 r;
  163.        
  164.         r.lo = a.lo & b.lo;
  165.         r.hi = a.hi & b.hi;
  166.        
  167.         return r;      
  168. }
  169.  
  170. UInt64 u64_zero(void){
  171.        
  172.         UInt64 r;
  173.        
  174.         r.lo = 0;
  175.         r.hi = 0;
  176.        
  177.         return r;      
  178. }
  179.  
  180.  
  181. UInt64 u64_sub(UInt64 a, UInt64 b){
  182.        
  183.         UInt64 bn;
  184.        
  185.         bn.lo = ~b.lo;
  186.         bn.hi = ~b.hi;
  187.        
  188.         bn = u64_inc(bn);
  189.        
  190.         return u64_add(a, bn);
  191. }
  192.  
  193.  
  194.  
  195.  
  196.  
  197. #endif