ref: c3f004633be7e8a15fe8e1e158dde24c2af2f765
parent: 467826415fe2cc2846097dfd37ec879b9d62cf62
author: Sigrid Solveig Haflínudóttir <[email protected]>
date: Sat Nov 16 22:05:28 EST 2024
import the rest of libmp tests from 9front
--- a/3rd/mp/test.c
+++ b/3rd/mp/test.c
@@ -436,7 +436,6 @@
if(argc == 3 && strcmp(argv[1], "-n") == 0)
loops = atoi(argv[2]);
- memset(str, 0, sizeof(str));
D_PNAN = D_NNAN = strtod("+NaN", nil);
D_PINF = D_NINF = strtod("+Inf", nil);
--- /dev/null
+++ b/3rd/mp/test/convtest.c
@@ -1,0 +1,126 @@
+#include "platform.h"
+#include "mp.h"
+#include "dat.h"
+#include "fns.h"
+
+/* these tests suck but better than nothing... but really should test more values than just 1<<i */
+
+#define MPTOX(_name,_type,_func) \
+static void \
+_name(void) \
+{ \
+ mpint *m; \
+ int i, sign, mag; \
+ _type v, e; \
+ int fail; \
+ \
+ fail = 0; \
+ m = mpnew(0); \
+ for(i = 0; i < 256; i++){ \
+ sign = i >= 128 ? -1 : 1; \
+ mag = i % 128; \
+ itomp(sign, m); \
+ mpleft(m, mag, m); \
+ v = _func(m); \
+ e = 0xcafebabe; USED(e);
+#define MPTOX_END(_func,_format) \
+ if(v != e){ \
+ fprintf(stderr, "FAIL: "#_func"(%s): return value: got "_format", expected "_format"\n", MFMT(m), v, e); \
+ fail=1; \
+ } \
+ } \
+ mpfree(m); \
+ if(!fail) \
+ fprintf(stderr, #_func": passed\n"); \
+}
+
+#define XTOMP(_name,_type,_func) \
+static void \
+_name(void) \
+{ \
+ mpint *m, *r; \
+ int i, sign, mag; \
+ _type v; \
+ int fail; \
+ \
+ fail = 0; \
+ m = mpnew(0); \
+ r = mpnew(0); \
+ for(i = 0; i < 256; i++){ \
+ sign = i >= 128 ? -1 : 1; \
+ mag = i % 128; \
+ itomp(sign, r); \
+ mpleft(r, mag, r);
+#define XTOMP_END(_func,_type,_format) \
+ _func(sign * ((_type)1<<mag), m); \
+ if(mpcmp(r, m) != 0){ \
+ fprintf(stderr, "FAIL: "#_func"("_format"): return value: got %s, expected %s\n", sign * ((_type)1<<mag), MFMT(m), MFMT(r)); \
+ fail=1; \
+ } \
+ } \
+ mpfree(m); \
+ mpfree(r); \
+ if(!fail) \
+ fprintf(stderr, #_func": passed\n"); \
+ USED(v); \
+}
+
+MPTOX(test_mptoi, int, mptoi)
+ if(mag < 31)
+ e = sign*(1<<mag);
+ else
+ e = sign > 0 ? (1U<<31)-1 : 1U<<31;
+MPTOX_END(mptoi, "%#x")
+
+MPTOX(test_mptoui, uint32_t, mptoui)
+ if(mag < 32 && sign > 0)
+ e = 1<<mag;
+ else
+ e = sign > 0 ? -1 : 0;
+MPTOX_END(mptoui, "%#x")
+
+
+MPTOX(test_mptov, int64_t, mptov)
+ if(mag < 63)
+ e = sign*(1LL<<mag);
+ else
+ e = sign > 0 ? (1ULL<<63)-1 : 1ULL<<63;
+MPTOX_END(mptov, "%#"PRIx64)
+
+MPTOX(test_mptouv, uint64_t, mptouv)
+ if(mag < 64 && sign > 0)
+ e = 1LL<<mag;
+ else
+ e = sign > 0 ? -1ULL : 0;
+MPTOX_END(mptouv, "%#"PRIx64)
+
+XTOMP(test_itomp, int, itomp)
+ if(mag >= 31) continue;
+XTOMP_END(vtomp, int64_t, "%"PRId64)
+
+XTOMP(test_uitomp, uint32_t, uitomp)
+ if(mag >= 32 || sign < 0) continue;
+XTOMP_END(uitomp, uint32_t, "%"PRIu32)
+
+XTOMP(test_vtomp, int64_t, vtomp)
+ if(mag >= 63) continue;
+XTOMP_END(vtomp, int64_t, "%"PRId64)
+
+XTOMP(test_uvtomp, uint64_t, uvtomp)
+ if(mag >= 64 || sign < 0) continue;
+XTOMP_END(uvtomp, int64_t, "%"PRId64)
+
+
+void
+convtests(void)
+{
+ test_mptoi();
+ test_mptoui();
+ test_mptov();
+ test_mptouv();
+ test_itomp();
+ test_uitomp();
+ test_vtomp();
+ test_uvtomp();
+}
+
--- /dev/null
+++ b/3rd/mp/test/dat.h
@@ -1,0 +1,8 @@
+typedef struct ldint ldint;
+
+struct ldint {
+ uint32_t n;
+ uint8_t *b;
+};
+
+enum {NTEST = 2 * 257 + 32};
--- /dev/null
+++ b/3rd/mp/test/fns.h
@@ -1,0 +1,28 @@
+ldint* ldnew(int);
+int ldcmp(ldint *, ldint *);
+int ldmagcmp(ldint *, ldint *);
+void ldadd(ldint *, ldint *, ldint *);
+void ldsub(ldint *, ldint *, ldint *);
+void ldmagadd(ldint *, ldint *, ldint *);
+void ldmagsub(ldint *, ldint *, ldint *);
+void ldand(ldint *, ldint *, ldint *);
+void ldbic(ldint *, ldint *, ldint *);
+void ldor(ldint *, ldint *, ldint *);
+void ldxor(ldint *, ldint *, ldint *);
+void ldnot(ldint *, ldint *);
+void ldleft(ldint *, int, ldint *);
+void ldright(ldint *, int, ldint *);
+void ldasr(ldint *, int, ldint *);
+void lddiv_(ldint *, ldint *, ldint *, ldint *);
+void ldfree(ldint *);
+void testgen(int, ldint *);
+int ldmpeq(ldint *, mpint *);
+mpint* ldtomp(ldint *, mpint *);
+void mptarget(mpint *);
+void tests(void);
+void mpdiv_(mpint *, mpint *, mpint *, mpint *);
+void convtests(void);
+
+char *LFMT(ldint *);
+char *MFMT(mpint *);
+void prng(uint8_t *p, int n);
--- /dev/null
+++ b/3rd/mp/test/gen.tab.c
@@ -1,0 +1,1170 @@
+#include "platform.h"
+#include "mp.h"
+#include "dat.h"
+#include "fns.h"
+static void
+testcmp(void)
+{
+ int fail=0;
+ int a, b;
+ ldint *l2 = ldnew(0);
+ mpint *m2 = mpnew(0);
+ int i2;
+ ldint *l3 = ldnew(0);
+ mpint *m3 = mpnew(0);
+ int i3;
+ for(i2=0;i2<NTEST;i2++){
+ testgen(i2, l2);
+ for(i3=0;i3<NTEST;i3++){
+ testgen(i3, l3);
+ a=ldcmp(l2, l3);
+ ldtomp(l2, m2);
+ ldtomp(l3, m3);
+ b=mpcmp(m2, m3);
+ if(b<0) b=-1;
+ if(b>0) b=1;
+ if(a != b){
+ fprintf(stderr, "FAIL: mpcmp(%s, %s): return value: got %d, expected %d\n", LFMT(l2), LFMT(l3), b, a);
+ fail=1;
+ }
+ if(!ldmpeq(l2, m2)){
+ fprintf(stderr, "FAIL: mpcmp(%s, %s): arg 1: input corrupted\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }
+ if(!ldmpeq(l3, m3)){
+ fprintf(stderr, "FAIL: mpcmp(%s, %s): arg 2: input corrupted\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }
+ }
+ }
+ ldfree(l2);
+ mpfree(m2);
+ ldfree(l3);
+ mpfree(m3);
+ if(!fail) fprintf(stderr, "mpcmp: passed\n");
+}
+static void
+testmagcmp(void)
+{
+ int fail=0;
+ int a, b;
+ ldint *l2 = ldnew(0);
+ mpint *m2 = mpnew(0);
+ int i2;
+ ldint *l3 = ldnew(0);
+ mpint *m3 = mpnew(0);
+ int i3;
+ for(i2=0;i2<NTEST;i2++){
+ testgen(i2, l2);
+ for(i3=0;i3<NTEST;i3++){
+ testgen(i3, l3);
+ a=ldmagcmp(l2, l3);
+ ldtomp(l2, m2);
+ ldtomp(l3, m3);
+ b=mpmagcmp(m2, m3);
+ if(b<0) b=-1;
+ if(b>0) b=1;
+ if(a != b){
+ fprintf(stderr, "FAIL: mpmagcmp(%s, %s): return value: got %d, expected %d\n", LFMT(l2), LFMT(l3), b, a);
+ fail=1;
+ }
+ if(!ldmpeq(l2, m2)){
+ fprintf(stderr, "FAIL: mpmagcmp(%s, %s): arg 1: input corrupted\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }
+ if(!ldmpeq(l3, m3)){
+ fprintf(stderr, "FAIL: mpmagcmp(%s, %s): arg 2: input corrupted\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }
+ }
+ }
+ ldfree(l2);
+ mpfree(m2);
+ ldfree(l3);
+ mpfree(m3);
+ if(!fail) fprintf(stderr, "mpmagcmp: passed\n");
+}
+static void
+testadd(void)
+{
+ int fail=0;
+ ldint *l2 = ldnew(0);
+ mpint *m2 = mpnew(0);
+ int i2;
+ ldint *l3 = ldnew(0);
+ mpint *m3 = mpnew(0);
+ int i3;
+ ldint *l4 = ldnew(0);
+ mpint *m4 = mpnew(0);
+ for(i2=0;i2<NTEST;i2++){
+ testgen(i2, l2);
+ for(i3=0;i3<NTEST;i3++){
+ testgen(i3, l3);
+ ldadd(l2, l3, l4);
+ ldtomp(l2, m2);
+ ldtomp(l3, m3);
+ mptarget(m4);
+ mpadd(m2, m3, m4);
+ if(!ldmpeq(l2, m2)){
+ fprintf(stderr, "FAIL: mpadd(%s, %s, out): arg 1: input corrupted\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }
+ if(!ldmpeq(l3, m3)){
+ fprintf(stderr, "FAIL: mpadd(%s, %s, out): arg 2: input corrupted\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }
+ if(m4->top == 0 && m4->sign < 0){
+ fprintf(stderr, "FAIL: mpadd(%s, %s, out): arg 3: got -0, shouldn't happen\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(m4->top != 0 && m4->p[m4->top - 1] == 0){
+ fprintf(stderr, "FAIL: mpadd(%s, %s, out): arg 3: got denormalised result\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(!ldmpeq(l4, m4)){
+ fprintf(stderr, "FAIL: mpadd(%s, %s, out): arg 3: got %s, expected %s\n", LFMT(l2), LFMT(l3), MFMT(m4), LFMT(l4));
+ fail=1;
+ }
+ ldtomp(l2, m2);
+ ldtomp(l3, m3);
+ mptarget(m4);
+ mpadd(m2, m3, m2);
+ if(!ldmpeq(l3, m3)){
+ fprintf(stderr, "FAIL: mpadd(%s, %s, out): alias 3 and 1: arg 2: input corrupted\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }
+ if(m2->top == 0 && m2->sign < 0){
+ fprintf(stderr, "FAIL: mpadd(%s, %s, out): alias 3 and 1: arg 3: got -0, shouldn't happen\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(m2->top != 0 && m2->p[m2->top - 1] == 0){
+ fprintf(stderr, "FAIL: mpadd(%s, %s, out): alias 3 and 1: arg 3: got denormalised result\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(!ldmpeq(l4, m2)){
+ fprintf(stderr, "FAIL: mpadd(%s, %s, out): alias 3 and 1: arg 3: got %s, expected %s\n", LFMT(l2), LFMT(l3), MFMT(m2), LFMT(l4));
+ fail=1;
+ }
+ ldtomp(l2, m2);
+ ldtomp(l3, m3);
+ mptarget(m4);
+ mpadd(m2, m3, m3);
+ if(!ldmpeq(l2, m2)){
+ fprintf(stderr, "FAIL: mpadd(%s, %s, out): alias 3 and 2: arg 1: input corrupted\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }
+ if(m3->top == 0 && m3->sign < 0){
+ fprintf(stderr, "FAIL: mpadd(%s, %s, out): alias 3 and 2: arg 3: got -0, shouldn't happen\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(m3->top != 0 && m3->p[m3->top - 1] == 0){
+ fprintf(stderr, "FAIL: mpadd(%s, %s, out): alias 3 and 2: arg 3: got denormalised result\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(!ldmpeq(l4, m3)){
+ fprintf(stderr, "FAIL: mpadd(%s, %s, out): alias 3 and 2: arg 3: got %s, expected %s\n", LFMT(l2), LFMT(l3), MFMT(m3), LFMT(l4));
+ fail=1;
+ }
+ }
+ }
+ ldfree(l2);
+ mpfree(m2);
+ ldfree(l3);
+ mpfree(m3);
+ ldfree(l4);
+ mpfree(m4);
+ if(!fail) fprintf(stderr, "mpadd: passed\n");
+}
+static void
+testsub(void)
+{
+ int fail=0;
+ ldint *l2 = ldnew(0);
+ mpint *m2 = mpnew(0);
+ int i2;
+ ldint *l3 = ldnew(0);
+ mpint *m3 = mpnew(0);
+ int i3;
+ ldint *l4 = ldnew(0);
+ mpint *m4 = mpnew(0);
+ for(i2=0;i2<NTEST;i2++){
+ testgen(i2, l2);
+ for(i3=0;i3<NTEST;i3++){
+ testgen(i3, l3);
+ ldsub(l2, l3, l4);
+ ldtomp(l2, m2);
+ ldtomp(l3, m3);
+ mptarget(m4);
+ mpsub(m2, m3, m4);
+ if(!ldmpeq(l2, m2)){
+ fprintf(stderr, "FAIL: mpsub(%s, %s, out): arg 1: input corrupted\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }
+ if(!ldmpeq(l3, m3)){
+ fprintf(stderr, "FAIL: mpsub(%s, %s, out): arg 2: input corrupted\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }
+ if(m4->top == 0 && m4->sign < 0){
+ fprintf(stderr, "FAIL: mpsub(%s, %s, out): arg 3: got -0, shouldn't happen\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(m4->top != 0 && m4->p[m4->top - 1] == 0){
+ fprintf(stderr, "FAIL: mpsub(%s, %s, out): arg 3: got denormalised result\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(!ldmpeq(l4, m4)){
+ fprintf(stderr, "FAIL: mpsub(%s, %s, out): arg 3: got %s, expected %s\n", LFMT(l2), LFMT(l3), MFMT(m4), LFMT(l4));
+ fail=1;
+ }
+ ldtomp(l2, m2);
+ ldtomp(l3, m3);
+ mptarget(m4);
+ mpsub(m2, m3, m2);
+ if(!ldmpeq(l3, m3)){
+ fprintf(stderr, "FAIL: mpsub(%s, %s, out): alias 3 and 1: arg 2: input corrupted\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }
+ if(m2->top == 0 && m2->sign < 0){
+ fprintf(stderr, "FAIL: mpsub(%s, %s, out): alias 3 and 1: arg 3: got -0, shouldn't happen\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(m2->top != 0 && m2->p[m2->top - 1] == 0){
+ fprintf(stderr, "FAIL: mpsub(%s, %s, out): alias 3 and 1: arg 3: got denormalised result\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(!ldmpeq(l4, m2)){
+ fprintf(stderr, "FAIL: mpsub(%s, %s, out): alias 3 and 1: arg 3: got %s, expected %s\n", LFMT(l2), LFMT(l3), MFMT(m2), LFMT(l4));
+ fail=1;
+ }
+ ldtomp(l2, m2);
+ ldtomp(l3, m3);
+ mptarget(m4);
+ mpsub(m2, m3, m3);
+ if(!ldmpeq(l2, m2)){
+ fprintf(stderr, "FAIL: mpsub(%s, %s, out): alias 3 and 2: arg 1: input corrupted\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }
+ if(m3->top == 0 && m3->sign < 0){
+ fprintf(stderr, "FAIL: mpsub(%s, %s, out): alias 3 and 2: arg 3: got -0, shouldn't happen\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(m3->top != 0 && m3->p[m3->top - 1] == 0){
+ fprintf(stderr, "FAIL: mpsub(%s, %s, out): alias 3 and 2: arg 3: got denormalised result\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(!ldmpeq(l4, m3)){
+ fprintf(stderr, "FAIL: mpsub(%s, %s, out): alias 3 and 2: arg 3: got %s, expected %s\n", LFMT(l2), LFMT(l3), MFMT(m3), LFMT(l4));
+ fail=1;
+ }
+ }
+ }
+ ldfree(l2);
+ mpfree(m2);
+ ldfree(l3);
+ mpfree(m3);
+ ldfree(l4);
+ mpfree(m4);
+ if(!fail) fprintf(stderr, "mpsub: passed\n");
+}
+static void
+testmagadd(void)
+{
+ int fail=0;
+ ldint *l2 = ldnew(0);
+ mpint *m2 = mpnew(0);
+ int i2;
+ ldint *l3 = ldnew(0);
+ mpint *m3 = mpnew(0);
+ int i3;
+ ldint *l4 = ldnew(0);
+ mpint *m4 = mpnew(0);
+ for(i2=0;i2<NTEST;i2++){
+ testgen(i2, l2);
+ for(i3=0;i3<NTEST;i3++){
+ testgen(i3, l3);
+ ldmagadd(l2, l3, l4);
+ ldtomp(l2, m2);
+ ldtomp(l3, m3);
+ mptarget(m4);
+ mpmagadd(m2, m3, m4);
+ if(!ldmpeq(l2, m2)){
+ fprintf(stderr, "FAIL: mpmagadd(%s, %s, out): arg 1: input corrupted\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }
+ if(!ldmpeq(l3, m3)){
+ fprintf(stderr, "FAIL: mpmagadd(%s, %s, out): arg 2: input corrupted\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }
+ if(m4->top == 0 && m4->sign < 0){
+ fprintf(stderr, "FAIL: mpmagadd(%s, %s, out): arg 3: got -0, shouldn't happen\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(m4->top != 0 && m4->p[m4->top - 1] == 0){
+ fprintf(stderr, "FAIL: mpmagadd(%s, %s, out): arg 3: got denormalised result\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(!ldmpeq(l4, m4)){
+ fprintf(stderr, "FAIL: mpmagadd(%s, %s, out): arg 3: got %s, expected %s\n", LFMT(l2), LFMT(l3), MFMT(m4), LFMT(l4));
+ fail=1;
+ }
+ ldtomp(l2, m2);
+ ldtomp(l3, m3);
+ mptarget(m4);
+ mpmagadd(m2, m3, m2);
+ if(!ldmpeq(l3, m3)){
+ fprintf(stderr, "FAIL: mpmagadd(%s, %s, out): alias 3 and 1: arg 2: input corrupted\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }
+ if(m2->top == 0 && m2->sign < 0){
+ fprintf(stderr, "FAIL: mpmagadd(%s, %s, out): alias 3 and 1: arg 3: got -0, shouldn't happen\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(m2->top != 0 && m2->p[m2->top - 1] == 0){
+ fprintf(stderr, "FAIL: mpmagadd(%s, %s, out): alias 3 and 1: arg 3: got denormalised result\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(!ldmpeq(l4, m2)){
+ fprintf(stderr, "FAIL: mpmagadd(%s, %s, out): alias 3 and 1: arg 3: got %s, expected %s\n", LFMT(l2), LFMT(l3), MFMT(m2), LFMT(l4));
+ fail=1;
+ }
+ ldtomp(l2, m2);
+ ldtomp(l3, m3);
+ mptarget(m4);
+ mpmagadd(m2, m3, m3);
+ if(!ldmpeq(l2, m2)){
+ fprintf(stderr, "FAIL: mpmagadd(%s, %s, out): alias 3 and 2: arg 1: input corrupted\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }
+ if(m3->top == 0 && m3->sign < 0){
+ fprintf(stderr, "FAIL: mpmagadd(%s, %s, out): alias 3 and 2: arg 3: got -0, shouldn't happen\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(m3->top != 0 && m3->p[m3->top - 1] == 0){
+ fprintf(stderr, "FAIL: mpmagadd(%s, %s, out): alias 3 and 2: arg 3: got denormalised result\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(!ldmpeq(l4, m3)){
+ fprintf(stderr, "FAIL: mpmagadd(%s, %s, out): alias 3 and 2: arg 3: got %s, expected %s\n", LFMT(l2), LFMT(l3), MFMT(m3), LFMT(l4));
+ fail=1;
+ }
+ }
+ }
+ ldfree(l2);
+ mpfree(m2);
+ ldfree(l3);
+ mpfree(m3);
+ ldfree(l4);
+ mpfree(m4);
+ if(!fail) fprintf(stderr, "mpmagadd: passed\n");
+}
+static void
+testmagsub(void)
+{
+ int fail=0;
+ ldint *l2 = ldnew(0);
+ mpint *m2 = mpnew(0);
+ int i2;
+ ldint *l3 = ldnew(0);
+ mpint *m3 = mpnew(0);
+ int i3;
+ ldint *l4 = ldnew(0);
+ mpint *m4 = mpnew(0);
+ for(i2=0;i2<NTEST;i2++){
+ testgen(i2, l2);
+ for(i3=0;i3<NTEST;i3++){
+ testgen(i3, l3);
+ ldmagsub(l2, l3, l4);
+ ldtomp(l2, m2);
+ ldtomp(l3, m3);
+ mptarget(m4);
+ mpmagsub(m2, m3, m4);
+ if(!ldmpeq(l2, m2)){
+ fprintf(stderr, "FAIL: mpmagsub(%s, %s, out): arg 1: input corrupted\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }
+ if(!ldmpeq(l3, m3)){
+ fprintf(stderr, "FAIL: mpmagsub(%s, %s, out): arg 2: input corrupted\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }
+ if(m4->top == 0 && m4->sign < 0){
+ fprintf(stderr, "FAIL: mpmagsub(%s, %s, out): arg 3: got -0, shouldn't happen\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(m4->top != 0 && m4->p[m4->top - 1] == 0){
+ fprintf(stderr, "FAIL: mpmagsub(%s, %s, out): arg 3: got denormalised result\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(!ldmpeq(l4, m4)){
+ fprintf(stderr, "FAIL: mpmagsub(%s, %s, out): arg 3: got %s, expected %s\n", LFMT(l2), LFMT(l3), MFMT(m4), LFMT(l4));
+ fail=1;
+ }
+ ldtomp(l2, m2);
+ ldtomp(l3, m3);
+ mptarget(m4);
+ mpmagsub(m2, m3, m2);
+ if(!ldmpeq(l3, m3)){
+ fprintf(stderr, "FAIL: mpmagsub(%s, %s, out): alias 3 and 1: arg 2: input corrupted\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }
+ if(m2->top == 0 && m2->sign < 0){
+ fprintf(stderr, "FAIL: mpmagsub(%s, %s, out): alias 3 and 1: arg 3: got -0, shouldn't happen\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(m2->top != 0 && m2->p[m2->top - 1] == 0){
+ fprintf(stderr, "FAIL: mpmagsub(%s, %s, out): alias 3 and 1: arg 3: got denormalised result\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(!ldmpeq(l4, m2)){
+ fprintf(stderr, "FAIL: mpmagsub(%s, %s, out): alias 3 and 1: arg 3: got %s, expected %s\n", LFMT(l2), LFMT(l3), MFMT(m2), LFMT(l4));
+ fail=1;
+ }
+ ldtomp(l2, m2);
+ ldtomp(l3, m3);
+ mptarget(m4);
+ mpmagsub(m2, m3, m3);
+ if(!ldmpeq(l2, m2)){
+ fprintf(stderr, "FAIL: mpmagsub(%s, %s, out): alias 3 and 2: arg 1: input corrupted\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }
+ if(m3->top == 0 && m3->sign < 0){
+ fprintf(stderr, "FAIL: mpmagsub(%s, %s, out): alias 3 and 2: arg 3: got -0, shouldn't happen\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(m3->top != 0 && m3->p[m3->top - 1] == 0){
+ fprintf(stderr, "FAIL: mpmagsub(%s, %s, out): alias 3 and 2: arg 3: got denormalised result\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(!ldmpeq(l4, m3)){
+ fprintf(stderr, "FAIL: mpmagsub(%s, %s, out): alias 3 and 2: arg 3: got %s, expected %s\n", LFMT(l2), LFMT(l3), MFMT(m3), LFMT(l4));
+ fail=1;
+ }
+ }
+ }
+ ldfree(l2);
+ mpfree(m2);
+ ldfree(l3);
+ mpfree(m3);
+ ldfree(l4);
+ mpfree(m4);
+ if(!fail) fprintf(stderr, "mpmagsub: passed\n");
+}
+static void
+testand(void)
+{
+ int fail=0;
+ ldint *l2 = ldnew(0);
+ mpint *m2 = mpnew(0);
+ int i2;
+ ldint *l3 = ldnew(0);
+ mpint *m3 = mpnew(0);
+ int i3;
+ ldint *l4 = ldnew(0);
+ mpint *m4 = mpnew(0);
+ for(i2=0;i2<NTEST;i2++){
+ testgen(i2, l2);
+ for(i3=0;i3<NTEST;i3++){
+ testgen(i3, l3);
+ ldand(l2, l3, l4);
+ ldtomp(l2, m2);
+ ldtomp(l3, m3);
+ mptarget(m4);
+ mpand(m2, m3, m4);
+ if(!ldmpeq(l2, m2)){
+ fprintf(stderr, "FAIL: mpand(%s, %s, out): arg 1: input corrupted\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }
+ if(!ldmpeq(l3, m3)){
+ fprintf(stderr, "FAIL: mpand(%s, %s, out): arg 2: input corrupted\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }
+ if(m4->top == 0 && m4->sign < 0){
+ fprintf(stderr, "FAIL: mpand(%s, %s, out): arg 3: got -0, shouldn't happen\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(m4->top != 0 && m4->p[m4->top - 1] == 0){
+ fprintf(stderr, "FAIL: mpand(%s, %s, out): arg 3: got denormalised result\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(!ldmpeq(l4, m4)){
+ fprintf(stderr, "FAIL: mpand(%s, %s, out): arg 3: got %s, expected %s\n", LFMT(l2), LFMT(l3), MFMT(m4), LFMT(l4));
+ fail=1;
+ }
+ ldtomp(l2, m2);
+ ldtomp(l3, m3);
+ mptarget(m4);
+ mpand(m2, m3, m2);
+ if(!ldmpeq(l3, m3)){
+ fprintf(stderr, "FAIL: mpand(%s, %s, out): alias 3 and 1: arg 2: input corrupted\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }
+ if(m2->top == 0 && m2->sign < 0){
+ fprintf(stderr, "FAIL: mpand(%s, %s, out): alias 3 and 1: arg 3: got -0, shouldn't happen\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(m2->top != 0 && m2->p[m2->top - 1] == 0){
+ fprintf(stderr, "FAIL: mpand(%s, %s, out): alias 3 and 1: arg 3: got denormalised result\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(!ldmpeq(l4, m2)){
+ fprintf(stderr, "FAIL: mpand(%s, %s, out): alias 3 and 1: arg 3: got %s, expected %s\n", LFMT(l2), LFMT(l3), MFMT(m2), LFMT(l4));
+ fail=1;
+ }
+ ldtomp(l2, m2);
+ ldtomp(l3, m3);
+ mptarget(m4);
+ mpand(m2, m3, m3);
+ if(!ldmpeq(l2, m2)){
+ fprintf(stderr, "FAIL: mpand(%s, %s, out): alias 3 and 2: arg 1: input corrupted\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }
+ if(m3->top == 0 && m3->sign < 0){
+ fprintf(stderr, "FAIL: mpand(%s, %s, out): alias 3 and 2: arg 3: got -0, shouldn't happen\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(m3->top != 0 && m3->p[m3->top - 1] == 0){
+ fprintf(stderr, "FAIL: mpand(%s, %s, out): alias 3 and 2: arg 3: got denormalised result\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(!ldmpeq(l4, m3)){
+ fprintf(stderr, "FAIL: mpand(%s, %s, out): alias 3 and 2: arg 3: got %s, expected %s\n", LFMT(l2), LFMT(l3), MFMT(m3), LFMT(l4));
+ fail=1;
+ }
+ }
+ }
+ ldfree(l2);
+ mpfree(m2);
+ ldfree(l3);
+ mpfree(m3);
+ ldfree(l4);
+ mpfree(m4);
+ if(!fail) fprintf(stderr, "mpand: passed\n");
+}
+static void
+testbic(void)
+{
+ int fail=0;
+ ldint *l2 = ldnew(0);
+ mpint *m2 = mpnew(0);
+ int i2;
+ ldint *l3 = ldnew(0);
+ mpint *m3 = mpnew(0);
+ int i3;
+ ldint *l4 = ldnew(0);
+ mpint *m4 = mpnew(0);
+ for(i2=0;i2<NTEST;i2++){
+ testgen(i2, l2);
+ for(i3=0;i3<NTEST;i3++){
+ testgen(i3, l3);
+ ldbic(l2, l3, l4);
+ ldtomp(l2, m2);
+ ldtomp(l3, m3);
+ mptarget(m4);
+ mpbic(m2, m3, m4);
+ if(!ldmpeq(l2, m2)){
+ fprintf(stderr, "FAIL: mpbic(%s, %s, out): arg 1: input corrupted\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }
+ if(!ldmpeq(l3, m3)){
+ fprintf(stderr, "FAIL: mpbic(%s, %s, out): arg 2: input corrupted\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }
+ if(m4->top == 0 && m4->sign < 0){
+ fprintf(stderr, "FAIL: mpbic(%s, %s, out): arg 3: got -0, shouldn't happen\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(m4->top != 0 && m4->p[m4->top - 1] == 0){
+ fprintf(stderr, "FAIL: mpbic(%s, %s, out): arg 3: got denormalised result\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(!ldmpeq(l4, m4)){
+ fprintf(stderr, "FAIL: mpbic(%s, %s, out): arg 3: got %s, expected %s\n", LFMT(l2), LFMT(l3), MFMT(m4), LFMT(l4));
+ fail=1;
+ }
+ ldtomp(l2, m2);
+ ldtomp(l3, m3);
+ mptarget(m4);
+ mpbic(m2, m3, m2);
+ if(!ldmpeq(l3, m3)){
+ fprintf(stderr, "FAIL: mpbic(%s, %s, out): alias 3 and 1: arg 2: input corrupted\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }
+ if(m2->top == 0 && m2->sign < 0){
+ fprintf(stderr, "FAIL: mpbic(%s, %s, out): alias 3 and 1: arg 3: got -0, shouldn't happen\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(m2->top != 0 && m2->p[m2->top - 1] == 0){
+ fprintf(stderr, "FAIL: mpbic(%s, %s, out): alias 3 and 1: arg 3: got denormalised result\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(!ldmpeq(l4, m2)){
+ fprintf(stderr, "FAIL: mpbic(%s, %s, out): alias 3 and 1: arg 3: got %s, expected %s\n", LFMT(l2), LFMT(l3), MFMT(m2), LFMT(l4));
+ fail=1;
+ }
+ ldtomp(l2, m2);
+ ldtomp(l3, m3);
+ mptarget(m4);
+ mpbic(m2, m3, m3);
+ if(!ldmpeq(l2, m2)){
+ fprintf(stderr, "FAIL: mpbic(%s, %s, out): alias 3 and 2: arg 1: input corrupted\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }
+ if(m3->top == 0 && m3->sign < 0){
+ fprintf(stderr, "FAIL: mpbic(%s, %s, out): alias 3 and 2: arg 3: got -0, shouldn't happen\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(m3->top != 0 && m3->p[m3->top - 1] == 0){
+ fprintf(stderr, "FAIL: mpbic(%s, %s, out): alias 3 and 2: arg 3: got denormalised result\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(!ldmpeq(l4, m3)){
+ fprintf(stderr, "FAIL: mpbic(%s, %s, out): alias 3 and 2: arg 3: got %s, expected %s\n", LFMT(l2), LFMT(l3), MFMT(m3), LFMT(l4));
+ fail=1;
+ }
+ }
+ }
+ ldfree(l2);
+ mpfree(m2);
+ ldfree(l3);
+ mpfree(m3);
+ ldfree(l4);
+ mpfree(m4);
+ if(!fail) fprintf(stderr, "mpbic: passed\n");
+}
+static void
+testor(void)
+{
+ int fail=0;
+ ldint *l2 = ldnew(0);
+ mpint *m2 = mpnew(0);
+ int i2;
+ ldint *l3 = ldnew(0);
+ mpint *m3 = mpnew(0);
+ int i3;
+ ldint *l4 = ldnew(0);
+ mpint *m4 = mpnew(0);
+ for(i2=0;i2<NTEST;i2++){
+ testgen(i2, l2);
+ for(i3=0;i3<NTEST;i3++){
+ testgen(i3, l3);
+ ldor(l2, l3, l4);
+ ldtomp(l2, m2);
+ ldtomp(l3, m3);
+ mptarget(m4);
+ mpor(m2, m3, m4);
+ if(!ldmpeq(l2, m2)){
+ fprintf(stderr, "FAIL: mpor(%s, %s, out): arg 1: input corrupted\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }
+ if(!ldmpeq(l3, m3)){
+ fprintf(stderr, "FAIL: mpor(%s, %s, out): arg 2: input corrupted\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }
+ if(m4->top == 0 && m4->sign < 0){
+ fprintf(stderr, "FAIL: mpor(%s, %s, out): arg 3: got -0, shouldn't happen\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(m4->top != 0 && m4->p[m4->top - 1] == 0){
+ fprintf(stderr, "FAIL: mpor(%s, %s, out): arg 3: got denormalised result\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(!ldmpeq(l4, m4)){
+ fprintf(stderr, "FAIL: mpor(%s, %s, out): arg 3: got %s, expected %s\n", LFMT(l2), LFMT(l3), MFMT(m4), LFMT(l4));
+ fail=1;
+ }
+ ldtomp(l2, m2);
+ ldtomp(l3, m3);
+ mptarget(m4);
+ mpor(m2, m3, m2);
+ if(!ldmpeq(l3, m3)){
+ fprintf(stderr, "FAIL: mpor(%s, %s, out): alias 3 and 1: arg 2: input corrupted\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }
+ if(m2->top == 0 && m2->sign < 0){
+ fprintf(stderr, "FAIL: mpor(%s, %s, out): alias 3 and 1: arg 3: got -0, shouldn't happen\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(m2->top != 0 && m2->p[m2->top - 1] == 0){
+ fprintf(stderr, "FAIL: mpor(%s, %s, out): alias 3 and 1: arg 3: got denormalised result\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(!ldmpeq(l4, m2)){
+ fprintf(stderr, "FAIL: mpor(%s, %s, out): alias 3 and 1: arg 3: got %s, expected %s\n", LFMT(l2), LFMT(l3), MFMT(m2), LFMT(l4));
+ fail=1;
+ }
+ ldtomp(l2, m2);
+ ldtomp(l3, m3);
+ mptarget(m4);
+ mpor(m2, m3, m3);
+ if(!ldmpeq(l2, m2)){
+ fprintf(stderr, "FAIL: mpor(%s, %s, out): alias 3 and 2: arg 1: input corrupted\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }
+ if(m3->top == 0 && m3->sign < 0){
+ fprintf(stderr, "FAIL: mpor(%s, %s, out): alias 3 and 2: arg 3: got -0, shouldn't happen\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(m3->top != 0 && m3->p[m3->top - 1] == 0){
+ fprintf(stderr, "FAIL: mpor(%s, %s, out): alias 3 and 2: arg 3: got denormalised result\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(!ldmpeq(l4, m3)){
+ fprintf(stderr, "FAIL: mpor(%s, %s, out): alias 3 and 2: arg 3: got %s, expected %s\n", LFMT(l2), LFMT(l3), MFMT(m3), LFMT(l4));
+ fail=1;
+ }
+ }
+ }
+ ldfree(l2);
+ mpfree(m2);
+ ldfree(l3);
+ mpfree(m3);
+ ldfree(l4);
+ mpfree(m4);
+ if(!fail) fprintf(stderr, "mpor: passed\n");
+}
+static void
+testxor(void)
+{
+ int fail=0;
+ ldint *l2 = ldnew(0);
+ mpint *m2 = mpnew(0);
+ int i2;
+ ldint *l3 = ldnew(0);
+ mpint *m3 = mpnew(0);
+ int i3;
+ ldint *l4 = ldnew(0);
+ mpint *m4 = mpnew(0);
+ for(i2=0;i2<NTEST;i2++){
+ testgen(i2, l2);
+ for(i3=0;i3<NTEST;i3++){
+ testgen(i3, l3);
+ ldxor(l2, l3, l4);
+ ldtomp(l2, m2);
+ ldtomp(l3, m3);
+ mptarget(m4);
+ mpxor(m2, m3, m4);
+ if(!ldmpeq(l2, m2)){
+ fprintf(stderr, "FAIL: mpxor(%s, %s, out): arg 1: input corrupted\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }
+ if(!ldmpeq(l3, m3)){
+ fprintf(stderr, "FAIL: mpxor(%s, %s, out): arg 2: input corrupted\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }
+ if(m4->top == 0 && m4->sign < 0){
+ fprintf(stderr, "FAIL: mpxor(%s, %s, out): arg 3: got -0, shouldn't happen\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(m4->top != 0 && m4->p[m4->top - 1] == 0){
+ fprintf(stderr, "FAIL: mpxor(%s, %s, out): arg 3: got denormalised result\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(!ldmpeq(l4, m4)){
+ fprintf(stderr, "FAIL: mpxor(%s, %s, out): arg 3: got %s, expected %s\n", LFMT(l2), LFMT(l3), MFMT(m4), LFMT(l4));
+ fail=1;
+ }
+ ldtomp(l2, m2);
+ ldtomp(l3, m3);
+ mptarget(m4);
+ mpxor(m2, m3, m2);
+ if(!ldmpeq(l3, m3)){
+ fprintf(stderr, "FAIL: mpxor(%s, %s, out): alias 3 and 1: arg 2: input corrupted\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }
+ if(m2->top == 0 && m2->sign < 0){
+ fprintf(stderr, "FAIL: mpxor(%s, %s, out): alias 3 and 1: arg 3: got -0, shouldn't happen\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(m2->top != 0 && m2->p[m2->top - 1] == 0){
+ fprintf(stderr, "FAIL: mpxor(%s, %s, out): alias 3 and 1: arg 3: got denormalised result\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(!ldmpeq(l4, m2)){
+ fprintf(stderr, "FAIL: mpxor(%s, %s, out): alias 3 and 1: arg 3: got %s, expected %s\n", LFMT(l2), LFMT(l3), MFMT(m2), LFMT(l4));
+ fail=1;
+ }
+ ldtomp(l2, m2);
+ ldtomp(l3, m3);
+ mptarget(m4);
+ mpxor(m2, m3, m3);
+ if(!ldmpeq(l2, m2)){
+ fprintf(stderr, "FAIL: mpxor(%s, %s, out): alias 3 and 2: arg 1: input corrupted\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }
+ if(m3->top == 0 && m3->sign < 0){
+ fprintf(stderr, "FAIL: mpxor(%s, %s, out): alias 3 and 2: arg 3: got -0, shouldn't happen\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(m3->top != 0 && m3->p[m3->top - 1] == 0){
+ fprintf(stderr, "FAIL: mpxor(%s, %s, out): alias 3 and 2: arg 3: got denormalised result\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(!ldmpeq(l4, m3)){
+ fprintf(stderr, "FAIL: mpxor(%s, %s, out): alias 3 and 2: arg 3: got %s, expected %s\n", LFMT(l2), LFMT(l3), MFMT(m3), LFMT(l4));
+ fail=1;
+ }
+ }
+ }
+ ldfree(l2);
+ mpfree(m2);
+ ldfree(l3);
+ mpfree(m3);
+ ldfree(l4);
+ mpfree(m4);
+ if(!fail) fprintf(stderr, "mpxor: passed\n");
+}
+static void
+testnot(void)
+{
+ int fail=0;
+ ldint *l2 = ldnew(0);
+ mpint *m2 = mpnew(0);
+ int i2;
+ ldint *l3 = ldnew(0);
+ mpint *m3 = mpnew(0);
+ for(i2=0;i2<NTEST;i2++){
+ testgen(i2, l2);
+ ldnot(l2, l3);
+ ldtomp(l2, m2);
+ mptarget(m3);
+ mpnot(m2, m3);
+ if(!ldmpeq(l2, m2)){
+ fprintf(stderr, "FAIL: mpnot(%s, out): arg 1: input corrupted\n", LFMT(l2));
+ fail=1;
+ }
+ if(m3->top == 0 && m3->sign < 0){
+ fprintf(stderr, "FAIL: mpnot(%s, out): arg 2: got -0, shouldn't happen\n", LFMT(l2));
+ fail=1;
+ }else if(m3->top != 0 && m3->p[m3->top - 1] == 0){
+ fprintf(stderr, "FAIL: mpnot(%s, out): arg 2: got denormalised result\n", LFMT(l2));
+ fail=1;
+ }else if(!ldmpeq(l3, m3)){
+ fprintf(stderr, "FAIL: mpnot(%s, out): arg 2: got %s, expected %s\n", LFMT(l2), MFMT(m3), LFMT(l3));
+ fail=1;
+ }
+ ldtomp(l2, m2);
+ mptarget(m3);
+ mpnot(m2, m2);
+ if(m2->top == 0 && m2->sign < 0){
+ fprintf(stderr, "FAIL: mpnot(%s, out): alias 2 and 1: arg 2: got -0, shouldn't happen\n", LFMT(l2));
+ fail=1;
+ }else if(m2->top != 0 && m2->p[m2->top - 1] == 0){
+ fprintf(stderr, "FAIL: mpnot(%s, out): alias 2 and 1: arg 2: got denormalised result\n", LFMT(l2));
+ fail=1;
+ }else if(!ldmpeq(l3, m2)){
+ fprintf(stderr, "FAIL: mpnot(%s, out): alias 2 and 1: arg 2: got %s, expected %s\n", LFMT(l2), MFMT(m2), LFMT(l3));
+ fail=1;
+ }
+ }
+ ldfree(l2);
+ mpfree(m2);
+ ldfree(l3);
+ mpfree(m3);
+ if(!fail) fprintf(stderr, "mpnot: passed\n");
+}
+static void
+testleft(void)
+{
+ int fail=0;
+ ldint *l2 = ldnew(0);
+ mpint *m2 = mpnew(0);
+ int i2;
+ int i3;
+ ldint *l4 = ldnew(0);
+ mpint *m4 = mpnew(0);
+ for(i2=0;i2<NTEST;i2++){
+ testgen(i2, l2);
+ for(i3=-128;i3<=128;i3++){
+ ldleft(l2, i3, l4);
+ ldtomp(l2, m2);
+ mptarget(m4);
+ mpleft(m2, i3, m4);
+ if(!ldmpeq(l2, m2)){
+ fprintf(stderr, "FAIL: mpleft(%s, %d, out): arg 1: input corrupted\n", LFMT(l2), i3);
+ fail=1;
+ }
+ if(m4->top == 0 && m4->sign < 0){
+ fprintf(stderr, "FAIL: mpleft(%s, %d, out): arg 3: got -0, shouldn't happen\n", LFMT(l2), i3);
+ fail=1;
+ }else if(m4->top != 0 && m4->p[m4->top - 1] == 0){
+ fprintf(stderr, "FAIL: mpleft(%s, %d, out): arg 3: got denormalised result\n", LFMT(l2), i3);
+ fail=1;
+ }else if(!ldmpeq(l4, m4)){
+ fprintf(stderr, "FAIL: mpleft(%s, %d, out): arg 3: got %s, expected %s\n", LFMT(l2), i3, MFMT(m4), LFMT(l4));
+ fail=1;
+ }
+ ldtomp(l2, m2);
+ mptarget(m4);
+ mpleft(m2, i3, m2);
+ if(m2->top == 0 && m2->sign < 0){
+ fprintf(stderr, "FAIL: mpleft(%s, %d, out): alias 3 and 1: arg 3: got -0, shouldn't happen\n", LFMT(l2), i3);
+ fail=1;
+ }else if(m2->top != 0 && m2->p[m2->top - 1] == 0){
+ fprintf(stderr, "FAIL: mpleft(%s, %d, out): alias 3 and 1: arg 3: got denormalised result\n", LFMT(l2), i3);
+ fail=1;
+ }else if(!ldmpeq(l4, m2)){
+ fprintf(stderr, "FAIL: mpleft(%s, %d, out): alias 3 and 1: arg 3: got %s, expected %s\n", LFMT(l2), i3, MFMT(m2), LFMT(l4));
+ fail=1;
+ }
+ }
+ }
+ ldfree(l2);
+ mpfree(m2);
+ ldfree(l4);
+ mpfree(m4);
+ if(!fail) fprintf(stderr, "mpleft: passed\n");
+}
+static void
+testright(void)
+{
+ int fail=0;
+ ldint *l2 = ldnew(0);
+ mpint *m2 = mpnew(0);
+ int i2;
+ int i3;
+ ldint *l4 = ldnew(0);
+ mpint *m4 = mpnew(0);
+ for(i2=0;i2<NTEST;i2++){
+ testgen(i2, l2);
+ for(i3=-128;i3<=128;i3++){
+ ldright(l2, i3, l4);
+ ldtomp(l2, m2);
+ mptarget(m4);
+ mpright(m2, i3, m4);
+ if(!ldmpeq(l2, m2)){
+ fprintf(stderr, "FAIL: mpright(%s, %d, out): arg 1: input corrupted\n", LFMT(l2), i3);
+ fail=1;
+ }
+ if(m4->top == 0 && m4->sign < 0){
+ fprintf(stderr, "FAIL: mpright(%s, %d, out): arg 3: got -0, shouldn't happen\n", LFMT(l2), i3);
+ fail=1;
+ }else if(m4->top != 0 && m4->p[m4->top - 1] == 0){
+ fprintf(stderr, "FAIL: mpright(%s, %d, out): arg 3: got denormalised result\n", LFMT(l2), i3);
+ fail=1;
+ }else if(!ldmpeq(l4, m4)){
+ fprintf(stderr, "FAIL: mpright(%s, %d, out): arg 3: got %s, expected %s\n", LFMT(l2), i3, MFMT(m4), LFMT(l4));
+ fail=1;
+ }
+ ldtomp(l2, m2);
+ mptarget(m4);
+ mpright(m2, i3, m2);
+ if(m2->top == 0 && m2->sign < 0){
+ fprintf(stderr, "FAIL: mpright(%s, %d, out): alias 3 and 1: arg 3: got -0, shouldn't happen\n", LFMT(l2), i3);
+ fail=1;
+ }else if(m2->top != 0 && m2->p[m2->top - 1] == 0){
+ fprintf(stderr, "FAIL: mpright(%s, %d, out): alias 3 and 1: arg 3: got denormalised result\n", LFMT(l2), i3);
+ fail=1;
+ }else if(!ldmpeq(l4, m2)){
+ fprintf(stderr, "FAIL: mpright(%s, %d, out): alias 3 and 1: arg 3: got %s, expected %s\n", LFMT(l2), i3, MFMT(m2), LFMT(l4));
+ fail=1;
+ }
+ }
+ }
+ ldfree(l2);
+ mpfree(m2);
+ ldfree(l4);
+ mpfree(m4);
+ if(!fail) fprintf(stderr, "mpright: passed\n");
+}
+static void
+testasr(void)
+{
+ int fail=0;
+ ldint *l2 = ldnew(0);
+ mpint *m2 = mpnew(0);
+ int i2;
+ int i3;
+ ldint *l4 = ldnew(0);
+ mpint *m4 = mpnew(0);
+ for(i2=0;i2<NTEST;i2++){
+ testgen(i2, l2);
+ for(i3=-128;i3<=128;i3++){
+ ldasr(l2, i3, l4);
+ ldtomp(l2, m2);
+ mptarget(m4);
+ mpasr(m2, i3, m4);
+ if(!ldmpeq(l2, m2)){
+ fprintf(stderr, "FAIL: mpasr(%s, %d, out): arg 1: input corrupted\n", LFMT(l2), i3);
+ fail=1;
+ }
+ if(m4->top == 0 && m4->sign < 0){
+ fprintf(stderr, "FAIL: mpasr(%s, %d, out): arg 3: got -0, shouldn't happen\n", LFMT(l2), i3);
+ fail=1;
+ }else if(m4->top != 0 && m4->p[m4->top - 1] == 0){
+ fprintf(stderr, "FAIL: mpasr(%s, %d, out): arg 3: got denormalised result\n", LFMT(l2), i3);
+ fail=1;
+ }else if(!ldmpeq(l4, m4)){
+ fprintf(stderr, "FAIL: mpasr(%s, %d, out): arg 3: got %s, expected %s\n", LFMT(l2), i3, MFMT(m4), LFMT(l4));
+ fail=1;
+ }
+ ldtomp(l2, m2);
+ mptarget(m4);
+ mpasr(m2, i3, m2);
+ if(m2->top == 0 && m2->sign < 0){
+ fprintf(stderr, "FAIL: mpasr(%s, %d, out): alias 3 and 1: arg 3: got -0, shouldn't happen\n", LFMT(l2), i3);
+ fail=1;
+ }else if(m2->top != 0 && m2->p[m2->top - 1] == 0){
+ fprintf(stderr, "FAIL: mpasr(%s, %d, out): alias 3 and 1: arg 3: got denormalised result\n", LFMT(l2), i3);
+ fail=1;
+ }else if(!ldmpeq(l4, m2)){
+ fprintf(stderr, "FAIL: mpasr(%s, %d, out): alias 3 and 1: arg 3: got %s, expected %s\n", LFMT(l2), i3, MFMT(m2), LFMT(l4));
+ fail=1;
+ }
+ }
+ }
+ ldfree(l2);
+ mpfree(m2);
+ ldfree(l4);
+ mpfree(m4);
+ if(!fail) fprintf(stderr, "mpasr: passed\n");
+}
+static void
+testdiv_(void)
+{
+ int fail=0;
+ ldint *l2 = ldnew(0);
+ mpint *m2 = mpnew(0);
+ int i2;
+ ldint *l3 = ldnew(0);
+ mpint *m3 = mpnew(0);
+ int i3;
+ ldint *l4 = ldnew(0);
+ mpint *m4 = mpnew(0);
+ ldint *l5 = ldnew(0);
+ mpint *m5 = mpnew(0);
+ for(i2=0;i2<NTEST;i2++){
+ testgen(i2, l2);
+ for(i3=0;i3<NTEST;i3++){
+ testgen(i3, l3);
+ lddiv_(l2, l3, l4, l5);
+ ldtomp(l2, m2);
+ ldtomp(l3, m3);
+ mptarget(m4);
+ mptarget(m5);
+ mpdiv_(m2, m3, m4, m5);
+ if(!ldmpeq(l2, m2)){
+ fprintf(stderr, "FAIL: mpdiv_(%s, %s, out, out): arg 1: input corrupted\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }
+ if(!ldmpeq(l3, m3)){
+ fprintf(stderr, "FAIL: mpdiv_(%s, %s, out, out): arg 2: input corrupted\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }
+ if(m4->top == 0 && m4->sign < 0){
+ fprintf(stderr, "FAIL: mpdiv_(%s, %s, out, out): arg 3: got -0, shouldn't happen\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(m4->top != 0 && m4->p[m4->top - 1] == 0){
+ fprintf(stderr, "FAIL: mpdiv_(%s, %s, out, out): arg 3: got denormalised result\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(!ldmpeq(l4, m4)){
+ fprintf(stderr, "FAIL: mpdiv_(%s, %s, out, out): arg 3: got %s, expected %s\n", LFMT(l2), LFMT(l3), MFMT(m4), LFMT(l4));
+ fail=1;
+ }
+ if(m5->top == 0 && m5->sign < 0){
+ fprintf(stderr, "FAIL: mpdiv_(%s, %s, out, out): arg 4: got -0, shouldn't happen\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(m5->top != 0 && m5->p[m5->top - 1] == 0){
+ fprintf(stderr, "FAIL: mpdiv_(%s, %s, out, out): arg 4: got denormalised result\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(!ldmpeq(l5, m5)){
+ fprintf(stderr, "FAIL: mpdiv_(%s, %s, out, out): arg 4: got %s, expected %s\n", LFMT(l2), LFMT(l3), MFMT(m5), LFMT(l5));
+ fail=1;
+ }
+ ldtomp(l2, m2);
+ ldtomp(l3, m3);
+ mptarget(m4);
+ mptarget(m5);
+ mpdiv_(m2, m3, m2, m5);
+ if(!ldmpeq(l3, m3)){
+ fprintf(stderr, "FAIL: mpdiv_(%s, %s, out, out): alias 3 and 1: arg 2: input corrupted\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }
+ if(m5->top == 0 && m5->sign < 0){
+ fprintf(stderr, "FAIL: mpdiv_(%s, %s, out, out): alias 3 and 1: arg 4: got -0, shouldn't happen\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(m5->top != 0 && m5->p[m5->top - 1] == 0){
+ fprintf(stderr, "FAIL: mpdiv_(%s, %s, out, out): alias 3 and 1: arg 4: got denormalised result\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(!ldmpeq(l5, m5)){
+ fprintf(stderr, "FAIL: mpdiv_(%s, %s, out, out): alias 3 and 1: arg 4: got %s, expected %s\n", LFMT(l2), LFMT(l3), MFMT(m5), LFMT(l5));
+ fail=1;
+ }
+ if(m2->top == 0 && m2->sign < 0){
+ fprintf(stderr, "FAIL: mpdiv_(%s, %s, out, out): alias 3 and 1: arg 3: got -0, shouldn't happen\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(m2->top != 0 && m2->p[m2->top - 1] == 0){
+ fprintf(stderr, "FAIL: mpdiv_(%s, %s, out, out): alias 3 and 1: arg 3: got denormalised result\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(!ldmpeq(l4, m2)){
+ fprintf(stderr, "FAIL: mpdiv_(%s, %s, out, out): alias 3 and 1: arg 3: got %s, expected %s\n", LFMT(l2), LFMT(l3), MFMT(m2), LFMT(l4));
+ fail=1;
+ }
+ ldtomp(l2, m2);
+ ldtomp(l3, m3);
+ mptarget(m4);
+ mptarget(m5);
+ mpdiv_(m2, m3, m3, m5);
+ if(!ldmpeq(l2, m2)){
+ fprintf(stderr, "FAIL: mpdiv_(%s, %s, out, out): alias 3 and 2: arg 1: input corrupted\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }
+ if(m5->top == 0 && m5->sign < 0){
+ fprintf(stderr, "FAIL: mpdiv_(%s, %s, out, out): alias 3 and 2: arg 4: got -0, shouldn't happen\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(m5->top != 0 && m5->p[m5->top - 1] == 0){
+ fprintf(stderr, "FAIL: mpdiv_(%s, %s, out, out): alias 3 and 2: arg 4: got denormalised result\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(!ldmpeq(l5, m5)){
+ fprintf(stderr, "FAIL: mpdiv_(%s, %s, out, out): alias 3 and 2: arg 4: got %s, expected %s\n", LFMT(l2), LFMT(l3), MFMT(m5), LFMT(l5));
+ fail=1;
+ }
+ if(m3->top == 0 && m3->sign < 0){
+ fprintf(stderr, "FAIL: mpdiv_(%s, %s, out, out): alias 3 and 2: arg 3: got -0, shouldn't happen\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(m3->top != 0 && m3->p[m3->top - 1] == 0){
+ fprintf(stderr, "FAIL: mpdiv_(%s, %s, out, out): alias 3 and 2: arg 3: got denormalised result\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(!ldmpeq(l4, m3)){
+ fprintf(stderr, "FAIL: mpdiv_(%s, %s, out, out): alias 3 and 2: arg 3: got %s, expected %s\n", LFMT(l2), LFMT(l3), MFMT(m3), LFMT(l4));
+ fail=1;
+ }
+ ldtomp(l2, m2);
+ ldtomp(l3, m3);
+ mptarget(m4);
+ mptarget(m5);
+ mpdiv_(m2, m3, m4, m2);
+ if(!ldmpeq(l3, m3)){
+ fprintf(stderr, "FAIL: mpdiv_(%s, %s, out, out): alias 4 and 1: arg 2: input corrupted\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }
+ if(m4->top == 0 && m4->sign < 0){
+ fprintf(stderr, "FAIL: mpdiv_(%s, %s, out, out): alias 4 and 1: arg 3: got -0, shouldn't happen\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(m4->top != 0 && m4->p[m4->top - 1] == 0){
+ fprintf(stderr, "FAIL: mpdiv_(%s, %s, out, out): alias 4 and 1: arg 3: got denormalised result\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(!ldmpeq(l4, m4)){
+ fprintf(stderr, "FAIL: mpdiv_(%s, %s, out, out): alias 4 and 1: arg 3: got %s, expected %s\n", LFMT(l2), LFMT(l3), MFMT(m4), LFMT(l4));
+ fail=1;
+ }
+ if(m2->top == 0 && m2->sign < 0){
+ fprintf(stderr, "FAIL: mpdiv_(%s, %s, out, out): alias 4 and 1: arg 4: got -0, shouldn't happen\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(m2->top != 0 && m2->p[m2->top - 1] == 0){
+ fprintf(stderr, "FAIL: mpdiv_(%s, %s, out, out): alias 4 and 1: arg 4: got denormalised result\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(!ldmpeq(l5, m2)){
+ fprintf(stderr, "FAIL: mpdiv_(%s, %s, out, out): alias 4 and 1: arg 4: got %s, expected %s\n", LFMT(l2), LFMT(l3), MFMT(m2), LFMT(l5));
+ fail=1;
+ }
+ ldtomp(l2, m2);
+ ldtomp(l3, m3);
+ mptarget(m4);
+ mptarget(m5);
+ mpdiv_(m2, m3, m4, m3);
+ if(!ldmpeq(l2, m2)){
+ fprintf(stderr, "FAIL: mpdiv_(%s, %s, out, out): alias 4 and 2: arg 1: input corrupted\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }
+ if(m4->top == 0 && m4->sign < 0){
+ fprintf(stderr, "FAIL: mpdiv_(%s, %s, out, out): alias 4 and 2: arg 3: got -0, shouldn't happen\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(m4->top != 0 && m4->p[m4->top - 1] == 0){
+ fprintf(stderr, "FAIL: mpdiv_(%s, %s, out, out): alias 4 and 2: arg 3: got denormalised result\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(!ldmpeq(l4, m4)){
+ fprintf(stderr, "FAIL: mpdiv_(%s, %s, out, out): alias 4 and 2: arg 3: got %s, expected %s\n", LFMT(l2), LFMT(l3), MFMT(m4), LFMT(l4));
+ fail=1;
+ }
+ if(m3->top == 0 && m3->sign < 0){
+ fprintf(stderr, "FAIL: mpdiv_(%s, %s, out, out): alias 4 and 2: arg 4: got -0, shouldn't happen\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(m3->top != 0 && m3->p[m3->top - 1] == 0){
+ fprintf(stderr, "FAIL: mpdiv_(%s, %s, out, out): alias 4 and 2: arg 4: got denormalised result\n", LFMT(l2), LFMT(l3));
+ fail=1;
+ }else if(!ldmpeq(l5, m3)){
+ fprintf(stderr, "FAIL: mpdiv_(%s, %s, out, out): alias 4 and 2: arg 4: got %s, expected %s\n", LFMT(l2), LFMT(l3), MFMT(m3), LFMT(l5));
+ fail=1;
+ }
+ }
+ }
+ ldfree(l2);
+ mpfree(m2);
+ ldfree(l3);
+ mpfree(m3);
+ ldfree(l4);
+ mpfree(m4);
+ ldfree(l5);
+ mpfree(m5);
+ if(!fail) fprintf(stderr, "mpdiv_: passed\n");
+}
+void
+tests(void)
+{
+ testcmp();
+ testmagcmp();
+ testadd();
+ testsub();
+ testmagadd();
+ testmagsub();
+ testand();
+ testbic();
+ testor();
+ testxor();
+ testnot();
+ testleft();
+ testright();
+ testasr();
+ testdiv_();
+}
--- /dev/null
+++ b/3rd/mp/test/ld.c
@@ -1,0 +1,560 @@
+#include "platform.h"
+#include "mp.h"
+#include "dat.h"
+#include "fns.h"
+
+static int
+ldget(ldint *a, uint32_t n)
+{
+ if(n < 0) return 0;
+ if(n >= a->n) return a->b[a->n - 1]&1;
+ return a->b[n]&1;
+}
+
+static void
+ldbits(ldint *a, int n)
+{
+ a->b = realloc(a->b, n);
+ a->n = n;
+}
+
+static ldint *
+ldnorm(ldint *a)
+{
+ int i;
+
+ if(a->n > 0){
+ for(i = a->n - 2; i >= 0; i--)
+ if(a->b[i] != a->b[a->n-1])
+ break;
+ ldbits(a, i + 2);
+ }else{
+ ldbits(a, 1);
+ a->b[0] = 0;
+ }
+ return a;
+}
+
+static void
+ldneg(ldint *a)
+{
+ int c, s, z;
+ uint32_t i;
+
+ c = 1;
+ s = a->b[a->n - 1];
+ z = 1;
+ for(i = 0; i < a->n; i++){
+ if(a->b[i]) z = 0;
+ c += 1 ^ a->b[i] & 1;
+ a->b[i] = c & 1;
+ c >>= 1;
+ }
+ if(!z && s == a->b[a->n - 1]){
+ ldbits(a, a->n + 1);
+ a->b[a->n - 1] = !s;
+ }
+}
+
+static int
+max(int a, int b)
+{
+ return a>b? a : b;
+}
+
+ldint *
+ldnew(int n)
+{
+ ldint *a;
+
+ a = malloc(sizeof(ldint));
+ if(n <= 0) n = 1;
+ a->b = malloc(n);
+ a->n = n;
+ return a;
+}
+
+void
+ldfree(ldint *a)
+{
+ if(a == nil) return;
+ free(a->b);
+ free(a);
+}
+
+mpint *
+ldtomp(ldint *a, mpint *b)
+{
+ int s, c;
+ uint32_t i;
+
+ if(b == nil)
+ b = mpnew(0);
+ mpbits(b, a->n);
+ s = a->b[a->n - 1] & 1;
+ b->sign = 1 - 2 * s;
+ c = s;
+ memset(b->p, 0, (a->n + Dbits - 1) / Dbits * Dbytes);
+ for(i = 0; i < a->n; i++){
+ c += s ^ a->b[i] & 1;
+ b->p[i / Dbits] |= (mpdigit)(c & 1) << (i & Dbits - 1);
+ c >>= 1;
+ }
+ b->top = (a->n + Dbits - 1) / Dbits;
+ mpnorm(b);
+ return b;
+}
+
+static ldint *
+itold(int n, ldint *a)
+{
+ uint32_t i;
+
+ if(a == nil)
+ a = ldnew(sizeof(n)*8);
+ else
+ ldbits(a, sizeof(n)*8);
+ for(i = 0; i < sizeof(n)*8; i++)
+ a->b[i] = n >> i & 1;
+ ldnorm(a);
+ return a;
+}
+
+static ldint *
+pow2told(int n, ldint *a)
+{
+ int k;
+
+ k = abs(n);
+ if(a == nil)
+ a = ldnew(k+2);
+ else
+ ldbits(a, k+2);
+ memset(a->b, 0, k+2);
+ a->b[k] = 1;
+ if(n < 0) ldneg(a);
+ ldnorm(a);
+ return a;
+}
+
+static char str[16][8192];
+static int istr = -1;
+
+char *
+LFMT(ldint *a)
+{
+ char *b, *p;
+ int s, c;
+ uint32_t i, d;
+
+ istr = (istr+1) % nelem(str);
+ b = str[istr] + 3;
+ d = (a->n + 3) / 4;
+ c = s = a->b[a->n - 1];
+ for(i = 0; i < a->n; i++){
+ c += s^ldget(a, i);
+ b[d - 1 - (i >> 2)] |= (c & 1) << (i & 3);
+ c >>= 1;
+ }
+ for(i = 0; i < d; i++)
+ b[i] = "0123456789ABCDEF"[(int)b[i]];
+ p = b;
+ while(*p == '0' && p[1] != 0) p++;
+ *--p = 'x';
+ *--p = '0';
+ if(a->b[a->n - 1])
+ *--p = '-';
+ return p;
+}
+
+char *
+MFMT(mpint *m)
+{
+ char *b;
+ istr = (istr+1) % nelem(str);
+ b = str[istr];
+ return mptoa(m, 16, b, sizeof(str[istr]));
+}
+
+int
+ldcmp(ldint *a, ldint *b)
+{
+ int x, y;
+ int i, r;
+
+ r = max(a->n, b->n);
+ if(a->b[a->n-1] != b->b[b->n-1])
+ return b->b[b->n - 1] - a->b[a->n - 1];
+ for(i = r - 1; --i >= 0; ){
+ x = ldget(a, i);
+ y = ldget(b, i);
+ if(x != y)
+ return x - y;
+ }
+ return 0;
+}
+
+int
+ldmagcmp(ldint *a, ldint *b)
+{
+ int s1, s2, r;
+
+ s1 = a->b[a->n - 1];
+ s2 = b->b[b->n - 1];
+ if(s1) ldneg(a);
+ if(s2) ldneg(b);
+ r = ldcmp(a, b);
+ if(s1) ldneg(a);
+ if(s2) ldneg(b);
+ return r;
+}
+
+int
+ldmpeq(ldint *a, mpint *b)
+{
+ uint32_t i, c;
+
+ if(b->sign > 0){
+ for(i = 0; i < b->top * Dbits; i++)
+ if(ldget(a, i) != (b->p[i / Dbits] >> (i & Dbits - 1) & 1))
+ return 0;
+ for(; i < a->n; i++)
+ if(a->b[i] != 0)
+ return 0;
+ return 1;
+ }else{
+ c = 1;
+ for(i = 0; i < b->top * Dbits; i++){
+ c += !ldget(a, i);
+ if((c & 1) != (b->p[i / Dbits] >> (i & Dbits - 1) & 1))
+ return 0;
+ c >>= 1;
+ }
+ for(; i < a->n; i++)
+ if(a->b[i] != 1)
+ return 0;
+ return 1;
+ }
+}
+
+void
+mptarget(mpint *r)
+{
+ int n;
+
+ n = rand() & 15;
+ mpbits(r, n * Dbits);
+ r->top = n;
+ prng((void *) r->p, n * Dbytes);
+ r->sign = 1 - 2 * (rand() & 1);
+}
+
+void
+ldadd(ldint *a, ldint *b, ldint *q)
+{
+ int r, i, c;
+
+ r = max(a->n, b->n) + 1;
+ ldbits(q, r);
+ c = 0;
+ for(i = 0; i < r; i++){
+ c += ldget(a, i) + ldget(b, i);
+ q->b[i] = c & 1;
+ c >>= 1;
+ }
+ ldnorm(q);
+}
+
+void
+ldmagadd(ldint *a, ldint *b, ldint *q)
+{
+ int i, r, s1, s2, c1, c2, co;
+
+ r = max(a->n, b->n) + 2;
+ ldbits(q, r);
+ co = 0;
+ s1 = c1 = a->b[a->n - 1] & 1;
+ s2 = c2 = b->b[b->n - 1] & 1;
+ for(i = 0; i < r; i++){
+ c1 += s1 ^ ldget(a, i) & 1;
+ c2 += s2 ^ ldget(b, i) & 1;
+ co += (c1 & 1) + (c2 & 1);
+ q->b[i] = co & 1;
+ co >>= 1;
+ c1 >>= 1;
+ c2 >>= 1;
+ }
+ ldnorm(q);
+}
+
+void
+ldmagsub(ldint *a, ldint *b, ldint *q)
+{
+ int i, r, s1, s2, c1, c2, co;
+
+ r = max(a->n, b->n) + 2;
+ ldbits(q, r);
+ co = 0;
+ s1 = c1 = a->b[a->n - 1] & 1;
+ s2 = c2 = 1 ^ b->b[b->n - 1] & 1;
+ for(i = 0; i < r; i++){
+ c1 += s1 ^ ldget(a, i) & 1;
+ c2 += s2 ^ ldget(b, i) & 1;
+ co += (c1 & 1) + (c2 & 1);
+ q->b[i] = co & 1;
+ co >>= 1;
+ c1 >>= 1;
+ c2 >>= 1;
+ }
+ ldnorm(q);
+}
+
+void
+ldsub(ldint *a, ldint *b, ldint *q)
+{
+ int r, i, c;
+
+ r = max(a->n, b->n) + 1;
+ ldbits(q, r);
+ c = 1;
+ for(i = 0; i < r; i++){
+ c += ldget(a, i) + (1^ldget(b, i));
+ q->b[i] = c & 1;
+ c >>= 1;
+ }
+ ldnorm(q);
+}
+
+static void
+lddiv(ldint *a, ldint *b, ldint *q, ldint *r)
+{
+ int n, i, j, c, s;
+
+ n = max(a->n, b->n) + 1;
+ ldbits(q, n);
+ ldbits(r, n);
+ memset(r->b, 0, n);
+ c = s = a->b[a->n-1];
+ for(i = 0; i < n; i++){
+ c += s ^ ldget(a, i);
+ q->b[i] = c & 1;
+ c >>= 1;
+ }
+ for(i = 0; i < n; i++){
+ for(j = n-1; --j >= 0; )
+ r->b[j + 1] = r->b[j];
+ r->b[0] = q->b[n - 1];
+ for(j = n-1; --j >= 0; )
+ q->b[j + 1] = q->b[j];
+ q->b[0] = !r->b[n - 1];
+ c = s = r->b[n - 1] == b->b[b->n - 1];
+ for(j = 0; j < n; j++){
+ c += r->b[j] + (s ^ ldget(b, j));
+ r->b[j] = c & 1;
+ c >>= 1;
+ }
+ }
+ for(j = n-1; --j >= 0; )
+ q->b[j + 1] = q->b[j];
+ q->b[0] = 1;
+ if(r->b[r->n - 1]){
+ c = 0;
+ for(j = 0; j < n; j++){
+ c += 1 + q->b[j];
+ q->b[j] = c & 1;
+ c >>= 1;
+ }
+ c = s = b->b[b->n - 1];
+ for(j = 0; j < n; j++){
+ c += r->b[j] + (s ^ ldget(b, j));
+ r->b[j] = c & 1;
+ c >>= 1;
+ }
+ }
+ c = s = a->b[a->n-1] ^ b->b[b->n-1];
+ for(j = 0; j < n; j++){
+ c += s ^ q->b[j];
+ q->b[j] = c & 1;
+ c >>= 1;
+ }
+ c = s = a->b[a->n-1];
+ for(j = 0; j < n; j++){
+ c += s ^ r->b[j];
+ r->b[j] = c & 1;
+ c >>= 1;
+ }
+ ldnorm(q);
+ ldnorm(r);
+}
+
+void
+lddiv_(ldint *a, ldint *b, ldint *q, ldint *r)
+{
+ if(ldmpeq(b, mpzero)){
+ memset(q->b, 0, q->n);
+ memset(r->b, 0, r->n);
+ return;
+ }
+ lddiv(a, b, q, r);
+}
+
+void
+mpdiv_(mpint *a, mpint *b, mpint *q, mpint *r)
+{
+ if(mpcmp(b, mpzero) == 0){
+ mpassign(mpzero, q);
+ mpassign(mpzero, r);
+ return;
+ }
+ mpdiv(a, b, q, r);
+}
+
+void
+ldand(ldint *a, ldint *b, ldint *q)
+{
+ int r, i;
+
+ r = max(a->n, b->n);
+ ldbits(q, r);
+ for(i = 0; i < r; i++)
+ q->b[i] = ldget(a, i) & ldget(b, i);
+ ldnorm(q);
+}
+
+void
+ldbic(ldint *a, ldint *b, ldint *q)
+{
+ int r, i;
+
+ r = max(a->n, b->n);
+ ldbits(q, r);
+ for(i = 0; i < r; i++)
+ q->b[i] = ldget(a, i) & ~ldget(b, i);
+ ldnorm(q);
+}
+
+void
+ldor(ldint *a, ldint *b, ldint *q)
+{
+ int r, i;
+
+ r = max(a->n, b->n);
+ ldbits(q, r);
+ for(i = 0; i < r; i++)
+ q->b[i] = ldget(a, i) | ldget(b, i);
+ ldnorm(q);
+}
+
+void
+ldxor(ldint *a, ldint *b, ldint *q)
+{
+ int r, i;
+
+ r = max(a->n, b->n);
+ ldbits(q, r);
+ for(i = 0; i < r; i++)
+ q->b[i] = ldget(a, i) ^ ldget(b, i);
+ ldnorm(q);
+}
+
+void
+ldleft(ldint *a, int n, ldint *b)
+{
+ int c;
+ uint32_t i;
+
+ if(n < 0){
+ if(a->n <= (uint32_t)-n){
+ b->n = 0;
+ ldnorm(b);
+ return;
+ }
+ c = 0;
+ if(a->b[a->n - 1])
+ for(i = 0; i < (uint32_t)-n; i++)
+ if(a->b[i]){
+ c = 1;
+ break;
+ }
+ ldbits(b, a->n + n);
+ for(i = 0; i < a->n + n; i++){
+ c += a->b[i - n] & 1;
+ b->b[i] = c & 1;
+ c >>= 1;
+ }
+ }else{
+ ldbits(b, a->n + n);
+ memmove(b->b + n, a->b, a->n);
+ memset(b->b, 0, n);
+ }
+ ldnorm(b);
+}
+
+void
+ldright(ldint *a, int n, ldint *b)
+{
+ ldleft(a, -n, b);
+}
+
+void
+ldasr(ldint *a, int n, ldint *b)
+{
+ if(n < 0){
+ ldleft(a, -n, b);
+ return;
+ }
+ if(a->n <= (uint32_t)n){
+ ldbits(b, 1);
+ b->b[0] = a->b[a->n - 1];
+ return;
+ }
+ ldbits(b, a->n - n);
+ memmove(b->b, a->b + n, a->n - n);
+ ldnorm(b);
+}
+
+void
+ldnot(ldint *a, ldint *b)
+{
+ uint32_t i;
+
+ ldbits(b, a->n);
+ for(i = 0; i < a->n; i++)
+ b->b[i] = a->b[i] ^ 1;
+}
+
+static uint32_t
+xorshift(uint32_t *state)
+{
+ uint32_t x = *state;
+ x ^= x << 13;
+ x ^= x >> 17;
+ x ^= x << 5;
+ *state = x;
+ return x;
+}
+
+void
+testgen(int i, ldint *a)
+{
+ uint32_t j, state;
+ uint32_t r = 0;
+
+ if(i < 257)
+ itold(i-128, a);
+ else if(i < 514)
+ pow2told(i-385, a);
+ else{
+ state = i;
+ xorshift(&state);
+ xorshift(&state);
+ xorshift(&state);
+ ldbits(a, Dbits * (1 + (xorshift(&state) & 15)));
+ for(j = 0; j < a->n; j++){
+ if((j & 31) == 0)
+ r = xorshift(&state);
+ a->b[j] = r & 1;
+ r >>= 1;
+ }
+ }
+}
--- /dev/null
+++ b/3rd/mp/test/main.c
@@ -1,0 +1,32 @@
+#include "platform.h"
+#include "mp.h"
+#include "dat.h"
+#include "fns.h"
+#include "ieee754.h"
+
+double D_PNAN, D_NNAN, D_PINF, D_NINF;
+float F_PNAN, F_NNAN, F_PINF, F_NINF;
+
+void
+prng(uint8_t *p, int n)
+{
+ while(n-- > 0)
+ *p++ = rand();
+}
+
+int
+main()
+{
+ D_PNAN = D_NNAN = strtod("+NaN", nil);
+ D_PINF = D_NINF = strtod("+Inf", nil);
+
+ union ieee754_double *d;
+ d = (union ieee754_double *)&D_NNAN;
+ d->ieee.negative = 1;
+ d = (union ieee754_double *)&D_NINF;
+ d->ieee.negative = 1;
+
+ convtests();
+ tests();
+ return 0;
+}
--- a/meson.build
+++ b/meson.build
@@ -25,40 +25,6 @@
language: 'c',
)
-mp = [
- '3rd/mp/mpadd.c',
- '3rd/mp/mpaux.c',
- '3rd/mp/mpcmp.c',
- '3rd/mp/mpdigdiv.c',
- '3rd/mp/mpdiv.c',
- '3rd/mp/mpextendedgcd.c',
- '3rd/mp/mpexp.c',
- '3rd/mp/mpfmt.c',
- '3rd/mp/mpinvert.c',
- '3rd/mp/mpleft.c',
- '3rd/mp/mplogic.c',
- '3rd/mp/mpmod.c',
- '3rd/mp/mpmodop.c',
- '3rd/mp/mpmul.c',
- '3rd/mp/mprand.c',
- '3rd/mp/mpright.c',
- '3rd/mp/mpsub.c',
- '3rd/mp/mptobe.c',
- '3rd/mp/mptober.c',
- '3rd/mp/mptod.c',
- '3rd/mp/mptoi.c',
- '3rd/mp/mptoui.c',
- '3rd/mp/mptouv.c',
- '3rd/mp/mptov.c',
- '3rd/mp/mpvecadd.c',
- '3rd/mp/mpveccmp.c',
- '3rd/mp/mpvecdigmuladd.c',
- '3rd/mp/mpvecsub.c',
- '3rd/mp/mpvectscmp.c',
- '3rd/mp/strtomp.c',
- '3rd/mp/u16.c',
-]
-
utf = [
'3rd/utf/rune.c',
'3rd/utf/runeistype.c',
@@ -153,11 +119,51 @@
],
)
+mp = static_library(
+ 'mp',
+ [
+ '3rd/mp/mpadd.c',
+ '3rd/mp/mpaux.c',
+ '3rd/mp/mpcmp.c',
+ '3rd/mp/mpdigdiv.c',
+ '3rd/mp/mpdiv.c',
+ '3rd/mp/mpexp.c',
+ '3rd/mp/mpextendedgcd.c',
+ '3rd/mp/mpfmt.c',
+ '3rd/mp/mpinvert.c',
+ '3rd/mp/mpleft.c',
+ '3rd/mp/mplogic.c',
+ '3rd/mp/mpmod.c',
+ '3rd/mp/mpmodop.c',
+ '3rd/mp/mpmul.c',
+ '3rd/mp/mprand.c',
+ '3rd/mp/mpright.c',
+ '3rd/mp/mpsub.c',
+ '3rd/mp/mptobe.c',
+ '3rd/mp/mptober.c',
+ '3rd/mp/mptod.c',
+ '3rd/mp/mptoi.c',
+ '3rd/mp/mptoui.c',
+ '3rd/mp/mptouv.c',
+ '3rd/mp/mptov.c',
+ '3rd/mp/mpvecadd.c',
+ '3rd/mp/mpveccmp.c',
+ '3rd/mp/mpvecdigmuladd.c',
+ '3rd/mp/mpvecsub.c',
+ '3rd/mp/mpvectscmp.c',
+ '3rd/mp/strtomp.c',
+ '3rd/mp/u16.c',
+ ],
+ include_directories: include_directories(
+ '3rd/mp',
+ 'posix',
+ ),
+)
+
flisp = executable(
'flisp',
sources: [
src,
- mp,
utf,
boot,
builtins,
@@ -171,6 +177,9 @@
'3rd/utf',
'posix',
),
+ link_with: [
+ mp,
+ ],
)
mptest = executable(
@@ -177,22 +186,40 @@
'mptest',
sources: [
'3rd/mp/test.c',
- mp,
],
include_directories: include_directories(
- '3rd',
- '3rd/mp',
'posix',
),
+ link_with: [
+ mp,
+ ],
)
test('mp', mptest)
+mptest2 = executable(
+ 'mptest2',
+ sources: [
+ '3rd/mp/test/convtest.c',
+ '3rd/mp/test/gen.tab.c',
+ '3rd/mp/test/ld.c',
+ '3rd/mp/test/main.c',
+ ],
+ include_directories: include_directories(
+ '3rd/mp/test',
+ 'posix',
+ ),
+ link_with: [
+ mp,
+ ],
+)
+test('mp2', mptest2, timeout: -1)
+
tests_dir = join_paths(meson.current_source_dir(), 'test')
test('argv', flisp, args: ['argv.lsp'], workdir: tests_dir)
test('hash', flisp, args: ['hashtest.lsp'], workdir: tests_dir)
-test('perf', flisp, args: ['perf.lsp'], workdir: tests_dir, timeout: 60)
+test('perf', flisp, args: ['perf.lsp'], workdir: tests_dir, timeout: -1)
test('tme', flisp, args: ['tme.lsp'], workdir: tests_dir)
-test('torture', flisp, args: ['torture.scm'], workdir: tests_dir, timeout: 60)
+test('torture', flisp, args: ['torture.scm'], workdir: tests_dir, timeout: -1)
test('torus', flisp, args: ['torus.lsp'], workdir: tests_dir)
test('unit', flisp, args: ['unittest.lsp'], workdir: tests_dir)