Mercurial > hg > CbC > CbC_gcc
comparison gcc/config/mcore/lib1.asm @ 0:a06113de4d67
first commit
author | kent <kent@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 17 Jul 2009 14:47:48 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:a06113de4d67 |
---|---|
1 /* libgcc routines for the MCore. | |
2 Copyright (C) 1993, 1999, 2000, 2009 Free Software Foundation, Inc. | |
3 | |
4 This file is part of GCC. | |
5 | |
6 GCC is free software; you can redistribute it and/or modify it | |
7 under the terms of the GNU General Public License as published by the | |
8 Free Software Foundation; either version 3, or (at your option) any | |
9 later version. | |
10 | |
11 This file is distributed in the hope that it will be useful, but | |
12 WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 General Public License for more details. | |
15 | |
16 Under Section 7 of GPL version 3, you are granted additional | |
17 permissions described in the GCC Runtime Library Exception, version | |
18 3.1, as published by the Free Software Foundation. | |
19 | |
20 You should have received a copy of the GNU General Public License and | |
21 a copy of the GCC Runtime Library Exception along with this program; | |
22 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see | |
23 <http://www.gnu.org/licenses/>. */ | |
24 | |
25 #define CONCAT1(a, b) CONCAT2(a, b) | |
26 #define CONCAT2(a, b) a ## b | |
27 | |
28 /* Use the right prefix for global labels. */ | |
29 | |
30 #define SYM(x) CONCAT1 (__, x) | |
31 | |
32 #ifdef __ELF__ | |
33 #define TYPE(x) .type SYM (x),@function | |
34 #define SIZE(x) .size SYM (x), . - SYM (x) | |
35 #else | |
36 #define TYPE(x) | |
37 #define SIZE(x) | |
38 #endif | |
39 | |
40 .macro FUNC_START name | |
41 .text | |
42 .globl SYM (\name) | |
43 TYPE (\name) | |
44 SYM (\name): | |
45 .endm | |
46 | |
47 .macro FUNC_END name | |
48 SIZE (\name) | |
49 .endm | |
50 | |
51 #ifdef L_udivsi3 | |
52 FUNC_START udiv32 | |
53 FUNC_START udivsi32 | |
54 | |
55 movi r1,0 // r1-r2 form 64 bit dividend | |
56 movi r4,1 // r4 is quotient (1 for a sentinel) | |
57 | |
58 cmpnei r3,0 // look for 0 divisor | |
59 bt 9f | |
60 trap 3 // divide by 0 | |
61 9: | |
62 // control iterations; skip across high order 0 bits in dividend | |
63 mov r7,r2 | |
64 cmpnei r7,0 | |
65 bt 8f | |
66 movi r2,0 // 0 dividend | |
67 jmp r15 // quick return | |
68 8: | |
69 ff1 r7 // figure distance to skip | |
70 lsl r4,r7 // move the sentinel along (with 0's behind) | |
71 lsl r2,r7 // and the low 32 bits of numerator | |
72 | |
73 // appears to be wrong... | |
74 // tested out incorrectly in our OS work... | |
75 // mov r7,r3 // looking at divisor | |
76 // ff1 r7 // I can move 32-r7 more bits to left. | |
77 // addi r7,1 // ok, one short of that... | |
78 // mov r1,r2 | |
79 // lsr r1,r7 // bits that came from low order... | |
80 // rsubi r7,31 // r7 == "32-n" == LEFT distance | |
81 // addi r7,1 // this is (32-n) | |
82 // lsl r4,r7 // fixes the high 32 (quotient) | |
83 // lsl r2,r7 | |
84 // cmpnei r4,0 | |
85 // bf 4f // the sentinel went away... | |
86 | |
87 // run the remaining bits | |
88 | |
89 1: lslc r2,1 // 1 bit left shift of r1-r2 | |
90 addc r1,r1 | |
91 cmphs r1,r3 // upper 32 of dividend >= divisor? | |
92 bf 2f | |
93 sub r1,r3 // if yes, subtract divisor | |
94 2: addc r4,r4 // shift by 1 and count subtracts | |
95 bf 1b // if sentinel falls out of quotient, stop | |
96 | |
97 4: mov r2,r4 // return quotient | |
98 mov r3,r1 // and piggyback the remainder | |
99 jmp r15 | |
100 FUNC_END udiv32 | |
101 FUNC_END udivsi32 | |
102 #endif | |
103 | |
104 #ifdef L_umodsi3 | |
105 FUNC_START urem32 | |
106 FUNC_START umodsi3 | |
107 movi r1,0 // r1-r2 form 64 bit dividend | |
108 movi r4,1 // r4 is quotient (1 for a sentinel) | |
109 cmpnei r3,0 // look for 0 divisor | |
110 bt 9f | |
111 trap 3 // divide by 0 | |
112 9: | |
113 // control iterations; skip across high order 0 bits in dividend | |
114 mov r7,r2 | |
115 cmpnei r7,0 | |
116 bt 8f | |
117 movi r2,0 // 0 dividend | |
118 jmp r15 // quick return | |
119 8: | |
120 ff1 r7 // figure distance to skip | |
121 lsl r4,r7 // move the sentinel along (with 0's behind) | |
122 lsl r2,r7 // and the low 32 bits of numerator | |
123 | |
124 1: lslc r2,1 // 1 bit left shift of r1-r2 | |
125 addc r1,r1 | |
126 cmphs r1,r3 // upper 32 of dividend >= divisor? | |
127 bf 2f | |
128 sub r1,r3 // if yes, subtract divisor | |
129 2: addc r4,r4 // shift by 1 and count subtracts | |
130 bf 1b // if sentinel falls out of quotient, stop | |
131 mov r2,r1 // return remainder | |
132 jmp r15 | |
133 FUNC_END urem32 | |
134 FUNC_END umodsi3 | |
135 #endif | |
136 | |
137 #ifdef L_divsi3 | |
138 FUNC_START div32 | |
139 FUNC_START divsi3 | |
140 mov r5,r2 // calc sign of quotient | |
141 xor r5,r3 | |
142 abs r2 // do unsigned divide | |
143 abs r3 | |
144 movi r1,0 // r1-r2 form 64 bit dividend | |
145 movi r4,1 // r4 is quotient (1 for a sentinel) | |
146 cmpnei r3,0 // look for 0 divisor | |
147 bt 9f | |
148 trap 3 // divide by 0 | |
149 9: | |
150 // control iterations; skip across high order 0 bits in dividend | |
151 mov r7,r2 | |
152 cmpnei r7,0 | |
153 bt 8f | |
154 movi r2,0 // 0 dividend | |
155 jmp r15 // quick return | |
156 8: | |
157 ff1 r7 // figure distance to skip | |
158 lsl r4,r7 // move the sentinel along (with 0's behind) | |
159 lsl r2,r7 // and the low 32 bits of numerator | |
160 | |
161 // tested out incorrectly in our OS work... | |
162 // mov r7,r3 // looking at divisor | |
163 // ff1 r7 // I can move 32-r7 more bits to left. | |
164 // addi r7,1 // ok, one short of that... | |
165 // mov r1,r2 | |
166 // lsr r1,r7 // bits that came from low order... | |
167 // rsubi r7,31 // r7 == "32-n" == LEFT distance | |
168 // addi r7,1 // this is (32-n) | |
169 // lsl r4,r7 // fixes the high 32 (quotient) | |
170 // lsl r2,r7 | |
171 // cmpnei r4,0 | |
172 // bf 4f // the sentinel went away... | |
173 | |
174 // run the remaining bits | |
175 1: lslc r2,1 // 1 bit left shift of r1-r2 | |
176 addc r1,r1 | |
177 cmphs r1,r3 // upper 32 of dividend >= divisor? | |
178 bf 2f | |
179 sub r1,r3 // if yes, subtract divisor | |
180 2: addc r4,r4 // shift by 1 and count subtracts | |
181 bf 1b // if sentinel falls out of quotient, stop | |
182 | |
183 4: mov r2,r4 // return quotient | |
184 mov r3,r1 // piggyback the remainder | |
185 btsti r5,31 // after adjusting for sign | |
186 bf 3f | |
187 rsubi r2,0 | |
188 rsubi r3,0 | |
189 3: jmp r15 | |
190 FUNC_END div32 | |
191 FUNC_END divsi3 | |
192 #endif | |
193 | |
194 #ifdef L_modsi3 | |
195 FUNC_START rem32 | |
196 FUNC_START modsi3 | |
197 mov r5,r2 // calc sign of remainder | |
198 abs r2 // do unsigned divide | |
199 abs r3 | |
200 movi r1,0 // r1-r2 form 64 bit dividend | |
201 movi r4,1 // r4 is quotient (1 for a sentinel) | |
202 cmpnei r3,0 // look for 0 divisor | |
203 bt 9f | |
204 trap 3 // divide by 0 | |
205 9: | |
206 // control iterations; skip across high order 0 bits in dividend | |
207 mov r7,r2 | |
208 cmpnei r7,0 | |
209 bt 8f | |
210 movi r2,0 // 0 dividend | |
211 jmp r15 // quick return | |
212 8: | |
213 ff1 r7 // figure distance to skip | |
214 lsl r4,r7 // move the sentinel along (with 0's behind) | |
215 lsl r2,r7 // and the low 32 bits of numerator | |
216 | |
217 1: lslc r2,1 // 1 bit left shift of r1-r2 | |
218 addc r1,r1 | |
219 cmphs r1,r3 // upper 32 of dividend >= divisor? | |
220 bf 2f | |
221 sub r1,r3 // if yes, subtract divisor | |
222 2: addc r4,r4 // shift by 1 and count subtracts | |
223 bf 1b // if sentinel falls out of quotient, stop | |
224 mov r2,r1 // return remainder | |
225 btsti r5,31 // after adjusting for sign | |
226 bf 3f | |
227 rsubi r2,0 | |
228 3: jmp r15 | |
229 FUNC_END rem32 | |
230 FUNC_END modsi3 | |
231 #endif | |
232 | |
233 | |
234 /* GCC expects that {__eq,__ne,__gt,__ge,__le,__lt}{df2,sf2} | |
235 will behave as __cmpdf2. So, we stub the implementations to | |
236 jump on to __cmpdf2 and __cmpsf2. | |
237 | |
238 All of these shortcircuit the return path so that __cmp{sd}f2 | |
239 will go directly back to the caller. */ | |
240 | |
241 .macro COMPARE_DF_JUMP name | |
242 .import SYM (cmpdf2) | |
243 FUNC_START \name | |
244 jmpi SYM (cmpdf2) | |
245 FUNC_END \name | |
246 .endm | |
247 | |
248 #ifdef L_eqdf2 | |
249 COMPARE_DF_JUMP eqdf2 | |
250 #endif /* L_eqdf2 */ | |
251 | |
252 #ifdef L_nedf2 | |
253 COMPARE_DF_JUMP nedf2 | |
254 #endif /* L_nedf2 */ | |
255 | |
256 #ifdef L_gtdf2 | |
257 COMPARE_DF_JUMP gtdf2 | |
258 #endif /* L_gtdf2 */ | |
259 | |
260 #ifdef L_gedf2 | |
261 COMPARE_DF_JUMP gedf2 | |
262 #endif /* L_gedf2 */ | |
263 | |
264 #ifdef L_ltdf2 | |
265 COMPARE_DF_JUMP ltdf2 | |
266 #endif /* L_ltdf2 */ | |
267 | |
268 #ifdef L_ledf2 | |
269 COMPARE_DF_JUMP ledf2 | |
270 #endif /* L_ledf2 */ | |
271 | |
272 /* SINGLE PRECISION FLOATING POINT STUBS */ | |
273 | |
274 .macro COMPARE_SF_JUMP name | |
275 .import SYM (cmpsf2) | |
276 FUNC_START \name | |
277 jmpi SYM (cmpsf2) | |
278 FUNC_END \name | |
279 .endm | |
280 | |
281 #ifdef L_eqsf2 | |
282 COMPARE_SF_JUMP eqsf2 | |
283 #endif /* L_eqsf2 */ | |
284 | |
285 #ifdef L_nesf2 | |
286 COMPARE_SF_JUMP nesf2 | |
287 #endif /* L_nesf2 */ | |
288 | |
289 #ifdef L_gtsf2 | |
290 COMPARE_SF_JUMP gtsf2 | |
291 #endif /* L_gtsf2 */ | |
292 | |
293 #ifdef L_gesf2 | |
294 COMPARE_SF_JUMP __gesf2 | |
295 #endif /* L_gesf2 */ | |
296 | |
297 #ifdef L_ltsf2 | |
298 COMPARE_SF_JUMP __ltsf2 | |
299 #endif /* L_ltsf2 */ | |
300 | |
301 #ifdef L_lesf2 | |
302 COMPARE_SF_JUMP lesf2 | |
303 #endif /* L_lesf2 */ |