]> git.lizzy.rs Git - plan9front.git/blob - sys/src/libc/sparc/muldivrt.s
fltfmt: %.ng is supposed to print a number with n significant figures, but it prints...
[plan9front.git] / sys / src / libc / sparc / muldivrt.s
1 /*
2  *      ulong
3  *      _udiv(ulong num, ulong den)
4  *      {
5  *              int i;
6  *              ulong quo;
7  *
8  *              if(den == 0)
9  *                      *(ulong*)-1 = 0;
10  *              quo = num;
11  *              if(quo > 1<<(32-1))
12  *                      quo = 1<<(32-1);
13  *              for(i=0; den<quo; i++)
14  *                      den <<= 1;
15  *              quo = 0;
16  *              for(; i>=0; i--) {
17  *                      quo <<= 1;
18  *                      if(num >= den) {
19  *                              num -= den;
20  *                              quo |= 1;
21  *                      }
22  *                      den >>= 1;
23  *              }
24  *              return quo::num;
25  *      }
26  */
27
28 #define NOPROF  1
29
30 /*
31  * calling sequence:
32  *      num: 4(R1)
33  *      den: 8(R1)
34  * returns
35  *      quo: 4(R1)
36  *      rem: 8(R1)
37  */
38 TEXT    _udivmod(SB), NOPROF, $-4
39
40         MOVW    $(1<<31), R11
41         MOVW    4(R1), R13      /* numerator */
42         MOVW    8(R1), R10      /* denominator */
43         CMP     R10, R0
44         BNE     udm20
45         MOVW    R0, -1(R0)      /* fault -- divide by zero */
46 udm20:
47         MOVW    R13, R12
48         CMP     R13, R11
49         BLEU    udm34
50         MOVW    R11, R12
51 udm34:
52         MOVW    R0, R11
53 udm38:
54         CMP     R10, R12
55         BCC     udm54
56         SLL     $1, R10
57         ADD     $1, R11
58         BA      udm38
59 udm54:
60         MOVW    R0, R12
61 udm58:
62         CMP     R11, R0
63         BL      udm8c
64         SLL     $1, R12
65         CMP     R13, R10
66         BCS     udm7c
67         SUB     R10, R13
68         OR      $1, R12
69 udm7c:
70         SRL     $1, R10
71         SUB     $1, R11
72         BA      udm58
73 udm8c:
74         MOVW    R12, 4(R1)      /* quotent */
75         MOVW    R13, 8(R1)      /* remainder */
76         JMPL    8(R15)
77
78 /*
79  * save working registers
80  * and bring in num/den parameters
81  */
82 TEXT    _unsarg(SB), NOPROF, $-4
83         MOVW    R10, 12(R1)
84         MOVW    R11, 16(R1)
85         MOVW    R12, 20(R1)
86         MOVW    R13, 24(R1)
87
88         MOVW    R14, 4(R1)
89         MOVW    32(R1), R14
90         MOVW    R14, 8(R1)
91
92         JMPL    8(R15)
93
94 /*
95  * save working registers
96  * and bring in absolute value
97  * of num/den parameters
98  */
99 TEXT    _absarg(SB), NOPROF, $-4
100         MOVW    R10, 12(R1)
101         MOVW    R11, 16(R1)
102         MOVW    R12, 20(R1)
103         MOVW    R13, 24(R1)
104
105         MOVW    R14, 28(R1)
106         CMP     R14, R0
107         BGE     ab1
108         SUB     R14, R0, R14
109 ab1:
110         MOVW    R14, 4(R1)      /* numerator */
111
112         MOVW    32(R1), R14
113         CMP     R14, R0
114         BGE     ab2
115         SUB     R14, R0, R14
116 ab2:
117         MOVW    R14, 8(R1)      /* denominator */
118         JMPL    8(R15)
119
120 /*
121  * restore registers and
122  * return to original caller
123  * answer is in R14
124  */
125 TEXT    _retarg(SB), NOPROF, $-4
126         MOVW    12(R1), R10
127         MOVW    16(R1), R11
128         MOVW    20(R1), R12
129         MOVW    24(R1), R13
130         MOVW    0(R1), R15
131
132         ADD     $28, R1
133         JMP     8(R15)          /* back to main sequence */
134
135 /*
136  * calling sequence
137  *      num: R14
138  *      den: 8(R1)
139  * returns
140  *      quo: R14
141  */
142 TEXT    _div(SB), NOPROF, $-4
143         SUB     $28, R1         /* 4 reg save, 2 parameters, link */
144         MOVW    R15, 0(R1)
145
146         JMPL    _absarg(SB)
147         JMPL    _udivmod(SB)
148         MOVW    4(R1), R14
149
150         MOVW    28(R1), R10     /* clean up the sign */
151         MOVW    32(R1), R11
152         XORCC   R11, R10, R0
153         BGE     div1
154         SUB     R14, R0, R14
155 div1:
156
157         JMPL    _retarg(SB)
158         JMP     8(R15)          /* not executed */
159
160 /*
161  * calling sequence
162  *      num: R14
163  *      den: 8(R1)
164  * returns
165  *      quo: R14
166  */
167 TEXT    _divl(SB), NOPROF, $-4
168         SUB     $((4+2+1)*4), R1        /* 4 reg save, 2 parameters, link */
169         MOVW    R15, 0(R1)
170
171         JMPL    _unsarg(SB)
172         JMPL    _udivmod(SB)
173         MOVW    4(R1), R14
174
175         JMPL    _retarg(SB)
176         JMP     8(R15)          /* not executed */
177
178 /*
179  * calling sequence
180  *      num: R14
181  *      den: 8(R1)
182  * returns
183  *      rem: R14
184  */
185 TEXT    _mod(SB), NOPROF, $-4
186         SUB     $28, R1         /* 4 reg save, 2 parameters, link */
187
188         MOVW    R15, 0(R1)
189         JMPL    _absarg(SB)
190         JMPL    _udivmod(SB)
191         MOVW    8(R1), R14
192
193         MOVW    28(R1), R10     /* clean up the sign */
194         CMP     R10, R0
195         BGE     mod1
196         SUB     R14, R0, R14
197 mod1:
198
199         JMPL    _retarg(SB)
200         JMP     8(R15)          /* not executed */
201
202 /*
203  * calling sequence
204  *      num: R14
205  *      den: 8(R1)
206  * returns
207  *      rem: R14
208  */
209 TEXT    _modl(SB), NOPROF, $-4
210         SUB     $28, R1         /* 4 reg save, 2 parameters, link */
211
212
213         MOVW    R15, 0(R1)
214         JMPL    _unsarg(SB)
215         JMPL    _udivmod(SB)
216         MOVW    8(R1), R14
217
218         JMPL    _retarg(SB)
219         JMP     8(R15)          /* not executed */
220
221 /*
222  * special calling sequence:
223  *      arg1 in R14
224  *      arg2 in 4(R1),    will save R9
225  *      nothing in 0(R1), will save R8
226  *      result in R14
227  */
228 TEXT    _mul+0(SB), NOPROF, $-4
229
230         /*
231          * exchange stack and registers
232          */
233         MOVW    R8, 0(R1)
234         MOVW    4(R1), R8
235         MOVW    R9, 4(R1)
236
237         CMP     R14, R8
238         BLE     mul1
239         MOVW    R14, R9
240         MOVW    R8, R14
241         MOVW    R9, R8
242 mul1:
243         MOVW    R14, Y
244         ANDNCC  $0xFFF, R14, R0
245         BE      mul_shortway
246         ANDCC   R0, R0, R9      /* zero partial product and clear N and V cond's */
247
248         /* long multiply */
249         MULSCC  R8, R9, R9              /* 0 */
250         MULSCC  R8, R9, R9              /* 1 */
251         MULSCC  R8, R9, R9              /* 2 */
252         MULSCC  R8, R9, R9              /* 3 */
253         MULSCC  R8, R9, R9              /* 4 */
254         MULSCC  R8, R9, R9              /* 5 */
255         MULSCC  R8, R9, R9              /* 6 */
256         MULSCC  R8, R9, R9              /* 7 */
257         MULSCC  R8, R9, R9              /* 8 */
258         MULSCC  R8, R9, R9              /* 9 */
259         MULSCC  R8, R9, R9              /* 10 */
260         MULSCC  R8, R9, R9              /* 11 */
261         MULSCC  R8, R9, R9              /* 12 */
262         MULSCC  R8, R9, R9              /* 13 */
263         MULSCC  R8, R9, R9              /* 14 */
264         MULSCC  R8, R9, R9              /* 15 */
265         MULSCC  R8, R9, R9              /* 16 */
266         MULSCC  R8, R9, R9              /* 17 */
267         MULSCC  R8, R9, R9              /* 18 */
268         MULSCC  R8, R9, R9              /* 19 */
269         MULSCC  R8, R9, R9              /* 20 */
270         MULSCC  R8, R9, R9              /* 21 */
271         MULSCC  R8, R9, R9              /* 22 */
272         MULSCC  R8, R9, R9              /* 23 */
273         MULSCC  R8, R9, R9              /* 24 */
274         MULSCC  R8, R9, R9              /* 25 */
275         MULSCC  R8, R9, R9              /* 26 */
276         MULSCC  R8, R9, R9              /* 27 */
277         MULSCC  R8, R9, R9              /* 28 */
278         MULSCC  R8, R9, R9              /* 29 */
279         MULSCC  R8, R9, R9              /* 30 */
280         MULSCC  R8, R9, R9              /* 31 */
281         MULSCC  R0, R9, R9              /* 32; shift only */
282
283         MOVW    Y, R14                  /* get low part */
284         BA      mul_return
285
286 mul_shortway:
287         ANDCC   R0, R0, R9      /* zero partial product and clear N and V cond's */
288         MULSCC  R8, R9, R9              /*  0 */
289         MULSCC  R8, R9, R9              /*  1 */
290         MULSCC  R8, R9, R9              /*  2 */
291         MULSCC  R8, R9, R9              /*  3 */
292         MULSCC  R8, R9, R9              /*  4 */
293         MULSCC  R8, R9, R9              /*  5 */
294         MULSCC  R8, R9, R9              /*  6 */
295         MULSCC  R8, R9, R9              /*  7 */
296         MULSCC  R8, R9, R9              /*  8 */
297         MULSCC  R8, R9, R9              /*  9 */
298         MULSCC  R8, R9, R9              /* 10 */
299         MULSCC  R8, R9, R9              /* 11 */
300         MULSCC  R0, R9, R9              /* 12; shift only */
301
302         MOVW    Y, R8
303         SLL     $12, R9
304         SRL     $20, R8
305         OR      R8, R9, R14
306
307 mul_return:
308         MOVW    0(R1), R8
309         MOVW    4(R1), R9
310         JMP     8(R15)