diff --git a/libguile/instructions.c b/libguile/instructions.c index a38035d25..3d20a6be8 100644 --- a/libguile/instructions.c +++ b/libguile/instructions.c @@ -40,6 +40,7 @@ SCM_SYMBOL (sym_bang, "!"); M(X8_S8_I16) \ M(X8_S12_S12) \ M(X8_S12_C12) \ + M(X8_S12_Z12) \ M(X8_C12_C12) \ M(X8_F12_F12) \ M(X8_S8_S8_S8) \ diff --git a/libguile/vm-engine.c b/libguile/vm-engine.c index a70f78a1c..e07bf46e5 100644 --- a/libguile/vm-engine.c +++ b/libguile/vm-engine.c @@ -4100,11 +4100,77 @@ VM_NAME (scm_i_thread *thread, struct scm_vm *vp, NEXT (1); } - VM_DEFINE_OP (218, unused_218, NULL, NOP) - VM_DEFINE_OP (219, unused_219, NULL, NOP) - VM_DEFINE_OP (220, unused_220, NULL, NOP) - VM_DEFINE_OP (221, unused_221, NULL, NOP) - VM_DEFINE_OP (222, unused_222, NULL, NOP) + VM_DEFINE_OP (218, s64_imm_numerically_equal, "s64-imm=?", OP1 (X8_S12_Z12)) + { + scm_t_uint16 a; + scm_t_int64 x, y; + + a = (op >> 8) & 0xfff; + x = SP_REF_S64 (a); + + y = ((scm_t_int32) op) >> 20; /* Sign extension. */ + + vp->compare_result = x == y ? SCM_F_COMPARE_EQUAL : SCM_F_COMPARE_NONE; + + NEXT (1); + } + + VM_DEFINE_OP (219, u64_imm_less, "u64-immcompare_result = x < y ? SCM_F_COMPARE_LESS_THAN : SCM_F_COMPARE_NONE; + + NEXT (1); + } + + VM_DEFINE_OP (220, imm_u64_less, "imm-u64compare_result = x < y ? SCM_F_COMPARE_LESS_THAN : SCM_F_COMPARE_NONE; + + NEXT (1); + } + + VM_DEFINE_OP (221, s64_imm_less, "s64-imm> 8) & 0xfff; + x = SP_REF_S64 (a); + + y = ((scm_t_int32) op) >> 20; /* Sign extension. */ + + vp->compare_result = x < y ? SCM_F_COMPARE_LESS_THAN : SCM_F_COMPARE_NONE; + + NEXT (1); + } + + VM_DEFINE_OP (222, imm_s64_less, "imm-s64> 8) & 0xfff; + y = SP_REF_S64 (a); + + x = ((scm_t_int32) op) >> 20; /* Sign extension. */ + + vp->compare_result = x < y ? SCM_F_COMPARE_LESS_THAN : SCM_F_COMPARE_NONE; + + NEXT (1); + } + VM_DEFINE_OP (223, unused_223, NULL, NOP) VM_DEFINE_OP (224, unused_224, NULL, NOP) VM_DEFINE_OP (225, unused_225, NULL, NOP) diff --git a/module/language/bytecode.scm b/module/language/bytecode.scm index 8372feb02..b6be04178 100644 --- a/module/language/bytecode.scm +++ b/module/language/bytecode.scm @@ -42,6 +42,7 @@ ((X8_S8_I16) 2) ((X8_S12_S12) 2) ((X8_S12_C12) 2) + ((X8_S12_Z12) 2) ((X8_C12_C12) 2) ((X8_F12_F12) 2) ((X8_S8_S8_S8) 3) diff --git a/module/language/cps/compile-bytecode.scm b/module/language/cps/compile-bytecode.scm index 429f7e777..f11a4c1ad 100644 --- a/module/language/cps/compile-bytecode.scm +++ b/module/language/cps/compile-bytecode.scm @@ -425,6 +425,12 @@ (binary op emit-je emit-jne a b)) (define (binary-< emit-= min c) (values #t #f)) + (else (values #f #f)))) +(define-branch-folder-alias s64-imm-< u64-imm-<) + +(define-unary-branch-folder* (imm-u64-< c type min max) + (cond + ((< c min) (values #t #t)) + ((>= c max) (values #t #f)) + (else (values #f #f)))) +(define-branch-folder-alias imm-s64-< imm-u64-<) + (define-binary-branch-folder (= type0 min0 max0 type1 min1 max1) (case (compare-integer-ranges type0 min0 max0 type1 min1 max1) ((=) (values #t #t)) ((< >) (values #t #f)) (else (values #f #f)))) (define-branch-folder-alias u64-= =) -(define-branch-folder-alias s64-= =) diff --git a/module/language/cps/types.scm b/module/language/cps/types.scm index 7dcafd663..841d29f28 100644 --- a/module/language/cps/types.scm +++ b/module/language/cps/types.scm @@ -471,6 +471,12 @@ minimum, and maximum." (let ((true? (not (zero? succ)))) body ...))) +(define-syntax-rule (define-predicate-inferrer/param + (name param arg ... true?) body ...) + (define-type-inferrer* (name param succ arg ...) + (let ((true? (not (zero? succ)))) + body ...))) + (define-syntax define-simple-type-checker (lambda (x) (define (parse-spec l) @@ -1007,16 +1013,31 @@ minimum, and maximum." (define-simple-type-checker (< &real &real)) (define-<-inferrer (< &real &exact-integer)) -(define-simple-type-checker (u64-= &u64 &u64)) (define-=-inferrer (u64-= &u64)) -(define-simple-type-checker (u64-< &u64 &u64)) (define-<-inferrer (u64-< &u64 &u64)) -(define-simple-type-checker (s64-= &s64 &s64)) -(define-=-inferrer (s64-= &s64)) -(define-simple-type-checker (s64-< &s64 &s64)) (define-<-inferrer (s64-< &s64 &s64)) +(define-predicate-inferrer/param (u64-imm-= b a true?) + (when true? + (restrict! a (logior &u64 &s64) (max (&min a) b) (min (&max a) b)))) + +(define-predicate-inferrer/param (u64-imm-< b a true?) + (if true? + (restrict! a (logior &u64 &s64) (&min a) (min (&max a) (1- b))) + (restrict! a (logior &u64 &s64) (max (&min a) b) (&max a)))) + +(define-predicate-inferrer/param (imm-u64-< b a true?) + (if true? + (restrict! a (logior &u64 &s64) (max (1+ (&min a)) b) (&max a)) + (restrict! a (logior &u64 &s64) (&min a) (min (&max a) b)))) + +(define-type-aliases u64-imm-= s64-imm-=) +(define-type-aliases u64-imm-< s64-imm-<) +(define-type-aliases imm-u64-< imm-s64-<) + + + ;; Unfortunately, we can't define f64 comparison inferrers because of ;; not-a-number values. diff --git a/module/system/vm/assembler.scm b/module/system/vm/assembler.scm index 718ff5ea2..3fd5bba79 100644 --- a/module/system/vm/assembler.scm +++ b/module/system/vm/assembler.scm @@ -66,8 +66,12 @@ emit-u64=? emit-u64