From 87abbc649f9064660128b840ef3aabad3e55abce Mon Sep 17 00:00:00 2001 From: aiju Date: Tue, 8 Dec 2015 18:29:22 +0100 Subject: [PATCH] mp: add logic operations; mpfmt: include 0x with # --- sys/include/mp.h | 9 ++ sys/src/libmp/port/mpfmt.c | 8 +- sys/src/libmp/port/mplogic.c | 194 +++++++++++++++++++++++++++++++++++ 3 files changed, 210 insertions(+), 1 deletion(-) create mode 100644 sys/src/libmp/port/mplogic.c diff --git a/sys/include/mp.h b/sys/include/mp.h index b17df619c..31e4ef3d8 100644 --- a/sys/include/mp.h +++ b/sys/include/mp.h @@ -76,6 +76,15 @@ void mpmul(mpint *b1, mpint *b2, mpint *prod); /* prod = b1*b2 */ void mpexp(mpint *b, mpint *e, mpint *m, mpint *res); /* res = b**e mod m */ void mpmod(mpint *b, mpint *m, mpint *remainder); /* remainder = b mod m */ +/* logical operations */ +void mpand(mpint *b1, mpint *b2, mpint *res); +void mpbic(mpint *b1, mpint *b2, mpint *res); +void mpor(mpint *b1, mpint *b2, mpint *res); +void mpnot(mpint *b, mpint *res); +void mpxor(mpint *b1, mpint *b2, mpint *res); +void mptrunc(mpint *b, int n, mpint *res); +void mpxtend(mpint *b, int n, mpint *res); + /* modular arithmetic, time invariant when 0≤b1≤m-1 and 0≤b2≤m-1 */ void mpmodadd(mpint *b1, mpint *b2, mpint *m, mpint *sum); /* sum = b1+b2 % m */ void mpmodsub(mpint *b1, mpint *b2, mpint *m, mpint *diff); /* diff = b1-b2 % m */ diff --git a/sys/src/libmp/port/mpfmt.c b/sys/src/libmp/port/mpfmt.c index 676b64be0..6c91e247d 100644 --- a/sys/src/libmp/port/mpfmt.c +++ b/sys/src/libmp/port/mpfmt.c @@ -146,7 +146,13 @@ mpfmt(Fmt *fmt) if(p == nil) return fmtstrcpy(fmt, "*"); else{ - fmtstrcpy(fmt, p); + if((fmt->flags & FmtSharp) != 0 && fmt->prec!=10 && fmt->prec!=32 && fmt->prec!=64) + if(*p == '-') + fmtprint(fmt, "-0x%s", p + 1); + else + fmtprint(fmt, "0x%s", p); + else + fmtstrcpy(fmt, p); free(p); return 0; } diff --git a/sys/src/libmp/port/mplogic.c b/sys/src/libmp/port/mplogic.c new file mode 100644 index 000000000..a5839073c --- /dev/null +++ b/sys/src/libmp/port/mplogic.c @@ -0,0 +1,194 @@ +#include "os.h" +#include +#include "dat.h" + +/* + mplogic calculates b1|b2 subject to the + following flag bits (fl) + + bit 0: subtract 1 from b1 + bit 1: invert b1 + bit 2: subtract 1 from b2 + bit 3: invert b2 + bit 4: add 1 to output + bit 5: invert output + + it inverts appropriate bits automatically + depending on the signs of the inputs +*/ + +static void +mplogic(mpint *b1, mpint *b2, mpint *sum, int fl) +{ + mpint *t; + mpdigit *dp1, *dp2, *dpo, d1, d2, d; + int c1, c2, co; + int i; + + assert(((b1->flags | b2->flags | sum->flags) & MPtimesafe) == 0); + if(b1->sign < 0) fl ^= 0x03; + if(b2->sign < 0) fl ^= 0x0c; + sum->sign = (int)(((fl|fl>>2)^fl>>4)<<30)>>31|1; + if(sum->sign < 0) fl ^= 0x30; + if(b2->top > b1->top){ + t = b1; + b1 = b2; + b2 = t; + fl = fl >> 2 & 0x03 | fl << 2 & 0x0c | fl & 0x30; + } + mpbits(sum, b1->top*Dbits); + dp1 = b1->p; + dp2 = b2->p; + dpo = sum->p; + c1 = fl & 1; + c2 = fl >> 2 & 1; + co = fl >> 4 & 1; + for(i = 0; i < b1->top; i++){ + d1 = dp1[i] - c1; + if(i < b2->top) + d2 = dp2[i] - c2; + else + d2 = 0; + if(d1 != (mpdigit)-1) c1 = 0; + if(d2 != (mpdigit)-1) c2 = 0; + if((fl & 2) != 0) d1 ^= -1; + if((fl & 8) != 0) d2 ^= -1; + d = d1 | d2; + if((fl & 32) != 0) d ^= -1; + d += co; + if(d != 0) co = 0; + dpo[i] = d; + } + sum->top = i; + mpnorm(sum); +} + +void +mpor(mpint *b1, mpint *b2, mpint *sum) +{ + mplogic(b1, b2, sum, 0); +} + +void +mpand(mpint *b1, mpint *b2, mpint *sum) +{ + mplogic(b1, b2, sum, 0x2a); +} + +void +mpbic(mpint *b1, mpint *b2, mpint *sum) +{ + mplogic(b1, b2, sum, 0x22); +} + +void +mpnot(mpint *b, mpint *r) +{ + mpadd(b, mpone, r); + r->sign ^= -2; +} + +void +mpxor(mpint *b1, mpint *b2, mpint *sum) +{ + mpint *t; + mpdigit *dp1, *dp2, *dpo, d1, d2, d; + int c1, c2, co; + int i, fl; + + assert(((b1->flags | b2->flags | sum->flags) & MPtimesafe) == 0); + if(b2->top > b1->top){ + t = b1; + b1 = b2; + b2 = t; + } + fl = (b1->sign & 10) ^ (b2->sign & 12); + sum->sign = (int)(fl << 28) >> 31; + mpbits(sum, b1->top*Dbits); + dp1 = b1->p; + dp2 = b2->p; + dpo = sum->p; + c1 = fl >> 1 & 1; + c2 = fl >> 2 & 1; + co = fl >> 3 & 1; + for(i = 0; i < b1->top; i++){ + d1 = dp1[i] - c1; + if(i < b2->top) + d2 = dp2[i] - c2; + else + d2 = 0; + if(d1 != (mpdigit)-1) c1 = 0; + if(d2 != (mpdigit)-1) c2 = 0; + d = d1 ^ d2; + d += co; + if(d != 0) co = 0; + dpo[i] = d; + } + sum->top = i; + mpnorm(sum); +} + +void +mptrunc(mpint *b, int n, mpint *r) +{ + int d, m, i, c; + + assert(((b->flags | r->flags) & MPtimesafe) == 0); + mpbits(r, n); + r->top = DIGITS(n); + d = n / Dbits; + m = n % Dbits; + r->sign = 1; + if(b->sign == -1){ + c = 1; + for(i = 0; i <= r->top; i++){ + if(i < b->top) + r->p[i] = ~(b->p[i] - c); + else + r->p[i] = -1; + if(r->p[i] != 0) + c = 0; + } + if(m != 0) + r->p[d] &= (1<sign == 1){ + if(d >= b->top){ + mpassign(b, r); + return; + } + if(b != r) + for(i = 0; i < d; i++) + r->p[i] = b->p[i]; + if(m != 0) + r->p[d] = b->p[d] & (1<= b->top){ + mpassign(b, r); + return; + } + mptrunc(b, n, r); + mpbits(r, n); + if((r->p[d] & 1<p[d] |= -(1<sign = -1; + c = 1; + for(i = 0; i < r->top; i++){ + r->p[i] = ~(r->p[i] - c); + if(r->p[i] != 0) + c = 0; + } + mpnorm(r); +}