1 /* libgcc routines for the MCore.
2 Copyright (C) 1993-2018 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 3, or (at your option) any
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.
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.
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/>. */
25 #define CONCAT1(a, b) CONCAT2(a, b)
26 #define CONCAT2(a, b) a ## b
28 /* Use the right prefix for global labels. */
30 #define SYM(x) CONCAT1 (__, x)
33 #define TYPE(x) .type SYM (x),@function
34 #define SIZE(x) .size SYM (x), . - SYM (x)
40 .macro FUNC_START name
55 movi r1,0 // r1-r2 form 64 bit dividend
56 movi r4,1 // r4 is quotient (1 for a sentinel)
58 cmpnei r3,0 // look for 0 divisor
62 // control iterations; skip across high order 0 bits in dividend
66 movi r2,0 // 0 dividend
67 jmp r15 // quick return
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
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...
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)
85 // bf 4f // the sentinel went away...
87 // run the remaining bits
89 1: lslc r2,1 // 1 bit left shift of r1-r2
91 cmphs r1,r3 // upper 32 of dividend >= divisor?
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
97 4: mov r2,r4 // return quotient
98 mov r3,r1 // and piggyback the remainder
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
111 trap 3 // divide by 0
113 // control iterations; skip across high order 0 bits in dividend
117 movi r2,0 // 0 dividend
118 jmp r15 // quick return
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
124 1: lslc r2,1 // 1 bit left shift of r1-r2
126 cmphs r1,r3 // upper 32 of dividend >= divisor?
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
140 mov r5,r2 // calc sign of quotient
142 abs r2 // do unsigned divide
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
148 trap 3 // divide by 0
150 // control iterations; skip across high order 0 bits in dividend
154 movi r2,0 // 0 dividend
155 jmp r15 // quick return
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
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...
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)
172 // bf 4f // the sentinel went away...
174 // run the remaining bits
175 1: lslc r2,1 // 1 bit left shift of r1-r2
177 cmphs r1,r3 // upper 32 of dividend >= divisor?
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
183 4: mov r2,r4 // return quotient
184 mov r3,r1 // piggyback the remainder
185 btsti r5,31 // after adjusting for sign
197 mov r5,r2 // calc sign of remainder
198 abs r2 // do unsigned divide
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
204 trap 3 // divide by 0
206 // control iterations; skip across high order 0 bits in dividend
210 movi r2,0 // 0 dividend
211 jmp r15 // quick return
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
217 1: lslc r2,1 // 1 bit left shift of r1-r2
219 cmphs r1,r3 // upper 32 of dividend >= divisor?
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
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.
238 All of these shortcircuit the return path so that __cmp{sd}f2
239 will go directly back to the caller. */
241 .macro COMPARE_DF_JUMP name
249 COMPARE_DF_JUMP eqdf2
253 COMPARE_DF_JUMP nedf2
257 COMPARE_DF_JUMP gtdf2
261 COMPARE_DF_JUMP gedf2
265 COMPARE_DF_JUMP ltdf2
269 COMPARE_DF_JUMP ledf2
272 /* SINGLE PRECISION FLOATING POINT STUBS */
274 .macro COMPARE_SF_JUMP name
282 COMPARE_SF_JUMP eqsf2
286 COMPARE_SF_JUMP nesf2
290 COMPARE_SF_JUMP gtsf2
294 COMPARE_SF_JUMP __gesf2
298 COMPARE_SF_JUMP __ltsf2
302 COMPARE_SF_JUMP lesf2