137a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan/* ===-- udivmodti4.c - Implement __udivmodti4 -----------------------------===
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 __udivmodti4 for the compiler_rt library.
1137a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan *
1237a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * ===----------------------------------------------------------------------===
1337a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan */
14b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
15b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar#include "int_lib.h"
16b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
177f2d7c75e713d778106d01a54e7aef40227bbf2dChandler Carruth#if __x86_64
187f2d7c75e713d778106d01a54e7aef40227bbf2dChandler Carruth
1937a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan/* Effects: if rem != 0, *rem = a % b
2037a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan * Returns: a / b
2137a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan */
22b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
2337a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan/* Translated from Figure 3-40 of The PowerPC Compiler Writer's Guide */
24b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
25b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbartu_int
26b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar__udivmodti4(tu_int a, tu_int b, tu_int* rem)
27b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar{
28b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    const unsigned n_udword_bits = sizeof(du_int) * CHAR_BIT;
29b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    const unsigned n_utword_bits = sizeof(tu_int) * CHAR_BIT;
30b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    utwords n;
31b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    n.all = a;
32b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    utwords d;
33b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    d.all = b;
34b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    utwords q;
35b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    utwords r;
36b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    unsigned sr;
3737a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan    /* special cases, X is unknown, K != 0 */
388bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan    if (n.s.high == 0)
39b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    {
408bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan        if (d.s.high == 0)
41b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar        {
4237a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan            /* 0 X
4337a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan             * ---
4437a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan             * 0 X
4537a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan             */
46b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar            if (rem)
478bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan                *rem = n.s.low % d.s.low;
488bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan            return n.s.low / d.s.low;
49b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar        }
5037a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan        /* 0 X
5137a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan         * ---
5237a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan         * K X
5337a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan         */
54b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar        if (rem)
558bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan            *rem = n.s.low;
56b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar        return 0;
57b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    }
588bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan    /* n.s.high != 0 */
598bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan    if (d.s.low == 0)
60b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    {
618bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan        if (d.s.high == 0)
62b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar        {
6337a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan            /* K X
6437a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan             * ---
6537a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan             * 0 0
6637a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan             */
67b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar            if (rem)
688bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan                *rem = n.s.high % d.s.low;
698bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan            return n.s.high / d.s.low;
70b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar        }
718bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan        /* d.s.high != 0 */
728bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan        if (n.s.low == 0)
73b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar        {
7437a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan            /* K 0
7537a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan             * ---
7637a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan             * K 0
7737a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan             */
78b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar            if (rem)
79b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar            {
808bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan                r.s.high = n.s.high % d.s.high;
818bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan                r.s.low = 0;
82b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar                *rem = r.all;
83b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar            }
848bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan            return n.s.high / d.s.high;
85b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar        }
8637a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan        /* K K
8737a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan         * ---
8837a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan         * K 0
8937a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan         */
908bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan        if ((d.s.high & (d.s.high - 1)) == 0)     /* if d is a power of 2 */
91b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar        {
92b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar            if (rem)
93b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar            {
948bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan                r.s.low = n.s.low;
958bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan                r.s.high = n.s.high & (d.s.high - 1);
96b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar                *rem = r.all;
97b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar            }
988bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan            return n.s.high >> __builtin_ctzll(d.s.high);
99b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar        }
10037a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan        /* K K
10137a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan         * ---
10237a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan         * K 0
10337a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan         */
1048bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan        sr = __builtin_clzll(d.s.high) - __builtin_clzll(n.s.high);
10537a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan        /* 0 <= sr <= n_udword_bits - 2 or sr large */
106b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar        if (sr > n_udword_bits - 2)
107b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar        {
108b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar           if (rem)
109b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar                *rem = n.all;
110b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar            return 0;
111b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar        }
112b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar        ++sr;
11337a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan        /* 1 <= sr <= n_udword_bits - 1 */
11437a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan        /* q.all = n.all << (n_utword_bits - sr); */
1158bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan        q.s.low = 0;
1168bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan        q.s.high = n.s.low << (n_udword_bits - sr);
11737a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan        /* r.all = n.all >> sr; */
1188bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan        r.s.high = n.s.high >> sr;
1198bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan        r.s.low = (n.s.high << (n_udword_bits - sr)) | (n.s.low >> sr);
120b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    }
1218bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan    else  /* d.s.low != 0 */
122b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    {
1238bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan        if (d.s.high == 0)
124b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar        {
12537a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan            /* K X
12637a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan             * ---
12737a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan             * 0 K
12837a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan             */
1298bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan            if ((d.s.low & (d.s.low - 1)) == 0)     /* if d is a power of 2 */
130b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar            {
131b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar                if (rem)
1328bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan                    *rem = n.s.low & (d.s.low - 1);
1338bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan                if (d.s.low == 1)
134b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar                    return n.all;
1354fcc9aacd048741a4934f044a295d1ccf73a0173Joerg Sonnenberger                sr = __builtin_ctzll(d.s.low);
1368bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan                q.s.high = n.s.high >> sr;
1378bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan                q.s.low = (n.s.high << (n_udword_bits - sr)) | (n.s.low >> sr);
138b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar                return q.all;
139b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar            }
14037a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan            /* K X
14137a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan             * ---
14237a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan             * 0 K
14337a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan             */
1448bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan            sr = 1 + n_udword_bits + __builtin_clzll(d.s.low)
1458bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan                                   - __builtin_clzll(n.s.high);
14637a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan            /* 2 <= sr <= n_utword_bits - 1
14737a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan             * q.all = n.all << (n_utword_bits - sr);
14837a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan             * r.all = n.all >> sr;
14937a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan             * if (sr == n_udword_bits)
15037a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan             * {
1518bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan             *     q.s.low = 0;
1528bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan             *     q.s.high = n.s.low;
1538bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan             *     r.s.high = 0;
1548bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan             *     r.s.low = n.s.high;
15537a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan             * }
15637a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan             * else if (sr < n_udword_bits)  // 2 <= sr <= n_udword_bits - 1
15737a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan             * {
1588bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan             *     q.s.low = 0;
1598bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan             *     q.s.high = n.s.low << (n_udword_bits - sr);
1608bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan             *     r.s.high = n.s.high >> sr;
1618bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan             *     r.s.low = (n.s.high << (n_udword_bits - sr)) | (n.s.low >> sr);
16237a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan             * }
16337a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan             * else              // n_udword_bits + 1 <= sr <= n_utword_bits - 1
16437a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan             * {
1658bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan             *     q.s.low = n.s.low << (n_utword_bits - sr);
1668bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan             *     q.s.high = (n.s.high << (n_utword_bits - sr)) |
1678bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan             *              (n.s.low >> (sr - n_udword_bits));
1688bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan             *     r.s.high = 0;
1698bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan             *     r.s.low = n.s.high >> (sr - n_udword_bits);
17037a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan             * }
17137a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan             */
1728bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan            q.s.low =  (n.s.low << (n_utword_bits - sr)) &
173b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar                     ((di_int)(int)(n_udword_bits - sr) >> (n_udword_bits-1));
1748bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan            q.s.high = ((n.s.low << ( n_udword_bits - sr))                        &
175b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar                     ((di_int)(int)(sr - n_udword_bits - 1) >> (n_udword_bits-1))) |
1768bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan                     (((n.s.high << (n_utword_bits - sr))                       |
1778bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan                     (n.s.low >> (sr - n_udword_bits)))                         &
178b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar                     ((di_int)(int)(n_udword_bits - sr) >> (n_udword_bits-1)));
1798bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan            r.s.high = (n.s.high >> sr) &
180b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar                     ((di_int)(int)(sr - n_udword_bits) >> (n_udword_bits-1));
1818bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan            r.s.low =  ((n.s.high >> (sr - n_udword_bits))                        &
182b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar                     ((di_int)(int)(n_udword_bits - sr - 1) >> (n_udword_bits-1))) |
1838bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan                     (((n.s.high << (n_udword_bits - sr))                       |
1848bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan                     (n.s.low >> sr))                                           &
185b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar                     ((di_int)(int)(sr - n_udword_bits) >> (n_udword_bits-1)));
186b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar        }
187b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar        else
188b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar        {
18937a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan            /* K X
19037a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan             * ---
19137a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan             * K K
19237a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan             */
1938bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan            sr = __builtin_clzll(d.s.high) - __builtin_clzll(n.s.high);
19437a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan            /*0 <= sr <= n_udword_bits - 1 or sr large */
195b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar            if (sr > n_udword_bits - 1)
196b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar            {
197b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar               if (rem)
198b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar                    *rem = n.all;
199b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar                return 0;
200b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar            }
201b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar            ++sr;
20237a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan            /* 1 <= sr <= n_udword_bits */
20337a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan            /* q.all = n.all << (n_utword_bits - sr); */
2048bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan            q.s.low = 0;
2058bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan            q.s.high = n.s.low << (n_udword_bits - sr);
20637a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan            /* r.all = n.all >> sr;
20737a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan             * if (sr < n_udword_bits)
20837a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan             * {
2098bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan             *     r.s.high = n.s.high >> sr;
2108bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan             *     r.s.low = (n.s.high << (n_udword_bits - sr)) | (n.s.low >> sr);
21137a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan             * }
21237a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan             * else
21337a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan             * {
2148bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan             *     r.s.high = 0;
2158bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan             *     r.s.low = n.s.high;
21637a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan             * }
21737a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan             */
2188bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan            r.s.high = (n.s.high >> sr) &
219b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar                     ((di_int)(int)(sr - n_udword_bits) >> (n_udword_bits-1));
2208bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan            r.s.low = (n.s.high << (n_udword_bits - sr)) |
2218bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan                    ((n.s.low >> sr)                   &
222b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar                    ((di_int)(int)(sr - n_udword_bits) >> (n_udword_bits-1)));
223b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar        }
224b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    }
22537a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan    /* Not a special case
22637a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan     * q and r are initialized with:
22737a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan     * q.all = n.all << (n_utword_bits - sr);
22837a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan     * r.all = n.all >> sr;
22937a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan     * 1 <= sr <= n_utword_bits - 1
23037a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan     */
231b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    su_int carry = 0;
232b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    for (; sr > 0; --sr)
233b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    {
23437a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan        /* r:q = ((r:q)  << 1) | carry */
2358bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan        r.s.high = (r.s.high << 1) | (r.s.low  >> (n_udword_bits - 1));
2368bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan        r.s.low  = (r.s.low  << 1) | (q.s.high >> (n_udword_bits - 1));
2378bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan        q.s.high = (q.s.high << 1) | (q.s.low  >> (n_udword_bits - 1));
2388bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan        q.s.low  = (q.s.low  << 1) | carry;
23937a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan        /* carry = 0;
24037a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan         * if (r.all >= d.all)
24137a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan         * {
24237a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan         *     r.all -= d.all;
24337a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan         *      carry = 1;
24437a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan         * }
24537a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan         */
246b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar        const ti_int s = (ti_int)(d.all - r.all - 1) >> (n_utword_bits - 1);
247b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar        carry = s & 1;
248b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar        r.all -= d.all & s;
249b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    }
250b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    q.all = (q.all << 1) | carry;
251b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    if (rem)
252b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar        *rem = r.all;
253b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    return q.all;
254b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar}
255b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
2568bf1e094893cb24796137b47ee0d46d18d299996Edward O'Callaghan#endif /* __x86_64 */
257