summaryrefslogtreecommitdiffstats
path: root/vm.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2018-03-15 06:09:26 -0700
committerKaz Kylheku <kaz@kylheku.com>2018-03-15 06:09:26 -0700
commit07019db7ceff2bf62fcd5e7ea5b0a011b359b73a (patch)
tree161dadb62323263c6c92f3cc563481487232249b /vm.c
parente6c37abe560ef78b8ba052fdd2d5034a5c57977d (diff)
downloadtxr-07019db7ceff2bf62fcd5e7ea5b0a011b359b73a.tar.gz
txr-07019db7ceff2bf62fcd5e7ea5b0a011b359b73a.tar.bz2
txr-07019db7ceff2bf62fcd5e7ea5b0a011b359b73a.zip
asm/vm: add ifq and ifql instructions.
* share/txr/stdlib/asm.tl (op-ifq, op-ifql): New opcode types. * vm.c (vm_ifq, vm_ifql): New static functions. (vm_execute): Handle IFQ and IFQL opcodes. * vmop.h (vm_op_t): Regenerated.
Diffstat (limited to 'vm.c')
-rw-r--r--vm.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/vm.c b/vm.c
index 4edf4a85..450165f0 100644
--- a/vm.c
+++ b/vm.c
@@ -441,6 +441,28 @@ static void vm_if(struct vm *vm, vm_word_t insn)
vm->ip = vm_insn_bigop(ip);
}
+static void vm_ifq(struct vm *vm, vm_word_t insn)
+{
+ unsigned ip = vm_insn_bigop(insn);
+ vm_word_t arg = vm->code[vm->ip++];
+ val a = vm_get(vm->dspl, vm_arg_operand_lo(arg));
+ val b = vm_get(vm->dspl, vm_arg_operand_hi(arg));
+
+ if (a != b)
+ vm->ip = vm_insn_bigop(ip);
+}
+
+static void vm_ifql(struct vm *vm, vm_word_t insn)
+{
+ unsigned ip = vm_insn_bigop(insn);
+ vm_word_t arg = vm->code[vm->ip++];
+ val a = vm_get(vm->dspl, vm_arg_operand_lo(arg));
+ val b = vm_get(vm->dspl, vm_arg_operand_hi(arg));
+
+ if (!eql(a, b))
+ vm->ip = vm_insn_bigop(ip);
+}
+
static void vm_uwprot(struct vm *vm, vm_word_t insn)
{
int saved_lev = vm->lev;
@@ -667,6 +689,12 @@ static val vm_execute(struct vm *vm)
case IF:
vm_if(vm, insn);
break;
+ case IFQ:
+ vm_ifq(vm, insn);
+ break;
+ case IFQL:
+ vm_ifql(vm, insn);
+ break;
case UWPROT:
vm_uwprot(vm, insn);
break;