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 */ 38TEXT _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 */ 46udm20: 47 MOVW R13, R12 48 CMP R13, R11 49 BLEU udm34 50 MOVW R11, R12 51udm34: 52 MOVW R0, R11 53udm38: 54 CMP R10, R12 55 BCC udm54 56 SLL $1, R10 57 ADD $1, R11 58 BA udm38 59udm54: 60 MOVW R0, R12 61udm58: 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 69udm7c: 70 SRL $1, R10 71 SUB $1, R11 72 BA udm58 73udm8c: 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 */ 82TEXT _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 */ 99TEXT _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 109ab1: 110 MOVW R14, 4(R1) /* numerator */ 111 112 MOVW 32(R1), R14 113 CMP R14, R0 114 BGE ab2 115 SUB R14, R0, R14 116ab2: 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 */ 125TEXT _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 */ 142TEXT _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 155div1: 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 */ 167TEXT _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 */ 185TEXT _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 197mod1: 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 */ 209TEXT _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 */ 228TEXT _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 242mul1: 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 286mul_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 307mul_return: 308 MOVW 0(R1), R8 309 MOVW 4(R1), R9 310 JMP 8(R15) 311