OSDN Git Service

8b591c19213e13c1314a291928e5464b2d940902
[pf3gnuchains/gcc-fork.git] / gcc / config / arc / lib1funcs.asm
1 ; libgcc routines for ARC cpu.
2
3 /* Copyright (C) 1995, 1997,2004 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
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.)
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
25 along with GCC; see the file COPYING.  If not, write to
26 the Free Software Foundation, 59 Temple Place - Suite 330,
27 Boston, MA 02111-1307, USA.  */
28
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         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
113
114 #endif /* L_umulsidi3 */
115
116 #ifdef L_divmod_tools
117
118 ; Utilities used by all routines.
119
120         .section .text
121         .align 4
122
123 ; inputs: r0 = numerator, r1 = denominator
124 ; outputs: positive r0/r1,
125 ;          r6.bit1 = sign of numerator, r6.bit0 = sign of result
126
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
137
138 /*
139 unsigned long
140 udivmodsi4(int modwanted, unsigned long num, unsigned long den)
141 {
142   unsigned long bit = 1;
143   unsigned long res = 0;
144
145   while (den < num && bit && !(den & (1L<<31)))
146     {
147       den <<=1;
148       bit <<=1;
149     }
150   while (bit)
151     {
152       if (num >= den)
153         {
154           num -= den;
155           res |= bit;
156         }
157       bit >>=1;
158       den >>=1;
159     }
160   if (modwanted) return num;
161   return res;
162 }
163 */
164
165 ; inputs: r0 = numerator, r1 = denominator
166 ; outputs: r0 = quotient, r1 = remainder, r2/r3 trashed
167
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
174         nop
175         bnc.nd .Lloop2
176         sub.f 0,r2,0            ; && bit
177         nop
178         bz.nd .Lloop2
179         lsl.f 0,r1              ; && !(den & (1<<31))
180         nop
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)
187         nop
188         bz.nd .Ldivmodend
189         sub.f 0,r0,r1           ; if (num >= den)
190         nop
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
202
203 #endif
204
205 #ifdef  L_udivsi3
206         .section .text
207         .align 4
208
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
217
218 #endif /* L_udivsi3 */
219
220 #ifdef  L_divsi3
221         .section .text
222         .align 4
223
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
235
236 #endif /* L_divsi3 */
237
238 #ifdef  L_umodsi3
239         .section .text
240         .align 4
241
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
251
252 #endif /* L_umodsi3 */
253
254 #ifdef  L_modsi3
255         .section .text
256         .align 4
257
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
270
271 #endif /* L_modsi3 */