OSDN Git Service

* config/sparc/freebsd.h (CPP_CPU64_DEFAULT_SPEC): Replace with...
[pf3gnuchains/gcc-fork.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 */