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