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
, 59 Temple Place
- Suite
330,
28 Boston
, MA
02111-1307, 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