Message ID | 1401461279-59617-9-git-send-email-leon.alrae@imgtec.com |
---|---|
State | New |
Headers | show |
On Fri, May 30, 2014 at 03:47:46PM +0100, Leon Alrae wrote: > The encoding of PREF, CACHE, LLD and SCD instruction changed in MIPS32R6. > Additionally, the hint codes in PREF instruction greater than or > equal to 24 generate Reserved Instruction Exception. > > Signed-off-by: Leon Alrae <leon.alrae@imgtec.com> > --- > disas/mips.c | 4 ++++ > target-mips/translate.c | 29 ++++++++++++++++++++++++++++- > 2 files changed, 32 insertions(+), 1 deletions(-) > > diff --git a/disas/mips.c b/disas/mips.c > index f41b89d..67da1f0 100644 > --- a/disas/mips.c > +++ b/disas/mips.c > @@ -1219,6 +1219,10 @@ const struct mips_opcode mips_builtin_opcodes[] = > /* name, args, match, mask, pinfo, membership */ > {"ll", "t,o(b)", 0x7c000036, 0xfc00003f, LDD|RD_b|WR_t, 0, I32R6}, > {"sc", "t,o(b)", 0x7c000026, 0xfc00003f, LDD|RD_b|WR_t, 0, I32R6}, > +{"lld", "t,o(b)", 0x7c000037, 0xfc00003f, LDD|RD_b|WR_t, 0, I64R6}, > +{"scd", "t,o(b)", 0x7c000027, 0xfc00003f, LDD|RD_b|WR_t, 0, I64R6}, > +{"pref", "h,o(b)", 0x7c000035, 0xfc00003f, RD_b, 0, I32R6}, > +{"cache", "k,o(b)", 0x7c000025, 0xfc00003f, RD_b, 0, I32R6}, > {"seleqz", "d,v,t", 0x00000035, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I32R6}, > {"selnez", "d,v,t", 0x00000037, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I32R6}, > {"pref", "k,o(b)", 0xcc000000, 0xfc000000, RD_b, 0, I4|I32|G3 }, > diff --git a/target-mips/translate.c b/target-mips/translate.c > index 8f1ade5..5557271 100644 > --- a/target-mips/translate.c > +++ b/target-mips/translate.c > @@ -347,8 +347,12 @@ enum { > OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3, > > /* R6 */ > + R6_OPC_PREF = 0x35 | OPC_SPECIAL3, > + R6_OPC_CACHE = 0x25 | OPC_SPECIAL3, > R6_OPC_LL = 0x36 | OPC_SPECIAL3, > R6_OPC_SC = 0x26 | OPC_SPECIAL3, > + R6_OPC_LLD = 0x37 | OPC_SPECIAL3, > + R6_OPC_SCD = 0x27 | OPC_SPECIAL3, > }; > > /* BSHFL opcodes */ > @@ -1641,6 +1645,7 @@ static void gen_ld(DisasContext *ctx, uint32_t opc, > opn = "ld"; > break; > case OPC_LLD: > + case R6_OPC_LLD: > save_cpu_state(ctx, 1); > op_ld_lld(t0, t0, ctx); > gen_store_gpr(t0, rt); > @@ -1863,6 +1868,7 @@ static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt, > switch (opc) { > #if defined(TARGET_MIPS64) > case OPC_SCD: > + case R6_OPC_SCD: > save_cpu_state(ctx, 1); > op_st_scd(t1, t0, rt, ctx); > opn = "scd"; > @@ -14815,12 +14821,30 @@ static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx) > > op1 = MASK_SPECIAL3(ctx->opcode); > switch (op1) { > + case R6_OPC_PREF: > + if (rt >= 24) { > + /* hint codes 24-31 are reserved and signal RI */ > + generate_exception(ctx, EXCP_RI); > + } > + /* Treat as NOP. */ > + break; > + case R6_OPC_CACHE: > + /* Treat as NOP. */ > + break; > case R6_OPC_SC: > gen_st_cond(ctx, op1, rt, rs, imm >> 7); > break; > case R6_OPC_LL: > gen_ld(ctx, op1, rt, rs, imm >> 7); > break; > +#if defined(TARGET_MIPS64) > + case R6_OPC_SCD: > + gen_st_cond(ctx, op1, rt, rs, imm >> 7); > + break; > + case R6_OPC_LLD: > + gen_ld(ctx, op1, rt, rs, imm >> 7); > + break; > +#endif > default: /* Invalid */ > MIPS_INVAL("special3_r6"); > generate_exception(ctx, EXCP_RI); > @@ -15632,11 +15656,13 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx) > gen_st_cond(ctx, op, rt, rs, imm); > break; > case OPC_CACHE: > + check_insn_opc_removed(ctx, ISA_MIPS32R6); > check_cp0_enabled(ctx); > check_insn(ctx, ISA_MIPS3 | ISA_MIPS32); > /* Treat as NOP. */ > break; > case OPC_PREF: > + check_insn_opc_removed(ctx, ISA_MIPS32R6); > check_insn(ctx, ISA_MIPS4 | ISA_MIPS32); > /* Treat as NOP. */ > break; > @@ -15759,9 +15785,9 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx) > #if defined(TARGET_MIPS64) > /* MIPS64 opcodes */ > case OPC_LDL ... OPC_LDR: > + case OPC_LLD: > check_insn_opc_removed(ctx, ISA_MIPS32R6); > case OPC_LWU: > - case OPC_LLD: > case OPC_LD: > check_insn(ctx, ISA_MIPS3); > check_mips_64(ctx); > @@ -15775,6 +15801,7 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx) > gen_st(ctx, op, rt, rs, imm); > break; > case OPC_SCD: > + check_insn_opc_removed(ctx, ISA_MIPS32R6); > check_insn(ctx, ISA_MIPS3); > check_mips_64(ctx); > gen_st_cond(ctx, op, rt, rs, imm); Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>
diff --git a/disas/mips.c b/disas/mips.c index f41b89d..67da1f0 100644 --- a/disas/mips.c +++ b/disas/mips.c @@ -1219,6 +1219,10 @@ const struct mips_opcode mips_builtin_opcodes[] = /* name, args, match, mask, pinfo, membership */ {"ll", "t,o(b)", 0x7c000036, 0xfc00003f, LDD|RD_b|WR_t, 0, I32R6}, {"sc", "t,o(b)", 0x7c000026, 0xfc00003f, LDD|RD_b|WR_t, 0, I32R6}, +{"lld", "t,o(b)", 0x7c000037, 0xfc00003f, LDD|RD_b|WR_t, 0, I64R6}, +{"scd", "t,o(b)", 0x7c000027, 0xfc00003f, LDD|RD_b|WR_t, 0, I64R6}, +{"pref", "h,o(b)", 0x7c000035, 0xfc00003f, RD_b, 0, I32R6}, +{"cache", "k,o(b)", 0x7c000025, 0xfc00003f, RD_b, 0, I32R6}, {"seleqz", "d,v,t", 0x00000035, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I32R6}, {"selnez", "d,v,t", 0x00000037, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I32R6}, {"pref", "k,o(b)", 0xcc000000, 0xfc000000, RD_b, 0, I4|I32|G3 }, diff --git a/target-mips/translate.c b/target-mips/translate.c index 8f1ade5..5557271 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -347,8 +347,12 @@ enum { OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3, /* R6 */ + R6_OPC_PREF = 0x35 | OPC_SPECIAL3, + R6_OPC_CACHE = 0x25 | OPC_SPECIAL3, R6_OPC_LL = 0x36 | OPC_SPECIAL3, R6_OPC_SC = 0x26 | OPC_SPECIAL3, + R6_OPC_LLD = 0x37 | OPC_SPECIAL3, + R6_OPC_SCD = 0x27 | OPC_SPECIAL3, }; /* BSHFL opcodes */ @@ -1641,6 +1645,7 @@ static void gen_ld(DisasContext *ctx, uint32_t opc, opn = "ld"; break; case OPC_LLD: + case R6_OPC_LLD: save_cpu_state(ctx, 1); op_ld_lld(t0, t0, ctx); gen_store_gpr(t0, rt); @@ -1863,6 +1868,7 @@ static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt, switch (opc) { #if defined(TARGET_MIPS64) case OPC_SCD: + case R6_OPC_SCD: save_cpu_state(ctx, 1); op_st_scd(t1, t0, rt, ctx); opn = "scd"; @@ -14815,12 +14821,30 @@ static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx) op1 = MASK_SPECIAL3(ctx->opcode); switch (op1) { + case R6_OPC_PREF: + if (rt >= 24) { + /* hint codes 24-31 are reserved and signal RI */ + generate_exception(ctx, EXCP_RI); + } + /* Treat as NOP. */ + break; + case R6_OPC_CACHE: + /* Treat as NOP. */ + break; case R6_OPC_SC: gen_st_cond(ctx, op1, rt, rs, imm >> 7); break; case R6_OPC_LL: gen_ld(ctx, op1, rt, rs, imm >> 7); break; +#if defined(TARGET_MIPS64) + case R6_OPC_SCD: + gen_st_cond(ctx, op1, rt, rs, imm >> 7); + break; + case R6_OPC_LLD: + gen_ld(ctx, op1, rt, rs, imm >> 7); + break; +#endif default: /* Invalid */ MIPS_INVAL("special3_r6"); generate_exception(ctx, EXCP_RI); @@ -15632,11 +15656,13 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx) gen_st_cond(ctx, op, rt, rs, imm); break; case OPC_CACHE: + check_insn_opc_removed(ctx, ISA_MIPS32R6); check_cp0_enabled(ctx); check_insn(ctx, ISA_MIPS3 | ISA_MIPS32); /* Treat as NOP. */ break; case OPC_PREF: + check_insn_opc_removed(ctx, ISA_MIPS32R6); check_insn(ctx, ISA_MIPS4 | ISA_MIPS32); /* Treat as NOP. */ break; @@ -15759,9 +15785,9 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx) #if defined(TARGET_MIPS64) /* MIPS64 opcodes */ case OPC_LDL ... OPC_LDR: + case OPC_LLD: check_insn_opc_removed(ctx, ISA_MIPS32R6); case OPC_LWU: - case OPC_LLD: case OPC_LD: check_insn(ctx, ISA_MIPS3); check_mips_64(ctx); @@ -15775,6 +15801,7 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx) gen_st(ctx, op, rt, rs, imm); break; case OPC_SCD: + check_insn_opc_removed(ctx, ISA_MIPS32R6); check_insn(ctx, ISA_MIPS3); check_mips_64(ctx); gen_st_cond(ctx, op, rt, rs, imm);
The encoding of PREF, CACHE, LLD and SCD instruction changed in MIPS32R6. Additionally, the hint codes in PREF instruction greater than or equal to 24 generate Reserved Instruction Exception. Signed-off-by: Leon Alrae <leon.alrae@imgtec.com> --- disas/mips.c | 4 ++++ target-mips/translate.c | 29 ++++++++++++++++++++++++++++- 2 files changed, 32 insertions(+), 1 deletions(-)