OSDN Git Service

* Makefile.in (LIBGCC_DEPS): Add libgcc2.h.
[pf3gnuchains/gcc-fork.git] / gcc / config / stormy16 / stormy16-lib2.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  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 2, or (at your option) any later
14    version.
15
16    In addition to the permissions in the GNU General Public License, the
17    Free Software Foundation gives you unlimited permission to link the
18    compiled version of this file into combinations with other programs,
19    and to distribute those combinations without any restriction coming
20    from the use of this file.  (The General Public License restrictions
21    do apply in other respects; for example, they cover modification of
22    the file, and distribution when not linked into a combine
23    executable.)
24
25    GCC is distributed in the hope that it will be useful, but WITHOUT ANY
26    WARRANTY; without even the implied warranty of MERCHANTABILITY or
27    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
28    for more details.
29
30    You should have received a copy of the GNU General Public License
31    along with GCC; see the file COPYING.  If not, write to the Free
32    Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
33    02110-1301, USA.  */
34
35 #include "tconfig.h"
36 #include "tsystem.h"
37 #include "coretypes.h"
38 #include "tm.h"
39
40 #ifdef HAVE_GAS_HIDDEN
41 #define ATTRIBUTE_HIDDEN  __attribute__ ((__visibility__ ("hidden")))
42 #else
43 #define ATTRIBUTE_HIDDEN
44 #endif
45
46 #include "libgcc2.h"
47 #undef int
48
49 /* These prototypes would normally live in libgcc2.h, but this can
50    only happen once the code below is integrated into libgcc2.c.  */
51
52 extern USItype udivmodsi4 (USItype, USItype, word_type);
53 extern SItype __divsi3 (SItype, SItype);
54 extern SItype __modsi3 (SItype, SItype);
55 extern SItype __udivsi3 (SItype, SItype);
56 extern SItype __umodsi3 (SItype, SItype);
57 extern SItype __ashlsi3 (SItype, SItype);
58 extern SItype __ashrsi3 (SItype, SItype);
59 extern USItype __lshrsi3 (USItype, USItype);
60 extern int __popcounthi2 (UHWtype);
61 extern int __parityhi2 (UHWtype);
62 extern int __clzhi2 (UHWtype);
63 extern int __ctzhi2 (UHWtype);
64
65
66
67 USItype
68 udivmodsi4 (USItype num, USItype den, word_type modwanted)
69 {
70   USItype bit = 1;
71   USItype res = 0;
72
73   while (den < num && bit && !(den & (1L << 31)))
74     {
75       den <<= 1;
76       bit <<= 1;
77     }
78   while (bit)
79     {
80       if (num >= den)
81         {
82           num -= den;
83           res |= bit;
84         }
85       bit >>= 1;
86       den >>= 1;
87     }
88
89   if (modwanted)
90     return num;
91   return res;
92 }
93
94 SItype
95 __divsi3 (SItype a, SItype b)
96 {
97   word_type neg = 0;
98   SItype res;
99
100   if (a < 0)
101     {
102       a = -a;
103       neg = !neg;
104     }
105
106   if (b < 0)
107     {
108       b = -b;
109       neg = !neg;
110     }
111
112   res = udivmodsi4 (a, b, 0);
113
114   if (neg)
115     res = -res;
116
117   return res;
118 }
119
120 SItype
121 __modsi3 (SItype a, SItype b)
122 {
123   word_type neg = 0;
124   SItype res;
125
126   if (a < 0)
127     {
128       a = -a;
129       neg = 1;
130     }
131
132   if (b < 0)
133     b = -b;
134
135   res = udivmodsi4 (a, b, 1);
136
137   if (neg)
138     res = -res;
139
140   return res;
141 }
142
143 SItype
144 __udivsi3 (SItype a, SItype b)
145 {
146   return udivmodsi4 (a, b, 0);
147 }
148
149 SItype
150 __umodsi3 (SItype a, SItype b)
151 {
152   return udivmodsi4 (a, b, 1);
153 }
154
155 SItype
156 __ashlsi3 (SItype a, SItype b)
157 {
158   word_type i;
159   
160   if (b & 16)
161     a <<= 16;
162   if (b & 8)
163     a <<= 8;
164   for (i = (b & 0x7); i > 0; --i)
165     a <<= 1;
166   return a;
167 }
168
169 SItype
170 __ashrsi3 (SItype a, SItype b)
171 {
172   word_type i;
173   
174   if (b & 16)
175     a >>= 16;
176   if (b & 8)
177     a >>= 8;
178   for (i = (b & 0x7); i > 0; --i)
179     a >>= 1;
180   return a;
181 }
182
183 USItype
184 __lshrsi3 (USItype a, USItype b)
185 {
186   word_type i;
187   
188   if (b & 16)
189     a >>= 16;
190   if (b & 8)
191     a >>= 8;
192   for (i = (b & 0x7); i > 0; --i)
193     a >>= 1;
194   return a;
195 }
196
197 /* Returns the number of set bits in X.
198    FIXME:  The return type really should be unsigned,
199    but this is not how the builtin is prototyped.  */
200 int
201 __popcounthi2 (UHWtype x)
202 {
203   int ret;
204
205   ret = __popcount_tab [x & 0xff];
206   ret += __popcount_tab [(x >> 8) & 0xff];
207
208   return ret;
209 }
210
211 /* Returns the number of set bits in X, modulo 2.
212    FIXME:  The return type really should be unsigned,
213    but this is not how the builtin is prototyped.  */
214
215 int
216 __parityhi2 (UHWtype x)
217 {
218   x ^= x >> 8;
219   x ^= x >> 4;
220   x &= 0xf;
221   return (0x6996 >> x) & 1;
222 }
223
224 /* Returns the number of leading zero bits in X.
225    FIXME:  The return type really should be unsigned,
226    but this is not how the builtin is prototyped.  */
227
228 int
229 __clzhi2 (UHWtype x)
230 {
231   if (x > 0xff)
232     return 8 - __clz_tab[x >> 8];
233   return 16 - __clz_tab[x];
234 }
235
236 /* Returns the number of trailing zero bits in X.
237    FIXME:  The return type really should be unsigned,
238    but this is not how the builtin is prototyped.  */
239
240 int
241 __ctzhi2 (UHWtype x)
242 {
243   /* This is cunning.  It converts X into a number with only the one bit
244      set, the bit was the least significant bit in X.  From this we can
245      use the __clz_tab[] array to compute the number of trailing bits.  */
246   x &= - x;
247
248   if (x > 0xff)
249     return __clz_tab[x >> 8] + 7;
250   return __clz_tab[x] - 1;
251 }