Line data Source code
1 : /* 2 : return 64 bit x / 1000 3 : faster than the normal gcc implementation using by about 3x 4 : With thanks to https://0x414b.com/2021/04/16/arm-division.html 5 : and https://stackoverflow.com/questions/74765410/multiply-two-uint64-ts-and-store-result-to-uint64-t-doesnt-seem-to-work 6 : */ 7 13358072142 : static inline uint64_t uint64_div1000(uint64_t x) 8 : { 9 13358072142 : x >>= 3U; 10 13358072142 : uint64_t a_lo = (uint32_t)x; 11 13358072142 : uint64_t a_hi = x >> 32; 12 13358072142 : const uint64_t b_lo = 0xe353f7cfU; 13 13358072142 : const uint64_t b_hi = 0x20c49ba5U; 14 : 15 13358072142 : uint64_t a_x_b_hi = a_hi * b_hi; 16 13358072142 : uint64_t a_x_b_mid = a_hi * b_lo; 17 13358072142 : uint64_t b_x_a_mid = b_hi * a_lo; 18 13358072142 : uint32_t a_x_b_lo = (a_lo * b_lo)>>32; 19 : 20 : // 64-bit product + two 32-bit values 21 13358072142 : uint64_t middle = a_x_b_mid + a_x_b_lo + (uint32_t)b_x_a_mid; 22 : 23 : // 64-bit product + two 32-bit values 24 13358072142 : uint64_t r = a_x_b_hi + (middle >> 32) + (b_x_a_mid >> 32); 25 13358072142 : return r >> 4U; 26 : }