diff options
| author | Charles.Forsyth <devnull@localhost> | 2006-12-22 17:07:39 +0000 |
|---|---|---|
| committer | Charles.Forsyth <devnull@localhost> | 2006-12-22 17:07:39 +0000 |
| commit | 37da2899f40661e3e9631e497da8dc59b971cbd0 (patch) | |
| tree | cbc6d4680e347d906f5fa7fca73214418741df72 /libmp/Plan9-mips | |
| parent | 54bc8ff236ac10b3eaa928fd6bcfc0cdb2ba46ae (diff) | |
20060303a
Diffstat (limited to 'libmp/Plan9-mips')
| -rw-r--r-- | libmp/Plan9-mips/mkfile | 21 | ||||
| -rw-r--r-- | libmp/Plan9-mips/mpdigdiv.s | 41 | ||||
| -rw-r--r-- | libmp/Plan9-mips/mpvecadd.s | 67 | ||||
| -rw-r--r-- | libmp/Plan9-mips/mpvecdigmuladd.s | 58 | ||||
| -rw-r--r-- | libmp/Plan9-mips/mpvecdigmulsub.s | 61 | ||||
| -rw-r--r-- | libmp/Plan9-mips/mpvecsub.s | 66 |
6 files changed, 314 insertions, 0 deletions
diff --git a/libmp/Plan9-mips/mkfile b/libmp/Plan9-mips/mkfile new file mode 100644 index 00000000..b5b8a6cf --- /dev/null +++ b/libmp/Plan9-mips/mkfile @@ -0,0 +1,21 @@ +objtype=mips +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-mips/mpdigdiv.s b/libmp/Plan9-mips/mpdigdiv.s new file mode 100644 index 00000000..b7fd330e --- /dev/null +++ b/libmp/Plan9-mips/mpdigdiv.s @@ -0,0 +1,41 @@ +/* + * This only works on R[45]000 chips that allow 64 bit + * integer arithmetic even when uding 32 bit addresses + * + * R1 = dividend* + * R2 = dividend[low] + * R3 = dividend[high] + * R4 = 32 bit divisor + * R5 = quotient* + */ +TEXT mpdigdiv(SB),$0 + + MOVW 0(R1),R2 + MOVW 4(R1),R3 + MOVW divisor+4(FP),R4 + MOVW quotient+8(FP),R5 + + /* divisor == 0 */ + BEQ R4,_digovfl + + /* dividend >= 2^32 * divisor */ + SGTU R4,R3,R7 + BEQ R7,_digovfl + +_digdiv1: + SLLV $32,R2 + SLLV $32,R3 + SRLV $32,R2 + ADDVU R2,R3 + SLLV $32,R4 + SRLV $32,R4 + DIVVU R4,R3 + MOVW LO,R1 + MOVW R1,0(R5) + RET + +_digovfl: + MOVW $-1,R1 + MOVW R1,0(R5) + RET + diff --git a/libmp/Plan9-mips/mpvecadd.s b/libmp/Plan9-mips/mpvecadd.s new file mode 100644 index 00000000..8d3e8d63 --- /dev/null +++ b/libmp/Plan9-mips/mpvecadd.s @@ -0,0 +1,67 @@ +#define BDNZ BC 16,0, +#define BDNE BC 0,2, + +/* + * 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 + * + * R1 == a (first arg passed in R1) + * R3 == carry + * R4 == alen + * R5 == b + * R6 == blen + * R7 == sum + * R2 == temporary + * R8 == temporary + * R9 == temporary + */ +TEXT mpvecadd(SB),$-4 + + MOVW alen+4(FP), R4 + MOVW b+8(FP), R5 + MOVW blen+12(FP), R6 + MOVW sum+16(FP), R7 + SUBU R6, R4 /* calculate counter for second loop (alen > blen) */ + MOVW R0, R3 + + /* if blen == 0, don't need to add it in */ + BEQ R6,_add1 + + /* sum[0:blen-1],carry = a[0:blen-1] + b[0:blen-1] */ +_addloop1: + MOVW 0(R1), R8 + ADDU $4, R1 + MOVW 0(R5), R9 + ADDU $4, R5 + ADDU R3, R8 + SGTU R3, R8, R3 + ADDU R8, R9 + SGTU R8, R9, R2 + ADDU R2, R3 + MOVW R9, 0(R7) + ADDU $4, R7 + SUBU $1, R6 + BNE R6, _addloop1 + +_add1: + /* if alen == blen, we're done */ + BEQ R4, _addend + + /* sum[blen:alen-1],carry = a[blen:alen-1] + 0 + carry */ +_addloop2: + MOVW 0(R1), R8 + ADDU $4, R1 + ADDU R3, R8 + SGTU R3, R8, R3 + MOVW R8, 0(R7) + ADDU $4, R7 + SUBU $1, R4 + BNE R4, _addloop2 + + /* sum[alen] = carry */ +_addend: + MOVW R3, 0(R7) + RET diff --git a/libmp/Plan9-mips/mpvecdigmuladd.s b/libmp/Plan9-mips/mpvecdigmuladd.s new file mode 100644 index 00000000..d80073b1 --- /dev/null +++ b/libmp/Plan9-mips/mpvecdigmuladd.s @@ -0,0 +1,58 @@ +/* + * mpvecdigmuladd(mpdigit *b, int n, mpdigit m, mpdigit *p) + * + * p += b*m + * + * each step looks like: + * hi,lo = m*b[i] + * lo += oldhi + carry + * hi += carry + * p[i] += lo + * oldhi = hi + * + * the registers are: + * b = R1 + * n = R4 + * m = R5 + * p = R6 + * i = R7 + * hi = R8 - constrained by hardware + * lo = R9 - constrained by hardware + * oldhi = R10 + * tmp = R11 + * + */ +TEXT mpvecdigmuladd(SB),$0 + + MOVW n+4(FP),R4 + MOVW m+8(FP),R5 + MOVW p+12(FP),R6 + + + MOVW R0, R10 /* oldhi = 0 */ + BEQ R6, _muladd1 +_muladdloop: + MOVW 0(R1), R9 /* lo = b[i] */ + ADDU $4, R1 + MOVW 0(R6), R11 /* tmp = p[i] */ + MULU R9, R5 + MOVW HI, R8 /* hi = (b[i] * m)>>32 */ + MOVW LO, R9 /* lo = b[i] * m */ + ADDU R10, R9 /* lo += oldhi */ + SGTU R10, R9, R2 + ADDU R2, R8 /* hi += carry */ + ADDU R9, R11 /* tmp += lo */ + SGTU R9, R11, R2 + ADDU R2, R8 /* hi += carry */ + MOVW R11, 0(R6) /* p[i] = tmp */ + ADDU $4, R6 + MOVW R8, R10 /* oldhi = hi */ + SUBU $1, R4 + BNE R4, _muladdloop + +_muladd1: + MOVW 0(R6), R11 /* tmp = p[i] */ + ADDU R10, R11 /* tmp += oldhi */ + MOVW R11, 0(R6) /* p[i] = tmp */ + + RET diff --git a/libmp/Plan9-mips/mpvecdigmulsub.s b/libmp/Plan9-mips/mpvecdigmulsub.s new file mode 100644 index 00000000..c1a1739c --- /dev/null +++ b/libmp/Plan9-mips/mpvecdigmulsub.s @@ -0,0 +1,61 @@ +/* + * mpvecdigmulsub(mpdigit *b, int n, mpdigit m, mpdigit *p) + * + * p -= b*m + * + * each step looks like: + * hi,lo = m*b[i] + * lo += oldhi + carry + * hi += carry + * p[i] += lo + * oldhi = hi + * + * the registers are: + * b = R1 + * n = R4 + * m = R5 + * p = R6 + * i = R7 + * hi = R8 - constrained by hardware + * lo = R9 - constrained by hardware + * oldhi = R10 + * tmp = R11 + * + */ +TEXT mpvecdigmulsub(SB),$0 + + MOVW n+4(FP),R4 + MOVW m+8(FP),R5 + MOVW p+12(FP),R6 + + MOVW R0, R10 /* oldhi = 0 */ +_mulsubloop: + MOVW 0(R1), R9 /* lo = b[i] */ + ADDU $4, R1 + MOVW 0(R6), R11 /* tmp = p[i] */ + MULU R9, R5 + MOVW HI, R8 /* hi = (b[i] * m)>>32 */ + MOVW LO, R9 /* lo = b[i] * m */ + ADDU R10, R9 /* lo += oldhi */ + SGTU R10, R9, R2 + ADDU R2, R8 /* hi += carry */ + SUBU R9, R11, R3 /* tmp -= lo */ + SGTU R3, R11, R2 + ADDU R2, R8 /* hi += carry */ + MOVW R3, 0(R6) /* p[i] = tmp */ + ADDU $4, R6 + MOVW R8, R10 /* oldhi = hi */ + SUBU $1, R4 + BNE R4, _mulsubloop + + MOVW 0(R6), R11 /* tmp = p[i] */ + SUBU R10, R11, R3 /* tmp -= oldhi */ + MOVW R3, 0(R6) /* p[i] = tmp */ + SGTU R3, R11, R1 + BNE R1, _mulsub2 + MOVW $1, R1 /* return +1 for positive result */ + RET + +_mulsub2: + MOVW $-1, R1 /* return -1 for negative result */ + RET diff --git a/libmp/Plan9-mips/mpvecsub.s b/libmp/Plan9-mips/mpvecsub.s new file mode 100644 index 00000000..ca156fb7 --- /dev/null +++ b/libmp/Plan9-mips/mpvecsub.s @@ -0,0 +1,66 @@ +#define BDNZ BC 16,0, +#define BDNE BC 0,2, + +/* + * 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 + * + * R1 == a (first arg passed in R1) + * R3 == carry + * R4 == alen + * R5 == b + * R6 == blen + * R7 == sum + * R2 == temporary + * R8 == temporary + * R9 == temporary + */ +TEXT mpvecsub(SB),$-4 + + MOVW alen+4(FP), R4 + MOVW b+8(FP), R5 + MOVW blen+12(FP), R6 + MOVW sum+16(FP), R7 + SUBU R6, R4 /* calculate counter for second loop (alen > blen) */ + MOVW R0, R3 + + /* if blen == 0, don't need to subtract it */ + BEQ R6,_sub1 + + /* sum[0:blen-1],carry = a[0:blen-1] - b[0:blen-1] */ +_subloop1: + MOVW 0(R1), R8 + ADDU $4, R1 + MOVW 0(R5), R9 + ADDU $4, R5 + SUBU R3, R8, R2 + SGTU R2, R8, R3 + SUBU R9, R2, R8 + SGTU R8, R2, R9 + ADDU R9, R3 + MOVW R8, 0(R7) + ADDU $4, R7 + SUBU $1, R6 + BNE R6, _subloop1 + +_sub1: + /* if alen == blen, we're done */ + BEQ R4, _subend + + /* sum[blen:alen-1],carry = a[blen:alen-1] + 0 + carry */ +_subloop2: + MOVW 0(R1), R8 + ADDU $4, R1 + SUBU R3, R8, R2 + SGTU R2, R8, R3 + MOVW R2, 0(R7) + ADDU $4, R7 + SUBU $1, R4 + BNE R4, _subloop2 + + /* sum[alen] = carry */ +_subend: + RET |
