0
|
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 */
|