lib2funcs.c revision 1.3
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-2015 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
65extern USItype udivmodsi4 (USItype, USItype, word_type);
66extern SItype __divsi3 (SItype, SItype);
67extern SItype __modsi3 (SItype, SItype);
68extern SItype __udivsi3 (SItype, SItype);
69extern SItype __umodsi3 (SItype, SItype);
70extern SItype __ashlsi3 (SItype, SItype);
71extern SItype __ashrsi3 (SItype, SItype);
72extern USItype __lshrsi3 (USItype, USItype);
73extern int __popcounthi2 (UHWtype);
74extern int __parityhi2 (UHWtype);
75extern int __clzhi2 (UHWtype);
76extern int __ctzhi2 (UHWtype);
77
78
79#ifdef XSTORMY16_UDIVMODSI4
80USItype
81udivmodsi4 (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
109SItype
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
137SItype
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
162SItype
163__udivsi3 (SItype a, SItype b)
164{
165  return udivmodsi4 (a, b, 0);
166}
167#endif
168
169#ifdef XSTORMY16_UMODSI3
170SItype
171__umodsi3 (SItype a, SItype b)
172{
173  return udivmodsi4 (a, b, 1);
174}
175#endif
176
177#ifdef XSTORMY16_ASHLSI3
178SItype
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
194SItype
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
210USItype
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.  */
229int
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
246int
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
264int
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
283int
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
302int
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
319int
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
335word_type
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
358word_type
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