Home | History | Annotate | Line # | Download | only in sh
lib1funcs-Os-4-200.S revision 1.1
      1  1.1  mrg /* Copyright (C) 2006-2013 Free Software Foundation, Inc.
      2  1.1  mrg 
      3  1.1  mrg This file is free software; you can redistribute it and/or modify it
      4  1.1  mrg under the terms of the GNU General Public License as published by the
      5  1.1  mrg Free Software Foundation; either version 3, or (at your option) any
      6  1.1  mrg later version.
      7  1.1  mrg 
      8  1.1  mrg This file is distributed in the hope that it will be useful, but
      9  1.1  mrg WITHOUT ANY WARRANTY; without even the implied warranty of
     10  1.1  mrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     11  1.1  mrg General Public License for more details.
     12  1.1  mrg 
     13  1.1  mrg Under Section 7 of GPL version 3, you are granted additional
     14  1.1  mrg permissions described in the GCC Runtime Library Exception, version
     15  1.1  mrg 3.1, as published by the Free Software Foundation.
     16  1.1  mrg 
     17  1.1  mrg You should have received a copy of the GNU General Public License and
     18  1.1  mrg a copy of the GCC Runtime Library Exception along with this program;
     19  1.1  mrg see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
     20  1.1  mrg <http://www.gnu.org/licenses/>.  */
     21  1.1  mrg 
     22  1.1  mrg /* Moderately Space-optimized libgcc routines for the Renesas SH /
     23  1.1  mrg    STMicroelectronics ST40 CPUs.
     24  1.1  mrg    Contributed by J"orn Rennecke joern.rennecke (at) st.com.  */
     25  1.1  mrg 
     26  1.1  mrg #include "lib1funcs.h"
     27  1.1  mrg 
     28  1.1  mrg #if !__SHMEDIA__
     29  1.1  mrg #ifdef L_udivsi3_i4i
     30  1.1  mrg 
     31  1.1  mrg /* 88 bytes; sh4-200 cycle counts:
     32  1.1  mrg    divisor  >= 2G: 11 cycles
     33  1.1  mrg    dividend <  2G: 48 cycles
     34  1.1  mrg    dividend >= 2G: divisor != 1: 54 cycles
     35  1.1  mrg    dividend >= 2G, divisor == 1: 22 cycles */
     36  1.1  mrg #if defined (__SH_FPU_DOUBLE__) || defined (__SH4_SINGLE_ONLY__)
     37  1.1  mrg !! args in r4 and r5, result in r0, clobber r1
     38  1.1  mrg 
     39  1.1  mrg 	.global GLOBAL(udivsi3_i4i)
     40  1.1  mrg 	FUNC(GLOBAL(udivsi3_i4i))
     41  1.1  mrg GLOBAL(udivsi3_i4i):
     42  1.1  mrg 	mova L1,r0
     43  1.1  mrg 	cmp/pz r5
     44  1.1  mrg 	sts fpscr,r1
     45  1.1  mrg 	lds.l @r0+,fpscr
     46  1.1  mrg 	sts.l fpul,@-r15
     47  1.1  mrg 	bf LOCAL(huge_divisor)
     48  1.1  mrg 	mov.l r1,@-r15
     49  1.1  mrg 	lds r4,fpul
     50  1.1  mrg 	cmp/pz r4
     51  1.1  mrg #ifdef FMOVD_WORKS
     52  1.1  mrg 	fmov.d dr0,@-r15
     53  1.1  mrg 	float fpul,dr0
     54  1.1  mrg 	fmov.d dr2,@-r15
     55  1.1  mrg 	bt LOCAL(dividend_adjusted)
     56  1.1  mrg 	mov #1,r1
     57  1.1  mrg 	fmov.d @r0,dr2
     58  1.1  mrg 	cmp/eq r1,r5
     59  1.1  mrg 	bt LOCAL(div_by_1)
     60  1.1  mrg 	fadd dr2,dr0
     61  1.1  mrg LOCAL(dividend_adjusted):
     62  1.1  mrg 	lds r5,fpul
     63  1.1  mrg 	float fpul,dr2
     64  1.1  mrg 	fdiv dr2,dr0
     65  1.1  mrg LOCAL(div_by_1):
     66  1.1  mrg 	fmov.d @r15+,dr2
     67  1.1  mrg 	ftrc dr0,fpul
     68  1.1  mrg 	fmov.d @r15+,dr0
     69  1.1  mrg #else /* !FMOVD_WORKS */
     70  1.1  mrg 	fmov.s DR01,@-r15
     71  1.1  mrg 	mov #1,r1
     72  1.1  mrg 	fmov.s DR00,@-r15
     73  1.1  mrg 	float fpul,dr0
     74  1.1  mrg 	fmov.s DR21,@-r15
     75  1.1  mrg 	bt/s LOCAL(dividend_adjusted)
     76  1.1  mrg 	fmov.s DR20,@-r15
     77  1.1  mrg 	cmp/eq r1,r5
     78  1.1  mrg 	bt LOCAL(div_by_1)
     79  1.1  mrg 	fmov.s @r0+,DR20
     80  1.1  mrg 	fmov.s @r0,DR21
     81  1.1  mrg 	fadd dr2,dr0
     82  1.1  mrg LOCAL(dividend_adjusted):
     83  1.1  mrg 	lds r5,fpul
     84  1.1  mrg 	float fpul,dr2
     85  1.1  mrg 	fdiv dr2,dr0
     86  1.1  mrg LOCAL(div_by_1):
     87  1.1  mrg 	fmov.s @r15+,DR20
     88  1.1  mrg 	fmov.s @r15+,DR21
     89  1.1  mrg 	ftrc dr0,fpul
     90  1.1  mrg 	fmov.s @r15+,DR00
     91  1.1  mrg 	fmov.s @r15+,DR01
     92  1.1  mrg #endif /* !FMOVD_WORKS */
     93  1.1  mrg 	lds.l @r15+,fpscr
     94  1.1  mrg 	sts fpul,r0
     95  1.1  mrg 	rts
     96  1.1  mrg 	lds.l @r15+,fpul
     97  1.1  mrg 
     98  1.1  mrg #ifdef FMOVD_WORKS
     99  1.1  mrg 	.p2align 3        ! make double below 8 byte aligned.
    100  1.1  mrg #endif
    101  1.1  mrg LOCAL(huge_divisor):
    102  1.1  mrg 	lds r1,fpscr
    103  1.1  mrg 	add #4,r15
    104  1.1  mrg 	cmp/hs r5,r4
    105  1.1  mrg 	rts
    106  1.1  mrg 	movt r0
    107  1.1  mrg 
    108  1.1  mrg 	.p2align 2
    109  1.1  mrg L1:
    110  1.1  mrg #ifndef FMOVD_WORKS
    111  1.1  mrg 	.long 0x80000
    112  1.1  mrg #else
    113  1.1  mrg 	.long 0x180000
    114  1.1  mrg #endif
    115  1.1  mrg 	.double 4294967296
    116  1.1  mrg 
    117  1.1  mrg 	ENDFUNC(GLOBAL(udivsi3_i4i))
    118  1.1  mrg #elif !defined (__sh1__)  /* !__SH_FPU_DOUBLE__ */
    119  1.1  mrg 
    120  1.1  mrg #if 0
    121  1.1  mrg /* With 36 bytes, the following would probably be the most compact
    122  1.1  mrg    implementation, but with 139 cycles on an sh4-200, it is extremely slow.  */
    123  1.1  mrg GLOBAL(udivsi3_i4i):
    124  1.1  mrg 	mov.l r2,@-r15
    125  1.1  mrg 	mov #0,r1
    126  1.1  mrg 	div0u
    127  1.1  mrg 	mov r1,r2
    128  1.1  mrg 	mov.l r3,@-r15
    129  1.1  mrg 	mov r1,r3
    130  1.1  mrg 	sett
    131  1.1  mrg 	mov r4,r0
    132  1.1  mrg LOCAL(loop):
    133  1.1  mrg 	rotcr r2
    134  1.1  mrg 	;
    135  1.1  mrg 	bt/s LOCAL(end)
    136  1.1  mrg 	cmp/gt r2,r3
    137  1.1  mrg 	rotcl r0
    138  1.1  mrg 	bra LOCAL(loop)
    139  1.1  mrg 	div1 r5,r1
    140  1.1  mrg LOCAL(end):
    141  1.1  mrg 	rotcl r0
    142  1.1  mrg 	mov.l @r15+,r3
    143  1.1  mrg 	rts
    144  1.1  mrg 	mov.l @r15+,r2
    145  1.1  mrg #endif /* 0 */
    146  1.1  mrg 
    147  1.1  mrg /* Size: 186 bytes jointly for udivsi3_i4i and sdivsi3_i4i
    148  1.1  mrg    sh4-200 run times:
    149  1.1  mrg    udiv small divisor: 55 cycles
    150  1.1  mrg    udiv large divisor: 52 cycles
    151  1.1  mrg    sdiv small divisor, positive result: 59 cycles
    152  1.1  mrg    sdiv large divisor, positive result: 56 cycles
    153  1.1  mrg    sdiv small divisor, negative result: 65 cycles (*)
    154  1.1  mrg    sdiv large divisor, negative result: 62 cycles (*)
    155  1.1  mrg    (*): r2 is restored in the rts delay slot and has a lingering latency
    156  1.1  mrg         of two more cycles.  */
    157  1.1  mrg 	.balign 4
    158  1.1  mrg 	.global	GLOBAL(udivsi3_i4i)
    159  1.1  mrg 	FUNC(GLOBAL(udivsi3_i4i))
    160  1.1  mrg 	FUNC(GLOBAL(sdivsi3_i4i))
    161  1.1  mrg GLOBAL(udivsi3_i4i):
    162  1.1  mrg 	sts pr,r1
    163  1.1  mrg 	mov.l r4,@-r15
    164  1.1  mrg 	extu.w r5,r0
    165  1.1  mrg 	cmp/eq r5,r0
    166  1.1  mrg 	swap.w r4,r0
    167  1.1  mrg 	shlr16 r4
    168  1.1  mrg 	bf/s LOCAL(large_divisor)
    169  1.1  mrg 	div0u
    170  1.1  mrg 	mov.l r5,@-r15
    171  1.1  mrg 	shll16 r5
    172  1.1  mrg LOCAL(sdiv_small_divisor):
    173  1.1  mrg 	div1 r5,r4
    174  1.1  mrg 	bsr LOCAL(div6)
    175  1.1  mrg 	div1 r5,r4
    176  1.1  mrg 	div1 r5,r4
    177  1.1  mrg 	bsr LOCAL(div6)
    178  1.1  mrg 	div1 r5,r4
    179  1.1  mrg 	xtrct r4,r0
    180  1.1  mrg 	xtrct r0,r4
    181  1.1  mrg 	bsr LOCAL(div7)
    182  1.1  mrg 	swap.w r4,r4
    183  1.1  mrg 	div1 r5,r4
    184  1.1  mrg 	bsr LOCAL(div7)
    185  1.1  mrg 	div1 r5,r4
    186  1.1  mrg 	xtrct r4,r0
    187  1.1  mrg 	mov.l @r15+,r5
    188  1.1  mrg 	swap.w r0,r0
    189  1.1  mrg 	mov.l @r15+,r4
    190  1.1  mrg 	jmp @r1
    191  1.1  mrg 	rotcl r0
    192  1.1  mrg LOCAL(div7):
    193  1.1  mrg 	div1 r5,r4
    194  1.1  mrg LOCAL(div6):
    195  1.1  mrg 	            div1 r5,r4; div1 r5,r4; div1 r5,r4
    196  1.1  mrg 	div1 r5,r4; div1 r5,r4; rts;        div1 r5,r4
    197  1.1  mrg 
    198  1.1  mrg LOCAL(divx3):
    199  1.1  mrg 	rotcl r0
    200  1.1  mrg 	div1 r5,r4
    201  1.1  mrg 	rotcl r0
    202  1.1  mrg 	div1 r5,r4
    203  1.1  mrg 	rotcl r0
    204  1.1  mrg 	rts
    205  1.1  mrg 	div1 r5,r4
    206  1.1  mrg 
    207  1.1  mrg LOCAL(large_divisor):
    208  1.1  mrg 	mov.l r5,@-r15
    209  1.1  mrg LOCAL(sdiv_large_divisor):
    210  1.1  mrg 	xor r4,r0
    211  1.1  mrg 	.rept 4
    212  1.1  mrg 	rotcl r0
    213  1.1  mrg 	bsr LOCAL(divx3)
    214  1.1  mrg 	div1 r5,r4
    215  1.1  mrg 	.endr
    216  1.1  mrg 	mov.l @r15+,r5
    217  1.1  mrg 	mov.l @r15+,r4
    218  1.1  mrg 	jmp @r1
    219  1.1  mrg 	rotcl r0
    220  1.1  mrg 	ENDFUNC(GLOBAL(udivsi3_i4i))
    221  1.1  mrg 
    222  1.1  mrg 	.global	GLOBAL(sdivsi3_i4i)
    223  1.1  mrg GLOBAL(sdivsi3_i4i):
    224  1.1  mrg 	mov.l r4,@-r15
    225  1.1  mrg 	cmp/pz r5
    226  1.1  mrg 	mov.l r5,@-r15
    227  1.1  mrg 	bt/s LOCAL(pos_divisor)
    228  1.1  mrg 	cmp/pz r4
    229  1.1  mrg 	neg r5,r5
    230  1.1  mrg 	extu.w r5,r0
    231  1.1  mrg 	bt/s LOCAL(neg_result)
    232  1.1  mrg 	cmp/eq r5,r0
    233  1.1  mrg 	neg r4,r4
    234  1.1  mrg LOCAL(pos_result):
    235  1.1  mrg 	swap.w r4,r0
    236  1.1  mrg 	bra LOCAL(sdiv_check_divisor)
    237  1.1  mrg 	sts pr,r1
    238  1.1  mrg LOCAL(pos_divisor):
    239  1.1  mrg 	extu.w r5,r0
    240  1.1  mrg 	bt/s LOCAL(pos_result)
    241  1.1  mrg 	cmp/eq r5,r0
    242  1.1  mrg 	neg r4,r4
    243  1.1  mrg LOCAL(neg_result):
    244  1.1  mrg 	mova LOCAL(negate_result),r0
    245  1.1  mrg 	;
    246  1.1  mrg 	mov r0,r1
    247  1.1  mrg 	swap.w r4,r0
    248  1.1  mrg 	lds r2,macl
    249  1.1  mrg 	sts pr,r2
    250  1.1  mrg LOCAL(sdiv_check_divisor):
    251  1.1  mrg 	shlr16 r4
    252  1.1  mrg 	bf/s LOCAL(sdiv_large_divisor)
    253  1.1  mrg 	div0u
    254  1.1  mrg 	bra LOCAL(sdiv_small_divisor)
    255  1.1  mrg 	shll16 r5
    256  1.1  mrg 	.balign 4
    257  1.1  mrg LOCAL(negate_result):
    258  1.1  mrg 	neg r0,r0
    259  1.1  mrg 	jmp @r2
    260  1.1  mrg 	sts macl,r2
    261  1.1  mrg 	ENDFUNC(GLOBAL(sdivsi3_i4i))
    262  1.1  mrg #endif /* !__SH_FPU_DOUBLE__ */
    263  1.1  mrg #endif /* L_udivsi3_i4i */
    264  1.1  mrg 
    265  1.1  mrg #ifdef L_sdivsi3_i4i
    266  1.1  mrg #if defined (__SH_FPU_DOUBLE__) || defined (__SH4_SINGLE_ONLY__)
    267  1.1  mrg /* 48 bytes, 45 cycles on sh4-200  */
    268  1.1  mrg !! args in r4 and r5, result in r0, clobber r1
    269  1.1  mrg 
    270  1.1  mrg 	.global GLOBAL(sdivsi3_i4i)
    271  1.1  mrg 	FUNC(GLOBAL(sdivsi3_i4i))
    272  1.1  mrg GLOBAL(sdivsi3_i4i):
    273  1.1  mrg 	sts.l fpscr,@-r15
    274  1.1  mrg 	sts fpul,r1
    275  1.1  mrg 	mova L1,r0
    276  1.1  mrg 	lds.l @r0+,fpscr
    277  1.1  mrg 	lds r4,fpul
    278  1.1  mrg #ifdef FMOVD_WORKS
    279  1.1  mrg 	fmov.d dr0,@-r15
    280  1.1  mrg 	float fpul,dr0
    281  1.1  mrg 	lds r5,fpul
    282  1.1  mrg 	fmov.d dr2,@-r15
    283  1.1  mrg #else
    284  1.1  mrg 	fmov.s DR01,@-r15
    285  1.1  mrg 	fmov.s DR00,@-r15
    286  1.1  mrg 	float fpul,dr0
    287  1.1  mrg 	lds r5,fpul
    288  1.1  mrg 	fmov.s DR21,@-r15
    289  1.1  mrg 	fmov.s DR20,@-r15
    290  1.1  mrg #endif
    291  1.1  mrg 	float fpul,dr2
    292  1.1  mrg 	fdiv dr2,dr0
    293  1.1  mrg #ifdef FMOVD_WORKS
    294  1.1  mrg 	fmov.d @r15+,dr2
    295  1.1  mrg #else
    296  1.1  mrg 	fmov.s @r15+,DR20
    297  1.1  mrg 	fmov.s @r15+,DR21
    298  1.1  mrg #endif
    299  1.1  mrg 	ftrc dr0,fpul
    300  1.1  mrg #ifdef FMOVD_WORKS
    301  1.1  mrg 	fmov.d @r15+,dr0
    302  1.1  mrg #else
    303  1.1  mrg 	fmov.s @r15+,DR00
    304  1.1  mrg 	fmov.s @r15+,DR01
    305  1.1  mrg #endif
    306  1.1  mrg 	lds.l @r15+,fpscr
    307  1.1  mrg 	sts fpul,r0
    308  1.1  mrg 	rts
    309  1.1  mrg 	lds r1,fpul
    310  1.1  mrg 
    311  1.1  mrg 	.p2align 2
    312  1.1  mrg L1:
    313  1.1  mrg #ifndef FMOVD_WORKS
    314  1.1  mrg 	.long 0x80000
    315  1.1  mrg #else
    316  1.1  mrg 	.long 0x180000
    317  1.1  mrg #endif
    318  1.1  mrg 
    319  1.1  mrg 	ENDFUNC(GLOBAL(sdivsi3_i4i))
    320  1.1  mrg #endif /* __SH_FPU_DOUBLE__ */
    321  1.1  mrg #endif /* L_sdivsi3_i4i */
    322  1.1  mrg #endif /* !__SHMEDIA__ */
    323