xref: /openbmc/u-boot/arch/arc/lib/libgcc2.c (revision 13bdce8f8cadf07bc81d7000a04e48f3028de543)
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  }
162