summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--disas/mips.c4
-rw-r--r--target-mips/translate.c29
2 files changed, 32 insertions, 1 deletions
diff --git a/disas/mips.c b/disas/mips.c
index f0efa8b29c..cae76ed482 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, 0xfc00007f, LDD|RD_b|WR_t, 0, I32R6},
{"sc", "t,o(b)", 0x7c000026, 0xfc00007f, LDD|RD_b|WR_t, 0, I32R6},
+{"lld", "t,o(b)", 0x7c000037, 0xfc00007f, LDD|RD_b|WR_t, 0, I64R6},
+{"scd", "t,o(b)", 0x7c000027, 0xfc00007f, LDD|RD_b|WR_t, 0, I64R6},
+{"pref", "h,o(b)", 0x7c000035, 0xfc00007f, RD_b, 0, I32R6},
+{"cache", "k,o(b)", 0x7c000025, 0xfc00007f, 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 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);