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