aboutsummaryrefslogtreecommitdiff
path: root/tcg
diff options
context:
space:
mode:
authorAurelien Jarno <aurelien@aurel32.net>2010-03-29 02:09:23 +0200
committerAurelien Jarno <aurelien@aurel32.net>2010-03-29 02:11:35 +0200
commit81b168a702ce7dd6d6504436d6c1f129ee44183e (patch)
treefa3a5775b0c1bb48ebbebd01b5d50daa390fd402 /tcg
parent5c6892078a2a9d3919a5b99942c9f0132e34080d (diff)
tcg/mips: fix branch offset during retranslation
Branch offsets should only be overwritten during relocation, to support partial retranslation. Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> (cherry picked from commit 6d8ff4d85ce2f3fc8a18dc8f077f73a4bd19a89a)
Diffstat (limited to 'tcg')
-rw-r--r--tcg/mips/tcg-target.c49
1 files changed, 30 insertions, 19 deletions
diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c
index 807b8fdfae..3ed9217e33 100644
--- a/tcg/mips/tcg-target.c
+++ b/tcg/mips/tcg-target.c
@@ -340,6 +340,17 @@ static inline void tcg_out_opc_imm(TCGContext *s, int opc, int rt, int rs, int i
}
/*
+ * Type branch
+ */
+static inline void tcg_out_opc_br(TCGContext *s, int opc, int rt, int rs)
+{
+ /* We need to keep the offset unchanged for retranslation */
+ uint16_t offset = (uint16_t)(*(uint32_t *) &s->code_ptr);
+
+ tcg_out_opc_imm(s, opc, rt, rs, offset);
+}
+
+/*
* Type sa
*/
static inline void tcg_out_opc_sa(TCGContext *s, int opc, int rd, int rt, int sa)
@@ -469,42 +480,42 @@ static void tcg_out_brcond(TCGContext *s, int cond, int arg1,
switch (cond) {
case TCG_COND_EQ:
- tcg_out_opc_imm(s, OPC_BEQ, arg1, arg2, 0);
+ tcg_out_opc_br(s, OPC_BEQ, arg1, arg2);
break;
case TCG_COND_NE:
- tcg_out_opc_imm(s, OPC_BNE, arg1, arg2, 0);
+ tcg_out_opc_br(s, OPC_BNE, arg1, arg2);
break;
case TCG_COND_LT:
tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg1, arg2);
- tcg_out_opc_imm(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO, 0);
+ tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
break;
case TCG_COND_LTU:
tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, arg1, arg2);
- tcg_out_opc_imm(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO, 0);
+ tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
break;
case TCG_COND_GE:
tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg1, arg2);
- tcg_out_opc_imm(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO, 0);
+ tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
break;
case TCG_COND_GEU:
tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, arg1, arg2);
- tcg_out_opc_imm(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO, 0);
+ tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
break;
case TCG_COND_LE:
tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg2, arg1);
- tcg_out_opc_imm(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO, 0);
+ tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
break;
case TCG_COND_LEU:
tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, arg2, arg1);
- tcg_out_opc_imm(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO, 0);
+ tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
break;
case TCG_COND_GT:
tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg2, arg1);
- tcg_out_opc_imm(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO, 0);
+ tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
break;
case TCG_COND_GTU:
tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, arg2, arg1);
- tcg_out_opc_imm(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO, 0);
+ tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
break;
default:
tcg_abort();
@@ -553,7 +564,7 @@ static void tcg_out_brcond2(TCGContext *s, int cond, int arg1,
}
label_ptr = s->code_ptr;
- tcg_out_opc_imm(s, OPC_BNE, arg2, arg4, 0);
+ tcg_out_opc_br(s, OPC_BNE, arg2, arg4);
tcg_out_nop(s);
switch(cond) {
@@ -670,20 +681,20 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
# if TARGET_LONG_BITS == 64
label3_ptr = s->code_ptr;
- tcg_out_opc_imm(s, OPC_BNE, TCG_REG_T0, TCG_REG_AT, 0);
+ tcg_out_opc_br(s, OPC_BNE, TCG_REG_T0, TCG_REG_AT);
tcg_out_nop(s);
tcg_out_opc_imm(s, OPC_LW, TCG_REG_AT, TCG_REG_A0,
offsetof(CPUState, tlb_table[mem_index][0].addr_read) + addr_memh);
label1_ptr = s->code_ptr;
- tcg_out_opc_imm(s, OPC_BEQ, addr_regh, TCG_REG_AT, 0);
+ tcg_out_opc_br(s, OPC_BEQ, addr_regh, TCG_REG_AT);
tcg_out_nop(s);
reloc_pc16(label3_ptr, (tcg_target_long) s->code_ptr);
# else
label1_ptr = s->code_ptr;
- tcg_out_opc_imm(s, OPC_BEQ, TCG_REG_T0, TCG_REG_AT, 0);
+ tcg_out_opc_br(s, OPC_BEQ, TCG_REG_T0, TCG_REG_AT);
tcg_out_nop(s);
# endif
@@ -725,7 +736,7 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
}
label2_ptr = s->code_ptr;
- tcg_out_opc_imm(s, OPC_BEQ, TCG_REG_ZERO, TCG_REG_ZERO, 0);
+ tcg_out_opc_br(s, OPC_BEQ, TCG_REG_ZERO, TCG_REG_ZERO);
tcg_out_nop(s);
/* label1: fast path */
@@ -857,20 +868,20 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
# if TARGET_LONG_BITS == 64
label3_ptr = s->code_ptr;
- tcg_out_opc_imm(s, OPC_BNE, TCG_REG_T0, TCG_REG_AT, 0);
+ tcg_out_opc_br(s, OPC_BNE, TCG_REG_T0, TCG_REG_AT);
tcg_out_nop(s);
tcg_out_opc_imm(s, OPC_LW, TCG_REG_AT, TCG_REG_A0,
offsetof(CPUState, tlb_table[mem_index][0].addr_write) + addr_memh);
label1_ptr = s->code_ptr;
- tcg_out_opc_imm(s, OPC_BEQ, addr_regh, TCG_REG_AT, 0);
+ tcg_out_opc_br(s, OPC_BEQ, addr_regh, TCG_REG_AT);
tcg_out_nop(s);
reloc_pc16(label3_ptr, (tcg_target_long) s->code_ptr);
# else
label1_ptr = s->code_ptr;
- tcg_out_opc_imm(s, OPC_BEQ, TCG_REG_T0, TCG_REG_AT, 0);
+ tcg_out_opc_br(s, OPC_BEQ, TCG_REG_T0, TCG_REG_AT);
tcg_out_nop(s);
# endif
@@ -911,7 +922,7 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
tcg_out_nop(s);
label2_ptr = s->code_ptr;
- tcg_out_opc_imm(s, OPC_BEQ, TCG_REG_ZERO, TCG_REG_ZERO, 0);
+ tcg_out_opc_br(s, OPC_BEQ, TCG_REG_ZERO, TCG_REG_ZERO);
tcg_out_nop(s);
/* label1: fast path */