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-2020 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
udivmodsi4(USItype num,USItype den,word_type modwanted)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
__divsi3(SItype a,SItype b)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
__modsi3(SItype a,SItype b)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
__udivsi3(SItype a,SItype b)163 __udivsi3 (SItype a, SItype b)
164 {
165   return udivmodsi4 (a, b, 0);
166 }
167 #endif
168 
169 #ifdef XSTORMY16_UMODSI3
170 SItype
__umodsi3(SItype a,SItype b)171 __umodsi3 (SItype a, SItype b)
172 {
173   return udivmodsi4 (a, b, 1);
174 }
175 #endif
176 
177 #ifdef XSTORMY16_ASHLSI3
178 SItype
__ashlsi3(SItype a,SItype b)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
__ashrsi3(SItype a,SItype b)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
__lshrsi3(USItype a,USItype b)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
__popcounthi2(UHWtype x)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
__parityhi2(UHWtype x)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
__clzhi2(UHWtype x)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
__ctzhi2(UHWtype x)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
__ffshi2(UHWtype u)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_CLRSBHI2
315 /* Returns the number of leading redundant sign bits in X.
316    I.e. the number of bits following the most significant bit which are
317    identical to it.  There are no special cases for 0 or other values.  */
318 
319 int
__clrsbhi2(HWtype x)320 __clrsbhi2 (HWtype x)
321 {
322   if (x < 0)
323     x = ~x;
324   if (x == 0)
325     return 15;
326   return __builtin_clz (x) - 1;
327 }
328 #endif
329 
330 #ifdef XSTORMY16_UCMPSI2
331 /* Performs an unsigned comparison of two 32-bit values: A and B.
332    If A is less than B, then 0 is returned.  If A is greater than B,
333    then 2 is returned.  Otherwise A and B are equal and 1 is returned.  */
334 
335 word_type
__ucmpsi2(USItype a,USItype b)336 __ucmpsi2 (USItype a, USItype b)
337 {
338   word_type hi_a = (a >> 16);
339   word_type hi_b = (b >> 16);
340 
341   if (hi_a == hi_b)
342     {
343       word_type low_a = (a & 0xffff);
344       word_type low_b = (b & 0xffff);
345 
346       return low_a < low_b ? 0 : (low_a > low_b ? 2 : 1);
347     }
348 
349   return hi_a < hi_b ? 0 : 2;
350 }
351 #endif
352 
353 #ifdef XSTORMY16_CMPSI2
354 /* Performs an signed comparison of two 32-bit values: A and B.
355    If A is less than B, then 0 is returned.  If A is greater than B,
356    then 2 is returned.  Otherwise A and B are equal and 1 is returned.  */
357 
358 word_type
__cmpsi2(SItype a,SItype b)359 __cmpsi2 (SItype a, SItype b)
360 {
361   word_type hi_a = (a >> 16);
362   word_type hi_b = (b >> 16);
363 
364   if (hi_a == hi_b)
365     {
366       word_type low_a = (a & 0xffff);
367       word_type low_b = (b & 0xffff);
368 
369       return low_a < low_b ? 0 : (low_a > low_b ? 2 : 1);
370     }
371 
372   return hi_a < hi_b ? 0 : 2;
373 }
374 #endif
375