123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666 |
- /* Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
- 2004, 2005, 2006
- Free Software Foundation, Inc.
- This file is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the
- Free Software Foundation; either version 2, or (at your option) any
- later version.
- In addition to the permissions in the GNU General Public License, the
- Free Software Foundation gives you unlimited permission to link the
- compiled version of this file into combinations with other programs,
- and to distribute those combinations without any restriction coming
- from the use of this file. (The General Public License restrictions
- do apply in other respects; for example, they cover modification of
- the file, and distribution when not linked into a combine
- executable.)
- This file is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING. If not, write to
- the Free Software Foundation, 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA. */
- !! libgcc routines for the Renesas / SuperH SH CPUs.
- !! Contributed by Steve Chamberlain.
- !! sac@cygnus.com
- !! ashiftrt_r4_x, ___ashrsi3, ___ashlsi3, ___lshrsi3 routines
- !! recoded in assembly by Toshiyasu Morita
- !! tm@netcom.com
- /* SH2 optimizations for ___ashrsi3, ___ashlsi3, ___lshrsi3 and
- ELF local label prefixes by J"orn Rennecke
- amylaar@cygnus.com */
- /* This code used shld, thus is not suitable for SH1 / SH2. */
- /* Signed / unsigned division without use of FPU, optimized for SH4.
- Uses a lookup table for divisors in the range -128 .. +128, and
- div1 with case distinction for larger divisors in three more ranges.
- The code is lumped together with the table to allow the use of mova. */
- #ifdef CONFIG_CPU_LITTLE_ENDIAN
- #define L_LSB 0
- #define L_LSWMSB 1
- #define L_MSWLSB 2
- #else
- #define L_LSB 3
- #define L_LSWMSB 2
- #define L_MSWLSB 1
- #endif
- .balign 4
- .global __udivsi3_i4i
- .global __udivsi3_i4
- .set __udivsi3_i4, __udivsi3_i4i
- .type __udivsi3_i4i, @function
- __udivsi3_i4i:
- mov.w c128_w, r1
- div0u
- mov r4,r0
- shlr8 r0
- cmp/hi r1,r5
- extu.w r5,r1
- bf udiv_le128
- cmp/eq r5,r1
- bf udiv_ge64k
- shlr r0
- mov r5,r1
- shll16 r5
- mov.l r4,@-r15
- div1 r5,r0
- mov.l r1,@-r15
- div1 r5,r0
- div1 r5,r0
- bra udiv_25
- div1 r5,r0
- div_le128:
- mova div_table_ix,r0
- bra div_le128_2
- mov.b @(r0,r5),r1
- udiv_le128:
- mov.l r4,@-r15
- mova div_table_ix,r0
- mov.b @(r0,r5),r1
- mov.l r5,@-r15
- div_le128_2:
- mova div_table_inv,r0
- mov.l @(r0,r1),r1
- mov r5,r0
- tst #0xfe,r0
- mova div_table_clz,r0
- dmulu.l r1,r4
- mov.b @(r0,r5),r1
- bt/s div_by_1
- mov r4,r0
- mov.l @r15+,r5
- sts mach,r0
- /* clrt */
- addc r4,r0
- mov.l @r15+,r4
- rotcr r0
- rts
- shld r1,r0
- div_by_1_neg:
- neg r4,r0
- div_by_1:
- mov.l @r15+,r5
- rts
- mov.l @r15+,r4
- div_ge64k:
- bt/s div_r8
- div0u
- shll8 r5
- bra div_ge64k_2
- div1 r5,r0
- udiv_ge64k:
- cmp/hi r0,r5
- mov r5,r1
- bt udiv_r8
- shll8 r5
- mov.l r4,@-r15
- div1 r5,r0
- mov.l r1,@-r15
- div_ge64k_2:
- div1 r5,r0
- mov.l zero_l,r1
- .rept 4
- div1 r5,r0
- .endr
- mov.l r1,@-r15
- div1 r5,r0
- mov.w m256_w,r1
- div1 r5,r0
- mov.b r0,@(L_LSWMSB,r15)
- xor r4,r0
- and r1,r0
- bra div_ge64k_end
- xor r4,r0
-
- div_r8:
- shll16 r4
- bra div_r8_2
- shll8 r4
- udiv_r8:
- mov.l r4,@-r15
- shll16 r4
- clrt
- shll8 r4
- mov.l r5,@-r15
- div_r8_2:
- rotcl r4
- mov r0,r1
- div1 r5,r1
- mov r4,r0
- rotcl r0
- mov r5,r4
- div1 r5,r1
- .rept 5
- rotcl r0; div1 r5,r1
- .endr
- rotcl r0
- mov.l @r15+,r5
- div1 r4,r1
- mov.l @r15+,r4
- rts
- rotcl r0
- .global __sdivsi3_i4i
- .global __sdivsi3_i4
- .global __sdivsi3
- .set __sdivsi3_i4, __sdivsi3_i4i
- .set __sdivsi3, __sdivsi3_i4i
- .type __sdivsi3_i4i, @function
- /* This is link-compatible with a __sdivsi3 call,
- but we effectively clobber only r1. */
- __sdivsi3_i4i:
- mov.l r4,@-r15
- cmp/pz r5
- mov.w c128_w, r1
- bt/s pos_divisor
- cmp/pz r4
- mov.l r5,@-r15
- neg r5,r5
- bt/s neg_result
- cmp/hi r1,r5
- neg r4,r4
- pos_result:
- extu.w r5,r0
- bf div_le128
- cmp/eq r5,r0
- mov r4,r0
- shlr8 r0
- bf/s div_ge64k
- cmp/hi r0,r5
- div0u
- shll16 r5
- div1 r5,r0
- div1 r5,r0
- div1 r5,r0
- udiv_25:
- mov.l zero_l,r1
- div1 r5,r0
- div1 r5,r0
- mov.l r1,@-r15
- .rept 3
- div1 r5,r0
- .endr
- mov.b r0,@(L_MSWLSB,r15)
- xtrct r4,r0
- swap.w r0,r0
- .rept 8
- div1 r5,r0
- .endr
- mov.b r0,@(L_LSWMSB,r15)
- div_ge64k_end:
- .rept 8
- div1 r5,r0
- .endr
- mov.l @r15+,r4 ! zero-extension and swap using LS unit.
- extu.b r0,r0
- mov.l @r15+,r5
- or r4,r0
- mov.l @r15+,r4
- rts
- rotcl r0
- div_le128_neg:
- tst #0xfe,r0
- mova div_table_ix,r0
- mov.b @(r0,r5),r1
- mova div_table_inv,r0
- bt/s div_by_1_neg
- mov.l @(r0,r1),r1
- mova div_table_clz,r0
- dmulu.l r1,r4
- mov.b @(r0,r5),r1
- mov.l @r15+,r5
- sts mach,r0
- /* clrt */
- addc r4,r0
- mov.l @r15+,r4
- rotcr r0
- shld r1,r0
- rts
- neg r0,r0
- pos_divisor:
- mov.l r5,@-r15
- bt/s pos_result
- cmp/hi r1,r5
- neg r4,r4
- neg_result:
- extu.w r5,r0
- bf div_le128_neg
- cmp/eq r5,r0
- mov r4,r0
- shlr8 r0
- bf/s div_ge64k_neg
- cmp/hi r0,r5
- div0u
- mov.l zero_l,r1
- shll16 r5
- div1 r5,r0
- mov.l r1,@-r15
- .rept 7
- div1 r5,r0
- .endr
- mov.b r0,@(L_MSWLSB,r15)
- xtrct r4,r0
- swap.w r0,r0
- .rept 8
- div1 r5,r0
- .endr
- mov.b r0,@(L_LSWMSB,r15)
- div_ge64k_neg_end:
- .rept 8
- div1 r5,r0
- .endr
- mov.l @r15+,r4 ! zero-extension and swap using LS unit.
- extu.b r0,r1
- mov.l @r15+,r5
- or r4,r1
- div_r8_neg_end:
- mov.l @r15+,r4
- rotcl r1
- rts
- neg r1,r0
- div_ge64k_neg:
- bt/s div_r8_neg
- div0u
- shll8 r5
- mov.l zero_l,r1
- .rept 6
- div1 r5,r0
- .endr
- mov.l r1,@-r15
- div1 r5,r0
- mov.w m256_w,r1
- div1 r5,r0
- mov.b r0,@(L_LSWMSB,r15)
- xor r4,r0
- and r1,r0
- bra div_ge64k_neg_end
- xor r4,r0
- c128_w:
- .word 128
- div_r8_neg:
- clrt
- shll16 r4
- mov r4,r1
- shll8 r1
- mov r5,r4
- .rept 7
- rotcl r1; div1 r5,r0
- .endr
- mov.l @r15+,r5
- rotcl r1
- bra div_r8_neg_end
- div1 r4,r0
- m256_w:
- .word 0xff00
- /* This table has been generated by divtab-sh4.c. */
- .balign 4
- div_table_clz:
- .byte 0
- .byte 1
- .byte 0
- .byte -1
- .byte -1
- .byte -2
- .byte -2
- .byte -2
- .byte -2
- .byte -3
- .byte -3
- .byte -3
- .byte -3
- .byte -3
- .byte -3
- .byte -3
- .byte -3
- .byte -4
- .byte -4
- .byte -4
- .byte -4
- .byte -4
- .byte -4
- .byte -4
- .byte -4
- .byte -4
- .byte -4
- .byte -4
- .byte -4
- .byte -4
- .byte -4
- .byte -4
- .byte -4
- .byte -5
- .byte -5
- .byte -5
- .byte -5
- .byte -5
- .byte -5
- .byte -5
- .byte -5
- .byte -5
- .byte -5
- .byte -5
- .byte -5
- .byte -5
- .byte -5
- .byte -5
- .byte -5
- .byte -5
- .byte -5
- .byte -5
- .byte -5
- .byte -5
- .byte -5
- .byte -5
- .byte -5
- .byte -5
- .byte -5
- .byte -5
- .byte -5
- .byte -5
- .byte -5
- .byte -5
- .byte -5
- .byte -6
- .byte -6
- .byte -6
- .byte -6
- .byte -6
- .byte -6
- .byte -6
- .byte -6
- .byte -6
- .byte -6
- .byte -6
- .byte -6
- .byte -6
- .byte -6
- .byte -6
- .byte -6
- .byte -6
- .byte -6
- .byte -6
- .byte -6
- .byte -6
- .byte -6
- .byte -6
- .byte -6
- .byte -6
- .byte -6
- .byte -6
- .byte -6
- .byte -6
- .byte -6
- .byte -6
- .byte -6
- .byte -6
- .byte -6
- .byte -6
- .byte -6
- .byte -6
- .byte -6
- .byte -6
- .byte -6
- .byte -6
- .byte -6
- .byte -6
- .byte -6
- .byte -6
- .byte -6
- .byte -6
- .byte -6
- .byte -6
- .byte -6
- .byte -6
- .byte -6
- .byte -6
- .byte -6
- .byte -6
- .byte -6
- .byte -6
- .byte -6
- .byte -6
- .byte -6
- .byte -6
- .byte -6
- .byte -6
- /* Lookup table translating positive divisor to index into table of
- normalized inverse. N.B. the '0' entry is also the last entry of the
- previous table, and causes an unaligned access for division by zero. */
- div_table_ix:
- .byte -6
- .byte -128
- .byte -128
- .byte 0
- .byte -128
- .byte -64
- .byte 0
- .byte 64
- .byte -128
- .byte -96
- .byte -64
- .byte -32
- .byte 0
- .byte 32
- .byte 64
- .byte 96
- .byte -128
- .byte -112
- .byte -96
- .byte -80
- .byte -64
- .byte -48
- .byte -32
- .byte -16
- .byte 0
- .byte 16
- .byte 32
- .byte 48
- .byte 64
- .byte 80
- .byte 96
- .byte 112
- .byte -128
- .byte -120
- .byte -112
- .byte -104
- .byte -96
- .byte -88
- .byte -80
- .byte -72
- .byte -64
- .byte -56
- .byte -48
- .byte -40
- .byte -32
- .byte -24
- .byte -16
- .byte -8
- .byte 0
- .byte 8
- .byte 16
- .byte 24
- .byte 32
- .byte 40
- .byte 48
- .byte 56
- .byte 64
- .byte 72
- .byte 80
- .byte 88
- .byte 96
- .byte 104
- .byte 112
- .byte 120
- .byte -128
- .byte -124
- .byte -120
- .byte -116
- .byte -112
- .byte -108
- .byte -104
- .byte -100
- .byte -96
- .byte -92
- .byte -88
- .byte -84
- .byte -80
- .byte -76
- .byte -72
- .byte -68
- .byte -64
- .byte -60
- .byte -56
- .byte -52
- .byte -48
- .byte -44
- .byte -40
- .byte -36
- .byte -32
- .byte -28
- .byte -24
- .byte -20
- .byte -16
- .byte -12
- .byte -8
- .byte -4
- .byte 0
- .byte 4
- .byte 8
- .byte 12
- .byte 16
- .byte 20
- .byte 24
- .byte 28
- .byte 32
- .byte 36
- .byte 40
- .byte 44
- .byte 48
- .byte 52
- .byte 56
- .byte 60
- .byte 64
- .byte 68
- .byte 72
- .byte 76
- .byte 80
- .byte 84
- .byte 88
- .byte 92
- .byte 96
- .byte 100
- .byte 104
- .byte 108
- .byte 112
- .byte 116
- .byte 120
- .byte 124
- .byte -128
- /* 1/64 .. 1/127, normalized. There is an implicit leading 1 in bit 32. */
- .balign 4
- zero_l:
- .long 0x0
- .long 0xF81F81F9
- .long 0xF07C1F08
- .long 0xE9131AC0
- .long 0xE1E1E1E2
- .long 0xDAE6076C
- .long 0xD41D41D5
- .long 0xCD856891
- .long 0xC71C71C8
- .long 0xC0E07039
- .long 0xBACF914D
- .long 0xB4E81B4F
- .long 0xAF286BCB
- .long 0xA98EF607
- .long 0xA41A41A5
- .long 0x9EC8E952
- .long 0x9999999A
- .long 0x948B0FCE
- .long 0x8F9C18FA
- .long 0x8ACB90F7
- .long 0x86186187
- .long 0x81818182
- .long 0x7D05F418
- .long 0x78A4C818
- .long 0x745D1746
- .long 0x702E05C1
- .long 0x6C16C16D
- .long 0x68168169
- .long 0x642C8591
- .long 0x60581606
- .long 0x5C9882BA
- .long 0x58ED2309
- div_table_inv:
- .long 0x55555556
- .long 0x51D07EAF
- .long 0x4E5E0A73
- .long 0x4AFD6A06
- .long 0x47AE147B
- .long 0x446F8657
- .long 0x41414142
- .long 0x3E22CBCF
- .long 0x3B13B13C
- .long 0x38138139
- .long 0x3521CFB3
- .long 0x323E34A3
- .long 0x2F684BDB
- .long 0x2C9FB4D9
- .long 0x29E4129F
- .long 0x27350B89
- .long 0x24924925
- .long 0x21FB7813
- .long 0x1F7047DD
- .long 0x1CF06ADB
- .long 0x1A7B9612
- .long 0x18118119
- .long 0x15B1E5F8
- .long 0x135C8114
- .long 0x11111112
- .long 0xECF56BF
- .long 0xC9714FC
- .long 0xA6810A7
- .long 0x8421085
- .long 0x624DD30
- .long 0x4104105
- .long 0x2040811
- /* maximum error: 0.987342 scaled: 0.921875*/
|