kvm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 00/24] target/mips: Convert MSA ASE to decodetree
@ 2020-12-15 22:57 Philippe Mathieu-Daudé
  2020-12-15 22:57 ` [PATCH v2 01/24] target/mips/translate: Extract decode_opc_legacy() from decode_opc() Philippe Mathieu-Daudé
                   ` (23 more replies)
  0 siblings, 24 replies; 48+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-12-15 22:57 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel
  Cc: kvm, Aleksandar Rikalo, Paolo Bonzini, Aurelien Jarno,
	Jiaxun Yang, Philippe Mathieu-Daudé,
	Huacai Chen

Missing review: 1-3 14 17 19-24

Since v1:
- rebased
- addressed Richard review comments
- reworded some commit descriptions
- avoid 64-bit ifdef'ry

Finally, we use decodetree with the MIPS target.

Starting easy with the MSA ASE. 2700+ lines extracted
from helper.h and translate.c, now built as an new
object: mod-msa_translate.o.

Phil.

Available:
  https://gitlab.com/philmd/qemu/-/commits/mips_msa_decodetree_v2

Based-on: <20201214183739.500368-1-f4bug@amsat.org>

Philippe Mathieu-Daudé (24):
  target/mips/translate: Extract decode_opc_legacy() from decode_opc()
  target/mips/translate: Expose check_mips_64() to 32-bit mode
  target/mips/cpu: Introduce isa_rel6_available() helper
  target/mips: Introduce ase_msa_available() helper
  target/mips: Simplify msa_reset()
  target/mips: Use CP0_Config3 to set MIPS_HFLAG_MSA
  target/mips: Simplify MSA TCG logic
  target/mips: Remove now unused ASE_MSA definition
  target/mips: Alias MSA vector registers on FPU scalar registers
  target/mips: Extract msa_translate_init() from mips_tcg_init()
  target/mips: Remove CPUMIPSState* argument from gen_msa*() methods
  target/mips: Explode gen_msa_branch() as gen_msa_BxZ_V/BxZ()
  target/mips: Rename msa_helper.c as mod-msa_helper.c
  target/mips: Move msa_reset() to mod-msa_helper.c
  target/mips: Extract MSA helpers from op_helper.c
  target/mips: Extract MSA helper definitions
  target/mips: Declare gen_msa/_branch() in 'translate.h'
  target/mips: Extract MSA translation routines
  target/mips: Introduce decode tree bindings for MSA opcodes
  target/mips: Use decode_ase_msa() generated from decodetree
  target/mips: Extract LSA/DLSA translation generators
  target/mips: Introduce decodetree helpers for MSA LSA/DLSA opcodes
  target/mips: Introduce decodetree helpers for Release6 LSA/DLSA
    opcodes
  target/mips/mod-msa: Pass TCGCond argument to gen_check_zero_element()

 target/mips/cpu.h                             |    7 +
 target/mips/helper.h                          |  436 +--
 target/mips/internal.h                        |    4 +-
 target/mips/mips-defs.h                       |    1 -
 target/mips/translate.h                       |   25 +-
 target/mips/isa-mips32r6.decode               |   17 +
 target/mips/isa-mips64r6.decode               |   17 +
 target/mips/mod-msa32.decode                  |   28 +
 target/mips/mod-msa64.decode                  |   17 +
 target/mips/cpu.c                             |   14 +-
 target/mips/isa-mips_rel6_translate.c         |   37 +
 target/mips/kvm.c                             |   12 +-
 .../mips/{msa_helper.c => mod-msa_helper.c}   |  429 +++
 target/mips/mod-msa_translate.c               | 2286 ++++++++++++++++
 target/mips/op_helper.c                       |  394 ---
 target/mips/translate.c                       | 2352 +----------------
 target/mips/translate_addr_const.c            |   52 +
 target/mips/cpu-defs.c.inc                    |   40 +-
 target/mips/meson.build                       |   14 +-
 target/mips/mod-msa_helper.h.inc              |  443 ++++
 20 files changed, 3437 insertions(+), 3188 deletions(-)
 create mode 100644 target/mips/isa-mips32r6.decode
 create mode 100644 target/mips/isa-mips64r6.decode
 create mode 100644 target/mips/mod-msa32.decode
 create mode 100644 target/mips/mod-msa64.decode
 create mode 100644 target/mips/isa-mips_rel6_translate.c
 rename target/mips/{msa_helper.c => mod-msa_helper.c} (93%)
 create mode 100644 target/mips/mod-msa_translate.c
 create mode 100644 target/mips/translate_addr_const.c
 create mode 100644 target/mips/mod-msa_helper.h.inc

-- 
2.26.2


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH v2 01/24] target/mips/translate: Extract decode_opc_legacy() from decode_opc()
  2020-12-15 22:57 [PATCH v2 00/24] target/mips: Convert MSA ASE to decodetree Philippe Mathieu-Daudé
@ 2020-12-15 22:57 ` Philippe Mathieu-Daudé
  2020-12-15 23:23   ` Richard Henderson
  2020-12-15 22:57 ` [PATCH v2 02/24] target/mips/translate: Expose check_mips_64() to 32-bit mode Philippe Mathieu-Daudé
                   ` (22 subsequent siblings)
  23 siblings, 1 reply; 48+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-12-15 22:57 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel
  Cc: kvm, Aleksandar Rikalo, Paolo Bonzini, Aurelien Jarno,
	Jiaxun Yang, Philippe Mathieu-Daudé,
	Huacai Chen

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é <f4bug@amsat.org>
---
 target/mips/translate.c | 45 ++++++++++++++++++++++++-----------------
 1 file changed, 26 insertions(+), 19 deletions(-)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index cc876019bf7..5c62b32c6ae 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -30518,30 +30518,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;
@@ -31269,8 +31252,32 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
         break;
     default:            /* Invalid */
         MIPS_INVAL("major opcode");
+        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)) {
         gen_reserved_instruction(ctx);
-        break;
     }
 }
 
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PATCH v2 02/24] target/mips/translate: Expose check_mips_64() to 32-bit mode
  2020-12-15 22:57 [PATCH v2 00/24] target/mips: Convert MSA ASE to decodetree Philippe Mathieu-Daudé
  2020-12-15 22:57 ` [PATCH v2 01/24] target/mips/translate: Extract decode_opc_legacy() from decode_opc() Philippe Mathieu-Daudé
@ 2020-12-15 22:57 ` Philippe Mathieu-Daudé
  2021-01-06 18:20   ` Philippe Mathieu-Daudé
  2020-12-15 22:57 ` [PATCH v2 03/24] target/mips/cpu: Introduce isa_rel6_available() helper Philippe Mathieu-Daudé
                   ` (21 subsequent siblings)
  23 siblings, 1 reply; 48+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-12-15 22:57 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel
  Cc: kvm, Aleksandar Rikalo, Paolo Bonzini, Aurelien Jarno,
	Jiaxun Yang, Philippe Mathieu-Daudé,
	Huacai Chen

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é <f4bug@amsat.org>
---
 target/mips/translate.h | 2 --
 target/mips/translate.c | 8 +++-----
 2 files changed, 3 insertions(+), 7 deletions(-)

diff --git a/target/mips/translate.h b/target/mips/translate.h
index a9eab69249f..942d803476c 100644
--- a/target/mips/translate.h
+++ b/target/mips/translate.h
@@ -127,9 +127,7 @@ 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
 void check_mips_64(DisasContext *ctx);
-#endif
 void check_cp1_enabled(DisasContext *ctx);
 
 void gen_base_offset_addr(DisasContext *ctx, TCGv addr, int base, int offset);
diff --git a/target/mips/translate.c b/target/mips/translate.c
index 5c62b32c6ae..af543d1f375 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -2972,18 +2972,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)
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PATCH v2 03/24] target/mips/cpu: Introduce isa_rel6_available() helper
  2020-12-15 22:57 [PATCH v2 00/24] target/mips: Convert MSA ASE to decodetree Philippe Mathieu-Daudé
  2020-12-15 22:57 ` [PATCH v2 01/24] target/mips/translate: Extract decode_opc_legacy() from decode_opc() Philippe Mathieu-Daudé
  2020-12-15 22:57 ` [PATCH v2 02/24] target/mips/translate: Expose check_mips_64() to 32-bit mode Philippe Mathieu-Daudé
@ 2020-12-15 22:57 ` Philippe Mathieu-Daudé
  2020-12-15 23:27   ` Richard Henderson
  2020-12-15 22:57 ` [PATCH v2 04/24] target/mips: Introduce ase_msa_available() helper Philippe Mathieu-Daudé
                   ` (20 subsequent siblings)
  23 siblings, 1 reply; 48+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-12-15 22:57 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel
  Cc: kvm, Aleksandar Rikalo, Paolo Bonzini, Aurelien Jarno,
	Jiaxun Yang, Philippe Mathieu-Daudé,
	Huacai Chen

Introduce the isa_rel6_available() helper to check if the
CPU supports the Release 6 ISA.

Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 target/mips/cpu.h | 1 +
 target/mips/cpu.c | 8 ++++++++
 2 files changed, 9 insertions(+)

diff --git a/target/mips/cpu.h b/target/mips/cpu.h
index 3ac21d0e9c0..c6a556efad5 100644
--- a/target/mips/cpu.h
+++ b/target/mips/cpu.h
@@ -1289,6 +1289,7 @@ int cpu_mips_signal_handler(int host_signum, void *pinfo, void *puc);
 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);
+bool isa_rel6_available(const CPUMIPSState *env);
 
 /* Check presence of multi-threading ASE implementation */
 static inline bool ase_mt_available(CPUMIPSState *env)
diff --git a/target/mips/cpu.c b/target/mips/cpu.c
index 4191c0741f4..9f082518076 100644
--- a/target/mips/cpu.c
+++ b/target/mips/cpu.c
@@ -789,6 +789,14 @@ bool cpu_supports_isa(const CPUMIPSState *env, uint64_t isa_mask)
     return (env->cpu_model->insn_flags & isa_mask) != 0;
 }
 
+bool isa_rel6_available(const CPUMIPSState *env)
+{
+    if (TARGET_LONG_BITS == 64) {
+        return cpu_supports_isa(env, ISA_MIPS64R6);
+    }
+    return cpu_supports_isa(env, ISA_MIPS32R6);
+}
+
 bool cpu_type_supports_isa(const char *cpu_type, uint64_t isa)
 {
     const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PATCH v2 04/24] target/mips: Introduce ase_msa_available() helper
  2020-12-15 22:57 [PATCH v2 00/24] target/mips: Convert MSA ASE to decodetree Philippe Mathieu-Daudé
                   ` (2 preceding siblings ...)
  2020-12-15 22:57 ` [PATCH v2 03/24] target/mips/cpu: Introduce isa_rel6_available() helper Philippe Mathieu-Daudé
@ 2020-12-15 22:57 ` Philippe Mathieu-Daudé
  2020-12-15 22:57 ` [PATCH v2 05/24] target/mips: Simplify msa_reset() Philippe Mathieu-Daudé
                   ` (19 subsequent siblings)
  23 siblings, 0 replies; 48+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-12-15 22:57 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel
  Cc: kvm, Aleksandar Rikalo, Paolo Bonzini, Aurelien Jarno,
	Jiaxun Yang, Philippe Mathieu-Daudé,
	Huacai Chen

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 <jiaxun.yang@flygoat.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 target/mips/cpu.h       |  6 ++++++
 target/mips/cpu.c       |  2 +-
 target/mips/kvm.c       | 12 ++++++------
 target/mips/translate.c |  6 ++----
 4 files changed, 15 insertions(+), 11 deletions(-)

diff --git a/target/mips/cpu.h b/target/mips/cpu.h
index c6a556efad5..1d72307c547 100644
--- a/target/mips/cpu.h
+++ b/target/mips/cpu.h
@@ -1291,6 +1291,12 @@ bool cpu_supports_isa(const CPUMIPSState *env, uint64_t isa_mask);
 bool cpu_type_supports_isa(const char *cpu_type, uint64_t isa);
 bool isa_rel6_available(const CPUMIPSState *env);
 
+/* 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/cpu.c b/target/mips/cpu.c
index 9f082518076..1b4c13bc972 100644
--- a/target/mips/cpu.c
+++ b/target/mips/cpu.c
@@ -532,7 +532,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/kvm.c b/target/mips/kvm.c
index a5b6fe35dbc..84fb10ea35d 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 af543d1f375..fc658b3be33 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -24920,8 +24920,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) ||
-            (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
+        if ((ctx->insn_flags & ISA_MIPS32R6) || ase_msa_available(env)) {
             decode_opc_special_r6(env, ctx);
         } else {
             /* Pmon entry point, also R4010 selsl */
@@ -25023,8 +25022,7 @@ static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
         }
         break;
     case OPC_DLSA:
-        if ((ctx->insn_flags & ISA_MIPS32R6) ||
-            (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
+        if ((ctx->insn_flags & ISA_MIPS32R6) || ase_msa_available(env)) {
             decode_opc_special_r6(env, ctx);
         }
         break;
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PATCH v2 05/24] target/mips: Simplify msa_reset()
  2020-12-15 22:57 [PATCH v2 00/24] target/mips: Convert MSA ASE to decodetree Philippe Mathieu-Daudé
                   ` (3 preceding siblings ...)
  2020-12-15 22:57 ` [PATCH v2 04/24] target/mips: Introduce ase_msa_available() helper Philippe Mathieu-Daudé
@ 2020-12-15 22:57 ` Philippe Mathieu-Daudé
  2020-12-15 22:57 ` [PATCH v2 06/24] target/mips: Use CP0_Config3 to set MIPS_HFLAG_MSA Philippe Mathieu-Daudé
                   ` (18 subsequent siblings)
  23 siblings, 0 replies; 48+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-12-15 22:57 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel
  Cc: kvm, Aleksandar Rikalo, Paolo Bonzini, Aurelien Jarno,
	Jiaxun Yang, Philippe Mathieu-Daudé,
	Huacai Chen

Call msa_reset() unconditionally, but only reset
the MSA registers if MSA is implemented.

Reviewed-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 target/mips/cpu.c          | 5 +----
 target/mips/cpu-defs.c.inc | 4 ++++
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/target/mips/cpu.c b/target/mips/cpu.c
index 1b4c13bc972..77ebd94c655 100644
--- a/target/mips/cpu.c
+++ b/target/mips/cpu.c
@@ -531,10 +531,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);
diff --git a/target/mips/cpu-defs.c.inc b/target/mips/cpu-defs.c.inc
index a788f5a6b6d..bf12e91f715 100644
--- a/target/mips/cpu-defs.c.inc
+++ b/target/mips/cpu-defs.c.inc
@@ -976,6 +976,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;
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PATCH v2 06/24] target/mips: Use CP0_Config3 to set MIPS_HFLAG_MSA
  2020-12-15 22:57 [PATCH v2 00/24] target/mips: Convert MSA ASE to decodetree Philippe Mathieu-Daudé
                   ` (4 preceding siblings ...)
  2020-12-15 22:57 ` [PATCH v2 05/24] target/mips: Simplify msa_reset() Philippe Mathieu-Daudé
@ 2020-12-15 22:57 ` Philippe Mathieu-Daudé
  2020-12-15 22:57 ` [PATCH v2 07/24] target/mips: Simplify MSA TCG logic Philippe Mathieu-Daudé
                   ` (17 subsequent siblings)
  23 siblings, 0 replies; 48+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-12-15 22:57 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel
  Cc: kvm, Aleksandar Rikalo, Paolo Bonzini, Aurelien Jarno,
	Jiaxun Yang, Philippe Mathieu-Daudé,
	Huacai Chen

MSA presence is expressed by the MSAP bit of CP0_Config3.
We don't need to check anything else.

Reviewed-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <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 968a3a8db8f..1ab2454e61d 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;
         }
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PATCH v2 07/24] target/mips: Simplify MSA TCG logic
  2020-12-15 22:57 [PATCH v2 00/24] target/mips: Convert MSA ASE to decodetree Philippe Mathieu-Daudé
                   ` (5 preceding siblings ...)
  2020-12-15 22:57 ` [PATCH v2 06/24] target/mips: Use CP0_Config3 to set MIPS_HFLAG_MSA Philippe Mathieu-Daudé
@ 2020-12-15 22:57 ` Philippe Mathieu-Daudé
  2020-12-15 22:57 ` [PATCH v2 08/24] target/mips: Remove now unused ASE_MSA definition Philippe Mathieu-Daudé
                   ` (16 subsequent siblings)
  23 siblings, 0 replies; 48+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-12-15 22:57 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel
  Cc: kvm, Aleksandar Rikalo, Paolo Bonzini, Aurelien Jarno,
	Jiaxun Yang, Philippe Mathieu-Daudé,
	Huacai Chen

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 <jiaxun.yang@flygoat.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 target/mips/translate.c | 22 ++++++++++------------
 1 file changed, 10 insertions(+), 12 deletions(-)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index fc658b3be33..02ea184f9a3 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -28568,13 +28568,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;
 }
@@ -30418,7 +30413,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)) {
@@ -31048,9 +31043,10 @@ 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;
+            }
         default:
             MIPS_INVAL("cp1");
             gen_reserved_instruction(ctx);
@@ -31239,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:
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PATCH v2 08/24] target/mips: Remove now unused ASE_MSA definition
  2020-12-15 22:57 [PATCH v2 00/24] target/mips: Convert MSA ASE to decodetree Philippe Mathieu-Daudé
                   ` (6 preceding siblings ...)
  2020-12-15 22:57 ` [PATCH v2 07/24] target/mips: Simplify MSA TCG logic Philippe Mathieu-Daudé
@ 2020-12-15 22:57 ` Philippe Mathieu-Daudé
  2020-12-15 22:57 ` [PATCH v2 09/24] target/mips: Alias MSA vector registers on FPU scalar registers Philippe Mathieu-Daudé
                   ` (15 subsequent siblings)
  23 siblings, 0 replies; 48+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-12-15 22:57 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel
  Cc: kvm, Aleksandar Rikalo, Paolo Bonzini, Aurelien Jarno,
	Jiaxun Yang, Philippe Mathieu-Daudé,
	Huacai Chen

We don't use ASE_MSA anymore (replaced by ase_msa_available()
checking MSAP bit from CP0_Config3). Remove it.

Reviewed-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 target/mips/mips-defs.h    | 1 -
 target/mips/cpu-defs.c.inc | 8 ++++----
 2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/target/mips/mips-defs.h b/target/mips/mips-defs.h
index ed6a7a9e545..805034b8956 100644
--- a/target/mips/mips-defs.h
+++ b/target/mips/mips-defs.h
@@ -45,7 +45,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
  */
diff --git a/target/mips/cpu-defs.c.inc b/target/mips/cpu-defs.c.inc
index bf12e91f715..325b24b8e2c 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,
     },
     {
@@ -721,7 +721,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,
     },
     {
@@ -761,7 +761,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,
     },
     {
@@ -887,7 +887,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,
     },
     {
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PATCH v2 09/24] target/mips: Alias MSA vector registers on FPU scalar registers
  2020-12-15 22:57 [PATCH v2 00/24] target/mips: Convert MSA ASE to decodetree Philippe Mathieu-Daudé
                   ` (7 preceding siblings ...)
  2020-12-15 22:57 ` [PATCH v2 08/24] target/mips: Remove now unused ASE_MSA definition Philippe Mathieu-Daudé
@ 2020-12-15 22:57 ` Philippe Mathieu-Daudé
  2020-12-15 22:57 ` [PATCH v2 10/24] target/mips: Extract msa_translate_init() from mips_tcg_init() Philippe Mathieu-Daudé
                   ` (14 subsequent siblings)
  23 siblings, 0 replies; 48+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-12-15 22:57 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel
  Cc: kvm, Aleksandar Rikalo, Paolo Bonzini, Aurelien Jarno,
	Jiaxun Yang, Philippe Mathieu-Daudé,
	Huacai Chen

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 <jiaxun.yang@flygoat.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 target/mips/translate.c | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index 02ea184f9a3..9b5b551b616 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -31560,16 +31560,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]);
-        msa_wr_d[i * 2] =
-                tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2]);
+
+        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]);
+
         /*
-         * 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]);
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PATCH v2 10/24] target/mips: Extract msa_translate_init() from mips_tcg_init()
  2020-12-15 22:57 [PATCH v2 00/24] target/mips: Convert MSA ASE to decodetree Philippe Mathieu-Daudé
                   ` (8 preceding siblings ...)
  2020-12-15 22:57 ` [PATCH v2 09/24] target/mips: Alias MSA vector registers on FPU scalar registers Philippe Mathieu-Daudé
@ 2020-12-15 22:57 ` Philippe Mathieu-Daudé
  2020-12-15 22:57 ` [PATCH v2 11/24] target/mips: Remove CPUMIPSState* argument from gen_msa*() methods Philippe Mathieu-Daudé
                   ` (13 subsequent siblings)
  23 siblings, 0 replies; 48+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-12-15 22:57 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel
  Cc: kvm, Aleksandar Rikalo, Paolo Bonzini, Aurelien Jarno,
	Jiaxun Yang, Philippe Mathieu-Daudé,
	Huacai Chen

The msa_wr_d[] registers are only initialized/used by MSA.

They are declared static. We want to move them to the new
'mod-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 <jiaxun.yang@flygoat.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 target/mips/translate.h |  3 +++
 target/mips/translate.c | 33 +++++++++++++++++++--------------
 2 files changed, 22 insertions(+), 14 deletions(-)

diff --git a/target/mips/translate.h b/target/mips/translate.h
index 942d803476c..f7e7037bab8 100644
--- a/target/mips/translate.h
+++ b/target/mips/translate.h
@@ -161,4 +161,7 @@ extern TCGv bcond;
         }                                                                     \
     } while (0)
 
+/* MSA */
+void msa_translate_init(void);
+
 #endif
diff --git a/target/mips/translate.c b/target/mips/translate.c
index 9b5b551b616..2dc7b446e9a 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -31550,6 +31550,24 @@ 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;
@@ -31565,20 +31583,7 @@ void mips_tcg_init(void)
 
         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]);
-
-        /*
-         * 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]);
-    }
-
+    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++) {
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PATCH v2 11/24] target/mips: Remove CPUMIPSState* argument from gen_msa*() methods
  2020-12-15 22:57 [PATCH v2 00/24] target/mips: Convert MSA ASE to decodetree Philippe Mathieu-Daudé
                   ` (9 preceding siblings ...)
  2020-12-15 22:57 ` [PATCH v2 10/24] target/mips: Extract msa_translate_init() from mips_tcg_init() Philippe Mathieu-Daudé
@ 2020-12-15 22:57 ` Philippe Mathieu-Daudé
  2020-12-15 22:57 ` [PATCH v2 12/24] target/mips: Explode gen_msa_branch() as gen_msa_BxZ_V/BxZ() Philippe Mathieu-Daudé
                   ` (12 subsequent siblings)
  23 siblings, 0 replies; 48+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-12-15 22:57 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel
  Cc: kvm, Aleksandar Rikalo, Paolo Bonzini, Aurelien Jarno,
	Jiaxun Yang, Philippe Mathieu-Daudé,
	Huacai Chen

The gen_msa*() methods don't use the "CPUMIPSState *env"
argument. Remove it to simplify.

Reviewed-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <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 2dc7b446e9a..a3618a3beb2 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -28615,7 +28615,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;
@@ -28660,7 +28660,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;
@@ -28718,7 +28718,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;
@@ -28791,7 +28791,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;
@@ -28875,7 +28875,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;
@@ -29857,7 +29857,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;
@@ -29889,8 +29889,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;
@@ -30000,7 +29999,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;
@@ -30019,17 +30018,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;
@@ -30187,7 +30186,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)))
@@ -30271,7 +30270,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)))
@@ -30342,7 +30341,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;
@@ -30385,7 +30384,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:
@@ -30395,13 +30394,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");
@@ -30410,7 +30409,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;
 
@@ -30420,15 +30419,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:
@@ -30439,18 +30438,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:
@@ -31044,7 +31043,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;
             }
         default:
@@ -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;
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PATCH v2 12/24] target/mips: Explode gen_msa_branch() as gen_msa_BxZ_V/BxZ()
  2020-12-15 22:57 [PATCH v2 00/24] target/mips: Convert MSA ASE to decodetree Philippe Mathieu-Daudé
                   ` (10 preceding siblings ...)
  2020-12-15 22:57 ` [PATCH v2 11/24] target/mips: Remove CPUMIPSState* argument from gen_msa*() methods Philippe Mathieu-Daudé
@ 2020-12-15 22:57 ` Philippe Mathieu-Daudé
  2020-12-15 22:57 ` [PATCH v2 13/24] target/mips: Rename msa_helper.c as mod-msa_helper.c Philippe Mathieu-Daudé
                   ` (11 subsequent siblings)
  23 siblings, 0 replies; 48+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-12-15 22:57 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel
  Cc: kvm, Aleksandar Rikalo, Paolo Bonzini, Aurelien Jarno,
	Jiaxun Yang, Philippe Mathieu-Daudé,
	Huacai Chen

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 <jiaxun.yang@flygoat.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 target/mips/translate.c | 71 ++++++++++++++++++++++++++++-------------
 1 file changed, 49 insertions(+), 22 deletions(-)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index a3618a3beb2..9be946256b3 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -28615,49 +28615,76 @@ static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt)
     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;
+}
+
 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;
 
-    check_msa_access(ctx);
-
-    if (ctx->hflags & MIPS_HFLAG_BMASK) {
-        gen_reserved_instruction(ctx);
-        return;
-    }
     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)
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PATCH v2 13/24] target/mips: Rename msa_helper.c as mod-msa_helper.c
  2020-12-15 22:57 [PATCH v2 00/24] target/mips: Convert MSA ASE to decodetree Philippe Mathieu-Daudé
                   ` (11 preceding siblings ...)
  2020-12-15 22:57 ` [PATCH v2 12/24] target/mips: Explode gen_msa_branch() as gen_msa_BxZ_V/BxZ() Philippe Mathieu-Daudé
@ 2020-12-15 22:57 ` Philippe Mathieu-Daudé
  2020-12-15 22:57 ` [PATCH v2 14/24] target/mips: Move msa_reset() to mod-msa_helper.c Philippe Mathieu-Daudé
                   ` (10 subsequent siblings)
  23 siblings, 0 replies; 48+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-12-15 22:57 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel
  Cc: kvm, Aleksandar Rikalo, Paolo Bonzini, Aurelien Jarno,
	Jiaxun Yang, Philippe Mathieu-Daudé,
	Huacai Chen

MSA means 'MIPS SIMD Architecture' and is defined as a Module by
MIPS.
To keep the directory sorted, we use the 'mod' prefix for MIPS
modules. Rename msa_helper.c as mod-msa_helper.c.

Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20201123204448.3260804-4-f4bug@amsat.org>
---
 target/mips/{msa_helper.c => mod-msa_helper.c} | 0
 target/mips/meson.build                        | 2 +-
 2 files changed, 1 insertion(+), 1 deletion(-)
 rename target/mips/{msa_helper.c => mod-msa_helper.c} (100%)

diff --git a/target/mips/msa_helper.c b/target/mips/mod-msa_helper.c
similarity index 100%
rename from target/mips/msa_helper.c
rename to target/mips/mod-msa_helper.c
diff --git a/target/mips/meson.build b/target/mips/meson.build
index 596eb1aeeb3..05ed33b75ce 100644
--- a/target/mips/meson.build
+++ b/target/mips/meson.build
@@ -7,8 +7,8 @@
   'dsp_helper.c',
   'fpu_helper.c',
   'lmmi_helper.c',
-  'msa_helper.c',
   'op_helper.c',
+  'mod-msa_helper.c',
   'tlb_helper.c',
   'translate.c',
 ))
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PATCH v2 14/24] target/mips: Move msa_reset() to mod-msa_helper.c
  2020-12-15 22:57 [PATCH v2 00/24] target/mips: Convert MSA ASE to decodetree Philippe Mathieu-Daudé
                   ` (12 preceding siblings ...)
  2020-12-15 22:57 ` [PATCH v2 13/24] target/mips: Rename msa_helper.c as mod-msa_helper.c Philippe Mathieu-Daudé
@ 2020-12-15 22:57 ` Philippe Mathieu-Daudé
  2020-12-15 23:09   ` Richard Henderson
  2020-12-15 22:57 ` [PATCH v2 15/24] target/mips: Extract MSA helpers from op_helper.c Philippe Mathieu-Daudé
                   ` (9 subsequent siblings)
  23 siblings, 1 reply; 48+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-12-15 22:57 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel
  Cc: kvm, Aleksandar Rikalo, Paolo Bonzini, Aurelien Jarno,
	Jiaxun Yang, Philippe Mathieu-Daudé,
	Huacai Chen

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é <f4bug@amsat.org>
---
 target/mips/internal.h       |  2 ++
 target/mips/cpu.c            |  1 +
 target/mips/mod-msa_helper.c | 36 ++++++++++++++++++++++++++++++++++++
 target/mips/cpu-defs.c.inc   | 36 ------------------------------------
 4 files changed, 39 insertions(+), 36 deletions(-)

diff --git a/target/mips/internal.h b/target/mips/internal.h
index 1ab2454e61d..76269cfc7bb 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/cpu.c b/target/mips/cpu.c
index 77ebd94c655..26e110b687e 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/mod-msa_helper.c b/target/mips/mod-msa_helper.c
index b89b4c44902..f0d728c03f0 100644
--- a/target/mips/mod-msa_helper.c
+++ b/target/mips/mod-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);
+}
diff --git a/target/mips/cpu-defs.c.inc b/target/mips/cpu-defs.c.inc
index 325b24b8e2c..320ebf29f1f 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 <http://www.gnu.org/licenses/>.
  */
 
-#include "fpu_helper.h"
-
 /* CPU / CPU family specific config register values. */
 
 /* Have config1, uncached coherency */
@@ -973,37 +971,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);
-}
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PATCH v2 15/24] target/mips: Extract MSA helpers from op_helper.c
  2020-12-15 22:57 [PATCH v2 00/24] target/mips: Convert MSA ASE to decodetree Philippe Mathieu-Daudé
                   ` (13 preceding siblings ...)
  2020-12-15 22:57 ` [PATCH v2 14/24] target/mips: Move msa_reset() to mod-msa_helper.c Philippe Mathieu-Daudé
@ 2020-12-15 22:57 ` Philippe Mathieu-Daudé
  2020-12-15 22:57 ` [PATCH v2 16/24] target/mips: Extract MSA helper definitions Philippe Mathieu-Daudé
                   ` (8 subsequent siblings)
  23 siblings, 0 replies; 48+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-12-15 22:57 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel
  Cc: kvm, Aleksandar Rikalo, Paolo Bonzini, Aurelien Jarno,
	Jiaxun Yang, Philippe Mathieu-Daudé,
	Huacai Chen

We have ~400 lines of MSA helpers in the generic op_helper.c,
move them with the other helpers in 'mod-msa_helper.c'.

Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20201123204448.3260804-5-f4bug@amsat.org>
---
 target/mips/mod-msa_helper.c | 393 ++++++++++++++++++++++++++++++++++
 target/mips/op_helper.c      | 394 -----------------------------------
 2 files changed, 393 insertions(+), 394 deletions(-)

diff --git a/target/mips/mod-msa_helper.c b/target/mips/mod-msa_helper.c
index f0d728c03f0..1298a1917ce 100644
--- a/target/mips/mod-msa_helper.c
+++ b/target/mips/mod-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 3386b8228e9..89c7d4556a0 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
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PATCH v2 16/24] target/mips: Extract MSA helper definitions
  2020-12-15 22:57 [PATCH v2 00/24] target/mips: Convert MSA ASE to decodetree Philippe Mathieu-Daudé
                   ` (14 preceding siblings ...)
  2020-12-15 22:57 ` [PATCH v2 15/24] target/mips: Extract MSA helpers from op_helper.c Philippe Mathieu-Daudé
@ 2020-12-15 22:57 ` Philippe Mathieu-Daudé
  2020-12-15 22:57 ` [PATCH v2 17/24] target/mips: Declare gen_msa/_branch() in 'translate.h' Philippe Mathieu-Daudé
                   ` (7 subsequent siblings)
  23 siblings, 0 replies; 48+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-12-15 22:57 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel
  Cc: kvm, Aleksandar Rikalo, Paolo Bonzini, Aurelien Jarno,
	Jiaxun Yang, Philippe Mathieu-Daudé,
	Huacai Chen

Keep all MSA-related code altogether.

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Message-Id: <20201120210844.2625602-4-f4bug@amsat.org>
---
 target/mips/helper.h             | 436 +-----------------------------
 target/mips/mod-msa_helper.h.inc | 443 +++++++++++++++++++++++++++++++
 2 files changed, 445 insertions(+), 434 deletions(-)
 create mode 100644 target/mips/mod-msa_helper.h.inc

diff --git a/target/mips/helper.h b/target/mips/helper.h
index e97655dc0eb..80eb675fa64 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 "mod-msa_helper.h.inc"
diff --git a/target/mips/mod-msa_helper.h.inc b/target/mips/mod-msa_helper.h.inc
new file mode 100644
index 00000000000..4963d1553a0
--- /dev/null
+++ b/target/mips/mod-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
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PATCH v2 17/24] target/mips: Declare gen_msa/_branch() in 'translate.h'
  2020-12-15 22:57 [PATCH v2 00/24] target/mips: Convert MSA ASE to decodetree Philippe Mathieu-Daudé
                   ` (15 preceding siblings ...)
  2020-12-15 22:57 ` [PATCH v2 16/24] target/mips: Extract MSA helper definitions Philippe Mathieu-Daudé
@ 2020-12-15 22:57 ` Philippe Mathieu-Daudé
  2020-12-15 23:10   ` Richard Henderson
  2020-12-15 22:57 ` [PATCH v2 19/24] target/mips: Introduce decode tree bindings for MSA opcodes Philippe Mathieu-Daudé
                   ` (6 subsequent siblings)
  23 siblings, 1 reply; 48+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-12-15 22:57 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel
  Cc: kvm, Aleksandar Rikalo, Paolo Bonzini, Aurelien Jarno,
	Jiaxun Yang, Philippe Mathieu-Daudé,
	Huacai Chen

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é <f4bug@amsat.org>
---
 target/mips/translate.h | 2 ++
 target/mips/translate.c | 4 ++--
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/target/mips/translate.h b/target/mips/translate.h
index f7e7037bab8..77dfec98792 100644
--- a/target/mips/translate.h
+++ b/target/mips/translate.h
@@ -163,5 +163,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
diff --git a/target/mips/translate.c b/target/mips/translate.c
index 9be946256b3..20174c4aa57 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -28660,7 +28660,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;
@@ -30436,7 +30436,7 @@ static void gen_msa_vec(DisasContext *ctx)
     }
 }
 
-static void gen_msa(DisasContext *ctx)
+void gen_msa(DisasContext *ctx)
 {
     uint32_t opcode = ctx->opcode;
 
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PATCH v2 19/24] target/mips: Introduce decode tree bindings for MSA opcodes
  2020-12-15 22:57 [PATCH v2 00/24] target/mips: Convert MSA ASE to decodetree Philippe Mathieu-Daudé
                   ` (16 preceding siblings ...)
  2020-12-15 22:57 ` [PATCH v2 17/24] target/mips: Declare gen_msa/_branch() in 'translate.h' Philippe Mathieu-Daudé
@ 2020-12-15 22:57 ` Philippe Mathieu-Daudé
  2020-12-15 23:11   ` Richard Henderson
  2020-12-15 22:57 ` [PATCH v2 20/24] target/mips: Use decode_ase_msa() generated from decodetree Philippe Mathieu-Daudé
                   ` (5 subsequent siblings)
  23 siblings, 1 reply; 48+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-12-15 22:57 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel
  Cc: kvm, Aleksandar Rikalo, Paolo Bonzini, Aurelien Jarno,
	Jiaxun Yang, Philippe Mathieu-Daudé,
	Huacai Chen

Introduce the 'mod-msa32' decodetree config for the 32-bit MSA ASE.

We decode the branch instructions, and all instructions based
on the MSA opcode.

Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 target/mips/translate.h         |  3 +++
 target/mips/mod-msa32.decode    | 24 +++++++++++++++++++++
 target/mips/mod-msa_translate.c | 37 ++++++++++++++++++++++++++++++++-
 target/mips/translate.c         |  1 -
 target/mips/meson.build         |  5 +++++
 5 files changed, 68 insertions(+), 2 deletions(-)
 create mode 100644 target/mips/mod-msa32.decode

diff --git a/target/mips/translate.h b/target/mips/translate.h
index 77dfec98792..7ca92bd6beb 100644
--- a/target/mips/translate.h
+++ b/target/mips/translate.h
@@ -166,4 +166,7 @@ void msa_translate_init(void);
 void gen_msa(DisasContext *ctx);
 void gen_msa_branch(DisasContext *ctx, uint32_t op1);
 
+/* decodetree generated */
+bool decode_ase_msa(DisasContext *ctx, uint32_t insn);
+
 #endif
diff --git a/target/mips/mod-msa32.decode b/target/mips/mod-msa32.decode
new file mode 100644
index 00000000000..d69675132b8
--- /dev/null
+++ b/target/mips/mod-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/mod-msa_translate.c b/target/mips/mod-msa_translate.c
index 63feedcb7ca..d0e393a6831 100644
--- a/target/mips/mod-msa_translate.c
+++ b/target/mips/mod-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
  */
@@ -13,10 +14,12 @@
 #include "tcg/tcg-op.h"
 #include "exec/helper-gen.h"
 #include "translate.h"
-#include "fpu_translate.h"
 #include "fpu_helper.h"
 #include "internal.h"
 
+/* Include the auto-generated decoder.  */
+#include "decode-mod-msa32.c.inc"
+
 #define OPC_MSA (0x1E << 26)
 
 #define MASK_MSA_MINOR(op)          (MASK_OP_MAJOR(op) | (op & 0x3F))
@@ -370,6 +373,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_msa_access(ctx);
@@ -391,6 +404,16 @@ static bool gen_msa_BxZ(DisasContext *ctx, int df, int wt, int s16, bool if_not)
     return true;
 }
 
+static bool trans_BZ_x(DisasContext *ctx, arg_msa_bz *a)
+{
+    return gen_msa_BxZ(ctx, a->df, a->wt, a->s16, false);
+}
+
+static bool trans_BNZ_x(DisasContext *ctx, arg_msa_bz *a)
+{
+    return gen_msa_BxZ(ctx, a->df, a->wt, a->s16, true);
+}
+
 void gen_msa_branch(DisasContext *ctx, uint32_t op1)
 {
     uint8_t df = (ctx->opcode >> 21) & 0x3;
@@ -2264,3 +2287,15 @@ void gen_msa(DisasContext *ctx)
         break;
     }
 }
+
+static bool trans_MSA(DisasContext *ctx, arg_MSA *a)
+{
+    gen_msa(ctx);
+
+    return true;
+}
+
+bool decode_ase_msa(DisasContext *ctx, uint32_t insn)
+{
+    return decode_msa32(ctx, insn);
+}
diff --git a/target/mips/translate.c b/target/mips/translate.c
index 1e20d426388..f36255f073a 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -2190,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) */
diff --git a/target/mips/meson.build b/target/mips/meson.build
index 41c3fe7c5bb..5ccc9ddc6b8 100644
--- a/target/mips/meson.build
+++ b/target/mips/meson.build
@@ -1,4 +1,9 @@
+gen = [
+  decodetree.process('mod-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',
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PATCH v2 20/24] target/mips: Use decode_ase_msa() generated from decodetree
  2020-12-15 22:57 [PATCH v2 00/24] target/mips: Convert MSA ASE to decodetree Philippe Mathieu-Daudé
                   ` (17 preceding siblings ...)
  2020-12-15 22:57 ` [PATCH v2 19/24] target/mips: Introduce decode tree bindings for MSA opcodes Philippe Mathieu-Daudé
@ 2020-12-15 22:57 ` Philippe Mathieu-Daudé
  2020-12-15 23:15   ` Richard Henderson
  2020-12-15 22:57 ` [PATCH v2 21/24] target/mips: Extract LSA/DLSA translation generators Philippe Mathieu-Daudé
                   ` (4 subsequent siblings)
  23 siblings, 1 reply; 48+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-12-15 22:57 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel
  Cc: kvm, Aleksandar Rikalo, Paolo Bonzini, Aurelien Jarno,
	Jiaxun Yang, Philippe Mathieu-Daudé,
	Huacai Chen

Now that we can decode the MSA ASE opcodes with decode_msa32(),
use it and remove the unreachable code.

Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 target/mips/translate.h         | 12 ------------
 target/mips/mod-msa_translate.c | 29 +----------------------------
 target/mips/translate.c         | 31 ++++++++++---------------------
 3 files changed, 11 insertions(+), 61 deletions(-)

diff --git a/target/mips/translate.h b/target/mips/translate.h
index 7ca92bd6beb..8d84e0c254d 100644
--- a/target/mips/translate.h
+++ b/target/mips/translate.h
@@ -82,8 +82,6 @@ enum {
     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,
@@ -93,14 +91,6 @@ enum {
     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))
@@ -163,8 +153,6 @@ extern TCGv bcond;
 
 /* MSA */
 void msa_translate_init(void);
-void gen_msa(DisasContext *ctx);
-void gen_msa_branch(DisasContext *ctx, uint32_t op1);
 
 /* decodetree generated */
 bool decode_ase_msa(DisasContext *ctx, uint32_t insn);
diff --git a/target/mips/mod-msa_translate.c b/target/mips/mod-msa_translate.c
index d0e393a6831..d1a8a95e62e 100644
--- a/target/mips/mod-msa_translate.c
+++ b/target/mips/mod-msa_translate.c
@@ -414,33 +414,6 @@ static bool trans_BNZ_x(DisasContext *ctx, arg_msa_bz *a)
     return gen_msa_BxZ(ctx, a->df, a->wt, a->s16, 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)))
@@ -2190,7 +2163,7 @@ static void gen_msa_vec(DisasContext *ctx)
     }
 }
 
-void gen_msa(DisasContext *ctx)
+static void gen_msa(DisasContext *ctx)
 {
     uint32_t opcode = ctx->opcode;
 
diff --git a/target/mips/translate.c b/target/mips/translate.c
index f36255f073a..2ce3dc10dfb 100644
--- a/target/mips/translate.c
+++ b/target/mips/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é
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -135,8 +136,6 @@ enum {
     OPC_JIALC    = (0x3E << 26),
     /* MDMX ASE specific */
     OPC_MDMX     = (0x1E << 26),
-    /* MSA ASE, same as MDMX */
-    OPC_MSA      = OPC_MDMX,
     /* Cache and prefetch */
     OPC_CACHE    = (0x2F << 26),
     OPC_PREF     = (0x33 << 26),
@@ -28828,20 +28827,6 @@ static bool decode_opc_legacy(CPUMIPSState *env, DisasContext *ctx)
             }
             break;
         }
-        case OPC_BZ_V:
-        case OPC_BNZ_V:
-        case OPC_BZ_B:
-        case OPC_BZ_H:
-        case OPC_BZ_W:
-        case OPC_BZ_D:
-        case OPC_BNZ_B:
-        case OPC_BNZ_H:
-        case OPC_BNZ_W:
-        case OPC_BNZ_D:
-            if (ase_msa_available(env)) {
-                gen_msa_branch(ctx, op1);
-                break;
-            }
         default:
             MIPS_INVAL("cp1");
             gen_reserved_instruction(ctx);
@@ -29023,16 +29008,13 @@ static bool decode_opc_legacy(CPUMIPSState *env, DisasContext *ctx)
             gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
         }
         break;
-    case OPC_MSA: /* OPC_MDMX */
+    case OPC_MDMX: /* MMI_OPC_LQ */
         if (ctx->insn_flags & INSN_R5900) {
 #if defined(TARGET_MIPS64)
-            gen_mmi_lq(env, ctx);    /* MMI_OPC_LQ */
+            gen_mmi_lq(env, ctx);
 #endif
         } else {
             /* MDMX: Not implemented. */
-            if (ase_msa_available(env)) {
-                gen_msa(ctx);
-            }
         }
         break;
     case OPC_PCREL:
@@ -29065,6 +29047,13 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
         gen_set_label(l1);
     }
 
+    /* Transition to the auto-generated decoder.  */
+
+    /* ISA Extensions */
+    if (ase_msa_available(env) && decode_ase_msa(ctx, ctx->opcode)) {
+        return;
+    }
+
     if (!decode_opc_legacy(env, ctx)) {
         gen_reserved_instruction(ctx);
     }
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PATCH v2 21/24] target/mips: Extract LSA/DLSA translation generators
  2020-12-15 22:57 [PATCH v2 00/24] target/mips: Convert MSA ASE to decodetree Philippe Mathieu-Daudé
                   ` (18 preceding siblings ...)
  2020-12-15 22:57 ` [PATCH v2 20/24] target/mips: Use decode_ase_msa() generated from decodetree Philippe Mathieu-Daudé
@ 2020-12-15 22:57 ` Philippe Mathieu-Daudé
  2020-12-15 23:17   ` Richard Henderson
  2020-12-15 22:57 ` [PATCH v2 22/24] target/mips: Introduce decodetree helpers for MSA LSA/DLSA opcodes Philippe Mathieu-Daudé
                   ` (3 subsequent siblings)
  23 siblings, 1 reply; 48+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-12-15 22:57 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel
  Cc: kvm, Aleksandar Rikalo, Paolo Bonzini, Aurelien Jarno,
	Jiaxun Yang, Philippe Mathieu-Daudé,
	Huacai Chen

Extract gen_lsa() from translate.c and explode it as
gen_LSA() and gen_DLSA().

Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 target/mips/translate.h            |  6 ++++
 target/mips/translate.c            | 35 +++-----------------
 target/mips/translate_addr_const.c | 52 ++++++++++++++++++++++++++++++
 target/mips/meson.build            |  1 +
 4 files changed, 63 insertions(+), 31 deletions(-)
 create mode 100644 target/mips/translate_addr_const.c

diff --git a/target/mips/translate.h b/target/mips/translate.h
index 8d84e0c254d..47129de81d9 100644
--- a/target/mips/translate.h
+++ b/target/mips/translate.h
@@ -128,6 +128,12 @@ void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg);
 void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg);
 int get_fp_bit(int cc);
 
+/*
+ * Address Computation and Large Constant Instructions
+ */
+bool gen_LSA(DisasContext *ctx, int rd, int rt, int rs, int sa);
+bool gen_DLSA(DisasContext *ctx, int rd, int rt, int rs, int sa);
+
 extern TCGv cpu_gpr[32], cpu_PC;
 extern TCGv_i32 fpu_fcr0, fpu_fcr31;
 extern TCGv_i64 fpu_f64[32];
diff --git a/target/mips/translate.c b/target/mips/translate.c
index 2ce3dc10dfb..e0439ba92d8 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -6616,31 +6616,6 @@ static void gen_bshfl(DisasContext *ctx, uint32_t op2, int rt, int rd)
     tcg_temp_free(t0);
 }
 
-static void gen_lsa(DisasContext *ctx, int opc, int rd, int rs, int rt,
-                    int imm2)
-{
-    TCGv t0;
-    TCGv t1;
-    if (rd == 0) {
-        /* Treat as NOP. */
-        return;
-    }
-    t0 = tcg_temp_new();
-    t1 = tcg_temp_new();
-    gen_load_gpr(t0, rs);
-    gen_load_gpr(t1, rt);
-    tcg_gen_shli_tl(t0, t0, imm2 + 1);
-    tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
-    if (opc == OPC_LSA) {
-        tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
-    }
-
-    tcg_temp_free(t1);
-    tcg_temp_free(t0);
-
-    return;
-}
-
 static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs,
                            int rt, int bits)
 {
@@ -16496,8 +16471,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
             return;
         case LSA:
             check_insn(ctx, ISA_MIPS32R6);
-            gen_lsa(ctx, OPC_LSA, rd, rs, rt,
-                    extract32(ctx->opcode, 9, 2));
+            gen_LSA(ctx, rd, rs, rt, extract32(ctx->opcode, 9, 2));
             break;
         case ALIGN:
             check_insn(ctx, ISA_MIPS32R6);
@@ -21460,8 +21434,7 @@ static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
                  * amount, meaning that the supported shift values are in
                  * the range 0 to 3 (instead of 1 to 4 in MIPSR6).
                  */
-                gen_lsa(ctx, OPC_LSA, rd, rs, rt,
-                        extract32(ctx->opcode, 9, 2) - 1);
+                gen_LSA(ctx, rd, rs, rt, extract32(ctx->opcode, 9, 2) - 1);
                 break;
             case NM_EXTW:
                 gen_ext(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 6, 5));
@@ -24347,7 +24320,7 @@ static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
     op1 = MASK_SPECIAL(ctx->opcode);
     switch (op1) {
     case OPC_LSA:
-        gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
+        gen_LSA(ctx, rd, rs, rt, extract32(ctx->opcode, 6, 2));
         break;
     case OPC_MULT:
     case OPC_MULTU:
@@ -24401,7 +24374,7 @@ static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
 #if defined(TARGET_MIPS64)
     case OPC_DLSA:
         check_mips_64(ctx);
-        gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
+        gen_DLSA(ctx, rd, rs, rt, extract32(ctx->opcode, 6, 2));
         break;
     case R6_OPC_DCLO:
     case R6_OPC_DCLZ:
diff --git a/target/mips/translate_addr_const.c b/target/mips/translate_addr_const.c
new file mode 100644
index 00000000000..84662933d49
--- /dev/null
+++ b/target/mips/translate_addr_const.c
@@ -0,0 +1,52 @@
+/*
+ * Address Computation and Large Constant Instructions
+ */
+#include "qemu/osdep.h"
+#include "tcg/tcg-op.h"
+#include "translate.h"
+
+bool gen_LSA(DisasContext *ctx, int rd, int rt, int rs, int sa)
+{
+    TCGv t0;
+    TCGv t1;
+
+    if (rd == 0) {
+        /* Treat as NOP. */
+        return true;
+    }
+    t0 = tcg_temp_new();
+    t1 = tcg_temp_new();
+    gen_load_gpr(t0, rs);
+    gen_load_gpr(t1, rt);
+    tcg_gen_shli_tl(t0, t0, sa + 1);
+    tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
+    tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
+
+    tcg_temp_free(t1);
+    tcg_temp_free(t0);
+
+    return true;
+}
+
+bool gen_DLSA(DisasContext *ctx, int rd, int rt, int rs, int sa)
+{
+    TCGv t0;
+    TCGv t1;
+
+    check_mips_64(ctx);
+
+    if (rd == 0) {
+        /* Treat as NOP. */
+        return true;
+    }
+    t0 = tcg_temp_new();
+    t1 = tcg_temp_new();
+    gen_load_gpr(t0, rs);
+    gen_load_gpr(t1, rt);
+    tcg_gen_shli_tl(t0, t0, sa + 1);
+    tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
+    tcg_temp_free(t1);
+    tcg_temp_free(t0);
+
+    return true;
+}
diff --git a/target/mips/meson.build b/target/mips/meson.build
index 5ccc9ddc6b8..dce0ca96527 100644
--- a/target/mips/meson.build
+++ b/target/mips/meson.build
@@ -16,6 +16,7 @@
   'mod-msa_helper.c',
   'tlb_helper.c',
   'translate.c',
+  'translate_addr_const.c',
   'mod-msa_translate.c',
 ))
 mips_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c'))
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PATCH v2 22/24] target/mips: Introduce decodetree helpers for MSA LSA/DLSA opcodes
  2020-12-15 22:57 [PATCH v2 00/24] target/mips: Convert MSA ASE to decodetree Philippe Mathieu-Daudé
                   ` (19 preceding siblings ...)
  2020-12-15 22:57 ` [PATCH v2 21/24] target/mips: Extract LSA/DLSA translation generators Philippe Mathieu-Daudé
@ 2020-12-15 22:57 ` Philippe Mathieu-Daudé
  2020-12-15 23:19   ` Richard Henderson
  2020-12-15 22:57 ` [PATCH v2 23/24] target/mips: Introduce decodetree helpers for Release6 " Philippe Mathieu-Daudé
                   ` (2 subsequent siblings)
  23 siblings, 1 reply; 48+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-12-15 22:57 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel
  Cc: kvm, Aleksandar Rikalo, Paolo Bonzini, Aurelien Jarno,
	Jiaxun Yang, Philippe Mathieu-Daudé,
	Huacai Chen

Add the LSA opcode to the MSA32 decodetree config, add DLSA
to a new config for the MSA64 ASE, and call decode_msa64()
in the main decode_opc() loop.

Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 target/mips/mod-msa32.decode    |  4 ++++
 target/mips/mod-msa64.decode    | 17 +++++++++++++++++
 target/mips/mod-msa_translate.c | 14 ++++++++++++++
 target/mips/meson.build         |  2 ++
 4 files changed, 37 insertions(+)
 create mode 100644 target/mips/mod-msa64.decode

diff --git a/target/mips/mod-msa32.decode b/target/mips/mod-msa32.decode
index d69675132b8..0b2f0863251 100644
--- a/target/mips/mod-msa32.decode
+++ b/target/mips/mod-msa32.decode
@@ -10,11 +10,15 @@
 #       (Document Number: MD00866-2B-MSA32-AFP-01.12)
 #
 
+&lsa                rd rt rs sa
 &msa_bz             df wt s16
 
+@lsa                ...... rs:5 rt:5 rd:5 ... sa:2 ......   &lsa
 @bz                 ...... ... ..   wt:5 s16:16             &msa_bz df=3
 @bz_df              ...... ... df:2 wt:5 s16:16             &msa_bz
 
+LSA                 000000 ..... ..... ..... 000 .. 000101  @lsa
+
 BZ_V                010001 01011  ..... ................    @bz
 BNZ_V               010001 01111  ..... ................    @bz
 
diff --git a/target/mips/mod-msa64.decode b/target/mips/mod-msa64.decode
new file mode 100644
index 00000000000..8dcbbcd8538
--- /dev/null
+++ b/target/mips/mod-msa64.decode
@@ -0,0 +1,17 @@
+# 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 MIPS64 SIMD Architecture Module, Revision 1.12
+#       (Document Number: MD00868-1D-MSA64-AFP-01.12)
+#
+
+&lsa                rd rt rs sa !extern
+
+@lsa                ...... rs:5 rt:5 rd:5 ... sa:2 ......   &lsa
+
+DLSA                 000000 ..... ..... ..... 000 .. 010101 @lsa
diff --git a/target/mips/mod-msa_translate.c b/target/mips/mod-msa_translate.c
index d1a8a95e62e..f139ba784dc 100644
--- a/target/mips/mod-msa_translate.c
+++ b/target/mips/mod-msa_translate.c
@@ -19,6 +19,7 @@
 
 /* Include the auto-generated decoder.  */
 #include "decode-mod-msa32.c.inc"
+#include "decode-mod-msa64.c.inc"
 
 #define OPC_MSA (0x1E << 26)
 
@@ -2268,7 +2269,20 @@ static bool trans_MSA(DisasContext *ctx, arg_MSA *a)
     return true;
 }
 
+static bool trans_LSA(DisasContext *ctx, arg_LSA *a)
+{
+    return gen_LSA(ctx, a->rd, a->rt, a->rs, a->sa);
+}
+
+static bool trans_DLSA(DisasContext *ctx, arg_LSA *a)
+{
+    return gen_DLSA(ctx, a->rd, a->rt, a->rs, a->sa);
+}
+
 bool decode_ase_msa(DisasContext *ctx, uint32_t insn)
 {
+    if (TARGET_LONG_BITS == 64 && decode_msa64(ctx, insn)) {
+        return true;
+    }
     return decode_msa32(ctx, insn);
 }
diff --git a/target/mips/meson.build b/target/mips/meson.build
index dce0ca96527..8e2e5fa40b8 100644
--- a/target/mips/meson.build
+++ b/target/mips/meson.build
@@ -1,5 +1,6 @@
 gen = [
   decodetree.process('mod-msa32.decode', extra_args: [ '--static-decode=decode_msa32' ]),
+  decodetree.process('mod-msa64.decode', extra_args: [ '--static-decode=decode_msa64' ]),
 ]
 
 mips_ss = ss.source_set()
@@ -19,6 +20,7 @@
   'translate_addr_const.c',
   'mod-msa_translate.c',
 ))
+
 mips_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c'))
 
 mips_softmmu_ss = ss.source_set()
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PATCH v2 23/24] target/mips: Introduce decodetree helpers for Release6 LSA/DLSA opcodes
  2020-12-15 22:57 [PATCH v2 00/24] target/mips: Convert MSA ASE to decodetree Philippe Mathieu-Daudé
                   ` (20 preceding siblings ...)
  2020-12-15 22:57 ` [PATCH v2 22/24] target/mips: Introduce decodetree helpers for MSA LSA/DLSA opcodes Philippe Mathieu-Daudé
@ 2020-12-15 22:57 ` Philippe Mathieu-Daudé
  2020-12-15 23:21   ` Richard Henderson
  2020-12-15 22:57 ` [RFC PATCH v2 24/24] target/mips/mod-msa: Pass TCGCond argument to gen_check_zero_element() Philippe Mathieu-Daudé
  2021-01-07 18:29 ` [PATCH v2 00/24] target/mips: Convert MSA ASE to decodetree Philippe Mathieu-Daudé
  23 siblings, 1 reply; 48+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-12-15 22:57 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel
  Cc: kvm, Aleksandar Rikalo, Paolo Bonzini, Aurelien Jarno,
	Jiaxun Yang, Philippe Mathieu-Daudé,
	Huacai Chen

LSA and LDSA opcodes are also available with MIPS release 6.
Introduce the decodetree config files and call the decode()
helpers in the main decode_opc() loop.

Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 target/mips/translate.h               |  1 +
 target/mips/isa-mips32r6.decode       | 17 ++++++++++++
 target/mips/isa-mips64r6.decode       | 17 ++++++++++++
 target/mips/isa-mips_rel6_translate.c | 37 +++++++++++++++++++++++++++
 target/mips/translate.c               |  5 ++++
 target/mips/meson.build               |  3 +++
 6 files changed, 80 insertions(+)
 create mode 100644 target/mips/isa-mips32r6.decode
 create mode 100644 target/mips/isa-mips64r6.decode
 create mode 100644 target/mips/isa-mips_rel6_translate.c

diff --git a/target/mips/translate.h b/target/mips/translate.h
index 47129de81d9..cbaef53b958 100644
--- a/target/mips/translate.h
+++ b/target/mips/translate.h
@@ -161,6 +161,7 @@ extern TCGv bcond;
 void msa_translate_init(void);
 
 /* decodetree generated */
+bool decode_isa_rel6(DisasContext *ctx, uint32_t insn);
 bool decode_ase_msa(DisasContext *ctx, uint32_t insn);
 
 #endif
diff --git a/target/mips/isa-mips32r6.decode b/target/mips/isa-mips32r6.decode
new file mode 100644
index 00000000000..027585ee042
--- /dev/null
+++ b/target/mips/isa-mips32r6.decode
@@ -0,0 +1,17 @@
+# MIPS32 Release 6 instruction set
+#
+# Copyright (C) 2020  Philippe Mathieu-Daudé
+#
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# Reference:
+#       MIPS Architecture for Programmers Volume II-A
+#       The MIPS32 Instruction Set Reference Manual, Revision 6.06
+#       (Document Number: MD00086-2B-MIPS32BIS-AFP-06.06)
+#
+
+&lsa                rd rt rs sa
+
+@lsa                ...... rs:5 rt:5 rd:5 ... sa:2 ......   &lsa
+
+LSA                 000000 ..... ..... ..... 000 .. 000101  @lsa
diff --git a/target/mips/isa-mips64r6.decode b/target/mips/isa-mips64r6.decode
new file mode 100644
index 00000000000..e812224341e
--- /dev/null
+++ b/target/mips/isa-mips64r6.decode
@@ -0,0 +1,17 @@
+# MIPS64 Release 6 instruction set
+#
+# Copyright (C) 2020  Philippe Mathieu-Daudé
+#
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# Reference:
+#       MIPS Architecture for Programmers Volume II-A
+#       The MIPS64 Instruction Set Reference Manual, Revision 6.06
+#       (Document Number: MD00087-2B-MIPS64BIS-AFP-6.06)
+#
+
+&lsa                rd rt rs sa !extern
+
+@lsa                ...... rs:5 rt:5 rd:5 ... sa:2 ......   &lsa
+
+DLSA                000000 ..... ..... ..... 000 .. 010101  @lsa
diff --git a/target/mips/isa-mips_rel6_translate.c b/target/mips/isa-mips_rel6_translate.c
new file mode 100644
index 00000000000..d5872bbf8fc
--- /dev/null
+++ b/target/mips/isa-mips_rel6_translate.c
@@ -0,0 +1,37 @@
+/*
+ *  MIPS emulation for QEMU - # Release 6 translation routines
+ *
+ *  Copyright (c) 2004-2005 Jocelyn Mayer
+ *  Copyright (c) 2006 Marius Groeger (FPU operations)
+ *  Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
+ *  Copyright (c) 2020 Philippe Mathieu-Daudé
+ *
+ * This code is licensed under the GNU GPLv2 and later.
+ */
+
+#include "qemu/osdep.h"
+#include "tcg/tcg-op.h"
+#include "exec/helper-gen.h"
+#include "translate.h"
+
+/* Include the auto-generated decoder.  */
+#include "decode-isa-mips32r6.c.inc"
+#include "decode-isa-mips64r6.c.inc"
+
+static bool trans_LSA(DisasContext *ctx, arg_LSA *a)
+{
+    return gen_LSA(ctx, a->rd, a->rt, a->rs, a->sa);
+}
+
+static bool trans_DLSA(DisasContext *ctx, arg_LSA *a)
+{
+    return gen_DLSA(ctx, a->rd, a->rt, a->rs, a->sa);
+}
+
+bool decode_isa_rel6(DisasContext *ctx, uint32_t insn)
+{
+    if (TARGET_LONG_BITS == 64 && decode_mips64r6(ctx, insn)) {
+        return true;
+    }
+    return decode_mips32r6(ctx, insn);
+}
diff --git a/target/mips/translate.c b/target/mips/translate.c
index e0439ba92d8..125b2aac848 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -29027,6 +29027,11 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
         return;
     }
 
+    /* ISA */
+    if (isa_rel6_available(env) && decode_isa_rel6(ctx, ctx->opcode)) {
+        return;
+    }
+
     if (!decode_opc_legacy(env, ctx)) {
         gen_reserved_instruction(ctx);
     }
diff --git a/target/mips/meson.build b/target/mips/meson.build
index 8e2e5fa40b8..2d62288d604 100644
--- a/target/mips/meson.build
+++ b/target/mips/meson.build
@@ -1,4 +1,6 @@
 gen = [
+  decodetree.process('isa-mips32r6.decode', extra_args: [ '--static-decode=decode_mips32r6' ]),
+  decodetree.process('isa-mips64r6.decode', extra_args: [ '--static-decode=decode_mips64r6' ]),
   decodetree.process('mod-msa32.decode', extra_args: [ '--static-decode=decode_msa32' ]),
   decodetree.process('mod-msa64.decode', extra_args: [ '--static-decode=decode_msa64' ]),
 ]
@@ -12,6 +14,7 @@
 mips_ss.add(when: 'CONFIG_TCG', if_true: files(
   'dsp_helper.c',
   'fpu_helper.c',
+  'isa-mips_rel6_translate.c',
   'lmmi_helper.c',
   'op_helper.c',
   'mod-msa_helper.c',
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [RFC PATCH v2 24/24] target/mips/mod-msa: Pass TCGCond argument to gen_check_zero_element()
  2020-12-15 22:57 [PATCH v2 00/24] target/mips: Convert MSA ASE to decodetree Philippe Mathieu-Daudé
                   ` (21 preceding siblings ...)
  2020-12-15 22:57 ` [PATCH v2 23/24] target/mips: Introduce decodetree helpers for Release6 " Philippe Mathieu-Daudé
@ 2020-12-15 22:57 ` Philippe Mathieu-Daudé
  2020-12-15 23:22   ` Richard Henderson
  2021-01-07 18:29 ` [PATCH v2 00/24] target/mips: Convert MSA ASE to decodetree Philippe Mathieu-Daudé
  23 siblings, 1 reply; 48+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-12-15 22:57 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel
  Cc: kvm, Aleksandar Rikalo, Paolo Bonzini, Aurelien Jarno,
	Jiaxun Yang, Philippe Mathieu-Daudé,
	Huacai Chen

Simplify gen_check_zero_element() by passing the TCGCond
argument along.

Suggested-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
Maybe this can be named 'msa_translate.c' after all...
---
 target/mips/mod-msa_translate.c | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/target/mips/mod-msa_translate.c b/target/mips/mod-msa_translate.c
index f139ba784dc..7ad14b19b0c 100644
--- a/target/mips/mod-msa_translate.c
+++ b/target/mips/mod-msa_translate.c
@@ -309,7 +309,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 */
@@ -344,7 +345,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);
@@ -393,10 +394,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;
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* Re: [PATCH v2 14/24] target/mips: Move msa_reset() to mod-msa_helper.c
  2020-12-15 22:57 ` [PATCH v2 14/24] target/mips: Move msa_reset() to mod-msa_helper.c Philippe Mathieu-Daudé
@ 2020-12-15 23:09   ` Richard Henderson
  0 siblings, 0 replies; 48+ messages in thread
From: Richard Henderson @ 2020-12-15 23:09 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé, qemu-devel
  Cc: kvm, Aleksandar Rikalo, Paolo Bonzini, Aurelien Jarno,
	Jiaxun Yang, Huacai Chen

On 12/15/20 4:57 PM, Philippe Mathieu-Daudé wrote:
> 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é <f4bug@amsat.org>
> ---
>  target/mips/internal.h       |  2 ++
>  target/mips/cpu.c            |  1 +
>  target/mips/mod-msa_helper.c | 36 ++++++++++++++++++++++++++++++++++++
>  target/mips/cpu-defs.c.inc   | 36 ------------------------------------
>  4 files changed, 39 insertions(+), 36 deletions(-)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>

r~

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v2 17/24] target/mips: Declare gen_msa/_branch() in 'translate.h'
  2020-12-15 22:57 ` [PATCH v2 17/24] target/mips: Declare gen_msa/_branch() in 'translate.h' Philippe Mathieu-Daudé
@ 2020-12-15 23:10   ` Richard Henderson
  0 siblings, 0 replies; 48+ messages in thread
From: Richard Henderson @ 2020-12-15 23:10 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé, qemu-devel
  Cc: kvm, Aleksandar Rikalo, Paolo Bonzini, Aurelien Jarno,
	Jiaxun Yang, Huacai Chen

On 12/15/20 4:57 PM, Philippe Mathieu-Daudé wrote:
> 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é <f4bug@amsat.org>
> ---
>  target/mips/translate.h | 2 ++
>  target/mips/translate.c | 4 ++--
>  2 files changed, 4 insertions(+), 2 deletions(-)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>

r~

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v2 19/24] target/mips: Introduce decode tree bindings for MSA opcodes
  2020-12-15 22:57 ` [PATCH v2 19/24] target/mips: Introduce decode tree bindings for MSA opcodes Philippe Mathieu-Daudé
@ 2020-12-15 23:11   ` Richard Henderson
  0 siblings, 0 replies; 48+ messages in thread
From: Richard Henderson @ 2020-12-15 23:11 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé, qemu-devel
  Cc: kvm, Aleksandar Rikalo, Paolo Bonzini, Aurelien Jarno,
	Jiaxun Yang, Huacai Chen

On 12/15/20 4:57 PM, Philippe Mathieu-Daudé wrote:
> Introduce the 'mod-msa32' decodetree config for the 32-bit MSA ASE.
> 
> We decode the branch instructions, and all instructions based
> on the MSA opcode.
> 
> Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> ---
>  target/mips/translate.h         |  3 +++
>  target/mips/mod-msa32.decode    | 24 +++++++++++++++++++++
>  target/mips/mod-msa_translate.c | 37 ++++++++++++++++++++++++++++++++-
>  target/mips/translate.c         |  1 -
>  target/mips/meson.build         |  5 +++++
>  5 files changed, 68 insertions(+), 2 deletions(-)
>  create mode 100644 target/mips/mod-msa32.decode

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>

r~

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v2 20/24] target/mips: Use decode_ase_msa() generated from decodetree
  2020-12-15 22:57 ` [PATCH v2 20/24] target/mips: Use decode_ase_msa() generated from decodetree Philippe Mathieu-Daudé
@ 2020-12-15 23:15   ` Richard Henderson
  0 siblings, 0 replies; 48+ messages in thread
From: Richard Henderson @ 2020-12-15 23:15 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé, qemu-devel
  Cc: kvm, Aleksandar Rikalo, Paolo Bonzini, Aurelien Jarno,
	Jiaxun Yang, Huacai Chen

On 12/15/20 4:57 PM, Philippe Mathieu-Daudé wrote:
> Now that we can decode the MSA ASE opcodes with decode_msa32(),
> use it and remove the unreachable code.
> 
> Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> ---
>  target/mips/translate.h         | 12 ------------
>  target/mips/mod-msa_translate.c | 29 +----------------------------
>  target/mips/translate.c         | 31 ++++++++++---------------------
>  3 files changed, 11 insertions(+), 61 deletions(-)

Need an update to the comment after function name change?

Otherwise,
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>

r~

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v2 21/24] target/mips: Extract LSA/DLSA translation generators
  2020-12-15 22:57 ` [PATCH v2 21/24] target/mips: Extract LSA/DLSA translation generators Philippe Mathieu-Daudé
@ 2020-12-15 23:17   ` Richard Henderson
  0 siblings, 0 replies; 48+ messages in thread
From: Richard Henderson @ 2020-12-15 23:17 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé, qemu-devel
  Cc: kvm, Aleksandar Rikalo, Paolo Bonzini, Aurelien Jarno,
	Jiaxun Yang, Huacai Chen

On 12/15/20 4:57 PM, Philippe Mathieu-Daudé wrote:
> Extract gen_lsa() from translate.c and explode it as
> gen_LSA() and gen_DLSA().
> 
> Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> ---
>  target/mips/translate.h            |  6 ++++
>  target/mips/translate.c            | 35 +++-----------------
>  target/mips/translate_addr_const.c | 52 ++++++++++++++++++++++++++++++
>  target/mips/meson.build            |  1 +
>  4 files changed, 63 insertions(+), 31 deletions(-)
>  create mode 100644 target/mips/translate_addr_const.c

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>

r~

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v2 22/24] target/mips: Introduce decodetree helpers for MSA LSA/DLSA opcodes
  2020-12-15 22:57 ` [PATCH v2 22/24] target/mips: Introduce decodetree helpers for MSA LSA/DLSA opcodes Philippe Mathieu-Daudé
@ 2020-12-15 23:19   ` Richard Henderson
  0 siblings, 0 replies; 48+ messages in thread
From: Richard Henderson @ 2020-12-15 23:19 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé, qemu-devel
  Cc: kvm, Aleksandar Rikalo, Paolo Bonzini, Aurelien Jarno,
	Jiaxun Yang, Huacai Chen

On 12/15/20 4:57 PM, Philippe Mathieu-Daudé wrote:
> Add the LSA opcode to the MSA32 decodetree config, add DLSA
> to a new config for the MSA64 ASE, and call decode_msa64()
> in the main decode_opc() loop.
> 
> Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> ---
>  target/mips/mod-msa32.decode    |  4 ++++
>  target/mips/mod-msa64.decode    | 17 +++++++++++++++++
>  target/mips/mod-msa_translate.c | 14 ++++++++++++++
>  target/mips/meson.build         |  2 ++
>  4 files changed, 37 insertions(+)
>  create mode 100644 target/mips/mod-msa64.decode

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>

r~

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v2 23/24] target/mips: Introduce decodetree helpers for Release6 LSA/DLSA opcodes
  2020-12-15 22:57 ` [PATCH v2 23/24] target/mips: Introduce decodetree helpers for Release6 " Philippe Mathieu-Daudé
@ 2020-12-15 23:21   ` Richard Henderson
  0 siblings, 0 replies; 48+ messages in thread
From: Richard Henderson @ 2020-12-15 23:21 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé, qemu-devel
  Cc: kvm, Aleksandar Rikalo, Paolo Bonzini, Aurelien Jarno,
	Jiaxun Yang, Huacai Chen

On 12/15/20 4:57 PM, Philippe Mathieu-Daudé wrote:
> LSA and LDSA opcodes are also available with MIPS release 6.
> Introduce the decodetree config files and call the decode()
> helpers in the main decode_opc() loop.
> 
> Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> ---
>  target/mips/translate.h               |  1 +
>  target/mips/isa-mips32r6.decode       | 17 ++++++++++++
>  target/mips/isa-mips64r6.decode       | 17 ++++++++++++
>  target/mips/isa-mips_rel6_translate.c | 37 +++++++++++++++++++++++++++
>  target/mips/translate.c               |  5 ++++
>  target/mips/meson.build               |  3 +++
>  6 files changed, 80 insertions(+)
>  create mode 100644 target/mips/isa-mips32r6.decode
>  create mode 100644 target/mips/isa-mips64r6.decode
>  create mode 100644 target/mips/isa-mips_rel6_translate.c

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>

r~

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [RFC PATCH v2 24/24] target/mips/mod-msa: Pass TCGCond argument to gen_check_zero_element()
  2020-12-15 22:57 ` [RFC PATCH v2 24/24] target/mips/mod-msa: Pass TCGCond argument to gen_check_zero_element() Philippe Mathieu-Daudé
@ 2020-12-15 23:22   ` Richard Henderson
  0 siblings, 0 replies; 48+ messages in thread
From: Richard Henderson @ 2020-12-15 23:22 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé, qemu-devel
  Cc: kvm, Aleksandar Rikalo, Paolo Bonzini, Aurelien Jarno,
	Jiaxun Yang, Huacai Chen

On 12/15/20 4:57 PM, Philippe Mathieu-Daudé wrote:
> Simplify gen_check_zero_element() by passing the TCGCond
> argument along.
> 
> Suggested-by: Richard Henderson <richard.henderson@linaro.org>
> Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> ---
> Maybe this can be named 'msa_translate.c' after all...
> ---
>  target/mips/mod-msa_translate.c | 10 ++++------
>  1 file changed, 4 insertions(+), 6 deletions(-)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>

r~

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v2 01/24] target/mips/translate: Extract decode_opc_legacy() from decode_opc()
  2020-12-15 22:57 ` [PATCH v2 01/24] target/mips/translate: Extract decode_opc_legacy() from decode_opc() Philippe Mathieu-Daudé
@ 2020-12-15 23:23   ` Richard Henderson
  0 siblings, 0 replies; 48+ messages in thread
From: Richard Henderson @ 2020-12-15 23:23 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé, qemu-devel
  Cc: kvm, Aleksandar Rikalo, Paolo Bonzini, Aurelien Jarno,
	Jiaxun Yang, Huacai Chen

On 12/15/20 4:57 PM, Philippe Mathieu-Daudé wrote:
> 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é <f4bug@amsat.org>
> ---
>  target/mips/translate.c | 45 ++++++++++++++++++++++++-----------------
>  1 file changed, 26 insertions(+), 19 deletions(-)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>

r~

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v2 03/24] target/mips/cpu: Introduce isa_rel6_available() helper
  2020-12-15 22:57 ` [PATCH v2 03/24] target/mips/cpu: Introduce isa_rel6_available() helper Philippe Mathieu-Daudé
@ 2020-12-15 23:27   ` Richard Henderson
  2020-12-15 23:48     ` Philippe Mathieu-Daudé
  0 siblings, 1 reply; 48+ messages in thread
From: Richard Henderson @ 2020-12-15 23:27 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé, qemu-devel
  Cc: kvm, Aleksandar Rikalo, Paolo Bonzini, Aurelien Jarno,
	Jiaxun Yang, Huacai Chen

On 12/15/20 4:57 PM, Philippe Mathieu-Daudé wrote:
> +bool isa_rel6_available(const CPUMIPSState *env)
> +{
> +    if (TARGET_LONG_BITS == 64) {
> +        return cpu_supports_isa(env, ISA_MIPS64R6);
> +    }
> +    return cpu_supports_isa(env, ISA_MIPS32R6);
> +}

So... does qemu-system-mips64 support 32-bit cpus?

If so, this needs to be written

  if (TARGET_LONG_BITS == 64 && cpu_supports_isa(...)) {
    return true;
  }

Otherwise, this will return false for a mips32r6 cpu.


r~

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v2 03/24] target/mips/cpu: Introduce isa_rel6_available() helper
  2020-12-15 23:27   ` Richard Henderson
@ 2020-12-15 23:48     ` Philippe Mathieu-Daudé
  2020-12-16  2:50       ` Jiaxun Yang
  2020-12-16 10:55       ` Philippe Mathieu-Daudé
  0 siblings, 2 replies; 48+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-12-15 23:48 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel, Aurelien Jarno
  Cc: Aleksandar Rikalo, kvm, Huacai Chen, Jiaxun Yang, Paolo Bonzini

On 12/16/20 12:27 AM, Richard Henderson wrote:
> On 12/15/20 4:57 PM, Philippe Mathieu-Daudé wrote:
>> +bool isa_rel6_available(const CPUMIPSState *env)
>> +{
>> +    if (TARGET_LONG_BITS == 64) {
>> +        return cpu_supports_isa(env, ISA_MIPS64R6);
>> +    }
>> +    return cpu_supports_isa(env, ISA_MIPS32R6);
>> +}
> 
> So... does qemu-system-mips64 support 32-bit cpus?

Well... TBH I never tested it :S It looks the TCG code
is compiled with 64-bit TL registers, the machine address
space is 64-bit regardless the CPU, and I see various
#ifdef MIPS64 code that look dubious with 32-bit CPU.

> 
> If so, this needs to be written
> 
>   if (TARGET_LONG_BITS == 64 && cpu_supports_isa(...)) {
>     return true;
>   }
> 
> Otherwise, this will return false for a mips32r6 cpu.

I see. Rel6 is new to me, so I'll have to look at the ISA
manuals before returning to this thread with an answer.

Thanks for reviewing the series!

Phil.

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v2 03/24] target/mips/cpu: Introduce isa_rel6_available() helper
  2020-12-15 23:48     ` Philippe Mathieu-Daudé
@ 2020-12-16  2:50       ` Jiaxun Yang
  2020-12-16  3:14         ` Jiaxun Yang
  2020-12-16 10:55       ` Philippe Mathieu-Daudé
  1 sibling, 1 reply; 48+ messages in thread
From: Jiaxun Yang @ 2020-12-16  2:50 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé,
	Richard Henderson, qemu-devel, Aurelien Jarno
  Cc: Aleksandar Rikalo, kvm, Huacai Chen, Paolo Bonzini



在 2020/12/16 上午7:48, Philippe Mathieu-Daudé 写道:
> On 12/16/20 12:27 AM, Richard Henderson wrote:
>> On 12/15/20 4:57 PM, Philippe Mathieu-Daudé wrote:
>>> +bool isa_rel6_available(const CPUMIPSState *env)
>>> +{
>>> +    if (TARGET_LONG_BITS == 64) {
>>> +        return cpu_supports_isa(env, ISA_MIPS64R6);
>>> +    }
>>> +    return cpu_supports_isa(env, ISA_MIPS32R6);
>>> +}
>> So... does qemu-system-mips64 support 32-bit cpus?
> Well... TBH I never tested it :S It looks the TCG code
> is compiled with 64-bit TL registers, the machine address
> space is 64-bit regardless the CPU, and I see various
> #ifdef MIPS64 code that look dubious with 32-bit CPU.
qemu-system-mips64 and qemu-system-mips64el do support 32bit
CPUs like M14Kc and P5600 :-)
Sometimes I'm just curious about the necessity of having mips/mipsel 
targets
>> If so, this needs to be written
>>
>>    if (TARGET_LONG_BITS == 64 && cpu_supports_isa(...)) {
>>      return true;
>>    }
>>
>> Otherwise, this will return false for a mips32r6 cpu.
> I see. Rel6 is new to me, so I'll have to look at the ISA
> manuals before returning to this thread with an answer.

TBH I do think it doesn't sounds like a good idea to make 32-bit
and 64-bit different. In fact ISA_MIPS32R6 is always set for targets
with ISA_MIPS64R6.

We're treating MIPS64R6 as a superset of MIPS32R6, and ISA_MIPS3
is used to tell if a CPU supports 64-bit.

FYI: https://commons.wikimedia.org/wiki/File:MIPS_instruction_set_family.svg

Thanks.

- Jiaxun


>
> Thanks for reviewing the series!
>
> Phil.

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v2 03/24] target/mips/cpu: Introduce isa_rel6_available() helper
  2020-12-16  2:50       ` Jiaxun Yang
@ 2020-12-16  3:14         ` Jiaxun Yang
  2020-12-16 10:50           ` Philippe Mathieu-Daudé
  2021-01-07  9:04           ` Philippe Mathieu-Daudé
  0 siblings, 2 replies; 48+ messages in thread
From: Jiaxun Yang @ 2020-12-16  3:14 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé,
	Richard Henderson, qemu-devel, Aurelien Jarno
  Cc: Aleksandar Rikalo, kvm, Huacai Chen, Paolo Bonzini



在 2020/12/16 上午10:50, Jiaxun Yang 写道:
>
>
> TBH I do think it doesn't sounds like a good idea to make 32-bit
> and 64-bit different. In fact ISA_MIPS32R6 is always set for targets
> with ISA_MIPS64R6.
>
> We're treating MIPS64R6 as a superset of MIPS32R6, and ISA_MIPS3
> is used to tell if a CPU supports 64-bit.
>
> FYI: 
> https://commons.wikimedia.org/wiki/File:MIPS_instruction_set_family.svg

Just add more cents here...
The current method we handle R6 makes me a little bit annoying.

Given that MIPS is backward compatible until R5, and R6 reorganized a lot
of opcodes, I do think decoding procdure of R6 should be dedicated from 
the rest,
otherwise we may fall into the hell of finding difference between R6 and 
previous
ISAs, also I've heard some R6 only ASEs is occupying opcodes marked as
"removed in R6", so it doesn't looks like a wise idea to check removed in R6
in helpers.

So we may end up having four series of decodetrees for ISA
Series1: MIPS-II, MIPS32, MIPS32R2, MIPS32R5 (32bit "old" ISAs)
Series2: MIPS-III, MIPS64, MIPS64R2, MIPS64R5 (64bit "old" ISAs)

Series3: MIPS32R6 (32bit "new" ISAs)
Series4: MIPS64R6 (64bit "new" ISAs)

Thanks

- Jiaxun
>
> Thanks.
>
> - Jiaxun
>
>
>>
>> Thanks for reviewing the series!
>>
>> Phil.
>

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v2 03/24] target/mips/cpu: Introduce isa_rel6_available() helper
  2020-12-16  3:14         ` Jiaxun Yang
@ 2020-12-16 10:50           ` Philippe Mathieu-Daudé
  2020-12-16 10:59             ` Philippe Mathieu-Daudé
  2021-01-07  9:04           ` Philippe Mathieu-Daudé
  1 sibling, 1 reply; 48+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-12-16 10:50 UTC (permalink / raw)
  To: Jiaxun Yang, Richard Henderson, qemu-devel, Aurelien Jarno
  Cc: Paolo Bonzini, Aleksandar Rikalo, Huacai Chen, kvm

On 12/16/20 4:14 AM, Jiaxun Yang wrote:
> 在 2020/12/16 上午10:50, Jiaxun Yang 写道:
>>
>>
>> TBH I do think it doesn't sounds like a good idea to make 32-bit
>> and 64-bit different. In fact ISA_MIPS32R6 is always set for targets
>> with ISA_MIPS64R6.
>>
>> We're treating MIPS64R6 as a superset of MIPS32R6, and ISA_MIPS3
>> is used to tell if a CPU supports 64-bit.

Which is why I don't understand why they are 2 ISA_MIPS32R6/ISA_MIPS64R6
definitions.

>>
>> FYI:
>> https://commons.wikimedia.org/wiki/File:MIPS_instruction_set_family.svg
> 
> Just add more cents here...
> The current method we handle R6 makes me a little bit annoying.
> 
> Given that MIPS is backward compatible until R5, and R6 reorganized a lot
> of opcodes, I do think decoding procdure of R6 should be dedicated from
> the rest,
> otherwise we may fall into the hell of finding difference between R6 and
> previous
> ISAs, also I've heard some R6 only ASEs is occupying opcodes marked as
> "removed in R6", so it doesn't looks like a wise idea to check removed
> in R6
> in helpers.

I'm not sure I understood well your comment, but I also find how
R6 is handled messy...

I'm doing this removal (from helper to decoder) with the decodetree
conversion.

> So we may end up having four series of decodetrees for ISA
> Series1: MIPS-II, MIPS32, MIPS32R2, MIPS32R5 (32bit "old" ISAs)
> Series2: MIPS-III, MIPS64, MIPS64R2, MIPS64R5 (64bit "old" ISAs)
> 
> Series3: MIPS32R6 (32bit "new" ISAs)
> Series4: MIPS64R6 (64bit "new" ISAs)

Something like that, I'm starting by converting the messier leaves
first, so the R6 and ASEs. My approach is from your "series4" to
"series1" last.

Regards,

Phil.

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v2 03/24] target/mips/cpu: Introduce isa_rel6_available() helper
  2020-12-15 23:48     ` Philippe Mathieu-Daudé
  2020-12-16  2:50       ` Jiaxun Yang
@ 2020-12-16 10:55       ` Philippe Mathieu-Daudé
  1 sibling, 0 replies; 48+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-12-16 10:55 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel, Aurelien Jarno
  Cc: Paolo Bonzini, Aleksandar Rikalo, Huacai Chen, Jiaxun Yang, kvm

On 12/16/20 12:48 AM, Philippe Mathieu-Daudé wrote:
> On 12/16/20 12:27 AM, Richard Henderson wrote:
>> On 12/15/20 4:57 PM, Philippe Mathieu-Daudé wrote:
>>> +bool isa_rel6_available(const CPUMIPSState *env)
>>> +{
>>> +    if (TARGET_LONG_BITS == 64) {
>>> +        return cpu_supports_isa(env, ISA_MIPS64R6);
>>> +    }
>>> +    return cpu_supports_isa(env, ISA_MIPS32R6);
>>> +}
>>
>> So... does qemu-system-mips64 support 32-bit cpus?
> 
> Well... TBH I never tested it :S It looks the TCG code
> is compiled with 64-bit TL registers, the machine address
> space is 64-bit regardless the CPU, and I see various
> #ifdef MIPS64 code that look dubious with 32-bit CPU.

I don't think 32-bit CPUs on 64-bit build currently work
well, see:

382     env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
383 # ifdef TARGET_MIPS64
384     /* Enable 64-bit register mode.  */
385     env->CP0_Status |= (1 << CP0St_PX);
386 # endif
387 # ifdef TARGET_ABI_MIPSN64
388     /* Enable 64-bit address mode.  */
389     env->CP0_Status |= (1 << CP0St_UX);
390 # endif
391     /*
392      * Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
393      * hardware registers.
394      */
395     env->CP0_HWREna |= 0x0000000F;
396     if (env->CP0_Config1 & (1 << CP0C1_FP)) {
397         env->CP0_Status |= (1 << CP0St_CU1);
398     }
399     if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
400         env->CP0_Status |= (1 << CP0St_MX);
401     }
402 # if defined(TARGET_MIPS64)
403     /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is
writable. */
404     if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
405         (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
406         env->CP0_Status |= (1 << CP0St_FR);
407     }
408 # endif

Or:

1018 void helper_mtc0_pwsize(CPUMIPSState *env, target_ulong arg1)
1019 {
1020 #if defined(TARGET_MIPS64)
1021     env->CP0_PWSize = arg1 & 0x3F7FFFFFFFULL;
1022 #else
1023     env->CP0_PWSize = arg1 & 0x3FFFFFFF;
1024 #endif
1025 }

1038 void helper_mtc0_pwctl(CPUMIPSState *env, target_ulong arg1)
1039 {
1040 #if defined(TARGET_MIPS64)
1041     /* PWEn = 0. Hardware page table walking is not implemented. */
1042     env->CP0_PWCtl = (env->CP0_PWCtl & 0x000000C0) | (arg1 &
0x5C00003F);
1043 #else
1044     env->CP0_PWCtl = (arg1 & 0x800000FF);
1045 #endif
1046 }

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v2 03/24] target/mips/cpu: Introduce isa_rel6_available() helper
  2020-12-16 10:50           ` Philippe Mathieu-Daudé
@ 2020-12-16 10:59             ` Philippe Mathieu-Daudé
  2020-12-16 11:30               ` Jiaxun Yang
  2020-12-16 11:36               ` Jiaxun Yang
  0 siblings, 2 replies; 48+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-12-16 10:59 UTC (permalink / raw)
  To: Jiaxun Yang, Richard Henderson, qemu-devel, Aurelien Jarno
  Cc: Paolo Bonzini, Aleksandar Rikalo, Huacai Chen, kvm

On 12/16/20 11:50 AM, Philippe Mathieu-Daudé wrote:
> On 12/16/20 4:14 AM, Jiaxun Yang wrote:
>> 在 2020/12/16 上午10:50, Jiaxun Yang 写道:
>>>
>>>
>>> TBH I do think it doesn't sounds like a good idea to make 32-bit
>>> and 64-bit different. In fact ISA_MIPS32R6 is always set for targets
>>> with ISA_MIPS64R6.
>>>
>>> We're treating MIPS64R6 as a superset of MIPS32R6, and ISA_MIPS3
>>> is used to tell if a CPU supports 64-bit.

I suppose you are talking about the CPU definitions
(CPU_MIPS32R6/CPU_MIPS64R6).

> 
> Which is why I don't understand why they are 2 ISA_MIPS32R6/ISA_MIPS64R6
> definitions.

My comment is about the ISA definitions:

#define ISA_MIPS32        0x0000000000000020ULL
#define ISA_MIPS32R2      0x0000000000000040ULL
#define ISA_MIPS64        0x0000000000000080ULL
#define ISA_MIPS64R2      0x0000000000000100ULL
#define ISA_MIPS32R3      0x0000000000000200ULL
#define ISA_MIPS64R3      0x0000000000000400ULL
#define ISA_MIPS32R5      0x0000000000000800ULL
#define ISA_MIPS64R5      0x0000000000001000ULL
#define ISA_MIPS32R6      0x0000000000002000ULL
#define ISA_MIPS64R6      0x0000000000004000ULL

> 
>>>
>>> FYI:
>>> https://commons.wikimedia.org/wiki/File:MIPS_instruction_set_family.svg
>>
>> Just add more cents here...
>> The current method we handle R6 makes me a little bit annoying.
>>
>> Given that MIPS is backward compatible until R5, and R6 reorganized a lot
>> of opcodes, I do think decoding procdure of R6 should be dedicated from
>> the rest,
>> otherwise we may fall into the hell of finding difference between R6 and
>> previous
>> ISAs, also I've heard some R6 only ASEs is occupying opcodes marked as
>> "removed in R6", so it doesn't looks like a wise idea to check removed
>> in R6
>> in helpers.
> 
> I'm not sure I understood well your comment, but I also find how
> R6 is handled messy...
> 
> I'm doing this removal (from helper to decoder) with the decodetree
> conversion.
> 
>> So we may end up having four series of decodetrees for ISA
>> Series1: MIPS-II, MIPS32, MIPS32R2, MIPS32R5 (32bit "old" ISAs)
>> Series2: MIPS-III, MIPS64, MIPS64R2, MIPS64R5 (64bit "old" ISAs)
>>
>> Series3: MIPS32R6 (32bit "new" ISAs)
>> Series4: MIPS64R6 (64bit "new" ISAs)
> 
> Something like that, I'm starting by converting the messier leaves
> first, so the R6 and ASEs. My approach is from your "series4" to
> "series1" last.
> 
> Regards,
> 
> Phil.
> 

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v2 03/24] target/mips/cpu: Introduce isa_rel6_available() helper
  2020-12-16 10:59             ` Philippe Mathieu-Daudé
@ 2020-12-16 11:30               ` Jiaxun Yang
  2020-12-16 11:36               ` Jiaxun Yang
  1 sibling, 0 replies; 48+ messages in thread
From: Jiaxun Yang @ 2020-12-16 11:30 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé,
	Richard Henderson, qemu-devel, Aurelien Jarno
  Cc: Paolo Bonzini, Aleksandar Rikalo, Huacai Chen, kvm



在 2020/12/16 下午6:59, Philippe Mathieu-Daudé 写道:
> On 12/16/20 11:50 AM, Philippe Mathieu-Daudé wrote:
>> On 12/16/20 4:14 AM, Jiaxun Yang wrote:
>>> 在 2020/12/16 上午10:50, Jiaxun Yang 写道:
>>>>
>>>> TBH I do think it doesn't sounds like a good idea to make 32-bit
>>>> and 64-bit different. In fact ISA_MIPS32R6 is always set for targets
>>>> with ISA_MIPS64R6.
>>>>
>>>> We're treating MIPS64R6 as a superset of MIPS32R6, and ISA_MIPS3
>>>> is used to tell if a CPU supports 64-bit.
> I suppose you are talking about the CPU definitions
> (CPU_MIPS32R6/CPU_MIPS64R6).
>
>> Which is why I don't understand why they are 2 ISA_MIPS32R6/ISA_MIPS64R6
>> definitions.
> My comment is about the ISA definitions:
>
> #define ISA_MIPS32        0x0000000000000020ULL
> #define ISA_MIPS32R2      0x0000000000000040ULL
> #define ISA_MIPS64        0x0000000000000080ULL
> #define ISA_MIPS64R2      0x0000000000000100ULL
> #define ISA_MIPS32R3      0x0000000000000200ULL
> #define ISA_MIPS64R3      0x0000000000000400ULL
> #define ISA_MIPS32R5      0x0000000000000800ULL
> #define ISA_MIPS64R5      0x0000000000001000ULL
> #define ISA_MIPS32R6      0x0000000000002000ULL
> #define ISA_MIPS64R6      0x0000000000004000ULL

Yes, as insn_flags is set by CPU definitions.

......
/* MIPS Technologies "Release 1" */
#define CPU_MIPS32      (CPU_MIPS2 | ISA_MIPS32)
#define CPU_MIPS64      (CPU_MIPS5 | CPU_MIPS32 | ISA_MIPS64)

/* MIPS Technologies "Release 2" */
#define CPU_MIPS32R2    (CPU_MIPS32 | ISA_MIPS32R2)
#define CPU_MIPS64R2    (CPU_MIPS64 | CPU_MIPS32R2 | ISA_MIPS64R2)
......

As you can see when you're set insn_flags to CPU_MIPS64R2 the ISA flags
for ISA_MIPS64R2 ISA_MIPS32R2 ISA_MIPS32 ISA_MIPS64 ISA_MIPS5
ISA_MIPS3 ISA_MIPS2 ISA_MIPS1 all get set as well.


>>> So we may end up having four series of decodetrees for ISA
>>> Series1: MIPS-II, MIPS32, MIPS32R2, MIPS32R5 (32bit "old" ISAs)
>>> Series2: MIPS-III, MIPS64, MIPS64R2, MIPS64R5 (64bit "old" ISAs)
>>>
>>> Series3: MIPS32R6 (32bit "new" ISAs)
>>> Series4: MIPS64R6 (64bit "new" ISAs)
>> Something like that, I'm starting by converting the messier leaves
>> first, so the R6 and ASEs. My approach is from your "series4" to
>> "series1" last.

Sounds neat!

Thanks

- Jiaxun


^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v2 03/24] target/mips/cpu: Introduce isa_rel6_available() helper
  2020-12-16 10:59             ` Philippe Mathieu-Daudé
  2020-12-16 11:30               ` Jiaxun Yang
@ 2020-12-16 11:36               ` Jiaxun Yang
  1 sibling, 0 replies; 48+ messages in thread
From: Jiaxun Yang @ 2020-12-16 11:36 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé,
	Richard Henderson, qemu-devel, Aurelien Jarno
  Cc: Paolo Bonzini, Aleksandar Rikalo, Huacai Chen, kvm



在 2020/12/16 下午6:59, Philippe Mathieu-Daudé 写道:
> On 12/16/20 11:50 AM, Philippe Mathieu-Daudé wrote:
>> On 12/16/20 4:14 AM, Jiaxun Yang wrote:
>>> 在 2020/12/16 上午10:50, Jiaxun Yang 写道:
>>>> TBH I do think it doesn't sounds like a good idea to make 32-bit
>>>> and 64-bit different. In fact ISA_MIPS32R6 is always set for targets
>>>> with ISA_MIPS64R6.
>>>>
>>>> We're treating MIPS64R6 as a superset of MIPS32R6, and ISA_MIPS3
>>>> is used to tell if a CPU supports 64-bit.
> I suppose you are talking about the CPU definitions
> (CPU_MIPS32R6/CPU_MIPS64R6).
>
>> Which is why I don't understand why they are 2 ISA_MIPS32R6/ISA_MIPS64R6
>> definitions.
> My comment is about the ISA definitions:
>
> #define ISA_MIPS32        0x0000000000000020ULL
> #define ISA_MIPS32R2      0x0000000000000040ULL
> #define ISA_MIPS64        0x0000000000000080ULL
> #define ISA_MIPS64R2      0x0000000000000100ULL
> #define ISA_MIPS32R3      0x0000000000000200ULL
> #define ISA_MIPS64R3      0x0000000000000400ULL
> #define ISA_MIPS32R5      0x0000000000000800ULL
> #define ISA_MIPS64R5      0x0000000000001000ULL
> #define ISA_MIPS32R6      0x0000000000002000ULL
> #define ISA_MIPS64R6      0x0000000000004000ULL

Yes, as insn_flags is

/* MIPS Technologies "Release 1" */
#define CPU_MIPS32      (CPU_MIPS2 | ISA_MIPS32)
#define CPU_MIPS64      (CPU_MIPS5 | CPU_MIPS32 | ISA_MIPS64)

/* MIPS Technologies "Release 2" */
#define CPU_MIPS32R2    (CPU_MIPS32 | ISA_MIPS32R2)
#define CPU_MIPS64R2    (CPU_MIPS64 | CPU_MIPS32R2 | ISA_MIPS64R2)

......

As you can see when you're set insn_flags to CPU_MIPS64R2 the ISA flags
for ISA_MIPS64R2 ISA_MIPS32R2 ISA_MIPS32 ISA_MIPS64 ISA_MIPS5
ISA_MIPS3 ISA_MIPS2 ISA_MIPS1 all get set as well.


>>
>>> So we may end up having four series of decodetrees for ISA
>>> Series1: MIPS-II, MIPS32, MIPS32R2, MIPS32R5 (32bit "old" ISAs)
>>> Series2: MIPS-III, MIPS64, MIPS64R2, MIPS64R5 (64bit "old" ISAs)
>>>
>>> Series3: MIPS32R6 (32bit "new" ISAs)
>>> Series4: MIPS64R6 (64bit "new" ISAs)
>> Something like that, I'm starting by converting the messier leaves
>> first, so the R6 and ASEs. My approach is from your "series4" to
>> "series1" last.

Sounds neat!

Thanks.

- Jiaxun

>>
>> Regards,
>>
>> Phil.
>>

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v2 02/24] target/mips/translate: Expose check_mips_64() to 32-bit mode
  2020-12-15 22:57 ` [PATCH v2 02/24] target/mips/translate: Expose check_mips_64() to 32-bit mode Philippe Mathieu-Daudé
@ 2021-01-06 18:20   ` Philippe Mathieu-Daudé
  2021-01-06 18:37     ` Philippe Mathieu-Daudé
  0 siblings, 1 reply; 48+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-01-06 18:20 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel
  Cc: Aleksandar Rikalo, kvm, Huacai Chen, Jiaxun Yang, Paolo Bonzini,
	Aurelien Jarno

Hi,

ping for code review? :)

Due to the "Simplify ISA definitions"
https://www.mail-archive.com/qemu-devel@nongnu.org/msg770056.html
patch #3 is not necessary.

This is the last patch unreviewed.

On 12/15/20 11:57 PM, Philippe Mathieu-Daudé wrote:
> 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é <f4bug@amsat.org>
> ---
>  target/mips/translate.h | 2 --
>  target/mips/translate.c | 8 +++-----
>  2 files changed, 3 insertions(+), 7 deletions(-)
> 
> diff --git a/target/mips/translate.h b/target/mips/translate.h
> index a9eab69249f..942d803476c 100644
> --- a/target/mips/translate.h
> +++ b/target/mips/translate.h
> @@ -127,9 +127,7 @@ 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
>  void check_mips_64(DisasContext *ctx);
> -#endif
>  void check_cp1_enabled(DisasContext *ctx);
>  
>  void gen_base_offset_addr(DisasContext *ctx, TCGv addr, int base, int offset);
> diff --git a/target/mips/translate.c b/target/mips/translate.c
> index 5c62b32c6ae..af543d1f375 100644
> --- a/target/mips/translate.c
> +++ b/target/mips/translate.c
> @@ -2972,18 +2972,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))) {

Since TARGET_LONG_BITS is known at build time, this can be simplified
as:

if ((TARGET_LONG_BITS != 64) || unlikely!(ctx->hflags & MIPS_HFLAG_64)))

>          gen_reserved_instruction(ctx);
>      }
>  }
> -#endif
>  
>  #ifndef CONFIG_USER_ONLY
>  static inline void check_mvh(DisasContext *ctx)
> 

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v2 02/24] target/mips/translate: Expose check_mips_64() to 32-bit mode
  2021-01-06 18:20   ` Philippe Mathieu-Daudé
@ 2021-01-06 18:37     ` Philippe Mathieu-Daudé
  2021-01-07  3:56       ` Jiaxun Yang
  0 siblings, 1 reply; 48+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-01-06 18:37 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel@nongnu.org Developers
  Cc: Aleksandar Rikalo, kvm, Huacai Chen, Jiaxun Yang, Paolo Bonzini,
	Aurelien Jarno

On Wed, Jan 6, 2021 at 7:20 PM Philippe Mathieu-Daudé <f4bug@amsat.org> wrote:
>
> Hi,
>
> ping for code review? :)

FWIW the full series (rebased on mips-next) is available here:
https://gitlab.com/philmd/qemu/-/commits/mips_msa_decodetree

>
> Due to the "Simplify ISA definitions"
> https://www.mail-archive.com/qemu-devel@nongnu.org/msg770056.html
> patch #3 is not necessary.
>
> This is the last patch unreviewed.
>
> On 12/15/20 11:57 PM, Philippe Mathieu-Daudé wrote:
> > 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é <f4bug@amsat.org>
> > ---
> >  target/mips/translate.h | 2 --
> >  target/mips/translate.c | 8 +++-----
> >  2 files changed, 3 insertions(+), 7 deletions(-)
> >
> > diff --git a/target/mips/translate.h b/target/mips/translate.h
> > index a9eab69249f..942d803476c 100644
> > --- a/target/mips/translate.h
> > +++ b/target/mips/translate.h
> > @@ -127,9 +127,7 @@ 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
> >  void check_mips_64(DisasContext *ctx);
> > -#endif
> >  void check_cp1_enabled(DisasContext *ctx);
> >
> >  void gen_base_offset_addr(DisasContext *ctx, TCGv addr, int base, int offset);
> > diff --git a/target/mips/translate.c b/target/mips/translate.c
> > index 5c62b32c6ae..af543d1f375 100644
> > --- a/target/mips/translate.c
> > +++ b/target/mips/translate.c
> > @@ -2972,18 +2972,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))) {
>
> Since TARGET_LONG_BITS is known at build time, this can be simplified
> as:
>
> if ((TARGET_LONG_BITS != 64) || unlikely!(ctx->hflags & MIPS_HFLAG_64)))
>
> >          gen_reserved_instruction(ctx);
> >      }
> >  }
> > -#endif
> >
> >  #ifndef CONFIG_USER_ONLY
> >  static inline void check_mvh(DisasContext *ctx)
> >

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v2 02/24] target/mips/translate: Expose check_mips_64() to 32-bit mode
  2021-01-06 18:37     ` Philippe Mathieu-Daudé
@ 2021-01-07  3:56       ` Jiaxun Yang
  0 siblings, 0 replies; 48+ messages in thread
From: Jiaxun Yang @ 2021-01-07  3:56 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé,
	Richard Henderson, qemu-devel@nongnu.org Developers
  Cc: Aleksandar Rikalo, kvm, Huacai Chen, Paolo Bonzini, Aurelien Jarno

在 2021/1/7 上午2:37, Philippe Mathieu-Daudé 写道:
> On Wed, Jan 6, 2021 at 7:20 PM Philippe Mathieu-Daudé <f4bug@amsat.org> wrote:
>> Hi,
>>
>> ping for code review? :)
> FWIW the full series (rebased on mips-next) is available here:
> https://gitlab.com/philmd/qemu/-/commits/mips_msa_decodetree

Reviewed-by: Jiaxun Yang <jiaxun.yang@flygoat.com>

- Jiaxun

>
>> Due to the "Simplify ISA definitions"
>> https://www.mail-archive.com/qemu-devel@nongnu.org/msg770056.html
>> patch #3 is not necessary.
>>
>> This is the last patch unreviewed.
>>
>> On 12/15/20 11:57 PM, Philippe Mathieu-Daudé wrote:
>>> 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é <f4bug@amsat.org>
>>> ---
>>>   target/mips/translate.h | 2 --
>>>   target/mips/translate.c | 8 +++-----
>>>   2 files changed, 3 insertions(+), 7 deletions(-)
>>>
>>> diff --git a/target/mips/translate.h b/target/mips/translate.h
>>> index a9eab69249f..942d803476c 100644
>>> --- a/target/mips/translate.h
>>> +++ b/target/mips/translate.h
>>> @@ -127,9 +127,7 @@ 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
>>>   void check_mips_64(DisasContext *ctx);
>>> -#endif
>>>   void check_cp1_enabled(DisasContext *ctx);
>>>
>>>   void gen_base_offset_addr(DisasContext *ctx, TCGv addr, int base, int offset);
>>> diff --git a/target/mips/translate.c b/target/mips/translate.c
>>> index 5c62b32c6ae..af543d1f375 100644
>>> --- a/target/mips/translate.c
>>> +++ b/target/mips/translate.c
>>> @@ -2972,18 +2972,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))) {
>> Since TARGET_LONG_BITS is known at build time, this can be simplified
>> as:
>>
>> if ((TARGET_LONG_BITS != 64) || unlikely!(ctx->hflags & MIPS_HFLAG_64)))
>>
>>>           gen_reserved_instruction(ctx);
>>>       }
>>>   }
>>> -#endif
>>>
>>>   #ifndef CONFIG_USER_ONLY
>>>   static inline void check_mvh(DisasContext *ctx)
>>>


^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v2 03/24] target/mips/cpu: Introduce isa_rel6_available() helper
  2020-12-16  3:14         ` Jiaxun Yang
  2020-12-16 10:50           ` Philippe Mathieu-Daudé
@ 2021-01-07  9:04           ` Philippe Mathieu-Daudé
  2021-01-07 13:17             ` Philippe Mathieu-Daudé
  1 sibling, 1 reply; 48+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-01-07  9:04 UTC (permalink / raw)
  To: Jiaxun Yang, Richard Henderson, qemu-devel, Aurelien Jarno
  Cc: Paolo Bonzini, Aleksandar Rikalo, Huacai Chen, kvm

On 12/16/20 4:14 AM, Jiaxun Yang wrote:
> 在 2020/12/16 上午10:50, Jiaxun Yang 写道:
>> TBH I do think it doesn't sounds like a good idea to make 32-bit
>> and 64-bit different. In fact ISA_MIPS32R6 is always set for targets
>> with ISA_MIPS64R6.
>>
>> We're treating MIPS64R6 as a superset of MIPS32R6, and ISA_MIPS3
>> is used to tell if a CPU supports 64-bit.
>>
>> FYI:
>> https://commons.wikimedia.org/wiki/File:MIPS_instruction_set_family.svg
> 
> Just add more cents here...
> The current method we handle R6 makes me a little bit annoying.
> 
> Given that MIPS is backward compatible until R5, and R6 reorganized a lot
> of opcodes, I do think decoding procdure of R6 should be dedicated from
> the rest,
> otherwise we may fall into the hell of finding difference between R6 and
> previous
> ISAs, also I've heard some R6 only ASEs is occupying opcodes marked as
> "removed in R6", so it doesn't looks like a wise idea to check removed
> in R6
> in helpers.

I think we are in agreement :) Your comment seems what I addressed
last month as this series:
https://gitlab.com/philmd/qemu/-/commits/mips_decodetree_lsa_r6/
(I'll try to rebase it and post during the week-end.)

> So we may end up having four series of decodetrees for ISA
> Series1: MIPS-II, MIPS32, MIPS32R2, MIPS32R5 (32bit "old" ISAs)
> Series2: MIPS-III, MIPS64, MIPS64R2, MIPS64R5 (64bit "old" ISAs)
> 
> Series3: MIPS32R6 (32bit "new" ISAs)
> Series4: MIPS64R6 (64bit "new" ISAs)
> 
> Thanks
> 
> - Jiaxun

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v2 03/24] target/mips/cpu: Introduce isa_rel6_available() helper
  2021-01-07  9:04           ` Philippe Mathieu-Daudé
@ 2021-01-07 13:17             ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 48+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-01-07 13:17 UTC (permalink / raw)
  To: Jiaxun Yang, Richard Henderson, qemu-devel, Aurelien Jarno
  Cc: Paolo Bonzini, Aleksandar Rikalo, Huacai Chen, kvm

On 1/7/21 10:04 AM, Philippe Mathieu-Daudé wrote:
> On 12/16/20 4:14 AM, Jiaxun Yang wrote:
>> 在 2020/12/16 上午10:50, Jiaxun Yang 写道:
>>> TBH I do think it doesn't sounds like a good idea to make 32-bit
>>> and 64-bit different. In fact ISA_MIPS32R6 is always set for targets
>>> with ISA_MIPS64R6.
>>>
>>> We're treating MIPS64R6 as a superset of MIPS32R6, and ISA_MIPS3
>>> is used to tell if a CPU supports 64-bit.
>>>
>>> FYI:
>>> https://commons.wikimedia.org/wiki/File:MIPS_instruction_set_family.svg
>>
>> Just add more cents here...
>> The current method we handle R6 makes me a little bit annoying.
>>
>> Given that MIPS is backward compatible until R5, and R6 reorganized a lot
>> of opcodes, I do think decoding procdure of R6 should be dedicated from
>> the rest,
>> otherwise we may fall into the hell of finding difference between R6 and
>> previous
>> ISAs, also I've heard some R6 only ASEs is occupying opcodes marked as
>> "removed in R6", so it doesn't looks like a wise idea to check removed
>> in R6
>> in helpers.
> 
> I think we are in agreement :) Your comment seems what I addressed
> last month as this series:
> https://gitlab.com/philmd/qemu/-/commits/mips_decodetree_lsa_r6/
> (I'll try to rebase it and post during the week-end.)

Bah actually it is already on the list and reviewed =)
https://www.mail-archive.com/qemu-devel@nongnu.org/msg765234.html

>> So we may end up having four series of decodetrees for ISA
>> Series1: MIPS-II, MIPS32, MIPS32R2, MIPS32R5 (32bit "old" ISAs)
>> Series2: MIPS-III, MIPS64, MIPS64R2, MIPS64R5 (64bit "old" ISAs)
>>
>> Series3: MIPS32R6 (32bit "new" ISAs)
>> Series4: MIPS64R6 (64bit "new" ISAs)
>>
>> Thanks
>>
>> - Jiaxun
> 

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v2 00/24] target/mips: Convert MSA ASE to decodetree
  2020-12-15 22:57 [PATCH v2 00/24] target/mips: Convert MSA ASE to decodetree Philippe Mathieu-Daudé
                   ` (22 preceding siblings ...)
  2020-12-15 22:57 ` [RFC PATCH v2 24/24] target/mips/mod-msa: Pass TCGCond argument to gen_check_zero_element() Philippe Mathieu-Daudé
@ 2021-01-07 18:29 ` Philippe Mathieu-Daudé
  23 siblings, 0 replies; 48+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-01-07 18:29 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel
  Cc: Aleksandar Rikalo, kvm, Huacai Chen, Jiaxun Yang, Paolo Bonzini,
	Aurelien Jarno

On 12/15/20 11:57 PM, Philippe Mathieu-Daudé wrote:
> Philippe Mathieu-Daudé (24):
>   target/mips/translate: Extract decode_opc_legacy() from decode_opc()
>   target/mips/translate: Expose check_mips_64() to 32-bit mode
>   target/mips/cpu: Introduce isa_rel6_available() helper
>   target/mips: Introduce ase_msa_available() helper
>   target/mips: Simplify msa_reset()
>   target/mips: Use CP0_Config3 to set MIPS_HFLAG_MSA
>   target/mips: Simplify MSA TCG logic
>   target/mips: Remove now unused ASE_MSA definition
>   target/mips: Alias MSA vector registers on FPU scalar registers
>   target/mips: Extract msa_translate_init() from mips_tcg_init()
>   target/mips: Remove CPUMIPSState* argument from gen_msa*() methods
>   target/mips: Explode gen_msa_branch() as gen_msa_BxZ_V/BxZ()
>   target/mips: Rename msa_helper.c as mod-msa_helper.c
>   target/mips: Move msa_reset() to mod-msa_helper.c
>   target/mips: Extract MSA helpers from op_helper.c
>   target/mips: Extract MSA helper definitions
>   target/mips: Declare gen_msa/_branch() in 'translate.h'
>   target/mips: Extract MSA translation routines
>   target/mips: Introduce decode tree bindings for MSA opcodes
>   target/mips: Use decode_ase_msa() generated from decodetree
>   target/mips: Extract LSA/DLSA translation generators
>   target/mips: Introduce decodetree helpers for MSA LSA/DLSA opcodes
>   target/mips: Introduce decodetree helpers for Release6 LSA/DLSA
>     opcodes
>   target/mips/mod-msa: Pass TCGCond argument to gen_check_zero_element()

Thanks, series queued to mips-next
(without patch #3 "Introduce isa_rel6_available helper").

^ permalink raw reply	[flat|nested] 48+ messages in thread

end of thread, other threads:[~2021-01-07 18:30 UTC | newest]

Thread overview: 48+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-12-15 22:57 [PATCH v2 00/24] target/mips: Convert MSA ASE to decodetree Philippe Mathieu-Daudé
2020-12-15 22:57 ` [PATCH v2 01/24] target/mips/translate: Extract decode_opc_legacy() from decode_opc() Philippe Mathieu-Daudé
2020-12-15 23:23   ` Richard Henderson
2020-12-15 22:57 ` [PATCH v2 02/24] target/mips/translate: Expose check_mips_64() to 32-bit mode Philippe Mathieu-Daudé
2021-01-06 18:20   ` Philippe Mathieu-Daudé
2021-01-06 18:37     ` Philippe Mathieu-Daudé
2021-01-07  3:56       ` Jiaxun Yang
2020-12-15 22:57 ` [PATCH v2 03/24] target/mips/cpu: Introduce isa_rel6_available() helper Philippe Mathieu-Daudé
2020-12-15 23:27   ` Richard Henderson
2020-12-15 23:48     ` Philippe Mathieu-Daudé
2020-12-16  2:50       ` Jiaxun Yang
2020-12-16  3:14         ` Jiaxun Yang
2020-12-16 10:50           ` Philippe Mathieu-Daudé
2020-12-16 10:59             ` Philippe Mathieu-Daudé
2020-12-16 11:30               ` Jiaxun Yang
2020-12-16 11:36               ` Jiaxun Yang
2021-01-07  9:04           ` Philippe Mathieu-Daudé
2021-01-07 13:17             ` Philippe Mathieu-Daudé
2020-12-16 10:55       ` Philippe Mathieu-Daudé
2020-12-15 22:57 ` [PATCH v2 04/24] target/mips: Introduce ase_msa_available() helper Philippe Mathieu-Daudé
2020-12-15 22:57 ` [PATCH v2 05/24] target/mips: Simplify msa_reset() Philippe Mathieu-Daudé
2020-12-15 22:57 ` [PATCH v2 06/24] target/mips: Use CP0_Config3 to set MIPS_HFLAG_MSA Philippe Mathieu-Daudé
2020-12-15 22:57 ` [PATCH v2 07/24] target/mips: Simplify MSA TCG logic Philippe Mathieu-Daudé
2020-12-15 22:57 ` [PATCH v2 08/24] target/mips: Remove now unused ASE_MSA definition Philippe Mathieu-Daudé
2020-12-15 22:57 ` [PATCH v2 09/24] target/mips: Alias MSA vector registers on FPU scalar registers Philippe Mathieu-Daudé
2020-12-15 22:57 ` [PATCH v2 10/24] target/mips: Extract msa_translate_init() from mips_tcg_init() Philippe Mathieu-Daudé
2020-12-15 22:57 ` [PATCH v2 11/24] target/mips: Remove CPUMIPSState* argument from gen_msa*() methods Philippe Mathieu-Daudé
2020-12-15 22:57 ` [PATCH v2 12/24] target/mips: Explode gen_msa_branch() as gen_msa_BxZ_V/BxZ() Philippe Mathieu-Daudé
2020-12-15 22:57 ` [PATCH v2 13/24] target/mips: Rename msa_helper.c as mod-msa_helper.c Philippe Mathieu-Daudé
2020-12-15 22:57 ` [PATCH v2 14/24] target/mips: Move msa_reset() to mod-msa_helper.c Philippe Mathieu-Daudé
2020-12-15 23:09   ` Richard Henderson
2020-12-15 22:57 ` [PATCH v2 15/24] target/mips: Extract MSA helpers from op_helper.c Philippe Mathieu-Daudé
2020-12-15 22:57 ` [PATCH v2 16/24] target/mips: Extract MSA helper definitions Philippe Mathieu-Daudé
2020-12-15 22:57 ` [PATCH v2 17/24] target/mips: Declare gen_msa/_branch() in 'translate.h' Philippe Mathieu-Daudé
2020-12-15 23:10   ` Richard Henderson
2020-12-15 22:57 ` [PATCH v2 19/24] target/mips: Introduce decode tree bindings for MSA opcodes Philippe Mathieu-Daudé
2020-12-15 23:11   ` Richard Henderson
2020-12-15 22:57 ` [PATCH v2 20/24] target/mips: Use decode_ase_msa() generated from decodetree Philippe Mathieu-Daudé
2020-12-15 23:15   ` Richard Henderson
2020-12-15 22:57 ` [PATCH v2 21/24] target/mips: Extract LSA/DLSA translation generators Philippe Mathieu-Daudé
2020-12-15 23:17   ` Richard Henderson
2020-12-15 22:57 ` [PATCH v2 22/24] target/mips: Introduce decodetree helpers for MSA LSA/DLSA opcodes Philippe Mathieu-Daudé
2020-12-15 23:19   ` Richard Henderson
2020-12-15 22:57 ` [PATCH v2 23/24] target/mips: Introduce decodetree helpers for Release6 " Philippe Mathieu-Daudé
2020-12-15 23:21   ` Richard Henderson
2020-12-15 22:57 ` [RFC PATCH v2 24/24] target/mips/mod-msa: Pass TCGCond argument to gen_check_zero_element() Philippe Mathieu-Daudé
2020-12-15 23:22   ` Richard Henderson
2021-01-07 18:29 ` [PATCH v2 00/24] target/mips: Convert MSA ASE to decodetree Philippe Mathieu-Daudé

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).