]> git.sur5r.net Git - u-boot/blob - arch/arc/lib/libgcc2.c
d5ad327f655dd2675be568b0c24acb68809448e4
[u-boot] / arch / arc / lib / libgcc2.c
1 /*
2  * Copyright (C) 1989-2013 Free Software Foundation, Inc.
3  *
4  * SPDX-License-Identifier:     GPL-2.0+
5  */
6
7 #include "libgcc2.h"
8
9 DWtype
10 __ashldi3(DWtype u, shift_count_type b)
11 {
12         if (b == 0)
13                 return u;
14
15         const DWunion uu = {.ll = u};
16         const shift_count_type bm = W_TYPE_SIZE - b;
17         DWunion w;
18
19         if (bm <= 0) {
20                 w.s.low = 0;
21                 w.s.high = (UWtype)uu.s.low << -bm;
22         } else {
23                 const UWtype carries = (UWtype) uu.s.low >> bm;
24
25                 w.s.low = (UWtype)uu.s.low << b;
26                 w.s.high = ((UWtype)uu.s.high << b) | carries;
27         }
28
29         return w.ll;
30 }
31
32 DWtype
33 __ashrdi3(DWtype u, shift_count_type b)
34 {
35         if (b == 0)
36                 return u;
37
38         const DWunion uu = {.ll = u};
39         const shift_count_type bm = W_TYPE_SIZE - b;
40         DWunion w;
41
42         if (bm <= 0) {
43                 /* w.s.high = 1..1 or 0..0 */
44                 w.s.high = uu.s.high >> (W_TYPE_SIZE - 1);
45                 w.s.low = uu.s.high >> -bm;
46         } else {
47                 const UWtype carries = (UWtype) uu.s.high << bm;
48
49                 w.s.high = uu.s.high >> b;
50                 w.s.low = ((UWtype)uu.s.low >> b) | carries;
51         }
52
53         return w.ll;
54 }
55
56 DWtype
57 __lshrdi3(DWtype u, shift_count_type b)
58 {
59         if (b == 0)
60                 return u;
61
62         const DWunion uu = {.ll = u};
63         const shift_count_type bm = W_TYPE_SIZE - b;
64         DWunion w;
65
66         if (bm <= 0) {
67                 w.s.high = 0;
68                 w.s.low = (UWtype)uu.s.high >> -bm;
69         } else {
70                 const UWtype carries = (UWtype)uu.s.high << bm;
71
72                 w.s.high = (UWtype)uu.s.high >> b;
73                 w.s.low = ((UWtype)uu.s.low >> b) | carries;
74         }
75
76         return w.ll;
77 }
78
79 unsigned long
80 udivmodsi4(unsigned long num, unsigned long den, int modwanted)
81 {
82         unsigned long bit = 1;
83         unsigned long res = 0;
84
85         while (den < num && bit && !(den & (1L<<31))) {
86                 den <<= 1;
87                 bit <<= 1;
88         }
89
90         while (bit) {
91                 if (num >= den) {
92                         num -= den;
93                         res |= bit;
94                 }
95                 bit >>= 1;
96                 den >>= 1;
97         }
98
99         if (modwanted)
100                 return num;
101
102         return res;
103 }
104
105 long
106 __divsi3(long a, long b)
107 {
108         int neg = 0;
109         long res;
110
111         if (a < 0) {
112                 a = -a;
113                 neg = !neg;
114         }
115
116         if (b < 0) {
117                 b = -b;
118                 neg = !neg;
119         }
120
121         res = udivmodsi4(a, b, 0);
122
123         if (neg)
124                 res = -res;
125
126         return res;
127 }
128
129 long
130 __modsi3(long a, long b)
131 {
132         int neg = 0;
133         long res;
134
135         if (a < 0) {
136                 a = -a;
137                 neg = 1;
138         }
139
140         if (b < 0)
141                 b = -b;
142
143         res = udivmodsi4(a, b, 1);
144
145         if (neg)
146                 res = -res;
147
148         return res;
149 }
150
151 long
152 __udivsi3(long a, long b)
153 {
154         return udivmodsi4(a, b, 0);
155 }
156
157 long
158 __umodsi3(long a, long b)
159 {
160         return udivmodsi4(a, b, 1);
161 }