]> git.ipfire.org Git - people/ms/u-boot.git/blob - arch/arc/lib/libgcc2.c
Merge branch 'master' of git://git.denx.de/u-boot-atmel
[people/ms/u-boot.git] / 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 }