1 1.1 joerg /* ===-- udivmoddi4.c - Implement __udivmoddi4 -----------------------------=== 2 1.1 joerg * 3 1.1 joerg * The LLVM Compiler Infrastructure 4 1.1 joerg * 5 1.1 joerg * This file is dual licensed under the MIT and the University of Illinois Open 6 1.1 joerg * Source Licenses. See LICENSE.TXT for details. 7 1.1 joerg * 8 1.1 joerg * ===----------------------------------------------------------------------=== 9 1.1 joerg * 10 1.1 joerg * This file implements __udivmoddi4 for the compiler_rt library. 11 1.1 joerg * 12 1.1 joerg * ===----------------------------------------------------------------------=== 13 1.1 joerg */ 14 1.1 joerg 15 1.1 joerg #include "int_lib.h" 16 1.1 joerg 17 1.1 joerg /* Effects: if rem != 0, *rem = a % b 18 1.1 joerg * Returns: a / b 19 1.1 joerg */ 20 1.1 joerg 21 1.1 joerg /* Translated from Figure 3-40 of The PowerPC Compiler Writer's Guide */ 22 1.1 joerg 23 1.1 joerg COMPILER_RT_ABI du_int 24 1.1 joerg __udivmoddi4(du_int a, du_int b, du_int* rem) 25 1.1 joerg { 26 1.1 joerg const unsigned n_uword_bits = sizeof(su_int) * CHAR_BIT; 27 1.1 joerg const unsigned n_udword_bits = sizeof(du_int) * CHAR_BIT; 28 1.1 joerg udwords n; 29 1.1 joerg n.all = a; 30 1.1 joerg udwords d; 31 1.1 joerg d.all = b; 32 1.1 joerg udwords q; 33 1.1 joerg udwords r; 34 1.1 joerg unsigned sr; 35 1.1 joerg /* special cases, X is unknown, K != 0 */ 36 1.1 joerg if (n.s.high == 0) 37 1.1 joerg { 38 1.1 joerg if (d.s.high == 0) 39 1.1 joerg { 40 1.1 joerg /* 0 X 41 1.1 joerg * --- 42 1.1 joerg * 0 X 43 1.1 joerg */ 44 1.1 joerg if (rem) 45 1.1 joerg *rem = n.s.low % d.s.low; 46 1.1 joerg return n.s.low / d.s.low; 47 1.1 joerg } 48 1.1 joerg /* 0 X 49 1.1 joerg * --- 50 1.1 joerg * K X 51 1.1 joerg */ 52 1.1 joerg if (rem) 53 1.1 joerg *rem = n.s.low; 54 1.1 joerg return 0; 55 1.1 joerg } 56 1.1 joerg /* n.s.high != 0 */ 57 1.1 joerg if (d.s.low == 0) 58 1.1 joerg { 59 1.1 joerg if (d.s.high == 0) 60 1.1 joerg { 61 1.1 joerg /* K X 62 1.1 joerg * --- 63 1.1 joerg * 0 0 64 1.1 joerg */ 65 1.1 joerg if (rem) 66 1.1 joerg *rem = n.s.high % d.s.low; 67 1.1 joerg return n.s.high / d.s.low; 68 1.1 joerg } 69 1.1 joerg /* d.s.high != 0 */ 70 1.1 joerg if (n.s.low == 0) 71 1.1 joerg { 72 1.1 joerg /* K 0 73 1.1 joerg * --- 74 1.1 joerg * K 0 75 1.1 joerg */ 76 1.1 joerg if (rem) 77 1.1 joerg { 78 1.1 joerg r.s.high = n.s.high % d.s.high; 79 1.1 joerg r.s.low = 0; 80 1.1 joerg *rem = r.all; 81 1.1 joerg } 82 1.1 joerg return n.s.high / d.s.high; 83 1.1 joerg } 84 1.1 joerg /* K K 85 1.1 joerg * --- 86 1.1 joerg * K 0 87 1.1 joerg */ 88 1.1 joerg if ((d.s.high & (d.s.high - 1)) == 0) /* if d is a power of 2 */ 89 1.1 joerg { 90 1.1 joerg if (rem) 91 1.1 joerg { 92 1.1 joerg r.s.low = n.s.low; 93 1.1 joerg r.s.high = n.s.high & (d.s.high - 1); 94 1.1 joerg *rem = r.all; 95 1.1 joerg } 96 1.1 joerg return n.s.high >> __builtin_ctz(d.s.high); 97 1.1 joerg } 98 1.1 joerg /* K K 99 1.1 joerg * --- 100 1.1 joerg * K 0 101 1.1 joerg */ 102 1.1 joerg sr = __builtin_clz(d.s.high) - __builtin_clz(n.s.high); 103 1.1 joerg /* 0 <= sr <= n_uword_bits - 2 or sr large */ 104 1.1 joerg if (sr > n_uword_bits - 2) 105 1.1 joerg { 106 1.1 joerg if (rem) 107 1.1 joerg *rem = n.all; 108 1.1 joerg return 0; 109 1.1 joerg } 110 1.1 joerg ++sr; 111 1.1 joerg /* 1 <= sr <= n_uword_bits - 1 */ 112 1.1 joerg /* q.all = n.all << (n_udword_bits - sr); */ 113 1.1 joerg q.s.low = 0; 114 1.1 joerg q.s.high = n.s.low << (n_uword_bits - sr); 115 1.1 joerg /* r.all = n.all >> sr; */ 116 1.1 joerg r.s.high = n.s.high >> sr; 117 1.1 joerg r.s.low = (n.s.high << (n_uword_bits - sr)) | (n.s.low >> sr); 118 1.1 joerg } 119 1.1 joerg else /* d.s.low != 0 */ 120 1.1 joerg { 121 1.1 joerg if (d.s.high == 0) 122 1.1 joerg { 123 1.1 joerg /* K X 124 1.1 joerg * --- 125 1.1 joerg * 0 K 126 1.1 joerg */ 127 1.1 joerg if ((d.s.low & (d.s.low - 1)) == 0) /* if d is a power of 2 */ 128 1.1 joerg { 129 1.1 joerg if (rem) 130 1.1 joerg *rem = n.s.low & (d.s.low - 1); 131 1.1 joerg if (d.s.low == 1) 132 1.1 joerg return n.all; 133 1.1 joerg sr = __builtin_ctz(d.s.low); 134 1.1 joerg q.s.high = n.s.high >> sr; 135 1.1 joerg q.s.low = (n.s.high << (n_uword_bits - sr)) | (n.s.low >> sr); 136 1.1 joerg return q.all; 137 1.1 joerg } 138 1.1 joerg /* K X 139 1.1 joerg * --- 140 1.1.1.2 joerg * 0 K 141 1.1 joerg */ 142 1.1 joerg sr = 1 + n_uword_bits + __builtin_clz(d.s.low) - __builtin_clz(n.s.high); 143 1.1 joerg /* 2 <= sr <= n_udword_bits - 1 144 1.1 joerg * q.all = n.all << (n_udword_bits - sr); 145 1.1 joerg * r.all = n.all >> sr; 146 1.1 joerg */ 147 1.1.1.2 joerg if (sr == n_uword_bits) 148 1.1.1.2 joerg { 149 1.1.1.2 joerg q.s.low = 0; 150 1.1.1.2 joerg q.s.high = n.s.low; 151 1.1.1.2 joerg r.s.high = 0; 152 1.1.1.2 joerg r.s.low = n.s.high; 153 1.1.1.2 joerg } 154 1.1.1.2 joerg else if (sr < n_uword_bits) // 2 <= sr <= n_uword_bits - 1 155 1.1.1.2 joerg { 156 1.1.1.2 joerg q.s.low = 0; 157 1.1.1.2 joerg q.s.high = n.s.low << (n_uword_bits - sr); 158 1.1.1.2 joerg r.s.high = n.s.high >> sr; 159 1.1.1.2 joerg r.s.low = (n.s.high << (n_uword_bits - sr)) | (n.s.low >> sr); 160 1.1.1.2 joerg } 161 1.1.1.2 joerg else // n_uword_bits + 1 <= sr <= n_udword_bits - 1 162 1.1.1.2 joerg { 163 1.1.1.2 joerg q.s.low = n.s.low << (n_udword_bits - sr); 164 1.1.1.2 joerg q.s.high = (n.s.high << (n_udword_bits - sr)) | 165 1.1.1.2 joerg (n.s.low >> (sr - n_uword_bits)); 166 1.1.1.2 joerg r.s.high = 0; 167 1.1.1.2 joerg r.s.low = n.s.high >> (sr - n_uword_bits); 168 1.1.1.2 joerg } 169 1.1 joerg } 170 1.1 joerg else 171 1.1 joerg { 172 1.1 joerg /* K X 173 1.1 joerg * --- 174 1.1 joerg * K K 175 1.1 joerg */ 176 1.1 joerg sr = __builtin_clz(d.s.high) - __builtin_clz(n.s.high); 177 1.1 joerg /* 0 <= sr <= n_uword_bits - 1 or sr large */ 178 1.1 joerg if (sr > n_uword_bits - 1) 179 1.1 joerg { 180 1.1.1.2 joerg if (rem) 181 1.1 joerg *rem = n.all; 182 1.1 joerg return 0; 183 1.1 joerg } 184 1.1 joerg ++sr; 185 1.1 joerg /* 1 <= sr <= n_uword_bits */ 186 1.1 joerg /* q.all = n.all << (n_udword_bits - sr); */ 187 1.1 joerg q.s.low = 0; 188 1.1.1.2 joerg if (sr == n_uword_bits) 189 1.1.1.2 joerg { 190 1.1.1.2 joerg q.s.high = n.s.low; 191 1.1.1.2 joerg r.s.high = 0; 192 1.1.1.2 joerg r.s.low = n.s.high; 193 1.1.1.2 joerg } 194 1.1.1.2 joerg else 195 1.1.1.2 joerg { 196 1.1.1.2 joerg q.s.high = n.s.low << (n_uword_bits - sr); 197 1.1.1.2 joerg r.s.high = n.s.high >> sr; 198 1.1.1.2 joerg r.s.low = (n.s.high << (n_uword_bits - sr)) | (n.s.low >> sr); 199 1.1.1.2 joerg } 200 1.1 joerg } 201 1.1 joerg } 202 1.1 joerg /* Not a special case 203 1.1 joerg * q and r are initialized with: 204 1.1 joerg * q.all = n.all << (n_udword_bits - sr); 205 1.1 joerg * r.all = n.all >> sr; 206 1.1 joerg * 1 <= sr <= n_udword_bits - 1 207 1.1 joerg */ 208 1.1 joerg su_int carry = 0; 209 1.1 joerg for (; sr > 0; --sr) 210 1.1 joerg { 211 1.1 joerg /* r:q = ((r:q) << 1) | carry */ 212 1.1 joerg r.s.high = (r.s.high << 1) | (r.s.low >> (n_uword_bits - 1)); 213 1.1 joerg r.s.low = (r.s.low << 1) | (q.s.high >> (n_uword_bits - 1)); 214 1.1 joerg q.s.high = (q.s.high << 1) | (q.s.low >> (n_uword_bits - 1)); 215 1.1 joerg q.s.low = (q.s.low << 1) | carry; 216 1.1 joerg /* carry = 0; 217 1.1 joerg * if (r.all >= d.all) 218 1.1 joerg * { 219 1.1 joerg * r.all -= d.all; 220 1.1 joerg * carry = 1; 221 1.1 joerg * } 222 1.1 joerg */ 223 1.1 joerg const di_int s = (di_int)(d.all - r.all - 1) >> (n_udword_bits - 1); 224 1.1 joerg carry = s & 1; 225 1.1 joerg r.all -= d.all & s; 226 1.1 joerg } 227 1.1 joerg q.all = (q.all << 1) | carry; 228 1.1 joerg if (rem) 229 1.1 joerg *rem = r.all; 230 1.1 joerg return q.all; 231 1.1 joerg } 232