diff options
author | Leon Alrae <leon.alrae@imgtec.com> | 2015-01-19 11:35:11 +0100 |
---|---|---|
committer | Miodrag Dinic <miodrag.dinic@imgtec.com> | 2015-02-05 11:21:14 +0100 |
commit | b211ef108da1d434d434b04ffc3a5f60a14328f3 (patch) | |
tree | 4c22ceae88a850d08f360cc0af9d451b5ceb7a9a | |
parent | f521bd2470294784df3bfed9704661583ce40573 (diff) | |
download | qemu-android-b211ef108da1d434d434b04ffc3a5f60a14328f3.tar.gz |
target-mips: add ERETNC instruction
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.
Software can detect the presence of ERETNC by reading Config5.LLB
Change-Id: Ifbd263b8cbd974d97c9f9f29488618117a16b460
-rw-r--r-- | disas/mips.c | 1 | ||||
-rw-r--r-- | target-mips/cpu.h | 1 | ||||
-rw-r--r-- | target-mips/helper.h | 1 | ||||
-rw-r--r-- | target-mips/op_helper.c | 12 | ||||
-rw-r--r-- | target-mips/translate.c | 16 | ||||
-rw-r--r-- | target-mips/translate_init.c | 7 |
6 files changed, 30 insertions, 8 deletions
diff --git a/disas/mips.c b/disas/mips.c index 2614c52a4b..66a5275738 100644 --- a/disas/mips.c +++ b/disas/mips.c @@ -2406,6 +2406,7 @@ const struct mips_opcode mips_builtin_opcodes[] = {"ei", "t", 0x41606020, 0xffe0ffff, WR_t|WR_C0, 0, I33 }, {"emt", "", 0x41600be1, 0xffffffff, TRAP, 0, MT32 }, {"emt", "t", 0x41600be1, 0xffe0ffff, TRAP|WR_t, 0, MT32 }, +{"eretnc", "", 0x42000058, 0xffffffff, 0, 0, I33 }, {"eret", "", 0x42000018, 0xffffffff, 0, 0, I3|I32 }, {"evpe", "", 0x41600021, 0xffffffff, TRAP, 0, MT32 }, {"evpe", "t", 0x41600021, 0xffe0ffff, TRAP|WR_t, 0, MT32 }, diff --git a/target-mips/cpu.h b/target-mips/cpu.h index c01bbdac2d..9963cffc72 100644 --- a/target-mips/cpu.h +++ b/target-mips/cpu.h @@ -464,6 +464,7 @@ struct CPUMIPSState { #define CP0C5_EVA 28 #define CP0C5_MSAEn 27 #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 9d0275891c..3687df4969 100644 --- a/target-mips/helper.h +++ b/target-mips/helper.h @@ -347,6 +347,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 638c9f9dfb..8630d44275 100644 --- a/target-mips/op_helper.c +++ b/target-mips/op_helper.c @@ -2160,7 +2160,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)) { @@ -2172,9 +2172,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 f0b8e6ffe4..2682c13294 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -7886,15 +7886,23 @@ 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; } - gen_helper_eret(cpu_env); + if (ctx->opcode & (1 << 6)) { + /* 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; break; case OPC_DERET: diff --git a/target-mips/translate_init.c b/target-mips/translate_init.c index 148b394cf0..4b70ccaac9 100644 --- a/target-mips/translate_init.c +++ b/target-mips/translate_init.c @@ -362,7 +362,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) | @@ -528,14 +528,15 @@ static const mips_def_t mips_defs[] = .CP0_Config0 = MIPS_CONFIG0 | (0x2 << CP0C0_AR) | (0x2 << CP0C0_AT) | (MMU_TYPE_R4000 << CP0C0_MT), .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (63 << CP0C1_MMU) | - (2 << CP0C1_IS) | (4 << CP0C1_IL) | (3 << CP0C1_IA) | - (2 << CP0C1_DS) | (4 << CP0C1_DL) | (3 << CP0C1_DA) | + (2 << CP0C1_IS) | (3 << CP0C1_IL) | (3 << CP0C1_IA) | + (2 << CP0C1_DS) | (3 << CP0C1_DL) | (3 << CP0C1_DA) | (0 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP), .CP0_Config2 = MIPS_CONFIG2, .CP0_Config3 = MIPS_CONFIG3 | (1 << CP0C3_RXI) | (1 << CP0C3_BP) | (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), .CP0_LLAddr_rw_bitmask = 0, .CP0_LLAddr_shift = 0, |