diff options
-rw-r--r-- | share/txr/stdlib/asm.tl | 17 | ||||
-rw-r--r-- | vm.c | 28 | ||||
-rw-r--r-- | vmop.h | 36 |
3 files changed, 64 insertions, 17 deletions
diff --git a/share/txr/stdlib/asm.tl b/share/txr/stdlib/asm.tl index a82ce156..2fc8b6fd 100644 --- a/share/txr/stdlib/asm.tl +++ b/share/txr/stdlib/asm.tl @@ -438,6 +438,23 @@ (reg (cadr asm.(get-pair)))) ^(,me.symbol ,(operand-to-sym reg) ,dst)))) +(defopcode op-ifq ifq auto + (:method asm (me asm syntax) + me.(chk-arg-count 3 syntax) + (tree-bind (lreg rreg dst) asm.(parse-args me syntax '(r r l)) + asm.(put-insn me.code (ash dst -16) (logtrunc dst 16)) + asm.(put-pair lreg rreg))) + + (:method backpatch (me asm at dst) + asm.(put-insn me.code (ash dst -16) (logtrunc dst 16))) + + (:method dis (me asm high16 low16) + (let ((dst (logior (ash high16 16) low16))) + (tree-bind (lreg rreg) asm.(get-pair) + ^(,me.symbol ,(operand-to-sym lreg) ,(operand-to-sym rreg) ,dst))))) + +(defopcode-derived op-ifql ifql auto op-ifq) + (defopcode-derived op-uwprot uwprot auto op-jmp) (defopcode op-block block auto @@ -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; @@ -42,21 +42,23 @@ typedef enum vm_op { MOVRBI = 13, JMP = 14, IF = 15, - UWPROT = 16, - BLOCK = 17, - RETSR = 18, - RETRS = 19, - RETRR = 20, - CATCH = 21, - HANDLE = 22, - GETV = 23, - GETF = 24, - GETL1 = 25, - GETVB = 26, - GETFB = 27, - GETL1B = 28, - SETV = 29, - SETL1 = 30, - BINDV = 31, - CLOSE = 32, + IFQ = 16, + IFQL = 17, + UWPROT = 18, + BLOCK = 19, + RETSR = 20, + RETRS = 21, + RETRR = 22, + CATCH = 23, + HANDLE = 24, + GETV = 25, + GETF = 26, + GETL1 = 27, + GETVB = 28, + GETFB = 29, + GETL1B = 30, + SETV = 31, + SETL1 = 32, + BINDV = 33, + CLOSE = 34, } vm_op_t; |