comparison gcc/config/stormy16/stormy16-lib2.c @ 0:a06113de4d67

first commit
author kent <kent@cr.ie.u-ryukyu.ac.jp>
date Fri, 17 Jul 2009 14:47:48 +0900
parents
children 77e2b8dfacca
comparison
equal deleted inserted replaced
-1:000000000000 0:a06113de4d67
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 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
35 #ifdef HAVE_GAS_HIDDEN
36 #define ATTRIBUTE_HIDDEN __attribute__ ((__visibility__ ("hidden")))
37 #else
38 #define ATTRIBUTE_HIDDEN
39 #endif
40
41 #ifndef MIN_UNITS_PER_WORD
42 #define MIN_UNITS_PER_WORD UNITS_PER_WORD
43 #endif
44
45 #ifndef LIBGCC2_UNITS_PER_WORD
46 # if MIN_UNITS_PER_WORD > 4
47 # define LIBGCC2_UNITS_PER_WORD 8
48 # elif (MIN_UNITS_PER_WORD > 2 \
49 || (MIN_UNITS_PER_WORD > 1 && LONG_LONG_TYPE_SIZE > 32))
50 # define LIBGCC2_UNITS_PER_WORD 4
51 # else
52 # define LIBGCC2_UNITS_PER_WORD MIN_UNITS_PER_WORD
53 # endif
54 #endif
55
56 #define word_type Wtype
57
58 #include "libgcc2.h"
59 #undef int
60
61 /* These prototypes would normally live in libgcc2.h, but this can
62 only happen once the code below is integrated into libgcc2.c. */
63
64 extern USItype udivmodsi4 (USItype, USItype, word_type);
65 extern SItype __divsi3 (SItype, SItype);
66 extern SItype __modsi3 (SItype, SItype);
67 extern SItype __udivsi3 (SItype, SItype);
68 extern SItype __umodsi3 (SItype, SItype);
69 extern SItype __ashlsi3 (SItype, SItype);
70 extern SItype __ashrsi3 (SItype, SItype);
71 extern USItype __lshrsi3 (USItype, USItype);
72 extern int __popcounthi2 (UHWtype);
73 extern int __parityhi2 (UHWtype);
74 extern int __clzhi2 (UHWtype);
75 extern int __ctzhi2 (UHWtype);
76
77
78
79 USItype
80 udivmodsi4 (USItype num, USItype den, word_type modwanted)
81 {
82 USItype bit = 1;
83 USItype res = 0;
84
85 while (den < num && bit && !(den & (1L << 31)))
86 {
87 den <<= 1;
88 bit <<= 1;
89 }
90 while (bit)
91 {
92 if (num >= den)
93 {
94 num -= den;
95 res |= bit;
96 }
97 bit >>= 1;
98 den >>= 1;
99 }
100
101 if (modwanted)
102 return num;
103 return res;
104 }
105
106 SItype
107 __divsi3 (SItype a, SItype b)
108 {
109 word_type neg = 0;
110 SItype res;
111
112 if (a < 0)
113 {
114 a = -a;
115 neg = !neg;
116 }
117
118 if (b < 0)
119 {
120 b = -b;
121 neg = !neg;
122 }
123
124 res = udivmodsi4 (a, b, 0);
125
126 if (neg)
127 res = -res;
128
129 return res;
130 }
131
132 SItype
133 __modsi3 (SItype a, SItype b)
134 {
135 word_type neg = 0;
136 SItype res;
137
138 if (a < 0)
139 {
140 a = -a;
141 neg = 1;
142 }
143
144 if (b < 0)
145 b = -b;
146
147 res = udivmodsi4 (a, b, 1);
148
149 if (neg)
150 res = -res;
151
152 return res;
153 }
154
155 SItype
156 __udivsi3 (SItype a, SItype b)
157 {
158 return udivmodsi4 (a, b, 0);
159 }
160
161 SItype
162 __umodsi3 (SItype a, SItype b)
163 {
164 return udivmodsi4 (a, b, 1);
165 }
166
167 SItype
168 __ashlsi3 (SItype a, SItype b)
169 {
170 word_type i;
171
172 if (b & 16)
173 a <<= 16;
174 if (b & 8)
175 a <<= 8;
176 for (i = (b & 0x7); i > 0; --i)
177 a <<= 1;
178 return a;
179 }
180
181 SItype
182 __ashrsi3 (SItype a, SItype b)
183 {
184 word_type i;
185
186 if (b & 16)
187 a >>= 16;
188 if (b & 8)
189 a >>= 8;
190 for (i = (b & 0x7); i > 0; --i)
191 a >>= 1;
192 return a;
193 }
194
195 USItype
196 __lshrsi3 (USItype a, USItype b)
197 {
198 word_type i;
199
200 if (b & 16)
201 a >>= 16;
202 if (b & 8)
203 a >>= 8;
204 for (i = (b & 0x7); i > 0; --i)
205 a >>= 1;
206 return a;
207 }
208
209 /* Returns the number of set bits in X.
210 FIXME: The return type really should be unsigned,
211 but this is not how the builtin is prototyped. */
212 int
213 __popcounthi2 (UHWtype x)
214 {
215 int ret;
216
217 ret = __popcount_tab [x & 0xff];
218 ret += __popcount_tab [(x >> 8) & 0xff];
219
220 return ret;
221 }
222
223 /* Returns the number of set bits in X, modulo 2.
224 FIXME: The return type really should be unsigned,
225 but this is not how the builtin is prototyped. */
226
227 int
228 __parityhi2 (UHWtype x)
229 {
230 x ^= x >> 8;
231 x ^= x >> 4;
232 x &= 0xf;
233 return (0x6996 >> x) & 1;
234 }
235
236 /* Returns the number of leading 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 __clzhi2 (UHWtype x)
242 {
243 if (x > 0xff)
244 return 8 - __clz_tab[x >> 8];
245 return 16 - __clz_tab[x];
246 }
247
248 /* Returns the number of trailing zero bits in X.
249 FIXME: The return type really should be unsigned,
250 but this is not how the builtin is prototyped. */
251
252 int
253 __ctzhi2 (UHWtype x)
254 {
255 /* This is cunning. It converts X into a number with only the one bit
256 set, the bit was the least significant bit in X. From this we can
257 use the __clz_tab[] array to compute the number of trailing bits. */
258 x &= - x;
259
260 if (x > 0xff)
261 return __clz_tab[x >> 8] + 7;
262 return __clz_tab[x] - 1;
263 }