uboot/arch/arc/lib/libgcc2.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (C) 1989-2013 Free Software Foundation, Inc.
   4 */
   5
   6#include "libgcc2.h"
   7
   8DWtype
   9__ashldi3(DWtype u, shift_count_type b)
  10{
  11        if (b == 0)
  12                return u;
  13
  14        const DWunion uu = {.ll = u};
  15        const shift_count_type bm = W_TYPE_SIZE - b;
  16        DWunion w;
  17
  18        if (bm <= 0) {
  19                w.s.low = 0;
  20                w.s.high = (UWtype)uu.s.low << -bm;
  21        } else {
  22                const UWtype carries = (UWtype) uu.s.low >> bm;
  23
  24                w.s.low = (UWtype)uu.s.low << b;
  25                w.s.high = ((UWtype)uu.s.high << b) | carries;
  26        }
  27
  28        return w.ll;
  29}
  30
  31DWtype
  32__ashrdi3(DWtype u, shift_count_type b)
  33{
  34        if (b == 0)
  35                return u;
  36
  37        const DWunion uu = {.ll = u};
  38        const shift_count_type bm = W_TYPE_SIZE - b;
  39        DWunion w;
  40
  41        if (bm <= 0) {
  42                /* w.s.high = 1..1 or 0..0 */
  43                w.s.high = uu.s.high >> (W_TYPE_SIZE - 1);
  44                w.s.low = uu.s.high >> -bm;
  45        } else {
  46                const UWtype carries = (UWtype) uu.s.high << bm;
  47
  48                w.s.high = uu.s.high >> b;
  49                w.s.low = ((UWtype)uu.s.low >> b) | carries;
  50        }
  51
  52        return w.ll;
  53}
  54
  55DWtype
  56__lshrdi3(DWtype u, shift_count_type b)
  57{
  58        if (b == 0)
  59                return u;
  60
  61        const DWunion uu = {.ll = u};
  62        const shift_count_type bm = W_TYPE_SIZE - b;
  63        DWunion w;
  64
  65        if (bm <= 0) {
  66                w.s.high = 0;
  67                w.s.low = (UWtype)uu.s.high >> -bm;
  68        } else {
  69                const UWtype carries = (UWtype)uu.s.high << bm;
  70
  71                w.s.high = (UWtype)uu.s.high >> b;
  72                w.s.low = ((UWtype)uu.s.low >> b) | carries;
  73        }
  74
  75        return w.ll;
  76}
  77
  78unsigned long
  79udivmodsi4(unsigned long num, unsigned long den, int modwanted)
  80{
  81        unsigned long bit = 1;
  82        unsigned long res = 0;
  83
  84        while (den < num && bit && !(den & (1L<<31))) {
  85                den <<= 1;
  86                bit <<= 1;
  87        }
  88
  89        while (bit) {
  90                if (num >= den) {
  91                        num -= den;
  92                        res |= bit;
  93                }
  94                bit >>= 1;
  95                den >>= 1;
  96        }
  97
  98        if (modwanted)
  99                return num;
 100
 101        return res;
 102}
 103
 104long
 105__divsi3(long a, long b)
 106{
 107        int neg = 0;
 108        long res;
 109
 110        if (a < 0) {
 111                a = -a;
 112                neg = !neg;
 113        }
 114
 115        if (b < 0) {
 116                b = -b;
 117                neg = !neg;
 118        }
 119
 120        res = udivmodsi4(a, b, 0);
 121
 122        if (neg)
 123                res = -res;
 124
 125        return res;
 126}
 127
 128long
 129__modsi3(long a, long b)
 130{
 131        int neg = 0;
 132        long res;
 133
 134        if (a < 0) {
 135                a = -a;
 136                neg = 1;
 137        }
 138
 139        if (b < 0)
 140                b = -b;
 141
 142        res = udivmodsi4(a, b, 1);
 143
 144        if (neg)
 145                res = -res;
 146
 147        return res;
 148}
 149
 150long
 151__udivsi3(long a, long b)
 152{
 153        return udivmodsi4(a, b, 0);
 154}
 155
 156long
 157__umodsi3(long a, long b)
 158{
 159        return udivmodsi4(a, b, 1);
 160}
 161
 162UDWtype
 163__udivmoddi4(UDWtype n, UDWtype d, UDWtype *rp)
 164{
 165        UDWtype q = 0, r = n, y = d;
 166        UWtype lz1, lz2, i, k;
 167
 168        /*
 169         * Implements align divisor shift dividend method. This algorithm
 170         * aligns the divisor under the dividend and then perform number of
 171         * test-subtract iterations which shift the dividend left. Number of
 172         * iterations is k + 1 where k is the number of bit positions the
 173         * divisor must be shifted left  to align it under the dividend.
 174         * quotient bits can be saved in the rightmost positions of the
 175         * dividend as it shifts left on each test-subtract iteration.
 176         */
 177
 178        if (y <= r) {
 179                lz1 = __builtin_clzll(d);
 180                lz2 = __builtin_clzll(n);
 181
 182                k = lz1 - lz2;
 183                y = (y << k);
 184
 185                /*
 186                 * Dividend can exceed 2 ^ (width - 1) - 1 but still be less
 187                 * than the aligned divisor. Normal iteration can drops the
 188                 * high order bit of the dividend. Therefore, first
 189                 * test-subtract iteration is a special case, saving its
 190                 * quotient bit in a separate location and not shifting
 191                 * the dividend.
 192                 */
 193
 194                if (r >= y) {
 195                        r = r - y;
 196                        q = (1ULL << k);
 197                }
 198
 199                if (k > 0) {
 200                        y = y >> 1;
 201
 202                        /*
 203                         * k additional iterations where k regular test
 204                         * subtract shift dividend iterations are done.
 205                         */
 206                        i = k;
 207                        do {
 208                                if (r >= y)
 209                                        r = ((r - y) << 1) + 1;
 210                                else
 211                                        r = (r << 1);
 212                                i = i - 1;
 213                        } while (i != 0);
 214
 215                        /*
 216                         * First quotient bit is combined with the quotient
 217                         * bits resulting from the k regular iterations.
 218                         */
 219                        q = q + r;
 220                        r = r >> k;
 221                        q = q - (r << k);
 222                }
 223        }
 224
 225        if (rp)
 226                *rp = r;
 227
 228        return q;
 229}
 230
 231UDWtype
 232__udivdi3(UDWtype n, UDWtype d)
 233{
 234        return __udivmoddi4(n, d, (UDWtype *)0);
 235}
 236