summaryrefslogtreecommitdiff
path: root/libmp/Plan9-mips
diff options
context:
space:
mode:
authorCharles.Forsyth <devnull@localhost>2006-12-22 17:07:39 +0000
committerCharles.Forsyth <devnull@localhost>2006-12-22 17:07:39 +0000
commit37da2899f40661e3e9631e497da8dc59b971cbd0 (patch)
treecbc6d4680e347d906f5fa7fca73214418741df72 /libmp/Plan9-mips
parent54bc8ff236ac10b3eaa928fd6bcfc0cdb2ba46ae (diff)
20060303a
Diffstat (limited to 'libmp/Plan9-mips')
-rw-r--r--libmp/Plan9-mips/mkfile21
-rw-r--r--libmp/Plan9-mips/mpdigdiv.s41
-rw-r--r--libmp/Plan9-mips/mpvecadd.s67
-rw-r--r--libmp/Plan9-mips/mpvecdigmuladd.s58
-rw-r--r--libmp/Plan9-mips/mpvecdigmulsub.s61
-rw-r--r--libmp/Plan9-mips/mpvecsub.s66
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