diff options
Diffstat (limited to 'libmp/Plan9-386')
| -rw-r--r-- | libmp/Plan9-386/mkfile | 21 | ||||
| -rw-r--r-- | libmp/Plan9-386/mpdigdiv.s | 21 | ||||
| -rw-r--r-- | libmp/Plan9-386/mpvecadd.s | 53 | ||||
| -rw-r--r-- | libmp/Plan9-386/mpvecdigmuladd.s | 52 | ||||
| -rw-r--r-- | libmp/Plan9-386/mpvecdigmulsub.s | 53 | ||||
| -rw-r--r-- | libmp/Plan9-386/mpvecsub.s | 44 |
6 files changed, 244 insertions, 0 deletions
diff --git a/libmp/Plan9-386/mkfile b/libmp/Plan9-386/mkfile new file mode 100644 index 00000000..87b8a068 --- /dev/null +++ b/libmp/Plan9-386/mkfile @@ -0,0 +1,21 @@ +objtype=386 +OBJTYPE=$objtype +<../../mkconfig + +LIB=libmp.a +SFILES=\ + mpvecadd.s\ + mpvecdigmuladd.s\ + mpvecdigmulsub.s\ + mpvecsub.s\ + mpdigdiv.s\ + +HFILES=$ROOT/$SYSTARG/$OBJTYPE/include/u.h $ROOT/include/mp.h ../port/dat.h + +OFILES=${SFILES:%.s=%.$O} + +UPDATE=mkfile\ + $HFILES\ + $SFILES\ + +<$ROOT/mkfiles/mksyslib-$SHELLTYPE diff --git a/libmp/Plan9-386/mpdigdiv.s b/libmp/Plan9-386/mpdigdiv.s new file mode 100644 index 00000000..8ee4d67a --- /dev/null +++ b/libmp/Plan9-386/mpdigdiv.s @@ -0,0 +1,21 @@ +TEXT mpdigdiv(SB),$0 + + MOVL dividend+0(FP),BX + MOVL 0(BX),AX + MOVL 4(BX),DX + MOVL divisor+4(FP),BX + MOVL quotient+8(FP),BP + XORL CX,CX + CMPL DX,BX /* dividend >= 2^32 * divisor */ + JHS _divovfl + CMPL BX,CX /* divisor == 0 */ + JE _divovfl + DIVL BX /* AX = DX:AX/BX */ + MOVL AX,0(BP) + RET + + /* return all 1's */ +_divovfl: + NOTL CX + MOVL CX,0(BP) + RET diff --git a/libmp/Plan9-386/mpvecadd.s b/libmp/Plan9-386/mpvecadd.s new file mode 100644 index 00000000..50a45b14 --- /dev/null +++ b/libmp/Plan9-386/mpvecadd.s @@ -0,0 +1,53 @@ +/* + * mpvecadd(mpdigit *a, int alen, mpdigit *b, int blen, mpdigit *sum) + * + * sum[0:alen] = a[0:alen-1] + b[0:blen-1] + * + * prereq: alen >= blen, sum has room for alen+1 digits + */ +TEXT mpvecadd(SB),$0 + + MOVL alen+4(FP),DX + MOVL blen+12(FP),CX + MOVL a+0(FP),SI + MOVL b+8(FP),BX + SUBL CX,DX + MOVL sum+16(FP),DI + XORL BP,BP /* this also sets carry to 0 */ + + /* skip addition if b is zero */ + TESTL CX,CX + JZ _add1 + + /* sum[0:blen-1],carry = a[0:blen-1] + b[0:blen-1] */ +_addloop1: + MOVL (SI)(BP*4), AX + ADCL (BX)(BP*4), AX + MOVL AX,(DI)(BP*4) + INCL BP + LOOP _addloop1 + +_add1: + /* jump if alen > blen */ + INCL DX + MOVL DX,CX + LOOP _addloop2 + + /* sum[alen] = carry */ +_addend: + JC _addcarry + MOVL $0,(DI)(BP*4) + RET +_addcarry: + MOVL $1,(DI)(BP*4) + RET + + /* sum[blen:alen-1],carry = a[blen:alen-1] + 0 */ +_addloop2: + MOVL (SI)(BP*4),AX + ADCL $0,AX + MOVL AX,(DI)(BP*4) + INCL BP + LOOP _addloop2 + JMP _addend + 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 diff --git a/libmp/Plan9-386/mpvecdigmulsub.s b/libmp/Plan9-386/mpvecdigmulsub.s new file mode 100644 index 00000000..ab28ef03 --- /dev/null +++ b/libmp/Plan9-386/mpvecdigmulsub.s @@ -0,0 +1,53 @@ +/* + * mpvecdigmulsub(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 = SI - can't be BP + * p = DI - can't be BP + * i = BP + * n = CX - constrained by LOOP instr + * m = BX + * oldhi = EX + * + */ +TEXT mpvecdigmulsub(SB),$0 + + MOVL b+0(FP),SI + MOVL n+4(FP),CX + MOVL m+8(FP),BX + MOVL p+12(FP),DI + XORL BP,BP + PUSHL BP +_mulsubloop: + MOVL (SI)(BP*4),AX /* lo = b[i] */ + MULL BX /* hi, lo = b[i] * m */ + ADDL 0(SP),AX /* lo += oldhi */ + JCC _mulsubnocarry1 + INCL DX /* hi += carry */ +_mulsubnocarry1: + SUBL AX,(DI)(BP*4) + JCC _mulsubnocarry2 + INCL DX /* hi += carry */ +_mulsubnocarry2: + MOVL DX,0(SP) + INCL BP + LOOP _mulsubloop + POPL AX + SUBL AX,(DI)(BP*4) + JCC _mulsubnocarry3 + MOVL $-1,AX + RET +_mulsubnocarry3: + MOVL $1,AX + RET diff --git a/libmp/Plan9-386/mpvecsub.s b/libmp/Plan9-386/mpvecsub.s new file mode 100644 index 00000000..ebe8d29a --- /dev/null +++ b/libmp/Plan9-386/mpvecsub.s @@ -0,0 +1,44 @@ +/* + * mpvecsub(mpdigit *a, int alen, mpdigit *b, int blen, mpdigit *diff) + * + * diff[0:alen-1] = a[0:alen-1] - b[0:blen-1] + * + * prereq: alen >= blen, diff has room for alen digits + */ +TEXT mpvecsub(SB),$0 + + MOVL a+0(FP),SI + MOVL b+8(FP),BX + MOVL alen+4(FP),DX + MOVL blen+12(FP),CX + MOVL diff+16(FP),DI + SUBL CX,DX + XORL BP,BP /* this also sets carry to 0 */ + + /* skip subraction if b is zero */ + TESTL CX,CX + JZ _sub1 + + /* diff[0:blen-1],borrow = a[0:blen-1] - b[0:blen-1] */ +_subloop1: + MOVL (SI)(BP*4),AX + SBBL (BX)(BP*4),AX + MOVL AX,(DI)(BP*4) + INCL BP + LOOP _subloop1 + +_sub1: + INCL DX + MOVL DX,CX + LOOP _subloop2 + RET + + /* diff[blen:alen-1] = a[blen:alen-1] - 0 */ +_subloop2: + MOVL (SI)(BP*4),AX + SBBL $0,AX + MOVL AX,(DI)(BP*4) + INCL BP + LOOP _subloop2 + RET + |
