diff options
author | Leon Alrae <leon.alrae@imgtec.com> | 2015-06-04 17:00:31 +0100 |
---|---|---|
committer | Leon Alrae <leon.alrae@imgtec.com> | 2015-06-11 10:13:29 +0100 |
commit | ce9782f40ac16660ea9437bfaa2c9c34d5ed8110 (patch) | |
tree | 359405ef71ce11ab76a77c82450f9af82f0c687e /target-mips/translate.c | |
parent | adc370a48fd26b92188fa4848dfb088578b1936c (diff) | |
download | qemu-ce9782f40ac16660ea9437bfaa2c9c34d5ed8110.zip |
target-mips: add ERETNC instruction and Config5.LLB bit
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 <leon.alrae@imgtec.com>
Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>
Diffstat (limited to 'target-mips/translate.c')
-rw-r--r-- | target-mips/translate.c | 20 |
1 files changed, 15 insertions, 5 deletions
diff --git a/target-mips/translate.c b/target-mips/translate.c index fe6bc16b18..f6ae0d3aec 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"; |