diff --git a/Makefile b/Makefile index 17519c1..96df21d 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ CC = gcc F = prog.bin # Compiler flags -CFLAGS = -I ./bigint -L ./bigint -g -Wall -std=c99 -pedantic -v -lbigint -lm +CFLAGS = -I ./bigint/build/include -L ./bigint/build/lib -g -Wall -std=c99 -pedantic # Source file SRC = njvm.c diff --git a/bigint/Makefile b/bigint/Makefile new file mode 100644 index 0000000..5b9ac79 --- /dev/null +++ b/bigint/Makefile @@ -0,0 +1,22 @@ +# +# Makefile for big integer library and test +# + +DIRS = src tst + +all: + for i in $(DIRS) ; do \ + $(MAKE) -C $$i install ; \ + done + +clean: + for i in $(DIRS) ; do \ + $(MAKE) -C $$i clean ; \ + done + rm -rf ./build + rm -f *~ + +dist: clean + (cd .. ; \ + tar -cvf bigint.tar bigint ; \ + gzip -f bigint.tar) diff --git a/bigint/bigint.o b/bigint/bigint.o deleted file mode 100644 index a35a447..0000000 Binary files a/bigint/bigint.o and /dev/null differ diff --git a/bigint/build/bin/testbip b/bigint/build/bin/testbip new file mode 100755 index 0000000..6d9fe44 Binary files /dev/null and b/bigint/build/bin/testbip differ diff --git a/bigint/bigint.h b/bigint/build/include/bigint.h similarity index 100% rename from bigint/bigint.h rename to bigint/build/include/bigint.h diff --git a/bigint/support.h b/bigint/build/include/support.h similarity index 100% rename from bigint/support.h rename to bigint/build/include/support.h diff --git a/bigint/build/lib/libbigint.a b/bigint/build/lib/libbigint.a new file mode 100644 index 0000000..a4ddb1a Binary files /dev/null and b/bigint/build/lib/libbigint.a differ diff --git a/bigint/libbigint.a b/bigint/libbigint.a deleted file mode 100644 index 1888300..0000000 Binary files a/bigint/libbigint.a and /dev/null differ diff --git a/bigint/src/Makefile b/bigint/src/Makefile new file mode 100644 index 0000000..6973380 --- /dev/null +++ b/bigint/src/Makefile @@ -0,0 +1,26 @@ +# +# Makefile for big integer library +# + +BUILD = ../build + +CC = gcc +CFLAGS = -g -Wall + +all: support.h bigint.h libbigint.a + +install: all + mkdir -p $(BUILD)/include + cp support.h $(BUILD)/include + cp bigint.h $(BUILD)/include + mkdir -p $(BUILD)/lib + cp libbigint.a $(BUILD)/lib + +libbigint.a: bigint.o + ar -crs libbigint.a bigint.o + +bigint.o: bigint.c bigint.h support.h + $(CC) $(CFLAGS) -o bigint.o -c bigint.c + +clean: + rm -f *~ bigint.o libbigint.a diff --git a/bigint/bigint.c b/bigint/src/bigint.c similarity index 100% rename from bigint/bigint.c rename to bigint/src/bigint.c diff --git a/bigint/src/bigint.h b/bigint/src/bigint.h new file mode 100644 index 0000000..b93d88e --- /dev/null +++ b/bigint/src/bigint.h @@ -0,0 +1,60 @@ +/* + * bigint.h -- big integer library + */ + + +#ifndef _BIGINT_H_ +#define _BIGINT_H_ + + +/* object representation */ +typedef void* BigObjRef; + + +#include + + +typedef struct { + int nd; /* number of digits; array may be bigger */ + /* nd = 0 exactly when number = 0 */ + unsigned char sign; /* one of BIG_NEGATIVE or BIG_POSITIVE */ + /* zero always has BIG_POSITIVE here */ + unsigned char digits[1]; /* the digits proper; number base is 256 */ + /* LS digit first; MS digit is not zero */ +} Big; + +#include "support.h" + + +/* big integer processor registers */ + +typedef struct { + BigObjRef op1; /* first (or single) operand */ + BigObjRef op2; /* second operand (if present) */ + BigObjRef res; /* result of operation */ + BigObjRef rem; /* remainder in case of division */ +} BIP; + +extern BIP bip; /* registers of the processor */ + + +/* big integer processor functions */ + +int bigSgn(void); /* sign */ +int bigCmp(void); /* comparison */ +void bigNeg(void); /* negation */ +void bigAdd(void); /* addition */ +void bigSub(void); /* subtraction */ +void bigMul(void); /* multiplication */ +void bigDiv(void); /* division */ + +void bigFromInt(int n); /* conversion int --> big */ +int bigToInt(void); /* conversion big --> int */ + +void bigRead(FILE *in); /* read a big integer */ +void bigPrint(FILE *out); /* print a big integer */ + +void bigDump(FILE *out, BigObjRef bigObjRef); /* dump a big integer object */ + + +#endif /* _BIGINT_H_ */ diff --git a/bigint/src/bigint.o b/bigint/src/bigint.o new file mode 100644 index 0000000..73a86c5 Binary files /dev/null and b/bigint/src/bigint.o differ diff --git a/bigint/src/libbigint.a b/bigint/src/libbigint.a new file mode 100644 index 0000000..a4ddb1a Binary files /dev/null and b/bigint/src/libbigint.a differ diff --git a/bigint/src/support.h b/bigint/src/support.h new file mode 100644 index 0000000..8e4455e --- /dev/null +++ b/bigint/src/support.h @@ -0,0 +1,15 @@ +/* + * support.h -- object representation and support functions + */ + + +#ifndef _SUPPORT_H_ +#define _SUPPORT_H_ + +/* support functions */ + +void fatalError(char *msg); /* print a message and exit */ +void * newPrimObject(int dataSize); /* create a new primitive object */ +void * getPrimObjectDataPointer(void * primObject); + +#endif /* _SUPPORT_H_ */ diff --git a/bigint/tst/Makefile b/bigint/tst/Makefile new file mode 100644 index 0000000..67ca0eb --- /dev/null +++ b/bigint/tst/Makefile @@ -0,0 +1,28 @@ +# +# Makefile for big integer test +# + +BUILD = ../build + +CC = gcc +CFLAGS = -g -Wall -I$(BUILD)/include +LDFLAGS = -g -Wall -L$(BUILD)/lib +LDLIBS = -lbigint + +all: testbip + +install: all + mkdir -p $(BUILD)/bin + cp testbip $(BUILD)/bin + +testbip: testbip.o support.o + $(CC) $(LDFLAGS) -o testbip testbip.o support.o $(LDLIBS) + +testbip.o: testbip.c + $(CC) $(CFLAGS) -o testbip.o -c testbip.c + +support.o: support.c + $(CC) $(CFLAGS) -o support.o -c support.c + +clean: + rm -f *~ testbip.o support.o testbip diff --git a/bigint/tst/support.c b/bigint/tst/support.c new file mode 100644 index 0000000..b036b1e --- /dev/null +++ b/bigint/tst/support.c @@ -0,0 +1,55 @@ +/* + * support.c -- support functions for big integer library + */ + + +#include +#include + +#include "support.h" + +typedef struct { + unsigned int size; /* byte count of payload data */ + unsigned char data[1]; /* payload data, size as needed */ +} *ObjRef; + + +/* + * This routine is called in case a fatal error has occurred. + * It should print the error message and terminate the program. + */ +void fatalError(char *msg) { + printf("Fatal error: %s\n", msg); + exit(1); +} + + +/* + * This function is called whenever a new primitive object with + * a certain amount of internal memory is needed. It should return + * an object reference to a regular object, which contains a freely + * usable memory area of at least the requested size (measured in + * bytes). The memory area need not be initialized in any way. + * + * Note that this function may move all objects in memory at will + * (due to, e.g., garbage collection), as long as the pointers in + * the global "bip" structure point to the correct objects when + * the function returns. + */ +void * newPrimObject(int dataSize) { + ObjRef bigObjRef; + + bigObjRef = malloc(sizeof(unsigned int) + + dataSize * sizeof(unsigned char)); + if (bigObjRef == NULL) { + fatalError("newPrimObject() got no memory"); + } + bigObjRef->size = dataSize; + return bigObjRef; +} + +void * getPrimObjectDataPointer(void * obj){ + ObjRef oo = ((ObjRef) (obj)); + return oo->data; +} + diff --git a/bigint/tst/support.o b/bigint/tst/support.o new file mode 100644 index 0000000..859a1a1 Binary files /dev/null and b/bigint/tst/support.o differ diff --git a/bigint/tst/testbip b/bigint/tst/testbip new file mode 100755 index 0000000..6d9fe44 Binary files /dev/null and b/bigint/tst/testbip differ diff --git a/bigint/tst/testbip.c b/bigint/tst/testbip.c new file mode 100644 index 0000000..7c65754 --- /dev/null +++ b/bigint/tst/testbip.c @@ -0,0 +1,1253 @@ +/* + * testbip.c -- test the big integer processor + */ + + +#include +#include +#include + +#include "bigint.h" + +typedef struct { + unsigned int size; /* byte count of payload data */ + unsigned char data[1]; /* payload data, size as needed */ +} *ObjRef; + +/**************************************************************/ + + +void dump(char *prefix, ObjRef x, char *suffix) { + if (prefix != NULL && *prefix != '\0') { + printf("%s", prefix); + } + bigDump(stdout, x); + if (suffix != NULL && *suffix != '\0') { + printf("%s", suffix); + } +} + + +/**************************************************************/ + + +void test00(void) { + bigFromInt(0); + dump("+0x00000000 = ", bip.res, "\n"); + + bigFromInt(1); + dump("+0x00000001 = ", bip.res, "\n"); + + bigFromInt(2); + dump("+0x00000002 = ", bip.res, "\n"); + + bigFromInt(0x12); + dump("+0x00000012 = ", bip.res, "\n"); + + bigFromInt(0x123); + dump("+0x00000123 = ", bip.res, "\n"); + + bigFromInt(0x1234); + dump("+0x00001234 = ", bip.res, "\n"); + + bigFromInt(0x12345); + dump("+0x00012345 = ", bip.res, "\n"); + + bigFromInt(0x123456); + dump("+0x00123456 = ", bip.res, "\n"); + + bigFromInt(0x1234567); + dump("+0x01234567 = ", bip.res, "\n"); + + bigFromInt(0x12345678); + dump("+0x12345678 = ", bip.res, "\n"); + + bigFromInt(-0); + dump("-0x00000000 = ", bip.res, "\n"); + + bigFromInt(-1); + dump("-0x00000001 = ", bip.res, "\n"); + + bigFromInt(-2); + dump("-0x00000002 = ", bip.res, "\n"); + + bigFromInt(-0x12); + dump("-0x00000012 = ", bip.res, "\n"); + + bigFromInt(-0x123); + dump("-0x00000123 = ", bip.res, "\n"); + + bigFromInt(-0x1234); + dump("-0x00001234 = ", bip.res, "\n"); + + bigFromInt(-0x12345); + dump("-0x00012345 = ", bip.res, "\n"); + + bigFromInt(-0x123456); + dump("-0x00123456 = ", bip.res, "\n"); + + bigFromInt(-0x1234567); + dump("-0x01234567 = ", bip.res, "\n"); + + bigFromInt(-0x12345678); + dump("-0x12345678 = ", bip.res, "\n"); +} + + +/**************************************************************/ + + +void test01(void) { + bigFromInt(0); + bip.op1 = bip.res; + printf("sign(+0x00000000) = %d\n", bigSgn()); + + bigFromInt(1); + bip.op1 = bip.res; + printf("sign(+0x00000001) = %d\n", bigSgn()); + + bigFromInt(2); + bip.op1 = bip.res; + printf("sign(+0x00000002) = %d\n", bigSgn()); + + bigFromInt(0x12); + bip.op1 = bip.res; + printf("sign(+0x00000012) = %d\n", bigSgn()); + + bigFromInt(0x123); + bip.op1 = bip.res; + printf("sign(+0x00000123) = %d\n", bigSgn()); + + bigFromInt(0x1234); + bip.op1 = bip.res; + printf("sign(+0x00001234) = %d\n", bigSgn()); + + bigFromInt(0x12345); + bip.op1 = bip.res; + printf("sign(+0x00012345) = %d\n", bigSgn()); + + bigFromInt(0x123456); + bip.op1 = bip.res; + printf("sign(+0x00123456) = %d\n", bigSgn()); + + bigFromInt(0x1234567); + bip.op1 = bip.res; + printf("sign(+0x01234567) = %d\n", bigSgn()); + + bigFromInt(0x12345678); + bip.op1 = bip.res; + printf("sign(+0x12345678) = %d\n", bigSgn()); + + bigFromInt(-0); + bip.op1 = bip.res; + printf("sign(-0x00000000) = %d\n", bigSgn()); + + bigFromInt(-1); + bip.op1 = bip.res; + printf("sign(-0x00000001) = %d\n", bigSgn()); + + bigFromInt(-2); + bip.op1 = bip.res; + printf("sign(-0x00000002) = %d\n", bigSgn()); + + bigFromInt(-0x12); + bip.op1 = bip.res; + printf("sign(-0x00000012) = %d\n", bigSgn()); + + bigFromInt(-0x123); + bip.op1 = bip.res; + printf("sign(-0x00000123) = %d\n", bigSgn()); + + bigFromInt(-0x1234); + bip.op1 = bip.res; + printf("sign(-0x00001234) = %d\n", bigSgn()); + + bigFromInt(-0x12345); + bip.op1 = bip.res; + printf("sign(-0x00012345) = %d\n", bigSgn()); + + bigFromInt(-0x123456); + bip.op1 = bip.res; + printf("sign(-0x00123456) = %d\n", bigSgn()); + + bigFromInt(-0x1234567); + bip.op1 = bip.res; + printf("sign(-0x01234567) = %d\n", bigSgn()); + + bigFromInt(-0x12345678); + bip.op1 = bip.res; + printf("sign(-0x12345678) = %d\n", bigSgn()); +} + + +/**************************************************************/ + + +void test02(void) { + int m[7]; + ObjRef n[7]; + int i, j; + int res; + + m[0] = 0; + bigFromInt(m[0]); + n[0] = bip.res; + printf("n[0] = %d\n", m[0]); + + m[1] = 100; + bigFromInt(m[1]); + n[1] = bip.res; + printf("n[1] = %d\n", m[1]); + + m[2] = -100; + bigFromInt(m[2]); + n[2] = bip.res; + printf("n[2] = %d\n", m[2]); + + m[3] = 101; + bigFromInt(m[3]); + n[3] = bip.res; + printf("n[3] = %d\n", m[3]); + + m[4] = -101; + bigFromInt(m[4]); + n[4] = bip.res; + printf("n[4] = %d\n", m[4]); + + m[5] = 12345678; + bigFromInt(m[5]); + n[5] = bip.res; + printf("n[5] = %d\n", m[5]); + + m[6] = -12345678; + bigFromInt(m[6]); + n[6] = bip.res; + printf("n[6] = %d\n", m[6]); + + for (i = 0; i < 7; i++) { + for (j = 0; j < 7; j++) { + printf("%12d ", m[i]); + bip.op1 = n[i]; + bip.op2 = n[j]; + res = bigCmp(); + if (res < 0) { + printf("<"); + } else + if (res > 0) { + printf(">"); + } else { + printf("="); + } + printf(" %12d", m[j]); + printf("\n"); + } + } +} + + +/**************************************************************/ + + +void test03(void) { + bigFromInt(0); + bip.op1 = bip.res; + bigNeg(); + dump("+n = ", bip.op1, "\n"); + dump("-n = ", bip.res, "\n"); + + bigFromInt(1); + bip.op1 = bip.res; + bigNeg(); + dump("+n = ", bip.op1, "\n"); + dump("-n = ", bip.res, "\n"); + + bigFromInt(-1); + bip.op1 = bip.res; + bigNeg(); + dump("+n = ", bip.op1, "\n"); + dump("-n = ", bip.res, "\n"); + + bigFromInt(0x12345678); + bip.op1 = bip.res; + bigNeg(); + dump("+n = ", bip.op1, "\n"); + dump("-n = ", bip.res, "\n"); + + bigFromInt(-0x12345678); + bip.op1 = bip.res; + bigNeg(); + dump("+n = ", bip.op1, "\n"); + dump("-n = ", bip.res, "\n"); +} + + +/**************************************************************/ + + +void test04(void) { + int m[6]; + ObjRef n[6]; + int i, j; + + m[0] = +0x12345679; + m[1] = +0x12345678; + m[2] = +0x12345677; + m[3] = -0x12345677; + m[4] = -0x12345678; + m[5] = -0x12345679; + + for (i = 0; i < 6; i++) { + bigFromInt(m[i]); + n[i] = bip.res; + } + + for (i = 0; i < 6; i++) { + for (j = 0; j < 6; j++) { + bip.op1 = n[i]; + bip.op2 = n[j]; + bigAdd(); + printf("%12d + %12d = ", m[i], m[j]); + dump("", bip.res, "\n"); + } + } +} + + +/**************************************************************/ + + +void test05(void) { + int m[5]; + ObjRef n[5]; + int i, j; + + m[0] = +0x12345678; + m[1] = +1; + m[2] = 0; + m[3] = -1; + m[4] = -0x12345678; + + for (i = 0; i < 5; i++) { + bigFromInt(m[i]); + n[i] = bip.res; + } + + for (i = 0; i < 5; i++) { + for (j = 0; j < 5; j++) { + bip.op1 = n[i]; + bip.op2 = n[j]; + bigAdd(); + printf("%12d + %12d = ", m[i], m[j]); + dump("", bip.res, "\n"); + } + } +} + + +/**************************************************************/ + + +void test06(void) { + int m[6]; + ObjRef n[6]; + int i, j; + + m[0] = +0x12345679; + m[1] = +0x12345678; + m[2] = +0x12345677; + m[3] = -0x12345677; + m[4] = -0x12345678; + m[5] = -0x12345679; + + for (i = 0; i < 6; i++) { + bigFromInt(m[i]); + n[i] = bip.res; + } + + for (i = 0; i < 6; i++) { + for (j = 0; j < 6; j++) { + bip.op1 = n[i]; + bip.op2 = n[j]; + bigSub(); + printf("%12d - %12d = ", m[i], m[j]); + dump("", bip.res, "\n"); + } + } +} + + +/**************************************************************/ + + +void test07(void) { + int m[5]; + ObjRef n[5]; + int i, j; + + m[0] = +0x12345678; + m[1] = +1; + m[2] = 0; + m[3] = -1; + m[4] = -0x12345678; + + for (i = 0; i < 5; i++) { + bigFromInt(m[i]); + n[i] = bip.res; + } + + for (i = 0; i < 5; i++) { + for (j = 0; j < 5; j++) { + bip.op1 = n[i]; + bip.op2 = n[j]; + bigSub(); + printf("%12d - %12d = ", m[i], m[j]); + dump("", bip.res, "\n"); + } + } +} + + +/**************************************************************/ + + +void test08(void) { + int i; + + bigFromInt(1); + for (i = 1; i < 100; i++) { + bip.op1 = bip.res; + bip.op2 = bip.res; + bigAdd(); + printf("2 ^ %2d = ", i); + dump("", bip.res, "\n"); + } +} + + +/**************************************************************/ + + +void test09(void) { + int i, j; + + bigFromInt(2); + bip.op2 = bip.res; + for (i = 1; i < 10; i++) { + bip.res = bip.op2; + for (j = 1; j < i * i; j++) { + bip.op1 = bip.res; + bigMul(); + } + printf("2 ^ (%d ^ 2) = ", i); + dump("", bip.res, "\n"); + } +} + + +/**************************************************************/ + + +void factorial(int n) { + bigFromInt(1); + while (n > 0) { + bip.op1 = bip.res; + bigFromInt(n); + bip.op2 = bip.res; + bigMul(); + n--; + } +} + + +void test10(void) { + int i; + + for (i = 0; i < 100; i++) { + factorial(i); + printf("%2d! = ", i); + dump("", bip.res, "\n"); + } +} + + +/**************************************************************/ + + +void test11(void) { + int n, m; + + n = 5; + m = 0; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); +} + + +/**************************************************************/ + + +void test12(void) { + int n, m; + + n = 12; + m = 12345678; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + n = 12345677; + m = 12345678; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + n = -12; + m = 12345678; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + n = -12345677; + m = 12345678; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + n = 12; + m = -12345678; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + n = 12345677; + m = -12345678; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + n = -12; + m = -12345678; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + n = -12345677; + m = -12345678; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); +} + + +/**************************************************************/ + + +void test13(void) { + int n, m; + + n = 12345678; + m = 1; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + n = 12345678; + m = 17; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + n = 12345678; + m = 255; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + n = -12345678; + m = 1; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + n = -12345678; + m = 17; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + n = -12345678; + m = 255; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + n = 12345678; + m = -1; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + n = 12345678; + m = -17; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + n = 12345678; + m = -255; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + n = -12345678; + m = -1; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + n = -12345678; + m = -17; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + n = -12345678; + m = -255; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); +} + + +/**************************************************************/ + + +void test14(void) { + int n, m; + ObjRef dividend; + ObjRef divisor; + int ok; + + printf("divisor"); + for (m = 0; m < 256; m++) { + if (m % 8 == 0) { + printf("\n%3d to %3d: ", m, m + 7); + } + if (m == 0) { + printf(" "); + fflush(stdout); + continue; + } + bigFromInt(m); + divisor = bip.res; + ok = 1; + for (n = 0; n < (1 << 18); n++) { + bigFromInt(n); + dividend = bip.res; + bip.op1 = dividend; + bip.op2 = divisor; + bigDiv(); + bip.op1 = bip.res; + bigMul(); + free(bip.op1); + bip.op1 = bip.res; + bip.op2 = bip.rem; + bigAdd(); + free(bip.op1); + free(bip.op2); + bip.op1 = bip.res; + bip.op2 = dividend; + if (bigCmp() != 0) { + ok = 0; + } + free(bip.op1); + free(dividend); + } + free(divisor); + printf("%c", ok ? '.' : '?'); + fflush(stdout); + } + printf("\n"); +} + + +/**************************************************************/ + + +void test15(void) { + int n, m; + + n = 123456789; + m = (0xFF << 16) + 0x1234; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + printf("--------------------------------------------------\n"); + + n = 123456789; + m = (0x80 << 16) + 0x1234; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + printf("--------------------------------------------------\n"); + + n = 123456789; + m = (0x7F << 16) + 0x1234; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + printf("--------------------------------------------------\n"); + + n = 123456789; + m = (0x55 << 16) + 0x1234; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + printf("--------------------------------------------------\n"); + + n = 123456789; + m = (0x2F << 16) + 0x1234; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + printf("--------------------------------------------------\n"); + + n = 123456789; + m = (0x18 << 16) + 0x1234; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + printf("--------------------------------------------------\n"); + + n = 123456789; + m = (0x0A << 16) + 0x1234; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + printf("--------------------------------------------------\n"); + + n = 123456789; + m = (0x03 << 16) + 0x1234; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + printf("--------------------------------------------------\n"); + + n = 123456789; + m = (0x02 << 16) + 0x1234; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); + + printf("--------------------------------------------------\n"); + + n = 123456789; + m = (0x01 << 16) + 0x1234; + bigFromInt(n); + bip.op1 = bip.res; + bigFromInt(m); + bip.op2 = bip.res; + bigDiv(); + printf("%12d / %12d = ", n, m); + dump("", bip.res, "\n"); + printf("%12d %% %12d = ", n, m); + dump("", bip.rem, "\n"); +} + + +/**************************************************************/ + + +void test16(void) { + int n1, n2, n3, m; + + n1 = 0x12345678; + n2 = 0x66554433; + n3 = 12; + bigFromInt(n1); + bip.op1 = bip.res; + bigFromInt(n2); + bip.op2 = bip.res; + bigMul(); + bip.op1 = bip.res; + bigFromInt(n3); + bip.op2 = bip.res; + bigMul(); + bip.op1 = bip.res; + m = 0x5764; + bigFromInt(m); + bip.op2 = bip.res; + dump("", bip.op1, " / "); + dump("", bip.op2, " =\n"); + bigDiv(); + dump("", bip.res, " R. "); + dump("", bip.rem, "\n"); + bip.op1 = bip.res; + bigMul(); + bip.op1 = bip.res; + bip.op2 = bip.rem; + bigAdd(); + dump("quotient * divisor + remainder =\n", bip.res, "\n"); +} + + +/**************************************************************/ + + +void test17(void) { + /* prepare two big integers with 8 and 4 digits, respectively */ + bigFromInt(0x11111111); + bip.op1 = bip.res; + bip.op2 = bip.res; + bigMul(); + bip.op1 = bip.res; + /* set all 8 digits of dividend */ + ((ObjRef) bip.op1)->data[5 + 0] = 0xF2; + ((ObjRef) bip.op1)->data[5 + 1] = 0xFB; + ((ObjRef) bip.op1)->data[5 + 2] = 0xE3; + ((ObjRef) bip.op1)->data[5 + 3] = 0x46; + ((ObjRef) bip.op1)->data[5 + 4] = 0x7C; + ((ObjRef) bip.op1)->data[5 + 5] = 0xC2; + ((ObjRef) bip.op1)->data[5 + 6] = 0x54; + ((ObjRef) bip.op1)->data[5 + 7] = 0xF8; + /* set )all 4 digits of divisor */ + ((ObjRef) bip.op2)->data[5 + 0] = 0x1B; + ((ObjRef) bip.op2)->data[5 + 1] = 0xE8; + ((ObjRef) bip.op2)->data[5 + 2] = 0xE7; + ((ObjRef) bip.op2)->data[5 + 3] = 0x8D; + /* divide */ + dump("", bip.op1, " / "); + dump("", bip.op2, " =\n"); + bigDiv(); + dump("", bip.res, " R. "); + dump("", bip.rem, "\n"); + /* verify */ + bip.op1 = bip.res; + bigMul(); + bip.op1 = bip.res; + bip.op2 = bip.rem; + bigAdd(); + dump("quotient * divisor + remainder =\n", bip.res, "\n"); +} + + +/**************************************************************/ + + +void test18(void) { + /* prepare two big integers with 8 and 4 digits, respectively */ + bigFromInt(0x11111111); + bip.op1 = bip.res; + bip.op2 = bip.res; + bigMul(); + bip.op1 = bip.res; + /* set all 8 digits of dividend */ + ((ObjRef) bip.op1)->data[5 + 0] = 0x4D; + ((ObjRef) bip.op1)->data[5 + 1] = 0xCC; + ((ObjRef) bip.op1)->data[5 + 2] = 0x8C; + ((ObjRef) bip.op1)->data[5 + 3] = 0x18; + ((ObjRef) bip.op1)->data[5 + 4] = 0x34; + ((ObjRef) bip.op1)->data[5 + 5] = 0xDF; + ((ObjRef) bip.op1)->data[5 + 6] = 0x1D; + ((ObjRef) bip.op1)->data[5 + 7] = 0xFD; + /* set all 4 digits of divisor */ + ((ObjRef) bip.op2)->data[5 + 0] = 0x69; + ((ObjRef) bip.op2)->data[5 + 1] = 0xF4; + ((ObjRef) bip.op2)->data[5 + 2] = 0x94; + ((ObjRef) bip.op2)->data[5 + 3] = 0x37; + /* divide */ + dump("", bip.op1, " / "); + dump("", bip.op2, " =\n"); + bigDiv(); + dump("", bip.res, " R. "); + dump("", bip.rem, "\n"); + /* verify */ + bip.op1 = bip.res; + bigMul(); + bip.op1 = bip.res; + bip.op2 = bip.rem; + bigAdd(); + dump("quotient * divisor + remainder =\n", bip.res, "\n"); +} + + +/**************************************************************/ + + +void test19(void) { + int n, m; + + n = 0x7FFFFFFF; + bigFromInt(n); + bip.op1 = bip.res; + m = bigToInt(); + printf("%12d = %12d\n", n, m); + + n = 0x00000001; + bigFromInt(n); + bip.op1 = bip.res; + m = bigToInt(); + printf("%12d = %12d\n", n, m); + + n = 0x00000000; + bigFromInt(n); + bip.op1 = bip.res; + m = bigToInt(); + printf("%12d = %12d\n", n, m); + + n = -0x00000001; + bigFromInt(n); + bip.op1 = bip.res; + m = bigToInt(); + printf("%12d = %12d\n", n, m); + + n = -0x7FFFFFFF; + bigFromInt(n); + bip.op1 = bip.res; + m = bigToInt(); + printf("%12d = %12d\n", n, m); +} + + +/**************************************************************/ + + +void test20(void) { + printf("please enter a number: "); + fflush(stdout); + bigRead(stdin); + dump("", bip.res, "\n"); +} + + +/**************************************************************/ + + +void test21(void) { + bigFromInt(0); + dump("", bip.res, " = "); + bip.op1 = bip.res; + bigPrint(stdout); + printf("\n"); + + bigFromInt(1); + dump("", bip.res, " = "); + bip.op1 = bip.res; + bigPrint(stdout); + printf("\n"); + + bigFromInt(-1); + dump("", bip.res, " = "); + bip.op1 = bip.res; + bigPrint(stdout); + printf("\n"); + + bigFromInt(0x1234); + dump("", bip.res, " = "); + bip.op1 = bip.res; + bigPrint(stdout); + printf("\n"); + + bigFromInt(-0x1234); + dump("", bip.res, " = "); + bip.op1 = bip.res; + bigPrint(stdout); + printf("\n"); + + bigFromInt(0x186A0); + dump("", bip.res, " = "); + bip.op1 = bip.res; + bigPrint(stdout); + printf("\n"); + + bigFromInt(-0x186A0); + dump("", bip.res, " = "); + bip.op1 = bip.res; + bigPrint(stdout); + printf("\n"); + + bigFromInt(0x12345678); + dump("", bip.res, " = "); + bip.op1 = bip.res; + bigPrint(stdout); + printf("\n"); + + bigFromInt(-0x12345678); + dump("", bip.res, " = "); + bip.op1 = bip.res; + bigPrint(stdout); + printf("\n"); + + bigFromInt(987654321); + bip.op1 = bip.res; + bip.op2 = bip.res; + bigMul(); + bip.op1 = bip.res; + bip.op2 = bip.res; + bigMul(); + dump("", bip.res, " =\n"); + bip.op1 = bip.res; + bigPrint(stdout); + printf("\n"); +} + + +/**************************************************************/ + + +typedef struct { + void (*func)(void); + char *explanation; +} TestFunc; + + +TestFunc tests[] = { + { test00, "representation" }, + { test01, "sign" }, + { test02, "comparison" }, + { test03, "negation" }, + { test04, "addition, equal sizes" }, + { test05, "addition, different sizes" }, + { test06, "subtraction, equal sizes" }, + { test07, "subtraction, different sizes" }, + { test08, "2^n by addition" }, + { test09, "2^(n^2) by multiplication" }, + { test10, "factorial" }, + { test11, "division by zero" }, + { test12, "division, small dividend" }, + { test13, "division, single digit divisor" }, + { test14, "division, systematic test of simple cases" }, + { test15, "division, general case, different scale factors" }, + { test16, "division, general case, qhat (first guess)" }, + { test17, "division, general case, qhat (decremented twice)" }, + { test18, "division, general case, qhat (final correction)" }, + { test19, "conversion big --> int" }, + { test20, "read from file" }, + { test21, "print to file" }, +}; + +int numTests = sizeof(tests) / sizeof(tests[0]); + + +/**************************************************************/ + + +void usage(char *myself) { + int i; + + printf("Usage: %s \n", myself); + printf("valid test numbers are:\n"); + for (i = 0; i < numTests; i++) { + printf(" %2d: %s\n", i, tests[i].explanation); + } + exit(1); +} + + +int main(int argc, char *argv[]) { + int testNumber; + char *endp; + + if (argc != 2) { + usage(argv[0]); + } + testNumber = strtol(argv[1], &endp, 0); + if (*endp != '\0') { + usage(argv[0]); + } + if (testNumber < 0 || testNumber >= numTests) { + usage(argv[0]); + } + printf("Test %d: %s\n", testNumber, tests[testNumber].explanation); + (*tests[testNumber].func)(); + return 0; +} diff --git a/bigint/tst/testbip.o b/bigint/tst/testbip.o new file mode 100644 index 0000000..7c17fd5 Binary files /dev/null and b/bigint/tst/testbip.o differ diff --git a/njvm.c b/njvm.c index ad6dd18..ff6b17e 100644 --- a/njvm.c +++ b/njvm.c @@ -8,8 +8,6 @@ #include "codeReader.c" #include "SDA.c" #include "debugMenu.c" -#include "bigint.h" -#include "support.h" // Debug int debug = 0; @@ -51,8 +49,7 @@ void execute(struct program program) { goto end; case PUSHC: if (debug == 1) printf("pushc: %i\n", IMMEDIATE(program.program[i])); - bigFromInt(IMMEDIATE(program.program[i])); - push(stack, stackSlotWithObjRef(bip.res)); + push(stack, stackSlotWithObjRef(getIntObj(SIGN_EXTEND(IMMEDIATE(program.program[i]))))); break; case ADD: if (debug == 1) printf("add: %i + %i\n",peek(stack, 2),peek(stack, 1)); diff --git a/stack.c b/stack.c index f563d4e..f7a6ee9 100755 --- a/stack.c +++ b/stack.c @@ -44,9 +44,9 @@ ObjRefContainer getRefs(struct stack stack){ } continer.size = counter; ObjRef *list = (ObjRef *)malloc(counter * sizeof(ObjRef)); - for (int j = 0; j<= *stack.current; j++) - if(stack.stack[j].isObjRef == true) - list[counter--] = stack.stack[j].u.objRef; + for (int i = 0; i<= *stack.current; i++) + if(stack.stack[i].isObjRef == true) + list[counter--] = stack.stack[i].u.objRef; continer.refs = list; return continer; }