PR c++/33620
[official-gcc.git] / gcc / config / arc / lib1funcs.asm
blob2d74cbee5bdae9ec52f3900a05dd0f9c882b894a
1 ; libgcc routines for ARC cpu.
3 /* Copyright (C) 1995, 1997,2004 Free Software Foundation, Inc.
5 This file is free software; you can redistribute it and/or modify it
6 under the terms of the GNU General Public License as published by the
7 Free Software Foundation; either version 2, or (at your option) any
8 later version.
10 In addition to the permissions in the GNU General Public License, the
11 Free Software Foundation gives you unlimited permission to link the
12 compiled version of this file into combinations with other programs,
13 and to distribute those combinations without any restriction coming
14 from the use of this file. (The General Public License restrictions
15 do apply in other respects; for example, they cover modification of
16 the file, and distribution when not linked into a combine
17 executable.)
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 GCC; see the file COPYING. If not, write to
26 the Free Software Foundation, 51 Franklin Street, Fifth Floor,
27 Boston, MA 02110-1301, USA. */
29 #ifdef L_mulsi3
30 .section .text
31 .align 4
33 #ifdef __base__
34 .cpu base
35 .global ___mulsi3
36 ___mulsi3:
38 /* This the simple version.
40 while (a)
42 if (a & 1)
43 r += b;
44 a >>= 1;
45 b <<= 1;
48 mov r2,0 ; Accumulate result here.
49 .Lloop:
50 sub.f 0,r0,0 ; while (a)
51 nop
52 beq.nd .Ldone
53 and.f 0,r0,1 ; if (a & 1)
54 add.nz r2,r2,r1 ; r += b
55 lsr r0,r0 ; a >>= 1
56 b.d .Lloop
57 lsl r1,r1 ; b <<= 1
58 .Ldone:
59 j.d blink
60 mov r0,r2
61 #endif
63 #endif /* L_mulsi3 */
65 #ifdef L_umulsidi3
66 .section .text
67 .align 4
69 #ifdef __base__
70 .cpu base
71 .global ___umulsidi3
72 ___umulsidi3:
74 /* This the simple version.
76 while (a)
78 if (a & 1)
79 r += b;
80 a >>= 1;
81 b <<= 1;
84 mov r2,0 ; Top part of b.
85 mov r3,0 ; Accumulate result here.
86 mov r4,0
87 .Lloop:
88 sub.f 0,r0,0 ; while (a)
89 nop
90 beq.nd .Ldone
91 and.f 0,r0,1 ; if (a & 1)
92 sub.f 0,r0,0
93 nop
94 beq .Ldontadd
95 add.f r4,r4,r1 ; r += b
96 adc r3,r3,r2
97 .Ldontadd:
98 lsr r0,r0 ; a >>= 1
99 lsl.f r1,r1 ; b <<= 1
100 b.d .Lloop
101 rlc r2,r2
102 .Ldone:
103 #ifdef __big_endian__
104 mov r1,r4
105 j.d blink
106 mov r0,r3
107 #else
108 mov r0,r4
109 j.d blink
110 mov r1,r3
111 #endif
112 #endif
114 #endif /* L_umulsidi3 */
116 #ifdef L_divmod_tools
118 ; Utilities used by all routines.
120 .section .text
121 .align 4
123 ; inputs: r0 = numerator, r1 = denominator
124 ; outputs: positive r0/r1,
125 ; r6.bit1 = sign of numerator, r6.bit0 = sign of result
127 .global ___divnorm
128 ___divnorm:
129 mov r6,0 ; keep sign in r6
130 sub.f 0,r0,0 ; is numerator -ve?
131 sub.lt r0,0,r0 ; negate numerator
132 mov.lt r6,3 ; sign is -ve
133 sub.f 0,r1,0 ; is denominator -ve?
134 sub.lt r1,0,r1 ; negate denominator
135 xor.lt r6,r6,1 ; toggle sign
136 j.nd blink
139 unsigned long
140 udivmodsi4(int modwanted, unsigned long num, unsigned long den)
142 unsigned long bit = 1;
143 unsigned long res = 0;
145 while (den < num && bit && !(den & (1L<<31)))
147 den <<=1;
148 bit <<=1;
150 while (bit)
152 if (num >= den)
154 num -= den;
155 res |= bit;
157 bit >>=1;
158 den >>=1;
160 if (modwanted) return num;
161 return res;
165 ; inputs: r0 = numerator, r1 = denominator
166 ; outputs: r0 = quotient, r1 = remainder, r2/r3 trashed
168 .global ___udivmodsi4
169 ___udivmodsi4:
170 mov r2,1 ; bit = 1
171 mov r3,0 ; res = 0
172 .Lloop1:
173 sub.f 0,r1,r0 ; while (den < num
175 bnc.nd .Lloop2
176 sub.f 0,r2,0 ; && bit
178 bz.nd .Lloop2
179 lsl.f 0,r1 ; && !(den & (1<<31))
181 bc.nd .Lloop2
182 lsl r1,r1 ; den <<= 1
183 b.d .Lloop1
184 lsl r2,r2 ; bit <<= 1
185 .Lloop2:
186 sub.f 0,r2,0 ; while (bit)
188 bz.nd .Ldivmodend
189 sub.f 0,r0,r1 ; if (num >= den)
191 bc.nd .Lshiftdown
192 sub r0,r0,r1 ; num -= den
193 or r3,r3,r2 ; res |= bit
194 .Lshiftdown:
195 lsr r2,r2 ; bit >>= 1
196 b.d .Lloop2
197 lsr r1,r1 ; den >>= 1
198 .Ldivmodend:
199 mov r1,r0 ; r1 = mod
200 j.d blink
201 mov r0,r3 ; r0 = res
203 #endif
205 #ifdef L_udivsi3
206 .section .text
207 .align 4
209 #ifdef __base__
210 .cpu base
211 .global ___udivsi3
212 ___udivsi3:
213 mov r7,blink
214 bl.nd ___udivmodsi4
215 j.nd r7
216 #endif
218 #endif /* L_udivsi3 */
220 #ifdef L_divsi3
221 .section .text
222 .align 4
224 #ifdef __base__
225 .cpu base
226 .global ___divsi3
227 ___divsi3:
228 mov r7,blink
229 bl.nd ___divnorm
230 bl.nd ___udivmodsi4
231 and.f 0,r6,1
232 sub.nz r0,0,r0 ; cannot go in delay slot, has limm value
233 j.nd r7
234 #endif
236 #endif /* L_divsi3 */
238 #ifdef L_umodsi3
239 .section .text
240 .align 4
242 #ifdef __base__
243 .cpu base
244 .global ___umodsi3
245 ___umodsi3:
246 mov r7,blink
247 bl.nd ___udivmodsi4
248 j.d r7
249 mov r0,r1
250 #endif
252 #endif /* L_umodsi3 */
254 #ifdef L_modsi3
255 .section .text
256 .align 4
258 #ifdef __base__
259 .cpu base
260 .global ___modsi3
261 ___modsi3:
262 mov r7,blink
263 bl.nd ___divnorm
264 bl.nd ___udivmodsi4
265 and.f 0,r6,2
266 sub.nz r1,0,r1
267 j.d r7
268 mov r0,r1
269 #endif
271 #endif /* L_modsi3 */