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