]> git.ipfire.org Git - thirdparty/gcc.git/blob - libgcc/config/stormy16/lib2funcs.c
Move libgcc_tm_file to toplevel libgcc
[thirdparty/gcc.git] / libgcc / config / stormy16 / lib2funcs.c
1 /* This file contains 16-bit versions of some of the functions found in
2 libgcc2.c. Really libgcc ought to be moved out of the gcc directory
3 and into its own top level directory, and then split up into multiple
4 files. On this glorious day maybe this code can be integrated into
5 it too. */
6
7 /* Copyright (C) 2005, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
8
9 This file is part of GCC.
10
11 GCC is free software; you can redistribute it and/or modify it under
12 the terms of the GNU General Public License as published by the Free
13 Software Foundation; either version 3, or (at your option) any later
14 version.
15
16 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
17 WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 for more details.
20
21 Under Section 7 of GPL version 3, you are granted additional
22 permissions described in the GCC Runtime Library Exception, version
23 3.1, as published by the Free Software Foundation.
24
25 You should have received a copy of the GNU General Public License and
26 a copy of the GCC Runtime Library Exception along with this program;
27 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
28 <http://www.gnu.org/licenses/>. */
29
30 #include "tconfig.h"
31 #include "tsystem.h"
32 #include "coretypes.h"
33 #include "tm.h"
34 #include "libgcc_tm.h"
35
36 #ifdef HAVE_GAS_HIDDEN
37 #define ATTRIBUTE_HIDDEN __attribute__ ((__visibility__ ("hidden")))
38 #else
39 #define ATTRIBUTE_HIDDEN
40 #endif
41
42 #ifndef MIN_UNITS_PER_WORD
43 #define MIN_UNITS_PER_WORD UNITS_PER_WORD
44 #endif
45
46 #ifndef LIBGCC2_UNITS_PER_WORD
47 # if MIN_UNITS_PER_WORD > 4
48 # define LIBGCC2_UNITS_PER_WORD 8
49 # elif (MIN_UNITS_PER_WORD > 2 \
50 || (MIN_UNITS_PER_WORD > 1 && LONG_LONG_TYPE_SIZE > 32))
51 # define LIBGCC2_UNITS_PER_WORD 4
52 # else
53 # define LIBGCC2_UNITS_PER_WORD MIN_UNITS_PER_WORD
54 # endif
55 #endif
56
57 #define word_type Wtype
58
59 #include "libgcc2.h"
60 #undef int
61
62 /* These prototypes would normally live in libgcc2.h, but this can
63 only happen once the code below is integrated into libgcc2.c. */
64
65 extern USItype udivmodsi4 (USItype, USItype, word_type);
66 extern SItype __divsi3 (SItype, SItype);
67 extern SItype __modsi3 (SItype, SItype);
68 extern SItype __udivsi3 (SItype, SItype);
69 extern SItype __umodsi3 (SItype, SItype);
70 extern SItype __ashlsi3 (SItype, SItype);
71 extern SItype __ashrsi3 (SItype, SItype);
72 extern USItype __lshrsi3 (USItype, USItype);
73 extern int __popcounthi2 (UHWtype);
74 extern int __parityhi2 (UHWtype);
75 extern int __clzhi2 (UHWtype);
76 extern int __ctzhi2 (UHWtype);
77
78
79 #ifdef XSTORMY16_UDIVMODSI4
80 USItype
81 udivmodsi4 (USItype num, USItype den, word_type modwanted)
82 {
83 USItype bit = 1;
84 USItype res = 0;
85
86 while (den < num && bit && !(den & (1L << 31)))
87 {
88 den <<= 1;
89 bit <<= 1;
90 }
91 while (bit)
92 {
93 if (num >= den)
94 {
95 num -= den;
96 res |= bit;
97 }
98 bit >>= 1;
99 den >>= 1;
100 }
101
102 if (modwanted)
103 return num;
104 return res;
105 }
106 #endif
107
108 #ifdef XSTORMY16_DIVSI3
109 SItype
110 __divsi3 (SItype a, SItype b)
111 {
112 word_type neg = 0;
113 SItype res;
114
115 if (a < 0)
116 {
117 a = -a;
118 neg = !neg;
119 }
120
121 if (b < 0)
122 {
123 b = -b;
124 neg = !neg;
125 }
126
127 res = udivmodsi4 (a, b, 0);
128
129 if (neg)
130 res = -res;
131
132 return res;
133 }
134 #endif
135
136 #ifdef XSTORMY16_MODSI3
137 SItype
138 __modsi3 (SItype a, SItype b)
139 {
140 word_type neg = 0;
141 SItype res;
142
143 if (a < 0)
144 {
145 a = -a;
146 neg = 1;
147 }
148
149 if (b < 0)
150 b = -b;
151
152 res = udivmodsi4 (a, b, 1);
153
154 if (neg)
155 res = -res;
156
157 return res;
158 }
159 #endif
160
161 #ifdef XSTORMY16_UDIVSI3
162 SItype
163 __udivsi3 (SItype a, SItype b)
164 {
165 return udivmodsi4 (a, b, 0);
166 }
167 #endif
168
169 #ifdef XSTORMY16_UMODSI3
170 SItype
171 __umodsi3 (SItype a, SItype b)
172 {
173 return udivmodsi4 (a, b, 1);
174 }
175 #endif
176
177 #ifdef XSTORMY16_ASHLSI3
178 SItype
179 __ashlsi3 (SItype a, SItype b)
180 {
181 word_type i;
182
183 if (b & 16)
184 a <<= 16;
185 if (b & 8)
186 a <<= 8;
187 for (i = (b & 0x7); i > 0; --i)
188 a <<= 1;
189 return a;
190 }
191 #endif
192
193 #ifdef XSTORMY16_ASHRSI3
194 SItype
195 __ashrsi3 (SItype a, SItype b)
196 {
197 word_type i;
198
199 if (b & 16)
200 a >>= 16;
201 if (b & 8)
202 a >>= 8;
203 for (i = (b & 0x7); i > 0; --i)
204 a >>= 1;
205 return a;
206 }
207 #endif
208
209 #ifdef XSTORMY16_LSHRSI3
210 USItype
211 __lshrsi3 (USItype a, USItype b)
212 {
213 word_type i;
214
215 if (b & 16)
216 a >>= 16;
217 if (b & 8)
218 a >>= 8;
219 for (i = (b & 0x7); i > 0; --i)
220 a >>= 1;
221 return a;
222 }
223 #endif
224
225 #ifdef XSTORMY16_POPCOUNTHI2
226 /* Returns the number of set bits in X.
227 FIXME: The return type really should be "unsigned int"
228 but this is not how the builtin is prototyped. */
229 int
230 __popcounthi2 (UHWtype x)
231 {
232 int ret;
233
234 ret = __popcount_tab [x & 0xff];
235 ret += __popcount_tab [(x >> 8) & 0xff];
236
237 return ret;
238 }
239 #endif
240
241 #ifdef XSTORMY16_PARITYHI2
242 /* Returns the number of set bits in X, modulo 2.
243 FIXME: The return type really should be "unsigned int"
244 but this is not how the builtin is prototyped. */
245
246 int
247 __parityhi2 (UHWtype x)
248 {
249 x ^= x >> 8;
250 x ^= x >> 4;
251 x &= 0xf;
252 return (0x6996 >> x) & 1;
253 }
254 #endif
255
256 #ifdef XSTORMY16_CLZHI2
257 /* Returns the number of zero-bits from the most significant bit to the
258 first nonzero bit in X. Returns 16 for X == 0. Implemented as a
259 simple for loop in order to save space by removing the need for
260 the __clz_tab array.
261 FIXME: The return type really should be "unsigned int" but this is
262 not how the builtin is prototyped. */
263 #undef unsigned
264 int
265 __clzhi2 (UHWtype x)
266 {
267 unsigned int i;
268 unsigned int c;
269 unsigned int value = x;
270
271 for (c = 0, i = 1 << 15; i; i >>= 1, c++)
272 if (i & value)
273 break;
274 return c;
275 }
276 #endif
277
278 #ifdef XSTORMY16_CTZHI2
279 /* Returns the number of trailing zero bits in X.
280 FIXME: The return type really should be "signed int" since
281 ctz(0) returns -1, but this is not how the builtin is prototyped. */
282
283 int
284 __ctzhi2 (UHWtype x)
285 {
286 /* This is cunning. It converts X into a number with only the one bit
287 set, the bit that was the least significant bit in X. From this we
288 can use the count_leading_zeros to compute the number of trailing
289 bits. */
290 x &= - x;
291
292 return 15 - __builtin_clz (x);
293 }
294 #endif
295
296 #ifdef XSTORMY16_FFSHI2
297 /* Returns one plus the index of the least significant 1-bit of X,
298 or if X is zero, returns zero. FIXME: The return type really
299 should be "unsigned int" but this is not how the builtin is
300 prototyped. */
301
302 int
303 __ffshi2 (UHWtype u)
304 {
305 UHWtype count;
306
307 if (u == 0)
308 return 0;
309
310 return 16 - __builtin_clz (u & - u);
311 }
312 #endif
313
314 #ifdef XSTORMY16_UCMPSI2
315 /* Performs an unsigned comparison of two 32-bit values: A and B.
316 If A is less than B, then 0 is returned. If A is greater than B,
317 then 2 is returned. Otherwise A and B are equal and 1 is returned. */
318
319 word_type
320 __ucmpsi2 (USItype a, USItype b)
321 {
322 word_type hi_a = (a >> 16);
323 word_type hi_b = (b >> 16);
324
325 if (hi_a == hi_b)
326 {
327 word_type low_a = (a & 0xffff);
328 word_type low_b = (b & 0xffff);
329
330 return low_a < low_b ? 0 : (low_a > low_b ? 2 : 1);
331 }
332
333 return hi_a < hi_b ? 0 : 2;
334 }
335 #endif
336
337 #ifdef XSTORMY16_CMPSI2
338 /* Performs an signed comparison of two 32-bit values: A and B.
339 If A is less than B, then 0 is returned. If A is greater than B,
340 then 2 is returned. Otherwise A and B are equal and 1 is returned. */
341
342 word_type
343 __cmpsi2 (SItype a, SItype b)
344 {
345 word_type hi_a = (a >> 16);
346 word_type hi_b = (b >> 16);
347
348 if (hi_a == hi_b)
349 {
350 word_type low_a = (a & 0xffff);
351 word_type low_b = (b & 0xffff);
352
353 return low_a < low_b ? 0 : (low_a > low_b ? 2 : 1);
354 }
355
356 return hi_a < hi_b ? 0 : 2;
357 }
358 #endif