diff options
Diffstat (limited to 'tcg/arm/tcg-target.c')
-rw-r--r-- | tcg/arm/tcg-target.c | 72 |
1 files changed, 47 insertions, 25 deletions
diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c index dee1ebc..8139da1 100644 --- a/tcg/arm/tcg-target.c +++ b/tcg/arm/tcg-target.c @@ -21,7 +21,9 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -const char *tcg_target_reg_names[TCG_TARGET_NB_REGS] = { + +#ifndef NDEBUG +static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = { "%r0", "%r1", "%r2", @@ -38,8 +40,9 @@ const char *tcg_target_reg_names[TCG_TARGET_NB_REGS] = { "%r13", "%r14", }; +#endif -int tcg_target_reg_alloc_order[] = { +static const int tcg_target_reg_alloc_order[] = { TCG_REG_R0, TCG_REG_R1, TCG_REG_R2, @@ -57,10 +60,10 @@ int tcg_target_reg_alloc_order[] = { TCG_REG_R14, }; -const int tcg_target_call_iarg_regs[4] = { +static const int tcg_target_call_iarg_regs[4] = { TCG_REG_R0, TCG_REG_R1, TCG_REG_R2, TCG_REG_R3 }; -const int tcg_target_call_oarg_regs[2] = { +static const int tcg_target_call_oarg_regs[2] = { TCG_REG_R0, TCG_REG_R1 }; @@ -91,7 +94,7 @@ static inline int tcg_target_get_call_iarg_regs_count(int flags) } /* parse target specific constraints */ -int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str) +static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str) { const char *ct_str; @@ -292,10 +295,19 @@ static inline void tcg_out_dat_reg2(TCGContext *s, int cond, int opc0, int opc1, int rd0, int rd1, int rn0, int rn1, int rm0, int rm1, int shift) { - tcg_out32(s, (cond << 28) | (0 << 25) | (opc0 << 21) | (1 << 20) | - (rn0 << 16) | (rd0 << 12) | shift | rm0); - tcg_out32(s, (cond << 28) | (0 << 25) | (opc1 << 21) | - (rn1 << 16) | (rd1 << 12) | shift | rm1); + if (rd0 == rn1 || rd0 == rm1) { + tcg_out32(s, (cond << 28) | (0 << 25) | (opc0 << 21) | (1 << 20) | + (rn0 << 16) | (8 << 12) | shift | rm0); + tcg_out32(s, (cond << 28) | (0 << 25) | (opc1 << 21) | + (rn1 << 16) | (rd1 << 12) | shift | rm1); + tcg_out_dat_reg(s, cond, ARITH_MOV, + rd0, 0, TCG_REG_R8, SHIFT_IMM_LSL(0)); + } else { + tcg_out32(s, (cond << 28) | (0 << 25) | (opc0 << 21) | (1 << 20) | + (rn0 << 16) | (rd0 << 12) | shift | rm0); + tcg_out32(s, (cond << 28) | (0 << 25) | (opc1 << 21) | + (rn1 << 16) | (rd1 << 12) | shift | rm1); + } } static inline void tcg_out_dat_imm(TCGContext *s, @@ -846,10 +858,10 @@ static inline void tcg_out_qemu_ld(TCGContext *s, int cond, else data_reg2 = 0; /* surpress warning */ addr_reg = *args++; -#if TARGET_LONG_BITS == 64 - addr_reg2 = *args++; -#endif #ifdef CONFIG_SOFTMMU +# if TARGET_LONG_BITS == 64 + addr_reg2 = *args++; +# endif mem_index = *args; s_bits = opc & 3; @@ -999,8 +1011,13 @@ static inline void tcg_out_qemu_ld(TCGContext *s, int cond, case 3: /* TODO: use block load - * check that data_reg2 > data_reg or the other way */ - tcg_out_ld32_12(s, COND_AL, data_reg, addr_reg, 0); - tcg_out_ld32_12(s, COND_AL, data_reg2, addr_reg, 4); + if (data_reg == addr_reg) { + tcg_out_ld32_12(s, COND_AL, data_reg2, addr_reg, 4); + tcg_out_ld32_12(s, COND_AL, data_reg, addr_reg, 0); + } else { + tcg_out_ld32_12(s, COND_AL, data_reg, addr_reg, 0); + tcg_out_ld32_12(s, COND_AL, data_reg2, addr_reg, 4); + } break; } #endif @@ -1024,10 +1041,10 @@ static inline void tcg_out_qemu_st(TCGContext *s, int cond, else data_reg2 = 0; /* surpress warning */ addr_reg = *args++; -#if TARGET_LONG_BITS == 64 - addr_reg2 = *args++; -#endif #ifdef CONFIG_SOFTMMU +# if TARGET_LONG_BITS == 64 + addr_reg2 = *args++; +# endif mem_index = *args; s_bits = opc & 3; @@ -1229,19 +1246,24 @@ static inline void tcg_out_op(TCGContext *s, int opc, if (args[0] >> 8) tcg_out32(s, args[0]); #else - if (args[0] >> 8) - tcg_out_ld32_12(s, COND_AL, 0, 15, 0); - else - tcg_out_dat_imm(s, COND_AL, ARITH_MOV, 0, 0, args[0]); - tcg_out_goto(s, COND_AL, (tcg_target_ulong) tb_ret_addr); - if (args[0] >> 8) - tcg_out32(s, args[0]); + { + uint8_t *ld_ptr = s->code_ptr; + if (args[0] >> 8) + tcg_out_ld32_12(s, COND_AL, 0, 15, 0); + else + tcg_out_dat_imm(s, COND_AL, ARITH_MOV, 0, 0, args[0]); + tcg_out_goto(s, COND_AL, (tcg_target_ulong) tb_ret_addr); + if (args[0] >> 8) { + *ld_ptr = (uint8_t) (s->code_ptr - ld_ptr) - 8; + tcg_out32(s, args[0]); + } + } #endif break; case INDEX_op_goto_tb: if (s->tb_jmp_offset) { /* Direct jump method */ -#if 1 +#if defined(USE_DIRECT_JUMP) s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf; tcg_out_b(s, COND_AL, 8); #else |