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 */