Home | History | Annotate | Line # | Download | only in common
      1  1.1  skrll ;	$NetBSD: milli_tiny.S,v 1.1 2014/02/24 07:23:43 skrll Exp $
      2  1.1  skrll 
      3  1.1  skrll ; Copyright (c) 2003 ITOH Yasufumi.
      4  1.1  skrll ; All rights reserved.
      5  1.1  skrll ;
      6  1.1  skrll ; Redistribution and use in source and binary forms, with or without
      7  1.1  skrll ; modification, are permitted provided that the following conditions
      8  1.1  skrll ; are met:
      9  1.1  skrll ; 1. Redistributions of source code must retain the above copyright
     10  1.1  skrll ;    notice, this list of conditions and the following disclaimer.
     11  1.1  skrll ; 2. Redistributions in binary forms are unlimited.
     12  1.1  skrll ;
     13  1.1  skrll ; THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS''
     14  1.1  skrll ; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     15  1.1  skrll ; THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     16  1.1  skrll ; PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS
     17  1.1  skrll ; BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     18  1.1  skrll ; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     19  1.1  skrll ; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     20  1.1  skrll ; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     21  1.1  skrll ; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     22  1.1  skrll ; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
     23  1.1  skrll ; THE POSSIBILITY OF SUCH DAMAGE.
     24  1.1  skrll 
     25  1.1  skrll ; millicode library, optimized for size
     26  1.1  skrll 
     27  1.1  skrll 	.level	1.0
     28  1.1  skrll 	.code
     29  1.1  skrll 	.align	4
     30  1.1  skrll 
     31  1.1  skrll ; $$divU	unsigned division, return quotient
     32  1.1  skrll ;
     33  1.1  skrll ; inputs:
     34  1.1  skrll ;	%r26	dividend
     35  1.1  skrll ;	%r25	divisor
     36  1.1  skrll ;	%r31	return address
     37  1.1  skrll ; outputs:
     38  1.1  skrll ;	%r29	quotient
     39  1.1  skrll ;	%r1, %r25, %r26	undefined
     40  1.1  skrll 	.export		$$divU,millicode
     41  1.1  skrll $$divU:
     42  1.1  skrll 	.proc
     43  1.1  skrll 	.callinfo	millicode,no_unwind
     44  1.1  skrll 	.entry
     45  1.1  skrll 	comb,<,n	%r25,0,bigdivisor_divU	; special case (>=0x80000000)
     46  1.1  skrll 	bl		sub_divU,%r29
     47  1.1  skrll 	subt,=		%r0,%r25,%r1		; trap divide by 0, negate
     48  1.1  skrll 
     49  1.1  skrll 	bv		%r0(%r31)		; return millicode
     50  1.1  skrll 	.exit
     51  1.1  skrll 	addc		%r26,%r26,%r29		; fix quotient
     52  1.1  skrll bigdivisor_divU:
     53  1.1  skrll 	comclr,<<	%r26,%r25,%r29		; if dividend >= divisor
     54  1.1  skrll 	ldi		1,%r29			;   quotient is 1
     55  1.1  skrll 	bv,n		%r0(%r31)		; return millicode
     56  1.1  skrll 	.procend
     57  1.1  skrll 
     58  1.1  skrll ; Note this is not a normal subroutine
     59  1.1  skrll ; r29: return address
     60  1.1  skrll sub_divU:
     61  1.1  skrll 	stwm		%r19,64(%sp)
     62  1.1  skrll 	ldi		31,%r19
     63  1.1  skrll 
     64  1.1  skrll 	ds		%r0,%r1,%r0
     65  1.1  skrll 	addc		%r26,%r26,%r26
     66  1.1  skrll 	ds		%r0,%r25,%r1
     67  1.1  skrll loop_sub_divU:					; addc/ds 31 times
     68  1.1  skrll 	addc		%r26,%r26,%r26
     69  1.1  skrll 	addib,<>	-1,%r19,loop_sub_divU
     70  1.1  skrll 	ds		%r1,%r25,%r1
     71  1.1  skrll 
     72  1.1  skrll 	bv		%r0(%r29)
     73  1.1  skrll 	ldwm		-64(%sp),%r19
     74  1.1  skrll 
     75  1.1  skrll ; $$remU	unsigned division, return remainder
     76  1.1  skrll ;
     77  1.1  skrll ; inputs:
     78  1.1  skrll ;	%r26	dividend
     79  1.1  skrll ;	%r25	divisor
     80  1.1  skrll ;	%r31	return address
     81  1.1  skrll ; outputs:
     82  1.1  skrll ;	%r29	remainder
     83  1.1  skrll ;	%r1, %r25, %r26	undefined
     84  1.1  skrll 	.export		$$remU,millicode
     85  1.1  skrll $$remU:
     86  1.1  skrll 	.proc
     87  1.1  skrll 	.callinfo	millicode,no_unwind
     88  1.1  skrll 	.entry
     89  1.1  skrll 	comb,<,n	%r25,0,bigdivisor_remU	; special case (>=0x80000000)
     90  1.1  skrll 	bl		sub_divU,%r29
     91  1.1  skrll 	subt,=		%r0,%r25,%r1		; trap divide by 0, negate
     92  1.1  skrll 
     93  1.1  skrll 	comclr,>=	%r1,%r0,%r0
     94  1.1  skrll 	addl		%r1,%r25,%r1		; fix remainder
     95  1.1  skrll 	bv		%r0(%r31)		; return millicode
     96  1.1  skrll 	.exit
     97  1.1  skrll 	copy		%r1,%r29		; the return value is remainder
     98  1.1  skrll bigdivisor_remU:
     99  1.1  skrll 	sub,>>=		%r26,%r25,%r29		; if dividend < divisor
    100  1.1  skrll 	copy		%r26,%r29		;   the remainder is dividend
    101  1.1  skrll 	bv,n		%r0(%r31)		; return millicode
    102  1.1  skrll 	.procend
    103  1.1  skrll 
    104  1.1  skrll ; $$mulU	unsigned multiplication
    105  1.1  skrll ;
    106  1.1  skrll ; inputs:
    107  1.1  skrll ;	%r26	multiplicand
    108  1.1  skrll ;	%r25	multiplier
    109  1.1  skrll ;	%r31	return address
    110  1.1  skrll ; outputs:
    111  1.1  skrll ;	%r29	product
    112  1.1  skrll ;	%r1, %r25, %r26	undefined
    113  1.1  skrll 	.export		$$mulU,millicode
    114  1.1  skrll 	.export		$$mulI,millicode
    115  1.1  skrll $$mulU:
    116  1.1  skrll $$mulI:	; XXX actually wrong (not signed) but works for small positive numbers
    117  1.1  skrll 	.proc
    118  1.1  skrll 	.callinfo	frame=0,no_calls,millicode
    119  1.1  skrll 	.entry
    120  1.1  skrll 	copy		%r0,%r29
    121  1.1  skrll 	ldi		32,%r1			; loop counter
    122  1.1  skrll 
    123  1.1  skrll 	add,nuv		%r25,%r25,%r25		; shift left, skip next if not C
    124  1.1  skrll loop_mul:
    125  1.1  skrll 	sh1add,tr	%r29,%r26,%r29		; shift left and add, skip next
    126  1.1  skrll 	sh1add		%r29,%r0,%r29		; shift left only
    127  1.1  skrll 	addib,<>,n	-1,%r1,loop_mul		; check loop condition
    128  1.1  skrll 	add,nuv		%r25,%r25,%r25		; shift left, skip next if not C
    129  1.1  skrll 	.exit
    130  1.1  skrll 	bv,n		%r0(%r31)		; return millicode
    131  1.1  skrll 	.procend
    132