137a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan/* ===-- udivmoddi4.c - Implement __udivmoddi4 -----------------------------=== 237a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * 337a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * The LLVM Compiler Infrastructure 437a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * 59ad441ffec97db647fee3725b3424284fb913e14Howard Hinnant * This file is dual licensed under the MIT and the University of Illinois Open 69ad441ffec97db647fee3725b3424284fb913e14Howard Hinnant * Source Licenses. See LICENSE.TXT for details. 737a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * 837a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * ===----------------------------------------------------------------------=== 937a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * 1037a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * This file implements __udivmoddi4 for the compiler_rt library. 1137a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * 1237a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * ===----------------------------------------------------------------------=== 1337a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan */ 14b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 15b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar#include "int_lib.h" 16b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 1737a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan/* Effects: if rem != 0, *rem = a % b 1837a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * Returns: a / b 1937a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan */ 20b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 2137a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan/* Translated from Figure 3-40 of The PowerPC Compiler Writer's Guide */ 22b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 231c5f89b1dd741135a4007ab577723d422f421eecAnton KorobeynikovCOMPILER_RT_ABI du_int 24b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar__udivmoddi4(du_int a, du_int b, du_int* rem) 25b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar{ 26b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar const unsigned n_uword_bits = sizeof(su_int) * CHAR_BIT; 27b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar const unsigned n_udword_bits = sizeof(du_int) * CHAR_BIT; 28b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar udwords n; 29b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar n.all = a; 30b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar udwords d; 31b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar d.all = b; 32b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar udwords q; 33b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar udwords r; 34b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar unsigned sr; 3537a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan /* special cases, X is unknown, K != 0 */ 368bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan if (n.s.high == 0) 37b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar { 388bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan if (d.s.high == 0) 39b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar { 4037a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan /* 0 X 4137a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * --- 4237a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * 0 X 4337a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan */ 44b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar if (rem) 458bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan *rem = n.s.low % d.s.low; 468bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan return n.s.low / d.s.low; 47b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar } 4837a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan /* 0 X 4937a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * --- 5037a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * K X 5137a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan */ 52b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar if (rem) 538bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan *rem = n.s.low; 54b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar return 0; 55b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar } 568bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan /* n.s.high != 0 */ 578bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan if (d.s.low == 0) 58b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar { 598bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan if (d.s.high == 0) 60b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar { 6137a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan /* K X 6237a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * --- 6337a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * 0 0 6437a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan */ 65b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar if (rem) 668bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan *rem = n.s.high % d.s.low; 678bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan return n.s.high / d.s.low; 68b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar } 698bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan /* d.s.high != 0 */ 708bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan if (n.s.low == 0) 71b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar { 7237a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan /* K 0 7337a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * --- 7437a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * K 0 7537a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan */ 76b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar if (rem) 77b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar { 788bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan r.s.high = n.s.high % d.s.high; 798bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan r.s.low = 0; 80b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar *rem = r.all; 81b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar } 828bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan return n.s.high / d.s.high; 83b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar } 8437a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan /* K K 8537a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * --- 8637a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * K 0 8737a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan */ 888bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan if ((d.s.high & (d.s.high - 1)) == 0) /* if d is a power of 2 */ 89b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar { 90b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar if (rem) 91b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar { 928bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan r.s.low = n.s.low; 938bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan r.s.high = n.s.high & (d.s.high - 1); 94b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar *rem = r.all; 95b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar } 968bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan return n.s.high >> __builtin_ctz(d.s.high); 97b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar } 9837a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan /* K K 9937a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * --- 10037a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * K 0 10137a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan */ 1028bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan sr = __builtin_clz(d.s.high) - __builtin_clz(n.s.high); 10337a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan /* 0 <= sr <= n_uword_bits - 2 or sr large */ 104b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar if (sr > n_uword_bits - 2) 105b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar { 106b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar if (rem) 107b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar *rem = n.all; 108b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar return 0; 109b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar } 110b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar ++sr; 11137a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan /* 1 <= sr <= n_uword_bits - 1 */ 11237a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan /* q.all = n.all << (n_udword_bits - sr); */ 1138bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan q.s.low = 0; 1148bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan q.s.high = n.s.low << (n_uword_bits - sr); 11537a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan /* r.all = n.all >> sr; */ 1168bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan r.s.high = n.s.high >> sr; 1178bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan r.s.low = (n.s.high << (n_uword_bits - sr)) | (n.s.low >> sr); 118b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar } 1198bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan else /* d.s.low != 0 */ 120b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar { 1218bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan if (d.s.high == 0) 122b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar { 12337a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan /* K X 12437a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * --- 12537a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * 0 K 12637a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan */ 1278bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan if ((d.s.low & (d.s.low - 1)) == 0) /* if d is a power of 2 */ 128b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar { 129b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar if (rem) 1308bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan *rem = n.s.low & (d.s.low - 1); 1318bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan if (d.s.low == 1) 132b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar return n.all; 133d426091fdf6a15db9a5db35d522fe69f5dee35afJoerg Sonnenberger sr = __builtin_ctz(d.s.low); 1348bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan q.s.high = n.s.high >> sr; 1358bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan q.s.low = (n.s.high << (n_uword_bits - sr)) | (n.s.low >> sr); 136b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar return q.all; 137b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar } 13837a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan /* K X 13937a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * --- 1402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines * 0 K 14137a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan */ 1428bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan sr = 1 + n_uword_bits + __builtin_clz(d.s.low) - __builtin_clz(n.s.high); 14337a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan /* 2 <= sr <= n_udword_bits - 1 14437a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * q.all = n.all << (n_udword_bits - sr); 14537a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * r.all = n.all >> sr; 14637a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan */ 1472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines if (sr == n_uword_bits) 1482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines { 1492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines q.s.low = 0; 1502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines q.s.high = n.s.low; 1512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines r.s.high = 0; 1522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines r.s.low = n.s.high; 1532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines } 1542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines else if (sr < n_uword_bits) // 2 <= sr <= n_uword_bits - 1 1552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines { 1562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines q.s.low = 0; 1572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines q.s.high = n.s.low << (n_uword_bits - sr); 1582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines r.s.high = n.s.high >> sr; 1592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines r.s.low = (n.s.high << (n_uword_bits - sr)) | (n.s.low >> sr); 1602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines } 1612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines else // n_uword_bits + 1 <= sr <= n_udword_bits - 1 1622d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines { 1632d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines q.s.low = n.s.low << (n_udword_bits - sr); 1642d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines q.s.high = (n.s.high << (n_udword_bits - sr)) | 1652d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines (n.s.low >> (sr - n_uword_bits)); 1662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines r.s.high = 0; 1672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines r.s.low = n.s.high >> (sr - n_uword_bits); 1682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines } 169b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar } 170b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar else 171b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar { 17237a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan /* K X 17337a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * --- 17437a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * K K 17537a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan */ 1768bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan sr = __builtin_clz(d.s.high) - __builtin_clz(n.s.high); 17737a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan /* 0 <= sr <= n_uword_bits - 1 or sr large */ 178b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar if (sr > n_uword_bits - 1) 179b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar { 1802d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines if (rem) 181b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar *rem = n.all; 182b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar return 0; 183b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar } 184b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar ++sr; 18537a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan /* 1 <= sr <= n_uword_bits */ 18637a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan /* q.all = n.all << (n_udword_bits - sr); */ 1878bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan q.s.low = 0; 1882d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines if (sr == n_uword_bits) 1892d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines { 1902d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines q.s.high = n.s.low; 1912d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines r.s.high = 0; 1922d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines r.s.low = n.s.high; 1932d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines } 1942d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines else 1952d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines { 1962d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines q.s.high = n.s.low << (n_uword_bits - sr); 1972d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines r.s.high = n.s.high >> sr; 1982d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines r.s.low = (n.s.high << (n_uword_bits - sr)) | (n.s.low >> sr); 1992d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines } 200b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar } 201b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar } 20237a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan /* Not a special case 20337a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * q and r are initialized with: 20437a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * q.all = n.all << (n_udword_bits - sr); 20537a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * r.all = n.all >> sr; 20637a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * 1 <= sr <= n_udword_bits - 1 20737a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan */ 208b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar su_int carry = 0; 209b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar for (; sr > 0; --sr) 210b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar { 21137a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan /* r:q = ((r:q) << 1) | carry */ 2128bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan r.s.high = (r.s.high << 1) | (r.s.low >> (n_uword_bits - 1)); 2138bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan r.s.low = (r.s.low << 1) | (q.s.high >> (n_uword_bits - 1)); 2148bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan q.s.high = (q.s.high << 1) | (q.s.low >> (n_uword_bits - 1)); 2158bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan q.s.low = (q.s.low << 1) | carry; 21637a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan /* carry = 0; 21737a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * if (r.all >= d.all) 21837a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * { 21937a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * r.all -= d.all; 22037a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * carry = 1; 22137a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * } 22237a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan */ 223b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar const di_int s = (di_int)(d.all - r.all - 1) >> (n_udword_bits - 1); 224b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar carry = s & 1; 225b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar r.all -= d.all & s; 226b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar } 227b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar q.all = (q.all << 1) | carry; 228b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar if (rem) 229b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar *rem = r.all; 230b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar return q.all; 231b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar} 232