summaryrefslogtreecommitdiffstats
path: root/target-sparc
ModeNameSize
-rw-r--r--Makefile.objs280logstatsplainblame
-rw-r--r--TODO2267logstatsplainblame
-rw-r--r--cc_helper.c11079logstatsplainblame
-rw-r--r--cpu-qom.h2577logstatsplainblame
-rw-r--r--cpu.c26506logstatsplainblame
-rw-r--r--cpu.h23021logstatsplainblame
-rw-r--r--fop_helper.c15350logstatsplainblame
-rw-r--r--gdbstub.c5618logstatsplainblame
-rw-r--r--helper.c6269logstatsplainblame
-rw-r--r--helper.h6750logstatsplainblame
-rw-r--r--int32_helper.c5275logstatsplainblame
-rw-r--r--int64_helper.c6093logstatsplainblame
-rw-r--r--ldst_helper.c76404logstatsplainblame
-rw-r--r--machine.c6912logstatsplainblame
-rw-r--r--mmu_helper.c27898logstatsplainblame
-rw-r--r--translate.c195611logstatsplainblame
-rw-r--r--vis_helper.c15133logstatsplainblame
-rw-r--r--win_helper.c9779logstatsplainblame
c @@ -444,7 +444,6 @@ static void boston_mach_init(MachineState *machine) DriveInfo *hd[6]; Chardev *chr; int fw_size, fit_err; - bool is_64b; if ((machine->ram_size % GiB) || (machine->ram_size > (2 * GiB))) { @@ -463,8 +462,6 @@ static void boston_mach_init(MachineState *machine) exit(1); } - is_64b = cpu_type_supports_isa(machine->cpu_type, ISA_MIPS64); - object_initialize_child(OBJECT(machine), "cps", &s->cps, TYPE_MIPS_CPS); object_property_set_str(OBJECT(&s->cps), "cpu-type", machine->cpu_type, &error_fatal); @@ -545,7 +542,8 @@ static void boston_mach_init(MachineState *machine) } gen_firmware(memory_region_get_ram_ptr(flash) + 0x7c00000, - s->kernel_entry, s->fdt_base, is_64b); + s->kernel_entry, s->fdt_base, + cpu_type_is_64bit(machine->cpu_type)); } else if (!qtest_enabled()) { error_report("Please provide either a -kernel or -bios argument"); exit(1); -- cgit v1.2.3-55-g7522 From 08e2262fada2de06232e8099bddf6e03df015c5a Mon Sep 17 00:00:00 2001 From: Philippe Mathieu-Daudé Date: Wed, 16 Dec 2020 17:23:15 +0100 Subject: target/mips/mips-defs: Use ISA_MIPS32 definition to check Release 1 Use the single ISA_MIPS32 definition to check if the Release 1 ISA is supported, whether the CPU support 32/64-bit. For now we keep '32' in the definition name, we will rename it as ISA_MIPS_R1 in few commits. Reviewed-by: Richard Henderson Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20210104221154.3127610-7-f4bug@amsat.org> --- target/mips/mips-defs.h | 3 +-- target/mips/translate.c | 10 +++++----- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/target/mips/mips-defs.h b/target/mips/mips-defs.h index 89a9a4dda3..23ce8b8406 100644 --- a/target/mips/mips-defs.h +++ b/target/mips/mips-defs.h @@ -18,7 +18,6 @@ #define ISA_MIPS5 0x0000000000000010ULL #define ISA_MIPS32 0x0000000000000020ULL #define ISA_MIPS32R2 0x0000000000000040ULL -#define ISA_MIPS64 0x0000000000000080ULL #define ISA_MIPS64R2 0x0000000000000100ULL #define ISA_MIPS32R3 0x0000000000000200ULL #define ISA_MIPS64R3 0x0000000000000400ULL @@ -75,7 +74,7 @@ /* MIPS Technologies "Release 1" */ #define CPU_MIPS32R1 (CPU_MIPS2 | ISA_MIPS32) -#define CPU_MIPS64R1 (CPU_MIPS5 | CPU_MIPS32R1 | ISA_MIPS64) +#define CPU_MIPS64R1 (CPU_MIPS5 | CPU_MIPS32R1) /* MIPS Technologies "Release 2" */ #define CPU_MIPS32R2 (CPU_MIPS32R1 | ISA_MIPS32R2) diff --git a/target/mips/translate.c b/target/mips/translate.c index 19933b7868..172027f9d6 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -8943,7 +8943,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) const char *register_name = "invalid"; if (sel != 0) { - check_insn(ctx, ISA_MIPS64); + check_insn(ctx, ISA_MIPS32); } switch (reg) { @@ -9669,7 +9669,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) const char *register_name = "invalid"; if (sel != 0) { - check_insn(ctx, ISA_MIPS64); + check_insn(ctx, ISA_MIPS32); } if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { @@ -14907,12 +14907,12 @@ static int decode_mips16_opc(CPUMIPSState *env, DisasContext *ctx) break; #if defined(TARGET_MIPS64) case RR_RY_CNVT_ZEW: - check_insn(ctx, ISA_MIPS64); + check_insn(ctx, ISA_MIPS32); check_mips_64(ctx); tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]); break; case RR_RY_CNVT_SEW: - check_insn(ctx, ISA_MIPS64); + check_insn(ctx, ISA_MIPS32); check_mips_64(ctx); tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]); break; @@ -27612,7 +27612,7 @@ static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx) #if defined(TARGET_MIPS64) case OPC_DCLO: case OPC_DCLZ: - check_insn(ctx, ISA_MIPS64); + check_insn(ctx, ISA_MIPS32); check_mips_64(ctx); gen_cl(ctx, op1, rd, rs); break; -- cgit v1.2.3-55-g7522 From f395cef7656e794a5c6c007bdf661603410640d8 Mon Sep 17 00:00:00 2001 From: Philippe Mathieu-Daudé Date: Wed, 16 Dec 2020 12:06:51 +0100 Subject: target/mips/mips-defs: Use ISA_MIPS32R2 definition to check Release 2 Use the single ISA_MIPS32R2 definition to check if the Release 2 ISA is supported, whether the CPU support 32/64-bit. For now we keep '32' in the definition name, we will rename it as ISA_MIPS_R2 in few commits. Reviewed-by: Richard Henderson Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20210104221154.3127610-8-f4bug@amsat.org> --- linux-user/mips/cpu_loop.c | 1 - target/mips/mips-defs.h | 3 +-- target/mips/translate.c | 4 ++-- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/linux-user/mips/cpu_loop.c b/linux-user/mips/cpu_loop.c index cfe7ba5c47..f0831379cc 100644 --- a/linux-user/mips/cpu_loop.c +++ b/linux-user/mips/cpu_loop.c @@ -385,7 +385,6 @@ void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs) prog_req.fre &= interp_req.fre; bool cpu_has_mips_r2_r6 = env->insn_flags & ISA_MIPS32R2 || - env->insn_flags & ISA_MIPS64R2 || env->insn_flags & ISA_MIPS32R6 || env->insn_flags & ISA_MIPS64R6; diff --git a/target/mips/mips-defs.h b/target/mips/mips-defs.h index 23ce8b8406..b36b59c12d 100644 --- a/target/mips/mips-defs.h +++ b/target/mips/mips-defs.h @@ -18,7 +18,6 @@ #define ISA_MIPS5 0x0000000000000010ULL #define ISA_MIPS32 0x0000000000000020ULL #define ISA_MIPS32R2 0x0000000000000040ULL -#define ISA_MIPS64R2 0x0000000000000100ULL #define ISA_MIPS32R3 0x0000000000000200ULL #define ISA_MIPS64R3 0x0000000000000400ULL #define ISA_MIPS32R5 0x0000000000000800ULL @@ -78,7 +77,7 @@ /* MIPS Technologies "Release 2" */ #define CPU_MIPS32R2 (CPU_MIPS32R1 | ISA_MIPS32R2) -#define CPU_MIPS64R2 (CPU_MIPS64R1 | CPU_MIPS32R2 | ISA_MIPS64R2) +#define CPU_MIPS64R2 (CPU_MIPS64R1 | CPU_MIPS32R2) /* MIPS Technologies "Release 3" */ #define CPU_MIPS32R3 (CPU_MIPS32R2 | ISA_MIPS32R3) diff --git a/target/mips/translate.c b/target/mips/translate.c index 172027f9d6..9fc9dedf30 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -28621,7 +28621,7 @@ static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx) case OPC_DINSM: case OPC_DINSU: case OPC_DINS: - check_insn(ctx, ISA_MIPS64R2); + check_insn(ctx, ISA_MIPS32R2); check_mips_64(ctx); gen_bitops(ctx, op1, rt, rs, sa, rd); break; @@ -28641,7 +28641,7 @@ static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx) decode_opc_special3_r6(env, ctx); break; default: - check_insn(ctx, ISA_MIPS64R2); + check_insn(ctx, ISA_MIPS32R2); check_mips_64(ctx); op2 = MASK_DBSHFL(ctx->opcode); gen_bshfl(ctx, op2, rt, rd); -- cgit v1.2.3-55-g7522 From 4d1524d2ce2f809ae514b23f8e9d502d051c6df4 Mon Sep 17 00:00:00 2001 From: Philippe Mathieu-Daudé Date: Wed, 16 Dec 2020 12:08:40 +0100 Subject: target/mips/mips-defs: Use ISA_MIPS32R3 definition to check Release 3 Use the single ISA_MIPS32R3 definition to check if the Release 3 ISA is supported, whether the CPU support 32/64-bit. For now we keep '32' in the definition name, we will rename it as ISA_MIPS_R3 in few commits. Reviewed-by: Richard Henderson Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20210104221154.3127610-9-f4bug@amsat.org> --- target/mips/mips-defs.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/target/mips/mips-defs.h b/target/mips/mips-defs.h index b36b59c12d..ccdde0b4a4 100644 --- a/target/mips/mips-defs.h +++ b/target/mips/mips-defs.h @@ -19,7 +19,6 @@ #define ISA_MIPS32 0x0000000000000020ULL #define ISA_MIPS32R2 0x0000000000000040ULL #define ISA_MIPS32R3 0x0000000000000200ULL -#define ISA_MIPS64R3 0x0000000000000400ULL #define ISA_MIPS32R5 0x0000000000000800ULL #define ISA_MIPS64R5 0x0000000000001000ULL #define ISA_MIPS32R6 0x0000000000002000ULL @@ -81,7 +80,7 @@ /* MIPS Technologies "Release 3" */ #define CPU_MIPS32R3 (CPU_MIPS32R2 | ISA_MIPS32R3) -#define CPU_MIPS64R3 (CPU_MIPS64R2 | CPU_MIPS32R3 | ISA_MIPS64R3) +#define CPU_MIPS64R3 (CPU_MIPS64R2 | CPU_MIPS32R3) /* MIPS Technologies "Release 5" */ #define CPU_MIPS32R5 (CPU_MIPS32R3 | ISA_MIPS32R5) -- cgit v1.2.3-55-g7522 From d913c3992dfd9506a8201c2995d7c910a18db92f Mon Sep 17 00:00:00 2001 From: Philippe Mathieu-Daudé Date: Wed, 16 Dec 2020 12:09:08 +0100 Subject: target/mips/mips-defs: Use ISA_MIPS32R5 definition to check Release 5 Use the single ISA_MIPS32R5 definition to check if the Release 5 ISA is supported, whether the CPU support 32/64-bit. For now we keep '32' in the definition name, we will rename it as ISA_MIPS_R5 in few commits. Reviewed-by: Richard Henderson Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20210104221154.3127610-10-f4bug@amsat.org> --- target/mips/mips-defs.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/target/mips/mips-defs.h b/target/mips/mips-defs.h index ccdde0b4a4..b71127ddd7 100644 --- a/target/mips/mips-defs.h +++ b/target/mips/mips-defs.h @@ -20,7 +20,6 @@ #define ISA_MIPS32R2 0x0000000000000040ULL #define ISA_MIPS32R3 0x0000000000000200ULL #define ISA_MIPS32R5 0x0000000000000800ULL -#define ISA_MIPS64R5 0x0000000000001000ULL #define ISA_MIPS32R6 0x0000000000002000ULL #define ISA_MIPS64R6 0x0000000000004000ULL #define ISA_NANOMIPS32 0x0000000000008000ULL @@ -84,7 +83,7 @@ /* MIPS Technologies "Release 5" */ #define CPU_MIPS32R5 (CPU_MIPS32R3 | ISA_MIPS32R5) -#define CPU_MIPS64R5 (CPU_MIPS64R3 | CPU_MIPS32R5 | ISA_MIPS64R5) +#define CPU_MIPS64R5 (CPU_MIPS64R3 | CPU_MIPS32R5) /* MIPS Technologies "Release 6" */ #define CPU_MIPS32R6 (CPU_MIPS32R5 | ISA_MIPS32R6) -- cgit v1.2.3-55-g7522 From 13514fc93e6b2ead6e984bcd104975b6b4f375e8 Mon Sep 17 00:00:00 2001 From: Philippe Mathieu-Daudé Date: Wed, 16 Dec 2020 12:14:00 +0100 Subject: target/mips/mips-defs: Use ISA_MIPS32R6 definition to check Release 6 Use the single ISA_MIPS32R6 definition to check if the Release 6 ISA is supported, whether the CPU support 32/64-bit. For now we keep '32' in the definition name, we will rename it as ISA_MIPS_R6 in few commits. Reviewed-by: Richard Henderson Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20210104221154.3127610-11-f4bug@amsat.org> --- linux-user/mips/cpu_loop.c | 3 +-- target/mips/helper.c | 6 +++--- target/mips/internal.h | 2 +- target/mips/mips-defs.h | 3 +-- target/mips/translate.c | 2 +- 5 files changed, 7 insertions(+), 9 deletions(-) diff --git a/linux-user/mips/cpu_loop.c b/linux-user/mips/cpu_loop.c index f0831379cc..e400166c58 100644 --- a/linux-user/mips/cpu_loop.c +++ b/linux-user/mips/cpu_loop.c @@ -385,8 +385,7 @@ void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs) prog_req.fre &= interp_req.fre; bool cpu_has_mips_r2_r6 = env->insn_flags & ISA_MIPS32R2 || - env->insn_flags & ISA_MIPS32R6 || - env->insn_flags & ISA_MIPS64R6; + env->insn_flags & ISA_MIPS32R6; if (prog_req.fre && !prog_req.frdefault && !prog_req.fr1) { env->CP0_Config5 |= (1 << CP0C5_FRE); diff --git a/target/mips/helper.c b/target/mips/helper.c index 87296fbad6..5b74815beb 100644 --- a/target/mips/helper.c +++ b/target/mips/helper.c @@ -1145,7 +1145,7 @@ void mips_cpu_do_interrupt(CPUState *cs) enter_debug_mode: if (env->insn_flags & ISA_MIPS3) { env->hflags |= MIPS_HFLAG_64; - if (!(env->insn_flags & ISA_MIPS64R6) || + if (!(env->insn_flags & ISA_MIPS32R6) || env->CP0_Status & (1 << CP0St_KX)) { env->hflags &= ~MIPS_HFLAG_AWRAP; } @@ -1174,7 +1174,7 @@ void mips_cpu_do_interrupt(CPUState *cs) env->CP0_Status |= (1 << CP0St_ERL) | (1 << CP0St_BEV); if (env->insn_flags & ISA_MIPS3) { env->hflags |= MIPS_HFLAG_64; - if (!(env->insn_flags & ISA_MIPS64R6) || + if (!(env->insn_flags & ISA_MIPS32R6) || env->CP0_Status & (1 << CP0St_KX)) { env->hflags &= ~MIPS_HFLAG_AWRAP; } @@ -1360,7 +1360,7 @@ void mips_cpu_do_interrupt(CPUState *cs) env->CP0_Status |= (1 << CP0St_EXL); if (env->insn_flags & ISA_MIPS3) { env->hflags |= MIPS_HFLAG_64; - if (!(env->insn_flags & ISA_MIPS64R6) || + if (!(env->insn_flags & ISA_MIPS32R6) || env->CP0_Status & (1 << CP0St_KX)) { env->hflags &= ~MIPS_HFLAG_AWRAP; } diff --git a/target/mips/internal.h b/target/mips/internal.h index e4d2d9f44f..3466725b76 100644 --- a/target/mips/internal.h +++ b/target/mips/internal.h @@ -354,7 +354,7 @@ static inline void compute_hflags(CPUMIPSState *env) } else if (((env->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) && !(env->CP0_Status & (1 << CP0St_UX))) { env->hflags |= MIPS_HFLAG_AWRAP; - } else if (env->insn_flags & ISA_MIPS64R6) { + } else if (env->insn_flags & ISA_MIPS32R6) { /* Address wrapping for Supervisor and Kernel is specified in R6 */ if ((((env->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_SM) && !(env->CP0_Status & (1 << CP0St_SX))) || diff --git a/target/mips/mips-defs.h b/target/mips/mips-defs.h index b71127ddd7..fea547508f 100644 --- a/target/mips/mips-defs.h +++ b/target/mips/mips-defs.h @@ -21,7 +21,6 @@ #define ISA_MIPS32R3 0x0000000000000200ULL #define ISA_MIPS32R5 0x0000000000000800ULL #define ISA_MIPS32R6 0x0000000000002000ULL -#define ISA_MIPS64R6 0x0000000000004000ULL #define ISA_NANOMIPS32 0x0000000000008000ULL /* * bits 24-39: MIPS ASEs @@ -87,7 +86,7 @@ /* MIPS Technologies "Release 6" */ #define CPU_MIPS32R6 (CPU_MIPS32R5 | ISA_MIPS32R6) -#define CPU_MIPS64R6 (CPU_MIPS64R5 | CPU_MIPS32R6 | ISA_MIPS64R6) +#define CPU_MIPS64R6 (CPU_MIPS64R5 | CPU_MIPS32R6) /* Wave Computing: "nanoMIPS" */ #define CPU_NANOMIPS32 (CPU_MIPS32R6 | ISA_NANOMIPS32) diff --git a/target/mips/translate.c b/target/mips/translate.c index 9fc9dedf30..fc93b9da8e 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -31438,7 +31438,7 @@ static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) #else ctx->mem_idx = hflags_mmu_index(ctx->hflags); #endif - ctx->default_tcg_memop_mask = (ctx->insn_flags & (ISA_MIPS32R6 | ISA_MIPS64R6 | + ctx->default_tcg_memop_mask = (ctx->insn_flags & (ISA_MIPS32R6 | INSN_LOONGSON3A)) ? MO_UNALN : MO_ALIGN; LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx, -- cgit v1.2.3-55-g7522 From bbd5e4a27f0e4e717f9bdf35fd9c1f42410dea04 Mon Sep 17 00:00:00 2001 From: Philippe Mathieu-Daudé Date: Wed, 16 Dec 2020 12:26:56 +0100 Subject: target/mips/mips-defs: Rename ISA_MIPS32 as ISA_MIPS_R1 The MIPS ISA release '1' is common to 32/64-bit CPUs. Reviewed-by: Richard Henderson Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20210104221154.3127610-12-f4bug@amsat.org> --- target/mips/internal.h | 2 +- target/mips/mips-defs.h | 4 ++-- target/mips/translate.c | 54 ++++++++++++++++++++++++------------------------- 3 files changed, 30 insertions(+), 30 deletions(-) diff --git a/target/mips/internal.h b/target/mips/internal.h index 3466725b76..94910f75a6 100644 --- a/target/mips/internal.h +++ b/target/mips/internal.h @@ -411,7 +411,7 @@ static inline void compute_hflags(CPUMIPSState *env) if (env->active_fpu.fcr0 & (1 << FCR0_F64)) { env->hflags |= MIPS_HFLAG_COP1X; } - } else if (env->insn_flags & ISA_MIPS32) { + } else if (env->insn_flags & ISA_MIPS_R1) { if (env->hflags & MIPS_HFLAG_64) { env->hflags |= MIPS_HFLAG_COP1X; } diff --git a/target/mips/mips-defs.h b/target/mips/mips-defs.h index fea547508f..a7048ffaff 100644 --- a/target/mips/mips-defs.h +++ b/target/mips/mips-defs.h @@ -16,7 +16,7 @@ #define ISA_MIPS3 0x0000000000000004ULL /* 64-bit */ #define ISA_MIPS4 0x0000000000000008ULL #define ISA_MIPS5 0x0000000000000010ULL -#define ISA_MIPS32 0x0000000000000020ULL +#define ISA_MIPS_R1 0x0000000000000020ULL #define ISA_MIPS32R2 0x0000000000000040ULL #define ISA_MIPS32R3 0x0000000000000200ULL #define ISA_MIPS32R5 0x0000000000000800ULL @@ -69,7 +69,7 @@ #define CPU_MIPS64 (ISA_MIPS3) /* MIPS Technologies "Release 1" */ -#define CPU_MIPS32R1 (CPU_MIPS2 | ISA_MIPS32) +#define CPU_MIPS32R1 (CPU_MIPS2 | ISA_MIPS_R1) #define CPU_MIPS64R1 (CPU_MIPS5 | CPU_MIPS32R1) /* MIPS Technologies "Release 2" */ diff --git a/target/mips/translate.c b/target/mips/translate.c index fc93b9da8e..a59fbd94ba 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -7411,7 +7411,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) const char *register_name = "invalid"; if (sel != 0) { - check_insn(ctx, ISA_MIPS32); + check_insn(ctx, ISA_MIPS_R1); } switch (reg) { @@ -8179,7 +8179,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) const char *register_name = "invalid"; if (sel != 0) { - check_insn(ctx, ISA_MIPS32); + check_insn(ctx, ISA_MIPS_R1); } if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { @@ -8943,7 +8943,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) const char *register_name = "invalid"; if (sel != 0) { - check_insn(ctx, ISA_MIPS32); + check_insn(ctx, ISA_MIPS_R1); } switch (reg) { @@ -9669,7 +9669,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) const char *register_name = "invalid"; if (sel != 0) { - check_insn(ctx, ISA_MIPS32); + check_insn(ctx, ISA_MIPS_R1); } if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { @@ -11006,7 +11006,7 @@ static void gen_cp0(CPUMIPSState *env, DisasContext *ctx, uint32_t opc, break; case OPC_DERET: opn = "deret"; - check_insn(ctx, ISA_MIPS32); + check_insn(ctx, ISA_MIPS_R1); if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) { goto die; @@ -11021,7 +11021,7 @@ static void gen_cp0(CPUMIPSState *env, DisasContext *ctx, uint32_t opc, break; case OPC_WAIT: opn = "wait"; - check_insn(ctx, ISA_MIPS3 | ISA_MIPS32); + check_insn(ctx, ISA_MIPS3 | ISA_MIPS_R1); if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) { goto die; @@ -11056,7 +11056,7 @@ static void gen_compute_branch1(DisasContext *ctx, uint32_t op, } if (cc != 0) { - check_insn(ctx, ISA_MIPS4 | ISA_MIPS32); + check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1); } btarget = ctx->base.pc_next + 4 + offset; @@ -14425,7 +14425,7 @@ static int decode_extended_mips16_opc(CPUMIPSState *env, DisasContext *ctx) gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm); break; case I8_SVRS: - check_insn(ctx, ISA_MIPS32); + check_insn(ctx, ISA_MIPS_R1); { int xsregs = (ctx->opcode >> 24) & 0x7; int aregs = (ctx->opcode >> 16) & 0xf; @@ -14675,7 +14675,7 @@ static int decode_mips16_opc(CPUMIPSState *env, DisasContext *ctx) ((int8_t)ctx->opcode) << 3); break; case I8_SVRS: - check_insn(ctx, ISA_MIPS32); + check_insn(ctx, ISA_MIPS_R1); { int do_ra = ctx->opcode & (1 << 6); int do_s0 = ctx->opcode & (1 << 5); @@ -14819,7 +14819,7 @@ static int decode_mips16_opc(CPUMIPSState *env, DisasContext *ctx) int ra = (ctx->opcode >> 5) & 0x1; if (nd) { - check_insn(ctx, ISA_MIPS32); + check_insn(ctx, ISA_MIPS_R1); } if (link) { @@ -14840,7 +14840,7 @@ static int decode_mips16_opc(CPUMIPSState *env, DisasContext *ctx) * XXX: not clear which exception should be raised * when in debug mode... */ - check_insn(ctx, ISA_MIPS32); + check_insn(ctx, ISA_MIPS_R1); generate_exception_end(ctx, EXCP_DBp); } break; @@ -14891,7 +14891,7 @@ static int decode_mips16_opc(CPUMIPSState *env, DisasContext *ctx) gen_HILO(ctx, OPC_MFHI, 0, rx); break; case RR_CNVT: - check_insn(ctx, ISA_MIPS32); + check_insn(ctx, ISA_MIPS_R1); switch (cnvt_op) { case RR_RY_CNVT_ZEB: tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]); @@ -14907,12 +14907,12 @@ static int decode_mips16_opc(CPUMIPSState *env, DisasContext *ctx) break; #if defined(TARGET_MIPS64) case RR_RY_CNVT_ZEW: - check_insn(ctx, ISA_MIPS32); + check_insn(ctx, ISA_MIPS_R1); check_mips_64(ctx); tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]); break; case RR_RY_CNVT_SEW: - check_insn(ctx, ISA_MIPS32); + check_insn(ctx, ISA_MIPS_R1); check_mips_64(ctx); tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]); break; @@ -15831,7 +15831,7 @@ static void gen_pool16c_insn(DisasContext *ctx) * XXX: not clear which exception should be raised * when in debug mode... */ - check_insn(ctx, ISA_MIPS32); + check_insn(ctx, ISA_MIPS_R1); generate_exception_end(ctx, EXCP_DBp); } break; @@ -16175,7 +16175,7 @@ static void gen_pool32axf(CPUMIPSState *env, DisasContext *ctx, int rt, int rs) case CLZ: mips32_op = OPC_CLZ; do_cl: - check_insn(ctx, ISA_MIPS32); + check_insn(ctx, ISA_MIPS_R1); gen_cl(ctx, mips32_op, rt, rs); break; case RDHWR: @@ -16202,7 +16202,7 @@ static void gen_pool32axf(CPUMIPSState *env, DisasContext *ctx, int rt, int rs) mips32_op = OPC_DIVU; goto do_div; do_div: - check_insn(ctx, ISA_MIPS32); + check_insn(ctx, ISA_MIPS_R1); gen_muldiv(ctx, mips32_op, 0, rs, rt); break; case MADD: @@ -16221,7 +16221,7 @@ static void gen_pool32axf(CPUMIPSState *env, DisasContext *ctx, int rt, int rs) check_insn_opc_removed(ctx, ISA_MIPS32R6); mips32_op = OPC_MSUBU; do_mul: - check_insn(ctx, ISA_MIPS32); + check_insn(ctx, ISA_MIPS_R1); gen_muldiv(ctx, mips32_op, 0, rs, rt); break; default: @@ -16369,7 +16369,7 @@ static void gen_pool32axf(CPUMIPSState *env, DisasContext *ctx, int rt, int rs) if (is_uhi(extract32(ctx->opcode, 16, 10))) { gen_helper_do_semihosting(cpu_env); } else { - check_insn(ctx, ISA_MIPS32); + check_insn(ctx, ISA_MIPS_R1); if (ctx->hflags & MIPS_HFLAG_SBRI) { generate_exception_end(ctx, EXCP_RI); } else { @@ -24889,7 +24889,7 @@ static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx) switch (op1) { case OPC_MOVN: /* Conditional move */ case OPC_MOVZ: - check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 | + check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1 | INSN_LOONGSON2E | INSN_LOONGSON2F); gen_cond_move(ctx, op1, rd, rs, rt); break; @@ -24902,7 +24902,7 @@ static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx) gen_HILO(ctx, op1, rd & 3, rs); break; case OPC_MOVCI: - check_insn(ctx, ISA_MIPS4 | ISA_MIPS32); + check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1); if (env->CP0_Config1 & (1 << CP0C1_FP)) { check_cp1_enabled(ctx); gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7, @@ -27577,7 +27577,7 @@ static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx) case OPC_MADDU: case OPC_MSUB: case OPC_MSUBU: - check_insn(ctx, ISA_MIPS32); + check_insn(ctx, ISA_MIPS_R1); gen_muldiv(ctx, op1, rd & 3, rs, rt); break; case OPC_MUL: @@ -27594,7 +27594,7 @@ static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx) break; case OPC_CLO: case OPC_CLZ: - check_insn(ctx, ISA_MIPS32); + check_insn(ctx, ISA_MIPS_R1); gen_cl(ctx, op1, rd, rs); break; case OPC_SDBBP: @@ -27605,14 +27605,14 @@ static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx) * XXX: not clear which exception should be raised * when in debug mode... */ - check_insn(ctx, ISA_MIPS32); + check_insn(ctx, ISA_MIPS_R1); generate_exception_end(ctx, EXCP_DBp); } break; #if defined(TARGET_MIPS64) case OPC_DCLO: case OPC_DCLZ: - check_insn(ctx, ISA_MIPS32); + check_insn(ctx, ISA_MIPS_R1); check_mips_64(ctx); gen_cl(ctx, op1, rd, rs); break; @@ -31025,7 +31025,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) case OPC_CACHE: check_insn_opc_removed(ctx, ISA_MIPS32R6); check_cp0_enabled(ctx); - check_insn(ctx, ISA_MIPS3 | ISA_MIPS32); + check_insn(ctx, ISA_MIPS3 | ISA_MIPS_R1); if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) { gen_cache_operation(ctx, rt, rs, imm); } @@ -31036,7 +31036,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) if (ctx->insn_flags & INSN_R5900) { /* Treat as NOP. */ } else { - check_insn(ctx, ISA_MIPS4 | ISA_MIPS32); + check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1); /* Treat as NOP. */ } break; -- cgit v1.2.3-55-g7522 From 7a47bae586865498ac55531141d9c3d4d9e3ff83 Mon Sep 17 00:00:00 2001 From: Philippe Mathieu-Daudé Date: Wed, 16 Dec 2020 12:29:00 +0100 Subject: target/mips/mips-defs: Rename ISA_MIPS32R2 as ISA_MIPS_R2 The MIPS ISA release 2 is common to 32/64-bit CPUs. Reviewed-by: Richard Henderson Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20210104221154.3127610-13-f4bug@amsat.org> --- linux-user/mips/cpu_loop.c | 2 +- target/mips/cp0_timer.c | 4 +- target/mips/helper.c | 2 +- target/mips/internal.h | 2 +- target/mips/mips-defs.h | 4 +- target/mips/translate.c | 138 ++++++++++++++++++++++----------------------- 6 files changed, 76 insertions(+), 76 deletions(-) diff --git a/linux-user/mips/cpu_loop.c b/linux-user/mips/cpu_loop.c index e400166c58..748e1c664f 100644 --- a/linux-user/mips/cpu_loop.c +++ b/linux-user/mips/cpu_loop.c @@ -384,7 +384,7 @@ void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs) prog_req.frdefault &= interp_req.frdefault; prog_req.fre &= interp_req.fre; - bool cpu_has_mips_r2_r6 = env->insn_flags & ISA_MIPS32R2 || + bool cpu_has_mips_r2_r6 = env->insn_flags & ISA_MIPS_R2 || env->insn_flags & ISA_MIPS32R6; if (prog_req.fre && !prog_req.frdefault && !prog_req.fr1) { diff --git a/target/mips/cp0_timer.c b/target/mips/cp0_timer.c index 5ec0d6249e..70de95d338 100644 --- a/target/mips/cp0_timer.c +++ b/target/mips/cp0_timer.c @@ -44,7 +44,7 @@ static void cpu_mips_timer_update(CPUMIPSState *env) static void cpu_mips_timer_expire(CPUMIPSState *env) { cpu_mips_timer_update(env); - if (env->insn_flags & ISA_MIPS32R2) { + if (env->insn_flags & ISA_MIPS_R2) { env->CP0_Cause |= 1 << CP0Ca_TI; } qemu_irq_raise(env->irq[(env->CP0_IntCtl >> CP0IntCtl_IPTI) & 0x7]); @@ -93,7 +93,7 @@ void cpu_mips_store_compare(CPUMIPSState *env, uint32_t value) if (!(env->CP0_Cause & (1 << CP0Ca_DC))) { cpu_mips_timer_update(env); } - if (env->insn_flags & ISA_MIPS32R2) { + if (env->insn_flags & ISA_MIPS_R2) { env->CP0_Cause &= ~(1 << CP0Ca_TI); } qemu_irq_lower(env->irq[(env->CP0_IntCtl >> CP0IntCtl_IPTI) & 0x7]); diff --git a/target/mips/helper.c b/target/mips/helper.c index 5b74815beb..98d6ecaa65 100644 --- a/target/mips/helper.c +++ b/target/mips/helper.c @@ -431,7 +431,7 @@ void cpu_mips_store_cause(CPUMIPSState *env, target_ulong val) uint32_t old = env->CP0_Cause; int i; - if (env->insn_flags & ISA_MIPS32R2) { + if (env->insn_flags & ISA_MIPS_R2) { mask |= 1 << CP0Ca_DC; } if (env->insn_flags & ISA_MIPS32R6) { diff --git a/target/mips/internal.h b/target/mips/internal.h index 94910f75a6..23ae31ef98 100644 --- a/target/mips/internal.h +++ b/target/mips/internal.h @@ -407,7 +407,7 @@ static inline void compute_hflags(CPUMIPSState *env) } } - if (env->insn_flags & ISA_MIPS32R2) { + if (env->insn_flags & ISA_MIPS_R2) { if (env->active_fpu.fcr0 & (1 << FCR0_F64)) { env->hflags |= MIPS_HFLAG_COP1X; } diff --git a/target/mips/mips-defs.h b/target/mips/mips-defs.h index a7048ffaff..d1eeb69dfd 100644 --- a/target/mips/mips-defs.h +++ b/target/mips/mips-defs.h @@ -17,7 +17,7 @@ #define ISA_MIPS4 0x0000000000000008ULL #define ISA_MIPS5 0x0000000000000010ULL #define ISA_MIPS_R1 0x0000000000000020ULL -#define ISA_MIPS32R2 0x0000000000000040ULL +#define ISA_MIPS_R2 0x0000000000000040ULL #define ISA_MIPS32R3 0x0000000000000200ULL #define ISA_MIPS32R5 0x0000000000000800ULL #define ISA_MIPS32R6 0x0000000000002000ULL @@ -73,7 +73,7 @@ #define CPU_MIPS64R1 (CPU_MIPS5 | CPU_MIPS32R1) /* MIPS Technologies "Release 2" */ -#define CPU_MIPS32R2 (CPU_MIPS32R1 | ISA_MIPS32R2) +#define CPU_MIPS32R2 (CPU_MIPS32R1 | ISA_MIPS_R2) #define CPU_MIPS64R2 (CPU_MIPS64R1 | CPU_MIPS32R2) /* MIPS Technologies "Release 3" */ diff --git a/target/mips/translate.c b/target/mips/translate.c index a59fbd94ba..9c71d306ee 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -7612,7 +7612,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) register_name = "PageMask"; break; case CP0_REG05__PAGEGRAIN: - check_insn(ctx, ISA_MIPS32R2); + check_insn(ctx, ISA_MIPS_R2); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain)); register_name = "PageGrain"; break; @@ -7660,27 +7660,27 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) register_name = "Wired"; break; case CP0_REG06__SRSCONF0: - check_insn(ctx, ISA_MIPS32R2); + check_insn(ctx, ISA_MIPS_R2); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0)); register_name = "SRSConf0"; break; case CP0_REG06__SRSCONF1: - check_insn(ctx, ISA_MIPS32R2); + check_insn(ctx, ISA_MIPS_R2); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1)); register_name = "SRSConf1"; break; case CP0_REG06__SRSCONF2: - check_insn(ctx, ISA_MIPS32R2); + check_insn(ctx, ISA_MIPS_R2); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2)); register_name = "SRSConf2"; break; case CP0_REG06__SRSCONF3: - check_insn(ctx, ISA_MIPS32R2); + check_insn(ctx, ISA_MIPS_R2); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3)); register_name = "SRSConf3"; break; case CP0_REG06__SRSCONF4: - check_insn(ctx, ISA_MIPS32R2); + check_insn(ctx, ISA_MIPS_R2); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4)); register_name = "SRSConf4"; break; @@ -7696,7 +7696,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) case CP0_REGISTER_07: switch (sel) { case CP0_REG07__HWRENA: - check_insn(ctx, ISA_MIPS32R2); + check_insn(ctx, ISA_MIPS_R2); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna)); register_name = "HWREna"; break; @@ -7791,17 +7791,17 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) register_name = "Status"; break; case CP0_REG12__INTCTL: - check_insn(ctx, ISA_MIPS32R2); + check_insn(ctx, ISA_MIPS_R2); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl)); register_name = "IntCtl"; break; case CP0_REG12__SRSCTL: - check_insn(ctx, ISA_MIPS32R2); + check_insn(ctx, ISA_MIPS_R2); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl)); register_name = "SRSCtl"; break; case CP0_REG12__SRSMAP: - check_insn(ctx, ISA_MIPS32R2); + check_insn(ctx, ISA_MIPS_R2); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); register_name = "SRSMap"; break; @@ -7837,13 +7837,13 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) register_name = "PRid"; break; case CP0_REG15__EBASE: - check_insn(ctx, ISA_MIPS32R2); + check_insn(ctx, ISA_MIPS_R2); tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase)); tcg_gen_ext32s_tl(arg, arg); register_name = "EBase"; break; case CP0_REG15__CMGCRBASE: - check_insn(ctx, ISA_MIPS32R2); + check_insn(ctx, ISA_MIPS_R2); CP0_CHECK(ctx->cmgcr); tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase)); tcg_gen_ext32s_tl(arg, arg); @@ -8357,7 +8357,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) register_name = "PageMask"; break; case CP0_REG05__PAGEGRAIN: - check_insn(ctx, ISA_MIPS32R2); + check_insn(ctx, ISA_MIPS_R2); gen_helper_mtc0_pagegrain(cpu_env, arg); register_name = "PageGrain"; ctx->base.is_jmp = DISAS_STOP; @@ -8403,27 +8403,27 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) register_name = "Wired"; break; case CP0_REG06__SRSCONF0: - check_insn(ctx, ISA_MIPS32R2); + check_insn(ctx, ISA_MIPS_R2); gen_helper_mtc0_srsconf0(cpu_env, arg); register_name = "SRSConf0"; break; case CP0_REG06__SRSCONF1: - check_insn(ctx, ISA_MIPS32R2); + check_insn(ctx, ISA_MIPS_R2); gen_helper_mtc0_srsconf1(cpu_env, arg); register_name = "SRSConf1"; break; case CP0_REG06__SRSCONF2: - check_insn(ctx, ISA_MIPS32R2); + check_insn(ctx, ISA_MIPS_R2); gen_helper_mtc0_srsconf2(cpu_env, arg); register_name = "SRSConf2"; break; case CP0_REG06__SRSCONF3: - check_insn(ctx, ISA_MIPS32R2); + check_insn(ctx, ISA_MIPS_R2); gen_helper_mtc0_srsconf3(cpu_env, arg); register_name = "SRSConf3"; break; case CP0_REG06__SRSCONF4: - check_insn(ctx, ISA_MIPS32R2); + check_insn(ctx, ISA_MIPS_R2); gen_helper_mtc0_srsconf4(cpu_env, arg); register_name = "SRSConf4"; break; @@ -8439,7 +8439,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) case CP0_REGISTER_07: switch (sel) { case CP0_REG07__HWRENA: - check_insn(ctx, ISA_MIPS32R2); + check_insn(ctx, ISA_MIPS_R2); gen_helper_mtc0_hwrena(cpu_env, arg); ctx->base.is_jmp = DISAS_STOP; register_name = "HWREna"; @@ -8522,21 +8522,21 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) register_name = "Status"; break; case CP0_REG12__INTCTL: - check_insn(ctx, ISA_MIPS32R2); + check_insn(ctx, ISA_MIPS_R2); gen_helper_mtc0_intctl(cpu_env, arg); /* Stop translation as we may have switched the execution mode */ ctx->base.is_jmp = DISAS_STOP; register_name = "IntCtl"; break; case CP0_REG12__SRSCTL: - check_insn(ctx, ISA_MIPS32R2); + check_insn(ctx, ISA_MIPS_R2); gen_helper_mtc0_srsctl(cpu_env, arg); /* Stop translation as we may have switched the execution mode */ ctx->base.is_jmp = DISAS_STOP; register_name = "SRSCtl"; break; case CP0_REG12__SRSMAP: - check_insn(ctx, ISA_MIPS32R2); + check_insn(ctx, ISA_MIPS_R2); gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); /* Stop translation as we may have switched the execution mode */ ctx->base.is_jmp = DISAS_STOP; @@ -8581,7 +8581,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) register_name = "PRid"; break; case CP0_REG15__EBASE: - check_insn(ctx, ISA_MIPS32R2); + check_insn(ctx, ISA_MIPS_R2); gen_helper_mtc0_ebase(cpu_env, arg); register_name = "EBase"; break; @@ -9120,7 +9120,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) register_name = "PageMask"; break; case CP0_REG05__PAGEGRAIN: - check_insn(ctx, ISA_MIPS32R2); + check_insn(ctx, ISA_MIPS_R2); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain)); register_name = "PageGrain"; break; @@ -9165,27 +9165,27 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) register_name = "Wired"; break; case CP0_REG06__SRSCONF0: - check_insn(ctx, ISA_MIPS32R2); + check_insn(ctx, ISA_MIPS_R2); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0)); register_name = "SRSConf0"; break; case CP0_REG06__SRSCONF1: - check_insn(ctx, ISA_MIPS32R2); + check_insn(ctx, ISA_MIPS_R2); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1)); register_name = "SRSConf1"; break; case CP0_REG06__SRSCONF2: - check_insn(ctx, ISA_MIPS32R2); + check_insn(ctx, ISA_MIPS_R2); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2)); register_name = "SRSConf2"; break; case CP0_REG06__SRSCONF3: - check_insn(ctx, ISA_MIPS32R2); + check_insn(ctx, ISA_MIPS_R2); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3)); register_name = "SRSConf3"; break; case CP0_REG06__SRSCONF4: - check_insn(ctx, ISA_MIPS32R2); + check_insn(ctx, ISA_MIPS_R2); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4)); register_name = "SRSConf4"; break; @@ -9201,7 +9201,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) case CP0_REGISTER_07: switch (sel) { case CP0_REG07__HWRENA: - check_insn(ctx, ISA_MIPS32R2); + check_insn(ctx, ISA_MIPS_R2); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna)); register_name = "HWREna"; break; @@ -9294,17 +9294,17 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) register_name = "Status"; break; case CP0_REG12__INTCTL: - check_insn(ctx, ISA_MIPS32R2); + check_insn(ctx, ISA_MIPS_R2); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl)); register_name = "IntCtl"; break; case CP0_REG12__SRSCTL: - check_insn(ctx, ISA_MIPS32R2); + check_insn(ctx, ISA_MIPS_R2); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl)); register_name = "SRSCtl"; break; case CP0_REG12__SRSMAP: - check_insn(ctx, ISA_MIPS32R2); + check_insn(ctx, ISA_MIPS_R2); gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); register_name = "SRSMap"; break; @@ -9339,12 +9339,12 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) register_name = "PRid"; break; case CP0_REG15__EBASE: - check_insn(ctx, ISA_MIPS32R2); + check_insn(ctx, ISA_MIPS_R2); tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase)); register_name = "EBase"; break; case CP0_REG15__CMGCRBASE: - check_insn(ctx, ISA_MIPS32R2); + check_insn(ctx, ISA_MIPS_R2); CP0_CHECK(ctx->cmgcr); tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase)); register_name = "CMGCRBase"; @@ -9847,7 +9847,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) register_name = "PageMask"; break; case CP0_REG05__PAGEGRAIN: - check_insn(ctx, ISA_MIPS32R2); + check_insn(ctx, ISA_MIPS_R2); gen_helper_mtc0_pagegrain(cpu_env, arg); register_name = "PageGrain"; break; @@ -9892,27 +9892,27 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) register_name = "Wired"; break; case CP0_REG06__SRSCONF0: - check_insn(ctx, ISA_MIPS32R2); + check_insn(ctx, ISA_MIPS_R2); gen_helper_mtc0_srsconf0(cpu_env, arg); register_name = "SRSConf0"; break; case CP0_REG06__SRSCONF1: - check_insn(ctx, ISA_MIPS32R2); + check_insn(ctx, ISA_MIPS_R2); gen_helper_mtc0_srsconf1(cpu_env, arg); register_name = "SRSConf1"; break; case CP0_REG06__SRSCONF2: - check_insn(ctx, ISA_MIPS32R2); + check_insn(ctx, ISA_MIPS_R2); gen_helper_mtc0_srsconf2(cpu_env, arg); register_name = "SRSConf2"; break; case CP0_REG06__SRSCONF3: - check_insn(ctx, ISA_MIPS32R2); + check_insn(ctx, ISA_MIPS_R2); gen_helper_mtc0_srsconf3(cpu_env, arg); register_name = "SRSConf3"; break; case CP0_REG06__SRSCONF4: - check_insn(ctx, ISA_MIPS32R2); + check_insn(ctx, ISA_MIPS_R2); gen_helper_mtc0_srsconf4(cpu_env, arg); register_name = "SRSConf4"; break; @@ -9928,7 +9928,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) case CP0_REGISTER_07: switch (sel) { case CP0_REG07__HWRENA: - check_insn(ctx, ISA_MIPS32R2); + check_insn(ctx, ISA_MIPS_R2); gen_helper_mtc0_hwrena(cpu_env, arg); ctx->base.is_jmp = DISAS_STOP; register_name = "HWREna"; @@ -10015,21 +10015,21 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) register_name = "Status"; break; case CP0_REG12__INTCTL: - check_insn(ctx, ISA_MIPS32R2); + check_insn(ctx, ISA_MIPS_R2); gen_helper_mtc0_intctl(cpu_env, arg); /* Stop translation as we may have switched the execution mode */ ctx->base.is_jmp = DISAS_STOP; register_name = "IntCtl"; break; case CP0_REG12__SRSCTL: - check_insn(ctx, ISA_MIPS32R2); + check_insn(ctx, ISA_MIPS_R2); gen_helper_mtc0_srsctl(cpu_env, arg); /* Stop translation as we may have switched the execution mode */ ctx->base.is_jmp = DISAS_STOP; register_name = "SRSCtl"; break; case CP0_REG12__SRSMAP: - check_insn(ctx, ISA_MIPS32R2); + check_insn(ctx, ISA_MIPS_R2); gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); /* Stop translation as we may have switched the execution mode */ ctx->base.is_jmp = DISAS_STOP; @@ -10074,7 +10074,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) register_name = "PRid"; break; case CP0_REG15__EBASE: - check_insn(ctx, ISA_MIPS32R2); + check_insn(ctx, ISA_MIPS_R2); gen_helper_mtc0_ebase(cpu_env, arg); register_name = "EBase"; break; @@ -13453,7 +13453,7 @@ static void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel) * The Linux kernel will emulate rdhwr if it's not supported natively. * Therefore only check the ISA in system mode. */ - check_insn(ctx, ISA_MIPS32R2); + check_insn(ctx, ISA_MIPS_R2); #endif t0 = tcg_temp_new(); @@ -16269,12 +16269,12 @@ static void gen_pool32axf(CPUMIPSState *env, DisasContext *ctx, int rt, int rs) switch (minor) { case RDPGPR: check_cp0_enabled(ctx); - check_insn(ctx, ISA_MIPS32R2); + check_insn(ctx, ISA_MIPS_R2); gen_load_srsgpr(rs, rt); break; case WRPGPR: check_cp0_enabled(ctx); - check_insn(ctx, ISA_MIPS32R2); + check_insn(ctx, ISA_MIPS_R2); gen_store_srsgpr(rs, rt); break; default: @@ -24984,7 +24984,7 @@ static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx) switch ((ctx->opcode >> 21) & 0x1f) { case 1: /* rotr is decoded as srl on non-R2 CPUs */ - if (ctx->insn_flags & ISA_MIPS32R2) { + if (ctx->insn_flags & ISA_MIPS_R2) { op1 = OPC_ROTR; } /* Fallthrough */ @@ -25010,7 +25010,7 @@ static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx) switch ((ctx->opcode >> 6) & 0x1f) { case 1: /* rotrv is decoded as srlv on non-R2 CPUs */ - if (ctx->insn_flags & ISA_MIPS32R2) { + if (ctx->insn_flags & ISA_MIPS_R2) { op1 = OPC_ROTRV; } /* Fallthrough */ @@ -25083,7 +25083,7 @@ static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx) switch ((ctx->opcode >> 21) & 0x1f) { case 1: /* drotr is decoded as dsrl on non-R2 CPUs */ - if (ctx->insn_flags & ISA_MIPS32R2) { + if (ctx->insn_flags & ISA_MIPS_R2) { op1 = OPC_DROTR; } /* Fallthrough */ @@ -25101,7 +25101,7 @@ static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx) switch ((ctx->opcode >> 21) & 0x1f) { case 1: /* drotr32 is decoded as dsrl32 on non-R2 CPUs */ - if (ctx->insn_flags & ISA_MIPS32R2) { + if (ctx->insn_flags & ISA_MIPS_R2) { op1 = OPC_DROTR32; } /* Fallthrough */ @@ -25133,7 +25133,7 @@ static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx) switch ((ctx->opcode >> 6) & 0x1f) { case 1: /* drotrv is decoded as dsrlv on non-R2 CPUs */ - if (ctx->insn_flags & ISA_MIPS32R2) { + if (ctx->insn_flags & ISA_MIPS_R2) { op1 = OPC_DROTRV; } /* Fallthrough */ @@ -28594,7 +28594,7 @@ static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx) switch (op1) { case OPC_EXT: case OPC_INS: - check_insn(ctx, ISA_MIPS32R2); + check_insn(ctx, ISA_MIPS_R2); gen_bitops(ctx, op1, rt, rs, sa, rd); break; case OPC_BSHFL: @@ -28609,7 +28609,7 @@ static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx) decode_opc_special3_r6(env, ctx); break; default: - check_insn(ctx, ISA_MIPS32R2); + check_insn(ctx, ISA_MIPS_R2); gen_bshfl(ctx, op2, rt, rd); break; } @@ -28621,7 +28621,7 @@ static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx) case OPC_DINSM: case OPC_DINSU: case OPC_DINS: - check_insn(ctx, ISA_MIPS32R2); + check_insn(ctx, ISA_MIPS_R2); check_mips_64(ctx); gen_bitops(ctx, op1, rt, rs, sa, rd); break; @@ -28641,7 +28641,7 @@ static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx) decode_opc_special3_r6(env, ctx); break; default: - check_insn(ctx, ISA_MIPS32R2); + check_insn(ctx, ISA_MIPS_R2); check_mips_64(ctx); op2 = MASK_DBSHFL(ctx->opcode); gen_bshfl(ctx, op2, rt, rd); @@ -30741,7 +30741,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) generate_exception_end(ctx, EXCP_RI); break; case OPC_SYNCI: - check_insn(ctx, ISA_MIPS32R2); + check_insn(ctx, ISA_MIPS_R2); /* * Break the TB to be able to sync copied instructions * immediately. @@ -30858,7 +30858,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) } break; case OPC_DI: - check_insn(ctx, ISA_MIPS32R2); + check_insn(ctx, ISA_MIPS_R2); save_cpu_state(ctx, 1); gen_helper_di(t0, cpu_env); gen_store_gpr(t0, rt); @@ -30869,7 +30869,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) ctx->base.is_jmp = DISAS_STOP; break; case OPC_EI: - check_insn(ctx, ISA_MIPS32R2); + check_insn(ctx, ISA_MIPS_R2); save_cpu_state(ctx, 1); gen_helper_ei(t0, cpu_env); gen_store_gpr(t0, rt); @@ -30890,11 +30890,11 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) #endif /* !CONFIG_USER_ONLY */ break; case OPC_RDPGPR: - check_insn(ctx, ISA_MIPS32R2); + check_insn(ctx, ISA_MIPS_R2); gen_load_srsgpr(rt, rd); break; case OPC_WRPGPR: - check_insn(ctx, ISA_MIPS32R2); + check_insn(ctx, ISA_MIPS_R2); gen_store_srsgpr(rt, rd); break; default: @@ -31056,7 +31056,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) case OPC_MFHC1: case OPC_MTHC1: check_cp1_enabled(ctx); - check_insn(ctx, ISA_MIPS32R2); + check_insn(ctx, ISA_MIPS_R2); /* fall through */ case OPC_MFC1: case OPC_CFC1: @@ -31250,21 +31250,21 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) switch (op1) { case OPC_LUXC1: case OPC_SUXC1: - check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2); + check_insn(ctx, ISA_MIPS5 | ISA_MIPS_R2); /* Fallthrough */ case OPC_LWXC1: case OPC_LDXC1: case OPC_SWXC1: case OPC_SDXC1: - check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2); + check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2); gen_flt3_ldst(ctx, op1, sa, rd, rs, rt); break; case OPC_PREFX: - check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2); + check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2); /* Treat as NOP. */ break; case OPC_ALNV_PS: - check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2); + check_insn(ctx, ISA_MIPS5 | ISA_MIPS_R2); /* Fallthrough */ case OPC_MADD_S: case OPC_MADD_D: @@ -31278,7 +31278,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) case OPC_NMSUB_S: case OPC_NMSUB_D: case OPC_NMSUB_PS: - check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2); + check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2); gen_flt3_arith(ctx, op1, sa, rs, rd, rt); break; default: -- cgit v1.2.3-55-g7522 From bae4b15aa4fa56815e08cee395486a1c990caa99 Mon Sep 17 00:00:00 2001 From: Philippe Mathieu-Daudé Date: Wed, 16 Dec 2020 12:29:34 +0100 Subject: target/mips/mips-defs: Rename ISA_MIPS32R3 as ISA_MIPS_R3 The MIPS ISA release 3 is common to 32/64-bit CPUs. To avoid holes in the insn_flags type, update the definition with the next available bit. Reviewed-by: Richard Henderson Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20210104221154.3127610-14-f4bug@amsat.org> --- target/mips/mips-defs.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/target/mips/mips-defs.h b/target/mips/mips-defs.h index d1eeb69dfd..12ff2b3280 100644 --- a/target/mips/mips-defs.h +++ b/target/mips/mips-defs.h @@ -18,7 +18,7 @@ #define ISA_MIPS5 0x0000000000000010ULL #define ISA_MIPS_R1 0x0000000000000020ULL #define ISA_MIPS_R2 0x0000000000000040ULL -#define ISA_MIPS32R3 0x0000000000000200ULL +#define ISA_MIPS_R3 0x0000000000000080ULL #define ISA_MIPS32R5 0x0000000000000800ULL #define ISA_MIPS32R6 0x0000000000002000ULL #define ISA_NANOMIPS32 0x0000000000008000ULL @@ -77,7 +77,7 @@ #define CPU_MIPS64R2 (CPU_MIPS64R1 | CPU_MIPS32R2) /* MIPS Technologies "Release 3" */ -#define CPU_MIPS32R3 (CPU_MIPS32R2 | ISA_MIPS32R3) +#define CPU_MIPS32R3 (CPU_MIPS32R2 | ISA_MIPS_R3) #define CPU_MIPS64R3 (CPU_MIPS64R2 | CPU_MIPS32R3) /* MIPS Technologies "Release 5" */ -- cgit v1.2.3-55-g7522 From 5f89ce4fc2afdb81eaed90f337d7016207a2b176 Mon Sep 17 00:00:00 2001 From: Philippe Mathieu-Daudé Date: Wed, 16 Dec 2020 12:30:11 +0100 Subject: target/mips/mips-defs: Rename ISA_MIPS32R5 as ISA_MIPS_R5 The MIPS ISA release 5 is common to 32/64-bit CPUs. To avoid holes in the insn_flags type, update the definition with the next available bit. Reviewed-by: Richard Henderson Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20210104221154.3127610-15-f4bug@amsat.org> --- target/mips/mips-defs.h | 4 ++-- target/mips/translate.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/target/mips/mips-defs.h b/target/mips/mips-defs.h index 12ff2b3280..181f371547 100644 --- a/target/mips/mips-defs.h +++ b/target/mips/mips-defs.h @@ -19,7 +19,7 @@ #define ISA_MIPS_R1 0x0000000000000020ULL #define ISA_MIPS_R2 0x0000000000000040ULL #define ISA_MIPS_R3 0x0000000000000080ULL -#define ISA_MIPS32R5 0x0000000000000800ULL +#define ISA_MIPS_R5 0x0000000000000100ULL #define ISA_MIPS32R6 0x0000000000002000ULL #define ISA_NANOMIPS32 0x0000000000008000ULL /* @@ -81,7 +81,7 @@ #define CPU_MIPS64R3 (CPU_MIPS64R2 | CPU_MIPS32R3) /* MIPS Technologies "Release 5" */ -#define CPU_MIPS32R5 (CPU_MIPS32R3 | ISA_MIPS32R5) +#define CPU_MIPS32R5 (CPU_MIPS32R3 | ISA_MIPS_R5) #define CPU_MIPS64R5 (CPU_MIPS64R3 | CPU_MIPS32R5) /* MIPS Technologies "Release 6" */ diff --git a/target/mips/translate.c b/target/mips/translate.c index 9c71d306ee..83fd6c473a 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -10993,7 +10993,7 @@ static void gen_cp0(CPUMIPSState *env, DisasContext *ctx, uint32_t opc, if (ctx->opcode & (1 << bit_shift)) { /* OPC_ERETNC */ opn = "eretnc"; - check_insn(ctx, ISA_MIPS32R5); + check_insn(ctx, ISA_MIPS_R5); gen_helper_eretnc(cpu_env); } else { /* OPC_ERET */ -- cgit v1.2.3-55-g7522 From 2e211e0a12e6cde512b65d25799bb3ac25baa371 Mon Sep 17 00:00:00 2001 From: Philippe Mathieu-Daudé Date: Wed, 16 Dec 2020 12:34:42 +0100 Subject: target/mips/mips-defs: Rename ISA_MIPS32R6 as ISA_MIPS_R6 The MIPS ISA release 6 is common to 32/64-bit CPUs. To avoid holes in the insn_flags type, update the definition with the next available bit. Reviewed-by: Richard Henderson Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20210104221154.3127610-16-f4bug@amsat.org> --- linux-user/mips/cpu_loop.c | 2 +- target/mips/cp0_helper.c | 18 +- target/mips/cpu.c | 6 +- target/mips/fpu_helper.c | 4 +- target/mips/helper.c | 10 +- target/mips/internal.h | 4 +- target/mips/mips-defs.h | 4 +- target/mips/translate.c | 426 ++++++++++++++++++++++----------------------- 8 files changed, 237 insertions(+), 237 deletions(-) diff --git a/linux-user/mips/cpu_loop.c b/linux-user/mips/cpu_loop.c index 748e1c664f..19947448a2 100644 --- a/linux-user/mips/cpu_loop.c +++ b/linux-user/mips/cpu_loop.c @@ -385,7 +385,7 @@ void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs) prog_req.fre &= interp_req.fre; bool cpu_has_mips_r2_r6 = env->insn_flags & ISA_MIPS_R2 || - env->insn_flags & ISA_MIPS32R6; + env->insn_flags & ISA_MIPS_R6; if (prog_req.fre && !prog_req.frdefault && !prog_req.fr1) { env->CP0_Config5 |= (1 << CP0C5_FRE); diff --git a/target/mips/cp0_helper.c b/target/mips/cp0_helper.c index 36a92857bf..aae2af6ecc 100644 --- a/target/mips/cp0_helper.c +++ b/target/mips/cp0_helper.c @@ -527,7 +527,7 @@ void helper_mtc0_index(CPUMIPSState *env, target_ulong arg1) uint32_t index_p = env->CP0_Index & 0x80000000; uint32_t tlb_index = arg1 & 0x7fffffff; if (tlb_index < env->tlb->nb_tlb) { - if (env->insn_flags & ISA_MIPS32R6) { + if (env->insn_flags & ISA_MIPS_R6) { index_p |= arg1 & 0x80000000; } env->CP0_Index = index_p | tlb_index; @@ -960,7 +960,7 @@ void helper_mtc0_pwfield(CPUMIPSState *env, target_ulong arg1) uint32_t old_ptei = (env->CP0_PWField >> CP0PF_PTEI) & 0x3FULL; uint32_t new_ptei = (arg1 >> CP0PF_PTEI) & 0x3FULL; - if ((env->insn_flags & ISA_MIPS32R6)) { + if ((env->insn_flags & ISA_MIPS_R6)) { if (((arg1 >> CP0PF_BDI) & 0x3FULL) < 12) { mask &= ~(0x3FULL << CP0PF_BDI); } @@ -980,7 +980,7 @@ void helper_mtc0_pwfield(CPUMIPSState *env, target_ulong arg1) env->CP0_PWField = arg1 & mask; if ((new_ptei >= 32) || - ((env->insn_flags & ISA_MIPS32R6) && + ((env->insn_flags & ISA_MIPS_R6) && (new_ptei == 0 || new_ptei == 1))) { env->CP0_PWField = (env->CP0_PWField & ~0x3FULL) | (old_ptei << CP0PF_PTEI); @@ -990,7 +990,7 @@ void helper_mtc0_pwfield(CPUMIPSState *env, target_ulong arg1) uint32_t old_ptew = (env->CP0_PWField >> CP0PF_PTEW) & 0x3F; uint32_t new_ptew = (arg1 >> CP0PF_PTEW) & 0x3F; - if ((env->insn_flags & ISA_MIPS32R6)) { + if ((env->insn_flags & ISA_MIPS_R6)) { if (((arg1 >> CP0PF_GDW) & 0x3F) < 12) { mask &= ~(0x3F << CP0PF_GDW); } @@ -1007,7 +1007,7 @@ void helper_mtc0_pwfield(CPUMIPSState *env, target_ulong arg1) env->CP0_PWField = arg1 & mask; if ((new_ptew >= 32) || - ((env->insn_flags & ISA_MIPS32R6) && + ((env->insn_flags & ISA_MIPS_R6) && (new_ptew == 0 || new_ptew == 1))) { env->CP0_PWField = (env->CP0_PWField & ~0x3F) | (old_ptew << CP0PF_PTEW); @@ -1026,7 +1026,7 @@ void helper_mtc0_pwsize(CPUMIPSState *env, target_ulong arg1) void helper_mtc0_wired(CPUMIPSState *env, target_ulong arg1) { - if (env->insn_flags & ISA_MIPS32R6) { + if (env->insn_flags & ISA_MIPS_R6) { if (arg1 < env->tlb->nb_tlb) { env->CP0_Wired = arg1; } @@ -1075,10 +1075,10 @@ void helper_mtc0_hwrena(CPUMIPSState *env, target_ulong arg1) uint32_t mask = 0x0000000F; if ((env->CP0_Config1 & (1 << CP0C1_PC)) && - (env->insn_flags & ISA_MIPS32R6)) { + (env->insn_flags & ISA_MIPS_R6)) { mask |= (1 << 4); } - if (env->insn_flags & ISA_MIPS32R6) { + if (env->insn_flags & ISA_MIPS_R6) { mask |= (1 << 5); } if (env->CP0_Config3 & (1 << CP0C3_ULRI)) { @@ -1149,7 +1149,7 @@ void helper_mtc0_entryhi(CPUMIPSState *env, target_ulong arg1) /* 1k pages not implemented */ #if defined(TARGET_MIPS64) - if (env->insn_flags & ISA_MIPS32R6) { + if (env->insn_flags & ISA_MIPS_R6) { int entryhi_r = extract64(arg1, 62, 2); int config0_at = extract32(env->CP0_Config0, 13, 2); bool no_supervisor = (env->CP0_Status_rw_bitmask & 0x8) == 0; diff --git a/target/mips/cpu.c b/target/mips/cpu.c index b2864d67d7..cb70fb2b9b 100644 --- a/target/mips/cpu.c +++ b/target/mips/cpu.c @@ -72,7 +72,7 @@ static bool mips_cpu_has_work(CPUState *cs) if ((cs->interrupt_request & CPU_INTERRUPT_HARD) && cpu_mips_hw_interrupts_pending(env)) { if (cpu_mips_hw_interrupts_enabled(env) || - (env->insn_flags & ISA_MIPS32R6)) { + (env->insn_flags & ISA_MIPS_R6)) { has_work = true; } } @@ -288,13 +288,13 @@ static void cpu_state_reset(CPUMIPSState *env) /* XKPhys (note, SegCtl2.XR = 0, so XAM won't be used) */ env->CP0_SegCtl1 |= (CP0SC_AM_UK << CP0SC1_XAM); #endif /* !CONFIG_USER_ONLY */ - if ((env->insn_flags & ISA_MIPS32R6) && + if ((env->insn_flags & ISA_MIPS_R6) && (env->active_fpu.fcr0 & (1 << FCR0_F64))) { /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */ env->CP0_Status |= (1 << CP0St_FR); } - if (env->insn_flags & ISA_MIPS32R6) { + if (env->insn_flags & ISA_MIPS_R6) { /* PTW = 1 */ env->CP0_PWSize = 0x40; /* GDI = 12 */ diff --git a/target/mips/fpu_helper.c b/target/mips/fpu_helper.c index bdb65065ee..91b6a2e11f 100644 --- a/target/mips/fpu_helper.c +++ b/target/mips/fpu_helper.c @@ -145,7 +145,7 @@ void helper_ctc1(CPUMIPSState *env, target_ulong arg1, uint32_t fs, uint32_t rt) } break; case 25: - if ((env->insn_flags & ISA_MIPS32R6) || (arg1 & 0xffffff00)) { + if ((env->insn_flags & ISA_MIPS_R6) || (arg1 & 0xffffff00)) { return; } env->active_fpu.fcr31 = (env->active_fpu.fcr31 & 0x017fffff) | @@ -172,7 +172,7 @@ void helper_ctc1(CPUMIPSState *env, target_ulong arg1, uint32_t fs, uint32_t rt) (env->active_fpu.fcr31 & ~(env->active_fpu.fcr31_rw_bitmask)); break; default: - if (env->insn_flags & ISA_MIPS32R6) { + if (env->insn_flags & ISA_MIPS_R6) { do_raise_exception(env, EXCP_RI, GETPC()); } return; diff --git a/target/mips/helper.c b/target/mips/helper.c index 98d6ecaa65..d1b6bb6fb2 100644 --- a/target/mips/helper.c +++ b/target/mips/helper.c @@ -397,7 +397,7 @@ void cpu_mips_store_status(CPUMIPSState *env, target_ulong val) uint32_t mask = env->CP0_Status_rw_bitmask; target_ulong old = env->CP0_Status; - if (env->insn_flags & ISA_MIPS32R6) { + if (env->insn_flags & ISA_MIPS_R6) { bool has_supervisor = extract32(mask, CP0St_KSU, 2) == 0x3; #if defined(TARGET_MIPS64) uint32_t ksux = (1 << CP0St_KX) & val; @@ -434,7 +434,7 @@ void cpu_mips_store_cause(CPUMIPSState *env, target_ulong val) if (env->insn_flags & ISA_MIPS_R2) { mask |= 1 << CP0Ca_DC; } - if (env->insn_flags & ISA_MIPS32R6) { + if (env->insn_flags & ISA_MIPS_R6) { mask &= ~((1 << CP0Ca_WP) & val); } @@ -1145,7 +1145,7 @@ void mips_cpu_do_interrupt(CPUState *cs) enter_debug_mode: if (env->insn_flags & ISA_MIPS3) { env->hflags |= MIPS_HFLAG_64; - if (!(env->insn_flags & ISA_MIPS32R6) || + if (!(env->insn_flags & ISA_MIPS_R6) || env->CP0_Status & (1 << CP0St_KX)) { env->hflags &= ~MIPS_HFLAG_AWRAP; } @@ -1174,7 +1174,7 @@ void mips_cpu_do_interrupt(CPUState *cs) env->CP0_Status |= (1 << CP0St_ERL) | (1 << CP0St_BEV); if (env->insn_flags & ISA_MIPS3) { env->hflags |= MIPS_HFLAG_64; - if (!(env->insn_flags & ISA_MIPS32R6) || + if (!(env->insn_flags & ISA_MIPS_R6) || env->CP0_Status & (1 << CP0St_KX)) { env->hflags &= ~MIPS_HFLAG_AWRAP; } @@ -1360,7 +1360,7 @@ void mips_cpu_do_interrupt(CPUState *cs) env->CP0_Status |= (1 << CP0St_EXL); if (env->insn_flags & ISA_MIPS3) { env->hflags |= MIPS_HFLAG_64; - if (!(env->insn_flags & ISA_MIPS32R6) || + if (!(env->insn_flags & ISA_MIPS_R6) || env->CP0_Status & (1 << CP0St_KX)) { env->hflags &= ~MIPS_HFLAG_AWRAP; } diff --git a/target/mips/internal.h b/target/mips/internal.h index 23ae31ef98..77a648bcf9 100644 --- a/target/mips/internal.h +++ b/target/mips/internal.h @@ -354,7 +354,7 @@ static inline void compute_hflags(CPUMIPSState *env) } else if (((env->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) && !(env->CP0_Status & (1 << CP0St_UX))) { env->hflags |= MIPS_HFLAG_AWRAP; - } else if (env->insn_flags & ISA_MIPS32R6) { + } else if (env->insn_flags & ISA_MIPS_R6) { /* Address wrapping for Supervisor and Kernel is specified in R6 */ if ((((env->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_SM) && !(env->CP0_Status & (1 << CP0St_SX))) || @@ -365,7 +365,7 @@ static inline void compute_hflags(CPUMIPSState *env) } #endif if (((env->CP0_Status & (1 << CP0St_CU0)) && - !(env->insn_flags & ISA_MIPS32R6)) || + !(env->insn_flags & ISA_MIPS_R6)) || !(env->hflags & MIPS_HFLAG_KSU)) { env->hflags |= MIPS_HFLAG_CP0; } diff --git a/target/mips/mips-defs.h b/target/mips/mips-defs.h index 181f371547..97866019a7 100644 --- a/target/mips/mips-defs.h +++ b/target/mips/mips-defs.h @@ -20,7 +20,7 @@ #define ISA_MIPS_R2 0x0000000000000040ULL #define ISA_MIPS_R3 0x0000000000000080ULL #define ISA_MIPS_R5 0x0000000000000100ULL -#define ISA_MIPS32R6 0x0000000000002000ULL +#define ISA_MIPS_R6 0x0000000000000200ULL #define ISA_NANOMIPS32 0x0000000000008000ULL /* * bits 24-39: MIPS ASEs @@ -85,7 +85,7 @@ #define CPU_MIPS64R5 (CPU_MIPS64R3 | CPU_MIPS32R5) /* MIPS Technologies "Release 6" */ -#define CPU_MIPS32R6 (CPU_MIPS32R5 | ISA_MIPS32R6) +#define CPU_MIPS32R6 (CPU_MIPS32R5 | ISA_MIPS_R6) #define CPU_MIPS64R6 (CPU_MIPS64R5 | CPU_MIPS32R6) /* Wave Computing: "nanoMIPS" */ diff --git a/target/mips/translate.c b/target/mips/translate.c index 83fd6c473a..e813add99c 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -4014,7 +4014,7 @@ static void gen_logic_imm(DisasContext *ctx, uint32_t opc, } break; case OPC_LUI: - if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) { + if (rs != 0 && (ctx->insn_flags & ISA_MIPS_R6)) { /* OPC_AUI */ tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16); tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); @@ -7399,7 +7399,7 @@ cp0_unimplemented: static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg) { - if (ctx->insn_flags & ISA_MIPS32R6) { + if (ctx->insn_flags & ISA_MIPS_R6) { tcg_gen_movi_tl(arg, 0); } else { tcg_gen_movi_tl(arg, ~0); @@ -7448,7 +7448,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) case CP0_REGISTER_01: switch (sel) { case CP0_REG01__RANDOM: - CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6)); + CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); gen_helper_mfc0_random(arg, cpu_env); register_name = "Random"; break; @@ -7964,7 +7964,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_21: /* Officially reserved, but sel 0 is used for R1x000 framemask */ - CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6)); + CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); switch (sel) { case 0: gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask)); @@ -8709,7 +8709,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_21: /* Officially reserved, but sel 0 is used for R1x000 framemask */ - CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6)); + CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); switch (sel) { case 0: gen_helper_mtc0_framemask(cpu_env, arg); @@ -8980,7 +8980,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) case CP0_REGISTER_01: switch (sel) { case CP0_REG01__RANDOM: - CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6)); + CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); gen_helper_mfc0_random(arg, cpu_env); register_name = "Random"; break; @@ -9461,7 +9461,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_21: /* Officially reserved, but sel 0 is used for R1x000 framemask */ - CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6)); + CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); switch (sel) { case 0: gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask)); @@ -10191,7 +10191,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REGISTER_21: /* Officially reserved, but sel 0 is used for R1x000 framemask */ - CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6)); + CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); switch (sel) { case 0: gen_helper_mtc0_framemask(cpu_env, arg); @@ -10985,7 +10985,7 @@ static void gen_cp0(CPUMIPSState *env, DisasContext *ctx, uint32_t opc, gen_helper_tlbr(cpu_env); break; case OPC_ERET: /* OPC_ERETNC */ - if ((ctx->insn_flags & ISA_MIPS32R6) && + if ((ctx->insn_flags & ISA_MIPS_R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) { goto die; } else { @@ -11007,7 +11007,7 @@ static void gen_cp0(CPUMIPSState *env, DisasContext *ctx, uint32_t opc, case OPC_DERET: opn = "deret"; check_insn(ctx, ISA_MIPS_R1); - if ((ctx->insn_flags & ISA_MIPS32R6) && + if ((ctx->insn_flags & ISA_MIPS_R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) { goto die; } @@ -11022,7 +11022,7 @@ static void gen_cp0(CPUMIPSState *env, DisasContext *ctx, uint32_t opc, case OPC_WAIT: opn = "wait"; check_insn(ctx, ISA_MIPS3 | ISA_MIPS_R1); - if ((ctx->insn_flags & ISA_MIPS32R6) && + if ((ctx->insn_flags & ISA_MIPS_R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) { goto die; } @@ -11050,7 +11050,7 @@ static void gen_compute_branch1(DisasContext *ctx, uint32_t op, target_ulong btarget; TCGv_i32 t0 = tcg_temp_new_i32(); - if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) { + if ((ctx->insn_flags & ISA_MIPS_R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) { generate_exception_end(ctx, EXCP_RI); goto out; } @@ -11906,23 +11906,23 @@ static void gen_farith(DisasContext *ctx, enum fopcode op1, } break; case OPC_SEL_S: - check_insn(ctx, ISA_MIPS32R6); + check_insn(ctx, ISA_MIPS_R6); gen_sel_s(ctx, op1, fd, ft, fs); break; case OPC_SELEQZ_S: - check_insn(ctx, ISA_MIPS32R6); + check_insn(ctx, ISA_MIPS_R6); gen_sel_s(ctx, op1, fd, ft, fs); break; case OPC_SELNEZ_S: - check_insn(ctx, ISA_MIPS32R6); + check_insn(ctx, ISA_MIPS_R6); gen_sel_s(ctx, op1, fd, ft, fs); break; case OPC_MOVCF_S: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1); break; case OPC_MOVZ_S: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); { TCGLabel *l1 = gen_new_label(); TCGv_i32 fp0; @@ -11938,7 +11938,7 @@ static void gen_farith(DisasContext *ctx, enum fopcode op1, } break; case OPC_MOVN_S: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); { TCGLabel *l1 = gen_new_label(); TCGv_i32 fp0; @@ -11974,7 +11974,7 @@ static void gen_farith(DisasContext *ctx, enum fopcode op1, } break; case OPC_MADDF_S: - check_insn(ctx, ISA_MIPS32R6); + check_insn(ctx, ISA_MIPS_R6); { TCGv_i32 fp0 = tcg_temp_new_i32(); TCGv_i32 fp1 = tcg_temp_new_i32(); @@ -11990,7 +11990,7 @@ static void gen_farith(DisasContext *ctx, enum fopcode op1, } break; case OPC_MSUBF_S: - check_insn(ctx, ISA_MIPS32R6); + check_insn(ctx, ISA_MIPS_R6); { TCGv_i32 fp0 = tcg_temp_new_i32(); TCGv_i32 fp1 = tcg_temp_new_i32(); @@ -12006,7 +12006,7 @@ static void gen_farith(DisasContext *ctx, enum fopcode op1, } break; case OPC_RINT_S: - check_insn(ctx, ISA_MIPS32R6); + check_insn(ctx, ISA_MIPS_R6); { TCGv_i32 fp0 = tcg_temp_new_i32(); gen_load_fpr32(ctx, fp0, fs); @@ -12016,7 +12016,7 @@ static void gen_farith(DisasContext *ctx, enum fopcode op1, } break; case OPC_CLASS_S: - check_insn(ctx, ISA_MIPS32R6); + check_insn(ctx, ISA_MIPS_R6); { TCGv_i32 fp0 = tcg_temp_new_i32(); gen_load_fpr32(ctx, fp0, fs); @@ -12026,7 +12026,7 @@ static void gen_farith(DisasContext *ctx, enum fopcode op1, } break; case OPC_MIN_S: /* OPC_RECIP2_S */ - if (ctx->insn_flags & ISA_MIPS32R6) { + if (ctx->insn_flags & ISA_MIPS_R6) { /* OPC_MIN_S */ TCGv_i32 fp0 = tcg_temp_new_i32(); TCGv_i32 fp1 = tcg_temp_new_i32(); @@ -12055,7 +12055,7 @@ static void gen_farith(DisasContext *ctx, enum fopcode op1, } break; case OPC_MINA_S: /* OPC_RECIP1_S */ - if (ctx->insn_flags & ISA_MIPS32R6) { + if (ctx->insn_flags & ISA_MIPS_R6) { /* OPC_MINA_S */ TCGv_i32 fp0 = tcg_temp_new_i32(); TCGv_i32 fp1 = tcg_temp_new_i32(); @@ -12081,7 +12081,7 @@ static void gen_farith(DisasContext *ctx, enum fopcode op1, } break; case OPC_MAX_S: /* OPC_RSQRT1_S */ - if (ctx->insn_flags & ISA_MIPS32R6) { + if (ctx->insn_flags & ISA_MIPS_R6) { /* OPC_MAX_S */ TCGv_i32 fp0 = tcg_temp_new_i32(); TCGv_i32 fp1 = tcg_temp_new_i32(); @@ -12105,7 +12105,7 @@ static void gen_farith(DisasContext *ctx, enum fopcode op1, } break; case OPC_MAXA_S: /* OPC_RSQRT2_S */ - if (ctx->insn_flags & ISA_MIPS32R6) { + if (ctx->insn_flags & ISA_MIPS_R6) { /* OPC_MAXA_S */ TCGv_i32 fp0 = tcg_temp_new_i32(); TCGv_i32 fp1 = tcg_temp_new_i32(); @@ -12207,7 +12207,7 @@ static void gen_farith(DisasContext *ctx, enum fopcode op1, case OPC_CMP_NGE_S: case OPC_CMP_LE_S: case OPC_CMP_NGT_S: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); if (ctx->opcode & (1 << 6)) { gen_cmpabs_s(ctx, func - 48, ft, fs, cc); } else { @@ -12450,23 +12450,23 @@ static void gen_farith(DisasContext *ctx, enum fopcode op1, } break; case OPC_SEL_D: - check_insn(ctx, ISA_MIPS32R6); + check_insn(ctx, ISA_MIPS_R6); gen_sel_d(ctx, op1, fd, ft, fs); break; case OPC_SELEQZ_D: - check_insn(ctx, ISA_MIPS32R6); + check_insn(ctx, ISA_MIPS_R6); gen_sel_d(ctx, op1, fd, ft, fs); break; case OPC_SELNEZ_D: - check_insn(ctx, ISA_MIPS32R6); + check_insn(ctx, ISA_MIPS_R6); gen_sel_d(ctx, op1, fd, ft, fs); break; case OPC_MOVCF_D: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1); break; case OPC_MOVZ_D: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); { TCGLabel *l1 = gen_new_label(); TCGv_i64 fp0; @@ -12482,7 +12482,7 @@ static void gen_farith(DisasContext *ctx, enum fopcode op1, } break; case OPC_MOVN_D: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); { TCGLabel *l1 = gen_new_label(); TCGv_i64 fp0; @@ -12520,7 +12520,7 @@ static void gen_farith(DisasContext *ctx, enum fopcode op1, } break; case OPC_MADDF_D: - check_insn(ctx, ISA_MIPS32R6); + check_insn(ctx, ISA_MIPS_R6); { TCGv_i64 fp0 = tcg_temp_new_i64(); TCGv_i64 fp1 = tcg_temp_new_i64(); @@ -12536,7 +12536,7 @@ static void gen_farith(DisasContext *ctx, enum fopcode op1, } break; case OPC_MSUBF_D: - check_insn(ctx, ISA_MIPS32R6); + check_insn(ctx, ISA_MIPS_R6); { TCGv_i64 fp0 = tcg_temp_new_i64(); TCGv_i64 fp1 = tcg_temp_new_i64(); @@ -12552,7 +12552,7 @@ static void gen_farith(DisasContext *ctx, enum fopcode op1, } break; case OPC_RINT_D: - check_insn(ctx, ISA_MIPS32R6); + check_insn(ctx, ISA_MIPS_R6); { TCGv_i64 fp0 = tcg_temp_new_i64(); gen_load_fpr64(ctx, fp0, fs); @@ -12562,7 +12562,7 @@ static void gen_farith(DisasContext *ctx, enum fopcode op1, } break; case OPC_CLASS_D: - check_insn(ctx, ISA_MIPS32R6); + check_insn(ctx, ISA_MIPS_R6); { TCGv_i64 fp0 = tcg_temp_new_i64(); gen_load_fpr64(ctx, fp0, fs); @@ -12572,7 +12572,7 @@ static void gen_farith(DisasContext *ctx, enum fopcode op1, } break; case OPC_MIN_D: /* OPC_RECIP2_D */ - if (ctx->insn_flags & ISA_MIPS32R6) { + if (ctx->insn_flags & ISA_MIPS_R6) { /* OPC_MIN_D */ TCGv_i64 fp0 = tcg_temp_new_i64(); TCGv_i64 fp1 = tcg_temp_new_i64(); @@ -12599,7 +12599,7 @@ static void gen_farith(DisasContext *ctx, enum fopcode op1, } break; case OPC_MINA_D: /* OPC_RECIP1_D */ - if (ctx->insn_flags & ISA_MIPS32R6) { + if (ctx->insn_flags & ISA_MIPS_R6) { /* OPC_MINA_D */ TCGv_i64 fp0 = tcg_temp_new_i64(); TCGv_i64 fp1 = tcg_temp_new_i64(); @@ -12623,7 +12623,7 @@ static void gen_farith(DisasContext *ctx, enum fopcode op1, } break; case OPC_MAX_D: /* OPC_RSQRT1_D */ - if (ctx->insn_flags & ISA_MIPS32R6) { + if (ctx->insn_flags & ISA_MIPS_R6) { /* OPC_MAX_D */ TCGv_i64 fp0 = tcg_temp_new_i64(); TCGv_i64 fp1 = tcg_temp_new_i64(); @@ -12647,7 +12647,7 @@ static void gen_farith(DisasContext *ctx, enum fopcode op1, } break; case OPC_MAXA_D: /* OPC_RSQRT2_D */ - if (ctx->insn_flags & ISA_MIPS32R6) { + if (ctx->insn_flags & ISA_MIPS_R6) { /* OPC_MAXA_D */ TCGv_i64 fp0 = tcg_temp_new_i64(); TCGv_i64 fp1 = tcg_temp_new_i64(); @@ -12689,7 +12689,7 @@ static void gen_farith(DisasContext *ctx, enum fopcode op1, case OPC_CMP_NGE_D: case OPC_CMP_LE_D: case OPC_CMP_NGT_D: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); if (ctx->opcode & (1 << 6)) { gen_cmpabs_d(ctx, func - 48, ft, fs, cc); } else { @@ -13485,7 +13485,7 @@ static void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel) gen_store_gpr(t0, rt); break; case 4: - check_insn(ctx, ISA_MIPS32R6); + check_insn(ctx, ISA_MIPS_R6); if (sel != 0) { /* * Performance counter registers are not implemented other than @@ -13497,7 +13497,7 @@ static void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel) gen_store_gpr(t0, rt); break; case 5: - check_insn(ctx, ISA_MIPS32R6); + check_insn(ctx, ISA_MIPS_R6); gen_helper_rdhwr_xnp(t0, cpu_env); gen_store_gpr(t0, rt); break; @@ -16160,7 +16160,7 @@ static void gen_pool32axf(CPUMIPSState *env, DisasContext *ctx, int rt, int rs) case 0x2c: switch (minor) { case BITSWAP: - check_insn(ctx, ISA_MIPS32R6); + check_insn(ctx, ISA_MIPS_R6); gen_bitswap(ctx, OPC_BITSWAP, rs, rt); break; case SEB: @@ -16179,26 +16179,26 @@ static void gen_pool32axf(CPUMIPSState *env, DisasContext *ctx, int rt, int rs) gen_cl(ctx, mips32_op, rt, rs); break; case RDHWR: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); gen_rdhwr(ctx, rt, rs, 0); break; case WSBH: gen_bshfl(ctx, OPC_WSBH, rs, rt); break; case MULT: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); mips32_op = OPC_MULT; goto do_mul; case MULTU: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); mips32_op = OPC_MULTU; goto do_mul; case DIV: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); mips32_op = OPC_DIV; goto do_div; case DIVU: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); mips32_op = OPC_DIVU; goto do_div; do_div: @@ -16206,19 +16206,19 @@ static void gen_pool32axf(CPUMIPSState *env, DisasContext *ctx, int rt, int rs) gen_muldiv(ctx, mips32_op, 0, rs, rt); break; case MADD: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); mips32_op = OPC_MADD; goto do_mul; case MADDU: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); mips32_op = OPC_MADDU; goto do_mul; case MSUB: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); mips32_op = OPC_MSUB; goto do_mul; case MSUBU: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); mips32_op = OPC_MSUBU; do_mul: check_insn(ctx, ISA_MIPS_R1); @@ -16246,7 +16246,7 @@ static void gen_pool32axf(CPUMIPSState *env, DisasContext *ctx, int rt, int rs) switch (minor) { case JALR: /* JALRC */ case JALR_HB: /* JALRC_HB */ - if (ctx->insn_flags & ISA_MIPS32R6) { + if (ctx->insn_flags & ISA_MIPS_R6) { /* JALRC, JALRC_HB */ gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0); } else { @@ -16257,7 +16257,7 @@ static void gen_pool32axf(CPUMIPSState *env, DisasContext *ctx, int rt, int rs) break; case JALRS: case JALRS_HB: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2); ctx->hflags |= MIPS_HFLAG_BDS_STRICT; break; @@ -16400,7 +16400,7 @@ static void gen_pool32axf(CPUMIPSState *env, DisasContext *ctx, int rt, int rs) } break; case 0x35: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); switch (minor) { case MFHI32: gen_HILO(ctx, OPC_MFHI, 0, rs); @@ -16674,7 +16674,7 @@ static void gen_pool32fxf(DisasContext *ctx, int rt, int rs) case COND_FLOAT_MOV(MOVT, 5): case COND_FLOAT_MOV(MOVT, 6): case COND_FLOAT_MOV(MOVT, 7): - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1); break; case COND_FLOAT_MOV(MOVF, 0): @@ -16685,7 +16685,7 @@ static void gen_pool32fxf(DisasContext *ctx, int rt, int rs) case COND_FLOAT_MOV(MOVF, 5): case COND_FLOAT_MOV(MOVF, 6): case COND_FLOAT_MOV(MOVF, 7): - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0); break; default: @@ -16736,15 +16736,15 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) gen_shift_imm(ctx, mips32_op, rt, rs, rd); break; case SELEQZ: - check_insn(ctx, ISA_MIPS32R6); + check_insn(ctx, ISA_MIPS_R6); gen_cond_move(ctx, OPC_SELEQZ, rd, rs, rt); break; case SELNEZ: - check_insn(ctx, ISA_MIPS32R6); + check_insn(ctx, ISA_MIPS_R6); gen_cond_move(ctx, OPC_SELNEZ, rd, rs, rt); break; case R6_RDHWR: - check_insn(ctx, ISA_MIPS32R6); + check_insn(ctx, ISA_MIPS_R6); gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3)); break; default: @@ -16768,7 +16768,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) mips32_op = OPC_SUBU; goto do_arith; case MUL: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); mips32_op = OPC_MUL; do_arith: gen_arith(ctx, mips32_op, rd, rs, rt); @@ -16821,7 +16821,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) switch (minor) { /* Conditional moves */ case MOVN: /* MUL */ - if (ctx->insn_flags & ISA_MIPS32R6) { + if (ctx->insn_flags & ISA_MIPS_R6) { /* MUL */ gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt); } else { @@ -16830,7 +16830,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) } break; case MOVZ: /* MUH */ - if (ctx->insn_flags & ISA_MIPS32R6) { + if (ctx->insn_flags & ISA_MIPS_R6) { /* MUH */ gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt); } else { @@ -16839,15 +16839,15 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) } break; case MULU: - check_insn(ctx, ISA_MIPS32R6); + check_insn(ctx, ISA_MIPS_R6); gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt); break; case MUHU: - check_insn(ctx, ISA_MIPS32R6); + check_insn(ctx, ISA_MIPS_R6); gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt); break; case LWXS: /* DIV */ - if (ctx->insn_flags & ISA_MIPS32R6) { + if (ctx->insn_flags & ISA_MIPS_R6) { /* DIV */ gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt); } else { @@ -16856,15 +16856,15 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) } break; case MOD: - check_insn(ctx, ISA_MIPS32R6); + check_insn(ctx, ISA_MIPS_R6); gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt); break; case R6_DIVU: - check_insn(ctx, ISA_MIPS32R6); + check_insn(ctx, ISA_MIPS_R6); gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt); break; case MODU: - check_insn(ctx, ISA_MIPS32R6); + check_insn(ctx, ISA_MIPS_R6); gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt); break; default: @@ -16875,12 +16875,12 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) gen_bitops(ctx, OPC_INS, rt, rs, rr, rd); return; case LSA: - check_insn(ctx, ISA_MIPS32R6); + check_insn(ctx, ISA_MIPS_R6); gen_lsa(ctx, OPC_LSA, rd, rs, rt, extract32(ctx->opcode, 9, 2)); break; case ALIGN: - check_insn(ctx, ISA_MIPS32R6); + check_insn(ctx, ISA_MIPS_R6); gen_align(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 9, 2)); break; case EXT: @@ -16893,7 +16893,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) generate_exception_end(ctx, EXCP_BREAK); break; case SIGRIE: - check_insn(ctx, ISA_MIPS32R6); + check_insn(ctx, ISA_MIPS_R6); generate_exception_end(ctx, EXCP_RI); break; default: @@ -16951,61 +16951,61 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) check_cp1_enabled(ctx); switch (minor) { case ALNV_PS: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); mips32_op = OPC_ALNV_PS; goto do_madd; case MADD_S: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); mips32_op = OPC_MADD_S; goto do_madd; case MADD_D: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); mips32_op = OPC_MADD_D; goto do_madd; case MADD_PS: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); mips32_op = OPC_MADD_PS; goto do_madd; case MSUB_S: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); mips32_op = OPC_MSUB_S; goto do_madd; case MSUB_D: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); mips32_op = OPC_MSUB_D; goto do_madd; case MSUB_PS: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); mips32_op = OPC_MSUB_PS; goto do_madd; case NMADD_S: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); mips32_op = OPC_NMADD_S; goto do_madd; case NMADD_D: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); mips32_op = OPC_NMADD_D; goto do_madd; case NMADD_PS: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); mips32_op = OPC_NMADD_PS; goto do_madd; case NMSUB_S: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); mips32_op = OPC_NMSUB_S; goto do_madd; case NMSUB_D: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); mips32_op = OPC_NMSUB_D; goto do_madd; case NMSUB_PS: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); mips32_op = OPC_NMSUB_PS; do_madd: gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt); break; case CABS_COND_FMT: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); cond = (ctx->opcode >> 6) & 0xf; cc = (ctx->opcode >> 13) & 0x7; fmt = (ctx->opcode >> 10) & 0x3; @@ -17024,7 +17024,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) } break; case C_COND_FMT: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); cond = (ctx->opcode >> 6) & 0xf; cc = (ctx->opcode >> 13) & 0x7; fmt = (ctx->opcode >> 10) & 0x3; @@ -17043,11 +17043,11 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) } break; case CMP_CONDN_S: - check_insn(ctx, ISA_MIPS32R6); + check_insn(ctx, ISA_MIPS_R6); gen_r6_cmp_s(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd); break; case CMP_CONDN_D: - check_insn(ctx, ISA_MIPS32R6); + check_insn(ctx, ISA_MIPS_R6); gen_r6_cmp_d(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd); break; case POOL32FXF: @@ -17069,7 +17069,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) mips32_op = OPC_PUU_PS; goto do_ps; case CVT_PS_S: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); mips32_op = OPC_CVT_PS_S; do_ps: gen_farith(ctx, mips32_op, rt, rs, rd, 0); @@ -17079,7 +17079,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) } break; case MIN_FMT: - check_insn(ctx, ISA_MIPS32R6); + check_insn(ctx, ISA_MIPS_R6); switch ((ctx->opcode >> 9) & 0x3) { case FMT_SDPS_S: gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0); @@ -17095,27 +17095,27 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) /* [LS][WDU]XC1 */ switch ((ctx->opcode >> 6) & 0x7) { case LWXC1: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); mips32_op = OPC_LWXC1; goto do_ldst_cp1; case SWXC1: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); mips32_op = OPC_SWXC1; goto do_ldst_cp1; case LDXC1: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); mips32_op = OPC_LDXC1; goto do_ldst_cp1; case SDXC1: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); mips32_op = OPC_SDXC1; goto do_ldst_cp1; case LUXC1: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); mips32_op = OPC_LUXC1; goto do_ldst_cp1; case SUXC1: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); mips32_op = OPC_SUXC1; do_ldst_cp1: gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs); @@ -17125,7 +17125,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) } break; case MAX_FMT: - check_insn(ctx, ISA_MIPS32R6); + check_insn(ctx, ISA_MIPS_R6); switch ((ctx->opcode >> 9) & 0x3) { case FMT_SDPS_S: gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0); @@ -17139,7 +17139,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) break; case 0x18: /* 3D insns */ - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); fmt = (ctx->opcode >> 9) & 0x3; switch ((ctx->opcode >> 6) & 0x7) { case RSQRT2_FMT: @@ -17190,7 +17190,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) fmt = (ctx->opcode >> 9) & 0x3; switch ((ctx->opcode >> 6) & 0x7) { case MOVF_FMT: /* RINT_FMT */ - if (ctx->insn_flags & ISA_MIPS32R6) { + if (ctx->insn_flags & ISA_MIPS_R6) { /* RINT_FMT */ switch (fmt) { case FMT_SDPS_S: @@ -17221,7 +17221,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) } break; case MOVT_FMT: /* CLASS_FMT */ - if (ctx->insn_flags & ISA_MIPS32R6) { + if (ctx->insn_flags & ISA_MIPS_R6) { /* CLASS_FMT */ switch (fmt) { case FMT_SDPS_S: @@ -17252,7 +17252,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) } break; case PREFX: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); break; default: goto pool32f_invalid; @@ -17274,7 +17274,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) goto pool32f_invalid; \ } case MINA_FMT: - check_insn(ctx, ISA_MIPS32R6); + check_insn(ctx, ISA_MIPS_R6); switch ((ctx->opcode >> 9) & 0x3) { case FMT_SDPS_S: gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0); @@ -17287,7 +17287,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) } break; case MAXA_FMT: - check_insn(ctx, ISA_MIPS32R6); + check_insn(ctx, ISA_MIPS_R6); switch ((ctx->opcode >> 9) & 0x3) { case FMT_SDPS_S: gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0); @@ -17329,7 +17329,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) /* cmovs */ switch ((ctx->opcode >> 6) & 0x7) { case MOVN_FMT: /* SELEQZ_FMT */ - if (ctx->insn_flags & ISA_MIPS32R6) { + if (ctx->insn_flags & ISA_MIPS_R6) { /* SELEQZ_FMT */ switch ((ctx->opcode >> 9) & 0x3) { case FMT_SDPS_S: @@ -17347,11 +17347,11 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) } break; case MOVN_FMT_04: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); FINSN_3ARG_SDPS(MOVN); break; case MOVZ_FMT: /* SELNEZ_FMT */ - if (ctx->insn_flags & ISA_MIPS32R6) { + if (ctx->insn_flags & ISA_MIPS_R6) { /* SELNEZ_FMT */ switch ((ctx->opcode >> 9) & 0x3) { case FMT_SDPS_S: @@ -17369,11 +17369,11 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) } break; case MOVZ_FMT_05: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); FINSN_3ARG_SDPS(MOVZ); break; case SEL_FMT: - check_insn(ctx, ISA_MIPS32R6); + check_insn(ctx, ISA_MIPS_R6); switch ((ctx->opcode >> 9) & 0x3) { case FMT_SDPS_S: gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs); @@ -17386,7 +17386,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) } break; case MADDF_FMT: - check_insn(ctx, ISA_MIPS32R6); + check_insn(ctx, ISA_MIPS_R6); switch ((ctx->opcode >> 9) & 0x3) { case FMT_SDPS_S: mips32_op = OPC_MADDF_S; @@ -17399,7 +17399,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) } break; case MSUBF_FMT: - check_insn(ctx, ISA_MIPS32R6); + check_insn(ctx, ISA_MIPS_R6); switch ((ctx->opcode >> 9) & 0x3) { case FMT_SDPS_S: mips32_op = OPC_MSUBF_S; @@ -17432,45 +17432,45 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) minor = (ctx->opcode >> 21) & 0x1f; switch (minor) { case BLTZ: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4); break; case BLTZAL: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4); ctx->hflags |= MIPS_HFLAG_BDS_STRICT; break; case BLTZALS: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2); ctx->hflags |= MIPS_HFLAG_BDS_STRICT; break; case BGEZ: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4); break; case BGEZAL: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4); ctx->hflags |= MIPS_HFLAG_BDS_STRICT; break; case BGEZALS: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2); ctx->hflags |= MIPS_HFLAG_BDS_STRICT; break; case BLEZ: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4); break; case BGTZ: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4); break; /* Traps */ case TLTI: /* BC1EQZC */ - if (ctx->insn_flags & ISA_MIPS32R6) { + if (ctx->insn_flags & ISA_MIPS_R6) { /* BC1EQZC */ check_cp1_enabled(ctx); gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rs, imm << 1, 0); @@ -17481,7 +17481,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) } break; case TGEI: /* BC1NEZC */ - if (ctx->insn_flags & ISA_MIPS32R6) { + if (ctx->insn_flags & ISA_MIPS_R6) { /* BC1NEZC */ check_cp1_enabled(ctx); gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rs, imm << 1, 0); @@ -17492,15 +17492,15 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) } break; case TLTIU: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); mips32_op = OPC_TLTIU; goto do_trapi; case TGEIU: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); mips32_op = OPC_TGEIU; goto do_trapi; case TNEI: /* SYNCI */ - if (ctx->insn_flags & ISA_MIPS32R6) { + if (ctx->insn_flags & ISA_MIPS_R6) { /* SYNCI */ /* * Break the TB to be able to sync copied instructions @@ -17514,7 +17514,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) } break; case TEQI: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); mips32_op = OPC_TEQI; do_trapi: gen_trap(ctx, mips32_op, rs, -1, imm); @@ -17522,7 +17522,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) case BNEZC: case BEQZC: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ, 4, rs, 0, imm << 1, 0); /* @@ -17532,11 +17532,11 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) */ break; case LUI: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); gen_logic_imm(ctx, OPC_LUI, rs, 0, imm); break; case SYNCI: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); /* * Break the TB to be able to sync copied instructions * immediately. @@ -17545,24 +17545,24 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) break; case BC2F: case BC2T: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); /* COP2: Not implemented. */ generate_exception_err(ctx, EXCP_CpU, 2); break; case BC1F: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F; goto do_cp1branch; case BC1T: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T; goto do_cp1branch; case BC1ANY4F: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); mips32_op = OPC_BC1FANY4; goto do_cp1mips3d; case BC1ANY4T: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); mips32_op = OPC_BC1TANY4; do_cp1mips3d: check_cop1x(ctx); @@ -17590,47 +17590,47 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) case POOL32C: minor = (ctx->opcode >> 12) & 0xf; offset = sextract32(ctx->opcode, 0, - (ctx->insn_flags & ISA_MIPS32R6) ? 9 : 12); + (ctx->insn_flags & ISA_MIPS_R6) ? 9 : 12); switch (minor) { case LWL: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); mips32_op = OPC_LWL; goto do_ld_lr; case SWL: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); mips32_op = OPC_SWL; goto do_st_lr; case LWR: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); mips32_op = OPC_LWR; goto do_ld_lr; case SWR: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); mips32_op = OPC_SWR; goto do_st_lr; #if defined(TARGET_MIPS64) case LDL: check_insn(ctx, ISA_MIPS3); check_mips_64(ctx); - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); mips32_op = OPC_LDL; goto do_ld_lr; case SDL: check_insn(ctx, ISA_MIPS3); check_mips_64(ctx); - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); mips32_op = OPC_SDL; goto do_st_lr; case LDR: check_insn(ctx, ISA_MIPS3); check_mips_64(ctx); - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); mips32_op = OPC_LDR; goto do_ld_lr; case SDR: check_insn(ctx, ISA_MIPS3); check_mips_64(ctx); - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); mips32_op = OPC_SDR; goto do_st_lr; case LWU: @@ -17681,11 +17681,11 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) mips32_op = OPC_LHUE; goto do_ld_lr; case LWLE: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); mips32_op = OPC_LWLE; goto do_ld_lr; case LWRE: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); mips32_op = OPC_LWRE; goto do_ld_lr; case LBE: @@ -17714,16 +17714,16 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) offset = sextract32(ctx->opcode, 0, 9); switch (minor2) { case SWLE: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); mips32_op = OPC_SWLE; goto do_st_lr; case SWRE: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); mips32_op = OPC_SWRE; goto do_st_lr; case PREFE: /* Treat as no-op */ - if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) { + if ((ctx->insn_flags & ISA_MIPS_R6) && (rt >= 24)) { /* hint codes 24-31 are reserved and signal RI */ generate_exception(ctx, EXCP_RI); } @@ -17750,7 +17750,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) break; case PREF: /* Treat as no-op */ - if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) { + if ((ctx->insn_flags & ISA_MIPS_R6) && (rt >= 24)) { /* hint codes 24-31 are reserved and signal RI */ generate_exception(ctx, EXCP_RI); } @@ -17762,7 +17762,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) } break; case ADDI32: /* AUI, LUI */ - if (ctx->insn_flags & ISA_MIPS32R6) { + if (ctx->insn_flags & ISA_MIPS_R6) { /* AUI, LUI */ gen_logic_imm(ctx, OPC_LUI, rt, rs, imm); } else { @@ -17800,13 +17800,13 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) gen_slt_imm(ctx, mips32_op, rt, rs, imm); break; case JALX32: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2; gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4); ctx->hflags |= MIPS_HFLAG_BDS_STRICT; break; case JALS32: /* BOVC, BEQC, BEQZALC */ - if (ctx->insn_flags & ISA_MIPS32R6) { + if (ctx->insn_flags & ISA_MIPS_R6) { if (rs >= rt) { /* BOVC */ mips32_op = OPC_BOVC; @@ -17826,7 +17826,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) } break; case BEQ32: /* BC */ - if (ctx->insn_flags & ISA_MIPS32R6) { + if (ctx->insn_flags & ISA_MIPS_R6) { /* BC */ gen_compute_compact_branch(ctx, OPC_BC, 0, 0, sextract32(ctx->opcode << 1, 0, 27)); @@ -17836,7 +17836,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) } break; case BNE32: /* BALC */ - if (ctx->insn_flags & ISA_MIPS32R6) { + if (ctx->insn_flags & ISA_MIPS_R6) { /* BALC */ gen_compute_compact_branch(ctx, OPC_BALC, 0, 0, sextract32(ctx->opcode << 1, 0, 27)); @@ -17846,7 +17846,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) } break; case J32: /* BGTZC, BLTZC, BLTC */ - if (ctx->insn_flags & ISA_MIPS32R6) { + if (ctx->insn_flags & ISA_MIPS_R6) { if (rs == 0 && rt != 0) { /* BGTZC */ mips32_op = OPC_BGTZC; @@ -17865,7 +17865,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) } break; case JAL32: /* BLEZC, BGEZC, BGEC */ - if (ctx->insn_flags & ISA_MIPS32R6) { + if (ctx->insn_flags & ISA_MIPS_R6) { if (rs == 0 && rt != 0) { /* BLEZC */ mips32_op = OPC_BLEZC; @@ -17900,7 +17900,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) gen_cop1_ldst(ctx, mips32_op, rt, rs, imm); break; case ADDIUPC: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */ - if (ctx->insn_flags & ISA_MIPS32R6) { + if (ctx->insn_flags & ISA_MIPS_R6) { /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */ switch ((ctx->opcode >> 16) & 0x1f) { case ADDIUPC_00: @@ -17942,7 +17942,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) } break; case BNVC: /* BNEC, BNEZALC */ - check_insn(ctx, ISA_MIPS32R6); + check_insn(ctx, ISA_MIPS_R6); if (rs >= rt) { /* BNVC */ mips32_op = OPC_BNVC; @@ -17956,7 +17956,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1); break; case R6_BNEZC: /* JIALC */ - check_insn(ctx, ISA_MIPS32R6); + check_insn(ctx, ISA_MIPS_R6); if (rt != 0) { /* BNEZC */ gen_compute_compact_branch(ctx, OPC_BNEZC, rt, 0, @@ -17967,7 +17967,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) } break; case R6_BEQZC: /* JIC */ - check_insn(ctx, ISA_MIPS32R6); + check_insn(ctx, ISA_MIPS_R6); if (rt != 0) { /* BEQZC */ gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0, @@ -17978,7 +17978,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) } break; case BLEZALC: /* BGEZALC, BGEUC */ - check_insn(ctx, ISA_MIPS32R6); + check_insn(ctx, ISA_MIPS_R6); if (rs == 0 && rt != 0) { /* BLEZALC */ mips32_op = OPC_BLEZALC; @@ -17992,7 +17992,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1); break; case BGTZALC: /* BLTZALC, BLTUC */ - check_insn(ctx, ISA_MIPS32R6); + check_insn(ctx, ISA_MIPS_R6); if (rs == 0 && rt != 0) { /* BGTZALC */ mips32_op = OPC_BGTZALC; @@ -18114,7 +18114,7 @@ static int decode_micromips_opc(CPUMIPSState *env, DisasContext *ctx) opc = OPC_SUBU; break; } - if (ctx->insn_flags & ISA_MIPS32R6) { + if (ctx->insn_flags & ISA_MIPS_R6) { /* * In the Release 6, the register number location in * the instruction encoding has changed. @@ -18146,7 +18146,7 @@ static int decode_micromips_opc(CPUMIPSState *env, DisasContext *ctx) } break; case POOL16C: - if (ctx->insn_flags & ISA_MIPS32R6) { + if (ctx->insn_flags & ISA_MIPS_R6) { gen_pool16c_r6_insn(ctx); } else { gen_pool16c_insn(ctx); @@ -18162,7 +18162,7 @@ static int decode_micromips_opc(CPUMIPSState *env, DisasContext *ctx) } break; case POOL16F: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); if (ctx->opcode & 1) { generate_exception_end(ctx, EXCP_RI); } else { @@ -18280,14 +18280,14 @@ static int decode_micromips_opc(CPUMIPSState *env, DisasContext *ctx) case B16: /* BC16 */ gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, sextract32(ctx->opcode, 0, 10) << 1, - (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4); + (ctx->insn_flags & ISA_MIPS_R6) ? 0 : 4); break; case BNEZ16: /* BNEZC16 */ case BEQZ16: /* BEQZC16 */ gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2, mmreg(uMIPS_RD(ctx->opcode)), 0, sextract32(ctx->opcode, 0, 7) << 1, - (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4); + (ctx->insn_flags & ISA_MIPS_R6) ? 0 : 4); break; case LI16: @@ -24970,7 +24970,7 @@ static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx) case OPC_SLL: /* Shift with immediate */ if (sa == 5 && rd == 0 && rs == 0 && rt == 0) { /* PAUSE */ - if ((ctx->insn_flags & ISA_MIPS32R6) && + if ((ctx->insn_flags & ISA_MIPS_R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) { generate_exception_end(ctx, EXCP_RI); break; @@ -25045,7 +25045,7 @@ static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx) gen_trap(ctx, op1, rs, rt, -1); break; case OPC_LSA: /* OPC_PMON */ - if ((ctx->insn_flags & ISA_MIPS32R6) || + if ((ctx->insn_flags & ISA_MIPS_R6) || (env->CP0_Config3 & (1 << CP0C3_MSAP))) { decode_opc_special_r6(env, ctx); } else { @@ -25148,14 +25148,14 @@ static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx) } break; case OPC_DLSA: - if ((ctx->insn_flags & ISA_MIPS32R6) || + if ((ctx->insn_flags & ISA_MIPS_R6) || (env->CP0_Config3 & (1 << CP0C3_MSAP))) { decode_opc_special_r6(env, ctx); } break; #endif default: - if (ctx->insn_flags & ISA_MIPS32R6) { + if (ctx->insn_flags & ISA_MIPS_R6) { decode_opc_special_r6(env, ctx); } else if (ctx->insn_flags & INSN_R5900) { decode_opc_special_tx79(env, ctx); @@ -27565,7 +27565,7 @@ static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx) int rs, rt, rd; uint32_t op1; - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); rs = (ctx->opcode >> 21) & 0x1f; rt = (ctx->opcode >> 16) & 0x1f; @@ -28552,7 +28552,7 @@ static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx) switch (op1) { case OPC_LWLE: case OPC_LWRE: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); /* fall through */ case OPC_LBUE: case OPC_LHUE: @@ -28565,7 +28565,7 @@ static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx) return; case OPC_SWLE: case OPC_SWRE: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); /* fall through */ case OPC_SBE: case OPC_SHE: @@ -28605,7 +28605,7 @@ static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx) case OPC_ALIGN_2: case OPC_ALIGN_3: case OPC_BITSWAP: - check_insn(ctx, ISA_MIPS32R6); + check_insn(ctx, ISA_MIPS_R6); decode_opc_special3_r6(env, ctx); break; default: @@ -28637,7 +28637,7 @@ static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx) case OPC_DALIGN_6: case OPC_DALIGN_7: case OPC_DBITSWAP: - check_insn(ctx, ISA_MIPS32R6); + check_insn(ctx, ISA_MIPS_R6); decode_opc_special3_r6(env, ctx); break; default: @@ -28677,7 +28677,7 @@ static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx) } break; default: - if (ctx->insn_flags & ISA_MIPS32R6) { + if (ctx->insn_flags & ISA_MIPS_R6) { decode_opc_special3_r6(env, ctx); } else { decode_opc_special3_legacy(env, ctx); @@ -30706,7 +30706,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) case OPC_BLTZALL: case OPC_BGEZALL: check_insn(ctx, ISA_MIPS2); - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); /* Fallthrough */ case OPC_BLTZ: case OPC_BGEZ: @@ -30714,7 +30714,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) break; case OPC_BLTZAL: case OPC_BGEZAL: - if (ctx->insn_flags & ISA_MIPS32R6) { + if (ctx->insn_flags & ISA_MIPS_R6) { if (rs == 0) { /* OPC_NAL, OPC_BAL */ gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4); @@ -30733,11 +30733,11 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) case OPC_TNEI: check_insn(ctx, ISA_MIPS2); - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); gen_trap(ctx, op1, rs, -1, imm); break; case OPC_SIGRIE: - check_insn(ctx, ISA_MIPS32R6); + check_insn(ctx, ISA_MIPS_R6); generate_exception_end(ctx, EXCP_RI); break; case OPC_SYNCI: @@ -30757,14 +30757,14 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) break; #if defined(TARGET_MIPS64) case OPC_DAHI: - check_insn(ctx, ISA_MIPS32R6); + check_insn(ctx, ISA_MIPS_R6); check_mips_64(ctx); if (rs != 0) { tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32); } break; case OPC_DATI: - check_insn(ctx, ISA_MIPS32R6); + check_insn(ctx, ISA_MIPS_R6); check_mips_64(ctx); if (rs != 0) { tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48); @@ -30844,14 +30844,14 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) gen_store_gpr(t0, rt); break; case OPC_DVP: - check_insn(ctx, ISA_MIPS32R6); + check_insn(ctx, ISA_MIPS_R6); if (ctx->vp) { gen_helper_dvp(t0, cpu_env); gen_store_gpr(t0, rt); } break; case OPC_EVP: - check_insn(ctx, ISA_MIPS32R6); + check_insn(ctx, ISA_MIPS_R6); if (ctx->vp) { gen_helper_evp(t0, cpu_env); gen_store_gpr(t0, rt); @@ -30904,7 +30904,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) } break; case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */ - if (ctx->insn_flags & ISA_MIPS32R6) { + if (ctx->insn_flags & ISA_MIPS_R6) { /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */ gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); } else { @@ -30933,7 +30933,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) break; /* Branch */ case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */ - if (ctx->insn_flags & ISA_MIPS32R6) { + if (ctx->insn_flags & ISA_MIPS_R6) { if (rt == 0) { generate_exception_end(ctx, EXCP_RI); break; @@ -30946,7 +30946,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) } break; case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */ - if (ctx->insn_flags & ISA_MIPS32R6) { + if (ctx->insn_flags & ISA_MIPS_R6) { if (rt == 0) { generate_exception_end(ctx, EXCP_RI); break; @@ -30963,7 +30963,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) /* OPC_BLEZ */ gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); } else { - check_insn(ctx, ISA_MIPS32R6); + check_insn(ctx, ISA_MIPS_R6); /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */ gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); } @@ -30973,7 +30973,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) /* OPC_BGTZ */ gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); } else { - check_insn(ctx, ISA_MIPS32R6); + check_insn(ctx, ISA_MIPS_R6); /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */ gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); } @@ -30981,7 +30981,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) case OPC_BEQL: case OPC_BNEL: check_insn(ctx, ISA_MIPS2); - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); /* Fallthrough */ case OPC_BEQ: case OPC_BNE: @@ -30995,7 +30995,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) /* Fallthrough */ case OPC_LWL: case OPC_LWR: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); /* Fallthrough */ case OPC_LB: case OPC_LH: @@ -31007,7 +31007,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) break; case OPC_SWL: case OPC_SWR: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); /* fall through */ case OPC_SB: case OPC_SH: @@ -31016,14 +31016,14 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) break; case OPC_SC: check_insn(ctx, ISA_MIPS2); - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); if (ctx->insn_flags & INSN_R5900) { check_insn_opc_user_only(ctx, INSN_R5900); } gen_st_cond(ctx, rt, rs, imm, MO_TESL, false); break; case OPC_CACHE: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); check_cp0_enabled(ctx); check_insn(ctx, ISA_MIPS3 | ISA_MIPS_R1); if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) { @@ -31032,7 +31032,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) /* Treat as NOP. */ break; case OPC_PREF: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); if (ctx->insn_flags & INSN_R5900) { /* Treat as NOP. */ } else { @@ -31076,7 +31076,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) #endif case OPC_BC1EQZ: /* OPC_BC1ANY2 */ check_cp1_enabled(ctx); - if (ctx->insn_flags & ISA_MIPS32R6) { + if (ctx->insn_flags & ISA_MIPS_R6) { /* OPC_BC1EQZ */ gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode), rt, imm << 2, 4); @@ -31090,19 +31090,19 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) break; case OPC_BC1NEZ: check_cp1_enabled(ctx); - check_insn(ctx, ISA_MIPS32R6); + check_insn(ctx, ISA_MIPS_R6); gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode), rt, imm << 2, 4); break; case OPC_BC1ANY4: check_cp1_enabled(ctx); - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); check_cop1x(ctx); check_insn(ctx, ASE_MIPS3D); /* fall through */ case OPC_BC1: check_cp1_enabled(ctx); - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); gen_compute_branch1(ctx, MASK_BC1(ctx->opcode), (rt >> 2) & 0x7, imm << 2); break; @@ -31120,7 +31120,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) { int r6_op = ctx->opcode & FOP(0x3f, 0x1f); check_cp1_enabled(ctx); - if (ctx->insn_flags & ISA_MIPS32R6) { + if (ctx->insn_flags & ISA_MIPS_R6) { switch (r6_op) { case R6_OPC_CMP_AF_S: case R6_OPC_CMP_UN_S: @@ -31205,7 +31205,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) /* Compact branches [R6] and COP2 [non-R6] */ case OPC_BC: /* OPC_LWC2 */ case OPC_BALC: /* OPC_SWC2 */ - if (ctx->insn_flags & ISA_MIPS32R6) { + if (ctx->insn_flags & ISA_MIPS_R6) { /* OPC_BC, OPC_BALC */ gen_compute_compact_branch(ctx, op, 0, 0, sextract32(ctx->opcode << 2, 0, 28)); @@ -31219,7 +31219,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) break; case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */ case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */ - if (ctx->insn_flags & ISA_MIPS32R6) { + if (ctx->insn_flags & ISA_MIPS_R6) { if (rs != 0) { /* OPC_BEQZC, OPC_BNEZC */ gen_compute_compact_branch(ctx, op, rs, 0, @@ -31243,7 +31243,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) break; case OPC_CP3: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); if (ctx->CP0_Config1 & (1 << CP0C1_FP)) { check_cp1_enabled(ctx); op1 = MASK_CP3(ctx->opcode); @@ -31300,7 +31300,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) /* fall through */ case OPC_LDL: case OPC_LDR: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); /* fall through */ case OPC_LWU: case OPC_LD: @@ -31310,7 +31310,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) break; case OPC_SDL: case OPC_SDR: - check_insn_opc_removed(ctx, ISA_MIPS32R6); + check_insn_opc_removed(ctx, ISA_MIPS_R6); /* fall through */ case OPC_SD: check_insn(ctx, ISA_MIPS3); @@ -31318,7 +31318,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_opc_removed(ctx, ISA_MIPS_R6); check_insn(ctx, ISA_MIPS3); if (ctx->insn_flags & INSN_R5900) { check_insn_opc_user_only(ctx, INSN_R5900); @@ -31327,7 +31327,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) gen_st_cond(ctx, rt, rs, imm, MO_TEQ, false); break; case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */ - if (ctx->insn_flags & ISA_MIPS32R6) { + if (ctx->insn_flags & ISA_MIPS_R6) { /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */ gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); } else { @@ -31344,7 +31344,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) break; #else case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */ - if (ctx->insn_flags & ISA_MIPS32R6) { + if (ctx->insn_flags & ISA_MIPS_R6) { gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); } else { MIPS_INVAL("major opcode"); @@ -31353,7 +31353,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) break; #endif case OPC_DAUI: /* OPC_JALX */ - if (ctx->insn_flags & ISA_MIPS32R6) { + if (ctx->insn_flags & ISA_MIPS_R6) { #if defined(TARGET_MIPS64) /* OPC_DAUI */ check_mips_64(ctx); @@ -31387,7 +31387,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) } break; case OPC_PCREL: - check_insn(ctx, ISA_MIPS32R6); + check_insn(ctx, ISA_MIPS_R6); gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs); break; default: /* Invalid */ @@ -31438,7 +31438,7 @@ static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) #else ctx->mem_idx = hflags_mmu_index(ctx->hflags); #endif - ctx->default_tcg_memop_mask = (ctx->insn_flags & (ISA_MIPS32R6 | + ctx->default_tcg_memop_mask = (ctx->insn_flags & (ISA_MIPS_R6 | INSN_LOONGSON3A)) ? MO_UNALN : MO_ALIGN; LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx, -- cgit v1.2.3-55-g7522 From 9bcd41d41fb4fd9efbc2fd657a4a12c614e78412 Mon Sep 17 00:00:00 2001 From: Philippe Mathieu-Daudé Date: Mon, 14 Dec 2020 15:07:13 +0100 Subject: target/mips: Inline cpu_state_reset() in mips_cpu_reset() Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20201214183739.500368-2-f4bug@amsat.org> --- target/mips/cpu.c | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/target/mips/cpu.c b/target/mips/cpu.c index cb70fb2b9b..77fb7366bf 100644 --- a/target/mips/cpu.c +++ b/target/mips/cpu.c @@ -105,10 +105,16 @@ static bool mips_cpu_has_work(CPUState *cs) #include "translate_init.c.inc" -/* TODO QOM'ify CPU reset and remove */ -static void cpu_state_reset(CPUMIPSState *env) +static void mips_cpu_reset(DeviceState *dev) { - CPUState *cs = env_cpu(env); + CPUState *cs = CPU(dev); + MIPSCPU *cpu = MIPS_CPU(cs); + MIPSCPUClass *mcc = MIPS_CPU_GET_CLASS(cpu); + CPUMIPSState *env = &cpu->env; + + mcc->parent_reset(dev); + + memset(env, 0, offsetof(CPUMIPSState, end_reset_fields)); /* Reset registers to their default values */ env->CP0_PRid = env->cpu_model->CP0_PRid; @@ -331,20 +337,6 @@ static void cpu_state_reset(CPUMIPSState *env) /* UHI interface can be used to obtain argc and argv */ env->active_tc.gpr[4] = -1; } -} - -static void mips_cpu_reset(DeviceState *dev) -{ - CPUState *s = CPU(dev); - MIPSCPU *cpu = MIPS_CPU(s); - MIPSCPUClass *mcc = MIPS_CPU_GET_CLASS(cpu); - CPUMIPSState *env = &cpu->env; - - mcc->parent_reset(dev); - - memset(env, 0, offsetof(CPUMIPSState, end_reset_fields)); - - cpu_state_reset(env); #ifndef CONFIG_USER_ONLY if (kvm_enabled()) { -- cgit v1.2.3-55-g7522 From 81ddae7c3095065466d235f782aa2af620db78d0 Mon Sep 17 00:00:00 2001 From: Philippe Mathieu-Daudé Date: Sat, 14 Nov 2020 19:03:11 +0100 Subject: target/mips: Extract FPU helpers to 'fpu_helper.h' Extract FPU specific helpers from "internal.h" to "fpu_helper.h". Reviewed-by: Richard Henderson Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20201120210844.2625602-2-f4bug@amsat.org> --- linux-user/mips/cpu_loop.c | 1 + target/mips/fpu_helper.c | 1 + target/mips/fpu_helper.h | 59 ++++++++++++++++++++++++++++++++++++++++ target/mips/gdbstub.c | 1 + target/mips/internal.h | 49 --------------------------------- target/mips/kvm.c | 1 + target/mips/machine.c | 1 + target/mips/msa_helper.c | 1 + target/mips/op_helper.c | 2 +- target/mips/translate.c | 1 + target/mips/translate_init.c.inc | 2 ++ 11 files changed, 69 insertions(+), 50 deletions(-) create mode 100644 target/mips/fpu_helper.h diff --git a/linux-user/mips/cpu_loop.c b/linux-user/mips/cpu_loop.c index 19947448a2..9d813ece4e 100644 --- a/linux-user/mips/cpu_loop.c +++ b/linux-user/mips/cpu_loop.c @@ -23,6 +23,7 @@ #include "cpu_loop-common.h" #include "elf.h" #include "internal.h" +#include "fpu_helper.h" # ifdef TARGET_ABI_MIPSO32 # define MIPS_SYSCALL_NUMBER_UNUSED -1 diff --git a/target/mips/fpu_helper.c b/target/mips/fpu_helper.c index 91b6a2e11f..6dd853259e 100644 --- a/target/mips/fpu_helper.c +++ b/target/mips/fpu_helper.c @@ -27,6 +27,7 @@ #include "exec/exec-all.h" #include "exec/cpu_ldst.h" #include "fpu/softfloat.h" +#include "fpu_helper.h" /* Complex FPU operations which may need stack space. */ diff --git a/target/mips/fpu_helper.h b/target/mips/fpu_helper.h new file mode 100644 index 0000000000..1c2d6d35a7 --- /dev/null +++ b/target/mips/fpu_helper.h @@ -0,0 +1,59 @@ +/* + * Helpers for emulation of FPU-related MIPS instructions. + * + * Copyright (C) 2004-2005 Jocelyn Mayer + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ +#include "fpu/softfloat-helpers.h" +#include "cpu.h" + +extern const FloatRoundMode ieee_rm[4]; + +uint32_t float_class_s(uint32_t arg, float_status *fst); +uint64_t float_class_d(uint64_t arg, float_status *fst); + +static inline void restore_rounding_mode(CPUMIPSState *env) +{ + set_float_rounding_mode(ieee_rm[env->active_fpu.fcr31 & 3], + &env->active_fpu.fp_status); +} + +static inline void restore_flush_mode(CPUMIPSState *env) +{ + set_flush_to_zero((env->active_fpu.fcr31 & (1 << FCR31_FS)) != 0, + &env->active_fpu.fp_status); +} + +static inline void restore_snan_bit_mode(CPUMIPSState *env) +{ + set_snan_bit_is_one((env->active_fpu.fcr31 & (1 << FCR31_NAN2008)) == 0, + &env->active_fpu.fp_status); +} + +static inline void restore_fp_status(CPUMIPSState *env) +{ + restore_rounding_mode(env); + restore_flush_mode(env); + restore_snan_bit_mode(env); +} + +/* MSA */ + +enum CPUMIPSMSADataFormat { + DF_BYTE = 0, + DF_HALF, + DF_WORD, + DF_DOUBLE +}; + +static inline void restore_msa_fp_status(CPUMIPSState *env) +{ + float_status *status = &env->active_tc.msa_fp_status; + int rounding_mode = (env->active_tc.msacsr & MSACSR_RM_MASK) >> MSACSR_RM; + bool flush_to_zero = (env->active_tc.msacsr & MSACSR_FS_MASK) != 0; + + set_float_rounding_mode(ieee_rm[rounding_mode], status); + set_flush_to_zero(flush_to_zero, status); + set_flush_inputs_to_zero(flush_to_zero, status); +} diff --git a/target/mips/gdbstub.c b/target/mips/gdbstub.c index e39f8d75cf..f1c2a2cf6d 100644 --- a/target/mips/gdbstub.c +++ b/target/mips/gdbstub.c @@ -21,6 +21,7 @@ #include "cpu.h" #include "internal.h" #include "exec/gdbstub.h" +#include "fpu_helper.h" int mips_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) { diff --git a/target/mips/internal.h b/target/mips/internal.h index 77a648bcf9..f159187b24 100644 --- a/target/mips/internal.h +++ b/target/mips/internal.h @@ -9,7 +9,6 @@ #define MIPS_INTERNAL_H #include "exec/memattrs.h" -#include "fpu/softfloat-helpers.h" /* * MMU types, the first four entries have the same layout as the @@ -75,13 +74,6 @@ struct mips_def_t { extern const struct mips_def_t mips_defs[]; extern const int mips_defs_number; -enum CPUMIPSMSADataFormat { - DF_BYTE = 0, - DF_HALF, - DF_WORD, - DF_DOUBLE -}; - void mips_cpu_do_interrupt(CPUState *cpu); bool mips_cpu_exec_interrupt(CPUState *cpu, int int_req); void mips_cpu_dump_state(CPUState *cpu, FILE *f, int flags); @@ -220,49 +212,8 @@ bool mips_cpu_tlb_fill(CPUState *cs, vaddr address, int size, bool probe, uintptr_t retaddr); /* op_helper.c */ -uint32_t float_class_s(uint32_t arg, float_status *fst); -uint64_t float_class_d(uint64_t arg, float_status *fst); - -extern const FloatRoundMode ieee_rm[4]; - void update_pagemask(CPUMIPSState *env, target_ulong arg1, int32_t *pagemask); -static inline void restore_rounding_mode(CPUMIPSState *env) -{ - set_float_rounding_mode(ieee_rm[env->active_fpu.fcr31 & 3], - &env->active_fpu.fp_status); -} - -static inline void restore_flush_mode(CPUMIPSState *env) -{ - set_flush_to_zero((env->active_fpu.fcr31 & (1 << FCR31_FS)) != 0, - &env->active_fpu.fp_status); -} - -static inline void restore_snan_bit_mode(CPUMIPSState *env) -{ - set_snan_bit_is_one((env->active_fpu.fcr31 & (1 << FCR31_NAN2008)) == 0, - &env->active_fpu.fp_status); -} - -static inline void restore_fp_status(CPUMIPSState *env) -{ - restore_rounding_mode(env); - restore_flush_mode(env); - restore_snan_bit_mode(env); -} - -static inline void restore_msa_fp_status(CPUMIPSState *env) -{ - float_status *status = &env->active_tc.msa_fp_status; - int rounding_mode = (env->active_tc.msacsr & MSACSR_RM_MASK) >> MSACSR_RM; - bool flush_to_zero = (env->active_tc.msacsr & MSACSR_FS_MASK) != 0; - - set_float_rounding_mode(ieee_rm[rounding_mode], status); - set_flush_to_zero(flush_to_zero, status); - set_flush_inputs_to_zero(flush_to_zero, status); -} - static inline void restore_pamask(CPUMIPSState *env) { if (env->hflags & MIPS_HFLAG_ELPA) { diff --git a/target/mips/kvm.c b/target/mips/kvm.c index 477692566a..a5b6fe35db 100644 --- a/target/mips/kvm.c +++ b/target/mips/kvm.c @@ -24,6 +24,7 @@ #include "sysemu/runstate.h" #include "kvm_mips.h" #include "hw/boards.h" +#include "fpu_helper.h" #define DEBUG_KVM 0 diff --git a/target/mips/machine.c b/target/mips/machine.c index 77afe654e9..b5fda6a278 100644 --- a/target/mips/machine.c +++ b/target/mips/machine.c @@ -2,6 +2,7 @@ #include "cpu.h" #include "internal.h" #include "migration/cpu.h" +#include "fpu_helper.h" static int cpu_post_load(void *opaque, int version_id) { diff --git a/target/mips/msa_helper.c b/target/mips/msa_helper.c index 249f0fdad8..b89b4c4490 100644 --- a/target/mips/msa_helper.c +++ b/target/mips/msa_helper.c @@ -23,6 +23,7 @@ #include "exec/exec-all.h" #include "exec/helper-proto.h" #include "fpu/softfloat.h" +#include "fpu_helper.h" /* Data format min and max values */ #define DF_BITS(df) (1 << ((df) + 3)) diff --git a/target/mips/op_helper.c b/target/mips/op_helper.c index 5aa97902e9..3386b8228e 100644 --- a/target/mips/op_helper.c +++ b/target/mips/op_helper.c @@ -24,7 +24,7 @@ #include "exec/helper-proto.h" #include "exec/exec-all.h" #include "exec/memop.h" - +#include "fpu_helper.h" /*****************************************************************************/ /* Exceptions processing helpers */ diff --git a/target/mips/translate.c b/target/mips/translate.c index e813add99c..f8f0f95509 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -35,6 +35,7 @@ #include "exec/translator.h" #include "exec/log.h" #include "qemu/qemu-print.h" +#include "fpu_helper.h" #define MIPS_DEBUG_DISAS 0 diff --git a/target/mips/translate_init.c.inc b/target/mips/translate_init.c.inc index 0ba3cf18ef..044052fb77 100644 --- a/target/mips/translate_init.c.inc +++ b/target/mips/translate_init.c.inc @@ -18,6 +18,8 @@ * License along with this library; if not, see . */ +#include "fpu_helper.h" + /* CPU / CPU family specific config register values. */ /* Have config1, uncached coherency */ -- cgit v1.2.3-55-g7522 From f9bd3d79f4f636ea9c9ce6dd2b6ad71b776458d6 Mon Sep 17 00:00:00 2001 From: Philippe Mathieu-Daudé Date: Sun, 6 Dec 2020 23:20:27 +0100 Subject: target/mips: Add !CONFIG_USER_ONLY comment after #endif To help understand ifdef'ry, add comment after #endif. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20201214183739.500368-4-f4bug@amsat.org> --- target/mips/helper.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/target/mips/helper.c b/target/mips/helper.c index d1b6bb6fb2..92bd3fb855 100644 --- a/target/mips/helper.c +++ b/target/mips/helper.c @@ -455,7 +455,8 @@ void cpu_mips_store_cause(CPUMIPSState *env, target_ulong val) } } } -#endif + +#endif /* !CONFIG_USER_ONLY */ static void raise_mmu_exception(CPUMIPSState *env, target_ulong address, int rw, int tlb_error) @@ -537,6 +538,7 @@ static void raise_mmu_exception(CPUMIPSState *env, target_ulong address, } #if !defined(CONFIG_USER_ONLY) + hwaddr mips_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) { MIPSCPU *cpu = MIPS_CPU(cs); @@ -550,7 +552,7 @@ hwaddr mips_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) } return phys_addr; } -#endif +#endif /* !CONFIG_USER_ONLY */ #if !defined(CONFIG_USER_ONLY) #if !defined(TARGET_MIPS64) @@ -886,7 +888,7 @@ refill: return true; } #endif -#endif +#endif /* !CONFIG_USER_ONLY */ bool mips_cpu_tlb_fill(CPUState *cs, vaddr address, int size, MMUAccessType access_type, int mmu_idx, @@ -1088,7 +1090,8 @@ static inline void set_badinstr_registers(CPUMIPSState *env) env->CP0_BadInstrP = cpu_ldl_code(env, env->active_tc.PC - 4); } } -#endif + +#endif /* !CONFIG_USER_ONLY */ void mips_cpu_do_interrupt(CPUState *cs) { @@ -1482,7 +1485,7 @@ void r4k_invalidate_tlb(CPUMIPSState *env, int idx, int use_extra) } } } -#endif +#endif /* !CONFIG_USER_ONLY */ void QEMU_NORETURN do_raise_exception_err(CPUMIPSState *env, uint32_t exception, -- cgit v1.2.3-55-g7522 From 2be565f9c2f8c2a1eb40efb86175e9f0c76761a4 Mon Sep 17 00:00:00 2001 From: Philippe Mathieu-Daudé Date: Sun, 13 Dec 2020 17:36:01 +0100 Subject: target/mips: Remove consecutive CONFIG_USER_ONLY ifdefs Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20201214183739.500368-5-f4bug@amsat.org> --- target/mips/helper.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/target/mips/helper.c b/target/mips/helper.c index 92bd3fb855..cfb6d82fd3 100644 --- a/target/mips/helper.c +++ b/target/mips/helper.c @@ -552,9 +552,7 @@ hwaddr mips_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) } return phys_addr; } -#endif /* !CONFIG_USER_ONLY */ -#if !defined(CONFIG_USER_ONLY) #if !defined(TARGET_MIPS64) /* -- cgit v1.2.3-55-g7522 From e9927723ba928230222d68ece45d232ed602e78a Mon Sep 17 00:00:00 2001 From: Philippe Mathieu-Daudé Date: Sun, 6 Dec 2020 23:12:23 +0100 Subject: target/mips: Move common helpers from helper.c to cpu.c The rest of helper.c is TLB related. Extract the non TLB specific functions to cpu.c, so we can rename helper.c as tlb_helper.c in the next commit. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20201214183739.500368-6-f4bug@amsat.org> --- target/mips/cpu.c | 215 +++++++++++++++++++++++++++++++++++++++++++++++-- target/mips/helper.c | 201 --------------------------------------------- target/mips/internal.h | 2 + 3 files changed, 211 insertions(+), 207 deletions(-) diff --git a/target/mips/cpu.c b/target/mips/cpu.c index 77fb7366bf..6376076a3f 100644 --- a/target/mips/cpu.c +++ b/target/mips/cpu.c @@ -34,6 +34,215 @@ #include "hw/semihosting/semihost.h" #include "qapi/qapi-commands-machine-target.h" +#if !defined(CONFIG_USER_ONLY) + +/* Called for updates to CP0_Status. */ +void sync_c0_status(CPUMIPSState *env, CPUMIPSState *cpu, int tc) +{ + int32_t tcstatus, *tcst; + uint32_t v = cpu->CP0_Status; + uint32_t cu, mx, asid, ksu; + uint32_t mask = ((1 << CP0TCSt_TCU3) + | (1 << CP0TCSt_TCU2) + | (1 << CP0TCSt_TCU1) + | (1 << CP0TCSt_TCU0) + | (1 << CP0TCSt_TMX) + | (3 << CP0TCSt_TKSU) + | (0xff << CP0TCSt_TASID)); + + cu = (v >> CP0St_CU0) & 0xf; + mx = (v >> CP0St_MX) & 0x1; + ksu = (v >> CP0St_KSU) & 0x3; + asid = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask; + + tcstatus = cu << CP0TCSt_TCU0; + tcstatus |= mx << CP0TCSt_TMX; + tcstatus |= ksu << CP0TCSt_TKSU; + tcstatus |= asid; + + if (tc == cpu->current_tc) { + tcst = &cpu->active_tc.CP0_TCStatus; + } else { + tcst = &cpu->tcs[tc].CP0_TCStatus; + } + + *tcst &= ~mask; + *tcst |= tcstatus; + compute_hflags(cpu); +} + +void cpu_mips_store_status(CPUMIPSState *env, target_ulong val) +{ + uint32_t mask = env->CP0_Status_rw_bitmask; + target_ulong old = env->CP0_Status; + + if (env->insn_flags & ISA_MIPS_R6) { + bool has_supervisor = extract32(mask, CP0St_KSU, 2) == 0x3; +#if defined(TARGET_MIPS64) + uint32_t ksux = (1 << CP0St_KX) & val; + ksux |= (ksux >> 1) & val; /* KX = 0 forces SX to be 0 */ + ksux |= (ksux >> 1) & val; /* SX = 0 forces UX to be 0 */ + val = (val & ~(7 << CP0St_UX)) | ksux; +#endif + if (has_supervisor && extract32(val, CP0St_KSU, 2) == 0x3) { + mask &= ~(3 << CP0St_KSU); + } + mask &= ~(((1 << CP0St_SR) | (1 << CP0St_NMI)) & val); + } + + env->CP0_Status = (old & ~mask) | (val & mask); +#if defined(TARGET_MIPS64) + if ((env->CP0_Status ^ old) & (old & (7 << CP0St_UX))) { + /* Access to at least one of the 64-bit segments has been disabled */ + tlb_flush(env_cpu(env)); + } +#endif + if (ase_mt_available(env)) { + sync_c0_status(env, env, env->current_tc); + } else { + compute_hflags(env); + } +} + +void cpu_mips_store_cause(CPUMIPSState *env, target_ulong val) +{ + uint32_t mask = 0x00C00300; + uint32_t old = env->CP0_Cause; + int i; + + if (env->insn_flags & ISA_MIPS_R2) { + mask |= 1 << CP0Ca_DC; + } + if (env->insn_flags & ISA_MIPS_R6) { + mask &= ~((1 << CP0Ca_WP) & val); + } + + env->CP0_Cause = (env->CP0_Cause & ~mask) | (val & mask); + + if ((old ^ env->CP0_Cause) & (1 << CP0Ca_DC)) { + if (env->CP0_Cause & (1 << CP0Ca_DC)) { + cpu_mips_stop_count(env); + } else { + cpu_mips_start_count(env); + } + } + + /* Set/reset software interrupts */ + for (i = 0 ; i < 2 ; i++) { + if ((old ^ env->CP0_Cause) & (1 << (CP0Ca_IP + i))) { + cpu_mips_soft_irq(env, i, env->CP0_Cause & (1 << (CP0Ca_IP + i))); + } + } +} + +#endif /* !CONFIG_USER_ONLY */ + +static const char * const excp_names[EXCP_LAST + 1] = { + [EXCP_RESET] = "reset", + [EXCP_SRESET] = "soft reset", + [EXCP_DSS] = "debug single step", + [EXCP_DINT] = "debug interrupt", + [EXCP_NMI] = "non-maskable interrupt", + [EXCP_MCHECK] = "machine check", + [EXCP_EXT_INTERRUPT] = "interrupt", + [EXCP_DFWATCH] = "deferred watchpoint", + [EXCP_DIB] = "debug instruction breakpoint", + [EXCP_IWATCH] = "instruction fetch watchpoint", + [EXCP_AdEL] = "address error load", + [EXCP_AdES] = "address error store", + [EXCP_TLBF] = "TLB refill", + [EXCP_IBE] = "instruction bus error", + [EXCP_DBp] = "debug breakpoint", + [EXCP_SYSCALL] = "syscall", + [EXCP_BREAK] = "break", + [EXCP_CpU] = "coprocessor unusable", + [EXCP_RI] = "reserved instruction", + [EXCP_OVERFLOW] = "arithmetic overflow", + [EXCP_TRAP] = "trap", + [EXCP_FPE] = "floating point", + [EXCP_DDBS] = "debug data break store", + [EXCP_DWATCH] = "data watchpoint", + [EXCP_LTLBL] = "TLB modify", + [EXCP_TLBL] = "TLB load", + [EXCP_TLBS] = "TLB store", + [EXCP_DBE] = "data bus error", + [EXCP_DDBL] = "debug data break load", + [EXCP_THREAD] = "thread", + [EXCP_MDMX] = "MDMX", + [EXCP_C2E] = "precise coprocessor 2", + [EXCP_CACHE] = "cache error", + [EXCP_TLBXI] = "TLB execute-inhibit", + [EXCP_TLBRI] = "TLB read-inhibit", + [EXCP_MSADIS] = "MSA disabled", + [EXCP_MSAFPE] = "MSA floating point", +}; + +const char *mips_exception_name(int32_t exception) +{ + if (exception < 0 || exception > EXCP_LAST) { + return "unknown"; + } + return excp_names[exception]; +} + +void cpu_set_exception_base(int vp_index, target_ulong address) +{ + MIPSCPU *vp = MIPS_CPU(qemu_get_cpu(vp_index)); + vp->env.exception_base = address; +} + +target_ulong exception_resume_pc(CPUMIPSState *env) +{ + target_ulong bad_pc; + target_ulong isa_mode; + + isa_mode = !!(env->hflags & MIPS_HFLAG_M16); + bad_pc = env->active_tc.PC | isa_mode; + if (env->hflags & MIPS_HFLAG_BMASK) { + /* + * If the exception was raised from a delay slot, come back to + * the jump. + */ + bad_pc -= (env->hflags & MIPS_HFLAG_B16 ? 2 : 4); + } + + return bad_pc; +} + +bool mips_cpu_exec_interrupt(CPUState *cs, int interrupt_request) +{ + if (interrupt_request & CPU_INTERRUPT_HARD) { + MIPSCPU *cpu = MIPS_CPU(cs); + CPUMIPSState *env = &cpu->env; + + if (cpu_mips_hw_interrupts_enabled(env) && + cpu_mips_hw_interrupts_pending(env)) { + /* Raise it */ + cs->exception_index = EXCP_EXT_INTERRUPT; + env->error_code = 0; + mips_cpu_do_interrupt(cs); + return true; + } + } + return false; +} + +void QEMU_NORETURN do_raise_exception_err(CPUMIPSState *env, + uint32_t exception, + int error_code, + uintptr_t pc) +{ + CPUState *cs = env_cpu(env); + + qemu_log_mask(CPU_LOG_INT, "%s: %d (%s) %d\n", + __func__, exception, mips_exception_name(exception), + error_code); + cs->exception_index = exception; + env->error_code = error_code; + + cpu_loop_exit_restore(cs, pc); +} + static void mips_cpu_set_pc(CPUState *cs, vaddr value) { MIPSCPU *cpu = MIPS_CPU(cs); @@ -588,9 +797,3 @@ bool cpu_type_supports_cps_smp(const char *cpu_type) const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type)); return (mcc->cpu_def->CP0_Config3 & (1 << CP0C3_CMGCR)) != 0; } - -void cpu_set_exception_base(int vp_index, target_ulong address) -{ - MIPSCPU *vp = MIPS_CPU(qemu_get_cpu(vp_index)); - vp->env.exception_base = address; -} diff --git a/target/mips/helper.c b/target/mips/helper.c index cfb6d82fd3..68804b84b1 100644 --- a/target/mips/helper.c +++ b/target/mips/helper.c @@ -357,105 +357,6 @@ void cpu_mips_tlb_flush(CPUMIPSState *env) env->tlb->tlb_in_use = env->tlb->nb_tlb; } -/* Called for updates to CP0_Status. */ -void sync_c0_status(CPUMIPSState *env, CPUMIPSState *cpu, int tc) -{ - int32_t tcstatus, *tcst; - uint32_t v = cpu->CP0_Status; - uint32_t cu, mx, asid, ksu; - uint32_t mask = ((1 << CP0TCSt_TCU3) - | (1 << CP0TCSt_TCU2) - | (1 << CP0TCSt_TCU1) - | (1 << CP0TCSt_TCU0) - | (1 << CP0TCSt_TMX) - | (3 << CP0TCSt_TKSU) - | (0xff << CP0TCSt_TASID)); - - cu = (v >> CP0St_CU0) & 0xf; - mx = (v >> CP0St_MX) & 0x1; - ksu = (v >> CP0St_KSU) & 0x3; - asid = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask; - - tcstatus = cu << CP0TCSt_TCU0; - tcstatus |= mx << CP0TCSt_TMX; - tcstatus |= ksu << CP0TCSt_TKSU; - tcstatus |= asid; - - if (tc == cpu->current_tc) { - tcst = &cpu->active_tc.CP0_TCStatus; - } else { - tcst = &cpu->tcs[tc].CP0_TCStatus; - } - - *tcst &= ~mask; - *tcst |= tcstatus; - compute_hflags(cpu); -} - -void cpu_mips_store_status(CPUMIPSState *env, target_ulong val) -{ - uint32_t mask = env->CP0_Status_rw_bitmask; - target_ulong old = env->CP0_Status; - - if (env->insn_flags & ISA_MIPS_R6) { - bool has_supervisor = extract32(mask, CP0St_KSU, 2) == 0x3; -#if defined(TARGET_MIPS64) - uint32_t ksux = (1 << CP0St_KX) & val; - ksux |= (ksux >> 1) & val; /* KX = 0 forces SX to be 0 */ - ksux |= (ksux >> 1) & val; /* SX = 0 forces UX to be 0 */ - val = (val & ~(7 << CP0St_UX)) | ksux; -#endif - if (has_supervisor && extract32(val, CP0St_KSU, 2) == 0x3) { - mask &= ~(3 << CP0St_KSU); - } - mask &= ~(((1 << CP0St_SR) | (1 << CP0St_NMI)) & val); - } - - env->CP0_Status = (old & ~mask) | (val & mask); -#if defined(TARGET_MIPS64) - if ((env->CP0_Status ^ old) & (old & (7 << CP0St_UX))) { - /* Access to at least one of the 64-bit segments has been disabled */ - tlb_flush(env_cpu(env)); - } -#endif - if (ase_mt_available(env)) { - sync_c0_status(env, env, env->current_tc); - } else { - compute_hflags(env); - } -} - -void cpu_mips_store_cause(CPUMIPSState *env, target_ulong val) -{ - uint32_t mask = 0x00C00300; - uint32_t old = env->CP0_Cause; - int i; - - if (env->insn_flags & ISA_MIPS_R2) { - mask |= 1 << CP0Ca_DC; - } - if (env->insn_flags & ISA_MIPS_R6) { - mask &= ~((1 << CP0Ca_WP) & val); - } - - env->CP0_Cause = (env->CP0_Cause & ~mask) | (val & mask); - - if ((old ^ env->CP0_Cause) & (1 << CP0Ca_DC)) { - if (env->CP0_Cause & (1 << CP0Ca_DC)) { - cpu_mips_stop_count(env); - } else { - cpu_mips_start_count(env); - } - } - - /* Set/reset software interrupts */ - for (i = 0 ; i < 2 ; i++) { - if ((old ^ env->CP0_Cause) & (1 << (CP0Ca_IP + i))) { - cpu_mips_soft_irq(env, i, env->CP0_Cause & (1 << (CP0Ca_IP + i))); - } - } -} - #endif /* !CONFIG_USER_ONLY */ static void raise_mmu_exception(CPUMIPSState *env, target_ulong address, @@ -977,75 +878,7 @@ hwaddr cpu_mips_translate_address(CPUMIPSState *env, target_ulong address, return physical; } } -#endif /* !CONFIG_USER_ONLY */ - -static const char * const excp_names[EXCP_LAST + 1] = { - [EXCP_RESET] = "reset", - [EXCP_SRESET] = "soft reset", - [EXCP_DSS] = "debug single step", - [EXCP_DINT] = "debug interrupt", - [EXCP_NMI] = "non-maskable interrupt", - [EXCP_MCHECK] = "machine check", - [EXCP_EXT_INTERRUPT] = "interrupt", - [EXCP_DFWATCH] = "deferred watchpoint", - [EXCP_DIB] = "debug instruction breakpoint", - [EXCP_IWATCH] = "instruction fetch watchpoint", - [EXCP_AdEL] = "address error load", - [EXCP_AdES] = "address error store", - [EXCP_TLBF] = "TLB refill", - [EXCP_IBE] = "instruction bus error", - [EXCP_DBp] = "debug breakpoint", - [EXCP_SYSCALL] = "syscall", - [EXCP_BREAK] = "break", - [EXCP_CpU] = "coprocessor unusable", - [EXCP_RI] = "reserved instruction", - [EXCP_OVERFLOW] = "arithmetic overflow", - [EXCP_TRAP] = "trap", - [EXCP_FPE] = "floating point", - [EXCP_DDBS] = "debug data break store", - [EXCP_DWATCH] = "data watchpoint", - [EXCP_LTLBL] = "TLB modify", - [EXCP_TLBL] = "TLB load", - [EXCP_TLBS] = "TLB store", - [EXCP_DBE] = "data bus error", - [EXCP_DDBL] = "debug data break load", - [EXCP_THREAD] = "thread", - [EXCP_MDMX] = "MDMX", - [EXCP_C2E] = "precise coprocessor 2", - [EXCP_CACHE] = "cache error", - [EXCP_TLBXI] = "TLB execute-inhibit", - [EXCP_TLBRI] = "TLB read-inhibit", - [EXCP_MSADIS] = "MSA disabled", - [EXCP_MSAFPE] = "MSA floating point", -}; - -static const char *mips_exception_name(int32_t exception) -{ - if (exception < 0 || exception > EXCP_LAST) { - return "unknown"; - } - return excp_names[exception]; -} - -target_ulong exception_resume_pc(CPUMIPSState *env) -{ - target_ulong bad_pc; - target_ulong isa_mode; - - isa_mode = !!(env->hflags & MIPS_HFLAG_M16); - bad_pc = env->active_tc.PC | isa_mode; - if (env->hflags & MIPS_HFLAG_BMASK) { - /* - * If the exception was raised from a delay slot, come back to - * the jump. - */ - bad_pc -= (env->hflags & MIPS_HFLAG_B16 ? 2 : 4); - } - - return bad_pc; -} -#if !defined(CONFIG_USER_ONLY) static void set_hflags_for_handler(CPUMIPSState *env) { /* Exception handlers are entered in 32-bit mode. */ @@ -1400,24 +1233,6 @@ void mips_cpu_do_interrupt(CPUState *cs) cs->exception_index = EXCP_NONE; } -bool mips_cpu_exec_interrupt(CPUState *cs, int interrupt_request) -{ - if (interrupt_request & CPU_INTERRUPT_HARD) { - MIPSCPU *cpu = MIPS_CPU(cs); - CPUMIPSState *env = &cpu->env; - - if (cpu_mips_hw_interrupts_enabled(env) && - cpu_mips_hw_interrupts_pending(env)) { - /* Raise it */ - cs->exception_index = EXCP_EXT_INTERRUPT; - env->error_code = 0; - mips_cpu_do_interrupt(cs); - return true; - } - } - return false; -} - #if !defined(CONFIG_USER_ONLY) void r4k_invalidate_tlb(CPUMIPSState *env, int idx, int use_extra) { @@ -1484,19 +1299,3 @@ void r4k_invalidate_tlb(CPUMIPSState *env, int idx, int use_extra) } } #endif /* !CONFIG_USER_ONLY */ - -void QEMU_NORETURN do_raise_exception_err(CPUMIPSState *env, - uint32_t exception, - int error_code, - uintptr_t pc) -{ - CPUState *cs = env_cpu(env); - - qemu_log_mask(CPU_LOG_INT, "%s: %d (%s) %d\n", - __func__, exception, mips_exception_name(exception), - error_code); - cs->exception_index = exception; - env->error_code = error_code; - - cpu_loop_exit_restore(cs, pc); -} diff --git a/target/mips/internal.h b/target/mips/internal.h index f159187b24..ae1181d202 100644 --- a/target/mips/internal.h +++ b/target/mips/internal.h @@ -399,6 +399,8 @@ void sync_c0_status(CPUMIPSState *env, CPUMIPSState *cpu, int tc); void cpu_mips_store_status(CPUMIPSState *env, target_ulong val); void cpu_mips_store_cause(CPUMIPSState *env, target_ulong val); +const char *mips_exception_name(int32_t exception); + void QEMU_NORETURN do_raise_exception_err(CPUMIPSState *env, uint32_t exception, int error_code, uintptr_t pc); -- cgit v1.2.3-55-g7522 From 4cb213dc90dfc53e447b057fe45d44ddfafc9933 Mon Sep 17 00:00:00 2001 From: Philippe Mathieu-Daudé Date: Sun, 6 Dec 2020 23:27:17 +0100 Subject: target/mips: Rename helper.c as tlb_helper.c This file contains functions related to TLB management, rename it as 'tlb_helper.c'. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20201206233949.3783184-13-f4bug@amsat.org> --- target/mips/helper.c | 1301 ---------------------------------------------- target/mips/meson.build | 2 +- target/mips/tlb_helper.c | 1301 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 1302 insertions(+), 1302 deletions(-) delete mode 100644 target/mips/helper.c create mode 100644 target/mips/tlb_helper.c diff --git a/target/mips/helper.c b/target/mips/helper.c deleted file mode 100644 index 68804b84b1..0000000000 --- a/target/mips/helper.c +++ /dev/null @@ -1,1301 +0,0 @@ -/* - * MIPS emulation helpers for qemu. - * - * Copyright (c) 2004-2005 Jocelyn Mayer - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see . - */ -#include "qemu/osdep.h" - -#include "cpu.h" -#include "internal.h" -#include "exec/exec-all.h" -#include "exec/cpu_ldst.h" -#include "exec/log.h" -#include "hw/mips/cpudevs.h" - -enum { - TLBRET_XI = -6, - TLBRET_RI = -5, - TLBRET_DIRTY = -4, - TLBRET_INVALID = -3, - TLBRET_NOMATCH = -2, - TLBRET_BADADDR = -1, - TLBRET_MATCH = 0 -}; - -#if !defined(CONFIG_USER_ONLY) - -/* no MMU emulation */ -int no_mmu_map_address(CPUMIPSState *env, hwaddr *physical, int *prot, - target_ulong address, int rw, int access_type) -{ - *physical = address; - *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; - return TLBRET_MATCH; -} - -/* fixed mapping MMU emulation */ -int fixed_mmu_map_address(CPUMIPSState *env, hwaddr *physical, int *prot, - target_ulong address, int rw, int access_type) -{ - if (address <= (int32_t)0x7FFFFFFFUL) { - if (!(env->CP0_Status & (1 << CP0St_ERL))) { - *physical = address + 0x40000000UL; - } else { - *physical = address; - } - } else if (address <= (int32_t)0xBFFFFFFFUL) { - *physical = address & 0x1FFFFFFF; - } else { - *physical = address; - } - - *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; - return TLBRET_MATCH; -} - -/* MIPS32/MIPS64 R4000-style MMU emulation */ -int r4k_map_address(CPUMIPSState *env, hwaddr *physical, int *prot, - target_ulong address, int rw, int access_type) -{ - uint16_t ASID = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask; - uint32_t MMID = env->CP0_MemoryMapID; - bool mi = !!((env->CP0_Config5 >> CP0C5_MI) & 1); - uint32_t tlb_mmid; - int i; - - MMID = mi ? MMID : (uint32_t) ASID; - - for (i = 0; i < env->tlb->tlb_in_use; i++) { - r4k_tlb_t *tlb = &env->tlb->mmu.r4k.tlb[i]; - /* 1k pages are not supported. */ - target_ulong mask = tlb->PageMask | ~(TARGET_PAGE_MASK << 1); - target_ulong tag = address & ~mask; - target_ulong VPN = tlb->VPN & ~mask; -#if defined(TARGET_MIPS64) - tag &= env->SEGMask; -#endif - - /* Check ASID/MMID, virtual page number & size */ - tlb_mmid = mi ? tlb->MMID : (uint32_t) tlb->ASID; - if ((tlb->G == 1 || tlb_mmid == MMID) && VPN == tag && !tlb->EHINV) { - /* TLB match */ - int n = !!(address & mask & ~(mask >> 1)); - /* Check access rights */ - if (!(n ? tlb->V1 : tlb->V0)) { - return TLBRET_INVALID; - } - if (rw == MMU_INST_FETCH && (n ? tlb->XI1 : tlb->XI0)) { - return TLBRET_XI; - } - if (rw == MMU_DATA_LOAD && (n ? tlb->RI1 : tlb->RI0)) { - return TLBRET_RI; - } - if (rw != MMU_DATA_STORE || (n ? tlb->D1 : tlb->D0)) { - *physical = tlb->PFN[n] | (address & (mask >> 1)); - *prot = PAGE_READ; - if (n ? tlb->D1 : tlb->D0) { - *prot |= PAGE_WRITE; - } - if (!(n ? tlb->XI1 : tlb->XI0)) { - *prot |= PAGE_EXEC; - } - return TLBRET_MATCH; - } - return TLBRET_DIRTY; - } - } - return TLBRET_NOMATCH; -} - -static int is_seg_am_mapped(unsigned int am, bool eu, int mmu_idx) -{ - /* - * Interpret access control mode and mmu_idx. - * AdE? TLB? - * AM K S U E K S U E - * UK 0 0 1 1 0 0 - - 0 - * MK 1 0 1 1 0 1 - - !eu - * MSK 2 0 0 1 0 1 1 - !eu - * MUSK 3 0 0 0 0 1 1 1 !eu - * MUSUK 4 0 0 0 0 0 1 1 0 - * USK 5 0 0 1 0 0 0 - 0 - * - 6 - - - - - - - - - * UUSK 7 0 0 0 0 0 0 0 0 - */ - int32_t adetlb_mask; - - switch (mmu_idx) { - case 3: /* ERL */ - /* If EU is set, always unmapped */ - if (eu) { - return 0; - } - /* fall through */ - case MIPS_HFLAG_KM: - /* Never AdE, TLB mapped if AM={1,2,3} */ - adetlb_mask = 0x70000000; - goto check_tlb; - - case MIPS_HFLAG_SM: - /* AdE if AM={0,1}, TLB mapped if AM={2,3,4} */ - adetlb_mask = 0xc0380000; - goto check_ade; - - case MIPS_HFLAG_UM: - /* AdE if AM={0,1,2,5}, TLB mapped if AM={3,4} */ - adetlb_mask = 0xe4180000; - /* fall through */ - check_ade: - /* does this AM cause AdE in current execution mode */ - if ((adetlb_mask << am) < 0) { - return TLBRET_BADADDR; - } - adetlb_mask <<= 8; - /* fall through */ - check_tlb: - /* is this AM mapped in current execution mode */ - return ((adetlb_mask << am) < 0); - default: - assert(0); - return TLBRET_BADADDR; - }; -} - -static int get_seg_physical_address(CPUMIPSState *env, hwaddr *physical, - int *prot, target_ulong real_address, - int rw, int access_type, int mmu_idx, - unsigned int am, bool eu, - target_ulong segmask, - hwaddr physical_base) -{ - int mapped = is_seg_am_mapped(am, eu, mmu_idx); - - if (mapped < 0) { - /* is_seg_am_mapped can report TLBRET_BADADDR */ - return mapped; - } else if (mapped) { - /* The segment is TLB mapped */ - return env->tlb->map_address(env, physical, prot, real_address, rw, - access_type); - } else { - /* The segment is unmapped */ - *physical = physical_base | (real_address & segmask); - *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; - return TLBRET_MATCH; - } -} - -static int get_segctl_physical_address(CPUMIPSState *env, hwaddr *physical, - int *prot, target_ulong real_address, - int rw, int access_type, int mmu_idx, - uint16_t segctl, target_ulong segmask) -{ - unsigned int am = (segctl & CP0SC_AM_MASK) >> CP0SC_AM; - bool eu = (segctl >> CP0SC_EU) & 1; - hwaddr pa = ((hwaddr)segctl & CP0SC_PA_MASK) << 20; - - return get_seg_physical_address(env, physical, prot, real_address, rw, - access_type, mmu_idx, am, eu, segmask, - pa & ~(hwaddr)segmask); -} - -static int get_physical_address(CPUMIPSState *env, hwaddr *physical, - int *prot, target_ulong real_address, - int rw, int access_type, int mmu_idx) -{ - /* User mode can only access useg/xuseg */ -#if defined(TARGET_MIPS64) - int user_mode = mmu_idx == MIPS_HFLAG_UM; - int supervisor_mode = mmu_idx == MIPS_HFLAG_SM; - int kernel_mode = !user_mode && !supervisor_mode; - int UX = (env->CP0_Status & (1 << CP0St_UX)) != 0; - int SX = (env->CP0_Status & (1 << CP0St_SX)) != 0; - int KX = (env->CP0_Status & (1 << CP0St_KX)) != 0; -#endif - int ret = TLBRET_MATCH; - /* effective address (modified for KVM T&E kernel segments) */ - target_ulong address = real_address; - -#define USEG_LIMIT ((target_ulong)(int32_t)0x7FFFFFFFUL) -#define KSEG0_BASE ((target_ulong)(int32_t)0x80000000UL) -#define KSEG1_BASE ((target_ulong)(int32_t)0xA0000000UL) -#define KSEG2_BASE ((target_ulong)(int32_t)0xC0000000UL) -#define KSEG3_BASE ((target_ulong)(int32_t)0xE0000000UL) - -#define KVM_KSEG0_BASE ((target_ulong)(int32_t)0x40000000UL) -#define KVM_KSEG2_BASE ((target_ulong)(int32_t)0x60000000UL) - - if (mips_um_ksegs_enabled()) { - /* KVM T&E adds guest kernel segments in useg */ - if (real_address >= KVM_KSEG0_BASE) { - if (real_address < KVM_KSEG2_BASE) { - /* kseg0 */ - address += KSEG0_BASE - KVM_KSEG0_BASE; - } else if (real_address <= USEG_LIMIT) { - /* kseg2/3 */ - address += KSEG2_BASE - KVM_KSEG2_BASE; - } - } - } - - if (address <= USEG_LIMIT) { - /* useg */ - uint16_t segctl; - - if (address >= 0x40000000UL) { - segctl = env->CP0_SegCtl2; - } else { - segctl = env->CP0_SegCtl2 >> 16; - } - ret = get_segctl_physical_address(env, physical, prot, - real_address, rw, access_type, - mmu_idx, segctl, 0x3FFFFFFF); -#if defined(TARGET_MIPS64) - } else if (address < 0x4000000000000000ULL) { - /* xuseg */ - if (UX && address <= (0x3FFFFFFFFFFFFFFFULL & env->SEGMask)) { - ret = env->tlb->map_address(env, physical, prot, - real_address, rw, access_type); - } else { - ret = TLBRET_BADADDR; - } - } else if (address < 0x8000000000000000ULL) { - /* xsseg */ - if ((supervisor_mode || kernel_mode) && - SX && address <= (0x7FFFFFFFFFFFFFFFULL & env->SEGMask)) { - ret = env->tlb->map_address(env, physical, prot, - real_address, rw, access_type); - } else { - ret = TLBRET_BADADDR; - } - } else if (address < 0xC000000000000000ULL) { - /* xkphys */ - if ((address & 0x07FFFFFFFFFFFFFFULL) <= env->PAMask) { - /* KX/SX/UX bit to check for each xkphys EVA access mode */ - static const uint8_t am_ksux[8] = { - [CP0SC_AM_UK] = (1u << CP0St_KX), - [CP0SC_AM_MK] = (1u << CP0St_KX), - [CP0SC_AM_MSK] = (1u << CP0St_SX), - [CP0SC_AM_MUSK] = (1u << CP0St_UX), - [CP0SC_AM_MUSUK] = (1u << CP0St_UX), - [CP0SC_AM_USK] = (1u << CP0St_SX), - [6] = (1u << CP0St_KX), - [CP0SC_AM_UUSK] = (1u << CP0St_UX), - }; - unsigned int am = CP0SC_AM_UK; - unsigned int xr = (env->CP0_SegCtl2 & CP0SC2_XR_MASK) >> CP0SC2_XR; - - if (xr & (1 << ((address >> 59) & 0x7))) { - am = (env->CP0_SegCtl1 & CP0SC1_XAM_MASK) >> CP0SC1_XAM; - } - /* Does CP0_Status.KX/SX/UX permit the access mode (am) */ - if (env->CP0_Status & am_ksux[am]) { - ret = get_seg_physical_address(env, physical, prot, - real_address, rw, access_type, - mmu_idx, am, false, env->PAMask, - 0); - } else { - ret = TLBRET_BADADDR; - } - } else { - ret = TLBRET_BADADDR; - } - } else if (address < 0xFFFFFFFF80000000ULL) { - /* xkseg */ - if (kernel_mode && KX && - address <= (0xFFFFFFFF7FFFFFFFULL & env->SEGMask)) { - ret = env->tlb->map_address(env, physical, prot, - real_address, rw, access_type); - } else { - ret = TLBRET_BADADDR; - } -#endif - } else if (address < KSEG1_BASE) { - /* kseg0 */ - ret = get_segctl_physical_address(env, physical, prot, real_address, rw, - access_type, mmu_idx, - env->CP0_SegCtl1 >> 16, 0x1FFFFFFF); - } else if (address < KSEG2_BASE) { - /* kseg1 */ - ret = get_segctl_physical_address(env, physical, prot, real_address, rw, - access_type, mmu_idx, - env->CP0_SegCtl1, 0x1FFFFFFF); - } else if (address < KSEG3_BASE) { - /* sseg (kseg2) */ - ret = get_segctl_physical_address(env, physical, prot, real_address, rw, - access_type, mmu_idx, - env->CP0_SegCtl0 >> 16, 0x1FFFFFFF); - } else { - /* - * kseg3 - * XXX: debug segment is not emulated - */ - ret = get_segctl_physical_address(env, physical, prot, real_address, rw, - access_type, mmu_idx, - env->CP0_SegCtl0, 0x1FFFFFFF); - } - return ret; -} - -void cpu_mips_tlb_flush(CPUMIPSState *env) -{ - /* Flush qemu's TLB and discard all shadowed entries. */ - tlb_flush(env_cpu(env)); - env->tlb->tlb_in_use = env->tlb->nb_tlb; -} - -#endif /* !CONFIG_USER_ONLY */ - -static void raise_mmu_exception(CPUMIPSState *env, target_ulong address, - int rw, int tlb_error) -{ - CPUState *cs = env_cpu(env); - int exception = 0, error_code = 0; - - if (rw == MMU_INST_FETCH) { - error_code |= EXCP_INST_NOTAVAIL; - } - - switch (tlb_error) { - default: - case TLBRET_BADADDR: - /* Reference to kernel address from user mode or supervisor mode */ - /* Reference to supervisor address from user mode */ - if (rw == MMU_DATA_STORE) { - exception = EXCP_AdES; - } else { - exception = EXCP_AdEL; - } - break; - case TLBRET_NOMATCH: - /* No TLB match for a mapped address */ - if (rw == MMU_DATA_STORE) { - exception = EXCP_TLBS; - } else { - exception = EXCP_TLBL; - } - error_code |= EXCP_TLB_NOMATCH; - break; - case TLBRET_INVALID: - /* TLB match with no valid bit */ - if (rw == MMU_DATA_STORE) { - exception = EXCP_TLBS; - } else { - exception = EXCP_TLBL; - } - break; - case TLBRET_DIRTY: - /* TLB match but 'D' bit is cleared */ - exception = EXCP_LTLBL; - break; - case TLBRET_XI: - /* Execute-Inhibit Exception */ - if (env->CP0_PageGrain & (1 << CP0PG_IEC)) { - exception = EXCP_TLBXI; - } else { - exception = EXCP_TLBL; - } - break; - case TLBRET_RI: - /* Read-Inhibit Exception */ - if (env->CP0_PageGrain & (1 << CP0PG_IEC)) { - exception = EXCP_TLBRI; - } else { - exception = EXCP_TLBL; - } - break; - } - /* Raise exception */ - if (!(env->hflags & MIPS_HFLAG_DM)) { - env->CP0_BadVAddr = address; - } - env->CP0_Context = (env->CP0_Context & ~0x007fffff) | - ((address >> 9) & 0x007ffff0); - env->CP0_EntryHi = (env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask) | - (env->CP0_EntryHi & (1 << CP0EnHi_EHINV)) | - (address & (TARGET_PAGE_MASK << 1)); -#if defined(TARGET_MIPS64) - env->CP0_EntryHi &= env->SEGMask; - env->CP0_XContext = - (env->CP0_XContext & ((~0ULL) << (env->SEGBITS - 7))) | /* PTEBase */ - (extract64(address, 62, 2) << (env->SEGBITS - 9)) | /* R */ - (extract64(address, 13, env->SEGBITS - 13) << 4); /* BadVPN2 */ -#endif - cs->exception_index = exception; - env->error_code = error_code; -} - -#if !defined(CONFIG_USER_ONLY) - -hwaddr mips_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) -{ - MIPSCPU *cpu = MIPS_CPU(cs); - CPUMIPSState *env = &cpu->env; - hwaddr phys_addr; - int prot; - - if (get_physical_address(env, &phys_addr, &prot, addr, 0, ACCESS_INT, - cpu_mmu_index(env, false)) != 0) { - return -1; - } - return phys_addr; -} - -#if !defined(TARGET_MIPS64) - -/* - * Perform hardware page table walk - * - * Memory accesses are performed using the KERNEL privilege level. - * Synchronous exceptions detected on memory accesses cause a silent exit - * from page table walking, resulting in a TLB or XTLB Refill exception. - * - * Implementations are not required to support page table walk memory - * accesses from mapped memory regions. When an unsupported access is - * attempted, a silent exit is taken, resulting in a TLB or XTLB Refill - * exception. - * - * Note that if an exception is caused by AddressTranslation or LoadMemory - * functions, the exception is not taken, a silent exit is taken, - * resulting in a TLB or XTLB Refill exception. - */ - -static bool get_pte(CPUMIPSState *env, uint64_t vaddr, int entry_size, - uint64_t *pte) -{ - if ((vaddr & ((entry_size >> 3) - 1)) != 0) { - return false; - } - if (entry_size == 64) { - *pte = cpu_ldq_code(env, vaddr); - } else { - *pte = cpu_ldl_code(env, vaddr); - } - return true; -} - -static uint64_t get_tlb_entry_layout(CPUMIPSState *env, uint64_t entry, - int entry_size, int ptei) -{ - uint64_t result = entry; - uint64_t rixi; - if (ptei > entry_size) { - ptei -= 32; - } - result >>= (ptei - 2); - rixi = result & 3; - result >>= 2; - result |= rixi << CP0EnLo_XI; - return result; -} - -static int walk_directory(CPUMIPSState *env, uint64_t *vaddr, - int directory_index, bool *huge_page, bool *hgpg_directory_hit, - uint64_t *pw_entrylo0, uint64_t *pw_entrylo1) -{ - int dph = (env->CP0_PWCtl >> CP0PC_DPH) & 0x1; - int psn = (env->CP0_PWCtl >> CP0PC_PSN) & 0x3F; - int hugepg = (env->CP0_PWCtl >> CP0PC_HUGEPG) & 0x1; - int pf_ptew = (env->CP0_PWField >> CP0PF_PTEW) & 0x3F; - int ptew = (env->CP0_PWSize >> CP0PS_PTEW) & 0x3F; - int native_shift = (((env->CP0_PWSize >> CP0PS_PS) & 1) == 0) ? 2 : 3; - int directory_shift = (ptew > 1) ? -1 : - (hugepg && (ptew == 1)) ? native_shift + 1 : native_shift; - int leaf_shift = (ptew > 1) ? -1 : - (ptew == 1) ? native_shift + 1 : native_shift; - uint32_t direntry_size = 1 << (directory_shift + 3); - uint32_t leafentry_size = 1 << (leaf_shift + 3); - uint64_t entry; - uint64_t paddr; - int prot; - uint64_t lsb = 0; - uint64_t w = 0; - - if (get_physical_address(env, &paddr, &prot, *vaddr, MMU_DATA_LOAD, - ACCESS_INT, cpu_mmu_index(env, false)) != - TLBRET_MATCH) { - /* wrong base address */ - return 0; - } - if (!get_pte(env, *vaddr, direntry_size, &entry)) { - return 0; - } - - if ((entry & (1 << psn)) && hugepg) { - *huge_page = true; - *hgpg_directory_hit = true; - entry = get_tlb_entry_layout(env, entry, leafentry_size, pf_ptew); - w = directory_index - 1; - if (directory_index & 0x1) { - /* Generate adjacent page from same PTE for odd TLB page */ - lsb = (1 << w) >> 6; - *pw_entrylo0 = entry & ~lsb; /* even page */ - *pw_entrylo1 = entry | lsb; /* odd page */ - } else if (dph) { - int oddpagebit = 1 << leaf_shift; - uint64_t vaddr2 = *vaddr ^ oddpagebit; - if (*vaddr & oddpagebit) { - *pw_entrylo1 = entry; - } else { - *pw_entrylo0 = entry; - } - if (get_physical_address(env, &paddr, &prot, vaddr2, MMU_DATA_LOAD, - ACCESS_INT, cpu_mmu_index(env, false)) != - TLBRET_MATCH) { - return 0; - } - if (!get_pte(env, vaddr2, leafentry_size, &entry)) { - return 0; - } - entry = get_tlb_entry_layout(env, entry, leafentry_size, pf_ptew); - if (*vaddr & oddpagebit) { - *pw_entrylo0 = entry; - } else { - *pw_entrylo1 = entry; - } - } else { - return 0; - } - return 1; - } else { - *vaddr = entry; - return 2; - } -} - -static bool page_table_walk_refill(CPUMIPSState *env, vaddr address, int rw, - int mmu_idx) -{ - int gdw = (env->CP0_PWSize >> CP0PS_GDW) & 0x3F; - int udw = (env->CP0_PWSize >> CP0PS_UDW) & 0x3F; - int mdw = (env->CP0_PWSize >> CP0PS_MDW) & 0x3F; - int ptw = (env->CP0_PWSize >> CP0PS_PTW) & 0x3F; - int ptew = (env->CP0_PWSize >> CP0PS_PTEW) & 0x3F; - - /* Initial values */ - bool huge_page = false; - bool hgpg_bdhit = false; - bool hgpg_gdhit = false; - bool hgpg_udhit = false; - bool hgpg_mdhit = false; - - int32_t pw_pagemask = 0; - target_ulong pw_entryhi = 0; - uint64_t pw_entrylo0 = 0; - uint64_t pw_entrylo1 = 0; - - /* Native pointer size */ - /*For the 32-bit architectures, this bit is fixed to 0.*/ - int native_shift = (((env->CP0_PWSize >> CP0PS_PS) & 1) == 0) ? 2 : 3; - - /* Indices from PWField */ - int pf_gdw = (env->CP0_PWField >> CP0PF_GDW) & 0x3F; - int pf_udw = (env->CP0_PWField >> CP0PF_UDW) & 0x3F; - int pf_mdw = (env->CP0_PWField >> CP0PF_MDW) & 0x3F; - int pf_ptw = (env->CP0_PWField >> CP0PF_PTW) & 0x3F; - int pf_ptew = (env->CP0_PWField >> CP0PF_PTEW) & 0x3F; - - /* Indices computed from faulting address */ - int gindex = (address >> pf_gdw) & ((1 << gdw) - 1); - int uindex = (address >> pf_udw) & ((1 << udw) - 1); - int mindex = (address >> pf_mdw) & ((1 << mdw) - 1); - int ptindex = (address >> pf_ptw) & ((1 << ptw) - 1); - - /* Other HTW configs */ - int hugepg = (env->CP0_PWCtl >> CP0PC_HUGEPG) & 0x1; - - /* HTW Shift values (depend on entry size) */ - int directory_shift = (ptew > 1) ? -1 : - (hugepg && (ptew == 1)) ? native_shift + 1 : native_shift; - int leaf_shift = (ptew > 1) ? -1 : - (ptew == 1) ? native_shift + 1 : native_shift; - - /* Offsets into tables */ - int goffset = gindex << directory_shift; - int uoffset = uindex << directory_shift; - int moffset = mindex << directory_shift; - int ptoffset0 = (ptindex >> 1) << (leaf_shift + 1); - int ptoffset1 = ptoffset0 | (1 << (leaf_shift)); - - uint32_t leafentry_size = 1 << (leaf_shift + 3); - - /* Starting address - Page Table Base */ - uint64_t vaddr = env->CP0_PWBase; - - uint64_t dir_entry; - uint64_t paddr; - int prot; - int m; - - if (!(env->CP0_Config3 & (1 << CP0C3_PW))) { - /* walker is unimplemented */ - return false; - } - if (!(env->CP0_PWCtl & (1 << CP0PC_PWEN))) { - /* walker is disabled */ - return false; - } - if (!(gdw > 0 || udw > 0 || mdw > 0)) { - /* no structure to walk */ - return false; - } - if ((directory_shift == -1) || (leaf_shift == -1)) { - return false; - } - - /* Global Directory */ - if (gdw > 0) { - vaddr |= goffset; - switch (walk_directory(env, &vaddr, pf_gdw, &huge_page, &hgpg_gdhit, - &pw_entrylo0, &pw_entrylo1)) - { - case 0: - return false; - case 1: - goto refill; - case 2: - default: - break; - } - } - - /* Upper directory */ - if (udw > 0) { - vaddr |= uoffset; - switch (walk_directory(env, &vaddr, pf_udw, &huge_page, &hgpg_udhit, - &pw_entrylo0, &pw_entrylo1)) - { - case 0: - return false; - case 1: - goto refill; - case 2: - default: - break; - } - } - - /* Middle directory */ - if (mdw > 0) { - vaddr |= moffset; - switch (walk_directory(env, &vaddr, pf_mdw, &huge_page, &hgpg_mdhit, - &pw_entrylo0, &pw_entrylo1)) - { - case 0: - return false; - case 1: - goto refill; - case 2: - default: - break; - } - } - - /* Leaf Level Page Table - First half of PTE pair */ - vaddr |= ptoffset0; - if (get_physical_address(env, &paddr, &prot, vaddr, MMU_DATA_LOAD, - ACCESS_INT, cpu_mmu_index(env, false)) != - TLBRET_MATCH) { - return false; - } - if (!get_pte(env, vaddr, leafentry_size, &dir_entry)) { - return false; - } - dir_entry = get_tlb_entry_layout(env, dir_entry, leafentry_size, pf_ptew); - pw_entrylo0 = dir_entry; - - /* Leaf Level Page Table - Second half of PTE pair */ - vaddr |= ptoffset1; - if (get_physical_address(env, &paddr, &prot, vaddr, MMU_DATA_LOAD, - ACCESS_INT, cpu_mmu_index(env, false)) != - TLBRET_MATCH) { - return false; - } - if (!get_pte(env, vaddr, leafentry_size, &dir_entry)) { - return false; - } - dir_entry = get_tlb_entry_layout(env, dir_entry, leafentry_size, pf_ptew); - pw_entrylo1 = dir_entry; - -refill: - - m = (1 << pf_ptw) - 1; - - if (huge_page) { - switch (hgpg_bdhit << 3 | hgpg_gdhit << 2 | hgpg_udhit << 1 | - hgpg_mdhit) - { - case 4: - m = (1 << pf_gdw) - 1; - if (pf_gdw & 1) { - m >>= 1; - } - break; - case 2: - m = (1 << pf_udw) - 1; - if (pf_udw & 1) { - m >>= 1; - } - break; - case 1: - m = (1 << pf_mdw) - 1; - if (pf_mdw & 1) { - m >>= 1; - } - break; - } - } - pw_pagemask = m >> TARGET_PAGE_BITS_MIN; - update_pagemask(env, pw_pagemask << CP0PM_MASK, &pw_pagemask); - pw_entryhi = (address & ~0x1fff) | (env->CP0_EntryHi & 0xFF); - { - target_ulong tmp_entryhi = env->CP0_EntryHi; - int32_t tmp_pagemask = env->CP0_PageMask; - uint64_t tmp_entrylo0 = env->CP0_EntryLo0; - uint64_t tmp_entrylo1 = env->CP0_EntryLo1; - - env->CP0_EntryHi = pw_entryhi; - env->CP0_PageMask = pw_pagemask; - env->CP0_EntryLo0 = pw_entrylo0; - env->CP0_EntryLo1 = pw_entrylo1; - - /* - * The hardware page walker inserts a page into the TLB in a manner - * identical to a TLBWR instruction as executed by the software refill - * handler. - */ - r4k_helper_tlbwr(env); - - env->CP0_EntryHi = tmp_entryhi; - env->CP0_PageMask = tmp_pagemask; - env->CP0_EntryLo0 = tmp_entrylo0; - env->CP0_EntryLo1 = tmp_entrylo1; - } - return true; -} -#endif -#endif /* !CONFIG_USER_ONLY */ - -bool mips_cpu_tlb_fill(CPUState *cs, vaddr address, int size, - MMUAccessType access_type, int mmu_idx, - bool probe, uintptr_t retaddr) -{ - MIPSCPU *cpu = MIPS_CPU(cs); - CPUMIPSState *env = &cpu->env; -#if !defined(CONFIG_USER_ONLY) - hwaddr physical; - int prot; - int mips_access_type; -#endif - int ret = TLBRET_BADADDR; - - /* data access */ -#if !defined(CONFIG_USER_ONLY) - /* XXX: put correct access by using cpu_restore_state() correctly */ - mips_access_type = ACCESS_INT; - ret = get_physical_address(env, &physical, &prot, address, - access_type, mips_access_type, mmu_idx); - switch (ret) { - case TLBRET_MATCH: - qemu_log_mask(CPU_LOG_MMU, - "%s address=%" VADDR_PRIx " physical " TARGET_FMT_plx - " prot %d\n", __func__, address, physical, prot); - break; - default: - qemu_log_mask(CPU_LOG_MMU, - "%s address=%" VADDR_PRIx " ret %d\n", __func__, address, - ret); - break; - } - if (ret == TLBRET_MATCH) { - tlb_set_page(cs, address & TARGET_PAGE_MASK, - physical & TARGET_PAGE_MASK, prot, - mmu_idx, TARGET_PAGE_SIZE); - return true; - } -#if !defined(TARGET_MIPS64) - if ((ret == TLBRET_NOMATCH) && (env->tlb->nb_tlb > 1)) { - /* - * Memory reads during hardware page table walking are performed - * as if they were kernel-mode load instructions. - */ - int mode = (env->hflags & MIPS_HFLAG_KSU); - bool ret_walker; - env->hflags &= ~MIPS_HFLAG_KSU; - ret_walker = page_table_walk_refill(env, address, access_type, mmu_idx); - env->hflags |= mode; - if (ret_walker) { - ret = get_physical_address(env, &physical, &prot, address, - access_type, mips_access_type, mmu_idx); - if (ret == TLBRET_MATCH) { - tlb_set_page(cs, address & TARGET_PAGE_MASK, - physical & TARGET_PAGE_MASK, prot, - mmu_idx, TARGET_PAGE_SIZE); - return true; - } - } - } -#endif - if (probe) { - return false; - } -#endif - - raise_mmu_exception(env, address, access_type, ret); - do_raise_exception_err(env, cs->exception_index, env->error_code, retaddr); -} - -#ifndef CONFIG_USER_ONLY -hwaddr cpu_mips_translate_address(CPUMIPSState *env, target_ulong address, - int rw) -{ - hwaddr physical; - int prot; - int access_type; - int ret = 0; - - /* data access */ - access_type = ACCESS_INT; - ret = get_physical_address(env, &physical, &prot, address, rw, access_type, - cpu_mmu_index(env, false)); - if (ret != TLBRET_MATCH) { - raise_mmu_exception(env, address, rw, ret); - return -1LL; - } else { - return physical; - } -} - -static void set_hflags_for_handler(CPUMIPSState *env) -{ - /* Exception handlers are entered in 32-bit mode. */ - env->hflags &= ~(MIPS_HFLAG_M16); - /* ...except that microMIPS lets you choose. */ - if (env->insn_flags & ASE_MICROMIPS) { - env->hflags |= (!!(env->CP0_Config3 & - (1 << CP0C3_ISA_ON_EXC)) - << MIPS_HFLAG_M16_SHIFT); - } -} - -static inline void set_badinstr_registers(CPUMIPSState *env) -{ - if (env->insn_flags & ISA_NANOMIPS32) { - if (env->CP0_Config3 & (1 << CP0C3_BI)) { - uint32_t instr = (cpu_lduw_code(env, env->active_tc.PC)) << 16; - if ((instr & 0x10000000) == 0) { - instr |= cpu_lduw_code(env, env->active_tc.PC + 2); - } - env->CP0_BadInstr = instr; - - if ((instr & 0xFC000000) == 0x60000000) { - instr = cpu_lduw_code(env, env->active_tc.PC + 4) << 16; - env->CP0_BadInstrX = instr; - } - } - return; - } - - if (env->hflags & MIPS_HFLAG_M16) { - /* TODO: add BadInstr support for microMIPS */ - return; - } - if (env->CP0_Config3 & (1 << CP0C3_BI)) { - env->CP0_BadInstr = cpu_ldl_code(env, env->active_tc.PC); - } - if ((env->CP0_Config3 & (1 << CP0C3_BP)) && - (env->hflags & MIPS_HFLAG_BMASK)) { - env->CP0_BadInstrP = cpu_ldl_code(env, env->active_tc.PC - 4); - } -} - -#endif /* !CONFIG_USER_ONLY */ - -void mips_cpu_do_interrupt(CPUState *cs) -{ -#if !defined(CONFIG_USER_ONLY) - MIPSCPU *cpu = MIPS_CPU(cs); - CPUMIPSState *env = &cpu->env; - bool update_badinstr = 0; - target_ulong offset; - int cause = -1; - - if (qemu_loglevel_mask(CPU_LOG_INT) - && cs->exception_index != EXCP_EXT_INTERRUPT) { - qemu_log("%s enter: PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx - " %s exception\n", - __func__, env->active_tc.PC, env->CP0_EPC, - mips_exception_name(cs->exception_index)); - } - if (cs->exception_index == EXCP_EXT_INTERRUPT && - (env->hflags & MIPS_HFLAG_DM)) { - cs->exception_index = EXCP_DINT; - } - offset = 0x180; - switch (cs->exception_index) { - case EXCP_DSS: - env->CP0_Debug |= 1 << CP0DB_DSS; - /* - * Debug single step cannot be raised inside a delay slot and - * resume will always occur on the next instruction - * (but we assume the pc has always been updated during - * code translation). - */ - env->CP0_DEPC = env->active_tc.PC | !!(env->hflags & MIPS_HFLAG_M16); - goto enter_debug_mode; - case EXCP_DINT: - env->CP0_Debug |= 1 << CP0DB_DINT; - goto set_DEPC; - case EXCP_DIB: - env->CP0_Debug |= 1 << CP0DB_DIB; - goto set_DEPC; - case EXCP_DBp: - env->CP0_Debug |= 1 << CP0DB_DBp; - /* Setup DExcCode - SDBBP instruction */ - env->CP0_Debug = (env->CP0_Debug & ~(0x1fULL << CP0DB_DEC)) | - (9 << CP0DB_DEC); - goto set_DEPC; - case EXCP_DDBS: - env->CP0_Debug |= 1 << CP0DB_DDBS; - goto set_DEPC; - case EXCP_DDBL: - env->CP0_Debug |= 1 << CP0DB_DDBL; - set_DEPC: - env->CP0_DEPC = exception_resume_pc(env); - env->hflags &= ~MIPS_HFLAG_BMASK; - enter_debug_mode: - if (env->insn_flags & ISA_MIPS3) { - env->hflags |= MIPS_HFLAG_64; - if (!(env->insn_flags & ISA_MIPS_R6) || - env->CP0_Status & (1 << CP0St_KX)) { - env->hflags &= ~MIPS_HFLAG_AWRAP; - } - } - env->hflags |= MIPS_HFLAG_DM | MIPS_HFLAG_CP0; - env->hflags &= ~(MIPS_HFLAG_KSU); - /* EJTAG probe trap enable is not implemented... */ - if (!(env->CP0_Status & (1 << CP0St_EXL))) { - env->CP0_Cause &= ~(1U << CP0Ca_BD); - } - env->active_tc.PC = env->exception_base + 0x480; - set_hflags_for_handler(env); - break; - case EXCP_RESET: - cpu_reset(CPU(cpu)); - break; - case EXCP_SRESET: - env->CP0_Status |= (1 << CP0St_SR); - memset(env->CP0_WatchLo, 0, sizeof(env->CP0_WatchLo)); - goto set_error_EPC; - case EXCP_NMI: - env->CP0_Status |= (1 << CP0St_NMI); - set_error_EPC: - env->CP0_ErrorEPC = exception_resume_pc(env); - env->hflags &= ~MIPS_HFLAG_BMASK; - env->CP0_Status |= (1 << CP0St_ERL) | (1 << CP0St_BEV); - if (env->insn_flags & ISA_MIPS3) { - env->hflags |= MIPS_HFLAG_64; - if (!(env->insn_flags & ISA_MIPS_R6) || - env->CP0_Status & (1 << CP0St_KX)) { - env->hflags &= ~MIPS_HFLAG_AWRAP; - } - } - env->hflags |= MIPS_HFLAG_CP0; - env->hflags &= ~(MIPS_HFLAG_KSU); - if (!(env->CP0_Status & (1 << CP0St_EXL))) { - env->CP0_Cause &= ~(1U << CP0Ca_BD); - } - env->active_tc.PC = env->exception_base; - set_hflags_for_handler(env); - break; - case EXCP_EXT_INTERRUPT: - cause = 0; - if (env->CP0_Cause & (1 << CP0Ca_IV)) { - uint32_t spacing = (env->CP0_IntCtl >> CP0IntCtl_VS) & 0x1f; - - if ((env->CP0_Status & (1 << CP0St_BEV)) || spacing == 0) { - offset = 0x200; - } else { - uint32_t vector = 0; - uint32_t pending = (env->CP0_Cause & CP0Ca_IP_mask) >> CP0Ca_IP; - - if (env->CP0_Config3 & (1 << CP0C3_VEIC)) { - /* - * For VEIC mode, the external interrupt controller feeds - * the vector through the CP0Cause IP lines. - */ - vector = pending; - } else { - /* - * Vectored Interrupts - * Mask with Status.IM7-IM0 to get enabled interrupts. - */ - pending &= (env->CP0_Status >> CP0St_IM) & 0xff; - /* Find the highest-priority interrupt. */ - while (pending >>= 1) { - vector++; - } - } - offset = 0x200 + (vector * (spacing << 5)); - } - } - goto set_EPC; - case EXCP_LTLBL: - cause = 1; - update_badinstr = !(env->error_code & EXCP_INST_NOTAVAIL); - goto set_EPC; - case EXCP_TLBL: - cause = 2; - update_badinstr = !(env->error_code & EXCP_INST_NOTAVAIL); - if ((env->error_code & EXCP_TLB_NOMATCH) && - !(env->CP0_Status & (1 << CP0St_EXL))) { -#if defined(TARGET_MIPS64) - int R = env->CP0_BadVAddr >> 62; - int UX = (env->CP0_Status & (1 << CP0St_UX)) != 0; - int KX = (env->CP0_Status & (1 << CP0St_KX)) != 0; - - if ((R != 0 || UX) && (R != 3 || KX) && - (!(env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)))) { - offset = 0x080; - } else { -#endif - offset = 0x000; -#if defined(TARGET_MIPS64) - } -#endif - } - goto set_EPC; - case EXCP_TLBS: - cause = 3; - update_badinstr = 1; - if ((env->error_code & EXCP_TLB_NOMATCH) && - !(env->CP0_Status & (1 << CP0St_EXL))) { -#if defined(TARGET_MIPS64) - int R = env->CP0_BadVAddr >> 62; - int UX = (env->CP0_Status & (1 << CP0St_UX)) != 0; - int KX = (env->CP0_Status & (1 << CP0St_KX)) != 0; - - if ((R != 0 || UX) && (R != 3 || KX) && - (!(env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)))) { - offset = 0x080; - } else { -#endif - offset = 0x000; -#if defined(TARGET_MIPS64) - } -#endif - } - goto set_EPC; - case EXCP_AdEL: - cause = 4; - update_badinstr = !(env->error_code & EXCP_INST_NOTAVAIL); - goto set_EPC; - case EXCP_AdES: - cause = 5; - update_badinstr = 1; - goto set_EPC; - case EXCP_IBE: - cause = 6; - goto set_EPC; - case EXCP_DBE: - cause = 7; - goto set_EPC; - case EXCP_SYSCALL: - cause = 8; - update_badinstr = 1; - goto set_EPC; - case EXCP_BREAK: - cause = 9; - update_badinstr = 1; - goto set_EPC; - case EXCP_RI: - cause = 10; - update_badinstr = 1; - goto set_EPC; - case EXCP_CpU: - cause = 11; - update_badinstr = 1; - env->CP0_Cause = (env->CP0_Cause & ~(0x3 << CP0Ca_CE)) | - (env->error_code << CP0Ca_CE); - goto set_EPC; - case EXCP_OVERFLOW: - cause = 12; - update_badinstr = 1; - goto set_EPC; - case EXCP_TRAP: - cause = 13; - update_badinstr = 1; - goto set_EPC; - case EXCP_MSAFPE: - cause = 14; - update_badinstr = 1; - goto set_EPC; - case EXCP_FPE: - cause = 15; - update_badinstr = 1; - goto set_EPC; - case EXCP_C2E: - cause = 18; - goto set_EPC; - case EXCP_TLBRI: - cause = 19; - update_badinstr = 1; - goto set_EPC; - case EXCP_TLBXI: - cause = 20; - goto set_EPC; - case EXCP_MSADIS: - cause = 21; - update_badinstr = 1; - goto set_EPC; - case EXCP_MDMX: - cause = 22; - goto set_EPC; - case EXCP_DWATCH: - cause = 23; - /* XXX: TODO: manage deferred watch exceptions */ - goto set_EPC; - case EXCP_MCHECK: - cause = 24; - goto set_EPC; - case EXCP_THREAD: - cause = 25; - goto set_EPC; - case EXCP_DSPDIS: - cause = 26; - goto set_EPC; - case EXCP_CACHE: - cause = 30; - offset = 0x100; - set_EPC: - if (!(env->CP0_Status & (1 << CP0St_EXL))) { - env->CP0_EPC = exception_resume_pc(env); - if (update_badinstr) { - set_badinstr_registers(env); - } - if (env->hflags & MIPS_HFLAG_BMASK) { - env->CP0_Cause |= (1U << CP0Ca_BD); - } else { - env->CP0_Cause &= ~(1U << CP0Ca_BD); - } - env->CP0_Status |= (1 << CP0St_EXL); - if (env->insn_flags & ISA_MIPS3) { - env->hflags |= MIPS_HFLAG_64; - if (!(env->insn_flags & ISA_MIPS_R6) || - env->CP0_Status & (1 << CP0St_KX)) { - env->hflags &= ~MIPS_HFLAG_AWRAP; - } - } - env->hflags |= MIPS_HFLAG_CP0; - env->hflags &= ~(MIPS_HFLAG_KSU); - } - env->hflags &= ~MIPS_HFLAG_BMASK; - if (env->CP0_Status & (1 << CP0St_BEV)) { - env->active_tc.PC = env->exception_base + 0x200; - } else if (cause == 30 && !(env->CP0_Config3 & (1 << CP0C3_SC) && - env->CP0_Config5 & (1 << CP0C5_CV))) { - /* Force KSeg1 for cache errors */ - env->active_tc.PC = KSEG1_BASE | (env->CP0_EBase & 0x1FFFF000); - } else { - env->active_tc.PC = env->CP0_EBase & ~0xfff; - } - - env->active_tc.PC += offset; - set_hflags_for_handler(env); - env->CP0_Cause = (env->CP0_Cause & ~(0x1f << CP0Ca_EC)) | - (cause << CP0Ca_EC); - break; - default: - abort(); - } - if (qemu_loglevel_mask(CPU_LOG_INT) - && cs->exception_index != EXCP_EXT_INTERRUPT) { - qemu_log("%s: PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx " cause %d\n" - " S %08x C %08x A " TARGET_FMT_lx " D " TARGET_FMT_lx "\n", - __func__, env->active_tc.PC, env->CP0_EPC, cause, - env->CP0_Status, env->CP0_Cause, env->CP0_BadVAddr, - env->CP0_DEPC); - } -#endif - cs->exception_index = EXCP_NONE; -} - -#if !defined(CONFIG_USER_ONLY) -void r4k_invalidate_tlb(CPUMIPSState *env, int idx, int use_extra) -{ - CPUState *cs = env_cpu(env); - r4k_tlb_t *tlb; - target_ulong addr; - target_ulong end; - uint16_t ASID = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask; - uint32_t MMID = env->CP0_MemoryMapID; - bool mi = !!((env->CP0_Config5 >> CP0C5_MI) & 1); - uint32_t tlb_mmid; - target_ulong mask; - - MMID = mi ? MMID : (uint32_t) ASID; - - tlb = &env->tlb->mmu.r4k.tlb[idx]; - /* - * The qemu TLB is flushed when the ASID/MMID changes, so no need to - * flush these entries again. - */ - tlb_mmid = mi ? tlb->MMID : (uint32_t) tlb->ASID; - if (tlb->G == 0 && tlb_mmid != MMID) { - return; - } - - if (use_extra && env->tlb->tlb_in_use < MIPS_TLB_MAX) { - /* - * For tlbwr, we can shadow the discarded entry into - * a new (fake) TLB entry, as long as the guest can not - * tell that it's there. - */ - env->tlb->mmu.r4k.tlb[env->tlb->tlb_in_use] = *tlb; - env->tlb->tlb_in_use++; - return; - } - - /* 1k pages are not supported. */ - mask = tlb->PageMask | ~(TARGET_PAGE_MASK << 1); - if (tlb->V0) { - addr = tlb->VPN & ~mask; -#if defined(TARGET_MIPS64) - if (addr >= (0xFFFFFFFF80000000ULL & env->SEGMask)) { - addr |= 0x3FFFFF0000000000ULL; - } -#endif - end = addr | (mask >> 1); - while (addr < end) { - tlb_flush_page(cs, addr); - addr += TARGET_PAGE_SIZE; - } - } - if (tlb->V1) { - addr = (tlb->VPN & ~mask) | ((mask >> 1) + 1); -#if defined(TARGET_MIPS64) - if (addr >= (0xFFFFFFFF80000000ULL & env->SEGMask)) { - addr |= 0x3FFFFF0000000000ULL; - } -#endif - end = addr | mask; - while (addr - 1 < end) { - tlb_flush_page(cs, addr); - addr += TARGET_PAGE_SIZE; - } - } -} -#endif /* !CONFIG_USER_ONLY */ diff --git a/target/mips/meson.build b/target/mips/meson.build index 4179395a8e..5a49951c6d 100644 --- a/target/mips/meson.build +++ b/target/mips/meson.build @@ -4,10 +4,10 @@ mips_ss.add(files( 'dsp_helper.c', 'fpu_helper.c', 'gdbstub.c', - 'helper.c', 'lmmi_helper.c', 'msa_helper.c', 'op_helper.c', + 'tlb_helper.c', 'translate.c', )) mips_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c')) diff --git a/target/mips/tlb_helper.c b/target/mips/tlb_helper.c new file mode 100644 index 0000000000..b02c0479e7 --- /dev/null +++ b/target/mips/tlb_helper.c @@ -0,0 +1,1301 @@ +/* + * MIPS TLB (Translation lookaside buffer) helpers. + * + * Copyright (c) 2004-2005 Jocelyn Mayer + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ +#include "qemu/osdep.h" + +#include "cpu.h" +#include "internal.h" +#include "exec/exec-all.h" +#include "exec/cpu_ldst.h" +#include "exec/log.h" +#include "hw/mips/cpudevs.h" + +enum { + TLBRET_XI = -6, + TLBRET_RI = -5, + TLBRET_DIRTY = -4, + TLBRET_INVALID = -3, + TLBRET_NOMATCH = -2, + TLBRET_BADADDR = -1, + TLBRET_MATCH = 0 +}; + +#if !defined(CONFIG_USER_ONLY) + +/* no MMU emulation */ +int no_mmu_map_address(CPUMIPSState *env, hwaddr *physical, int *prot, + target_ulong address, int rw, int access_type) +{ + *physical = address; + *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; + return TLBRET_MATCH; +} + +/* fixed mapping MMU emulation */ +int fixed_mmu_map_address(CPUMIPSState *env, hwaddr *physical, int *prot, + target_ulong address, int rw, int access_type) +{ + if (address <= (int32_t)0x7FFFFFFFUL) { + if (!(env->CP0_Status & (1 << CP0St_ERL))) { + *physical = address + 0x40000000UL; + } else { + *physical = address; + } + } else if (address <= (int32_t)0xBFFFFFFFUL) { + *physical = address & 0x1FFFFFFF; + } else { + *physical = address; + } + + *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; + return TLBRET_MATCH; +} + +/* MIPS32/MIPS64 R4000-style MMU emulation */ +int r4k_map_address(CPUMIPSState *env, hwaddr *physical, int *prot, + target_ulong address, int rw, int access_type) +{ + uint16_t ASID = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask; + uint32_t MMID = env->CP0_MemoryMapID; + bool mi = !!((env->CP0_Config5 >> CP0C5_MI) & 1); + uint32_t tlb_mmid; + int i; + + MMID = mi ? MMID : (uint32_t) ASID; + + for (i = 0; i < env->tlb->tlb_in_use; i++) { + r4k_tlb_t *tlb = &env->tlb->mmu.r4k.tlb[i]; + /* 1k pages are not supported. */ + target_ulong mask = tlb->PageMask | ~(TARGET_PAGE_MASK << 1); + target_ulong tag = address & ~mask; + target_ulong VPN = tlb->VPN & ~mask; +#if defined(TARGET_MIPS64) + tag &= env->SEGMask; +#endif + + /* Check ASID/MMID, virtual page number & size */ + tlb_mmid = mi ? tlb->MMID : (uint32_t) tlb->ASID; + if ((tlb->G == 1 || tlb_mmid == MMID) && VPN == tag && !tlb->EHINV) { + /* TLB match */ + int n = !!(address & mask & ~(mask >> 1)); + /* Check access rights */ + if (!(n ? tlb->V1 : tlb->V0)) { + return TLBRET_INVALID; + } + if (rw == MMU_INST_FETCH && (n ? tlb->XI1 : tlb->XI0)) { + return TLBRET_XI; + } + if (rw == MMU_DATA_LOAD && (n ? tlb->RI1 : tlb->RI0)) { + return TLBRET_RI; + } + if (rw != MMU_DATA_STORE || (n ? tlb->D1 : tlb->D0)) { + *physical = tlb->PFN[n] | (address & (mask >> 1)); + *prot = PAGE_READ; + if (n ? tlb->D1 : tlb->D0) { + *prot |= PAGE_WRITE; + } + if (!(n ? tlb->XI1 : tlb->XI0)) { + *prot |= PAGE_EXEC; + } + return TLBRET_MATCH; + } + return TLBRET_DIRTY; + } + } + return TLBRET_NOMATCH; +} + +static int is_seg_am_mapped(unsigned int am, bool eu, int mmu_idx) +{ + /* + * Interpret access control mode and mmu_idx. + * AdE? TLB? + * AM K S U E K S U E + * UK 0 0 1 1 0 0 - - 0 + * MK 1 0 1 1 0 1 - - !eu + * MSK 2 0 0 1 0 1 1 - !eu + * MUSK 3 0 0 0 0 1 1 1 !eu + * MUSUK 4 0 0 0 0 0 1 1 0 + * USK 5 0 0 1 0 0 0 - 0 + * - 6 - - - - - - - - + * UUSK 7 0 0 0 0 0 0 0 0 + */ + int32_t adetlb_mask; + + switch (mmu_idx) { + case 3: /* ERL */ + /* If EU is set, always unmapped */ + if (eu) { + return 0; + } + /* fall through */ + case MIPS_HFLAG_KM: + /* Never AdE, TLB mapped if AM={1,2,3} */ + adetlb_mask = 0x70000000; + goto check_tlb; + + case MIPS_HFLAG_SM: + /* AdE if AM={0,1}, TLB mapped if AM={2,3,4} */ + adetlb_mask = 0xc0380000; + goto check_ade; + + case MIPS_HFLAG_UM: + /* AdE if AM={0,1,2,5}, TLB mapped if AM={3,4} */ + adetlb_mask = 0xe4180000; + /* fall through */ + check_ade: + /* does this AM cause AdE in current execution mode */ + if ((adetlb_mask << am) < 0) { + return TLBRET_BADADDR; + } + adetlb_mask <<= 8; + /* fall through */ + check_tlb: + /* is this AM mapped in current execution mode */ + return ((adetlb_mask << am) < 0); + default: + assert(0); + return TLBRET_BADADDR; + }; +} + +static int get_seg_physical_address(CPUMIPSState *env, hwaddr *physical, + int *prot, target_ulong real_address, + int rw, int access_type, int mmu_idx, + unsigned int am, bool eu, + target_ulong segmask, + hwaddr physical_base) +{ + int mapped = is_seg_am_mapped(am, eu, mmu_idx); + + if (mapped < 0) { + /* is_seg_am_mapped can report TLBRET_BADADDR */ + return mapped; + } else if (mapped) { + /* The segment is TLB mapped */ + return env->tlb->map_address(env, physical, prot, real_address, rw, + access_type); + } else { + /* The segment is unmapped */ + *physical = physical_base | (real_address & segmask); + *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; + return TLBRET_MATCH; + } +} + +static int get_segctl_physical_address(CPUMIPSState *env, hwaddr *physical, + int *prot, target_ulong real_address, + int rw, int access_type, int mmu_idx, + uint16_t segctl, target_ulong segmask) +{ + unsigned int am = (segctl & CP0SC_AM_MASK) >> CP0SC_AM; + bool eu = (segctl >> CP0SC_EU) & 1; + hwaddr pa = ((hwaddr)segctl & CP0SC_PA_MASK) << 20; + + return get_seg_physical_address(env, physical, prot, real_address, rw, + access_type, mmu_idx, am, eu, segmask, + pa & ~(hwaddr)segmask); +} + +static int get_physical_address(CPUMIPSState *env, hwaddr *physical, + int *prot, target_ulong real_address, + int rw, int access_type, int mmu_idx) +{ + /* User mode can only access useg/xuseg */ +#if defined(TARGET_MIPS64) + int user_mode = mmu_idx == MIPS_HFLAG_UM; + int supervisor_mode = mmu_idx == MIPS_HFLAG_SM; + int kernel_mode = !user_mode && !supervisor_mode; + int UX = (env->CP0_Status & (1 << CP0St_UX)) != 0; + int SX = (env->CP0_Status & (1 << CP0St_SX)) != 0; + int KX = (env->CP0_Status & (1 << CP0St_KX)) != 0; +#endif + int ret = TLBRET_MATCH; + /* effective address (modified for KVM T&E kernel segments) */ + target_ulong address = real_address; + +#define USEG_LIMIT ((target_ulong)(int32_t)0x7FFFFFFFUL) +#define KSEG0_BASE ((target_ulong)(int32_t)0x80000000UL) +#define KSEG1_BASE ((target_ulong)(int32_t)0xA0000000UL) +#define KSEG2_BASE ((target_ulong)(int32_t)0xC0000000UL) +#define KSEG3_BASE ((target_ulong)(int32_t)0xE0000000UL) + +#define KVM_KSEG0_BASE ((target_ulong)(int32_t)0x40000000UL) +#define KVM_KSEG2_BASE ((target_ulong)(int32_t)0x60000000UL) + + if (mips_um_ksegs_enabled()) { + /* KVM T&E adds guest kernel segments in useg */ + if (real_address >= KVM_KSEG0_BASE) { + if (real_address < KVM_KSEG2_BASE) { + /* kseg0 */ + address += KSEG0_BASE - KVM_KSEG0_BASE; + } else if (real_address <= USEG_LIMIT) { + /* kseg2/3 */ + address += KSEG2_BASE - KVM_KSEG2_BASE; + } + } + } + + if (address <= USEG_LIMIT) { + /* useg */ + uint16_t segctl; + + if (address >= 0x40000000UL) { + segctl = env->CP0_SegCtl2; + } else { + segctl = env->CP0_SegCtl2 >> 16; + } + ret = get_segctl_physical_address(env, physical, prot, + real_address, rw, access_type, + mmu_idx, segctl, 0x3FFFFFFF); +#if defined(TARGET_MIPS64) + } else if (address < 0x4000000000000000ULL) { + /* xuseg */ + if (UX && address <= (0x3FFFFFFFFFFFFFFFULL & env->SEGMask)) { + ret = env->tlb->map_address(env, physical, prot, + real_address, rw, access_type); + } else { + ret = TLBRET_BADADDR; + } + } else if (address < 0x8000000000000000ULL) { + /* xsseg */ + if ((supervisor_mode || kernel_mode) && + SX && address <= (0x7FFFFFFFFFFFFFFFULL & env->SEGMask)) { + ret = env->tlb->map_address(env, physical, prot, + real_address, rw, access_type); + } else { + ret = TLBRET_BADADDR; + } + } else if (address < 0xC000000000000000ULL) { + /* xkphys */ + if ((address & 0x07FFFFFFFFFFFFFFULL) <= env->PAMask) { + /* KX/SX/UX bit to check for each xkphys EVA access mode */ + static const uint8_t am_ksux[8] = { + [CP0SC_AM_UK] = (1u << CP0St_KX), + [CP0SC_AM_MK] = (1u << CP0St_KX), + [CP0SC_AM_MSK] = (1u << CP0St_SX), + [CP0SC_AM_MUSK] = (1u << CP0St_UX), + [CP0SC_AM_MUSUK] = (1u << CP0St_UX), + [CP0SC_AM_USK] = (1u << CP0St_SX), + [6] = (1u << CP0St_KX), + [CP0SC_AM_UUSK] = (1u << CP0St_UX), + }; + unsigned int am = CP0SC_AM_UK; + unsigned int xr = (env->CP0_SegCtl2 & CP0SC2_XR_MASK) >> CP0SC2_XR; + + if (xr & (1 << ((address >> 59) & 0x7))) { + am = (env->CP0_SegCtl1 & CP0SC1_XAM_MASK) >> CP0SC1_XAM; + } + /* Does CP0_Status.KX/SX/UX permit the access mode (am) */ + if (env->CP0_Status & am_ksux[am]) { + ret = get_seg_physical_address(env, physical, prot, + real_address, rw, access_type, + mmu_idx, am, false, env->PAMask, + 0); + } else { + ret = TLBRET_BADADDR; + } + } else { + ret = TLBRET_BADADDR; + } + } else if (address < 0xFFFFFFFF80000000ULL) { + /* xkseg */ + if (kernel_mode && KX && + address <= (0xFFFFFFFF7FFFFFFFULL & env->SEGMask)) { + ret = env->tlb->map_address(env, physical, prot, + real_address, rw, access_type); + } else { + ret = TLBRET_BADADDR; + } +#endif + } else if (address < KSEG1_BASE) { + /* kseg0 */ + ret = get_segctl_physical_address(env, physical, prot, real_address, rw, + access_type, mmu_idx, + env->CP0_SegCtl1 >> 16, 0x1FFFFFFF); + } else if (address < KSEG2_BASE) { + /* kseg1 */ + ret = get_segctl_physical_address(env, physical, prot, real_address, rw, + access_type, mmu_idx, + env->CP0_SegCtl1, 0x1FFFFFFF); + } else if (address < KSEG3_BASE) { + /* sseg (kseg2) */ + ret = get_segctl_physical_address(env, physical, prot, real_address, rw, + access_type, mmu_idx, + env->CP0_SegCtl0 >> 16, 0x1FFFFFFF); + } else { + /* + * kseg3 + * XXX: debug segment is not emulated + */ + ret = get_segctl_physical_address(env, physical, prot, real_address, rw, + access_type, mmu_idx, + env->CP0_SegCtl0, 0x1FFFFFFF); + } + return ret; +} + +void cpu_mips_tlb_flush(CPUMIPSState *env) +{ + /* Flush qemu's TLB and discard all shadowed entries. */ + tlb_flush(env_cpu(env)); + env->tlb->tlb_in_use = env->tlb->nb_tlb; +} + +#endif /* !CONFIG_USER_ONLY */ + +static void raise_mmu_exception(CPUMIPSState *env, target_ulong address, + int rw, int tlb_error) +{ + CPUState *cs = env_cpu(env); + int exception = 0, error_code = 0; + + if (rw == MMU_INST_FETCH) { + error_code |= EXCP_INST_NOTAVAIL; + } + + switch (tlb_error) { + default: + case TLBRET_BADADDR: + /* Reference to kernel address from user mode or supervisor mode */ + /* Reference to supervisor address from user mode */ + if (rw == MMU_DATA_STORE) { + exception = EXCP_AdES; + } else { + exception = EXCP_AdEL; + } + break; + case TLBRET_NOMATCH: + /* No TLB match for a mapped address */ + if (rw == MMU_DATA_STORE) { + exception = EXCP_TLBS; + } else { + exception = EXCP_TLBL; + } + error_code |= EXCP_TLB_NOMATCH; + break; + case TLBRET_INVALID: + /* TLB match with no valid bit */ + if (rw == MMU_DATA_STORE) { + exception = EXCP_TLBS; + } else { + exception = EXCP_TLBL; + } + break; + case TLBRET_DIRTY: + /* TLB match but 'D' bit is cleared */ + exception = EXCP_LTLBL; + break; + case TLBRET_XI: + /* Execute-Inhibit Exception */ + if (env->CP0_PageGrain & (1 << CP0PG_IEC)) { + exception = EXCP_TLBXI; + } else { + exception = EXCP_TLBL; + } + break; + case TLBRET_RI: + /* Read-Inhibit Exception */ + if (env->CP0_PageGrain & (1 << CP0PG_IEC)) { + exception = EXCP_TLBRI; + } else { + exception = EXCP_TLBL; + } + break; + } + /* Raise exception */ + if (!(env->hflags & MIPS_HFLAG_DM)) { + env->CP0_BadVAddr = address; + } + env->CP0_Context = (env->CP0_Context & ~0x007fffff) | + ((address >> 9) & 0x007ffff0); + env->CP0_EntryHi = (env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask) | + (env->CP0_EntryHi & (1 << CP0EnHi_EHINV)) | + (address & (TARGET_PAGE_MASK << 1)); +#if defined(TARGET_MIPS64) + env->CP0_EntryHi &= env->SEGMask; + env->CP0_XContext = + (env->CP0_XContext & ((~0ULL) << (env->SEGBITS - 7))) | /* PTEBase */ + (extract64(address, 62, 2) << (env->SEGBITS - 9)) | /* R */ + (extract64(address, 13, env->SEGBITS - 13) << 4); /* BadVPN2 */ +#endif + cs->exception_index = exception; + env->error_code = error_code; +} + +#if !defined(CONFIG_USER_ONLY) + +hwaddr mips_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) +{ + MIPSCPU *cpu = MIPS_CPU(cs); + CPUMIPSState *env = &cpu->env; + hwaddr phys_addr; + int prot; + + if (get_physical_address(env, &phys_addr, &prot, addr, 0, ACCESS_INT, + cpu_mmu_index(env, false)) != 0) { + return -1; + } + return phys_addr; +} + +#if !defined(TARGET_MIPS64) + +/* + * Perform hardware page table walk + * + * Memory accesses are performed using the KERNEL privilege level. + * Synchronous exceptions detected on memory accesses cause a silent exit + * from page table walking, resulting in a TLB or XTLB Refill exception. + * + * Implementations are not required to support page table walk memory + * accesses from mapped memory regions. When an unsupported access is + * attempted, a silent exit is taken, resulting in a TLB or XTLB Refill + * exception. + * + * Note that if an exception is caused by AddressTranslation or LoadMemory + * functions, the exception is not taken, a silent exit is taken, + * resulting in a TLB or XTLB Refill exception. + */ + +static bool get_pte(CPUMIPSState *env, uint64_t vaddr, int entry_size, + uint64_t *pte) +{ + if ((vaddr & ((entry_size >> 3) - 1)) != 0) { + return false; + } + if (entry_size == 64) { + *pte = cpu_ldq_code(env, vaddr); + } else { + *pte = cpu_ldl_code(env, vaddr); + } + return true; +} + +static uint64_t get_tlb_entry_layout(CPUMIPSState *env, uint64_t entry, + int entry_size, int ptei) +{ + uint64_t result = entry; + uint64_t rixi; + if (ptei > entry_size) { + ptei -= 32; + } + result >>= (ptei - 2); + rixi = result & 3; + result >>= 2; + result |= rixi << CP0EnLo_XI; + return result; +} + +static int walk_directory(CPUMIPSState *env, uint64_t *vaddr, + int directory_index, bool *huge_page, bool *hgpg_directory_hit, + uint64_t *pw_entrylo0, uint64_t *pw_entrylo1) +{ + int dph = (env->CP0_PWCtl >> CP0PC_DPH) & 0x1; + int psn = (env->CP0_PWCtl >> CP0PC_PSN) & 0x3F; + int hugepg = (env->CP0_PWCtl >> CP0PC_HUGEPG) & 0x1; + int pf_ptew = (env->CP0_PWField >> CP0PF_PTEW) & 0x3F; + int ptew = (env->CP0_PWSize >> CP0PS_PTEW) & 0x3F; + int native_shift = (((env->CP0_PWSize >> CP0PS_PS) & 1) == 0) ? 2 : 3; + int directory_shift = (ptew > 1) ? -1 : + (hugepg && (ptew == 1)) ? native_shift + 1 : native_shift; + int leaf_shift = (ptew > 1) ? -1 : + (ptew == 1) ? native_shift + 1 : native_shift; + uint32_t direntry_size = 1 << (directory_shift + 3); + uint32_t leafentry_size = 1 << (leaf_shift + 3); + uint64_t entry; + uint64_t paddr; + int prot; + uint64_t lsb = 0; + uint64_t w = 0; + + if (get_physical_address(env, &paddr, &prot, *vaddr, MMU_DATA_LOAD, + ACCESS_INT, cpu_mmu_index(env, false)) != + TLBRET_MATCH) { + /* wrong base address */ + return 0; + } + if (!get_pte(env, *vaddr, direntry_size, &entry)) { + return 0; + } + + if ((entry & (1 << psn)) && hugepg) { + *huge_page = true; + *hgpg_directory_hit = true; + entry = get_tlb_entry_layout(env, entry, leafentry_size, pf_ptew); + w = directory_index - 1; + if (directory_index & 0x1) { + /* Generate adjacent page from same PTE for odd TLB page */ + lsb = (1 << w) >> 6; + *pw_entrylo0 = entry & ~lsb; /* even page */ + *pw_entrylo1 = entry | lsb; /* odd page */ + } else if (dph) { + int oddpagebit = 1 << leaf_shift; + uint64_t vaddr2 = *vaddr ^ oddpagebit; + if (*vaddr & oddpagebit) { + *pw_entrylo1 = entry; + } else { + *pw_entrylo0 = entry; + } + if (get_physical_address(env, &paddr, &prot, vaddr2, MMU_DATA_LOAD, + ACCESS_INT, cpu_mmu_index(env, false)) != + TLBRET_MATCH) { + return 0; + } + if (!get_pte(env, vaddr2, leafentry_size, &entry)) { + return 0; + } + entry = get_tlb_entry_layout(env, entry, leafentry_size, pf_ptew); + if (*vaddr & oddpagebit) { + *pw_entrylo0 = entry; + } else { + *pw_entrylo1 = entry; + } + } else { + return 0; + } + return 1; + } else { + *vaddr = entry; + return 2; + } +} + +static bool page_table_walk_refill(CPUMIPSState *env, vaddr address, int rw, + int mmu_idx) +{ + int gdw = (env->CP0_PWSize >> CP0PS_GDW) & 0x3F; + int udw = (env->CP0_PWSize >> CP0PS_UDW) & 0x3F; + int mdw = (env->CP0_PWSize >> CP0PS_MDW) & 0x3F; + int ptw = (env->CP0_PWSize >> CP0PS_PTW) & 0x3F; + int ptew = (env->CP0_PWSize >> CP0PS_PTEW) & 0x3F; + + /* Initial values */ + bool huge_page = false; + bool hgpg_bdhit = false; + bool hgpg_gdhit = false; + bool hgpg_udhit = false; + bool hgpg_mdhit = false; + + int32_t pw_pagemask = 0; + target_ulong pw_entryhi = 0; + uint64_t pw_entrylo0 = 0; + uint64_t pw_entrylo1 = 0; + + /* Native pointer size */ + /*For the 32-bit architectures, this bit is fixed to 0.*/ + int native_shift = (((env->CP0_PWSize >> CP0PS_PS) & 1) == 0) ? 2 : 3; + + /* Indices from PWField */ + int pf_gdw = (env->CP0_PWField >> CP0PF_GDW) & 0x3F; + int pf_udw = (env->CP0_PWField >> CP0PF_UDW) & 0x3F; + int pf_mdw = (env->CP0_PWField >> CP0PF_MDW) & 0x3F; + int pf_ptw = (env->CP0_PWField >> CP0PF_PTW) & 0x3F; + int pf_ptew = (env->CP0_PWField >> CP0PF_PTEW) & 0x3F; + + /* Indices computed from faulting address */ + int gindex = (address >> pf_gdw) & ((1 << gdw) - 1); + int uindex = (address >> pf_udw) & ((1 << udw) - 1); + int mindex = (address >> pf_mdw) & ((1 << mdw) - 1); + int ptindex = (address >> pf_ptw) & ((1 << ptw) - 1); + + /* Other HTW configs */ + int hugepg = (env->CP0_PWCtl >> CP0PC_HUGEPG) & 0x1; + + /* HTW Shift values (depend on entry size) */ + int directory_shift = (ptew > 1) ? -1 : + (hugepg && (ptew == 1)) ? native_shift + 1 : native_shift; + int leaf_shift = (ptew > 1) ? -1 : + (ptew == 1) ? native_shift + 1 : native_shift; + + /* Offsets into tables */ + int goffset = gindex << directory_shift; + int uoffset = uindex << directory_shift; + int moffset = mindex << directory_shift; + int ptoffset0 = (ptindex >> 1) << (leaf_shift + 1); + int ptoffset1 = ptoffset0 | (1 << (leaf_shift)); + + uint32_t leafentry_size = 1 << (leaf_shift + 3); + + /* Starting address - Page Table Base */ + uint64_t vaddr = env->CP0_PWBase; + + uint64_t dir_entry; + uint64_t paddr; + int prot; + int m; + + if (!(env->CP0_Config3 & (1 << CP0C3_PW))) { + /* walker is unimplemented */ + return false; + } + if (!(env->CP0_PWCtl & (1 << CP0PC_PWEN))) { + /* walker is disabled */ + return false; + } + if (!(gdw > 0 || udw > 0 || mdw > 0)) { + /* no structure to walk */ + return false; + } + if ((directory_shift == -1) || (leaf_shift == -1)) { + return false; + } + + /* Global Directory */ + if (gdw > 0) { + vaddr |= goffset; + switch (walk_directory(env, &vaddr, pf_gdw, &huge_page, &hgpg_gdhit, + &pw_entrylo0, &pw_entrylo1)) + { + case 0: + return false; + case 1: + goto refill; + case 2: + default: + break; + } + } + + /* Upper directory */ + if (udw > 0) { + vaddr |= uoffset; + switch (walk_directory(env, &vaddr, pf_udw, &huge_page, &hgpg_udhit, + &pw_entrylo0, &pw_entrylo1)) + { + case 0: + return false; + case 1: + goto refill; + case 2: + default: + break; + } + } + + /* Middle directory */ + if (mdw > 0) { + vaddr |= moffset; + switch (walk_directory(env, &vaddr, pf_mdw, &huge_page, &hgpg_mdhit, + &pw_entrylo0, &pw_entrylo1)) + { + case 0: + return false; + case 1: + goto refill; + case 2: + default: + break; + } + } + + /* Leaf Level Page Table - First half of PTE pair */ + vaddr |= ptoffset0; + if (get_physical_address(env, &paddr, &prot, vaddr, MMU_DATA_LOAD, + ACCESS_INT, cpu_mmu_index(env, false)) != + TLBRET_MATCH) { + return false; + } + if (!get_pte(env, vaddr, leafentry_size, &dir_entry)) { + return false; + } + dir_entry = get_tlb_entry_layout(env, dir_entry, leafentry_size, pf_ptew); + pw_entrylo0 = dir_entry; + + /* Leaf Level Page Table - Second half of PTE pair */ + vaddr |= ptoffset1; + if (get_physical_address(env, &paddr, &prot, vaddr, MMU_DATA_LOAD, + ACCESS_INT, cpu_mmu_index(env, false)) != + TLBRET_MATCH) { + return false; + } + if (!get_pte(env, vaddr, leafentry_size, &dir_entry)) { + return false; + } + dir_entry = get_tlb_entry_layout(env, dir_entry, leafentry_size, pf_ptew); + pw_entrylo1 = dir_entry; + +refill: + + m = (1 << pf_ptw) - 1; + + if (huge_page) { + switch (hgpg_bdhit << 3 | hgpg_gdhit << 2 | hgpg_udhit << 1 | + hgpg_mdhit) + { + case 4: + m = (1 << pf_gdw) - 1; + if (pf_gdw & 1) { + m >>= 1; + } + break; + case 2: + m = (1 << pf_udw) - 1; + if (pf_udw & 1) { + m >>= 1; + } + break; + case 1: + m = (1 << pf_mdw) - 1; + if (pf_mdw & 1) { + m >>= 1; + } + break; + } + } + pw_pagemask = m >> TARGET_PAGE_BITS_MIN; + update_pagemask(env, pw_pagemask << CP0PM_MASK, &pw_pagemask); + pw_entryhi = (address & ~0x1fff) | (env->CP0_EntryHi & 0xFF); + { + target_ulong tmp_entryhi = env->CP0_EntryHi; + int32_t tmp_pagemask = env->CP0_PageMask; + uint64_t tmp_entrylo0 = env->CP0_EntryLo0; + uint64_t tmp_entrylo1 = env->CP0_EntryLo1; + + env->CP0_EntryHi = pw_entryhi; + env->CP0_PageMask = pw_pagemask; + env->CP0_EntryLo0 = pw_entrylo0; + env->CP0_EntryLo1 = pw_entrylo1; + + /* + * The hardware page walker inserts a page into the TLB in a manner + * identical to a TLBWR instruction as executed by the software refill + * handler. + */ + r4k_helper_tlbwr(env); + + env->CP0_EntryHi = tmp_entryhi; + env->CP0_PageMask = tmp_pagemask; + env->CP0_EntryLo0 = tmp_entrylo0; + env->CP0_EntryLo1 = tmp_entrylo1; + } + return true; +} +#endif +#endif /* !CONFIG_USER_ONLY */ + +bool mips_cpu_tlb_fill(CPUState *cs, vaddr address, int size, + MMUAccessType access_type, int mmu_idx, + bool probe, uintptr_t retaddr) +{ + MIPSCPU *cpu = MIPS_CPU(cs); + CPUMIPSState *env = &cpu->env; +#if !defined(CONFIG_USER_ONLY) + hwaddr physical; + int prot; + int mips_access_type; +#endif + int ret = TLBRET_BADADDR; + + /* data access */ +#if !defined(CONFIG_USER_ONLY) + /* XXX: put correct access by using cpu_restore_state() correctly */ + mips_access_type = ACCESS_INT; + ret = get_physical_address(env, &physical, &prot, address, + access_type, mips_access_type, mmu_idx); + switch (ret) { + case TLBRET_MATCH: + qemu_log_mask(CPU_LOG_MMU, + "%s address=%" VADDR_PRIx " physical " TARGET_FMT_plx + " prot %d\n", __func__, address, physical, prot); + break; + default: + qemu_log_mask(CPU_LOG_MMU, + "%s address=%" VADDR_PRIx " ret %d\n", __func__, address, + ret); + break; + } + if (ret == TLBRET_MATCH) { + tlb_set_page(cs, address & TARGET_PAGE_MASK, + physical & TARGET_PAGE_MASK, prot, + mmu_idx, TARGET_PAGE_SIZE); + return true; + } +#if !defined(TARGET_MIPS64) + if ((ret == TLBRET_NOMATCH) && (env->tlb->nb_tlb > 1)) { + /* + * Memory reads during hardware page table walking are performed + * as if they were kernel-mode load instructions. + */ + int mode = (env->hflags & MIPS_HFLAG_KSU); + bool ret_walker; + env->hflags &= ~MIPS_HFLAG_KSU; + ret_walker = page_table_walk_refill(env, address, access_type, mmu_idx); + env->hflags |= mode; + if (ret_walker) { + ret = get_physical_address(env, &physical, &prot, address, + access_type, mips_access_type, mmu_idx); + if (ret == TLBRET_MATCH) { + tlb_set_page(cs, address & TARGET_PAGE_MASK, + physical & TARGET_PAGE_MASK, prot, + mmu_idx, TARGET_PAGE_SIZE); + return true; + } + } + } +#endif + if (probe) { + return false; + } +#endif + + raise_mmu_exception(env, address, access_type, ret); + do_raise_exception_err(env, cs->exception_index, env->error_code, retaddr); +} + +#ifndef CONFIG_USER_ONLY +hwaddr cpu_mips_translate_address(CPUMIPSState *env, target_ulong address, + int rw) +{ + hwaddr physical; + int prot; + int access_type; + int ret = 0; + + /* data access */ + access_type = ACCESS_INT; + ret = get_physical_address(env, &physical, &prot, address, rw, access_type, + cpu_mmu_index(env, false)); + if (ret != TLBRET_MATCH) { + raise_mmu_exception(env, address, rw, ret); + return -1LL; + } else { + return physical; + } +} + +static void set_hflags_for_handler(CPUMIPSState *env) +{ + /* Exception handlers are entered in 32-bit mode. */ + env->hflags &= ~(MIPS_HFLAG_M16); + /* ...except that microMIPS lets you choose. */ + if (env->insn_flags & ASE_MICROMIPS) { + env->hflags |= (!!(env->CP0_Config3 & + (1 << CP0C3_ISA_ON_EXC)) + << MIPS_HFLAG_M16_SHIFT); + } +} + +static inline void set_badinstr_registers(CPUMIPSState *env) +{ + if (env->insn_flags & ISA_NANOMIPS32) { + if (env->CP0_Config3 & (1 << CP0C3_BI)) { + uint32_t instr = (cpu_lduw_code(env, env->active_tc.PC)) << 16; + if ((instr & 0x10000000) == 0) { + instr |= cpu_lduw_code(env, env->active_tc.PC + 2); + } + env->CP0_BadInstr = instr; + + if ((instr & 0xFC000000) == 0x60000000) { + instr = cpu_lduw_code(env, env->active_tc.PC + 4) << 16; + env->CP0_BadInstrX = instr; + } + } + return; + } + + if (env->hflags & MIPS_HFLAG_M16) { + /* TODO: add BadInstr support for microMIPS */ + return; + } + if (env->CP0_Config3 & (1 << CP0C3_BI)) { + env->CP0_BadInstr = cpu_ldl_code(env, env->active_tc.PC); + } + if ((env->CP0_Config3 & (1 << CP0C3_BP)) && + (env->hflags & MIPS_HFLAG_BMASK)) { + env->CP0_BadInstrP = cpu_ldl_code(env, env->active_tc.PC - 4); + } +} + +#endif /* !CONFIG_USER_ONLY */ + +void mips_cpu_do_interrupt(CPUState *cs) +{ +#if !defined(CONFIG_USER_ONLY) + MIPSCPU *cpu = MIPS_CPU(cs); + CPUMIPSState *env = &cpu->env; + bool update_badinstr = 0; + target_ulong offset; + int cause = -1; + + if (qemu_loglevel_mask(CPU_LOG_INT) + && cs->exception_index != EXCP_EXT_INTERRUPT) { + qemu_log("%s enter: PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx + " %s exception\n", + __func__, env->active_tc.PC, env->CP0_EPC, + mips_exception_name(cs->exception_index)); + } + if (cs->exception_index == EXCP_EXT_INTERRUPT && + (env->hflags & MIPS_HFLAG_DM)) { + cs->exception_index = EXCP_DINT; + } + offset = 0x180; + switch (cs->exception_index) { + case EXCP_DSS: + env->CP0_Debug |= 1 << CP0DB_DSS; + /* + * Debug single step cannot be raised inside a delay slot and + * resume will always occur on the next instruction + * (but we assume the pc has always been updated during + * code translation). + */ + env->CP0_DEPC = env->active_tc.PC | !!(env->hflags & MIPS_HFLAG_M16); + goto enter_debug_mode; + case EXCP_DINT: + env->CP0_Debug |= 1 << CP0DB_DINT; + goto set_DEPC; + case EXCP_DIB: + env->CP0_Debug |= 1 << CP0DB_DIB; + goto set_DEPC; + case EXCP_DBp: + env->CP0_Debug |= 1 << CP0DB_DBp; + /* Setup DExcCode - SDBBP instruction */ + env->CP0_Debug = (env->CP0_Debug & ~(0x1fULL << CP0DB_DEC)) | + (9 << CP0DB_DEC); + goto set_DEPC; + case EXCP_DDBS: + env->CP0_Debug |= 1 << CP0DB_DDBS; + goto set_DEPC; + case EXCP_DDBL: + env->CP0_Debug |= 1 << CP0DB_DDBL; + set_DEPC: + env->CP0_DEPC = exception_resume_pc(env); + env->hflags &= ~MIPS_HFLAG_BMASK; + enter_debug_mode: + if (env->insn_flags & ISA_MIPS3) { + env->hflags |= MIPS_HFLAG_64; + if (!(env->insn_flags & ISA_MIPS_R6) || + env->CP0_Status & (1 << CP0St_KX)) { + env->hflags &= ~MIPS_HFLAG_AWRAP; + } + } + env->hflags |= MIPS_HFLAG_DM | MIPS_HFLAG_CP0; + env->hflags &= ~(MIPS_HFLAG_KSU); + /* EJTAG probe trap enable is not implemented... */ + if (!(env->CP0_Status & (1 << CP0St_EXL))) { + env->CP0_Cause &= ~(1U << CP0Ca_BD); + } + env->active_tc.PC = env->exception_base + 0x480; + set_hflags_for_handler(env); + break; + case EXCP_RESET: + cpu_reset(CPU(cpu)); + break; + case EXCP_SRESET: + env->CP0_Status |= (1 << CP0St_SR); + memset(env->CP0_WatchLo, 0, sizeof(env->CP0_WatchLo)); + goto set_error_EPC; + case EXCP_NMI: + env->CP0_Status |= (1 << CP0St_NMI); + set_error_EPC: + env->CP0_ErrorEPC = exception_resume_pc(env); + env->hflags &= ~MIPS_HFLAG_BMASK; + env->CP0_Status |= (1 << CP0St_ERL) | (1 << CP0St_BEV); + if (env->insn_flags & ISA_MIPS3) { + env->hflags |= MIPS_HFLAG_64; + if (!(env->insn_flags & ISA_MIPS_R6) || + env->CP0_Status & (1 << CP0St_KX)) { + env->hflags &= ~MIPS_HFLAG_AWRAP; + } + } + env->hflags |= MIPS_HFLAG_CP0; + env->hflags &= ~(MIPS_HFLAG_KSU); + if (!(env->CP0_Status & (1 << CP0St_EXL))) { + env->CP0_Cause &= ~(1U << CP0Ca_BD); + } + env->active_tc.PC = env->exception_base; + set_hflags_for_handler(env); + break; + case EXCP_EXT_INTERRUPT: + cause = 0; + if (env->CP0_Cause & (1 << CP0Ca_IV)) { + uint32_t spacing = (env->CP0_IntCtl >> CP0IntCtl_VS) & 0x1f; + + if ((env->CP0_Status & (1 << CP0St_BEV)) || spacing == 0) { + offset = 0x200; + } else { + uint32_t vector = 0; + uint32_t pending = (env->CP0_Cause & CP0Ca_IP_mask) >> CP0Ca_IP; + + if (env->CP0_Config3 & (1 << CP0C3_VEIC)) { + /* + * For VEIC mode, the external interrupt controller feeds + * the vector through the CP0Cause IP lines. + */ + vector = pending; + } else { + /* + * Vectored Interrupts + * Mask with Status.IM7-IM0 to get enabled interrupts. + */ + pending &= (env->CP0_Status >> CP0St_IM) & 0xff; + /* Find the highest-priority interrupt. */ + while (pending >>= 1) { + vector++; + } + } + offset = 0x200 + (vector * (spacing << 5)); + } + } + goto set_EPC; + case EXCP_LTLBL: + cause = 1; + update_badinstr = !(env->error_code & EXCP_INST_NOTAVAIL); + goto set_EPC; + case EXCP_TLBL: + cause = 2; + update_badinstr = !(env->error_code & EXCP_INST_NOTAVAIL); + if ((env->error_code & EXCP_TLB_NOMATCH) && + !(env->CP0_Status & (1 << CP0St_EXL))) { +#if defined(TARGET_MIPS64) + int R = env->CP0_BadVAddr >> 62; + int UX = (env->CP0_Status & (1 << CP0St_UX)) != 0; + int KX = (env->CP0_Status & (1 << CP0St_KX)) != 0; + + if ((R != 0 || UX) && (R != 3 || KX) && + (!(env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)))) { + offset = 0x080; + } else { +#endif + offset = 0x000; +#if defined(TARGET_MIPS64) + } +#endif + } + goto set_EPC; + case EXCP_TLBS: + cause = 3; + update_badinstr = 1; + if ((env->error_code & EXCP_TLB_NOMATCH) && + !(env->CP0_Status & (1 << CP0St_EXL))) { +#if defined(TARGET_MIPS64) + int R = env->CP0_BadVAddr >> 62; + int UX = (env->CP0_Status & (1 << CP0St_UX)) != 0; + int KX = (env->CP0_Status & (1 << CP0St_KX)) != 0; + + if ((R != 0 || UX) && (R != 3 || KX) && + (!(env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)))) { + offset = 0x080; + } else { +#endif + offset = 0x000; +#if defined(TARGET_MIPS64) + } +#endif + } + goto set_EPC; + case EXCP_AdEL: + cause = 4; + update_badinstr = !(env->error_code & EXCP_INST_NOTAVAIL); + goto set_EPC; + case EXCP_AdES: + cause = 5; + update_badinstr = 1; + goto set_EPC; + case EXCP_IBE: + cause = 6; + goto set_EPC; + case EXCP_DBE: + cause = 7; + goto set_EPC; + case EXCP_SYSCALL: + cause = 8; + update_badinstr = 1; + goto set_EPC; + case EXCP_BREAK: + cause = 9; + update_badinstr = 1; + goto set_EPC; + case EXCP_RI: + cause = 10; + update_badinstr = 1; + goto set_EPC; + case EXCP_CpU: + cause = 11; + update_badinstr = 1; + env->CP0_Cause = (env->CP0_Cause & ~(0x3 << CP0Ca_CE)) | + (env->error_code << CP0Ca_CE); + goto set_EPC; + case EXCP_OVERFLOW: + cause = 12; + update_badinstr = 1; + goto set_EPC; + case EXCP_TRAP: + cause = 13; + update_badinstr = 1; + goto set_EPC; + case EXCP_MSAFPE: + cause = 14; + update_badinstr = 1; + goto set_EPC; + case EXCP_FPE: + cause = 15; + update_badinstr = 1; + goto set_EPC; + case EXCP_C2E: + cause = 18; + goto set_EPC; + case EXCP_TLBRI: + cause = 19; + update_badinstr = 1; + goto set_EPC; + case EXCP_TLBXI: + cause = 20; + goto set_EPC; + case EXCP_MSADIS: + cause = 21; + update_badinstr = 1; + goto set_EPC; + case EXCP_MDMX: + cause = 22; + goto set_EPC; + case EXCP_DWATCH: + cause = 23; + /* XXX: TODO: manage deferred watch exceptions */ + goto set_EPC; + case EXCP_MCHECK: + cause = 24; + goto set_EPC; + case EXCP_THREAD: + cause = 25; + goto set_EPC; + case EXCP_DSPDIS: + cause = 26; + goto set_EPC; + case EXCP_CACHE: + cause = 30; + offset = 0x100; + set_EPC: + if (!(env->CP0_Status & (1 << CP0St_EXL))) { + env->CP0_EPC = exception_resume_pc(env); + if (update_badinstr) { + set_badinstr_registers(env); + } + if (env->hflags & MIPS_HFLAG_BMASK) { + env->CP0_Cause |= (1U << CP0Ca_BD); + } else { + env->CP0_Cause &= ~(1U << CP0Ca_BD); + } + env->CP0_Status |= (1 << CP0St_EXL); + if (env->insn_flags & ISA_MIPS3) { + env->hflags |= MIPS_HFLAG_64; + if (!(env->insn_flags & ISA_MIPS_R6) || + env->CP0_Status & (1 << CP0St_KX)) { + env->hflags &= ~MIPS_HFLAG_AWRAP; + } + } + env->hflags |= MIPS_HFLAG_CP0; + env->hflags &= ~(MIPS_HFLAG_KSU); + } + env->hflags &= ~MIPS_HFLAG_BMASK; + if (env->CP0_Status & (1 << CP0St_BEV)) { + env->active_tc.PC = env->exception_base + 0x200; + } else if (cause == 30 && !(env->CP0_Config3 & (1 << CP0C3_SC) && + env->CP0_Config5 & (1 << CP0C5_CV))) { + /* Force KSeg1 for cache errors */ + env->active_tc.PC = KSEG1_BASE | (env->CP0_EBase & 0x1FFFF000); + } else { + env->active_tc.PC = env->CP0_EBase & ~0xfff; + } + + env->active_tc.PC += offset; + set_hflags_for_handler(env); + env->CP0_Cause = (env->CP0_Cause & ~(0x1f << CP0Ca_EC)) | + (cause << CP0Ca_EC); + break; + default: + abort(); + } + if (qemu_loglevel_mask(CPU_LOG_INT) + && cs->exception_index != EXCP_EXT_INTERRUPT) { + qemu_log("%s: PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx " cause %d\n" + " S %08x C %08x A " TARGET_FMT_lx " D " TARGET_FMT_lx "\n", + __func__, env->active_tc.PC, env->CP0_EPC, cause, + env->CP0_Status, env->CP0_Cause, env->CP0_BadVAddr, + env->CP0_DEPC); + } +#endif + cs->exception_index = EXCP_NONE; +} + +#if !defined(CONFIG_USER_ONLY) +void r4k_invalidate_tlb(CPUMIPSState *env, int idx, int use_extra) +{ + CPUState *cs = env_cpu(env); + r4k_tlb_t *tlb; + target_ulong addr; + target_ulong end; + uint16_t ASID = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask; + uint32_t MMID = env->CP0_MemoryMapID; + bool mi = !!((env->CP0_Config5 >> CP0C5_MI) & 1); + uint32_t tlb_mmid; + target_ulong mask; + + MMID = mi ? MMID : (uint32_t) ASID; + + tlb = &env->tlb->mmu.r4k.tlb[idx]; + /* + * The qemu TLB is flushed when the ASID/MMID changes, so no need to + * flush these entries again. + */ + tlb_mmid = mi ? tlb->MMID : (uint32_t) tlb->ASID; + if (tlb->G == 0 && tlb_mmid != MMID) { + return; + } + + if (use_extra && env->tlb->tlb_in_use < MIPS_TLB_MAX) { + /* + * For tlbwr, we can shadow the discarded entry into + * a new (fake) TLB entry, as long as the guest can not + * tell that it's there. + */ + env->tlb->mmu.r4k.tlb[env->tlb->tlb_in_use] = *tlb; + env->tlb->tlb_in_use++; + return; + } + + /* 1k pages are not supported. */ + mask = tlb->PageMask | ~(TARGET_PAGE_MASK << 1); + if (tlb->V0) { + addr = tlb->VPN & ~mask; +#if defined(TARGET_MIPS64) + if (addr >= (0xFFFFFFFF80000000ULL & env->SEGMask)) { + addr |= 0x3FFFFF0000000000ULL; + } +#endif + end = addr | (mask >> 1); + while (addr < end) { + tlb_flush_page(cs, addr); + addr += TARGET_PAGE_SIZE; + } + } + if (tlb->V1) { + addr = (tlb->VPN & ~mask) | ((mask >> 1) + 1); +#if defined(TARGET_MIPS64) + if (addr >= (0xFFFFFFFF80000000ULL & env->SEGMask)) { + addr |= 0x3FFFFF0000000000ULL; + } +#endif + end = addr | mask; + while (addr - 1 < end) { + tlb_flush_page(cs, addr); + addr += TARGET_PAGE_SIZE; + } + } +} +#endif /* !CONFIG_USER_ONLY */ -- cgit v1.2.3-55-g7522 From ca2690e36a96ca17c50f2be8aaa63d782e2126c3 Mon Sep 17 00:00:00 2001 From: Philippe Mathieu-Daudé Date: Sun, 6 Dec 2020 22:31:09 +0100 Subject: target/mips: Fix code style for checkpatch.pl We are going to move this code, fix its style first. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20201206233949.3783184-14-f4bug@amsat.org> --- target/mips/translate_init.c.inc | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/target/mips/translate_init.c.inc b/target/mips/translate_init.c.inc index 044052fb77..21ee22c05d 100644 --- a/target/mips/translate_init.c.inc +++ b/target/mips/translate_init.c.inc @@ -936,19 +936,19 @@ void mips_cpu_list(void) } #ifndef CONFIG_USER_ONLY -static void no_mmu_init (CPUMIPSState *env, const mips_def_t *def) +static void no_mmu_init(CPUMIPSState *env, const mips_def_t *def) { env->tlb->nb_tlb = 1; env->tlb->map_address = &no_mmu_map_address; } -static void fixed_mmu_init (CPUMIPSState *env, const mips_def_t *def) +static void fixed_mmu_init(CPUMIPSState *env, const mips_def_t *def) { env->tlb->nb_tlb = 1; env->tlb->map_address = &fixed_mmu_map_address; } -static void r4k_mmu_init (CPUMIPSState *env, const mips_def_t *def) +static void r4k_mmu_init(CPUMIPSState *env, const mips_def_t *def) { env->tlb->nb_tlb = 1 + ((def->CP0_Config1 >> CP0C1_MMU) & 63); env->tlb->map_address = &r4k_map_address; @@ -960,25 +960,25 @@ static void r4k_mmu_init (CPUMIPSState *env, const mips_def_t *def) env->tlb->helper_tlbinvf = r4k_helper_tlbinvf; } -static void mmu_init (CPUMIPSState *env, const mips_def_t *def) +static void mmu_init(CPUMIPSState *env, const mips_def_t *def) { env->tlb = g_malloc0(sizeof(CPUMIPSTLBContext)); switch (def->mmu_type) { - case MMU_TYPE_NONE: - no_mmu_init(env, def); - break; - case MMU_TYPE_R4000: - r4k_mmu_init(env, def); - break; - case MMU_TYPE_FMT: - fixed_mmu_init(env, def); - break; - case MMU_TYPE_R3000: - case MMU_TYPE_R6000: - case MMU_TYPE_R8000: - default: - cpu_abort(env_cpu(env), "MMU type not supported\n"); + case MMU_TYPE_NONE: + no_mmu_init(env, def); + break; + case MMU_TYPE_R4000: + r4k_mmu_init(env, def); + break; + case MMU_TYPE_FMT: + fixed_mmu_init(env, def); + break; + case MMU_TYPE_R3000: + case MMU_TYPE_R6000: + case MMU_TYPE_R8000: + default: + cpu_abort(env_cpu(env), "MMU type not supported\n"); } } #endif /* CONFIG_USER_ONLY */ -- cgit v1.2.3-55-g7522 From f2c5b39ecdcc3d99f53517c18acfb950bfeecfd3 Mon Sep 17 00:00:00 2001 From: Philippe Mathieu-Daudé Date: Sun, 6 Dec 2020 23:28:48 +0100 Subject: target/mips: Move mmu_init() functions to tlb_helper.c Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20201206233949.3783184-15-f4bug@amsat.org> --- target/mips/internal.h | 1 + target/mips/tlb_helper.c | 46 ++++++++++++++++++++++++++++++++++++++ target/mips/translate_init.c.inc | 48 ---------------------------------------- 3 files changed, 47 insertions(+), 48 deletions(-) diff --git a/target/mips/internal.h b/target/mips/internal.h index ae1181d202..9a7698019e 100644 --- a/target/mips/internal.h +++ b/target/mips/internal.h @@ -207,6 +207,7 @@ void cpu_mips_start_count(CPUMIPSState *env); void cpu_mips_stop_count(CPUMIPSState *env); /* helper.c */ +void mmu_init(CPUMIPSState *env, const mips_def_t *def); bool mips_cpu_tlb_fill(CPUState *cs, vaddr address, int size, MMUAccessType access_type, int mmu_idx, bool probe, uintptr_t retaddr); diff --git a/target/mips/tlb_helper.c b/target/mips/tlb_helper.c index b02c0479e7..082c17928d 100644 --- a/target/mips/tlb_helper.c +++ b/target/mips/tlb_helper.c @@ -120,6 +120,52 @@ int r4k_map_address(CPUMIPSState *env, hwaddr *physical, int *prot, return TLBRET_NOMATCH; } +static void no_mmu_init(CPUMIPSState *env, const mips_def_t *def) +{ + env->tlb->nb_tlb = 1; + env->tlb->map_address = &no_mmu_map_address; +} + +static void fixed_mmu_init(CPUMIPSState *env, const mips_def_t *def) +{ + env->tlb->nb_tlb = 1; + env->tlb->map_address = &fixed_mmu_map_address; +} + +static void r4k_mmu_init(CPUMIPSState *env, const mips_def_t *def) +{ + env->tlb->nb_tlb = 1 + ((def->CP0_Config1 >> CP0C1_MMU) & 63); + env->tlb->map_address = &r4k_map_address; + env->tlb->helper_tlbwi = r4k_helper_tlbwi; + env->tlb->helper_tlbwr = r4k_helper_tlbwr; + env->tlb->helper_tlbp = r4k_helper_tlbp; + env->tlb->helper_tlbr = r4k_helper_tlbr; + env->tlb->helper_tlbinv = r4k_helper_tlbinv; + env->tlb->helper_tlbinvf = r4k_helper_tlbinvf; +} + +void mmu_init(CPUMIPSState *env, const mips_def_t *def) +{ + env->tlb = g_malloc0(sizeof(CPUMIPSTLBContext)); + + switch (def->mmu_type) { + case MMU_TYPE_NONE: + no_mmu_init(env, def); + break; + case MMU_TYPE_R4000: + r4k_mmu_init(env, def); + break; + case MMU_TYPE_FMT: + fixed_mmu_init(env, def); + break; + case MMU_TYPE_R3000: + case MMU_TYPE_R6000: + case MMU_TYPE_R8000: + default: + cpu_abort(env_cpu(env), "MMU type not supported\n"); + } +} + static int is_seg_am_mapped(unsigned int am, bool eu, int mmu_idx) { /* diff --git a/target/mips/translate_init.c.inc b/target/mips/translate_init.c.inc index 21ee22c05d..535d4c0c70 100644 --- a/target/mips/translate_init.c.inc +++ b/target/mips/translate_init.c.inc @@ -935,54 +935,6 @@ void mips_cpu_list(void) } } -#ifndef CONFIG_USER_ONLY -static void no_mmu_init(CPUMIPSState *env, const mips_def_t *def) -{ - env->tlb->nb_tlb = 1; - env->tlb->map_address = &no_mmu_map_address; -} - -static void fixed_mmu_init(CPUMIPSState *env, const mips_def_t *def) -{ - env->tlb->nb_tlb = 1; - env->tlb->map_address = &fixed_mmu_map_address; -} - -static void r4k_mmu_init(CPUMIPSState *env, const mips_def_t *def) -{ - env->tlb->nb_tlb = 1 + ((def->CP0_Config1 >> CP0C1_MMU) & 63); - env->tlb->map_address = &r4k_map_address; - env->tlb->helper_tlbwi = r4k_helper_tlbwi; - env->tlb->helper_tlbwr = r4k_helper_tlbwr; - env->tlb->helper_tlbp = r4k_helper_tlbp; - env->tlb->helper_tlbr = r4k_helper_tlbr; - env->tlb->helper_tlbinv = r4k_helper_tlbinv; - env->tlb->helper_tlbinvf = r4k_helper_tlbinvf; -} - -static void mmu_init(CPUMIPSState *env, const mips_def_t *def) -{ - env->tlb = g_malloc0(sizeof(CPUMIPSTLBContext)); - - switch (def->mmu_type) { - case MMU_TYPE_NONE: - no_mmu_init(env, def); - break; - case MMU_TYPE_R4000: - r4k_mmu_init(env, def); - break; - case MMU_TYPE_FMT: - fixed_mmu_init(env, def); - break; - case MMU_TYPE_R3000: - case MMU_TYPE_R6000: - case MMU_TYPE_R8000: - default: - cpu_abort(env_cpu(env), "MMU type not supported\n"); - } -} -#endif /* CONFIG_USER_ONLY */ - static void fpu_init (CPUMIPSState *env, const mips_def_t *def) { int i; -- cgit v1.2.3-55-g7522 From 0dc351ca6bf5ffbdb63bbecf718d4917491b2c28 Mon Sep 17 00:00:00 2001 From: Philippe Mathieu-Daudé Date: Sun, 6 Dec 2020 23:52:07 +0100 Subject: target/mips: Rename translate_init.c as cpu-defs.c This file is not TCG specific, contains CPU definitions and is consumed by cpu.c. Rename it as such. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20201214183739.500368-10-f4bug@amsat.org> --- target/mips/cpu-defs.c.inc | 1007 ++++++++++++++++++++++++++++++++++++++ target/mips/cpu.c | 2 +- target/mips/translate_init.c.inc | 1007 -------------------------------------- 3 files changed, 1008 insertions(+), 1008 deletions(-) create mode 100644 target/mips/cpu-defs.c.inc delete mode 100644 target/mips/translate_init.c.inc diff --git a/target/mips/cpu-defs.c.inc b/target/mips/cpu-defs.c.inc new file mode 100644 index 0000000000..535d4c0c70 --- /dev/null +++ b/target/mips/cpu-defs.c.inc @@ -0,0 +1,1007 @@ +/* + * MIPS emulation for qemu: CPU initialisation routines. + * + * Copyright (c) 2004-2005 Jocelyn Mayer + * Copyright (c) 2007 Herve Poussineau + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include "fpu_helper.h" + +/* CPU / CPU family specific config register values. */ + +/* Have config1, uncached coherency */ +#define MIPS_CONFIG0 \ + ((1U << CP0C0_M) | (0x2 << CP0C0_K0)) + +/* Have config2, no coprocessor2 attached, no MDMX support attached, + no performance counters, watch registers present, + no code compression, EJTAG present, no FPU */ +#define MIPS_CONFIG1 \ +((1U << CP0C1_M) | \ + (0 << CP0C1_C2) | (0 << CP0C1_MD) | (0 << CP0C1_PC) | \ + (1 << CP0C1_WR) | (0 << CP0C1_CA) | (1 << CP0C1_EP) | \ + (0 << CP0C1_FP)) + +/* Have config3, no tertiary/secondary caches implemented */ +#define MIPS_CONFIG2 \ +((1U << CP0C2_M)) + +/* No config4, no DSP ASE, no large physaddr (PABITS), + no external interrupt controller, no vectored interrupts, + no 1kb pages, no SmartMIPS ASE, no trace logic */ +#define MIPS_CONFIG3 \ +((0 << CP0C3_M) | (0 << CP0C3_DSPP) | (0 << CP0C3_LPA) | \ + (0 << CP0C3_VEIC) | (0 << CP0C3_VInt) | (0 << CP0C3_SP) | \ + (0 << CP0C3_SM) | (0 << CP0C3_TL)) + +#define MIPS_CONFIG4 \ +((0 << CP0C4_M)) + +#define MIPS_CONFIG5 \ +((0 << CP0C5_M)) + +/*****************************************************************************/ +/* MIPS CPU definitions */ +const mips_def_t mips_defs[] = +{ + { + .name = "4Kc", + .CP0_PRid = 0x00018000, + .CP0_Config0 = MIPS_CONFIG0 | (MMU_TYPE_R4000 << CP0C0_MT), + .CP0_Config1 = MIPS_CONFIG1 | (15 << CP0C1_MMU) | + (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) | + (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA) | + (0 << CP0C1_CA), + .CP0_Config2 = MIPS_CONFIG2, + .CP0_Config3 = MIPS_CONFIG3, + .CP0_LLAddr_rw_bitmask = 0, + .CP0_LLAddr_shift = 4, + .SYNCI_Step = 32, + .CCRes = 2, + .CP0_Status_rw_bitmask = 0x1278FF17, + .SEGBITS = 32, + .PABITS = 32, + .insn_flags = CPU_MIPS32R1, + .mmu_type = MMU_TYPE_R4000, + }, + { + .name = "4Km", + .CP0_PRid = 0x00018300, + /* Config1 implemented, fixed mapping MMU, + no virtual icache, uncached coherency. */ + .CP0_Config0 = MIPS_CONFIG0 | (MMU_TYPE_FMT << CP0C0_MT), + .CP0_Config1 = MIPS_CONFIG1 | + (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) | + (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA) | + (1 << CP0C1_CA), + .CP0_Config2 = MIPS_CONFIG2, + .CP0_Config3 = MIPS_CONFIG3, + .CP0_LLAddr_rw_bitmask = 0, + .CP0_LLAddr_shift = 4, + .SYNCI_Step = 32, + .CCRes = 2, + .CP0_Status_rw_bitmask = 0x1258FF17, + .SEGBITS = 32, + .PABITS = 32, + .insn_flags = CPU_MIPS32R1 | ASE_MIPS16, + .mmu_type = MMU_TYPE_FMT, + }, + { + .name = "4KEcR1", + .CP0_PRid = 0x00018400, + .CP0_Config0 = MIPS_CONFIG0 | (MMU_TYPE_R4000 << CP0C0_MT), + .CP0_Config1 = MIPS_CONFIG1 | (15 << CP0C1_MMU) | + (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) | + (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA) | + (0 << CP0C1_CA), + .CP0_Config2 = MIPS_CONFIG2, + .CP0_Config3 = MIPS_CONFIG3, + .CP0_LLAddr_rw_bitmask = 0, + .CP0_LLAddr_shift = 4, + .SYNCI_Step = 32, + .CCRes = 2, + .CP0_Status_rw_bitmask = 0x1278FF17, + .SEGBITS = 32, + .PABITS = 32, + .insn_flags = CPU_MIPS32R1, + .mmu_type = MMU_TYPE_R4000, + }, + { + .name = "4KEmR1", + .CP0_PRid = 0x00018500, + .CP0_Config0 = MIPS_CONFIG0 | (MMU_TYPE_FMT << CP0C0_MT), + .CP0_Config1 = MIPS_CONFIG1 | + (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) | + (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA) | + (1 << CP0C1_CA), + .CP0_Config2 = MIPS_CONFIG2, + .CP0_Config3 = MIPS_CONFIG3, + .CP0_LLAddr_rw_bitmask = 0, + .CP0_LLAddr_shift = 4, + .SYNCI_Step = 32, + .CCRes = 2, + .CP0_Status_rw_bitmask = 0x1258FF17, + .SEGBITS = 32, + .PABITS = 32, + .insn_flags = CPU_MIPS32R1 | ASE_MIPS16, + .mmu_type = MMU_TYPE_FMT, + }, + { + .name = "4KEc", + .CP0_PRid = 0x00019000, + .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) | + (MMU_TYPE_R4000 << CP0C0_MT), + .CP0_Config1 = MIPS_CONFIG1 | (15 << CP0C1_MMU) | + (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) | + (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA) | + (0 << CP0C1_CA), + .CP0_Config2 = MIPS_CONFIG2, + .CP0_Config3 = MIPS_CONFIG3 | (0 << CP0C3_VInt), + .CP0_LLAddr_rw_bitmask = 0, + .CP0_LLAddr_shift = 4, + .SYNCI_Step = 32, + .CCRes = 2, + .CP0_Status_rw_bitmask = 0x1278FF17, + .SEGBITS = 32, + .PABITS = 32, + .insn_flags = CPU_MIPS32R2, + .mmu_type = MMU_TYPE_R4000, + }, + { + .name = "4KEm", + .CP0_PRid = 0x00019100, + .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) | + (MMU_TYPE_FMT << CP0C0_MT), + .CP0_Config1 = MIPS_CONFIG1 | + (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) | + (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA) | + (1 << CP0C1_CA), + .CP0_Config2 = MIPS_CONFIG2, + .CP0_Config3 = MIPS_CONFIG3, + .CP0_LLAddr_rw_bitmask = 0, + .CP0_LLAddr_shift = 4, + .SYNCI_Step = 32, + .CCRes = 2, + .CP0_Status_rw_bitmask = 0x1258FF17, + .SEGBITS = 32, + .PABITS = 32, + .insn_flags = CPU_MIPS32R2 | ASE_MIPS16, + .mmu_type = MMU_TYPE_FMT, + }, + { + .name = "24Kc", + .CP0_PRid = 0x00019300, + .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) | + (MMU_TYPE_R4000 << CP0C0_MT), + .CP0_Config1 = MIPS_CONFIG1 | (15 << CP0C1_MMU) | + (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) | + (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA) | + (1 << CP0C1_CA), + .CP0_Config2 = MIPS_CONFIG2, + .CP0_Config3 = MIPS_CONFIG3 | (0 << CP0C3_VInt), + .CP0_LLAddr_rw_bitmask = 0, + .CP0_LLAddr_shift = 4, + .SYNCI_Step = 32, + .CCRes = 2, + /* No DSP implemented. */ + .CP0_Status_rw_bitmask = 0x1278FF1F, + .SEGBITS = 32, + .PABITS = 32, + .insn_flags = CPU_MIPS32R2 | ASE_MIPS16, + .mmu_type = MMU_TYPE_R4000, + }, + { + .name = "24KEc", + .CP0_PRid = 0x00019600, + .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) | + (MMU_TYPE_R4000 << CP0C0_MT), + .CP0_Config1 = MIPS_CONFIG1 | (15 << CP0C1_MMU) | + (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) | + (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA) | + (1 << CP0C1_CA), + .CP0_Config2 = MIPS_CONFIG2, + .CP0_Config3 = MIPS_CONFIG3 | (1 << CP0C3_DSPP) | (0 << CP0C3_VInt), + .CP0_LLAddr_rw_bitmask = 0, + .CP0_LLAddr_shift = 4, + .SYNCI_Step = 32, + .CCRes = 2, + /* we have a DSP, but no FPU */ + .CP0_Status_rw_bitmask = 0x1378FF1F, + .SEGBITS = 32, + .PABITS = 32, + .insn_flags = CPU_MIPS32R2 | ASE_MIPS16 | ASE_DSP, + .mmu_type = MMU_TYPE_R4000, + }, + { + .name = "24Kf", + .CP0_PRid = 0x00019300, + .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) | + (MMU_TYPE_R4000 << CP0C0_MT), + .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (15 << CP0C1_MMU) | + (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) | + (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA) | + (1 << CP0C1_CA), + .CP0_Config2 = MIPS_CONFIG2, + .CP0_Config3 = MIPS_CONFIG3 | (0 << CP0C3_VInt), + .CP0_LLAddr_rw_bitmask = 0, + .CP0_LLAddr_shift = 4, + .SYNCI_Step = 32, + .CCRes = 2, + /* No DSP implemented. */ + .CP0_Status_rw_bitmask = 0x3678FF1F, + .CP1_fcr0 = (1 << FCR0_F64) | (1 << FCR0_L) | (1 << FCR0_W) | + (1 << FCR0_D) | (1 << FCR0_S) | (0x93 << FCR0_PRID), + .CP1_fcr31 = 0, + .CP1_fcr31_rw_bitmask = 0xFF83FFFF, + .SEGBITS = 32, + .PABITS = 32, + .insn_flags = CPU_MIPS32R2 | ASE_MIPS16, + .mmu_type = MMU_TYPE_R4000, + }, + { + .name = "34Kf", + .CP0_PRid = 0x00019500, + .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) | + (MMU_TYPE_R4000 << CP0C0_MT), + .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (63 << CP0C1_MMU) | + (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) | + (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA) | + (1 << CP0C1_CA), + .CP0_Config2 = MIPS_CONFIG2, + .CP0_Config3 = MIPS_CONFIG3 | (1 << CP0C3_VInt) | (1 << CP0C3_MT) | + (1 << CP0C3_DSPP), + .CP0_LLAddr_rw_bitmask = 0, + .CP0_LLAddr_shift = 0, + .SYNCI_Step = 32, + .CCRes = 2, + .CP0_Status_rw_bitmask = 0x3778FF1F, + .CP0_TCStatus_rw_bitmask = (0 << CP0TCSt_TCU3) | (0 << CP0TCSt_TCU2) | + (1 << CP0TCSt_TCU1) | (1 << CP0TCSt_TCU0) | + (0 << CP0TCSt_TMX) | (1 << CP0TCSt_DT) | + (1 << CP0TCSt_DA) | (1 << CP0TCSt_A) | + (0x3 << CP0TCSt_TKSU) | (1 << CP0TCSt_IXMT) | + (0xff << CP0TCSt_TASID), + .CP1_fcr0 = (1 << FCR0_F64) | (1 << FCR0_L) | (1 << FCR0_W) | + (1 << FCR0_D) | (1 << FCR0_S) | (0x95 << FCR0_PRID), + .CP1_fcr31 = 0, + .CP1_fcr31_rw_bitmask = 0xFF83FFFF, + .CP0_SRSCtl = (0xf << CP0SRSCtl_HSS), + .CP0_SRSConf0_rw_bitmask = 0x3fffffff, + .CP0_SRSConf0 = (1U << CP0SRSC0_M) | (0x3fe << CP0SRSC0_SRS3) | + (0x3fe << CP0SRSC0_SRS2) | (0x3fe << CP0SRSC0_SRS1), + .CP0_SRSConf1_rw_bitmask = 0x3fffffff, + .CP0_SRSConf1 = (1U << CP0SRSC1_M) | (0x3fe << CP0SRSC1_SRS6) | + (0x3fe << CP0SRSC1_SRS5) | (0x3fe << CP0SRSC1_SRS4), + .CP0_SRSConf2_rw_bitmask = 0x3fffffff, + .CP0_SRSConf2 = (1U << CP0SRSC2_M) | (0x3fe << CP0SRSC2_SRS9) | + (0x3fe << CP0SRSC2_SRS8) | (0x3fe << CP0SRSC2_SRS7), + .CP0_SRSConf3_rw_bitmask = 0x3fffffff, + .CP0_SRSConf3 = (1U << CP0SRSC3_M) | (0x3fe << CP0SRSC3_SRS12) | + (0x3fe << CP0SRSC3_SRS11) | (0x3fe << CP0SRSC3_SRS10), + .CP0_SRSConf4_rw_bitmask = 0x3fffffff, + .CP0_SRSConf4 = (0x3fe << CP0SRSC4_SRS15) | + (0x3fe << CP0SRSC4_SRS14) | (0x3fe << CP0SRSC4_SRS13), + .SEGBITS = 32, + .PABITS = 32, + .insn_flags = CPU_MIPS32R2 | ASE_MIPS16 | ASE_DSP | ASE_MT, + .mmu_type = MMU_TYPE_R4000, + }, + { + .name = "74Kf", + .CP0_PRid = 0x00019700, + .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) | + (MMU_TYPE_R4000 << CP0C0_MT), + .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (15 << CP0C1_MMU) | + (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) | + (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA) | + (1 << CP0C1_CA), + .CP0_Config2 = MIPS_CONFIG2, + .CP0_Config3 = MIPS_CONFIG3 | (1 << CP0C3_DSP2P) | (1 << CP0C3_DSPP) | + (1 << CP0C3_VInt), + .CP0_LLAddr_rw_bitmask = 0, + .CP0_LLAddr_shift = 4, + .SYNCI_Step = 32, + .CCRes = 2, + .CP0_Status_rw_bitmask = 0x3778FF1F, + .CP1_fcr0 = (1 << FCR0_F64) | (1 << FCR0_L) | (1 << FCR0_W) | + (1 << FCR0_D) | (1 << FCR0_S) | (0x93 << FCR0_PRID), + .CP1_fcr31 = 0, + .CP1_fcr31_rw_bitmask = 0xFF83FFFF, + .SEGBITS = 32, + .PABITS = 32, + .insn_flags = CPU_MIPS32R2 | ASE_MIPS16 | ASE_DSP | ASE_DSP_R2, + .mmu_type = MMU_TYPE_R4000, + }, + { + .name = "M14K", + .CP0_PRid = 0x00019b00, + /* Config1 implemented, fixed mapping MMU, + no virtual icache, uncached coherency. */ + .CP0_Config0 = MIPS_CONFIG0 | (0x2 << CP0C0_KU) | (0x2 << CP0C0_K23) | + (0x1 << CP0C0_AR) | (MMU_TYPE_FMT << CP0C0_MT), + .CP0_Config1 = MIPS_CONFIG1, + .CP0_Config2 = MIPS_CONFIG2, + .CP0_Config3 = MIPS_CONFIG3 | (0x2 << CP0C3_ISA) | (1 << CP0C3_VInt), + .CP0_LLAddr_rw_bitmask = 0, + .CP0_LLAddr_shift = 4, + .SYNCI_Step = 32, + .CCRes = 2, + .CP0_Status_rw_bitmask = 0x1258FF17, + .SEGBITS = 32, + .PABITS = 32, + .insn_flags = CPU_MIPS32R2 | ASE_MICROMIPS, + .mmu_type = MMU_TYPE_FMT, + }, + { + .name = "M14Kc", + /* This is the TLB-based MMU core. */ + .CP0_PRid = 0x00019c00, + .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) | + (MMU_TYPE_R4000 << CP0C0_MT), + .CP0_Config1 = MIPS_CONFIG1 | (15 << CP0C1_MMU) | + (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) | + (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA), + .CP0_Config2 = MIPS_CONFIG2, + .CP0_Config3 = MIPS_CONFIG3 | (0x2 << CP0C3_ISA) | (0 << CP0C3_VInt), + .CP0_LLAddr_rw_bitmask = 0, + .CP0_LLAddr_shift = 4, + .SYNCI_Step = 32, + .CCRes = 2, + .CP0_Status_rw_bitmask = 0x1278FF17, + .SEGBITS = 32, + .PABITS = 32, + .insn_flags = CPU_MIPS32R2 | ASE_MICROMIPS, + .mmu_type = MMU_TYPE_R4000, + }, + { + /* FIXME: + * Config3: VZ, CTXTC, CDMM, TL + * Config4: MMUExtDef + * Config5: MRP + * FIR(FCR0): Has2008 + * */ + .name = "P5600", + .CP0_PRid = 0x0001A800, + .CP0_Config0 = MIPS_CONFIG0 | (1 << CP0C0_MM) | (1 << CP0C0_AR) | + (MMU_TYPE_R4000 << CP0C0_MT), + .CP0_Config1 = MIPS_CONFIG1 | (0x3F << CP0C1_MMU) | + (2 << CP0C1_IS) | (4 << CP0C1_IL) | (3 << CP0C1_IA) | + (2 << CP0C1_DS) | (4 << CP0C1_DL) | (3 << CP0C1_DA) | + (1 << CP0C1_PC) | (1 << CP0C1_FP), + .CP0_Config2 = MIPS_CONFIG2, + .CP0_Config3 = MIPS_CONFIG3 | (1U << CP0C3_M) | + (1 << CP0C3_CMGCR) | (1 << CP0C3_MSAP) | + (1 << CP0C3_BP) | (1 << CP0C3_BI) | (1 << CP0C3_SC) | + (1 << CP0C3_PW) | (1 << CP0C3_ULRI) | (1 << CP0C3_RXI) | + (1 << CP0C3_LPA) | (1 << CP0C3_VInt), + .CP0_Config4 = MIPS_CONFIG4 | (1U << CP0C4_M) | (2 << CP0C4_IE) | + (0x1c << CP0C4_KScrExist), + .CP0_Config4_rw_bitmask = 0, + .CP0_Config5 = MIPS_CONFIG5 | (1 << CP0C5_EVA) | (1 << CP0C5_MVH) | + (1 << CP0C5_LLB) | (1 << CP0C5_MRP), + .CP0_Config5_rw_bitmask = (1 << CP0C5_K) | (1 << CP0C5_CV) | + (1 << CP0C5_MSAEn) | (1 << CP0C5_UFE) | + (1 << CP0C5_FRE) | (1 << CP0C5_UFR), + .CP0_LLAddr_rw_bitmask = 0, + .CP0_LLAddr_shift = 0, + .SYNCI_Step = 32, + .CCRes = 2, + .CP0_Status_rw_bitmask = 0x3C68FF1F, + .CP0_PageGrain_rw_bitmask = (1U << CP0PG_RIE) | (1 << CP0PG_XIE) | + (1 << CP0PG_ELPA) | (1 << CP0PG_IEC), + .CP0_EBaseWG_rw_bitmask = (1 << CP0EBase_WG), + .CP1_fcr0 = (1 << FCR0_FREP) | (1 << FCR0_UFRP) | (1 << FCR0_HAS2008) | + (1 << FCR0_F64) | (1 << FCR0_L) | (1 << FCR0_W) | + (1 << FCR0_D) | (1 << FCR0_S) | (0x03 << FCR0_PRID), + .CP1_fcr31 = (1 << FCR31_ABS2008) | (1 << FCR31_NAN2008), + .CP1_fcr31_rw_bitmask = 0xFF83FFFF, + .SEGBITS = 32, + .PABITS = 40, + .insn_flags = CPU_MIPS32R5 | ASE_MSA, + .mmu_type = MMU_TYPE_R4000, + }, + { + /* A generic CPU supporting MIPS32 Release 6 ISA. + FIXME: Support IEEE 754-2008 FP. + Eventually this should be replaced by a real CPU model. */ + .name = "mips32r6-generic", + .CP0_PRid = 0x00010000, + .CP0_Config0 = MIPS_CONFIG0 | (0x2 << CP0C0_AR) | + (MMU_TYPE_R4000 << CP0C0_MT), + .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (31 << CP0C1_MMU) | + (2 << CP0C1_IS) | (4 << CP0C1_IL) | (3 << CP0C1_IA) | + (2 << CP0C1_DS) | (4 << CP0C1_DL) | (3 << CP0C1_DA) | + (0 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP), + .CP0_Config2 = MIPS_CONFIG2, + .CP0_Config3 = MIPS_CONFIG3 | (1 << CP0C3_BP) | (1 << CP0C3_BI) | + (2 << CP0C3_ISA) | (1 << CP0C3_ULRI) | + (1 << CP0C3_RXI) | (1U << CP0C3_M), + .CP0_Config4 = MIPS_CONFIG4 | (0xfc << CP0C4_KScrExist) | + (3 << CP0C4_IE) | (1U << CP0C4_M), + .CP0_Config5 = MIPS_CONFIG5 | (1 << CP0C5_XNP) | (1 << CP0C5_LLB), + .CP0_Config5_rw_bitmask = (1 << CP0C5_SBRI) | (1 << CP0C5_FRE) | + (1 << CP0C5_UFE), + .CP0_LLAddr_rw_bitmask = 0, + .CP0_LLAddr_shift = 0, + .SYNCI_Step = 32, + .CCRes = 2, + .CP0_Status_rw_bitmask = 0x3058FF1F, + .CP0_PageGrain = (1 << CP0PG_IEC) | (1 << CP0PG_XIE) | + (1U << CP0PG_RIE), + .CP0_PageGrain_rw_bitmask = 0, + .CP1_fcr0 = (1 << FCR0_FREP) | (1 << FCR0_HAS2008) | (1 << FCR0_F64) | + (1 << FCR0_L) | (1 << FCR0_W) | (1 << FCR0_D) | + (1 << FCR0_S) | (0x00 << FCR0_PRID) | (0x0 << FCR0_REV), + .CP1_fcr31 = (1 << FCR31_ABS2008) | (1 << FCR31_NAN2008), + .CP1_fcr31_rw_bitmask = 0x0103FFFF, + .SEGBITS = 32, + .PABITS = 32, + .insn_flags = CPU_MIPS32R6 | ASE_MICROMIPS, + .mmu_type = MMU_TYPE_R4000, + }, + { + .name = "I7200", + .CP0_PRid = 0x00010000, + .CP0_Config0 = MIPS_CONFIG0 | (1 << CP0C0_MM) | (0x2 << CP0C0_AR) | + (MMU_TYPE_R4000 << CP0C0_MT), + .CP0_Config1 = (1U << CP0C1_M) | (15 << CP0C1_MMU) | (2 << CP0C1_IS) | + (4 << CP0C1_IL) | (3 << CP0C1_IA) | (2 << CP0C1_DS) | + (4 << CP0C1_DL) | (3 << CP0C1_DA) | (1 << CP0C1_PC) | + (1 << CP0C1_EP), + .CP0_Config2 = MIPS_CONFIG2, + .CP0_Config3 = MIPS_CONFIG3 | (1U << CP0C3_M) | (1 << CP0C3_CMGCR) | + (1 << CP0C3_BI) | (1 << CP0C3_SC) | (3 << CP0C3_MMAR) | + (1 << CP0C3_ISA_ON_EXC) | (1 << CP0C3_ISA) | + (1 << CP0C3_ULRI) | (1 << CP0C3_RXI) | + (1 << CP0C3_DSP2P) | (1 << CP0C3_DSPP) | + (1 << CP0C3_CTXTC) | (1 << CP0C3_VInt) | + (1 << CP0C3_CDMM) | (1 << CP0C3_MT) | (1 << CP0C3_TL), + .CP0_Config4 = MIPS_CONFIG4 | (0xfc << CP0C4_KScrExist) | + (2 << CP0C4_IE) | (1U << CP0C4_M), + .CP0_Config5 = MIPS_CONFIG5 | (1 << CP0C5_MVH) | (1 << CP0C5_LLB), + .CP0_Config5_rw_bitmask = (1 << CP0C5_SBRI) | (1 << CP0C5_FRE) | + (1 << CP0C5_UFE), + .CP0_LLAddr_rw_bitmask = 0, + .CP0_LLAddr_shift = 0, + .SYNCI_Step = 32, + .CCRes = 2, + .CP0_Status_rw_bitmask = 0x3158FF1F, + .CP0_PageGrain = (1 << CP0PG_IEC) | (1 << CP0PG_XIE) | + (1U << CP0PG_RIE), + .CP0_PageGrain_rw_bitmask = 0, + .CP1_fcr0 = (1 << FCR0_FREP) | (1 << FCR0_HAS2008) | (1 << FCR0_F64) | + (1 << FCR0_L) | (1 << FCR0_W) | (1 << FCR0_D) | + (1 << FCR0_S) | (0x02 << FCR0_PRID) | (0x0 << FCR0_REV), + .CP1_fcr31 = (1 << FCR31_ABS2008) | (1 << FCR31_NAN2008), + .SEGBITS = 32, + .PABITS = 32, + .insn_flags = CPU_NANOMIPS32 | ASE_DSP | ASE_DSP_R2 | ASE_DSP_R3 | + ASE_MT, + .mmu_type = MMU_TYPE_R4000, + }, +#if defined(TARGET_MIPS64) + { + .name = "R4000", + .CP0_PRid = 0x00000400, + /* No L2 cache, icache size 8k, dcache size 8k, uncached coherency. */ + .CP0_Config0 = (2 << CP0C0_Impl) | (1 << CP0C0_IC) | (1 << CP0C0_DC) | + (2 << CP0C0_K0), + /* Note: Config1 is only used internally, the R4000 has only Config0. */ + .CP0_Config1 = (1 << CP0C1_FP) | (47 << CP0C1_MMU), + .CP0_LLAddr_rw_bitmask = 0xFFFFFFFF, + .CP0_LLAddr_shift = 4, + .SYNCI_Step = 16, + .CCRes = 2, + .CP0_Status_rw_bitmask = 0x3678FFFF, + /* The R4000 has a full 64bit FPU but doesn't use the fcr0 bits. */ + .CP1_fcr0 = (0x5 << FCR0_PRID) | (0x0 << FCR0_REV), + .CP1_fcr31 = 0, + .CP1_fcr31_rw_bitmask = 0x0183FFFF, + .SEGBITS = 40, + .PABITS = 36, + .insn_flags = CPU_MIPS3, + .mmu_type = MMU_TYPE_R4000, + }, + { + .name = "VR5432", + .CP0_PRid = 0x00005400, + /* No L2 cache, icache size 8k, dcache size 8k, uncached coherency. */ + .CP0_Config0 = (2 << CP0C0_Impl) | (1 << CP0C0_IC) | (1 << CP0C0_DC) | + (2 << CP0C0_K0), + .CP0_Config1 = (1 << CP0C1_FP) | (47 << CP0C1_MMU), + .CP0_LLAddr_rw_bitmask = 0xFFFFFFFFL, + .CP0_LLAddr_shift = 4, + .SYNCI_Step = 16, + .CCRes = 2, + .CP0_Status_rw_bitmask = 0x3678FFFF, + /* The VR5432 has a full 64bit FPU but doesn't use the fcr0 bits. */ + .CP1_fcr0 = (0x54 << FCR0_PRID) | (0x0 << FCR0_REV), + .CP1_fcr31 = 0, + .CP1_fcr31_rw_bitmask = 0xFF83FFFF, + .SEGBITS = 40, + .PABITS = 32, + .insn_flags = CPU_VR54XX, + .mmu_type = MMU_TYPE_R4000, + }, + { + .name = "5Kc", + .CP0_PRid = 0x00018100, + .CP0_Config0 = MIPS_CONFIG0 | (0x2 << CP0C0_AT) | + (MMU_TYPE_R4000 << CP0C0_MT), + .CP0_Config1 = MIPS_CONFIG1 | (31 << CP0C1_MMU) | + (1 << CP0C1_IS) | (4 << CP0C1_IL) | (1 << CP0C1_IA) | + (1 << CP0C1_DS) | (4 << CP0C1_DL) | (1 << CP0C1_DA) | + (1 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP), + .CP0_Config2 = MIPS_CONFIG2, + .CP0_Config3 = MIPS_CONFIG3, + .CP0_LLAddr_rw_bitmask = 0, + .CP0_LLAddr_shift = 4, + .SYNCI_Step = 32, + .CCRes = 2, + .CP0_Status_rw_bitmask = 0x12F8FFFF, + .SEGBITS = 42, + .PABITS = 36, + .insn_flags = CPU_MIPS64R1, + .mmu_type = MMU_TYPE_R4000, + }, + { + .name = "5Kf", + .CP0_PRid = 0x00018100, + .CP0_Config0 = MIPS_CONFIG0 | (0x2 << CP0C0_AT) | + (MMU_TYPE_R4000 << CP0C0_MT), + .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (31 << CP0C1_MMU) | + (1 << CP0C1_IS) | (4 << CP0C1_IL) | (1 << CP0C1_IA) | + (1 << CP0C1_DS) | (4 << CP0C1_DL) | (1 << CP0C1_DA) | + (1 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP), + .CP0_Config2 = MIPS_CONFIG2, + .CP0_Config3 = MIPS_CONFIG3, + .CP0_LLAddr_rw_bitmask = 0, + .CP0_LLAddr_shift = 4, + .SYNCI_Step = 32, + .CCRes = 2, + .CP0_Status_rw_bitmask = 0x36F8FFFF, + /* The 5Kf has F64 / L / W but doesn't use the fcr0 bits. */ + .CP1_fcr0 = (1 << FCR0_D) | (1 << FCR0_S) | + (0x81 << FCR0_PRID) | (0x0 << FCR0_REV), + .CP1_fcr31 = 0, + .CP1_fcr31_rw_bitmask = 0xFF83FFFF, + .SEGBITS = 42, + .PABITS = 36, + .insn_flags = CPU_MIPS64R1, + .mmu_type = MMU_TYPE_R4000, + }, + { + .name = "20Kc", + /* We emulate a later version of the 20Kc, earlier ones had a broken + WAIT instruction. */ + .CP0_PRid = 0x000182a0, + .CP0_Config0 = MIPS_CONFIG0 | (0x2 << CP0C0_AT) | + (MMU_TYPE_R4000 << CP0C0_MT) | (1 << CP0C0_VI), + .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (47 << CP0C1_MMU) | + (2 << CP0C1_IS) | (4 << CP0C1_IL) | (3 << CP0C1_IA) | + (2 << CP0C1_DS) | (4 << CP0C1_DL) | (3 << CP0C1_DA) | + (1 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP), + .CP0_Config2 = MIPS_CONFIG2, + .CP0_Config3 = MIPS_CONFIG3, + .CP0_LLAddr_rw_bitmask = 0, + .CP0_LLAddr_shift = 0, + .SYNCI_Step = 32, + .CCRes = 1, + .CP0_Status_rw_bitmask = 0x36FBFFFF, + /* The 20Kc has F64 / L / W but doesn't use the fcr0 bits. */ + .CP1_fcr0 = (1 << FCR0_3D) | (1 << FCR0_PS) | + (1 << FCR0_D) | (1 << FCR0_S) | + (0x82 << FCR0_PRID) | (0x0 << FCR0_REV), + .CP1_fcr31 = 0, + .CP1_fcr31_rw_bitmask = 0xFF83FFFF, + .SEGBITS = 40, + .PABITS = 36, + .insn_flags = CPU_MIPS64R1 | ASE_MIPS3D, + .mmu_type = MMU_TYPE_R4000, + }, + { + /* A generic CPU providing MIPS64 Release 2 features. + FIXME: Eventually this should be replaced by a real CPU model. */ + .name = "MIPS64R2-generic", + .CP0_PRid = 0x00010000, + .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) | (0x2 << CP0C0_AT) | + (MMU_TYPE_R4000 << CP0C0_MT), + .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (63 << CP0C1_MMU) | + (2 << CP0C1_IS) | (4 << CP0C1_IL) | (3 << CP0C1_IA) | + (2 << CP0C1_DS) | (4 << CP0C1_DL) | (3 << CP0C1_DA) | + (1 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP), + .CP0_Config2 = MIPS_CONFIG2, + .CP0_Config3 = MIPS_CONFIG3 | (1 << CP0C3_LPA), + .CP0_LLAddr_rw_bitmask = 0, + .CP0_LLAddr_shift = 0, + .SYNCI_Step = 32, + .CCRes = 2, + .CP0_Status_rw_bitmask = 0x36FBFFFF, + .CP0_EBaseWG_rw_bitmask = (1 << CP0EBase_WG), + .CP1_fcr0 = (1 << FCR0_F64) | (1 << FCR0_3D) | (1 << FCR0_PS) | + (1 << FCR0_L) | (1 << FCR0_W) | (1 << FCR0_D) | + (1 << FCR0_S) | (0x00 << FCR0_PRID) | (0x0 << FCR0_REV), + .CP1_fcr31 = 0, + .CP1_fcr31_rw_bitmask = 0xFF83FFFF, + .SEGBITS = 42, + .PABITS = 36, + .insn_flags = CPU_MIPS64R2 | ASE_MIPS3D, + .mmu_type = MMU_TYPE_R4000, + }, + { + .name = "5KEc", + .CP0_PRid = 0x00018900, + .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) | (0x2 << CP0C0_AT) | + (MMU_TYPE_R4000 << CP0C0_MT), + .CP0_Config1 = MIPS_CONFIG1 | (31 << CP0C1_MMU) | + (1 << CP0C1_IS) | (4 << CP0C1_IL) | (1 << CP0C1_IA) | + (1 << CP0C1_DS) | (4 << CP0C1_DL) | (1 << CP0C1_DA) | + (1 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP), + .CP0_Config2 = MIPS_CONFIG2, + .CP0_Config3 = MIPS_CONFIG3, + .CP0_LLAddr_rw_bitmask = 0, + .CP0_LLAddr_shift = 4, + .SYNCI_Step = 32, + .CCRes = 2, + .CP0_Status_rw_bitmask = 0x12F8FFFF, + .SEGBITS = 42, + .PABITS = 36, + .insn_flags = CPU_MIPS64R2, + .mmu_type = MMU_TYPE_R4000, + }, + { + .name = "5KEf", + .CP0_PRid = 0x00018900, + .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) | (0x2 << CP0C0_AT) | + (MMU_TYPE_R4000 << CP0C0_MT), + .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (31 << CP0C1_MMU) | + (1 << CP0C1_IS) | (4 << CP0C1_IL) | (1 << CP0C1_IA) | + (1 << CP0C1_DS) | (4 << CP0C1_DL) | (1 << CP0C1_DA) | + (1 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP), + .CP0_Config2 = MIPS_CONFIG2, + .CP0_Config3 = MIPS_CONFIG3, + .CP0_LLAddr_rw_bitmask = 0, + .CP0_LLAddr_shift = 4, + .SYNCI_Step = 32, + .CCRes = 2, + .CP0_Status_rw_bitmask = 0x36F8FFFF, + .CP1_fcr0 = (1 << FCR0_F64) | (1 << FCR0_L) | (1 << FCR0_W) | + (1 << FCR0_D) | (1 << FCR0_S) | + (0x89 << FCR0_PRID) | (0x0 << FCR0_REV), + .SEGBITS = 42, + .PABITS = 36, + .insn_flags = CPU_MIPS64R2, + .mmu_type = MMU_TYPE_R4000, + }, + { + .name = "I6400", + .CP0_PRid = 0x1A900, + .CP0_Config0 = MIPS_CONFIG0 | (0x2 << CP0C0_AR) | (0x2 << CP0C0_AT) | + (MMU_TYPE_R4000 << CP0C0_MT), + .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (15 << CP0C1_MMU) | + (2 << CP0C1_IS) | (5 << CP0C1_IL) | (3 << CP0C1_IA) | + (2 << CP0C1_DS) | (5 << CP0C1_DL) | (3 << CP0C1_DA) | + (0 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP), + .CP0_Config2 = MIPS_CONFIG2, + .CP0_Config3 = MIPS_CONFIG3 | (1U << CP0C3_M) | + (1 << CP0C3_CMGCR) | (1 << CP0C3_MSAP) | + (1 << CP0C3_BP) | (1 << CP0C3_BI) | (1 << CP0C3_ULRI) | + (1 << CP0C3_RXI) | (1 << CP0C3_LPA) | (1 << CP0C3_VInt), + .CP0_Config4 = MIPS_CONFIG4 | (1U << CP0C4_M) | (3 << CP0C4_IE) | + (1 << CP0C4_AE) | (0xfc << CP0C4_KScrExist), + .CP0_Config5 = MIPS_CONFIG5 | (1 << CP0C5_XNP) | (1 << CP0C5_VP) | + (1 << CP0C5_LLB) | (1 << CP0C5_MRP), + .CP0_Config5_rw_bitmask = (1 << CP0C5_MSAEn) | (1 << CP0C5_SBRI) | + (1 << CP0C5_FRE) | (1 << CP0C5_UFE), + .CP0_LLAddr_rw_bitmask = 0, + .CP0_LLAddr_shift = 0, + .SYNCI_Step = 32, + .CCRes = 2, + .CP0_Status_rw_bitmask = 0x30D8FFFF, + .CP0_PageGrain = (1 << CP0PG_IEC) | (1 << CP0PG_XIE) | + (1U << CP0PG_RIE), + .CP0_PageGrain_rw_bitmask = (1 << CP0PG_ELPA), + .CP0_EBaseWG_rw_bitmask = (1 << CP0EBase_WG), + .CP1_fcr0 = (1 << FCR0_FREP) | (1 << FCR0_HAS2008) | (1 << FCR0_F64) | + (1 << FCR0_L) | (1 << FCR0_W) | (1 << FCR0_D) | + (1 << FCR0_S) | (0x03 << FCR0_PRID) | (0x0 << FCR0_REV), + .CP1_fcr31 = (1 << FCR31_ABS2008) | (1 << FCR31_NAN2008), + .CP1_fcr31_rw_bitmask = 0x0103FFFF, + .MSAIR = 0x03 << MSAIR_ProcID, + .SEGBITS = 48, + .PABITS = 48, + .insn_flags = CPU_MIPS64R6 | ASE_MSA, + .mmu_type = MMU_TYPE_R4000, + }, + { + .name = "I6500", + .CP0_PRid = 0x1B000, + .CP0_Config0 = MIPS_CONFIG0 | (0x2 << CP0C0_AR) | (0x2 << CP0C0_AT) | + (MMU_TYPE_R4000 << CP0C0_MT), + .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (15 << CP0C1_MMU) | + (2 << CP0C1_IS) | (5 << CP0C1_IL) | (3 << CP0C1_IA) | + (2 << CP0C1_DS) | (5 << CP0C1_DL) | (3 << CP0C1_DA) | + (0 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP), + .CP0_Config2 = MIPS_CONFIG2, + .CP0_Config3 = MIPS_CONFIG3 | (1U << CP0C3_M) | + (1 << CP0C3_CMGCR) | (1 << CP0C3_MSAP) | + (1 << CP0C3_BP) | (1 << CP0C3_BI) | (1 << CP0C3_ULRI) | + (1 << CP0C3_RXI) | (1 << CP0C3_LPA) | (1 << CP0C3_VInt), + .CP0_Config4 = MIPS_CONFIG4 | (1U << CP0C4_M) | (3 << CP0C4_IE) | + (1 << CP0C4_AE) | (0xfc << CP0C4_KScrExist), + .CP0_Config5 = MIPS_CONFIG5 | (1 << CP0C5_XNP) | (1 << CP0C5_VP) | + (1 << CP0C5_LLB) | (1 << CP0C5_MRP), + .CP0_Config5_rw_bitmask = (1 << CP0C5_MSAEn) | (1 << CP0C5_SBRI) | + (1 << CP0C5_FRE) | (1 << CP0C5_UFE), + .CP0_LLAddr_rw_bitmask = 0, + .CP0_LLAddr_shift = 0, + .SYNCI_Step = 64, + .CCRes = 2, + .CP0_Status_rw_bitmask = 0x30D8FFFF, + .CP0_PageGrain = (1 << CP0PG_IEC) | (1 << CP0PG_XIE) | + (1U << CP0PG_RIE), + .CP0_PageGrain_rw_bitmask = (1 << CP0PG_ELPA), + .CP0_EBaseWG_rw_bitmask = (1 << CP0EBase_WG), + .CP1_fcr0 = (1 << FCR0_FREP) | (1 << FCR0_HAS2008) | (1 << FCR0_F64) | + (1 << FCR0_L) | (1 << FCR0_W) | (1 << FCR0_D) | + (1 << FCR0_S) | (0x03 << FCR0_PRID) | (0x0 << FCR0_REV), + .CP1_fcr31 = (1 << FCR31_ABS2008) | (1 << FCR31_NAN2008), + .CP1_fcr31_rw_bitmask = 0x0103FFFF, + .MSAIR = 0x03 << MSAIR_ProcID, + .SEGBITS = 48, + .PABITS = 48, + .insn_flags = CPU_MIPS64R6 | ASE_MSA, + .mmu_type = MMU_TYPE_R4000, + }, + { + .name = "Loongson-2E", + .CP0_PRid = 0x6302, + /* 64KB I-cache and d-cache. 4 way with 32 bit cache line size. */ + .CP0_Config0 = (3 << CP0C0_Impl) | (4 << CP0C0_IC) | (4 << CP0C0_DC) | + (1 << CP0C0_IB) | (1 << CP0C0_DB) | (0x2 << CP0C0_K0), + /* Note: Config1 is only used internally, + Loongson-2E has only Config0. */ + .CP0_Config1 = (1 << CP0C1_FP) | (47 << CP0C1_MMU), + .SYNCI_Step = 16, + .CCRes = 2, + .CP0_Status_rw_bitmask = 0x35D0FFFF, + .CP1_fcr0 = (0x5 << FCR0_PRID) | (0x1 << FCR0_REV), + .CP1_fcr31 = 0, + .CP1_fcr31_rw_bitmask = 0xFF83FFFF, + .SEGBITS = 40, + .PABITS = 40, + .insn_flags = CPU_LOONGSON2E, + .mmu_type = MMU_TYPE_R4000, + }, + { + .name = "Loongson-2F", + .CP0_PRid = 0x6303, + /* 64KB I-cache and d-cache. 4 way with 32 bit cache line size. */ + .CP0_Config0 = (3 << CP0C0_Impl) | (4 << CP0C0_IC) | (4 << CP0C0_DC) | + (1 << CP0C0_IB) | (1 << CP0C0_DB) | (0x2 << CP0C0_K0), + /* Note: Config1 is only used internally, + Loongson-2F has only Config0. */ + .CP0_Config1 = (1 << CP0C1_FP) | (47 << CP0C1_MMU), + .SYNCI_Step = 16, + .CCRes = 2, + .CP0_Status_rw_bitmask = 0xF5D0FF1F, /* Bits 7:5 not writable. */ + .CP1_fcr0 = (0x5 << FCR0_PRID) | (0x1 << FCR0_REV), + .CP1_fcr31 = 0, + .CP1_fcr31_rw_bitmask = 0xFF83FFFF, + .SEGBITS = 40, + .PABITS = 40, + .insn_flags = CPU_LOONGSON2F, + .mmu_type = MMU_TYPE_R4000, + }, + { + .name = "Loongson-3A1000", + .CP0_PRid = 0x6305, + /* 64KB I-cache and d-cache. 4 way with 32 bit cache line size. */ + .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) | (0x2 << CP0C0_AT) | + (MMU_TYPE_R4000 << CP0C0_MT), + .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (63 << CP0C1_MMU) | + (3 << CP0C1_IS) | (4 << CP0C1_IL) | (3 << CP0C1_IA) | + (3 << CP0C1_DS) | (4 << CP0C1_DL) | (3 << CP0C1_DA) | + (1 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP), + .CP0_Config2 = MIPS_CONFIG2 | (7 << CP0C2_SS) | (4 << CP0C2_SL) | + (3 << CP0C2_SA), + .CP0_Config3 = MIPS_CONFIG3 | (1 << CP0C3_LPA), + .CP0_LLAddr_rw_bitmask = 0, + .SYNCI_Step = 32, + .CCRes = 2, + .CP0_Status_rw_bitmask = 0x74D8FFFF, + .CP0_PageGrain = (1 << CP0PG_ELPA), + .CP0_PageGrain_rw_bitmask = (1 << CP0PG_ELPA), + .CP1_fcr0 = (0x5 << FCR0_PRID) | (0x1 << FCR0_REV) | (0x1 << FCR0_F64) | + (0x1 << FCR0_PS) | (0x1 << FCR0_L) | (0x1 << FCR0_W) | + (0x1 << FCR0_D) | (0x1 << FCR0_S), + .CP1_fcr31 = 0, + .CP1_fcr31_rw_bitmask = 0xFF83FFFF, + .SEGBITS = 42, + .PABITS = 48, + .insn_flags = CPU_LOONGSON3A, + .mmu_type = MMU_TYPE_R4000, + }, + { + .name = "Loongson-3A4000", /* GS464V-based */ + .CP0_PRid = 0x14C000, + /* 64KB I-cache and d-cache. 4 way with 32 bit cache line size. */ + .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) | (0x2 << CP0C0_AT) | + (MMU_TYPE_R4000 << CP0C0_MT), + .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (63 << CP0C1_MMU) | + (2 << CP0C1_IS) | (5 << CP0C1_IL) | (3 << CP0C1_IA) | + (2 << CP0C1_DS) | (5 << CP0C1_DL) | (3 << CP0C1_DA) | + (1 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP), + .CP0_Config2 = MIPS_CONFIG2 | (5 << CP0C2_SS) | (5 << CP0C2_SL) | + (15 << CP0C2_SA), + .CP0_Config3 = MIPS_CONFIG3 | (1U << CP0C3_M) | (1 << CP0C3_MSAP) | + (1 << CP0C3_BP) | (1 << CP0C3_BI) | (1 << CP0C3_ULRI) | + (1 << CP0C3_RXI) | (1 << CP0C3_LPA) | (1 << CP0C3_VInt), + .CP0_Config4 = MIPS_CONFIG4 | (1U << CP0C4_M) | (2 << CP0C4_IE) | + (1 << CP0C4_AE) | (0x1c << CP0C4_KScrExist), + .CP0_Config4_rw_bitmask = 0, + .CP0_Config5 = MIPS_CONFIG5 | (1 << CP0C5_CRCP) | (1 << CP0C5_NFExists), + .CP0_Config5_rw_bitmask = (1 << CP0C5_K) | (1 << CP0C5_CV) | + (1 << CP0C5_MSAEn) | (1 << CP0C5_UFE) | + (1 << CP0C5_FRE) | (1 << CP0C5_SBRI), + .CP0_Config6 = (1 << CP0C6_VCLRU) | (1 << CP0C6_DCLRU) | + (1 << CP0C6_SFBEN) | (1 << CP0C6_VLTINT) | + (1 << CP0C6_INSTPREF) | (1 << CP0C6_DATAPREF), + .CP0_Config6_rw_bitmask = (1 << CP0C6_BPPASS) | (0x3f << CP0C6_KPOS) | + (1 << CP0C6_KE) | (1 << CP0C6_VTLBONLY) | + (1 << CP0C6_LASX) | (1 << CP0C6_SSEN) | + (1 << CP0C6_DISDRTIME) | (1 << CP0C6_PIXNUEN) | + (1 << CP0C6_SCRAND) | (1 << CP0C6_LLEXCEN) | + (1 << CP0C6_DISVC) | (1 << CP0C6_VCLRU) | + (1 << CP0C6_DCLRU) | (1 << CP0C6_PIXUEN) | + (1 << CP0C6_DISBLKLYEN) | (1 << CP0C6_UMEMUALEN) | + (1 << CP0C6_SFBEN) | (1 << CP0C6_FLTINT) | + (1 << CP0C6_VLTINT) | (1 << CP0C6_DISBTB) | + (3 << CP0C6_STPREFCTL) | (1 << CP0C6_INSTPREF) | + (1 << CP0C6_DATAPREF), + .CP0_Config7 = 0, + .CP0_Config7_rw_bitmask = (1 << CP0C7_NAPCGEN) | (1 << CP0C7_UNIMUEN) | + (1 << CP0C7_VFPUCGEN), + .CP0_LLAddr_rw_bitmask = 1, + .SYNCI_Step = 16, + .CCRes = 2, + .CP0_Status_rw_bitmask = 0x7DDBFFFF, + .CP0_PageGrain = (1 << CP0PG_ELPA), + .CP0_PageGrain_rw_bitmask = (1U << CP0PG_RIE) | (1 << CP0PG_XIE) | + (1 << CP0PG_ELPA) | (1 << CP0PG_IEC), + .CP1_fcr0 = (0x5 << FCR0_PRID) | (0x1 << FCR0_REV) | (0x1 << FCR0_F64) | + (0x1 << FCR0_PS) | (0x1 << FCR0_L) | (0x1 << FCR0_W) | + (0x1 << FCR0_D) | (0x1 << FCR0_S), + .CP1_fcr31 = 0, + .CP1_fcr31_rw_bitmask = 0xFF83FFFF, + .SEGBITS = 48, + .PABITS = 48, + .insn_flags = CPU_LOONGSON3A | ASE_MSA, + .mmu_type = MMU_TYPE_R4000, + }, + { + /* A generic CPU providing MIPS64 DSP R2 ASE features. + FIXME: Eventually this should be replaced by a real CPU model. */ + .name = "mips64dspr2", + .CP0_PRid = 0x00010000, + .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) | (0x2 << CP0C0_AT) | + (MMU_TYPE_R4000 << CP0C0_MT), + .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (63 << CP0C1_MMU) | + (2 << CP0C1_IS) | (4 << CP0C1_IL) | (3 << CP0C1_IA) | + (2 << CP0C1_DS) | (4 << CP0C1_DL) | (3 << CP0C1_DA) | + (1 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP), + .CP0_Config2 = MIPS_CONFIG2, + .CP0_Config3 = MIPS_CONFIG3 | (1U << CP0C3_M) | (1 << CP0C3_DSP2P) | + (1 << CP0C3_DSPP) | (1 << CP0C3_LPA), + .CP0_LLAddr_rw_bitmask = 0, + .CP0_LLAddr_shift = 0, + .SYNCI_Step = 32, + .CCRes = 2, + .CP0_Status_rw_bitmask = 0x37FBFFFF, + .CP1_fcr0 = (1 << FCR0_F64) | (1 << FCR0_3D) | (1 << FCR0_PS) | + (1 << FCR0_L) | (1 << FCR0_W) | (1 << FCR0_D) | + (1 << FCR0_S) | (0x00 << FCR0_PRID) | (0x0 << FCR0_REV), + .CP1_fcr31 = 0, + .CP1_fcr31_rw_bitmask = 0xFF83FFFF, + .SEGBITS = 42, + .PABITS = 36, + .insn_flags = CPU_MIPS64R2 | ASE_DSP | ASE_DSP_R2, + .mmu_type = MMU_TYPE_R4000, + }, + +#endif +}; +const int mips_defs_number = ARRAY_SIZE(mips_defs); + +void mips_cpu_list(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(mips_defs); i++) { + qemu_printf("MIPS '%s'\n", mips_defs[i].name); + } +} + +static void fpu_init (CPUMIPSState *env, const mips_def_t *def) +{ + int i; + + for (i = 0; i < MIPS_FPU_MAX; i++) + env->fpus[i].fcr0 = def->CP1_fcr0; + + memcpy(&env->active_fpu, &env->fpus[0], sizeof(env->active_fpu)); +} + +static void mvp_init(CPUMIPSState *env) +{ + env->mvp = g_malloc0(sizeof(CPUMIPSMVPContext)); + + if (!ase_mt_available(env)) { + return; + } + + /* MVPConf1 implemented, TLB sharable, no gating storage support, + programmable cache partitioning implemented, number of allocatable + and shareable TLB entries, MVP has allocatable TCs, 2 VPEs + implemented, 5 TCs implemented. */ + env->mvp->CP0_MVPConf0 = (1U << CP0MVPC0_M) | (1 << CP0MVPC0_TLBS) | + (0 << CP0MVPC0_GS) | (1 << CP0MVPC0_PCP) | +// TODO: actually do 2 VPEs. +// (1 << CP0MVPC0_TCA) | (0x1 << CP0MVPC0_PVPE) | +// (0x04 << CP0MVPC0_PTC); + (1 << CP0MVPC0_TCA) | (0x0 << CP0MVPC0_PVPE) | + (0x00 << CP0MVPC0_PTC); +#if !defined(CONFIG_USER_ONLY) + /* Usermode has no TLB support */ + env->mvp->CP0_MVPConf0 |= (env->tlb->nb_tlb << CP0MVPC0_PTLBE); +#endif + + /* Allocatable CP1 have media extensions, allocatable CP1 have FP support, + no UDI implemented, no CP2 implemented, 1 CP1 implemented. */ + env->mvp->CP0_MVPConf1 = (1U << CP0MVPC1_CIM) | (1 << CP0MVPC1_CIF) | + (0x0 << CP0MVPC1_PCX) | (0x0 << CP0MVPC1_PCP2) | + (0x1 << CP0MVPC1_PCP1); +} + +static void msa_reset(CPUMIPSState *env) +{ +#ifdef CONFIG_USER_ONLY + /* MSA access enabled */ + env->CP0_Config5 |= 1 << CP0C5_MSAEn; + env->CP0_Status |= (1 << CP0St_CU1) | (1 << CP0St_FR); +#endif + + /* MSA CSR: + - non-signaling floating point exception mode off (NX bit is 0) + - Cause, Enables, and Flags are all 0 + - round to nearest / ties to even (RM bits are 0) */ + env->active_tc.msacsr = 0; + + restore_msa_fp_status(env); + + /* tininess detected after rounding.*/ + set_float_detect_tininess(float_tininess_after_rounding, + &env->active_tc.msa_fp_status); + + /* clear float_status exception flags */ + set_float_exception_flags(0, &env->active_tc.msa_fp_status); + + /* clear float_status nan mode */ + set_default_nan_mode(0, &env->active_tc.msa_fp_status); + + /* set proper signanling bit meaning ("1" means "quiet") */ + set_snan_bit_is_one(0, &env->active_tc.msa_fp_status); +} diff --git a/target/mips/cpu.c b/target/mips/cpu.c index 6376076a3f..f3bf0466a4 100644 --- a/target/mips/cpu.c +++ b/target/mips/cpu.c @@ -312,7 +312,7 @@ static bool mips_cpu_has_work(CPUState *cs) return has_work; } -#include "translate_init.c.inc" +#include "cpu-defs.c.inc" static void mips_cpu_reset(DeviceState *dev) { diff --git a/target/mips/translate_init.c.inc b/target/mips/translate_init.c.inc deleted file mode 100644 index 535d4c0c70..0000000000 --- a/target/mips/translate_init.c.inc +++ /dev/null @@ -1,1007 +0,0 @@ -/* - * MIPS emulation for qemu: CPU initialisation routines. - * - * Copyright (c) 2004-2005 Jocelyn Mayer - * Copyright (c) 2007 Herve Poussineau - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see . - */ - -#include "fpu_helper.h" - -/* CPU / CPU family specific config register values. */ - -/* Have config1, uncached coherency */ -#define MIPS_CONFIG0 \ - ((1U << CP0C0_M) | (0x2 << CP0C0_K0)) - -/* Have config2, no coprocessor2 attached, no MDMX support attached, - no performance counters, watch registers present, - no code compression, EJTAG present, no FPU */ -#define MIPS_CONFIG1 \ -((1U << CP0C1_M) | \ - (0 << CP0C1_C2) | (0 << CP0C1_MD) | (0 << CP0C1_PC) | \ - (1 << CP0C1_WR) | (0 << CP0C1_CA) | (1 << CP0C1_EP) | \ - (0 << CP0C1_FP)) - -/* Have config3, no tertiary/secondary caches implemented */ -#define MIPS_CONFIG2 \ -((1U << CP0C2_M)) - -/* No config4, no DSP ASE, no large physaddr (PABITS), - no external interrupt controller, no vectored interrupts, - no 1kb pages, no SmartMIPS ASE, no trace logic */ -#define MIPS_CONFIG3 \ -((0 << CP0C3_M) | (0 << CP0C3_DSPP) | (0 << CP0C3_LPA) | \ - (0 << CP0C3_VEIC) | (0 << CP0C3_VInt) | (0 << CP0C3_SP) | \ - (0 << CP0C3_SM) | (0 << CP0C3_TL)) - -#define MIPS_CONFIG4 \ -((0 << CP0C4_M)) - -#define MIPS_CONFIG5 \ -((0 << CP0C5_M)) - -/*****************************************************************************/ -/* MIPS CPU definitions */ -const mips_def_t mips_defs[] = -{ - { - .name = "4Kc", - .CP0_PRid = 0x00018000, - .CP0_Config0 = MIPS_CONFIG0 | (MMU_TYPE_R4000 << CP0C0_MT), - .CP0_Config1 = MIPS_CONFIG1 | (15 << CP0C1_MMU) | - (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) | - (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA) | - (0 << CP0C1_CA), - .CP0_Config2 = MIPS_CONFIG2, - .CP0_Config3 = MIPS_CONFIG3, - .CP0_LLAddr_rw_bitmask = 0, - .CP0_LLAddr_shift = 4, - .SYNCI_Step = 32, - .CCRes = 2, - .CP0_Status_rw_bitmask = 0x1278FF17, - .SEGBITS = 32, - .PABITS = 32, - .insn_flags = CPU_MIPS32R1, - .mmu_type = MMU_TYPE_R4000, - }, - { - .name = "4Km", - .CP0_PRid = 0x00018300, - /* Config1 implemented, fixed mapping MMU, - no virtual icache, uncached coherency. */ - .CP0_Config0 = MIPS_CONFIG0 | (MMU_TYPE_FMT << CP0C0_MT), - .CP0_Config1 = MIPS_CONFIG1 | - (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) | - (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA) | - (1 << CP0C1_CA), - .CP0_Config2 = MIPS_CONFIG2, - .CP0_Config3 = MIPS_CONFIG3, - .CP0_LLAddr_rw_bitmask = 0, - .CP0_LLAddr_shift = 4, - .SYNCI_Step = 32, - .CCRes = 2, - .CP0_Status_rw_bitmask = 0x1258FF17, - .SEGBITS = 32, - .PABITS = 32, - .insn_flags = CPU_MIPS32R1 | ASE_MIPS16, - .mmu_type = MMU_TYPE_FMT, - }, - { - .name = "4KEcR1", - .CP0_PRid = 0x00018400, - .CP0_Config0 = MIPS_CONFIG0 | (MMU_TYPE_R4000 << CP0C0_MT), - .CP0_Config1 = MIPS_CONFIG1 | (15 << CP0C1_MMU) | - (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) | - (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA) | - (0 << CP0C1_CA), - .CP0_Config2 = MIPS_CONFIG2, - .CP0_Config3 = MIPS_CONFIG3, - .CP0_LLAddr_rw_bitmask = 0, - .CP0_LLAddr_shift = 4, - .SYNCI_Step = 32, - .CCRes = 2, - .CP0_Status_rw_bitmask = 0x1278FF17, - .SEGBITS = 32, - .PABITS = 32, - .insn_flags = CPU_MIPS32R1, - .mmu_type = MMU_TYPE_R4000, - }, - { - .name = "4KEmR1", - .CP0_PRid = 0x00018500, - .CP0_Config0 = MIPS_CONFIG0 | (MMU_TYPE_FMT << CP0C0_MT), - .CP0_Config1 = MIPS_CONFIG1 | - (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) | - (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA) | - (1 << CP0C1_CA), - .CP0_Config2 = MIPS_CONFIG2, - .CP0_Config3 = MIPS_CONFIG3, - .CP0_LLAddr_rw_bitmask = 0, - .CP0_LLAddr_shift = 4, - .SYNCI_Step = 32, - .CCRes = 2, - .CP0_Status_rw_bitmask = 0x1258FF17, - .SEGBITS = 32, - .PABITS = 32, - .insn_flags = CPU_MIPS32R1 | ASE_MIPS16, - .mmu_type = MMU_TYPE_FMT, - }, - { - .name = "4KEc", - .CP0_PRid = 0x00019000, - .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) | - (MMU_TYPE_R4000 << CP0C0_MT), - .CP0_Config1 = MIPS_CONFIG1 | (15 << CP0C1_MMU) | - (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) | - (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA) | - (0 << CP0C1_CA), - .CP0_Config2 = MIPS_CONFIG2, - .CP0_Config3 = MIPS_CONFIG3 | (0 << CP0C3_VInt), - .CP0_LLAddr_rw_bitmask = 0, - .CP0_LLAddr_shift = 4, - .SYNCI_Step = 32, - .CCRes = 2, - .CP0_Status_rw_bitmask = 0x1278FF17, - .SEGBITS = 32, - .PABITS = 32, - .insn_flags = CPU_MIPS32R2, - .mmu_type = MMU_TYPE_R4000, - }, - { - .name = "4KEm", - .CP0_PRid = 0x00019100, - .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) | - (MMU_TYPE_FMT << CP0C0_MT), - .CP0_Config1 = MIPS_CONFIG1 | - (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) | - (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA) | - (1 << CP0C1_CA), - .CP0_Config2 = MIPS_CONFIG2, - .CP0_Config3 = MIPS_CONFIG3, - .CP0_LLAddr_rw_bitmask = 0, - .CP0_LLAddr_shift = 4, - .SYNCI_Step = 32, - .CCRes = 2, - .CP0_Status_rw_bitmask = 0x1258FF17, - .SEGBITS = 32, - .PABITS = 32, - .insn_flags = CPU_MIPS32R2 | ASE_MIPS16, - .mmu_type = MMU_TYPE_FMT, - }, - { - .name = "24Kc", - .CP0_PRid = 0x00019300, - .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) | - (MMU_TYPE_R4000 << CP0C0_MT), - .CP0_Config1 = MIPS_CONFIG1 | (15 << CP0C1_MMU) | - (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) | - (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA) | - (1 << CP0C1_CA), - .CP0_Config2 = MIPS_CONFIG2, - .CP0_Config3 = MIPS_CONFIG3 | (0 << CP0C3_VInt), - .CP0_LLAddr_rw_bitmask = 0, - .CP0_LLAddr_shift = 4, - .SYNCI_Step = 32, - .CCRes = 2, - /* No DSP implemented. */ - .CP0_Status_rw_bitmask = 0x1278FF1F, - .SEGBITS = 32, - .PABITS = 32, - .insn_flags = CPU_MIPS32R2 | ASE_MIPS16, - .mmu_type = MMU_TYPE_R4000, - }, - { - .name = "24KEc", - .CP0_PRid = 0x00019600, - .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) | - (MMU_TYPE_R4000 << CP0C0_MT), - .CP0_Config1 = MIPS_CONFIG1 | (15 << CP0C1_MMU) | - (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) | - (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA) | - (1 << CP0C1_CA), - .CP0_Config2 = MIPS_CONFIG2, - .CP0_Config3 = MIPS_CONFIG3 | (1 << CP0C3_DSPP) | (0 << CP0C3_VInt), - .CP0_LLAddr_rw_bitmask = 0, - .CP0_LLAddr_shift = 4, - .SYNCI_Step = 32, - .CCRes = 2, - /* we have a DSP, but no FPU */ - .CP0_Status_rw_bitmask = 0x1378FF1F, - .SEGBITS = 32, - .PABITS = 32, - .insn_flags = CPU_MIPS32R2 | ASE_MIPS16 | ASE_DSP, - .mmu_type = MMU_TYPE_R4000, - }, - { - .name = "24Kf", - .CP0_PRid = 0x00019300, - .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) | - (MMU_TYPE_R4000 << CP0C0_MT), - .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (15 << CP0C1_MMU) | - (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) | - (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA) | - (1 << CP0C1_CA), - .CP0_Config2 = MIPS_CONFIG2, - .CP0_Config3 = MIPS_CONFIG3 | (0 << CP0C3_VInt), - .CP0_LLAddr_rw_bitmask = 0, - .CP0_LLAddr_shift = 4, - .SYNCI_Step = 32, - .CCRes = 2, - /* No DSP implemented. */ - .CP0_Status_rw_bitmask = 0x3678FF1F, - .CP1_fcr0 = (1 << FCR0_F64) | (1 << FCR0_L) | (1 << FCR0_W) | - (1 << FCR0_D) | (1 << FCR0_S) | (0x93 << FCR0_PRID), - .CP1_fcr31 = 0, - .CP1_fcr31_rw_bitmask = 0xFF83FFFF, - .SEGBITS = 32, - .PABITS = 32, - .insn_flags = CPU_MIPS32R2 | ASE_MIPS16, - .mmu_type = MMU_TYPE_R4000, - }, - { - .name = "34Kf", - .CP0_PRid = 0x00019500, - .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) | - (MMU_TYPE_R4000 << CP0C0_MT), - .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (63 << CP0C1_MMU) | - (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) | - (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA) | - (1 << CP0C1_CA), - .CP0_Config2 = MIPS_CONFIG2, - .CP0_Config3 = MIPS_CONFIG3 | (1 << CP0C3_VInt) | (1 << CP0C3_MT) | - (1 << CP0C3_DSPP), - .CP0_LLAddr_rw_bitmask = 0, - .CP0_LLAddr_shift = 0, - .SYNCI_Step = 32, - .CCRes = 2, - .CP0_Status_rw_bitmask = 0x3778FF1F, - .CP0_TCStatus_rw_bitmask = (0 << CP0TCSt_TCU3) | (0 << CP0TCSt_TCU2) | - (1 << CP0TCSt_TCU1) | (1 << CP0TCSt_TCU0) | - (0 << CP0TCSt_TMX) | (1 << CP0TCSt_DT) | - (1 << CP0TCSt_DA) | (1 << CP0TCSt_A) | - (0x3 << CP0TCSt_TKSU) | (1 << CP0TCSt_IXMT) | - (0xff << CP0TCSt_TASID), - .CP1_fcr0 = (1 << FCR0_F64) | (1 << FCR0_L) | (1 << FCR0_W) | - (1 << FCR0_D) | (1 << FCR0_S) | (0x95 << FCR0_PRID), - .CP1_fcr31 = 0, - .CP1_fcr31_rw_bitmask = 0xFF83FFFF, - .CP0_SRSCtl = (0xf << CP0SRSCtl_HSS), - .CP0_SRSConf0_rw_bitmask = 0x3fffffff, - .CP0_SRSConf0 = (1U << CP0SRSC0_M) | (0x3fe << CP0SRSC0_SRS3) | - (0x3fe << CP0SRSC0_SRS2) | (0x3fe << CP0SRSC0_SRS1), - .CP0_SRSConf1_rw_bitmask = 0x3fffffff, - .CP0_SRSConf1 = (1U << CP0SRSC1_M) | (0x3fe << CP0SRSC1_SRS6) | - (0x3fe << CP0SRSC1_SRS5) | (0x3fe << CP0SRSC1_SRS4), - .CP0_SRSConf2_rw_bitmask = 0x3fffffff, - .CP0_SRSConf2 = (1U << CP0SRSC2_M) | (0x3fe << CP0SRSC2_SRS9) | - (0x3fe << CP0SRSC2_SRS8) | (0x3fe << CP0SRSC2_SRS7), - .CP0_SRSConf3_rw_bitmask = 0x3fffffff, - .CP0_SRSConf3 = (1U << CP0SRSC3_M) | (0x3fe << CP0SRSC3_SRS12) | - (0x3fe << CP0SRSC3_SRS11) | (0x3fe << CP0SRSC3_SRS10), - .CP0_SRSConf4_rw_bitmask = 0x3fffffff, - .CP0_SRSConf4 = (0x3fe << CP0SRSC4_SRS15) | - (0x3fe << CP0SRSC4_SRS14) | (0x3fe << CP0SRSC4_SRS13), - .SEGBITS = 32, - .PABITS = 32, - .insn_flags = CPU_MIPS32R2 | ASE_MIPS16 | ASE_DSP | ASE_MT, - .mmu_type = MMU_TYPE_R4000, - }, - { - .name = "74Kf", - .CP0_PRid = 0x00019700, - .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) | - (MMU_TYPE_R4000 << CP0C0_MT), - .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (15 << CP0C1_MMU) | - (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) | - (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA) | - (1 << CP0C1_CA), - .CP0_Config2 = MIPS_CONFIG2, - .CP0_Config3 = MIPS_CONFIG3 | (1 << CP0C3_DSP2P) | (1 << CP0C3_DSPP) | - (1 << CP0C3_VInt), - .CP0_LLAddr_rw_bitmask = 0, - .CP0_LLAddr_shift = 4, - .SYNCI_Step = 32, - .CCRes = 2, - .CP0_Status_rw_bitmask = 0x3778FF1F, - .CP1_fcr0 = (1 << FCR0_F64) | (1 << FCR0_L) | (1 << FCR0_W) | - (1 << FCR0_D) | (1 << FCR0_S) | (0x93 << FCR0_PRID), - .CP1_fcr31 = 0, - .CP1_fcr31_rw_bitmask = 0xFF83FFFF, - .SEGBITS = 32, - .PABITS = 32, - .insn_flags = CPU_MIPS32R2 | ASE_MIPS16 | ASE_DSP | ASE_DSP_R2, - .mmu_type = MMU_TYPE_R4000, - }, - { - .name = "M14K", - .CP0_PRid = 0x00019b00, - /* Config1 implemented, fixed mapping MMU, - no virtual icache, uncached coherency. */ - .CP0_Config0 = MIPS_CONFIG0 | (0x2 << CP0C0_KU) | (0x2 << CP0C0_K23) | - (0x1 << CP0C0_AR) | (MMU_TYPE_FMT << CP0C0_MT), - .CP0_Config1 = MIPS_CONFIG1, - .CP0_Config2 = MIPS_CONFIG2, - .CP0_Config3 = MIPS_CONFIG3 | (0x2 << CP0C3_ISA) | (1 << CP0C3_VInt), - .CP0_LLAddr_rw_bitmask = 0, - .CP0_LLAddr_shift = 4, - .SYNCI_Step = 32, - .CCRes = 2, - .CP0_Status_rw_bitmask = 0x1258FF17, - .SEGBITS = 32, - .PABITS = 32, - .insn_flags = CPU_MIPS32R2 | ASE_MICROMIPS, - .mmu_type = MMU_TYPE_FMT, - }, - { - .name = "M14Kc", - /* This is the TLB-based MMU core. */ - .CP0_PRid = 0x00019c00, - .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) | - (MMU_TYPE_R4000 << CP0C0_MT), - .CP0_Config1 = MIPS_CONFIG1 | (15 << CP0C1_MMU) | - (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) | - (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA), - .CP0_Config2 = MIPS_CONFIG2, - .CP0_Config3 = MIPS_CONFIG3 | (0x2 << CP0C3_ISA) | (0 << CP0C3_VInt), - .CP0_LLAddr_rw_bitmask = 0, - .CP0_LLAddr_shift = 4, - .SYNCI_Step = 32, - .CCRes = 2, - .CP0_Status_rw_bitmask = 0x1278FF17, - .SEGBITS = 32, - .PABITS = 32, - .insn_flags = CPU_MIPS32R2 | ASE_MICROMIPS, - .mmu_type = MMU_TYPE_R4000, - }, - { - /* FIXME: - * Config3: VZ, CTXTC, CDMM, TL - * Config4: MMUExtDef - * Config5: MRP - * FIR(FCR0): Has2008 - * */ - .name = "P5600", - .CP0_PRid = 0x0001A800, - .CP0_Config0 = MIPS_CONFIG0 | (1 << CP0C0_MM) | (1 << CP0C0_AR) | - (MMU_TYPE_R4000 << CP0C0_MT), - .CP0_Config1 = MIPS_CONFIG1 | (0x3F << CP0C1_MMU) | - (2 << CP0C1_IS) | (4 << CP0C1_IL) | (3 << CP0C1_IA) | - (2 << CP0C1_DS) | (4 << CP0C1_DL) | (3 << CP0C1_DA) | - (1 << CP0C1_PC) | (1 << CP0C1_FP), - .CP0_Config2 = MIPS_CONFIG2, - .CP0_Config3 = MIPS_CONFIG3 | (1U << CP0C3_M) | - (1 << CP0C3_CMGCR) | (1 << CP0C3_MSAP) | - (1 << CP0C3_BP) | (1 << CP0C3_BI) | (1 << CP0C3_SC) | - (1 << CP0C3_PW) | (1 << CP0C3_ULRI) | (1 << CP0C3_RXI) | - (1 << CP0C3_LPA) | (1 << CP0C3_VInt), - .CP0_Config4 = MIPS_CONFIG4 | (1U << CP0C4_M) | (2 << CP0C4_IE) | - (0x1c << CP0C4_KScrExist), - .CP0_Config4_rw_bitmask = 0, - .CP0_Config5 = MIPS_CONFIG5 | (1 << CP0C5_EVA) | (1 << CP0C5_MVH) | - (1 << CP0C5_LLB) | (1 << CP0C5_MRP), - .CP0_Config5_rw_bitmask = (1 << CP0C5_K) | (1 << CP0C5_CV) | - (1 << CP0C5_MSAEn) | (1 << CP0C5_UFE) | - (1 << CP0C5_FRE) | (1 << CP0C5_UFR), - .CP0_LLAddr_rw_bitmask = 0, - .CP0_LLAddr_shift = 0, - .SYNCI_Step = 32, - .CCRes = 2, - .CP0_Status_rw_bitmask = 0x3C68FF1F, - .CP0_PageGrain_rw_bitmask = (1U << CP0PG_RIE) | (1 << CP0PG_XIE) | - (1 << CP0PG_ELPA) | (1 << CP0PG_IEC), - .CP0_EBaseWG_rw_bitmask = (1 << CP0EBase_WG), - .CP1_fcr0 = (1 << FCR0_FREP) | (1 << FCR0_UFRP) | (1 << FCR0_HAS2008) | - (1 << FCR0_F64) | (1 << FCR0_L) | (1 << FCR0_W) | - (1 << FCR0_D) | (1 << FCR0_S) | (0x03 << FCR0_PRID), - .CP1_fcr31 = (1 << FCR31_ABS2008) | (1 << FCR31_NAN2008), - .CP1_fcr31_rw_bitmask = 0xFF83FFFF, - .SEGBITS = 32, - .PABITS = 40, - .insn_flags = CPU_MIPS32R5 | ASE_MSA, - .mmu_type = MMU_TYPE_R4000, - }, - { - /* A generic CPU supporting MIPS32 Release 6 ISA. - FIXME: Support IEEE 754-2008 FP. - Eventually this should be replaced by a real CPU model. */ - .name = "mips32r6-generic", - .CP0_PRid = 0x00010000, - .CP0_Config0 = MIPS_CONFIG0 | (0x2 << CP0C0_AR) | - (MMU_TYPE_R4000 << CP0C0_MT), - .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (31 << CP0C1_MMU) | - (2 << CP0C1_IS) | (4 << CP0C1_IL) | (3 << CP0C1_IA) | - (2 << CP0C1_DS) | (4 << CP0C1_DL) | (3 << CP0C1_DA) | - (0 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP), - .CP0_Config2 = MIPS_CONFIG2, - .CP0_Config3 = MIPS_CONFIG3 | (1 << CP0C3_BP) | (1 << CP0C3_BI) | - (2 << CP0C3_ISA) | (1 << CP0C3_ULRI) | - (1 << CP0C3_RXI) | (1U << CP0C3_M), - .CP0_Config4 = MIPS_CONFIG4 | (0xfc << CP0C4_KScrExist) | - (3 << CP0C4_IE) | (1U << CP0C4_M), - .CP0_Config5 = MIPS_CONFIG5 | (1 << CP0C5_XNP) | (1 << CP0C5_LLB), - .CP0_Config5_rw_bitmask = (1 << CP0C5_SBRI) | (1 << CP0C5_FRE) | - (1 << CP0C5_UFE), - .CP0_LLAddr_rw_bitmask = 0, - .CP0_LLAddr_shift = 0, - .SYNCI_Step = 32, - .CCRes = 2, - .CP0_Status_rw_bitmask = 0x3058FF1F, - .CP0_PageGrain = (1 << CP0PG_IEC) | (1 << CP0PG_XIE) | - (1U << CP0PG_RIE), - .CP0_PageGrain_rw_bitmask = 0, - .CP1_fcr0 = (1 << FCR0_FREP) | (1 << FCR0_HAS2008) | (1 << FCR0_F64) | - (1 << FCR0_L) | (1 << FCR0_W) | (1 << FCR0_D) | - (1 << FCR0_S) | (0x00 << FCR0_PRID) | (0x0 << FCR0_REV), - .CP1_fcr31 = (1 << FCR31_ABS2008) | (1 << FCR31_NAN2008), - .CP1_fcr31_rw_bitmask = 0x0103FFFF, - .SEGBITS = 32, - .PABITS = 32, - .insn_flags = CPU_MIPS32R6 | ASE_MICROMIPS, - .mmu_type = MMU_TYPE_R4000, - }, - { - .name = "I7200", - .CP0_PRid = 0x00010000, - .CP0_Config0 = MIPS_CONFIG0 | (1 << CP0C0_MM) | (0x2 << CP0C0_AR) | - (MMU_TYPE_R4000 << CP0C0_MT), - .CP0_Config1 = (1U << CP0C1_M) | (15 << CP0C1_MMU) | (2 << CP0C1_IS) | - (4 << CP0C1_IL) | (3 << CP0C1_IA) | (2 << CP0C1_DS) | - (4 << CP0C1_DL) | (3 << CP0C1_DA) | (1 << CP0C1_PC) | - (1 << CP0C1_EP), - .CP0_Config2 = MIPS_CONFIG2, - .CP0_Config3 = MIPS_CONFIG3 | (1U << CP0C3_M) | (1 << CP0C3_CMGCR) | - (1 << CP0C3_BI) | (1 << CP0C3_SC) | (3 << CP0C3_MMAR) | - (1 << CP0C3_ISA_ON_EXC) | (1 << CP0C3_ISA) | - (1 << CP0C3_ULRI) | (1 << CP0C3_RXI) | - (1 << CP0C3_DSP2P) | (1 << CP0C3_DSPP) | - (1 << CP0C3_CTXTC) | (1 << CP0C3_VInt) | - (1 << CP0C3_CDMM) | (1 << CP0C3_MT) | (1 << CP0C3_TL), - .CP0_Config4 = MIPS_CONFIG4 | (0xfc << CP0C4_KScrExist) | - (2 << CP0C4_IE) | (1U << CP0C4_M), - .CP0_Config5 = MIPS_CONFIG5 | (1 << CP0C5_MVH) | (1 << CP0C5_LLB), - .CP0_Config5_rw_bitmask = (1 << CP0C5_SBRI) | (1 << CP0C5_FRE) | - (1 << CP0C5_UFE), - .CP0_LLAddr_rw_bitmask = 0, - .CP0_LLAddr_shift = 0, - .SYNCI_Step = 32, - .CCRes = 2, - .CP0_Status_rw_bitmask = 0x3158FF1F, - .CP0_PageGrain = (1 << CP0PG_IEC) | (1 << CP0PG_XIE) | - (1U << CP0PG_RIE), - .CP0_PageGrain_rw_bitmask = 0, - .CP1_fcr0 = (1 << FCR0_FREP) | (1 << FCR0_HAS2008) | (1 << FCR0_F64) | - (1 << FCR0_L) | (1 << FCR0_W) | (1 << FCR0_D) | - (1 << FCR0_S) | (0x02 << FCR0_PRID) | (0x0 << FCR0_REV), - .CP1_fcr31 = (1 << FCR31_ABS2008) | (1 << FCR31_NAN2008), - .SEGBITS = 32, - .PABITS = 32, - .insn_flags = CPU_NANOMIPS32 | ASE_DSP | ASE_DSP_R2 | ASE_DSP_R3 | - ASE_MT, - .mmu_type = MMU_TYPE_R4000, - }, -#if defined(TARGET_MIPS64) - { - .name = "R4000", - .CP0_PRid = 0x00000400, - /* No L2 cache, icache size 8k, dcache size 8k, uncached coherency. */ - .CP0_Config0 = (2 << CP0C0_Impl) | (1 << CP0C0_IC) | (1 << CP0C0_DC) | - (2 << CP0C0_K0), - /* Note: Config1 is only used internally, the R4000 has only Config0. */ - .CP0_Config1 = (1 << CP0C1_FP) | (47 << CP0C1_MMU), - .CP0_LLAddr_rw_bitmask = 0xFFFFFFFF, - .CP0_LLAddr_shift = 4, - .SYNCI_Step = 16, - .CCRes = 2, - .CP0_Status_rw_bitmask = 0x3678FFFF, - /* The R4000 has a full 64bit FPU but doesn't use the fcr0 bits. */ - .CP1_fcr0 = (0x5 << FCR0_PRID) | (0x0 << FCR0_REV), - .CP1_fcr31 = 0, - .CP1_fcr31_rw_bitmask = 0x0183FFFF, - .SEGBITS = 40, - .PABITS = 36, - .insn_flags = CPU_MIPS3, - .mmu_type = MMU_TYPE_R4000, - }, - { - .name = "VR5432", - .CP0_PRid = 0x00005400, - /* No L2 cache, icache size 8k, dcache size 8k, uncached coherency. */ - .CP0_Config0 = (2 << CP0C0_Impl) | (1 << CP0C0_IC) | (1 << CP0C0_DC) | - (2 << CP0C0_K0), - .CP0_Config1 = (1 << CP0C1_FP) | (47 << CP0C1_MMU), - .CP0_LLAddr_rw_bitmask = 0xFFFFFFFFL, - .CP0_LLAddr_shift = 4, - .SYNCI_Step = 16, - .CCRes = 2, - .CP0_Status_rw_bitmask = 0x3678FFFF, - /* The VR5432 has a full 64bit FPU but doesn't use the fcr0 bits. */ - .CP1_fcr0 = (0x54 << FCR0_PRID) | (0x0 << FCR0_REV), - .CP1_fcr31 = 0, - .CP1_fcr31_rw_bitmask = 0xFF83FFFF, - .SEGBITS = 40, - .PABITS = 32, - .insn_flags = CPU_VR54XX, - .mmu_type = MMU_TYPE_R4000, - }, - { - .name = "5Kc", - .CP0_PRid = 0x00018100, - .CP0_Config0 = MIPS_CONFIG0 | (0x2 << CP0C0_AT) | - (MMU_TYPE_R4000 << CP0C0_MT), - .CP0_Config1 = MIPS_CONFIG1 | (31 << CP0C1_MMU) | - (1 << CP0C1_IS) | (4 << CP0C1_IL) | (1 << CP0C1_IA) | - (1 << CP0C1_DS) | (4 << CP0C1_DL) | (1 << CP0C1_DA) | - (1 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP), - .CP0_Config2 = MIPS_CONFIG2, - .CP0_Config3 = MIPS_CONFIG3, - .CP0_LLAddr_rw_bitmask = 0, - .CP0_LLAddr_shift = 4, - .SYNCI_Step = 32, - .CCRes = 2, - .CP0_Status_rw_bitmask = 0x12F8FFFF, - .SEGBITS = 42, - .PABITS = 36, - .insn_flags = CPU_MIPS64R1, - .mmu_type = MMU_TYPE_R4000, - }, - { - .name = "5Kf", - .CP0_PRid = 0x00018100, - .CP0_Config0 = MIPS_CONFIG0 | (0x2 << CP0C0_AT) | - (MMU_TYPE_R4000 << CP0C0_MT), - .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (31 << CP0C1_MMU) | - (1 << CP0C1_IS) | (4 << CP0C1_IL) | (1 << CP0C1_IA) | - (1 << CP0C1_DS) | (4 << CP0C1_DL) | (1 << CP0C1_DA) | - (1 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP), - .CP0_Config2 = MIPS_CONFIG2, - .CP0_Config3 = MIPS_CONFIG3, - .CP0_LLAddr_rw_bitmask = 0, - .CP0_LLAddr_shift = 4, - .SYNCI_Step = 32, - .CCRes = 2, - .CP0_Status_rw_bitmask = 0x36F8FFFF, - /* The 5Kf has F64 / L / W but doesn't use the fcr0 bits. */ - .CP1_fcr0 = (1 << FCR0_D) | (1 << FCR0_S) | - (0x81 << FCR0_PRID) | (0x0 << FCR0_REV), - .CP1_fcr31 = 0, - .CP1_fcr31_rw_bitmask = 0xFF83FFFF, - .SEGBITS = 42, - .PABITS = 36, - .insn_flags = CPU_MIPS64R1, - .mmu_type = MMU_TYPE_R4000, - }, - { - .name = "20Kc", - /* We emulate a later version of the 20Kc, earlier ones had a broken - WAIT instruction. */ - .CP0_PRid = 0x000182a0, - .CP0_Config0 = MIPS_CONFIG0 | (0x2 << CP0C0_AT) | - (MMU_TYPE_R4000 << CP0C0_MT) | (1 << CP0C0_VI), - .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (47 << CP0C1_MMU) | - (2 << CP0C1_IS) | (4 << CP0C1_IL) | (3 << CP0C1_IA) | - (2 << CP0C1_DS) | (4 << CP0C1_DL) | (3 << CP0C1_DA) | - (1 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP), - .CP0_Config2 = MIPS_CONFIG2, - .CP0_Config3 = MIPS_CONFIG3, - .CP0_LLAddr_rw_bitmask = 0, - .CP0_LLAddr_shift = 0, - .SYNCI_Step = 32, - .CCRes = 1, - .CP0_Status_rw_bitmask = 0x36FBFFFF, - /* The 20Kc has F64 / L / W but doesn't use the fcr0 bits. */ - .CP1_fcr0 = (1 << FCR0_3D) | (1 << FCR0_PS) | - (1 << FCR0_D) | (1 << FCR0_S) | - (0x82 << FCR0_PRID) | (0x0 << FCR0_REV), - .CP1_fcr31 = 0, - .CP1_fcr31_rw_bitmask = 0xFF83FFFF, - .SEGBITS = 40, - .PABITS = 36, - .insn_flags = CPU_MIPS64R1 | ASE_MIPS3D, - .mmu_type = MMU_TYPE_R4000, - }, - { - /* A generic CPU providing MIPS64 Release 2 features. - FIXME: Eventually this should be replaced by a real CPU model. */ - .name = "MIPS64R2-generic", - .CP0_PRid = 0x00010000, - .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) | (0x2 << CP0C0_AT) | - (MMU_TYPE_R4000 << CP0C0_MT), - .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (63 << CP0C1_MMU) | - (2 << CP0C1_IS) | (4 << CP0C1_IL) | (3 << CP0C1_IA) | - (2 << CP0C1_DS) | (4 << CP0C1_DL) | (3 << CP0C1_DA) | - (1 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP), - .CP0_Config2 = MIPS_CONFIG2, - .CP0_Config3 = MIPS_CONFIG3 | (1 << CP0C3_LPA), - .CP0_LLAddr_rw_bitmask = 0, - .CP0_LLAddr_shift = 0, - .SYNCI_Step = 32, - .CCRes = 2, - .CP0_Status_rw_bitmask = 0x36FBFFFF, - .CP0_EBaseWG_rw_bitmask = (1 << CP0EBase_WG), - .CP1_fcr0 = (1 << FCR0_F64) | (1 << FCR0_3D) | (1 << FCR0_PS) | - (1 << FCR0_L) | (1 << FCR0_W) | (1 << FCR0_D) | - (1 << FCR0_S) | (0x00 << FCR0_PRID) | (0x0 << FCR0_REV), - .CP1_fcr31 = 0, - .CP1_fcr31_rw_bitmask = 0xFF83FFFF, - .SEGBITS = 42, - .PABITS = 36, - .insn_flags = CPU_MIPS64R2 | ASE_MIPS3D, - .mmu_type = MMU_TYPE_R4000, - }, - { - .name = "5KEc", - .CP0_PRid = 0x00018900, - .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) | (0x2 << CP0C0_AT) | - (MMU_TYPE_R4000 << CP0C0_MT), - .CP0_Config1 = MIPS_CONFIG1 | (31 << CP0C1_MMU) | - (1 << CP0C1_IS) | (4 << CP0C1_IL) | (1 << CP0C1_IA) | - (1 << CP0C1_DS) | (4 << CP0C1_DL) | (1 << CP0C1_DA) | - (1 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP), - .CP0_Config2 = MIPS_CONFIG2, - .CP0_Config3 = MIPS_CONFIG3, - .CP0_LLAddr_rw_bitmask = 0, - .CP0_LLAddr_shift = 4, - .SYNCI_Step = 32, - .CCRes = 2, - .CP0_Status_rw_bitmask = 0x12F8FFFF, - .SEGBITS = 42, - .PABITS = 36, - .insn_flags = CPU_MIPS64R2, - .mmu_type = MMU_TYPE_R4000, - }, - { - .name = "5KEf", - .CP0_PRid = 0x00018900, - .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) | (0x2 << CP0C0_AT) | - (MMU_TYPE_R4000 << CP0C0_MT), - .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (31 << CP0C1_MMU) | - (1 << CP0C1_IS) | (4 << CP0C1_IL) | (1 << CP0C1_IA) | - (1 << CP0C1_DS) | (4 << CP0C1_DL) | (1 << CP0C1_DA) | - (1 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP), - .CP0_Config2 = MIPS_CONFIG2, - .CP0_Config3 = MIPS_CONFIG3, - .CP0_LLAddr_rw_bitmask = 0, - .CP0_LLAddr_shift = 4, - .SYNCI_Step = 32, - .CCRes = 2, - .CP0_Status_rw_bitmask = 0x36F8FFFF, - .CP1_fcr0 = (1 << FCR0_F64) | (1 << FCR0_L) | (1 << FCR0_W) | - (1 << FCR0_D) | (1 << FCR0_S) | - (0x89 << FCR0_PRID) | (0x0 << FCR0_REV), - .SEGBITS = 42, - .PABITS = 36, - .insn_flags = CPU_MIPS64R2, - .mmu_type = MMU_TYPE_R4000, - }, - { - .name = "I6400", - .CP0_PRid = 0x1A900, - .CP0_Config0 = MIPS_CONFIG0 | (0x2 << CP0C0_AR) | (0x2 << CP0C0_AT) | - (MMU_TYPE_R4000 << CP0C0_MT), - .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (15 << CP0C1_MMU) | - (2 << CP0C1_IS) | (5 << CP0C1_IL) | (3 << CP0C1_IA) | - (2 << CP0C1_DS) | (5 << CP0C1_DL) | (3 << CP0C1_DA) | - (0 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP), - .CP0_Config2 = MIPS_CONFIG2, - .CP0_Config3 = MIPS_CONFIG3 | (1U << CP0C3_M) | - (1 << CP0C3_CMGCR) | (1 << CP0C3_MSAP) | - (1 << CP0C3_BP) | (1 << CP0C3_BI) | (1 << CP0C3_ULRI) | - (1 << CP0C3_RXI) | (1 << CP0C3_LPA) | (1 << CP0C3_VInt), - .CP0_Config4 = MIPS_CONFIG4 | (1U << CP0C4_M) | (3 << CP0C4_IE) | - (1 << CP0C4_AE) | (0xfc << CP0C4_KScrExist), - .CP0_Config5 = MIPS_CONFIG5 | (1 << CP0C5_XNP) | (1 << CP0C5_VP) | - (1 << CP0C5_LLB) | (1 << CP0C5_MRP), - .CP0_Config5_rw_bitmask = (1 << CP0C5_MSAEn) | (1 << CP0C5_SBRI) | - (1 << CP0C5_FRE) | (1 << CP0C5_UFE), - .CP0_LLAddr_rw_bitmask = 0, - .CP0_LLAddr_shift = 0, - .SYNCI_Step = 32, - .CCRes = 2, - .CP0_Status_rw_bitmask = 0x30D8FFFF, - .CP0_PageGrain = (1 << CP0PG_IEC) | (1 << CP0PG_XIE) | - (1U << CP0PG_RIE), - .CP0_PageGrain_rw_bitmask = (1 << CP0PG_ELPA), - .CP0_EBaseWG_rw_bitmask = (1 << CP0EBase_WG), - .CP1_fcr0 = (1 << FCR0_FREP) | (1 << FCR0_HAS2008) | (1 << FCR0_F64) | - (1 << FCR0_L) | (1 << FCR0_W) | (1 << FCR0_D) | - (1 << FCR0_S) | (0x03 << FCR0_PRID) | (0x0 << FCR0_REV), - .CP1_fcr31 = (1 << FCR31_ABS2008) | (1 << FCR31_NAN2008), - .CP1_fcr31_rw_bitmask = 0x0103FFFF, - .MSAIR = 0x03 << MSAIR_ProcID, - .SEGBITS = 48, - .PABITS = 48, - .insn_flags = CPU_MIPS64R6 | ASE_MSA, - .mmu_type = MMU_TYPE_R4000, - }, - { - .name = "I6500", - .CP0_PRid = 0x1B000, - .CP0_Config0 = MIPS_CONFIG0 | (0x2 << CP0C0_AR) | (0x2 << CP0C0_AT) | - (MMU_TYPE_R4000 << CP0C0_MT), - .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (15 << CP0C1_MMU) | - (2 << CP0C1_IS) | (5 << CP0C1_IL) | (3 << CP0C1_IA) | - (2 << CP0C1_DS) | (5 << CP0C1_DL) | (3 << CP0C1_DA) | - (0 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP), - .CP0_Config2 = MIPS_CONFIG2, - .CP0_Config3 = MIPS_CONFIG3 | (1U << CP0C3_M) | - (1 << CP0C3_CMGCR) | (1 << CP0C3_MSAP) | - (1 << CP0C3_BP) | (1 << CP0C3_BI) | (1 << CP0C3_ULRI) | - (1 << CP0C3_RXI) | (1 << CP0C3_LPA) | (1 << CP0C3_VInt), - .CP0_Config4 = MIPS_CONFIG4 | (1U << CP0C4_M) | (3 << CP0C4_IE) | - (1 << CP0C4_AE) | (0xfc << CP0C4_KScrExist), - .CP0_Config5 = MIPS_CONFIG5 | (1 << CP0C5_XNP) | (1 << CP0C5_VP) | - (1 << CP0C5_LLB) | (1 << CP0C5_MRP), - .CP0_Config5_rw_bitmask = (1 << CP0C5_MSAEn) | (1 << CP0C5_SBRI) | - (1 << CP0C5_FRE) | (1 << CP0C5_UFE), - .CP0_LLAddr_rw_bitmask = 0, - .CP0_LLAddr_shift = 0, - .SYNCI_Step = 64, - .CCRes = 2, - .CP0_Status_rw_bitmask = 0x30D8FFFF, - .CP0_PageGrain = (1 << CP0PG_IEC) | (1 << CP0PG_XIE) | - (1U << CP0PG_RIE), - .CP0_PageGrain_rw_bitmask = (1 << CP0PG_ELPA), - .CP0_EBaseWG_rw_bitmask = (1 << CP0EBase_WG), - .CP1_fcr0 = (1 << FCR0_FREP) | (1 << FCR0_HAS2008) | (1 << FCR0_F64) | - (1 << FCR0_L) | (1 << FCR0_W) | (1 << FCR0_D) | - (1 << FCR0_S) | (0x03 << FCR0_PRID) | (0x0 << FCR0_REV), - .CP1_fcr31 = (1 << FCR31_ABS2008) | (1 << FCR31_NAN2008), - .CP1_fcr31_rw_bitmask = 0x0103FFFF, - .MSAIR = 0x03 << MSAIR_ProcID, - .SEGBITS = 48, - .PABITS = 48, - .insn_flags = CPU_MIPS64R6 | ASE_MSA, - .mmu_type = MMU_TYPE_R4000, - }, - { - .name = "Loongson-2E", - .CP0_PRid = 0x6302, - /* 64KB I-cache and d-cache. 4 way with 32 bit cache line size. */ - .CP0_Config0 = (3 << CP0C0_Impl) | (4 << CP0C0_IC) | (4 << CP0C0_DC) | - (1 << CP0C0_IB) | (1 << CP0C0_DB) | (0x2 << CP0C0_K0), - /* Note: Config1 is only used internally, - Loongson-2E has only Config0. */ - .CP0_Config1 = (1 << CP0C1_FP) | (47 << CP0C1_MMU), - .SYNCI_Step = 16, - .CCRes = 2, - .CP0_Status_rw_bitmask = 0x35D0FFFF, - .CP1_fcr0 = (0x5 << FCR0_PRID) | (0x1 << FCR0_REV), - .CP1_fcr31 = 0, - .CP1_fcr31_rw_bitmask = 0xFF83FFFF, - .SEGBITS = 40, - .PABITS = 40, - .insn_flags = CPU_LOONGSON2E, - .mmu_type = MMU_TYPE_R4000, - }, - { - .name = "Loongson-2F", - .CP0_PRid = 0x6303, - /* 64KB I-cache and d-cache. 4 way with 32 bit cache line size. */ - .CP0_Config0 = (3 << CP0C0_Impl) | (4 << CP0C0_IC) | (4 << CP0C0_DC) | - (1 << CP0C0_IB) | (1 << CP0C0_DB) | (0x2 << CP0C0_K0), - /* Note: Config1 is only used internally, - Loongson-2F has only Config0. */ - .CP0_Config1 = (1 << CP0C1_FP) | (47 << CP0C1_MMU), - .SYNCI_Step = 16, - .CCRes = 2, - .CP0_Status_rw_bitmask = 0xF5D0FF1F, /* Bits 7:5 not writable. */ - .CP1_fcr0 = (0x5 << FCR0_PRID) | (0x1 << FCR0_REV), - .CP1_fcr31 = 0, - .CP1_fcr31_rw_bitmask = 0xFF83FFFF, - .SEGBITS = 40, - .PABITS = 40, - .insn_flags = CPU_LOONGSON2F, - .mmu_type = MMU_TYPE_R4000, - }, - { - .name = "Loongson-3A1000", - .CP0_PRid = 0x6305, - /* 64KB I-cache and d-cache. 4 way with 32 bit cache line size. */ - .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) | (0x2 << CP0C0_AT) | - (MMU_TYPE_R4000 << CP0C0_MT), - .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (63 << CP0C1_MMU) | - (3 << CP0C1_IS) | (4 << CP0C1_IL) | (3 << CP0C1_IA) | - (3 << CP0C1_DS) | (4 << CP0C1_DL) | (3 << CP0C1_DA) | - (1 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP), - .CP0_Config2 = MIPS_CONFIG2 | (7 << CP0C2_SS) | (4 << CP0C2_SL) | - (3 << CP0C2_SA), - .CP0_Config3 = MIPS_CONFIG3 | (1 << CP0C3_LPA), - .CP0_LLAddr_rw_bitmask = 0, - .SYNCI_Step = 32, - .CCRes = 2, - .CP0_Status_rw_bitmask = 0x74D8FFFF, - .CP0_PageGrain = (1 << CP0PG_ELPA), - .CP0_PageGrain_rw_bitmask = (1 << CP0PG_ELPA), - .CP1_fcr0 = (0x5 << FCR0_PRID) | (0x1 << FCR0_REV) | (0x1 << FCR0_F64) | - (0x1 << FCR0_PS) | (0x1 << FCR0_L) | (0x1 << FCR0_W) | - (0x1 << FCR0_D) | (0x1 << FCR0_S), - .CP1_fcr31 = 0, - .CP1_fcr31_rw_bitmask = 0xFF83FFFF, - .SEGBITS = 42, - .PABITS = 48, - .insn_flags = CPU_LOONGSON3A, - .mmu_type = MMU_TYPE_R4000, - }, - { - .name = "Loongson-3A4000", /* GS464V-based */ - .CP0_PRid = 0x14C000, - /* 64KB I-cache and d-cache. 4 way with 32 bit cache line size. */ - .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) | (0x2 << CP0C0_AT) | - (MMU_TYPE_R4000 << CP0C0_MT), - .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (63 << CP0C1_MMU) | - (2 << CP0C1_IS) | (5 << CP0C1_IL) | (3 << CP0C1_IA) | - (2 << CP0C1_DS) | (5 << CP0C1_DL) | (3 << CP0C1_DA) | - (1 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP), - .CP0_Config2 = MIPS_CONFIG2 | (5 << CP0C2_SS) | (5 << CP0C2_SL) | - (15 << CP0C2_SA), - .CP0_Config3 = MIPS_CONFIG3 | (1U << CP0C3_M) | (1 << CP0C3_MSAP) | - (1 << CP0C3_BP) | (1 << CP0C3_BI) | (1 << CP0C3_ULRI) | - (1 << CP0C3_RXI) | (1 << CP0C3_LPA) | (1 << CP0C3_VInt), - .CP0_Config4 = MIPS_CONFIG4 | (1U << CP0C4_M) | (2 << CP0C4_IE) | - (1 << CP0C4_AE) | (0x1c << CP0C4_KScrExist), - .CP0_Config4_rw_bitmask = 0, - .CP0_Config5 = MIPS_CONFIG5 | (1 << CP0C5_CRCP) | (1 << CP0C5_NFExists), - .CP0_Config5_rw_bitmask = (1 << CP0C5_K) | (1 << CP0C5_CV) | - (1 << CP0C5_MSAEn) | (1 << CP0C5_UFE) | - (1 << CP0C5_FRE) | (1 << CP0C5_SBRI), - .CP0_Config6 = (1 << CP0C6_VCLRU) | (1 << CP0C6_DCLRU) | - (1 << CP0C6_SFBEN) | (1 << CP0C6_VLTINT) | - (1 << CP0C6_INSTPREF) | (1 << CP0C6_DATAPREF), - .CP0_Config6_rw_bitmask = (1 << CP0C6_BPPASS) | (0x3f << CP0C6_KPOS) | - (1 << CP0C6_KE) | (1 << CP0C6_VTLBONLY) | - (1 << CP0C6_LASX) | (1 << CP0C6_SSEN) | - (1 << CP0C6_DISDRTIME) | (1 << CP0C6_PIXNUEN) | - (1 << CP0C6_SCRAND) | (1 << CP0C6_LLEXCEN) | - (1 << CP0C6_DISVC) | (1 << CP0C6_VCLRU) | - (1 << CP0C6_DCLRU) | (1 << CP0C6_PIXUEN) | - (1 << CP0C6_DISBLKLYEN) | (1 << CP0C6_UMEMUALEN) | - (1 << CP0C6_SFBEN) | (1 << CP0C6_FLTINT) | - (1 << CP0C6_VLTINT) | (1 << CP0C6_DISBTB) | - (3 << CP0C6_STPREFCTL) | (1 << CP0C6_INSTPREF) | - (1 << CP0C6_DATAPREF), - .CP0_Config7 = 0, - .CP0_Config7_rw_bitmask = (1 << CP0C7_NAPCGEN) | (1 << CP0C7_UNIMUEN) | - (1 << CP0C7_VFPUCGEN), - .CP0_LLAddr_rw_bitmask = 1, - .SYNCI_Step = 16, - .CCRes = 2, - .CP0_Status_rw_bitmask = 0x7DDBFFFF, - .CP0_PageGrain = (1 << CP0PG_ELPA), - .CP0_PageGrain_rw_bitmask = (1U << CP0PG_RIE) | (1 << CP0PG_XIE) | - (1 << CP0PG_ELPA) | (1 << CP0PG_IEC), - .CP1_fcr0 = (0x5 << FCR0_PRID) | (0x1 << FCR0_REV) | (0x1 << FCR0_F64) | - (0x1 << FCR0_PS) | (0x1 << FCR0_L) | (0x1 << FCR0_W) | - (0x1 << FCR0_D) | (0x1 << FCR0_S), - .CP1_fcr31 = 0, - .CP1_fcr31_rw_bitmask = 0xFF83FFFF, - .SEGBITS = 48, - .PABITS = 48, - .insn_flags = CPU_LOONGSON3A | ASE_MSA, - .mmu_type = MMU_TYPE_R4000, - }, - { - /* A generic CPU providing MIPS64 DSP R2 ASE features. - FIXME: Eventually this should be replaced by a real CPU model. */ - .name = "mips64dspr2", - .CP0_PRid = 0x00010000, - .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) | (0x2 << CP0C0_AT) | - (MMU_TYPE_R4000 << CP0C0_MT), - .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (63 << CP0C1_MMU) | - (2 << CP0C1_IS) | (4 << CP0C1_IL) | (3 << CP0C1_IA) | - (2 << CP0C1_DS) | (4 << CP0C1_DL) | (3 << CP0C1_DA) | - (1 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP), - .CP0_Config2 = MIPS_CONFIG2, - .CP0_Config3 = MIPS_CONFIG3 | (1U << CP0C3_M) | (1 << CP0C3_DSP2P) | - (1 << CP0C3_DSPP) | (1 << CP0C3_LPA), - .CP0_LLAddr_rw_bitmask = 0, - .CP0_LLAddr_shift = 0, - .SYNCI_Step = 32, - .CCRes = 2, - .CP0_Status_rw_bitmask = 0x37FBFFFF, - .CP1_fcr0 = (1 << FCR0_F64) | (1 << FCR0_3D) | (1 << FCR0_PS) | - (1 << FCR0_L) | (1 << FCR0_W) | (1 << FCR0_D) | - (1 << FCR0_S) | (0x00 << FCR0_PRID) | (0x0 << FCR0_REV), - .CP1_fcr31 = 0, - .CP1_fcr31_rw_bitmask = 0xFF83FFFF, - .SEGBITS = 42, - .PABITS = 36, - .insn_flags = CPU_MIPS64R2 | ASE_DSP | ASE_DSP_R2, - .mmu_type = MMU_TYPE_R4000, - }, - -#endif -}; -const int mips_defs_number = ARRAY_SIZE(mips_defs); - -void mips_cpu_list(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(mips_defs); i++) { - qemu_printf("MIPS '%s'\n", mips_defs[i].name); - } -} - -static void fpu_init (CPUMIPSState *env, const mips_def_t *def) -{ - int i; - - for (i = 0; i < MIPS_FPU_MAX; i++) - env->fpus[i].fcr0 = def->CP1_fcr0; - - memcpy(&env->active_fpu, &env->fpus[0], sizeof(env->active_fpu)); -} - -static void mvp_init(CPUMIPSState *env) -{ - env->mvp = g_malloc0(sizeof(CPUMIPSMVPContext)); - - if (!ase_mt_available(env)) { - return; - } - - /* MVPConf1 implemented, TLB sharable, no gating storage support, - programmable cache partitioning implemented, number of allocatable - and shareable TLB entries, MVP has allocatable TCs, 2 VPEs - implemented, 5 TCs implemented. */ - env->mvp->CP0_MVPConf0 = (1U << CP0MVPC0_M) | (1 << CP0MVPC0_TLBS) | - (0 << CP0MVPC0_GS) | (1 << CP0MVPC0_PCP) | -// TODO: actually do 2 VPEs. -// (1 << CP0MVPC0_TCA) | (0x1 << CP0MVPC0_PVPE) | -// (0x04 << CP0MVPC0_PTC); - (1 << CP0MVPC0_TCA) | (0x0 << CP0MVPC0_PVPE) | - (0x00 << CP0MVPC0_PTC); -#if !defined(CONFIG_USER_ONLY) - /* Usermode has no TLB support */ - env->mvp->CP0_MVPConf0 |= (env->tlb->nb_tlb << CP0MVPC0_PTLBE); -#endif - - /* Allocatable CP1 have media extensions, allocatable CP1 have FP support, - no UDI implemented, no CP2 implemented, 1 CP1 implemented. */ - env->mvp->CP0_MVPConf1 = (1U << CP0MVPC1_CIM) | (1 << CP0MVPC1_CIF) | - (0x0 << CP0MVPC1_PCX) | (0x0 << CP0MVPC1_PCP2) | - (0x1 << CP0MVPC1_PCP1); -} - -static void msa_reset(CPUMIPSState *env) -{ -#ifdef CONFIG_USER_ONLY - /* MSA access enabled */ - env->CP0_Config5 |= 1 << CP0C5_MSAEn; - env->CP0_Status |= (1 << CP0St_CU1) | (1 << CP0St_FR); -#endif - - /* MSA CSR: - - non-signaling floating point exception mode off (NX bit is 0) - - Cause, Enables, and Flags are all 0 - - round to nearest / ties to even (RM bits are 0) */ - env->active_tc.msacsr = 0; - - restore_msa_fp_status(env); - - /* tininess detected after rounding.*/ - set_float_detect_tininess(float_tininess_after_rounding, - &env->active_tc.msa_fp_status); - - /* clear float_status exception flags */ - set_float_exception_flags(0, &env->active_tc.msa_fp_status); - - /* clear float_status nan mode */ - set_default_nan_mode(0, &env->active_tc.msa_fp_status); - - /* set proper signanling bit meaning ("1" means "quiet") */ - set_snan_bit_is_one(0, &env->active_tc.msa_fp_status); -} -- cgit v1.2.3-55-g7522 From e31309365e50a44ebaa6490445d877d8c4acb4f0 Mon Sep 17 00:00:00 2001 From: Philippe Mathieu-Daudé Date: Fri, 13 Nov 2020 19:27:28 +0100 Subject: target/mips/translate: Extract DisasContext structure Extract DisasContext to a new 'translate.h' header so different translation files (ISA, ASE, extensions) can use it. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20201207235539.4070364-2-f4bug@amsat.org> --- target/mips/translate.c | 38 +------------------------------------ target/mips/translate.h | 50 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 37 deletions(-) create mode 100644 target/mips/translate.h diff --git a/target/mips/translate.c b/target/mips/translate.c index f8f0f95509..9e824e12d4 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -36,6 +36,7 @@ #include "exec/log.h" #include "qemu/qemu-print.h" #include "fpu_helper.h" +#include "translate.h" #define MIPS_DEBUG_DISAS 0 @@ -2554,43 +2555,6 @@ static TCGv mxu_CR; tcg_temp_free_i32(helper_tmp); \ } while (0) -typedef struct DisasContext { - DisasContextBase base; - target_ulong saved_pc; - target_ulong page_start; - uint32_t opcode; - uint64_t insn_flags; - int32_t CP0_Config1; - int32_t CP0_Config2; - int32_t CP0_Config3; - int32_t CP0_Config5; - /* Routine used to access memory */ - int mem_idx; - MemOp default_tcg_memop_mask; - uint32_t hflags, saved_hflags; - target_ulong btarget; - bool ulri; - int kscrexist; - bool rxi; - int ie; - bool bi; - bool bp; - uint64_t PAMask; - bool mvh; - bool eva; - bool sc; - int CP0_LLAddr_shift; - bool ps; - bool vp; - bool cmgcr; - bool mrp; - bool nan2008; - bool abs2008; - bool saar; - bool mi; - int gi; -} DisasContext; - #define DISAS_STOP DISAS_TARGET_0 #define DISAS_EXIT DISAS_TARGET_1 diff --git a/target/mips/translate.h b/target/mips/translate.h new file mode 100644 index 0000000000..fcda1a9900 --- /dev/null +++ b/target/mips/translate.h @@ -0,0 +1,50 @@ +/* + * MIPS translation routines. + * + * Copyright (c) 2004-2005 Jocelyn Mayer + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ +#ifndef TARGET_MIPS_TRANSLATE_H +#define TARGET_MIPS_TRANSLATE_H + +#include "exec/translator.h" + +typedef struct DisasContext { + DisasContextBase base; + target_ulong saved_pc; + target_ulong page_start; + uint32_t opcode; + uint64_t insn_flags; + int32_t CP0_Config1; + int32_t CP0_Config2; + int32_t CP0_Config3; + int32_t CP0_Config5; + /* Routine used to access memory */ + int mem_idx; + MemOp default_tcg_memop_mask; + uint32_t hflags, saved_hflags; + target_ulong btarget; + bool ulri; + int kscrexist; + bool rxi; + int ie; + bool bi; + bool bp; + uint64_t PAMask; + bool mvh; + bool eva; + bool sc; + int CP0_LLAddr_shift; + bool ps; + bool vp; + bool cmgcr; + bool mrp; + bool nan2008; + bool abs2008; + bool saar; + bool mi; + int gi; +} DisasContext; + +#endif -- cgit v1.2.3-55-g7522 From 46c9e2b3dddc63bc85e07e3ad33fceb9d300be67 Mon Sep 17 00:00:00 2001 From: Philippe Mathieu-Daudé Date: Sun, 29 Nov 2020 19:13:28 +0100 Subject: target/mips/translate: Add declarations for generic code Some CPU translation functions / registers / macros and definitions can be used by ISA / ASE / extensions out of the big translate.c file. Declare them in "translate.h". Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20201207235539.4070364-3-f4bug@amsat.org> --- target/mips/translate.c | 52 +++++++++++++------------------------------------ target/mips/translate.h | 43 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 38 deletions(-) diff --git a/target/mips/translate.c b/target/mips/translate.c index 9e824e12d4..72cbf604ac 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -38,11 +38,6 @@ #include "fpu_helper.h" #include "translate.h" -#define MIPS_DEBUG_DISAS 0 - -/* MIPS major opcodes */ -#define MASK_OP_MAJOR(op) (op & (0x3F << 26)) - enum { /* indirect opcode tables */ OPC_SPECIAL = (0x00 << 26), @@ -2491,9 +2486,10 @@ enum { }; /* global register indices */ -static TCGv cpu_gpr[32], cpu_PC; +TCGv cpu_gpr[32], cpu_PC; static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC]; -static TCGv cpu_dspctrl, btarget, bcond; +static TCGv cpu_dspctrl, btarget; +TCGv bcond; static TCGv cpu_lladdr, cpu_llval; static TCGv_i32 hflags; static TCGv_i32 fpu_fcr0, fpu_fcr31; @@ -2606,26 +2602,8 @@ static const char * const mxuregnames[] = { }; #endif -#define LOG_DISAS(...) \ - do { \ - if (MIPS_DEBUG_DISAS) { \ - qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \ - } \ - } while (0) - -#define MIPS_INVAL(op) \ - do { \ - if (MIPS_DEBUG_DISAS) { \ - qemu_log_mask(CPU_LOG_TB_IN_ASM, \ - TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \ - ctx->base.pc_next, ctx->opcode, op, \ - ctx->opcode >> 26, ctx->opcode & 0x3F, \ - ((ctx->opcode >> 16) & 0x1F)); \ - } \ - } while (0) - /* General purpose registers moves. */ -static inline void gen_load_gpr(TCGv t, int reg) +void gen_load_gpr(TCGv t, int reg) { if (reg == 0) { tcg_gen_movi_tl(t, 0); @@ -2634,7 +2612,7 @@ static inline void gen_load_gpr(TCGv t, int reg) } } -static inline void gen_store_gpr(TCGv t, int reg) +void gen_store_gpr(TCGv t, int reg) { if (reg != 0) { tcg_gen_mov_tl(cpu_gpr[reg], t); @@ -2763,7 +2741,7 @@ static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx) } } -static inline void generate_exception_err(DisasContext *ctx, int excp, int err) +void generate_exception_err(DisasContext *ctx, int excp, int err) { TCGv_i32 texcp = tcg_const_i32(excp); TCGv_i32 terr = tcg_const_i32(err); @@ -2774,12 +2752,12 @@ static inline void generate_exception_err(DisasContext *ctx, int excp, int err) ctx->base.is_jmp = DISAS_NORETURN; } -static inline void generate_exception(DisasContext *ctx, int excp) +void generate_exception(DisasContext *ctx, int excp) { gen_helper_0e0i(raise_exception, excp); } -static inline void generate_exception_end(DisasContext *ctx, int excp) +void generate_exception_end(DisasContext *ctx, int excp) { generate_exception_err(ctx, excp, 0); } @@ -2859,8 +2837,7 @@ static inline int get_fp_bit(int cc) } /* Addresses computation */ -static inline void gen_op_addr_add(DisasContext *ctx, TCGv ret, TCGv arg0, - TCGv arg1) +void gen_op_addr_add(DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1) { tcg_gen_add_tl(ret, arg0, arg1); @@ -2898,7 +2875,7 @@ static target_long addr_add(DisasContext *ctx, target_long base, } /* Sign-extract the low 32-bits to a target_long. */ -static inline void gen_move_low32(TCGv ret, TCGv_i64 arg) +void gen_move_low32(TCGv ret, TCGv_i64 arg) { #if defined(TARGET_MIPS64) tcg_gen_ext32s_i64(ret, arg); @@ -2908,7 +2885,7 @@ static inline void gen_move_low32(TCGv ret, TCGv_i64 arg) } /* Sign-extract the high 32-bits to a target_long. */ -static inline void gen_move_high32(TCGv ret, TCGv_i64 arg) +void gen_move_high32(TCGv ret, TCGv_i64 arg) { #if defined(TARGET_MIPS64) tcg_gen_sari_i64(ret, arg, 32); @@ -3013,7 +2990,7 @@ static inline void check_dsp_r3(DisasContext *ctx) * This code generates a "reserved instruction" exception if the * CPU does not support the instruction set corresponding to flags. */ -static inline void check_insn(DisasContext *ctx, uint64_t flags) +void check_insn(DisasContext *ctx, uint64_t flags) { if (unlikely(!(ctx->insn_flags & flags))) { generate_exception_end(ctx, EXCP_RI); @@ -3064,7 +3041,7 @@ static inline void check_ps(DisasContext *ctx) * This code generates a "reserved instruction" exception if 64-bit * instructions are not enabled. */ -static inline void check_mips_64(DisasContext *ctx) +void check_mips_64(DisasContext *ctx) { if (unlikely(!(ctx->hflags & MIPS_HFLAG_64))) { generate_exception_end(ctx, EXCP_RI); @@ -3390,8 +3367,7 @@ OP_LD_ATOMIC(lld, ld64); #endif #undef OP_LD_ATOMIC -static void gen_base_offset_addr(DisasContext *ctx, TCGv addr, - int base, int offset) +void gen_base_offset_addr(DisasContext *ctx, TCGv addr, int base, int offset) { if (base == 0) { tcg_gen_movi_tl(addr, offset); diff --git a/target/mips/translate.h b/target/mips/translate.h index fcda1a9900..3d640912f1 100644 --- a/target/mips/translate.h +++ b/target/mips/translate.h @@ -10,6 +10,8 @@ #include "exec/translator.h" +#define MIPS_DEBUG_DISAS 0 + typedef struct DisasContext { DisasContextBase base; target_ulong saved_pc; @@ -47,4 +49,45 @@ typedef struct DisasContext { int gi; } DisasContext; +/* MIPS major opcodes */ +#define MASK_OP_MAJOR(op) (op & (0x3F << 26)) + +void generate_exception(DisasContext *ctx, int excp); +void generate_exception_err(DisasContext *ctx, int excp, int err); +void generate_exception_end(DisasContext *ctx, int excp); + +void check_insn(DisasContext *ctx, uint64_t flags); +#ifdef TARGET_MIPS64 +void check_mips_64(DisasContext *ctx); +#endif + +void gen_base_offset_addr(DisasContext *ctx, TCGv addr, int base, int offset); +void gen_move_low32(TCGv ret, TCGv_i64 arg); +void gen_move_high32(TCGv ret, TCGv_i64 arg); +void gen_load_gpr(TCGv t, int reg); +void gen_store_gpr(TCGv t, int reg); + +void gen_op_addr_add(DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1); + +extern TCGv cpu_gpr[32], cpu_PC; +extern TCGv bcond; + +#define LOG_DISAS(...) \ + do { \ + if (MIPS_DEBUG_DISAS) { \ + qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \ + } \ + } while (0) + +#define MIPS_INVAL(op) \ + do { \ + if (MIPS_DEBUG_DISAS) { \ + qemu_log_mask(CPU_LOG_TB_IN_ASM, \ + TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \ + ctx->base.pc_next, ctx->opcode, op, \ + ctx->opcode >> 26, ctx->opcode & 0x3F, \ + ((ctx->opcode >> 16) & 0x1F)); \ + } \ + } while (0) + #endif -- cgit v1.2.3-55-g7522 From 11a7511856a059796812f7c25ceca6b35cae4b3e Mon Sep 17 00:00:00 2001 From: Philippe Mathieu-Daudé Date: Mon, 14 Dec 2020 19:08:45 +0100 Subject: target/mips: Replace gen_exception_err(err=0) by gen_exception_end() generate_exception_err(err=0) is simply generate_exception_end(). Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20201214183739.500368-11-f4bug@amsat.org> --- target/mips/translate.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/target/mips/translate.c b/target/mips/translate.c index 72cbf604ac..fa11c8ffe0 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -2897,7 +2897,7 @@ void gen_move_high32(TCGv ret, TCGv_i64 arg) static inline void check_cp0_enabled(DisasContext *ctx) { if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) { - generate_exception_err(ctx, EXCP_CpU, 0); + generate_exception_end(ctx, EXCP_CpU); } } @@ -3103,10 +3103,10 @@ static inline void check_mt(DisasContext *ctx) static inline void check_cp0_mt(DisasContext *ctx) { if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) { - generate_exception_err(ctx, EXCP_CpU, 0); + generate_exception_end(ctx, EXCP_CpU); } else { if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) { - generate_exception_err(ctx, EXCP_RI, 0); + generate_exception_end(ctx, EXCP_RI); } } } -- cgit v1.2.3-55-g7522 From 3a4ef3b7ee35613f5318f27321c8255606e4623f Mon Sep 17 00:00:00 2001 From: Philippe Mathieu-Daudé Date: Thu, 10 Dec 2020 20:44:23 +0100 Subject: target/mips: Replace gen_exception_end(EXCP_RI) by gen_rsvd_instruction gen_reserved_instruction() is easier to read than generate_exception_end(ctx, EXCP_RI), replace it. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20201214183739.500368-12-f4bug@amsat.org> --- target/mips/translate.c | 729 ++++++++++++++++++++++++------------------------ target/mips/translate.h | 1 + 2 files changed, 368 insertions(+), 362 deletions(-) diff --git a/target/mips/translate.c b/target/mips/translate.c index fa11c8ffe0..d776721505 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -2762,6 +2762,11 @@ void generate_exception_end(DisasContext *ctx, int excp) generate_exception_err(ctx, excp, 0); } +void gen_reserved_instruction(DisasContext *ctx) +{ + generate_exception_end(ctx, EXCP_RI); +} + /* Floating point register moves. */ static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg) { @@ -2916,7 +2921,7 @@ static inline void check_cp1_enabled(DisasContext *ctx) static inline void check_cop1x(DisasContext *ctx) { if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X))) { - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); } } @@ -2927,7 +2932,7 @@ static inline void check_cop1x(DisasContext *ctx) static inline void check_cp1_64bitmode(DisasContext *ctx) { if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X))) { - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); } } @@ -2945,7 +2950,7 @@ static inline void check_cp1_64bitmode(DisasContext *ctx) static inline void check_cp1_registers(DisasContext *ctx, int regs) { if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1))) { - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); } } @@ -2959,7 +2964,7 @@ static inline void check_dsp(DisasContext *ctx) if (ctx->insn_flags & ASE_DSP) { generate_exception_end(ctx, EXCP_DSPDIS); } else { - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); } } } @@ -2970,7 +2975,7 @@ static inline void check_dsp_r2(DisasContext *ctx) if (ctx->insn_flags & ASE_DSP) { generate_exception_end(ctx, EXCP_DSPDIS); } else { - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); } } } @@ -2981,7 +2986,7 @@ static inline void check_dsp_r3(DisasContext *ctx) if (ctx->insn_flags & ASE_DSP) { generate_exception_end(ctx, EXCP_DSPDIS); } else { - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); } } } @@ -2993,7 +2998,7 @@ static inline void check_dsp_r3(DisasContext *ctx) void check_insn(DisasContext *ctx, uint64_t flags) { if (unlikely(!(ctx->insn_flags & flags))) { - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); } } @@ -3005,7 +3010,7 @@ void check_insn(DisasContext *ctx, uint64_t flags) static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags) { if (unlikely(ctx->insn_flags & flags)) { - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); } } @@ -3044,7 +3049,7 @@ static inline void check_ps(DisasContext *ctx) void check_mips_64(DisasContext *ctx) { if (unlikely(!(ctx->hflags & MIPS_HFLAG_64))) { - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); } } #endif @@ -3065,7 +3070,7 @@ static inline void check_mvh(DisasContext *ctx) static inline void check_xnp(DisasContext *ctx) { if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_XNP))) { - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); } } @@ -3077,7 +3082,7 @@ static inline void check_xnp(DisasContext *ctx) static inline void check_pw(DisasContext *ctx) { if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_PW)))) { - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); } } #endif @@ -3089,7 +3094,7 @@ static inline void check_pw(DisasContext *ctx) static inline void check_mt(DisasContext *ctx) { if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) { - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); } } @@ -3106,7 +3111,7 @@ static inline void check_cp0_mt(DisasContext *ctx) generate_exception_end(ctx, EXCP_CpU); } else { if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) { - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); } } } @@ -3119,7 +3124,7 @@ static inline void check_cp0_mt(DisasContext *ctx) static inline void check_nms(DisasContext *ctx) { if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS))) { - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); } } @@ -3136,7 +3141,7 @@ static inline void check_nms_dl_il_sl_tl_l2c(DisasContext *ctx) !(ctx->CP0_Config2 & (1 << CP0C2_SL)) && !(ctx->CP0_Config2 & (1 << CP0C2_TL)) && !(ctx->CP0_Config5 & (1 << CP0C5_L2C)))) { - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); } } @@ -3147,7 +3152,7 @@ static inline void check_nms_dl_il_sl_tl_l2c(DisasContext *ctx) static inline void check_eva(DisasContext *ctx) { if (unlikely(!(ctx->CP0_Config5 & (1 << CP0C5_EVA)))) { - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); } } @@ -3812,7 +3817,7 @@ static void gen_flt_ldst(DisasContext *ctx, uint32_t opc, int ft, break; default: MIPS_INVAL("flt_ldst"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } } @@ -4461,7 +4466,7 @@ static void gen_HILO1_tx79(DisasContext *ctx, uint32_t opc, int reg) break; default: MIPS_INVAL("mfthilo1 TX79"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } } @@ -4596,7 +4601,7 @@ static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc, #endif default: MIPS_INVAL("OPC_PCREL"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; @@ -4807,7 +4812,7 @@ static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt) #endif default: MIPS_INVAL("r6 mul/div"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); goto out; } out: @@ -4865,7 +4870,7 @@ static void gen_div1_tx79(DisasContext *ctx, uint32_t opc, int rs, int rt) break; default: MIPS_INVAL("div1 TX79"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); goto out; } out: @@ -5058,7 +5063,7 @@ static void gen_muldiv(DisasContext *ctx, uint32_t opc, break; default: MIPS_INVAL("mul/div"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); goto out; } out: @@ -5189,7 +5194,7 @@ static void gen_mul_txx9(DisasContext *ctx, uint32_t opc, break; default: MIPS_INVAL("mul/madd TXx9"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); goto out; } @@ -5252,7 +5257,7 @@ static void gen_mul_vr54xx(DisasContext *ctx, uint32_t opc, break; default: MIPS_INVAL("mul vr54xx"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); goto out; } gen_store_gpr(t0, rd); @@ -5878,7 +5883,7 @@ static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt) break; default: MIPS_INVAL("loongson_cp2"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); return; } @@ -6067,7 +6072,7 @@ static void gen_loongson_lswc2(DisasContext *ctx, int rt, #endif default: MIPS_INVAL("loongson_gsshfl"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; @@ -6115,13 +6120,13 @@ static void gen_loongson_lswc2(DisasContext *ctx, int rt, #endif default: MIPS_INVAL("loongson_gsshfs"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; default: MIPS_INVAL("loongson_gslsq"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } tcg_temp_free(t0); @@ -6170,7 +6175,7 @@ static void gen_loongson_lsdc2(DisasContext *ctx, int rt, break; default: MIPS_INVAL("loongson_lsdc2"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); return; break; } @@ -6426,7 +6431,7 @@ static void gen_compute_branch(DisasContext *ctx, uint32_t opc, LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx "\n", ctx->base.pc_next); #endif - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); goto out; } @@ -6489,14 +6494,14 @@ static void gen_compute_branch(DisasContext *ctx, uint32_t opc, * others are reserved. */ MIPS_INVAL("jump hint"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); goto out; } gen_load_gpr(btarget, rs); break; default: MIPS_INVAL("branch/jump"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); goto out; } if (bcond_compute == 0) { @@ -6561,7 +6566,7 @@ static void gen_compute_branch(DisasContext *ctx, uint32_t opc, break; default: MIPS_INVAL("branch/jump"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); goto out; } } else { @@ -6632,7 +6637,7 @@ static void gen_compute_branch(DisasContext *ctx, uint32_t opc, break; default: MIPS_INVAL("conditional branch/jump"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); goto out; } } @@ -6709,14 +6714,14 @@ static void gen_compute_branch_nm(DisasContext *ctx, uint32_t opc, * others are reserved. */ MIPS_INVAL("jump hint"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); goto out; } gen_load_gpr(btarget, rs); break; default: MIPS_INVAL("branch/jump"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); goto out; } if (bcond_compute == 0) { @@ -6749,7 +6754,7 @@ static void gen_compute_branch_nm(DisasContext *ctx, uint32_t opc, break; default: MIPS_INVAL("branch/jump"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); goto out; } } else { @@ -6772,7 +6777,7 @@ static void gen_compute_branch_nm(DisasContext *ctx, uint32_t opc, break; default: MIPS_INVAL("conditional branch/jump"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); goto out; } } @@ -6852,7 +6857,7 @@ static void gen_bitops(DisasContext *ctx, uint32_t opc, int rt, default: fail: MIPS_INVAL("bitops"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); tcg_temp_free(t0); tcg_temp_free(t1); return; @@ -6930,7 +6935,7 @@ static void gen_bshfl(DisasContext *ctx, uint32_t op2, int rt, int rd) #endif default: MIPS_INVAL("bsfhl"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); tcg_temp_free(t0); return; } @@ -10584,7 +10589,7 @@ static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd, die: tcg_temp_free(t0); LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); } static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt, @@ -10794,7 +10799,7 @@ static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt, die: tcg_temp_free(t0); LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); } static void gen_cp0(CPUMIPSState *env, DisasContext *ctx, uint32_t opc, @@ -10954,7 +10959,7 @@ static void gen_cp0(CPUMIPSState *env, DisasContext *ctx, uint32_t opc, } if (!(ctx->hflags & MIPS_HFLAG_DM)) { MIPS_INVAL(opn); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); } else { gen_helper_deret(cpu_env); ctx->base.is_jmp = DISAS_EXIT; @@ -10977,7 +10982,7 @@ static void gen_cp0(CPUMIPSState *env, DisasContext *ctx, uint32_t opc, default: die: MIPS_INVAL(opn); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); return; } (void)opn; /* avoid a compiler warning */ @@ -10992,7 +10997,7 @@ static void gen_compute_branch1(DisasContext *ctx, uint32_t op, TCGv_i32 t0 = tcg_temp_new_i32(); if ((ctx->insn_flags & ISA_MIPS_R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) { - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); goto out; } @@ -11083,7 +11088,7 @@ static void gen_compute_branch1(DisasContext *ctx, uint32_t op, break; default: MIPS_INVAL("cp1 cond branch"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); goto out; } ctx->btarget = btarget; @@ -11105,7 +11110,7 @@ static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op, LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx "\n", ctx->base.pc_next); #endif - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); goto out; } @@ -11125,7 +11130,7 @@ static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op, break; default: MIPS_INVAL("cp1 cond branch"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); goto out; } @@ -11433,7 +11438,7 @@ static void gen_cp1(DisasContext *ctx, uint32_t opc, int rt, int fs) break; default: MIPS_INVAL("cp1 move"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); goto out; } @@ -11570,7 +11575,7 @@ static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft, break; default: MIPS_INVAL("gen_sel_s"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } @@ -11607,7 +11612,7 @@ static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft, break; default: MIPS_INVAL("gen_sel_d"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } @@ -13041,7 +13046,7 @@ static void gen_farith(DisasContext *ctx, enum fopcode op1, break; default: MIPS_INVAL("farith"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); return; } } @@ -13380,7 +13385,7 @@ static void gen_flt3_arith(DisasContext *ctx, uint32_t opc, break; default: MIPS_INVAL("flt3_arith"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); return; } } @@ -13455,13 +13460,13 @@ static void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel) offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); gen_store_gpr(t0, rt); } else { - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); } break; #endif default: /* Invalid */ MIPS_INVAL("rdhwr"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } tcg_temp_free(t0); @@ -13560,7 +13565,7 @@ static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc, LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx "\n", ctx->base.pc_next); #endif - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); goto out; } @@ -13622,7 +13627,7 @@ static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc, break; default: MIPS_INVAL("Compact branch/jump"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); goto out; } @@ -13643,7 +13648,7 @@ static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc, break; default: MIPS_INVAL("Compact branch/jump"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); goto out; } @@ -13766,7 +13771,7 @@ static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc, break; default: MIPS_INVAL("Compact conditional branch/jump"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); goto out; } @@ -13940,7 +13945,7 @@ static void gen_mips16_save(DisasContext *ctx, args = 4; break; default: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); return; } @@ -14036,7 +14041,7 @@ static void gen_mips16_save(DisasContext *ctx, astatic = 4; break; default: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); return; } @@ -14142,7 +14147,7 @@ static void gen_mips16_restore(DisasContext *ctx, astatic = 4; break; default: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); return; } @@ -14173,7 +14178,7 @@ static void gen_addiupc(DisasContext *ctx, int rx, int imm, TCGv t0; if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) { - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); return; } @@ -14231,7 +14236,7 @@ static void decode_i64_mips16(DisasContext *ctx, check_insn(ctx, ISA_MIPS3); check_mips_64(ctx); if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) { - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); } else { offset = extended ? offset : offset << 3; gen_ld(ctx, OPC_LDPC, ry, 0, offset); @@ -14308,7 +14313,7 @@ static int decode_extended_mips16_opc(CPUMIPSState *env, DisasContext *ctx) check_mips_64(ctx); gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa); #else - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); #endif break; case 0x2: @@ -14336,7 +14341,7 @@ static int decode_extended_mips16_opc(CPUMIPSState *env, DisasContext *ctx) check_mips_64(ctx); gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm); #else - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); #endif } else { gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm); @@ -14388,7 +14393,7 @@ static int decode_extended_mips16_opc(CPUMIPSState *env, DisasContext *ctx) } break; default: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; @@ -14451,7 +14456,7 @@ static int decode_extended_mips16_opc(CPUMIPSState *env, DisasContext *ctx) break; #endif default: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } @@ -14540,7 +14545,7 @@ static int decode_mips16_opc(CPUMIPSState *env, DisasContext *ctx) check_mips_64(ctx); gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa); #else - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); #endif break; case 0x2: @@ -14568,7 +14573,7 @@ static int decode_mips16_opc(CPUMIPSState *env, DisasContext *ctx) check_mips_64(ctx); gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm); #else - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); #endif } else { gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm); @@ -14652,7 +14657,7 @@ static int decode_mips16_opc(CPUMIPSState *env, DisasContext *ctx) gen_arith(ctx, OPC_ADDU, ry, reg32, 0); break; default: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } } @@ -14742,7 +14747,7 @@ static int decode_mips16_opc(CPUMIPSState *env, DisasContext *ctx) break; #endif default: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); goto done; } @@ -14859,7 +14864,7 @@ static int decode_mips16_opc(CPUMIPSState *env, DisasContext *ctx) break; #endif default: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; @@ -14923,7 +14928,7 @@ static int decode_mips16_opc(CPUMIPSState *env, DisasContext *ctx) break; #endif default: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; @@ -14938,7 +14943,7 @@ static int decode_mips16_opc(CPUMIPSState *env, DisasContext *ctx) break; #endif default: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } @@ -15636,7 +15641,7 @@ static void gen_ldst_multiple(DisasContext *ctx, uint32_t opc, int reglist, TCGv_i32 t2; if (ctx->hflags & MIPS_HFLAG_BMASK) { - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); return; } @@ -15789,7 +15794,7 @@ static void gen_pool16c_insn(DisasContext *ctx) } break; default: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } } @@ -15934,7 +15939,7 @@ static void gen_ldst_pair(DisasContext *ctx, uint32_t opc, int rd, TCGv t0, t1; if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) { - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); return; } @@ -15946,7 +15951,7 @@ static void gen_ldst_pair(DisasContext *ctx, uint32_t opc, int rd, switch (opc) { case LWP: if (rd == base) { - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); return; } tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); @@ -15967,7 +15972,7 @@ static void gen_ldst_pair(DisasContext *ctx, uint32_t opc, int rd, #ifdef TARGET_MIPS64 case LDP: if (rd == base) { - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); return; } tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ); @@ -16312,7 +16317,7 @@ static void gen_pool32axf(CPUMIPSState *env, DisasContext *ctx, int rt, int rs) } else { check_insn(ctx, ISA_MIPS_R1); if (ctx->hflags & MIPS_HFLAG_SBRI) { - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); } else { generate_exception_end(ctx, EXCP_DBp); } @@ -16362,7 +16367,7 @@ static void gen_pool32axf(CPUMIPSState *env, DisasContext *ctx, int rt, int rs) default: pool32axf_invalid: MIPS_INVAL("pool32axf"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } } @@ -16631,7 +16636,7 @@ static void gen_pool32fxf(DisasContext *ctx, int rt, int rs) break; default: MIPS_INVAL("pool32fxf"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } } @@ -16835,12 +16840,12 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) break; case SIGRIE: check_insn(ctx, ISA_MIPS_R6); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; default: pool32a_invalid: MIPS_INVAL("pool32a"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; @@ -16882,7 +16887,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) break; default: MIPS_INVAL("pool32b"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; @@ -17362,7 +17367,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) default: pool32f_invalid: MIPS_INVAL("pool32f"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } } else { @@ -17524,7 +17529,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) /* Fall through */ default: MIPS_INVAL("pool32i"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; @@ -17607,7 +17612,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) case LD_EVA: if (!ctx->eva) { MIPS_INVAL("pool32c ld-eva"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } check_cp0_enabled(ctx); @@ -17646,7 +17651,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) case ST_EVA: if (!ctx->eva) { MIPS_INVAL("pool32c st-eva"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } check_cp0_enabled(ctx); @@ -17698,7 +17703,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) break; default: MIPS_INVAL("pool32c"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; @@ -17990,7 +17995,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) gen_st(ctx, mips32_op, rt, rs, imm); break; default: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } } @@ -18021,7 +18026,7 @@ static int decode_micromips_opc(CPUMIPSState *env, DisasContext *ctx) case 7: /* LB32, LH32, LWC132, LDC132, LW32 */ if (ctx->hflags & MIPS_HFLAG_BDS16) { - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); return 2; } break; @@ -18032,7 +18037,7 @@ static int decode_micromips_opc(CPUMIPSState *env, DisasContext *ctx) case 3: /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */ if (ctx->hflags & MIPS_HFLAG_BDS32) { - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); return 2; } break; @@ -18105,7 +18110,7 @@ static int decode_micromips_opc(CPUMIPSState *env, DisasContext *ctx) case POOL16F: check_insn_opc_removed(ctx, ISA_MIPS_R6); if (ctx->opcode & 1) { - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); } else { /* MOVEP */ int enc_dest = uMIPS_RD(ctx->opcode); @@ -18243,7 +18248,7 @@ static int decode_micromips_opc(CPUMIPSState *env, DisasContext *ctx) case RES_29: case RES_31: case RES_39: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; default: decode_micromips32_opc(env, ctx); @@ -19501,7 +19506,7 @@ static void gen_pool32a0_nanomips_insn(CPUMIPSState *env, DisasContext *ctx) gen_helper_dvpe(t0, cpu_env); gen_store_gpr(t0, rt); } else { - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); } break; case 1: @@ -19516,7 +19521,7 @@ static void gen_pool32a0_nanomips_insn(CPUMIPSState *env, DisasContext *ctx) gen_helper_evpe(t0, cpu_env); gen_store_gpr(t0, rt); } else { - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); } break; } @@ -19566,7 +19571,7 @@ static void gen_pool32a0_nanomips_insn(CPUMIPSState *env, DisasContext *ctx) break; #endif default: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } } @@ -19607,7 +19612,7 @@ static void gen_pool32axf_1_5_nanomips_insn(DisasContext *ctx, uint32_t opc, gen_helper_maq_sa_w_phl(t0, v1_t, v0_t, cpu_env); break; default: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } @@ -19658,7 +19663,7 @@ static void gen_pool32axf_1_nanomips_insn(DisasContext *ctx, uint32_t opc, gen_helper_shilo(t0, v0_t, cpu_env); break; default: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; @@ -19732,7 +19737,7 @@ static void gen_pool32axf_1_nanomips_insn(DisasContext *ctx, uint32_t opc, } break; default: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } @@ -19770,7 +19775,7 @@ static void gen_pool32axf_2_multiply(DisasContext *ctx, uint32_t opc, gen_helper_dpsq_s_w_ph(t0, v1, v0, cpu_env); break; default: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; @@ -19793,7 +19798,7 @@ static void gen_pool32axf_2_multiply(DisasContext *ctx, uint32_t opc, gen_helper_dpsq_sa_l_w(t0, v0, v1, cpu_env); break; default: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; @@ -19820,7 +19825,7 @@ static void gen_pool32axf_2_multiply(DisasContext *ctx, uint32_t opc, gen_helper_mulsa_w_ph(t0, v0, v1, cpu_env); break; default: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; @@ -19847,12 +19852,12 @@ static void gen_pool32axf_2_multiply(DisasContext *ctx, uint32_t opc, gen_helper_mulsaq_s_w_ph(t0, v1, v0, cpu_env); break; default: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; default: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } @@ -19996,7 +20001,7 @@ static void gen_pool32axf_2_nanomips_insn(DisasContext *ctx, uint32_t opc, gen_store_gpr(t0, ret); break; default: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; @@ -20089,7 +20094,7 @@ static void gen_pool32axf_2_nanomips_insn(DisasContext *ctx, uint32_t opc, } break; default: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } @@ -20232,7 +20237,7 @@ static void gen_pool32axf_4_nanomips_insn(DisasContext *ctx, uint32_t opc, gen_bshfl(ctx, OPC_WSBH, ret, rs); break; default: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } @@ -20287,7 +20292,7 @@ static void gen_pool32axf_7_nanomips_insn(DisasContext *ctx, uint32_t opc, } break; default: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } tcg_temp_free(t0); @@ -20384,7 +20389,7 @@ static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *ctx) break; #endif default: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; @@ -20395,7 +20400,7 @@ static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *ctx) } break; default: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } } @@ -20428,7 +20433,7 @@ static void gen_compute_imm_branch(DisasContext *ctx, uint32_t opc, case NM_BBNEZC: check_nms(ctx); if (imm >= 32 && !(ctx->hflags & MIPS_HFLAG_64)) { - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); goto out; } else if (rt == 0 && opc == NM_BBEQZC) { /* Unconditional branch */ @@ -20478,7 +20483,7 @@ static void gen_compute_imm_branch(DisasContext *ctx, uint32_t opc, break; default: MIPS_INVAL("Immediate Value Compact branch"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); goto out; } @@ -20591,7 +20596,7 @@ static void gen_compute_compact_branch_nm(DisasContext *ctx, uint32_t opc, break; default: MIPS_INVAL("Compact branch/jump"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); goto out; } @@ -20603,7 +20608,7 @@ static void gen_compute_compact_branch_nm(DisasContext *ctx, uint32_t opc, break; default: MIPS_INVAL("Compact branch/jump"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); goto out; } } else { @@ -20664,7 +20669,7 @@ static void gen_compute_compact_branch_nm(DisasContext *ctx, uint32_t opc, break; default: MIPS_INVAL("Compact conditional branch/jump"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); goto out; } @@ -20708,7 +20713,7 @@ static void gen_compute_branch_cp1_nm(DisasContext *ctx, uint32_t op, break; default: MIPS_INVAL("cp1 cond branch"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); goto out; } @@ -20838,7 +20843,7 @@ static void gen_p_lsx(DisasContext *ctx, int rd, int rs, int rt) } break; default: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } @@ -20855,7 +20860,7 @@ static void gen_pool32f_nanomips_insn(DisasContext *ctx) rd = extract32(ctx->opcode, 11, 5); if (!(ctx->CP0_Config1 & (1 << CP0C1_FP))) { - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); return; } check_cp1_enabled(ctx); @@ -20929,7 +20934,7 @@ static void gen_pool32f_nanomips_insn(DisasContext *ctx) gen_farith(ctx, OPC_MSUBF_D, rt, rs, rd, 0); break; default: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; @@ -21118,7 +21123,7 @@ static void gen_pool32f_nanomips_insn(DisasContext *ctx) gen_farith(ctx, OPC_CVT_S_L, -1, rs, rt, 0); break; default: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; @@ -21135,12 +21140,12 @@ static void gen_pool32f_nanomips_insn(DisasContext *ctx) gen_r6_cmp_d(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd); break; default: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; default: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } } @@ -21666,7 +21671,7 @@ static void gen_pool32a5_nanomips_insn(DisasContext *ctx, int opc, gen_store_gpr(v1_t, rt); break; default: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; @@ -21688,7 +21693,7 @@ static void gen_pool32a5_nanomips_insn(DisasContext *ctx, int opc, } break; default: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } } @@ -21716,13 +21721,13 @@ static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx) switch (extract32(ctx->opcode, 19, 2)) { case NM_SIGRIE: default: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case NM_P_SYSCALL: if ((extract32(ctx->opcode, 18, 1)) == NM_SYSCALL) { generate_exception_end(ctx, EXCP_SYSCALL); } else { - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); } break; case NM_BREAK: @@ -21733,7 +21738,7 @@ static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx) gen_helper_do_semihosting(cpu_env); } else { if (ctx->hflags & MIPS_HFLAG_SBRI) { - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); } else { generate_exception_end(ctx, EXCP_DBp); } @@ -21791,12 +21796,12 @@ static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx) gen_pool32axf_nanomips_insn(env, ctx); break; default: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; default: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; @@ -21815,7 +21820,7 @@ static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx) gen_st(ctx, OPC_SW, rt, 28, extract32(ctx->opcode, 2, 19) << 2); break; default: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; @@ -21886,7 +21891,7 @@ static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx) } break; default: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } return 6; @@ -21921,12 +21926,12 @@ static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx) } break; default: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; case NM_P_SR_F: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; @@ -22014,7 +22019,7 @@ static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx) extract32(ctx->opcode, 6, 5)); break; default: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; @@ -22027,12 +22032,12 @@ static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx) extract32(ctx->opcode, 6, 5)); break; default: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; default: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; @@ -22100,7 +22105,7 @@ static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx) gen_st(ctx, OPC_SH, rt, 28, u); break; default: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; @@ -22122,7 +22127,7 @@ static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx) } break; default: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } } @@ -22182,7 +22187,7 @@ static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx) gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, u); break; default: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } } @@ -22245,7 +22250,7 @@ static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx) } break; default: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; @@ -22385,7 +22390,7 @@ static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx) gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5)); break; default: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; @@ -22405,7 +22410,7 @@ static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx) true); break; default: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; @@ -22456,7 +22461,7 @@ static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx) } break; default: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } } @@ -22500,7 +22505,7 @@ static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx) gen_compute_nanomips_pbalrsc_branch(ctx, rs, rt); break; default: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; @@ -22535,7 +22540,7 @@ static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx) } break; default: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; @@ -22584,7 +22589,7 @@ static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx) } break; default: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } } @@ -22600,7 +22605,7 @@ static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx) } break; default: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } return 4; @@ -22639,7 +22644,7 @@ static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx) if (extract32(ctx->opcode, 2, 1) == 0) { generate_exception_end(ctx, EXCP_SYSCALL); } else { - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); } break; case NM_BREAK16: @@ -22650,14 +22655,14 @@ static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx) gen_helper_do_semihosting(cpu_env); } else { if (ctx->hflags & MIPS_HFLAG_SBRI) { - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); } else { generate_exception_end(ctx, EXCP_DBp); } } break; default: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } } @@ -22696,7 +22701,7 @@ static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx) gen_arith_imm(ctx, OPC_ADDIU, rt, 29, imm); break; default: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; @@ -22745,7 +22750,7 @@ static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx) gen_r6_muldiv(ctx, R6_OPC_MUL, rt, rs, rt); break; default: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; @@ -22781,7 +22786,7 @@ static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx) gen_ld(ctx, OPC_LBU, rt, rs, offset); break; default: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; @@ -22800,7 +22805,7 @@ static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx) gen_ld(ctx, OPC_LHU, rt, rs, offset); break; default: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; @@ -23579,7 +23584,7 @@ static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc, break; default: /* Invalid */ MIPS_INVAL("MASK SHLL.QB"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; @@ -23694,7 +23699,7 @@ static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc, break; default: /* Invalid */ MIPS_INVAL("MASK SHLL.OB"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; @@ -24385,7 +24390,7 @@ static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx, break; default: /* Invalid */ MIPS_INVAL("MASK APPEND"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; @@ -24419,7 +24424,7 @@ static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx, break; default: /* Invalid */ MIPS_INVAL("MASK DAPPEND"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; @@ -24688,7 +24693,7 @@ static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx) break; default: MIPS_INVAL("special_r6 muldiv"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; @@ -24705,7 +24710,7 @@ static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx) */ gen_cl(ctx, op1, rd, rs); } else { - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); } break; case R6_OPC_SDBBP: @@ -24713,7 +24718,7 @@ static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx) gen_helper_do_semihosting(cpu_env); } else { if (ctx->hflags & MIPS_HFLAG_SBRI) { - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); } else { generate_exception_end(ctx, EXCP_DBp); } @@ -24734,7 +24739,7 @@ static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx) check_mips_64(ctx); gen_cl(ctx, op1, rd, rs); } else { - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); } break; case OPC_DMULT: @@ -24757,14 +24762,14 @@ static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx) break; default: MIPS_INVAL("special_r6 muldiv"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; #endif default: /* Invalid */ MIPS_INVAL("special_r6"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } } @@ -24811,7 +24816,7 @@ static void decode_opc_special_tx79(CPUMIPSState *env, DisasContext *ctx) break; default: /* Invalid */ MIPS_INVAL("special_tx79"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } } @@ -24882,16 +24887,16 @@ static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx) case OPC_SPIM: #ifdef MIPS_STRICT_STANDARD MIPS_INVAL("SPIM"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); #else /* Implemented as RI exception for now. */ MIPS_INVAL("spim (unofficial)"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); #endif break; default: /* Invalid */ MIPS_INVAL("special_legacy"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } } @@ -24913,7 +24918,7 @@ static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx) rs == 0 && rt == 0) { /* PAUSE */ if ((ctx->insn_flags & ISA_MIPS_R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) { - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } } @@ -24933,7 +24938,7 @@ static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx) gen_shift_imm(ctx, op1, rd, rt, sa); break; default: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; @@ -24959,7 +24964,7 @@ static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx) gen_shift(ctx, op1, rd, rs, rt); break; default: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; @@ -24993,7 +24998,7 @@ static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx) /* Pmon entry point, also R4010 selsl */ #ifdef MIPS_STRICT_STANDARD MIPS_INVAL("PMON / selsl"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); #else gen_helper_0e0i(pmon, sa); #endif @@ -25034,7 +25039,7 @@ static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx) gen_shift_imm(ctx, op1, rd, rt, sa); break; default: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; @@ -25052,7 +25057,7 @@ static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx) gen_shift_imm(ctx, op1, rd, rt, sa); break; default: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; @@ -25084,7 +25089,7 @@ static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx) gen_shift(ctx, op1, rd, rs, rt); break; default: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; @@ -25149,7 +25154,7 @@ static void gen_mmi_pcpyh(DisasContext *ctx) rd = extract32(opcode, 11, 5); if (unlikely(pd != 0)) { - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); } else if (rd == 0) { /* nop */ } else if (rt == 0) { @@ -26356,16 +26361,16 @@ static void decode_opc_mxu__pool00(CPUMIPSState *env, DisasContext *ctx) case OPC_MXU_Q8SLT: /* TODO: Implement emulation of Q8SLT instruction. */ MIPS_INVAL("OPC_MXU_Q8SLT"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_Q8SLTU: /* TODO: Implement emulation of Q8SLTU instruction. */ MIPS_INVAL("OPC_MXU_Q8SLTU"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; default: MIPS_INVAL("decode_opc_mxu"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } } @@ -26395,41 +26400,41 @@ static void decode_opc_mxu__pool01(CPUMIPSState *env, DisasContext *ctx) case OPC_MXU_S32SLT: /* TODO: Implement emulation of S32SLT instruction. */ MIPS_INVAL("OPC_MXU_S32SLT"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_D16SLT: /* TODO: Implement emulation of D16SLT instruction. */ MIPS_INVAL("OPC_MXU_D16SLT"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_D16AVG: /* TODO: Implement emulation of D16AVG instruction. */ MIPS_INVAL("OPC_MXU_D16AVG"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_D16AVGR: /* TODO: Implement emulation of D16AVGR instruction. */ MIPS_INVAL("OPC_MXU_D16AVGR"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_Q8AVG: /* TODO: Implement emulation of Q8AVG instruction. */ MIPS_INVAL("OPC_MXU_Q8AVG"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_Q8AVGR: /* TODO: Implement emulation of Q8AVGR instruction. */ MIPS_INVAL("OPC_MXU_Q8AVGR"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_Q8ADD: /* TODO: Implement emulation of Q8ADD instruction. */ MIPS_INVAL("OPC_MXU_Q8ADD"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; default: MIPS_INVAL("decode_opc_mxu"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } } @@ -26452,26 +26457,26 @@ static void decode_opc_mxu__pool02(CPUMIPSState *env, DisasContext *ctx) case OPC_MXU_S32CPS: /* TODO: Implement emulation of S32CPS instruction. */ MIPS_INVAL("OPC_MXU_S32CPS"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_D16CPS: /* TODO: Implement emulation of D16CPS instruction. */ MIPS_INVAL("OPC_MXU_D16CPS"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_Q8ABD: /* TODO: Implement emulation of Q8ABD instruction. */ MIPS_INVAL("OPC_MXU_Q8ABD"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_Q16SAT: /* TODO: Implement emulation of Q16SAT instruction. */ MIPS_INVAL("OPC_MXU_Q16SAT"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; default: MIPS_INVAL("decode_opc_mxu"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } } @@ -26501,16 +26506,16 @@ static void decode_opc_mxu__pool03(CPUMIPSState *env, DisasContext *ctx) case OPC_MXU_D16MULF: /* TODO: Implement emulation of D16MULF instruction. */ MIPS_INVAL("OPC_MXU_D16MULF"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_D16MULE: /* TODO: Implement emulation of D16MULE instruction. */ MIPS_INVAL("OPC_MXU_D16MULE"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; default: MIPS_INVAL("decode_opc_mxu"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } } @@ -26536,7 +26541,7 @@ static void decode_opc_mxu__pool04(CPUMIPSState *env, DisasContext *ctx) break; default: MIPS_INVAL("decode_opc_mxu"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } } @@ -26559,16 +26564,16 @@ static void decode_opc_mxu__pool05(CPUMIPSState *env, DisasContext *ctx) case OPC_MXU_S32STD: /* TODO: Implement emulation of S32STD instruction. */ MIPS_INVAL("OPC_MXU_S32STD"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_S32STDR: /* TODO: Implement emulation of S32STDR instruction. */ MIPS_INVAL("OPC_MXU_S32STDR"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; default: MIPS_INVAL("decode_opc_mxu"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } } @@ -26591,16 +26596,16 @@ static void decode_opc_mxu__pool06(CPUMIPSState *env, DisasContext *ctx) case OPC_MXU_S32LDDV: /* TODO: Implement emulation of S32LDDV instruction. */ MIPS_INVAL("OPC_MXU_S32LDDV"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_S32LDDVR: /* TODO: Implement emulation of S32LDDVR instruction. */ MIPS_INVAL("OPC_MXU_S32LDDVR"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; default: MIPS_INVAL("decode_opc_mxu"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } } @@ -26623,16 +26628,16 @@ static void decode_opc_mxu__pool07(CPUMIPSState *env, DisasContext *ctx) case OPC_MXU_S32STDV: /* TODO: Implement emulation of S32TDV instruction. */ MIPS_INVAL("OPC_MXU_S32TDV"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_S32STDVR: /* TODO: Implement emulation of S32TDVR instruction. */ MIPS_INVAL("OPC_MXU_S32TDVR"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; default: MIPS_INVAL("decode_opc_mxu"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } } @@ -26655,16 +26660,16 @@ static void decode_opc_mxu__pool08(CPUMIPSState *env, DisasContext *ctx) case OPC_MXU_S32LDI: /* TODO: Implement emulation of S32LDI instruction. */ MIPS_INVAL("OPC_MXU_S32LDI"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_S32LDIR: /* TODO: Implement emulation of S32LDIR instruction. */ MIPS_INVAL("OPC_MXU_S32LDIR"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; default: MIPS_INVAL("decode_opc_mxu"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } } @@ -26687,16 +26692,16 @@ static void decode_opc_mxu__pool09(CPUMIPSState *env, DisasContext *ctx) case OPC_MXU_S32SDI: /* TODO: Implement emulation of S32SDI instruction. */ MIPS_INVAL("OPC_MXU_S32SDI"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_S32SDIR: /* TODO: Implement emulation of S32SDIR instruction. */ MIPS_INVAL("OPC_MXU_S32SDIR"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; default: MIPS_INVAL("decode_opc_mxu"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } } @@ -26719,16 +26724,16 @@ static void decode_opc_mxu__pool10(CPUMIPSState *env, DisasContext *ctx) case OPC_MXU_S32LDIV: /* TODO: Implement emulation of S32LDIV instruction. */ MIPS_INVAL("OPC_MXU_S32LDIV"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_S32LDIVR: /* TODO: Implement emulation of S32LDIVR instruction. */ MIPS_INVAL("OPC_MXU_S32LDIVR"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; default: MIPS_INVAL("decode_opc_mxu"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } } @@ -26751,16 +26756,16 @@ static void decode_opc_mxu__pool11(CPUMIPSState *env, DisasContext *ctx) case OPC_MXU_S32SDIV: /* TODO: Implement emulation of S32SDIV instruction. */ MIPS_INVAL("OPC_MXU_S32SDIV"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_S32SDIVR: /* TODO: Implement emulation of S32SDIVR instruction. */ MIPS_INVAL("OPC_MXU_S32SDIVR"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; default: MIPS_INVAL("decode_opc_mxu"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } } @@ -26783,21 +26788,21 @@ static void decode_opc_mxu__pool12(CPUMIPSState *env, DisasContext *ctx) case OPC_MXU_D32ACC: /* TODO: Implement emulation of D32ACC instruction. */ MIPS_INVAL("OPC_MXU_D32ACC"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_D32ACCM: /* TODO: Implement emulation of D32ACCM instruction. */ MIPS_INVAL("OPC_MXU_D32ACCM"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_D32ASUM: /* TODO: Implement emulation of D32ASUM instruction. */ MIPS_INVAL("OPC_MXU_D32ASUM"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; default: MIPS_INVAL("decode_opc_mxu"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } } @@ -26820,21 +26825,21 @@ static void decode_opc_mxu__pool13(CPUMIPSState *env, DisasContext *ctx) case OPC_MXU_Q16ACC: /* TODO: Implement emulation of Q16ACC instruction. */ MIPS_INVAL("OPC_MXU_Q16ACC"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_Q16ACCM: /* TODO: Implement emulation of Q16ACCM instruction. */ MIPS_INVAL("OPC_MXU_Q16ACCM"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_Q16ASUM: /* TODO: Implement emulation of Q16ASUM instruction. */ MIPS_INVAL("OPC_MXU_Q16ASUM"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; default: MIPS_INVAL("decode_opc_mxu"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } } @@ -26864,21 +26869,21 @@ static void decode_opc_mxu__pool14(CPUMIPSState *env, DisasContext *ctx) case OPC_MXU_Q8ADDE: /* TODO: Implement emulation of Q8ADDE instruction. */ MIPS_INVAL("OPC_MXU_Q8ADDE"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_D8SUM: /* TODO: Implement emulation of D8SUM instruction. */ MIPS_INVAL("OPC_MXU_D8SUM"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_D8SUMC: /* TODO: Implement emulation of D8SUMC instruction. */ MIPS_INVAL("OPC_MXU_D8SUMC"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; default: MIPS_INVAL("decode_opc_mxu"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } } @@ -26908,26 +26913,26 @@ static void decode_opc_mxu__pool15(CPUMIPSState *env, DisasContext *ctx) case OPC_MXU_S32MUL: /* TODO: Implement emulation of S32MUL instruction. */ MIPS_INVAL("OPC_MXU_S32MUL"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_S32MULU: /* TODO: Implement emulation of S32MULU instruction. */ MIPS_INVAL("OPC_MXU_S32MULU"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_S32EXTR: /* TODO: Implement emulation of S32EXTR instruction. */ MIPS_INVAL("OPC_MXU_S32EXTR"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_S32EXTRV: /* TODO: Implement emulation of S32EXTRV instruction. */ MIPS_INVAL("OPC_MXU_S32EXTRV"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; default: MIPS_INVAL("decode_opc_mxu"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } } @@ -26975,12 +26980,12 @@ static void decode_opc_mxu__pool16(CPUMIPSState *env, DisasContext *ctx) case OPC_MXU_D32SARW: /* TODO: Implement emulation of D32SARW instruction. */ MIPS_INVAL("OPC_MXU_D32SARW"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_S32ALN: /* TODO: Implement emulation of S32ALN instruction. */ MIPS_INVAL("OPC_MXU_S32ALN"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_S32ALNI: gen_mxu_S32ALNI(ctx); @@ -26988,7 +26993,7 @@ static void decode_opc_mxu__pool16(CPUMIPSState *env, DisasContext *ctx) case OPC_MXU_S32LUI: /* TODO: Implement emulation of S32LUI instruction. */ MIPS_INVAL("OPC_MXU_S32LUI"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_S32NOR: gen_mxu_S32NOR(ctx); @@ -27004,7 +27009,7 @@ static void decode_opc_mxu__pool16(CPUMIPSState *env, DisasContext *ctx) break; default: MIPS_INVAL("decode_opc_mxu"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } } @@ -27027,31 +27032,31 @@ static void decode_opc_mxu__pool17(CPUMIPSState *env, DisasContext *ctx) case OPC_MXU_LXW: /* TODO: Implement emulation of LXW instruction. */ MIPS_INVAL("OPC_MXU_LXW"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_LXH: /* TODO: Implement emulation of LXH instruction. */ MIPS_INVAL("OPC_MXU_LXH"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_LXHU: /* TODO: Implement emulation of LXHU instruction. */ MIPS_INVAL("OPC_MXU_LXHU"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_LXB: /* TODO: Implement emulation of LXB instruction. */ MIPS_INVAL("OPC_MXU_LXB"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_LXBU: /* TODO: Implement emulation of LXBU instruction. */ MIPS_INVAL("OPC_MXU_LXBU"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; default: MIPS_INVAL("decode_opc_mxu"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } } @@ -27073,36 +27078,36 @@ static void decode_opc_mxu__pool18(CPUMIPSState *env, DisasContext *ctx) case OPC_MXU_D32SLLV: /* TODO: Implement emulation of D32SLLV instruction. */ MIPS_INVAL("OPC_MXU_D32SLLV"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_D32SLRV: /* TODO: Implement emulation of D32SLRV instruction. */ MIPS_INVAL("OPC_MXU_D32SLRV"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_D32SARV: /* TODO: Implement emulation of D32SARV instruction. */ MIPS_INVAL("OPC_MXU_D32SARV"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_Q16SLLV: /* TODO: Implement emulation of Q16SLLV instruction. */ MIPS_INVAL("OPC_MXU_Q16SLLV"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_Q16SLRV: /* TODO: Implement emulation of Q16SLRV instruction. */ MIPS_INVAL("OPC_MXU_Q16SLRV"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_Q16SARV: /* TODO: Implement emulation of Q16SARV instruction. */ MIPS_INVAL("OPC_MXU_Q16SARV"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; default: MIPS_INVAL("decode_opc_mxu"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } } @@ -27128,7 +27133,7 @@ static void decode_opc_mxu__pool19(CPUMIPSState *env, DisasContext *ctx) break; default: MIPS_INVAL("decode_opc_mxu"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } } @@ -27151,36 +27156,36 @@ static void decode_opc_mxu__pool20(CPUMIPSState *env, DisasContext *ctx) case OPC_MXU_Q8MOVZ: /* TODO: Implement emulation of Q8MOVZ instruction. */ MIPS_INVAL("OPC_MXU_Q8MOVZ"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_Q8MOVN: /* TODO: Implement emulation of Q8MOVN instruction. */ MIPS_INVAL("OPC_MXU_Q8MOVN"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_D16MOVZ: /* TODO: Implement emulation of D16MOVZ instruction. */ MIPS_INVAL("OPC_MXU_D16MOVZ"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_D16MOVN: /* TODO: Implement emulation of D16MOVN instruction. */ MIPS_INVAL("OPC_MXU_D16MOVN"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_S32MOVZ: /* TODO: Implement emulation of S32MOVZ instruction. */ MIPS_INVAL("OPC_MXU_S32MOVZ"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_S32MOVN: /* TODO: Implement emulation of S32MOVN instruction. */ MIPS_INVAL("OPC_MXU_S32MOVN"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; default: MIPS_INVAL("decode_opc_mxu"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } } @@ -27203,16 +27208,16 @@ static void decode_opc_mxu__pool21(CPUMIPSState *env, DisasContext *ctx) case OPC_MXU_Q8MAC: /* TODO: Implement emulation of Q8MAC instruction. */ MIPS_INVAL("OPC_MXU_Q8MAC"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_Q8MACSU: /* TODO: Implement emulation of Q8MACSU instruction. */ MIPS_INVAL("OPC_MXU_Q8MACSU"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; default: MIPS_INVAL("decode_opc_mxu"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } } @@ -27271,12 +27276,12 @@ static void decode_opc_mxu(CPUMIPSState *env, DisasContext *ctx) case OPC_MXU_S32MADD: /* TODO: Implement emulation of S32MADD instruction. */ MIPS_INVAL("OPC_MXU_S32MADD"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_S32MADDU: /* TODO: Implement emulation of S32MADDU instruction. */ MIPS_INVAL("OPC_MXU_S32MADDU"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU__POOL00: decode_opc_mxu__pool00(env, ctx); @@ -27284,12 +27289,12 @@ static void decode_opc_mxu(CPUMIPSState *env, DisasContext *ctx) case OPC_MXU_S32MSUB: /* TODO: Implement emulation of S32MSUB instruction. */ MIPS_INVAL("OPC_MXU_S32MSUB"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_S32MSUBU: /* TODO: Implement emulation of S32MSUBU instruction. */ MIPS_INVAL("OPC_MXU_S32MSUBU"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU__POOL01: decode_opc_mxu__pool01(env, ctx); @@ -27309,27 +27314,27 @@ static void decode_opc_mxu(CPUMIPSState *env, DisasContext *ctx) case OPC_MXU_D16MACF: /* TODO: Implement emulation of D16MACF instruction. */ MIPS_INVAL("OPC_MXU_D16MACF"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_D16MADL: /* TODO: Implement emulation of D16MADL instruction. */ MIPS_INVAL("OPC_MXU_D16MADL"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_S16MAD: /* TODO: Implement emulation of S16MAD instruction. */ MIPS_INVAL("OPC_MXU_S16MAD"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_Q16ADD: /* TODO: Implement emulation of Q16ADD instruction. */ MIPS_INVAL("OPC_MXU_Q16ADD"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_D16MACE: /* TODO: Implement emulation of D16MACE instruction. */ MIPS_INVAL("OPC_MXU_D16MACE"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU__POOL04: decode_opc_mxu__pool04(env, ctx); @@ -27358,7 +27363,7 @@ static void decode_opc_mxu(CPUMIPSState *env, DisasContext *ctx) case OPC_MXU_D32ADD: /* TODO: Implement emulation of D32ADD instruction. */ MIPS_INVAL("OPC_MXU_D32ADD"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU__POOL12: decode_opc_mxu__pool12(env, ctx); @@ -27372,7 +27377,7 @@ static void decode_opc_mxu(CPUMIPSState *env, DisasContext *ctx) case OPC_MXU_Q8ACCE: /* TODO: Implement emulation of Q8ACCE instruction. */ MIPS_INVAL("OPC_MXU_Q8ACCE"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_S8LDD: gen_mxu_s8ldd(ctx); @@ -27380,17 +27385,17 @@ static void decode_opc_mxu(CPUMIPSState *env, DisasContext *ctx) case OPC_MXU_S8STD: /* TODO: Implement emulation of S8STD instruction. */ MIPS_INVAL("OPC_MXU_S8STD"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_S8LDI: /* TODO: Implement emulation of S8LDI instruction. */ MIPS_INVAL("OPC_MXU_S8LDI"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_S8SDI: /* TODO: Implement emulation of S8SDI instruction. */ MIPS_INVAL("OPC_MXU_S8SDI"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU__POOL15: decode_opc_mxu__pool15(env, ctx); @@ -27404,52 +27409,52 @@ static void decode_opc_mxu(CPUMIPSState *env, DisasContext *ctx) case OPC_MXU_S16LDD: /* TODO: Implement emulation of S16LDD instruction. */ MIPS_INVAL("OPC_MXU_S16LDD"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_S16STD: /* TODO: Implement emulation of S16STD instruction. */ MIPS_INVAL("OPC_MXU_S16STD"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_S16LDI: /* TODO: Implement emulation of S16LDI instruction. */ MIPS_INVAL("OPC_MXU_S16LDI"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_S16SDI: /* TODO: Implement emulation of S16SDI instruction. */ MIPS_INVAL("OPC_MXU_S16SDI"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_D32SLL: /* TODO: Implement emulation of D32SLL instruction. */ MIPS_INVAL("OPC_MXU_D32SLL"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_D32SLR: /* TODO: Implement emulation of D32SLR instruction. */ MIPS_INVAL("OPC_MXU_D32SLR"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_D32SARL: /* TODO: Implement emulation of D32SARL instruction. */ MIPS_INVAL("OPC_MXU_D32SARL"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_D32SAR: /* TODO: Implement emulation of D32SAR instruction. */ MIPS_INVAL("OPC_MXU_D32SAR"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_Q16SLL: /* TODO: Implement emulation of Q16SLL instruction. */ MIPS_INVAL("OPC_MXU_Q16SLL"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_Q16SLR: /* TODO: Implement emulation of Q16SLR instruction. */ MIPS_INVAL("OPC_MXU_Q16SLR"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU__POOL18: decode_opc_mxu__pool18(env, ctx); @@ -27457,7 +27462,7 @@ static void decode_opc_mxu(CPUMIPSState *env, DisasContext *ctx) case OPC_MXU_Q16SAR: /* TODO: Implement emulation of Q16SAR instruction. */ MIPS_INVAL("OPC_MXU_Q16SAR"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU__POOL19: decode_opc_mxu__pool19(env, ctx); @@ -27471,26 +27476,26 @@ static void decode_opc_mxu(CPUMIPSState *env, DisasContext *ctx) case OPC_MXU_Q16SCOP: /* TODO: Implement emulation of Q16SCOP instruction. */ MIPS_INVAL("OPC_MXU_Q16SCOP"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_Q8MADL: /* TODO: Implement emulation of Q8MADL instruction. */ MIPS_INVAL("OPC_MXU_Q8MADL"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_S32SFL: /* TODO: Implement emulation of S32SFL instruction. */ MIPS_INVAL("OPC_MXU_S32SFL"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_MXU_Q8SAD: /* TODO: Implement emulation of Q8SAD instruction. */ MIPS_INVAL("OPC_MXU_Q8SAD"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; default: MIPS_INVAL("decode_opc_mxu"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); } gen_set_label(l_exit); @@ -27569,7 +27574,7 @@ static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx) #endif default: /* Invalid */ MIPS_INVAL("special2_legacy"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } } @@ -27591,7 +27596,7 @@ static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx) case R6_OPC_PREF: if (rt >= 24) { /* hint codes 24-31 are reserved and signal RI */ - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); } /* Treat as NOP. */ break; @@ -27630,7 +27635,7 @@ static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx) #ifndef CONFIG_USER_ONLY case OPC_GINV: if (unlikely(ctx->gi <= 1)) { - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); } check_cp0_enabled(ctx); switch ((ctx->opcode >> 6) & 3) { @@ -27641,7 +27646,7 @@ static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx) gen_helper_0e1i(ginvt, cpu_gpr[rs], extract32(ctx->opcode, 8, 2)); break; default: - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; @@ -27682,7 +27687,7 @@ static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx) #endif default: /* Invalid */ MIPS_INVAL("special3_r6"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } } @@ -27733,13 +27738,13 @@ static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx) break; default: MIPS_INVAL("MASK ADDUH.QB"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } } else if (ctx->insn_flags & INSN_LOONGSON2E) { gen_loongson_integer(ctx, op1, rd, rs, rt); } else { - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); } break; case OPC_LX_DSP: @@ -27755,7 +27760,7 @@ static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx) break; default: /* Invalid */ MIPS_INVAL("MASK LX"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; @@ -27786,7 +27791,7 @@ static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx) break; default: MIPS_INVAL("MASK ABSQ_S.PH"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; @@ -27823,7 +27828,7 @@ static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx) break; default: /* Invalid */ MIPS_INVAL("MASK ADDU.QB"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } @@ -27863,7 +27868,7 @@ static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx) break; default: /* Invalid */ MIPS_INVAL("MASK CMPU.EQ.QB"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; @@ -27899,7 +27904,7 @@ static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx) break; default: /* Invalid */ MIPS_INVAL("MASK DPAW.PH"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; @@ -27929,7 +27934,7 @@ static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx) } default: /* Invalid */ MIPS_INVAL("MASK INSV"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; @@ -27964,7 +27969,7 @@ static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx) break; default: /* Invalid */ MIPS_INVAL("MASK EXTR.W"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; @@ -28010,7 +28015,7 @@ static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx) break; default: /* Invalid */ MIPS_INVAL("MASK ABSQ_S.QH"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; @@ -28049,7 +28054,7 @@ static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx) break; default: /* Invalid */ MIPS_INVAL("MASK ADDU.OB"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; @@ -28094,7 +28099,7 @@ static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx) break; default: /* Invalid */ MIPS_INVAL("MASK CMPU_EQ.OB"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; @@ -28131,7 +28136,7 @@ static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx) break; default: /* Invalid */ MIPS_INVAL("MASK EXTR.W"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; @@ -28170,7 +28175,7 @@ static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx) break; default: /* Invalid */ MIPS_INVAL("MASK DPAQ.W.QH"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; @@ -28200,7 +28205,7 @@ static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx) } default: /* Invalid */ MIPS_INVAL("MASK DINSV"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; @@ -28210,7 +28215,7 @@ static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx) #endif default: /* Invalid */ MIPS_INVAL("special3_legacy"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } } @@ -28248,11 +28253,11 @@ static void decode_mmi0(CPUMIPSState *env, DisasContext *ctx) case MMI_OPC_0_PPACB: /* TODO: MMI_OPC_0_PPACB */ case MMI_OPC_0_PEXT5: /* TODO: MMI_OPC_0_PEXT5 */ case MMI_OPC_0_PPAC5: /* TODO: MMI_OPC_0_PPAC5 */ - generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI0 */ + gen_reserved_instruction(ctx); /* TODO: MMI_OPC_CLASS_MMI0 */ break; default: MIPS_INVAL("TX79 MMI class MMI0"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } } @@ -28280,11 +28285,11 @@ static void decode_mmi1(CPUMIPSState *env, DisasContext *ctx) case MMI_OPC_1_PSUBUB: /* TODO: MMI_OPC_1_PSUBUB */ case MMI_OPC_1_PEXTUB: /* TODO: MMI_OPC_1_PEXTUB */ case MMI_OPC_1_QFSRV: /* TODO: MMI_OPC_1_QFSRV */ - generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI1 */ + gen_reserved_instruction(ctx); /* TODO: MMI_OPC_CLASS_MMI1 */ break; default: MIPS_INVAL("TX79 MMI class MMI1"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } } @@ -28315,14 +28320,14 @@ static void decode_mmi2(CPUMIPSState *env, DisasContext *ctx) case MMI_OPC_2_PDIVBW: /* TODO: MMI_OPC_2_PDIVBW */ case MMI_OPC_2_PEXEW: /* TODO: MMI_OPC_2_PEXEW */ case MMI_OPC_2_PROT3W: /* TODO: MMI_OPC_2_PROT3W */ - generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI2 */ + gen_reserved_instruction(ctx); /* TODO: MMI_OPC_CLASS_MMI2 */ break; case MMI_OPC_2_PCPYLD: gen_mmi_pcpyld(ctx); break; default: MIPS_INVAL("TX79 MMI class MMI2"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } } @@ -28343,7 +28348,7 @@ static void decode_mmi3(CPUMIPSState *env, DisasContext *ctx) case MMI_OPC_3_PNOR: /* TODO: MMI_OPC_3_PNOR */ case MMI_OPC_3_PEXCH: /* TODO: MMI_OPC_3_PEXCH */ case MMI_OPC_3_PEXCW: /* TODO: MMI_OPC_3_PEXCW */ - generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI3 */ + gen_reserved_instruction(ctx); /* TODO: MMI_OPC_CLASS_MMI3 */ break; case MMI_OPC_3_PCPYH: gen_mmi_pcpyh(ctx); @@ -28353,7 +28358,7 @@ static void decode_mmi3(CPUMIPSState *env, DisasContext *ctx) break; default: MIPS_INVAL("TX79 MMI class MMI3"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } } @@ -28407,23 +28412,23 @@ static void decode_mmi(CPUMIPSState *env, DisasContext *ctx) case MMI_OPC_PSLLW: /* TODO: MMI_OPC_PSLLW */ case MMI_OPC_PSRLW: /* TODO: MMI_OPC_PSRLW */ case MMI_OPC_PSRAW: /* TODO: MMI_OPC_PSRAW */ - generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI */ + gen_reserved_instruction(ctx); /* TODO: MMI_OPC_CLASS_MMI */ break; default: MIPS_INVAL("TX79 MMI class"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } } static void gen_mmi_lq(CPUMIPSState *env, DisasContext *ctx) { - generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_LQ */ + gen_reserved_instruction(ctx); /* TODO: MMI_OPC_LQ */ } static void gen_mmi_sq(DisasContext *ctx, int base, int rt, int offset) { - generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_SQ */ + gen_reserved_instruction(ctx); /* TODO: MMI_OPC_SQ */ } /* @@ -28631,7 +28636,7 @@ static inline int check_msa_access(DisasContext *ctx) { if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) && !(ctx->hflags & MIPS_HFLAG_F64))) { - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); return 0; } @@ -28640,7 +28645,7 @@ static inline int check_msa_access(DisasContext *ctx) generate_exception_end(ctx, EXCP_MSADIS); return 0; } else { - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); return 0; } } @@ -28697,7 +28702,7 @@ static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1) check_msa_access(ctx); if (ctx->hflags & MIPS_HFLAG_BMASK) { - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); return; } switch (op1) { @@ -28772,7 +28777,7 @@ static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx) { uint8_t df = (ctx->opcode >> 24) & 0x3; if (df == DF_DOUBLE) { - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); } else { TCGv_i32 tdf = tcg_const_i32(df); gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8); @@ -28782,7 +28787,7 @@ static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx) break; default: MIPS_INVAL("MSA instruction"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } @@ -28854,7 +28859,7 @@ static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx) break; default: MIPS_INVAL("MSA instruction"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } @@ -28890,7 +28895,7 @@ static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx) m = dfm & 0x7; df = DF_BYTE; } else { - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); return; } @@ -28938,7 +28943,7 @@ static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx) break; default: MIPS_INVAL("MSA instruction"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } @@ -29783,7 +29788,7 @@ static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx) case OPC_HSUB_S_df: case OPC_HSUB_U_df: if (df == DF_BYTE) { - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } switch (MASK_MSA_3R(ctx->opcode)) { @@ -29921,7 +29926,7 @@ static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx) break; default: MIPS_INVAL("MSA instruction"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } tcg_temp_free_i32(twd); @@ -29953,7 +29958,7 @@ static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx) break; default: MIPS_INVAL("MSA instruction"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } @@ -29990,12 +29995,12 @@ static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df, #if !defined(TARGET_MIPS64) /* Double format valid only for MIPS64 */ if (df == DF_DOUBLE) { - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } if ((MASK_MSA_ELM(ctx->opcode) == OPC_COPY_U_df) && (df == DF_WORD)) { - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } #endif @@ -30065,7 +30070,7 @@ static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df, break; default: MIPS_INVAL("MSA instruction"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); } tcg_temp_free_i32(twd); tcg_temp_free_i32(tws); @@ -30095,7 +30100,7 @@ static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx) gen_msa_elm_3e(env, ctx); return; } else { - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); return; } @@ -30250,7 +30255,7 @@ static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx) break; default: MIPS_INVAL("MSA instruction"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } @@ -30278,7 +30283,7 @@ static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx) #if !defined(TARGET_MIPS64) /* Double format valid only for MIPS64 */ if (df == DF_DOUBLE) { - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } #endif @@ -30334,7 +30339,7 @@ static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx) break; default: MIPS_INVAL("MSA instruction"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } @@ -30449,7 +30454,7 @@ static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx) break; default: MIPS_INVAL("MSA instruction"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } @@ -30478,7 +30483,7 @@ static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx) break; default: MIPS_INVAL("MSA instruction"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } } @@ -30576,7 +30581,7 @@ static void gen_msa(CPUMIPSState *env, DisasContext *ctx) break; default: MIPS_INVAL("MSA instruction"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } @@ -30660,7 +30665,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) /* OPC_NAL, OPC_BAL */ gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4); } else { - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); } } else { gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4); @@ -30679,7 +30684,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) break; case OPC_SIGRIE: check_insn(ctx, ISA_MIPS_R6); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; case OPC_SYNCI: check_insn(ctx, ISA_MIPS_R2); @@ -30714,7 +30719,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) #endif default: /* Invalid */ MIPS_INVAL("regimm"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; @@ -30823,7 +30828,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) break; default: /* Invalid */ MIPS_INVAL("mfmc0"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } tcg_temp_free(t0); @@ -30840,7 +30845,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) break; default: MIPS_INVAL("cp0"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; @@ -30876,7 +30881,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */ if (ctx->insn_flags & ISA_MIPS_R6) { if (rt == 0) { - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */ @@ -30889,7 +30894,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */ if (ctx->insn_flags & ISA_MIPS_R6) { if (rt == 0) { - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */ @@ -31138,7 +31143,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) break; default: MIPS_INVAL("cp1"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } break; @@ -31224,7 +31229,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) break; default: MIPS_INVAL("cp3"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } } else { @@ -31289,7 +31294,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); } else { MIPS_INVAL("major opcode"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); } break; #endif @@ -31307,7 +31312,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) tcg_temp_free(t0); } #else - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); MIPS_INVAL("major opcode"); #endif } else { @@ -31333,7 +31338,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) break; default: /* Invalid */ MIPS_INVAL("major opcode"); - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); break; } } @@ -31438,7 +31443,7 @@ static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next); insn_bytes = decode_mips16_opc(env, ctx); } else { - generate_exception_end(ctx, EXCP_RI); + gen_reserved_instruction(ctx); g_assert(ctx->base.is_jmp == DISAS_NORETURN); return; } diff --git a/target/mips/translate.h b/target/mips/translate.h index 3d640912f1..98cadffe4e 100644 --- a/target/mips/translate.h +++ b/target/mips/translate.h @@ -55,6 +55,7 @@ typedef struct DisasContext { void generate_exception(DisasContext *ctx, int excp); void generate_exception_err(DisasContext *ctx, int excp, int err); void generate_exception_end(DisasContext *ctx, int excp); +void gen_reserved_instruction(DisasContext *ctx); void check_insn(DisasContext *ctx, uint64_t flags); #ifdef TARGET_MIPS64 -- cgit v1.2.3-55-g7522 From 8758d1b8aa3ee91b294ea862f89092c20428928e Mon Sep 17 00:00:00 2001 From: Philippe Mathieu-Daudé Date: Sun, 29 Nov 2020 17:38:13 +0100 Subject: target/mips: Declare generic FPU / Coprocessor functions in translate.h Some FPU / Coprocessor translation functions / registers can be used by ISA / ASE / extensions out of the big translate.c file. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20201214183739.500368-15-f4bug@amsat.org> --- target/mips/translate.c | 24 ++++++++++++------------ target/mips/translate.h | 12 ++++++++++++ 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/target/mips/translate.c b/target/mips/translate.c index d776721505..9b822344a2 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -2492,8 +2492,8 @@ static TCGv cpu_dspctrl, btarget; TCGv bcond; static TCGv cpu_lladdr, cpu_llval; static TCGv_i32 hflags; -static TCGv_i32 fpu_fcr0, fpu_fcr31; -static TCGv_i64 fpu_f64[32]; +TCGv_i32 fpu_fcr0, fpu_fcr31; +TCGv_i64 fpu_f64[32]; static TCGv_i64 msa_wr_d[64]; #if defined(TARGET_MIPS64) @@ -2768,7 +2768,7 @@ void gen_reserved_instruction(DisasContext *ctx) } /* Floating point register moves. */ -static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg) +void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg) { if (ctx->hflags & MIPS_HFLAG_FRE) { generate_exception(ctx, EXCP_RI); @@ -2776,7 +2776,7 @@ static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg) tcg_gen_extrl_i64_i32(t, fpu_f64[reg]); } -static void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg) +void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg) { TCGv_i64 t64; if (ctx->hflags & MIPS_HFLAG_FRE) { @@ -2809,7 +2809,7 @@ static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg) } } -static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg) +void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg) { if (ctx->hflags & MIPS_HFLAG_F64) { tcg_gen_mov_i64(t, fpu_f64[reg]); @@ -2818,7 +2818,7 @@ static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg) } } -static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg) +void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg) { if (ctx->hflags & MIPS_HFLAG_F64) { tcg_gen_mov_i64(fpu_f64[reg], t); @@ -2832,7 +2832,7 @@ static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg) } } -static inline int get_fp_bit(int cc) +int get_fp_bit(int cc) { if (cc) { return 24 + cc; @@ -2899,14 +2899,14 @@ void gen_move_high32(TCGv ret, TCGv_i64 arg) #endif } -static inline void check_cp0_enabled(DisasContext *ctx) +void check_cp0_enabled(DisasContext *ctx) { if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) { generate_exception_end(ctx, EXCP_CpU); } } -static inline void check_cp1_enabled(DisasContext *ctx) +void check_cp1_enabled(DisasContext *ctx) { if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU))) { generate_exception_err(ctx, EXCP_CpU, 1); @@ -2918,7 +2918,7 @@ static inline void check_cp1_enabled(DisasContext *ctx) * This is associated with the nabla symbol in the MIPS32 and MIPS64 * opcode tables. */ -static inline void check_cop1x(DisasContext *ctx) +void check_cop1x(DisasContext *ctx) { if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X))) { gen_reserved_instruction(ctx); @@ -2929,7 +2929,7 @@ static inline void check_cop1x(DisasContext *ctx) * Verify that the processor is running with 64-bit floating-point * operations enabled. */ -static inline void check_cp1_64bitmode(DisasContext *ctx) +void check_cp1_64bitmode(DisasContext *ctx) { if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X))) { gen_reserved_instruction(ctx); @@ -2947,7 +2947,7 @@ static inline void check_cp1_64bitmode(DisasContext *ctx) * Multiple 64 bit wide registers can be checked by calling * gen_op_cp1_registers(freg1 | freg2 | ... | fregN); */ -static inline void check_cp1_registers(DisasContext *ctx, int regs) +void check_cp1_registers(DisasContext *ctx, int regs) { if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1))) { gen_reserved_instruction(ctx); diff --git a/target/mips/translate.h b/target/mips/translate.h index 98cadffe4e..a3f4a56750 100644 --- a/target/mips/translate.h +++ b/target/mips/translate.h @@ -61,16 +61,28 @@ void check_insn(DisasContext *ctx, uint64_t flags); #ifdef TARGET_MIPS64 void check_mips_64(DisasContext *ctx); #endif +void check_cp0_enabled(DisasContext *ctx); +void check_cp1_enabled(DisasContext *ctx); +void check_cp1_64bitmode(DisasContext *ctx); +void check_cp1_registers(DisasContext *ctx, int regs); +void check_cop1x(DisasContext *ctx); void gen_base_offset_addr(DisasContext *ctx, TCGv addr, int base, int offset); void gen_move_low32(TCGv ret, TCGv_i64 arg); void gen_move_high32(TCGv ret, TCGv_i64 arg); void gen_load_gpr(TCGv t, int reg); void gen_store_gpr(TCGv t, int reg); +void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg); +void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg); +void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg); +void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg); +int get_fp_bit(int cc); void gen_op_addr_add(DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1); extern TCGv cpu_gpr[32], cpu_PC; +extern TCGv_i32 fpu_fcr0, fpu_fcr31; +extern TCGv_i64 fpu_f64[32]; extern TCGv bcond; #define LOG_DISAS(...) \ -- cgit v1.2.3-55-g7522 From 57eedcf7e33c9833f97101034142cd546ae839bb Mon Sep 17 00:00:00 2001 From: Philippe Mathieu-Daudé Date: Sun, 29 Nov 2020 19:12:49 +0100 Subject: target/mips: Extract FPU specific definitions to translate.h Extract FPU specific definitions that can be used by ISA / ASE / extensions to translate.h header. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20201214183739.500368-16-f4bug@amsat.org> --- target/mips/translate.c | 70 ------------------------------------------------ target/mips/translate.h | 71 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 70 deletions(-) diff --git a/target/mips/translate.c b/target/mips/translate.c index 9b822344a2..4c400ec0b3 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -43,7 +43,6 @@ enum { OPC_SPECIAL = (0x00 << 26), OPC_REGIMM = (0x01 << 26), OPC_CP0 = (0x10 << 26), - OPC_CP1 = (0x11 << 26), OPC_CP2 = (0x12 << 26), OPC_CP3 = (0x13 << 26), OPC_SPECIAL2 = (0x1C << 26), @@ -996,75 +995,6 @@ enum { OPC_WAIT = 0x20 | OPC_C0, }; -/* Coprocessor 1 (rs field) */ -#define MASK_CP1(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21))) - -/* Values for the fmt field in FP instructions */ -enum { - /* 0 - 15 are reserved */ - FMT_S = 16, /* single fp */ - FMT_D = 17, /* double fp */ - FMT_E = 18, /* extended fp */ - FMT_Q = 19, /* quad fp */ - FMT_W = 20, /* 32-bit fixed */ - FMT_L = 21, /* 64-bit fixed */ - FMT_PS = 22, /* paired single fp */ - /* 23 - 31 are reserved */ -}; - -enum { - OPC_MFC1 = (0x00 << 21) | OPC_CP1, - OPC_DMFC1 = (0x01 << 21) | OPC_CP1, - OPC_CFC1 = (0x02 << 21) | OPC_CP1, - OPC_MFHC1 = (0x03 << 21) | OPC_CP1, - OPC_MTC1 = (0x04 << 21) | OPC_CP1, - OPC_DMTC1 = (0x05 << 21) | OPC_CP1, - OPC_CTC1 = (0x06 << 21) | OPC_CP1, - OPC_MTHC1 = (0x07 << 21) | OPC_CP1, - OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */ - OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1, - OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1, - OPC_BZ_V = (0x0B << 21) | OPC_CP1, - OPC_BNZ_V = (0x0F << 21) | OPC_CP1, - OPC_S_FMT = (FMT_S << 21) | OPC_CP1, - OPC_D_FMT = (FMT_D << 21) | OPC_CP1, - OPC_E_FMT = (FMT_E << 21) | OPC_CP1, - OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1, - OPC_W_FMT = (FMT_W << 21) | OPC_CP1, - OPC_L_FMT = (FMT_L << 21) | OPC_CP1, - OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1, - OPC_BC1EQZ = (0x09 << 21) | OPC_CP1, - OPC_BC1NEZ = (0x0D << 21) | OPC_CP1, - OPC_BZ_B = (0x18 << 21) | OPC_CP1, - OPC_BZ_H = (0x19 << 21) | OPC_CP1, - OPC_BZ_W = (0x1A << 21) | OPC_CP1, - OPC_BZ_D = (0x1B << 21) | OPC_CP1, - OPC_BNZ_B = (0x1C << 21) | OPC_CP1, - OPC_BNZ_H = (0x1D << 21) | OPC_CP1, - OPC_BNZ_W = (0x1E << 21) | OPC_CP1, - OPC_BNZ_D = (0x1F << 21) | OPC_CP1, -}; - -#define MASK_CP1_FUNC(op) (MASK_CP1(op) | (op & 0x3F)) -#define MASK_BC1(op) (MASK_CP1(op) | (op & (0x3 << 16))) - -enum { - OPC_BC1F = (0x00 << 16) | OPC_BC1, - OPC_BC1T = (0x01 << 16) | OPC_BC1, - OPC_BC1FL = (0x02 << 16) | OPC_BC1, - OPC_BC1TL = (0x03 << 16) | OPC_BC1, -}; - -enum { - OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2, - OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2, -}; - -enum { - OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4, - OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4, -}; - #define MASK_CP2(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21))) enum { diff --git a/target/mips/translate.h b/target/mips/translate.h index a3f4a56750..1b918a439b 100644 --- a/target/mips/translate.h +++ b/target/mips/translate.h @@ -52,6 +52,77 @@ typedef struct DisasContext { /* MIPS major opcodes */ #define MASK_OP_MAJOR(op) (op & (0x3F << 26)) +#define OPC_CP1 (0x11 << 26) + +/* Coprocessor 1 (rs field) */ +#define MASK_CP1(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21))) + +/* Values for the fmt field in FP instructions */ +enum { + /* 0 - 15 are reserved */ + FMT_S = 16, /* single fp */ + FMT_D = 17, /* double fp */ + FMT_E = 18, /* extended fp */ + FMT_Q = 19, /* quad fp */ + FMT_W = 20, /* 32-bit fixed */ + FMT_L = 21, /* 64-bit fixed */ + FMT_PS = 22, /* paired single fp */ + /* 23 - 31 are reserved */ +}; + +enum { + OPC_MFC1 = (0x00 << 21) | OPC_CP1, + OPC_DMFC1 = (0x01 << 21) | OPC_CP1, + OPC_CFC1 = (0x02 << 21) | OPC_CP1, + OPC_MFHC1 = (0x03 << 21) | OPC_CP1, + OPC_MTC1 = (0x04 << 21) | OPC_CP1, + OPC_DMTC1 = (0x05 << 21) | OPC_CP1, + OPC_CTC1 = (0x06 << 21) | OPC_CP1, + OPC_MTHC1 = (0x07 << 21) | OPC_CP1, + OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */ + OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1, + OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1, + OPC_BZ_V = (0x0B << 21) | OPC_CP1, + OPC_BNZ_V = (0x0F << 21) | OPC_CP1, + OPC_S_FMT = (FMT_S << 21) | OPC_CP1, + OPC_D_FMT = (FMT_D << 21) | OPC_CP1, + OPC_E_FMT = (FMT_E << 21) | OPC_CP1, + OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1, + OPC_W_FMT = (FMT_W << 21) | OPC_CP1, + OPC_L_FMT = (FMT_L << 21) | OPC_CP1, + OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1, + OPC_BC1EQZ = (0x09 << 21) | OPC_CP1, + OPC_BC1NEZ = (0x0D << 21) | OPC_CP1, + OPC_BZ_B = (0x18 << 21) | OPC_CP1, + OPC_BZ_H = (0x19 << 21) | OPC_CP1, + OPC_BZ_W = (0x1A << 21) | OPC_CP1, + OPC_BZ_D = (0x1B << 21) | OPC_CP1, + OPC_BNZ_B = (0x1C << 21) | OPC_CP1, + OPC_BNZ_H = (0x1D << 21) | OPC_CP1, + OPC_BNZ_W = (0x1E << 21) | OPC_CP1, + OPC_BNZ_D = (0x1F << 21) | OPC_CP1, +}; + +#define MASK_CP1_FUNC(op) (MASK_CP1(op) | (op & 0x3F)) +#define MASK_BC1(op) (MASK_CP1(op) | (op & (0x3 << 16))) + +enum { + OPC_BC1F = (0x00 << 16) | OPC_BC1, + OPC_BC1T = (0x01 << 16) | OPC_BC1, + OPC_BC1FL = (0x02 << 16) | OPC_BC1, + OPC_BC1TL = (0x03 << 16) | OPC_BC1, +}; + +enum { + OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2, + OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2, +}; + +enum { + OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4, + OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4, +}; + void generate_exception(DisasContext *ctx, int excp); void generate_exception_err(DisasContext *ctx, int excp, int err); void generate_exception_end(DisasContext *ctx, int excp); -- cgit v1.2.3-55-g7522 From 8b7322add375fb13d199079368bc84e4619478fa Mon Sep 17 00:00:00 2001 From: Philippe Mathieu-Daudé Date: Sun, 6 Dec 2020 23:45:09 +0100 Subject: target/mips: Only build TCG code when CONFIG_TCG is set Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20201206233949.3783184-20-f4bug@amsat.org> --- target/mips/meson.build | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/target/mips/meson.build b/target/mips/meson.build index 5a49951c6d..596eb1aeeb 100644 --- a/target/mips/meson.build +++ b/target/mips/meson.build @@ -1,9 +1,11 @@ mips_ss = ss.source_set() mips_ss.add(files( 'cpu.c', + 'gdbstub.c', +)) +mips_ss.add(when: 'CONFIG_TCG', if_true: files( 'dsp_helper.c', 'fpu_helper.c', - 'gdbstub.c', 'lmmi_helper.c', 'msa_helper.c', 'op_helper.c', @@ -15,11 +17,13 @@ mips_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c')) mips_softmmu_ss = ss.source_set() mips_softmmu_ss.add(files( 'addr.c', - 'cp0_helper.c', 'cp0_timer.c', 'machine.c', 'mips-semi.c', )) +mips_softmmu_ss.add(when: 'CONFIG_TCG', if_true: files( + 'cp0_helper.c', +)) target_arch += {'mips': mips_ss} target_softmmu_arch += {'mips': mips_softmmu_ss} -- cgit v1.2.3-55-g7522 From 311edee771510436fc70b2e4fbe5f9fd3cf3d14d Mon Sep 17 00:00:00 2001 From: Philippe Mathieu-Daudé Date: Wed, 9 Dec 2020 14:16:01 +0100 Subject: target/mips/translate: Extract decode_opc_legacy() from decode_opc() As we will slowly move to decodetree generated decoders, extract the legacy decoding from decode_opc(), so new decoders are added in decode_opc() while old code is removed from decode_opc_legacy(). Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20201215225757.764263-2-f4bug@amsat.org> --- target/mips/translate.c | 49 +++++++++++++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/target/mips/translate.c b/target/mips/translate.c index 4c400ec0b3..d4d5d294f3 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -30517,30 +30517,13 @@ static void gen_msa(CPUMIPSState *env, DisasContext *ctx) } -static void decode_opc(CPUMIPSState *env, DisasContext *ctx) +static bool decode_opc_legacy(CPUMIPSState *env, DisasContext *ctx) { int32_t offset; int rs, rt, rd, sa; uint32_t op, op1; int16_t imm; - /* make sure instructions are on a word boundary */ - if (ctx->base.pc_next & 0x3) { - env->CP0_BadVAddr = ctx->base.pc_next; - generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL); - return; - } - - /* Handle blikely not taken case */ - if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) { - TCGLabel *l1 = gen_new_label(); - - tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1); - tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK); - gen_goto_tb(ctx, 1, ctx->base.pc_next + 4); - gen_set_label(l1); - } - op = MASK_OP_MAJOR(ctx->opcode); rs = (ctx->opcode >> 21) & 0x1f; rt = (ctx->opcode >> 16) & 0x1f; @@ -31268,9 +31251,35 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) break; default: /* Invalid */ MIPS_INVAL("major opcode"); - gen_reserved_instruction(ctx); - break; + return false; } + return true; +} + +static void decode_opc(CPUMIPSState *env, DisasContext *ctx) +{ + /* make sure instructions are on a word boundary */ + if (ctx->base.pc_next & 0x3) { + env->CP0_BadVAddr = ctx->base.pc_next; + generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL); + return; + } + + /* Handle blikely not taken case */ + if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) { + TCGLabel *l1 = gen_new_label(); + + tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1); + tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK); + gen_goto_tb(ctx, 1, ctx->base.pc_next + 4); + gen_set_label(l1); + } + + if (decode_opc_legacy(env, ctx)) { + return; + } + + gen_reserved_instruction(ctx); } static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) -- cgit v1.2.3-55-g7522 From d7efb69382cde8f29cd37df321b399542db9fdd2 Mon Sep 17 00:00:00 2001 From: Philippe Mathieu-Daudé Date: Tue, 15 Dec 2020 00:54:34 +0100 Subject: target/mips/translate: Expose check_mips_64() to 32-bit mode To allow compiling 64-bit specific translation code more generically (and removing #ifdef'ry), allow compiling check_mips_64() on 32-bit targets. If ever called on 32-bit, we obviously emit a reserved instruction exception. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Jiaxun Yang Message-Id: <20201215225757.764263-3-f4bug@amsat.org> --- target/mips/translate.c | 8 +++----- target/mips/translate.h | 2 -- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/target/mips/translate.c b/target/mips/translate.c index d4d5d294f3..7e8afb363a 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -2971,18 +2971,16 @@ static inline void check_ps(DisasContext *ctx) check_cp1_64bitmode(ctx); } -#ifdef TARGET_MIPS64 /* - * This code generates a "reserved instruction" exception if 64-bit - * instructions are not enabled. + * This code generates a "reserved instruction" exception if cpu is not + * 64-bit or 64-bit instructions are not enabled. */ void check_mips_64(DisasContext *ctx) { - if (unlikely(!(ctx->hflags & MIPS_HFLAG_64))) { + if (unlikely((TARGET_LONG_BITS != 64) || !(ctx->hflags & MIPS_HFLAG_64))) { gen_reserved_instruction(ctx); } } -#endif #ifndef CONFIG_USER_ONLY static inline void check_mvh(DisasContext *ctx) diff --git a/target/mips/translate.h b/target/mips/translate.h index 1b918a439b..60e59675ef 100644 --- a/target/mips/translate.h +++ b/target/mips/translate.h @@ -129,9 +129,7 @@ void generate_exception_end(DisasContext *ctx, int excp); void gen_reserved_instruction(DisasContext *ctx); void check_insn(DisasContext *ctx, uint64_t flags); -#ifdef TARGET_MIPS64 void check_mips_64(DisasContext *ctx); -#endif void check_cp0_enabled(DisasContext *ctx); void check_cp1_enabled(DisasContext *ctx); void check_cp1_64bitmode(DisasContext *ctx); -- cgit v1.2.3-55-g7522 From 25a1362875874936c185eba72203de6e9581251e Mon Sep 17 00:00:00 2001 From: Philippe Mathieu-Daudé Date: Sun, 29 Nov 2020 23:22:20 +0100 Subject: target/mips: Introduce ase_msa_available() helper Instead of accessing CP0_Config3 directly and checking the 'MSA Present' bit, introduce an explicit helper, making the code easier to read. Reviewed-by: Jiaxun Yang Reviewed-by: Richard Henderson Signed-off-by: Philippe Mathieu-Daudé Tested-by: Jiaxun Yang Message-Id: <20201208003702.4088927-2-f4bug@amsat.org> --- target/mips/cpu.c | 2 +- target/mips/cpu.h | 6 ++++++ target/mips/kvm.c | 12 ++++++------ target/mips/translate.c | 6 ++---- 4 files changed, 15 insertions(+), 11 deletions(-) diff --git a/target/mips/cpu.c b/target/mips/cpu.c index f3bf0466a4..0643a5784c 100644 --- a/target/mips/cpu.c +++ b/target/mips/cpu.c @@ -533,7 +533,7 @@ static void mips_cpu_reset(DeviceState *dev) } /* MSA */ - if (env->CP0_Config3 & (1 << CP0C3_MSAP)) { + if (ase_msa_available(env)) { msa_reset(env); } diff --git a/target/mips/cpu.h b/target/mips/cpu.h index 9c45744c5c..b9e227a30e 100644 --- a/target/mips/cpu.h +++ b/target/mips/cpu.h @@ -1299,6 +1299,12 @@ bool cpu_type_supports_cps_smp(const char *cpu_type); bool cpu_supports_isa(const CPUMIPSState *env, uint64_t isa_mask); bool cpu_type_supports_isa(const char *cpu_type, uint64_t isa); +/* Check presence of MSA implementation */ +static inline bool ase_msa_available(CPUMIPSState *env) +{ + return env->CP0_Config3 & (1 << CP0C3_MSAP); +} + /* Check presence of multi-threading ASE implementation */ static inline bool ase_mt_available(CPUMIPSState *env) { diff --git a/target/mips/kvm.c b/target/mips/kvm.c index a5b6fe35db..84fb10ea35 100644 --- a/target/mips/kvm.c +++ b/target/mips/kvm.c @@ -79,7 +79,7 @@ int kvm_arch_init_vcpu(CPUState *cs) } } - if (kvm_mips_msa_cap && env->CP0_Config3 & (1 << CP0C3_MSAP)) { + if (kvm_mips_msa_cap && ase_msa_available(env)) { ret = kvm_vcpu_enable_cap(cs, KVM_CAP_MIPS_MSA, 0, 0); if (ret < 0) { /* mark unsupported so it gets disabled on reset */ @@ -105,7 +105,7 @@ void kvm_mips_reset_vcpu(MIPSCPU *cpu) warn_report("KVM does not support FPU, disabling"); env->CP0_Config1 &= ~(1 << CP0C1_FP); } - if (!kvm_mips_msa_cap && env->CP0_Config3 & (1 << CP0C3_MSAP)) { + if (!kvm_mips_msa_cap && ase_msa_available(env)) { warn_report("KVM does not support MSA, disabling"); env->CP0_Config3 &= ~(1 << CP0C3_MSAP); } @@ -618,7 +618,7 @@ static int kvm_mips_put_fpu_registers(CPUState *cs, int level) * FPU register state is a subset of MSA vector state, so don't put FPU * registers if we're emulating a CPU with MSA. */ - if (!(env->CP0_Config3 & (1 << CP0C3_MSAP))) { + if (!ase_msa_available(env)) { /* Floating point registers */ for (i = 0; i < 32; ++i) { if (env->CP0_Status & (1 << CP0St_FR)) { @@ -637,7 +637,7 @@ static int kvm_mips_put_fpu_registers(CPUState *cs, int level) } /* Only put MSA state if we're emulating a CPU with MSA */ - if (env->CP0_Config3 & (1 << CP0C3_MSAP)) { + if (ase_msa_available(env)) { /* MSA Control Registers */ if (level == KVM_PUT_FULL_STATE) { err = kvm_mips_put_one_reg(cs, KVM_REG_MIPS_MSA_IR, @@ -698,7 +698,7 @@ static int kvm_mips_get_fpu_registers(CPUState *cs) * FPU register state is a subset of MSA vector state, so don't save FPU * registers if we're emulating a CPU with MSA. */ - if (!(env->CP0_Config3 & (1 << CP0C3_MSAP))) { + if (!ase_msa_available(env)) { /* Floating point registers */ for (i = 0; i < 32; ++i) { if (env->CP0_Status & (1 << CP0St_FR)) { @@ -717,7 +717,7 @@ static int kvm_mips_get_fpu_registers(CPUState *cs) } /* Only get MSA state if we're emulating a CPU with MSA */ - if (env->CP0_Config3 & (1 << CP0C3_MSAP)) { + if (ase_msa_available(env)) { /* MSA Control Registers */ err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_MSA_IR, &env->msair); diff --git a/target/mips/translate.c b/target/mips/translate.c index 7e8afb363a..d87fbaf0ec 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -24919,8 +24919,7 @@ static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx) gen_trap(ctx, op1, rs, rt, -1); break; case OPC_LSA: /* OPC_PMON */ - if ((ctx->insn_flags & ISA_MIPS_R6) || - (env->CP0_Config3 & (1 << CP0C3_MSAP))) { + if ((ctx->insn_flags & ISA_MIPS_R6) || ase_msa_available(env)) { decode_opc_special_r6(env, ctx); } else { /* Pmon entry point, also R4010 selsl */ @@ -25022,8 +25021,7 @@ static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx) } break; case OPC_DLSA: - if ((ctx->insn_flags & ISA_MIPS_R6) || - (env->CP0_Config3 & (1 << CP0C3_MSAP))) { + if ((ctx->insn_flags & ISA_MIPS_R6) || ase_msa_available(env)) { decode_opc_special_r6(env, ctx); } break; -- cgit v1.2.3-55-g7522 From 72f31f60f829980ad22da8049bb41af0dc49c3f4 Mon Sep 17 00:00:00 2001 From: Philippe Mathieu-Daudé Date: Sun, 29 Nov 2020 23:57:02 +0100 Subject: target/mips: Simplify msa_reset() Call msa_reset() unconditionally, but only reset the MSA registers if MSA is implemented. Reviewed-by: Jiaxun Yang Reviewed-by: Richard Henderson Signed-off-by: Philippe Mathieu-Daudé Tested-by: Jiaxun Yang Message-Id: <20201208003702.4088927-3-f4bug@amsat.org> --- target/mips/cpu-defs.c.inc | 4 ++++ target/mips/cpu.c | 5 +---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/target/mips/cpu-defs.c.inc b/target/mips/cpu-defs.c.inc index 535d4c0c70..fe0f47aadf 100644 --- a/target/mips/cpu-defs.c.inc +++ b/target/mips/cpu-defs.c.inc @@ -978,6 +978,10 @@ static void mvp_init(CPUMIPSState *env) static void msa_reset(CPUMIPSState *env) { + if (!ase_msa_available(env)) { + return; + } + #ifdef CONFIG_USER_ONLY /* MSA access enabled */ env->CP0_Config5 |= 1 << CP0C5_MSAEn; diff --git a/target/mips/cpu.c b/target/mips/cpu.c index 0643a5784c..001b1b88e2 100644 --- a/target/mips/cpu.c +++ b/target/mips/cpu.c @@ -532,10 +532,7 @@ static void mips_cpu_reset(DeviceState *dev) env->hflags |= MIPS_HFLAG_M16; } - /* MSA */ - if (ase_msa_available(env)) { - msa_reset(env); - } + msa_reset(env); compute_hflags(env); restore_fp_status(env); -- cgit v1.2.3-55-g7522 From aa314198ca8d51e5c250e83a5cf160b38db6a7d9 Mon Sep 17 00:00:00 2001 From: Philippe Mathieu-Daudé Date: Sun, 29 Nov 2020 23:32:27 +0100 Subject: target/mips: Use CP0_Config3 to set MIPS_HFLAG_MSA MSA presence is expressed by the MSAP bit of CP0_Config3. We don't need to check anything else. Reviewed-by: Jiaxun Yang Reviewed-by: Richard Henderson Signed-off-by: Philippe Mathieu-Daudé Tested-by: Jiaxun Yang Message-Id: <20201208003702.4088927-4-f4bug@amsat.org> --- target/mips/internal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/mips/internal.h b/target/mips/internal.h index 9a7698019e..1048781bcf 100644 --- a/target/mips/internal.h +++ b/target/mips/internal.h @@ -378,7 +378,7 @@ static inline void compute_hflags(CPUMIPSState *env) env->hflags |= MIPS_HFLAG_COP1X; } } - if (env->insn_flags & ASE_MSA) { + if (ase_msa_available(env)) { if (env->CP0_Config5 & (1 << CP0C5_MSAEn)) { env->hflags |= MIPS_HFLAG_MSA; } -- cgit v1.2.3-55-g7522 From 33942f94604153af66f50ad0bc41edc620e82d51 Mon Sep 17 00:00:00 2001 From: Philippe Mathieu-Daudé Date: Sun, 29 Nov 2020 23:39:04 +0100 Subject: target/mips: Simplify MSA TCG logic Only decode MSA opcodes if MSA is present (implemented). Now than check_msa_access() will only be called if MSA is present, the only way to have MIPS_HFLAG_MSA unset is if MSA is disabled (bit CP0C5_MSAEn cleared, see previous commit). Therefore we can remove the 'reserved instruction' exception. Reviewed-by: Jiaxun Yang Reviewed-by: Richard Henderson Signed-off-by: Philippe Mathieu-Daudé Tested-by: Jiaxun Yang Message-Id: <20201208003702.4088927-5-f4bug@amsat.org> --- target/mips/translate.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/target/mips/translate.c b/target/mips/translate.c index d87fbaf0ec..9a0dcde2a0 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -28567,13 +28567,8 @@ static inline int check_msa_access(DisasContext *ctx) } if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) { - if (ctx->insn_flags & ASE_MSA) { - generate_exception_end(ctx, EXCP_MSADIS); - return 0; - } else { - gen_reserved_instruction(ctx); - return 0; - } + generate_exception_end(ctx, EXCP_MSADIS); + return 0; } return 1; } @@ -30417,7 +30412,7 @@ static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx) static void gen_msa(CPUMIPSState *env, DisasContext *ctx) { uint32_t opcode = ctx->opcode; - check_insn(ctx, ASE_MSA); + check_msa_access(ctx); switch (MASK_MSA_MINOR(opcode)) { @@ -31047,9 +31042,11 @@ static bool decode_opc_legacy(CPUMIPSState *env, DisasContext *ctx) case OPC_BNZ_H: case OPC_BNZ_W: case OPC_BNZ_D: - check_insn(ctx, ASE_MSA); - gen_msa_branch(env, ctx, op1); - break; + if (ase_msa_available(env)) { + gen_msa_branch(env, ctx, op1); + break; + } + /* fall through */ default: MIPS_INVAL("cp1"); gen_reserved_instruction(ctx); @@ -31238,7 +31235,9 @@ static bool decode_opc_legacy(CPUMIPSState *env, DisasContext *ctx) #endif } else { /* MDMX: Not implemented. */ - gen_msa(env, ctx); + if (ase_msa_available(env)) { + gen_msa(env, ctx); + } } break; case OPC_PCREL: -- cgit v1.2.3-55-g7522 From 7e2a619a0436a959fe2795cce829d1cc89448a43 Mon Sep 17 00:00:00 2001 From: Philippe Mathieu-Daudé Date: Sun, 29 Nov 2020 23:32:40 +0100 Subject: target/mips: Remove now unused ASE_MSA definition We don't use ASE_MSA anymore (replaced by ase_msa_available() checking MSAP bit from CP0_Config3). Remove it. Reviewed-by: Jiaxun Yang Reviewed-by: Richard Henderson Signed-off-by: Philippe Mathieu-Daudé Tested-by: Jiaxun Yang Message-Id: <20201208003702.4088927-6-f4bug@amsat.org> --- target/mips/cpu-defs.c.inc | 8 ++++---- target/mips/mips-defs.h | 1 - 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/target/mips/cpu-defs.c.inc b/target/mips/cpu-defs.c.inc index fe0f47aadf..3d44b39477 100644 --- a/target/mips/cpu-defs.c.inc +++ b/target/mips/cpu-defs.c.inc @@ -410,7 +410,7 @@ const mips_def_t mips_defs[] = .CP1_fcr31_rw_bitmask = 0xFF83FFFF, .SEGBITS = 32, .PABITS = 40, - .insn_flags = CPU_MIPS32R5 | ASE_MSA, + .insn_flags = CPU_MIPS32R5, .mmu_type = MMU_TYPE_R4000, }, { @@ -723,7 +723,7 @@ const mips_def_t mips_defs[] = .MSAIR = 0x03 << MSAIR_ProcID, .SEGBITS = 48, .PABITS = 48, - .insn_flags = CPU_MIPS64R6 | ASE_MSA, + .insn_flags = CPU_MIPS64R6, .mmu_type = MMU_TYPE_R4000, }, { @@ -763,7 +763,7 @@ const mips_def_t mips_defs[] = .MSAIR = 0x03 << MSAIR_ProcID, .SEGBITS = 48, .PABITS = 48, - .insn_flags = CPU_MIPS64R6 | ASE_MSA, + .insn_flags = CPU_MIPS64R6, .mmu_type = MMU_TYPE_R4000, }, { @@ -889,7 +889,7 @@ const mips_def_t mips_defs[] = .CP1_fcr31_rw_bitmask = 0xFF83FFFF, .SEGBITS = 48, .PABITS = 48, - .insn_flags = CPU_LOONGSON3A | ASE_MSA, + .insn_flags = CPU_LOONGSON3A, .mmu_type = MMU_TYPE_R4000, }, { diff --git a/target/mips/mips-defs.h b/target/mips/mips-defs.h index 97866019a7..6b8e680011 100644 --- a/target/mips/mips-defs.h +++ b/target/mips/mips-defs.h @@ -34,7 +34,6 @@ #define ASE_MT 0x0000000040000000ULL #define ASE_SMARTMIPS 0x0000000080000000ULL #define ASE_MICROMIPS 0x0000000100000000ULL -#define ASE_MSA 0x0000000200000000ULL /* * bits 40-51: vendor-specific base instruction sets */ -- cgit v1.2.3-55-g7522 From e2665f314d80d7edbfe7f8275abed7e2c93c0ddc Mon Sep 17 00:00:00 2001 From: Philippe Mathieu-Daudé Date: Sun, 29 Nov 2020 21:11:00 +0100 Subject: target/mips: Alias MSA vector registers on FPU scalar registers Commits 863f264d10f ("add msa_reset(), global msa register") and cb269f273fd ("fix multiple TCG registers covering same data") removed the FPU scalar registers and replaced them by aliases to the MSA vector registers. It is not very clear to have FPU registers displayed with MSA register names, even if MSA ASE is not present. Instead of aliasing FPU registers to the MSA ones (even when MSA is absent), we now alias the MSA ones to the FPU ones (only when MSA is present). Reviewed-by: Jiaxun Yang Reviewed-by: Richard Henderson Signed-off-by: Philippe Mathieu-Daudé Tested-by: Jiaxun Yang Message-Id: <20201208003702.4088927-7-f4bug@amsat.org> --- target/mips/translate.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/target/mips/translate.c b/target/mips/translate.c index 9a0dcde2a0..f1d4256081 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -31562,16 +31562,20 @@ void mips_tcg_init(void) offsetof(CPUMIPSState, active_tc.gpr[i]), regnames[i]); + for (i = 0; i < 32; i++) { + int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]); + fpu_f64[i] = tcg_global_mem_new_i64(cpu_env, off, fregnames[i]); + } + /* MSA */ for (i = 0; i < 32; i++) { int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]); - msa_wr_d[i * 2] = - tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2]); + /* - * The scalar floating-point unit (FPU) registers are mapped on - * the MSA vector registers. + * The MSA vector registers are mapped on the + * scalar floating-point unit (FPU) registers. */ - fpu_f64[i] = msa_wr_d[i * 2]; + msa_wr_d[i * 2] = fpu_f64[i]; off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]); msa_wr_d[i * 2 + 1] = tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2 + 1]); -- cgit v1.2.3-55-g7522 From 959c5da28e7e1ae59e122f952fdbad02fb754cad Mon Sep 17 00:00:00 2001 From: Philippe Mathieu-Daudé Date: Sun, 29 Nov 2020 21:12:53 +0100 Subject: target/mips: Extract msa_translate_init() from mips_tcg_init() The msa_wr_d[] registers are only initialized/used by MSA. They are declared static. We want to move them to the new 'msa_translate.c' unit in few commits, without having to declare them global (with extern). Extract first the logic initialization of the MSA registers from the generic initialization. We will later move this function along with the MSA registers to the new C unit. Reviewed-by: Jiaxun Yang Reviewed-by: Richard Henderson Signed-off-by: Philippe Mathieu-Daudé Tested-by: Jiaxun Yang Message-Id: <20201208003702.4088927-8-f4bug@amsat.org> --- target/mips/translate.c | 31 ++++++++++++++++++------------- target/mips/translate.h | 3 +++ 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/target/mips/translate.c b/target/mips/translate.c index f1d4256081..0df7f7a980 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -31552,22 +31552,10 @@ void mips_cpu_dump_state(CPUState *cs, FILE *f, int flags) } } -void mips_tcg_init(void) +void msa_translate_init(void) { int i; - cpu_gpr[0] = NULL; - for (i = 1; i < 32; i++) - cpu_gpr[i] = tcg_global_mem_new(cpu_env, - offsetof(CPUMIPSState, - active_tc.gpr[i]), - regnames[i]); - for (i = 0; i < 32; i++) { - int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]); - - fpu_f64[i] = tcg_global_mem_new_i64(cpu_env, off, fregnames[i]); - } - /* MSA */ for (i = 0; i < 32; i++) { int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]); @@ -31580,7 +31568,24 @@ void mips_tcg_init(void) msa_wr_d[i * 2 + 1] = tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2 + 1]); } +} + +void mips_tcg_init(void) +{ + int i; + + cpu_gpr[0] = NULL; + for (i = 1; i < 32; i++) + cpu_gpr[i] = tcg_global_mem_new(cpu_env, + offsetof(CPUMIPSState, + active_tc.gpr[i]), + regnames[i]); + for (i = 0; i < 32; i++) { + int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]); + fpu_f64[i] = tcg_global_mem_new_i64(cpu_env, off, fregnames[i]); + } + msa_translate_init(); cpu_PC = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, active_tc.PC), "PC"); for (i = 0; i < MIPS_DSP_ACC; i++) { diff --git a/target/mips/translate.h b/target/mips/translate.h index 60e59675ef..190d415c3b 100644 --- a/target/mips/translate.h +++ b/target/mips/translate.h @@ -172,4 +172,7 @@ extern TCGv bcond; } \ } while (0) +/* MSA */ +void msa_translate_init(void); + #endif -- cgit v1.2.3-55-g7522 From 63af5b9018e2983364d7cb4b0047cb8f566fcfe9 Mon Sep 17 00:00:00 2001 From: Philippe Mathieu-Daudé Date: Sun, 29 Nov 2020 21:16:49 +0100 Subject: target/mips: Remove CPUMIPSState* argument from gen_msa*() methods The gen_msa*() methods don't use the "CPUMIPSState *env" argument. Remove it to simplify. Reviewed-by: Jiaxun Yang Reviewed-by: Richard Henderson Signed-off-by: Philippe Mathieu-Daudé Tested-by: Jiaxun Yang Message-Id: <20201208003702.4088927-9-f4bug@amsat.org> --- target/mips/translate.c | 57 ++++++++++++++++++++++++------------------------- 1 file changed, 28 insertions(+), 29 deletions(-) diff --git a/target/mips/translate.c b/target/mips/translate.c index 0df7f7a980..2b0bd8769a 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -28614,7 +28614,7 @@ static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt) tcg_temp_free_i64(t1); } -static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1) +static void gen_msa_branch(DisasContext *ctx, uint32_t op1) { uint8_t df = (ctx->opcode >> 21) & 0x3; uint8_t wt = (ctx->opcode >> 16) & 0x1f; @@ -28659,7 +28659,7 @@ static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1) ctx->hflags |= MIPS_HFLAG_BDS32; } -static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx) +static void gen_msa_i8(DisasContext *ctx) { #define MASK_MSA_I8(op) (MASK_MSA_MINOR(op) | (op & (0x03 << 24))) uint8_t i8 = (ctx->opcode >> 16) & 0xff; @@ -28717,7 +28717,7 @@ static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx) tcg_temp_free_i32(ti8); } -static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx) +static void gen_msa_i5(DisasContext *ctx) { #define MASK_MSA_I5(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23))) uint8_t df = (ctx->opcode >> 21) & 0x3; @@ -28790,7 +28790,7 @@ static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx) tcg_temp_free_i32(timm); } -static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx) +static void gen_msa_bit(DisasContext *ctx) { #define MASK_MSA_BIT(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23))) uint8_t dfm = (ctx->opcode >> 16) & 0x7f; @@ -28874,7 +28874,7 @@ static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx) tcg_temp_free_i32(tws); } -static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx) +static void gen_msa_3r(DisasContext *ctx) { #define MASK_MSA_3R(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23))) uint8_t df = (ctx->opcode >> 21) & 0x3; @@ -29856,7 +29856,7 @@ static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx) tcg_temp_free_i32(tdf); } -static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx) +static void gen_msa_elm_3e(DisasContext *ctx) { #define MASK_MSA_ELM_DF3E(op) (MASK_MSA_MINOR(op) | (op & (0x3FF << 16))) uint8_t source = (ctx->opcode >> 11) & 0x1f; @@ -29888,8 +29888,7 @@ static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx) tcg_temp_free_i32(tsr); } -static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df, - uint32_t n) +static void gen_msa_elm_df(DisasContext *ctx, uint32_t df, uint32_t n) { #define MASK_MSA_ELM(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22))) uint8_t ws = (ctx->opcode >> 11) & 0x1f; @@ -29999,7 +29998,7 @@ static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df, tcg_temp_free_i32(tdf); } -static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx) +static void gen_msa_elm(DisasContext *ctx) { uint8_t dfn = (ctx->opcode >> 16) & 0x3f; uint32_t df = 0, n = 0; @@ -30018,17 +30017,17 @@ static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx) df = DF_DOUBLE; } else if (dfn == 0x3E) { /* CTCMSA, CFCMSA, MOVE.V */ - gen_msa_elm_3e(env, ctx); + gen_msa_elm_3e(ctx); return; } else { gen_reserved_instruction(ctx); return; } - gen_msa_elm_df(env, ctx, df, n); + gen_msa_elm_df(ctx, df, n); } -static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx) +static void gen_msa_3rf(DisasContext *ctx) { #define MASK_MSA_3RF(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22))) uint8_t df = (ctx->opcode >> 21) & 0x1; @@ -30186,7 +30185,7 @@ static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx) tcg_temp_free_i32(tdf); } -static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx) +static void gen_msa_2r(DisasContext *ctx) { #define MASK_MSA_2R(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \ (op & (0x7 << 18))) @@ -30270,7 +30269,7 @@ static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx) tcg_temp_free_i32(tdf); } -static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx) +static void gen_msa_2rf(DisasContext *ctx) { #define MASK_MSA_2RF(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \ (op & (0xf << 17))) @@ -30341,7 +30340,7 @@ static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx) tcg_temp_free_i32(tdf); } -static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx) +static void gen_msa_vec_v(DisasContext *ctx) { #define MASK_MSA_VEC(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21))) uint8_t wt = (ctx->opcode >> 16) & 0x1f; @@ -30384,7 +30383,7 @@ static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx) tcg_temp_free_i32(twt); } -static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx) +static void gen_msa_vec(DisasContext *ctx) { switch (MASK_MSA_VEC(ctx->opcode)) { case OPC_AND_V: @@ -30394,13 +30393,13 @@ static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx) case OPC_BMNZ_V: case OPC_BMZ_V: case OPC_BSEL_V: - gen_msa_vec_v(env, ctx); + gen_msa_vec_v(ctx); break; case OPC_MSA_2R: - gen_msa_2r(env, ctx); + gen_msa_2r(ctx); break; case OPC_MSA_2RF: - gen_msa_2rf(env, ctx); + gen_msa_2rf(ctx); break; default: MIPS_INVAL("MSA instruction"); @@ -30409,7 +30408,7 @@ static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx) } } -static void gen_msa(CPUMIPSState *env, DisasContext *ctx) +static void gen_msa(DisasContext *ctx) { uint32_t opcode = ctx->opcode; @@ -30419,15 +30418,15 @@ static void gen_msa(CPUMIPSState *env, DisasContext *ctx) case OPC_MSA_I8_00: case OPC_MSA_I8_01: case OPC_MSA_I8_02: - gen_msa_i8(env, ctx); + gen_msa_i8(ctx); break; case OPC_MSA_I5_06: case OPC_MSA_I5_07: - gen_msa_i5(env, ctx); + gen_msa_i5(ctx); break; case OPC_MSA_BIT_09: case OPC_MSA_BIT_0A: - gen_msa_bit(env, ctx); + gen_msa_bit(ctx); break; case OPC_MSA_3R_0D: case OPC_MSA_3R_0E: @@ -30438,18 +30437,18 @@ static void gen_msa(CPUMIPSState *env, DisasContext *ctx) case OPC_MSA_3R_13: case OPC_MSA_3R_14: case OPC_MSA_3R_15: - gen_msa_3r(env, ctx); + gen_msa_3r(ctx); break; case OPC_MSA_ELM: - gen_msa_elm(env, ctx); + gen_msa_elm(ctx); break; case OPC_MSA_3RF_1A: case OPC_MSA_3RF_1B: case OPC_MSA_3RF_1C: - gen_msa_3rf(env, ctx); + gen_msa_3rf(ctx); break; case OPC_MSA_VEC: - gen_msa_vec(env, ctx); + gen_msa_vec(ctx); break; case OPC_LD_B: case OPC_LD_H: @@ -31043,7 +31042,7 @@ static bool decode_opc_legacy(CPUMIPSState *env, DisasContext *ctx) case OPC_BNZ_W: case OPC_BNZ_D: if (ase_msa_available(env)) { - gen_msa_branch(env, ctx, op1); + gen_msa_branch(ctx, op1); break; } /* fall through */ @@ -31236,7 +31235,7 @@ static bool decode_opc_legacy(CPUMIPSState *env, DisasContext *ctx) } else { /* MDMX: Not implemented. */ if (ase_msa_available(env)) { - gen_msa(env, ctx); + gen_msa(ctx); } } break; -- cgit v1.2.3-55-g7522 From 810fda17c8ea9b93f7c2bcc48e70cf7a3dbc7e91 Mon Sep 17 00:00:00 2001 From: Philippe Mathieu-Daudé Date: Mon, 30 Nov 2020 14:03:31 +0100 Subject: target/mips: Explode gen_msa_branch() as gen_msa_BxZ_V/BxZ() In preparation of using the decodetree script, explode gen_msa_branch() as following: - OPC_BZ_V -> BxZ_V(EQ) - OPC_BNZ_V -> BxZ_V(NE) - OPC_BZ_[BHWD] -> BxZ(false) - OPC_BNZ_[BHWD] -> BxZ(true) Reviewed-by: Jiaxun Yang Reviewed-by: Richard Henderson Signed-off-by: Philippe Mathieu-Daudé Tested-by: Jiaxun Yang Message-Id: <20201208003702.4088927-10-f4bug@amsat.org> --- target/mips/translate.c | 69 ++++++++++++++++++++++++++++++++++--------------- 1 file changed, 48 insertions(+), 21 deletions(-) diff --git a/target/mips/translate.c b/target/mips/translate.c index 2b0bd8769a..67418621bc 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -28614,49 +28614,76 @@ static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt) tcg_temp_free_i64(t1); } -static void gen_msa_branch(DisasContext *ctx, uint32_t op1) +static bool gen_msa_BxZ_V(DisasContext *ctx, int wt, int s16, TCGCond cond) { - uint8_t df = (ctx->opcode >> 21) & 0x3; - uint8_t wt = (ctx->opcode >> 16) & 0x1f; - int64_t s16 = (int16_t)ctx->opcode; + TCGv_i64 t0; check_msa_access(ctx); if (ctx->hflags & MIPS_HFLAG_BMASK) { gen_reserved_instruction(ctx); - return; + return true; + } + t0 = tcg_temp_new_i64(); + tcg_gen_or_i64(t0, msa_wr_d[wt << 1], msa_wr_d[(wt << 1) + 1]); + tcg_gen_setcondi_i64(cond, t0, t0, 0); + tcg_gen_trunc_i64_tl(bcond, t0); + tcg_temp_free_i64(t0); + + ctx->btarget = ctx->base.pc_next + (s16 << 2) + 4; + + ctx->hflags |= MIPS_HFLAG_BC; + ctx->hflags |= MIPS_HFLAG_BDS32; + + return true; +} + +static bool gen_msa_BxZ(DisasContext *ctx, int df, int wt, int s16, bool if_not) +{ + check_msa_access(ctx); + + if (ctx->hflags & MIPS_HFLAG_BMASK) { + gen_reserved_instruction(ctx); + return true; } + + gen_check_zero_element(bcond, df, wt); + if (if_not) { + tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0); + } + + ctx->btarget = ctx->base.pc_next + (s16 << 2) + 4; + ctx->hflags |= MIPS_HFLAG_BC; + ctx->hflags |= MIPS_HFLAG_BDS32; + + return true; +} + +static void gen_msa_branch(DisasContext *ctx, uint32_t op1) +{ + uint8_t df = (ctx->opcode >> 21) & 0x3; + uint8_t wt = (ctx->opcode >> 16) & 0x1f; + int64_t s16 = (int16_t)ctx->opcode; + switch (op1) { case OPC_BZ_V: case OPC_BNZ_V: - { - TCGv_i64 t0 = tcg_temp_new_i64(); - tcg_gen_or_i64(t0, msa_wr_d[wt << 1], msa_wr_d[(wt << 1) + 1]); - tcg_gen_setcondi_i64((op1 == OPC_BZ_V) ? - TCG_COND_EQ : TCG_COND_NE, t0, t0, 0); - tcg_gen_trunc_i64_tl(bcond, t0); - tcg_temp_free_i64(t0); - } + gen_msa_BxZ_V(ctx, wt, s16, (op1 == OPC_BZ_V) ? + TCG_COND_EQ : TCG_COND_NE); break; case OPC_BZ_B: case OPC_BZ_H: case OPC_BZ_W: case OPC_BZ_D: - gen_check_zero_element(bcond, df, wt); + gen_msa_BxZ(ctx, df, wt, s16, false); break; case OPC_BNZ_B: case OPC_BNZ_H: case OPC_BNZ_W: case OPC_BNZ_D: - gen_check_zero_element(bcond, df, wt); - tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0); + gen_msa_BxZ(ctx, df, wt, s16, true); break; } - - ctx->btarget = ctx->base.pc_next + (s16 << 2) + 4; - - ctx->hflags |= MIPS_HFLAG_BC; - ctx->hflags |= MIPS_HFLAG_BDS32; } static void gen_msa_i8(DisasContext *ctx) -- cgit v1.2.3-55-g7522 From 03e4d95c91fb29e27b0248dd18c236c6fcc8dc02 Mon Sep 17 00:00:00 2001 From: Philippe Mathieu-Daudé Date: Mon, 30 Nov 2020 13:47:40 +0100 Subject: target/mips: Move msa_reset() to msa_helper.c translate_init.c.inc mostly contains CPU definitions. msa_reset() doesn't belong here, move it with the MSA helpers. One comment style is updated to avoid checkpatch.pl warning. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20201215225757.764263-15-f4bug@amsat.org> Tested-by: Jiaxun Yang --- target/mips/cpu-defs.c.inc | 36 ------------------------------------ target/mips/cpu.c | 1 + target/mips/internal.h | 2 ++ target/mips/msa_helper.c | 36 ++++++++++++++++++++++++++++++++++++ 4 files changed, 39 insertions(+), 36 deletions(-) diff --git a/target/mips/cpu-defs.c.inc b/target/mips/cpu-defs.c.inc index 3d44b39477..ba22ff4bcd 100644 --- a/target/mips/cpu-defs.c.inc +++ b/target/mips/cpu-defs.c.inc @@ -18,8 +18,6 @@ * License along with this library; if not, see . */ -#include "fpu_helper.h" - /* CPU / CPU family specific config register values. */ /* Have config1, uncached coherency */ @@ -975,37 +973,3 @@ static void mvp_init(CPUMIPSState *env) (0x0 << CP0MVPC1_PCX) | (0x0 << CP0MVPC1_PCP2) | (0x1 << CP0MVPC1_PCP1); } - -static void msa_reset(CPUMIPSState *env) -{ - if (!ase_msa_available(env)) { - return; - } - -#ifdef CONFIG_USER_ONLY - /* MSA access enabled */ - env->CP0_Config5 |= 1 << CP0C5_MSAEn; - env->CP0_Status |= (1 << CP0St_CU1) | (1 << CP0St_FR); -#endif - - /* MSA CSR: - - non-signaling floating point exception mode off (NX bit is 0) - - Cause, Enables, and Flags are all 0 - - round to nearest / ties to even (RM bits are 0) */ - env->active_tc.msacsr = 0; - - restore_msa_fp_status(env); - - /* tininess detected after rounding.*/ - set_float_detect_tininess(float_tininess_after_rounding, - &env->active_tc.msa_fp_status); - - /* clear float_status exception flags */ - set_float_exception_flags(0, &env->active_tc.msa_fp_status); - - /* clear float_status nan mode */ - set_default_nan_mode(0, &env->active_tc.msa_fp_status); - - /* set proper signanling bit meaning ("1" means "quiet") */ - set_snan_bit_is_one(0, &env->active_tc.msa_fp_status); -} diff --git a/target/mips/cpu.c b/target/mips/cpu.c index 001b1b88e2..4c4548233c 100644 --- a/target/mips/cpu.c +++ b/target/mips/cpu.c @@ -33,6 +33,7 @@ #include "hw/qdev-clock.h" #include "hw/semihosting/semihost.h" #include "qapi/qapi-commands-machine-target.h" +#include "fpu_helper.h" #if !defined(CONFIG_USER_ONLY) diff --git a/target/mips/internal.h b/target/mips/internal.h index 1048781bcf..5dd17ff733 100644 --- a/target/mips/internal.h +++ b/target/mips/internal.h @@ -199,6 +199,8 @@ static inline bool cpu_mips_hw_interrupts_pending(CPUMIPSState *env) void mips_tcg_init(void); +void msa_reset(CPUMIPSState *env); + /* cp0_timer.c */ uint32_t cpu_mips_get_count(CPUMIPSState *env); void cpu_mips_store_count(CPUMIPSState *env, uint32_t value); diff --git a/target/mips/msa_helper.c b/target/mips/msa_helper.c index b89b4c4490..f0d728c03f 100644 --- a/target/mips/msa_helper.c +++ b/target/mips/msa_helper.c @@ -8201,3 +8201,39 @@ void helper_msa_ffint_u_df(CPUMIPSState *env, uint32_t df, uint32_t wd, msa_move_v(pwd, pwx); } + +void msa_reset(CPUMIPSState *env) +{ + if (!ase_msa_available(env)) { + return; + } + +#ifdef CONFIG_USER_ONLY + /* MSA access enabled */ + env->CP0_Config5 |= 1 << CP0C5_MSAEn; + env->CP0_Status |= (1 << CP0St_CU1) | (1 << CP0St_FR); +#endif + + /* + * MSA CSR: + * - non-signaling floating point exception mode off (NX bit is 0) + * - Cause, Enables, and Flags are all 0 + * - round to nearest / ties to even (RM bits are 0) + */ + env->active_tc.msacsr = 0; + + restore_msa_fp_status(env); + + /* tininess detected after rounding.*/ + set_float_detect_tininess(float_tininess_after_rounding, + &env->active_tc.msa_fp_status); + + /* clear float_status exception flags */ + set_float_exception_flags(0, &env->active_tc.msa_fp_status); + + /* clear float_status nan mode */ + set_default_nan_mode(0, &env->active_tc.msa_fp_status); + + /* set proper signanling bit meaning ("1" means "quiet") */ + set_snan_bit_is_one(0, &env->active_tc.msa_fp_status); +} -- cgit v1.2.3-55-g7522 From 3ef60574b6b9caecf539408ceb9f7fe6ece1ce08 Mon Sep 17 00:00:00 2001 From: Philippe Mathieu-Daudé Date: Sun, 22 Nov 2020 18:20:04 +0100 Subject: target/mips: Extract MSA helpers from op_helper.c We have ~400 lines of MSA helpers in the generic op_helper.c, move them with the other helpers in 'msa_helper.c'. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20201123204448.3260804-5-f4bug@amsat.org> Tested-by: Jiaxun Yang --- target/mips/msa_helper.c | 393 ++++++++++++++++++++++++++++++++++++++++++++++ target/mips/op_helper.c | 394 ----------------------------------------------- 2 files changed, 393 insertions(+), 394 deletions(-) diff --git a/target/mips/msa_helper.c b/target/mips/msa_helper.c index f0d728c03f..1298a1917c 100644 --- a/target/mips/msa_helper.c +++ b/target/mips/msa_helper.c @@ -22,6 +22,7 @@ #include "internal.h" #include "exec/exec-all.h" #include "exec/helper-proto.h" +#include "exec/memop.h" #include "fpu/softfloat.h" #include "fpu_helper.h" @@ -8202,6 +8203,398 @@ void helper_msa_ffint_u_df(CPUMIPSState *env, uint32_t df, uint32_t wd, msa_move_v(pwd, pwx); } +/* Data format min and max values */ +#define DF_BITS(df) (1 << ((df) + 3)) + +/* Element-by-element access macros */ +#define DF_ELEMENTS(df) (MSA_WRLEN / DF_BITS(df)) + +#if !defined(CONFIG_USER_ONLY) +#define MEMOP_IDX(DF) \ + TCGMemOpIdx oi = make_memop_idx(MO_TE | DF | MO_UNALN, \ + cpu_mmu_index(env, false)); +#else +#define MEMOP_IDX(DF) +#endif + +void helper_msa_ld_b(CPUMIPSState *env, uint32_t wd, + target_ulong addr) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + MEMOP_IDX(DF_BYTE) +#if !defined(CONFIG_USER_ONLY) +#if !defined(HOST_WORDS_BIGENDIAN) + pwd->b[0] = helper_ret_ldub_mmu(env, addr + (0 << DF_BYTE), oi, GETPC()); + pwd->b[1] = helper_ret_ldub_mmu(env, addr + (1 << DF_BYTE), oi, GETPC()); + pwd->b[2] = helper_ret_ldub_mmu(env, addr + (2 << DF_BYTE), oi, GETPC()); + pwd->b[3] = helper_ret_ldub_mmu(env, addr + (3 << DF_BYTE), oi, GETPC()); + pwd->b[4] = helper_ret_ldub_mmu(env, addr + (4 << DF_BYTE), oi, GETPC()); + pwd->b[5] = helper_ret_ldub_mmu(env, addr + (5 << DF_BYTE), oi, GETPC()); + pwd->b[6] = helper_ret_ldub_mmu(env, addr + (6 << DF_BYTE), oi, GETPC()); + pwd->b[7] = helper_ret_ldub_mmu(env, addr + (7 << DF_BYTE), oi, GETPC()); + pwd->b[8] = helper_ret_ldub_mmu(env, addr + (8 << DF_BYTE), oi, GETPC()); + pwd->b[9] = helper_ret_ldub_mmu(env, addr + (9 << DF_BYTE), oi, GETPC()); + pwd->b[10] = helper_ret_ldub_mmu(env, addr + (10 << DF_BYTE), oi, GETPC()); + pwd->b[11] = helper_ret_ldub_mmu(env, addr + (11 << DF_BYTE), oi, GETPC()); + pwd->b[12] = helper_ret_ldub_mmu(env, addr + (12 << DF_BYTE), oi, GETPC()); + pwd->b[13] = helper_ret_ldub_mmu(env, addr + (13 << DF_BYTE), oi, GETPC()); + pwd->b[14] = helper_ret_ldub_mmu(env, addr + (14 << DF_BYTE), oi, GETPC()); + pwd->b[15] = helper_ret_ldub_mmu(env, addr + (15 << DF_BYTE), oi, GETPC()); +#else + pwd->b[0] = helper_ret_ldub_mmu(env, addr + (7 << DF_BYTE), oi, GETPC()); + pwd->b[1] = helper_ret_ldub_mmu(env, addr + (6 << DF_BYTE), oi, GETPC()); + pwd->b[2] = helper_ret_ldub_mmu(env, addr + (5 << DF_BYTE), oi, GETPC()); + pwd->b[3] = helper_ret_ldub_mmu(env, addr + (4 << DF_BYTE), oi, GETPC()); + pwd->b[4] = helper_ret_ldub_mmu(env, addr + (3 << DF_BYTE), oi, GETPC()); + pwd->b[5] = helper_ret_ldub_mmu(env, addr + (2 << DF_BYTE), oi, GETPC()); + pwd->b[6] = helper_ret_ldub_mmu(env, addr + (1 << DF_BYTE), oi, GETPC()); + pwd->b[7] = helper_ret_ldub_mmu(env, addr + (0 << DF_BYTE), oi, GETPC()); + pwd->b[8] = helper_ret_ldub_mmu(env, addr + (15 << DF_BYTE), oi, GETPC()); + pwd->b[9] = helper_ret_ldub_mmu(env, addr + (14 << DF_BYTE), oi, GETPC()); + pwd->b[10] = helper_ret_ldub_mmu(env, addr + (13 << DF_BYTE), oi, GETPC()); + pwd->b[11] = helper_ret_ldub_mmu(env, addr + (12 << DF_BYTE), oi, GETPC()); + pwd->b[12] = helper_ret_ldub_mmu(env, addr + (11 << DF_BYTE), oi, GETPC()); + pwd->b[13] = helper_ret_ldub_mmu(env, addr + (10 << DF_BYTE), oi, GETPC()); + pwd->b[14] = helper_ret_ldub_mmu(env, addr + (9 << DF_BYTE), oi, GETPC()); + pwd->b[15] = helper_ret_ldub_mmu(env, addr + (8 << DF_BYTE), oi, GETPC()); +#endif +#else +#if !defined(HOST_WORDS_BIGENDIAN) + pwd->b[0] = cpu_ldub_data(env, addr + (0 << DF_BYTE)); + pwd->b[1] = cpu_ldub_data(env, addr + (1 << DF_BYTE)); + pwd->b[2] = cpu_ldub_data(env, addr + (2 << DF_BYTE)); + pwd->b[3] = cpu_ldub_data(env, addr + (3 << DF_BYTE)); + pwd->b[4] = cpu_ldub_data(env, addr + (4 << DF_BYTE)); + pwd->b[5] = cpu_ldub_data(env, addr + (5 << DF_BYTE)); + pwd->b[6] = cpu_ldub_data(env, addr + (6 << DF_BYTE)); + pwd->b[7] = cpu_ldub_data(env, addr + (7 << DF_BYTE)); + pwd->b[8] = cpu_ldub_data(env, addr + (8 << DF_BYTE)); + pwd->b[9] = cpu_ldub_data(env, addr + (9 << DF_BYTE)); + pwd->b[10] = cpu_ldub_data(env, addr + (10 << DF_BYTE)); + pwd->b[11] = cpu_ldub_data(env, addr + (11 << DF_BYTE)); + pwd->b[12] = cpu_ldub_data(env, addr + (12 << DF_BYTE)); + pwd->b[13] = cpu_ldub_data(env, addr + (13 << DF_BYTE)); + pwd->b[14] = cpu_ldub_data(env, addr + (14 << DF_BYTE)); + pwd->b[15] = cpu_ldub_data(env, addr + (15 << DF_BYTE)); +#else + pwd->b[0] = cpu_ldub_data(env, addr + (7 << DF_BYTE)); + pwd->b[1] = cpu_ldub_data(env, addr + (6 << DF_BYTE)); + pwd->b[2] = cpu_ldub_data(env, addr + (5 << DF_BYTE)); + pwd->b[3] = cpu_ldub_data(env, addr + (4 << DF_BYTE)); + pwd->b[4] = cpu_ldub_data(env, addr + (3 << DF_BYTE)); + pwd->b[5] = cpu_ldub_data(env, addr + (2 << DF_BYTE)); + pwd->b[6] = cpu_ldub_data(env, addr + (1 << DF_BYTE)); + pwd->b[7] = cpu_ldub_data(env, addr + (0 << DF_BYTE)); + pwd->b[8] = cpu_ldub_data(env, addr + (15 << DF_BYTE)); + pwd->b[9] = cpu_ldub_data(env, addr + (14 << DF_BYTE)); + pwd->b[10] = cpu_ldub_data(env, addr + (13 << DF_BYTE)); + pwd->b[11] = cpu_ldub_data(env, addr + (12 << DF_BYTE)); + pwd->b[12] = cpu_ldub_data(env, addr + (11 << DF_BYTE)); + pwd->b[13] = cpu_ldub_data(env, addr + (10 << DF_BYTE)); + pwd->b[14] = cpu_ldub_data(env, addr + (9 << DF_BYTE)); + pwd->b[15] = cpu_ldub_data(env, addr + (8 << DF_BYTE)); +#endif +#endif +} + +void helper_msa_ld_h(CPUMIPSState *env, uint32_t wd, + target_ulong addr) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + MEMOP_IDX(DF_HALF) +#if !defined(CONFIG_USER_ONLY) +#if !defined(HOST_WORDS_BIGENDIAN) + pwd->h[0] = helper_ret_lduw_mmu(env, addr + (0 << DF_HALF), oi, GETPC()); + pwd->h[1] = helper_ret_lduw_mmu(env, addr + (1 << DF_HALF), oi, GETPC()); + pwd->h[2] = helper_ret_lduw_mmu(env, addr + (2 << DF_HALF), oi, GETPC()); + pwd->h[3] = helper_ret_lduw_mmu(env, addr + (3 << DF_HALF), oi, GETPC()); + pwd->h[4] = helper_ret_lduw_mmu(env, addr + (4 << DF_HALF), oi, GETPC()); + pwd->h[5] = helper_ret_lduw_mmu(env, addr + (5 << DF_HALF), oi, GETPC()); + pwd->h[6] = helper_ret_lduw_mmu(env, addr + (6 << DF_HALF), oi, GETPC()); + pwd->h[7] = helper_ret_lduw_mmu(env, addr + (7 << DF_HALF), oi, GETPC()); +#else + pwd->h[0] = helper_ret_lduw_mmu(env, addr + (3 << DF_HALF), oi, GETPC()); + pwd->h[1] = helper_ret_lduw_mmu(env, addr + (2 << DF_HALF), oi, GETPC()); + pwd->h[2] = helper_ret_lduw_mmu(env, addr + (1 << DF_HALF), oi, GETPC()); + pwd->h[3] = helper_ret_lduw_mmu(env, addr + (0 << DF_HALF), oi, GETPC()); + pwd->h[4] = helper_ret_lduw_mmu(env, addr + (7 << DF_HALF), oi, GETPC()); + pwd->h[5] = helper_ret_lduw_mmu(env, addr + (6 << DF_HALF), oi, GETPC()); + pwd->h[6] = helper_ret_lduw_mmu(env, addr + (5 << DF_HALF), oi, GETPC()); + pwd->h[7] = helper_ret_lduw_mmu(env, addr + (4 << DF_HALF), oi, GETPC()); +#endif +#else +#if !defined(HOST_WORDS_BIGENDIAN) + pwd->h[0] = cpu_lduw_data(env, addr + (0 << DF_HALF)); + pwd->h[1] = cpu_lduw_data(env, addr + (1 << DF_HALF)); + pwd->h[2] = cpu_lduw_data(env, addr + (2 << DF_HALF)); + pwd->h[3] = cpu_lduw_data(env, addr + (3 << DF_HALF)); + pwd->h[4] = cpu_lduw_data(env, addr + (4 << DF_HALF)); + pwd->h[5] = cpu_lduw_data(env, addr + (5 << DF_HALF)); + pwd->h[6] = cpu_lduw_data(env, addr + (6 << DF_HALF)); + pwd->h[7] = cpu_lduw_data(env, addr + (7 << DF_HALF)); +#else + pwd->h[0] = cpu_lduw_data(env, addr + (3 << DF_HALF)); + pwd->h[1] = cpu_lduw_data(env, addr + (2 << DF_HALF)); + pwd->h[2] = cpu_lduw_data(env, addr + (1 << DF_HALF)); + pwd->h[3] = cpu_lduw_data(env, addr + (0 << DF_HALF)); + pwd->h[4] = cpu_lduw_data(env, addr + (7 << DF_HALF)); + pwd->h[5] = cpu_lduw_data(env, addr + (6 << DF_HALF)); + pwd->h[6] = cpu_lduw_data(env, addr + (5 << DF_HALF)); + pwd->h[7] = cpu_lduw_data(env, addr + (4 << DF_HALF)); +#endif +#endif +} + +void helper_msa_ld_w(CPUMIPSState *env, uint32_t wd, + target_ulong addr) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + MEMOP_IDX(DF_WORD) +#if !defined(CONFIG_USER_ONLY) +#if !defined(HOST_WORDS_BIGENDIAN) + pwd->w[0] = helper_ret_ldul_mmu(env, addr + (0 << DF_WORD), oi, GETPC()); + pwd->w[1] = helper_ret_ldul_mmu(env, addr + (1 << DF_WORD), oi, GETPC()); + pwd->w[2] = helper_ret_ldul_mmu(env, addr + (2 << DF_WORD), oi, GETPC()); + pwd->w[3] = helper_ret_ldul_mmu(env, addr + (3 << DF_WORD), oi, GETPC()); +#else + pwd->w[0] = helper_ret_ldul_mmu(env, addr + (1 << DF_WORD), oi, GETPC()); + pwd->w[1] = helper_ret_ldul_mmu(env, addr + (0 << DF_WORD), oi, GETPC()); + pwd->w[2] = helper_ret_ldul_mmu(env, addr + (3 << DF_WORD), oi, GETPC()); + pwd->w[3] = helper_ret_ldul_mmu(env, addr + (2 << DF_WORD), oi, GETPC()); +#endif +#else +#if !defined(HOST_WORDS_BIGENDIAN) + pwd->w[0] = cpu_ldl_data(env, addr + (0 << DF_WORD)); + pwd->w[1] = cpu_ldl_data(env, addr + (1 << DF_WORD)); + pwd->w[2] = cpu_ldl_data(env, addr + (2 << DF_WORD)); + pwd->w[3] = cpu_ldl_data(env, addr + (3 << DF_WORD)); +#else + pwd->w[0] = cpu_ldl_data(env, addr + (1 << DF_WORD)); + pwd->w[1] = cpu_ldl_data(env, addr + (0 << DF_WORD)); + pwd->w[2] = cpu_ldl_data(env, addr + (3 << DF_WORD)); + pwd->w[3] = cpu_ldl_data(env, addr + (2 << DF_WORD)); +#endif +#endif +} + +void helper_msa_ld_d(CPUMIPSState *env, uint32_t wd, + target_ulong addr) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + MEMOP_IDX(DF_DOUBLE) +#if !defined(CONFIG_USER_ONLY) + pwd->d[0] = helper_ret_ldq_mmu(env, addr + (0 << DF_DOUBLE), oi, GETPC()); + pwd->d[1] = helper_ret_ldq_mmu(env, addr + (1 << DF_DOUBLE), oi, GETPC()); +#else + pwd->d[0] = cpu_ldq_data(env, addr + (0 << DF_DOUBLE)); + pwd->d[1] = cpu_ldq_data(env, addr + (1 << DF_DOUBLE)); +#endif +} + +#define MSA_PAGESPAN(x) \ + ((((x) & ~TARGET_PAGE_MASK) + MSA_WRLEN / 8 - 1) >= TARGET_PAGE_SIZE) + +static inline void ensure_writable_pages(CPUMIPSState *env, + target_ulong addr, + int mmu_idx, + uintptr_t retaddr) +{ + /* FIXME: Probe the actual accesses (pass and use a size) */ + if (unlikely(MSA_PAGESPAN(addr))) { + /* first page */ + probe_write(env, addr, 0, mmu_idx, retaddr); + /* second page */ + addr = (addr & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE; + probe_write(env, addr, 0, mmu_idx, retaddr); + } +} + +void helper_msa_st_b(CPUMIPSState *env, uint32_t wd, + target_ulong addr) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + int mmu_idx = cpu_mmu_index(env, false); + + MEMOP_IDX(DF_BYTE) + ensure_writable_pages(env, addr, mmu_idx, GETPC()); +#if !defined(CONFIG_USER_ONLY) +#if !defined(HOST_WORDS_BIGENDIAN) + helper_ret_stb_mmu(env, addr + (0 << DF_BYTE), pwd->b[0], oi, GETPC()); + helper_ret_stb_mmu(env, addr + (1 << DF_BYTE), pwd->b[1], oi, GETPC()); + helper_ret_stb_mmu(env, addr + (2 << DF_BYTE), pwd->b[2], oi, GETPC()); + helper_ret_stb_mmu(env, addr + (3 << DF_BYTE), pwd->b[3], oi, GETPC()); + helper_ret_stb_mmu(env, addr + (4 << DF_BYTE), pwd->b[4], oi, GETPC()); + helper_ret_stb_mmu(env, addr + (5 << DF_BYTE), pwd->b[5], oi, GETPC()); + helper_ret_stb_mmu(env, addr + (6 << DF_BYTE), pwd->b[6], oi, GETPC()); + helper_ret_stb_mmu(env, addr + (7 << DF_BYTE), pwd->b[7], oi, GETPC()); + helper_ret_stb_mmu(env, addr + (8 << DF_BYTE), pwd->b[8], oi, GETPC()); + helper_ret_stb_mmu(env, addr + (9 << DF_BYTE), pwd->b[9], oi, GETPC()); + helper_ret_stb_mmu(env, addr + (10 << DF_BYTE), pwd->b[10], oi, GETPC()); + helper_ret_stb_mmu(env, addr + (11 << DF_BYTE), pwd->b[11], oi, GETPC()); + helper_ret_stb_mmu(env, addr + (12 << DF_BYTE), pwd->b[12], oi, GETPC()); + helper_ret_stb_mmu(env, addr + (13 << DF_BYTE), pwd->b[13], oi, GETPC()); + helper_ret_stb_mmu(env, addr + (14 << DF_BYTE), pwd->b[14], oi, GETPC()); + helper_ret_stb_mmu(env, addr + (15 << DF_BYTE), pwd->b[15], oi, GETPC()); +#else + helper_ret_stb_mmu(env, addr + (7 << DF_BYTE), pwd->b[0], oi, GETPC()); + helper_ret_stb_mmu(env, addr + (6 << DF_BYTE), pwd->b[1], oi, GETPC()); + helper_ret_stb_mmu(env, addr + (5 << DF_BYTE), pwd->b[2], oi, GETPC()); + helper_ret_stb_mmu(env, addr + (4 << DF_BYTE), pwd->b[3], oi, GETPC()); + helper_ret_stb_mmu(env, addr + (3 << DF_BYTE), pwd->b[4], oi, GETPC()); + helper_ret_stb_mmu(env, addr + (2 << DF_BYTE), pwd->b[5], oi, GETPC()); + helper_ret_stb_mmu(env, addr + (1 << DF_BYTE), pwd->b[6], oi, GETPC()); + helper_ret_stb_mmu(env, addr + (0 << DF_BYTE), pwd->b[7], oi, GETPC()); + helper_ret_stb_mmu(env, addr + (15 << DF_BYTE), pwd->b[8], oi, GETPC()); + helper_ret_stb_mmu(env, addr + (14 << DF_BYTE), pwd->b[9], oi, GETPC()); + helper_ret_stb_mmu(env, addr + (13 << DF_BYTE), pwd->b[10], oi, GETPC()); + helper_ret_stb_mmu(env, addr + (12 << DF_BYTE), pwd->b[11], oi, GETPC()); + helper_ret_stb_mmu(env, addr + (11 << DF_BYTE), pwd->b[12], oi, GETPC()); + helper_ret_stb_mmu(env, addr + (10 << DF_BYTE), pwd->b[13], oi, GETPC()); + helper_ret_stb_mmu(env, addr + (9 << DF_BYTE), pwd->b[14], oi, GETPC()); + helper_ret_stb_mmu(env, addr + (8 << DF_BYTE), pwd->b[15], oi, GETPC()); +#endif +#else +#if !defined(HOST_WORDS_BIGENDIAN) + cpu_stb_data(env, addr + (0 << DF_BYTE), pwd->b[0]); + cpu_stb_data(env, addr + (1 << DF_BYTE), pwd->b[1]); + cpu_stb_data(env, addr + (2 << DF_BYTE), pwd->b[2]); + cpu_stb_data(env, addr + (3 << DF_BYTE), pwd->b[3]); + cpu_stb_data(env, addr + (4 << DF_BYTE), pwd->b[4]); + cpu_stb_data(env, addr + (5 << DF_BYTE), pwd->b[5]); + cpu_stb_data(env, addr + (6 << DF_BYTE), pwd->b[6]); + cpu_stb_data(env, addr + (7 << DF_BYTE), pwd->b[7]); + cpu_stb_data(env, addr + (8 << DF_BYTE), pwd->b[8]); + cpu_stb_data(env, addr + (9 << DF_BYTE), pwd->b[9]); + cpu_stb_data(env, addr + (10 << DF_BYTE), pwd->b[10]); + cpu_stb_data(env, addr + (11 << DF_BYTE), pwd->b[11]); + cpu_stb_data(env, addr + (12 << DF_BYTE), pwd->b[12]); + cpu_stb_data(env, addr + (13 << DF_BYTE), pwd->b[13]); + cpu_stb_data(env, addr + (14 << DF_BYTE), pwd->b[14]); + cpu_stb_data(env, addr + (15 << DF_BYTE), pwd->b[15]); +#else + cpu_stb_data(env, addr + (7 << DF_BYTE), pwd->b[0]); + cpu_stb_data(env, addr + (6 << DF_BYTE), pwd->b[1]); + cpu_stb_data(env, addr + (5 << DF_BYTE), pwd->b[2]); + cpu_stb_data(env, addr + (4 << DF_BYTE), pwd->b[3]); + cpu_stb_data(env, addr + (3 << DF_BYTE), pwd->b[4]); + cpu_stb_data(env, addr + (2 << DF_BYTE), pwd->b[5]); + cpu_stb_data(env, addr + (1 << DF_BYTE), pwd->b[6]); + cpu_stb_data(env, addr + (0 << DF_BYTE), pwd->b[7]); + cpu_stb_data(env, addr + (15 << DF_BYTE), pwd->b[8]); + cpu_stb_data(env, addr + (14 << DF_BYTE), pwd->b[9]); + cpu_stb_data(env, addr + (13 << DF_BYTE), pwd->b[10]); + cpu_stb_data(env, addr + (12 << DF_BYTE), pwd->b[11]); + cpu_stb_data(env, addr + (11 << DF_BYTE), pwd->b[12]); + cpu_stb_data(env, addr + (10 << DF_BYTE), pwd->b[13]); + cpu_stb_data(env, addr + (9 << DF_BYTE), pwd->b[14]); + cpu_stb_data(env, addr + (8 << DF_BYTE), pwd->b[15]); +#endif +#endif +} + +void helper_msa_st_h(CPUMIPSState *env, uint32_t wd, + target_ulong addr) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + int mmu_idx = cpu_mmu_index(env, false); + + MEMOP_IDX(DF_HALF) + ensure_writable_pages(env, addr, mmu_idx, GETPC()); +#if !defined(CONFIG_USER_ONLY) +#if !defined(HOST_WORDS_BIGENDIAN) + helper_ret_stw_mmu(env, addr + (0 << DF_HALF), pwd->h[0], oi, GETPC()); + helper_ret_stw_mmu(env, addr + (1 << DF_HALF), pwd->h[1], oi, GETPC()); + helper_ret_stw_mmu(env, addr + (2 << DF_HALF), pwd->h[2], oi, GETPC()); + helper_ret_stw_mmu(env, addr + (3 << DF_HALF), pwd->h[3], oi, GETPC()); + helper_ret_stw_mmu(env, addr + (4 << DF_HALF), pwd->h[4], oi, GETPC()); + helper_ret_stw_mmu(env, addr + (5 << DF_HALF), pwd->h[5], oi, GETPC()); + helper_ret_stw_mmu(env, addr + (6 << DF_HALF), pwd->h[6], oi, GETPC()); + helper_ret_stw_mmu(env, addr + (7 << DF_HALF), pwd->h[7], oi, GETPC()); +#else + helper_ret_stw_mmu(env, addr + (3 << DF_HALF), pwd->h[0], oi, GETPC()); + helper_ret_stw_mmu(env, addr + (2 << DF_HALF), pwd->h[1], oi, GETPC()); + helper_ret_stw_mmu(env, addr + (1 << DF_HALF), pwd->h[2], oi, GETPC()); + helper_ret_stw_mmu(env, addr + (0 << DF_HALF), pwd->h[3], oi, GETPC()); + helper_ret_stw_mmu(env, addr + (7 << DF_HALF), pwd->h[4], oi, GETPC()); + helper_ret_stw_mmu(env, addr + (6 << DF_HALF), pwd->h[5], oi, GETPC()); + helper_ret_stw_mmu(env, addr + (5 << DF_HALF), pwd->h[6], oi, GETPC()); + helper_ret_stw_mmu(env, addr + (4 << DF_HALF), pwd->h[7], oi, GETPC()); +#endif +#else +#if !defined(HOST_WORDS_BIGENDIAN) + cpu_stw_data(env, addr + (0 << DF_HALF), pwd->h[0]); + cpu_stw_data(env, addr + (1 << DF_HALF), pwd->h[1]); + cpu_stw_data(env, addr + (2 << DF_HALF), pwd->h[2]); + cpu_stw_data(env, addr + (3 << DF_HALF), pwd->h[3]); + cpu_stw_data(env, addr + (4 << DF_HALF), pwd->h[4]); + cpu_stw_data(env, addr + (5 << DF_HALF), pwd->h[5]); + cpu_stw_data(env, addr + (6 << DF_HALF), pwd->h[6]); + cpu_stw_data(env, addr + (7 << DF_HALF), pwd->h[7]); +#else + cpu_stw_data(env, addr + (3 << DF_HALF), pwd->h[0]); + cpu_stw_data(env, addr + (2 << DF_HALF), pwd->h[1]); + cpu_stw_data(env, addr + (1 << DF_HALF), pwd->h[2]); + cpu_stw_data(env, addr + (0 << DF_HALF), pwd->h[3]); + cpu_stw_data(env, addr + (7 << DF_HALF), pwd->h[4]); + cpu_stw_data(env, addr + (6 << DF_HALF), pwd->h[5]); + cpu_stw_data(env, addr + (5 << DF_HALF), pwd->h[6]); + cpu_stw_data(env, addr + (4 << DF_HALF), pwd->h[7]); +#endif +#endif +} + +void helper_msa_st_w(CPUMIPSState *env, uint32_t wd, + target_ulong addr) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + int mmu_idx = cpu_mmu_index(env, false); + + MEMOP_IDX(DF_WORD) + ensure_writable_pages(env, addr, mmu_idx, GETPC()); +#if !defined(CONFIG_USER_ONLY) +#if !defined(HOST_WORDS_BIGENDIAN) + helper_ret_stl_mmu(env, addr + (0 << DF_WORD), pwd->w[0], oi, GETPC()); + helper_ret_stl_mmu(env, addr + (1 << DF_WORD), pwd->w[1], oi, GETPC()); + helper_ret_stl_mmu(env, addr + (2 << DF_WORD), pwd->w[2], oi, GETPC()); + helper_ret_stl_mmu(env, addr + (3 << DF_WORD), pwd->w[3], oi, GETPC()); +#else + helper_ret_stl_mmu(env, addr + (1 << DF_WORD), pwd->w[0], oi, GETPC()); + helper_ret_stl_mmu(env, addr + (0 << DF_WORD), pwd->w[1], oi, GETPC()); + helper_ret_stl_mmu(env, addr + (3 << DF_WORD), pwd->w[2], oi, GETPC()); + helper_ret_stl_mmu(env, addr + (2 << DF_WORD), pwd->w[3], oi, GETPC()); +#endif +#else +#if !defined(HOST_WORDS_BIGENDIAN) + cpu_stl_data(env, addr + (0 << DF_WORD), pwd->w[0]); + cpu_stl_data(env, addr + (1 << DF_WORD), pwd->w[1]); + cpu_stl_data(env, addr + (2 << DF_WORD), pwd->w[2]); + cpu_stl_data(env, addr + (3 << DF_WORD), pwd->w[3]); +#else + cpu_stl_data(env, addr + (1 << DF_WORD), pwd->w[0]); + cpu_stl_data(env, addr + (0 << DF_WORD), pwd->w[1]); + cpu_stl_data(env, addr + (3 << DF_WORD), pwd->w[2]); + cpu_stl_data(env, addr + (2 << DF_WORD), pwd->w[3]); +#endif +#endif +} + +void helper_msa_st_d(CPUMIPSState *env, uint32_t wd, + target_ulong addr) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + int mmu_idx = cpu_mmu_index(env, false); + + MEMOP_IDX(DF_DOUBLE) + ensure_writable_pages(env, addr, mmu_idx, GETPC()); +#if !defined(CONFIG_USER_ONLY) + helper_ret_stq_mmu(env, addr + (0 << DF_DOUBLE), pwd->d[0], oi, GETPC()); + helper_ret_stq_mmu(env, addr + (1 << DF_DOUBLE), pwd->d[1], oi, GETPC()); +#else + cpu_stq_data(env, addr + (0 << DF_DOUBLE), pwd->d[0]); + cpu_stq_data(env, addr + (1 << DF_DOUBLE), pwd->d[1]); +#endif +} + void msa_reset(CPUMIPSState *env) { if (!ase_msa_available(env)) { diff --git a/target/mips/op_helper.c b/target/mips/op_helper.c index 3386b8228e..89c7d4556a 100644 --- a/target/mips/op_helper.c +++ b/target/mips/op_helper.c @@ -1173,400 +1173,6 @@ void mips_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr, } #endif /* !CONFIG_USER_ONLY */ - -/* MSA */ -/* Data format min and max values */ -#define DF_BITS(df) (1 << ((df) + 3)) - -/* Element-by-element access macros */ -#define DF_ELEMENTS(df) (MSA_WRLEN / DF_BITS(df)) - -#if !defined(CONFIG_USER_ONLY) -#define MEMOP_IDX(DF) \ - TCGMemOpIdx oi = make_memop_idx(MO_TE | DF | MO_UNALN, \ - cpu_mmu_index(env, false)); -#else -#define MEMOP_IDX(DF) -#endif - -void helper_msa_ld_b(CPUMIPSState *env, uint32_t wd, - target_ulong addr) -{ - wr_t *pwd = &(env->active_fpu.fpr[wd].wr); - MEMOP_IDX(DF_BYTE) -#if !defined(CONFIG_USER_ONLY) -#if !defined(HOST_WORDS_BIGENDIAN) - pwd->b[0] = helper_ret_ldub_mmu(env, addr + (0 << DF_BYTE), oi, GETPC()); - pwd->b[1] = helper_ret_ldub_mmu(env, addr + (1 << DF_BYTE), oi, GETPC()); - pwd->b[2] = helper_ret_ldub_mmu(env, addr + (2 << DF_BYTE), oi, GETPC()); - pwd->b[3] = helper_ret_ldub_mmu(env, addr + (3 << DF_BYTE), oi, GETPC()); - pwd->b[4] = helper_ret_ldub_mmu(env, addr + (4 << DF_BYTE), oi, GETPC()); - pwd->b[5] = helper_ret_ldub_mmu(env, addr + (5 << DF_BYTE), oi, GETPC()); - pwd->b[6] = helper_ret_ldub_mmu(env, addr + (6 << DF_BYTE), oi, GETPC()); - pwd->b[7] = helper_ret_ldub_mmu(env, addr + (7 << DF_BYTE), oi, GETPC()); - pwd->b[8] = helper_ret_ldub_mmu(env, addr + (8 << DF_BYTE), oi, GETPC()); - pwd->b[9] = helper_ret_ldub_mmu(env, addr + (9 << DF_BYTE), oi, GETPC()); - pwd->b[10] = helper_ret_ldub_mmu(env, addr + (10 << DF_BYTE), oi, GETPC()); - pwd->b[11] = helper_ret_ldub_mmu(env, addr + (11 << DF_BYTE), oi, GETPC()); - pwd->b[12] = helper_ret_ldub_mmu(env, addr + (12 << DF_BYTE), oi, GETPC()); - pwd->b[13] = helper_ret_ldub_mmu(env, addr + (13 << DF_BYTE), oi, GETPC()); - pwd->b[14] = helper_ret_ldub_mmu(env, addr + (14 << DF_BYTE), oi, GETPC()); - pwd->b[15] = helper_ret_ldub_mmu(env, addr + (15 << DF_BYTE), oi, GETPC()); -#else - pwd->b[0] = helper_ret_ldub_mmu(env, addr + (7 << DF_BYTE), oi, GETPC()); - pwd->b[1] = helper_ret_ldub_mmu(env, addr + (6 << DF_BYTE), oi, GETPC()); - pwd->b[2] = helper_ret_ldub_mmu(env, addr + (5 << DF_BYTE), oi, GETPC()); - pwd->b[3] = helper_ret_ldub_mmu(env, addr + (4 << DF_BYTE), oi, GETPC()); - pwd->b[4] = helper_ret_ldub_mmu(env, addr + (3 << DF_BYTE), oi, GETPC()); - pwd->b[5] = helper_ret_ldub_mmu(env, addr + (2 << DF_BYTE), oi, GETPC()); - pwd->b[6] = helper_ret_ldub_mmu(env, addr + (1 << DF_BYTE), oi, GETPC()); - pwd->b[7] = helper_ret_ldub_mmu(env, addr + (0 << DF_BYTE), oi, GETPC()); - pwd->b[8] = helper_ret_ldub_mmu(env, addr + (15 << DF_BYTE), oi, GETPC()); - pwd->b[9] = helper_ret_ldub_mmu(env, addr + (14 << DF_BYTE), oi, GETPC()); - pwd->b[10] = helper_ret_ldub_mmu(env, addr + (13 << DF_BYTE), oi, GETPC()); - pwd->b[11] = helper_ret_ldub_mmu(env, addr + (12 << DF_BYTE), oi, GETPC()); - pwd->b[12] = helper_ret_ldub_mmu(env, addr + (11 << DF_BYTE), oi, GETPC()); - pwd->b[13] = helper_ret_ldub_mmu(env, addr + (10 << DF_BYTE), oi, GETPC()); - pwd->b[14] = helper_ret_ldub_mmu(env, addr + (9 << DF_BYTE), oi, GETPC()); - pwd->b[15] = helper_ret_ldub_mmu(env, addr + (8 << DF_BYTE), oi, GETPC()); -#endif -#else -#if !defined(HOST_WORDS_BIGENDIAN) - pwd->b[0] = cpu_ldub_data(env, addr + (0 << DF_BYTE)); - pwd->b[1] = cpu_ldub_data(env, addr + (1 << DF_BYTE)); - pwd->b[2] = cpu_ldub_data(env, addr + (2 << DF_BYTE)); - pwd->b[3] = cpu_ldub_data(env, addr + (3 << DF_BYTE)); - pwd->b[4] = cpu_ldub_data(env, addr + (4 << DF_BYTE)); - pwd->b[5] = cpu_ldub_data(env, addr + (5 << DF_BYTE)); - pwd->b[6] = cpu_ldub_data(env, addr + (6 << DF_BYTE)); - pwd->b[7] = cpu_ldub_data(env, addr + (7 << DF_BYTE)); - pwd->b[8] = cpu_ldub_data(env, addr + (8 << DF_BYTE)); - pwd->b[9] = cpu_ldub_data(env, addr + (9 << DF_BYTE)); - pwd->b[10] = cpu_ldub_data(env, addr + (10 << DF_BYTE)); - pwd->b[11] = cpu_ldub_data(env, addr + (11 << DF_BYTE)); - pwd->b[12] = cpu_ldub_data(env, addr + (12 << DF_BYTE)); - pwd->b[13] = cpu_ldub_data(env, addr + (13 << DF_BYTE)); - pwd->b[14] = cpu_ldub_data(env, addr + (14 << DF_BYTE)); - pwd->b[15] = cpu_ldub_data(env, addr + (15 << DF_BYTE)); -#else - pwd->b[0] = cpu_ldub_data(env, addr + (7 << DF_BYTE)); - pwd->b[1] = cpu_ldub_data(env, addr + (6 << DF_BYTE)); - pwd->b[2] = cpu_ldub_data(env, addr + (5 << DF_BYTE)); - pwd->b[3] = cpu_ldub_data(env, addr + (4 << DF_BYTE)); - pwd->b[4] = cpu_ldub_data(env, addr + (3 << DF_BYTE)); - pwd->b[5] = cpu_ldub_data(env, addr + (2 << DF_BYTE)); - pwd->b[6] = cpu_ldub_data(env, addr + (1 << DF_BYTE)); - pwd->b[7] = cpu_ldub_data(env, addr + (0 << DF_BYTE)); - pwd->b[8] = cpu_ldub_data(env, addr + (15 << DF_BYTE)); - pwd->b[9] = cpu_ldub_data(env, addr + (14 << DF_BYTE)); - pwd->b[10] = cpu_ldub_data(env, addr + (13 << DF_BYTE)); - pwd->b[11] = cpu_ldub_data(env, addr + (12 << DF_BYTE)); - pwd->b[12] = cpu_ldub_data(env, addr + (11 << DF_BYTE)); - pwd->b[13] = cpu_ldub_data(env, addr + (10 << DF_BYTE)); - pwd->b[14] = cpu_ldub_data(env, addr + (9 << DF_BYTE)); - pwd->b[15] = cpu_ldub_data(env, addr + (8 << DF_BYTE)); -#endif -#endif -} - -void helper_msa_ld_h(CPUMIPSState *env, uint32_t wd, - target_ulong addr) -{ - wr_t *pwd = &(env->active_fpu.fpr[wd].wr); - MEMOP_IDX(DF_HALF) -#if !defined(CONFIG_USER_ONLY) -#if !defined(HOST_WORDS_BIGENDIAN) - pwd->h[0] = helper_ret_lduw_mmu(env, addr + (0 << DF_HALF), oi, GETPC()); - pwd->h[1] = helper_ret_lduw_mmu(env, addr + (1 << DF_HALF), oi, GETPC()); - pwd->h[2] = helper_ret_lduw_mmu(env, addr + (2 << DF_HALF), oi, GETPC()); - pwd->h[3] = helper_ret_lduw_mmu(env, addr + (3 << DF_HALF), oi, GETPC()); - pwd->h[4] = helper_ret_lduw_mmu(env, addr + (4 << DF_HALF), oi, GETPC()); - pwd->h[5] = helper_ret_lduw_mmu(env, addr + (5 << DF_HALF), oi, GETPC()); - pwd->h[6] = helper_ret_lduw_mmu(env, addr + (6 << DF_HALF), oi, GETPC()); - pwd->h[7] = helper_ret_lduw_mmu(env, addr + (7 << DF_HALF), oi, GETPC()); -#else - pwd->h[0] = helper_ret_lduw_mmu(env, addr + (3 << DF_HALF), oi, GETPC()); - pwd->h[1] = helper_ret_lduw_mmu(env, addr + (2 << DF_HALF), oi, GETPC()); - pwd->h[2] = helper_ret_lduw_mmu(env, addr + (1 << DF_HALF), oi, GETPC()); - pwd->h[3] = helper_ret_lduw_mmu(env, addr + (0 << DF_HALF), oi, GETPC()); - pwd->h[4] = helper_ret_lduw_mmu(env, addr + (7 << DF_HALF), oi, GETPC()); - pwd->h[5] = helper_ret_lduw_mmu(env, addr + (6 << DF_HALF), oi, GETPC()); - pwd->h[6] = helper_ret_lduw_mmu(env, addr + (5 << DF_HALF), oi, GETPC()); - pwd->h[7] = helper_ret_lduw_mmu(env, addr + (4 << DF_HALF), oi, GETPC()); -#endif -#else -#if !defined(HOST_WORDS_BIGENDIAN) - pwd->h[0] = cpu_lduw_data(env, addr + (0 << DF_HALF)); - pwd->h[1] = cpu_lduw_data(env, addr + (1 << DF_HALF)); - pwd->h[2] = cpu_lduw_data(env, addr + (2 << DF_HALF)); - pwd->h[3] = cpu_lduw_data(env, addr + (3 << DF_HALF)); - pwd->h[4] = cpu_lduw_data(env, addr + (4 << DF_HALF)); - pwd->h[5] = cpu_lduw_data(env, addr + (5 << DF_HALF)); - pwd->h[6] = cpu_lduw_data(env, addr + (6 << DF_HALF)); - pwd->h[7] = cpu_lduw_data(env, addr + (7 << DF_HALF)); -#else - pwd->h[0] = cpu_lduw_data(env, addr + (3 << DF_HALF)); - pwd->h[1] = cpu_lduw_data(env, addr + (2 << DF_HALF)); - pwd->h[2] = cpu_lduw_data(env, addr + (1 << DF_HALF)); - pwd->h[3] = cpu_lduw_data(env, addr + (0 << DF_HALF)); - pwd->h[4] = cpu_lduw_data(env, addr + (7 << DF_HALF)); - pwd->h[5] = cpu_lduw_data(env, addr + (6 << DF_HALF)); - pwd->h[6] = cpu_lduw_data(env, addr + (5 << DF_HALF)); - pwd->h[7] = cpu_lduw_data(env, addr + (4 << DF_HALF)); -#endif -#endif -} - -void helper_msa_ld_w(CPUMIPSState *env, uint32_t wd, - target_ulong addr) -{ - wr_t *pwd = &(env->active_fpu.fpr[wd].wr); - MEMOP_IDX(DF_WORD) -#if !defined(CONFIG_USER_ONLY) -#if !defined(HOST_WORDS_BIGENDIAN) - pwd->w[0] = helper_ret_ldul_mmu(env, addr + (0 << DF_WORD), oi, GETPC()); - pwd->w[1] = helper_ret_ldul_mmu(env, addr + (1 << DF_WORD), oi, GETPC()); - pwd->w[2] = helper_ret_ldul_mmu(env, addr + (2 << DF_WORD), oi, GETPC()); - pwd->w[3] = helper_ret_ldul_mmu(env, addr + (3 << DF_WORD), oi, GETPC()); -#else - pwd->w[0] = helper_ret_ldul_mmu(env, addr + (1 << DF_WORD), oi, GETPC()); - pwd->w[1] = helper_ret_ldul_mmu(env, addr + (0 << DF_WORD), oi, GETPC()); - pwd->w[2] = helper_ret_ldul_mmu(env, addr + (3 << DF_WORD), oi, GETPC()); - pwd->w[3] = helper_ret_ldul_mmu(env, addr + (2 << DF_WORD), oi, GETPC()); -#endif -#else -#if !defined(HOST_WORDS_BIGENDIAN) - pwd->w[0] = cpu_ldl_data(env, addr + (0 << DF_WORD)); - pwd->w[1] = cpu_ldl_data(env, addr + (1 << DF_WORD)); - pwd->w[2] = cpu_ldl_data(env, addr + (2 << DF_WORD)); - pwd->w[3] = cpu_ldl_data(env, addr + (3 << DF_WORD)); -#else - pwd->w[0] = cpu_ldl_data(env, addr + (1 << DF_WORD)); - pwd->w[1] = cpu_ldl_data(env, addr + (0 << DF_WORD)); - pwd->w[2] = cpu_ldl_data(env, addr + (3 << DF_WORD)); - pwd->w[3] = cpu_ldl_data(env, addr + (2 << DF_WORD)); -#endif -#endif -} - -void helper_msa_ld_d(CPUMIPSState *env, uint32_t wd, - target_ulong addr) -{ - wr_t *pwd = &(env->active_fpu.fpr[wd].wr); - MEMOP_IDX(DF_DOUBLE) -#if !defined(CONFIG_USER_ONLY) - pwd->d[0] = helper_ret_ldq_mmu(env, addr + (0 << DF_DOUBLE), oi, GETPC()); - pwd->d[1] = helper_ret_ldq_mmu(env, addr + (1 << DF_DOUBLE), oi, GETPC()); -#else - pwd->d[0] = cpu_ldq_data(env, addr + (0 << DF_DOUBLE)); - pwd->d[1] = cpu_ldq_data(env, addr + (1 << DF_DOUBLE)); -#endif -} - -#define MSA_PAGESPAN(x) \ - ((((x) & ~TARGET_PAGE_MASK) + MSA_WRLEN / 8 - 1) >= TARGET_PAGE_SIZE) - -static inline void ensure_writable_pages(CPUMIPSState *env, - target_ulong addr, - int mmu_idx, - uintptr_t retaddr) -{ - /* FIXME: Probe the actual accesses (pass and use a size) */ - if (unlikely(MSA_PAGESPAN(addr))) { - /* first page */ - probe_write(env, addr, 0, mmu_idx, retaddr); - /* second page */ - addr = (addr & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE; - probe_write(env, addr, 0, mmu_idx, retaddr); - } -} - -void helper_msa_st_b(CPUMIPSState *env, uint32_t wd, - target_ulong addr) -{ - wr_t *pwd = &(env->active_fpu.fpr[wd].wr); - int mmu_idx = cpu_mmu_index(env, false); - - MEMOP_IDX(DF_BYTE) - ensure_writable_pages(env, addr, mmu_idx, GETPC()); -#if !defined(CONFIG_USER_ONLY) -#if !defined(HOST_WORDS_BIGENDIAN) - helper_ret_stb_mmu(env, addr + (0 << DF_BYTE), pwd->b[0], oi, GETPC()); - helper_ret_stb_mmu(env, addr + (1 << DF_BYTE), pwd->b[1], oi, GETPC()); - helper_ret_stb_mmu(env, addr + (2 << DF_BYTE), pwd->b[2], oi, GETPC()); - helper_ret_stb_mmu(env, addr + (3 << DF_BYTE), pwd->b[3], oi, GETPC()); - helper_ret_stb_mmu(env, addr + (4 << DF_BYTE), pwd->b[4], oi, GETPC()); - helper_ret_stb_mmu(env, addr + (5 << DF_BYTE), pwd->b[5], oi, GETPC()); - helper_ret_stb_mmu(env, addr + (6 << DF_BYTE), pwd->b[6], oi, GETPC()); - helper_ret_stb_mmu(env, addr + (7 << DF_BYTE), pwd->b[7], oi, GETPC()); - helper_ret_stb_mmu(env, addr + (8 << DF_BYTE), pwd->b[8], oi, GETPC()); - helper_ret_stb_mmu(env, addr + (9 << DF_BYTE), pwd->b[9], oi, GETPC()); - helper_ret_stb_mmu(env, addr + (10 << DF_BYTE), pwd->b[10], oi, GETPC()); - helper_ret_stb_mmu(env, addr + (11 << DF_BYTE), pwd->b[11], oi, GETPC()); - helper_ret_stb_mmu(env, addr + (12 << DF_BYTE), pwd->b[12], oi, GETPC()); - helper_ret_stb_mmu(env, addr + (13 << DF_BYTE), pwd->b[13], oi, GETPC()); - helper_ret_stb_mmu(env, addr + (14 << DF_BYTE), pwd->b[14], oi, GETPC()); - helper_ret_stb_mmu(env, addr + (15 << DF_BYTE), pwd->b[15], oi, GETPC()); -#else - helper_ret_stb_mmu(env, addr + (7 << DF_BYTE), pwd->b[0], oi, GETPC()); - helper_ret_stb_mmu(env, addr + (6 << DF_BYTE), pwd->b[1], oi, GETPC()); - helper_ret_stb_mmu(env, addr + (5 << DF_BYTE), pwd->b[2], oi, GETPC()); - helper_ret_stb_mmu(env, addr + (4 << DF_BYTE), pwd->b[3], oi, GETPC()); - helper_ret_stb_mmu(env, addr + (3 << DF_BYTE), pwd->b[4], oi, GETPC()); - helper_ret_stb_mmu(env, addr + (2 << DF_BYTE), pwd->b[5], oi, GETPC()); - helper_ret_stb_mmu(env, addr + (1 << DF_BYTE), pwd->b[6], oi, GETPC()); - helper_ret_stb_mmu(env, addr + (0 << DF_BYTE), pwd->b[7], oi, GETPC()); - helper_ret_stb_mmu(env, addr + (15 << DF_BYTE), pwd->b[8], oi, GETPC()); - helper_ret_stb_mmu(env, addr + (14 << DF_BYTE), pwd->b[9], oi, GETPC()); - helper_ret_stb_mmu(env, addr + (13 << DF_BYTE), pwd->b[10], oi, GETPC()); - helper_ret_stb_mmu(env, addr + (12 << DF_BYTE), pwd->b[11], oi, GETPC()); - helper_ret_stb_mmu(env, addr + (11 << DF_BYTE), pwd->b[12], oi, GETPC()); - helper_ret_stb_mmu(env, addr + (10 << DF_BYTE), pwd->b[13], oi, GETPC()); - helper_ret_stb_mmu(env, addr + (9 << DF_BYTE), pwd->b[14], oi, GETPC()); - helper_ret_stb_mmu(env, addr + (8 << DF_BYTE), pwd->b[15], oi, GETPC()); -#endif -#else -#if !defined(HOST_WORDS_BIGENDIAN) - cpu_stb_data(env, addr + (0 << DF_BYTE), pwd->b[0]); - cpu_stb_data(env, addr + (1 << DF_BYTE), pwd->b[1]); - cpu_stb_data(env, addr + (2 << DF_BYTE), pwd->b[2]); - cpu_stb_data(env, addr + (3 << DF_BYTE), pwd->b[3]); - cpu_stb_data(env, addr + (4 << DF_BYTE), pwd->b[4]); - cpu_stb_data(env, addr + (5 << DF_BYTE), pwd->b[5]); - cpu_stb_data(env, addr + (6 << DF_BYTE), pwd->b[6]); - cpu_stb_data(env, addr + (7 << DF_BYTE), pwd->b[7]); - cpu_stb_data(env, addr + (8 << DF_BYTE), pwd->b[8]); - cpu_stb_data(env, addr + (9 << DF_BYTE), pwd->b[9]); - cpu_stb_data(env, addr + (10 << DF_BYTE), pwd->b[10]); - cpu_stb_data(env, addr + (11 << DF_BYTE), pwd->b[11]); - cpu_stb_data(env, addr + (12 << DF_BYTE), pwd->b[12]); - cpu_stb_data(env, addr + (13 << DF_BYTE), pwd->b[13]); - cpu_stb_data(env, addr + (14 << DF_BYTE), pwd->b[14]); - cpu_stb_data(env, addr + (15 << DF_BYTE), pwd->b[15]); -#else - cpu_stb_data(env, addr + (7 << DF_BYTE), pwd->b[0]); - cpu_stb_data(env, addr + (6 << DF_BYTE), pwd->b[1]); - cpu_stb_data(env, addr + (5 << DF_BYTE), pwd->b[2]); - cpu_stb_data(env, addr + (4 << DF_BYTE), pwd->b[3]); - cpu_stb_data(env, addr + (3 << DF_BYTE), pwd->b[4]); - cpu_stb_data(env, addr + (2 << DF_BYTE), pwd->b[5]); - cpu_stb_data(env, addr + (1 << DF_BYTE), pwd->b[6]); - cpu_stb_data(env, addr + (0 << DF_BYTE), pwd->b[7]); - cpu_stb_data(env, addr + (15 << DF_BYTE), pwd->b[8]); - cpu_stb_data(env, addr + (14 << DF_BYTE), pwd->b[9]); - cpu_stb_data(env, addr + (13 << DF_BYTE), pwd->b[10]); - cpu_stb_data(env, addr + (12 << DF_BYTE), pwd->b[11]); - cpu_stb_data(env, addr + (11 << DF_BYTE), pwd->b[12]); - cpu_stb_data(env, addr + (10 << DF_BYTE), pwd->b[13]); - cpu_stb_data(env, addr + (9 << DF_BYTE), pwd->b[14]); - cpu_stb_data(env, addr + (8 << DF_BYTE), pwd->b[15]); -#endif -#endif -} - -void helper_msa_st_h(CPUMIPSState *env, uint32_t wd, - target_ulong addr) -{ - wr_t *pwd = &(env->active_fpu.fpr[wd].wr); - int mmu_idx = cpu_mmu_index(env, false); - - MEMOP_IDX(DF_HALF) - ensure_writable_pages(env, addr, mmu_idx, GETPC()); -#if !defined(CONFIG_USER_ONLY) -#if !defined(HOST_WORDS_BIGENDIAN) - helper_ret_stw_mmu(env, addr + (0 << DF_HALF), pwd->h[0], oi, GETPC()); - helper_ret_stw_mmu(env, addr + (1 << DF_HALF), pwd->h[1], oi, GETPC()); - helper_ret_stw_mmu(env, addr + (2 << DF_HALF), pwd->h[2], oi, GETPC()); - helper_ret_stw_mmu(env, addr + (3 << DF_HALF), pwd->h[3], oi, GETPC()); - helper_ret_stw_mmu(env, addr + (4 << DF_HALF), pwd->h[4], oi, GETPC()); - helper_ret_stw_mmu(env, addr + (5 << DF_HALF), pwd->h[5], oi, GETPC()); - helper_ret_stw_mmu(env, addr + (6 << DF_HALF), pwd->h[6], oi, GETPC()); - helper_ret_stw_mmu(env, addr + (7 << DF_HALF), pwd->h[7], oi, GETPC()); -#else - helper_ret_stw_mmu(env, addr + (3 << DF_HALF), pwd->h[0], oi, GETPC()); - helper_ret_stw_mmu(env, addr + (2 << DF_HALF), pwd->h[1], oi, GETPC()); - helper_ret_stw_mmu(env, addr + (1 << DF_HALF), pwd->h[2], oi, GETPC()); - helper_ret_stw_mmu(env, addr + (0 << DF_HALF), pwd->h[3], oi, GETPC()); - helper_ret_stw_mmu(env, addr + (7 << DF_HALF), pwd->h[4], oi, GETPC()); - helper_ret_stw_mmu(env, addr + (6 << DF_HALF), pwd->h[5], oi, GETPC()); - helper_ret_stw_mmu(env, addr + (5 << DF_HALF), pwd->h[6], oi, GETPC()); - helper_ret_stw_mmu(env, addr + (4 << DF_HALF), pwd->h[7], oi, GETPC()); -#endif -#else -#if !defined(HOST_WORDS_BIGENDIAN) - cpu_stw_data(env, addr + (0 << DF_HALF), pwd->h[0]); - cpu_stw_data(env, addr + (1 << DF_HALF), pwd->h[1]); - cpu_stw_data(env, addr + (2 << DF_HALF), pwd->h[2]); - cpu_stw_data(env, addr + (3 << DF_HALF), pwd->h[3]); - cpu_stw_data(env, addr + (4 << DF_HALF), pwd->h[4]); - cpu_stw_data(env, addr + (5 << DF_HALF), pwd->h[5]); - cpu_stw_data(env, addr + (6 << DF_HALF), pwd->h[6]); - cpu_stw_data(env, addr + (7 << DF_HALF), pwd->h[7]); -#else - cpu_stw_data(env, addr + (3 << DF_HALF), pwd->h[0]); - cpu_stw_data(env, addr + (2 << DF_HALF), pwd->h[1]); - cpu_stw_data(env, addr + (1 << DF_HALF), pwd->h[2]); - cpu_stw_data(env, addr + (0 << DF_HALF), pwd->h[3]); - cpu_stw_data(env, addr + (7 << DF_HALF), pwd->h[4]); - cpu_stw_data(env, addr + (6 << DF_HALF), pwd->h[5]); - cpu_stw_data(env, addr + (5 << DF_HALF), pwd->h[6]); - cpu_stw_data(env, addr + (4 << DF_HALF), pwd->h[7]); -#endif -#endif -} - -void helper_msa_st_w(CPUMIPSState *env, uint32_t wd, - target_ulong addr) -{ - wr_t *pwd = &(env->active_fpu.fpr[wd].wr); - int mmu_idx = cpu_mmu_index(env, false); - - MEMOP_IDX(DF_WORD) - ensure_writable_pages(env, addr, mmu_idx, GETPC()); -#if !defined(CONFIG_USER_ONLY) -#if !defined(HOST_WORDS_BIGENDIAN) - helper_ret_stl_mmu(env, addr + (0 << DF_WORD), pwd->w[0], oi, GETPC()); - helper_ret_stl_mmu(env, addr + (1 << DF_WORD), pwd->w[1], oi, GETPC()); - helper_ret_stl_mmu(env, addr + (2 << DF_WORD), pwd->w[2], oi, GETPC()); - helper_ret_stl_mmu(env, addr + (3 << DF_WORD), pwd->w[3], oi, GETPC()); -#else - helper_ret_stl_mmu(env, addr + (1 << DF_WORD), pwd->w[0], oi, GETPC()); - helper_ret_stl_mmu(env, addr + (0 << DF_WORD), pwd->w[1], oi, GETPC()); - helper_ret_stl_mmu(env, addr + (3 << DF_WORD), pwd->w[2], oi, GETPC()); - helper_ret_stl_mmu(env, addr + (2 << DF_WORD), pwd->w[3], oi, GETPC()); -#endif -#else -#if !defined(HOST_WORDS_BIGENDIAN) - cpu_stl_data(env, addr + (0 << DF_WORD), pwd->w[0]); - cpu_stl_data(env, addr + (1 << DF_WORD), pwd->w[1]); - cpu_stl_data(env, addr + (2 << DF_WORD), pwd->w[2]); - cpu_stl_data(env, addr + (3 << DF_WORD), pwd->w[3]); -#else - cpu_stl_data(env, addr + (1 << DF_WORD), pwd->w[0]); - cpu_stl_data(env, addr + (0 << DF_WORD), pwd->w[1]); - cpu_stl_data(env, addr + (3 << DF_WORD), pwd->w[2]); - cpu_stl_data(env, addr + (2 << DF_WORD), pwd->w[3]); -#endif -#endif -} - -void helper_msa_st_d(CPUMIPSState *env, uint32_t wd, - target_ulong addr) -{ - wr_t *pwd = &(env->active_fpu.fpr[wd].wr); - int mmu_idx = cpu_mmu_index(env, false); - - MEMOP_IDX(DF_DOUBLE) - ensure_writable_pages(env, addr, mmu_idx, GETPC()); -#if !defined(CONFIG_USER_ONLY) - helper_ret_stq_mmu(env, addr + (0 << DF_DOUBLE), pwd->d[0], oi, GETPC()); - helper_ret_stq_mmu(env, addr + (1 << DF_DOUBLE), pwd->d[1], oi, GETPC()); -#else - cpu_stq_data(env, addr + (0 << DF_DOUBLE), pwd->d[0]); - cpu_stq_data(env, addr + (1 << DF_DOUBLE), pwd->d[1]); -#endif -} - void helper_cache(CPUMIPSState *env, target_ulong addr, uint32_t op) { #ifndef CONFIG_USER_ONLY -- cgit v1.2.3-55-g7522 From edb23847283341bc22ed3830edb21647f49d15dd Mon Sep 17 00:00:00 2001 From: Philippe Mathieu-Daudé Date: Mon, 16 Nov 2020 05:56:44 +0100 Subject: target/mips: Extract MSA helper definitions Keep all MSA-related code altogether. Reviewed-by: Richard Henderson Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20201120210844.2625602-4-f4bug@amsat.org> Tested-by: Jiaxun Yang --- target/mips/helper.h | 436 +----------------------------------------- target/mips/msa_helper.h.inc | 443 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 445 insertions(+), 434 deletions(-) create mode 100644 target/mips/msa_helper.h.inc diff --git a/target/mips/helper.h b/target/mips/helper.h index e97655dc0e..709494445d 100644 --- a/target/mips/helper.h +++ b/target/mips/helper.h @@ -781,438 +781,6 @@ DEF_HELPER_FLAGS_3(dmthlip, 0, void, tl, tl, env) DEF_HELPER_FLAGS_3(wrdsp, 0, void, tl, tl, env) DEF_HELPER_FLAGS_2(rddsp, 0, tl, tl, env) -/* MIPS SIMD Architecture */ - -DEF_HELPER_3(msa_nloc_b, void, env, i32, i32) -DEF_HELPER_3(msa_nloc_h, void, env, i32, i32) -DEF_HELPER_3(msa_nloc_w, void, env, i32, i32) -DEF_HELPER_3(msa_nloc_d, void, env, i32, i32) - -DEF_HELPER_3(msa_nlzc_b, void, env, i32, i32) -DEF_HELPER_3(msa_nlzc_h, void, env, i32, i32) -DEF_HELPER_3(msa_nlzc_w, void, env, i32, i32) -DEF_HELPER_3(msa_nlzc_d, void, env, i32, i32) - -DEF_HELPER_3(msa_pcnt_b, void, env, i32, i32) -DEF_HELPER_3(msa_pcnt_h, void, env, i32, i32) -DEF_HELPER_3(msa_pcnt_w, void, env, i32, i32) -DEF_HELPER_3(msa_pcnt_d, void, env, i32, i32) - -DEF_HELPER_4(msa_binsl_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_binsl_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_binsl_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_binsl_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_binsr_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_binsr_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_binsr_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_binsr_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_bmnz_v, void, env, i32, i32, i32) -DEF_HELPER_4(msa_bmz_v, void, env, i32, i32, i32) -DEF_HELPER_4(msa_bsel_v, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_bclr_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_bclr_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_bclr_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_bclr_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_bneg_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_bneg_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_bneg_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_bneg_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_bset_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_bset_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_bset_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_bset_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_add_a_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_add_a_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_add_a_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_add_a_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_adds_a_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_adds_a_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_adds_a_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_adds_a_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_adds_s_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_adds_s_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_adds_s_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_adds_s_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_adds_u_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_adds_u_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_adds_u_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_adds_u_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_addv_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_addv_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_addv_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_addv_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_hadd_s_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_hadd_s_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_hadd_s_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_hadd_u_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_hadd_u_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_hadd_u_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_ave_s_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ave_s_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ave_s_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ave_s_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_ave_u_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ave_u_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ave_u_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ave_u_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_aver_s_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_aver_s_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_aver_s_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_aver_s_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_aver_u_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_aver_u_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_aver_u_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_aver_u_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_ceq_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ceq_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ceq_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ceq_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_cle_s_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_cle_s_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_cle_s_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_cle_s_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_cle_u_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_cle_u_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_cle_u_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_cle_u_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_clt_s_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_clt_s_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_clt_s_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_clt_s_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_clt_u_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_clt_u_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_clt_u_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_clt_u_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_div_s_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_div_s_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_div_s_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_div_s_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_div_u_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_div_u_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_div_u_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_div_u_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_max_a_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_max_a_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_max_a_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_max_a_d, void, env, i32, i32, i32) -DEF_HELPER_4(msa_max_s_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_max_s_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_max_s_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_max_s_d, void, env, i32, i32, i32) -DEF_HELPER_4(msa_max_u_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_max_u_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_max_u_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_max_u_d, void, env, i32, i32, i32) -DEF_HELPER_4(msa_min_a_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_min_a_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_min_a_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_min_a_d, void, env, i32, i32, i32) -DEF_HELPER_4(msa_min_s_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_min_s_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_min_s_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_min_s_d, void, env, i32, i32, i32) -DEF_HELPER_4(msa_min_u_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_min_u_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_min_u_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_min_u_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_mod_u_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_mod_u_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_mod_u_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_mod_u_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_mod_s_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_mod_s_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_mod_s_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_mod_s_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_maddv_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_maddv_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_maddv_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_maddv_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_msubv_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_msubv_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_msubv_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_msubv_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_mulv_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_mulv_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_mulv_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_mulv_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_asub_s_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_asub_s_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_asub_s_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_asub_s_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_asub_u_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_asub_u_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_asub_u_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_asub_u_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_hsub_s_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_hsub_s_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_hsub_s_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_hsub_u_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_hsub_u_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_hsub_u_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_subs_s_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_subs_s_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_subs_s_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_subs_s_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_subs_u_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_subs_u_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_subs_u_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_subs_u_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_subsus_u_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_subsus_u_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_subsus_u_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_subsus_u_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_subsuu_s_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_subsuu_s_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_subsuu_s_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_subsuu_s_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_subv_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_subv_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_subv_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_subv_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_ilvev_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ilvev_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ilvev_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ilvev_d, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ilvod_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ilvod_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ilvod_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ilvod_d, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ilvl_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ilvl_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ilvl_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ilvl_d, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ilvr_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ilvr_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ilvr_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ilvr_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_and_v, void, env, i32, i32, i32) -DEF_HELPER_4(msa_nor_v, void, env, i32, i32, i32) -DEF_HELPER_4(msa_or_v, void, env, i32, i32, i32) -DEF_HELPER_4(msa_xor_v, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_pckev_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_pckev_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_pckev_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_pckev_d, void, env, i32, i32, i32) -DEF_HELPER_4(msa_pckod_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_pckod_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_pckod_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_pckod_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_sll_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_sll_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_sll_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_sll_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_sra_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_sra_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_sra_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_sra_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_srar_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_srar_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_srar_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_srar_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_srl_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_srl_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_srl_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_srl_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_srlr_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_srlr_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_srlr_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_srlr_d, void, env, i32, i32, i32) - -DEF_HELPER_3(msa_move_v, void, env, i32, i32) - -DEF_HELPER_4(msa_andi_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ori_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_nori_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_xori_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_bmnzi_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_bmzi_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_bseli_b, void, env, i32, i32, i32) -DEF_HELPER_5(msa_shf_df, void, env, i32, i32, i32, i32) - -DEF_HELPER_5(msa_addvi_df, void, env, i32, i32, i32, s32) -DEF_HELPER_5(msa_subvi_df, void, env, i32, i32, i32, s32) -DEF_HELPER_5(msa_maxi_s_df, void, env, i32, i32, i32, s32) -DEF_HELPER_5(msa_maxi_u_df, void, env, i32, i32, i32, s32) -DEF_HELPER_5(msa_mini_s_df, void, env, i32, i32, i32, s32) -DEF_HELPER_5(msa_mini_u_df, void, env, i32, i32, i32, s32) -DEF_HELPER_5(msa_ceqi_df, void, env, i32, i32, i32, s32) -DEF_HELPER_5(msa_clti_s_df, void, env, i32, i32, i32, s32) -DEF_HELPER_5(msa_clti_u_df, void, env, i32, i32, i32, s32) -DEF_HELPER_5(msa_clei_s_df, void, env, i32, i32, i32, s32) -DEF_HELPER_5(msa_clei_u_df, void, env, i32, i32, i32, s32) -DEF_HELPER_4(msa_ldi_df, void, env, i32, i32, s32) - -DEF_HELPER_5(msa_slli_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_srai_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_srli_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_bclri_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_bseti_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_bnegi_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_binsli_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_binsri_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_sat_s_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_sat_u_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_srari_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_srlri_df, void, env, i32, i32, i32, i32) - -DEF_HELPER_5(msa_binsl_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_binsr_df, void, env, i32, i32, i32, i32) - -DEF_HELPER_4(msa_dotp_s_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_dotp_s_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_dotp_s_d, void, env, i32, i32, i32) -DEF_HELPER_4(msa_dotp_u_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_dotp_u_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_dotp_u_d, void, env, i32, i32, i32) -DEF_HELPER_4(msa_dpadd_s_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_dpadd_s_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_dpadd_s_d, void, env, i32, i32, i32) -DEF_HELPER_4(msa_dpadd_u_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_dpadd_u_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_dpadd_u_d, void, env, i32, i32, i32) -DEF_HELPER_4(msa_dpsub_s_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_dpsub_s_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_dpsub_s_d, void, env, i32, i32, i32) -DEF_HELPER_4(msa_dpsub_u_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_dpsub_u_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_dpsub_u_d, void, env, i32, i32, i32) -DEF_HELPER_5(msa_sld_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_splat_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_vshf_df, void, env, i32, i32, i32, i32) - -DEF_HELPER_5(msa_sldi_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_splati_df, void, env, i32, i32, i32, i32) - -DEF_HELPER_5(msa_insve_df, void, env, i32, i32, i32, i32) -DEF_HELPER_3(msa_ctcmsa, void, env, tl, i32) -DEF_HELPER_2(msa_cfcmsa, tl, env, i32) - -DEF_HELPER_5(msa_fcaf_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fcun_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fceq_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fcueq_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fclt_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fcult_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fcle_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fcule_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fsaf_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fsun_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fseq_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fsueq_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fslt_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fsult_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fsle_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fsule_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fadd_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fsub_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fmul_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fdiv_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fmadd_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fmsub_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fexp2_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fexdo_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_ftq_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fmin_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fmin_a_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fmax_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fmax_a_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fcor_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fcune_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fcne_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_mul_q_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_madd_q_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_msub_q_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fsor_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fsune_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_fsne_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_mulr_q_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_maddr_q_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_msubr_q_df, void, env, i32, i32, i32, i32) - -DEF_HELPER_4(msa_fill_df, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_copy_s_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_copy_s_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_copy_s_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_copy_s_d, void, env, i32, i32, i32) -DEF_HELPER_4(msa_copy_u_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_copy_u_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_copy_u_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_insert_b, void, env, i32, i32, i32) -DEF_HELPER_4(msa_insert_h, void, env, i32, i32, i32) -DEF_HELPER_4(msa_insert_w, void, env, i32, i32, i32) -DEF_HELPER_4(msa_insert_d, void, env, i32, i32, i32) - -DEF_HELPER_4(msa_fclass_df, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ftrunc_s_df, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ftrunc_u_df, void, env, i32, i32, i32) -DEF_HELPER_4(msa_fsqrt_df, void, env, i32, i32, i32) -DEF_HELPER_4(msa_frsqrt_df, void, env, i32, i32, i32) -DEF_HELPER_4(msa_frcp_df, void, env, i32, i32, i32) -DEF_HELPER_4(msa_frint_df, void, env, i32, i32, i32) -DEF_HELPER_4(msa_flog2_df, void, env, i32, i32, i32) -DEF_HELPER_4(msa_fexupl_df, void, env, i32, i32, i32) -DEF_HELPER_4(msa_fexupr_df, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ffql_df, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ffqr_df, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ftint_s_df, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ftint_u_df, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ffint_s_df, void, env, i32, i32, i32) -DEF_HELPER_4(msa_ffint_u_df, void, env, i32, i32, i32) - -#define MSALDST_PROTO(type) \ -DEF_HELPER_3(msa_ld_ ## type, void, env, i32, tl) \ -DEF_HELPER_3(msa_st_ ## type, void, env, i32, tl) -MSALDST_PROTO(b) -MSALDST_PROTO(h) -MSALDST_PROTO(w) -MSALDST_PROTO(d) -#undef MSALDST_PROTO - DEF_HELPER_3(cache, void, env, tl, i32) + +#include "msa_helper.h.inc" diff --git a/target/mips/msa_helper.h.inc b/target/mips/msa_helper.h.inc new file mode 100644 index 0000000000..4963d1553a --- /dev/null +++ b/target/mips/msa_helper.h.inc @@ -0,0 +1,443 @@ +/* + * MIPS SIMD Architecture Module (MSA) helpers for QEMU. + * + * Copyright (c) 2004-2005 Jocelyn Mayer + * Copyright (c) 2006 Marius Groeger (FPU operations) + * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support) + * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support) + * Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support) + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +DEF_HELPER_3(msa_nloc_b, void, env, i32, i32) +DEF_HELPER_3(msa_nloc_h, void, env, i32, i32) +DEF_HELPER_3(msa_nloc_w, void, env, i32, i32) +DEF_HELPER_3(msa_nloc_d, void, env, i32, i32) + +DEF_HELPER_3(msa_nlzc_b, void, env, i32, i32) +DEF_HELPER_3(msa_nlzc_h, void, env, i32, i32) +DEF_HELPER_3(msa_nlzc_w, void, env, i32, i32) +DEF_HELPER_3(msa_nlzc_d, void, env, i32, i32) + +DEF_HELPER_3(msa_pcnt_b, void, env, i32, i32) +DEF_HELPER_3(msa_pcnt_h, void, env, i32, i32) +DEF_HELPER_3(msa_pcnt_w, void, env, i32, i32) +DEF_HELPER_3(msa_pcnt_d, void, env, i32, i32) + +DEF_HELPER_4(msa_binsl_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_binsl_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_binsl_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_binsl_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_binsr_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_binsr_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_binsr_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_binsr_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_bmnz_v, void, env, i32, i32, i32) +DEF_HELPER_4(msa_bmz_v, void, env, i32, i32, i32) +DEF_HELPER_4(msa_bsel_v, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_bclr_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_bclr_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_bclr_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_bclr_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_bneg_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_bneg_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_bneg_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_bneg_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_bset_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_bset_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_bset_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_bset_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_add_a_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_add_a_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_add_a_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_add_a_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_adds_a_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_adds_a_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_adds_a_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_adds_a_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_adds_s_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_adds_s_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_adds_s_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_adds_s_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_adds_u_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_adds_u_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_adds_u_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_adds_u_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_addv_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_addv_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_addv_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_addv_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_hadd_s_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_hadd_s_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_hadd_s_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_hadd_u_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_hadd_u_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_hadd_u_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_ave_s_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ave_s_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ave_s_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ave_s_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_ave_u_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ave_u_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ave_u_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ave_u_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_aver_s_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_aver_s_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_aver_s_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_aver_s_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_aver_u_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_aver_u_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_aver_u_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_aver_u_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_ceq_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ceq_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ceq_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ceq_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_cle_s_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_cle_s_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_cle_s_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_cle_s_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_cle_u_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_cle_u_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_cle_u_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_cle_u_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_clt_s_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_clt_s_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_clt_s_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_clt_s_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_clt_u_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_clt_u_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_clt_u_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_clt_u_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_div_s_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_div_s_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_div_s_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_div_s_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_div_u_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_div_u_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_div_u_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_div_u_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_max_a_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_max_a_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_max_a_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_max_a_d, void, env, i32, i32, i32) +DEF_HELPER_4(msa_max_s_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_max_s_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_max_s_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_max_s_d, void, env, i32, i32, i32) +DEF_HELPER_4(msa_max_u_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_max_u_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_max_u_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_max_u_d, void, env, i32, i32, i32) +DEF_HELPER_4(msa_min_a_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_min_a_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_min_a_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_min_a_d, void, env, i32, i32, i32) +DEF_HELPER_4(msa_min_s_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_min_s_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_min_s_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_min_s_d, void, env, i32, i32, i32) +DEF_HELPER_4(msa_min_u_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_min_u_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_min_u_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_min_u_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_mod_u_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_mod_u_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_mod_u_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_mod_u_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_mod_s_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_mod_s_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_mod_s_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_mod_s_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_maddv_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_maddv_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_maddv_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_maddv_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_msubv_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_msubv_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_msubv_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_msubv_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_mulv_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_mulv_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_mulv_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_mulv_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_asub_s_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_asub_s_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_asub_s_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_asub_s_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_asub_u_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_asub_u_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_asub_u_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_asub_u_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_hsub_s_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_hsub_s_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_hsub_s_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_hsub_u_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_hsub_u_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_hsub_u_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_subs_s_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_subs_s_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_subs_s_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_subs_s_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_subs_u_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_subs_u_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_subs_u_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_subs_u_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_subsus_u_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_subsus_u_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_subsus_u_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_subsus_u_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_subsuu_s_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_subsuu_s_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_subsuu_s_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_subsuu_s_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_subv_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_subv_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_subv_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_subv_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_ilvev_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ilvev_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ilvev_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ilvev_d, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ilvod_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ilvod_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ilvod_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ilvod_d, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ilvl_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ilvl_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ilvl_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ilvl_d, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ilvr_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ilvr_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ilvr_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ilvr_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_and_v, void, env, i32, i32, i32) +DEF_HELPER_4(msa_nor_v, void, env, i32, i32, i32) +DEF_HELPER_4(msa_or_v, void, env, i32, i32, i32) +DEF_HELPER_4(msa_xor_v, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_pckev_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_pckev_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_pckev_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_pckev_d, void, env, i32, i32, i32) +DEF_HELPER_4(msa_pckod_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_pckod_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_pckod_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_pckod_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_sll_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_sll_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_sll_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_sll_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_sra_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_sra_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_sra_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_sra_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_srar_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_srar_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_srar_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_srar_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_srl_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_srl_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_srl_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_srl_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_srlr_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_srlr_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_srlr_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_srlr_d, void, env, i32, i32, i32) + +DEF_HELPER_3(msa_move_v, void, env, i32, i32) + +DEF_HELPER_4(msa_andi_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ori_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_nori_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_xori_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_bmnzi_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_bmzi_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_bseli_b, void, env, i32, i32, i32) +DEF_HELPER_5(msa_shf_df, void, env, i32, i32, i32, i32) + +DEF_HELPER_5(msa_addvi_df, void, env, i32, i32, i32, s32) +DEF_HELPER_5(msa_subvi_df, void, env, i32, i32, i32, s32) +DEF_HELPER_5(msa_maxi_s_df, void, env, i32, i32, i32, s32) +DEF_HELPER_5(msa_maxi_u_df, void, env, i32, i32, i32, s32) +DEF_HELPER_5(msa_mini_s_df, void, env, i32, i32, i32, s32) +DEF_HELPER_5(msa_mini_u_df, void, env, i32, i32, i32, s32) +DEF_HELPER_5(msa_ceqi_df, void, env, i32, i32, i32, s32) +DEF_HELPER_5(msa_clti_s_df, void, env, i32, i32, i32, s32) +DEF_HELPER_5(msa_clti_u_df, void, env, i32, i32, i32, s32) +DEF_HELPER_5(msa_clei_s_df, void, env, i32, i32, i32, s32) +DEF_HELPER_5(msa_clei_u_df, void, env, i32, i32, i32, s32) +DEF_HELPER_4(msa_ldi_df, void, env, i32, i32, s32) + +DEF_HELPER_5(msa_slli_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_srai_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_srli_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_bclri_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_bseti_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_bnegi_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_binsli_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_binsri_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_sat_s_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_sat_u_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_srari_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_srlri_df, void, env, i32, i32, i32, i32) + +DEF_HELPER_5(msa_binsl_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_binsr_df, void, env, i32, i32, i32, i32) + +DEF_HELPER_4(msa_dotp_s_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_dotp_s_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_dotp_s_d, void, env, i32, i32, i32) +DEF_HELPER_4(msa_dotp_u_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_dotp_u_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_dotp_u_d, void, env, i32, i32, i32) +DEF_HELPER_4(msa_dpadd_s_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_dpadd_s_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_dpadd_s_d, void, env, i32, i32, i32) +DEF_HELPER_4(msa_dpadd_u_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_dpadd_u_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_dpadd_u_d, void, env, i32, i32, i32) +DEF_HELPER_4(msa_dpsub_s_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_dpsub_s_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_dpsub_s_d, void, env, i32, i32, i32) +DEF_HELPER_4(msa_dpsub_u_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_dpsub_u_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_dpsub_u_d, void, env, i32, i32, i32) +DEF_HELPER_5(msa_sld_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_splat_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_vshf_df, void, env, i32, i32, i32, i32) + +DEF_HELPER_5(msa_sldi_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_splati_df, void, env, i32, i32, i32, i32) + +DEF_HELPER_5(msa_insve_df, void, env, i32, i32, i32, i32) +DEF_HELPER_3(msa_ctcmsa, void, env, tl, i32) +DEF_HELPER_2(msa_cfcmsa, tl, env, i32) + +DEF_HELPER_5(msa_fcaf_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fcun_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fceq_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fcueq_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fclt_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fcult_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fcle_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fcule_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fsaf_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fsun_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fseq_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fsueq_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fslt_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fsult_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fsle_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fsule_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fadd_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fsub_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fmul_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fdiv_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fmadd_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fmsub_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fexp2_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fexdo_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_ftq_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fmin_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fmin_a_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fmax_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fmax_a_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fcor_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fcune_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fcne_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_mul_q_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_madd_q_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_msub_q_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fsor_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fsune_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_fsne_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_mulr_q_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_maddr_q_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_msubr_q_df, void, env, i32, i32, i32, i32) + +DEF_HELPER_4(msa_fill_df, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_copy_s_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_copy_s_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_copy_s_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_copy_s_d, void, env, i32, i32, i32) +DEF_HELPER_4(msa_copy_u_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_copy_u_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_copy_u_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_insert_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_insert_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_insert_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_insert_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_fclass_df, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ftrunc_s_df, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ftrunc_u_df, void, env, i32, i32, i32) +DEF_HELPER_4(msa_fsqrt_df, void, env, i32, i32, i32) +DEF_HELPER_4(msa_frsqrt_df, void, env, i32, i32, i32) +DEF_HELPER_4(msa_frcp_df, void, env, i32, i32, i32) +DEF_HELPER_4(msa_frint_df, void, env, i32, i32, i32) +DEF_HELPER_4(msa_flog2_df, void, env, i32, i32, i32) +DEF_HELPER_4(msa_fexupl_df, void, env, i32, i32, i32) +DEF_HELPER_4(msa_fexupr_df, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ffql_df, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ffqr_df, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ftint_s_df, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ftint_u_df, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ffint_s_df, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ffint_u_df, void, env, i32, i32, i32) + +#define MSALDST_PROTO(type) \ +DEF_HELPER_3(msa_ld_ ## type, void, env, i32, tl) \ +DEF_HELPER_3(msa_st_ ## type, void, env, i32, tl) +MSALDST_PROTO(b) +MSALDST_PROTO(h) +MSALDST_PROTO(w) +MSALDST_PROTO(d) +#undef MSALDST_PROTO -- cgit v1.2.3-55-g7522 From 54ccff51022fcb93d8b3febe18c2bd663ce15ed9 Mon Sep 17 00:00:00 2001 From: Philippe Mathieu-Daudé Date: Sun, 29 Nov 2020 21:17:46 +0100 Subject: target/mips: Declare gen_msa/_branch() in 'translate.h' Make gen_msa() and gen_msa_branch() public declarations so we can keep calling them once extracted from the big translate.c in the next commit. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20201215225757.764263-18-f4bug@amsat.org> Tested-by: Jiaxun Yang --- target/mips/translate.c | 4 ++-- target/mips/translate.h | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/target/mips/translate.c b/target/mips/translate.c index 67418621bc..0f1f89af84 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -28659,7 +28659,7 @@ static bool gen_msa_BxZ(DisasContext *ctx, int df, int wt, int s16, bool if_not) return true; } -static void gen_msa_branch(DisasContext *ctx, uint32_t op1) +void gen_msa_branch(DisasContext *ctx, uint32_t op1) { uint8_t df = (ctx->opcode >> 21) & 0x3; uint8_t wt = (ctx->opcode >> 16) & 0x1f; @@ -30435,7 +30435,7 @@ static void gen_msa_vec(DisasContext *ctx) } } -static void gen_msa(DisasContext *ctx) +void gen_msa(DisasContext *ctx) { uint32_t opcode = ctx->opcode; diff --git a/target/mips/translate.h b/target/mips/translate.h index 190d415c3b..ea9c18029d 100644 --- a/target/mips/translate.h +++ b/target/mips/translate.h @@ -174,5 +174,7 @@ extern TCGv bcond; /* MSA */ void msa_translate_init(void); +void gen_msa(DisasContext *ctx); +void gen_msa_branch(DisasContext *ctx, uint32_t op1); #endif -- cgit v1.2.3-55-g7522 From 80e64a380feb891700cbb21e4966c898dd9c5af9 Mon Sep 17 00:00:00 2001 From: Philippe Mathieu-Daudé Date: Mon, 16 Nov 2020 05:13:37 +0100 Subject: target/mips: Extract MSA translation routines Extract 2200 lines from the huge translate.c to a new file, 'msa_translate.c'. As there are too many inter-dependencies we don't compile it as another object yet, but keep including it in the big translate.o. We gain in code maintainability. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20201120210844.2625602-5-f4bug@amsat.org> Tested-by: Jiaxun Yang --- target/mips/meson.build | 1 + target/mips/msa_translate.c | 2265 +++++++++++++++++++++++++++++++++++++++ target/mips/translate.c | 2485 ++----------------------------------------- 3 files changed, 2384 insertions(+), 2367 deletions(-) create mode 100644 target/mips/msa_translate.c diff --git a/target/mips/meson.build b/target/mips/meson.build index 596eb1aeeb..2aa4d81300 100644 --- a/target/mips/meson.build +++ b/target/mips/meson.build @@ -8,6 +8,7 @@ mips_ss.add(when: 'CONFIG_TCG', if_true: files( 'fpu_helper.c', 'lmmi_helper.c', 'msa_helper.c', + 'msa_translate.c', 'op_helper.c', 'tlb_helper.c', 'translate.c', diff --git a/target/mips/msa_translate.c b/target/mips/msa_translate.c new file mode 100644 index 0000000000..a4f9a6c128 --- /dev/null +++ b/target/mips/msa_translate.c @@ -0,0 +1,2265 @@ +/* + * MIPS SIMD Architecture (MSA) translation routines + * + * Copyright (c) 2004-2005 Jocelyn Mayer + * Copyright (c) 2006 Marius Groeger (FPU operations) + * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support) + * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support) + * Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support) + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ +#include "qemu/osdep.h" +#include "tcg/tcg-op.h" +#include "exec/helper-gen.h" +#include "translate.h" +#include "fpu_helper.h" +#include "internal.h" + +#define OPC_MSA (0x1E << 26) + +#define MASK_MSA_MINOR(op) (MASK_OP_MAJOR(op) | (op & 0x3F)) +enum { + OPC_MSA_I8_00 = 0x00 | OPC_MSA, + OPC_MSA_I8_01 = 0x01 | OPC_MSA, + OPC_MSA_I8_02 = 0x02 | OPC_MSA, + OPC_MSA_I5_06 = 0x06 | OPC_MSA, + OPC_MSA_I5_07 = 0x07 | OPC_MSA, + OPC_MSA_BIT_09 = 0x09 | OPC_MSA, + OPC_MSA_BIT_0A = 0x0A | OPC_MSA, + OPC_MSA_3R_0D = 0x0D | OPC_MSA, + OPC_MSA_3R_0E = 0x0E | OPC_MSA, + OPC_MSA_3R_0F = 0x0F | OPC_MSA, + OPC_MSA_3R_10 = 0x10 | OPC_MSA, + OPC_MSA_3R_11 = 0x11 | OPC_MSA, + OPC_MSA_3R_12 = 0x12 | OPC_MSA, + OPC_MSA_3R_13 = 0x13 | OPC_MSA, + OPC_MSA_3R_14 = 0x14 | OPC_MSA, + OPC_MSA_3R_15 = 0x15 | OPC_MSA, + OPC_MSA_ELM = 0x19 | OPC_MSA, + OPC_MSA_3RF_1A = 0x1A | OPC_MSA, + OPC_MSA_3RF_1B = 0x1B | OPC_MSA, + OPC_MSA_3RF_1C = 0x1C | OPC_MSA, + OPC_MSA_VEC = 0x1E | OPC_MSA, + + /* MI10 instruction */ + OPC_LD_B = (0x20) | OPC_MSA, + OPC_LD_H = (0x21) | OPC_MSA, + OPC_LD_W = (0x22) | OPC_MSA, + OPC_LD_D = (0x23) | OPC_MSA, + OPC_ST_B = (0x24) | OPC_MSA, + OPC_ST_H = (0x25) | OPC_MSA, + OPC_ST_W = (0x26) | OPC_MSA, + OPC_ST_D = (0x27) | OPC_MSA, +}; + +enum { + /* I5 instruction df(bits 22..21) = _b, _h, _w, _d */ + OPC_ADDVI_df = (0x0 << 23) | OPC_MSA_I5_06, + OPC_CEQI_df = (0x0 << 23) | OPC_MSA_I5_07, + OPC_SUBVI_df = (0x1 << 23) | OPC_MSA_I5_06, + OPC_MAXI_S_df = (0x2 << 23) | OPC_MSA_I5_06, + OPC_CLTI_S_df = (0x2 << 23) | OPC_MSA_I5_07, + OPC_MAXI_U_df = (0x3 << 23) | OPC_MSA_I5_06, + OPC_CLTI_U_df = (0x3 << 23) | OPC_MSA_I5_07, + OPC_MINI_S_df = (0x4 << 23) | OPC_MSA_I5_06, + OPC_CLEI_S_df = (0x4 << 23) | OPC_MSA_I5_07, + OPC_MINI_U_df = (0x5 << 23) | OPC_MSA_I5_06, + OPC_CLEI_U_df = (0x5 << 23) | OPC_MSA_I5_07, + OPC_LDI_df = (0x6 << 23) | OPC_MSA_I5_07, + + /* I8 instruction */ + OPC_ANDI_B = (0x0 << 24) | OPC_MSA_I8_00, + OPC_BMNZI_B = (0x0 << 24) | OPC_MSA_I8_01, + OPC_SHF_B = (0x0 << 24) | OPC_MSA_I8_02, + OPC_ORI_B = (0x1 << 24) | OPC_MSA_I8_00, + OPC_BMZI_B = (0x1 << 24) | OPC_MSA_I8_01, + OPC_SHF_H = (0x1 << 24) | OPC_MSA_I8_02, + OPC_NORI_B = (0x2 << 24) | OPC_MSA_I8_00, + OPC_BSELI_B = (0x2 << 24) | OPC_MSA_I8_01, + OPC_SHF_W = (0x2 << 24) | OPC_MSA_I8_02, + OPC_XORI_B = (0x3 << 24) | OPC_MSA_I8_00, + + /* VEC/2R/2RF instruction */ + OPC_AND_V = (0x00 << 21) | OPC_MSA_VEC, + OPC_OR_V = (0x01 << 21) | OPC_MSA_VEC, + OPC_NOR_V = (0x02 << 21) | OPC_MSA_VEC, + OPC_XOR_V = (0x03 << 21) | OPC_MSA_VEC, + OPC_BMNZ_V = (0x04 << 21) | OPC_MSA_VEC, + OPC_BMZ_V = (0x05 << 21) | OPC_MSA_VEC, + OPC_BSEL_V = (0x06 << 21) | OPC_MSA_VEC, + + OPC_MSA_2R = (0x18 << 21) | OPC_MSA_VEC, + OPC_MSA_2RF = (0x19 << 21) | OPC_MSA_VEC, + + /* 2R instruction df(bits 17..16) = _b, _h, _w, _d */ + OPC_FILL_df = (0x00 << 18) | OPC_MSA_2R, + OPC_PCNT_df = (0x01 << 18) | OPC_MSA_2R, + OPC_NLOC_df = (0x02 << 18) | OPC_MSA_2R, + OPC_NLZC_df = (0x03 << 18) | OPC_MSA_2R, + + /* 2RF instruction df(bit 16) = _w, _d */ + OPC_FCLASS_df = (0x00 << 17) | OPC_MSA_2RF, + OPC_FTRUNC_S_df = (0x01 << 17) | OPC_MSA_2RF, + OPC_FTRUNC_U_df = (0x02 << 17) | OPC_MSA_2RF, + OPC_FSQRT_df = (0x03 << 17) | OPC_MSA_2RF, + OPC_FRSQRT_df = (0x04 << 17) | OPC_MSA_2RF, + OPC_FRCP_df = (0x05 << 17) | OPC_MSA_2RF, + OPC_FRINT_df = (0x06 << 17) | OPC_MSA_2RF, + OPC_FLOG2_df = (0x07 << 17) | OPC_MSA_2RF, + OPC_FEXUPL_df = (0x08 << 17) | OPC_MSA_2RF, + OPC_FEXUPR_df = (0x09 << 17) | OPC_MSA_2RF, + OPC_FFQL_df = (0x0A << 17) | OPC_MSA_2RF, + OPC_FFQR_df = (0x0B << 17) | OPC_MSA_2RF, + OPC_FTINT_S_df = (0x0C << 17) | OPC_MSA_2RF, + OPC_FTINT_U_df = (0x0D << 17) | OPC_MSA_2RF, + OPC_FFINT_S_df = (0x0E << 17) | OPC_MSA_2RF, + OPC_FFINT_U_df = (0x0F << 17) | OPC_MSA_2RF, + + /* 3R instruction df(bits 22..21) = _b, _h, _w, d */ + OPC_SLL_df = (0x0 << 23) | OPC_MSA_3R_0D, + OPC_ADDV_df = (0x0 << 23) | OPC_MSA_3R_0E, + OPC_CEQ_df = (0x0 << 23) | OPC_MSA_3R_0F, + OPC_ADD_A_df = (0x0 << 23) | OPC_MSA_3R_10, + OPC_SUBS_S_df = (0x0 << 23) | OPC_MSA_3R_11, + OPC_MULV_df = (0x0 << 23) | OPC_MSA_3R_12, + OPC_DOTP_S_df = (0x0 << 23) | OPC_MSA_3R_13, + OPC_SLD_df = (0x0 << 23) | OPC_MSA_3R_14, + OPC_VSHF_df = (0x0 << 23) | OPC_MSA_3R_15, + OPC_SRA_df = (0x1 << 23) | OPC_MSA_3R_0D, + OPC_SUBV_df = (0x1 << 23) | OPC_MSA_3R_0E, + OPC_ADDS_A_df = (0x1 << 23) | OPC_MSA_3R_10, + OPC_SUBS_U_df = (0x1 << 23) | OPC_MSA_3R_11, + OPC_MADDV_df = (0x1 << 23) | OPC_MSA_3R_12, + OPC_DOTP_U_df = (0x1 << 23) | OPC_MSA_3R_13, + OPC_SPLAT_df = (0x1 << 23) | OPC_MSA_3R_14, + OPC_SRAR_df = (0x1 << 23) | OPC_MSA_3R_15, + OPC_SRL_df = (0x2 << 23) | OPC_MSA_3R_0D, + OPC_MAX_S_df = (0x2 << 23) | OPC_MSA_3R_0E, + OPC_CLT_S_df = (0x2 << 23) | OPC_MSA_3R_0F, + OPC_ADDS_S_df = (0x2 << 23) | OPC_MSA_3R_10, + OPC_SUBSUS_U_df = (0x2 << 23) | OPC_MSA_3R_11, + OPC_MSUBV_df = (0x2 << 23) | OPC_MSA_3R_12, + OPC_DPADD_S_df = (0x2 << 23) | OPC_MSA_3R_13, + OPC_PCKEV_df = (0x2 << 23) | OPC_MSA_3R_14, + OPC_SRLR_df = (0x2 << 23) | OPC_MSA_3R_15, + OPC_BCLR_df = (0x3 << 23) | OPC_MSA_3R_0D, + OPC_MAX_U_df = (0x3 << 23) | OPC_MSA_3R_0E, + OPC_CLT_U_df = (0x3 << 23) | OPC_MSA_3R_0F, + OPC_ADDS_U_df = (0x3 << 23) | OPC_MSA_3R_10, + OPC_SUBSUU_S_df = (0x3 << 23) | OPC_MSA_3R_11, + OPC_DPADD_U_df = (0x3 << 23) | OPC_MSA_3R_13, + OPC_PCKOD_df = (0x3 << 23) | OPC_MSA_3R_14, + OPC_BSET_df = (0x4 << 23) | OPC_MSA_3R_0D, + OPC_MIN_S_df = (0x4 << 23) | OPC_MSA_3R_0E, + OPC_CLE_S_df = (0x4 << 23) | OPC_MSA_3R_0F, + OPC_AVE_S_df = (0x4 << 23) | OPC_MSA_3R_10, + OPC_ASUB_S_df = (0x4 << 23) | OPC_MSA_3R_11, + OPC_DIV_S_df = (0x4 << 23) | OPC_MSA_3R_12, + OPC_DPSUB_S_df = (0x4 << 23) | OPC_MSA_3R_13, + OPC_ILVL_df = (0x4 << 23) | OPC_MSA_3R_14, + OPC_HADD_S_df = (0x4 << 23) | OPC_MSA_3R_15, + OPC_BNEG_df = (0x5 << 23) | OPC_MSA_3R_0D, + OPC_MIN_U_df = (0x5 << 23) | OPC_MSA_3R_0E, + OPC_CLE_U_df = (0x5 << 23) | OPC_MSA_3R_0F, + OPC_AVE_U_df = (0x5 << 23) | OPC_MSA_3R_10, + OPC_ASUB_U_df = (0x5 << 23) | OPC_MSA_3R_11, + OPC_DIV_U_df = (0x5 << 23) | OPC_MSA_3R_12, + OPC_DPSUB_U_df = (0x5 << 23) | OPC_MSA_3R_13, + OPC_ILVR_df = (0x5 << 23) | OPC_MSA_3R_14, + OPC_HADD_U_df = (0x5 << 23) | OPC_MSA_3R_15, + OPC_BINSL_df = (0x6 << 23) | OPC_MSA_3R_0D, + OPC_MAX_A_df = (0x6 << 23) | OPC_MSA_3R_0E, + OPC_AVER_S_df = (0x6 << 23) | OPC_MSA_3R_10, + OPC_MOD_S_df = (0x6 << 23) | OPC_MSA_3R_12, + OPC_ILVEV_df = (0x6 << 23) | OPC_MSA_3R_14, + OPC_HSUB_S_df = (0x6 << 23) | OPC_MSA_3R_15, + OPC_BINSR_df = (0x7 << 23) | OPC_MSA_3R_0D, + OPC_MIN_A_df = (0x7 << 23) | OPC_MSA_3R_0E, + OPC_AVER_U_df = (0x7 << 23) | OPC_MSA_3R_10, + OPC_MOD_U_df = (0x7 << 23) | OPC_MSA_3R_12, + OPC_ILVOD_df = (0x7 << 23) | OPC_MSA_3R_14, + OPC_HSUB_U_df = (0x7 << 23) | OPC_MSA_3R_15, + + /* ELM instructions df(bits 21..16) = _b, _h, _w, _d */ + OPC_SLDI_df = (0x0 << 22) | (0x00 << 16) | OPC_MSA_ELM, + OPC_CTCMSA = (0x0 << 22) | (0x3E << 16) | OPC_MSA_ELM, + OPC_SPLATI_df = (0x1 << 22) | (0x00 << 16) | OPC_MSA_ELM, + OPC_CFCMSA = (0x1 << 22) | (0x3E << 16) | OPC_MSA_ELM, + OPC_COPY_S_df = (0x2 << 22) | (0x00 << 16) | OPC_MSA_ELM, + OPC_MOVE_V = (0x2 << 22) | (0x3E << 16) | OPC_MSA_ELM, + OPC_COPY_U_df = (0x3 << 22) | (0x00 << 16) | OPC_MSA_ELM, + OPC_INSERT_df = (0x4 << 22) | (0x00 << 16) | OPC_MSA_ELM, + OPC_INSVE_df = (0x5 << 22) | (0x00 << 16) | OPC_MSA_ELM, + + /* 3RF instruction _df(bit 21) = _w, _d */ + OPC_FCAF_df = (0x0 << 22) | OPC_MSA_3RF_1A, + OPC_FADD_df = (0x0 << 22) | OPC_MSA_3RF_1B, + OPC_FCUN_df = (0x1 << 22) | OPC_MSA_3RF_1A, + OPC_FSUB_df = (0x1 << 22) | OPC_MSA_3RF_1B, + OPC_FCOR_df = (0x1 << 22) | OPC_MSA_3RF_1C, + OPC_FCEQ_df = (0x2 << 22) | OPC_MSA_3RF_1A, + OPC_FMUL_df = (0x2 << 22) | OPC_MSA_3RF_1B, + OPC_FCUNE_df = (0x2 << 22) | OPC_MSA_3RF_1C, + OPC_FCUEQ_df = (0x3 << 22) | OPC_MSA_3RF_1A, + OPC_FDIV_df = (0x3 << 22) | OPC_MSA_3RF_1B, + OPC_FCNE_df = (0x3 << 22) | OPC_MSA_3RF_1C, + OPC_FCLT_df = (0x4 << 22) | OPC_MSA_3RF_1A, + OPC_FMADD_df = (0x4 << 22) | OPC_MSA_3RF_1B, + OPC_MUL_Q_df = (0x4 << 22) | OPC_MSA_3RF_1C, + OPC_FCULT_df = (0x5 << 22) | OPC_MSA_3RF_1A, + OPC_FMSUB_df = (0x5 << 22) | OPC_MSA_3RF_1B, + OPC_MADD_Q_df = (0x5 << 22) | OPC_MSA_3RF_1C, + OPC_FCLE_df = (0x6 << 22) | OPC_MSA_3RF_1A, + OPC_MSUB_Q_df = (0x6 << 22) | OPC_MSA_3RF_1C, + OPC_FCULE_df = (0x7 << 22) | OPC_MSA_3RF_1A, + OPC_FEXP2_df = (0x7 << 22) | OPC_MSA_3RF_1B, + OPC_FSAF_df = (0x8 << 22) | OPC_MSA_3RF_1A, + OPC_FEXDO_df = (0x8 << 22) | OPC_MSA_3RF_1B, + OPC_FSUN_df = (0x9 << 22) | OPC_MSA_3RF_1A, + OPC_FSOR_df = (0x9 << 22) | OPC_MSA_3RF_1C, + OPC_FSEQ_df = (0xA << 22) | OPC_MSA_3RF_1A, + OPC_FTQ_df = (0xA << 22) | OPC_MSA_3RF_1B, + OPC_FSUNE_df = (0xA << 22) | OPC_MSA_3RF_1C, + OPC_FSUEQ_df = (0xB << 22) | OPC_MSA_3RF_1A, + OPC_FSNE_df = (0xB << 22) | OPC_MSA_3RF_1C, + OPC_FSLT_df = (0xC << 22) | OPC_MSA_3RF_1A, + OPC_FMIN_df = (0xC << 22) | OPC_MSA_3RF_1B, + OPC_MULR_Q_df = (0xC << 22) | OPC_MSA_3RF_1C, + OPC_FSULT_df = (0xD << 22) | OPC_MSA_3RF_1A, + OPC_FMIN_A_df = (0xD << 22) | OPC_MSA_3RF_1B, + OPC_MADDR_Q_df = (0xD << 22) | OPC_MSA_3RF_1C, + OPC_FSLE_df = (0xE << 22) | OPC_MSA_3RF_1A, + OPC_FMAX_df = (0xE << 22) | OPC_MSA_3RF_1B, + OPC_MSUBR_Q_df = (0xE << 22) | OPC_MSA_3RF_1C, + OPC_FSULE_df = (0xF << 22) | OPC_MSA_3RF_1A, + OPC_FMAX_A_df = (0xF << 22) | OPC_MSA_3RF_1B, + + /* BIT instruction df(bits 22..16) = _B _H _W _D */ + OPC_SLLI_df = (0x0 << 23) | OPC_MSA_BIT_09, + OPC_SAT_S_df = (0x0 << 23) | OPC_MSA_BIT_0A, + OPC_SRAI_df = (0x1 << 23) | OPC_MSA_BIT_09, + OPC_SAT_U_df = (0x1 << 23) | OPC_MSA_BIT_0A, + OPC_SRLI_df = (0x2 << 23) | OPC_MSA_BIT_09, + OPC_SRARI_df = (0x2 << 23) | OPC_MSA_BIT_0A, + OPC_BCLRI_df = (0x3 << 23) | OPC_MSA_BIT_09, + OPC_SRLRI_df = (0x3 << 23) | OPC_MSA_BIT_0A, + OPC_BSETI_df = (0x4 << 23) | OPC_MSA_BIT_09, + OPC_BNEGI_df = (0x5 << 23) | OPC_MSA_BIT_09, + OPC_BINSLI_df = (0x6 << 23) | OPC_MSA_BIT_09, + OPC_BINSRI_df = (0x7 << 23) | OPC_MSA_BIT_09, +}; + +static const char * const msaregnames[] = { + "w0.d0", "w0.d1", "w1.d0", "w1.d1", + "w2.d0", "w2.d1", "w3.d0", "w3.d1", + "w4.d0", "w4.d1", "w5.d0", "w5.d1", + "w6.d0", "w6.d1", "w7.d0", "w7.d1", + "w8.d0", "w8.d1", "w9.d0", "w9.d1", + "w10.d0", "w10.d1", "w11.d0", "w11.d1", + "w12.d0", "w12.d1", "w13.d0", "w13.d1", + "w14.d0", "w14.d1", "w15.d0", "w15.d1", + "w16.d0", "w16.d1", "w17.d0", "w17.d1", + "w18.d0", "w18.d1", "w19.d0", "w19.d1", + "w20.d0", "w20.d1", "w21.d0", "w21.d1", + "w22.d0", "w22.d1", "w23.d0", "w23.d1", + "w24.d0", "w24.d1", "w25.d0", "w25.d1", + "w26.d0", "w26.d1", "w27.d0", "w27.d1", + "w28.d0", "w28.d1", "w29.d0", "w29.d1", + "w30.d0", "w30.d1", "w31.d0", "w31.d1", +}; + +static TCGv_i64 msa_wr_d[64]; + +void msa_translate_init(void) +{ + int i; + + for (i = 0; i < 32; i++) { + int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]); + + /* + * The MSA vector registers are mapped on the + * scalar floating-point unit (FPU) registers. + */ + msa_wr_d[i * 2] = fpu_f64[i]; + off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]); + msa_wr_d[i * 2 + 1] = + tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2 + 1]); + } +} + +static inline int check_msa_access(DisasContext *ctx) +{ + if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) && + !(ctx->hflags & MIPS_HFLAG_F64))) { + gen_reserved_instruction(ctx); + return 0; + } + + if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) { + generate_exception_end(ctx, EXCP_MSADIS); + return 0; + } + return 1; +} + +static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt) +{ + /* generates tcg ops to check if any element is 0 */ + /* Note this function only works with MSA_WRLEN = 128 */ + uint64_t eval_zero_or_big = 0; + uint64_t eval_big = 0; + TCGv_i64 t0 = tcg_temp_new_i64(); + TCGv_i64 t1 = tcg_temp_new_i64(); + switch (df) { + case DF_BYTE: + eval_zero_or_big = 0x0101010101010101ULL; + eval_big = 0x8080808080808080ULL; + break; + case DF_HALF: + eval_zero_or_big = 0x0001000100010001ULL; + eval_big = 0x8000800080008000ULL; + break; + case DF_WORD: + eval_zero_or_big = 0x0000000100000001ULL; + eval_big = 0x8000000080000000ULL; + break; + case DF_DOUBLE: + eval_zero_or_big = 0x0000000000000001ULL; + eval_big = 0x8000000000000000ULL; + break; + } + tcg_gen_subi_i64(t0, msa_wr_d[wt << 1], eval_zero_or_big); + tcg_gen_andc_i64(t0, t0, msa_wr_d[wt << 1]); + tcg_gen_andi_i64(t0, t0, eval_big); + tcg_gen_subi_i64(t1, msa_wr_d[(wt << 1) + 1], eval_zero_or_big); + tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt << 1) + 1]); + tcg_gen_andi_i64(t1, t1, eval_big); + tcg_gen_or_i64(t0, t0, t1); + /* if all bits are zero then all elements are not zero */ + /* if some bit is non-zero then some element is zero */ + tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0); + tcg_gen_trunc_i64_tl(tresult, t0); + tcg_temp_free_i64(t0); + tcg_temp_free_i64(t1); +} + +static bool gen_msa_BxZ_V(DisasContext *ctx, int wt, int s16, TCGCond cond) +{ + TCGv_i64 t0; + + check_msa_access(ctx); + + if (ctx->hflags & MIPS_HFLAG_BMASK) { + gen_reserved_instruction(ctx); + return true; + } + t0 = tcg_temp_new_i64(); + tcg_gen_or_i64(t0, msa_wr_d[wt << 1], msa_wr_d[(wt << 1) + 1]); + tcg_gen_setcondi_i64(cond, t0, t0, 0); + tcg_gen_trunc_i64_tl(bcond, t0); + tcg_temp_free_i64(t0); + + ctx->btarget = ctx->base.pc_next + (s16 << 2) + 4; + + ctx->hflags |= MIPS_HFLAG_BC; + ctx->hflags |= MIPS_HFLAG_BDS32; + + return true; +} + +static bool gen_msa_BxZ(DisasContext *ctx, int df, int wt, int s16, bool if_not) +{ + check_msa_access(ctx); + + if (ctx->hflags & MIPS_HFLAG_BMASK) { + gen_reserved_instruction(ctx); + return true; + } + + gen_check_zero_element(bcond, df, wt); + if (if_not) { + tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0); + } + + ctx->btarget = ctx->base.pc_next + (s16 << 2) + 4; + ctx->hflags |= MIPS_HFLAG_BC; + ctx->hflags |= MIPS_HFLAG_BDS32; + + return true; +} + +void gen_msa_branch(DisasContext *ctx, uint32_t op1) +{ + uint8_t df = (ctx->opcode >> 21) & 0x3; + uint8_t wt = (ctx->opcode >> 16) & 0x1f; + int64_t s16 = (int16_t)ctx->opcode; + + switch (op1) { + case OPC_BZ_V: + case OPC_BNZ_V: + gen_msa_BxZ_V(ctx, wt, s16, (op1 == OPC_BZ_V) ? + TCG_COND_EQ : TCG_COND_NE); + break; + case OPC_BZ_B: + case OPC_BZ_H: + case OPC_BZ_W: + case OPC_BZ_D: + gen_msa_BxZ(ctx, df, wt, s16, false); + break; + case OPC_BNZ_B: + case OPC_BNZ_H: + case OPC_BNZ_W: + case OPC_BNZ_D: + gen_msa_BxZ(ctx, df, wt, s16, true); + break; + } +} + +static void gen_msa_i8(DisasContext *ctx) +{ +#define MASK_MSA_I8(op) (MASK_MSA_MINOR(op) | (op & (0x03 << 24))) + uint8_t i8 = (ctx->opcode >> 16) & 0xff; + uint8_t ws = (ctx->opcode >> 11) & 0x1f; + uint8_t wd = (ctx->opcode >> 6) & 0x1f; + + TCGv_i32 twd = tcg_const_i32(wd); + TCGv_i32 tws = tcg_const_i32(ws); + TCGv_i32 ti8 = tcg_const_i32(i8); + + switch (MASK_MSA_I8(ctx->opcode)) { + case OPC_ANDI_B: + gen_helper_msa_andi_b(cpu_env, twd, tws, ti8); + break; + case OPC_ORI_B: + gen_helper_msa_ori_b(cpu_env, twd, tws, ti8); + break; + case OPC_NORI_B: + gen_helper_msa_nori_b(cpu_env, twd, tws, ti8); + break; + case OPC_XORI_B: + gen_helper_msa_xori_b(cpu_env, twd, tws, ti8); + break; + case OPC_BMNZI_B: + gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8); + break; + case OPC_BMZI_B: + gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8); + break; + case OPC_BSELI_B: + gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8); + break; + case OPC_SHF_B: + case OPC_SHF_H: + case OPC_SHF_W: + { + uint8_t df = (ctx->opcode >> 24) & 0x3; + if (df == DF_DOUBLE) { + gen_reserved_instruction(ctx); + } else { + TCGv_i32 tdf = tcg_const_i32(df); + gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8); + tcg_temp_free_i32(tdf); + } + } + break; + default: + MIPS_INVAL("MSA instruction"); + gen_reserved_instruction(ctx); + break; + } + + tcg_temp_free_i32(twd); + tcg_temp_free_i32(tws); + tcg_temp_free_i32(ti8); +} + +static void gen_msa_i5(DisasContext *ctx) +{ +#define MASK_MSA_I5(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23))) + uint8_t df = (ctx->opcode >> 21) & 0x3; + int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5); + uint8_t u5 = (ctx->opcode >> 16) & 0x1f; + uint8_t ws = (ctx->opcode >> 11) & 0x1f; + uint8_t wd = (ctx->opcode >> 6) & 0x1f; + + TCGv_i32 tdf = tcg_const_i32(df); + TCGv_i32 twd = tcg_const_i32(wd); + TCGv_i32 tws = tcg_const_i32(ws); + TCGv_i32 timm = tcg_temp_new_i32(); + tcg_gen_movi_i32(timm, u5); + + switch (MASK_MSA_I5(ctx->opcode)) { + case OPC_ADDVI_df: + gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm); + break; + case OPC_SUBVI_df: + gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm); + break; + case OPC_MAXI_S_df: + tcg_gen_movi_i32(timm, s5); + gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm); + break; + case OPC_MAXI_U_df: + gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm); + break; + case OPC_MINI_S_df: + tcg_gen_movi_i32(timm, s5); + gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm); + break; + case OPC_MINI_U_df: + gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm); + break; + case OPC_CEQI_df: + tcg_gen_movi_i32(timm, s5); + gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm); + break; + case OPC_CLTI_S_df: + tcg_gen_movi_i32(timm, s5); + gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm); + break; + case OPC_CLTI_U_df: + gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm); + break; + case OPC_CLEI_S_df: + tcg_gen_movi_i32(timm, s5); + gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm); + break; + case OPC_CLEI_U_df: + gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm); + break; + case OPC_LDI_df: + { + int32_t s10 = sextract32(ctx->opcode, 11, 10); + tcg_gen_movi_i32(timm, s10); + gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm); + } + break; + default: + MIPS_INVAL("MSA instruction"); + gen_reserved_instruction(ctx); + break; + } + + tcg_temp_free_i32(tdf); + tcg_temp_free_i32(twd); + tcg_temp_free_i32(tws); + tcg_temp_free_i32(timm); +} + +static void gen_msa_bit(DisasContext *ctx) +{ +#define MASK_MSA_BIT(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23))) + uint8_t dfm = (ctx->opcode >> 16) & 0x7f; + uint32_t df = 0, m = 0; + uint8_t ws = (ctx->opcode >> 11) & 0x1f; + uint8_t wd = (ctx->opcode >> 6) & 0x1f; + + TCGv_i32 tdf; + TCGv_i32 tm; + TCGv_i32 twd; + TCGv_i32 tws; + + if ((dfm & 0x40) == 0x00) { + m = dfm & 0x3f; + df = DF_DOUBLE; + } else if ((dfm & 0x60) == 0x40) { + m = dfm & 0x1f; + df = DF_WORD; + } else if ((dfm & 0x70) == 0x60) { + m = dfm & 0x0f; + df = DF_HALF; + } else if ((dfm & 0x78) == 0x70) { + m = dfm & 0x7; + df = DF_BYTE; + } else { + gen_reserved_instruction(ctx); + return; + } + + tdf = tcg_const_i32(df); + tm = tcg_const_i32(m); + twd = tcg_const_i32(wd); + tws = tcg_const_i32(ws); + + switch (MASK_MSA_BIT(ctx->opcode)) { + case OPC_SLLI_df: + gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm); + break; + case OPC_SRAI_df: + gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm); + break; + case OPC_SRLI_df: + gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm); + break; + case OPC_BCLRI_df: + gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm); + break; + case OPC_BSETI_df: + gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm); + break; + case OPC_BNEGI_df: + gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm); + break; + case OPC_BINSLI_df: + gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm); + break; + case OPC_BINSRI_df: + gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm); + break; + case OPC_SAT_S_df: + gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm); + break; + case OPC_SAT_U_df: + gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm); + break; + case OPC_SRARI_df: + gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm); + break; + case OPC_SRLRI_df: + gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm); + break; + default: + MIPS_INVAL("MSA instruction"); + gen_reserved_instruction(ctx); + break; + } + + tcg_temp_free_i32(tdf); + tcg_temp_free_i32(tm); + tcg_temp_free_i32(twd); + tcg_temp_free_i32(tws); +} + +static void gen_msa_3r(DisasContext *ctx) +{ +#define MASK_MSA_3R(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23))) + uint8_t df = (ctx->opcode >> 21) & 0x3; + uint8_t wt = (ctx->opcode >> 16) & 0x1f; + uint8_t ws = (ctx->opcode >> 11) & 0x1f; + uint8_t wd = (ctx->opcode >> 6) & 0x1f; + + TCGv_i32 tdf = tcg_const_i32(df); + TCGv_i32 twd = tcg_const_i32(wd); + TCGv_i32 tws = tcg_const_i32(ws); + TCGv_i32 twt = tcg_const_i32(wt); + + switch (MASK_MSA_3R(ctx->opcode)) { + case OPC_BINSL_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_binsl_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_binsl_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_binsl_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_binsl_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_BINSR_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_binsr_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_binsr_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_binsr_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_binsr_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_BCLR_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_bclr_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_bclr_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_bclr_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_bclr_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_BNEG_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_bneg_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_bneg_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_bneg_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_bneg_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_BSET_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_bset_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_bset_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_bset_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_bset_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_ADD_A_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_add_a_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_add_a_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_add_a_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_add_a_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_ADDS_A_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_adds_a_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_adds_a_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_adds_a_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_adds_a_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_ADDS_S_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_adds_s_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_adds_s_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_adds_s_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_adds_s_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_ADDS_U_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_adds_u_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_adds_u_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_adds_u_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_adds_u_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_ADDV_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_addv_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_addv_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_addv_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_addv_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_AVE_S_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_ave_s_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_ave_s_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_ave_s_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_ave_s_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_AVE_U_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_ave_u_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_ave_u_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_ave_u_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_ave_u_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_AVER_S_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_aver_s_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_aver_s_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_aver_s_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_aver_s_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_AVER_U_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_aver_u_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_aver_u_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_aver_u_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_aver_u_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_CEQ_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_ceq_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_ceq_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_ceq_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_ceq_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_CLE_S_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_cle_s_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_cle_s_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_cle_s_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_cle_s_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_CLE_U_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_cle_u_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_cle_u_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_cle_u_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_cle_u_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_CLT_S_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_clt_s_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_clt_s_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_clt_s_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_clt_s_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_CLT_U_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_clt_u_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_clt_u_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_clt_u_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_clt_u_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_DIV_S_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_div_s_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_div_s_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_div_s_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_div_s_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_DIV_U_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_div_u_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_div_u_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_div_u_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_div_u_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_MAX_A_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_max_a_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_max_a_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_max_a_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_max_a_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_MAX_S_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_max_s_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_max_s_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_max_s_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_max_s_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_MAX_U_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_max_u_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_max_u_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_max_u_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_max_u_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_MIN_A_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_min_a_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_min_a_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_min_a_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_min_a_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_MIN_S_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_min_s_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_min_s_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_min_s_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_min_s_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_MIN_U_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_min_u_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_min_u_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_min_u_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_min_u_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_MOD_S_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_mod_s_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_mod_s_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_mod_s_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_mod_s_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_MOD_U_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_mod_u_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_mod_u_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_mod_u_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_mod_u_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_MADDV_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_maddv_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_maddv_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_maddv_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_maddv_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_MSUBV_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_msubv_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_msubv_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_msubv_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_msubv_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_ASUB_S_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_asub_s_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_asub_s_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_asub_s_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_asub_s_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_ASUB_U_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_asub_u_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_asub_u_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_asub_u_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_asub_u_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_ILVEV_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_ilvev_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_ilvev_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_ilvev_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_ilvev_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_ILVOD_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_ilvod_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_ilvod_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_ilvod_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_ilvod_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_ILVL_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_ilvl_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_ilvl_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_ilvl_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_ilvl_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_ILVR_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_ilvr_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_ilvr_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_ilvr_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_ilvr_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_PCKEV_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_pckev_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_pckev_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_pckev_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_pckev_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_PCKOD_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_pckod_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_pckod_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_pckod_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_pckod_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_SLL_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_sll_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_sll_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_sll_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_sll_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_SRA_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_sra_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_sra_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_sra_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_sra_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_SRAR_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_srar_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_srar_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_srar_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_srar_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_SRL_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_srl_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_srl_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_srl_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_srl_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_SRLR_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_srlr_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_srlr_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_srlr_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_srlr_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_SUBS_S_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_subs_s_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_subs_s_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_subs_s_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_subs_s_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_MULV_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_mulv_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_mulv_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_mulv_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_mulv_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_SLD_df: + gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_VSHF_df: + gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_SUBV_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_subv_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_subv_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_subv_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_subv_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_SUBS_U_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_subs_u_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_subs_u_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_subs_u_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_subs_u_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_SPLAT_df: + gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_SUBSUS_U_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_subsus_u_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_subsus_u_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_subsus_u_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_subsus_u_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_SUBSUU_S_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_subsuu_s_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_subsuu_s_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_subsuu_s_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_subsuu_s_d(cpu_env, twd, tws, twt); + break; + } + break; + + case OPC_DOTP_S_df: + case OPC_DOTP_U_df: + case OPC_DPADD_S_df: + case OPC_DPADD_U_df: + case OPC_DPSUB_S_df: + case OPC_HADD_S_df: + case OPC_DPSUB_U_df: + case OPC_HADD_U_df: + case OPC_HSUB_S_df: + case OPC_HSUB_U_df: + if (df == DF_BYTE) { + gen_reserved_instruction(ctx); + break; + } + switch (MASK_MSA_3R(ctx->opcode)) { + case OPC_HADD_S_df: + switch (df) { + case DF_HALF: + gen_helper_msa_hadd_s_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_hadd_s_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_hadd_s_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_HADD_U_df: + switch (df) { + case DF_HALF: + gen_helper_msa_hadd_u_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_hadd_u_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_hadd_u_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_HSUB_S_df: + switch (df) { + case DF_HALF: + gen_helper_msa_hsub_s_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_hsub_s_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_hsub_s_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_HSUB_U_df: + switch (df) { + case DF_HALF: + gen_helper_msa_hsub_u_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_hsub_u_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_hsub_u_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_DOTP_S_df: + switch (df) { + case DF_HALF: + gen_helper_msa_dotp_s_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_dotp_s_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_dotp_s_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_DOTP_U_df: + switch (df) { + case DF_HALF: + gen_helper_msa_dotp_u_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_dotp_u_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_dotp_u_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_DPADD_S_df: + switch (df) { + case DF_HALF: + gen_helper_msa_dpadd_s_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_dpadd_s_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_dpadd_s_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_DPADD_U_df: + switch (df) { + case DF_HALF: + gen_helper_msa_dpadd_u_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_dpadd_u_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_dpadd_u_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_DPSUB_S_df: + switch (df) { + case DF_HALF: + gen_helper_msa_dpsub_s_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_dpsub_s_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_dpsub_s_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_DPSUB_U_df: + switch (df) { + case DF_HALF: + gen_helper_msa_dpsub_u_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_dpsub_u_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_dpsub_u_d(cpu_env, twd, tws, twt); + break; + } + break; + } + break; + default: + MIPS_INVAL("MSA instruction"); + gen_reserved_instruction(ctx); + break; + } + tcg_temp_free_i32(twd); + tcg_temp_free_i32(tws); + tcg_temp_free_i32(twt); + tcg_temp_free_i32(tdf); +} + +static void gen_msa_elm_3e(DisasContext *ctx) +{ +#define MASK_MSA_ELM_DF3E(op) (MASK_MSA_MINOR(op) | (op & (0x3FF << 16))) + uint8_t source = (ctx->opcode >> 11) & 0x1f; + uint8_t dest = (ctx->opcode >> 6) & 0x1f; + TCGv telm = tcg_temp_new(); + TCGv_i32 tsr = tcg_const_i32(source); + TCGv_i32 tdt = tcg_const_i32(dest); + + switch (MASK_MSA_ELM_DF3E(ctx->opcode)) { + case OPC_CTCMSA: + gen_load_gpr(telm, source); + gen_helper_msa_ctcmsa(cpu_env, telm, tdt); + break; + case OPC_CFCMSA: + gen_helper_msa_cfcmsa(telm, cpu_env, tsr); + gen_store_gpr(telm, dest); + break; + case OPC_MOVE_V: + gen_helper_msa_move_v(cpu_env, tdt, tsr); + break; + default: + MIPS_INVAL("MSA instruction"); + gen_reserved_instruction(ctx); + break; + } + + tcg_temp_free(telm); + tcg_temp_free_i32(tdt); + tcg_temp_free_i32(tsr); +} + +static void gen_msa_elm_df(DisasContext *ctx, uint32_t df, uint32_t n) +{ +#define MASK_MSA_ELM(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22))) + uint8_t ws = (ctx->opcode >> 11) & 0x1f; + uint8_t wd = (ctx->opcode >> 6) & 0x1f; + + TCGv_i32 tws = tcg_const_i32(ws); + TCGv_i32 twd = tcg_const_i32(wd); + TCGv_i32 tn = tcg_const_i32(n); + TCGv_i32 tdf = tcg_const_i32(df); + + switch (MASK_MSA_ELM(ctx->opcode)) { + case OPC_SLDI_df: + gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn); + break; + case OPC_SPLATI_df: + gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn); + break; + case OPC_INSVE_df: + gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn); + break; + case OPC_COPY_S_df: + case OPC_COPY_U_df: + case OPC_INSERT_df: +#if !defined(TARGET_MIPS64) + /* Double format valid only for MIPS64 */ + if (df == DF_DOUBLE) { + gen_reserved_instruction(ctx); + break; + } + if ((MASK_MSA_ELM(ctx->opcode) == OPC_COPY_U_df) && + (df == DF_WORD)) { + gen_reserved_instruction(ctx); + break; + } +#endif + switch (MASK_MSA_ELM(ctx->opcode)) { + case OPC_COPY_S_df: + if (likely(wd != 0)) { + switch (df) { + case DF_BYTE: + gen_helper_msa_copy_s_b(cpu_env, twd, tws, tn); + break; + case DF_HALF: + gen_helper_msa_copy_s_h(cpu_env, twd, tws, tn); + break; + case DF_WORD: + gen_helper_msa_copy_s_w(cpu_env, twd, tws, tn); + break; +#if defined(TARGET_MIPS64) + case DF_DOUBLE: + gen_helper_msa_copy_s_d(cpu_env, twd, tws, tn); + break; +#endif + default: + assert(0); + } + } + break; + case OPC_COPY_U_df: + if (likely(wd != 0)) { + switch (df) { + case DF_BYTE: + gen_helper_msa_copy_u_b(cpu_env, twd, tws, tn); + break; + case DF_HALF: + gen_helper_msa_copy_u_h(cpu_env, twd, tws, tn); + break; +#if defined(TARGET_MIPS64) + case DF_WORD: + gen_helper_msa_copy_u_w(cpu_env, twd, tws, tn); + break; +#endif + default: + assert(0); + } + } + break; + case OPC_INSERT_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_insert_b(cpu_env, twd, tws, tn); + break; + case DF_HALF: + gen_helper_msa_insert_h(cpu_env, twd, tws, tn); + break; + case DF_WORD: + gen_helper_msa_insert_w(cpu_env, twd, tws, tn); + break; +#if defined(TARGET_MIPS64) + case DF_DOUBLE: + gen_helper_msa_insert_d(cpu_env, twd, tws, tn); + break; +#endif + default: + assert(0); + } + break; + } + break; + default: + MIPS_INVAL("MSA instruction"); + gen_reserved_instruction(ctx); + } + tcg_temp_free_i32(twd); + tcg_temp_free_i32(tws); + tcg_temp_free_i32(tn); + tcg_temp_free_i32(tdf); +} + +static void gen_msa_elm(DisasContext *ctx) +{ + uint8_t dfn = (ctx->opcode >> 16) & 0x3f; + uint32_t df = 0, n = 0; + + if ((dfn & 0x30) == 0x00) { + n = dfn & 0x0f; + df = DF_BYTE; + } else if ((dfn & 0x38) == 0x20) { + n = dfn & 0x07; + df = DF_HALF; + } else if ((dfn & 0x3c) == 0x30) { + n = dfn & 0x03; + df = DF_WORD; + } else if ((dfn & 0x3e) == 0x38) { + n = dfn & 0x01; + df = DF_DOUBLE; + } else if (dfn == 0x3E) { + /* CTCMSA, CFCMSA, MOVE.V */ + gen_msa_elm_3e(ctx); + return; + } else { + gen_reserved_instruction(ctx); + return; + } + + gen_msa_elm_df(ctx, df, n); +} + +static void gen_msa_3rf(DisasContext *ctx) +{ +#define MASK_MSA_3RF(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22))) + uint8_t df = (ctx->opcode >> 21) & 0x1; + uint8_t wt = (ctx->opcode >> 16) & 0x1f; + uint8_t ws = (ctx->opcode >> 11) & 0x1f; + uint8_t wd = (ctx->opcode >> 6) & 0x1f; + + TCGv_i32 twd = tcg_const_i32(wd); + TCGv_i32 tws = tcg_const_i32(ws); + TCGv_i32 twt = tcg_const_i32(wt); + TCGv_i32 tdf = tcg_temp_new_i32(); + + /* adjust df value for floating-point instruction */ + tcg_gen_movi_i32(tdf, df + 2); + + switch (MASK_MSA_3RF(ctx->opcode)) { + case OPC_FCAF_df: + gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FADD_df: + gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FCUN_df: + gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FSUB_df: + gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FCOR_df: + gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FCEQ_df: + gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FMUL_df: + gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FCUNE_df: + gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FCUEQ_df: + gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FDIV_df: + gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FCNE_df: + gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FCLT_df: + gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FMADD_df: + gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_MUL_Q_df: + tcg_gen_movi_i32(tdf, df + 1); + gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FCULT_df: + gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FMSUB_df: + gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_MADD_Q_df: + tcg_gen_movi_i32(tdf, df + 1); + gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FCLE_df: + gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_MSUB_Q_df: + tcg_gen_movi_i32(tdf, df + 1); + gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FCULE_df: + gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FEXP2_df: + gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FSAF_df: + gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FEXDO_df: + gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FSUN_df: + gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FSOR_df: + gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FSEQ_df: + gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FTQ_df: + gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FSUNE_df: + gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FSUEQ_df: + gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FSNE_df: + gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FSLT_df: + gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FMIN_df: + gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_MULR_Q_df: + tcg_gen_movi_i32(tdf, df + 1); + gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FSULT_df: + gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FMIN_A_df: + gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_MADDR_Q_df: + tcg_gen_movi_i32(tdf, df + 1); + gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FSLE_df: + gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FMAX_df: + gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_MSUBR_Q_df: + tcg_gen_movi_i32(tdf, df + 1); + gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FSULE_df: + gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt); + break; + case OPC_FMAX_A_df: + gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt); + break; + default: + MIPS_INVAL("MSA instruction"); + gen_reserved_instruction(ctx); + break; + } + + tcg_temp_free_i32(twd); + tcg_temp_free_i32(tws); + tcg_temp_free_i32(twt); + tcg_temp_free_i32(tdf); +} + +static void gen_msa_2r(DisasContext *ctx) +{ +#define MASK_MSA_2R(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \ + (op & (0x7 << 18))) + uint8_t wt = (ctx->opcode >> 16) & 0x1f; + uint8_t ws = (ctx->opcode >> 11) & 0x1f; + uint8_t wd = (ctx->opcode >> 6) & 0x1f; + uint8_t df = (ctx->opcode >> 16) & 0x3; + TCGv_i32 twd = tcg_const_i32(wd); + TCGv_i32 tws = tcg_const_i32(ws); + TCGv_i32 twt = tcg_const_i32(wt); + TCGv_i32 tdf = tcg_const_i32(df); + + switch (MASK_MSA_2R(ctx->opcode)) { + case OPC_FILL_df: +#if !defined(TARGET_MIPS64) + /* Double format valid only for MIPS64 */ + if (df == DF_DOUBLE) { + gen_reserved_instruction(ctx); + break; + } +#endif + gen_helper_msa_fill_df(cpu_env, tdf, twd, tws); /* trs */ + break; + case OPC_NLOC_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_nloc_b(cpu_env, twd, tws); + break; + case DF_HALF: + gen_helper_msa_nloc_h(cpu_env, twd, tws); + break; + case DF_WORD: + gen_helper_msa_nloc_w(cpu_env, twd, tws); + break; + case DF_DOUBLE: + gen_helper_msa_nloc_d(cpu_env, twd, tws); + break; + } + break; + case OPC_NLZC_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_nlzc_b(cpu_env, twd, tws); + break; + case DF_HALF: + gen_helper_msa_nlzc_h(cpu_env, twd, tws); + break; + case DF_WORD: + gen_helper_msa_nlzc_w(cpu_env, twd, tws); + break; + case DF_DOUBLE: + gen_helper_msa_nlzc_d(cpu_env, twd, tws); + break; + } + break; + case OPC_PCNT_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_pcnt_b(cpu_env, twd, tws); + break; + case DF_HALF: + gen_helper_msa_pcnt_h(cpu_env, twd, tws); + break; + case DF_WORD: + gen_helper_msa_pcnt_w(cpu_env, twd, tws); + break; + case DF_DOUBLE: + gen_helper_msa_pcnt_d(cpu_env, twd, tws); + break; + } + break; + default: + MIPS_INVAL("MSA instruction"); + gen_reserved_instruction(ctx); + break; + } + + tcg_temp_free_i32(twd); + tcg_temp_free_i32(tws); + tcg_temp_free_i32(twt); + tcg_temp_free_i32(tdf); +} + +static void gen_msa_2rf(DisasContext *ctx) +{ +#define MASK_MSA_2RF(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \ + (op & (0xf << 17))) + uint8_t wt = (ctx->opcode >> 16) & 0x1f; + uint8_t ws = (ctx->opcode >> 11) & 0x1f; + uint8_t wd = (ctx->opcode >> 6) & 0x1f; + uint8_t df = (ctx->opcode >> 16) & 0x1; + TCGv_i32 twd = tcg_const_i32(wd); + TCGv_i32 tws = tcg_const_i32(ws); + TCGv_i32 twt = tcg_const_i32(wt); + /* adjust df value for floating-point instruction */ + TCGv_i32 tdf = tcg_const_i32(df + 2); + + switch (MASK_MSA_2RF(ctx->opcode)) { + case OPC_FCLASS_df: + gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws); + break; + case OPC_FTRUNC_S_df: + gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws); + break; + case OPC_FTRUNC_U_df: + gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws); + break; + case OPC_FSQRT_df: + gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws); + break; + case OPC_FRSQRT_df: + gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws); + break; + case OPC_FRCP_df: + gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws); + break; + case OPC_FRINT_df: + gen_helper_msa_frint_df(cpu_env, tdf, twd, tws); + break; + case OPC_FLOG2_df: + gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws); + break; + case OPC_FEXUPL_df: + gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws); + break; + case OPC_FEXUPR_df: + gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws); + break; + case OPC_FFQL_df: + gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws); + break; + case OPC_FFQR_df: + gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws); + break; + case OPC_FTINT_S_df: + gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws); + break; + case OPC_FTINT_U_df: + gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws); + break; + case OPC_FFINT_S_df: + gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws); + break; + case OPC_FFINT_U_df: + gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws); + break; + } + + tcg_temp_free_i32(twd); + tcg_temp_free_i32(tws); + tcg_temp_free_i32(twt); + tcg_temp_free_i32(tdf); +} + +static void gen_msa_vec_v(DisasContext *ctx) +{ +#define MASK_MSA_VEC(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21))) + uint8_t wt = (ctx->opcode >> 16) & 0x1f; + uint8_t ws = (ctx->opcode >> 11) & 0x1f; + uint8_t wd = (ctx->opcode >> 6) & 0x1f; + TCGv_i32 twd = tcg_const_i32(wd); + TCGv_i32 tws = tcg_const_i32(ws); + TCGv_i32 twt = tcg_const_i32(wt); + + switch (MASK_MSA_VEC(ctx->opcode)) { + case OPC_AND_V: + gen_helper_msa_and_v(cpu_env, twd, tws, twt); + break; + case OPC_OR_V: + gen_helper_msa_or_v(cpu_env, twd, tws, twt); + break; + case OPC_NOR_V: + gen_helper_msa_nor_v(cpu_env, twd, tws, twt); + break; + case OPC_XOR_V: + gen_helper_msa_xor_v(cpu_env, twd, tws, twt); + break; + case OPC_BMNZ_V: + gen_helper_msa_bmnz_v(cpu_env, twd, tws, twt); + break; + case OPC_BMZ_V: + gen_helper_msa_bmz_v(cpu_env, twd, tws, twt); + break; + case OPC_BSEL_V: + gen_helper_msa_bsel_v(cpu_env, twd, tws, twt); + break; + default: + MIPS_INVAL("MSA instruction"); + gen_reserved_instruction(ctx); + break; + } + + tcg_temp_free_i32(twd); + tcg_temp_free_i32(tws); + tcg_temp_free_i32(twt); +} + +static void gen_msa_vec(DisasContext *ctx) +{ + switch (MASK_MSA_VEC(ctx->opcode)) { + case OPC_AND_V: + case OPC_OR_V: + case OPC_NOR_V: + case OPC_XOR_V: + case OPC_BMNZ_V: + case OPC_BMZ_V: + case OPC_BSEL_V: + gen_msa_vec_v(ctx); + break; + case OPC_MSA_2R: + gen_msa_2r(ctx); + break; + case OPC_MSA_2RF: + gen_msa_2rf(ctx); + break; + default: + MIPS_INVAL("MSA instruction"); + gen_reserved_instruction(ctx); + break; + } +} + +void gen_msa(DisasContext *ctx) +{ + uint32_t opcode = ctx->opcode; + + check_msa_access(ctx); + + switch (MASK_MSA_MINOR(opcode)) { + case OPC_MSA_I8_00: + case OPC_MSA_I8_01: + case OPC_MSA_I8_02: + gen_msa_i8(ctx); + break; + case OPC_MSA_I5_06: + case OPC_MSA_I5_07: + gen_msa_i5(ctx); + break; + case OPC_MSA_BIT_09: + case OPC_MSA_BIT_0A: + gen_msa_bit(ctx); + break; + case OPC_MSA_3R_0D: + case OPC_MSA_3R_0E: + case OPC_MSA_3R_0F: + case OPC_MSA_3R_10: + case OPC_MSA_3R_11: + case OPC_MSA_3R_12: + case OPC_MSA_3R_13: + case OPC_MSA_3R_14: + case OPC_MSA_3R_15: + gen_msa_3r(ctx); + break; + case OPC_MSA_ELM: + gen_msa_elm(ctx); + break; + case OPC_MSA_3RF_1A: + case OPC_MSA_3RF_1B: + case OPC_MSA_3RF_1C: + gen_msa_3rf(ctx); + break; + case OPC_MSA_VEC: + gen_msa_vec(ctx); + break; + case OPC_LD_B: + case OPC_LD_H: + case OPC_LD_W: + case OPC_LD_D: + case OPC_ST_B: + case OPC_ST_H: + case OPC_ST_W: + case OPC_ST_D: + { + int32_t s10 = sextract32(ctx->opcode, 16, 10); + uint8_t rs = (ctx->opcode >> 11) & 0x1f; + uint8_t wd = (ctx->opcode >> 6) & 0x1f; + uint8_t df = (ctx->opcode >> 0) & 0x3; + + TCGv_i32 twd = tcg_const_i32(wd); + TCGv taddr = tcg_temp_new(); + gen_base_offset_addr(ctx, taddr, rs, s10 << df); + + switch (MASK_MSA_MINOR(opcode)) { + case OPC_LD_B: + gen_helper_msa_ld_b(cpu_env, twd, taddr); + break; + case OPC_LD_H: + gen_helper_msa_ld_h(cpu_env, twd, taddr); + break; + case OPC_LD_W: + gen_helper_msa_ld_w(cpu_env, twd, taddr); + break; + case OPC_LD_D: + gen_helper_msa_ld_d(cpu_env, twd, taddr); + break; + case OPC_ST_B: + gen_helper_msa_st_b(cpu_env, twd, taddr); + break; + case OPC_ST_H: + gen_helper_msa_st_h(cpu_env, twd, taddr); + break; + case OPC_ST_W: + gen_helper_msa_st_w(cpu_env, twd, taddr); + break; + case OPC_ST_D: + gen_helper_msa_st_d(cpu_env, twd, taddr); + break; + } + + tcg_temp_free_i32(twd); + tcg_temp_free(taddr); + } + break; + default: + MIPS_INVAL("MSA instruction"); + gen_reserved_instruction(ctx); + break; + } +} diff --git a/target/mips/translate.c b/target/mips/translate.c index 0f1f89af84..da5d555916 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -1133,240 +1133,6 @@ enum { OPC_NMSUB_PS = 0x3E | OPC_CP3, }; -/* MSA Opcodes */ -#define MASK_MSA_MINOR(op) (MASK_OP_MAJOR(op) | (op & 0x3F)) -enum { - OPC_MSA_I8_00 = 0x00 | OPC_MSA, - OPC_MSA_I8_01 = 0x01 | OPC_MSA, - OPC_MSA_I8_02 = 0x02 | OPC_MSA, - OPC_MSA_I5_06 = 0x06 | OPC_MSA, - OPC_MSA_I5_07 = 0x07 | OPC_MSA, - OPC_MSA_BIT_09 = 0x09 | OPC_MSA, - OPC_MSA_BIT_0A = 0x0A | OPC_MSA, - OPC_MSA_3R_0D = 0x0D | OPC_MSA, - OPC_MSA_3R_0E = 0x0E | OPC_MSA, - OPC_MSA_3R_0F = 0x0F | OPC_MSA, - OPC_MSA_3R_10 = 0x10 | OPC_MSA, - OPC_MSA_3R_11 = 0x11 | OPC_MSA, - OPC_MSA_3R_12 = 0x12 | OPC_MSA, - OPC_MSA_3R_13 = 0x13 | OPC_MSA, - OPC_MSA_3R_14 = 0x14 | OPC_MSA, - OPC_MSA_3R_15 = 0x15 | OPC_MSA, - OPC_MSA_ELM = 0x19 | OPC_MSA, - OPC_MSA_3RF_1A = 0x1A | OPC_MSA, - OPC_MSA_3RF_1B = 0x1B | OPC_MSA, - OPC_MSA_3RF_1C = 0x1C | OPC_MSA, - OPC_MSA_VEC = 0x1E | OPC_MSA, - - /* MI10 instruction */ - OPC_LD_B = (0x20) | OPC_MSA, - OPC_LD_H = (0x21) | OPC_MSA, - OPC_LD_W = (0x22) | OPC_MSA, - OPC_LD_D = (0x23) | OPC_MSA, - OPC_ST_B = (0x24) | OPC_MSA, - OPC_ST_H = (0x25) | OPC_MSA, - OPC_ST_W = (0x26) | OPC_MSA, - OPC_ST_D = (0x27) | OPC_MSA, -}; - -enum { - /* I5 instruction df(bits 22..21) = _b, _h, _w, _d */ - OPC_ADDVI_df = (0x0 << 23) | OPC_MSA_I5_06, - OPC_CEQI_df = (0x0 << 23) | OPC_MSA_I5_07, - OPC_SUBVI_df = (0x1 << 23) | OPC_MSA_I5_06, - OPC_MAXI_S_df = (0x2 << 23) | OPC_MSA_I5_06, - OPC_CLTI_S_df = (0x2 << 23) | OPC_MSA_I5_07, - OPC_MAXI_U_df = (0x3 << 23) | OPC_MSA_I5_06, - OPC_CLTI_U_df = (0x3 << 23) | OPC_MSA_I5_07, - OPC_MINI_S_df = (0x4 << 23) | OPC_MSA_I5_06, - OPC_CLEI_S_df = (0x4 << 23) | OPC_MSA_I5_07, - OPC_MINI_U_df = (0x5 << 23) | OPC_MSA_I5_06, - OPC_CLEI_U_df = (0x5 << 23) | OPC_MSA_I5_07, - OPC_LDI_df = (0x6 << 23) | OPC_MSA_I5_07, - - /* I8 instruction */ - OPC_ANDI_B = (0x0 << 24) | OPC_MSA_I8_00, - OPC_BMNZI_B = (0x0 << 24) | OPC_MSA_I8_01, - OPC_SHF_B = (0x0 << 24) | OPC_MSA_I8_02, - OPC_ORI_B = (0x1 << 24) | OPC_MSA_I8_00, - OPC_BMZI_B = (0x1 << 24) | OPC_MSA_I8_01, - OPC_SHF_H = (0x1 << 24) | OPC_MSA_I8_02, - OPC_NORI_B = (0x2 << 24) | OPC_MSA_I8_00, - OPC_BSELI_B = (0x2 << 24) | OPC_MSA_I8_01, - OPC_SHF_W = (0x2 << 24) | OPC_MSA_I8_02, - OPC_XORI_B = (0x3 << 24) | OPC_MSA_I8_00, - - /* VEC/2R/2RF instruction */ - OPC_AND_V = (0x00 << 21) | OPC_MSA_VEC, - OPC_OR_V = (0x01 << 21) | OPC_MSA_VEC, - OPC_NOR_V = (0x02 << 21) | OPC_MSA_VEC, - OPC_XOR_V = (0x03 << 21) | OPC_MSA_VEC, - OPC_BMNZ_V = (0x04 << 21) | OPC_MSA_VEC, - OPC_BMZ_V = (0x05 << 21) | OPC_MSA_VEC, - OPC_BSEL_V = (0x06 << 21) | OPC_MSA_VEC, - - OPC_MSA_2R = (0x18 << 21) | OPC_MSA_VEC, - OPC_MSA_2RF = (0x19 << 21) | OPC_MSA_VEC, - - /* 2R instruction df(bits 17..16) = _b, _h, _w, _d */ - OPC_FILL_df = (0x00 << 18) | OPC_MSA_2R, - OPC_PCNT_df = (0x01 << 18) | OPC_MSA_2R, - OPC_NLOC_df = (0x02 << 18) | OPC_MSA_2R, - OPC_NLZC_df = (0x03 << 18) | OPC_MSA_2R, - - /* 2RF instruction df(bit 16) = _w, _d */ - OPC_FCLASS_df = (0x00 << 17) | OPC_MSA_2RF, - OPC_FTRUNC_S_df = (0x01 << 17) | OPC_MSA_2RF, - OPC_FTRUNC_U_df = (0x02 << 17) | OPC_MSA_2RF, - OPC_FSQRT_df = (0x03 << 17) | OPC_MSA_2RF, - OPC_FRSQRT_df = (0x04 << 17) | OPC_MSA_2RF, - OPC_FRCP_df = (0x05 << 17) | OPC_MSA_2RF, - OPC_FRINT_df = (0x06 << 17) | OPC_MSA_2RF, - OPC_FLOG2_df = (0x07 << 17) | OPC_MSA_2RF, - OPC_FEXUPL_df = (0x08 << 17) | OPC_MSA_2RF, - OPC_FEXUPR_df = (0x09 << 17) | OPC_MSA_2RF, - OPC_FFQL_df = (0x0A << 17) | OPC_MSA_2RF, - OPC_FFQR_df = (0x0B << 17) | OPC_MSA_2RF, - OPC_FTINT_S_df = (0x0C << 17) | OPC_MSA_2RF, - OPC_FTINT_U_df = (0x0D << 17) | OPC_MSA_2RF, - OPC_FFINT_S_df = (0x0E << 17) | OPC_MSA_2RF, - OPC_FFINT_U_df = (0x0F << 17) | OPC_MSA_2RF, - - /* 3R instruction df(bits 22..21) = _b, _h, _w, d */ - OPC_SLL_df = (0x0 << 23) | OPC_MSA_3R_0D, - OPC_ADDV_df = (0x0 << 23) | OPC_MSA_3R_0E, - OPC_CEQ_df = (0x0 << 23) | OPC_MSA_3R_0F, - OPC_ADD_A_df = (0x0 << 23) | OPC_MSA_3R_10, - OPC_SUBS_S_df = (0x0 << 23) | OPC_MSA_3R_11, - OPC_MULV_df = (0x0 << 23) | OPC_MSA_3R_12, - OPC_DOTP_S_df = (0x0 << 23) | OPC_MSA_3R_13, - OPC_SLD_df = (0x0 << 23) | OPC_MSA_3R_14, - OPC_VSHF_df = (0x0 << 23) | OPC_MSA_3R_15, - OPC_SRA_df = (0x1 << 23) | OPC_MSA_3R_0D, - OPC_SUBV_df = (0x1 << 23) | OPC_MSA_3R_0E, - OPC_ADDS_A_df = (0x1 << 23) | OPC_MSA_3R_10, - OPC_SUBS_U_df = (0x1 << 23) | OPC_MSA_3R_11, - OPC_MADDV_df = (0x1 << 23) | OPC_MSA_3R_12, - OPC_DOTP_U_df = (0x1 << 23) | OPC_MSA_3R_13, - OPC_SPLAT_df = (0x1 << 23) | OPC_MSA_3R_14, - OPC_SRAR_df = (0x1 << 23) | OPC_MSA_3R_15, - OPC_SRL_df = (0x2 << 23) | OPC_MSA_3R_0D, - OPC_MAX_S_df = (0x2 << 23) | OPC_MSA_3R_0E, - OPC_CLT_S_df = (0x2 << 23) | OPC_MSA_3R_0F, - OPC_ADDS_S_df = (0x2 << 23) | OPC_MSA_3R_10, - OPC_SUBSUS_U_df = (0x2 << 23) | OPC_MSA_3R_11, - OPC_MSUBV_df = (0x2 << 23) | OPC_MSA_3R_12, - OPC_DPADD_S_df = (0x2 << 23) | OPC_MSA_3R_13, - OPC_PCKEV_df = (0x2 << 23) | OPC_MSA_3R_14, - OPC_SRLR_df = (0x2 << 23) | OPC_MSA_3R_15, - OPC_BCLR_df = (0x3 << 23) | OPC_MSA_3R_0D, - OPC_MAX_U_df = (0x3 << 23) | OPC_MSA_3R_0E, - OPC_CLT_U_df = (0x3 << 23) | OPC_MSA_3R_0F, - OPC_ADDS_U_df = (0x3 << 23) | OPC_MSA_3R_10, - OPC_SUBSUU_S_df = (0x3 << 23) | OPC_MSA_3R_11, - OPC_DPADD_U_df = (0x3 << 23) | OPC_MSA_3R_13, - OPC_PCKOD_df = (0x3 << 23) | OPC_MSA_3R_14, - OPC_BSET_df = (0x4 << 23) | OPC_MSA_3R_0D, - OPC_MIN_S_df = (0x4 << 23) | OPC_MSA_3R_0E, - OPC_CLE_S_df = (0x4 << 23) | OPC_MSA_3R_0F, - OPC_AVE_S_df = (0x4 << 23) | OPC_MSA_3R_10, - OPC_ASUB_S_df = (0x4 << 23) | OPC_MSA_3R_11, - OPC_DIV_S_df = (0x4 << 23) | OPC_MSA_3R_12, - OPC_DPSUB_S_df = (0x4 << 23) | OPC_MSA_3R_13, - OPC_ILVL_df = (0x4 << 23) | OPC_MSA_3R_14, - OPC_HADD_S_df = (0x4 << 23) | OPC_MSA_3R_15, - OPC_BNEG_df = (0x5 << 23) | OPC_MSA_3R_0D, - OPC_MIN_U_df = (0x5 << 23) | OPC_MSA_3R_0E, - OPC_CLE_U_df = (0x5 << 23) | OPC_MSA_3R_0F, - OPC_AVE_U_df = (0x5 << 23) | OPC_MSA_3R_10, - OPC_ASUB_U_df = (0x5 << 23) | OPC_MSA_3R_11, - OPC_DIV_U_df = (0x5 << 23) | OPC_MSA_3R_12, - OPC_DPSUB_U_df = (0x5 << 23) | OPC_MSA_3R_13, - OPC_ILVR_df = (0x5 << 23) | OPC_MSA_3R_14, - OPC_HADD_U_df = (0x5 << 23) | OPC_MSA_3R_15, - OPC_BINSL_df = (0x6 << 23) | OPC_MSA_3R_0D, - OPC_MAX_A_df = (0x6 << 23) | OPC_MSA_3R_0E, - OPC_AVER_S_df = (0x6 << 23) | OPC_MSA_3R_10, - OPC_MOD_S_df = (0x6 << 23) | OPC_MSA_3R_12, - OPC_ILVEV_df = (0x6 << 23) | OPC_MSA_3R_14, - OPC_HSUB_S_df = (0x6 << 23) | OPC_MSA_3R_15, - OPC_BINSR_df = (0x7 << 23) | OPC_MSA_3R_0D, - OPC_MIN_A_df = (0x7 << 23) | OPC_MSA_3R_0E, - OPC_AVER_U_df = (0x7 << 23) | OPC_MSA_3R_10, - OPC_MOD_U_df = (0x7 << 23) | OPC_MSA_3R_12, - OPC_ILVOD_df = (0x7 << 23) | OPC_MSA_3R_14, - OPC_HSUB_U_df = (0x7 << 23) | OPC_MSA_3R_15, - - /* ELM instructions df(bits 21..16) = _b, _h, _w, _d */ - OPC_SLDI_df = (0x0 << 22) | (0x00 << 16) | OPC_MSA_ELM, - OPC_CTCMSA = (0x0 << 22) | (0x3E << 16) | OPC_MSA_ELM, - OPC_SPLATI_df = (0x1 << 22) | (0x00 << 16) | OPC_MSA_ELM, - OPC_CFCMSA = (0x1 << 22) | (0x3E << 16) | OPC_MSA_ELM, - OPC_COPY_S_df = (0x2 << 22) | (0x00 << 16) | OPC_MSA_ELM, - OPC_MOVE_V = (0x2 << 22) | (0x3E << 16) | OPC_MSA_ELM, - OPC_COPY_U_df = (0x3 << 22) | (0x00 << 16) | OPC_MSA_ELM, - OPC_INSERT_df = (0x4 << 22) | (0x00 << 16) | OPC_MSA_ELM, - OPC_INSVE_df = (0x5 << 22) | (0x00 << 16) | OPC_MSA_ELM, - - /* 3RF instruction _df(bit 21) = _w, _d */ - OPC_FCAF_df = (0x0 << 22) | OPC_MSA_3RF_1A, - OPC_FADD_df = (0x0 << 22) | OPC_MSA_3RF_1B, - OPC_FCUN_df = (0x1 << 22) | OPC_MSA_3RF_1A, - OPC_FSUB_df = (0x1 << 22) | OPC_MSA_3RF_1B, - OPC_FCOR_df = (0x1 << 22) | OPC_MSA_3RF_1C, - OPC_FCEQ_df = (0x2 << 22) | OPC_MSA_3RF_1A, - OPC_FMUL_df = (0x2 << 22) | OPC_MSA_3RF_1B, - OPC_FCUNE_df = (0x2 << 22) | OPC_MSA_3RF_1C, - OPC_FCUEQ_df = (0x3 << 22) | OPC_MSA_3RF_1A, - OPC_FDIV_df = (0x3 << 22) | OPC_MSA_3RF_1B, - OPC_FCNE_df = (0x3 << 22) | OPC_MSA_3RF_1C, - OPC_FCLT_df = (0x4 << 22) | OPC_MSA_3RF_1A, - OPC_FMADD_df = (0x4 << 22) | OPC_MSA_3RF_1B, - OPC_MUL_Q_df = (0x4 << 22) | OPC_MSA_3RF_1C, - OPC_FCULT_df = (0x5 << 22) | OPC_MSA_3RF_1A, - OPC_FMSUB_df = (0x5 << 22) | OPC_MSA_3RF_1B, - OPC_MADD_Q_df = (0x5 << 22) | OPC_MSA_3RF_1C, - OPC_FCLE_df = (0x6 << 22) | OPC_MSA_3RF_1A, - OPC_MSUB_Q_df = (0x6 << 22) | OPC_MSA_3RF_1C, - OPC_FCULE_df = (0x7 << 22) | OPC_MSA_3RF_1A, - OPC_FEXP2_df = (0x7 << 22) | OPC_MSA_3RF_1B, - OPC_FSAF_df = (0x8 << 22) | OPC_MSA_3RF_1A, - OPC_FEXDO_df = (0x8 << 22) | OPC_MSA_3RF_1B, - OPC_FSUN_df = (0x9 << 22) | OPC_MSA_3RF_1A, - OPC_FSOR_df = (0x9 << 22) | OPC_MSA_3RF_1C, - OPC_FSEQ_df = (0xA << 22) | OPC_MSA_3RF_1A, - OPC_FTQ_df = (0xA << 22) | OPC_MSA_3RF_1B, - OPC_FSUNE_df = (0xA << 22) | OPC_MSA_3RF_1C, - OPC_FSUEQ_df = (0xB << 22) | OPC_MSA_3RF_1A, - OPC_FSNE_df = (0xB << 22) | OPC_MSA_3RF_1C, - OPC_FSLT_df = (0xC << 22) | OPC_MSA_3RF_1A, - OPC_FMIN_df = (0xC << 22) | OPC_MSA_3RF_1B, - OPC_MULR_Q_df = (0xC << 22) | OPC_MSA_3RF_1C, - OPC_FSULT_df = (0xD << 22) | OPC_MSA_3RF_1A, - OPC_FMIN_A_df = (0xD << 22) | OPC_MSA_3RF_1B, - OPC_MADDR_Q_df = (0xD << 22) | OPC_MSA_3RF_1C, - OPC_FSLE_df = (0xE << 22) | OPC_MSA_3RF_1A, - OPC_FMAX_df = (0xE << 22) | OPC_MSA_3RF_1B, - OPC_MSUBR_Q_df = (0xE << 22) | OPC_MSA_3RF_1C, - OPC_FSULE_df = (0xF << 22) | OPC_MSA_3RF_1A, - OPC_FMAX_A_df = (0xF << 22) | OPC_MSA_3RF_1B, - - /* BIT instruction df(bits 22..16) = _B _H _W _D */ - OPC_SLLI_df = (0x0 << 23) | OPC_MSA_BIT_09, - OPC_SAT_S_df = (0x0 << 23) | OPC_MSA_BIT_0A, - OPC_SRAI_df = (0x1 << 23) | OPC_MSA_BIT_09, - OPC_SAT_U_df = (0x1 << 23) | OPC_MSA_BIT_0A, - OPC_SRLI_df = (0x2 << 23) | OPC_MSA_BIT_09, - OPC_SRARI_df = (0x2 << 23) | OPC_MSA_BIT_0A, - OPC_BCLRI_df = (0x3 << 23) | OPC_MSA_BIT_09, - OPC_SRLRI_df = (0x3 << 23) | OPC_MSA_BIT_0A, - OPC_BSETI_df = (0x4 << 23) | OPC_MSA_BIT_09, - OPC_BNEGI_df = (0x5 << 23) | OPC_MSA_BIT_09, - OPC_BINSLI_df = (0x6 << 23) | OPC_MSA_BIT_09, - OPC_BINSRI_df = (0x7 << 23) | OPC_MSA_BIT_09, -}; - - /* * * AN OVERVIEW OF MXU EXTENSION INSTRUCTION SET @@ -2424,7 +2190,6 @@ static TCGv cpu_lladdr, cpu_llval; static TCGv_i32 hflags; TCGv_i32 fpu_fcr0, fpu_fcr31; TCGv_i64 fpu_f64[32]; -static TCGv_i64 msa_wr_d[64]; #if defined(TARGET_MIPS64) /* Upper halves of R5900's 128-bit registers: MMRs (multimedia registers) */ @@ -2506,25 +2271,6 @@ static const char * const fregnames[] = { "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", }; -static const char * const msaregnames[] = { - "w0.d0", "w0.d1", "w1.d0", "w1.d1", - "w2.d0", "w2.d1", "w3.d0", "w3.d1", - "w4.d0", "w4.d1", "w5.d0", "w5.d1", - "w6.d0", "w6.d1", "w7.d0", "w7.d1", - "w8.d0", "w8.d1", "w9.d0", "w9.d1", - "w10.d0", "w10.d1", "w11.d0", "w11.d1", - "w12.d0", "w12.d1", "w13.d0", "w13.d1", - "w14.d0", "w14.d1", "w15.d0", "w15.d1", - "w16.d0", "w16.d1", "w17.d0", "w17.d1", - "w18.d0", "w18.d1", "w19.d0", "w19.d1", - "w20.d0", "w20.d1", "w21.d0", "w21.d1", - "w22.d0", "w22.d1", "w23.d0", "w23.d1", - "w24.d0", "w24.d1", "w25.d0", "w25.d1", - "w26.d0", "w26.d1", "w27.d0", "w27.d1", - "w28.d0", "w28.d1", "w29.d0", "w29.d1", - "w30.d0", "w30.d1", "w31.d0", "w31.d1", -}; - #if !defined(TARGET_MIPS64) static const char * const mxuregnames[] = { "XR1", "XR2", "XR3", "XR4", "XR5", "XR6", "XR7", "XR8", @@ -28557,2119 +28303,142 @@ static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx) } } -/* MIPS SIMD Architecture (MSA) */ -static inline int check_msa_access(DisasContext *ctx) -{ - if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) && - !(ctx->hflags & MIPS_HFLAG_F64))) { - gen_reserved_instruction(ctx); - return 0; - } - - if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) { - generate_exception_end(ctx, EXCP_MSADIS); - return 0; - } - return 1; -} - -static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt) -{ - /* generates tcg ops to check if any element is 0 */ - /* Note this function only works with MSA_WRLEN = 128 */ - uint64_t eval_zero_or_big = 0; - uint64_t eval_big = 0; - TCGv_i64 t0 = tcg_temp_new_i64(); - TCGv_i64 t1 = tcg_temp_new_i64(); - switch (df) { - case DF_BYTE: - eval_zero_or_big = 0x0101010101010101ULL; - eval_big = 0x8080808080808080ULL; - break; - case DF_HALF: - eval_zero_or_big = 0x0001000100010001ULL; - eval_big = 0x8000800080008000ULL; - break; - case DF_WORD: - eval_zero_or_big = 0x0000000100000001ULL; - eval_big = 0x8000000080000000ULL; - break; - case DF_DOUBLE: - eval_zero_or_big = 0x0000000000000001ULL; - eval_big = 0x8000000000000000ULL; - break; - } - tcg_gen_subi_i64(t0, msa_wr_d[wt << 1], eval_zero_or_big); - tcg_gen_andc_i64(t0, t0, msa_wr_d[wt << 1]); - tcg_gen_andi_i64(t0, t0, eval_big); - tcg_gen_subi_i64(t1, msa_wr_d[(wt << 1) + 1], eval_zero_or_big); - tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt << 1) + 1]); - tcg_gen_andi_i64(t1, t1, eval_big); - tcg_gen_or_i64(t0, t0, t1); - /* if all bits are zero then all elements are not zero */ - /* if some bit is non-zero then some element is zero */ - tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0); - tcg_gen_trunc_i64_tl(tresult, t0); - tcg_temp_free_i64(t0); - tcg_temp_free_i64(t1); -} - -static bool gen_msa_BxZ_V(DisasContext *ctx, int wt, int s16, TCGCond cond) -{ - TCGv_i64 t0; - - check_msa_access(ctx); - - if (ctx->hflags & MIPS_HFLAG_BMASK) { - gen_reserved_instruction(ctx); - return true; - } - t0 = tcg_temp_new_i64(); - tcg_gen_or_i64(t0, msa_wr_d[wt << 1], msa_wr_d[(wt << 1) + 1]); - tcg_gen_setcondi_i64(cond, t0, t0, 0); - tcg_gen_trunc_i64_tl(bcond, t0); - tcg_temp_free_i64(t0); - - ctx->btarget = ctx->base.pc_next + (s16 << 2) + 4; - - ctx->hflags |= MIPS_HFLAG_BC; - ctx->hflags |= MIPS_HFLAG_BDS32; - - return true; -} - -static bool gen_msa_BxZ(DisasContext *ctx, int df, int wt, int s16, bool if_not) -{ - check_msa_access(ctx); - - if (ctx->hflags & MIPS_HFLAG_BMASK) { - gen_reserved_instruction(ctx); - return true; - } - - gen_check_zero_element(bcond, df, wt); - if (if_not) { - tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0); - } - - ctx->btarget = ctx->base.pc_next + (s16 << 2) + 4; - ctx->hflags |= MIPS_HFLAG_BC; - ctx->hflags |= MIPS_HFLAG_BDS32; - - return true; -} - -void gen_msa_branch(DisasContext *ctx, uint32_t op1) -{ - uint8_t df = (ctx->opcode >> 21) & 0x3; - uint8_t wt = (ctx->opcode >> 16) & 0x1f; - int64_t s16 = (int16_t)ctx->opcode; - - switch (op1) { - case OPC_BZ_V: - case OPC_BNZ_V: - gen_msa_BxZ_V(ctx, wt, s16, (op1 == OPC_BZ_V) ? - TCG_COND_EQ : TCG_COND_NE); - break; - case OPC_BZ_B: - case OPC_BZ_H: - case OPC_BZ_W: - case OPC_BZ_D: - gen_msa_BxZ(ctx, df, wt, s16, false); - break; - case OPC_BNZ_B: - case OPC_BNZ_H: - case OPC_BNZ_W: - case OPC_BNZ_D: - gen_msa_BxZ(ctx, df, wt, s16, true); - break; - } -} - -static void gen_msa_i8(DisasContext *ctx) +static bool decode_opc_legacy(CPUMIPSState *env, DisasContext *ctx) { -#define MASK_MSA_I8(op) (MASK_MSA_MINOR(op) | (op & (0x03 << 24))) - uint8_t i8 = (ctx->opcode >> 16) & 0xff; - uint8_t ws = (ctx->opcode >> 11) & 0x1f; - uint8_t wd = (ctx->opcode >> 6) & 0x1f; - - TCGv_i32 twd = tcg_const_i32(wd); - TCGv_i32 tws = tcg_const_i32(ws); - TCGv_i32 ti8 = tcg_const_i32(i8); + int32_t offset; + int rs, rt, rd, sa; + uint32_t op, op1; + int16_t imm; - switch (MASK_MSA_I8(ctx->opcode)) { - case OPC_ANDI_B: - gen_helper_msa_andi_b(cpu_env, twd, tws, ti8); - break; - case OPC_ORI_B: - gen_helper_msa_ori_b(cpu_env, twd, tws, ti8); - break; - case OPC_NORI_B: - gen_helper_msa_nori_b(cpu_env, twd, tws, ti8); - break; - case OPC_XORI_B: - gen_helper_msa_xori_b(cpu_env, twd, tws, ti8); - break; - case OPC_BMNZI_B: - gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8); - break; - case OPC_BMZI_B: - gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8); - break; - case OPC_BSELI_B: - gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8); + op = MASK_OP_MAJOR(ctx->opcode); + rs = (ctx->opcode >> 21) & 0x1f; + rt = (ctx->opcode >> 16) & 0x1f; + rd = (ctx->opcode >> 11) & 0x1f; + sa = (ctx->opcode >> 6) & 0x1f; + imm = (int16_t)ctx->opcode; + switch (op) { + case OPC_SPECIAL: + decode_opc_special(env, ctx); break; - case OPC_SHF_B: - case OPC_SHF_H: - case OPC_SHF_W: - { - uint8_t df = (ctx->opcode >> 24) & 0x3; - if (df == DF_DOUBLE) { - gen_reserved_instruction(ctx); - } else { - TCGv_i32 tdf = tcg_const_i32(df); - gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8); - tcg_temp_free_i32(tdf); - } + case OPC_SPECIAL2: +#if defined(TARGET_MIPS64) + if ((ctx->insn_flags & INSN_R5900) && (ctx->insn_flags & ASE_MMI)) { + decode_mmi(env, ctx); +#else + if (ctx->insn_flags & ASE_MXU) { + decode_opc_mxu(env, ctx); +#endif + } else { + decode_opc_special2_legacy(env, ctx); } break; - default: - MIPS_INVAL("MSA instruction"); - gen_reserved_instruction(ctx); - break; - } - - tcg_temp_free_i32(twd); - tcg_temp_free_i32(tws); - tcg_temp_free_i32(ti8); -} - -static void gen_msa_i5(DisasContext *ctx) -{ -#define MASK_MSA_I5(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23))) - uint8_t df = (ctx->opcode >> 21) & 0x3; - int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5); - uint8_t u5 = (ctx->opcode >> 16) & 0x1f; - uint8_t ws = (ctx->opcode >> 11) & 0x1f; - uint8_t wd = (ctx->opcode >> 6) & 0x1f; - - TCGv_i32 tdf = tcg_const_i32(df); - TCGv_i32 twd = tcg_const_i32(wd); - TCGv_i32 tws = tcg_const_i32(ws); - TCGv_i32 timm = tcg_temp_new_i32(); - tcg_gen_movi_i32(timm, u5); - - switch (MASK_MSA_I5(ctx->opcode)) { - case OPC_ADDVI_df: - gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm); - break; - case OPC_SUBVI_df: - gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm); - break; - case OPC_MAXI_S_df: - tcg_gen_movi_i32(timm, s5); - gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm); - break; - case OPC_MAXI_U_df: - gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm); - break; - case OPC_MINI_S_df: - tcg_gen_movi_i32(timm, s5); - gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm); - break; - case OPC_MINI_U_df: - gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm); - break; - case OPC_CEQI_df: - tcg_gen_movi_i32(timm, s5); - gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm); - break; - case OPC_CLTI_S_df: - tcg_gen_movi_i32(timm, s5); - gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm); - break; - case OPC_CLTI_U_df: - gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm); - break; - case OPC_CLEI_S_df: - tcg_gen_movi_i32(timm, s5); - gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm); - break; - case OPC_CLEI_U_df: - gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm); - break; - case OPC_LDI_df: - { - int32_t s10 = sextract32(ctx->opcode, 11, 10); - tcg_gen_movi_i32(timm, s10); - gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm); + case OPC_SPECIAL3: +#if defined(TARGET_MIPS64) + if (ctx->insn_flags & INSN_R5900) { + decode_mmi_sq(env, ctx); /* MMI_OPC_SQ */ + } else { + decode_opc_special3(env, ctx); } +#else + decode_opc_special3(env, ctx); +#endif break; - default: - MIPS_INVAL("MSA instruction"); - gen_reserved_instruction(ctx); - break; - } - - tcg_temp_free_i32(tdf); - tcg_temp_free_i32(twd); - tcg_temp_free_i32(tws); - tcg_temp_free_i32(timm); -} - -static void gen_msa_bit(DisasContext *ctx) -{ -#define MASK_MSA_BIT(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23))) - uint8_t dfm = (ctx->opcode >> 16) & 0x7f; - uint32_t df = 0, m = 0; - uint8_t ws = (ctx->opcode >> 11) & 0x1f; - uint8_t wd = (ctx->opcode >> 6) & 0x1f; - - TCGv_i32 tdf; - TCGv_i32 tm; - TCGv_i32 twd; - TCGv_i32 tws; - - if ((dfm & 0x40) == 0x00) { - m = dfm & 0x3f; - df = DF_DOUBLE; - } else if ((dfm & 0x60) == 0x40) { - m = dfm & 0x1f; - df = DF_WORD; - } else if ((dfm & 0x70) == 0x60) { - m = dfm & 0x0f; - df = DF_HALF; - } else if ((dfm & 0x78) == 0x70) { - m = dfm & 0x7; - df = DF_BYTE; - } else { - gen_reserved_instruction(ctx); - return; - } - - tdf = tcg_const_i32(df); - tm = tcg_const_i32(m); - twd = tcg_const_i32(wd); - tws = tcg_const_i32(ws); - - switch (MASK_MSA_BIT(ctx->opcode)) { - case OPC_SLLI_df: - gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm); - break; - case OPC_SRAI_df: - gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm); - break; - case OPC_SRLI_df: - gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm); - break; - case OPC_BCLRI_df: - gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm); - break; - case OPC_BSETI_df: - gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm); - break; - case OPC_BNEGI_df: - gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm); - break; - case OPC_BINSLI_df: - gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm); - break; - case OPC_BINSRI_df: - gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm); - break; - case OPC_SAT_S_df: - gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm); - break; - case OPC_SAT_U_df: - gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm); - break; - case OPC_SRARI_df: - gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm); - break; - case OPC_SRLRI_df: - gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm); - break; - default: - MIPS_INVAL("MSA instruction"); - gen_reserved_instruction(ctx); - break; - } - - tcg_temp_free_i32(tdf); - tcg_temp_free_i32(tm); - tcg_temp_free_i32(twd); - tcg_temp_free_i32(tws); -} - -static void gen_msa_3r(DisasContext *ctx) -{ -#define MASK_MSA_3R(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23))) - uint8_t df = (ctx->opcode >> 21) & 0x3; - uint8_t wt = (ctx->opcode >> 16) & 0x1f; - uint8_t ws = (ctx->opcode >> 11) & 0x1f; - uint8_t wd = (ctx->opcode >> 6) & 0x1f; - - TCGv_i32 tdf = tcg_const_i32(df); - TCGv_i32 twd = tcg_const_i32(wd); - TCGv_i32 tws = tcg_const_i32(ws); - TCGv_i32 twt = tcg_const_i32(wt); - - switch (MASK_MSA_3R(ctx->opcode)) { - case OPC_BINSL_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_binsl_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_binsl_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_binsl_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_binsl_d(cpu_env, twd, tws, twt); + case OPC_REGIMM: + op1 = MASK_REGIMM(ctx->opcode); + switch (op1) { + case OPC_BLTZL: /* REGIMM branches */ + case OPC_BGEZL: + case OPC_BLTZALL: + case OPC_BGEZALL: + check_insn(ctx, ISA_MIPS2); + check_insn_opc_removed(ctx, ISA_MIPS_R6); + /* Fallthrough */ + case OPC_BLTZ: + case OPC_BGEZ: + gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4); break; - } - break; - case OPC_BINSR_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_binsr_b(cpu_env, twd, tws, twt); + case OPC_BLTZAL: + case OPC_BGEZAL: + if (ctx->insn_flags & ISA_MIPS_R6) { + if (rs == 0) { + /* OPC_NAL, OPC_BAL */ + gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4); + } else { + gen_reserved_instruction(ctx); + } + } else { + gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4); + } break; - case DF_HALF: - gen_helper_msa_binsr_h(cpu_env, twd, tws, twt); + case OPC_TGEI: /* REGIMM traps */ + case OPC_TGEIU: + case OPC_TLTI: + case OPC_TLTIU: + case OPC_TEQI: + + case OPC_TNEI: + check_insn(ctx, ISA_MIPS2); + check_insn_opc_removed(ctx, ISA_MIPS_R6); + gen_trap(ctx, op1, rs, -1, imm); break; - case DF_WORD: - gen_helper_msa_binsr_w(cpu_env, twd, tws, twt); + case OPC_SIGRIE: + check_insn(ctx, ISA_MIPS_R6); + gen_reserved_instruction(ctx); break; - case DF_DOUBLE: - gen_helper_msa_binsr_d(cpu_env, twd, tws, twt); + case OPC_SYNCI: + check_insn(ctx, ISA_MIPS_R2); + /* + * Break the TB to be able to sync copied instructions + * immediately. + */ + ctx->base.is_jmp = DISAS_STOP; break; - } - break; - case OPC_BCLR_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_bclr_b(cpu_env, twd, tws, twt); + case OPC_BPOSGE32: /* MIPS DSP branch */ +#if defined(TARGET_MIPS64) + case OPC_BPOSGE64: +#endif + check_dsp(ctx); + gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4); break; - case DF_HALF: - gen_helper_msa_bclr_h(cpu_env, twd, tws, twt); +#if defined(TARGET_MIPS64) + case OPC_DAHI: + check_insn(ctx, ISA_MIPS_R6); + check_mips_64(ctx); + if (rs != 0) { + tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32); + } break; - case DF_WORD: - gen_helper_msa_bclr_w(cpu_env, twd, tws, twt); + case OPC_DATI: + check_insn(ctx, ISA_MIPS_R6); + check_mips_64(ctx); + if (rs != 0) { + tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48); + } break; - case DF_DOUBLE: - gen_helper_msa_bclr_d(cpu_env, twd, tws, twt); +#endif + default: /* Invalid */ + MIPS_INVAL("regimm"); + gen_reserved_instruction(ctx); break; } break; - case OPC_BNEG_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_bneg_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_bneg_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_bneg_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_bneg_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_BSET_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_bset_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_bset_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_bset_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_bset_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_ADD_A_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_add_a_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_add_a_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_add_a_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_add_a_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_ADDS_A_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_adds_a_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_adds_a_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_adds_a_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_adds_a_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_ADDS_S_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_adds_s_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_adds_s_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_adds_s_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_adds_s_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_ADDS_U_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_adds_u_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_adds_u_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_adds_u_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_adds_u_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_ADDV_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_addv_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_addv_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_addv_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_addv_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_AVE_S_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_ave_s_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_ave_s_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_ave_s_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_ave_s_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_AVE_U_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_ave_u_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_ave_u_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_ave_u_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_ave_u_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_AVER_S_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_aver_s_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_aver_s_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_aver_s_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_aver_s_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_AVER_U_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_aver_u_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_aver_u_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_aver_u_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_aver_u_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_CEQ_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_ceq_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_ceq_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_ceq_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_ceq_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_CLE_S_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_cle_s_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_cle_s_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_cle_s_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_cle_s_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_CLE_U_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_cle_u_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_cle_u_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_cle_u_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_cle_u_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_CLT_S_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_clt_s_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_clt_s_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_clt_s_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_clt_s_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_CLT_U_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_clt_u_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_clt_u_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_clt_u_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_clt_u_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_DIV_S_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_div_s_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_div_s_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_div_s_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_div_s_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_DIV_U_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_div_u_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_div_u_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_div_u_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_div_u_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_MAX_A_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_max_a_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_max_a_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_max_a_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_max_a_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_MAX_S_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_max_s_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_max_s_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_max_s_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_max_s_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_MAX_U_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_max_u_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_max_u_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_max_u_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_max_u_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_MIN_A_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_min_a_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_min_a_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_min_a_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_min_a_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_MIN_S_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_min_s_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_min_s_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_min_s_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_min_s_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_MIN_U_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_min_u_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_min_u_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_min_u_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_min_u_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_MOD_S_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_mod_s_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_mod_s_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_mod_s_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_mod_s_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_MOD_U_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_mod_u_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_mod_u_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_mod_u_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_mod_u_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_MADDV_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_maddv_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_maddv_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_maddv_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_maddv_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_MSUBV_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_msubv_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_msubv_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_msubv_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_msubv_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_ASUB_S_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_asub_s_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_asub_s_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_asub_s_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_asub_s_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_ASUB_U_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_asub_u_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_asub_u_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_asub_u_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_asub_u_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_ILVEV_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_ilvev_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_ilvev_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_ilvev_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_ilvev_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_ILVOD_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_ilvod_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_ilvod_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_ilvod_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_ilvod_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_ILVL_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_ilvl_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_ilvl_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_ilvl_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_ilvl_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_ILVR_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_ilvr_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_ilvr_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_ilvr_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_ilvr_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_PCKEV_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_pckev_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_pckev_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_pckev_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_pckev_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_PCKOD_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_pckod_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_pckod_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_pckod_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_pckod_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_SLL_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_sll_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_sll_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_sll_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_sll_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_SRA_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_sra_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_sra_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_sra_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_sra_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_SRAR_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_srar_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_srar_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_srar_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_srar_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_SRL_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_srl_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_srl_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_srl_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_srl_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_SRLR_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_srlr_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_srlr_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_srlr_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_srlr_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_SUBS_S_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_subs_s_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_subs_s_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_subs_s_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_subs_s_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_MULV_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_mulv_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_mulv_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_mulv_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_mulv_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_SLD_df: - gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_VSHF_df: - gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_SUBV_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_subv_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_subv_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_subv_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_subv_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_SUBS_U_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_subs_u_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_subs_u_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_subs_u_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_subs_u_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_SPLAT_df: - gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_SUBSUS_U_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_subsus_u_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_subsus_u_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_subsus_u_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_subsus_u_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_SUBSUU_S_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_subsuu_s_b(cpu_env, twd, tws, twt); - break; - case DF_HALF: - gen_helper_msa_subsuu_s_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_subsuu_s_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_subsuu_s_d(cpu_env, twd, tws, twt); - break; - } - break; - - case OPC_DOTP_S_df: - case OPC_DOTP_U_df: - case OPC_DPADD_S_df: - case OPC_DPADD_U_df: - case OPC_DPSUB_S_df: - case OPC_HADD_S_df: - case OPC_DPSUB_U_df: - case OPC_HADD_U_df: - case OPC_HSUB_S_df: - case OPC_HSUB_U_df: - if (df == DF_BYTE) { - gen_reserved_instruction(ctx); - break; - } - switch (MASK_MSA_3R(ctx->opcode)) { - case OPC_HADD_S_df: - switch (df) { - case DF_HALF: - gen_helper_msa_hadd_s_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_hadd_s_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_hadd_s_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_HADD_U_df: - switch (df) { - case DF_HALF: - gen_helper_msa_hadd_u_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_hadd_u_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_hadd_u_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_HSUB_S_df: - switch (df) { - case DF_HALF: - gen_helper_msa_hsub_s_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_hsub_s_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_hsub_s_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_HSUB_U_df: - switch (df) { - case DF_HALF: - gen_helper_msa_hsub_u_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_hsub_u_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_hsub_u_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_DOTP_S_df: - switch (df) { - case DF_HALF: - gen_helper_msa_dotp_s_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_dotp_s_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_dotp_s_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_DOTP_U_df: - switch (df) { - case DF_HALF: - gen_helper_msa_dotp_u_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_dotp_u_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_dotp_u_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_DPADD_S_df: - switch (df) { - case DF_HALF: - gen_helper_msa_dpadd_s_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_dpadd_s_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_dpadd_s_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_DPADD_U_df: - switch (df) { - case DF_HALF: - gen_helper_msa_dpadd_u_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_dpadd_u_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_dpadd_u_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_DPSUB_S_df: - switch (df) { - case DF_HALF: - gen_helper_msa_dpsub_s_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_dpsub_s_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_dpsub_s_d(cpu_env, twd, tws, twt); - break; - } - break; - case OPC_DPSUB_U_df: - switch (df) { - case DF_HALF: - gen_helper_msa_dpsub_u_h(cpu_env, twd, tws, twt); - break; - case DF_WORD: - gen_helper_msa_dpsub_u_w(cpu_env, twd, tws, twt); - break; - case DF_DOUBLE: - gen_helper_msa_dpsub_u_d(cpu_env, twd, tws, twt); - break; - } - break; - } - break; - default: - MIPS_INVAL("MSA instruction"); - gen_reserved_instruction(ctx); - break; - } - tcg_temp_free_i32(twd); - tcg_temp_free_i32(tws); - tcg_temp_free_i32(twt); - tcg_temp_free_i32(tdf); -} - -static void gen_msa_elm_3e(DisasContext *ctx) -{ -#define MASK_MSA_ELM_DF3E(op) (MASK_MSA_MINOR(op) | (op & (0x3FF << 16))) - uint8_t source = (ctx->opcode >> 11) & 0x1f; - uint8_t dest = (ctx->opcode >> 6) & 0x1f; - TCGv telm = tcg_temp_new(); - TCGv_i32 tsr = tcg_const_i32(source); - TCGv_i32 tdt = tcg_const_i32(dest); - - switch (MASK_MSA_ELM_DF3E(ctx->opcode)) { - case OPC_CTCMSA: - gen_load_gpr(telm, source); - gen_helper_msa_ctcmsa(cpu_env, telm, tdt); - break; - case OPC_CFCMSA: - gen_helper_msa_cfcmsa(telm, cpu_env, tsr); - gen_store_gpr(telm, dest); - break; - case OPC_MOVE_V: - gen_helper_msa_move_v(cpu_env, tdt, tsr); - break; - default: - MIPS_INVAL("MSA instruction"); - gen_reserved_instruction(ctx); - break; - } - - tcg_temp_free(telm); - tcg_temp_free_i32(tdt); - tcg_temp_free_i32(tsr); -} - -static void gen_msa_elm_df(DisasContext *ctx, uint32_t df, uint32_t n) -{ -#define MASK_MSA_ELM(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22))) - uint8_t ws = (ctx->opcode >> 11) & 0x1f; - uint8_t wd = (ctx->opcode >> 6) & 0x1f; - - TCGv_i32 tws = tcg_const_i32(ws); - TCGv_i32 twd = tcg_const_i32(wd); - TCGv_i32 tn = tcg_const_i32(n); - TCGv_i32 tdf = tcg_const_i32(df); - - switch (MASK_MSA_ELM(ctx->opcode)) { - case OPC_SLDI_df: - gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn); - break; - case OPC_SPLATI_df: - gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn); - break; - case OPC_INSVE_df: - gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn); - break; - case OPC_COPY_S_df: - case OPC_COPY_U_df: - case OPC_INSERT_df: -#if !defined(TARGET_MIPS64) - /* Double format valid only for MIPS64 */ - if (df == DF_DOUBLE) { - gen_reserved_instruction(ctx); - break; - } - if ((MASK_MSA_ELM(ctx->opcode) == OPC_COPY_U_df) && - (df == DF_WORD)) { - gen_reserved_instruction(ctx); - break; - } -#endif - switch (MASK_MSA_ELM(ctx->opcode)) { - case OPC_COPY_S_df: - if (likely(wd != 0)) { - switch (df) { - case DF_BYTE: - gen_helper_msa_copy_s_b(cpu_env, twd, tws, tn); - break; - case DF_HALF: - gen_helper_msa_copy_s_h(cpu_env, twd, tws, tn); - break; - case DF_WORD: - gen_helper_msa_copy_s_w(cpu_env, twd, tws, tn); - break; -#if defined(TARGET_MIPS64) - case DF_DOUBLE: - gen_helper_msa_copy_s_d(cpu_env, twd, tws, tn); - break; -#endif - default: - assert(0); - } - } - break; - case OPC_COPY_U_df: - if (likely(wd != 0)) { - switch (df) { - case DF_BYTE: - gen_helper_msa_copy_u_b(cpu_env, twd, tws, tn); - break; - case DF_HALF: - gen_helper_msa_copy_u_h(cpu_env, twd, tws, tn); - break; -#if defined(TARGET_MIPS64) - case DF_WORD: - gen_helper_msa_copy_u_w(cpu_env, twd, tws, tn); - break; -#endif - default: - assert(0); - } - } - break; - case OPC_INSERT_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_insert_b(cpu_env, twd, tws, tn); - break; - case DF_HALF: - gen_helper_msa_insert_h(cpu_env, twd, tws, tn); - break; - case DF_WORD: - gen_helper_msa_insert_w(cpu_env, twd, tws, tn); - break; -#if defined(TARGET_MIPS64) - case DF_DOUBLE: - gen_helper_msa_insert_d(cpu_env, twd, tws, tn); - break; -#endif - default: - assert(0); - } - break; - } - break; - default: - MIPS_INVAL("MSA instruction"); - gen_reserved_instruction(ctx); - } - tcg_temp_free_i32(twd); - tcg_temp_free_i32(tws); - tcg_temp_free_i32(tn); - tcg_temp_free_i32(tdf); -} - -static void gen_msa_elm(DisasContext *ctx) -{ - uint8_t dfn = (ctx->opcode >> 16) & 0x3f; - uint32_t df = 0, n = 0; - - if ((dfn & 0x30) == 0x00) { - n = dfn & 0x0f; - df = DF_BYTE; - } else if ((dfn & 0x38) == 0x20) { - n = dfn & 0x07; - df = DF_HALF; - } else if ((dfn & 0x3c) == 0x30) { - n = dfn & 0x03; - df = DF_WORD; - } else if ((dfn & 0x3e) == 0x38) { - n = dfn & 0x01; - df = DF_DOUBLE; - } else if (dfn == 0x3E) { - /* CTCMSA, CFCMSA, MOVE.V */ - gen_msa_elm_3e(ctx); - return; - } else { - gen_reserved_instruction(ctx); - return; - } - - gen_msa_elm_df(ctx, df, n); -} - -static void gen_msa_3rf(DisasContext *ctx) -{ -#define MASK_MSA_3RF(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22))) - uint8_t df = (ctx->opcode >> 21) & 0x1; - uint8_t wt = (ctx->opcode >> 16) & 0x1f; - uint8_t ws = (ctx->opcode >> 11) & 0x1f; - uint8_t wd = (ctx->opcode >> 6) & 0x1f; - - TCGv_i32 twd = tcg_const_i32(wd); - TCGv_i32 tws = tcg_const_i32(ws); - TCGv_i32 twt = tcg_const_i32(wt); - TCGv_i32 tdf = tcg_temp_new_i32(); - - /* adjust df value for floating-point instruction */ - tcg_gen_movi_i32(tdf, df + 2); - - switch (MASK_MSA_3RF(ctx->opcode)) { - case OPC_FCAF_df: - gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FADD_df: - gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FCUN_df: - gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FSUB_df: - gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FCOR_df: - gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FCEQ_df: - gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FMUL_df: - gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FCUNE_df: - gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FCUEQ_df: - gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FDIV_df: - gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FCNE_df: - gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FCLT_df: - gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FMADD_df: - gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_MUL_Q_df: - tcg_gen_movi_i32(tdf, df + 1); - gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FCULT_df: - gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FMSUB_df: - gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_MADD_Q_df: - tcg_gen_movi_i32(tdf, df + 1); - gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FCLE_df: - gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_MSUB_Q_df: - tcg_gen_movi_i32(tdf, df + 1); - gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FCULE_df: - gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FEXP2_df: - gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FSAF_df: - gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FEXDO_df: - gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FSUN_df: - gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FSOR_df: - gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FSEQ_df: - gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FTQ_df: - gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FSUNE_df: - gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FSUEQ_df: - gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FSNE_df: - gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FSLT_df: - gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FMIN_df: - gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_MULR_Q_df: - tcg_gen_movi_i32(tdf, df + 1); - gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FSULT_df: - gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FMIN_A_df: - gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_MADDR_Q_df: - tcg_gen_movi_i32(tdf, df + 1); - gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FSLE_df: - gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FMAX_df: - gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_MSUBR_Q_df: - tcg_gen_movi_i32(tdf, df + 1); - gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FSULE_df: - gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt); - break; - case OPC_FMAX_A_df: - gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt); - break; - default: - MIPS_INVAL("MSA instruction"); - gen_reserved_instruction(ctx); - break; - } - - tcg_temp_free_i32(twd); - tcg_temp_free_i32(tws); - tcg_temp_free_i32(twt); - tcg_temp_free_i32(tdf); -} - -static void gen_msa_2r(DisasContext *ctx) -{ -#define MASK_MSA_2R(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \ - (op & (0x7 << 18))) - uint8_t wt = (ctx->opcode >> 16) & 0x1f; - uint8_t ws = (ctx->opcode >> 11) & 0x1f; - uint8_t wd = (ctx->opcode >> 6) & 0x1f; - uint8_t df = (ctx->opcode >> 16) & 0x3; - TCGv_i32 twd = tcg_const_i32(wd); - TCGv_i32 tws = tcg_const_i32(ws); - TCGv_i32 twt = tcg_const_i32(wt); - TCGv_i32 tdf = tcg_const_i32(df); - - switch (MASK_MSA_2R(ctx->opcode)) { - case OPC_FILL_df: -#if !defined(TARGET_MIPS64) - /* Double format valid only for MIPS64 */ - if (df == DF_DOUBLE) { - gen_reserved_instruction(ctx); - break; - } -#endif - gen_helper_msa_fill_df(cpu_env, tdf, twd, tws); /* trs */ - break; - case OPC_NLOC_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_nloc_b(cpu_env, twd, tws); - break; - case DF_HALF: - gen_helper_msa_nloc_h(cpu_env, twd, tws); - break; - case DF_WORD: - gen_helper_msa_nloc_w(cpu_env, twd, tws); - break; - case DF_DOUBLE: - gen_helper_msa_nloc_d(cpu_env, twd, tws); - break; - } - break; - case OPC_NLZC_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_nlzc_b(cpu_env, twd, tws); - break; - case DF_HALF: - gen_helper_msa_nlzc_h(cpu_env, twd, tws); - break; - case DF_WORD: - gen_helper_msa_nlzc_w(cpu_env, twd, tws); - break; - case DF_DOUBLE: - gen_helper_msa_nlzc_d(cpu_env, twd, tws); - break; - } - break; - case OPC_PCNT_df: - switch (df) { - case DF_BYTE: - gen_helper_msa_pcnt_b(cpu_env, twd, tws); - break; - case DF_HALF: - gen_helper_msa_pcnt_h(cpu_env, twd, tws); - break; - case DF_WORD: - gen_helper_msa_pcnt_w(cpu_env, twd, tws); - break; - case DF_DOUBLE: - gen_helper_msa_pcnt_d(cpu_env, twd, tws); - break; - } - break; - default: - MIPS_INVAL("MSA instruction"); - gen_reserved_instruction(ctx); - break; - } - - tcg_temp_free_i32(twd); - tcg_temp_free_i32(tws); - tcg_temp_free_i32(twt); - tcg_temp_free_i32(tdf); -} - -static void gen_msa_2rf(DisasContext *ctx) -{ -#define MASK_MSA_2RF(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \ - (op & (0xf << 17))) - uint8_t wt = (ctx->opcode >> 16) & 0x1f; - uint8_t ws = (ctx->opcode >> 11) & 0x1f; - uint8_t wd = (ctx->opcode >> 6) & 0x1f; - uint8_t df = (ctx->opcode >> 16) & 0x1; - TCGv_i32 twd = tcg_const_i32(wd); - TCGv_i32 tws = tcg_const_i32(ws); - TCGv_i32 twt = tcg_const_i32(wt); - /* adjust df value for floating-point instruction */ - TCGv_i32 tdf = tcg_const_i32(df + 2); - - switch (MASK_MSA_2RF(ctx->opcode)) { - case OPC_FCLASS_df: - gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws); - break; - case OPC_FTRUNC_S_df: - gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws); - break; - case OPC_FTRUNC_U_df: - gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws); - break; - case OPC_FSQRT_df: - gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws); - break; - case OPC_FRSQRT_df: - gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws); - break; - case OPC_FRCP_df: - gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws); - break; - case OPC_FRINT_df: - gen_helper_msa_frint_df(cpu_env, tdf, twd, tws); - break; - case OPC_FLOG2_df: - gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws); - break; - case OPC_FEXUPL_df: - gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws); - break; - case OPC_FEXUPR_df: - gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws); - break; - case OPC_FFQL_df: - gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws); - break; - case OPC_FFQR_df: - gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws); - break; - case OPC_FTINT_S_df: - gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws); - break; - case OPC_FTINT_U_df: - gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws); - break; - case OPC_FFINT_S_df: - gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws); - break; - case OPC_FFINT_U_df: - gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws); - break; - } - - tcg_temp_free_i32(twd); - tcg_temp_free_i32(tws); - tcg_temp_free_i32(twt); - tcg_temp_free_i32(tdf); -} - -static void gen_msa_vec_v(DisasContext *ctx) -{ -#define MASK_MSA_VEC(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21))) - uint8_t wt = (ctx->opcode >> 16) & 0x1f; - uint8_t ws = (ctx->opcode >> 11) & 0x1f; - uint8_t wd = (ctx->opcode >> 6) & 0x1f; - TCGv_i32 twd = tcg_const_i32(wd); - TCGv_i32 tws = tcg_const_i32(ws); - TCGv_i32 twt = tcg_const_i32(wt); - - switch (MASK_MSA_VEC(ctx->opcode)) { - case OPC_AND_V: - gen_helper_msa_and_v(cpu_env, twd, tws, twt); - break; - case OPC_OR_V: - gen_helper_msa_or_v(cpu_env, twd, tws, twt); - break; - case OPC_NOR_V: - gen_helper_msa_nor_v(cpu_env, twd, tws, twt); - break; - case OPC_XOR_V: - gen_helper_msa_xor_v(cpu_env, twd, tws, twt); - break; - case OPC_BMNZ_V: - gen_helper_msa_bmnz_v(cpu_env, twd, tws, twt); - break; - case OPC_BMZ_V: - gen_helper_msa_bmz_v(cpu_env, twd, tws, twt); - break; - case OPC_BSEL_V: - gen_helper_msa_bsel_v(cpu_env, twd, tws, twt); - break; - default: - MIPS_INVAL("MSA instruction"); - gen_reserved_instruction(ctx); - break; - } - - tcg_temp_free_i32(twd); - tcg_temp_free_i32(tws); - tcg_temp_free_i32(twt); -} - -static void gen_msa_vec(DisasContext *ctx) -{ - switch (MASK_MSA_VEC(ctx->opcode)) { - case OPC_AND_V: - case OPC_OR_V: - case OPC_NOR_V: - case OPC_XOR_V: - case OPC_BMNZ_V: - case OPC_BMZ_V: - case OPC_BSEL_V: - gen_msa_vec_v(ctx); - break; - case OPC_MSA_2R: - gen_msa_2r(ctx); - break; - case OPC_MSA_2RF: - gen_msa_2rf(ctx); - break; - default: - MIPS_INVAL("MSA instruction"); - gen_reserved_instruction(ctx); - break; - } -} - -void gen_msa(DisasContext *ctx) -{ - uint32_t opcode = ctx->opcode; - - check_msa_access(ctx); - - switch (MASK_MSA_MINOR(opcode)) { - case OPC_MSA_I8_00: - case OPC_MSA_I8_01: - case OPC_MSA_I8_02: - gen_msa_i8(ctx); - break; - case OPC_MSA_I5_06: - case OPC_MSA_I5_07: - gen_msa_i5(ctx); - break; - case OPC_MSA_BIT_09: - case OPC_MSA_BIT_0A: - gen_msa_bit(ctx); - break; - case OPC_MSA_3R_0D: - case OPC_MSA_3R_0E: - case OPC_MSA_3R_0F: - case OPC_MSA_3R_10: - case OPC_MSA_3R_11: - case OPC_MSA_3R_12: - case OPC_MSA_3R_13: - case OPC_MSA_3R_14: - case OPC_MSA_3R_15: - gen_msa_3r(ctx); - break; - case OPC_MSA_ELM: - gen_msa_elm(ctx); - break; - case OPC_MSA_3RF_1A: - case OPC_MSA_3RF_1B: - case OPC_MSA_3RF_1C: - gen_msa_3rf(ctx); - break; - case OPC_MSA_VEC: - gen_msa_vec(ctx); - break; - case OPC_LD_B: - case OPC_LD_H: - case OPC_LD_W: - case OPC_LD_D: - case OPC_ST_B: - case OPC_ST_H: - case OPC_ST_W: - case OPC_ST_D: - { - int32_t s10 = sextract32(ctx->opcode, 16, 10); - uint8_t rs = (ctx->opcode >> 11) & 0x1f; - uint8_t wd = (ctx->opcode >> 6) & 0x1f; - uint8_t df = (ctx->opcode >> 0) & 0x3; - - TCGv_i32 twd = tcg_const_i32(wd); - TCGv taddr = tcg_temp_new(); - gen_base_offset_addr(ctx, taddr, rs, s10 << df); - - switch (MASK_MSA_MINOR(opcode)) { - case OPC_LD_B: - gen_helper_msa_ld_b(cpu_env, twd, taddr); - break; - case OPC_LD_H: - gen_helper_msa_ld_h(cpu_env, twd, taddr); - break; - case OPC_LD_W: - gen_helper_msa_ld_w(cpu_env, twd, taddr); - break; - case OPC_LD_D: - gen_helper_msa_ld_d(cpu_env, twd, taddr); - break; - case OPC_ST_B: - gen_helper_msa_st_b(cpu_env, twd, taddr); - break; - case OPC_ST_H: - gen_helper_msa_st_h(cpu_env, twd, taddr); - break; - case OPC_ST_W: - gen_helper_msa_st_w(cpu_env, twd, taddr); - break; - case OPC_ST_D: - gen_helper_msa_st_d(cpu_env, twd, taddr); - break; - } - - tcg_temp_free_i32(twd); - tcg_temp_free(taddr); - } - break; - default: - MIPS_INVAL("MSA instruction"); - gen_reserved_instruction(ctx); - break; - } - -} - -static bool decode_opc_legacy(CPUMIPSState *env, DisasContext *ctx) -{ - int32_t offset; - int rs, rt, rd, sa; - uint32_t op, op1; - int16_t imm; - - op = MASK_OP_MAJOR(ctx->opcode); - rs = (ctx->opcode >> 21) & 0x1f; - rt = (ctx->opcode >> 16) & 0x1f; - rd = (ctx->opcode >> 11) & 0x1f; - sa = (ctx->opcode >> 6) & 0x1f; - imm = (int16_t)ctx->opcode; - switch (op) { - case OPC_SPECIAL: - decode_opc_special(env, ctx); - break; - case OPC_SPECIAL2: -#if defined(TARGET_MIPS64) - if ((ctx->insn_flags & INSN_R5900) && (ctx->insn_flags & ASE_MMI)) { - decode_mmi(env, ctx); -#else - if (ctx->insn_flags & ASE_MXU) { - decode_opc_mxu(env, ctx); -#endif - } else { - decode_opc_special2_legacy(env, ctx); - } - break; - case OPC_SPECIAL3: -#if defined(TARGET_MIPS64) - if (ctx->insn_flags & INSN_R5900) { - decode_mmi_sq(env, ctx); /* MMI_OPC_SQ */ - } else { - decode_opc_special3(env, ctx); - } -#else - decode_opc_special3(env, ctx); -#endif - break; - case OPC_REGIMM: - op1 = MASK_REGIMM(ctx->opcode); - switch (op1) { - case OPC_BLTZL: /* REGIMM branches */ - case OPC_BGEZL: - case OPC_BLTZALL: - case OPC_BGEZALL: - check_insn(ctx, ISA_MIPS2); - check_insn_opc_removed(ctx, ISA_MIPS_R6); - /* Fallthrough */ - case OPC_BLTZ: - case OPC_BGEZ: - gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4); - break; - case OPC_BLTZAL: - case OPC_BGEZAL: - if (ctx->insn_flags & ISA_MIPS_R6) { - if (rs == 0) { - /* OPC_NAL, OPC_BAL */ - gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4); - } else { - gen_reserved_instruction(ctx); - } - } else { - gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4); - } - break; - case OPC_TGEI: /* REGIMM traps */ - case OPC_TGEIU: - case OPC_TLTI: - case OPC_TLTIU: - case OPC_TEQI: - - case OPC_TNEI: - check_insn(ctx, ISA_MIPS2); - check_insn_opc_removed(ctx, ISA_MIPS_R6); - gen_trap(ctx, op1, rs, -1, imm); - break; - case OPC_SIGRIE: - check_insn(ctx, ISA_MIPS_R6); - gen_reserved_instruction(ctx); - break; - case OPC_SYNCI: - check_insn(ctx, ISA_MIPS_R2); - /* - * Break the TB to be able to sync copied instructions - * immediately. - */ - ctx->base.is_jmp = DISAS_STOP; - break; - case OPC_BPOSGE32: /* MIPS DSP branch */ -#if defined(TARGET_MIPS64) - case OPC_BPOSGE64: -#endif - check_dsp(ctx); - gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4); - break; -#if defined(TARGET_MIPS64) - case OPC_DAHI: - check_insn(ctx, ISA_MIPS_R6); - check_mips_64(ctx); - if (rs != 0) { - tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32); - } - break; - case OPC_DATI: - check_insn(ctx, ISA_MIPS_R6); - check_mips_64(ctx); - if (rs != 0) { - tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48); - } - break; -#endif - default: /* Invalid */ - MIPS_INVAL("regimm"); - gen_reserved_instruction(ctx); - break; - } - break; - case OPC_CP0: - check_cp0_enabled(ctx); - op1 = MASK_CP0(ctx->opcode); - switch (op1) { - case OPC_MFC0: - case OPC_MTC0: - case OPC_MFTR: - case OPC_MTTR: - case OPC_MFHC0: - case OPC_MTHC0: -#if defined(TARGET_MIPS64) - case OPC_DMFC0: - case OPC_DMTC0: -#endif -#ifndef CONFIG_USER_ONLY - gen_cp0(env, ctx, op1, rt, rd); -#endif /* !CONFIG_USER_ONLY */ + case OPC_CP0: + check_cp0_enabled(ctx); + op1 = MASK_CP0(ctx->opcode); + switch (op1) { + case OPC_MFC0: + case OPC_MTC0: + case OPC_MFTR: + case OPC_MTTR: + case OPC_MFHC0: + case OPC_MTHC0: +#if defined(TARGET_MIPS64) + case OPC_DMFC0: + case OPC_DMTC0: +#endif +#ifndef CONFIG_USER_ONLY + gen_cp0(env, ctx, op1, rt, rd); +#endif /* !CONFIG_USER_ONLY */ break; case OPC_C0: case OPC_C0_1: @@ -31578,24 +29347,6 @@ void mips_cpu_dump_state(CPUState *cs, FILE *f, int flags) } } -void msa_translate_init(void) -{ - int i; - - for (i = 0; i < 32; i++) { - int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]); - - /* - * The MSA vector registers are mapped on the - * scalar floating-point unit (FPU) registers. - */ - msa_wr_d[i * 2] = fpu_f64[i]; - off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]); - msa_wr_d[i * 2 + 1] = - tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2 + 1]); - } -} - void mips_tcg_init(void) { int i; -- cgit v1.2.3-55-g7522 From 878b87b54176d7cea4a74ec544703e408776ed34 Mon Sep 17 00:00:00 2001 From: Philippe Mathieu-Daudé Date: Tue, 15 Dec 2020 22:40:50 +0100 Subject: target/mips: Pass TCGCond argument to MSA gen_check_zero_element() Simplify gen_check_zero_element() by passing the TCGCond argument along. Suggested-by: Richard Henderson Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20201215225757.764263-25-f4bug@amsat.org> --- target/mips/msa_translate.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/target/mips/msa_translate.c b/target/mips/msa_translate.c index a4f9a6c128..52bd428759 100644 --- a/target/mips/msa_translate.c +++ b/target/mips/msa_translate.c @@ -304,7 +304,8 @@ static inline int check_msa_access(DisasContext *ctx) return 1; } -static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt) +static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt, + TCGCond cond) { /* generates tcg ops to check if any element is 0 */ /* Note this function only works with MSA_WRLEN = 128 */ @@ -339,7 +340,7 @@ static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt) tcg_gen_or_i64(t0, t0, t1); /* if all bits are zero then all elements are not zero */ /* if some bit is non-zero then some element is zero */ - tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0); + tcg_gen_setcondi_i64(cond, t0, t0, 0); tcg_gen_trunc_i64_tl(tresult, t0); tcg_temp_free_i64(t0); tcg_temp_free_i64(t1); @@ -378,10 +379,7 @@ static bool gen_msa_BxZ(DisasContext *ctx, int df, int wt, int s16, bool if_not) return true; } - gen_check_zero_element(bcond, df, wt); - if (if_not) { - tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0); - } + gen_check_zero_element(bcond, df, wt, if_not ? TCG_COND_EQ : TCG_COND_NE); ctx->btarget = ctx->base.pc_next + (s16 << 2) + 4; ctx->hflags |= MIPS_HFLAG_BC; -- cgit v1.2.3-55-g7522 From c7a9ef75173f090616328d6870f71e8da2b6bd50 Mon Sep 17 00:00:00 2001 From: Philippe Mathieu-Daudé Date: Sun, 29 Nov 2020 22:24:40 +0100 Subject: target/mips: Introduce decode tree bindings for MSA ASE Introduce the 'msa32' decodetree config for the 32-bit MSA ASE. We start by decoding: - the branch instructions, - all instructions based on the MSA opcode. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20201215225757.764263-20-f4bug@amsat.org> Reviewed-by: Jiaxun Yang Tested-by: Jiaxun Yang --- target/mips/meson.build | 5 +++++ target/mips/msa32.decode | 24 ++++++++++++++++++++++++ target/mips/msa_translate.c | 36 ++++++++++++++++++++++++++++++++++++ target/mips/translate.h | 3 +++ 4 files changed, 68 insertions(+) create mode 100644 target/mips/msa32.decode diff --git a/target/mips/meson.build b/target/mips/meson.build index 2aa4d81300..a3c3724188 100644 --- a/target/mips/meson.build +++ b/target/mips/meson.build @@ -1,4 +1,9 @@ +gen = [ + decodetree.process('msa32.decode', extra_args: '--static-decode=decode_msa32'), +] + mips_ss = ss.source_set() +mips_ss.add(gen) mips_ss.add(files( 'cpu.c', 'gdbstub.c', diff --git a/target/mips/msa32.decode b/target/mips/msa32.decode new file mode 100644 index 0000000000..d69675132b --- /dev/null +++ b/target/mips/msa32.decode @@ -0,0 +1,24 @@ +# MIPS SIMD Architecture Module instruction set +# +# Copyright (C) 2020 Philippe Mathieu-Daudé +# +# SPDX-License-Identifier: LGPL-2.1-or-later +# +# Reference: +# MIPS Architecture for Programmers Volume IV-j +# The MIPS32 SIMD Architecture Module, Revision 1.12 +# (Document Number: MD00866-2B-MSA32-AFP-01.12) +# + +&msa_bz df wt s16 + +@bz ...... ... .. wt:5 s16:16 &msa_bz df=3 +@bz_df ...... ... df:2 wt:5 s16:16 &msa_bz + +BZ_V 010001 01011 ..... ................ @bz +BNZ_V 010001 01111 ..... ................ @bz + +BZ_x 010001 110 .. ..... ................ @bz_df +BNZ_x 010001 111 .. ..... ................ @bz_df + +MSA 011110 -------------------------- diff --git a/target/mips/msa_translate.c b/target/mips/msa_translate.c index 52bd428759..5efb0a1fc8 100644 --- a/target/mips/msa_translate.c +++ b/target/mips/msa_translate.c @@ -6,6 +6,7 @@ * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support) * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support) * Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support) + * Copyright (c) 2020 Philippe Mathieu-Daudé * * SPDX-License-Identifier: LGPL-2.1-or-later */ @@ -16,6 +17,9 @@ #include "fpu_helper.h" #include "internal.h" +/* Include the auto-generated decoder. */ +#include "decode-msa32.c.inc" + #define OPC_MSA (0x1E << 26) #define MASK_MSA_MINOR(op) (MASK_OP_MAJOR(op) | (op & 0x3F)) @@ -370,6 +374,16 @@ static bool gen_msa_BxZ_V(DisasContext *ctx, int wt, int s16, TCGCond cond) return true; } +static bool trans_BZ_V(DisasContext *ctx, arg_msa_bz *a) +{ + return gen_msa_BxZ_V(ctx, a->wt, a->s16, TCG_COND_EQ); +} + +static bool trans_BNZ_V(DisasContext *ctx, arg_msa_bz *a) +{ + return gen_msa_BxZ_V(ctx, a->wt, a->s16, TCG_COND_NE); +} + static bool gen_msa_BxZ(DisasContext *ctx, int df, int wt, int s16, bool if_not) { check_