c61f39a5ca701eb679bc3ab2a413c6ee939e1ec2
[gcc.git] / gcc / config / arc / lib1funcs.asm
1 ; libgcc routines for ARC cpu.
2
3 /* Copyright (C) 1995, 1997,2004, 2009 Free Software Foundation, Inc.
4
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 3, or (at your option) any
8 later version.
9
10 This file is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 Under Section 7 of GPL version 3, you are granted additional
16 permissions described in the GCC Runtime Library Exception, version
17 3.1, as published by the Free Software Foundation.
18
19 You should have received a copy of the GNU General Public License and
20 a copy of the GCC Runtime Library Exception along with this program;
21 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
22 <http://www.gnu.org/licenses/>. */
23
24 #ifdef L_mulsi3
25 .section .text
26 .align 4
27
28 #ifdef __base__
29 .cpu base
30 .global ___mulsi3
31 ___mulsi3:
32
33 /* This the simple version.
34
35 while (a)
36 {
37 if (a & 1)
38 r += b;
39 a >>= 1;
40 b <<= 1;
41 }
42 */
43 mov r2,0 ; Accumulate result here.
44 .Lloop:
45 sub.f 0,r0,0 ; while (a)
46 nop
47 beq.nd .Ldone
48 and.f 0,r0,1 ; if (a & 1)
49 add.nz r2,r2,r1 ; r += b
50 lsr r0,r0 ; a >>= 1
51 b.d .Lloop
52 lsl r1,r1 ; b <<= 1
53 .Ldone:
54 j.d blink
55 mov r0,r2
56 #endif
57
58 #endif /* L_mulsi3 */
59
60 #ifdef L_umulsidi3
61 .section .text
62 .align 4
63
64 #ifdef __base__
65 .cpu base
66 .global ___umulsidi3
67 ___umulsidi3:
68
69 /* This the simple version.
70
71 while (a)
72 {
73 if (a & 1)
74 r += b;
75 a >>= 1;
76 b <<= 1;
77 }
78 */
79 mov r2,0 ; Top part of b.
80 mov r3,0 ; Accumulate result here.
81 mov r4,0
82 .Lloop:
83 sub.f 0,r0,0 ; while (a)
84 nop
85 beq.nd .Ldone
86 and.f 0,r0,1 ; if (a & 1)
87 sub.f 0,r0,0
88 nop
89 beq .Ldontadd
90 add.f r4,r4,r1 ; r += b
91 adc r3,r3,r2
92 .Ldontadd:
93 lsr r0,r0 ; a >>= 1
94 lsl.f r1,r1 ; b <<= 1
95 b.d .Lloop
96 rlc r2,r2
97 .Ldone:
98 #ifdef __big_endian__
99 mov r1,r4
100 j.d blink
101 mov r0,r3
102 #else
103 mov r0,r4
104 j.d blink
105 mov r1,r3
106 #endif
107 #endif
108
109 #endif /* L_umulsidi3 */
110
111 #ifdef L_divmod_tools
112
113 ; Utilities used by all routines.
114
115 .section .text
116 .align 4
117
118 ; inputs: r0 = numerator, r1 = denominator
119 ; outputs: positive r0/r1,
120 ; r6.bit1 = sign of numerator, r6.bit0 = sign of result
121
122 .global ___divnorm
123 ___divnorm:
124 mov r6,0 ; keep sign in r6
125 sub.f 0,r0,0 ; is numerator -ve?
126 sub.lt r0,0,r0 ; negate numerator
127 mov.lt r6,3 ; sign is -ve
128 sub.f 0,r1,0 ; is denominator -ve?
129 sub.lt r1,0,r1 ; negate denominator
130 xor.lt r6,r6,1 ; toggle sign
131 j.nd blink
132
133 /*
134 unsigned long
135 udivmodsi4(int modwanted, unsigned long num, unsigned long den)
136 {
137 unsigned long bit = 1;
138 unsigned long res = 0;
139
140 while (den < num && bit && !(den & (1L<<31)))
141 {
142 den <<=1;
143 bit <<=1;
144 }
145 while (bit)
146 {
147 if (num >= den)
148 {
149 num -= den;
150 res |= bit;
151 }
152 bit >>=1;
153 den >>=1;
154 }
155 if (modwanted) return num;
156 return res;
157 }
158 */
159
160 ; inputs: r0 = numerator, r1 = denominator
161 ; outputs: r0 = quotient, r1 = remainder, r2/r3 trashed
162
163 .global ___udivmodsi4
164 ___udivmodsi4:
165 mov r2,1 ; bit = 1
166 mov r3,0 ; res = 0
167 .Lloop1:
168 sub.f 0,r1,r0 ; while (den < num
169 nop
170 bnc.nd .Lloop2
171 sub.f 0,r2,0 ; && bit
172 nop
173 bz.nd .Lloop2
174 lsl.f 0,r1 ; && !(den & (1<<31))
175 nop
176 bc.nd .Lloop2
177 lsl r1,r1 ; den <<= 1
178 b.d .Lloop1
179 lsl r2,r2 ; bit <<= 1
180 .Lloop2:
181 sub.f 0,r2,0 ; while (bit)
182 nop
183 bz.nd .Ldivmodend
184 sub.f 0,r0,r1 ; if (num >= den)
185 nop
186 bc.nd .Lshiftdown
187 sub r0,r0,r1 ; num -= den
188 or r3,r3,r2 ; res |= bit
189 .Lshiftdown:
190 lsr r2,r2 ; bit >>= 1
191 b.d .Lloop2
192 lsr r1,r1 ; den >>= 1
193 .Ldivmodend:
194 mov r1,r0 ; r1 = mod
195 j.d blink
196 mov r0,r3 ; r0 = res
197
198 #endif
199
200 #ifdef L_udivsi3
201 .section .text
202 .align 4
203
204 #ifdef __base__
205 .cpu base
206 .global ___udivsi3
207 ___udivsi3:
208 mov r7,blink
209 bl.nd ___udivmodsi4
210 j.nd r7
211 #endif
212
213 #endif /* L_udivsi3 */
214
215 #ifdef L_divsi3
216 .section .text
217 .align 4
218
219 #ifdef __base__
220 .cpu base
221 .global ___divsi3
222 ___divsi3:
223 mov r7,blink
224 bl.nd ___divnorm
225 bl.nd ___udivmodsi4
226 and.f 0,r6,1
227 sub.nz r0,0,r0 ; cannot go in delay slot, has limm value
228 j.nd r7
229 #endif
230
231 #endif /* L_divsi3 */
232
233 #ifdef L_umodsi3
234 .section .text
235 .align 4
236
237 #ifdef __base__
238 .cpu base
239 .global ___umodsi3
240 ___umodsi3:
241 mov r7,blink
242 bl.nd ___udivmodsi4
243 j.d r7
244 mov r0,r1
245 #endif
246
247 #endif /* L_umodsi3 */
248
249 #ifdef L_modsi3
250 .section .text
251 .align 4
252
253 #ifdef __base__
254 .cpu base
255 .global ___modsi3
256 ___modsi3:
257 mov r7,blink
258 bl.nd ___divnorm
259 bl.nd ___udivmodsi4
260 and.f 0,r6,2
261 sub.nz r1,0,r1
262 j.d r7
263 mov r0,r1
264 #endif
265
266 #endif /* L_modsi3 */