]> git.ipfire.org Git - thirdparty/gcc.git/blame - libgcc/config/mcore/lib1funcs.S
Update copyright years.
[thirdparty/gcc.git] / libgcc / config / mcore / lib1funcs.S
CommitLineData
7857f134 1/* libgcc routines for the MCore.
a5544970 2 Copyright (C) 1993-2019 Free Software Foundation, Inc.
8f90be4c 3
7ec022b2 4This file is part of GCC.
8f90be4c 5
7ec022b2 6GCC is free software; you can redistribute it and/or modify it
8f90be4c 7under the terms of the GNU General Public License as published by the
748086b7 8Free Software Foundation; either version 3, or (at your option) any
8f90be4c
NC
9later version.
10
8f90be4c
NC
11This file is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14General Public License for more details.
15
748086b7
JJ
16Under Section 7 of GPL version 3, you are granted additional
17permissions described in the GCC Runtime Library Exception, version
183.1, as published by the Free Software Foundation.
19
20You should have received a copy of the GNU General Public License and
21a copy of the GCC Runtime Library Exception along with this program;
22see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23<http://www.gnu.org/licenses/>. */
8f90be4c 24
8f90be4c
NC
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)
44SYM (\name):
45.endm
46
47.macro FUNC_END name
48 SIZE (\name)
49.endm
50
51#ifdef L_udivsi3
52FUNC_START udiv32
53FUNC_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
619:
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
688:
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
891: 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
942: addc r4,r4 // shift by 1 and count subtracts
95 bf 1b // if sentinel falls out of quotient, stop
96
974: mov r2,r4 // return quotient
98 mov r3,r1 // and piggyback the remainder
99 jmp r15
100FUNC_END udiv32
101FUNC_END udivsi32
102#endif
103
104#ifdef L_umodsi3
105FUNC_START urem32
106FUNC_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
1129:
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
1198:
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
1241: 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
1292: 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
133FUNC_END urem32
134FUNC_END umodsi3
135#endif
136
137#ifdef L_divsi3
138FUNC_START div32
139FUNC_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
1499:
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
1568:
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
1751: 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
1802: addc r4,r4 // shift by 1 and count subtracts
181 bf 1b // if sentinel falls out of quotient, stop
182
1834: 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
1893: jmp r15
190FUNC_END div32
191FUNC_END divsi3
192#endif
193
194#ifdef L_modsi3
195FUNC_START rem32
196FUNC_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
2059:
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
2128:
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
2171: 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
2222: 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
2283: jmp r15
229FUNC_END rem32
230FUNC_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
14bc6742 239 will go directly back to the caller. */
8f90be4c
NC
240
241.macro COMPARE_DF_JUMP name
242 .import SYM (cmpdf2)
243FUNC_START \name
244 jmpi SYM (cmpdf2)
245FUNC_END \name
246.endm
247
248#ifdef L_eqdf2
249COMPARE_DF_JUMP eqdf2
250#endif /* L_eqdf2 */
251
252#ifdef L_nedf2
253COMPARE_DF_JUMP nedf2
254#endif /* L_nedf2 */
255
256#ifdef L_gtdf2
257COMPARE_DF_JUMP gtdf2
258#endif /* L_gtdf2 */
259
260#ifdef L_gedf2
261COMPARE_DF_JUMP gedf2
262#endif /* L_gedf2 */
263
264#ifdef L_ltdf2
265COMPARE_DF_JUMP ltdf2
266#endif /* L_ltdf2 */
267
268#ifdef L_ledf2
269COMPARE_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)
276FUNC_START \name
277 jmpi SYM (cmpsf2)
278FUNC_END \name
279.endm
280
281#ifdef L_eqsf2
282COMPARE_SF_JUMP eqsf2
283#endif /* L_eqsf2 */
284
285#ifdef L_nesf2
286COMPARE_SF_JUMP nesf2
287#endif /* L_nesf2 */
288
289#ifdef L_gtsf2
290COMPARE_SF_JUMP gtsf2
291#endif /* L_gtsf2 */
292
293#ifdef L_gesf2
294COMPARE_SF_JUMP __gesf2
295#endif /* L_gesf2 */
296
297#ifdef L_ltsf2
298COMPARE_SF_JUMP __ltsf2
299#endif /* L_ltsf2 */
300
301#ifdef L_lesf2
302COMPARE_SF_JUMP lesf2
303#endif /* L_lesf2 */