ref: 943e142d5b46b45b782c5ab4e42fc3d79f6f4435
parent: ee260887863628ae373d9fabcddeac3b0071237a
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Fri May 11 11:37:59 EDT 2018
libmp: apply fixes for mplogic, mpdiv and mpmagadd from 9front (thanks aiju)
--- a/libmp/mpadd.c
+++ b/libmp/mpadd.c
@@ -25,6 +25,7 @@
}
if(m == 0){
mpassign(b1, sum);
+ sum->sign = 1;
return;
}
mpbits(sum, (n+1)*Dbits);
--- a/libmp/mpdiv.c
+++ b/libmp/mpdiv.c
@@ -9,7 +9,7 @@
void
mpdiv(mpint *dividend, mpint *divisor, mpint *quotient, mpint *remainder)
{
- int j, s, vn, sign;
+ int j, s, vn, sign, qsign, rsign;
mpdigit qd, *up, *vp, *qp;
mpint *u, *v, *t;
@@ -22,7 +22,9 @@
// division by one or small powers of two
if(divisor->top == 1 && (divisor->p[0] & divisor->p[0]-1) == 0){
- vlong r = (vlong)dividend->sign * (dividend->p[0] & divisor->p[0]-1);
+ vlong r = 0;
+ if(dividend->top > 0)
+ r = (vlong)dividend->sign * (dividend->p[0] & divisor->p[0]-1);
if(quotient != nil){
sign = divisor->sign;
for(s = 0; ((divisor->p[0] >> s) & 1) == 0; s++)
@@ -47,6 +49,9 @@
mpassign(mpzero, quotient);
return;
}
+
+ qsign = divisor->sign * dividend->sign;
+ rsign = dividend->sign;
// D1: shift until divisor, v, has hi bit set (needed to make trial
// divisor accurate)
@@ -119,14 +124,15 @@
if(qp != nil){
assert((quotient->flags & MPtimesafe) == 0);
mpnorm(quotient);
- if(dividend->sign != divisor->sign)
- quotient->sign = -1;
+ if(quotient->top != 0)
+ quotient->sign = qsign;
}
if(remainder != nil){
assert((remainder->flags & MPtimesafe) == 0);
mpright(u, s, remainder); // u is the remainder shifted
- remainder->sign = dividend->sign;
+ if(remainder->top != 0)
+ remainder->sign = rsign;
}
mpfree(t);
--- a/libmp/mplogic.c
+++ b/libmp/mplogic.c
@@ -36,7 +36,7 @@
b2 = t;
fl = fl >> 2 & 0x03 | fl << 2 & 0x0c | fl & 0x30;
}
- mpbits(sum, b1->top*Dbits);
+ mpbits(sum, b1->top*Dbits+1);
dp1 = b1->p;
dp2 = b2->p;
dpo = sum->p;
@@ -60,6 +60,8 @@
dpo[i] = d;
}
sum->top = i;
+ if(co)
+ dpo[sum->top++] = co;
mpnorm(sum);
}
@@ -105,7 +107,7 @@
}
fl = (b1->sign & 10) ^ (b2->sign & 12);
sum->sign = (int)(fl << 28) >> 31 | 1;
- mpbits(sum, b1->top*Dbits);
+ mpbits(sum, b1->top*Dbits+1);
dp1 = b1->p;
dp2 = b2->p;
dpo = sum->p;
@@ -126,6 +128,8 @@
dpo[i] = d;
}
sum->top = i;
+ if(co)
+ dpo[sum->top++] = co;
mpnorm(sum);
}