From ab7fe0a04a2a166b841cf356774af47cb4a3e90b Mon Sep 17 00:00:00 2001 From: Aleksey Demakov Date: Fri, 24 Apr 2009 13:35:17 +0000 Subject: [PATCH] ARM backend fixes --- ChangeLog | 5 ++ jit/jit-gen-arm.h | 4 +- jit/jit-rules-arm.c | 168 ++++++++++++++++++++++++++++++++++---------- 3 files changed, 138 insertions(+), 39 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3691eb0..5ce0bc6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2009-04-24 Michele Tartara + + * jit/jit-gen-arm.h (arm_mov_reg_float): fix typo. + * jit/jit-rules-arm.c (_jit_gen_load_value): fix load logic. + 2009-04-22 Aleksey Demakov * jit/jit-insn.c (jit_insn_call, jit_insn_call_indirect) diff --git a/jit/jit-gen-arm.h b/jit/jit-gen-arm.h index 9a14b86..0f3580d 100644 --- a/jit/jit-gen-arm.h +++ b/jit/jit-gen-arm.h @@ -1671,8 +1671,8 @@ do { \ */ #define arm_mov_reg_float(inst,dreg,sreg) \ do { \ - char sreg_top_4_bits = (dreg & 0x1E) >> 1; \ - char sreg_bottom_bit = (dreg & 0x01); \ + char sreg_top_4_bits = (sreg & 0x1E) >> 1; \ + char sreg_bottom_bit = (sreg & 0x01); \ arm_inst_add((inst), arm_prefix(0x0E100A10) | \ (((unsigned int)(dreg)) << 12) | \ (((unsigned int)(sreg_top_4_bits)) << 16) | \ diff --git a/jit/jit-rules-arm.c b/jit/jit-rules-arm.c index 46af7b4..748a50a 100644 --- a/jit/jit-rules-arm.c +++ b/jit/jit-rules-arm.c @@ -31,6 +31,7 @@ #include "jit-reg-alloc.h" #include "jit-setjmp.h" #include +#include /* * Pseudo register numbers for the ARM registers. These are not the @@ -144,7 +145,7 @@ static _jit_regclass_t *arm_lreg; * Get a temporary register that isn't one of the specified registers. * When this function is used EVERY REGISTER COULD BE DESTROYED!!! * TODO: this function is only used by JIT_OP_STORE_RELATIVE_STRUCT, through memory_copy: remove - * the need of using it by sustituting it with register allocation with [scratch reg] + * the need of using it by substituting it with register allocation with [scratch reg] */ static int get_temp_reg(int reg1, int reg2, int reg3) { @@ -988,6 +989,9 @@ void _jit_gen_free_reg(jit_gencode_t gen, int reg, /* We don't have to do anything to free ARM registers */ } +/* + * Loads the content of the value @var{value} into register @var{reg} and (if needed) @var{other_reg} + */ void _jit_gen_load_value (jit_gencode_t gen, int reg, int other_reg, jit_value_t value) { @@ -1072,34 +1076,14 @@ void _jit_gen_load_value break; } } - else if(value->has_global_register) + else if(value->in_global_register) { - /* - * This value has been assinged a global register. This means - * that it can use that register, but not necessarily that it's - * already in it!! - */ - - /* Ensure that the value is already in the global_register */ - if (!value->in_global_register) - { - /* Find the other register in a long pair */ - int reg = value->reg; - int other_reg = jit_reg_current_other_reg(gen,reg); - - //Spill to the global register - _jit_gen_spill_reg(gen, reg, other_reg, value); - value->in_global_register=1; - - /* A new instruction has probably been generated by _jit_gen_spill_reg: reload the inst pointer */ - jit_gen_load_inst_ptr(gen, inst); - } /* Load the value out of a global register */ if(IS_FLOAT_REG(reg)) { /* Load into a floating point register */ #ifdef JIT_ARM_HAS_VFP - /* Vector floating point instructions */ + /* Vector Floating Point instructions */ if(jit_type_normalize(value->type)->kind == JIT_TYPE_FLOAT32) { arm_mov_float_reg(inst, @@ -1116,6 +1100,7 @@ void _jit_gen_load_value } #endif #ifdef JIT_ARM_HAS_FPA + /* Floating Point Architecture instructions */ TODO(); abort(); #endif @@ -1128,26 +1113,135 @@ void _jit_gen_load_value _jit_reg_info[value->global_reg].cpu_reg); } } + else if(value->in_register) + { + /* The value is already in another register. Move it */ + 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_reg(inst, jit_reg_code(reg), jit_reg_code(value->reg)); + } + break; + + case JIT_TYPE_LONG: + case JIT_TYPE_ULONG: + { + assert(jit_reg_code(other_reg) !=-1); + assert(jit_reg_other_reg(value->reg) != -1); + + arm_mov_reg_reg(inst, jit_reg_code(reg), jit_reg_code(value->reg)); + arm_mov_reg_reg(inst, jit_reg_code(other_reg), jit_reg_other_reg(value->reg)); + } + break; + + case JIT_TYPE_FLOAT32: + { +#ifdef JIT_ARM_HAS_VFP + /* Vector Floating Point instructions */ + if(IS_FLOAT_REG(reg)) + { + if(IS_WORD_REG(value->reg)) + { + arm_mov_float_reg(inst, + jit_reg_code(reg), + jit_reg_code(value->reg)); + } + else + { + arm_alu_freg_32(inst, ARM_MVF, + jit_reg_code(reg), + jit_reg_code(value->reg)); + } + } + else + { + if(IS_WORD_REG(value->reg)) + { + arm_mov_reg_reg(inst, + jit_reg_code(reg), + jit_reg_code(value->reg)); + } + else + { + arm_mov_reg_float(inst, + jit_reg_code(reg), + jit_reg_code(value->reg)); + } + } +#endif +#ifdef JIT_ARM_HAS_FPA + /* Floating Point Architecture instructions */ + TODO(); + abort(); +#endif + } + break; + + case JIT_TYPE_FLOAT64: + case JIT_TYPE_NFLOAT: + { +#ifdef JIT_ARM_HAS_VFP + /* Vector Floating Point instruction */ + if(IS_FLOAT_REG(reg)) + { + if(IS_WORD_REG(value->reg)) + { + assert(jit_reg_other_reg(value->reg) != -1); + + arm_mov_double_reg_reg(inst, + jit_reg_code(reg), + jit_reg_code(value->reg), + jit_reg_other_reg(value->reg)); + } + else + { + arm_alu_freg(inst, ARM_MVF, + jit_reg_code(reg), + jit_reg_code(value->reg)); + } + } + else + { + if(IS_WORD_REG(value->reg)) + { + arm_mov_reg_reg(inst, + jit_reg_code(reg), + jit_reg_code(value->reg)); + } + else + { + assert(jit_reg_other_reg(reg)); + arm_mov_reg_reg_double(inst, + jit_reg_code(reg), + jit_reg_other_reg(reg), + jit_reg_code(value->reg)); + } + } +#endif +#ifdef JIT_ARM_HAS_FPA + /* Floating Point Architecture instructions */ + TODO(); + abort(); +#endif + } + break; + } + } else { + /* Load from the stack */ + assert(!value->in_global_register && !value->is_constant && !value->in_register); + /* Fix the position of the value in the stack frame */ _jit_gen_fix_value(value); offset = (int)(value->frame_offset); - /* Ensure that the value is already in the stack frame */ - if(value->in_register) - { - /* Find the other register in a long pair */ - int reg = value->reg; - int other_reg = jit_reg_current_other_reg(gen,reg); - - _jit_gen_spill_reg(gen, reg, other_reg, value); - value->in_frame=1; - - /* A new instruction has probably been generated by _jit_gen_spill_reg: reload the inst pointer */ - jit_gen_load_inst_ptr(gen, inst); - } - switch(jit_type_normalize(value->type)->kind) { case JIT_TYPE_SBYTE: -- 2.47.3