1 /* libgcc1 routines for the MCore.
2 Copyright (C) 1993, 1999, 2000 Free Software Foundation, Inc.
4 This file is part of GNU CC.
6 GNU CC 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 2, or (at your option) any
11 In addition to the permissions in the GNU General Public License, the
12 Free Software Foundation gives you unlimited permission to link the
13 compiled version of this file with other programs, and to distribute
14 those programs without any restriction coming from the use of this
15 file. (The General Public License restrictions do apply in other
16 respects; for example, they cover modification of the file, and
17 distribution when not linked into another program.)
19 This file is distributed in the hope that it will be useful, but
20 WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 General Public License for more details.
24 You should have received a copy of the GNU General Public License
25 along with this program; see the file COPYING. If not, write to
26 the Free Software Foundation, 59 Temple Place - Suite 330,
27 Boston, MA 02111-1307, USA. */
29 /* As a special exception, if you link this library with files
30 compiled with GCC to produce an executable, this does not cause
31 the resulting executable to be covered by the GNU General Public License.
32 This exception does not however invalidate any other reasons why
33 the executable file might be covered by the GNU General Public License. */
35 #define CONCAT1(a, b) CONCAT2(a, b)
36 #define CONCAT2(a, b) a ## b
38 /* Use the right prefix for global labels. */
40 #define SYM(x) CONCAT1 (__, x)
43 #define TYPE(x) .type SYM (x),@function
44 #define SIZE(x) .size SYM (x), . - SYM (x)
50 .macro FUNC_START name
65 movi r1,0 // r1-r2 form 64 bit dividend
66 movi r4,1 // r4 is quotient (1 for a sentinel)
68 cmpnei r3,0 // look for 0 divisor
72 // control iterations; skip across high order 0 bits in dividend
76 movi r2,0 // 0 dividend
77 jmp r15 // quick return
79 ff1 r7 // figure distance to skip
80 lsl r4,r7 // move the sentinel along (with 0's behind)
81 lsl r2,r7 // and the low 32 bits of numerator
83 // appears to be wrong...
84 // tested out incorrectly in our OS work...
85 // mov r7,r3 // looking at divisor
86 // ff1 r7 // I can move 32-r7 more bits to left.
87 // addi r7,1 // ok, one short of that...
89 // lsr r1,r7 // bits that came from low order...
90 // rsubi r7,31 // r7 == "32-n" == LEFT distance
91 // addi r7,1 // this is (32-n)
92 // lsl r4,r7 // fixes the high 32 (quotient)
95 // bf 4f // the sentinel went away...
97 // run the remaining bits
99 1: lslc r2,1 // 1 bit left shift of r1-r2
101 cmphs r1,r3 // upper 32 of dividend >= divisor?
103 sub r1,r3 // if yes, subtract divisor
104 2: addc r4,r4 // shift by 1 and count subtracts
105 bf 1b // if sentinel falls out of quotient, stop
107 4: mov r2,r4 // return quotient
108 mov r3,r1 // and piggyback the remainder
117 movi r1,0 // r1-r2 form 64 bit dividend
118 movi r4,1 // r4 is quotient (1 for a sentinel)
119 cmpnei r3,0 // look for 0 divisor
121 trap 3 // divide by 0
123 // control iterations; skip across high order 0 bits in dividend
127 movi r2,0 // 0 dividend
128 jmp r15 // quick return
130 ff1 r7 // figure distance to skip
131 lsl r4,r7 // move the sentinel along (with 0's behind)
132 lsl r2,r7 // and the low 32 bits of numerator
134 1: lslc r2,1 // 1 bit left shift of r1-r2
136 cmphs r1,r3 // upper 32 of dividend >= divisor?
138 sub r1,r3 // if yes, subtract divisor
139 2: addc r4,r4 // shift by 1 and count subtracts
140 bf 1b // if sentinel falls out of quotient, stop
141 mov r2,r1 // return remainder
150 mov r5,r2 // calc sign of quotient
152 abs r2 // do unsigned divide
154 movi r1,0 // r1-r2 form 64 bit dividend
155 movi r4,1 // r4 is quotient (1 for a sentinel)
156 cmpnei r3,0 // look for 0 divisor
158 trap 3 // divide by 0
160 // control iterations; skip across high order 0 bits in dividend
164 movi r2,0 // 0 dividend
165 jmp r15 // quick return
167 ff1 r7 // figure distance to skip
168 lsl r4,r7 // move the sentinel along (with 0's behind)
169 lsl r2,r7 // and the low 32 bits of numerator
171 // tested out incorrectly in our OS work...
172 // mov r7,r3 // looking at divisor
173 // ff1 r7 // I can move 32-r7 more bits to left.
174 // addi r7,1 // ok, one short of that...
176 // lsr r1,r7 // bits that came from low order...
177 // rsubi r7,31 // r7 == "32-n" == LEFT distance
178 // addi r7,1 // this is (32-n)
179 // lsl r4,r7 // fixes the high 32 (quotient)
182 // bf 4f // the sentinel went away...
184 // run the remaining bits
185 1: lslc r2,1 // 1 bit left shift of r1-r2
187 cmphs r1,r3 // upper 32 of dividend >= divisor?
189 sub r1,r3 // if yes, subtract divisor
190 2: addc r4,r4 // shift by 1 and count subtracts
191 bf 1b // if sentinel falls out of quotient, stop
193 4: mov r2,r4 // return quotient
194 mov r3,r1 // piggyback the remainder
195 btsti r5,31 // after adjusting for sign
207 mov r5,r2 // calc sign of remainder
208 abs r2 // do unsigned divide
210 movi r1,0 // r1-r2 form 64 bit dividend
211 movi r4,1 // r4 is quotient (1 for a sentinel)
212 cmpnei r3,0 // look for 0 divisor
214 trap 3 // divide by 0
216 // control iterations; skip across high order 0 bits in dividend
220 movi r2,0 // 0 dividend
221 jmp r15 // quick return
223 ff1 r7 // figure distance to skip
224 lsl r4,r7 // move the sentinel along (with 0's behind)
225 lsl r2,r7 // and the low 32 bits of numerator
227 1: lslc r2,1 // 1 bit left shift of r1-r2
229 cmphs r1,r3 // upper 32 of dividend >= divisor?
231 sub r1,r3 // if yes, subtract divisor
232 2: addc r4,r4 // shift by 1 and count subtracts
233 bf 1b // if sentinel falls out of quotient, stop
234 mov r2,r1 // return remainder
235 btsti r5,31 // after adjusting for sign
244 /* GCC expects that {__eq,__ne,__gt,__ge,__le,__lt}{df2,sf2}
245 will behave as __cmpdf2. So, we stub the implementations to
246 jump on to __cmpdf2 and __cmpsf2.
248 All of these shortcircuit the return path so that __cmp{sd}f2
249 will go directly back to the caller. */
251 .macro COMPARE_DF_JUMP name
259 COMPARE_DF_JUMP eqdf2
263 COMPARE_DF_JUMP nedf2
267 COMPARE_DF_JUMP gtdf2
271 COMPARE_DF_JUMP gedf2
275 COMPARE_DF_JUMP ltdf2
279 COMPARE_DF_JUMP ledf2
282 /* SINGLE PRECISION FLOATING POINT STUBS */
284 .macro COMPARE_SF_JUMP name
292 COMPARE_SF_JUMP eqsf2
296 COMPARE_SF_JUMP nesf2
300 COMPARE_SF_JUMP gtsf2
304 COMPARE_SF_JUMP __gesf2
308 COMPARE_SF_JUMP __ltsf2
312 COMPARE_SF_JUMP lesf2