diff options
Diffstat (limited to 'target-mips')
-rw-r--r-- | target-mips/translate.c | 29 |
1 files changed, 28 insertions, 1 deletions
diff --git a/target-mips/translate.c b/target-mips/translate.c index 11967a0..f50d906 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -349,8 +349,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 */ @@ -1645,6 +1649,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); @@ -1867,6 +1872,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"; @@ -14866,12 +14872,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); break; case R6_OPC_LL: gen_ld(ctx, op1, rt, rs, imm); break; +#if defined(TARGET_MIPS64) + case R6_OPC_SCD: + gen_st_cond(ctx, op1, rt, rs, imm); + break; + case R6_OPC_LLD: + gen_ld(ctx, op1, rt, rs, imm); + break; +#endif default: /* Invalid */ MIPS_INVAL("special3_r6"); generate_exception(ctx, EXCP_RI); @@ -15686,11 +15710,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; @@ -15813,9 +15839,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); @@ -15829,6 +15855,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); |