Pull cpuidle into release branch
[pandora-kernel.git] / arch / parisc / lib / milli / remI.S
1 /* 32 and 64-bit millicode, original author Hewlett-Packard
2    adapted for gcc by Paul Bame <bame@debian.org>
3    and Alan Modra <alan@linuxcare.com.au>.
4
5    Copyright 2001, 2002, 2003 Free Software Foundation, Inc.
6
7    This file is part of GCC and is released under the terms of
8    of the GNU General Public License as published by the Free Software
9    Foundation; either version 2, or (at your option) any later version.
10    See the file COPYING in the top-level GCC source directory for a copy
11    of the license.  */
12
13 #include "milli.h"
14
15 #ifdef L_remI
16 /* ROUTINE:     $$remI
17
18    DESCRIPTION:
19    .    $$remI returns the remainder of the division of two signed 32-bit
20    .    integers.  The sign of the remainder is the same as the sign of
21    .    the dividend.
22
23
24    INPUT REGISTERS:
25    .    arg0 == dividend
26    .    arg1 == divisor
27    .    mrp  == return pc
28    .    sr0  == return space when called externally
29
30    OUTPUT REGISTERS:
31    .    arg0 = destroyed
32    .    arg1 = destroyed
33    .    ret1 = remainder
34
35    OTHER REGISTERS AFFECTED:
36    .    r1   = undefined
37
38    SIDE EFFECTS:
39    .    Causes a trap under the following conditions:  DIVIDE BY ZERO
40    .    Changes memory at the following places:  NONE
41
42    PERMISSIBLE CONTEXT:
43    .    Unwindable
44    .    Does not create a stack frame
45    .    Is usable for internal or external microcode
46
47    DISCUSSION:
48    .    Calls other millicode routines via mrp:  NONE
49    .    Calls other millicode routines:  NONE  */
50
51 RDEFINE(tmp,r1)
52 RDEFINE(retreg,ret1)
53
54         SUBSPA_MILLI
55         ATTR_MILLI
56         .proc
57         .callinfo millicode
58         .entry
59 GSYM($$remI)
60 GSYM($$remoI)
61         .export $$remI,MILLICODE
62         .export $$remoI,MILLICODE
63         ldo             -1(arg1),tmp            /*  is there at most one bit set ? */
64         and,<>          arg1,tmp,r0             /*  if not, don't use power of 2 */
65         addi,>          0,arg1,r0               /*  if denominator > 0, use power */
66                                                 /*  of 2 */
67         b,n             LREF(neg_denom)
68 LSYM(pow2)
69         comb,>,n        0,arg0,LREF(neg_num)    /*  is numerator < 0 ? */
70         and             arg0,tmp,retreg         /*  get the result */
71         MILLIRETN
72 LSYM(neg_num)
73         subi            0,arg0,arg0             /*  negate numerator */
74         and             arg0,tmp,retreg         /*  get the result */
75         subi            0,retreg,retreg         /*  negate result */
76         MILLIRETN
77 LSYM(neg_denom)
78         addi,<          0,arg1,r0               /*  if arg1 >= 0, it's not power */
79                                                 /*  of 2 */
80         b,n             LREF(regular_seq)
81         sub             r0,arg1,tmp             /*  make denominator positive */
82         comb,=,n        arg1,tmp,LREF(regular_seq) /*  test against 0x80000000 and 0 */
83         ldo             -1(tmp),retreg          /*  is there at most one bit set ? */
84         and,=           tmp,retreg,r0           /*  if not, go to regular_seq */
85         b,n             LREF(regular_seq)
86         comb,>,n        0,arg0,LREF(neg_num_2)  /*  if arg0 < 0, negate it  */
87         and             arg0,retreg,retreg
88         MILLIRETN
89 LSYM(neg_num_2)
90         subi            0,arg0,tmp              /*  test against 0x80000000 */
91         and             tmp,retreg,retreg
92         subi            0,retreg,retreg
93         MILLIRETN
94 LSYM(regular_seq)
95         addit,=         0,arg1,0                /*  trap if div by zero */
96         add,>=          0,arg0,retreg           /*  move dividend, if retreg < 0, */
97         sub             0,retreg,retreg         /*    make it positive */
98         sub             0,arg1, tmp             /*  clear carry,  */
99                                                 /*    negate the divisor */
100         ds              0, tmp,0                /*  set V-bit to the comple- */
101                                                 /*    ment of the divisor sign */
102         or              0,0, tmp                /*  clear  tmp */
103         add             retreg,retreg,retreg    /*  shift msb bit into carry */
104         ds               tmp,arg1, tmp          /*  1st divide step, if no carry */
105                                                 /*    out, msb of quotient = 0 */
106         addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
107 LSYM(t1)
108         ds               tmp,arg1, tmp          /*  2nd divide step */
109         addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
110         ds               tmp,arg1, tmp          /*  3rd divide step */
111         addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
112         ds               tmp,arg1, tmp          /*  4th divide step */
113         addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
114         ds               tmp,arg1, tmp          /*  5th divide step */
115         addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
116         ds               tmp,arg1, tmp          /*  6th divide step */
117         addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
118         ds               tmp,arg1, tmp          /*  7th divide step */
119         addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
120         ds               tmp,arg1, tmp          /*  8th divide step */
121         addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
122         ds               tmp,arg1, tmp          /*  9th divide step */
123         addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
124         ds               tmp,arg1, tmp          /*  10th divide step */
125         addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
126         ds               tmp,arg1, tmp          /*  11th divide step */
127         addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
128         ds               tmp,arg1, tmp          /*  12th divide step */
129         addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
130         ds               tmp,arg1, tmp          /*  13th divide step */
131         addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
132         ds               tmp,arg1, tmp          /*  14th divide step */
133         addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
134         ds               tmp,arg1, tmp          /*  15th divide step */
135         addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
136         ds               tmp,arg1, tmp          /*  16th divide step */
137         addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
138         ds               tmp,arg1, tmp          /*  17th divide step */
139         addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
140         ds               tmp,arg1, tmp          /*  18th divide step */
141         addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
142         ds               tmp,arg1, tmp          /*  19th divide step */
143         addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
144         ds               tmp,arg1, tmp          /*  20th divide step */
145         addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
146         ds               tmp,arg1, tmp          /*  21st divide step */
147         addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
148         ds               tmp,arg1, tmp          /*  22nd divide step */
149         addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
150         ds               tmp,arg1, tmp          /*  23rd divide step */
151         addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
152         ds               tmp,arg1, tmp          /*  24th divide step */
153         addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
154         ds               tmp,arg1, tmp          /*  25th divide step */
155         addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
156         ds               tmp,arg1, tmp          /*  26th divide step */
157         addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
158         ds               tmp,arg1, tmp          /*  27th divide step */
159         addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
160         ds               tmp,arg1, tmp          /*  28th divide step */
161         addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
162         ds               tmp,arg1, tmp          /*  29th divide step */
163         addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
164         ds               tmp,arg1, tmp          /*  30th divide step */
165         addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
166         ds               tmp,arg1, tmp          /*  31st divide step */
167         addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
168         ds               tmp,arg1, tmp          /*  32nd divide step, */
169         addc            retreg,retreg,retreg    /*  shift last bit into retreg */
170         movb,>=,n        tmp,retreg,LREF(finish) /*  branch if pos.  tmp */
171         add,<           arg1,0,0                /*  if arg1 > 0, add arg1 */
172         add,tr           tmp,arg1,retreg        /*    for correcting remainder tmp */
173         sub              tmp,arg1,retreg        /*  else add absolute value arg1 */
174 LSYM(finish)
175         add,>=          arg0,0,0                /*  set sign of remainder */
176         sub             0,retreg,retreg         /*    to sign of dividend */
177         MILLIRET
178         nop
179         .exit
180         .procend
181 #ifdef milliext
182         .origin 0x00000200
183 #endif
184         .end
185 #endif