1 #ifndef _CPU_MATH_H_ 2 #define _CPU_MATH_H_ 3 4 #include <stdint.h> 5 6 uint32_t cpuMathUint44Div1000ToUint32_slow_path(uint64_t val); 7 8 static inline uint32_t cpuMathUint44Div1000ToUint32(uint64_t val) 9 { 10 if (val >> 32) 11 return cpuMathUint44Div1000ToUint32_slow_path(val); 12 else 13 return (uint32_t)val / 1000; 14 } 15 16 uint64_t cpuMathU64DivByU16(uint64_t val, uint32_t divBy /* 16 bits max*/); 17 18 //DO NOT USE ON NON_COMPILE-TIME-CONSTANT VALUES OF u16, use cpuMathU64DivByU16() 19 20 #define U64_DIV_BY_CONST_U16(u64, u16) \ 21 ({ \ 22 const uint16_t divBy = u16; \ 23 const uint64_t _num = u64; \ 24 const uint32_t numHi = _num >> 32, numLo = _num; \ 25 uint32_t t1, t2, t3, t4, t5; \ 26 \ 27 t1 = numHi / divBy; \ 28 t2 = numHi % divBy; \ 29 t2 <<= 16; \ 30 t2 += numLo >> 16; \ 31 t3 = t2 / divBy; \ 32 t4 = t2 % divBy; \ 33 t4 <<= 16; \ 34 t4 += numLo & 0xFFFF; \ 35 t5 = t4 / divBy; \ 36 \ 37 (((uint64_t)t1) << 32) + (((uint64_t)t3) << 16) + t5; \ 38 }) 39 40 //correctly handles 0, 1, powers of 2, and all else to calculate "(1 << 64) / val" 41 //do not even think of using this on non-compile-time-constant values! 42 #define U64_RECIPROCAL_CALCULATE(val) ((val) & ((val) - 1)) ? (0xffffffffffffffffull / (val)) : (((val) <= 1) ? 0xffffffffffffffffull : (0x8000000000000000ull / ((val) >> 1))) 43 44 uint64_t cpuMathRecipAssistedUdiv64by64(uint64_t num, uint64_t denom, uint64_t denomRecip); 45 uint64_t cpuMathRecipAssistedUdiv64by32(uint64_t num, uint32_t denom, uint64_t denomRecip); 46 47 #define U64_DIV_BY_U64_CONSTANT(val, constantVal) cpuMathRecipAssistedUdiv64by64((val), (constantVal), U64_RECIPROCAL_CALCULATE(constantVal)) 48 #define I64_DIV_BY_I64_CONSTANT(val, constantVal) \ 49 ({ \ 50 char neg = ((uint32_t)((val) >> 32) ^ (uint32_t)(((uint64_t)(constantVal)) >> 32)) >> 31; \ 51 uint64_t valP = (val < 0) ? -val : val; \ 52 const uint64_t conP = (constantVal < 0) ? -constantVal : constantVal; \ 53 uint64_t ret = cpuMathRecipAssistedUdiv64by64(valP, conP, U64_RECIPROCAL_CALCULATE(conP)); \ 54 if (neg) \ 55 ret =-ret; \ 56 ret; \ 57 }) 58 59 60 #endif 61 62