si_div.c (1240B)
1 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 2 // 3 // 32-bit integer division helpers required by compiler-rt routines even on 4 // LP64 targets where normal C int division is otherwise a single instruction. 5 6 #include "int_lib.h" 7 8 COMPILER_RT_ABI su_int __udivsi3(su_int n, su_int d) { 9 const unsigned bits = sizeof(su_int) * CHAR_BIT; 10 su_int q = 0; 11 su_int r = 0; 12 for (unsigned i = bits; i > 0; --i) { 13 r = (su_int)((r << 1) | ((n >> (i - 1u)) & 1u)); 14 if (r >= d) { 15 r = (su_int)(r - d); 16 q |= (su_int)1u << (i - 1u); 17 } 18 } 19 return q; 20 } 21 22 COMPILER_RT_ABI su_int __udivmodsi4(su_int n, su_int d, su_int* rem) { 23 const unsigned bits = sizeof(su_int) * CHAR_BIT; 24 su_int q = 0; 25 su_int r = 0; 26 for (unsigned i = bits; i > 0; --i) { 27 r = (su_int)((r << 1) | ((n >> (i - 1u)) & 1u)); 28 if (r >= d) { 29 r = (su_int)(r - d); 30 q |= (su_int)1u << (i - 1u); 31 } 32 } 33 if (rem) *rem = r; 34 return q; 35 } 36 37 COMPILER_RT_ABI si_int __divsi3(si_int a, si_int b) { 38 su_int sa = (su_int)(a >> 31); 39 su_int sb = (su_int)(b >> 31); 40 su_int ua = ((su_int)a ^ sa) - sa; 41 su_int ub = ((su_int)b ^ sb) - sb; 42 su_int sign = sa ^ sb; 43 su_int q = __udivsi3(ua, ub); 44 return (si_int)((q ^ sign) - sign); 45 }