From 70e2b39b7b4c49bf945fefdaae648c962055ba5c Mon Sep 17 00:00:00 2001 From: Matt Birkholz Date: Tue, 14 Feb 2012 09:45:55 -0700 Subject: [PATCH] svm: Added "product" instruction, i.e. Mul(). Using this new instruction only when overflow detection is required. --- src/compiler/machines/svm/assembler-rules.scm | 1 + src/compiler/machines/svm/machine.scm | 2 +- src/compiler/machines/svm/rules.scm | 7 +++- src/microcode/svm1-defns.h | 33 +++++++++++-------- src/microcode/svm1-interp.c | 10 ++++++ 5 files changed, 38 insertions(+), 15 deletions(-) diff --git a/src/compiler/machines/svm/assembler-rules.scm b/src/compiler/machines/svm/assembler-rules.scm index 531c7c97f..d24ed4895 100644 --- a/src/compiler/machines/svm/assembler-rules.scm +++ b/src/compiler/machines/svm/assembler-rules.scm @@ -574,6 +574,7 @@ USA. SOURCE1 SOURCE2)))) +(define-word-binary-instruction product) (define-word-binary-instruction quotient) (define-word-binary-instruction remainder) (define-word-binary-instruction lsh) diff --git a/src/compiler/machines/svm/machine.scm b/src/compiler/machines/svm/machine.scm index fd0785f04..6129638ec 100644 --- a/src/compiler/machines/svm/machine.scm +++ b/src/compiler/machines/svm/machine.scm @@ -161,7 +161,7 @@ USA. (define-binary-operations + - * - quotient remainder + product quotient remainder lsh and andc or xor max-unsigned min-unsigned / atan2) diff --git a/src/compiler/machines/svm/rules.scm b/src/compiler/machines/svm/rules.scm index 07c8b82dd..e22bc1115 100644 --- a/src/compiler/machines/svm/rules.scm +++ b/src/compiler/machines/svm/rules.scm @@ -376,7 +376,6 @@ USA. (inst target source1 source2)))))) (standard 'PLUS-FIXNUM inst:+) (standard 'MINUS-FIXNUM inst:-) - (standard 'MULTIPLY-FIXNUM inst:*) (standard 'FIXNUM-QUOTIENT inst:quotient) (standard 'FIXNUM-REMAINDER inst:remainder) (standard 'FIXNUM-LSH inst:lsh) @@ -384,6 +383,12 @@ USA. (standard 'FIXNUM-ANDC inst:andc) (standard 'FIXNUM-OR inst:or) (standard 'FIXNUM-XOR inst:xor)) + +(define-fixnum-2-args-method 'MULTIPLY-FIXNUM + (lambda (target source1 source2 overflow?) + (if overflow? (simple-branches! 'NFIX target)) + ((if overflow? inst:product inst:*) + target source1 source2))) ;;;; Flonums diff --git a/src/microcode/svm1-defns.h b/src/microcode/svm1-defns.h index 4245af33c..596299019 100644 --- a/src/microcode/svm1-defns.h +++ b/src/microcode/svm1-defns.h @@ -2,7 +2,7 @@ DO NOT EDIT: this file was generated by a program. -Copyright (C) 2010 Massachusetts Institute of Technology +Copyright (C) 2011 Massachusetts Institute of Technology This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. @@ -205,7 +205,7 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. DECODE_SIGNED_32 (value) #define SVM1_INST_START_CODE 0x01 -#define SVM1_INST_END_CODE 0xce +#define SVM1_INST_END_CODE 0xcf #define SVM1_INST_BINDINGS(binder) \ binder (SVM1_INST_STORE_B_WR_ADDR, store_b_wr_addr); \ @@ -402,6 +402,7 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. binder (SVM1_INST_SUBTRACT_FR, subtract_fr); \ binder (SVM1_INST_MULTIPLY_WR, multiply_wr); \ binder (SVM1_INST_MULTIPLY_FR, multiply_fr); \ + binder (SVM1_INST_PRODUCT, product); \ binder (SVM1_INST_QUOTIENT, quotient); \ binder (SVM1_INST_REMAINDER, remainder); \ binder (SVM1_INST_LSH, lsh); \ @@ -1435,67 +1436,73 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. DECODE_FLOAT_REGISTER (source1); \ DECODE_FLOAT_REGISTER (source2) -#define SVM1_INST_QUOTIENT 0xc3 +#define SVM1_INST_PRODUCT 0xc3 +#define DECODE_SVM1_INST_PRODUCT(target, source1, source2) \ + DECODE_WORD_REGISTER (target); \ + DECODE_WORD_REGISTER (source1); \ + DECODE_WORD_REGISTER (source2) + +#define SVM1_INST_QUOTIENT 0xc4 #define DECODE_SVM1_INST_QUOTIENT(target, source1, source2) \ DECODE_WORD_REGISTER (target); \ DECODE_WORD_REGISTER (source1); \ DECODE_WORD_REGISTER (source2) -#define SVM1_INST_REMAINDER 0xc4 +#define SVM1_INST_REMAINDER 0xc5 #define DECODE_SVM1_INST_REMAINDER(target, source1, source2) \ DECODE_WORD_REGISTER (target); \ DECODE_WORD_REGISTER (source1); \ DECODE_WORD_REGISTER (source2) -#define SVM1_INST_LSH 0xc5 +#define SVM1_INST_LSH 0xc6 #define DECODE_SVM1_INST_LSH(target, source1, source2) \ DECODE_WORD_REGISTER (target); \ DECODE_WORD_REGISTER (source1); \ DECODE_WORD_REGISTER (source2) -#define SVM1_INST_AND 0xc6 +#define SVM1_INST_AND 0xc7 #define DECODE_SVM1_INST_AND(target, source1, source2) \ DECODE_WORD_REGISTER (target); \ DECODE_WORD_REGISTER (source1); \ DECODE_WORD_REGISTER (source2) -#define SVM1_INST_ANDC 0xc7 +#define SVM1_INST_ANDC 0xc8 #define DECODE_SVM1_INST_ANDC(target, source1, source2) \ DECODE_WORD_REGISTER (target); \ DECODE_WORD_REGISTER (source1); \ DECODE_WORD_REGISTER (source2) -#define SVM1_INST_OR 0xc8 +#define SVM1_INST_OR 0xc9 #define DECODE_SVM1_INST_OR(target, source1, source2) \ DECODE_WORD_REGISTER (target); \ DECODE_WORD_REGISTER (source1); \ DECODE_WORD_REGISTER (source2) -#define SVM1_INST_XOR 0xc9 +#define SVM1_INST_XOR 0xca #define DECODE_SVM1_INST_XOR(target, source1, source2) \ DECODE_WORD_REGISTER (target); \ DECODE_WORD_REGISTER (source1); \ DECODE_WORD_REGISTER (source2) -#define SVM1_INST_MAX_UNSIGNED 0xca +#define SVM1_INST_MAX_UNSIGNED 0xcb #define DECODE_SVM1_INST_MAX_UNSIGNED(target, source1, source2) \ DECODE_WORD_REGISTER (target); \ DECODE_WORD_REGISTER (source1); \ DECODE_WORD_REGISTER (source2) -#define SVM1_INST_MIN_UNSIGNED 0xcb +#define SVM1_INST_MIN_UNSIGNED 0xcc #define DECODE_SVM1_INST_MIN_UNSIGNED(target, source1, source2) \ DECODE_WORD_REGISTER (target); \ DECODE_WORD_REGISTER (source1); \ DECODE_WORD_REGISTER (source2) -#define SVM1_INST_DIVIDE 0xcc +#define SVM1_INST_DIVIDE 0xcd #define DECODE_SVM1_INST_DIVIDE(target, source1, source2) \ DECODE_FLOAT_REGISTER (target); \ DECODE_FLOAT_REGISTER (source1); \ DECODE_FLOAT_REGISTER (source2) -#define SVM1_INST_ATAN2 0xcd +#define SVM1_INST_ATAN2 0xce #define DECODE_SVM1_INST_ATAN2(target, source1, source2) \ DECODE_FLOAT_REGISTER (target); \ DECODE_FLOAT_REGISTER (source1); \ diff --git a/src/microcode/svm1-interp.c b/src/microcode/svm1-interp.c index 38638269e..e46748d31 100644 --- a/src/microcode/svm1-interp.c +++ b/src/microcode/svm1-interp.c @@ -1188,9 +1188,19 @@ DEFINE_INST (nl) \ NEXT_PC; \ } +static word_t +multiply_with_overflow (long x, long y) +{ + word_t ans = (Mul ((LONG_TO_FIXNUM (x)), (LONG_TO_FIXNUM (y)))); + return (ans == SHARP_F + ? SHARP_T /* This need only be !NFIX for overflow-test. */ + : FIXNUM_TO_LONG (ans)); +} + DEFINE_BINARY_WR (add_wr, ADD_WR, OP_ADD) DEFINE_BINARY_WR (subtract_wr, SUBTRACT_WR, OP_SUBTRACT) DEFINE_BINARY_WR (multiply_wr, MULTIPLY_WR, OP_MULTIPLY) +DEFINE_BINARY_WR (product, PRODUCT, multiply_with_overflow) DEFINE_BINARY_WR (quotient, QUOTIENT, OP_DIVIDE) DEFINE_BINARY_WR (remainder, REMAINDER, OP_REMAINDER) DEFINE_BINARY_WR (and, AND, OP_AND) -- 2.25.1