]> git.karo-electronics.de Git - mv-sheeva.git/blob - arch/sh/lib/udivsi3.S
sh: Add exports for __udivsi3/__sdivsi3 and the _i4 versions.
[mv-sheeva.git] / arch / sh / lib / udivsi3.S
1 /* Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
2    2004, 2005, 2006
3    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 this program; see the file COPYING.  If not, write to
26 the Free Software Foundation, 51 Franklin Street, Fifth Floor,
27 Boston, MA 02110-1301, USA.  */
28
29 !! libgcc routines for the Renesas / SuperH SH CPUs.
30 !! Contributed by Steve Chamberlain.
31 !! sac@cygnus.com
32
33 !! ashiftrt_r4_x, ___ashrsi3, ___ashlsi3, ___lshrsi3 routines
34 !! recoded in assembly by Toshiyasu Morita
35 !! tm@netcom.com
36
37 /* SH2 optimizations for ___ashrsi3, ___ashlsi3, ___lshrsi3 and
38    ELF local label prefixes by J"orn Rennecke
39    amylaar@cygnus.com  */
40
41 /* This code used shld, thus is not suitable for SH1 / SH2.  */
42
43 /* Signed / unsigned division without use of FPU, optimized for SH4.
44    Uses a lookup table for divisors in the range -128 .. +128, and
45    div1 with case distinction for larger divisors in three more ranges.
46    The code is lumped together with the table to allow the use of mova.  */
47 #ifdef CONFIG_CPU_LITTLE_ENDIAN
48 #define L_LSB 0
49 #define L_LSWMSB 1
50 #define L_MSWLSB 2
51 #else
52 #define L_LSB 3
53 #define L_LSWMSB 2
54 #define L_MSWLSB 1
55 #endif
56
57         .balign 4
58         .global __udivsi3_i4i
59         .global __udivsi3_i4
60         .global __udivsi3
61         .set    __udivsi3_i4, __udivsi3_i4i
62         .set    __udivsi3, __udivsi3_i4i
63         .type   __udivsi3_i4i, @function
64 __udivsi3_i4i:
65         mov.w c128_w, r1
66         div0u
67         mov r4,r0
68         shlr8 r0
69         cmp/hi r1,r5
70         extu.w r5,r1
71         bf udiv_le128
72         cmp/eq r5,r1
73         bf udiv_ge64k
74         shlr r0
75         mov r5,r1
76         shll16 r5
77         mov.l r4,@-r15
78         div1 r5,r0
79         mov.l r1,@-r15
80         div1 r5,r0
81         div1 r5,r0
82         bra udiv_25
83         div1 r5,r0
84
85 div_le128:
86         mova div_table_ix,r0
87         bra div_le128_2
88         mov.b @(r0,r5),r1
89 udiv_le128:
90         mov.l r4,@-r15
91         mova div_table_ix,r0
92         mov.b @(r0,r5),r1
93         mov.l r5,@-r15
94 div_le128_2:
95         mova div_table_inv,r0
96         mov.l @(r0,r1),r1
97         mov r5,r0
98         tst #0xfe,r0
99         mova div_table_clz,r0
100         dmulu.l r1,r4
101         mov.b @(r0,r5),r1
102         bt/s div_by_1
103         mov r4,r0
104         mov.l @r15+,r5
105         sts mach,r0
106         /* clrt */
107         addc r4,r0
108         mov.l @r15+,r4
109         rotcr r0
110         rts
111         shld r1,r0
112
113 div_by_1_neg:
114         neg r4,r0
115 div_by_1:
116         mov.l @r15+,r5
117         rts
118         mov.l @r15+,r4
119
120 div_ge64k:
121         bt/s div_r8
122         div0u
123         shll8 r5
124         bra div_ge64k_2
125         div1 r5,r0
126 udiv_ge64k:
127         cmp/hi r0,r5
128         mov r5,r1
129         bt udiv_r8
130         shll8 r5
131         mov.l r4,@-r15
132         div1 r5,r0
133         mov.l r1,@-r15
134 div_ge64k_2:
135         div1 r5,r0
136         mov.l zero_l,r1
137         .rept 4
138         div1 r5,r0
139         .endr
140         mov.l r1,@-r15
141         div1 r5,r0
142         mov.w m256_w,r1
143         div1 r5,r0
144         mov.b r0,@(L_LSWMSB,r15)
145         xor r4,r0
146         and r1,r0
147         bra div_ge64k_end
148         xor r4,r0
149         
150 div_r8:
151         shll16 r4
152         bra div_r8_2
153         shll8 r4
154 udiv_r8:
155         mov.l r4,@-r15
156         shll16 r4
157         clrt
158         shll8 r4
159         mov.l r5,@-r15
160 div_r8_2:
161         rotcl r4
162         mov r0,r1
163         div1 r5,r1
164         mov r4,r0
165         rotcl r0
166         mov r5,r4
167         div1 r5,r1
168         .rept 5
169         rotcl r0; div1 r5,r1
170         .endr
171         rotcl r0
172         mov.l @r15+,r5
173         div1 r4,r1
174         mov.l @r15+,r4
175         rts
176         rotcl r0
177
178         .global __sdivsi3_i4i
179         .global __sdivsi3_i4
180         .global __sdivsi3
181         .set    __sdivsi3_i4, __sdivsi3_i4i
182         .set    __sdivsi3, __sdivsi3_i4i
183         .type   __sdivsi3_i4i, @function
184         /* This is link-compatible with a __sdivsi3 call,
185            but we effectively clobber only r1.  */
186 __sdivsi3_i4i:
187         mov.l r4,@-r15
188         cmp/pz r5
189         mov.w c128_w, r1
190         bt/s pos_divisor
191         cmp/pz r4
192         mov.l r5,@-r15
193         neg r5,r5
194         bt/s neg_result
195         cmp/hi r1,r5
196         neg r4,r4
197 pos_result:
198         extu.w r5,r0
199         bf div_le128
200         cmp/eq r5,r0
201         mov r4,r0
202         shlr8 r0
203         bf/s div_ge64k
204         cmp/hi r0,r5
205         div0u
206         shll16 r5
207         div1 r5,r0
208         div1 r5,r0
209         div1 r5,r0
210 udiv_25:
211         mov.l zero_l,r1
212         div1 r5,r0
213         div1 r5,r0
214         mov.l r1,@-r15
215         .rept 3
216         div1 r5,r0
217         .endr
218         mov.b r0,@(L_MSWLSB,r15)
219         xtrct r4,r0
220         swap.w r0,r0
221         .rept 8
222         div1 r5,r0
223         .endr
224         mov.b r0,@(L_LSWMSB,r15)
225 div_ge64k_end:
226         .rept 8
227         div1 r5,r0
228         .endr
229         mov.l @r15+,r4 ! zero-extension and swap using LS unit.
230         extu.b r0,r0
231         mov.l @r15+,r5
232         or r4,r0
233         mov.l @r15+,r4
234         rts
235         rotcl r0
236
237 div_le128_neg:
238         tst #0xfe,r0
239         mova div_table_ix,r0
240         mov.b @(r0,r5),r1
241         mova div_table_inv,r0
242         bt/s div_by_1_neg
243         mov.l @(r0,r1),r1
244         mova div_table_clz,r0
245         dmulu.l r1,r4
246         mov.b @(r0,r5),r1
247         mov.l @r15+,r5
248         sts mach,r0
249         /* clrt */
250         addc r4,r0
251         mov.l @r15+,r4
252         rotcr r0
253         shld r1,r0
254         rts
255         neg r0,r0
256
257 pos_divisor:
258         mov.l r5,@-r15
259         bt/s pos_result
260         cmp/hi r1,r5
261         neg r4,r4
262 neg_result:
263         extu.w r5,r0
264         bf div_le128_neg
265         cmp/eq r5,r0
266         mov r4,r0
267         shlr8 r0
268         bf/s div_ge64k_neg
269         cmp/hi r0,r5
270         div0u
271         mov.l zero_l,r1
272         shll16 r5
273         div1 r5,r0
274         mov.l r1,@-r15
275         .rept 7
276         div1 r5,r0
277         .endr
278         mov.b r0,@(L_MSWLSB,r15)
279         xtrct r4,r0
280         swap.w r0,r0
281         .rept 8
282         div1 r5,r0
283         .endr
284         mov.b r0,@(L_LSWMSB,r15)
285 div_ge64k_neg_end:
286         .rept 8
287         div1 r5,r0
288         .endr
289         mov.l @r15+,r4 ! zero-extension and swap using LS unit.
290         extu.b r0,r1
291         mov.l @r15+,r5
292         or r4,r1
293 div_r8_neg_end:
294         mov.l @r15+,r4
295         rotcl r1
296         rts
297         neg r1,r0
298
299 div_ge64k_neg:
300         bt/s div_r8_neg
301         div0u
302         shll8 r5
303         mov.l zero_l,r1
304         .rept 6
305         div1 r5,r0
306         .endr
307         mov.l r1,@-r15
308         div1 r5,r0
309         mov.w m256_w,r1
310         div1 r5,r0
311         mov.b r0,@(L_LSWMSB,r15)
312         xor r4,r0
313         and r1,r0
314         bra div_ge64k_neg_end
315         xor r4,r0
316
317 c128_w:
318         .word 128
319
320 div_r8_neg:
321         clrt
322         shll16 r4
323         mov r4,r1
324         shll8 r1
325         mov r5,r4
326         .rept 7
327         rotcl r1; div1 r5,r0
328         .endr
329         mov.l @r15+,r5
330         rotcl r1
331         bra div_r8_neg_end
332         div1 r4,r0
333
334 m256_w:
335         .word 0xff00
336 /* This table has been generated by divtab-sh4.c.  */
337         .balign 4
338 div_table_clz:
339         .byte   0
340         .byte   1
341         .byte   0
342         .byte   -1
343         .byte   -1
344         .byte   -2
345         .byte   -2
346         .byte   -2
347         .byte   -2
348         .byte   -3
349         .byte   -3
350         .byte   -3
351         .byte   -3
352         .byte   -3
353         .byte   -3
354         .byte   -3
355         .byte   -3
356         .byte   -4
357         .byte   -4
358         .byte   -4
359         .byte   -4
360         .byte   -4
361         .byte   -4
362         .byte   -4
363         .byte   -4
364         .byte   -4
365         .byte   -4
366         .byte   -4
367         .byte   -4
368         .byte   -4
369         .byte   -4
370         .byte   -4
371         .byte   -4
372         .byte   -5
373         .byte   -5
374         .byte   -5
375         .byte   -5
376         .byte   -5
377         .byte   -5
378         .byte   -5
379         .byte   -5
380         .byte   -5
381         .byte   -5
382         .byte   -5
383         .byte   -5
384         .byte   -5
385         .byte   -5
386         .byte   -5
387         .byte   -5
388         .byte   -5
389         .byte   -5
390         .byte   -5
391         .byte   -5
392         .byte   -5
393         .byte   -5
394         .byte   -5
395         .byte   -5
396         .byte   -5
397         .byte   -5
398         .byte   -5
399         .byte   -5
400         .byte   -5
401         .byte   -5
402         .byte   -5
403         .byte   -5
404         .byte   -6
405         .byte   -6
406         .byte   -6
407         .byte   -6
408         .byte   -6
409         .byte   -6
410         .byte   -6
411         .byte   -6
412         .byte   -6
413         .byte   -6
414         .byte   -6
415         .byte   -6
416         .byte   -6
417         .byte   -6
418         .byte   -6
419         .byte   -6
420         .byte   -6
421         .byte   -6
422         .byte   -6
423         .byte   -6
424         .byte   -6
425         .byte   -6
426         .byte   -6
427         .byte   -6
428         .byte   -6
429         .byte   -6
430         .byte   -6
431         .byte   -6
432         .byte   -6
433         .byte   -6
434         .byte   -6
435         .byte   -6
436         .byte   -6
437         .byte   -6
438         .byte   -6
439         .byte   -6
440         .byte   -6
441         .byte   -6
442         .byte   -6
443         .byte   -6
444         .byte   -6
445         .byte   -6
446         .byte   -6
447         .byte   -6
448         .byte   -6
449         .byte   -6
450         .byte   -6
451         .byte   -6
452         .byte   -6
453         .byte   -6
454         .byte   -6
455         .byte   -6
456         .byte   -6
457         .byte   -6
458         .byte   -6
459         .byte   -6
460         .byte   -6
461         .byte   -6
462         .byte   -6
463         .byte   -6
464         .byte   -6
465         .byte   -6
466         .byte   -6
467 /* Lookup table translating positive divisor to index into table of
468    normalized inverse.  N.B. the '0' entry is also the last entry of the
469  previous table, and causes an unaligned access for division by zero.  */
470 div_table_ix:
471         .byte   -6
472         .byte   -128
473         .byte   -128
474         .byte   0
475         .byte   -128
476         .byte   -64
477         .byte   0
478         .byte   64
479         .byte   -128
480         .byte   -96
481         .byte   -64
482         .byte   -32
483         .byte   0
484         .byte   32
485         .byte   64
486         .byte   96
487         .byte   -128
488         .byte   -112
489         .byte   -96
490         .byte   -80
491         .byte   -64
492         .byte   -48
493         .byte   -32
494         .byte   -16
495         .byte   0
496         .byte   16
497         .byte   32
498         .byte   48
499         .byte   64
500         .byte   80
501         .byte   96
502         .byte   112
503         .byte   -128
504         .byte   -120
505         .byte   -112
506         .byte   -104
507         .byte   -96
508         .byte   -88
509         .byte   -80
510         .byte   -72
511         .byte   -64
512         .byte   -56
513         .byte   -48
514         .byte   -40
515         .byte   -32
516         .byte   -24
517         .byte   -16
518         .byte   -8
519         .byte   0
520         .byte   8
521         .byte   16
522         .byte   24
523         .byte   32
524         .byte   40
525         .byte   48
526         .byte   56
527         .byte   64
528         .byte   72
529         .byte   80
530         .byte   88
531         .byte   96
532         .byte   104
533         .byte   112
534         .byte   120
535         .byte   -128
536         .byte   -124
537         .byte   -120
538         .byte   -116
539         .byte   -112
540         .byte   -108
541         .byte   -104
542         .byte   -100
543         .byte   -96
544         .byte   -92
545         .byte   -88
546         .byte   -84
547         .byte   -80
548         .byte   -76
549         .byte   -72
550         .byte   -68
551         .byte   -64
552         .byte   -60
553         .byte   -56
554         .byte   -52
555         .byte   -48
556         .byte   -44
557         .byte   -40
558         .byte   -36
559         .byte   -32
560         .byte   -28
561         .byte   -24
562         .byte   -20
563         .byte   -16
564         .byte   -12
565         .byte   -8
566         .byte   -4
567         .byte   0
568         .byte   4
569         .byte   8
570         .byte   12
571         .byte   16
572         .byte   20
573         .byte   24
574         .byte   28
575         .byte   32
576         .byte   36
577         .byte   40
578         .byte   44
579         .byte   48
580         .byte   52
581         .byte   56
582         .byte   60
583         .byte   64
584         .byte   68
585         .byte   72
586         .byte   76
587         .byte   80
588         .byte   84
589         .byte   88
590         .byte   92
591         .byte   96
592         .byte   100
593         .byte   104
594         .byte   108
595         .byte   112
596         .byte   116
597         .byte   120
598         .byte   124
599         .byte   -128
600 /* 1/64 .. 1/127, normalized.  There is an implicit leading 1 in bit 32.  */
601         .balign 4
602 zero_l:
603         .long   0x0
604         .long   0xF81F81F9
605         .long   0xF07C1F08
606         .long   0xE9131AC0
607         .long   0xE1E1E1E2
608         .long   0xDAE6076C
609         .long   0xD41D41D5
610         .long   0xCD856891
611         .long   0xC71C71C8
612         .long   0xC0E07039
613         .long   0xBACF914D
614         .long   0xB4E81B4F
615         .long   0xAF286BCB
616         .long   0xA98EF607
617         .long   0xA41A41A5
618         .long   0x9EC8E952
619         .long   0x9999999A
620         .long   0x948B0FCE
621         .long   0x8F9C18FA
622         .long   0x8ACB90F7
623         .long   0x86186187
624         .long   0x81818182
625         .long   0x7D05F418
626         .long   0x78A4C818
627         .long   0x745D1746
628         .long   0x702E05C1
629         .long   0x6C16C16D
630         .long   0x68168169
631         .long   0x642C8591
632         .long   0x60581606
633         .long   0x5C9882BA
634         .long   0x58ED2309
635 div_table_inv:
636         .long   0x55555556
637         .long   0x51D07EAF
638         .long   0x4E5E0A73
639         .long   0x4AFD6A06
640         .long   0x47AE147B
641         .long   0x446F8657
642         .long   0x41414142
643         .long   0x3E22CBCF
644         .long   0x3B13B13C
645         .long   0x38138139
646         .long   0x3521CFB3
647         .long   0x323E34A3
648         .long   0x2F684BDB
649         .long   0x2C9FB4D9
650         .long   0x29E4129F
651         .long   0x27350B89
652         .long   0x24924925
653         .long   0x21FB7813
654         .long   0x1F7047DD
655         .long   0x1CF06ADB
656         .long   0x1A7B9612
657         .long   0x18118119
658         .long   0x15B1E5F8
659         .long   0x135C8114
660         .long   0x11111112
661         .long   0xECF56BF
662         .long   0xC9714FC
663         .long   0xA6810A7
664         .long   0x8421085
665         .long   0x624DD30
666         .long   0x4104105
667         .long   0x2040811
668         /* maximum error: 0.987342 scaled: 0.921875*/