summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/src/cmd/5c/peep.c3
-rw-r--r--sys/src/libmp/arm/mkfile8
-rw-r--r--sys/src/libmp/arm/mpvecdigmuladd.s19
-rw-r--r--sys/src/libmp/arm/mpvecdigmulsub.s22
-rw-r--r--sys/src/libmp/port/mpdigdiv.c13
5 files changed, 62 insertions, 3 deletions
diff --git a/sys/src/cmd/5c/peep.c b/sys/src/cmd/5c/peep.c
index 3d624a93d..0c126c0d8 100644
--- a/sys/src/cmd/5c/peep.c
+++ b/sys/src/cmd/5c/peep.c
@@ -306,6 +306,7 @@ subprop(Reg *r0)
case AAND:
case AEOR:
case AMUL:
+ case AMULU:
case ADIV:
case ADIVU:
@@ -977,6 +978,7 @@ copyu(Prog *p, Adr *v, Adr *s)
case AAND:
case AEOR:
case AMUL:
+ case AMULU:
case ADIV:
case ADIVU:
case AADDF:
@@ -1112,6 +1114,7 @@ a2type(Prog *p)
case AAND:
case AEOR:
case AMUL:
+ case AMULU:
case ADIV:
case ADIVU:
return D_REG;
diff --git a/sys/src/libmp/arm/mkfile b/sys/src/libmp/arm/mkfile
index e90c8b6ab..c939f5c41 100644
--- a/sys/src/libmp/arm/mkfile
+++ b/sys/src/libmp/arm/mkfile
@@ -2,12 +2,14 @@ objtype=arm
</$objtype/mkfile
LIB=/$objtype/lib/libmp.a
-OFILES= \
+SFILES=mpvecdigmuladd.s mpvecdigmulsub.s
HFILES=/$objtype/include/u.h /sys/include/mp.h ../port/dat.h
-UPDATE=\
- mkfile\
+OFILES=${SFILES:%.s=%.$O}
+
+UPDATE=mkfile\
$HFILES\
+ $SFILES\
</sys/src/cmd/mksyslib
diff --git a/sys/src/libmp/arm/mpvecdigmuladd.s b/sys/src/libmp/arm/mpvecdigmuladd.s
new file mode 100644
index 000000000..a3833bee0
--- /dev/null
+++ b/sys/src/libmp/arm/mpvecdigmuladd.s
@@ -0,0 +1,19 @@
+TEXT mpvecdigmuladd(SB),$0
+ MOVW n+4(FP),R4
+ MOVW m+8(FP),R5
+ MOVW p+12(FP),R6
+ MOVW $0, R2
+_muladdloop:
+ MOVW $0, R1
+ MOVW.W.P 4(R0), R3
+ MULALU R3, R5, (R1, R2)
+ MOVW (R6), R7
+ ADD.S R2, R7
+ ADC $0, R1, R2
+ MOVW.W.P R7, 4(R6)
+ SUB.S $1, R4
+ B.NE _muladdloop
+ MOVW (R6), R7
+ ADD R2, R7
+ MOVW R7, (R6)
+ RET
diff --git a/sys/src/libmp/arm/mpvecdigmulsub.s b/sys/src/libmp/arm/mpvecdigmulsub.s
new file mode 100644
index 000000000..7f877a64b
--- /dev/null
+++ b/sys/src/libmp/arm/mpvecdigmulsub.s
@@ -0,0 +1,22 @@
+TEXT mpvecdigmulsub(SB),$0
+ MOVW n+4(FP),R4
+ MOVW m+8(FP),R5
+ MOVW p+12(FP),R6
+ MOVW $0, R2
+_mulsubloop:
+ MOVW $0, R1
+ MOVW.W.P 4(R0), R3
+ MULALU R3, R5, (R1, R2)
+ MOVW (R6), R7
+ SUB.S R2, R7
+ ADD.CC $1, R1
+ MOVW R1, R2
+ MOVW.W.P R7, 4(R6)
+ SUB.S $1, R4
+ B.NE _mulsubloop
+ MOVW (R6), R7
+ SUB.S R2, R7
+ MOVW.CS $1, R0
+ MOVW.CC $-1, R0
+ MOVW R7, (R6)
+ RET
diff --git a/sys/src/libmp/port/mpdigdiv.c b/sys/src/libmp/port/mpdigdiv.c
index 4a73bb3a4..32b166765 100644
--- a/sys/src/libmp/port/mpdigdiv.c
+++ b/sys/src/libmp/port/mpdigdiv.c
@@ -21,6 +21,19 @@ mpdigdiv(mpdigit *dividend, mpdigit divisor, mpdigit *quotient)
return;
}
+ // very common case
+ if(~divisor == 0){
+ lo += hi;
+ if(lo < hi){
+ hi++;
+ lo++;
+ }
+ if(lo+1 == 0)
+ hi++;
+ *quotient = hi;
+ return;
+ }
+
// at this point we know that hi < divisor
// just shift and subtract till we're done
q = 0;