]>
Commit | Line | Data |
---|---|---|
7857f134 | 1 | ; libgcc routines for ARC cpu. |
6eb70e69 JL |
2 | |
3 | /* Copyright (C) 1995, 1997 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 2, or (at your option) any | |
8 | later version. | |
9 | ||
10 | In addition to the permissions in the GNU General Public License, the | |
11 | Free Software Foundation gives you unlimited permission to link the | |
f7af368f JL |
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.) | |
6eb70e69 JL |
18 | |
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. | |
23 | ||
24 | You should have received a copy of the GNU General Public License | |
7ec022b2 | 25 | along with GCC; see the file COPYING. If not, write to |
6eb70e69 JL |
26 | the Free Software Foundation, 59 Temple Place - Suite 330, |
27 | Boston, MA 02111-1307, USA. */ | |
28 | ||
6eb70e69 JL |
29 | #ifdef L_mulsi3 |
30 | .section .text | |
31 | .align 4 | |
32 | ||
33 | #ifdef __base__ | |
34 | .cpu base | |
35 | .global ___mulsi3 | |
36 | ___mulsi3: | |
37 | ||
38 | /* This the simple version. | |
39 | ||
40 | while (a) | |
41 | { | |
42 | if (a & 1) | |
43 | r += b; | |
44 | a >>= 1; | |
45 | b <<= 1; | |
46 | } | |
47 | */ | |
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 | |
62 | ||
63 | #endif /* L_mulsi3 */ | |
64 | ||
65 | #ifdef L_umulsidi3 | |
66 | .section .text | |
67 | .align 4 | |
68 | ||
69 | #ifdef __base__ | |
70 | .cpu base | |
71 | .global ___umulsidi3 | |
72 | ___umulsidi3: | |
73 | ||
74 | /* This the simple version. | |
75 | ||
76 | while (a) | |
77 | { | |
78 | if (a & 1) | |
79 | r += b; | |
80 | a >>= 1; | |
81 | b <<= 1; | |
82 | } | |
83 | */ | |
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 | add.nz r4,r4,r1 ; r += b | |
93 | adc.nz r3,r3,r2 | |
94 | lsr r0,r0 ; a >>= 1 | |
95 | lsl.f r1,r1 ; b <<= 1 | |
96 | b.d .Lloop | |
97 | rlc r2,r2 | |
98 | .Ldone: | |
99 | #ifdef __big_endian__ | |
100 | mov r1,r4 | |
101 | j.d blink | |
102 | mov r0,r3 | |
103 | #else | |
104 | mov r0,r4 | |
105 | j.d blink | |
106 | mov r1,r3 | |
107 | #endif | |
108 | #endif | |
109 | ||
110 | #endif /* L_umulsidi3 */ | |
111 | ||
112 | #ifdef L_divmod_tools | |
113 | ||
114 | ; Utilities used by all routines. | |
115 | ||
116 | .section .text | |
117 | .align 4 | |
118 | ||
119 | ; inputs: r0 = numerator, r1 = denominator | |
120 | ; outputs: positive r0/r1, | |
121 | ; r6.bit1 = sign of numerator, r6.bit0 = sign of result | |
122 | ||
123 | .global ___divnorm | |
124 | ___divnorm: | |
125 | mov r6,0 ; keep sign in r6 | |
126 | sub.f 0,r0,0 ; is numerator -ve? | |
127 | sub.lt r0,0,r0 ; negate numerator | |
128 | mov.lt r6,3 ; sign is -ve | |
129 | sub.f 0,r1,0 ; is denominator -ve? | |
130 | sub.lt r1,0,r1 ; negate denominator | |
131 | xor.lt r6,r6,1 ; toggle sign | |
132 | j.nd blink | |
133 | ||
134 | /* | |
135 | unsigned long | |
136 | udivmodsi4(int modwanted, unsigned long num, unsigned long den) | |
137 | { | |
138 | unsigned long bit = 1; | |
139 | unsigned long res = 0; | |
140 | ||
141 | while (den < num && bit && !(den & (1L<<31))) | |
142 | { | |
143 | den <<=1; | |
144 | bit <<=1; | |
145 | } | |
146 | while (bit) | |
147 | { | |
148 | if (num >= den) | |
149 | { | |
150 | num -= den; | |
151 | res |= bit; | |
152 | } | |
153 | bit >>=1; | |
154 | den >>=1; | |
155 | } | |
156 | if (modwanted) return num; | |
157 | return res; | |
158 | } | |
159 | */ | |
160 | ||
161 | ; inputs: r0 = numerator, r1 = denominator | |
162 | ; outputs: r0 = quotient, r1 = remainder, r2/r3 trashed | |
163 | ||
164 | .global ___udivmodsi4 | |
165 | ___udivmodsi4: | |
166 | mov r2,1 ; bit = 1 | |
167 | mov r3,0 ; res = 0 | |
168 | .Lloop1: | |
169 | sub.f 0,r1,r0 ; while (den < num | |
170 | nop | |
171 | bnc.nd .Lloop2 | |
172 | sub.f 0,r2,0 ; && bit | |
173 | nop | |
174 | bz.nd .Lloop2 | |
175 | lsl.f 0,r1 ; && !(den & (1<<31)) | |
176 | nop | |
177 | bc.nd .Lloop2 | |
178 | lsl r1,r1 ; den <<= 1 | |
179 | b.d .Lloop1 | |
180 | lsl r2,r2 ; bit <<= 1 | |
181 | .Lloop2: | |
182 | sub.f 0,r2,0 ; while (bit) | |
183 | nop | |
184 | bz.nd .Ldivmodend | |
185 | sub.f 0,r0,r1 ; if (num >= den) | |
186 | nop | |
187 | bc.nd .Lshiftdown | |
188 | sub r0,r0,r1 ; num -= den | |
189 | or r3,r3,r2 ; res |= bit | |
190 | .Lshiftdown: | |
191 | lsr r2,r2 ; bit >>= 1 | |
192 | b.d .Lloop2 | |
193 | lsr r1,r1 ; den >>= 1 | |
194 | .Ldivmodend: | |
195 | mov r1,r0 ; r1 = mod | |
196 | j.d blink | |
197 | mov r0,r3 ; r0 = res | |
198 | ||
199 | #endif | |
200 | ||
201 | #ifdef L_udivsi3 | |
202 | .section .text | |
203 | .align 4 | |
204 | ||
205 | #ifdef __base__ | |
206 | .cpu base | |
207 | .global ___udivsi3 | |
208 | ___udivsi3: | |
209 | mov r7,blink | |
210 | bl.nd ___udivmodsi4 | |
211 | j.nd r7 | |
212 | #endif | |
213 | ||
214 | #endif /* L_udivsi3 */ | |
215 | ||
216 | #ifdef L_divsi3 | |
217 | .section .text | |
218 | .align 4 | |
219 | ||
220 | #ifdef __base__ | |
221 | .cpu base | |
222 | .global ___divsi3 | |
223 | ___divsi3: | |
224 | mov r7,blink | |
225 | bl.nd ___divnorm | |
226 | bl.nd ___udivmodsi4 | |
227 | and.f 0,r6,1 | |
228 | sub.nz r0,0,r0 ; cannot go in delay slot, has limm value | |
229 | j.nd r7 | |
230 | #endif | |
231 | ||
232 | #endif /* L_divsi3 */ | |
233 | ||
234 | #ifdef L_umodsi3 | |
235 | .section .text | |
236 | .align 4 | |
237 | ||
238 | #ifdef __base__ | |
239 | .cpu base | |
240 | .global ___umodsi3 | |
241 | ___umodsi3: | |
242 | mov r7,blink | |
243 | bl.nd ___udivmodsi4 | |
244 | j.d r7 | |
245 | mov r0,r1 | |
246 | #endif | |
247 | ||
248 | #endif /* L_umodsi3 */ | |
249 | ||
250 | #ifdef L_modsi3 | |
251 | .section .text | |
252 | .align 4 | |
253 | ||
254 | #ifdef __base__ | |
255 | .cpu base | |
256 | .global ___modsi3 | |
257 | ___modsi3: | |
258 | mov r7,blink | |
259 | bl.nd ___divnorm | |
260 | bl.nd ___udivmodsi4 | |
261 | and.f 0,r6,2 | |
262 | sub.nz r1,0,r1 | |
263 | j.d r7 | |
264 | mov r0,r1 | |
265 | #endif | |
266 | ||
267 | #endif /* L_modsi3 */ |