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