On Fri, May 30, 2014 at 03:47:42PM +0100, Leon Alrae wrote: > The encoding of LL and SC instruction has changed in MIPS32 Release 6. > > Signed-off-by: Leon Alrae <leon.al...@imgtec.com> > --- > disas/mips.c | 9 ++++++++- > target-mips/translate.c | 29 +++++++++++++++++++++++++++-- > 2 files changed, 35 insertions(+), 3 deletions(-) > > diff --git a/disas/mips.c b/disas/mips.c > index b950e53..f41b89d 100644 > --- a/disas/mips.c > +++ b/disas/mips.c > @@ -119,6 +119,8 @@ see <http://www.gnu.org/licenses/>. */ > #define OP_SH_IMMEDIATE 0 > #define OP_MASK_DELTA 0xffff > #define OP_SH_DELTA 0 > +#define OP_MASK_DELTA_R6 0x1ff > +#define OP_SH_DELTA_R6 7 > #define OP_MASK_FUNCT 0x3f > #define OP_SH_FUNCT 0 > #define OP_MASK_SPEC 0x3f > @@ -1215,6 +1217,8 @@ const struct mips_opcode mips_builtin_opcodes[] = > them first. The assemblers uses a hash table based on the > instruction name anyhow. */ > /* 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}, > {"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 }, > @@ -3734,7 +3738,10 @@ print_insn_args (const char *d, > > case 'j': /* Same as i, but sign-extended. */ > case 'o': > - delta = (l >> OP_SH_DELTA) & OP_MASK_DELTA; > + delta = (opp->membership == I32R6) ? > + (l >> OP_SH_DELTA_R6) & OP_MASK_DELTA_R6 : > + (l >> OP_SH_DELTA) & OP_MASK_DELTA; > + > if (delta & 0x8000) > delta |= ~0xffff; > (*info->fprintf_func) (info->stream, "%d", > diff --git a/target-mips/translate.c b/target-mips/translate.c > index e5bafae..5d6be30 100644 > --- a/target-mips/translate.c > +++ b/target-mips/translate.c > @@ -345,6 +345,10 @@ enum { > /* MIPS DSP Accumulator and DSPControl Access Sub-class */ > OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3, > OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3, > + > + /* R6 */ > + R6_OPC_LL = 0x36 | OPC_SPECIAL3, > + R6_OPC_SC = 0x26 | OPC_SPECIAL3, > }; > > /* BSHFL opcodes */ > @@ -1771,6 +1775,7 @@ static void gen_ld(DisasContext *ctx, uint32_t opc, > opn = "lwr"; > break; > case OPC_LL: > + case R6_OPC_LL: > save_cpu_state(ctx, 1); > op_ld_ll(t0, t0, ctx); > gen_store_gpr(t0, rt); > @@ -1864,6 +1869,7 @@ static void gen_st_cond (DisasContext *ctx, uint32_t > opc, int rt, > break; > #endif > case OPC_SC: > + case R6_OPC_SC: > save_cpu_state(ctx, 1); > op_st_sc(t1, t0, rt, ctx); > opn = "sc"; > @@ -14753,6 +14759,10 @@ static void decode_opc (CPUMIPSState *env, > DisasContext *ctx) > case OPC_SPECIAL3: > op1 = MASK_SPECIAL3(ctx->opcode); > switch (op1) { > + case R6_OPC_LL: > + check_insn(ctx, ISA_MIPS32R6); > + gen_ld(ctx, op1, rt, rs, imm >> 7); > + break; > case OPC_EXT: > case OPC_INS: > check_insn(ctx, ISA_MIPS32R2); > @@ -15057,6 +15067,19 @@ static void decode_opc (CPUMIPSState *env, > DisasContext *ctx) > break; > } > break; > + case R6_OPC_SC: /* OPC_DMOD_G_2E */ > + if (ctx->insn_flags & ISA_MIPS32R6) { > + gen_st_cond(ctx, op1, rt, rs, imm >> 7); > + } else { > +#if defined(TARGET_MIPS64) > + check_insn(ctx, INSN_LOONGSON2E); > + gen_loongson_integer(ctx, op1, rd, rs, rt); > +#else > + /* Invalid in MIPS32 */ > + generate_exception(ctx, EXCP_RI); > +#endif > + } > + break; > #if defined(TARGET_MIPS64) > case OPC_DEXTM ... OPC_DEXT: > case OPC_DINSM ... OPC_DINS: > @@ -15072,7 +15095,8 @@ static void decode_opc (CPUMIPSState *env, > DisasContext *ctx) > break; > case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E: > case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E: > - case OPC_DMOD_G_2E ... OPC_DMODU_G_2E: > + case OPC_DMODU_G_2E: > + check_insn_opc_removed(ctx, ISA_MIPS32R6); > check_insn(ctx, INSN_LOONGSON2E); > gen_loongson_integer(ctx, op1, rd, rs, rt); > break; > @@ -15458,10 +15482,10 @@ static void decode_opc (CPUMIPSState *env, > DisasContext *ctx) > break; > case OPC_LWL: /* Load and stores */ > case OPC_LWR: > + case OPC_LL: > check_insn_opc_removed(ctx, ISA_MIPS32R6); > case OPC_LB ... OPC_LH: > case OPC_LW ... OPC_LHU: > - case OPC_LL: > gen_ld(ctx, op, rt, rs, imm); > break; > case OPC_SWL: > @@ -15472,6 +15496,7 @@ static void decode_opc (CPUMIPSState *env, > DisasContext *ctx) > gen_st(ctx, op, rt, rs, imm); > break; > case OPC_SC: > + check_insn_opc_removed(ctx, ISA_MIPS32R6); > gen_st_cond(ctx, op, rt, rs, imm); > break; > case OPC_CACHE:
Reviewed-by: Aurelien Jarno <aurel...@aurel32.net> -- Aurelien Jarno GPG: 1024D/F1BCDB73 aurel...@aurel32.net http://www.aurel32.net