]> git.unchartedbackwaters.co.uk Git - francis/libjit.git/commitdiff
Selectors for call instructions.
authorRhys Weatherley <rweather@southern-storm.com.au>
Tue, 25 May 2004 10:24:10 +0000 (10:24 +0000)
committerRhys Weatherley <rweather@southern-storm.com.au>
Tue, 25 May 2004 10:24:10 +0000 (10:24 +0000)
ChangeLog
jit/jit-rules-x86.sel

index 3b1db139c30c6d4ff021e624952ec815783f445f..2806e5396f876f90f9336b673f3389f91dc785a7 100644 (file)
--- 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  <rweather@southern-storm.com.au>
 
        * include/jit/jit-insn.h, include/jit/jit-opcode.h, jit/jit-block.c,
index 22e358ad99b93a2722c6a43cb1134c178ab2b024..a3edaf389af3af7c7f0b2214e2f8fc078a837d4c 100644 (file)
@@ -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 */
+       }