197 lines
2.4 KiB
C
197 lines
2.4 KiB
C
|
#include "math64.h"
|
||
|
|
||
|
#ifndef COMPILER_SUPPORTS_LONG_LONG
|
||
|
|
||
|
|
||
|
|
||
|
UInt64 u64_from_halves(UInt32 hi, UInt32 lo){
|
||
|
|
||
|
UInt64 r;
|
||
|
|
||
|
r.lo = lo;
|
||
|
r.hi = hi;
|
||
|
|
||
|
return r;
|
||
|
}
|
||
|
|
||
|
|
||
|
UInt64 u64_32_to_64(UInt32 v){
|
||
|
|
||
|
UInt64 r;
|
||
|
|
||
|
r.hi = 0;
|
||
|
r.lo = v;
|
||
|
|
||
|
return r;
|
||
|
}
|
||
|
|
||
|
UInt32 u64_64_to_32(UInt64 v){
|
||
|
|
||
|
return v.lo;
|
||
|
}
|
||
|
|
||
|
UInt32 u64_get_hi(UInt64 v){
|
||
|
|
||
|
return v.hi;
|
||
|
}
|
||
|
|
||
|
UInt64 u64_add(UInt64 a, UInt64 b){
|
||
|
|
||
|
UInt64 r;
|
||
|
|
||
|
r.lo = a.lo + b.lo;
|
||
|
r.hi = a.hi + b.hi;
|
||
|
if(r.lo < a.lo) r.hi++;
|
||
|
|
||
|
return r;
|
||
|
}
|
||
|
|
||
|
UInt64 u64_add32(UInt64 a, UInt32 b){
|
||
|
|
||
|
UInt64 r;
|
||
|
|
||
|
r.lo = a.lo + b;
|
||
|
r.hi = a.hi;
|
||
|
if(r.lo < a.lo) r.hi++;
|
||
|
|
||
|
return r;
|
||
|
}
|
||
|
|
||
|
UInt64 u64_umul3232(UInt32 a, UInt32 b){
|
||
|
|
||
|
UInt64 r;
|
||
|
UInt32 ah, al, bh, bl;
|
||
|
|
||
|
ah = a >> 16;
|
||
|
al = a & 0xFFFFUL;
|
||
|
bh = b >> 16;
|
||
|
bl = b & 0xFFFFUL;
|
||
|
|
||
|
r = u64_shl(u64_32_to_64(ah * bh), 16);
|
||
|
r = u64_add32(r, ah * bl);
|
||
|
r = u64_add32(r, al * bh);
|
||
|
r = u64_add32(u64_shl(r, 16), al * bl);
|
||
|
|
||
|
return r;
|
||
|
}
|
||
|
|
||
|
UInt64 u64_smul3232(Int32 a, Int32 b){
|
||
|
|
||
|
Boolean negative = false;
|
||
|
UInt64 r;
|
||
|
|
||
|
if(a < 0){
|
||
|
a = -a;
|
||
|
negative = !negative;
|
||
|
}
|
||
|
|
||
|
if(b < 0){
|
||
|
b = -b;
|
||
|
negative = !negative;
|
||
|
}
|
||
|
|
||
|
r = u64_umul3232(a, b);
|
||
|
|
||
|
if(negative){
|
||
|
|
||
|
r.hi = ~r.hi; //negate r
|
||
|
r.lo = ~r.lo;
|
||
|
r = u64_inc(r);
|
||
|
}
|
||
|
|
||
|
return r;
|
||
|
}
|
||
|
|
||
|
UInt64 u64_shr(UInt64 v, unsigned bits){
|
||
|
|
||
|
UInt64 a = v;
|
||
|
|
||
|
while(bits >= 32){
|
||
|
a.lo = a.hi;
|
||
|
a.hi = 0;
|
||
|
bits -= 32;
|
||
|
}
|
||
|
|
||
|
a.lo = (a.lo >> bits) + (a.hi << (32 - bits));
|
||
|
a.hi >>= bits;
|
||
|
|
||
|
return a;
|
||
|
}
|
||
|
|
||
|
UInt64 u64_shl(UInt64 v, unsigned bits){
|
||
|
|
||
|
UInt64 a = v;
|
||
|
|
||
|
while(bits >= 32){
|
||
|
a.hi = a.lo;
|
||
|
a.lo = 0;
|
||
|
bits -= 32;
|
||
|
}
|
||
|
|
||
|
a.hi = (a.hi << bits) + (a.lo >> (32 - bits));
|
||
|
a.lo <<= bits;
|
||
|
|
||
|
return a;
|
||
|
}
|
||
|
|
||
|
UInt64 u64_xtnd32(UInt64 v){
|
||
|
|
||
|
UInt64 a = v;
|
||
|
|
||
|
if(a.lo & 0x80000000UL) a.hi = 0xFFFFFFFFUL;
|
||
|
|
||
|
return a;
|
||
|
}
|
||
|
|
||
|
Boolean u64_isZero(UInt64 a){
|
||
|
|
||
|
return a.lo == 0 && a.hi == 0;
|
||
|
}
|
||
|
|
||
|
UInt64 u64_inc(UInt64 v){
|
||
|
|
||
|
UInt64 a = v;
|
||
|
|
||
|
if(!++a.lo) a.hi++;
|
||
|
|
||
|
return a;
|
||
|
}
|
||
|
|
||
|
UInt64 u64_and(UInt64 a, UInt64 b){
|
||
|
|
||
|
UInt64 r;
|
||
|
|
||
|
r.lo = a.lo & b.lo;
|
||
|
r.hi = a.hi & b.hi;
|
||
|
|
||
|
return r;
|
||
|
}
|
||
|
|
||
|
UInt64 u64_zero(void){
|
||
|
|
||
|
UInt64 r;
|
||
|
|
||
|
r.lo = 0;
|
||
|
r.hi = 0;
|
||
|
|
||
|
return r;
|
||
|
}
|
||
|
|
||
|
|
||
|
UInt64 u64_sub(UInt64 a, UInt64 b){
|
||
|
|
||
|
UInt64 bn;
|
||
|
|
||
|
bn.lo = ~b.lo;
|
||
|
bn.hi = ~b.hi;
|
||
|
|
||
|
bn = u64_inc(bn);
|
||
|
|
||
|
return u64_add(a, bn);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
#endif
|