]> git.unchartedbackwaters.co.uk Git - francis/libjit.git/commitdiff
Add some more instructions to the ARM back end; split some x86
authorRhys Weatherley <rweather@southern-storm.com.au>
Sun, 6 Jun 2004 04:53:08 +0000 (04:53 +0000)
committerRhys Weatherley <rweather@southern-storm.com.au>
Sun, 6 Jun 2004 04:53:08 +0000 (04:53 +0000)
back end code out into common code for ARM to use as well.

ChangeLog
jit/jit-reg-alloc.c
jit/jit-reg-alloc.h
jit/jit-rules-arm.c
jit/jit-rules-arm.sel
jit/jit-rules-x86.c
jit/jit-rules-x86.sel

index b7c3d1363ed125e6e0813767951f5a9d5a323976..0f204ac2b5ba9a12f8ea32b5ee541866cf29ae43 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,11 @@
 
+2004-06-06  Rhys Weatherley  <rweather@southern-storm.com.au>
+
+       * jit/jit-reg-alloc.c, jit/jit-reg-alloc.h, jit/jit-rules-arm.c,
+       jit/jit-rules-arm.sel, jit/jit-rules-x86.c, jit/jit-rules-x86.sel:
+       add some more instructions to the ARM back end; split some x86
+       back end code out into common code for ARM to use as well.
+
 2004-06-02  Rhys Weatherley  <rweather@southern-storm.com.au>
 
        * jit/jit-function.c, jit/jit-insn.c, jit/jit-internal.h,
index 190c01b52aff5521ca60ef844f78f87d197b16f2..7fa88cadbd46c294c9659b3d7cfdeda1c28d79f5 100644 (file)
@@ -1468,3 +1468,51 @@ void _jit_regs_alloc_global(jit_gencode_t gen, jit_function_t func)
 
 #endif
 }
+
+/*
+ * @deftypefun void _jit_regs_get_reg_pair (jit_gencode_t gen, int not_this1, int not_this2, int not_this3, {int *} reg, {int *} reg2)
+ * Get a register pair for temporary operations on "long" values.
+ * @end deftypefun
+ */
+void _jit_regs_get_reg_pair(jit_gencode_t gen, int not_this1, int not_this2,
+                                                   int not_this3, int *reg, int *reg2)
+{
+       int index;
+       for(index = 0; index < 8; ++index)
+       {
+               if((_jit_reg_info[index].flags & JIT_REG_WORD) == 0 ||
+                  jit_reg_is_used(gen->permanent, index))
+               {
+                       continue;
+               }
+               if(index != not_this1 && index != not_this2 &&
+                  index != not_this3)
+               {
+                       break;
+               }
+       }
+       *reg = index;
+       _jit_regs_want_reg(gen, index, 0);
+       for(; index < 8; ++index)
+       {
+               if((_jit_reg_info[index].flags & JIT_REG_WORD) == 0 ||
+                  jit_reg_is_used(gen->permanent, index))
+               {
+                       continue;
+               }
+               if(index != not_this1 && index != not_this2 &&
+                  index != not_this3 && index != *reg)
+               {
+                       break;
+               }
+       }
+       if(index >= 8)
+       {
+               *reg2 = -1;
+       }
+       else
+       {
+               *reg2 = index;
+               _jit_regs_want_reg(gen, index, 0);
+       }
+}
index cc781bfd73107dbc8a0811f596be7d933a5a3e64..4ce0b02081e6812266505e172a246ef6a1e39f9d 100644 (file)
@@ -56,6 +56,8 @@ int _jit_regs_num_used(jit_gencode_t gen, int type_reg);
 int _jit_regs_new_top(jit_gencode_t gen, jit_value_t value, int type_reg);
 void _jit_regs_force_out(jit_gencode_t gen, jit_value_t value, int is_dest);
 void _jit_regs_alloc_global(jit_gencode_t gen, jit_function_t func);
+void _jit_regs_get_reg_pair(jit_gencode_t gen, int not_this1, int not_this2,
+                                                   int not_this3, int *reg, int *reg2);
 
 #ifdef __cplusplus
 };
index 63c08bce48180edec4b3cc2c87b6068321e92e01..4e6f2b12629d747a8e8b727e29ffc4131348d0d7 100644 (file)
@@ -26,6 +26,7 @@
 
 #include "jit-gen-arm.h"
 #include "jit-reg-alloc.h"
+#include "jit-setjmp.h"
 #include <stdio.h>
 
 /*
@@ -659,7 +660,155 @@ void _jit_gen_free_reg(jit_gencode_t gen, int reg,
 void _jit_gen_load_value
        (jit_gencode_t gen, int reg, int other_reg, jit_value_t value)
 {
-       /* TODO */
+       void *ptr;
+       int offset;
+
+       /* Make sure that we have sufficient space */
+       jit_cache_setup_output(16);
+
+       if(value->is_constant)
+       {
+               /* Determine the type of constant to be loaded */
+               switch(jit_type_normalize(value->type)->kind)
+               {
+                       case JIT_TYPE_SBYTE:
+                       case JIT_TYPE_UBYTE:
+                       case JIT_TYPE_SHORT:
+                       case JIT_TYPE_USHORT:
+                       case JIT_TYPE_INT:
+                       case JIT_TYPE_UINT:
+                       {
+                               arm_mov_reg_imm(inst, _jit_reg_info[reg].cpu_reg,
+                                                               (jit_nint)(value->address));
+                       }
+                       break;
+
+                       case JIT_TYPE_LONG:
+                       case JIT_TYPE_ULONG:
+                       {
+                               jit_long long_value;
+                               long_value = jit_value_get_long_constant(value);
+                               arm_mov_reg_imm(inst, _jit_reg_info[reg].cpu_reg,
+                                                               (jit_int)long_value);
+                               arm_mov_reg_imm(inst, _jit_reg_info[other_reg].cpu_reg,
+                                                               (jit_int)(long_value >> 32));
+                       }
+                       break;
+
+                       case JIT_TYPE_FLOAT32:
+                       {
+                               jit_float32 float32_value;
+                               float32_value = jit_value_get_float32_constant(value);
+                               if(!jit_cache_check_for_n(&(gen->posn), 32))
+                               {
+                                       jit_cache_mark_full(&(gen->posn));
+                                       return;
+                               }
+                               ptr = _jit_cache_alloc(&(gen->posn), sizeof(jit_float32));
+                               jit_memcpy(ptr, &float32_value, sizeof(float32_value));
+                               /* TODO */
+                               /*x86_fld(inst, ptr, 0);*/
+                       }
+                       break;
+
+                       case JIT_TYPE_FLOAT64:
+                       case JIT_TYPE_NFLOAT:
+                       {
+                               jit_float64 float64_value;
+                               float64_value = jit_value_get_float64_constant(value);
+                               if(!jit_cache_check_for_n(&(gen->posn), 32))
+                               {
+                                       jit_cache_mark_full(&(gen->posn));
+                                       return;
+                               }
+                               ptr = _jit_cache_alloc(&(gen->posn), sizeof(jit_float64));
+                               jit_memcpy(ptr, &float64_value, sizeof(float64_value));
+                               /* TODO */
+                               /*x86_fld(inst, ptr, 1);*/
+                       }
+                       break;
+               }
+       }
+       else if(value->has_global_register)
+       {
+               /* Load the value out of a global register */
+               arm_mov_reg_reg(inst, _jit_reg_info[reg].cpu_reg,
+                                               _jit_reg_info[value->global_reg].cpu_reg);
+       }
+       else
+       {
+               /* Fix the position of the value in the stack frame */
+               _jit_gen_fix_value(value);
+               offset = (int)(value->frame_offset);
+
+               /* Load the value into the specified register */
+               switch(jit_type_normalize(value->type)->kind)
+               {
+                       case JIT_TYPE_SBYTE:
+                       {
+                               arm_load_membase_sbyte(inst, _jit_reg_info[reg].cpu_reg,
+                                                                      ARM_FP, offset);
+                       }
+                       break;
+
+                       case JIT_TYPE_UBYTE:
+                       {
+                               arm_load_membase_byte(inst, _jit_reg_info[reg].cpu_reg,
+                                                                     ARM_FP, offset);
+                       }
+                       break;
+
+                       case JIT_TYPE_SHORT:
+                       {
+                               arm_load_membase_short(inst, _jit_reg_info[reg].cpu_reg,
+                                                                      ARM_FP, offset);
+                       }
+                       break;
+
+                       case JIT_TYPE_USHORT:
+                       {
+                               arm_load_membase_ushort(inst, _jit_reg_info[reg].cpu_reg,
+                                                                       ARM_FP, offset);
+                       }
+                       break;
+
+                       case JIT_TYPE_INT:
+                       case JIT_TYPE_UINT:
+                       {
+                               arm_load_membase(inst, _jit_reg_info[reg].cpu_reg,
+                                                                ARM_FP, offset);
+                       }
+                       break;
+
+                       case JIT_TYPE_LONG:
+                       case JIT_TYPE_ULONG:
+                       {
+                               arm_load_membase(inst, _jit_reg_info[reg].cpu_reg,
+                                                                ARM_FP, offset);
+                               arm_load_membase(inst, _jit_reg_info[other_reg].cpu_reg,
+                                                                ARM_FP, offset + 4);
+                       }
+                       break;
+
+                       case JIT_TYPE_FLOAT32:
+                       {
+                               /* TODO */
+                               /*x86_fld_membase(inst, X86_EBP, offset, 0);*/
+                       }
+                       break;
+
+                       case JIT_TYPE_FLOAT64:
+                       case JIT_TYPE_NFLOAT:
+                       {
+                               /* TODO */
+                               /*x86_fld_membase(inst, X86_EBP, offset, 1);*/
+                       }
+                       break;
+               }
+       }
+
+       /* End the code output process */
+       jit_cache_end_output();
 }
 
 void _jit_gen_fix_value(jit_value_t value)
@@ -715,24 +864,31 @@ static arm_inst_ptr output_branch
 static arm_inst_ptr throw_builtin
                (arm_inst_ptr inst, jit_function_t func, int cond, int type)
 {
-#if 0
-       /* TODO: port to ARM */
+       arm_inst_ptr patch;
+
+       /* Branch past the following code if "cond" is not true */
+       patch = inst;
+       arm_branch_imm(inst, cond ^ 0x01, 0);
+
        /* We need to update "catch_pc" if we have a "try" block */
        if(func->builder->setjmp_value != 0)
        {
                _jit_gen_fix_value(func->builder->setjmp_value);
-               x86_call_imm(inst, 0);
-               x86_pop_membase(inst, X86_EBP,
-                                               func->builder->setjmp_value->frame_offset +
-                                               jit_jmp_catch_pc_offset);
+               arm_mov_reg_reg(inst, ARM_WORK, ARM_PC);
+               arm_store_membase(inst, ARM_WORK, ARM_FP,
+                                                 func->builder->setjmp_value->frame_offset +
+                                                 jit_jmp_catch_pc_offset);
        }
 
        /* Push the exception type onto the stack */
-       x86_push_imm(inst, type);
+       arm_mov_reg_imm(inst, ARM_WORK, type);
+       arm_push_reg(inst, ARM_WORK);
 
        /* Call the "jit_exception_builtin" function, which will never return */
-       x86_call_code(inst, jit_exception_builtin);
-#endif
+       arm_call(inst, jit_exception_builtin);
+
+       /* Back-patch the previous branch instruction */
+       arm_patch(patch, inst);
        return inst;
 }
 
index 0fab535401599be568a6a300d8b0202809087626..b70b8e98be975e103f1b970967f42a0ce38894c8 100644 (file)
@@ -582,7 +582,7 @@ JIT_OP_RETURN_NFLOAT: manual
 
 JIT_OP_RETURN_SMALL_STRUCT: spill_before
        [] -> {
-               /* TODO: load the structure value into EAX:EDX */
+               /* TODO: load the structure value into r0:r1 */
                TODO();
                inst = jump_to_epilog(gen, inst, block);
        }
@@ -638,3 +638,452 @@ JIT_OP_IMPORT:
                TODO();
        }
 
+/*
+ * Data manipulation.
+ */
+
+JIT_OP_COPY_LOAD_SBYTE: unary
+       [reg] -> {}
+
+JIT_OP_COPY_LOAD_UBYTE: unary
+       [reg] -> {}
+
+JIT_OP_COPY_LOAD_SHORT: unary
+       [reg] -> {}
+
+JIT_OP_COPY_LOAD_USHORT: unary
+       [reg] -> {}
+
+JIT_OP_COPY_INT: unary
+       [reg] -> {}
+
+JIT_OP_COPY_LONG: spill_before
+       [] -> {
+               /* TODO */
+               TODO();
+       }
+
+JIT_OP_COPY_FLOAT32: manual
+       [] -> {
+               /* TODO */
+               TODO();
+       }
+
+JIT_OP_COPY_FLOAT64: manual
+       [] -> {
+               /* TODO */
+               TODO();
+       }
+
+JIT_OP_COPY_NFLOAT: manual
+       [] -> {
+               /* TODO */
+               TODO();
+       }
+
+JIT_OP_COPY_STRUCT: manual
+       [] -> {
+               /* TODO */
+               TODO();
+       }
+
+JIT_OP_COPY_STORE_BYTE: manual
+       [] -> {
+               arm_inst_ptr inst;
+               int reg;
+               _jit_regs_force_out(gen, insn->dest, 1);
+               _jit_gen_fix_value(insn->dest);
+               reg = _jit_regs_load_value
+                       (gen, insn->value1, 0,
+                        (insn->flags & (JIT_INSN_VALUE1_NEXT_USE |
+                                                        JIT_INSN_VALUE1_LIVE)));
+               inst = (arm_inst_ptr)(gen->posn.ptr);
+               if(!jit_cache_check_for_n(&(gen->posn), 32))
+               {
+                       jit_cache_mark_full(&(gen->posn));
+                       return;
+               }
+               arm_store_membase_byte(inst, _jit_reg_info[reg].cpu_reg,
+                                                          ARM_FP, insn->dest->frame_offset);
+               gen->posn.ptr = (unsigned char *)inst;
+       }
+
+JIT_OP_COPY_STORE_SHORT: manual
+       [] -> {
+               arm_inst_ptr inst;
+               int reg;
+               _jit_regs_force_out(gen, insn->dest, 1);
+               _jit_gen_fix_value(insn->dest);
+               reg = _jit_regs_load_value
+                       (gen, insn->value1, 1,
+                        (insn->flags & (JIT_INSN_VALUE1_NEXT_USE |
+                                                        JIT_INSN_VALUE1_LIVE)));
+               inst = (arm_inst_ptr)(gen->posn.ptr);
+               if(!jit_cache_check_for_n(&(gen->posn), 32))
+               {
+                       jit_cache_mark_full(&(gen->posn));
+                       return;
+               }
+               arm_store_membase_short(inst, _jit_reg_info[reg].cpu_reg,
+                                                           ARM_FP, insn->dest->frame_offset);
+               gen->posn.ptr = (unsigned char *)inst;
+               _jit_regs_free_reg(gen, reg, 1);
+       }
+
+JIT_OP_ADDRESS_OF: manual
+       [] -> {
+               arm_inst_ptr inst;
+               int reg, offset;
+               _jit_regs_force_out(gen, insn->value1, 0);
+               _jit_gen_fix_value(insn->value1);
+               inst = (arm_inst_ptr)(gen->posn.ptr);
+               if(!jit_cache_check_for_n(&(gen->posn), 32))
+               {
+                       jit_cache_mark_full(&(gen->posn));
+                       return;
+               }
+               reg = _jit_regs_dest_value(gen, insn->dest);
+               reg = _jit_reg_info[reg].cpu_reg;
+               offset = insn->value1->frame_offset;
+               if(offset > 0)
+               {
+                       arm_alu_reg_imm(inst, ARM_ADD, reg, ARM_FP, offset);
+               }
+               else if(offset < 0)
+               {
+                       arm_alu_reg_imm(inst, ARM_SUB, reg, ARM_FP, -offset);
+               }
+               else
+               {
+                       arm_mov_reg_reg(inst, reg, ARM_FP);
+               }
+               gen->posn.ptr = (unsigned char *)inst;
+       }
+
+/*
+ * Stack pushes and pops.
+ */
+
+JIT_OP_RETURN_REG: manual
+       [] -> { /* Nothing to do here */ }
+
+JIT_OP_PUSH_INT: unary_note
+       [reg] -> {
+               arm_push_reg(inst, $1);
+       }
+
+JIT_OP_PUSH_LONG: manual
+       [] -> {
+               /* TODO */
+               TODO();
+       }
+
+JIT_OP_PUSH_FLOAT32: manual
+       [] -> {
+               /* TODO */
+               TODO();
+       }
+
+JIT_OP_PUSH_FLOAT64: manual
+       [] -> {
+               /* TODO */
+               TODO();
+       }
+
+JIT_OP_PUSH_NFLOAT: manual
+       [] -> {
+               /* TODO */
+               TODO();
+       }
+
+JIT_OP_PUSH_STRUCT: unary_note
+       [reg] -> {
+               /* TODO */
+               TODO();
+       }
+
+JIT_OP_POP_STACK:
+       [] -> {
+               arm_alu_reg_imm(inst, ARM_ADD, ARM_SP, ARM_SP, insn->value1->address);
+       }
+
+JIT_OP_FLUSH_SMALL_STRUCT:
+       [] -> {
+               jit_nuint size;
+               jit_nint offset;
+               _jit_gen_fix_value(insn->value1);
+               size = jit_type_get_size(jit_value_get_type(insn->value1));
+               offset = insn->value1->frame_offset;
+               switch(size)
+               {
+                       case 1:
+                       {
+                               arm_store_membase_byte(inst, ARM_R0, ARM_FP, offset);
+                       }
+                       break;
+
+                       case 2:
+                       {
+                               arm_store_membase_short(inst, ARM_R0, ARM_FP, offset);
+                       }
+                       break;
+
+                       case 3:
+                       {
+                               arm_mov_reg_reg(inst, ARM_R1, ARM_R0);
+                               arm_store_membase_short(inst, ARM_R0, ARM_FP, offset);
+                               arm_shift_reg_imm8(inst, ARM_SHR, ARM_R0, ARM_R1, 16);
+                               arm_store_membase_byte(inst, ARM_R0, ARM_FP, offset + 2);
+                       }
+                       break;
+
+                       case 4:
+                       {
+                               arm_store_membase(inst, ARM_R0, ARM_FP, offset);
+                       }
+                       break;
+
+                       case 5:
+                       {
+                               arm_store_membase(inst, ARM_R0, ARM_FP, offset);
+                               arm_store_membase_byte(inst, ARM_R1, ARM_FP, offset + 4);
+                       }
+                       break;
+
+                       case 6:
+                       {
+                               arm_store_membase(inst, ARM_R0, ARM_FP, offset);
+                               arm_store_membase_short(inst, ARM_R1, ARM_FP, offset + 4);
+                       }
+                       break;
+
+                       case 7:
+                       {
+                               arm_store_membase(inst, ARM_R0, ARM_FP, offset);
+                               arm_mov_reg_reg(inst, ARM_R2, ARM_R1);
+                               arm_store_membase_short(inst, ARM_R1, ARM_FP, offset + 4);
+                               arm_shift_reg_imm8(inst, ARM_SHR, ARM_R1, ARM_R2, 16);
+                               arm_store_membase_byte(inst, ARM_R1, ARM_FP, offset + 6);
+                       }
+                       break;
+
+                       case 8:
+                       {
+                               arm_store_membase(inst, ARM_R0, ARM_FP, offset);
+                               arm_store_membase(inst, ARM_R1, ARM_FP, offset + 4);
+                       }
+                       break;
+               }
+       }
+
+/*
+ * Pointer-relative loads and stores.
+ */
+
+JIT_OP_LOAD_RELATIVE_SBYTE: unary
+       [reg] -> {
+               arm_load_membase_sbyte(inst, $1, $1, insn->value2->address);
+       }
+
+JIT_OP_LOAD_RELATIVE_UBYTE: unary
+       [reg] -> {
+               arm_load_membase_byte(inst, $1, $1, insn->value2->address);
+       }
+
+JIT_OP_LOAD_RELATIVE_SHORT: unary
+       [reg] -> {
+               arm_load_membase_short(inst, $1, $1, insn->value2->address);
+       }
+
+JIT_OP_LOAD_RELATIVE_USHORT: unary
+       [reg] -> {
+               arm_load_membase_ushort(inst, $1, $1, insn->value2->address);
+       }
+
+JIT_OP_LOAD_RELATIVE_INT: unary
+       [reg] -> {
+               arm_load_membase(inst, $1, $1, insn->value2->address);
+       }
+
+JIT_OP_LOAD_RELATIVE_LONG: manual
+       [] -> {
+               arm_inst_ptr inst;
+               int reg = _jit_regs_load_value
+                       (gen, insn->value1, 0,
+                        (insn->flags & (JIT_INSN_VALUE1_NEXT_USE |
+                                                        JIT_INSN_VALUE1_LIVE)));
+               int reg2, reg3;
+               int frame_offset;
+               _jit_gen_fix_value(insn->dest);
+               _jit_regs_get_reg_pair(gen, reg, -1, -1, &reg2, &reg3);
+               reg  = _jit_reg_info[reg].cpu_reg;
+               reg2 = _jit_reg_info[reg2].cpu_reg;
+               reg3 = _jit_reg_info[reg3].cpu_reg;
+               frame_offset = insn->dest->frame_offset;
+               inst = (arm_inst_ptr)(gen->posn.ptr);
+               if(!jit_cache_check_for_n(&(gen->posn), 32))
+               {
+                       jit_cache_mark_full(&(gen->posn));
+                       return;
+               }
+               arm_load_membase(inst, reg2, reg, insn->value2->address);
+               arm_load_membase(inst, reg3, reg, insn->value2->address + 4);
+               arm_store_membase(inst, reg2, ARM_FP, frame_offset);
+               arm_store_membase(inst, reg3, ARM_FP, frame_offset + 4);
+               insn->dest->in_frame = 1;
+               gen->posn.ptr = (unsigned char *)inst;
+       }
+
+JIT_OP_LOAD_RELATIVE_FLOAT32: manual
+       [] -> {
+               /* TODO */
+               TODO();
+       }
+
+JIT_OP_LOAD_RELATIVE_FLOAT64: manual
+       [] -> {
+               /* TODO */
+               TODO();
+       }
+
+JIT_OP_LOAD_RELATIVE_NFLOAT: manual
+       [] -> {
+               /* TODO */
+               TODO();
+       }
+
+JIT_OP_LOAD_RELATIVE_STRUCT: manual
+       [] -> {
+               /* TODO */
+               TODO();
+       }
+
+JIT_OP_STORE_RELATIVE_BYTE: manual
+       [] -> {
+               arm_inst_ptr inst;
+               int reg = _jit_regs_load_value
+                       (gen, insn->dest, 0,
+                        (insn->flags & (JIT_INSN_DEST_NEXT_USE |
+                                                        JIT_INSN_DEST_LIVE)));
+               int reg2 = _jit_regs_load_value
+                       (gen, insn->value1, 0,
+                        (insn->flags & (JIT_INSN_VALUE1_NEXT_USE |
+                                                        JIT_INSN_VALUE1_LIVE)));
+               inst = (arm_inst_ptr)(gen->posn.ptr);
+               if(!jit_cache_check_for_n(&(gen->posn), 32))
+               {
+                       jit_cache_mark_full(&(gen->posn));
+                       return;
+               }
+               reg  = _jit_reg_info[reg].cpu_reg;
+               reg2 = _jit_reg_info[reg2].cpu_reg;
+               arm_store_membase_byte(inst, reg2, reg, insn->value2->address);
+               gen->posn.ptr = (unsigned char *)inst;
+       }
+
+JIT_OP_STORE_RELATIVE_SHORT: manual
+       [] -> {
+               arm_inst_ptr inst;
+               int reg = _jit_regs_load_value
+                       (gen, insn->dest, 0,
+                        (insn->flags & (JIT_INSN_DEST_NEXT_USE |
+                                                        JIT_INSN_DEST_LIVE)));
+               int reg2 = _jit_regs_load_value
+                       (gen, insn->value1, 1,
+                        (insn->flags & (JIT_INSN_VALUE1_NEXT_USE |
+                                                        JIT_INSN_VALUE1_LIVE)));
+               inst = (arm_inst_ptr)(gen->posn.ptr);
+               if(!jit_cache_check_for_n(&(gen->posn), 32))
+               {
+                       jit_cache_mark_full(&(gen->posn));
+                       return;
+               }
+               reg  = _jit_reg_info[reg].cpu_reg;
+               reg2 = _jit_reg_info[reg2].cpu_reg;
+               arm_store_membase_short(inst, reg2, reg, insn->value2->address);
+               gen->posn.ptr = (unsigned char *)inst;
+               _jit_regs_free_reg(gen, reg2, 1);
+       }
+
+JIT_OP_STORE_RELATIVE_INT: manual
+       [] -> {
+               arm_inst_ptr inst;
+               int reg = _jit_regs_load_value
+                       (gen, insn->dest, 0,
+                        (insn->flags & (JIT_INSN_DEST_NEXT_USE |
+                                                        JIT_INSN_DEST_LIVE)));
+               int reg2 = _jit_regs_load_value
+                       (gen, insn->value1, 0,
+                        (insn->flags & (JIT_INSN_VALUE1_NEXT_USE |
+                                                        JIT_INSN_VALUE1_LIVE)));
+               inst = (arm_inst_ptr)(gen->posn.ptr);
+               if(!jit_cache_check_for_n(&(gen->posn), 32))
+               {
+                       jit_cache_mark_full(&(gen->posn));
+                       return;
+               }
+               reg  = _jit_reg_info[reg].cpu_reg;
+               reg2 = _jit_reg_info[reg2].cpu_reg;
+               arm_store_membase(inst, reg2, reg, insn->value2->address);
+               gen->posn.ptr = (unsigned char *)inst;
+       }
+
+JIT_OP_STORE_RELATIVE_LONG: manual
+       [] -> {
+               arm_inst_ptr inst;
+               int reg = _jit_regs_load_value
+                       (gen, insn->dest, 0,
+                        (insn->flags & (JIT_INSN_DEST_NEXT_USE |
+                                                        JIT_INSN_DEST_LIVE)));
+               int reg2, reg3;
+               int frame_offset;
+               _jit_regs_get_reg_pair(gen, reg, -1, -1, &reg2, &reg3);
+               _jit_gen_fix_value(insn->value1);
+               inst = (arm_inst_ptr)(gen->posn.ptr);
+               if(!jit_cache_check_for_n(&(gen->posn), 32))
+               {
+                       jit_cache_mark_full(&(gen->posn));
+                       return;
+               }
+               reg  = _jit_reg_info[reg].cpu_reg;
+               reg2 = _jit_reg_info[reg2].cpu_reg;
+               reg3 = _jit_reg_info[reg3].cpu_reg;
+               frame_offset = insn->value1->frame_offset;
+               arm_load_membase(inst, reg2, ARM_FP, frame_offset);
+               arm_load_membase(inst, reg3, ARM_FP, frame_offset + 4);
+               arm_store_membase(inst, reg2, reg, insn->value2->address);
+               arm_store_membase(inst, reg3, reg, insn->value2->address + 4);
+               gen->posn.ptr = (unsigned char *)inst;
+       }
+
+JIT_OP_STORE_RELATIVE_FLOAT32: manual
+       [] -> {
+               /* TODO */
+               TODO();
+       }
+
+JIT_OP_STORE_RELATIVE_FLOAT64: manual
+       [] -> {
+               /* TODO */
+               TODO();
+       }
+
+JIT_OP_STORE_RELATIVE_NFLOAT: manual
+       [] -> {
+               /* TODO */
+               TODO();
+       }
+
+JIT_OP_STORE_RELATIVE_STRUCT: manual
+       [] -> {
+               /* TODO */
+               TODO();
+       }
+
+JIT_OP_ADD_RELATIVE: unary
+       [reg] -> {
+               if(insn->value2->address != 0)
+               {
+                       arm_alu_reg_imm(inst, ARM_ADD, $1, $1, insn->value2->address);
+               }
+       }
index 86d33e0b4ce515c9d8ed67d9be451438bae0823e..9de63bd31ede3aea9eb8d3c53d9595fa0bf2db31 100644 (file)
@@ -1353,52 +1353,6 @@ static unsigned char *jump_to_epilog
        return inst;
 }
 
-/*
- * Get a register pair for temporary operations on "long" values.
- */
-static void get_reg_pair(jit_gencode_t gen, int not_this1, int not_this2,
-                                                int not_this3, int *reg, int *reg2)
-{
-       int index;
-       for(index = 0; index < 8; ++index)
-       {
-               if((_jit_reg_info[index].flags & JIT_REG_WORD) == 0 ||
-                  jit_reg_is_used(gen->permanent, index))
-               {
-                       continue;
-               }
-               if(index != not_this1 && index != not_this2 &&
-                  index != not_this3)
-               {
-                       break;
-               }
-       }
-       *reg = index;
-       _jit_regs_want_reg(gen, index, 0);
-       for(; index < 8; ++index)
-       {
-               if((_jit_reg_info[index].flags & JIT_REG_WORD) == 0 ||
-                  jit_reg_is_used(gen->permanent, index))
-               {
-                       continue;
-               }
-               if(index != not_this1 && index != not_this2 &&
-                  index != not_this3 && index != *reg)
-               {
-                       break;
-               }
-       }
-       if(index >= 8)
-       {
-               *reg2 = -1;
-       }
-       else
-       {
-               *reg2 = index;
-               _jit_regs_want_reg(gen, index, 0);
-       }
-}
-
 /*
  * Store a byte value to a membase address.
  */
index b6b38c772760c8ce5362ee5e23db083dcc652e8c..d00602cc9f07d003ab45159dfcea15696358ac19 100644 (file)
@@ -1911,7 +1911,7 @@ JIT_OP_LOAD_RELATIVE_LONG: manual
                int reg2, reg3;
                int frame_offset;
                _jit_gen_fix_value(insn->dest);
-               get_reg_pair(gen, reg, -1, -1, &reg2, &reg3);
+               _jit_regs_get_reg_pair(gen, reg, -1, -1, &reg2, &reg3);
                reg  = _jit_reg_info[reg].cpu_reg;
                reg2 = _jit_reg_info[reg2].cpu_reg;
                reg3 = _jit_reg_info[reg3].cpu_reg;
@@ -2129,7 +2129,7 @@ JIT_OP_STORE_RELATIVE_LONG: manual
                int frame_offset;
                if(!(insn->value1->is_constant))
                {
-                       get_reg_pair(gen, reg, -1, -1, &reg2, &reg3);
+                       _jit_regs_get_reg_pair(gen, reg, -1, -1, &reg2, &reg3);
                        _jit_gen_fix_value(insn->value1);
                        inst = gen->posn.ptr;
                        if(!jit_cache_check_for_n(&(gen->posn), 32))