1156cd587Sjoerg /* ===-- udivsi3.c - Implement __udivsi3 -----------------------------------=== 2156cd587Sjoerg * 3156cd587Sjoerg * The LLVM Compiler Infrastructure 4156cd587Sjoerg * 5156cd587Sjoerg * This file is dual licensed under the MIT and the University of Illinois Open 6156cd587Sjoerg * Source Licenses. See LICENSE.TXT for details. 7156cd587Sjoerg * 8156cd587Sjoerg * ===----------------------------------------------------------------------=== 9156cd587Sjoerg * 10156cd587Sjoerg * This file implements __udivsi3 for the compiler_rt library. 11156cd587Sjoerg * 12156cd587Sjoerg * ===----------------------------------------------------------------------=== 13156cd587Sjoerg */ 14156cd587Sjoerg 15156cd587Sjoerg #include "int_lib.h" 16156cd587Sjoerg 17156cd587Sjoerg /* Returns: a / b */ 18156cd587Sjoerg 19156cd587Sjoerg /* Translated from Figure 3-40 of The PowerPC Compiler Writer's Guide */ 20156cd587Sjoerg 21156cd587Sjoerg /* This function should not call __divsi3! */ 22156cd587Sjoerg COMPILER_RT_ABI su_int __udivsi3(su_int n,su_int d)23156cd587Sjoerg__udivsi3(su_int n, su_int d) 24156cd587Sjoerg { 25156cd587Sjoerg const unsigned n_uword_bits = sizeof(su_int) * CHAR_BIT; 26156cd587Sjoerg su_int q; 27156cd587Sjoerg su_int r; 28156cd587Sjoerg unsigned sr; 29156cd587Sjoerg /* special cases */ 30156cd587Sjoerg if (d == 0) 31156cd587Sjoerg return 0; /* ?! */ 32156cd587Sjoerg if (n == 0) 33156cd587Sjoerg return 0; 34156cd587Sjoerg sr = __builtin_clz(d) - __builtin_clz(n); 35156cd587Sjoerg /* 0 <= sr <= n_uword_bits - 1 or sr large */ 36156cd587Sjoerg if (sr > n_uword_bits - 1) /* d > r */ 37156cd587Sjoerg return 0; 38156cd587Sjoerg if (sr == n_uword_bits - 1) /* d == 1 */ 39156cd587Sjoerg return n; 40156cd587Sjoerg ++sr; 41156cd587Sjoerg /* 1 <= sr <= n_uword_bits - 1 */ 42156cd587Sjoerg /* Not a special case */ 43156cd587Sjoerg q = n << (n_uword_bits - sr); 44156cd587Sjoerg r = n >> sr; 45156cd587Sjoerg su_int carry = 0; 46156cd587Sjoerg for (; sr > 0; --sr) 47156cd587Sjoerg { 48156cd587Sjoerg /* r:q = ((r:q) << 1) | carry */ 49156cd587Sjoerg r = (r << 1) | (q >> (n_uword_bits - 1)); 50156cd587Sjoerg q = (q << 1) | carry; 51156cd587Sjoerg /* carry = 0; 52156cd587Sjoerg * if (r.all >= d.all) 53156cd587Sjoerg * { 54156cd587Sjoerg * r.all -= d.all; 55156cd587Sjoerg * carry = 1; 56156cd587Sjoerg * } 57156cd587Sjoerg */ 58156cd587Sjoerg const si_int s = (si_int)(d - r - 1) >> (n_uword_bits - 1); 59156cd587Sjoerg carry = s & 1; 60156cd587Sjoerg r -= d & s; 61156cd587Sjoerg } 62156cd587Sjoerg q = (q << 1) | carry; 63156cd587Sjoerg return q; 64156cd587Sjoerg } 653044ee7eSrin 663044ee7eSrin #if defined(__ARM_EABI__) 67*d3143459Srin AEABI_RTABI su_int __aeabi_uidiv(su_int n, su_int d) COMPILER_RT_ALIAS(__udivsi3); 683044ee7eSrin #endif 69