From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([140.186.70.92]:42072) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QpiNj-00005L-E5 for qemu-devel@nongnu.org; Sat, 06 Aug 2011 11:01:48 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QpiNh-0003LI-VO for qemu-devel@nongnu.org; Sat, 06 Aug 2011 11:01:43 -0400 Received: from mail-fx0-f45.google.com ([209.85.161.45]:52033) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QpiNh-0003LA-P7 for qemu-devel@nongnu.org; Sat, 06 Aug 2011 11:01:41 -0400 Received: by fxbb27 with SMTP id b27so2439914fxb.4 for ; Sat, 06 Aug 2011 08:01:40 -0700 (PDT) From: Artyom Tarasenko Date: Sat, 6 Aug 2011 17:01:24 +0200 Message-Id: Subject: [Qemu-devel] [PATCH][SPARC] Fix handling of conditional branches in delay slot of a conditional branch List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: blauwirbel@gmail.com, Artyom Tarasenko Check whether dc->npc is dynamic before using its value for branch. Signed-off-by: Artyom Tarasenko --- Particaluary the patch fixes handling of the constructions like 0x13e26c0: brz,pn %o0, 0x13e26e4 0x13e26c4: brlez,pn %o1, 0x13e26e4 present in NetBSD-5.1 target-sparc/translate.c | 30 +++++++++++++++++++++--------- 1 files changed, 21 insertions(+), 9 deletions(-) diff --git a/target-sparc/translate.c b/target-sparc/translate.c index 958fbc5..dee67b3 100644 --- a/target-sparc/translate.c +++ b/target-sparc/translate.c @@ -1286,7 +1286,6 @@ static inline void gen_cond_reg(TCGv r_dst, int cond, TCGv r_src) } #endif -/* XXX: potentially incorrect if dynamic npc */ static void do_branch(DisasContext *dc, int32_t offset, uint32_t insn, int cc, TCGv r_cond) { @@ -1321,13 +1320,17 @@ static void do_branch(DisasContext *dc, int32_t offset, uint32_t insn, int cc, } else { dc->pc = dc->npc; dc->jump_pc[0] = target; - dc->jump_pc[1] = dc->npc + 4; - dc->npc = JUMP_PC; + if (unlikely(dc->npc == DYNAMIC_PC)) { + dc->jump_pc[1] = DYNAMIC_PC; + tcg_gen_addi_tl(cpu_pc, cpu_npc, 4); + } else { + dc->jump_pc[1] = dc->npc + 4; + dc->npc = JUMP_PC; + } } } } -/* XXX: potentially incorrect if dynamic npc */ static void do_fbranch(DisasContext *dc, int32_t offset, uint32_t insn, int cc, TCGv r_cond) { @@ -1362,14 +1365,18 @@ static void do_fbranch(DisasContext *dc, int32_t offset, uint32_t insn, int cc, } else { dc->pc = dc->npc; dc->jump_pc[0] = target; - dc->jump_pc[1] = dc->npc + 4; - dc->npc = JUMP_PC; + if (unlikely(dc->npc == DYNAMIC_PC)) { + dc->jump_pc[1] = DYNAMIC_PC; + tcg_gen_addi_tl(cpu_pc, cpu_npc, 4); + } else { + dc->jump_pc[1] = dc->npc + 4; + dc->npc = JUMP_PC; + } } } } #ifdef TARGET_SPARC64 -/* XXX: potentially incorrect if dynamic npc */ static void do_branch_reg(DisasContext *dc, int32_t offset, uint32_t insn, TCGv r_cond, TCGv r_reg) { @@ -1384,8 +1391,13 @@ static void do_branch_reg(DisasContext *dc, int32_t offset, uint32_t insn, } else { dc->pc = dc->npc; dc->jump_pc[0] = target; - dc->jump_pc[1] = dc->npc + 4; - dc->npc = JUMP_PC; + if (unlikely(dc->npc == DYNAMIC_PC)) { + dc->jump_pc[1] = DYNAMIC_PC; + tcg_gen_addi_tl(cpu_pc, cpu_npc, 4); + } else { + dc->jump_pc[1] = dc->npc + 4; + dc->npc = JUMP_PC; + } } } -- 1.7.3.4