aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi YOSHII <yoshii.takashi@renesas.com>2008-12-07 21:33:06 -0500
committerPaul Mundt <lethal@linux-sh.org>2008-12-22 04:43:53 -0500
commit3b041227f7ef7c7e97f205c68c6069c0c62e5204 (patch)
treea860f34b268a257611415f33ea8f9df4ad188cb6
parent1fdae0e59a3fc9e391d2422ddcfbdbdec1e8f724 (diff)
sh: Add plain udivsi3 (not _i4*) for gcc-4.1 and lower.
We chan't share code for udivsi3 and udivsi3_i4, because they have a different clobber list. Copy udivsi3 from gcc-4.1.2. As shown in arch/sh/lib/udivsi3.S (and -Os.S), .global __udivsi3_i4i .global __udivsi3_i4 .global __udivsi3 __udivsi3_i4i: ... Three symbols are sharing one code, which is actually udivsi3_i4i. But, this results unwanted code with gcc 4.1. In gcc, these three are treated as pseudo instructions that have their own clobber list apart from the usual calling convention. According to sh's machine description. The clobber list is as follows: - udivsi3_i4i : t,r1,pr,mach,macl - udivsi3_i4 : t,r0,r1,r4,r5,pr,dr0,dr2,dr4 - udivsi3 : t,r4,pr The caller of udivsi3 will be left with a broken r1 and mac*. gcc-4.1.x and older(at least to 3.4) generate udivsi3. ST's gcc-4.1.1 seems to be OK because it has _i4i. Signed-off-by: Takashi YOSHII <yoshii.takashi@renesas.com> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
-rw-r--r--arch/sh/lib/Makefile7
-rw-r--r--arch/sh/lib/udivsi3.S667
-rw-r--r--arch/sh/lib/udivsi3_i4i-Os.S (renamed from arch/sh/lib/udivsi3-Os.S)2
-rw-r--r--arch/sh/lib/udivsi3_i4i.S666
4 files changed, 713 insertions, 629 deletions
diff --git a/arch/sh/lib/Makefile b/arch/sh/lib/Makefile
index a30acb8342d9..aaea580b65bb 100644
--- a/arch/sh/lib/Makefile
+++ b/arch/sh/lib/Makefile
@@ -10,12 +10,13 @@ lib-y += movmem.o ashldi3.o ashrdi3.o lshrdi3.o \
10 ashlsi3.o ashrsi3.o ashiftrt.o lshrsi3.o \ 10 ashlsi3.o ashrsi3.o ashiftrt.o lshrsi3.o \
11 udiv_qrnnd.o 11 udiv_qrnnd.o
12 12
13udivsi3-y := udivsi3-Os.o 13udivsi3-y := udivsi3_i4i-Os.o
14 14
15ifneq ($(CONFIG_CC_OPTIMIZE_FOR_SIZE),y) 15ifneq ($(CONFIG_CC_OPTIMIZE_FOR_SIZE),y)
16udivsi3-$(CONFIG_CPU_SH3) := udivsi3.o 16udivsi3-$(CONFIG_CPU_SH3) := udivsi3_i4i.o
17udivsi3-$(CONFIG_CPU_SH4) := udivsi3.o 17udivsi3-$(CONFIG_CPU_SH4) := udivsi3_i4i.o
18endif 18endif
19udivsi3-y += udivsi3.o
19 20
20obj-y += io.o 21obj-y += io.o
21 22
diff --git a/arch/sh/lib/udivsi3.S b/arch/sh/lib/udivsi3.S
index 388e15d75193..72157ab5c314 100644
--- a/arch/sh/lib/udivsi3.S
+++ b/arch/sh/lib/udivsi3.S
@@ -1,5 +1,5 @@
1/* Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 1/* Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
2 2004, 2005, 2006 2 2004, 2005
3 Free Software Foundation, Inc. 3 Free Software Foundation, Inc.
4 4
5This file is free software; you can redistribute it and/or modify it 5This file is free software; you can redistribute it and/or modify it
@@ -30,639 +30,58 @@ Boston, MA 02110-1301, USA. */
30!! Contributed by Steve Chamberlain. 30!! Contributed by Steve Chamberlain.
31!! sac@cygnus.com 31!! sac@cygnus.com
32 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 33 .balign 4
58 .global __udivsi3_i4i
59 .global __udivsi3_i4
60 .global __udivsi3 34 .global __udivsi3
61 .set __udivsi3_i4, __udivsi3_i4i 35 .type __udivsi3, @function
62 .set __udivsi3, __udivsi3_i4i 36div8:
63 .type __udivsi3_i4i, @function 37 div1 r5,r4
64__udivsi3_i4i: 38div7:
65 mov.w c128_w, r1 39 div1 r5,r4; div1 r5,r4; div1 r5,r4
66 div0u 40 div1 r5,r4; div1 r5,r4; div1 r5,r4; rts; div1 r5,r4
67 mov r4,r0 41
68 shlr8 r0 42divx4:
69 cmp/hi r1,r5 43 div1 r5,r4; rotcl r0
70 extu.w r5,r1 44 div1 r5,r4; rotcl r0
71 bf udiv_le128 45 div1 r5,r4; rotcl r0
72 cmp/eq r5,r1 46 rts; div1 r5,r4
73 bf udiv_ge64k 47
74 shlr r0 48__udivsi3:
75 mov r5,r1 49 sts.l pr,@-r15
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
85div_le128:
86 mova div_table_ix,r0
87 bra div_le128_2
88 mov.b @(r0,r5),r1
89udiv_le128:
90 mov.l r4,@-r15
91 mova div_table_ix,r0
92 mov.b @(r0,r5),r1
93 mov.l r5,@-r15
94div_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
113div_by_1_neg:
114 neg r4,r0
115div_by_1:
116 mov.l @r15+,r5
117 rts
118 mov.l @r15+,r4
119
120div_ge64k:
121 bt/s div_r8
122 div0u
123 shll8 r5
124 bra div_ge64k_2
125 div1 r5,r0
126udiv_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
134div_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
150div_r8:
151 shll16 r4
152 bra div_r8_2
153 shll8 r4
154udiv_r8:
155 mov.l r4,@-r15
156 shll16 r4
157 clrt
158 shll8 r4
159 mov.l r5,@-r15
160div_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
197pos_result:
198 extu.w r5,r0 50 extu.w r5,r0
199 bf div_le128
200 cmp/eq r5,r0 51 cmp/eq r5,r0
201 mov r4,r0 52 bf/s large_divisor
202 shlr8 r0
203 bf/s div_ge64k
204 cmp/hi r0,r5
205 div0u 53 div0u
54 swap.w r4,r0
55 shlr16 r4
56 bsr div8
206 shll16 r5 57 shll16 r5
207 div1 r5,r0 58 bsr div7
208 div1 r5,r0 59 div1 r5,r4
209 div1 r5,r0 60 xtrct r4,r0
210udiv_25: 61 xtrct r0,r4
211 mov.l zero_l,r1 62 bsr div8
212 div1 r5,r0 63 swap.w r4,r4
213 div1 r5,r0 64 bsr div7
214 mov.l r1,@-r15 65 div1 r5,r4
215 .rept 3 66 lds.l @r15+,pr
216 div1 r5,r0
217 .endr
218 mov.b r0,@(L_MSWLSB,r15)
219 xtrct r4,r0 67 xtrct r4,r0
220 swap.w r0,r0 68 swap.w r0,r0
221 .rept 8
222 div1 r5,r0
223 .endr
224 mov.b r0,@(L_LSWMSB,r15)
225div_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 69 rotcl r0
236
237div_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 70 rts
255 neg r0,r0 71 shlr16 r5
256 72
257pos_divisor: 73large_divisor:
258 mov.l r5,@-r15 74 mov #0,r0
259 bt/s pos_result
260 cmp/hi r1,r5
261 neg r4,r4
262neg_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 75 xtrct r4,r0
280 swap.w r0,r0 76 xtrct r0,r4
281 .rept 8 77 bsr divx4
282 div1 r5,r0 78 rotcl r0
283 .endr 79 bsr divx4
284 mov.b r0,@(L_LSWMSB,r15) 80 rotcl r0
285div_ge64k_neg_end: 81 bsr divx4
286 .rept 8 82 rotcl r0
287 div1 r5,r0 83 bsr divx4
288 .endr 84 rotcl r0
289 mov.l @r15+,r4 ! zero-extension and swap using LS unit. 85 lds.l @r15+,pr
290 extu.b r0,r1
291 mov.l @r15+,r5
292 or r4,r1
293div_r8_neg_end:
294 mov.l @r15+,r4
295 rotcl r1
296 rts 86 rts
297 neg r1,r0 87 rotcl r0
298
299div_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
317c128_w:
318 .word 128
319
320div_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
334m256_w:
335 .word 0xff00
336/* This table has been generated by divtab-sh4.c. */
337 .balign 4
338div_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. */
470div_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
602zero_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
635div_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*/
diff --git a/arch/sh/lib/udivsi3-Os.S b/arch/sh/lib/udivsi3_i4i-Os.S
index 110c5ea769e0..4835553e1ea9 100644
--- a/arch/sh/lib/udivsi3-Os.S
+++ b/arch/sh/lib/udivsi3_i4i-Os.S
@@ -41,9 +41,7 @@ Boston, MA 02110-1301, USA. */
41 .balign 4 41 .balign 4
42 .global __udivsi3_i4i 42 .global __udivsi3_i4i
43 .global __udivsi3_i4 43 .global __udivsi3_i4
44 .global __udivsi3
45 .set __udivsi3_i4, __udivsi3_i4i 44 .set __udivsi3_i4, __udivsi3_i4i
46 .set __udivsi3, __udivsi3_i4i
47 .type __udivsi3_i4i, @function 45 .type __udivsi3_i4i, @function
48 .type __sdivsi3_i4i, @function 46 .type __sdivsi3_i4i, @function
49__udivsi3_i4i: 47__udivsi3_i4i:
diff --git a/arch/sh/lib/udivsi3_i4i.S b/arch/sh/lib/udivsi3_i4i.S
new file mode 100644
index 000000000000..f1a79d9c5015
--- /dev/null
+++ b/arch/sh/lib/udivsi3_i4i.S
@@ -0,0 +1,666 @@
1/* Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
2 2004, 2005, 2006
3 Free Software Foundation, Inc.
4
5This file is free software; you can redistribute it and/or modify it
6under the terms of the GNU General Public License as published by the
7Free Software Foundation; either version 2, or (at your option) any
8later version.
9
10In addition to the permissions in the GNU General Public License, the
11Free Software Foundation gives you unlimited permission to link the
12compiled version of this file into combinations with other programs,
13and to distribute those combinations without any restriction coming
14from the use of this file. (The General Public License restrictions
15do apply in other respects; for example, they cover modification of
16the file, and distribution when not linked into a combine
17executable.)
18
19This file is distributed in the hope that it will be useful, but
20WITHOUT ANY WARRANTY; without even the implied warranty of
21MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22General Public License for more details.
23
24You should have received a copy of the GNU General Public License
25along with this program; see the file COPYING. If not, write to
26the Free Software Foundation, 51 Franklin Street, Fifth Floor,
27Boston, 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 .set __udivsi3_i4, __udivsi3_i4i
61 .type __udivsi3_i4i, @function
62__udivsi3_i4i:
63 mov.w c128_w, r1
64 div0u
65 mov r4,r0
66 shlr8 r0
67 cmp/hi r1,r5
68 extu.w r5,r1
69 bf udiv_le128
70 cmp/eq r5,r1
71 bf udiv_ge64k
72 shlr r0
73 mov r5,r1
74 shll16 r5
75 mov.l r4,@-r15
76 div1 r5,r0
77 mov.l r1,@-r15
78 div1 r5,r0
79 div1 r5,r0
80 bra udiv_25
81 div1 r5,r0
82
83div_le128:
84 mova div_table_ix,r0
85 bra div_le128_2
86 mov.b @(r0,r5),r1
87udiv_le128:
88 mov.l r4,@-r15
89 mova div_table_ix,r0
90 mov.b @(r0,r5),r1
91 mov.l r5,@-r15
92div_le128_2:
93 mova div_table_inv,r0
94 mov.l @(r0,r1),r1
95 mov r5,r0
96 tst #0xfe,r0
97 mova div_table_clz,r0
98 dmulu.l r1,r4
99 mov.b @(r0,r5),r1
100 bt/s div_by_1
101 mov r4,r0
102 mov.l @r15+,r5
103 sts mach,r0
104 /* clrt */
105 addc r4,r0
106 mov.l @r15+,r4
107 rotcr r0
108 rts
109 shld r1,r0
110
111div_by_1_neg:
112 neg r4,r0
113div_by_1:
114 mov.l @r15+,r5
115 rts
116 mov.l @r15+,r4
117
118div_ge64k:
119 bt/s div_r8
120 div0u
121 shll8 r5
122 bra div_ge64k_2
123 div1 r5,r0
124udiv_ge64k:
125 cmp/hi r0,r5
126 mov r5,r1
127 bt udiv_r8
128 shll8 r5
129 mov.l r4,@-r15
130 div1 r5,r0
131 mov.l r1,@-r15
132div_ge64k_2:
133 div1 r5,r0
134 mov.l zero_l,r1
135 .rept 4
136 div1 r5,r0
137 .endr
138 mov.l r1,@-r15
139 div1 r5,r0
140 mov.w m256_w,r1
141 div1 r5,r0
142 mov.b r0,@(L_LSWMSB,r15)
143 xor r4,r0
144 and r1,r0
145 bra div_ge64k_end
146 xor r4,r0
147
148div_r8:
149 shll16 r4
150 bra div_r8_2
151 shll8 r4
152udiv_r8:
153 mov.l r4,@-r15
154 shll16 r4
155 clrt
156 shll8 r4
157 mov.l r5,@-r15
158div_r8_2:
159 rotcl r4
160 mov r0,r1
161 div1 r5,r1
162 mov r4,r0
163 rotcl r0
164 mov r5,r4
165 div1 r5,r1
166 .rept 5
167 rotcl r0; div1 r5,r1
168 .endr
169 rotcl r0
170 mov.l @r15+,r5
171 div1 r4,r1
172 mov.l @r15+,r4
173 rts
174 rotcl r0
175
176 .global __sdivsi3_i4i
177 .global __sdivsi3_i4
178 .global __sdivsi3
179 .set __sdivsi3_i4, __sdivsi3_i4i
180 .set __sdivsi3, __sdivsi3_i4i
181 .type __sdivsi3_i4i, @function
182 /* This is link-compatible with a __sdivsi3 call,
183 but we effectively clobber only r1. */
184__sdivsi3_i4i:
185 mov.l r4,@-r15
186 cmp/pz r5
187 mov.w c128_w, r1
188 bt/s pos_divisor
189 cmp/pz r4
190 mov.l r5,@-r15
191 neg r5,r5
192 bt/s neg_result
193 cmp/hi r1,r5
194 neg r4,r4
195pos_result:
196 extu.w r5,r0
197 bf div_le128
198 cmp/eq r5,r0
199 mov r4,r0
200 shlr8 r0
201 bf/s div_ge64k
202 cmp/hi r0,r5
203 div0u
204 shll16 r5
205 div1 r5,r0
206 div1 r5,r0
207 div1 r5,r0
208udiv_25:
209 mov.l zero_l,r1
210 div1 r5,r0
211 div1 r5,r0
212 mov.l r1,@-r15
213 .rept 3
214 div1 r5,r0
215 .endr
216 mov.b r0,@(L_MSWLSB,r15)
217 xtrct r4,r0
218 swap.w r0,r0
219 .rept 8
220 div1 r5,r0
221 .endr
222 mov.b r0,@(L_LSWMSB,r15)
223div_ge64k_end:
224 .rept 8
225 div1 r5,r0
226 .endr
227 mov.l @r15+,r4 ! zero-extension and swap using LS unit.
228 extu.b r0,r0
229 mov.l @r15+,r5
230 or r4,r0
231 mov.l @r15+,r4
232 rts
233 rotcl r0
234
235div_le128_neg:
236 tst #0xfe,r0
237 mova div_table_ix,r0
238 mov.b @(r0,r5),r1
239 mova div_table_inv,r0
240 bt/s div_by_1_neg
241 mov.l @(r0,r1),r1
242 mova div_table_clz,r0
243 dmulu.l r1,r4
244 mov.b @(r0,r5),r1
245 mov.l @r15+,r5
246 sts mach,r0
247 /* clrt */
248 addc r4,r0
249 mov.l @r15+,r4
250 rotcr r0
251 shld r1,r0
252 rts
253 neg r0,r0
254
255pos_divisor:
256 mov.l r5,@-r15
257 bt/s pos_result
258 cmp/hi r1,r5
259 neg r4,r4
260neg_result:
261 extu.w r5,r0
262 bf div_le128_neg
263 cmp/eq r5,r0
264 mov r4,r0
265 shlr8 r0
266 bf/s div_ge64k_neg
267 cmp/hi r0,r5
268 div0u
269 mov.l zero_l,r1
270 shll16 r5
271 div1 r5,r0
272 mov.l r1,@-r15
273 .rept 7
274 div1 r5,r0
275 .endr
276 mov.b r0,@(L_MSWLSB,r15)
277 xtrct r4,r0
278 swap.w r0,r0
279 .rept 8
280 div1 r5,r0
281 .endr
282 mov.b r0,@(L_LSWMSB,r15)
283div_ge64k_neg_end:
284 .rept 8
285 div1 r5,r0
286 .endr
287 mov.l @r15+,r4 ! zero-extension and swap using LS unit.
288 extu.b r0,r1
289 mov.l @r15+,r5
290 or r4,r1
291div_r8_neg_end:
292 mov.l @r15+,r4
293 rotcl r1
294 rts
295 neg r1,r0
296
297div_ge64k_neg:
298 bt/s div_r8_neg
299 div0u
300 shll8 r5
301 mov.l zero_l,r1
302 .rept 6
303 div1 r5,r0
304 .endr
305 mov.l r1,@-r15
306 div1 r5,r0
307 mov.w m256_w,r1
308 div1 r5,r0
309 mov.b r0,@(L_LSWMSB,r15)
310 xor r4,r0
311 and r1,r0
312 bra div_ge64k_neg_end
313 xor r4,r0
314
315c128_w:
316 .word 128
317
318div_r8_neg:
319 clrt
320 shll16 r4
321 mov r4,r1
322 shll8 r1
323 mov r5,r4
324 .rept 7
325 rotcl r1; div1 r5,r0
326 .endr
327 mov.l @r15+,r5
328 rotcl r1
329 bra div_r8_neg_end
330 div1 r4,r0
331
332m256_w:
333 .word 0xff00
334/* This table has been generated by divtab-sh4.c. */
335 .balign 4
336div_table_clz:
337 .byte 0
338 .byte 1
339 .byte 0
340 .byte -1
341 .byte -1
342 .byte -2
343 .byte -2
344 .byte -2
345 .byte -2
346 .byte -3
347 .byte -3
348 .byte -3
349 .byte -3
350 .byte -3
351 .byte -3
352 .byte -3
353 .byte -3
354 .byte -4
355 .byte -4
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 -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 -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 -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 .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/* Lookup table translating positive divisor to index into table of
466 normalized inverse. N.B. the '0' entry is also the last entry of the
467 previous table, and causes an unaligned access for division by zero. */
468div_table_ix:
469 .byte -6
470 .byte -128
471 .byte -128
472 .byte 0
473 .byte -128
474 .byte -64
475 .byte 0
476 .byte 64
477 .byte -128
478 .byte -96
479 .byte -64
480 .byte -32
481 .byte 0
482 .byte 32
483 .byte 64
484 .byte 96
485 .byte -128
486 .byte -112
487 .byte -96
488 .byte -80
489 .byte -64
490 .byte -48
491 .byte -32
492 .byte -16
493 .byte 0
494 .byte 16
495 .byte 32
496 .byte 48
497 .byte 64
498 .byte 80
499 .byte 96
500 .byte 112
501 .byte -128
502 .byte -120
503 .byte -112
504 .byte -104
505 .byte -96
506 .byte -88
507 .byte -80
508 .byte -72
509 .byte -64
510 .byte -56
511 .byte -48
512 .byte -40
513 .byte -32
514 .byte -24
515 .byte -16
516 .byte -8
517 .byte 0
518 .byte 8
519 .byte 16
520 .byte 24
521 .byte 32
522 .byte 40
523 .byte 48
524 .byte 56
525 .byte 64
526 .byte 72
527 .byte 80
528 .byte 88
529 .byte 96
530 .byte 104
531 .byte 112
532 .byte 120
533 .byte -128
534 .byte -124
535 .byte -120
536 .byte -116
537 .byte -112
538 .byte -108
539 .byte -104
540 .byte -100
541 .byte -96
542 .byte -92
543 .byte -88
544 .byte -84
545 .byte -80
546 .byte -76
547 .byte -72
548 .byte -68
549 .byte -64
550 .byte -60
551 .byte -56
552 .byte -52
553 .byte -48
554 .byte -44
555 .byte -40
556 .byte -36
557 .byte -32
558 .byte -28
559 .byte -24
560 .byte -20
561 .byte -16
562 .byte -12
563 .byte -8
564 .byte -4
565 .byte 0
566 .byte 4
567 .byte 8
568 .byte 12
569 .byte 16
570 .byte 20
571 .byte 24
572 .byte 28
573 .byte 32
574 .byte 36
575 .byte 40
576 .byte 44
577 .byte 48
578 .byte 52
579 .byte 56
580 .byte 60
581 .byte 64
582 .byte 68
583 .byte 72
584 .byte 76
585 .byte 80
586 .byte 84
587 .byte 88
588 .byte 92
589 .byte 96
590 .byte 100
591 .byte 104
592 .byte 108
593 .byte 112
594 .byte 116
595 .byte 120
596 .byte 124
597 .byte -128
598/* 1/64 .. 1/127, normalized. There is an implicit leading 1 in bit 32. */
599 .balign 4
600zero_l:
601 .long 0x0
602 .long 0xF81F81F9
603 .long 0xF07C1F08
604 .long 0xE9131AC0
605 .long 0xE1E1E1E2
606 .long 0xDAE6076C
607 .long 0xD41D41D5
608 .long 0xCD856891
609 .long 0xC71C71C8
610 .long 0xC0E07039
611 .long 0xBACF914D
612 .long 0xB4E81B4F
613 .long 0xAF286BCB
614 .long 0xA98EF607
615 .long 0xA41A41A5
616 .long 0x9EC8E952
617 .long 0x9999999A
618 .long 0x948B0FCE
619 .long 0x8F9C18FA
620 .long 0x8ACB90F7
621 .long 0x86186187
622 .long 0x81818182
623 .long 0x7D05F418
624 .long 0x78A4C818
625 .long 0x745D1746
626 .long 0x702E05C1
627 .long 0x6C16C16D
628 .long 0x68168169
629 .long 0x642C8591
630 .long 0x60581606
631 .long 0x5C9882BA
632 .long 0x58ED2309
633div_table_inv:
634 .long 0x55555556
635 .long 0x51D07EAF
636 .long 0x4E5E0A73
637 .long 0x4AFD6A06
638 .long 0x47AE147B
639 .long 0x446F8657
640 .long 0x41414142
641 .long 0x3E22CBCF
642 .long 0x3B13B13C
643 .long 0x38138139
644 .long 0x3521CFB3
645 .long 0x323E34A3
646 .long 0x2F684BDB
647 .long 0x2C9FB4D9
648 .long 0x29E4129F
649 .long 0x27350B89
650 .long 0x24924925
651 .long 0x21FB7813
652 .long 0x1F7047DD
653 .long 0x1CF06ADB
654 .long 0x1A7B9612
655 .long 0x18118119
656 .long 0x15B1E5F8
657 .long 0x135C8114
658 .long 0x11111112
659 .long 0xECF56BF
660 .long 0xC9714FC
661 .long 0xA6810A7
662 .long 0x8421085
663 .long 0x624DD30
664 .long 0x4104105
665 .long 0x2040811
666 /* maximum error: 0.987342 scaled: 0.921875*/