1 /* libgcc routines for the MCore.
2 Copyright (C) 1993, 1999, 2000 Free Software Foundation, Inc.
4 This file is part of GCC.
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 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 into combinations with other programs,
14 and to distribute those combinations without any restriction coming
15 from the use of this file. (The General Public License restrictions
16 do apply in other respects; for example, they cover modification of
17 the file, and distribution when not linked into a combine
20 This file is distributed in the hope that it will be useful, but
21 WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 General Public License for more details.
25 You should have received a copy of the GNU General Public License
26 along with this program; see the file COPYING. If not, write to
27 the Free Software Foundation, 51 Franklin Street, Fifth Floor,
28 Boston, MA 02110-1301, USA. */
30 #define CONCAT1(a, b) CONCAT2(a, b)
31 #define CONCAT2(a, b) a ## b
33 /* Use the right prefix for global labels. */
35 #define SYM(x) CONCAT1 (__, x)
38 #define TYPE(x) .type SYM (x),@function
39 #define SIZE(x) .size SYM (x), . - SYM (x)
45 .macro FUNC_START name
60 movi r1,0 // r1-r2 form 64 bit dividend
61 movi r4,1 // r4 is quotient (1 for a sentinel)
63 cmpnei r3,0 // look for 0 divisor
67 // control iterations; skip across high order 0 bits in dividend
71 movi r2,0 // 0 dividend
72 jmp r15 // quick return
74 ff1 r7 // figure distance to skip
75 lsl r4,r7 // move the sentinel along (with 0's behind)
76 lsl r2,r7 // and the low 32 bits of numerator
78 // appears to be wrong...
79 // tested out incorrectly in our OS work...
80 // mov r7,r3 // looking at divisor
81 // ff1 r7 // I can move 32-r7 more bits to left.
82 // addi r7,1 // ok, one short of that...
84 // lsr r1,r7 // bits that came from low order...
85 // rsubi r7,31 // r7 == "32-n" == LEFT distance
86 // addi r7,1 // this is (32-n)
87 // lsl r4,r7 // fixes the high 32 (quotient)
90 // bf 4f // the sentinel went away...
92 // run the remaining bits
94 1: lslc r2,1 // 1 bit left shift of r1-r2
96 cmphs r1,r3 // upper 32 of dividend >= divisor?
98 sub r1,r3 // if yes, subtract divisor
99 2: addc r4,r4 // shift by 1 and count subtracts
100 bf 1b // if sentinel falls out of quotient, stop
102 4: mov r2,r4 // return quotient
103 mov r3,r1 // and piggyback the remainder
112 movi r1,0 // r1-r2 form 64 bit dividend
113 movi r4,1 // r4 is quotient (1 for a sentinel)
114 cmpnei r3,0 // look for 0 divisor
116 trap 3 // divide by 0
118 // control iterations; skip across high order 0 bits in dividend
122 movi r2,0 // 0 dividend
123 jmp r15 // quick return
125 ff1 r7 // figure distance to skip
126 lsl r4,r7 // move the sentinel along (with 0's behind)
127 lsl r2,r7 // and the low 32 bits of numerator
129 1: lslc r2,1 // 1 bit left shift of r1-r2
131 cmphs r1,r3 // upper 32 of dividend >= divisor?
133 sub r1,r3 // if yes, subtract divisor
134 2: addc r4,r4 // shift by 1 and count subtracts
135 bf 1b // if sentinel falls out of quotient, stop
136 mov r2,r1 // return remainder
145 mov r5,r2 // calc sign of quotient
147 abs r2 // do unsigned divide
149 movi r1,0 // r1-r2 form 64 bit dividend
150 movi r4,1 // r4 is quotient (1 for a sentinel)
151 cmpnei r3,0 // look for 0 divisor
153 trap 3 // divide by 0
155 // control iterations; skip across high order 0 bits in dividend
159 movi r2,0 // 0 dividend
160 jmp r15 // quick return
162 ff1 r7 // figure distance to skip
163 lsl r4,r7 // move the sentinel along (with 0's behind)
164 lsl r2,r7 // and the low 32 bits of numerator
166 // tested out incorrectly in our OS work...
167 // mov r7,r3 // looking at divisor
168 // ff1 r7 // I can move 32-r7 more bits to left.
169 // addi r7,1 // ok, one short of that...
171 // lsr r1,r7 // bits that came from low order...
172 // rsubi r7,31 // r7 == "32-n" == LEFT distance
173 // addi r7,1 // this is (32-n)
174 // lsl r4,r7 // fixes the high 32 (quotient)
177 // bf 4f // the sentinel went away...
179 // run the remaining bits
180 1: lslc r2,1 // 1 bit left shift of r1-r2
182 cmphs r1,r3 // upper 32 of dividend >= divisor?
184 sub r1,r3 // if yes, subtract divisor
185 2: addc r4,r4 // shift by 1 and count subtracts
186 bf 1b // if sentinel falls out of quotient, stop
188 4: mov r2,r4 // return quotient
189 mov r3,r1 // piggyback the remainder
190 btsti r5,31 // after adjusting for sign
202 mov r5,r2 // calc sign of remainder
203 abs r2 // do unsigned divide
205 movi r1,0 // r1-r2 form 64 bit dividend
206 movi r4,1 // r4 is quotient (1 for a sentinel)
207 cmpnei r3,0 // look for 0 divisor
209 trap 3 // divide by 0
211 // control iterations; skip across high order 0 bits in dividend
215 movi r2,0 // 0 dividend
216 jmp r15 // quick return
218 ff1 r7 // figure distance to skip
219 lsl r4,r7 // move the sentinel along (with 0's behind)
220 lsl r2,r7 // and the low 32 bits of numerator
222 1: lslc r2,1 // 1 bit left shift of r1-r2
224 cmphs r1,r3 // upper 32 of dividend >= divisor?
226 sub r1,r3 // if yes, subtract divisor
227 2: addc r4,r4 // shift by 1 and count subtracts
228 bf 1b // if sentinel falls out of quotient, stop
229 mov r2,r1 // return remainder
230 btsti r5,31 // after adjusting for sign
239 /* GCC expects that {__eq,__ne,__gt,__ge,__le,__lt}{df2,sf2}
240 will behave as __cmpdf2. So, we stub the implementations to
241 jump on to __cmpdf2 and __cmpsf2.
243 All of these shortcircuit the return path so that __cmp{sd}f2
244 will go directly back to the caller. */
246 .macro COMPARE_DF_JUMP name
254 COMPARE_DF_JUMP eqdf2
258 COMPARE_DF_JUMP nedf2
262 COMPARE_DF_JUMP gtdf2
266 COMPARE_DF_JUMP gedf2
270 COMPARE_DF_JUMP ltdf2
274 COMPARE_DF_JUMP ledf2
277 /* SINGLE PRECISION FLOATING POINT STUBS */
279 .macro COMPARE_SF_JUMP name
287 COMPARE_SF_JUMP eqsf2
291 COMPARE_SF_JUMP nesf2
295 COMPARE_SF_JUMP gtsf2
299 COMPARE_SF_JUMP __gesf2
303 COMPARE_SF_JUMP __ltsf2
307 COMPARE_SF_JUMP lesf2