diff options
Diffstat (limited to 'libmp/Plan9-386/mpvecdigmuladd.s')
| -rw-r--r-- | libmp/Plan9-386/mpvecdigmuladd.s | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/libmp/Plan9-386/mpvecdigmuladd.s b/libmp/Plan9-386/mpvecdigmuladd.s new file mode 100644 index 00000000..5a262ce8 --- /dev/null +++ b/libmp/Plan9-386/mpvecdigmuladd.s @@ -0,0 +1,52 @@ +/* + * mpvecdigmul(mpdigit *b, int n, mpdigit m, mpdigit *p) + * + * p += b*m + * + * each step look like: + * hi,lo = m*b[i] + * lo += oldhi + carry + * hi += carry + * p[i] += lo + * oldhi = hi + * + * the registers are: + * hi = DX - constrained by hardware + * lo = AX - constrained by hardware + * b+n = SI - can't be BP + * p+n = DI - can't be BP + * i-n = BP + * m = BX + * oldhi = CX + * + */ +TEXT mpvecdigmuladd(SB),$0 + + MOVL b+0(FP),SI + MOVL n+4(FP),CX + MOVL m+8(FP),BX + MOVL p+12(FP),DI + MOVL CX,BP + NEGL BP /* BP = -n */ + SHLL $2,CX + ADDL CX,SI /* SI = b + n */ + ADDL CX,DI /* DI = p + n */ + XORL CX,CX +_muladdloop: + MOVL (SI)(BP*4),AX /* lo = b[i] */ + MULL BX /* hi, lo = b[i] * m */ + ADDL CX,AX /* lo += oldhi */ + JCC _muladdnocarry1 + INCL DX /* hi += carry */ +_muladdnocarry1: + ADDL AX,(DI)(BP*4) /* p[i] += lo */ + JCC _muladdnocarry2 + INCL DX /* hi += carry */ +_muladdnocarry2: + MOVL DX,CX /* oldhi = hi */ + INCL BP /* i++ */ + JNZ _muladdloop + XORL AX,AX + ADDL CX,(DI)(BP*4) /* p[n] + oldhi */ + ADCL AX,AX /* return carry out of p[n] */ + RET |
