summaryrefslogtreecommitdiff
path: root/libmp/Plan9-386
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-386
parent54bc8ff236ac10b3eaa928fd6bcfc0cdb2ba46ae (diff)
20060303a
Diffstat (limited to 'libmp/Plan9-386')
-rw-r--r--libmp/Plan9-386/mkfile21
-rw-r--r--libmp/Plan9-386/mpdigdiv.s21
-rw-r--r--libmp/Plan9-386/mpvecadd.s53
-rw-r--r--libmp/Plan9-386/mpvecdigmuladd.s52
-rw-r--r--libmp/Plan9-386/mpvecdigmulsub.s53
-rw-r--r--libmp/Plan9-386/mpvecsub.s44
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
+