From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:47503) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Z3LO3-0005Ez-DJ for qemu-devel@nongnu.org; Fri, 12 Jun 2015 05:36:51 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Z3LNw-0006b2-6T for qemu-devel@nongnu.org; Fri, 12 Jun 2015 05:36:31 -0400 Received: from mailapp01.imgtec.com ([195.59.15.196]:62502) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Z3LNv-0006aP-PB for qemu-devel@nongnu.org; Fri, 12 Jun 2015 05:36:24 -0400 Received: from KLMAIL01.kl.imgtec.org (unknown [192.168.5.35]) by Websense Email Security Gateway with ESMTPS id 8B37FF4F3D0D9 for ; Fri, 12 Jun 2015 10:36:20 +0100 (IST) From: Leon Alrae Date: Fri, 12 Jun 2015 10:35:14 +0100 Message-ID: <1434101736-11558-8-git-send-email-leon.alrae@imgtec.com> In-Reply-To: <1434101736-11558-1-git-send-email-leon.alrae@imgtec.com> References: <1434101736-11558-1-git-send-email-leon.alrae@imgtec.com> MIME-Version: 1.0 Content-Type: text/plain Subject: [Qemu-devel] [PULL 07/29] target-mips: add ERETNC instruction and Config5.LLB bit List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org ERETNC is identical to ERET except that an ERETNC will not clear the LLbit that is set by execution of an LL instruction, and thus when placed between an LL and SC sequence, will never cause the SC to fail. Presence of ERETNC is denoted by the Config5.LLB. Signed-off-by: Leon Alrae Reviewed-by: Aurelien Jarno --- disas/mips.c | 1 + target-mips/cpu.h | 1 + target-mips/helper.h | 1 + target-mips/op_helper.c | 12 +++++++++++- target-mips/translate.c | 20 +++++++++++++++----- target-mips/translate_init.c | 3 ++- 6 files changed, 31 insertions(+), 7 deletions(-) diff --git a/disas/mips.c b/disas/mips.c index 1afe0c5..832468c 100644 --- a/disas/mips.c +++ b/disas/mips.c @@ -2407,6 +2407,7 @@ const struct mips_opcode mips_builtin_opcodes[] = {"emt", "", 0x41600be1, 0xffffffff, TRAP, 0, MT32 }, {"emt", "t", 0x41600be1, 0xffe0ffff, TRAP|WR_t, 0, MT32 }, {"eret", "", 0x42000018, 0xffffffff, 0, 0, I3|I32 }, +{"eretnc", "", 0x42000058, 0xffffffff, 0, 0, I33}, {"evpe", "", 0x41600021, 0xffffffff, TRAP, 0, MT32 }, {"evpe", "t", 0x41600021, 0xffe0ffff, TRAP|WR_t, 0, MT32 }, {"ext", "t,r,+A,+C", 0x7c000000, 0xfc00003f, WR_t|RD_s, 0, I33 }, diff --git a/target-mips/cpu.h b/target-mips/cpu.h index 03eb888..2c68782 100644 --- a/target-mips/cpu.h +++ b/target-mips/cpu.h @@ -466,6 +466,7 @@ struct CPUMIPSState { #define CP0C5_UFE 9 #define CP0C5_FRE 8 #define CP0C5_SBRI 6 +#define CP0C5_LLB 4 #define CP0C5_UFR 2 #define CP0C5_NFExists 0 int32_t CP0_Config6; diff --git a/target-mips/helper.h b/target-mips/helper.h index bdd5ba5..8df98c7 100644 --- a/target-mips/helper.h +++ b/target-mips/helper.h @@ -348,6 +348,7 @@ DEF_HELPER_1(tlbinvf, void, env) DEF_HELPER_1(di, tl, env) DEF_HELPER_1(ei, tl, env) DEF_HELPER_1(eret, void, env) +DEF_HELPER_1(eretnc, void, env) DEF_HELPER_1(deret, void, env) #endif /* !CONFIG_USER_ONLY */ DEF_HELPER_1(rdhwr_cpunum, tl, env) diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c index 2fe862a..b412f94 100644 --- a/target-mips/op_helper.c +++ b/target-mips/op_helper.c @@ -2099,7 +2099,7 @@ static void set_pc(CPUMIPSState *env, target_ulong error_pc) } } -void helper_eret(CPUMIPSState *env) +static inline void exception_return(CPUMIPSState *env) { debug_pre_eret(env); if (env->CP0_Status & (1 << CP0St_ERL)) { @@ -2111,9 +2111,19 @@ void helper_eret(CPUMIPSState *env) } compute_hflags(env); debug_post_eret(env); +} + +void helper_eret(CPUMIPSState *env) +{ + exception_return(env); env->lladdr = 1; } +void helper_eretnc(CPUMIPSState *env) +{ + exception_return(env); +} + void helper_deret(CPUMIPSState *env) { debug_pre_eret(env); diff --git a/target-mips/translate.c b/target-mips/translate.c index fe6bc16..f6ae0d3 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -7917,16 +7917,26 @@ static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, goto die; gen_helper_tlbr(cpu_env); break; - case OPC_ERET: - opn = "eret"; - check_insn(ctx, ISA_MIPS2); + case OPC_ERET: /* OPC_ERETNC */ if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) { MIPS_DEBUG("CTI in delay / forbidden slot"); goto die; + } else { + int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6; + if (ctx->opcode & (1 << bit_shift)) { + /* OPC_ERETNC */ + opn = "eretnc"; + check_insn(ctx, ISA_MIPS32R5); + gen_helper_eretnc(cpu_env); + } else { + /* OPC_ERET */ + opn = "eret"; + check_insn(ctx, ISA_MIPS2); + gen_helper_eret(cpu_env); + } + ctx->bstate = BS_EXCP; } - gen_helper_eret(cpu_env); - ctx->bstate = BS_EXCP; break; case OPC_DERET: opn = "deret"; diff --git a/target-mips/translate_init.c b/target-mips/translate_init.c index 00369f1..51e7c98 100644 --- a/target-mips/translate_init.c +++ b/target-mips/translate_init.c @@ -403,7 +403,7 @@ static const mips_def_t mips_defs[] = .CP0_Config3 = MIPS_CONFIG3 | (1U << CP0C3_M) | (1 << CP0C3_MSAP), .CP0_Config4 = MIPS_CONFIG4 | (1U << CP0C4_M), .CP0_Config4_rw_bitmask = 0, - .CP0_Config5 = MIPS_CONFIG5 | (1 << CP0C5_UFR), + .CP0_Config5 = MIPS_CONFIG5 | (1 << CP0C5_UFR) | (1 << CP0C5_LLB), .CP0_Config5_rw_bitmask = (0 << CP0C5_M) | (1 << CP0C5_K) | (1 << CP0C5_CV) | (0 << CP0C5_EVA) | (1 << CP0C5_MSAEn) | (1 << CP0C5_UFR) | @@ -622,6 +622,7 @@ static const mips_def_t mips_defs[] = (1 << CP0C3_BI) | (1 << CP0C3_ULRI) | (1U << CP0C3_M), .CP0_Config4 = MIPS_CONFIG4 | (0xfc << CP0C4_KScrExist) | (3 << CP0C4_IE) | (1 << CP0C4_M), + .CP0_Config5 = MIPS_CONFIG5 | (1 << CP0C5_LLB), .CP0_Config5_rw_bitmask = (1 << CP0C5_SBRI) | (1 << CP0C5_FRE) | (1 << CP0C5_UFE), .CP0_LLAddr_rw_bitmask = 0, -- 2.1.0