diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2018-04-16 21:42:45 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2018-04-16 21:42:45 -0700 |
commit | 4e8c983e12b8235cfd4fa3594c8064d51fcb67c6 (patch) | |
tree | 1b0caddd2600849ab505aadf17636413d5296d4f /vm.c | |
parent | 49249272d243f6b27af4cf8cebbbb63d16dcdce7 (diff) | |
download | txr-4e8c983e12b8235cfd4fa3594c8064d51fcb67c6.tar.gz txr-4e8c983e12b8235cfd4fa3594c8064d51fcb67c6.tar.bz2 txr-4e8c983e12b8235cfd4fa3594c8064d51fcb67c6.zip |
vm/asm/compiler: parametrize display parameters.
In this patch we replace some hard-coded constants related to
the dimensions of the frame display, which will make it
easier to experiment with changes to the configuration:
to set up wider frames at the cost of max display depth.
The encoding of small operands needs to be abstracted because
games can be played here. A 10 bit small operand can be
configured in various ways: for instance a 5:5 split
would mean that the first 32 entries in the first 32 levels
can be small operands. That's independent of the display
configuration.
* share/txr/stdlib/asm.tl: Load vm-param to get some
fundamental constants.
(small-op-p): New macro.
(assembler parse-args, parse-compound-operand, parse-operand,
operand-to-sym): Use constants.
(enc-small-oip, small-op-to-sym): New macros.
(op-frame asm): Use constants. Small range check problem
fixed here: a frame level of 1 mustn't be allowed.
(op-movrs, op-movsr, op-mov-pseudo, op-movsmi, op-movrbi,
op-movi-pseudo, op-retsr, op-retrs, op-retrr, op-ret-pseudo,
op-getv, op-setv): Deal with small operand via functions.
(op-close): Use constants. Off-by-one problem: frame size
of 256 must be allowed.
* share/txr/stdlib/compiler.tl: Load vm-param to get
constants.
(compiler get-dreg, compiler get-funvec): Use constant for max
frame size.
(compiler new-env): Check for maximum levels being exceeded.
(compiler comp-atom): Use constant for maximum immediate
integer operand width.
* share/txr/stdlib/vm-param.tl: New file.
* vm.c (vm_insn_extra_dec_small): New macro.
(VM_LEV_BITS, VM_LEV_MASK, VM_SM_LEV_BITS, VM_SM_LEV_MASK):
New preprocessor constants.
(vm_lev, vm_idx, vm_sm_lev, vm_sm_idx): New macros.
(vm_get, vm_set): Use macros instead of literals.
(vm_sm_get, vm_sm_set): New inline functions.
(vm_movrs, vm_movsr, vm_movsmi, vm_retsr, vm_retrs,
vm_abscsr, vm_get_binding, vm_bindv): Use
vm_sm_get or vm_sm_set to access the display using
the small operand.
(vm_close): Use preprocessor symbols instead of hard-coded
literals.
Diffstat (limited to 'vm.c')
-rw-r--r-- | vm.c | 58 |
1 files changed, 45 insertions, 13 deletions
@@ -293,18 +293,49 @@ static void vm_reset(struct vm *vm, struct vm_desc *vd, #define vm_insn_bigop(insn) (((insn) & 0x3FFFFFFU)) #define vm_arg_operand_lo(arg) ((arg) & 0xFFFFU) #define vm_arg_operand_hi(arg) ((arg) >> 16) +#define VM_LEV_BITS 8 +#define VM_LEV_MASK 0xFF +#define VM_SM_LEV_BITS 8 +#define VM_SM_LEV_MASK 0xFF +#define vm_lev(arg) ((arg) >> VM_LEV_BITS) +#define vm_idx(arg) ((arg) & VM_LEV_MASK) +#define vm_sm_lev(arg) ((arg) >> VM_SM_LEV_BITS) +#define vm_sm_idx(arg) ((arg) & VM_SM_LEV_MASK) static val vm_execute(struct vm *vm); INLINE val vm_get(struct vm_env *dspl, unsigned ref) { - return dspl[ref >> 8].mem[ref & 0xFF]; + return dspl[vm_lev(ref)].mem[vm_idx(ref)]; +} + +INLINE val vm_sm_get(struct vm_env *dspl, unsigned ref) +{ + return dspl[vm_sm_lev(ref)].mem[vm_sm_idx(ref)]; } INLINE void vm_set(struct vm_env *dspl, unsigned ref, val newval) { - unsigned d = ref >> 8; - unsigned i = ref & 0xFF; + unsigned d = vm_lev(ref); + unsigned i = vm_idx(ref); + struct vm_env *env = &dspl[d]; + + if (d == 1) + uw_throwf(error_s, lit("modification of VM static data"), nao); + + if (ref == 0) + uw_throwf(error_s, lit("modification of t00/nil"), nao); + + env->mem[i] = newval; + + if (is_ptr(env->vec)) + mut(env->vec); +} + +INLINE void vm_sm_set(struct vm_env *dspl, unsigned ref, val newval) +{ + unsigned d = vm_sm_lev(ref); + unsigned i = vm_sm_idx(ref); struct vm_env *env = &dspl[d]; if (d == 1) @@ -319,6 +350,7 @@ INLINE void vm_set(struct vm_env *dspl, unsigned ref, val newval) mut(env->vec); } + static void vm_do_frame(struct vm *vm, vm_word_t insn, int capturable) { int lev = vm_insn_extra(insn); @@ -511,14 +543,14 @@ static void vm_gapply(struct vm *vm, vm_word_t insn) static void vm_movrs(struct vm *vm, vm_word_t insn) { - val datum = vm_get(vm->dspl, vm_insn_extra(insn)); + val datum = vm_sm_get(vm->dspl, vm_insn_extra(insn)); vm_set(vm->dspl, vm_insn_operand(insn), datum); } static void vm_movsr(struct vm *vm, vm_word_t insn) { val datum = vm_get(vm->dspl, vm_insn_operand(insn)); - vm_set(vm->dspl, vm_insn_extra(insn), datum); + vm_sm_set(vm->dspl, vm_insn_extra(insn), datum); } static void vm_movrr(struct vm *vm, vm_word_t insn) @@ -549,7 +581,7 @@ static void vm_movsmi(struct vm *vm, vm_word_t insn) if ((imm & TAG_MASK) == NUM && (imm & 0x8000)) imm |= negmask; - vm_set(vm->dspl, dst, coerce(val, imm)); + vm_sm_set(vm->dspl, dst, coerce(val, imm)); } static void vm_movrbi(struct vm *vm, vm_word_t insn) @@ -669,7 +701,7 @@ static void vm_no_block_err(struct vm *vm, val name) static void vm_retsr(struct vm *vm, vm_word_t insn) { val res = vm_get(vm->dspl, vm_insn_operand(insn)); - val tag = vm_get(vm->dspl, vm_insn_extra(insn)); + val tag = vm_sm_get(vm->dspl, vm_insn_extra(insn)); uw_block_return(tag, res); vm_no_block_err(vm, tag); @@ -677,7 +709,7 @@ static void vm_retsr(struct vm *vm, vm_word_t insn) static void vm_retrs(struct vm *vm, vm_word_t insn) { - val res = vm_get(vm->dspl, vm_insn_extra(insn)); + val res = vm_sm_get(vm->dspl, vm_insn_extra(insn)); val tag = vm_get(vm->dspl, vm_insn_operand(insn)); uw_block_return(tag, res); @@ -697,7 +729,7 @@ static void vm_retrr(struct vm *vm, vm_word_t insn) static void vm_abscsr(struct vm *vm, vm_word_t insn) { val res = vm_get(vm->dspl, vm_insn_operand(insn)); - val tag = vm_get(vm->dspl, vm_insn_extra(insn)); + val tag = vm_sm_get(vm->dspl, vm_insn_extra(insn)); uw_block_abscond(tag, res); vm_no_block_err(vm, tag); @@ -750,7 +782,7 @@ static val vm_get_binding(struct vm *vm, vm_word_t insn, val (*lookup_fn)(val env, val sym), val kind_str) { - val sym = vm_get(vm->dspl, vm_insn_extra(insn)); + val sym = vm_sm_get(vm->dspl, vm_insn_extra(insn)); val binding = lookup_fn(nil, sym); if (nilp(binding)) @@ -788,7 +820,7 @@ static void vm_setsym(struct vm *vm, vm_word_t insn, static void vm_bindv(struct vm *vm, vm_word_t insn) { - val sym = vm_get(vm->dspl, vm_insn_extra(insn)); + val sym = vm_sm_get(vm->dspl, vm_insn_extra(insn)); int src = vm_insn_operand(insn); if (nilp(dyn_env)) @@ -804,8 +836,8 @@ static void vm_close(struct vm *vm, vm_word_t insn) vm_word_t arg1 = vm->code[vm->ip++]; vm_word_t arg2 = vm->code[vm->ip++]; unsigned vari_fr = vm_arg_operand_hi(arg1); - int variadic = vari_fr & 0x100; - int frsz = vari_fr & 0xFF; + int variadic = vari_fr & (1 << VM_LEV_BITS); + int frsz = vari_fr & VM_LEV_MASK; unsigned reg = vm_arg_operand_lo(arg1); int reqargs = vm_arg_operand_hi(arg2); int fixparam = vm_arg_operand_lo(arg2); |