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>.
5 Copyright 2001, 2002, 2003 Free Software Foundation, Inc.
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
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
28 . sr0 == return space when called externally
35 OTHER REGISTERS AFFECTED:
39 . Causes a trap under the following conditions: DIVIDE BY ZERO
40 . Changes memory at the following places: NONE
44 . Does not create a stack frame
45 . Is usable for internal or external microcode
48 . Calls other millicode routines via mrp: NONE
49 . Calls other millicode routines: NONE */
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 */
69 comb,>,n 0,arg0,LREF(neg_num) /* is numerator < 0 ? */
70 and arg0,tmp,retreg /* get the result */
73 subi 0,arg0,arg0 /* negate numerator */
74 and arg0,tmp,retreg /* get the result */
75 subi 0,retreg,retreg /* negate result */
78 addi,< 0,arg1,r0 /* if arg1 >= 0, it's not power */
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 */
86 comb,>,n 0,arg0,LREF(neg_num_2) /* if arg0 < 0, negate it */
87 and arg0,retreg,retreg
90 subi 0,arg0,tmp /* test against 0x80000000 */
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 */
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 */
175 add,>= arg0,0,0 /* set sign of remainder */
176 sub 0,retreg,retreg /* to sign of dividend */