From 2cbc27913eb9eb7cdc4a41fc6efafccf3db7ebe6 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Fri, 21 Sep 2012 11:00:23 -0700 Subject: [PATCH] tcg-sparc: Preserve branch destinations during retranslation Signed-off-by: Richard Henderson Signed-off-by: Michael Roth --- tcg/sparc/tcg-target.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c index 1db0c9d..876da4f 100644 --- a/tcg/sparc/tcg-target.c +++ b/tcg/sparc/tcg-target.c @@ -488,30 +488,33 @@ static inline void tcg_out_nop(TCGContext *s) static void tcg_out_branch_i32(TCGContext *s, int opc, int label_index) { TCGLabel *l = &s->labels[label_index]; + uint32_t off22; if (l->has_value) { - tcg_out32(s, (INSN_OP(0) | INSN_COND(opc, 0) | INSN_OP2(0x2) - | INSN_OFF22(l->u.value - (unsigned long)s->code_ptr))); + off22 = INSN_OFF22(l->u.value - (unsigned long)s->code_ptr); } else { + /* Make sure to preserve destinations during retranslation. */ + off22 = *(uint32_t *)s->code_ptr & INSN_OFF22(-1); tcg_out_reloc(s, s->code_ptr, R_SPARC_WDISP22, label_index, 0); - tcg_out32(s, (INSN_OP(0) | INSN_COND(opc, 0) | INSN_OP2(0x2) | 0)); } + tcg_out32(s, INSN_OP(0) | INSN_COND(opc, 0) | INSN_OP2(0x2) | off22); } #if TCG_TARGET_REG_BITS == 64 static void tcg_out_branch_i64(TCGContext *s, int opc, int label_index) { TCGLabel *l = &s->labels[label_index]; + uint32_t off19; if (l->has_value) { - tcg_out32(s, (INSN_OP(0) | INSN_COND(opc, 0) | INSN_OP2(0x1) | - (0x5 << 19) | - INSN_OFF19(l->u.value - (unsigned long)s->code_ptr))); + off19 = INSN_OFF19(l->u.value - (unsigned long)s->code_ptr); } else { + /* Make sure to preserve destinations during retranslation. */ + off19 = *(uint32_t *)s->code_ptr & INSN_OFF19(-1); tcg_out_reloc(s, s->code_ptr, R_SPARC_WDISP19, label_index, 0); - tcg_out32(s, (INSN_OP(0) | INSN_COND(opc, 0) | INSN_OP2(0x1) | - (0x5 << 19) | 0)); } + tcg_out32(s, (INSN_OP(0) | INSN_COND(opc, 0) | INSN_OP2(0x1) | + (0x5 << 19) | off19)); } #endif -- 1.7.12.1