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