From: Rhys Weatherley Date: Tue, 25 May 2004 10:24:10 +0000 (+0000) Subject: Selectors for call instructions. X-Git-Tag: r.0.0.4~84 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=fcf10faf7d22c7ffbb0c5695b44ee3987fe0ac1d;p=francis%2Flibjit.git Selectors for call instructions. --- diff --git a/ChangeLog b/ChangeLog index 3b1db13..2806e53 100644 --- a/ChangeLog +++ b/ChangeLog @@ -12,6 +12,8 @@ * jit/jit-rules-x86.sel, tools/gen-sel-parser.y, tools/gen-sel-scanner.l: selectors for branch instructions. + * jit/jit-rules-x86.sel: selectors for call instructions. + 2004-05-24 Rhys Weatherley * include/jit/jit-insn.h, include/jit/jit-opcode.h, jit/jit-block.c, diff --git a/jit/jit-rules-x86.sel b/jit/jit-rules-x86.sel index 22e358a..a3edaf3 100644 --- a/jit/jit-rules-x86.sel +++ b/jit/jit-rules-x86.sel @@ -464,3 +464,142 @@ JIT_OP_IGE_UN: binary x86_alu_reg_reg(inst, X86_CMP, $1, $2); inst = setcc_reg(inst, $1, X86_CC_GE, 0); } + +/* + * Pointer check opcodes. + */ + +JIT_OP_CHECK_NULL: unary_branch + [reg] -> { + /* TODO: won't work in a function with a "try" block */ + unsigned char *patch; + x86_alu_reg_reg(inst, X86_OR, $1, $1); + patch = inst; + x86_branch8(inst, X86_CC_NE, 0, 0); + x86_push_imm(inst, JIT_RESULT_NULL_REFERENCE); + x86_call_code(inst, (void *)jit_exception_builtin); + x86_patch(patch, inst); + } + +/* + * Function calls. + */ + +JIT_OP_CALL: + [] -> { + jit_function_t func = (jit_function_t)(insn->dest); + x86_call_code(inst, func->closure_entry); + } + +JIT_OP_CALL_TAIL: + [] -> { + jit_function_t func = (jit_function_t)(insn->dest); + x86_jump_code(inst, func->closure_entry); + } + +JIT_OP_CALL_INDIRECT: + [] -> { + x86_call_reg(inst, X86_EAX); + } + +JIT_OP_CALL_VTABLE_PTR: + [] -> { + x86_call_reg(inst, X86_EAX); + } + +JIT_OP_CALL_EXTERNAL: + [] -> { + x86_call_code(inst, (void *)(insn->dest)); + } + +JIT_OP_RETURN: + [] -> { + inst = jump_to_epilog(gen, inst, insn); + } + +JIT_OP_RETURN_INT: unary_branch + [reg] -> { + int cpu_reg = $1; + if(cpu_reg != X86_EAX) + { + x86_mov_reg_reg(inst, X86_EAX, cpu_reg, 4); + } + inst = jump_to_epilog(gen, inst, insn); + } + +JIT_OP_RETURN_LONG: spill_before + [] -> { + /* TODO: load the return value into EAX:EDX */ + inst = jump_to_epilog(gen, inst, insn); + } + +JIT_OP_RETURN_FLOAT32: unary_branch, stack /*, only*/ + [freg] -> { + inst = jump_to_epilog(gen, inst, insn); + } + +JIT_OP_RETURN_FLOAT64: unary_branch, stack /*, only*/ + [freg] -> { + inst = jump_to_epilog(gen, inst, insn); + } + +JIT_OP_RETURN_NFLOAT: unary_branch, stack /*, only*/ + [freg] -> { + inst = jump_to_epilog(gen, inst, insn); + } + +JIT_OP_RETURN_SMALL_STRUCT: spill_before + [] -> { + /* TODO: load the structure value into EAX:EDX */ + inst = jump_to_epilog(gen, inst, insn); + } + +JIT_OP_SETUP_FOR_NESTED: spill_before + [] -> { + jit_nint nest_reg = jit_value_get_nint_constant(insn->value1); + if(nest_reg == -1) + { + x86_push_reg(inst, X86_EBP); + } + else + { + x86_mov_reg_reg(inst, _jit_reg_info[nest_reg].cpu_reg, + X86_EBP, sizeof(void *)); + } + } + +JIT_OP_SETUP_FOR_SIBLING: spill_before + [] -> { + jit_nint level = jit_value_get_nint_constant(insn->value1); + jit_nint nest_reg = jit_value_get_nint_constant(insn->value2); + int cpu_reg; + if(nest_reg == -1) + { + cpu_reg = X86_EAX; + } + else + { + cpu_reg = _jit_reg_info[nest_reg].cpu_reg; + } + x86_mov_reg_membase(inst, cpu_reg, X86_EBP, 0, sizeof(void *)); + while(level > 0) + { + gen->posn.ptr = inst; + if(!jit_cache_check_for_n(&(gen->posn), 16)) + { + jit_cache_mark_full(&(gen->posn)); + return; + } + x86_mov_reg_membase(inst, cpu_reg, cpu_reg, 0, sizeof(void *)); + --level; + } + if(nest_reg == -1) + { + x86_push_reg(inst, cpu_reg); + } + } + +JIT_OP_IMPORT: + [] -> { + /* TODO */ + }