aboutsummaryrefslogtreecommitdiff
path: root/target-mips/translate.c
diff options
context:
space:
mode:
Diffstat (limited to 'target-mips/translate.c')
-rw-r--r--target-mips/translate.c29
1 files changed, 28 insertions, 1 deletions
diff --git a/target-mips/translate.c b/target-mips/translate.c
index 11967a0585..f50d906cc1 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);