OSDN Git Service

* config/score/crti.asm: add pic support.
[pf3gnuchains/gcc-fork.git] / gcc / config / score / mul-div.S
1 /* Copyright (C) 2005 Free Software Foundation, Inc.
2    Contributed by Sunnorth
3
4    This file is part of GCC.
5
6    GCC is free software; you can redistribute it and/or modify it
7    under the terms of the GNU General Public License as published
8    by the Free Software Foundation; either version 2, or (at your
9    option) any later version.
10
11    GCC is distributed in the hope that it will be useful, but WITHOUT
12    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
14    License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with GCC; see the file COPYING.  If not, write to
18    the Free Software Foundation, 51 Franklin Street, Fifth Floor,
19    Boston, MA 02110-1301, USA.  */
20
21 #define ra r3
22 #define a0 r4
23 #define a1 r5
24 #define a2 r6
25 #define a3 r7
26 #define v0 r23
27
28 #define t0 r8
29 #define t1 r9
30 #define t2 r10
31 #define t3 r11
32 #define t4 r22
33
34 #ifndef __pic__
35 #if !defined(L_mulsi3) && !defined(L_divsi3)
36        .text
37        .global _flush_cache
38 _flush_cache:
39         srli    r9, r5, 4
40         mv      r8, r4
41         mtsr    r9, sr0
42 1:
43         cache   0xe, [r8, 0]            # write back invalid dcache
44         addi    r8, 16
45         bcnz    1b
46         mfcr    r8, cr4
47         bittst! r8, 0x3                 # if LDM is enable, write back LDM
48         beq!    6f
49         ldi     r10, 0
50         cache   0xc, [r10, 0]
51 6:
52         bittst! r8, 0x2                 # if LIM is enable, refill it
53         beq!    7f
54         cache   0x4, [r10, 0]
55 7:
56         #nop!
57         #nop!
58         #nop!
59         #nop!
60         #nop!
61         mv      r8, r4
62         mtsr    r9, sr0
63 2:
64         cache   0x2, [r8, 0]            # invalid unlock icache
65         #nop!
66         #nop!
67         #nop!
68         #nop!
69         #nop!
70         addi    r8, 16
71         bcnz    2b
72         br      r3
73 #endif
74
75 /* FUNCTION
76    (U) INT32 v0 = __mulsi3 ((U) INT32 a0, (U) INT32 a1);
77    REGISTERS:
78         use     t0
79         modify  a0
80         a1      -> become 0
81    NOTE:
82    this seems to give better performance to just rotate and add.  */
83
84 #ifdef L_mulsi3
85         .text
86         .global __umulsi3
87         .global __mulsi3
88         /* signed multiplication (32x32)  */
89         .ent    __mulsi3
90 __umulsi3:
91 __mulsi3:
92         li      t1, 0
93 __mulsi3_loop:
94         andri.c t0, a1, 1               # t0 = multiplier[0]
95         srli    a1, a1, 1               # a1 /= 2
96         beq     __mulsi3_loop2          # skip if (t0 == 0)
97         add     t1, t1, a0              # add multiplicand
98 __mulsi3_loop2:
99         slli    a0, a0, 1               # multiplicand mul 2
100         cmpi.c  a1, 0
101         bne     __mulsi3_loop
102         mv      r4, t1
103         br      ra
104         .end    __mulsi3
105 #endif /* L_mulsi3 */
106
107 /* FUNCTION
108    UINT32 (v0) = __udivsi3 (UINT32 (a0), UINT32 (a1));
109    INT32 (v0) = __divsi3 (INT32 (a0),  INT32 (a1));
110    UINT32 (v0) = __umodsi3 (UINT32 (a0), UINT32 (a1));
111    INT32 (v0) = __modsi3 (INT32 (a0),  INT32 (a1));
112    DESCRIPTION
113    performs 32-bit division/modulo.
114    REGISTERS
115    used t0      bit-index
116         t1
117    modify a0    becomes remainer  */
118 #ifdef L_divsi3
119         .text
120         .global __udivsi3
121         .global __umodsi3
122         .global __divsi3
123         .global __modsi3
124
125         /* unsigned division  */
126         .ent    __udivsi3
127 __udivsi3:
128         li      t4, 0
129         cmpi.c  a1, 0
130         beq     __uds_exit
131         li      t0, 1
132         blt     __uds_ok
133 __uds_normalize:
134         cmp.c   a0, a1
135         bcc     __uds_ok
136         slli    a1, a1, 1
137         slli    t0, t0, 1
138         cmpi.c  a1, 0
139         bge     __uds_normalize
140 __uds_ok:
141 __uds_loop2:
142         cmp.c   a0, a1
143         bcc     __uds_loop3
144         sub     a0, a0, a1
145         or      t4, t4, t0
146 __uds_loop3:
147         srli    t0, t0, 1
148         srli    a1, a1, 1
149         cmpi.c  t0, 0
150         bne     __uds_loop2
151 __uds_exit:
152         mv      a1, a0
153         mv      r4, t4
154         br      ra
155         .end    __udivsi3
156
157         /* unsigned modulus  */
158         .ent    __umodsi3
159 __umodsi3:
160         mv      t3, ra
161         jl      __udivsi3
162         mv      r4, a1
163         br      t3
164         .end    __umodsi3
165
166         /* abs and div  */
167         .ent    __orgsi3
168 __orgsi3:
169         cmpi.c  a0, 0
170         bge     __orgsi3_a0p
171         neg     a0, a0
172 __orgsi3_a0p:
173         cmpi.c  a1, 0
174         bge     __udivsi3
175         neg     a1, a1
176         b       __udivsi3               # goto udivsi3
177         .end    __orgsi3
178
179         /* signed division  */
180         .ent    __divsi3
181 __divsi3:
182         mv      t3, ra
183         xor     t2, a0, a1
184         jl      __orgsi3
185 __divsi3_adjust:
186         cmpi.c  t2, 0
187         bge     __divsi3_exit
188         neg     r4, r4
189 __divsi3_exit:
190         br      t3
191         .end    __divsi3
192
193         /* signed modulus  */
194         .ent    __modsi3
195 __modsi3:
196         mv      t3, ra
197         mv      t2, a0
198         jl      __orgsi3
199         mv      r4, a1
200         b       __divsi3_adjust
201         .end    __modsi3
202
203 #endif /* L_divsi3 */
204 #else /* -fPIC */
205 #if !defined(L_mulsi3) && !defined(L_divsi3)
206         .set pic
207         .text
208         .global _flush_cache
209 _flush_cache:
210         addi    r0, -8                  # pic used
211         .cpload r29                     # pic used
212         srli    r9, r5, 4
213         mv      r8, r4
214         mtsr    r9, sr0
215 1:
216         cache   0xe, [r8, 0]            # write back invalid dcache
217         addi    r8, 16
218         bcnz    1b
219         mfcr    r8, cr4
220         bittst! r8, 0x3                 # if LDM is enable, write back LDM
221         beq!    6f
222         ldi     r10, 0
223         cache   0xc, [r10, 0]
224 6:
225         bittst! r8, 0x2                 # if LIM is enable, refill it
226         beq!    7f
227         cache   0x4, [r10, 0]
228 7:
229         #nop!
230         #nop!
231         #nop!
232         #nop!
233         #nop!
234         mv      r8, r4
235         mtsr    r9, sr0
236 2:
237         cache   0x2, [r8, 0]            # invalid unlock icache
238         #nop!
239         #nop!
240         #nop!
241         #nop!
242         #nop!
243         addi    r8, 16
244         bcnz    2b
245         .cprestore      12              # pic used
246         addi    r0, 8                   # pic used
247         br      r3
248 #endif
249
250 /* FUNCTION
251    (U) INT32 v0 = __mulsi3 ((U) INT32 a0, (U) INT32 a1);
252    REGISTERS:
253         use     t0
254         modify  a0
255         a1      -> become 0
256    NOTE:
257    this seems to give better performance to just rotate and add.  */
258
259 #ifdef L_mulsi3
260         .set pic
261         .text
262         .global __umulsi3
263         .global __mulsi3
264         /* signed multiplication (32x32)  */
265         .ent    __mulsi3
266 __umulsi3:
267 __mulsi3:
268         addi    r0, -8                  # pic used
269         .cpload r29                     # pic used
270         li      t1, 0
271 __mulsi3_loop:
272         andri.c t0, a1, 1               # t0 = multiplier[0]
273         srli    a1, a1, 1               # a1 /= 2
274         beq     __mulsi3_loop2          # skip if (t0 == 0)
275         add     t1, t1, a0              # add multiplicand
276 __mulsi3_loop2:
277         slli    a0, a0, 1               # multiplicand mul 2
278         cmpi.c  a1, 0
279         bne     __mulsi3_loop
280         mv      r4, t1
281         .cprestore 12                   # pic used
282         addi    r0, 8                   # pic used
283         br      ra
284         .end    __mulsi3
285 #endif /* L_mulsi3 */
286
287 /* FUNCTION
288    UINT32 (v0) = __udivsi3 (UINT32 (a0), UINT32 (a1));
289    INT32 (v0) = __divsi3 (INT32 (a0),  INT32 (a1));
290    UINT32 (v0) = __umodsi3 (UINT32 (a0), UINT32 (a1));
291    INT32 (v0) = __modsi3 (INT32 (a0),  INT32 (a1));
292    DESCRIPTION
293    performs 32-bit division/modulo.
294    REGISTERS
295    used t0      bit-index
296         t1
297    modify a0    becomes remainer  */
298 #ifdef L_divsi3
299         .set pic
300         .text
301         .global __udivsi3
302         .global __umodsi3
303         .global __divsi3
304         .global __modsi3
305
306         /* unsigned division  */
307         .ent    __udivsi3
308 __udivsi3:
309         addi    r0, -8                  # pic used
310         .cpload r29                     # pic used
311         li      t4, 0
312         cmpi.c  a1, 0
313         beq     __uds_exit
314         li      t0, 1
315         blt     __uds_ok
316 __uds_normalize:
317         cmp.c   a0, a1
318         bcc     __uds_ok
319         slli    a1, a1, 1
320         slli    t0, t0, 1
321         cmpi.c  a1, 0
322         bge     __uds_normalize
323 __uds_ok:
324 __uds_loop2:
325         cmp.c   a0, a1
326         bcc     __uds_loop3
327         sub     a0, a0, a1
328         or      t4, t4, t0
329 __uds_loop3:
330         srli    t0, t0, 1
331         srli    a1, a1, 1
332         cmpi.c  t0, 0
333         bne     __uds_loop2
334 __uds_exit:
335         mv      a1, a0
336         mv      r4, t4
337         .cprestore 12                   # pic used
338         addi    r0, 8                   # pic used
339         br      ra
340         .end    __udivsi3
341
342         /* unsigned modulus  */
343         .ent    __umodsi3
344 __umodsi3:
345         addi    r0, -8                  # pic used
346         .cpload r29                     # pic used
347         li      t1, 0
348         mv      t3, ra
349 #       jl      __udivsi3
350         la      r29, __udivsi3
351         brl     r29
352         mv      r4, a1
353         .cprestore 12                   # pic used
354         addi    r0, 8                   # pic used
355         br      t3
356         .end    __umodsi3
357
358         /* abs and div  */
359         .ent    __orgsi3
360 __orgsi3:
361         cmpi.c  a0, 0
362         bge     __orgsi3_a0p
363         neg     a0, a0
364 __orgsi3_a0p:
365         cmpi.c  a1, 0
366         bge     __udivsi3
367         neg     a1, a1
368         b       __udivsi3               # goto udivsi3
369         .end    __orgsi3
370
371         /* signed division  */
372         .ent    __divsi3
373 __divsi3:
374         addi    r0, -8                  # pic used
375         .cpload r29                     # pic used
376         mv      t3, ra
377         xor     t2, a0, a1
378 #       jl      __orgsi3
379         la      r29, __orgsi3
380         brl     r29
381 __divsi3_adjust:
382         cmpi.c  t2, 0
383         bge     __divsi3_exit
384         neg     r4, r4
385 __divsi3_exit:
386         .cprestore 12                   # pic used
387         addi    r0, 8                   # pic used
388         br      t3
389         .end    __divsi3
390
391         /* signed modulus  */
392         .ent    __modsi3
393 __modsi3:
394         addi    r0, -8                  # pic used
395         .cpload r29                     # pic used
396         mv      t3, ra
397         mv      t2, a0
398 #       jl      __orgsi3
399         la      r29, __orgsi3
400         brl     r29
401         mv      r4, a1
402         b       __divsi3_adjust
403         .end    __modsi3
404
405 #endif /*L_divsi3 */
406 #endif