All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 00/10] target/mips: Extract MXU code to new mxu_translate.c file
@ 2021-02-22 22:38 Philippe Mathieu-Daudé
  2021-02-22 22:38 ` [PATCH v3 01/10] target/mips: Rewrite complex ifdef'ry Philippe Mathieu-Daudé
                   ` (9 more replies)
  0 siblings, 10 replies; 21+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-02-22 22:38 UTC (permalink / raw)
  To: qemu-devel
  Cc: Aleksandar Rikalo, Richard Henderson, Aurelien Jarno,
	Philippe Mathieu-Daudé

Hi,

This is a respin of "Extract XBurst Media eXtension Unit
translation routines" v2:
https://lists.gnu.org/archive/html/qemu-devel/2020-11/msg05889.html

But instead of an included C file (.c.inc) we now have an
independent C unit. We gain faster recompilation time when
hacking translate.c or mxu_translate.c, and we also gain
in code maintainability.

Review should be trivial, with almost no logical code change.

Regards,

Phil.

Philippe Mathieu-Daudé (10):
  target/mips: Rewrite complex ifdef'ry
  target/mips: Remove XBurst Media eXtension Unit dead code
  target/mips: Remove unused CPUMIPSState* from MXU functions
  target/mips: Pass instruction opcode to decode_opc_mxu()
  target/mips: Extract decode_ase_mxu() from decode_opc_mxu()
  target/mips: Use OPC_MUL instead of OPC__MXU_MUL
  target/mips: Introduce mxu_translate_init() helper
  target/mips: Make mxu_translate_init() / decode_ase_mxu() proto public
  target/mips: Simplify 64-bit ifdef'ry of MXU code
  target/mips: Extract MXU code to new mxu_translate.c file

 target/mips/translate.h     |    4 +
 target/mips/mxu_translate.c | 1625 +++++++++++++++++++
 target/mips/translate.c     | 2909 +----------------------------------
 target/mips/meson.build     |    1 +
 4 files changed, 1645 insertions(+), 2894 deletions(-)
 create mode 100644 target/mips/mxu_translate.c

-- 
2.26.2



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

* [PATCH v3 01/10] target/mips: Rewrite complex ifdef'ry
  2021-02-22 22:38 [PATCH v3 00/10] target/mips: Extract MXU code to new mxu_translate.c file Philippe Mathieu-Daudé
@ 2021-02-22 22:38 ` Philippe Mathieu-Daudé
  2021-02-24  1:21   ` Richard Henderson
  2021-02-22 22:38 ` [PATCH v3 02/10] target/mips: Remove XBurst Media eXtension Unit dead code Philippe Mathieu-Daudé
                   ` (8 subsequent siblings)
  9 siblings, 1 reply; 21+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-02-22 22:38 UTC (permalink / raw)
  To: qemu-devel
  Cc: Aleksandar Rikalo, Richard Henderson, Aurelien Jarno,
	Philippe Mathieu-Daudé

No need for this obfuscated ifdef'ry, KISS.

Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 target/mips/translate.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index 70891c37cdd..1f1c5f33c87 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -28276,13 +28276,16 @@ static bool decode_opc_legacy(CPUMIPSState *env, DisasContext *ctx)
 #if defined(TARGET_MIPS64)
         if ((ctx->insn_flags & INSN_R5900) && (ctx->insn_flags & ASE_MMI)) {
             decode_mmi(env, ctx);
-#else
+            break;
+        }
+#endif
+#if !defined(TARGET_MIPS64)
         if (ctx->insn_flags & ASE_MXU) {
             decode_opc_mxu(env, ctx);
-#endif
-        } else {
-            decode_opc_special2_legacy(env, ctx);
+            break;
         }
+#endif
+        decode_opc_special2_legacy(env, ctx);
         break;
     case OPC_SPECIAL3:
 #if defined(TARGET_MIPS64)
-- 
2.26.2



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

* [PATCH v3 02/10] target/mips: Remove XBurst Media eXtension Unit dead code
  2021-02-22 22:38 [PATCH v3 00/10] target/mips: Extract MXU code to new mxu_translate.c file Philippe Mathieu-Daudé
  2021-02-22 22:38 ` [PATCH v3 01/10] target/mips: Rewrite complex ifdef'ry Philippe Mathieu-Daudé
@ 2021-02-22 22:38 ` Philippe Mathieu-Daudé
  2021-02-22 22:38 ` [PATCH v3 03/10] target/mips: Remove unused CPUMIPSState* from MXU functions Philippe Mathieu-Daudé
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 21+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-02-22 22:38 UTC (permalink / raw)
  To: qemu-devel
  Cc: Aleksandar Rikalo, Richard Henderson, Aurelien Jarno,
	Philippe Mathieu-Daudé

All these unimplemented MXU opcodes end up calling
gen_reserved_instruction() which is the default switch
case in decode_opc_mxu().

The translate.c file is already big enough and hard to maintain,
remove 1300 lines of unnecessary code and /* TODO */ comments.

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 target/mips/translate.c | 1286 ---------------------------------------
 1 file changed, 1286 deletions(-)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index 1f1c5f33c87..a53ce6adb9a 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -1464,70 +1464,16 @@ enum {
  */
 
 enum {
-    OPC_MXU_S32MADD  = 0x00,
-    OPC_MXU_S32MADDU = 0x01,
     OPC__MXU_MUL     = 0x02,
     OPC_MXU__POOL00  = 0x03,
-    OPC_MXU_S32MSUB  = 0x04,
-    OPC_MXU_S32MSUBU = 0x05,
-    OPC_MXU__POOL01  = 0x06,
-    OPC_MXU__POOL02  = 0x07,
     OPC_MXU_D16MUL   = 0x08,
-    OPC_MXU__POOL03  = 0x09,
     OPC_MXU_D16MAC   = 0x0A,
-    OPC_MXU_D16MACF  = 0x0B,
-    OPC_MXU_D16MADL  = 0x0C,
-    OPC_MXU_S16MAD   = 0x0D,
-    OPC_MXU_Q16ADD   = 0x0E,
-    OPC_MXU_D16MACE  = 0x0F,
     OPC_MXU__POOL04  = 0x10,
-    OPC_MXU__POOL05  = 0x11,
-    OPC_MXU__POOL06  = 0x12,
-    OPC_MXU__POOL07  = 0x13,
-    OPC_MXU__POOL08  = 0x14,
-    OPC_MXU__POOL09  = 0x15,
-    OPC_MXU__POOL10  = 0x16,
-    OPC_MXU__POOL11  = 0x17,
-    OPC_MXU_D32ADD   = 0x18,
-    OPC_MXU__POOL12  = 0x19,
-    /* not assigned 0x1A */
-    OPC_MXU__POOL13  = 0x1B,
-    OPC_MXU__POOL14  = 0x1C,
-    OPC_MXU_Q8ACCE   = 0x1D,
-    /* not assigned 0x1E */
-    /* not assigned 0x1F */
-    /* not assigned 0x20 */
-    /* not assigned 0x21 */
     OPC_MXU_S8LDD    = 0x22,
-    OPC_MXU_S8STD    = 0x23,
-    OPC_MXU_S8LDI    = 0x24,
-    OPC_MXU_S8SDI    = 0x25,
-    OPC_MXU__POOL15  = 0x26,
     OPC_MXU__POOL16  = 0x27,
-    OPC_MXU__POOL17  = 0x28,
-    /* not assigned 0x29 */
-    OPC_MXU_S16LDD   = 0x2A,
-    OPC_MXU_S16STD   = 0x2B,
-    OPC_MXU_S16LDI   = 0x2C,
-    OPC_MXU_S16SDI   = 0x2D,
     OPC_MXU_S32M2I   = 0x2E,
     OPC_MXU_S32I2M   = 0x2F,
-    OPC_MXU_D32SLL   = 0x30,
-    OPC_MXU_D32SLR   = 0x31,
-    OPC_MXU_D32SARL  = 0x32,
-    OPC_MXU_D32SAR   = 0x33,
-    OPC_MXU_Q16SLL   = 0x34,
-    OPC_MXU_Q16SLR   = 0x35,
-    OPC_MXU__POOL18  = 0x36,
-    OPC_MXU_Q16SAR   = 0x37,
     OPC_MXU__POOL19  = 0x38,
-    OPC_MXU__POOL20  = 0x39,
-    OPC_MXU__POOL21  = 0x3A,
-    OPC_MXU_Q16SCOP  = 0x3B,
-    OPC_MXU_Q8MADL   = 0x3C,
-    OPC_MXU_S32SFL   = 0x3D,
-    OPC_MXU_Q8SAD    = 0x3E,
-    /* not assigned 0x3F */
 };
 
 
@@ -1541,39 +1487,6 @@ enum {
     OPC_MXU_D16MIN   = 0x03,
     OPC_MXU_Q8MAX    = 0x04,
     OPC_MXU_Q8MIN    = 0x05,
-    OPC_MXU_Q8SLT    = 0x06,
-    OPC_MXU_Q8SLTU   = 0x07,
-};
-
-/*
- * MXU pool 01
- */
-enum {
-    OPC_MXU_S32SLT   = 0x00,
-    OPC_MXU_D16SLT   = 0x01,
-    OPC_MXU_D16AVG   = 0x02,
-    OPC_MXU_D16AVGR  = 0x03,
-    OPC_MXU_Q8AVG    = 0x04,
-    OPC_MXU_Q8AVGR   = 0x05,
-    OPC_MXU_Q8ADD    = 0x07,
-};
-
-/*
- * MXU pool 02
- */
-enum {
-    OPC_MXU_S32CPS   = 0x00,
-    OPC_MXU_D16CPS   = 0x02,
-    OPC_MXU_Q8ABD    = 0x04,
-    OPC_MXU_Q16SAT   = 0x06,
-};
-
-/*
- * MXU pool 03
- */
-enum {
-    OPC_MXU_D16MULF  = 0x00,
-    OPC_MXU_D16MULE  = 0x01,
 };
 
 /*
@@ -1584,136 +1497,17 @@ enum {
     OPC_MXU_S32LDDR  = 0x01,
 };
 
-/*
- * MXU pool 05
- */
-enum {
-    OPC_MXU_S32STD   = 0x00,
-    OPC_MXU_S32STDR  = 0x01,
-};
-
-/*
- * MXU pool 06
- */
-enum {
-    OPC_MXU_S32LDDV  = 0x00,
-    OPC_MXU_S32LDDVR = 0x01,
-};
-
-/*
- * MXU pool 07
- */
-enum {
-    OPC_MXU_S32STDV  = 0x00,
-    OPC_MXU_S32STDVR = 0x01,
-};
-
-/*
- * MXU pool 08
- */
-enum {
-    OPC_MXU_S32LDI   = 0x00,
-    OPC_MXU_S32LDIR  = 0x01,
-};
-
-/*
- * MXU pool 09
- */
-enum {
-    OPC_MXU_S32SDI   = 0x00,
-    OPC_MXU_S32SDIR  = 0x01,
-};
-
-/*
- * MXU pool 10
- */
-enum {
-    OPC_MXU_S32LDIV  = 0x00,
-    OPC_MXU_S32LDIVR = 0x01,
-};
-
-/*
- * MXU pool 11
- */
-enum {
-    OPC_MXU_S32SDIV  = 0x00,
-    OPC_MXU_S32SDIVR = 0x01,
-};
-
-/*
- * MXU pool 12
- */
-enum {
-    OPC_MXU_D32ACC   = 0x00,
-    OPC_MXU_D32ACCM  = 0x01,
-    OPC_MXU_D32ASUM  = 0x02,
-};
-
-/*
- * MXU pool 13
- */
-enum {
-    OPC_MXU_Q16ACC   = 0x00,
-    OPC_MXU_Q16ACCM  = 0x01,
-    OPC_MXU_Q16ASUM  = 0x02,
-};
-
-/*
- * MXU pool 14
- */
-enum {
-    OPC_MXU_Q8ADDE   = 0x00,
-    OPC_MXU_D8SUM    = 0x01,
-    OPC_MXU_D8SUMC   = 0x02,
-};
-
-/*
- * MXU pool 15
- */
-enum {
-    OPC_MXU_S32MUL   = 0x00,
-    OPC_MXU_S32MULU  = 0x01,
-    OPC_MXU_S32EXTR  = 0x02,
-    OPC_MXU_S32EXTRV = 0x03,
-};
-
 /*
  * MXU pool 16
  */
 enum {
-    OPC_MXU_D32SARW  = 0x00,
-    OPC_MXU_S32ALN   = 0x01,
     OPC_MXU_S32ALNI  = 0x02,
-    OPC_MXU_S32LUI   = 0x03,
     OPC_MXU_S32NOR   = 0x04,
     OPC_MXU_S32AND   = 0x05,
     OPC_MXU_S32OR    = 0x06,
     OPC_MXU_S32XOR   = 0x07,
 };
 
-/*
- * MXU pool 17
- */
-enum {
-    OPC_MXU_LXB      = 0x00,
-    OPC_MXU_LXH      = 0x01,
-    OPC_MXU_LXW      = 0x03,
-    OPC_MXU_LXBU     = 0x04,
-    OPC_MXU_LXHU     = 0x05,
-};
-
-/*
- * MXU pool 18
- */
-enum {
-    OPC_MXU_D32SLLV  = 0x00,
-    OPC_MXU_D32SLRV  = 0x01,
-    OPC_MXU_D32SARV  = 0x03,
-    OPC_MXU_Q16SLLV  = 0x04,
-    OPC_MXU_Q16SLRV  = 0x05,
-    OPC_MXU_Q16SARV  = 0x07,
-};
-
 /*
  * MXU pool 19
  */
@@ -1722,26 +1516,6 @@ enum {
     OPC_MXU_Q8MULSU  = 0x01,
 };
 
-/*
- * MXU pool 20
- */
-enum {
-    OPC_MXU_Q8MOVZ   = 0x00,
-    OPC_MXU_Q8MOVN   = 0x01,
-    OPC_MXU_D16MOVZ  = 0x02,
-    OPC_MXU_D16MOVN  = 0x03,
-    OPC_MXU_S32MOVZ  = 0x04,
-    OPC_MXU_S32MOVN  = 0x05,
-};
-
-/*
- * MXU pool 21
- */
-enum {
-    OPC_MXU_Q8MAC    = 0x00,
-    OPC_MXU_Q8MACSU  = 0x01,
-};
-
 /*
  *     Overview of the TX79-specific instruction set
  *     =============================================
@@ -25332,11 +25106,6 @@ static void gen_mxu_s32ldd_s32lddr(DisasContext *ctx)
  *  S32NOR XRa, XRb, XRc
  *    Update XRa with the result of logical bitwise 'nor' operation
  *    applied to the content of XRb and XRc.
- *
- *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
- *  +-----------+---------+-----+-------+-------+-------+-----------+
- *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL16|
- *  +-----------+---------+-----+-------+-------+-------+-----------+
  */
 static void gen_mxu_S32NOR(DisasContext *ctx)
 {
@@ -25373,11 +25142,6 @@ static void gen_mxu_S32NOR(DisasContext *ctx)
  *  S32AND XRa, XRb, XRc
  *    Update XRa with the result of logical bitwise 'and' operation
  *    applied to the content of XRb and XRc.
- *
- *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
- *  +-----------+---------+-----+-------+-------+-------+-----------+
- *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL16|
- *  +-----------+---------+-----+-------+-------+-------+-----------+
  */
 static void gen_mxu_S32AND(DisasContext *ctx)
 {
@@ -25408,11 +25172,6 @@ static void gen_mxu_S32AND(DisasContext *ctx)
  *  S32OR XRa, XRb, XRc
  *    Update XRa with the result of logical bitwise 'or' operation
  *    applied to the content of XRb and XRc.
- *
- *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
- *  +-----------+---------+-----+-------+-------+-------+-----------+
- *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL16|
- *  +-----------+---------+-----+-------+-------+-------+-----------+
  */
 static void gen_mxu_S32OR(DisasContext *ctx)
 {
@@ -25449,11 +25208,6 @@ static void gen_mxu_S32OR(DisasContext *ctx)
  *  S32XOR XRa, XRb, XRc
  *    Update XRa with the result of logical bitwise 'xor' operation
  *    applied to the content of XRb and XRc.
- *
- *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
- *  +-----------+---------+-----+-------+-------+-------+-----------+
- *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL16|
- *  +-----------+---------+-----+-------+-------+-------+-----------+
  */
 static void gen_mxu_S32XOR(DisasContext *ctx)
 {
@@ -25503,11 +25257,6 @@ static void gen_mxu_S32XOR(DisasContext *ctx)
  *  S32MIN XRa, XRb, XRc
  *    Update XRa with the minimum of signed 32-bit integers contained
  *    in XRb and XRc.
- *
- *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
- *  +-----------+---------+-----+-------+-------+-------+-----------+
- *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL00|
- *  +-----------+---------+-----+-------+-------+-------+-----------+
  */
 static void gen_mxu_S32MAX_S32MIN(DisasContext *ctx)
 {
@@ -25558,11 +25307,6 @@ static void gen_mxu_S32MAX_S32MIN(DisasContext *ctx)
  *  D16MIN
  *    Update XRa with the 16-bit-wise minimums of signed integers
  *    contained in XRb and XRc.
- *
- *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
- *  +-----------+---------+-----+-------+-------+-------+-----------+
- *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL00|
- *  +-----------+---------+-----+-------+-------+-------+-----------+
  */
 static void gen_mxu_D16MAX_D16MIN(DisasContext *ctx)
 {
@@ -25660,11 +25404,6 @@ static void gen_mxu_D16MAX_D16MIN(DisasContext *ctx)
  *  Q8MIN
  *    Update XRa with the 8-bit-wise minimums of signed integers
  *    contained in XRb and XRc.
- *
- *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
- *  +-----------+---------+-----+-------+-------+-------+-----------+
- *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL00|
- *  +-----------+---------+-----+-------+-------+-------+-----------+
  */
 static void gen_mxu_Q8MAX_Q8MIN(DisasContext *ctx)
 {
@@ -25774,12 +25513,6 @@ static void gen_mxu_Q8MAX_Q8MIN(DisasContext *ctx)
  *  S32ALNI XRc, XRb, XRa, optn3
  *    Arrange bytes from XRb and XRc according to one of five sets of
  *    rules determined by optn3, and place the result in XRa.
- *
- *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
- *  +-----------+-----+---+-----+-------+-------+-------+-----------+
- *  |  SPECIAL2 |optn3|0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL16|
- *  +-----------+-----+---+-----+-------+-------+-------+-----------+
- *
  */
 static void gen_mxu_S32ALNI(DisasContext *ctx)
 {
@@ -25961,16 +25694,6 @@ static void gen_mxu_S32ALNI(DisasContext *ctx)
  * =======================
  */
 
-/*
- *
- * Decode MXU pool00
- *
- *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
- *  +-----------+---------+-----+-------+-------+-------+-----------+
- *  |  SPECIAL2 |0 0 0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL00|
- *  +-----------+---------+-----+-------+-------+-------+-----------+
- *
- */
 static void decode_opc_mxu__pool00(CPUMIPSState *env, DisasContext *ctx)
 {
     uint32_t opcode = extract32(ctx->opcode, 18, 3);
@@ -25988,16 +25711,6 @@ static void decode_opc_mxu__pool00(CPUMIPSState *env, DisasContext *ctx)
     case OPC_MXU_Q8MIN:
         gen_mxu_Q8MAX_Q8MIN(ctx);
         break;
-    case OPC_MXU_Q8SLT:
-        /* TODO: Implement emulation of Q8SLT instruction. */
-        MIPS_INVAL("OPC_MXU_Q8SLT");
-        gen_reserved_instruction(ctx);
-        break;
-    case OPC_MXU_Q8SLTU:
-        /* TODO: Implement emulation of Q8SLTU instruction. */
-        MIPS_INVAL("OPC_MXU_Q8SLTU");
-        gen_reserved_instruction(ctx);
-        break;
     default:
         MIPS_INVAL("decode_opc_mxu");
         gen_reserved_instruction(ctx);
@@ -26005,161 +25718,6 @@ static void decode_opc_mxu__pool00(CPUMIPSState *env, DisasContext *ctx)
     }
 }
 
-/*
- *
- * Decode MXU pool01
- *
- *  S32SLT, D16SLT, D16AVG, D16AVGR, Q8AVG, Q8AVGR:
- *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
- *  +-----------+---------+-----+-------+-------+-------+-----------+
- *  |  SPECIAL2 |0 0 0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL01|
- *  +-----------+---------+-----+-------+-------+-------+-----------+
- *
- *  Q8ADD:
- *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
- *  +-----------+---+-----+-----+-------+-------+-------+-----------+
- *  |  SPECIAL2 |en2|0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL01|
- *  +-----------+---+-----+-----+-------+-------+-------+-----------+
- *
- */
-static void decode_opc_mxu__pool01(CPUMIPSState *env, DisasContext *ctx)
-{
-    uint32_t opcode = extract32(ctx->opcode, 18, 3);
-
-    switch (opcode) {
-    case OPC_MXU_S32SLT:
-        /* TODO: Implement emulation of S32SLT instruction. */
-        MIPS_INVAL("OPC_MXU_S32SLT");
-        gen_reserved_instruction(ctx);
-        break;
-    case OPC_MXU_D16SLT:
-        /* TODO: Implement emulation of D16SLT instruction. */
-        MIPS_INVAL("OPC_MXU_D16SLT");
-        gen_reserved_instruction(ctx);
-        break;
-    case OPC_MXU_D16AVG:
-        /* TODO: Implement emulation of D16AVG instruction. */
-        MIPS_INVAL("OPC_MXU_D16AVG");
-        gen_reserved_instruction(ctx);
-        break;
-    case OPC_MXU_D16AVGR:
-        /* TODO: Implement emulation of D16AVGR instruction. */
-        MIPS_INVAL("OPC_MXU_D16AVGR");
-        gen_reserved_instruction(ctx);
-        break;
-    case OPC_MXU_Q8AVG:
-        /* TODO: Implement emulation of Q8AVG instruction. */
-        MIPS_INVAL("OPC_MXU_Q8AVG");
-        gen_reserved_instruction(ctx);
-        break;
-    case OPC_MXU_Q8AVGR:
-        /* TODO: Implement emulation of Q8AVGR instruction. */
-        MIPS_INVAL("OPC_MXU_Q8AVGR");
-        gen_reserved_instruction(ctx);
-        break;
-    case OPC_MXU_Q8ADD:
-        /* TODO: Implement emulation of Q8ADD instruction. */
-        MIPS_INVAL("OPC_MXU_Q8ADD");
-        gen_reserved_instruction(ctx);
-        break;
-    default:
-        MIPS_INVAL("decode_opc_mxu");
-        gen_reserved_instruction(ctx);
-        break;
-    }
-}
-
-/*
- *
- * Decode MXU pool02
- *
- *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
- *  +-----------+---------+-----+-------+-------+-------+-----------+
- *  |  SPECIAL2 |0 0 0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL02|
- *  +-----------+---------+-----+-------+-------+-------+-----------+
- *
- */
-static void decode_opc_mxu__pool02(CPUMIPSState *env, DisasContext *ctx)
-{
-    uint32_t opcode = extract32(ctx->opcode, 18, 3);
-
-    switch (opcode) {
-    case OPC_MXU_S32CPS:
-        /* TODO: Implement emulation of S32CPS instruction. */
-        MIPS_INVAL("OPC_MXU_S32CPS");
-        gen_reserved_instruction(ctx);
-        break;
-    case OPC_MXU_D16CPS:
-        /* TODO: Implement emulation of D16CPS instruction. */
-        MIPS_INVAL("OPC_MXU_D16CPS");
-        gen_reserved_instruction(ctx);
-        break;
-    case OPC_MXU_Q8ABD:
-        /* TODO: Implement emulation of Q8ABD instruction. */
-        MIPS_INVAL("OPC_MXU_Q8ABD");
-        gen_reserved_instruction(ctx);
-        break;
-    case OPC_MXU_Q16SAT:
-        /* TODO: Implement emulation of Q16SAT instruction. */
-        MIPS_INVAL("OPC_MXU_Q16SAT");
-        gen_reserved_instruction(ctx);
-        break;
-    default:
-        MIPS_INVAL("decode_opc_mxu");
-        gen_reserved_instruction(ctx);
-        break;
-    }
-}
-
-/*
- *
- * Decode MXU pool03
- *
- *  D16MULF:
- *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
- *  +-----------+---+---+-------+-------+-------+-------+-----------+
- *  |  SPECIAL2 |x x|on2|0 0 0 0|  XRc  |  XRb  |  XRa  |MXU__POOL03|
- *  +-----------+---+---+-------+-------+-------+-------+-----------+
- *
- *  D16MULE:
- *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
- *  +-----------+---+---+-------+-------+-------+-------+-----------+
- *  |  SPECIAL2 |x x|on2|   Xd  |  XRc  |  XRb  |  XRa  |MXU__POOL03|
- *  +-----------+---+---+-------+-------+-------+-------+-----------+
- *
- */
-static void decode_opc_mxu__pool03(CPUMIPSState *env, DisasContext *ctx)
-{
-    uint32_t opcode = extract32(ctx->opcode, 24, 2);
-
-    switch (opcode) {
-    case OPC_MXU_D16MULF:
-        /* TODO: Implement emulation of D16MULF instruction. */
-        MIPS_INVAL("OPC_MXU_D16MULF");
-        gen_reserved_instruction(ctx);
-        break;
-    case OPC_MXU_D16MULE:
-        /* TODO: Implement emulation of D16MULE instruction. */
-        MIPS_INVAL("OPC_MXU_D16MULE");
-        gen_reserved_instruction(ctx);
-        break;
-    default:
-        MIPS_INVAL("decode_opc_mxu");
-        gen_reserved_instruction(ctx);
-        break;
-    }
-}
-
-/*
- *
- * Decode MXU pool04
- *
- *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
- *  +-----------+---------+-+-------------------+-------+-----------+
- *  |  SPECIAL2 |    rb   |x|        s12        |  XRa  |MXU__POOL04|
- *  +-----------+---------+-+-------------------+-------+-----------+
- *
- */
 static void decode_opc_mxu__pool04(CPUMIPSState *env, DisasContext *ctx)
 {
     uint32_t opcode = extract32(ctx->opcode, 20, 1);
@@ -26176,455 +25734,14 @@ static void decode_opc_mxu__pool04(CPUMIPSState *env, DisasContext *ctx)
     }
 }
 
-/*
- *
- * Decode MXU pool05
- *
- *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
- *  +-----------+---------+-+-------------------+-------+-----------+
- *  |  SPECIAL2 |    rb   |x|        s12        |  XRa  |MXU__POOL05|
- *  +-----------+---------+-+-------------------+-------+-----------+
- *
- */
-static void decode_opc_mxu__pool05(CPUMIPSState *env, DisasContext *ctx)
-{
-    uint32_t opcode = extract32(ctx->opcode, 20, 1);
-
-    switch (opcode) {
-    case OPC_MXU_S32STD:
-        /* TODO: Implement emulation of S32STD instruction. */
-        MIPS_INVAL("OPC_MXU_S32STD");
-        gen_reserved_instruction(ctx);
-        break;
-    case OPC_MXU_S32STDR:
-        /* TODO: Implement emulation of S32STDR instruction. */
-        MIPS_INVAL("OPC_MXU_S32STDR");
-        gen_reserved_instruction(ctx);
-        break;
-    default:
-        MIPS_INVAL("decode_opc_mxu");
-        gen_reserved_instruction(ctx);
-        break;
-    }
-}
-
-/*
- *
- * Decode MXU pool06
- *
- *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
- *  +-----------+---------+---------+---+-------+-------+-----------+
- *  |  SPECIAL2 |    rb   |    rc   |st2|x x x x|  XRa  |MXU__POOL06|
- *  +-----------+---------+---------+---+-------+-------+-----------+
- *
- */
-static void decode_opc_mxu__pool06(CPUMIPSState *env, DisasContext *ctx)
-{
-    uint32_t opcode = extract32(ctx->opcode, 10, 4);
-
-    switch (opcode) {
-    case OPC_MXU_S32LDDV:
-        /* TODO: Implement emulation of S32LDDV instruction. */
-        MIPS_INVAL("OPC_MXU_S32LDDV");
-        gen_reserved_instruction(ctx);
-        break;
-    case OPC_MXU_S32LDDVR:
-        /* TODO: Implement emulation of S32LDDVR instruction. */
-        MIPS_INVAL("OPC_MXU_S32LDDVR");
-        gen_reserved_instruction(ctx);
-        break;
-    default:
-        MIPS_INVAL("decode_opc_mxu");
-        gen_reserved_instruction(ctx);
-        break;
-    }
-}
-
-/*
- *
- * Decode MXU pool07
- *
- *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
- *  +-----------+---------+---------+---+-------+-------+-----------+
- *  |  SPECIAL2 |    rb   |    rc   |st2|x x x x|  XRa  |MXU__POOL07|
- *  +-----------+---------+---------+---+-------+-------+-----------+
- *
- */
-static void decode_opc_mxu__pool07(CPUMIPSState *env, DisasContext *ctx)
-{
-    uint32_t opcode = extract32(ctx->opcode, 10, 4);
-
-    switch (opcode) {
-    case OPC_MXU_S32STDV:
-        /* TODO: Implement emulation of S32TDV instruction. */
-        MIPS_INVAL("OPC_MXU_S32TDV");
-        gen_reserved_instruction(ctx);
-        break;
-    case OPC_MXU_S32STDVR:
-        /* TODO: Implement emulation of S32TDVR instruction. */
-        MIPS_INVAL("OPC_MXU_S32TDVR");
-        gen_reserved_instruction(ctx);
-        break;
-    default:
-        MIPS_INVAL("decode_opc_mxu");
-        gen_reserved_instruction(ctx);
-        break;
-    }
-}
-
-/*
- *
- * Decode MXU pool08
- *
- *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
- *  +-----------+---------+-+-------------------+-------+-----------+
- *  |  SPECIAL2 |    rb   |x|        s12        |  XRa  |MXU__POOL08|
- *  +-----------+---------+-+-------------------+-------+-----------+
- *
- */
-static void decode_opc_mxu__pool08(CPUMIPSState *env, DisasContext *ctx)
-{
-    uint32_t opcode = extract32(ctx->opcode, 20, 1);
-
-    switch (opcode) {
-    case OPC_MXU_S32LDI:
-        /* TODO: Implement emulation of S32LDI instruction. */
-        MIPS_INVAL("OPC_MXU_S32LDI");
-        gen_reserved_instruction(ctx);
-        break;
-    case OPC_MXU_S32LDIR:
-        /* TODO: Implement emulation of S32LDIR instruction. */
-        MIPS_INVAL("OPC_MXU_S32LDIR");
-        gen_reserved_instruction(ctx);
-        break;
-    default:
-        MIPS_INVAL("decode_opc_mxu");
-        gen_reserved_instruction(ctx);
-        break;
-    }
-}
-
-/*
- *
- * Decode MXU pool09
- *
- *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
- *  +-----------+---------+-+-------------------+-------+-----------+
- *  |  SPECIAL2 |    rb   |x|        s12        |  XRa  |MXU__POOL09|
- *  +-----------+---------+-+-------------------+-------+-----------+
- *
- */
-static void decode_opc_mxu__pool09(CPUMIPSState *env, DisasContext *ctx)
-{
-    uint32_t opcode = extract32(ctx->opcode, 5, 0);
-
-    switch (opcode) {
-    case OPC_MXU_S32SDI:
-        /* TODO: Implement emulation of S32SDI instruction. */
-        MIPS_INVAL("OPC_MXU_S32SDI");
-        gen_reserved_instruction(ctx);
-        break;
-    case OPC_MXU_S32SDIR:
-        /* TODO: Implement emulation of S32SDIR instruction. */
-        MIPS_INVAL("OPC_MXU_S32SDIR");
-        gen_reserved_instruction(ctx);
-        break;
-    default:
-        MIPS_INVAL("decode_opc_mxu");
-        gen_reserved_instruction(ctx);
-        break;
-    }
-}
-
-/*
- *
- * Decode MXU pool10
- *
- *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
- *  +-----------+---------+---------+---+-------+-------+-----------+
- *  |  SPECIAL2 |    rb   |    rc   |st2|x x x x|  XRa  |MXU__POOL10|
- *  +-----------+---------+---------+---+-------+-------+-----------+
- *
- */
-static void decode_opc_mxu__pool10(CPUMIPSState *env, DisasContext *ctx)
-{
-    uint32_t opcode = extract32(ctx->opcode, 5, 0);
-
-    switch (opcode) {
-    case OPC_MXU_S32LDIV:
-        /* TODO: Implement emulation of S32LDIV instruction. */
-        MIPS_INVAL("OPC_MXU_S32LDIV");
-        gen_reserved_instruction(ctx);
-        break;
-    case OPC_MXU_S32LDIVR:
-        /* TODO: Implement emulation of S32LDIVR instruction. */
-        MIPS_INVAL("OPC_MXU_S32LDIVR");
-        gen_reserved_instruction(ctx);
-        break;
-    default:
-        MIPS_INVAL("decode_opc_mxu");
-        gen_reserved_instruction(ctx);
-        break;
-    }
-}
-
-/*
- *
- * Decode MXU pool11
- *
- *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
- *  +-----------+---------+---------+---+-------+-------+-----------+
- *  |  SPECIAL2 |    rb   |    rc   |st2|x x x x|  XRa  |MXU__POOL11|
- *  +-----------+---------+---------+---+-------+-------+-----------+
- *
- */
-static void decode_opc_mxu__pool11(CPUMIPSState *env, DisasContext *ctx)
-{
-    uint32_t opcode = extract32(ctx->opcode, 10, 4);
-
-    switch (opcode) {
-    case OPC_MXU_S32SDIV:
-        /* TODO: Implement emulation of S32SDIV instruction. */
-        MIPS_INVAL("OPC_MXU_S32SDIV");
-        gen_reserved_instruction(ctx);
-        break;
-    case OPC_MXU_S32SDIVR:
-        /* TODO: Implement emulation of S32SDIVR instruction. */
-        MIPS_INVAL("OPC_MXU_S32SDIVR");
-        gen_reserved_instruction(ctx);
-        break;
-    default:
-        MIPS_INVAL("decode_opc_mxu");
-        gen_reserved_instruction(ctx);
-        break;
-    }
-}
-
-/*
- *
- * Decode MXU pool12
- *
- *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
- *  +-----------+---+---+-------+-------+-------+-------+-----------+
- *  |  SPECIAL2 |an2|x x|   Xd  |  XRc  |  XRb  |  XRa  |MXU__POOL12|
- *  +-----------+---+---+-------+-------+-------+-------+-----------+
- *
- */
-static void decode_opc_mxu__pool12(CPUMIPSState *env, DisasContext *ctx)
-{
-    uint32_t opcode = extract32(ctx->opcode, 22, 2);
-
-    switch (opcode) {
-    case OPC_MXU_D32ACC:
-        /* TODO: Implement emulation of D32ACC instruction. */
-        MIPS_INVAL("OPC_MXU_D32ACC");
-        gen_reserved_instruction(ctx);
-        break;
-    case OPC_MXU_D32ACCM:
-        /* TODO: Implement emulation of D32ACCM instruction. */
-        MIPS_INVAL("OPC_MXU_D32ACCM");
-        gen_reserved_instruction(ctx);
-        break;
-    case OPC_MXU_D32ASUM:
-        /* TODO: Implement emulation of D32ASUM instruction. */
-        MIPS_INVAL("OPC_MXU_D32ASUM");
-        gen_reserved_instruction(ctx);
-        break;
-    default:
-        MIPS_INVAL("decode_opc_mxu");
-        gen_reserved_instruction(ctx);
-        break;
-    }
-}
-
-/*
- *
- * Decode MXU pool13
- *
- *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
- *  +-----------+---+---+-------+-------+-------+-------+-----------+
- *  |  SPECIAL2 |en2|x x|0 0 0 0|  XRc  |  XRb  |  XRa  |MXU__POOL13|
- *  +-----------+---+---+-------+-------+-------+-------+-----------+
- *
- */
-static void decode_opc_mxu__pool13(CPUMIPSState *env, DisasContext *ctx)
-{
-    uint32_t opcode = extract32(ctx->opcode, 22, 2);
-
-    switch (opcode) {
-    case OPC_MXU_Q16ACC:
-        /* TODO: Implement emulation of Q16ACC instruction. */
-        MIPS_INVAL("OPC_MXU_Q16ACC");
-        gen_reserved_instruction(ctx);
-        break;
-    case OPC_MXU_Q16ACCM:
-        /* TODO: Implement emulation of Q16ACCM instruction. */
-        MIPS_INVAL("OPC_MXU_Q16ACCM");
-        gen_reserved_instruction(ctx);
-        break;
-    case OPC_MXU_Q16ASUM:
-        /* TODO: Implement emulation of Q16ASUM instruction. */
-        MIPS_INVAL("OPC_MXU_Q16ASUM");
-        gen_reserved_instruction(ctx);
-        break;
-    default:
-        MIPS_INVAL("decode_opc_mxu");
-        gen_reserved_instruction(ctx);
-        break;
-    }
-}
-
-/*
- *
- * Decode MXU pool14
- *
- *  Q8ADDE, Q8ACCE:
- *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
- *  +-----------+---+---+-------+-------+-------+-------+-----------+
- *  |  SPECIAL2 |0 0|x x|  XRd  |  XRc  |  XRb  |  XRa  |MXU__POOL14|
- *  +-----------+---+---+-------+-------+-------+-------+-----------+
- *
- *  D8SUM, D8SUMC:
- *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
- *  +-----------+---+---+-------+-------+-------+-------+-----------+
- *  |  SPECIAL2 |en2|x x|0 0 0 0|  XRc  |  XRb  |  XRa  |MXU__POOL14|
- *  +-----------+---+---+-------+-------+-------+-------+-----------+
- *
- */
-static void decode_opc_mxu__pool14(CPUMIPSState *env, DisasContext *ctx)
-{
-    uint32_t opcode = extract32(ctx->opcode, 22, 2);
-
-    switch (opcode) {
-    case OPC_MXU_Q8ADDE:
-        /* TODO: Implement emulation of Q8ADDE instruction. */
-        MIPS_INVAL("OPC_MXU_Q8ADDE");
-        gen_reserved_instruction(ctx);
-        break;
-    case OPC_MXU_D8SUM:
-        /* TODO: Implement emulation of D8SUM instruction. */
-        MIPS_INVAL("OPC_MXU_D8SUM");
-        gen_reserved_instruction(ctx);
-        break;
-    case OPC_MXU_D8SUMC:
-        /* TODO: Implement emulation of D8SUMC instruction. */
-        MIPS_INVAL("OPC_MXU_D8SUMC");
-        gen_reserved_instruction(ctx);
-        break;
-    default:
-        MIPS_INVAL("decode_opc_mxu");
-        gen_reserved_instruction(ctx);
-        break;
-    }
-}
-
-/*
- *
- * Decode MXU pool15
- *
- *  S32MUL, S32MULU, S32EXTRV:
- *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
- *  +-----------+---------+---------+---+-------+-------+-----------+
- *  |  SPECIAL2 |    rs   |    rt   |x x|  XRd  |  XRa  |MXU__POOL15|
- *  +-----------+---------+---------+---+-------+-------+-----------+
- *
- *  S32EXTR:
- *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
- *  +-----------+---------+---------+---+-------+-------+-----------+
- *  |  SPECIAL2 |    rb   |   sft5  |x x|  XRd  |  XRa  |MXU__POOL15|
- *  +-----------+---------+---------+---+-------+-------+-----------+
- *
- */
-static void decode_opc_mxu__pool15(CPUMIPSState *env, DisasContext *ctx)
-{
-    uint32_t opcode = extract32(ctx->opcode, 14, 2);
-
-    switch (opcode) {
-    case OPC_MXU_S32MUL:
-        /* TODO: Implement emulation of S32MUL instruction. */
-        MIPS_INVAL("OPC_MXU_S32MUL");
-        gen_reserved_instruction(ctx);
-        break;
-    case OPC_MXU_S32MULU:
-        /* TODO: Implement emulation of S32MULU instruction. */
-        MIPS_INVAL("OPC_MXU_S32MULU");
-        gen_reserved_instruction(ctx);
-        break;
-    case OPC_MXU_S32EXTR:
-        /* TODO: Implement emulation of S32EXTR instruction. */
-        MIPS_INVAL("OPC_MXU_S32EXTR");
-        gen_reserved_instruction(ctx);
-        break;
-    case OPC_MXU_S32EXTRV:
-        /* TODO: Implement emulation of S32EXTRV instruction. */
-        MIPS_INVAL("OPC_MXU_S32EXTRV");
-        gen_reserved_instruction(ctx);
-        break;
-    default:
-        MIPS_INVAL("decode_opc_mxu");
-        gen_reserved_instruction(ctx);
-        break;
-    }
-}
-
-/*
- *
- * Decode MXU pool16
- *
- *  D32SARW:
- *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
- *  +-----------+---------+-----+-------+-------+-------+-----------+
- *  |  SPECIAL2 |    rb   |x x x|  XRc  |  XRb  |  XRa  |MXU__POOL16|
- *  +-----------+---------+-----+-------+-------+-------+-----------+
- *
- *  S32ALN:
- *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
- *  +-----------+---------+-----+-------+-------+-------+-----------+
- *  |  SPECIAL2 |    rs   |x x x|  XRc  |  XRb  |  XRa  |MXU__POOL16|
- *  +-----------+---------+-----+-------+-------+-------+-----------+
- *
- *  S32ALNI:
- *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
- *  +-----------+-----+---+-----+-------+-------+-------+-----------+
- *  |  SPECIAL2 |  s3 |0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL16|
- *  +-----------+-----+---+-----+-------+-------+-------+-----------+
- *
- *  S32LUI:
- *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
- *  +-----------+-----+---+-----+-------+---------------+-----------+
- *  |  SPECIAL2 |optn3|0 0|x x x|  XRc  |       s8      |MXU__POOL16|
- *  +-----------+-----+---+-----+-------+---------------+-----------+
- *
- *  S32NOR, S32AND, S32OR, S32XOR:
- *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
- *  +-----------+---------+-----+-------+-------+-------+-----------+
- *  |  SPECIAL2 |0 0 0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL16|
- *  +-----------+---------+-----+-------+-------+-------+-----------+
- *
- */
 static void decode_opc_mxu__pool16(CPUMIPSState *env, DisasContext *ctx)
 {
     uint32_t opcode = extract32(ctx->opcode, 18, 3);
 
     switch (opcode) {
-    case OPC_MXU_D32SARW:
-        /* TODO: Implement emulation of D32SARW instruction. */
-        MIPS_INVAL("OPC_MXU_D32SARW");
-        gen_reserved_instruction(ctx);
-        break;
-    case OPC_MXU_S32ALN:
-        /* TODO: Implement emulation of S32ALN instruction. */
-        MIPS_INVAL("OPC_MXU_S32ALN");
-        gen_reserved_instruction(ctx);
-        break;
     case OPC_MXU_S32ALNI:
         gen_mxu_S32ALNI(ctx);
         break;
-    case OPC_MXU_S32LUI:
-        /* TODO: Implement emulation of S32LUI instruction. */
-        MIPS_INVAL("OPC_MXU_S32LUI");
-        gen_reserved_instruction(ctx);
-        break;
     case OPC_MXU_S32NOR:
         gen_mxu_S32NOR(ctx);
         break;
@@ -26644,114 +25761,6 @@ static void decode_opc_mxu__pool16(CPUMIPSState *env, DisasContext *ctx)
     }
 }
 
-/*
- *
- * Decode MXU pool17
- *
- *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
- *  +-----------+---------+---------+---+---------+-----+-----------+
- *  |  SPECIAL2 |    rs   |    rt   |0 0|    rd   |x x x|MXU__POOL15|
- *  +-----------+---------+---------+---+---------+-----+-----------+
- *
- */
-static void decode_opc_mxu__pool17(CPUMIPSState *env, DisasContext *ctx)
-{
-    uint32_t opcode = extract32(ctx->opcode, 6, 2);
-
-    switch (opcode) {
-    case OPC_MXU_LXW:
-        /* TODO: Implement emulation of LXW instruction. */
-        MIPS_INVAL("OPC_MXU_LXW");
-        gen_reserved_instruction(ctx);
-        break;
-    case OPC_MXU_LXH:
-        /* TODO: Implement emulation of LXH instruction. */
-        MIPS_INVAL("OPC_MXU_LXH");
-        gen_reserved_instruction(ctx);
-        break;
-    case OPC_MXU_LXHU:
-        /* TODO: Implement emulation of LXHU instruction. */
-        MIPS_INVAL("OPC_MXU_LXHU");
-        gen_reserved_instruction(ctx);
-        break;
-    case OPC_MXU_LXB:
-        /* TODO: Implement emulation of LXB instruction. */
-        MIPS_INVAL("OPC_MXU_LXB");
-        gen_reserved_instruction(ctx);
-        break;
-    case OPC_MXU_LXBU:
-        /* TODO: Implement emulation of LXBU instruction. */
-        MIPS_INVAL("OPC_MXU_LXBU");
-        gen_reserved_instruction(ctx);
-        break;
-    default:
-        MIPS_INVAL("decode_opc_mxu");
-        gen_reserved_instruction(ctx);
-        break;
-    }
-}
-/*
- *
- * Decode MXU pool18
- *
- *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
- *  +-----------+---------+-----+-------+-------+-------+-----------+
- *  |  SPECIAL2 |    rb   |x x x|  XRd  |  XRa  |0 0 0 0|MXU__POOL18|
- *  +-----------+---------+-----+-------+-------+-------+-----------+
- *
- */
-static void decode_opc_mxu__pool18(CPUMIPSState *env, DisasContext *ctx)
-{
-    uint32_t opcode = extract32(ctx->opcode, 18, 3);
-
-    switch (opcode) {
-    case OPC_MXU_D32SLLV:
-        /* TODO: Implement emulation of D32SLLV instruction. */
-        MIPS_INVAL("OPC_MXU_D32SLLV");
-        gen_reserved_instruction(ctx);
-        break;
-    case OPC_MXU_D32SLRV:
-        /* TODO: Implement emulation of D32SLRV instruction. */
-        MIPS_INVAL("OPC_MXU_D32SLRV");
-        gen_reserved_instruction(ctx);
-        break;
-    case OPC_MXU_D32SARV:
-        /* TODO: Implement emulation of D32SARV instruction. */
-        MIPS_INVAL("OPC_MXU_D32SARV");
-        gen_reserved_instruction(ctx);
-        break;
-    case OPC_MXU_Q16SLLV:
-        /* TODO: Implement emulation of Q16SLLV instruction. */
-        MIPS_INVAL("OPC_MXU_Q16SLLV");
-        gen_reserved_instruction(ctx);
-        break;
-    case OPC_MXU_Q16SLRV:
-        /* TODO: Implement emulation of Q16SLRV instruction. */
-        MIPS_INVAL("OPC_MXU_Q16SLRV");
-        gen_reserved_instruction(ctx);
-        break;
-    case OPC_MXU_Q16SARV:
-        /* TODO: Implement emulation of Q16SARV instruction. */
-        MIPS_INVAL("OPC_MXU_Q16SARV");
-        gen_reserved_instruction(ctx);
-        break;
-    default:
-        MIPS_INVAL("decode_opc_mxu");
-        gen_reserved_instruction(ctx);
-        break;
-    }
-}
-
-/*
- *
- * Decode MXU pool19
- *
- *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
- *  +-----------+---+---+-------+-------+-------+-------+-----------+
- *  |  SPECIAL2 |0 0|x x|  XRd  |  XRc  |  XRb  |  XRa  |MXU__POOL19|
- *  +-----------+---+---+-------+-------+-------+-------+-----------+
- *
- */
 static void decode_opc_mxu__pool19(CPUMIPSState *env, DisasContext *ctx)
 {
     uint32_t opcode = extract32(ctx->opcode, 22, 2);
@@ -26768,107 +25777,11 @@ static void decode_opc_mxu__pool19(CPUMIPSState *env, DisasContext *ctx)
     }
 }
 
-/*
- *
- * Decode MXU pool20
- *
- *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
- *  +-----------+---------+-----+-------+-------+-------+-----------+
- *  |  SPECIAL2 |0 0 0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL20|
- *  +-----------+---------+-----+-------+-------+-------+-----------+
- *
- */
-static void decode_opc_mxu__pool20(CPUMIPSState *env, DisasContext *ctx)
-{
-    uint32_t opcode = extract32(ctx->opcode, 18, 3);
-
-    switch (opcode) {
-    case OPC_MXU_Q8MOVZ:
-        /* TODO: Implement emulation of Q8MOVZ instruction. */
-        MIPS_INVAL("OPC_MXU_Q8MOVZ");
-        gen_reserved_instruction(ctx);
-        break;
-    case OPC_MXU_Q8MOVN:
-        /* TODO: Implement emulation of Q8MOVN instruction. */
-        MIPS_INVAL("OPC_MXU_Q8MOVN");
-        gen_reserved_instruction(ctx);
-        break;
-    case OPC_MXU_D16MOVZ:
-        /* TODO: Implement emulation of D16MOVZ instruction. */
-        MIPS_INVAL("OPC_MXU_D16MOVZ");
-        gen_reserved_instruction(ctx);
-        break;
-    case OPC_MXU_D16MOVN:
-        /* TODO: Implement emulation of D16MOVN instruction. */
-        MIPS_INVAL("OPC_MXU_D16MOVN");
-        gen_reserved_instruction(ctx);
-        break;
-    case OPC_MXU_S32MOVZ:
-        /* TODO: Implement emulation of S32MOVZ instruction. */
-        MIPS_INVAL("OPC_MXU_S32MOVZ");
-        gen_reserved_instruction(ctx);
-        break;
-    case OPC_MXU_S32MOVN:
-        /* TODO: Implement emulation of S32MOVN instruction. */
-        MIPS_INVAL("OPC_MXU_S32MOVN");
-        gen_reserved_instruction(ctx);
-        break;
-    default:
-        MIPS_INVAL("decode_opc_mxu");
-        gen_reserved_instruction(ctx);
-        break;
-    }
-}
-
-/*
- *
- * Decode MXU pool21
- *
- *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
- *  +-----------+---+---+-------+-------+-------+-------+-----------+
- *  |  SPECIAL2 |an2|x x|  XRd  |  XRc  |  XRb  |  XRa  |MXU__POOL21|
- *  +-----------+---+---+-------+-------+-------+-------+-----------+
- *
- */
-static void decode_opc_mxu__pool21(CPUMIPSState *env, DisasContext *ctx)
-{
-    uint32_t opcode = extract32(ctx->opcode, 22, 2);
-
-    switch (opcode) {
-    case OPC_MXU_Q8MAC:
-        /* TODO: Implement emulation of Q8MAC instruction. */
-        MIPS_INVAL("OPC_MXU_Q8MAC");
-        gen_reserved_instruction(ctx);
-        break;
-    case OPC_MXU_Q8MACSU:
-        /* TODO: Implement emulation of Q8MACSU instruction. */
-        MIPS_INVAL("OPC_MXU_Q8MACSU");
-        gen_reserved_instruction(ctx);
-        break;
-    default:
-        MIPS_INVAL("decode_opc_mxu");
-        gen_reserved_instruction(ctx);
-        break;
-    }
-}
-
-
 /*
  * Main MXU decoding function
- *
- *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
- *  +-----------+---------------------------------------+-----------+
- *  |  SPECIAL2 |                                       |x x x x x x|
- *  +-----------+---------------------------------------+-----------+
- *
  */
 static void decode_opc_mxu(CPUMIPSState *env, DisasContext *ctx)
 {
-    /*
-     * TODO: Investigate necessity of including handling of
-     * CLZ, CLO, SDBB in this function, as they belong to
-     * SPECIAL2 opcode space for regular pre-R6 MIPS ISAs.
-     */
     uint32_t opcode = extract32(ctx->opcode, 0, 6);
 
     if (opcode == OPC__MXU_MUL) {
@@ -26903,226 +25816,27 @@ static void decode_opc_mxu(CPUMIPSState *env, DisasContext *ctx)
         tcg_gen_brcondi_tl(TCG_COND_NE, t_mxu_cr, MXU_CR_MXU_EN, l_exit);
 
         switch (opcode) {
-        case OPC_MXU_S32MADD:
-            /* TODO: Implement emulation of S32MADD instruction. */
-            MIPS_INVAL("OPC_MXU_S32MADD");
-            gen_reserved_instruction(ctx);
-            break;
-        case OPC_MXU_S32MADDU:
-            /* TODO: Implement emulation of S32MADDU instruction. */
-            MIPS_INVAL("OPC_MXU_S32MADDU");
-            gen_reserved_instruction(ctx);
-            break;
         case OPC_MXU__POOL00:
             decode_opc_mxu__pool00(env, ctx);
             break;
-        case OPC_MXU_S32MSUB:
-            /* TODO: Implement emulation of S32MSUB instruction. */
-            MIPS_INVAL("OPC_MXU_S32MSUB");
-            gen_reserved_instruction(ctx);
-            break;
-        case OPC_MXU_S32MSUBU:
-            /* TODO: Implement emulation of S32MSUBU instruction. */
-            MIPS_INVAL("OPC_MXU_S32MSUBU");
-            gen_reserved_instruction(ctx);
-            break;
-        case OPC_MXU__POOL01:
-            decode_opc_mxu__pool01(env, ctx);
-            break;
-        case OPC_MXU__POOL02:
-            decode_opc_mxu__pool02(env, ctx);
-            break;
         case OPC_MXU_D16MUL:
             gen_mxu_d16mul(ctx);
             break;
-        case OPC_MXU__POOL03:
-            decode_opc_mxu__pool03(env, ctx);
-            break;
         case OPC_MXU_D16MAC:
             gen_mxu_d16mac(ctx);
             break;
-        case OPC_MXU_D16MACF:
-            /* TODO: Implement emulation of D16MACF instruction. */
-            MIPS_INVAL("OPC_MXU_D16MACF");
-            gen_reserved_instruction(ctx);
-            break;
-        case OPC_MXU_D16MADL:
-            /* TODO: Implement emulation of D16MADL instruction. */
-            MIPS_INVAL("OPC_MXU_D16MADL");
-            gen_reserved_instruction(ctx);
-            break;
-        case OPC_MXU_S16MAD:
-            /* TODO: Implement emulation of S16MAD instruction. */
-            MIPS_INVAL("OPC_MXU_S16MAD");
-            gen_reserved_instruction(ctx);
-            break;
-        case OPC_MXU_Q16ADD:
-            /* TODO: Implement emulation of Q16ADD instruction. */
-            MIPS_INVAL("OPC_MXU_Q16ADD");
-            gen_reserved_instruction(ctx);
-            break;
-        case OPC_MXU_D16MACE:
-            /* TODO: Implement emulation of D16MACE instruction. */
-            MIPS_INVAL("OPC_MXU_D16MACE");
-            gen_reserved_instruction(ctx);
-            break;
         case OPC_MXU__POOL04:
             decode_opc_mxu__pool04(env, ctx);
             break;
-        case OPC_MXU__POOL05:
-            decode_opc_mxu__pool05(env, ctx);
-            break;
-        case OPC_MXU__POOL06:
-            decode_opc_mxu__pool06(env, ctx);
-            break;
-        case OPC_MXU__POOL07:
-            decode_opc_mxu__pool07(env, ctx);
-            break;
-        case OPC_MXU__POOL08:
-            decode_opc_mxu__pool08(env, ctx);
-            break;
-        case OPC_MXU__POOL09:
-            decode_opc_mxu__pool09(env, ctx);
-            break;
-        case OPC_MXU__POOL10:
-            decode_opc_mxu__pool10(env, ctx);
-            break;
-        case OPC_MXU__POOL11:
-            decode_opc_mxu__pool11(env, ctx);
-            break;
-        case OPC_MXU_D32ADD:
-            /* TODO: Implement emulation of D32ADD instruction. */
-            MIPS_INVAL("OPC_MXU_D32ADD");
-            gen_reserved_instruction(ctx);
-            break;
-        case OPC_MXU__POOL12:
-            decode_opc_mxu__pool12(env, ctx);
-            break;
-        case OPC_MXU__POOL13:
-            decode_opc_mxu__pool13(env, ctx);
-            break;
-        case OPC_MXU__POOL14:
-            decode_opc_mxu__pool14(env, ctx);
-            break;
-        case OPC_MXU_Q8ACCE:
-            /* TODO: Implement emulation of Q8ACCE instruction. */
-            MIPS_INVAL("OPC_MXU_Q8ACCE");
-            gen_reserved_instruction(ctx);
-            break;
         case OPC_MXU_S8LDD:
             gen_mxu_s8ldd(ctx);
             break;
-        case OPC_MXU_S8STD:
-            /* TODO: Implement emulation of S8STD instruction. */
-            MIPS_INVAL("OPC_MXU_S8STD");
-            gen_reserved_instruction(ctx);
-            break;
-        case OPC_MXU_S8LDI:
-            /* TODO: Implement emulation of S8LDI instruction. */
-            MIPS_INVAL("OPC_MXU_S8LDI");
-            gen_reserved_instruction(ctx);
-            break;
-        case OPC_MXU_S8SDI:
-            /* TODO: Implement emulation of S8SDI instruction. */
-            MIPS_INVAL("OPC_MXU_S8SDI");
-            gen_reserved_instruction(ctx);
-            break;
-        case OPC_MXU__POOL15:
-            decode_opc_mxu__pool15(env, ctx);
-            break;
         case OPC_MXU__POOL16:
             decode_opc_mxu__pool16(env, ctx);
             break;
-        case OPC_MXU__POOL17:
-            decode_opc_mxu__pool17(env, ctx);
-            break;
-        case OPC_MXU_S16LDD:
-            /* TODO: Implement emulation of S16LDD instruction. */
-            MIPS_INVAL("OPC_MXU_S16LDD");
-            gen_reserved_instruction(ctx);
-            break;
-        case OPC_MXU_S16STD:
-            /* TODO: Implement emulation of S16STD instruction. */
-            MIPS_INVAL("OPC_MXU_S16STD");
-            gen_reserved_instruction(ctx);
-            break;
-        case OPC_MXU_S16LDI:
-            /* TODO: Implement emulation of S16LDI instruction. */
-            MIPS_INVAL("OPC_MXU_S16LDI");
-            gen_reserved_instruction(ctx);
-            break;
-        case OPC_MXU_S16SDI:
-            /* TODO: Implement emulation of S16SDI instruction. */
-            MIPS_INVAL("OPC_MXU_S16SDI");
-            gen_reserved_instruction(ctx);
-            break;
-        case OPC_MXU_D32SLL:
-            /* TODO: Implement emulation of D32SLL instruction. */
-            MIPS_INVAL("OPC_MXU_D32SLL");
-            gen_reserved_instruction(ctx);
-            break;
-        case OPC_MXU_D32SLR:
-            /* TODO: Implement emulation of D32SLR instruction. */
-            MIPS_INVAL("OPC_MXU_D32SLR");
-            gen_reserved_instruction(ctx);
-            break;
-        case OPC_MXU_D32SARL:
-            /* TODO: Implement emulation of D32SARL instruction. */
-            MIPS_INVAL("OPC_MXU_D32SARL");
-            gen_reserved_instruction(ctx);
-            break;
-        case OPC_MXU_D32SAR:
-            /* TODO: Implement emulation of D32SAR instruction. */
-            MIPS_INVAL("OPC_MXU_D32SAR");
-            gen_reserved_instruction(ctx);
-            break;
-        case OPC_MXU_Q16SLL:
-            /* TODO: Implement emulation of Q16SLL instruction. */
-            MIPS_INVAL("OPC_MXU_Q16SLL");
-            gen_reserved_instruction(ctx);
-            break;
-        case OPC_MXU_Q16SLR:
-            /* TODO: Implement emulation of Q16SLR instruction. */
-            MIPS_INVAL("OPC_MXU_Q16SLR");
-            gen_reserved_instruction(ctx);
-            break;
-        case OPC_MXU__POOL18:
-            decode_opc_mxu__pool18(env, ctx);
-            break;
-        case OPC_MXU_Q16SAR:
-            /* TODO: Implement emulation of Q16SAR instruction. */
-            MIPS_INVAL("OPC_MXU_Q16SAR");
-            gen_reserved_instruction(ctx);
-            break;
         case OPC_MXU__POOL19:
             decode_opc_mxu__pool19(env, ctx);
             break;
-        case OPC_MXU__POOL20:
-            decode_opc_mxu__pool20(env, ctx);
-            break;
-        case OPC_MXU__POOL21:
-            decode_opc_mxu__pool21(env, ctx);
-            break;
-        case OPC_MXU_Q16SCOP:
-            /* TODO: Implement emulation of Q16SCOP instruction. */
-            MIPS_INVAL("OPC_MXU_Q16SCOP");
-            gen_reserved_instruction(ctx);
-            break;
-        case OPC_MXU_Q8MADL:
-            /* TODO: Implement emulation of Q8MADL instruction. */
-            MIPS_INVAL("OPC_MXU_Q8MADL");
-            gen_reserved_instruction(ctx);
-            break;
-        case OPC_MXU_S32SFL:
-            /* TODO: Implement emulation of S32SFL instruction. */
-            MIPS_INVAL("OPC_MXU_S32SFL");
-            gen_reserved_instruction(ctx);
-            break;
-        case OPC_MXU_Q8SAD:
-            /* TODO: Implement emulation of Q8SAD instruction. */
-            MIPS_INVAL("OPC_MXU_Q8SAD");
-            gen_reserved_instruction(ctx);
-            break;
         default:
             MIPS_INVAL("decode_opc_mxu");
             gen_reserved_instruction(ctx);
-- 
2.26.2



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

* [PATCH v3 03/10] target/mips: Remove unused CPUMIPSState* from MXU functions
  2021-02-22 22:38 [PATCH v3 00/10] target/mips: Extract MXU code to new mxu_translate.c file Philippe Mathieu-Daudé
  2021-02-22 22:38 ` [PATCH v3 01/10] target/mips: Rewrite complex ifdef'ry Philippe Mathieu-Daudé
  2021-02-22 22:38 ` [PATCH v3 02/10] target/mips: Remove XBurst Media eXtension Unit dead code Philippe Mathieu-Daudé
@ 2021-02-22 22:38 ` Philippe Mathieu-Daudé
  2021-02-24  1:22   ` Richard Henderson
  2021-02-22 22:38 ` [PATCH v3 04/10] target/mips: Pass instruction opcode to decode_opc_mxu() Philippe Mathieu-Daudé
                   ` (6 subsequent siblings)
  9 siblings, 1 reply; 21+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-02-22 22:38 UTC (permalink / raw)
  To: qemu-devel
  Cc: Aleksandar Rikalo, Richard Henderson, Aurelien Jarno,
	Philippe Mathieu-Daudé

None of these MXU functions use their CPUMIPSState* env argument,
remove it.

Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 target/mips/translate.c | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index a53ce6adb9a..6f5ccd667da 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -25694,7 +25694,7 @@ static void gen_mxu_S32ALNI(DisasContext *ctx)
  * =======================
  */
 
-static void decode_opc_mxu__pool00(CPUMIPSState *env, DisasContext *ctx)
+static void decode_opc_mxu__pool00(DisasContext *ctx)
 {
     uint32_t opcode = extract32(ctx->opcode, 18, 3);
 
@@ -25718,7 +25718,7 @@ static void decode_opc_mxu__pool00(CPUMIPSState *env, DisasContext *ctx)
     }
 }
 
-static void decode_opc_mxu__pool04(CPUMIPSState *env, DisasContext *ctx)
+static void decode_opc_mxu__pool04(DisasContext *ctx)
 {
     uint32_t opcode = extract32(ctx->opcode, 20, 1);
 
@@ -25734,7 +25734,7 @@ static void decode_opc_mxu__pool04(CPUMIPSState *env, DisasContext *ctx)
     }
 }
 
-static void decode_opc_mxu__pool16(CPUMIPSState *env, DisasContext *ctx)
+static void decode_opc_mxu__pool16(DisasContext *ctx)
 {
     uint32_t opcode = extract32(ctx->opcode, 18, 3);
 
@@ -25761,7 +25761,7 @@ static void decode_opc_mxu__pool16(CPUMIPSState *env, DisasContext *ctx)
     }
 }
 
-static void decode_opc_mxu__pool19(CPUMIPSState *env, DisasContext *ctx)
+static void decode_opc_mxu__pool19(DisasContext *ctx)
 {
     uint32_t opcode = extract32(ctx->opcode, 22, 2);
 
@@ -25780,7 +25780,7 @@ static void decode_opc_mxu__pool19(CPUMIPSState *env, DisasContext *ctx)
 /*
  * Main MXU decoding function
  */
-static void decode_opc_mxu(CPUMIPSState *env, DisasContext *ctx)
+static void decode_opc_mxu(DisasContext *ctx)
 {
     uint32_t opcode = extract32(ctx->opcode, 0, 6);
 
@@ -25817,7 +25817,7 @@ static void decode_opc_mxu(CPUMIPSState *env, DisasContext *ctx)
 
         switch (opcode) {
         case OPC_MXU__POOL00:
-            decode_opc_mxu__pool00(env, ctx);
+            decode_opc_mxu__pool00(ctx);
             break;
         case OPC_MXU_D16MUL:
             gen_mxu_d16mul(ctx);
@@ -25826,16 +25826,16 @@ static void decode_opc_mxu(CPUMIPSState *env, DisasContext *ctx)
             gen_mxu_d16mac(ctx);
             break;
         case OPC_MXU__POOL04:
-            decode_opc_mxu__pool04(env, ctx);
+            decode_opc_mxu__pool04(ctx);
             break;
         case OPC_MXU_S8LDD:
             gen_mxu_s8ldd(ctx);
             break;
         case OPC_MXU__POOL16:
-            decode_opc_mxu__pool16(env, ctx);
+            decode_opc_mxu__pool16(ctx);
             break;
         case OPC_MXU__POOL19:
-            decode_opc_mxu__pool19(env, ctx);
+            decode_opc_mxu__pool19(ctx);
             break;
         default:
             MIPS_INVAL("decode_opc_mxu");
@@ -26995,7 +26995,7 @@ static bool decode_opc_legacy(CPUMIPSState *env, DisasContext *ctx)
 #endif
 #if !defined(TARGET_MIPS64)
         if (ctx->insn_flags & ASE_MXU) {
-            decode_opc_mxu(env, ctx);
+            decode_opc_mxu(ctx);
             break;
         }
 #endif
-- 
2.26.2



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

* [PATCH v3 04/10] target/mips: Pass instruction opcode to decode_opc_mxu()
  2021-02-22 22:38 [PATCH v3 00/10] target/mips: Extract MXU code to new mxu_translate.c file Philippe Mathieu-Daudé
                   ` (2 preceding siblings ...)
  2021-02-22 22:38 ` [PATCH v3 03/10] target/mips: Remove unused CPUMIPSState* from MXU functions Philippe Mathieu-Daudé
@ 2021-02-22 22:38 ` Philippe Mathieu-Daudé
  2021-02-24  1:22   ` Richard Henderson
  2021-02-22 22:38 ` [PATCH v3 05/10] target/mips: Extract decode_ase_mxu() from decode_opc_mxu() Philippe Mathieu-Daudé
                   ` (5 subsequent siblings)
  9 siblings, 1 reply; 21+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-02-22 22:38 UTC (permalink / raw)
  To: qemu-devel
  Cc: Aleksandar Rikalo, Richard Henderson, Aurelien Jarno,
	Philippe Mathieu-Daudé

In the next commit we'll make decode_opc_mxu() match decodetree
prototype by returning a boolean. First pass ctx->opcode as an
argument.

Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 target/mips/translate.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index 6f5ccd667da..9e875fa4a25 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -25780,17 +25780,17 @@ static void decode_opc_mxu__pool19(DisasContext *ctx)
 /*
  * Main MXU decoding function
  */
-static void decode_opc_mxu(DisasContext *ctx)
+static void decode_opc_mxu(DisasContext *ctx, uint32_t insn)
 {
-    uint32_t opcode = extract32(ctx->opcode, 0, 6);
+    uint32_t opcode = extract32(insn, 0, 6);
 
     if (opcode == OPC__MXU_MUL) {
         uint32_t  rs, rt, rd, op1;
 
-        rs = extract32(ctx->opcode, 21, 5);
-        rt = extract32(ctx->opcode, 16, 5);
-        rd = extract32(ctx->opcode, 11, 5);
-        op1 = MASK_SPECIAL2(ctx->opcode);
+        rs = extract32(insn, 21, 5);
+        rt = extract32(insn, 16, 5);
+        rd = extract32(insn, 11, 5);
+        op1 = MASK_SPECIAL2(insn);
 
         gen_arith(ctx, op1, rd, rs, rt);
 
@@ -26995,7 +26995,7 @@ static bool decode_opc_legacy(CPUMIPSState *env, DisasContext *ctx)
 #endif
 #if !defined(TARGET_MIPS64)
         if (ctx->insn_flags & ASE_MXU) {
-            decode_opc_mxu(ctx);
+            decode_opc_mxu(ctx, ctx->opcode);
             break;
         }
 #endif
-- 
2.26.2



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

* [PATCH v3 05/10] target/mips: Extract decode_ase_mxu() from decode_opc_mxu()
  2021-02-22 22:38 [PATCH v3 00/10] target/mips: Extract MXU code to new mxu_translate.c file Philippe Mathieu-Daudé
                   ` (3 preceding siblings ...)
  2021-02-22 22:38 ` [PATCH v3 04/10] target/mips: Pass instruction opcode to decode_opc_mxu() Philippe Mathieu-Daudé
@ 2021-02-22 22:38 ` Philippe Mathieu-Daudé
  2021-02-24  1:25   ` Richard Henderson
  2021-02-22 22:38 ` [PATCH v3 06/10] target/mips: Use OPC_MUL instead of OPC__MXU_MUL Philippe Mathieu-Daudé
                   ` (4 subsequent siblings)
  9 siblings, 1 reply; 21+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-02-22 22:38 UTC (permalink / raw)
  To: qemu-devel
  Cc: Aleksandar Rikalo, Richard Henderson, Aurelien Jarno,
	Philippe Mathieu-Daudé

To easily convert MXU code to decodetree, extract decode_ase_mxu()
from decode_opc_mxu(), making it return a boolean.
We will keep decode_opc_mxu() in the translate.c unit because it
calls gen_arith().

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 9e875fa4a25..6f853fcdcce 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -25777,34 +25777,18 @@ static void decode_opc_mxu__pool19(DisasContext *ctx)
     }
 }
 
-/*
- * Main MXU decoding function
- */
-static void decode_opc_mxu(DisasContext *ctx, uint32_t insn)
+static bool decode_ase_mxu(DisasContext *ctx, uint32_t insn)
 {
     uint32_t opcode = extract32(insn, 0, 6);
 
-    if (opcode == OPC__MXU_MUL) {
-        uint32_t  rs, rt, rd, op1;
-
-        rs = extract32(insn, 21, 5);
-        rt = extract32(insn, 16, 5);
-        rd = extract32(insn, 11, 5);
-        op1 = MASK_SPECIAL2(insn);
-
-        gen_arith(ctx, op1, rd, rs, rt);
-
-        return;
-    }
-
     if (opcode == OPC_MXU_S32M2I) {
         gen_mxu_s32m2i(ctx);
-        return;
+        return true;
     }
 
     if (opcode == OPC_MXU_S32I2M) {
         gen_mxu_s32i2m(ctx);
-        return;
+        return true;
     }
 
     {
@@ -25845,6 +25829,29 @@ static void decode_opc_mxu(DisasContext *ctx, uint32_t insn)
         gen_set_label(l_exit);
         tcg_temp_free(t_mxu_cr);
     }
+
+    return true;
+}
+
+/*
+ * Main MXU decoding function
+ */
+static void decode_opc_mxu(DisasContext *ctx, uint32_t insn)
+{
+    if (extract32(insn, 0, 6) == OPC__MXU_MUL) {
+        uint32_t  rs, rt, rd, op1;
+
+        rs = extract32(insn, 21, 5);
+        rt = extract32(insn, 16, 5);
+        rd = extract32(insn, 11, 5);
+        op1 = MASK_SPECIAL2(insn);
+
+        gen_arith(ctx, op1, rd, rs, rt);
+
+        return;
+    }
+
+    decode_ase_mxu(ctx, insn);
 }
 
 #endif /* !defined(TARGET_MIPS64) */
-- 
2.26.2



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

* [PATCH v3 06/10] target/mips: Use OPC_MUL instead of OPC__MXU_MUL
  2021-02-22 22:38 [PATCH v3 00/10] target/mips: Extract MXU code to new mxu_translate.c file Philippe Mathieu-Daudé
                   ` (4 preceding siblings ...)
  2021-02-22 22:38 ` [PATCH v3 05/10] target/mips: Extract decode_ase_mxu() from decode_opc_mxu() Philippe Mathieu-Daudé
@ 2021-02-22 22:38 ` Philippe Mathieu-Daudé
  2021-02-24  1:34   ` Richard Henderson
  2021-02-22 22:38 ` [PATCH v3 07/10] target/mips: Introduce mxu_translate_init() helper Philippe Mathieu-Daudé
                   ` (3 subsequent siblings)
  9 siblings, 1 reply; 21+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-02-22 22:38 UTC (permalink / raw)
  To: qemu-devel
  Cc: Aleksandar Rikalo, Richard Henderson, Aurelien Jarno,
	Philippe Mathieu-Daudé

We already have a macro and definition to extract / check
the Special2 MUL opcode. Use it instead of the unnecessary
OPC__MXU_MUL macro.

Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 target/mips/translate.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index 6f853fcdcce..c897f3900d8 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -1464,7 +1464,6 @@ enum {
  */
 
 enum {
-    OPC__MXU_MUL     = 0x02,
     OPC_MXU__POOL00  = 0x03,
     OPC_MXU_D16MUL   = 0x08,
     OPC_MXU_D16MAC   = 0x0A,
@@ -25838,7 +25837,7 @@ static bool decode_ase_mxu(DisasContext *ctx, uint32_t insn)
  */
 static void decode_opc_mxu(DisasContext *ctx, uint32_t insn)
 {
-    if (extract32(insn, 0, 6) == OPC__MXU_MUL) {
+    if (MASK_SPECIAL2(insn) == OPC_MUL) {
         uint32_t  rs, rt, rd, op1;
 
         rs = extract32(insn, 21, 5);
-- 
2.26.2



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

* [PATCH v3 07/10] target/mips: Introduce mxu_translate_init() helper
  2021-02-22 22:38 [PATCH v3 00/10] target/mips: Extract MXU code to new mxu_translate.c file Philippe Mathieu-Daudé
                   ` (5 preceding siblings ...)
  2021-02-22 22:38 ` [PATCH v3 06/10] target/mips: Use OPC_MUL instead of OPC__MXU_MUL Philippe Mathieu-Daudé
@ 2021-02-22 22:38 ` Philippe Mathieu-Daudé
  2021-02-24  1:36   ` Richard Henderson
  2021-02-22 22:38 ` [PATCH v3 08/10] target/mips: Make mxu_translate_init() / decode_ase_mxu() proto public Philippe Mathieu-Daudé
                   ` (2 subsequent siblings)
  9 siblings, 1 reply; 21+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-02-22 22:38 UTC (permalink / raw)
  To: qemu-devel
  Cc: Aleksandar Rikalo, Richard Henderson, Aurelien Jarno,
	Philippe Mathieu-Daudé

Extract the MXU register initialization code from mips_tcg_init()
as a new mxu_translate_init() helper

Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 target/mips/translate.c | 26 +++++++++++++++-----------
 1 file changed, 15 insertions(+), 11 deletions(-)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index c897f3900d8..52a7005e18f 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -2045,7 +2045,20 @@ static const char * const mxuregnames[] = {
     "XR1",  "XR2",  "XR3",  "XR4",  "XR5",  "XR6",  "XR7",  "XR8",
     "XR9",  "XR10", "XR11", "XR12", "XR13", "XR14", "XR15", "MXU_CR",
 };
-#endif
+
+static void mxu_translate_init(void)
+{
+    for (unsigned i = 0; i < NUMBER_OF_MXU_REGISTERS - 1; i++) {
+        mxu_gpr[i] = tcg_global_mem_new(cpu_env,
+                                        offsetof(CPUMIPSState, active_tc.mxu_gpr[i]),
+                                        mxuregnames[i]);
+    }
+
+    mxu_CR = tcg_global_mem_new(cpu_env,
+                                offsetof(CPUMIPSState, active_tc.mxu_cr),
+                                mxuregnames[NUMBER_OF_MXU_REGISTERS - 1]);
+}
+#endif /* defined(TARGET_MIPS64) */
 
 /* General purpose registers moves. */
 void gen_load_gpr(TCGv t, int reg)
@@ -28064,16 +28077,7 @@ void mips_tcg_init(void)
                                    "llval");
 
 #if !defined(TARGET_MIPS64)
-    for (i = 0; i < NUMBER_OF_MXU_REGISTERS - 1; i++) {
-        mxu_gpr[i] = tcg_global_mem_new(cpu_env,
-                                        offsetof(CPUMIPSState,
-                                                 active_tc.mxu_gpr[i]),
-                                        mxuregnames[i]);
-    }
-
-    mxu_CR = tcg_global_mem_new(cpu_env,
-                                offsetof(CPUMIPSState, active_tc.mxu_cr),
-                                mxuregnames[NUMBER_OF_MXU_REGISTERS - 1]);
+    mxu_translate_init();
 #endif /* !TARGET_MIPS64 */
 }
 
-- 
2.26.2



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

* [PATCH v3 08/10] target/mips: Make mxu_translate_init() / decode_ase_mxu() proto public
  2021-02-22 22:38 [PATCH v3 00/10] target/mips: Extract MXU code to new mxu_translate.c file Philippe Mathieu-Daudé
                   ` (6 preceding siblings ...)
  2021-02-22 22:38 ` [PATCH v3 07/10] target/mips: Introduce mxu_translate_init() helper Philippe Mathieu-Daudé
@ 2021-02-22 22:38 ` Philippe Mathieu-Daudé
  2021-02-24  1:38   ` Richard Henderson
  2021-02-22 22:39 ` [PATCH v3 09/10] target/mips: Simplify 64-bit ifdef'ry of MXU code Philippe Mathieu-Daudé
  2021-02-22 22:39 ` [PATCH v3 10/10] target/mips: Extract MXU code to new mxu_translate.c file Philippe Mathieu-Daudé
  9 siblings, 1 reply; 21+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-02-22 22:38 UTC (permalink / raw)
  To: qemu-devel
  Cc: Aleksandar Rikalo, Richard Henderson, Aurelien Jarno,
	Philippe Mathieu-Daudé

To be able to move these functions out of the big translate.c,
make their prototype public.

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

diff --git a/target/mips/translate.h b/target/mips/translate.h
index 468e29d7578..1801e7f819e 100644
--- a/target/mips/translate.h
+++ b/target/mips/translate.h
@@ -178,6 +178,12 @@ extern TCGv bcond;
 /* MSA */
 void msa_translate_init(void);
 
+/* MXU */
+#if !defined(TARGET_MIPS64)
+void mxu_translate_init(void);
+bool decode_ase_mxu(DisasContext *ctx, uint32_t insn);
+#endif /* !TARGET_MIPS64 */
+
 /* decodetree generated */
 bool decode_isa_rel6(DisasContext *ctx, uint32_t insn);
 bool decode_ase_msa(DisasContext *ctx, uint32_t insn);
diff --git a/target/mips/translate.c b/target/mips/translate.c
index 52a7005e18f..609798a0bee 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -2046,7 +2046,7 @@ static const char * const mxuregnames[] = {
     "XR9",  "XR10", "XR11", "XR12", "XR13", "XR14", "XR15", "MXU_CR",
 };
 
-static void mxu_translate_init(void)
+void mxu_translate_init(void)
 {
     for (unsigned i = 0; i < NUMBER_OF_MXU_REGISTERS - 1; i++) {
         mxu_gpr[i] = tcg_global_mem_new(cpu_env,
@@ -2058,6 +2058,11 @@ static void mxu_translate_init(void)
                                 offsetof(CPUMIPSState, active_tc.mxu_cr),
                                 mxuregnames[NUMBER_OF_MXU_REGISTERS - 1]);
 }
+#else /* !defined(TARGET_MIPS64) */
+void mxu_translate_init(void)
+{
+    g_assert_not_reached();
+}
 #endif /* defined(TARGET_MIPS64) */
 
 /* General purpose registers moves. */
@@ -25789,7 +25794,7 @@ static void decode_opc_mxu__pool19(DisasContext *ctx)
     }
 }
 
-static bool decode_ase_mxu(DisasContext *ctx, uint32_t insn)
+bool decode_ase_mxu(DisasContext *ctx, uint32_t insn)
 {
     uint32_t opcode = extract32(insn, 0, 6);
 
-- 
2.26.2



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

* [PATCH v3 09/10] target/mips: Simplify 64-bit ifdef'ry of MXU code
  2021-02-22 22:38 [PATCH v3 00/10] target/mips: Extract MXU code to new mxu_translate.c file Philippe Mathieu-Daudé
                   ` (7 preceding siblings ...)
  2021-02-22 22:38 ` [PATCH v3 08/10] target/mips: Make mxu_translate_init() / decode_ase_mxu() proto public Philippe Mathieu-Daudé
@ 2021-02-22 22:39 ` Philippe Mathieu-Daudé
  2021-02-24  1:48   ` Richard Henderson
  2021-02-22 22:39 ` [PATCH v3 10/10] target/mips: Extract MXU code to new mxu_translate.c file Philippe Mathieu-Daudé
  9 siblings, 1 reply; 21+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-02-22 22:39 UTC (permalink / raw)
  To: qemu-devel
  Cc: Aleksandar Rikalo, Richard Henderson, Aurelien Jarno,
	Philippe Mathieu-Daudé

Check for 'TARGET_LONG_BITS == 32' and simplify 64-bit ifdef'ry.

Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 target/mips/translate.h |  2 --
 target/mips/translate.c | 18 ++++++++++--------
 2 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/target/mips/translate.h b/target/mips/translate.h
index 1801e7f819e..a807b3d2566 100644
--- a/target/mips/translate.h
+++ b/target/mips/translate.h
@@ -179,10 +179,8 @@ extern TCGv bcond;
 void msa_translate_init(void);
 
 /* MXU */
-#if !defined(TARGET_MIPS64)
 void mxu_translate_init(void);
 bool decode_ase_mxu(DisasContext *ctx, uint32_t insn);
-#endif /* !TARGET_MIPS64 */
 
 /* decodetree generated */
 bool decode_isa_rel6(DisasContext *ctx, uint32_t insn);
diff --git a/target/mips/translate.c b/target/mips/translate.c
index 609798a0bee..68b5dee4bab 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -25850,6 +25850,15 @@ bool decode_ase_mxu(DisasContext *ctx, uint32_t insn)
     return true;
 }
 
+#else /* !defined(TARGET_MIPS64) */
+
+bool decode_ase_mxu(DisasContext *ctx, uint32_t insn)
+{
+    return false;
+}
+
+#endif /* defined(TARGET_MIPS64) */
+
 /*
  * Main MXU decoding function
  */
@@ -25871,9 +25880,6 @@ static void decode_opc_mxu(DisasContext *ctx, uint32_t insn)
     decode_ase_mxu(ctx, insn);
 }
 
-#endif /* !defined(TARGET_MIPS64) */
-
-
 static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
 {
     int rs, rt, rd;
@@ -27017,12 +27023,10 @@ static bool decode_opc_legacy(CPUMIPSState *env, DisasContext *ctx)
             break;
         }
 #endif
-#if !defined(TARGET_MIPS64)
-        if (ctx->insn_flags & ASE_MXU) {
+        if ((TARGET_LONG_BITS == 32) && (ctx->insn_flags & ASE_MXU)) {
             decode_opc_mxu(ctx, ctx->opcode);
             break;
         }
-#endif
         decode_opc_special2_legacy(env, ctx);
         break;
     case OPC_SPECIAL3:
@@ -28081,9 +28085,7 @@ void mips_tcg_init(void)
     cpu_llval = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, llval),
                                    "llval");
 
-#if !defined(TARGET_MIPS64)
     mxu_translate_init();
-#endif /* !TARGET_MIPS64 */
 }
 
 void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb,
-- 
2.26.2



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

* [PATCH v3 10/10] target/mips: Extract MXU code to new mxu_translate.c file
  2021-02-22 22:38 [PATCH v3 00/10] target/mips: Extract MXU code to new mxu_translate.c file Philippe Mathieu-Daudé
                   ` (8 preceding siblings ...)
  2021-02-22 22:39 ` [PATCH v3 09/10] target/mips: Simplify 64-bit ifdef'ry of MXU code Philippe Mathieu-Daudé
@ 2021-02-22 22:39 ` Philippe Mathieu-Daudé
  2021-02-24  2:16   ` Richard Henderson
  9 siblings, 1 reply; 21+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-02-22 22:39 UTC (permalink / raw)
  To: qemu-devel
  Cc: Aleksandar Rikalo, Richard Henderson, Aurelien Jarno,
	Philippe Mathieu-Daudé

Extract 1600+ lines from the big translate.c into a new file.

Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 target/mips/mxu_translate.c | 1625 +++++++++++++++++++++++++++++++++++
 target/mips/translate.c     | 1613 ----------------------------------
 target/mips/meson.build     |    1 +
 3 files changed, 1626 insertions(+), 1613 deletions(-)
 create mode 100644 target/mips/mxu_translate.c

diff --git a/target/mips/mxu_translate.c b/target/mips/mxu_translate.c
new file mode 100644
index 00000000000..a3a95b50c42
--- /dev/null
+++ b/target/mips/mxu_translate.c
@@ -0,0 +1,1625 @@
+/*
+ *  Ingenic XBurst Media eXtension Unit (MXU) translation routines.
+ *
+ *  Copyright (c) 2004-2005 Jocelyn Mayer
+ *  Copyright (c) 2006 Marius Groeger (FPU operations)
+ *  Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
+ *  Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
+ *  Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support)
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ *
+ * Datasheet:
+ *
+ *   "XBurst® Instruction Set Architecture MIPS eXtension/enhanced Unit
+ *   Programming Manual", Ingenic Semiconductor Co, Ltd., revision June 2, 2017
+ */
+
+#include "qemu/osdep.h"
+#include "tcg/tcg-op.h"
+#include "exec/helper-gen.h"
+#include "translate.h"
+
+#if !defined(TARGET_MIPS64)
+
+/*
+ *
+ *       AN OVERVIEW OF MXU EXTENSION INSTRUCTION SET
+ *       ============================================
+ *
+ *
+ * MXU (full name: MIPS eXtension/enhanced Unit) is a SIMD extension of MIPS32
+ * instructions set. It is designed to fit the needs of signal, graphical and
+ * video processing applications. MXU instruction set is used in Xburst family
+ * of microprocessors by Ingenic.
+ *
+ * MXU unit contains 17 registers called X0-X16. X0 is always zero, and X16 is
+ * the control register.
+ *
+ *
+ *     The notation used in MXU assembler mnemonics
+ *     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  Register operands:
+ *
+ *   XRa, XRb, XRc, XRd - MXU registers
+ *   Rb, Rc, Rd, Rs, Rt - general purpose MIPS registers
+ *
+ *  Non-register operands:
+ *
+ *   aptn1 - 1-bit accumulate add/subtract pattern
+ *   aptn2 - 2-bit accumulate add/subtract pattern
+ *   eptn2 - 2-bit execute add/subtract pattern
+ *   optn2 - 2-bit operand pattern
+ *   optn3 - 3-bit operand pattern
+ *   sft4  - 4-bit shift amount
+ *   strd2 - 2-bit stride amount
+ *
+ *  Prefixes:
+ *
+ *   Level of parallelism:                Operand size:
+ *    S - single operation at a time       32 - word
+ *    D - two operations in parallel       16 - half word
+ *    Q - four operations in parallel       8 - byte
+ *
+ *  Operations:
+ *
+ *   ADD   - Add or subtract
+ *   ADDC  - Add with carry-in
+ *   ACC   - Accumulate
+ *   ASUM  - Sum together then accumulate (add or subtract)
+ *   ASUMC - Sum together then accumulate (add or subtract) with carry-in
+ *   AVG   - Average between 2 operands
+ *   ABD   - Absolute difference
+ *   ALN   - Align data
+ *   AND   - Logical bitwise 'and' operation
+ *   CPS   - Copy sign
+ *   EXTR  - Extract bits
+ *   I2M   - Move from GPR register to MXU register
+ *   LDD   - Load data from memory to XRF
+ *   LDI   - Load data from memory to XRF (and increase the address base)
+ *   LUI   - Load unsigned immediate
+ *   MUL   - Multiply
+ *   MULU  - Unsigned multiply
+ *   MADD  - 64-bit operand add 32x32 product
+ *   MSUB  - 64-bit operand subtract 32x32 product
+ *   MAC   - Multiply and accumulate (add or subtract)
+ *   MAD   - Multiply and add or subtract
+ *   MAX   - Maximum between 2 operands
+ *   MIN   - Minimum between 2 operands
+ *   M2I   - Move from MXU register to GPR register
+ *   MOVZ  - Move if zero
+ *   MOVN  - Move if non-zero
+ *   NOR   - Logical bitwise 'nor' operation
+ *   OR    - Logical bitwise 'or' operation
+ *   STD   - Store data from XRF to memory
+ *   SDI   - Store data from XRF to memory (and increase the address base)
+ *   SLT   - Set of less than comparison
+ *   SAD   - Sum of absolute differences
+ *   SLL   - Logical shift left
+ *   SLR   - Logical shift right
+ *   SAR   - Arithmetic shift right
+ *   SAT   - Saturation
+ *   SFL   - Shuffle
+ *   SCOP  - Calculate x’s scope (-1, means x<0; 0, means x==0; 1, means x>0)
+ *   XOR   - Logical bitwise 'exclusive or' operation
+ *
+ *  Suffixes:
+ *
+ *   E - Expand results
+ *   F - Fixed point multiplication
+ *   L - Low part result
+ *   R - Doing rounding
+ *   V - Variable instead of immediate
+ *   W - Combine above L and V
+ *
+ *
+ *     The list of MXU instructions grouped by functionality
+ *     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * Load/Store instructions           Multiplication instructions
+ * -----------------------           ---------------------------
+ *
+ *  S32LDD XRa, Rb, s12               S32MADD XRa, XRd, Rs, Rt
+ *  S32STD XRa, Rb, s12               S32MADDU XRa, XRd, Rs, Rt
+ *  S32LDDV XRa, Rb, rc, strd2        S32MSUB XRa, XRd, Rs, Rt
+ *  S32STDV XRa, Rb, rc, strd2        S32MSUBU XRa, XRd, Rs, Rt
+ *  S32LDI XRa, Rb, s12               S32MUL XRa, XRd, Rs, Rt
+ *  S32SDI XRa, Rb, s12               S32MULU XRa, XRd, Rs, Rt
+ *  S32LDIV XRa, Rb, rc, strd2        D16MUL XRa, XRb, XRc, XRd, optn2
+ *  S32SDIV XRa, Rb, rc, strd2        D16MULE XRa, XRb, XRc, optn2
+ *  S32LDDR XRa, Rb, s12              D16MULF XRa, XRb, XRc, optn2
+ *  S32STDR XRa, Rb, s12              D16MAC XRa, XRb, XRc, XRd, aptn2, optn2
+ *  S32LDDVR XRa, Rb, rc, strd2       D16MACE XRa, XRb, XRc, XRd, aptn2, optn2
+ *  S32STDVR XRa, Rb, rc, strd2       D16MACF XRa, XRb, XRc, XRd, aptn2, optn2
+ *  S32LDIR XRa, Rb, s12              D16MADL XRa, XRb, XRc, XRd, aptn2, optn2
+ *  S32SDIR XRa, Rb, s12              S16MAD XRa, XRb, XRc, XRd, aptn1, optn2
+ *  S32LDIVR XRa, Rb, rc, strd2       Q8MUL XRa, XRb, XRc, XRd
+ *  S32SDIVR XRa, Rb, rc, strd2       Q8MULSU XRa, XRb, XRc, XRd
+ *  S16LDD XRa, Rb, s10, eptn2        Q8MAC XRa, XRb, XRc, XRd, aptn2
+ *  S16STD XRa, Rb, s10, eptn2        Q8MACSU XRa, XRb, XRc, XRd, aptn2
+ *  S16LDI XRa, Rb, s10, eptn2        Q8MADL XRa, XRb, XRc, XRd, aptn2
+ *  S16SDI XRa, Rb, s10, eptn2
+ *  S8LDD XRa, Rb, s8, eptn3
+ *  S8STD XRa, Rb, s8, eptn3         Addition and subtraction instructions
+ *  S8LDI XRa, Rb, s8, eptn3         -------------------------------------
+ *  S8SDI XRa, Rb, s8, eptn3
+ *  LXW Rd, Rs, Rt, strd2             D32ADD XRa, XRb, XRc, XRd, eptn2
+ *  LXH Rd, Rs, Rt, strd2             D32ADDC XRa, XRb, XRc, XRd
+ *  LXHU Rd, Rs, Rt, strd2            D32ACC XRa, XRb, XRc, XRd, eptn2
+ *  LXB Rd, Rs, Rt, strd2             D32ACCM XRa, XRb, XRc, XRd, eptn2
+ *  LXBU Rd, Rs, Rt, strd2            D32ASUM XRa, XRb, XRc, XRd, eptn2
+ *                                    S32CPS XRa, XRb, XRc
+ *                                    Q16ADD XRa, XRb, XRc, XRd, eptn2, optn2
+ * Comparison instructions            Q16ACC XRa, XRb, XRc, XRd, eptn2
+ * -----------------------            Q16ACCM XRa, XRb, XRc, XRd, eptn2
+ *                                    D16ASUM XRa, XRb, XRc, XRd, eptn2
+ *  S32MAX XRa, XRb, XRc              D16CPS XRa, XRb,
+ *  S32MIN XRa, XRb, XRc              D16AVG XRa, XRb, XRc
+ *  S32SLT XRa, XRb, XRc              D16AVGR XRa, XRb, XRc
+ *  S32MOVZ XRa, XRb, XRc             Q8ADD XRa, XRb, XRc, eptn2
+ *  S32MOVN XRa, XRb, XRc             Q8ADDE XRa, XRb, XRc, XRd, eptn2
+ *  D16MAX XRa, XRb, XRc              Q8ACCE XRa, XRb, XRc, XRd, eptn2
+ *  D16MIN XRa, XRb, XRc              Q8ABD XRa, XRb, XRc
+ *  D16SLT XRa, XRb, XRc              Q8SAD XRa, XRb, XRc, XRd
+ *  D16MOVZ XRa, XRb, XRc             Q8AVG XRa, XRb, XRc
+ *  D16MOVN XRa, XRb, XRc             Q8AVGR XRa, XRb, XRc
+ *  Q8MAX XRa, XRb, XRc               D8SUM XRa, XRb, XRc, XRd
+ *  Q8MIN XRa, XRb, XRc               D8SUMC XRa, XRb, XRc, XRd
+ *  Q8SLT XRa, XRb, XRc
+ *  Q8SLTU XRa, XRb, XRc
+ *  Q8MOVZ XRa, XRb, XRc             Shift instructions
+ *  Q8MOVN XRa, XRb, XRc             ------------------
+ *
+ *                                    D32SLL XRa, XRb, XRc, XRd, sft4
+ * Bitwise instructions               D32SLR XRa, XRb, XRc, XRd, sft4
+ * --------------------               D32SAR XRa, XRb, XRc, XRd, sft4
+ *                                    D32SARL XRa, XRb, XRc, sft4
+ *  S32NOR XRa, XRb, XRc              D32SLLV XRa, XRb, Rb
+ *  S32AND XRa, XRb, XRc              D32SLRV XRa, XRb, Rb
+ *  S32XOR XRa, XRb, XRc              D32SARV XRa, XRb, Rb
+ *  S32OR XRa, XRb, XRc               D32SARW XRa, XRb, XRc, Rb
+ *                                    Q16SLL XRa, XRb, XRc, XRd, sft4
+ *                                    Q16SLR XRa, XRb, XRc, XRd, sft4
+ * Miscellaneous instructions         Q16SAR XRa, XRb, XRc, XRd, sft4
+ * -------------------------          Q16SLLV XRa, XRb, Rb
+ *                                    Q16SLRV XRa, XRb, Rb
+ *  S32SFL XRa, XRb, XRc, XRd, optn2  Q16SARV XRa, XRb, Rb
+ *  S32ALN XRa, XRb, XRc, Rb
+ *  S32ALNI XRa, XRb, XRc, s3
+ *  S32LUI XRa, s8, optn3            Move instructions
+ *  S32EXTR XRa, XRb, Rb, bits5      -----------------
+ *  S32EXTRV XRa, XRb, Rs, Rt
+ *  Q16SCOP XRa, XRb, XRc, XRd        S32M2I XRa, Rb
+ *  Q16SAT XRa, XRb, XRc              S32I2M XRa, Rb
+ *
+ *
+ *     The opcode organization of MXU instructions
+ *     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * The bits 31..26 of all MXU instructions are equal to 0x1C (also referred
+ * as opcode SPECIAL2 in the base MIPS ISA). The organization and meaning of
+ * other bits up to the instruction level is as follows:
+ *
+ *              bits
+ *             05..00
+ *
+ *          ┌─ 000000 ─ OPC_MXU_S32MADD
+ *          ├─ 000001 ─ OPC_MXU_S32MADDU
+ *          ├─ 000010 ─ <not assigned>   (non-MXU OPC_MUL)
+ *          │
+ *          │                               20..18
+ *          ├─ 000011 ─ OPC_MXU__POOL00 ─┬─ 000 ─ OPC_MXU_S32MAX
+ *          │                            ├─ 001 ─ OPC_MXU_S32MIN
+ *          │                            ├─ 010 ─ OPC_MXU_D16MAX
+ *          │                            ├─ 011 ─ OPC_MXU_D16MIN
+ *          │                            ├─ 100 ─ OPC_MXU_Q8MAX
+ *          │                            ├─ 101 ─ OPC_MXU_Q8MIN
+ *          │                            ├─ 110 ─ OPC_MXU_Q8SLT
+ *          │                            └─ 111 ─ OPC_MXU_Q8SLTU
+ *          ├─ 000100 ─ OPC_MXU_S32MSUB
+ *          ├─ 000101 ─ OPC_MXU_S32MSUBU    20..18
+ *          ├─ 000110 ─ OPC_MXU__POOL01 ─┬─ 000 ─ OPC_MXU_S32SLT
+ *          │                            ├─ 001 ─ OPC_MXU_D16SLT
+ *          │                            ├─ 010 ─ OPC_MXU_D16AVG
+ *          │                            ├─ 011 ─ OPC_MXU_D16AVGR
+ *          │                            ├─ 100 ─ OPC_MXU_Q8AVG
+ *          │                            ├─ 101 ─ OPC_MXU_Q8AVGR
+ *          │                            └─ 111 ─ OPC_MXU_Q8ADD
+ *          │
+ *          │                               20..18
+ *          ├─ 000111 ─ OPC_MXU__POOL02 ─┬─ 000 ─ OPC_MXU_S32CPS
+ *          │                            ├─ 010 ─ OPC_MXU_D16CPS
+ *          │                            ├─ 100 ─ OPC_MXU_Q8ABD
+ *          │                            └─ 110 ─ OPC_MXU_Q16SAT
+ *          ├─ 001000 ─ OPC_MXU_D16MUL
+ *          │                               25..24
+ *          ├─ 001001 ─ OPC_MXU__POOL03 ─┬─ 00 ─ OPC_MXU_D16MULF
+ *          │                            └─ 01 ─ OPC_MXU_D16MULE
+ *          ├─ 001010 ─ OPC_MXU_D16MAC
+ *          ├─ 001011 ─ OPC_MXU_D16MACF
+ *          ├─ 001100 ─ OPC_MXU_D16MADL
+ *          ├─ 001101 ─ OPC_MXU_S16MAD
+ *          ├─ 001110 ─ OPC_MXU_Q16ADD
+ *          ├─ 001111 ─ OPC_MXU_D16MACE     23
+ *          │                            ┌─ 0 ─ OPC_MXU_S32LDD
+ *          ├─ 010000 ─ OPC_MXU__POOL04 ─┴─ 1 ─ OPC_MXU_S32LDDR
+ *          │
+ *          │                               23
+ *          ├─ 010001 ─ OPC_MXU__POOL05 ─┬─ 0 ─ OPC_MXU_S32STD
+ *          │                            └─ 1 ─ OPC_MXU_S32STDR
+ *          │
+ *          │                               13..10
+ *          ├─ 010010 ─ OPC_MXU__POOL06 ─┬─ 0000 ─ OPC_MXU_S32LDDV
+ *          │                            └─ 0001 ─ OPC_MXU_S32LDDVR
+ *          │
+ *          │                               13..10
+ *          ├─ 010011 ─ OPC_MXU__POOL07 ─┬─ 0000 ─ OPC_MXU_S32STDV
+ *          │                            └─ 0001 ─ OPC_MXU_S32STDVR
+ *          │
+ *          │                               23
+ *          ├─ 010100 ─ OPC_MXU__POOL08 ─┬─ 0 ─ OPC_MXU_S32LDI
+ *          │                            └─ 1 ─ OPC_MXU_S32LDIR
+ *          │
+ *          │                               23
+ *          ├─ 010101 ─ OPC_MXU__POOL09 ─┬─ 0 ─ OPC_MXU_S32SDI
+ *          │                            └─ 1 ─ OPC_MXU_S32SDIR
+ *          │
+ *          │                               13..10
+ *          ├─ 010110 ─ OPC_MXU__POOL10 ─┬─ 0000 ─ OPC_MXU_S32LDIV
+ *          │                            └─ 0001 ─ OPC_MXU_S32LDIVR
+ *          │
+ *          │                               13..10
+ *          ├─ 010111 ─ OPC_MXU__POOL11 ─┬─ 0000 ─ OPC_MXU_S32SDIV
+ *          │                            └─ 0001 ─ OPC_MXU_S32SDIVR
+ *          ├─ 011000 ─ OPC_MXU_D32ADD
+ *          │                               23..22
+ *   MXU    ├─ 011001 ─ OPC_MXU__POOL12 ─┬─ 00 ─ OPC_MXU_D32ACC
+ * opcodes ─┤                            ├─ 01 ─ OPC_MXU_D32ACCM
+ *          │                            └─ 10 ─ OPC_MXU_D32ASUM
+ *          ├─ 011010 ─ <not assigned>
+ *          │                               23..22
+ *          ├─ 011011 ─ OPC_MXU__POOL13 ─┬─ 00 ─ OPC_MXU_Q16ACC
+ *          │                            ├─ 01 ─ OPC_MXU_Q16ACCM
+ *          │                            └─ 10 ─ OPC_MXU_Q16ASUM
+ *          │
+ *          │                               23..22
+ *          ├─ 011100 ─ OPC_MXU__POOL14 ─┬─ 00 ─ OPC_MXU_Q8ADDE
+ *          │                            ├─ 01 ─ OPC_MXU_D8SUM
+ *          ├─ 011101 ─ OPC_MXU_Q8ACCE   └─ 10 ─ OPC_MXU_D8SUMC
+ *          ├─ 011110 ─ <not assigned>
+ *          ├─ 011111 ─ <not assigned>
+ *          ├─ 100000 ─ <not assigned>   (overlaps with CLZ)
+ *          ├─ 100001 ─ <not assigned>   (overlaps with CLO)
+ *          ├─ 100010 ─ OPC_MXU_S8LDD
+ *          ├─ 100011 ─ OPC_MXU_S8STD       15..14
+ *          ├─ 100100 ─ OPC_MXU_S8LDI    ┌─ 00 ─ OPC_MXU_S32MUL
+ *          ├─ 100101 ─ OPC_MXU_S8SDI    ├─ 00 ─ OPC_MXU_S32MULU
+ *          │                            ├─ 00 ─ OPC_MXU_S32EXTR
+ *          ├─ 100110 ─ OPC_MXU__POOL15 ─┴─ 00 ─ OPC_MXU_S32EXTRV
+ *          │
+ *          │                               20..18
+ *          ├─ 100111 ─ OPC_MXU__POOL16 ─┬─ 000 ─ OPC_MXU_D32SARW
+ *          │                            ├─ 001 ─ OPC_MXU_S32ALN
+ *          │                            ├─ 010 ─ OPC_MXU_S32ALNI
+ *          │                            ├─ 011 ─ OPC_MXU_S32LUI
+ *          │                            ├─ 100 ─ OPC_MXU_S32NOR
+ *          │                            ├─ 101 ─ OPC_MXU_S32AND
+ *          │                            ├─ 110 ─ OPC_MXU_S32OR
+ *          │                            └─ 111 ─ OPC_MXU_S32XOR
+ *          │
+ *          │                               7..5
+ *          ├─ 101000 ─ OPC_MXU__POOL17 ─┬─ 000 ─ OPC_MXU_LXB
+ *          │                            ├─ 001 ─ OPC_MXU_LXH
+ *          ├─ 101001 ─ <not assigned>   ├─ 011 ─ OPC_MXU_LXW
+ *          ├─ 101010 ─ OPC_MXU_S16LDD   ├─ 100 ─ OPC_MXU_LXBU
+ *          ├─ 101011 ─ OPC_MXU_S16STD   └─ 101 ─ OPC_MXU_LXHU
+ *          ├─ 101100 ─ OPC_MXU_S16LDI
+ *          ├─ 101101 ─ OPC_MXU_S16SDI
+ *          ├─ 101110 ─ OPC_MXU_S32M2I
+ *          ├─ 101111 ─ OPC_MXU_S32I2M
+ *          ├─ 110000 ─ OPC_MXU_D32SLL
+ *          ├─ 110001 ─ OPC_MXU_D32SLR      20..18
+ *          ├─ 110010 ─ OPC_MXU_D32SARL  ┌─ 000 ─ OPC_MXU_D32SLLV
+ *          ├─ 110011 ─ OPC_MXU_D32SAR   ├─ 001 ─ OPC_MXU_D32SLRV
+ *          ├─ 110100 ─ OPC_MXU_Q16SLL   ├─ 010 ─ OPC_MXU_D32SARV
+ *          ├─ 110101 ─ OPC_MXU_Q16SLR   ├─ 011 ─ OPC_MXU_Q16SLLV
+ *          │                            ├─ 100 ─ OPC_MXU_Q16SLRV
+ *          ├─ 110110 ─ OPC_MXU__POOL18 ─┴─ 101 ─ OPC_MXU_Q16SARV
+ *          │
+ *          ├─ 110111 ─ OPC_MXU_Q16SAR
+ *          │                               23..22
+ *          ├─ 111000 ─ OPC_MXU__POOL19 ─┬─ 00 ─ OPC_MXU_Q8MUL
+ *          │                            └─ 01 ─ OPC_MXU_Q8MULSU
+ *          │
+ *          │                               20..18
+ *          ├─ 111001 ─ OPC_MXU__POOL20 ─┬─ 000 ─ OPC_MXU_Q8MOVZ
+ *          │                            ├─ 001 ─ OPC_MXU_Q8MOVN
+ *          │                            ├─ 010 ─ OPC_MXU_D16MOVZ
+ *          │                            ├─ 011 ─ OPC_MXU_D16MOVN
+ *          │                            ├─ 100 ─ OPC_MXU_S32MOVZ
+ *          │                            └─ 101 ─ OPC_MXU_S32MOVN
+ *          │
+ *          │                               23..22
+ *          ├─ 111010 ─ OPC_MXU__POOL21 ─┬─ 00 ─ OPC_MXU_Q8MAC
+ *          │                            └─ 10 ─ OPC_MXU_Q8MACSU
+ *          ├─ 111011 ─ OPC_MXU_Q16SCOP
+ *          ├─ 111100 ─ OPC_MXU_Q8MADL
+ *          ├─ 111101 ─ OPC_MXU_S32SFL
+ *          ├─ 111110 ─ OPC_MXU_Q8SAD
+ *          └─ 111111 ─ <not assigned>   (overlaps with SDBBP)
+ *
+ *
+ * Compiled after:
+ *
+ *   "XBurst® Instruction Set Architecture MIPS eXtension/enhanced Unit
+ *   Programming Manual", Ingenic Semiconductor Co, Ltd., revision June 2, 2017
+ */
+
+enum {
+    OPC_MXU__POOL00  = 0x03,
+    OPC_MXU_D16MUL   = 0x08,
+    OPC_MXU_D16MAC   = 0x0A,
+    OPC_MXU__POOL04  = 0x10,
+    OPC_MXU_S8LDD    = 0x22,
+    OPC_MXU__POOL16  = 0x27,
+    OPC_MXU_S32M2I   = 0x2E,
+    OPC_MXU_S32I2M   = 0x2F,
+    OPC_MXU__POOL19  = 0x38,
+};
+
+
+/*
+ * MXU pool 00
+ */
+enum {
+    OPC_MXU_S32MAX   = 0x00,
+    OPC_MXU_S32MIN   = 0x01,
+    OPC_MXU_D16MAX   = 0x02,
+    OPC_MXU_D16MIN   = 0x03,
+    OPC_MXU_Q8MAX    = 0x04,
+    OPC_MXU_Q8MIN    = 0x05,
+};
+
+/*
+ * MXU pool 04
+ */
+enum {
+    OPC_MXU_S32LDD   = 0x00,
+    OPC_MXU_S32LDDR  = 0x01,
+};
+
+/*
+ * MXU pool 16
+ */
+enum {
+    OPC_MXU_S32ALNI  = 0x02,
+    OPC_MXU_S32NOR   = 0x04,
+    OPC_MXU_S32AND   = 0x05,
+    OPC_MXU_S32OR    = 0x06,
+    OPC_MXU_S32XOR   = 0x07,
+};
+
+/*
+ * MXU pool 19
+ */
+enum {
+    OPC_MXU_Q8MUL    = 0x00,
+    OPC_MXU_Q8MULSU  = 0x01,
+};
+
+/* MXU accumulate add/subtract 1-bit pattern 'aptn1' */
+#define MXU_APTN1_A    0
+#define MXU_APTN1_S    1
+
+/* MXU accumulate add/subtract 2-bit pattern 'aptn2' */
+#define MXU_APTN2_AA    0
+#define MXU_APTN2_AS    1
+#define MXU_APTN2_SA    2
+#define MXU_APTN2_SS    3
+
+/* MXU execute add/subtract 2-bit pattern 'eptn2' */
+#define MXU_EPTN2_AA    0
+#define MXU_EPTN2_AS    1
+#define MXU_EPTN2_SA    2
+#define MXU_EPTN2_SS    3
+
+/* MXU operand getting pattern 'optn2' */
+#define MXU_OPTN2_PTN0  0
+#define MXU_OPTN2_PTN1  1
+#define MXU_OPTN2_PTN2  2
+#define MXU_OPTN2_PTN3  3
+/* alternative naming scheme for 'optn2' */
+#define MXU_OPTN2_WW    0
+#define MXU_OPTN2_LW    1
+#define MXU_OPTN2_HW    2
+#define MXU_OPTN2_XW    3
+
+/* MXU operand getting pattern 'optn3' */
+#define MXU_OPTN3_PTN0  0
+#define MXU_OPTN3_PTN1  1
+#define MXU_OPTN3_PTN2  2
+#define MXU_OPTN3_PTN3  3
+#define MXU_OPTN3_PTN4  4
+#define MXU_OPTN3_PTN5  5
+#define MXU_OPTN3_PTN6  6
+#define MXU_OPTN3_PTN7  7
+
+/* MXU registers */
+static TCGv mxu_gpr[NUMBER_OF_MXU_REGISTERS - 1];
+static TCGv mxu_CR;
+
+static const char * const mxuregnames[] = {
+    "XR1",  "XR2",  "XR3",  "XR4",  "XR5",  "XR6",  "XR7",  "XR8",
+    "XR9",  "XR10", "XR11", "XR12", "XR13", "XR14", "XR15", "MXU_CR",
+};
+
+void mxu_translate_init(void)
+{
+    for (unsigned i = 0; i < NUMBER_OF_MXU_REGISTERS - 1; i++) {
+        mxu_gpr[i] = tcg_global_mem_new(cpu_env,
+                                        offsetof(CPUMIPSState, active_tc.mxu_gpr[i]),
+                                        mxuregnames[i]);
+    }
+
+    mxu_CR = tcg_global_mem_new(cpu_env,
+                                offsetof(CPUMIPSState, active_tc.mxu_cr),
+                                mxuregnames[NUMBER_OF_MXU_REGISTERS - 1]);
+}
+
+/* MXU General purpose registers moves. */
+static inline void gen_load_mxu_gpr(TCGv t, unsigned int reg)
+{
+    if (reg == 0) {
+        tcg_gen_movi_tl(t, 0);
+    } else if (reg <= 15) {
+        tcg_gen_mov_tl(t, mxu_gpr[reg - 1]);
+    }
+}
+
+static inline void gen_store_mxu_gpr(TCGv t, unsigned int reg)
+{
+    if (reg > 0 && reg <= 15) {
+        tcg_gen_mov_tl(mxu_gpr[reg - 1], t);
+    }
+}
+
+/* MXU control register moves. */
+static inline void gen_load_mxu_cr(TCGv t)
+{
+    tcg_gen_mov_tl(t, mxu_CR);
+}
+
+static inline void gen_store_mxu_cr(TCGv t)
+{
+    /* TODO: Add handling of RW rules for MXU_CR. */
+    tcg_gen_mov_tl(mxu_CR, t);
+}
+
+/*
+ * S32I2M XRa, rb - Register move from GRF to XRF
+ */
+static void gen_mxu_s32i2m(DisasContext *ctx)
+{
+    TCGv t0;
+    uint32_t XRa, Rb;
+
+    t0 = tcg_temp_new();
+
+    XRa = extract32(ctx->opcode, 6, 5);
+    Rb = extract32(ctx->opcode, 16, 5);
+
+    gen_load_gpr(t0, Rb);
+    if (XRa <= 15) {
+        gen_store_mxu_gpr(t0, XRa);
+    } else if (XRa == 16) {
+        gen_store_mxu_cr(t0);
+    }
+
+    tcg_temp_free(t0);
+}
+
+/*
+ * S32M2I XRa, rb - Register move from XRF to GRF
+ */
+static void gen_mxu_s32m2i(DisasContext *ctx)
+{
+    TCGv t0;
+    uint32_t XRa, Rb;
+
+    t0 = tcg_temp_new();
+
+    XRa = extract32(ctx->opcode, 6, 5);
+    Rb = extract32(ctx->opcode, 16, 5);
+
+    if (XRa <= 15) {
+        gen_load_mxu_gpr(t0, XRa);
+    } else if (XRa == 16) {
+        gen_load_mxu_cr(t0);
+    }
+
+    gen_store_gpr(t0, Rb);
+
+    tcg_temp_free(t0);
+}
+
+/*
+ * S8LDD XRa, Rb, s8, optn3 - Load a byte from memory to XRF
+ */
+static void gen_mxu_s8ldd(DisasContext *ctx)
+{
+    TCGv t0, t1;
+    uint32_t XRa, Rb, s8, optn3;
+
+    t0 = tcg_temp_new();
+    t1 = tcg_temp_new();
+
+    XRa = extract32(ctx->opcode, 6, 4);
+    s8 = extract32(ctx->opcode, 10, 8);
+    optn3 = extract32(ctx->opcode, 18, 3);
+    Rb = extract32(ctx->opcode, 21, 5);
+
+    gen_load_gpr(t0, Rb);
+    tcg_gen_addi_tl(t0, t0, (int8_t)s8);
+
+    switch (optn3) {
+    /* XRa[7:0] = tmp8 */
+    case MXU_OPTN3_PTN0:
+        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
+        gen_load_mxu_gpr(t0, XRa);
+        tcg_gen_deposit_tl(t0, t0, t1, 0, 8);
+        break;
+    /* XRa[15:8] = tmp8 */
+    case MXU_OPTN3_PTN1:
+        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
+        gen_load_mxu_gpr(t0, XRa);
+        tcg_gen_deposit_tl(t0, t0, t1, 8, 8);
+        break;
+    /* XRa[23:16] = tmp8 */
+    case MXU_OPTN3_PTN2:
+        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
+        gen_load_mxu_gpr(t0, XRa);
+        tcg_gen_deposit_tl(t0, t0, t1, 16, 8);
+        break;
+    /* XRa[31:24] = tmp8 */
+    case MXU_OPTN3_PTN3:
+        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
+        gen_load_mxu_gpr(t0, XRa);
+        tcg_gen_deposit_tl(t0, t0, t1, 24, 8);
+        break;
+    /* XRa = {8'b0, tmp8, 8'b0, tmp8} */
+    case MXU_OPTN3_PTN4:
+        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
+        tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
+        break;
+    /* XRa = {tmp8, 8'b0, tmp8, 8'b0} */
+    case MXU_OPTN3_PTN5:
+        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
+        tcg_gen_shli_tl(t1, t1, 8);
+        tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
+        break;
+    /* XRa = {{8{sign of tmp8}}, tmp8, {8{sign of tmp8}}, tmp8} */
+    case MXU_OPTN3_PTN6:
+        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_SB);
+        tcg_gen_mov_tl(t0, t1);
+        tcg_gen_andi_tl(t0, t0, 0xFF00FFFF);
+        tcg_gen_shli_tl(t1, t1, 16);
+        tcg_gen_or_tl(t0, t0, t1);
+        break;
+    /* XRa = {tmp8, tmp8, tmp8, tmp8} */
+    case MXU_OPTN3_PTN7:
+        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
+        tcg_gen_deposit_tl(t1, t1, t1, 8, 8);
+        tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
+        break;
+    }
+
+    gen_store_mxu_gpr(t0, XRa);
+
+    tcg_temp_free(t0);
+    tcg_temp_free(t1);
+}
+
+/*
+ * D16MUL XRa, XRb, XRc, XRd, optn2 - Signed 16 bit pattern multiplication
+ */
+static void gen_mxu_d16mul(DisasContext *ctx)
+{
+    TCGv t0, t1, t2, t3;
+    uint32_t XRa, XRb, XRc, XRd, optn2;
+
+    t0 = tcg_temp_new();
+    t1 = tcg_temp_new();
+    t2 = tcg_temp_new();
+    t3 = tcg_temp_new();
+
+    XRa = extract32(ctx->opcode, 6, 4);
+    XRb = extract32(ctx->opcode, 10, 4);
+    XRc = extract32(ctx->opcode, 14, 4);
+    XRd = extract32(ctx->opcode, 18, 4);
+    optn2 = extract32(ctx->opcode, 22, 2);
+
+    gen_load_mxu_gpr(t1, XRb);
+    tcg_gen_sextract_tl(t0, t1, 0, 16);
+    tcg_gen_sextract_tl(t1, t1, 16, 16);
+    gen_load_mxu_gpr(t3, XRc);
+    tcg_gen_sextract_tl(t2, t3, 0, 16);
+    tcg_gen_sextract_tl(t3, t3, 16, 16);
+
+    switch (optn2) {
+    case MXU_OPTN2_WW: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
+        tcg_gen_mul_tl(t3, t1, t3);
+        tcg_gen_mul_tl(t2, t0, t2);
+        break;
+    case MXU_OPTN2_LW: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
+        tcg_gen_mul_tl(t3, t0, t3);
+        tcg_gen_mul_tl(t2, t0, t2);
+        break;
+    case MXU_OPTN2_HW: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
+        tcg_gen_mul_tl(t3, t1, t3);
+        tcg_gen_mul_tl(t2, t1, t2);
+        break;
+    case MXU_OPTN2_XW: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
+        tcg_gen_mul_tl(t3, t0, t3);
+        tcg_gen_mul_tl(t2, t1, t2);
+        break;
+    }
+    gen_store_mxu_gpr(t3, XRa);
+    gen_store_mxu_gpr(t2, XRd);
+
+    tcg_temp_free(t0);
+    tcg_temp_free(t1);
+    tcg_temp_free(t2);
+    tcg_temp_free(t3);
+}
+
+/*
+ * D16MAC XRa, XRb, XRc, XRd, aptn2, optn2 - Signed 16 bit pattern multiply
+ *                                           and accumulate
+ */
+static void gen_mxu_d16mac(DisasContext *ctx)
+{
+    TCGv t0, t1, t2, t3;
+    uint32_t XRa, XRb, XRc, XRd, optn2, aptn2;
+
+    t0 = tcg_temp_new();
+    t1 = tcg_temp_new();
+    t2 = tcg_temp_new();
+    t3 = tcg_temp_new();
+
+    XRa = extract32(ctx->opcode, 6, 4);
+    XRb = extract32(ctx->opcode, 10, 4);
+    XRc = extract32(ctx->opcode, 14, 4);
+    XRd = extract32(ctx->opcode, 18, 4);
+    optn2 = extract32(ctx->opcode, 22, 2);
+    aptn2 = extract32(ctx->opcode, 24, 2);
+
+    gen_load_mxu_gpr(t1, XRb);
+    tcg_gen_sextract_tl(t0, t1, 0, 16);
+    tcg_gen_sextract_tl(t1, t1, 16, 16);
+
+    gen_load_mxu_gpr(t3, XRc);
+    tcg_gen_sextract_tl(t2, t3, 0, 16);
+    tcg_gen_sextract_tl(t3, t3, 16, 16);
+
+    switch (optn2) {
+    case MXU_OPTN2_WW: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
+        tcg_gen_mul_tl(t3, t1, t3);
+        tcg_gen_mul_tl(t2, t0, t2);
+        break;
+    case MXU_OPTN2_LW: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
+        tcg_gen_mul_tl(t3, t0, t3);
+        tcg_gen_mul_tl(t2, t0, t2);
+        break;
+    case MXU_OPTN2_HW: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
+        tcg_gen_mul_tl(t3, t1, t3);
+        tcg_gen_mul_tl(t2, t1, t2);
+        break;
+    case MXU_OPTN2_XW: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
+        tcg_gen_mul_tl(t3, t0, t3);
+        tcg_gen_mul_tl(t2, t1, t2);
+        break;
+    }
+    gen_load_mxu_gpr(t0, XRa);
+    gen_load_mxu_gpr(t1, XRd);
+
+    switch (aptn2) {
+    case MXU_APTN2_AA:
+        tcg_gen_add_tl(t3, t0, t3);
+        tcg_gen_add_tl(t2, t1, t2);
+        break;
+    case MXU_APTN2_AS:
+        tcg_gen_add_tl(t3, t0, t3);
+        tcg_gen_sub_tl(t2, t1, t2);
+        break;
+    case MXU_APTN2_SA:
+        tcg_gen_sub_tl(t3, t0, t3);
+        tcg_gen_add_tl(t2, t1, t2);
+        break;
+    case MXU_APTN2_SS:
+        tcg_gen_sub_tl(t3, t0, t3);
+        tcg_gen_sub_tl(t2, t1, t2);
+        break;
+    }
+    gen_store_mxu_gpr(t3, XRa);
+    gen_store_mxu_gpr(t2, XRd);
+
+    tcg_temp_free(t0);
+    tcg_temp_free(t1);
+    tcg_temp_free(t2);
+    tcg_temp_free(t3);
+}
+
+/*
+ * Q8MUL   XRa, XRb, XRc, XRd - Parallel unsigned 8 bit pattern multiply
+ * Q8MULSU XRa, XRb, XRc, XRd - Parallel signed 8 bit pattern multiply
+ */
+static void gen_mxu_q8mul_q8mulsu(DisasContext *ctx)
+{
+    TCGv t0, t1, t2, t3, t4, t5, t6, t7;
+    uint32_t XRa, XRb, XRc, XRd, sel;
+
+    t0 = tcg_temp_new();
+    t1 = tcg_temp_new();
+    t2 = tcg_temp_new();
+    t3 = tcg_temp_new();
+    t4 = tcg_temp_new();
+    t5 = tcg_temp_new();
+    t6 = tcg_temp_new();
+    t7 = tcg_temp_new();
+
+    XRa = extract32(ctx->opcode, 6, 4);
+    XRb = extract32(ctx->opcode, 10, 4);
+    XRc = extract32(ctx->opcode, 14, 4);
+    XRd = extract32(ctx->opcode, 18, 4);
+    sel = extract32(ctx->opcode, 22, 2);
+
+    gen_load_mxu_gpr(t3, XRb);
+    gen_load_mxu_gpr(t7, XRc);
+
+    if (sel == 0x2) {
+        /* Q8MULSU */
+        tcg_gen_ext8s_tl(t0, t3);
+        tcg_gen_shri_tl(t3, t3, 8);
+        tcg_gen_ext8s_tl(t1, t3);
+        tcg_gen_shri_tl(t3, t3, 8);
+        tcg_gen_ext8s_tl(t2, t3);
+        tcg_gen_shri_tl(t3, t3, 8);
+        tcg_gen_ext8s_tl(t3, t3);
+    } else {
+        /* Q8MUL */
+        tcg_gen_ext8u_tl(t0, t3);
+        tcg_gen_shri_tl(t3, t3, 8);
+        tcg_gen_ext8u_tl(t1, t3);
+        tcg_gen_shri_tl(t3, t3, 8);
+        tcg_gen_ext8u_tl(t2, t3);
+        tcg_gen_shri_tl(t3, t3, 8);
+        tcg_gen_ext8u_tl(t3, t3);
+    }
+
+    tcg_gen_ext8u_tl(t4, t7);
+    tcg_gen_shri_tl(t7, t7, 8);
+    tcg_gen_ext8u_tl(t5, t7);
+    tcg_gen_shri_tl(t7, t7, 8);
+    tcg_gen_ext8u_tl(t6, t7);
+    tcg_gen_shri_tl(t7, t7, 8);
+    tcg_gen_ext8u_tl(t7, t7);
+
+    tcg_gen_mul_tl(t0, t0, t4);
+    tcg_gen_mul_tl(t1, t1, t5);
+    tcg_gen_mul_tl(t2, t2, t6);
+    tcg_gen_mul_tl(t3, t3, t7);
+
+    tcg_gen_andi_tl(t0, t0, 0xFFFF);
+    tcg_gen_andi_tl(t1, t1, 0xFFFF);
+    tcg_gen_andi_tl(t2, t2, 0xFFFF);
+    tcg_gen_andi_tl(t3, t3, 0xFFFF);
+
+    tcg_gen_shli_tl(t1, t1, 16);
+    tcg_gen_shli_tl(t3, t3, 16);
+
+    tcg_gen_or_tl(t0, t0, t1);
+    tcg_gen_or_tl(t1, t2, t3);
+
+    gen_store_mxu_gpr(t0, XRd);
+    gen_store_mxu_gpr(t1, XRa);
+
+    tcg_temp_free(t0);
+    tcg_temp_free(t1);
+    tcg_temp_free(t2);
+    tcg_temp_free(t3);
+    tcg_temp_free(t4);
+    tcg_temp_free(t5);
+    tcg_temp_free(t6);
+    tcg_temp_free(t7);
+}
+
+/*
+ * S32LDD  XRa, Rb, S12 - Load a word from memory to XRF
+ * S32LDDR XRa, Rb, S12 - Load a word from memory to XRF, reversed byte seq.
+ */
+static void gen_mxu_s32ldd_s32lddr(DisasContext *ctx)
+{
+    TCGv t0, t1;
+    uint32_t XRa, Rb, s12, sel;
+
+    t0 = tcg_temp_new();
+    t1 = tcg_temp_new();
+
+    XRa = extract32(ctx->opcode, 6, 4);
+    s12 = extract32(ctx->opcode, 10, 10);
+    sel = extract32(ctx->opcode, 20, 1);
+    Rb = extract32(ctx->opcode, 21, 5);
+
+    gen_load_gpr(t0, Rb);
+
+    tcg_gen_movi_tl(t1, s12);
+    tcg_gen_shli_tl(t1, t1, 2);
+    if (s12 & 0x200) {
+        tcg_gen_ori_tl(t1, t1, 0xFFFFF000);
+    }
+    tcg_gen_add_tl(t1, t0, t1);
+    tcg_gen_qemu_ld_tl(t1, t1, ctx->mem_idx, MO_SL);
+
+    if (sel == 1) {
+        /* S32LDDR */
+        tcg_gen_bswap32_tl(t1, t1);
+    }
+    gen_store_mxu_gpr(t1, XRa);
+
+    tcg_temp_free(t0);
+    tcg_temp_free(t1);
+}
+
+
+/*
+ *                 MXU instruction category: logic
+ *                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *               S32NOR    S32AND    S32OR    S32XOR
+ */
+
+/*
+ *  S32NOR XRa, XRb, XRc
+ *    Update XRa with the result of logical bitwise 'nor' operation
+ *    applied to the content of XRb and XRc.
+ */
+static void gen_mxu_S32NOR(DisasContext *ctx)
+{
+    uint32_t pad, XRc, XRb, XRa;
+
+    pad = extract32(ctx->opcode, 21, 5);
+    XRc = extract32(ctx->opcode, 14, 4);
+    XRb = extract32(ctx->opcode, 10, 4);
+    XRa = extract32(ctx->opcode,  6, 4);
+
+    if (unlikely(pad != 0)) {
+        /* opcode padding incorrect -> do nothing */
+    } else if (unlikely(XRa == 0)) {
+        /* destination is zero register -> do nothing */
+    } else if (unlikely((XRb == 0) && (XRc == 0))) {
+        /* both operands zero registers -> just set destination to all 1s */
+        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0xFFFFFFFF);
+    } else if (unlikely(XRb == 0)) {
+        /* XRb zero register -> just set destination to the negation of XRc */
+        tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
+    } else if (unlikely(XRc == 0)) {
+        /* XRa zero register -> just set destination to the negation of XRb */
+        tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
+    } else if (unlikely(XRb == XRc)) {
+        /* both operands same -> just set destination to the negation of XRb */
+        tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
+    } else {
+        /* the most general case */
+        tcg_gen_nor_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
+    }
+}
+
+/*
+ *  S32AND XRa, XRb, XRc
+ *    Update XRa with the result of logical bitwise 'and' operation
+ *    applied to the content of XRb and XRc.
+ */
+static void gen_mxu_S32AND(DisasContext *ctx)
+{
+    uint32_t pad, XRc, XRb, XRa;
+
+    pad = extract32(ctx->opcode, 21, 5);
+    XRc = extract32(ctx->opcode, 14, 4);
+    XRb = extract32(ctx->opcode, 10, 4);
+    XRa = extract32(ctx->opcode,  6, 4);
+
+    if (unlikely(pad != 0)) {
+        /* opcode padding incorrect -> do nothing */
+    } else if (unlikely(XRa == 0)) {
+        /* destination is zero register -> do nothing */
+    } else if (unlikely((XRb == 0) || (XRc == 0))) {
+        /* one of operands zero register -> just set destination to all 0s */
+        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
+    } else if (unlikely(XRb == XRc)) {
+        /* both operands same -> just set destination to one of them */
+        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
+    } else {
+        /* the most general case */
+        tcg_gen_and_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
+    }
+}
+
+/*
+ *  S32OR XRa, XRb, XRc
+ *    Update XRa with the result of logical bitwise 'or' operation
+ *    applied to the content of XRb and XRc.
+ */
+static void gen_mxu_S32OR(DisasContext *ctx)
+{
+    uint32_t pad, XRc, XRb, XRa;
+
+    pad = extract32(ctx->opcode, 21, 5);
+    XRc = extract32(ctx->opcode, 14, 4);
+    XRb = extract32(ctx->opcode, 10, 4);
+    XRa = extract32(ctx->opcode,  6, 4);
+
+    if (unlikely(pad != 0)) {
+        /* opcode padding incorrect -> do nothing */
+    } else if (unlikely(XRa == 0)) {
+        /* destination is zero register -> do nothing */
+    } else if (unlikely((XRb == 0) && (XRc == 0))) {
+        /* both operands zero registers -> just set destination to all 0s */
+        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
+    } else if (unlikely(XRb == 0)) {
+        /* XRb zero register -> just set destination to the content of XRc */
+        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
+    } else if (unlikely(XRc == 0)) {
+        /* XRc zero register -> just set destination to the content of XRb */
+        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
+    } else if (unlikely(XRb == XRc)) {
+        /* both operands same -> just set destination to one of them */
+        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
+    } else {
+        /* the most general case */
+        tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
+    }
+}
+
+/*
+ *  S32XOR XRa, XRb, XRc
+ *    Update XRa with the result of logical bitwise 'xor' operation
+ *    applied to the content of XRb and XRc.
+ */
+static void gen_mxu_S32XOR(DisasContext *ctx)
+{
+    uint32_t pad, XRc, XRb, XRa;
+
+    pad = extract32(ctx->opcode, 21, 5);
+    XRc = extract32(ctx->opcode, 14, 4);
+    XRb = extract32(ctx->opcode, 10, 4);
+    XRa = extract32(ctx->opcode,  6, 4);
+
+    if (unlikely(pad != 0)) {
+        /* opcode padding incorrect -> do nothing */
+    } else if (unlikely(XRa == 0)) {
+        /* destination is zero register -> do nothing */
+    } else if (unlikely((XRb == 0) && (XRc == 0))) {
+        /* both operands zero registers -> just set destination to all 0s */
+        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
+    } else if (unlikely(XRb == 0)) {
+        /* XRb zero register -> just set destination to the content of XRc */
+        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
+    } else if (unlikely(XRc == 0)) {
+        /* XRc zero register -> just set destination to the content of XRb */
+        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
+    } else if (unlikely(XRb == XRc)) {
+        /* both operands same -> just set destination to all 0s */
+        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
+    } else {
+        /* the most general case */
+        tcg_gen_xor_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
+    }
+}
+
+
+/*
+ *                   MXU instruction category max/min
+ *                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *                     S32MAX     D16MAX     Q8MAX
+ *                     S32MIN     D16MIN     Q8MIN
+ */
+
+/*
+ *  S32MAX XRa, XRb, XRc
+ *    Update XRa with the maximum of signed 32-bit integers contained
+ *    in XRb and XRc.
+ *
+ *  S32MIN XRa, XRb, XRc
+ *    Update XRa with the minimum of signed 32-bit integers contained
+ *    in XRb and XRc.
+ */
+static void gen_mxu_S32MAX_S32MIN(DisasContext *ctx)
+{
+    uint32_t pad, opc, XRc, XRb, XRa;
+
+    pad = extract32(ctx->opcode, 21, 5);
+    opc = extract32(ctx->opcode, 18, 3);
+    XRc = extract32(ctx->opcode, 14, 4);
+    XRb = extract32(ctx->opcode, 10, 4);
+    XRa = extract32(ctx->opcode,  6, 4);
+
+    if (unlikely(pad != 0)) {
+        /* opcode padding incorrect -> do nothing */
+    } else if (unlikely(XRa == 0)) {
+        /* destination is zero register -> do nothing */
+    } else if (unlikely((XRb == 0) && (XRc == 0))) {
+        /* both operands zero registers -> just set destination to zero */
+        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
+    } else if (unlikely((XRb == 0) || (XRc == 0))) {
+        /* exactly one operand is zero register - find which one is not...*/
+        uint32_t XRx = XRb ? XRb : XRc;
+        /* ...and do max/min operation with one operand 0 */
+        if (opc == OPC_MXU_S32MAX) {
+            tcg_gen_smax_i32(mxu_gpr[XRa - 1], mxu_gpr[XRx - 1], 0);
+        } else {
+            tcg_gen_smin_i32(mxu_gpr[XRa - 1], mxu_gpr[XRx - 1], 0);
+        }
+    } else if (unlikely(XRb == XRc)) {
+        /* both operands same -> just set destination to one of them */
+        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
+    } else {
+        /* the most general case */
+        if (opc == OPC_MXU_S32MAX) {
+            tcg_gen_smax_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1],
+                                               mxu_gpr[XRc - 1]);
+        } else {
+            tcg_gen_smin_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1],
+                                               mxu_gpr[XRc - 1]);
+        }
+    }
+}
+
+/*
+ *  D16MAX
+ *    Update XRa with the 16-bit-wise maximums of signed integers
+ *    contained in XRb and XRc.
+ *
+ *  D16MIN
+ *    Update XRa with the 16-bit-wise minimums of signed integers
+ *    contained in XRb and XRc.
+ */
+static void gen_mxu_D16MAX_D16MIN(DisasContext *ctx)
+{
+    uint32_t pad, opc, XRc, XRb, XRa;
+
+    pad = extract32(ctx->opcode, 21, 5);
+    opc = extract32(ctx->opcode, 18, 3);
+    XRc = extract32(ctx->opcode, 14, 4);
+    XRb = extract32(ctx->opcode, 10, 4);
+    XRa = extract32(ctx->opcode,  6, 4);
+
+    if (unlikely(pad != 0)) {
+        /* opcode padding incorrect -> do nothing */
+    } else if (unlikely(XRc == 0)) {
+        /* destination is zero register -> do nothing */
+    } else if (unlikely((XRb == 0) && (XRa == 0))) {
+        /* both operands zero registers -> just set destination to zero */
+        tcg_gen_movi_i32(mxu_gpr[XRc - 1], 0);
+    } else if (unlikely((XRb == 0) || (XRa == 0))) {
+        /* exactly one operand is zero register - find which one is not...*/
+        uint32_t XRx = XRb ? XRb : XRc;
+        /* ...and do half-word-wise max/min with one operand 0 */
+        TCGv_i32 t0 = tcg_temp_new();
+        TCGv_i32 t1 = tcg_const_i32(0);
+
+        /* the left half-word first */
+        tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFFFF0000);
+        if (opc == OPC_MXU_D16MAX) {
+            tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
+        } else {
+            tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
+        }
+
+        /* the right half-word */
+        tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0x0000FFFF);
+        /* move half-words to the leftmost position */
+        tcg_gen_shli_i32(t0, t0, 16);
+        /* t0 will be max/min of t0 and t1 */
+        if (opc == OPC_MXU_D16MAX) {
+            tcg_gen_smax_i32(t0, t0, t1);
+        } else {
+            tcg_gen_smin_i32(t0, t0, t1);
+        }
+        /* return resulting half-words to its original position */
+        tcg_gen_shri_i32(t0, t0, 16);
+        /* finally update the destination */
+        tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
+
+        tcg_temp_free(t1);
+        tcg_temp_free(t0);
+    } else if (unlikely(XRb == XRc)) {
+        /* both operands same -> just set destination to one of them */
+        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
+    } else {
+        /* the most general case */
+        TCGv_i32 t0 = tcg_temp_new();
+        TCGv_i32 t1 = tcg_temp_new();
+
+        /* the left half-word first */
+        tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFFFF0000);
+        tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFF0000);
+        if (opc == OPC_MXU_D16MAX) {
+            tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
+        } else {
+            tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
+        }
+
+        /* the right half-word */
+        tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x0000FFFF);
+        tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0x0000FFFF);
+        /* move half-words to the leftmost position */
+        tcg_gen_shli_i32(t0, t0, 16);
+        tcg_gen_shli_i32(t1, t1, 16);
+        /* t0 will be max/min of t0 and t1 */
+        if (opc == OPC_MXU_D16MAX) {
+            tcg_gen_smax_i32(t0, t0, t1);
+        } else {
+            tcg_gen_smin_i32(t0, t0, t1);
+        }
+        /* return resulting half-words to its original position */
+        tcg_gen_shri_i32(t0, t0, 16);
+        /* finally update the destination */
+        tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
+
+        tcg_temp_free(t1);
+        tcg_temp_free(t0);
+    }
+}
+
+/*
+ *  Q8MAX
+ *    Update XRa with the 8-bit-wise maximums of signed integers
+ *    contained in XRb and XRc.
+ *
+ *  Q8MIN
+ *    Update XRa with the 8-bit-wise minimums of signed integers
+ *    contained in XRb and XRc.
+ */
+static void gen_mxu_Q8MAX_Q8MIN(DisasContext *ctx)
+{
+    uint32_t pad, opc, XRc, XRb, XRa;
+
+    pad = extract32(ctx->opcode, 21, 5);
+    opc = extract32(ctx->opcode, 18, 3);
+    XRc = extract32(ctx->opcode, 14, 4);
+    XRb = extract32(ctx->opcode, 10, 4);
+    XRa = extract32(ctx->opcode,  6, 4);
+
+    if (unlikely(pad != 0)) {
+        /* opcode padding incorrect -> do nothing */
+    } else if (unlikely(XRa == 0)) {
+        /* destination is zero register -> do nothing */
+    } else if (unlikely((XRb == 0) && (XRc == 0))) {
+        /* both operands zero registers -> just set destination to zero */
+        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
+    } else if (unlikely((XRb == 0) || (XRc == 0))) {
+        /* exactly one operand is zero register - make it be the first...*/
+        uint32_t XRx = XRb ? XRb : XRc;
+        /* ...and do byte-wise max/min with one operand 0 */
+        TCGv_i32 t0 = tcg_temp_new();
+        TCGv_i32 t1 = tcg_const_i32(0);
+        int32_t i;
+
+        /* the leftmost byte (byte 3) first */
+        tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFF000000);
+        if (opc == OPC_MXU_Q8MAX) {
+            tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
+        } else {
+            tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
+        }
+
+        /* bytes 2, 1, 0 */
+        for (i = 2; i >= 0; i--) {
+            /* extract the byte */
+            tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFF << (8 * i));
+            /* move the byte to the leftmost position */
+            tcg_gen_shli_i32(t0, t0, 8 * (3 - i));
+            /* t0 will be max/min of t0 and t1 */
+            if (opc == OPC_MXU_Q8MAX) {
+                tcg_gen_smax_i32(t0, t0, t1);
+            } else {
+                tcg_gen_smin_i32(t0, t0, t1);
+            }
+            /* return resulting byte to its original position */
+            tcg_gen_shri_i32(t0, t0, 8 * (3 - i));
+            /* finally update the destination */
+            tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
+        }
+
+        tcg_temp_free(t1);
+        tcg_temp_free(t0);
+    } else if (unlikely(XRb == XRc)) {
+        /* both operands same -> just set destination to one of them */
+        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
+    } else {
+        /* the most general case */
+        TCGv_i32 t0 = tcg_temp_new();
+        TCGv_i32 t1 = tcg_temp_new();
+        int32_t i;
+
+        /* the leftmost bytes (bytes 3) first */
+        tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFF000000);
+        tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF000000);
+        if (opc == OPC_MXU_Q8MAX) {
+            tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
+        } else {
+            tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
+        }
+
+        /* bytes 2, 1, 0 */
+        for (i = 2; i >= 0; i--) {
+            /* extract corresponding bytes */
+            tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFF << (8 * i));
+            tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF << (8 * i));
+            /* move the bytes to the leftmost position */
+            tcg_gen_shli_i32(t0, t0, 8 * (3 - i));
+            tcg_gen_shli_i32(t1, t1, 8 * (3 - i));
+            /* t0 will be max/min of t0 and t1 */
+            if (opc == OPC_MXU_Q8MAX) {
+                tcg_gen_smax_i32(t0, t0, t1);
+            } else {
+                tcg_gen_smin_i32(t0, t0, t1);
+            }
+            /* return resulting byte to its original position */
+            tcg_gen_shri_i32(t0, t0, 8 * (3 - i));
+            /* finally update the destination */
+            tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
+        }
+
+        tcg_temp_free(t1);
+        tcg_temp_free(t0);
+    }
+}
+
+
+/*
+ *                 MXU instruction category: align
+ *                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *                       S32ALN     S32ALNI
+ */
+
+/*
+ *  S32ALNI XRc, XRb, XRa, optn3
+ *    Arrange bytes from XRb and XRc according to one of five sets of
+ *    rules determined by optn3, and place the result in XRa.
+ */
+static void gen_mxu_S32ALNI(DisasContext *ctx)
+{
+    uint32_t optn3, pad, XRc, XRb, XRa;
+
+    optn3 = extract32(ctx->opcode,  23, 3);
+    pad   = extract32(ctx->opcode,  21, 2);
+    XRc   = extract32(ctx->opcode, 14, 4);
+    XRb   = extract32(ctx->opcode, 10, 4);
+    XRa   = extract32(ctx->opcode,  6, 4);
+
+    if (unlikely(pad != 0)) {
+        /* opcode padding incorrect -> do nothing */
+    } else if (unlikely(XRa == 0)) {
+        /* destination is zero register -> do nothing */
+    } else if (unlikely((XRb == 0) && (XRc == 0))) {
+        /* both operands zero registers -> just set destination to all 0s */
+        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
+    } else if (unlikely(XRb == 0)) {
+        /* XRb zero register -> just appropriatelly shift XRc into XRa */
+        switch (optn3) {
+        case MXU_OPTN3_PTN0:
+            tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
+            break;
+        case MXU_OPTN3_PTN1:
+        case MXU_OPTN3_PTN2:
+        case MXU_OPTN3_PTN3:
+            tcg_gen_shri_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1],
+                             8 * (4 - optn3));
+            break;
+        case MXU_OPTN3_PTN4:
+            tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
+            break;
+        }
+    } else if (unlikely(XRc == 0)) {
+        /* XRc zero register -> just appropriatelly shift XRb into XRa */
+        switch (optn3) {
+        case MXU_OPTN3_PTN0:
+            tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
+            break;
+        case MXU_OPTN3_PTN1:
+        case MXU_OPTN3_PTN2:
+        case MXU_OPTN3_PTN3:
+            tcg_gen_shri_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], 8 * optn3);
+            break;
+        case MXU_OPTN3_PTN4:
+            tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
+            break;
+        }
+    } else if (unlikely(XRb == XRc)) {
+        /* both operands same -> just rotation or moving from any of them */
+        switch (optn3) {
+        case MXU_OPTN3_PTN0:
+        case MXU_OPTN3_PTN4:
+            tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
+            break;
+        case MXU_OPTN3_PTN1:
+        case MXU_OPTN3_PTN2:
+        case MXU_OPTN3_PTN3:
+            tcg_gen_rotli_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], 8 * optn3);
+            break;
+        }
+    } else {
+        /* the most general case */
+        switch (optn3) {
+        case MXU_OPTN3_PTN0:
+            {
+                /*                                         */
+                /*         XRb                XRc          */
+                /*  +---------------+                      */
+                /*  | A   B   C   D |    E   F   G   H     */
+                /*  +-------+-------+                      */
+                /*          |                              */
+                /*         XRa                             */
+                /*                                         */
+
+                tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
+            }
+            break;
+        case MXU_OPTN3_PTN1:
+            {
+                /*                                         */
+                /*         XRb                 XRc         */
+                /*      +-------------------+              */
+                /*    A | B   C   D       E | F   G   H    */
+                /*      +---------+---------+              */
+                /*                |                        */
+                /*               XRa                       */
+                /*                                         */
+
+                TCGv_i32 t0 = tcg_temp_new();
+                TCGv_i32 t1 = tcg_temp_new();
+
+                tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x00FFFFFF);
+                tcg_gen_shli_i32(t0, t0, 8);
+
+                tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF000000);
+                tcg_gen_shri_i32(t1, t1, 24);
+
+                tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
+
+                tcg_temp_free(t1);
+                tcg_temp_free(t0);
+            }
+            break;
+        case MXU_OPTN3_PTN2:
+            {
+                /*                                         */
+                /*         XRb                 XRc         */
+                /*          +-------------------+          */
+                /*    A   B | C   D       E   F | G   H    */
+                /*          +---------+---------+          */
+                /*                    |                    */
+                /*                   XRa                   */
+                /*                                         */
+
+                TCGv_i32 t0 = tcg_temp_new();
+                TCGv_i32 t1 = tcg_temp_new();
+
+                tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x0000FFFF);
+                tcg_gen_shli_i32(t0, t0, 16);
+
+                tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFF0000);
+                tcg_gen_shri_i32(t1, t1, 16);
+
+                tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
+
+                tcg_temp_free(t1);
+                tcg_temp_free(t0);
+            }
+            break;
+        case MXU_OPTN3_PTN3:
+            {
+                /*                                         */
+                /*         XRb                 XRc         */
+                /*              +-------------------+      */
+                /*    A   B   C | D       E   F   G | H    */
+                /*              +---------+---------+      */
+                /*                        |                */
+                /*                       XRa               */
+                /*                                         */
+
+                TCGv_i32 t0 = tcg_temp_new();
+                TCGv_i32 t1 = tcg_temp_new();
+
+                tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x000000FF);
+                tcg_gen_shli_i32(t0, t0, 24);
+
+                tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFFFF00);
+                tcg_gen_shri_i32(t1, t1, 8);
+
+                tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
+
+                tcg_temp_free(t1);
+                tcg_temp_free(t0);
+            }
+            break;
+        case MXU_OPTN3_PTN4:
+            {
+                /*                                         */
+                /*         XRb                 XRc         */
+                /*                     +---------------+   */
+                /*    A   B   C   D    | E   F   G   H |   */
+                /*                     +-------+-------+   */
+                /*                             |           */
+                /*                            XRa          */
+                /*                                         */
+
+                tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
+            }
+            break;
+        }
+    }
+}
+
+
+/*
+ * Decoding engine for MXU
+ * =======================
+ */
+
+static void decode_opc_mxu__pool00(DisasContext *ctx)
+{
+    uint32_t opcode = extract32(ctx->opcode, 18, 3);
+
+    switch (opcode) {
+    case OPC_MXU_S32MAX:
+    case OPC_MXU_S32MIN:
+        gen_mxu_S32MAX_S32MIN(ctx);
+        break;
+    case OPC_MXU_D16MAX:
+    case OPC_MXU_D16MIN:
+        gen_mxu_D16MAX_D16MIN(ctx);
+        break;
+    case OPC_MXU_Q8MAX:
+    case OPC_MXU_Q8MIN:
+        gen_mxu_Q8MAX_Q8MIN(ctx);
+        break;
+    default:
+        MIPS_INVAL("decode_opc_mxu");
+        gen_reserved_instruction(ctx);
+        break;
+    }
+}
+
+static void decode_opc_mxu__pool04(DisasContext *ctx)
+{
+    uint32_t opcode = extract32(ctx->opcode, 20, 1);
+
+    switch (opcode) {
+    case OPC_MXU_S32LDD:
+    case OPC_MXU_S32LDDR:
+        gen_mxu_s32ldd_s32lddr(ctx);
+        break;
+    default:
+        MIPS_INVAL("decode_opc_mxu");
+        gen_reserved_instruction(ctx);
+        break;
+    }
+}
+
+static void decode_opc_mxu__pool16(DisasContext *ctx)
+{
+    uint32_t opcode = extract32(ctx->opcode, 18, 3);
+
+    switch (opcode) {
+    case OPC_MXU_S32ALNI:
+        gen_mxu_S32ALNI(ctx);
+        break;
+    case OPC_MXU_S32NOR:
+        gen_mxu_S32NOR(ctx);
+        break;
+    case OPC_MXU_S32AND:
+        gen_mxu_S32AND(ctx);
+        break;
+    case OPC_MXU_S32OR:
+        gen_mxu_S32OR(ctx);
+        break;
+    case OPC_MXU_S32XOR:
+        gen_mxu_S32XOR(ctx);
+        break;
+    default:
+        MIPS_INVAL("decode_opc_mxu");
+        gen_reserved_instruction(ctx);
+        break;
+    }
+}
+
+static void decode_opc_mxu__pool19(DisasContext *ctx)
+{
+    uint32_t opcode = extract32(ctx->opcode, 22, 2);
+
+    switch (opcode) {
+    case OPC_MXU_Q8MUL:
+    case OPC_MXU_Q8MULSU:
+        gen_mxu_q8mul_q8mulsu(ctx);
+        break;
+    default:
+        MIPS_INVAL("decode_opc_mxu");
+        gen_reserved_instruction(ctx);
+        break;
+    }
+}
+
+bool decode_ase_mxu(DisasContext *ctx, uint32_t insn)
+{
+    uint32_t opcode = extract32(insn, 0, 6);
+
+    if (opcode == OPC_MXU_S32M2I) {
+        gen_mxu_s32m2i(ctx);
+        return true;
+    }
+
+    if (opcode == OPC_MXU_S32I2M) {
+        gen_mxu_s32i2m(ctx);
+        return true;
+    }
+
+    {
+        TCGv t_mxu_cr = tcg_temp_new();
+        TCGLabel *l_exit = gen_new_label();
+
+        gen_load_mxu_cr(t_mxu_cr);
+        tcg_gen_andi_tl(t_mxu_cr, t_mxu_cr, MXU_CR_MXU_EN);
+        tcg_gen_brcondi_tl(TCG_COND_NE, t_mxu_cr, MXU_CR_MXU_EN, l_exit);
+
+        switch (opcode) {
+        case OPC_MXU__POOL00:
+            decode_opc_mxu__pool00(ctx);
+            break;
+        case OPC_MXU_D16MUL:
+            gen_mxu_d16mul(ctx);
+            break;
+        case OPC_MXU_D16MAC:
+            gen_mxu_d16mac(ctx);
+            break;
+        case OPC_MXU__POOL04:
+            decode_opc_mxu__pool04(ctx);
+            break;
+        case OPC_MXU_S8LDD:
+            gen_mxu_s8ldd(ctx);
+            break;
+        case OPC_MXU__POOL16:
+            decode_opc_mxu__pool16(ctx);
+            break;
+        case OPC_MXU__POOL19:
+            decode_opc_mxu__pool19(ctx);
+            break;
+        default:
+            MIPS_INVAL("decode_opc_mxu");
+            gen_reserved_instruction(ctx);
+        }
+
+        gen_set_label(l_exit);
+        tcg_temp_free(t_mxu_cr);
+    }
+
+    return true;
+}
+
+#else /* !defined(TARGET_MIPS64) */
+
+void mxu_translate_init(void)
+{
+    g_assert_not_reached();
+}
+
+bool decode_ase_mxu(DisasContext *ctx, uint32_t insn)
+{
+    return false;
+}
+
+#endif /* defined(TARGET_MIPS64) */
diff --git a/target/mips/translate.c b/target/mips/translate.c
index 68b5dee4bab..0d7482b243a 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -1129,392 +1129,6 @@ enum {
     OPC_NMSUB_PS    = 0x3E | OPC_CP3,
 };
 
-/*
- *
- *       AN OVERVIEW OF MXU EXTENSION INSTRUCTION SET
- *       ============================================
- *
- *
- * MXU (full name: MIPS eXtension/enhanced Unit) is a SIMD extension of MIPS32
- * instructions set. It is designed to fit the needs of signal, graphical and
- * video processing applications. MXU instruction set is used in Xburst family
- * of microprocessors by Ingenic.
- *
- * MXU unit contains 17 registers called X0-X16. X0 is always zero, and X16 is
- * the control register.
- *
- *
- *     The notation used in MXU assembler mnemonics
- *     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- *  Register operands:
- *
- *   XRa, XRb, XRc, XRd - MXU registers
- *   Rb, Rc, Rd, Rs, Rt - general purpose MIPS registers
- *
- *  Non-register operands:
- *
- *   aptn1 - 1-bit accumulate add/subtract pattern
- *   aptn2 - 2-bit accumulate add/subtract pattern
- *   eptn2 - 2-bit execute add/subtract pattern
- *   optn2 - 2-bit operand pattern
- *   optn3 - 3-bit operand pattern
- *   sft4  - 4-bit shift amount
- *   strd2 - 2-bit stride amount
- *
- *  Prefixes:
- *
- *   Level of parallelism:                Operand size:
- *    S - single operation at a time       32 - word
- *    D - two operations in parallel       16 - half word
- *    Q - four operations in parallel       8 - byte
- *
- *  Operations:
- *
- *   ADD   - Add or subtract
- *   ADDC  - Add with carry-in
- *   ACC   - Accumulate
- *   ASUM  - Sum together then accumulate (add or subtract)
- *   ASUMC - Sum together then accumulate (add or subtract) with carry-in
- *   AVG   - Average between 2 operands
- *   ABD   - Absolute difference
- *   ALN   - Align data
- *   AND   - Logical bitwise 'and' operation
- *   CPS   - Copy sign
- *   EXTR  - Extract bits
- *   I2M   - Move from GPR register to MXU register
- *   LDD   - Load data from memory to XRF
- *   LDI   - Load data from memory to XRF (and increase the address base)
- *   LUI   - Load unsigned immediate
- *   MUL   - Multiply
- *   MULU  - Unsigned multiply
- *   MADD  - 64-bit operand add 32x32 product
- *   MSUB  - 64-bit operand subtract 32x32 product
- *   MAC   - Multiply and accumulate (add or subtract)
- *   MAD   - Multiply and add or subtract
- *   MAX   - Maximum between 2 operands
- *   MIN   - Minimum between 2 operands
- *   M2I   - Move from MXU register to GPR register
- *   MOVZ  - Move if zero
- *   MOVN  - Move if non-zero
- *   NOR   - Logical bitwise 'nor' operation
- *   OR    - Logical bitwise 'or' operation
- *   STD   - Store data from XRF to memory
- *   SDI   - Store data from XRF to memory (and increase the address base)
- *   SLT   - Set of less than comparison
- *   SAD   - Sum of absolute differences
- *   SLL   - Logical shift left
- *   SLR   - Logical shift right
- *   SAR   - Arithmetic shift right
- *   SAT   - Saturation
- *   SFL   - Shuffle
- *   SCOP  - Calculate x’s scope (-1, means x<0; 0, means x==0; 1, means x>0)
- *   XOR   - Logical bitwise 'exclusive or' operation
- *
- *  Suffixes:
- *
- *   E - Expand results
- *   F - Fixed point multiplication
- *   L - Low part result
- *   R - Doing rounding
- *   V - Variable instead of immediate
- *   W - Combine above L and V
- *
- *
- *     The list of MXU instructions grouped by functionality
- *     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * Load/Store instructions           Multiplication instructions
- * -----------------------           ---------------------------
- *
- *  S32LDD XRa, Rb, s12               S32MADD XRa, XRd, Rs, Rt
- *  S32STD XRa, Rb, s12               S32MADDU XRa, XRd, Rs, Rt
- *  S32LDDV XRa, Rb, rc, strd2        S32MSUB XRa, XRd, Rs, Rt
- *  S32STDV XRa, Rb, rc, strd2        S32MSUBU XRa, XRd, Rs, Rt
- *  S32LDI XRa, Rb, s12               S32MUL XRa, XRd, Rs, Rt
- *  S32SDI XRa, Rb, s12               S32MULU XRa, XRd, Rs, Rt
- *  S32LDIV XRa, Rb, rc, strd2        D16MUL XRa, XRb, XRc, XRd, optn2
- *  S32SDIV XRa, Rb, rc, strd2        D16MULE XRa, XRb, XRc, optn2
- *  S32LDDR XRa, Rb, s12              D16MULF XRa, XRb, XRc, optn2
- *  S32STDR XRa, Rb, s12              D16MAC XRa, XRb, XRc, XRd, aptn2, optn2
- *  S32LDDVR XRa, Rb, rc, strd2       D16MACE XRa, XRb, XRc, XRd, aptn2, optn2
- *  S32STDVR XRa, Rb, rc, strd2       D16MACF XRa, XRb, XRc, XRd, aptn2, optn2
- *  S32LDIR XRa, Rb, s12              D16MADL XRa, XRb, XRc, XRd, aptn2, optn2
- *  S32SDIR XRa, Rb, s12              S16MAD XRa, XRb, XRc, XRd, aptn1, optn2
- *  S32LDIVR XRa, Rb, rc, strd2       Q8MUL XRa, XRb, XRc, XRd
- *  S32SDIVR XRa, Rb, rc, strd2       Q8MULSU XRa, XRb, XRc, XRd
- *  S16LDD XRa, Rb, s10, eptn2        Q8MAC XRa, XRb, XRc, XRd, aptn2
- *  S16STD XRa, Rb, s10, eptn2        Q8MACSU XRa, XRb, XRc, XRd, aptn2
- *  S16LDI XRa, Rb, s10, eptn2        Q8MADL XRa, XRb, XRc, XRd, aptn2
- *  S16SDI XRa, Rb, s10, eptn2
- *  S8LDD XRa, Rb, s8, eptn3
- *  S8STD XRa, Rb, s8, eptn3         Addition and subtraction instructions
- *  S8LDI XRa, Rb, s8, eptn3         -------------------------------------
- *  S8SDI XRa, Rb, s8, eptn3
- *  LXW Rd, Rs, Rt, strd2             D32ADD XRa, XRb, XRc, XRd, eptn2
- *  LXH Rd, Rs, Rt, strd2             D32ADDC XRa, XRb, XRc, XRd
- *  LXHU Rd, Rs, Rt, strd2            D32ACC XRa, XRb, XRc, XRd, eptn2
- *  LXB Rd, Rs, Rt, strd2             D32ACCM XRa, XRb, XRc, XRd, eptn2
- *  LXBU Rd, Rs, Rt, strd2            D32ASUM XRa, XRb, XRc, XRd, eptn2
- *                                    S32CPS XRa, XRb, XRc
- *                                    Q16ADD XRa, XRb, XRc, XRd, eptn2, optn2
- * Comparison instructions            Q16ACC XRa, XRb, XRc, XRd, eptn2
- * -----------------------            Q16ACCM XRa, XRb, XRc, XRd, eptn2
- *                                    D16ASUM XRa, XRb, XRc, XRd, eptn2
- *  S32MAX XRa, XRb, XRc              D16CPS XRa, XRb,
- *  S32MIN XRa, XRb, XRc              D16AVG XRa, XRb, XRc
- *  S32SLT XRa, XRb, XRc              D16AVGR XRa, XRb, XRc
- *  S32MOVZ XRa, XRb, XRc             Q8ADD XRa, XRb, XRc, eptn2
- *  S32MOVN XRa, XRb, XRc             Q8ADDE XRa, XRb, XRc, XRd, eptn2
- *  D16MAX XRa, XRb, XRc              Q8ACCE XRa, XRb, XRc, XRd, eptn2
- *  D16MIN XRa, XRb, XRc              Q8ABD XRa, XRb, XRc
- *  D16SLT XRa, XRb, XRc              Q8SAD XRa, XRb, XRc, XRd
- *  D16MOVZ XRa, XRb, XRc             Q8AVG XRa, XRb, XRc
- *  D16MOVN XRa, XRb, XRc             Q8AVGR XRa, XRb, XRc
- *  Q8MAX XRa, XRb, XRc               D8SUM XRa, XRb, XRc, XRd
- *  Q8MIN XRa, XRb, XRc               D8SUMC XRa, XRb, XRc, XRd
- *  Q8SLT XRa, XRb, XRc
- *  Q8SLTU XRa, XRb, XRc
- *  Q8MOVZ XRa, XRb, XRc             Shift instructions
- *  Q8MOVN XRa, XRb, XRc             ------------------
- *
- *                                    D32SLL XRa, XRb, XRc, XRd, sft4
- * Bitwise instructions               D32SLR XRa, XRb, XRc, XRd, sft4
- * --------------------               D32SAR XRa, XRb, XRc, XRd, sft4
- *                                    D32SARL XRa, XRb, XRc, sft4
- *  S32NOR XRa, XRb, XRc              D32SLLV XRa, XRb, Rb
- *  S32AND XRa, XRb, XRc              D32SLRV XRa, XRb, Rb
- *  S32XOR XRa, XRb, XRc              D32SARV XRa, XRb, Rb
- *  S32OR XRa, XRb, XRc               D32SARW XRa, XRb, XRc, Rb
- *                                    Q16SLL XRa, XRb, XRc, XRd, sft4
- *                                    Q16SLR XRa, XRb, XRc, XRd, sft4
- * Miscellaneous instructions         Q16SAR XRa, XRb, XRc, XRd, sft4
- * -------------------------          Q16SLLV XRa, XRb, Rb
- *                                    Q16SLRV XRa, XRb, Rb
- *  S32SFL XRa, XRb, XRc, XRd, optn2  Q16SARV XRa, XRb, Rb
- *  S32ALN XRa, XRb, XRc, Rb
- *  S32ALNI XRa, XRb, XRc, s3
- *  S32LUI XRa, s8, optn3            Move instructions
- *  S32EXTR XRa, XRb, Rb, bits5      -----------------
- *  S32EXTRV XRa, XRb, Rs, Rt
- *  Q16SCOP XRa, XRb, XRc, XRd        S32M2I XRa, Rb
- *  Q16SAT XRa, XRb, XRc              S32I2M XRa, Rb
- *
- *
- *     The opcode organization of MXU instructions
- *     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * The bits 31..26 of all MXU instructions are equal to 0x1C (also referred
- * as opcode SPECIAL2 in the base MIPS ISA). The organization and meaning of
- * other bits up to the instruction level is as follows:
- *
- *              bits
- *             05..00
- *
- *          ┌─ 000000 ─ OPC_MXU_S32MADD
- *          ├─ 000001 ─ OPC_MXU_S32MADDU
- *          ├─ 000010 ─ <not assigned>   (non-MXU OPC_MUL)
- *          │
- *          │                               20..18
- *          ├─ 000011 ─ OPC_MXU__POOL00 ─┬─ 000 ─ OPC_MXU_S32MAX
- *          │                            ├─ 001 ─ OPC_MXU_S32MIN
- *          │                            ├─ 010 ─ OPC_MXU_D16MAX
- *          │                            ├─ 011 ─ OPC_MXU_D16MIN
- *          │                            ├─ 100 ─ OPC_MXU_Q8MAX
- *          │                            ├─ 101 ─ OPC_MXU_Q8MIN
- *          │                            ├─ 110 ─ OPC_MXU_Q8SLT
- *          │                            └─ 111 ─ OPC_MXU_Q8SLTU
- *          ├─ 000100 ─ OPC_MXU_S32MSUB
- *          ├─ 000101 ─ OPC_MXU_S32MSUBU    20..18
- *          ├─ 000110 ─ OPC_MXU__POOL01 ─┬─ 000 ─ OPC_MXU_S32SLT
- *          │                            ├─ 001 ─ OPC_MXU_D16SLT
- *          │                            ├─ 010 ─ OPC_MXU_D16AVG
- *          │                            ├─ 011 ─ OPC_MXU_D16AVGR
- *          │                            ├─ 100 ─ OPC_MXU_Q8AVG
- *          │                            ├─ 101 ─ OPC_MXU_Q8AVGR
- *          │                            └─ 111 ─ OPC_MXU_Q8ADD
- *          │
- *          │                               20..18
- *          ├─ 000111 ─ OPC_MXU__POOL02 ─┬─ 000 ─ OPC_MXU_S32CPS
- *          │                            ├─ 010 ─ OPC_MXU_D16CPS
- *          │                            ├─ 100 ─ OPC_MXU_Q8ABD
- *          │                            └─ 110 ─ OPC_MXU_Q16SAT
- *          ├─ 001000 ─ OPC_MXU_D16MUL
- *          │                               25..24
- *          ├─ 001001 ─ OPC_MXU__POOL03 ─┬─ 00 ─ OPC_MXU_D16MULF
- *          │                            └─ 01 ─ OPC_MXU_D16MULE
- *          ├─ 001010 ─ OPC_MXU_D16MAC
- *          ├─ 001011 ─ OPC_MXU_D16MACF
- *          ├─ 001100 ─ OPC_MXU_D16MADL
- *          ├─ 001101 ─ OPC_MXU_S16MAD
- *          ├─ 001110 ─ OPC_MXU_Q16ADD
- *          ├─ 001111 ─ OPC_MXU_D16MACE     23
- *          │                            ┌─ 0 ─ OPC_MXU_S32LDD
- *          ├─ 010000 ─ OPC_MXU__POOL04 ─┴─ 1 ─ OPC_MXU_S32LDDR
- *          │
- *          │                               23
- *          ├─ 010001 ─ OPC_MXU__POOL05 ─┬─ 0 ─ OPC_MXU_S32STD
- *          │                            └─ 1 ─ OPC_MXU_S32STDR
- *          │
- *          │                               13..10
- *          ├─ 010010 ─ OPC_MXU__POOL06 ─┬─ 0000 ─ OPC_MXU_S32LDDV
- *          │                            └─ 0001 ─ OPC_MXU_S32LDDVR
- *          │
- *          │                               13..10
- *          ├─ 010011 ─ OPC_MXU__POOL07 ─┬─ 0000 ─ OPC_MXU_S32STDV
- *          │                            └─ 0001 ─ OPC_MXU_S32STDVR
- *          │
- *          │                               23
- *          ├─ 010100 ─ OPC_MXU__POOL08 ─┬─ 0 ─ OPC_MXU_S32LDI
- *          │                            └─ 1 ─ OPC_MXU_S32LDIR
- *          │
- *          │                               23
- *          ├─ 010101 ─ OPC_MXU__POOL09 ─┬─ 0 ─ OPC_MXU_S32SDI
- *          │                            └─ 1 ─ OPC_MXU_S32SDIR
- *          │
- *          │                               13..10
- *          ├─ 010110 ─ OPC_MXU__POOL10 ─┬─ 0000 ─ OPC_MXU_S32LDIV
- *          │                            └─ 0001 ─ OPC_MXU_S32LDIVR
- *          │
- *          │                               13..10
- *          ├─ 010111 ─ OPC_MXU__POOL11 ─┬─ 0000 ─ OPC_MXU_S32SDIV
- *          │                            └─ 0001 ─ OPC_MXU_S32SDIVR
- *          ├─ 011000 ─ OPC_MXU_D32ADD
- *          │                               23..22
- *   MXU    ├─ 011001 ─ OPC_MXU__POOL12 ─┬─ 00 ─ OPC_MXU_D32ACC
- * opcodes ─┤                            ├─ 01 ─ OPC_MXU_D32ACCM
- *          │                            └─ 10 ─ OPC_MXU_D32ASUM
- *          ├─ 011010 ─ <not assigned>
- *          │                               23..22
- *          ├─ 011011 ─ OPC_MXU__POOL13 ─┬─ 00 ─ OPC_MXU_Q16ACC
- *          │                            ├─ 01 ─ OPC_MXU_Q16ACCM
- *          │                            └─ 10 ─ OPC_MXU_Q16ASUM
- *          │
- *          │                               23..22
- *          ├─ 011100 ─ OPC_MXU__POOL14 ─┬─ 00 ─ OPC_MXU_Q8ADDE
- *          │                            ├─ 01 ─ OPC_MXU_D8SUM
- *          ├─ 011101 ─ OPC_MXU_Q8ACCE   └─ 10 ─ OPC_MXU_D8SUMC
- *          ├─ 011110 ─ <not assigned>
- *          ├─ 011111 ─ <not assigned>
- *          ├─ 100000 ─ <not assigned>   (overlaps with CLZ)
- *          ├─ 100001 ─ <not assigned>   (overlaps with CLO)
- *          ├─ 100010 ─ OPC_MXU_S8LDD
- *          ├─ 100011 ─ OPC_MXU_S8STD       15..14
- *          ├─ 100100 ─ OPC_MXU_S8LDI    ┌─ 00 ─ OPC_MXU_S32MUL
- *          ├─ 100101 ─ OPC_MXU_S8SDI    ├─ 00 ─ OPC_MXU_S32MULU
- *          │                            ├─ 00 ─ OPC_MXU_S32EXTR
- *          ├─ 100110 ─ OPC_MXU__POOL15 ─┴─ 00 ─ OPC_MXU_S32EXTRV
- *          │
- *          │                               20..18
- *          ├─ 100111 ─ OPC_MXU__POOL16 ─┬─ 000 ─ OPC_MXU_D32SARW
- *          │                            ├─ 001 ─ OPC_MXU_S32ALN
- *          │                            ├─ 010 ─ OPC_MXU_S32ALNI
- *          │                            ├─ 011 ─ OPC_MXU_S32LUI
- *          │                            ├─ 100 ─ OPC_MXU_S32NOR
- *          │                            ├─ 101 ─ OPC_MXU_S32AND
- *          │                            ├─ 110 ─ OPC_MXU_S32OR
- *          │                            └─ 111 ─ OPC_MXU_S32XOR
- *          │
- *          │                               7..5
- *          ├─ 101000 ─ OPC_MXU__POOL17 ─┬─ 000 ─ OPC_MXU_LXB
- *          │                            ├─ 001 ─ OPC_MXU_LXH
- *          ├─ 101001 ─ <not assigned>   ├─ 011 ─ OPC_MXU_LXW
- *          ├─ 101010 ─ OPC_MXU_S16LDD   ├─ 100 ─ OPC_MXU_LXBU
- *          ├─ 101011 ─ OPC_MXU_S16STD   └─ 101 ─ OPC_MXU_LXHU
- *          ├─ 101100 ─ OPC_MXU_S16LDI
- *          ├─ 101101 ─ OPC_MXU_S16SDI
- *          ├─ 101110 ─ OPC_MXU_S32M2I
- *          ├─ 101111 ─ OPC_MXU_S32I2M
- *          ├─ 110000 ─ OPC_MXU_D32SLL
- *          ├─ 110001 ─ OPC_MXU_D32SLR      20..18
- *          ├─ 110010 ─ OPC_MXU_D32SARL  ┌─ 000 ─ OPC_MXU_D32SLLV
- *          ├─ 110011 ─ OPC_MXU_D32SAR   ├─ 001 ─ OPC_MXU_D32SLRV
- *          ├─ 110100 ─ OPC_MXU_Q16SLL   ├─ 010 ─ OPC_MXU_D32SARV
- *          ├─ 110101 ─ OPC_MXU_Q16SLR   ├─ 011 ─ OPC_MXU_Q16SLLV
- *          │                            ├─ 100 ─ OPC_MXU_Q16SLRV
- *          ├─ 110110 ─ OPC_MXU__POOL18 ─┴─ 101 ─ OPC_MXU_Q16SARV
- *          │
- *          ├─ 110111 ─ OPC_MXU_Q16SAR
- *          │                               23..22
- *          ├─ 111000 ─ OPC_MXU__POOL19 ─┬─ 00 ─ OPC_MXU_Q8MUL
- *          │                            └─ 01 ─ OPC_MXU_Q8MULSU
- *          │
- *          │                               20..18
- *          ├─ 111001 ─ OPC_MXU__POOL20 ─┬─ 000 ─ OPC_MXU_Q8MOVZ
- *          │                            ├─ 001 ─ OPC_MXU_Q8MOVN
- *          │                            ├─ 010 ─ OPC_MXU_D16MOVZ
- *          │                            ├─ 011 ─ OPC_MXU_D16MOVN
- *          │                            ├─ 100 ─ OPC_MXU_S32MOVZ
- *          │                            └─ 101 ─ OPC_MXU_S32MOVN
- *          │
- *          │                               23..22
- *          ├─ 111010 ─ OPC_MXU__POOL21 ─┬─ 00 ─ OPC_MXU_Q8MAC
- *          │                            └─ 10 ─ OPC_MXU_Q8MACSU
- *          ├─ 111011 ─ OPC_MXU_Q16SCOP
- *          ├─ 111100 ─ OPC_MXU_Q8MADL
- *          ├─ 111101 ─ OPC_MXU_S32SFL
- *          ├─ 111110 ─ OPC_MXU_Q8SAD
- *          └─ 111111 ─ <not assigned>   (overlaps with SDBBP)
- *
- *
- * Compiled after:
- *
- *   "XBurst® Instruction Set Architecture MIPS eXtension/enhanced Unit
- *   Programming Manual", Ingenic Semiconductor Co, Ltd., revision June 2, 2017
- */
-
-enum {
-    OPC_MXU__POOL00  = 0x03,
-    OPC_MXU_D16MUL   = 0x08,
-    OPC_MXU_D16MAC   = 0x0A,
-    OPC_MXU__POOL04  = 0x10,
-    OPC_MXU_S8LDD    = 0x22,
-    OPC_MXU__POOL16  = 0x27,
-    OPC_MXU_S32M2I   = 0x2E,
-    OPC_MXU_S32I2M   = 0x2F,
-    OPC_MXU__POOL19  = 0x38,
-};
-
-
-/*
- * MXU pool 00
- */
-enum {
-    OPC_MXU_S32MAX   = 0x00,
-    OPC_MXU_S32MIN   = 0x01,
-    OPC_MXU_D16MAX   = 0x02,
-    OPC_MXU_D16MIN   = 0x03,
-    OPC_MXU_Q8MAX    = 0x04,
-    OPC_MXU_Q8MIN    = 0x05,
-};
-
-/*
- * MXU pool 04
- */
-enum {
-    OPC_MXU_S32LDD   = 0x00,
-    OPC_MXU_S32LDDR  = 0x01,
-};
-
-/*
- * MXU pool 16
- */
-enum {
-    OPC_MXU_S32ALNI  = 0x02,
-    OPC_MXU_S32NOR   = 0x04,
-    OPC_MXU_S32AND   = 0x05,
-    OPC_MXU_S32OR    = 0x06,
-    OPC_MXU_S32XOR   = 0x07,
-};
-
-/*
- * MXU pool 19
- */
-enum {
-    OPC_MXU_Q8MUL    = 0x00,
-    OPC_MXU_Q8MULSU  = 0x01,
-};
-
 /*
  *     Overview of the TX79-specific instruction set
  *     =============================================
@@ -1965,12 +1579,6 @@ static TCGv_i32 hflags;
 TCGv_i32 fpu_fcr0, fpu_fcr31;
 TCGv_i64 fpu_f64[32];
 
-#if !defined(TARGET_MIPS64)
-/* MXU registers */
-static TCGv mxu_gpr[NUMBER_OF_MXU_REGISTERS - 1];
-static TCGv mxu_CR;
-#endif
-
 #include "exec/gen-icount.h"
 
 #define gen_helper_0e0i(name, arg) do {                           \
@@ -2040,31 +1648,6 @@ static const char * const fregnames[] = {
     "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
 };
 
-#if !defined(TARGET_MIPS64)
-static const char * const mxuregnames[] = {
-    "XR1",  "XR2",  "XR3",  "XR4",  "XR5",  "XR6",  "XR7",  "XR8",
-    "XR9",  "XR10", "XR11", "XR12", "XR13", "XR14", "XR15", "MXU_CR",
-};
-
-void mxu_translate_init(void)
-{
-    for (unsigned i = 0; i < NUMBER_OF_MXU_REGISTERS - 1; i++) {
-        mxu_gpr[i] = tcg_global_mem_new(cpu_env,
-                                        offsetof(CPUMIPSState, active_tc.mxu_gpr[i]),
-                                        mxuregnames[i]);
-    }
-
-    mxu_CR = tcg_global_mem_new(cpu_env,
-                                offsetof(CPUMIPSState, active_tc.mxu_cr),
-                                mxuregnames[NUMBER_OF_MXU_REGISTERS - 1]);
-}
-#else /* !defined(TARGET_MIPS64) */
-void mxu_translate_init(void)
-{
-    g_assert_not_reached();
-}
-#endif /* defined(TARGET_MIPS64) */
-
 /* General purpose registers moves. */
 void gen_load_gpr(TCGv t, int reg)
 {
@@ -2148,38 +1731,6 @@ static inline void gen_store_srsgpr(int from, int to)
     }
 }
 
-#if !defined(TARGET_MIPS64)
-/* MXU General purpose registers moves. */
-static inline void gen_load_mxu_gpr(TCGv t, unsigned int reg)
-{
-    if (reg == 0) {
-        tcg_gen_movi_tl(t, 0);
-    } else if (reg <= 15) {
-        tcg_gen_mov_tl(t, mxu_gpr[reg - 1]);
-    }
-}
-
-static inline void gen_store_mxu_gpr(TCGv t, unsigned int reg)
-{
-    if (reg > 0 && reg <= 15) {
-        tcg_gen_mov_tl(mxu_gpr[reg - 1], t);
-    }
-}
-
-/* MXU control register moves. */
-static inline void gen_load_mxu_cr(TCGv t)
-{
-    tcg_gen_mov_tl(t, mxu_CR);
-}
-
-static inline void gen_store_mxu_cr(TCGv t)
-{
-    /* TODO: Add handling of RW rules for MXU_CR. */
-    tcg_gen_mov_tl(mxu_CR, t);
-}
-#endif
-
-
 /* Tests */
 static inline void gen_save_pc(target_ulong pc)
 {
@@ -24695,1170 +24246,6 @@ static void gen_mmi_pcpyud(DisasContext *ctx)
 
 #endif
 
-
-#if !defined(TARGET_MIPS64)
-
-/* MXU accumulate add/subtract 1-bit pattern 'aptn1' */
-#define MXU_APTN1_A    0
-#define MXU_APTN1_S    1
-
-/* MXU accumulate add/subtract 2-bit pattern 'aptn2' */
-#define MXU_APTN2_AA    0
-#define MXU_APTN2_AS    1
-#define MXU_APTN2_SA    2
-#define MXU_APTN2_SS    3
-
-/* MXU execute add/subtract 2-bit pattern 'eptn2' */
-#define MXU_EPTN2_AA    0
-#define MXU_EPTN2_AS    1
-#define MXU_EPTN2_SA    2
-#define MXU_EPTN2_SS    3
-
-/* MXU operand getting pattern 'optn2' */
-#define MXU_OPTN2_PTN0  0
-#define MXU_OPTN2_PTN1  1
-#define MXU_OPTN2_PTN2  2
-#define MXU_OPTN2_PTN3  3
-/* alternative naming scheme for 'optn2' */
-#define MXU_OPTN2_WW    0
-#define MXU_OPTN2_LW    1
-#define MXU_OPTN2_HW    2
-#define MXU_OPTN2_XW    3
-
-/* MXU operand getting pattern 'optn3' */
-#define MXU_OPTN3_PTN0  0
-#define MXU_OPTN3_PTN1  1
-#define MXU_OPTN3_PTN2  2
-#define MXU_OPTN3_PTN3  3
-#define MXU_OPTN3_PTN4  4
-#define MXU_OPTN3_PTN5  5
-#define MXU_OPTN3_PTN6  6
-#define MXU_OPTN3_PTN7  7
-
-
-/*
- * S32I2M XRa, rb - Register move from GRF to XRF
- */
-static void gen_mxu_s32i2m(DisasContext *ctx)
-{
-    TCGv t0;
-    uint32_t XRa, Rb;
-
-    t0 = tcg_temp_new();
-
-    XRa = extract32(ctx->opcode, 6, 5);
-    Rb = extract32(ctx->opcode, 16, 5);
-
-    gen_load_gpr(t0, Rb);
-    if (XRa <= 15) {
-        gen_store_mxu_gpr(t0, XRa);
-    } else if (XRa == 16) {
-        gen_store_mxu_cr(t0);
-    }
-
-    tcg_temp_free(t0);
-}
-
-/*
- * S32M2I XRa, rb - Register move from XRF to GRF
- */
-static void gen_mxu_s32m2i(DisasContext *ctx)
-{
-    TCGv t0;
-    uint32_t XRa, Rb;
-
-    t0 = tcg_temp_new();
-
-    XRa = extract32(ctx->opcode, 6, 5);
-    Rb = extract32(ctx->opcode, 16, 5);
-
-    if (XRa <= 15) {
-        gen_load_mxu_gpr(t0, XRa);
-    } else if (XRa == 16) {
-        gen_load_mxu_cr(t0);
-    }
-
-    gen_store_gpr(t0, Rb);
-
-    tcg_temp_free(t0);
-}
-
-/*
- * S8LDD XRa, Rb, s8, optn3 - Load a byte from memory to XRF
- */
-static void gen_mxu_s8ldd(DisasContext *ctx)
-{
-    TCGv t0, t1;
-    uint32_t XRa, Rb, s8, optn3;
-
-    t0 = tcg_temp_new();
-    t1 = tcg_temp_new();
-
-    XRa = extract32(ctx->opcode, 6, 4);
-    s8 = extract32(ctx->opcode, 10, 8);
-    optn3 = extract32(ctx->opcode, 18, 3);
-    Rb = extract32(ctx->opcode, 21, 5);
-
-    gen_load_gpr(t0, Rb);
-    tcg_gen_addi_tl(t0, t0, (int8_t)s8);
-
-    switch (optn3) {
-    /* XRa[7:0] = tmp8 */
-    case MXU_OPTN3_PTN0:
-        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
-        gen_load_mxu_gpr(t0, XRa);
-        tcg_gen_deposit_tl(t0, t0, t1, 0, 8);
-        break;
-    /* XRa[15:8] = tmp8 */
-    case MXU_OPTN3_PTN1:
-        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
-        gen_load_mxu_gpr(t0, XRa);
-        tcg_gen_deposit_tl(t0, t0, t1, 8, 8);
-        break;
-    /* XRa[23:16] = tmp8 */
-    case MXU_OPTN3_PTN2:
-        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
-        gen_load_mxu_gpr(t0, XRa);
-        tcg_gen_deposit_tl(t0, t0, t1, 16, 8);
-        break;
-    /* XRa[31:24] = tmp8 */
-    case MXU_OPTN3_PTN3:
-        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
-        gen_load_mxu_gpr(t0, XRa);
-        tcg_gen_deposit_tl(t0, t0, t1, 24, 8);
-        break;
-    /* XRa = {8'b0, tmp8, 8'b0, tmp8} */
-    case MXU_OPTN3_PTN4:
-        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
-        tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
-        break;
-    /* XRa = {tmp8, 8'b0, tmp8, 8'b0} */
-    case MXU_OPTN3_PTN5:
-        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
-        tcg_gen_shli_tl(t1, t1, 8);
-        tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
-        break;
-    /* XRa = {{8{sign of tmp8}}, tmp8, {8{sign of tmp8}}, tmp8} */
-    case MXU_OPTN3_PTN6:
-        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_SB);
-        tcg_gen_mov_tl(t0, t1);
-        tcg_gen_andi_tl(t0, t0, 0xFF00FFFF);
-        tcg_gen_shli_tl(t1, t1, 16);
-        tcg_gen_or_tl(t0, t0, t1);
-        break;
-    /* XRa = {tmp8, tmp8, tmp8, tmp8} */
-    case MXU_OPTN3_PTN7:
-        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
-        tcg_gen_deposit_tl(t1, t1, t1, 8, 8);
-        tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
-        break;
-    }
-
-    gen_store_mxu_gpr(t0, XRa);
-
-    tcg_temp_free(t0);
-    tcg_temp_free(t1);
-}
-
-/*
- * D16MUL XRa, XRb, XRc, XRd, optn2 - Signed 16 bit pattern multiplication
- */
-static void gen_mxu_d16mul(DisasContext *ctx)
-{
-    TCGv t0, t1, t2, t3;
-    uint32_t XRa, XRb, XRc, XRd, optn2;
-
-    t0 = tcg_temp_new();
-    t1 = tcg_temp_new();
-    t2 = tcg_temp_new();
-    t3 = tcg_temp_new();
-
-    XRa = extract32(ctx->opcode, 6, 4);
-    XRb = extract32(ctx->opcode, 10, 4);
-    XRc = extract32(ctx->opcode, 14, 4);
-    XRd = extract32(ctx->opcode, 18, 4);
-    optn2 = extract32(ctx->opcode, 22, 2);
-
-    gen_load_mxu_gpr(t1, XRb);
-    tcg_gen_sextract_tl(t0, t1, 0, 16);
-    tcg_gen_sextract_tl(t1, t1, 16, 16);
-    gen_load_mxu_gpr(t3, XRc);
-    tcg_gen_sextract_tl(t2, t3, 0, 16);
-    tcg_gen_sextract_tl(t3, t3, 16, 16);
-
-    switch (optn2) {
-    case MXU_OPTN2_WW: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
-        tcg_gen_mul_tl(t3, t1, t3);
-        tcg_gen_mul_tl(t2, t0, t2);
-        break;
-    case MXU_OPTN2_LW: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
-        tcg_gen_mul_tl(t3, t0, t3);
-        tcg_gen_mul_tl(t2, t0, t2);
-        break;
-    case MXU_OPTN2_HW: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
-        tcg_gen_mul_tl(t3, t1, t3);
-        tcg_gen_mul_tl(t2, t1, t2);
-        break;
-    case MXU_OPTN2_XW: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
-        tcg_gen_mul_tl(t3, t0, t3);
-        tcg_gen_mul_tl(t2, t1, t2);
-        break;
-    }
-    gen_store_mxu_gpr(t3, XRa);
-    gen_store_mxu_gpr(t2, XRd);
-
-    tcg_temp_free(t0);
-    tcg_temp_free(t1);
-    tcg_temp_free(t2);
-    tcg_temp_free(t3);
-}
-
-/*
- * D16MAC XRa, XRb, XRc, XRd, aptn2, optn2 - Signed 16 bit pattern multiply
- *                                           and accumulate
- */
-static void gen_mxu_d16mac(DisasContext *ctx)
-{
-    TCGv t0, t1, t2, t3;
-    uint32_t XRa, XRb, XRc, XRd, optn2, aptn2;
-
-    t0 = tcg_temp_new();
-    t1 = tcg_temp_new();
-    t2 = tcg_temp_new();
-    t3 = tcg_temp_new();
-
-    XRa = extract32(ctx->opcode, 6, 4);
-    XRb = extract32(ctx->opcode, 10, 4);
-    XRc = extract32(ctx->opcode, 14, 4);
-    XRd = extract32(ctx->opcode, 18, 4);
-    optn2 = extract32(ctx->opcode, 22, 2);
-    aptn2 = extract32(ctx->opcode, 24, 2);
-
-    gen_load_mxu_gpr(t1, XRb);
-    tcg_gen_sextract_tl(t0, t1, 0, 16);
-    tcg_gen_sextract_tl(t1, t1, 16, 16);
-
-    gen_load_mxu_gpr(t3, XRc);
-    tcg_gen_sextract_tl(t2, t3, 0, 16);
-    tcg_gen_sextract_tl(t3, t3, 16, 16);
-
-    switch (optn2) {
-    case MXU_OPTN2_WW: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
-        tcg_gen_mul_tl(t3, t1, t3);
-        tcg_gen_mul_tl(t2, t0, t2);
-        break;
-    case MXU_OPTN2_LW: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
-        tcg_gen_mul_tl(t3, t0, t3);
-        tcg_gen_mul_tl(t2, t0, t2);
-        break;
-    case MXU_OPTN2_HW: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
-        tcg_gen_mul_tl(t3, t1, t3);
-        tcg_gen_mul_tl(t2, t1, t2);
-        break;
-    case MXU_OPTN2_XW: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
-        tcg_gen_mul_tl(t3, t0, t3);
-        tcg_gen_mul_tl(t2, t1, t2);
-        break;
-    }
-    gen_load_mxu_gpr(t0, XRa);
-    gen_load_mxu_gpr(t1, XRd);
-
-    switch (aptn2) {
-    case MXU_APTN2_AA:
-        tcg_gen_add_tl(t3, t0, t3);
-        tcg_gen_add_tl(t2, t1, t2);
-        break;
-    case MXU_APTN2_AS:
-        tcg_gen_add_tl(t3, t0, t3);
-        tcg_gen_sub_tl(t2, t1, t2);
-        break;
-    case MXU_APTN2_SA:
-        tcg_gen_sub_tl(t3, t0, t3);
-        tcg_gen_add_tl(t2, t1, t2);
-        break;
-    case MXU_APTN2_SS:
-        tcg_gen_sub_tl(t3, t0, t3);
-        tcg_gen_sub_tl(t2, t1, t2);
-        break;
-    }
-    gen_store_mxu_gpr(t3, XRa);
-    gen_store_mxu_gpr(t2, XRd);
-
-    tcg_temp_free(t0);
-    tcg_temp_free(t1);
-    tcg_temp_free(t2);
-    tcg_temp_free(t3);
-}
-
-/*
- * Q8MUL   XRa, XRb, XRc, XRd - Parallel unsigned 8 bit pattern multiply
- * Q8MULSU XRa, XRb, XRc, XRd - Parallel signed 8 bit pattern multiply
- */
-static void gen_mxu_q8mul_q8mulsu(DisasContext *ctx)
-{
-    TCGv t0, t1, t2, t3, t4, t5, t6, t7;
-    uint32_t XRa, XRb, XRc, XRd, sel;
-
-    t0 = tcg_temp_new();
-    t1 = tcg_temp_new();
-    t2 = tcg_temp_new();
-    t3 = tcg_temp_new();
-    t4 = tcg_temp_new();
-    t5 = tcg_temp_new();
-    t6 = tcg_temp_new();
-    t7 = tcg_temp_new();
-
-    XRa = extract32(ctx->opcode, 6, 4);
-    XRb = extract32(ctx->opcode, 10, 4);
-    XRc = extract32(ctx->opcode, 14, 4);
-    XRd = extract32(ctx->opcode, 18, 4);
-    sel = extract32(ctx->opcode, 22, 2);
-
-    gen_load_mxu_gpr(t3, XRb);
-    gen_load_mxu_gpr(t7, XRc);
-
-    if (sel == 0x2) {
-        /* Q8MULSU */
-        tcg_gen_ext8s_tl(t0, t3);
-        tcg_gen_shri_tl(t3, t3, 8);
-        tcg_gen_ext8s_tl(t1, t3);
-        tcg_gen_shri_tl(t3, t3, 8);
-        tcg_gen_ext8s_tl(t2, t3);
-        tcg_gen_shri_tl(t3, t3, 8);
-        tcg_gen_ext8s_tl(t3, t3);
-    } else {
-        /* Q8MUL */
-        tcg_gen_ext8u_tl(t0, t3);
-        tcg_gen_shri_tl(t3, t3, 8);
-        tcg_gen_ext8u_tl(t1, t3);
-        tcg_gen_shri_tl(t3, t3, 8);
-        tcg_gen_ext8u_tl(t2, t3);
-        tcg_gen_shri_tl(t3, t3, 8);
-        tcg_gen_ext8u_tl(t3, t3);
-    }
-
-    tcg_gen_ext8u_tl(t4, t7);
-    tcg_gen_shri_tl(t7, t7, 8);
-    tcg_gen_ext8u_tl(t5, t7);
-    tcg_gen_shri_tl(t7, t7, 8);
-    tcg_gen_ext8u_tl(t6, t7);
-    tcg_gen_shri_tl(t7, t7, 8);
-    tcg_gen_ext8u_tl(t7, t7);
-
-    tcg_gen_mul_tl(t0, t0, t4);
-    tcg_gen_mul_tl(t1, t1, t5);
-    tcg_gen_mul_tl(t2, t2, t6);
-    tcg_gen_mul_tl(t3, t3, t7);
-
-    tcg_gen_andi_tl(t0, t0, 0xFFFF);
-    tcg_gen_andi_tl(t1, t1, 0xFFFF);
-    tcg_gen_andi_tl(t2, t2, 0xFFFF);
-    tcg_gen_andi_tl(t3, t3, 0xFFFF);
-
-    tcg_gen_shli_tl(t1, t1, 16);
-    tcg_gen_shli_tl(t3, t3, 16);
-
-    tcg_gen_or_tl(t0, t0, t1);
-    tcg_gen_or_tl(t1, t2, t3);
-
-    gen_store_mxu_gpr(t0, XRd);
-    gen_store_mxu_gpr(t1, XRa);
-
-    tcg_temp_free(t0);
-    tcg_temp_free(t1);
-    tcg_temp_free(t2);
-    tcg_temp_free(t3);
-    tcg_temp_free(t4);
-    tcg_temp_free(t5);
-    tcg_temp_free(t6);
-    tcg_temp_free(t7);
-}
-
-/*
- * S32LDD  XRa, Rb, S12 - Load a word from memory to XRF
- * S32LDDR XRa, Rb, S12 - Load a word from memory to XRF, reversed byte seq.
- */
-static void gen_mxu_s32ldd_s32lddr(DisasContext *ctx)
-{
-    TCGv t0, t1;
-    uint32_t XRa, Rb, s12, sel;
-
-    t0 = tcg_temp_new();
-    t1 = tcg_temp_new();
-
-    XRa = extract32(ctx->opcode, 6, 4);
-    s12 = extract32(ctx->opcode, 10, 10);
-    sel = extract32(ctx->opcode, 20, 1);
-    Rb = extract32(ctx->opcode, 21, 5);
-
-    gen_load_gpr(t0, Rb);
-
-    tcg_gen_movi_tl(t1, s12);
-    tcg_gen_shli_tl(t1, t1, 2);
-    if (s12 & 0x200) {
-        tcg_gen_ori_tl(t1, t1, 0xFFFFF000);
-    }
-    tcg_gen_add_tl(t1, t0, t1);
-    tcg_gen_qemu_ld_tl(t1, t1, ctx->mem_idx, MO_SL);
-
-    if (sel == 1) {
-        /* S32LDDR */
-        tcg_gen_bswap32_tl(t1, t1);
-    }
-    gen_store_mxu_gpr(t1, XRa);
-
-    tcg_temp_free(t0);
-    tcg_temp_free(t1);
-}
-
-
-/*
- *                 MXU instruction category: logic
- *                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- *               S32NOR    S32AND    S32OR    S32XOR
- */
-
-/*
- *  S32NOR XRa, XRb, XRc
- *    Update XRa with the result of logical bitwise 'nor' operation
- *    applied to the content of XRb and XRc.
- */
-static void gen_mxu_S32NOR(DisasContext *ctx)
-{
-    uint32_t pad, XRc, XRb, XRa;
-
-    pad = extract32(ctx->opcode, 21, 5);
-    XRc = extract32(ctx->opcode, 14, 4);
-    XRb = extract32(ctx->opcode, 10, 4);
-    XRa = extract32(ctx->opcode,  6, 4);
-
-    if (unlikely(pad != 0)) {
-        /* opcode padding incorrect -> do nothing */
-    } else if (unlikely(XRa == 0)) {
-        /* destination is zero register -> do nothing */
-    } else if (unlikely((XRb == 0) && (XRc == 0))) {
-        /* both operands zero registers -> just set destination to all 1s */
-        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0xFFFFFFFF);
-    } else if (unlikely(XRb == 0)) {
-        /* XRb zero register -> just set destination to the negation of XRc */
-        tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
-    } else if (unlikely(XRc == 0)) {
-        /* XRa zero register -> just set destination to the negation of XRb */
-        tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
-    } else if (unlikely(XRb == XRc)) {
-        /* both operands same -> just set destination to the negation of XRb */
-        tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
-    } else {
-        /* the most general case */
-        tcg_gen_nor_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
-    }
-}
-
-/*
- *  S32AND XRa, XRb, XRc
- *    Update XRa with the result of logical bitwise 'and' operation
- *    applied to the content of XRb and XRc.
- */
-static void gen_mxu_S32AND(DisasContext *ctx)
-{
-    uint32_t pad, XRc, XRb, XRa;
-
-    pad = extract32(ctx->opcode, 21, 5);
-    XRc = extract32(ctx->opcode, 14, 4);
-    XRb = extract32(ctx->opcode, 10, 4);
-    XRa = extract32(ctx->opcode,  6, 4);
-
-    if (unlikely(pad != 0)) {
-        /* opcode padding incorrect -> do nothing */
-    } else if (unlikely(XRa == 0)) {
-        /* destination is zero register -> do nothing */
-    } else if (unlikely((XRb == 0) || (XRc == 0))) {
-        /* one of operands zero register -> just set destination to all 0s */
-        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
-    } else if (unlikely(XRb == XRc)) {
-        /* both operands same -> just set destination to one of them */
-        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
-    } else {
-        /* the most general case */
-        tcg_gen_and_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
-    }
-}
-
-/*
- *  S32OR XRa, XRb, XRc
- *    Update XRa with the result of logical bitwise 'or' operation
- *    applied to the content of XRb and XRc.
- */
-static void gen_mxu_S32OR(DisasContext *ctx)
-{
-    uint32_t pad, XRc, XRb, XRa;
-
-    pad = extract32(ctx->opcode, 21, 5);
-    XRc = extract32(ctx->opcode, 14, 4);
-    XRb = extract32(ctx->opcode, 10, 4);
-    XRa = extract32(ctx->opcode,  6, 4);
-
-    if (unlikely(pad != 0)) {
-        /* opcode padding incorrect -> do nothing */
-    } else if (unlikely(XRa == 0)) {
-        /* destination is zero register -> do nothing */
-    } else if (unlikely((XRb == 0) && (XRc == 0))) {
-        /* both operands zero registers -> just set destination to all 0s */
-        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
-    } else if (unlikely(XRb == 0)) {
-        /* XRb zero register -> just set destination to the content of XRc */
-        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
-    } else if (unlikely(XRc == 0)) {
-        /* XRc zero register -> just set destination to the content of XRb */
-        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
-    } else if (unlikely(XRb == XRc)) {
-        /* both operands same -> just set destination to one of them */
-        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
-    } else {
-        /* the most general case */
-        tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
-    }
-}
-
-/*
- *  S32XOR XRa, XRb, XRc
- *    Update XRa with the result of logical bitwise 'xor' operation
- *    applied to the content of XRb and XRc.
- */
-static void gen_mxu_S32XOR(DisasContext *ctx)
-{
-    uint32_t pad, XRc, XRb, XRa;
-
-    pad = extract32(ctx->opcode, 21, 5);
-    XRc = extract32(ctx->opcode, 14, 4);
-    XRb = extract32(ctx->opcode, 10, 4);
-    XRa = extract32(ctx->opcode,  6, 4);
-
-    if (unlikely(pad != 0)) {
-        /* opcode padding incorrect -> do nothing */
-    } else if (unlikely(XRa == 0)) {
-        /* destination is zero register -> do nothing */
-    } else if (unlikely((XRb == 0) && (XRc == 0))) {
-        /* both operands zero registers -> just set destination to all 0s */
-        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
-    } else if (unlikely(XRb == 0)) {
-        /* XRb zero register -> just set destination to the content of XRc */
-        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
-    } else if (unlikely(XRc == 0)) {
-        /* XRc zero register -> just set destination to the content of XRb */
-        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
-    } else if (unlikely(XRb == XRc)) {
-        /* both operands same -> just set destination to all 0s */
-        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
-    } else {
-        /* the most general case */
-        tcg_gen_xor_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
-    }
-}
-
-
-/*
- *                   MXU instruction category max/min
- *                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- *                     S32MAX     D16MAX     Q8MAX
- *                     S32MIN     D16MIN     Q8MIN
- */
-
-/*
- *  S32MAX XRa, XRb, XRc
- *    Update XRa with the maximum of signed 32-bit integers contained
- *    in XRb and XRc.
- *
- *  S32MIN XRa, XRb, XRc
- *    Update XRa with the minimum of signed 32-bit integers contained
- *    in XRb and XRc.
- */
-static void gen_mxu_S32MAX_S32MIN(DisasContext *ctx)
-{
-    uint32_t pad, opc, XRc, XRb, XRa;
-
-    pad = extract32(ctx->opcode, 21, 5);
-    opc = extract32(ctx->opcode, 18, 3);
-    XRc = extract32(ctx->opcode, 14, 4);
-    XRb = extract32(ctx->opcode, 10, 4);
-    XRa = extract32(ctx->opcode,  6, 4);
-
-    if (unlikely(pad != 0)) {
-        /* opcode padding incorrect -> do nothing */
-    } else if (unlikely(XRa == 0)) {
-        /* destination is zero register -> do nothing */
-    } else if (unlikely((XRb == 0) && (XRc == 0))) {
-        /* both operands zero registers -> just set destination to zero */
-        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
-    } else if (unlikely((XRb == 0) || (XRc == 0))) {
-        /* exactly one operand is zero register - find which one is not...*/
-        uint32_t XRx = XRb ? XRb : XRc;
-        /* ...and do max/min operation with one operand 0 */
-        if (opc == OPC_MXU_S32MAX) {
-            tcg_gen_smax_i32(mxu_gpr[XRa - 1], mxu_gpr[XRx - 1], 0);
-        } else {
-            tcg_gen_smin_i32(mxu_gpr[XRa - 1], mxu_gpr[XRx - 1], 0);
-        }
-    } else if (unlikely(XRb == XRc)) {
-        /* both operands same -> just set destination to one of them */
-        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
-    } else {
-        /* the most general case */
-        if (opc == OPC_MXU_S32MAX) {
-            tcg_gen_smax_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1],
-                                               mxu_gpr[XRc - 1]);
-        } else {
-            tcg_gen_smin_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1],
-                                               mxu_gpr[XRc - 1]);
-        }
-    }
-}
-
-/*
- *  D16MAX
- *    Update XRa with the 16-bit-wise maximums of signed integers
- *    contained in XRb and XRc.
- *
- *  D16MIN
- *    Update XRa with the 16-bit-wise minimums of signed integers
- *    contained in XRb and XRc.
- */
-static void gen_mxu_D16MAX_D16MIN(DisasContext *ctx)
-{
-    uint32_t pad, opc, XRc, XRb, XRa;
-
-    pad = extract32(ctx->opcode, 21, 5);
-    opc = extract32(ctx->opcode, 18, 3);
-    XRc = extract32(ctx->opcode, 14, 4);
-    XRb = extract32(ctx->opcode, 10, 4);
-    XRa = extract32(ctx->opcode,  6, 4);
-
-    if (unlikely(pad != 0)) {
-        /* opcode padding incorrect -> do nothing */
-    } else if (unlikely(XRc == 0)) {
-        /* destination is zero register -> do nothing */
-    } else if (unlikely((XRb == 0) && (XRa == 0))) {
-        /* both operands zero registers -> just set destination to zero */
-        tcg_gen_movi_i32(mxu_gpr[XRc - 1], 0);
-    } else if (unlikely((XRb == 0) || (XRa == 0))) {
-        /* exactly one operand is zero register - find which one is not...*/
-        uint32_t XRx = XRb ? XRb : XRc;
-        /* ...and do half-word-wise max/min with one operand 0 */
-        TCGv_i32 t0 = tcg_temp_new();
-        TCGv_i32 t1 = tcg_const_i32(0);
-
-        /* the left half-word first */
-        tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFFFF0000);
-        if (opc == OPC_MXU_D16MAX) {
-            tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
-        } else {
-            tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
-        }
-
-        /* the right half-word */
-        tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0x0000FFFF);
-        /* move half-words to the leftmost position */
-        tcg_gen_shli_i32(t0, t0, 16);
-        /* t0 will be max/min of t0 and t1 */
-        if (opc == OPC_MXU_D16MAX) {
-            tcg_gen_smax_i32(t0, t0, t1);
-        } else {
-            tcg_gen_smin_i32(t0, t0, t1);
-        }
-        /* return resulting half-words to its original position */
-        tcg_gen_shri_i32(t0, t0, 16);
-        /* finally update the destination */
-        tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
-
-        tcg_temp_free(t1);
-        tcg_temp_free(t0);
-    } else if (unlikely(XRb == XRc)) {
-        /* both operands same -> just set destination to one of them */
-        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
-    } else {
-        /* the most general case */
-        TCGv_i32 t0 = tcg_temp_new();
-        TCGv_i32 t1 = tcg_temp_new();
-
-        /* the left half-word first */
-        tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFFFF0000);
-        tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFF0000);
-        if (opc == OPC_MXU_D16MAX) {
-            tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
-        } else {
-            tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
-        }
-
-        /* the right half-word */
-        tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x0000FFFF);
-        tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0x0000FFFF);
-        /* move half-words to the leftmost position */
-        tcg_gen_shli_i32(t0, t0, 16);
-        tcg_gen_shli_i32(t1, t1, 16);
-        /* t0 will be max/min of t0 and t1 */
-        if (opc == OPC_MXU_D16MAX) {
-            tcg_gen_smax_i32(t0, t0, t1);
-        } else {
-            tcg_gen_smin_i32(t0, t0, t1);
-        }
-        /* return resulting half-words to its original position */
-        tcg_gen_shri_i32(t0, t0, 16);
-        /* finally update the destination */
-        tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
-
-        tcg_temp_free(t1);
-        tcg_temp_free(t0);
-    }
-}
-
-/*
- *  Q8MAX
- *    Update XRa with the 8-bit-wise maximums of signed integers
- *    contained in XRb and XRc.
- *
- *  Q8MIN
- *    Update XRa with the 8-bit-wise minimums of signed integers
- *    contained in XRb and XRc.
- */
-static void gen_mxu_Q8MAX_Q8MIN(DisasContext *ctx)
-{
-    uint32_t pad, opc, XRc, XRb, XRa;
-
-    pad = extract32(ctx->opcode, 21, 5);
-    opc = extract32(ctx->opcode, 18, 3);
-    XRc = extract32(ctx->opcode, 14, 4);
-    XRb = extract32(ctx->opcode, 10, 4);
-    XRa = extract32(ctx->opcode,  6, 4);
-
-    if (unlikely(pad != 0)) {
-        /* opcode padding incorrect -> do nothing */
-    } else if (unlikely(XRa == 0)) {
-        /* destination is zero register -> do nothing */
-    } else if (unlikely((XRb == 0) && (XRc == 0))) {
-        /* both operands zero registers -> just set destination to zero */
-        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
-    } else if (unlikely((XRb == 0) || (XRc == 0))) {
-        /* exactly one operand is zero register - make it be the first...*/
-        uint32_t XRx = XRb ? XRb : XRc;
-        /* ...and do byte-wise max/min with one operand 0 */
-        TCGv_i32 t0 = tcg_temp_new();
-        TCGv_i32 t1 = tcg_const_i32(0);
-        int32_t i;
-
-        /* the leftmost byte (byte 3) first */
-        tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFF000000);
-        if (opc == OPC_MXU_Q8MAX) {
-            tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
-        } else {
-            tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
-        }
-
-        /* bytes 2, 1, 0 */
-        for (i = 2; i >= 0; i--) {
-            /* extract the byte */
-            tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFF << (8 * i));
-            /* move the byte to the leftmost position */
-            tcg_gen_shli_i32(t0, t0, 8 * (3 - i));
-            /* t0 will be max/min of t0 and t1 */
-            if (opc == OPC_MXU_Q8MAX) {
-                tcg_gen_smax_i32(t0, t0, t1);
-            } else {
-                tcg_gen_smin_i32(t0, t0, t1);
-            }
-            /* return resulting byte to its original position */
-            tcg_gen_shri_i32(t0, t0, 8 * (3 - i));
-            /* finally update the destination */
-            tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
-        }
-
-        tcg_temp_free(t1);
-        tcg_temp_free(t0);
-    } else if (unlikely(XRb == XRc)) {
-        /* both operands same -> just set destination to one of them */
-        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
-    } else {
-        /* the most general case */
-        TCGv_i32 t0 = tcg_temp_new();
-        TCGv_i32 t1 = tcg_temp_new();
-        int32_t i;
-
-        /* the leftmost bytes (bytes 3) first */
-        tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFF000000);
-        tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF000000);
-        if (opc == OPC_MXU_Q8MAX) {
-            tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
-        } else {
-            tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
-        }
-
-        /* bytes 2, 1, 0 */
-        for (i = 2; i >= 0; i--) {
-            /* extract corresponding bytes */
-            tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFF << (8 * i));
-            tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF << (8 * i));
-            /* move the bytes to the leftmost position */
-            tcg_gen_shli_i32(t0, t0, 8 * (3 - i));
-            tcg_gen_shli_i32(t1, t1, 8 * (3 - i));
-            /* t0 will be max/min of t0 and t1 */
-            if (opc == OPC_MXU_Q8MAX) {
-                tcg_gen_smax_i32(t0, t0, t1);
-            } else {
-                tcg_gen_smin_i32(t0, t0, t1);
-            }
-            /* return resulting byte to its original position */
-            tcg_gen_shri_i32(t0, t0, 8 * (3 - i));
-            /* finally update the destination */
-            tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
-        }
-
-        tcg_temp_free(t1);
-        tcg_temp_free(t0);
-    }
-}
-
-
-/*
- *                 MXU instruction category: align
- *                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- *                       S32ALN     S32ALNI
- */
-
-/*
- *  S32ALNI XRc, XRb, XRa, optn3
- *    Arrange bytes from XRb and XRc according to one of five sets of
- *    rules determined by optn3, and place the result in XRa.
- */
-static void gen_mxu_S32ALNI(DisasContext *ctx)
-{
-    uint32_t optn3, pad, XRc, XRb, XRa;
-
-    optn3 = extract32(ctx->opcode,  23, 3);
-    pad   = extract32(ctx->opcode,  21, 2);
-    XRc   = extract32(ctx->opcode, 14, 4);
-    XRb   = extract32(ctx->opcode, 10, 4);
-    XRa   = extract32(ctx->opcode,  6, 4);
-
-    if (unlikely(pad != 0)) {
-        /* opcode padding incorrect -> do nothing */
-    } else if (unlikely(XRa == 0)) {
-        /* destination is zero register -> do nothing */
-    } else if (unlikely((XRb == 0) && (XRc == 0))) {
-        /* both operands zero registers -> just set destination to all 0s */
-        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
-    } else if (unlikely(XRb == 0)) {
-        /* XRb zero register -> just appropriatelly shift XRc into XRa */
-        switch (optn3) {
-        case MXU_OPTN3_PTN0:
-            tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
-            break;
-        case MXU_OPTN3_PTN1:
-        case MXU_OPTN3_PTN2:
-        case MXU_OPTN3_PTN3:
-            tcg_gen_shri_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1],
-                             8 * (4 - optn3));
-            break;
-        case MXU_OPTN3_PTN4:
-            tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
-            break;
-        }
-    } else if (unlikely(XRc == 0)) {
-        /* XRc zero register -> just appropriatelly shift XRb into XRa */
-        switch (optn3) {
-        case MXU_OPTN3_PTN0:
-            tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
-            break;
-        case MXU_OPTN3_PTN1:
-        case MXU_OPTN3_PTN2:
-        case MXU_OPTN3_PTN3:
-            tcg_gen_shri_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], 8 * optn3);
-            break;
-        case MXU_OPTN3_PTN4:
-            tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
-            break;
-        }
-    } else if (unlikely(XRb == XRc)) {
-        /* both operands same -> just rotation or moving from any of them */
-        switch (optn3) {
-        case MXU_OPTN3_PTN0:
-        case MXU_OPTN3_PTN4:
-            tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
-            break;
-        case MXU_OPTN3_PTN1:
-        case MXU_OPTN3_PTN2:
-        case MXU_OPTN3_PTN3:
-            tcg_gen_rotli_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], 8 * optn3);
-            break;
-        }
-    } else {
-        /* the most general case */
-        switch (optn3) {
-        case MXU_OPTN3_PTN0:
-            {
-                /*                                         */
-                /*         XRb                XRc          */
-                /*  +---------------+                      */
-                /*  | A   B   C   D |    E   F   G   H     */
-                /*  +-------+-------+                      */
-                /*          |                              */
-                /*         XRa                             */
-                /*                                         */
-
-                tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
-            }
-            break;
-        case MXU_OPTN3_PTN1:
-            {
-                /*                                         */
-                /*         XRb                 XRc         */
-                /*      +-------------------+              */
-                /*    A | B   C   D       E | F   G   H    */
-                /*      +---------+---------+              */
-                /*                |                        */
-                /*               XRa                       */
-                /*                                         */
-
-                TCGv_i32 t0 = tcg_temp_new();
-                TCGv_i32 t1 = tcg_temp_new();
-
-                tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x00FFFFFF);
-                tcg_gen_shli_i32(t0, t0, 8);
-
-                tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF000000);
-                tcg_gen_shri_i32(t1, t1, 24);
-
-                tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
-
-                tcg_temp_free(t1);
-                tcg_temp_free(t0);
-            }
-            break;
-        case MXU_OPTN3_PTN2:
-            {
-                /*                                         */
-                /*         XRb                 XRc         */
-                /*          +-------------------+          */
-                /*    A   B | C   D       E   F | G   H    */
-                /*          +---------+---------+          */
-                /*                    |                    */
-                /*                   XRa                   */
-                /*                                         */
-
-                TCGv_i32 t0 = tcg_temp_new();
-                TCGv_i32 t1 = tcg_temp_new();
-
-                tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x0000FFFF);
-                tcg_gen_shli_i32(t0, t0, 16);
-
-                tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFF0000);
-                tcg_gen_shri_i32(t1, t1, 16);
-
-                tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
-
-                tcg_temp_free(t1);
-                tcg_temp_free(t0);
-            }
-            break;
-        case MXU_OPTN3_PTN3:
-            {
-                /*                                         */
-                /*         XRb                 XRc         */
-                /*              +-------------------+      */
-                /*    A   B   C | D       E   F   G | H    */
-                /*              +---------+---------+      */
-                /*                        |                */
-                /*                       XRa               */
-                /*                                         */
-
-                TCGv_i32 t0 = tcg_temp_new();
-                TCGv_i32 t1 = tcg_temp_new();
-
-                tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x000000FF);
-                tcg_gen_shli_i32(t0, t0, 24);
-
-                tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFFFF00);
-                tcg_gen_shri_i32(t1, t1, 8);
-
-                tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
-
-                tcg_temp_free(t1);
-                tcg_temp_free(t0);
-            }
-            break;
-        case MXU_OPTN3_PTN4:
-            {
-                /*                                         */
-                /*         XRb                 XRc         */
-                /*                     +---------------+   */
-                /*    A   B   C   D    | E   F   G   H |   */
-                /*                     +-------+-------+   */
-                /*                             |           */
-                /*                            XRa          */
-                /*                                         */
-
-                tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
-            }
-            break;
-        }
-    }
-}
-
-
-/*
- * Decoding engine for MXU
- * =======================
- */
-
-static void decode_opc_mxu__pool00(DisasContext *ctx)
-{
-    uint32_t opcode = extract32(ctx->opcode, 18, 3);
-
-    switch (opcode) {
-    case OPC_MXU_S32MAX:
-    case OPC_MXU_S32MIN:
-        gen_mxu_S32MAX_S32MIN(ctx);
-        break;
-    case OPC_MXU_D16MAX:
-    case OPC_MXU_D16MIN:
-        gen_mxu_D16MAX_D16MIN(ctx);
-        break;
-    case OPC_MXU_Q8MAX:
-    case OPC_MXU_Q8MIN:
-        gen_mxu_Q8MAX_Q8MIN(ctx);
-        break;
-    default:
-        MIPS_INVAL("decode_opc_mxu");
-        gen_reserved_instruction(ctx);
-        break;
-    }
-}
-
-static void decode_opc_mxu__pool04(DisasContext *ctx)
-{
-    uint32_t opcode = extract32(ctx->opcode, 20, 1);
-
-    switch (opcode) {
-    case OPC_MXU_S32LDD:
-    case OPC_MXU_S32LDDR:
-        gen_mxu_s32ldd_s32lddr(ctx);
-        break;
-    default:
-        MIPS_INVAL("decode_opc_mxu");
-        gen_reserved_instruction(ctx);
-        break;
-    }
-}
-
-static void decode_opc_mxu__pool16(DisasContext *ctx)
-{
-    uint32_t opcode = extract32(ctx->opcode, 18, 3);
-
-    switch (opcode) {
-    case OPC_MXU_S32ALNI:
-        gen_mxu_S32ALNI(ctx);
-        break;
-    case OPC_MXU_S32NOR:
-        gen_mxu_S32NOR(ctx);
-        break;
-    case OPC_MXU_S32AND:
-        gen_mxu_S32AND(ctx);
-        break;
-    case OPC_MXU_S32OR:
-        gen_mxu_S32OR(ctx);
-        break;
-    case OPC_MXU_S32XOR:
-        gen_mxu_S32XOR(ctx);
-        break;
-    default:
-        MIPS_INVAL("decode_opc_mxu");
-        gen_reserved_instruction(ctx);
-        break;
-    }
-}
-
-static void decode_opc_mxu__pool19(DisasContext *ctx)
-{
-    uint32_t opcode = extract32(ctx->opcode, 22, 2);
-
-    switch (opcode) {
-    case OPC_MXU_Q8MUL:
-    case OPC_MXU_Q8MULSU:
-        gen_mxu_q8mul_q8mulsu(ctx);
-        break;
-    default:
-        MIPS_INVAL("decode_opc_mxu");
-        gen_reserved_instruction(ctx);
-        break;
-    }
-}
-
-bool decode_ase_mxu(DisasContext *ctx, uint32_t insn)
-{
-    uint32_t opcode = extract32(insn, 0, 6);
-
-    if (opcode == OPC_MXU_S32M2I) {
-        gen_mxu_s32m2i(ctx);
-        return true;
-    }
-
-    if (opcode == OPC_MXU_S32I2M) {
-        gen_mxu_s32i2m(ctx);
-        return true;
-    }
-
-    {
-        TCGv t_mxu_cr = tcg_temp_new();
-        TCGLabel *l_exit = gen_new_label();
-
-        gen_load_mxu_cr(t_mxu_cr);
-        tcg_gen_andi_tl(t_mxu_cr, t_mxu_cr, MXU_CR_MXU_EN);
-        tcg_gen_brcondi_tl(TCG_COND_NE, t_mxu_cr, MXU_CR_MXU_EN, l_exit);
-
-        switch (opcode) {
-        case OPC_MXU__POOL00:
-            decode_opc_mxu__pool00(ctx);
-            break;
-        case OPC_MXU_D16MUL:
-            gen_mxu_d16mul(ctx);
-            break;
-        case OPC_MXU_D16MAC:
-            gen_mxu_d16mac(ctx);
-            break;
-        case OPC_MXU__POOL04:
-            decode_opc_mxu__pool04(ctx);
-            break;
-        case OPC_MXU_S8LDD:
-            gen_mxu_s8ldd(ctx);
-            break;
-        case OPC_MXU__POOL16:
-            decode_opc_mxu__pool16(ctx);
-            break;
-        case OPC_MXU__POOL19:
-            decode_opc_mxu__pool19(ctx);
-            break;
-        default:
-            MIPS_INVAL("decode_opc_mxu");
-            gen_reserved_instruction(ctx);
-        }
-
-        gen_set_label(l_exit);
-        tcg_temp_free(t_mxu_cr);
-    }
-
-    return true;
-}
-
-#else /* !defined(TARGET_MIPS64) */
-
-bool decode_ase_mxu(DisasContext *ctx, uint32_t insn)
-{
-    return false;
-}
-
-#endif /* defined(TARGET_MIPS64) */
-
 /*
  * Main MXU decoding function
  */
diff --git a/target/mips/meson.build b/target/mips/meson.build
index 9741545440c..a909da46063 100644
--- a/target/mips/meson.build
+++ b/target/mips/meson.build
@@ -17,6 +17,7 @@
   'lmmi_helper.c',
   'msa_helper.c',
   'msa_translate.c',
+  'mxu_translate.c',
   'op_helper.c',
   'rel6_translate.c',
   'tlb_helper.c',
-- 
2.26.2



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

* Re: [PATCH v3 01/10] target/mips: Rewrite complex ifdef'ry
  2021-02-22 22:38 ` [PATCH v3 01/10] target/mips: Rewrite complex ifdef'ry Philippe Mathieu-Daudé
@ 2021-02-24  1:21   ` Richard Henderson
  0 siblings, 0 replies; 21+ messages in thread
From: Richard Henderson @ 2021-02-24  1:21 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé, qemu-devel; +Cc: Aleksandar Rikalo, Aurelien Jarno

On 2/22/21 2:38 PM, Philippe Mathieu-Daudé wrote:
> No need for this obfuscated ifdef'ry, KISS.
> 
> Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> ---
>  target/mips/translate.c | 11 +++++++----
>  1 file changed, 7 insertions(+), 4 deletions(-)

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

r~


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

* Re: [PATCH v3 03/10] target/mips: Remove unused CPUMIPSState* from MXU functions
  2021-02-22 22:38 ` [PATCH v3 03/10] target/mips: Remove unused CPUMIPSState* from MXU functions Philippe Mathieu-Daudé
@ 2021-02-24  1:22   ` Richard Henderson
  0 siblings, 0 replies; 21+ messages in thread
From: Richard Henderson @ 2021-02-24  1:22 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé, qemu-devel; +Cc: Aleksandar Rikalo, Aurelien Jarno

On 2/22/21 2:38 PM, Philippe Mathieu-Daudé wrote:
> None of these MXU functions use their CPUMIPSState* env argument,
> remove it.
> 
> Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> ---
>  target/mips/translate.c | 20 ++++++++++----------
>  1 file changed, 10 insertions(+), 10 deletions(-)

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

r~


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

* Re: [PATCH v3 04/10] target/mips: Pass instruction opcode to decode_opc_mxu()
  2021-02-22 22:38 ` [PATCH v3 04/10] target/mips: Pass instruction opcode to decode_opc_mxu() Philippe Mathieu-Daudé
@ 2021-02-24  1:22   ` Richard Henderson
  0 siblings, 0 replies; 21+ messages in thread
From: Richard Henderson @ 2021-02-24  1:22 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé, qemu-devel; +Cc: Aleksandar Rikalo, Aurelien Jarno

On 2/22/21 2:38 PM, Philippe Mathieu-Daudé wrote:
> In the next commit we'll make decode_opc_mxu() match decodetree
> prototype by returning a boolean. First pass ctx->opcode as an
> argument.
> 
> Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> ---
>  target/mips/translate.c | 14 +++++++-------
>  1 file changed, 7 insertions(+), 7 deletions(-)

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

r~


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

* Re: [PATCH v3 05/10] target/mips: Extract decode_ase_mxu() from decode_opc_mxu()
  2021-02-22 22:38 ` [PATCH v3 05/10] target/mips: Extract decode_ase_mxu() from decode_opc_mxu() Philippe Mathieu-Daudé
@ 2021-02-24  1:25   ` Richard Henderson
  2021-02-26  9:09     ` Philippe Mathieu-Daudé
  0 siblings, 1 reply; 21+ messages in thread
From: Richard Henderson @ 2021-02-24  1:25 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé, qemu-devel; +Cc: Aleksandar Rikalo, Aurelien Jarno

On 2/22/21 2:38 PM, Philippe Mathieu-Daudé wrote:
> To easily convert MXU code to decodetree, extract decode_ase_mxu()
> from decode_opc_mxu(), making it return a boolean.
> We will keep decode_opc_mxu() in the translate.c unit because it
> calls gen_arith().
> 
> Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> ---
>  target/mips/translate.c | 45 ++++++++++++++++++++++++-----------------
>  1 file changed, 26 insertions(+), 19 deletions(-)

I guess the split is fine until you can just call gen_mul() from a trans() from
the mxu decodetree.

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

r~


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

* Re: [PATCH v3 06/10] target/mips: Use OPC_MUL instead of OPC__MXU_MUL
  2021-02-22 22:38 ` [PATCH v3 06/10] target/mips: Use OPC_MUL instead of OPC__MXU_MUL Philippe Mathieu-Daudé
@ 2021-02-24  1:34   ` Richard Henderson
  0 siblings, 0 replies; 21+ messages in thread
From: Richard Henderson @ 2021-02-24  1:34 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé, qemu-devel; +Cc: Aleksandar Rikalo, Aurelien Jarno

On 2/22/21 2:38 PM, Philippe Mathieu-Daudé wrote:
> We already have a macro and definition to extract / check
> the Special2 MUL opcode. Use it instead of the unnecessary
> OPC__MXU_MUL macro.
> 
> Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> ---
>  target/mips/translate.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)

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

r~



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

* Re: [PATCH v3 07/10] target/mips: Introduce mxu_translate_init() helper
  2021-02-22 22:38 ` [PATCH v3 07/10] target/mips: Introduce mxu_translate_init() helper Philippe Mathieu-Daudé
@ 2021-02-24  1:36   ` Richard Henderson
  0 siblings, 0 replies; 21+ messages in thread
From: Richard Henderson @ 2021-02-24  1:36 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé, qemu-devel; +Cc: Aleksandar Rikalo, Aurelien Jarno

On 2/22/21 2:38 PM, Philippe Mathieu-Daudé wrote:
> Extract the MXU register initialization code from mips_tcg_init()
> as a new mxu_translate_init() helper
> 
> Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> ---
>  target/mips/translate.c | 26 +++++++++++++++-----------
>  1 file changed, 15 insertions(+), 11 deletions(-)

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

r~



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

* Re: [PATCH v3 08/10] target/mips: Make mxu_translate_init() / decode_ase_mxu() proto public
  2021-02-22 22:38 ` [PATCH v3 08/10] target/mips: Make mxu_translate_init() / decode_ase_mxu() proto public Philippe Mathieu-Daudé
@ 2021-02-24  1:38   ` Richard Henderson
  0 siblings, 0 replies; 21+ messages in thread
From: Richard Henderson @ 2021-02-24  1:38 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé, qemu-devel; +Cc: Aleksandar Rikalo, Aurelien Jarno

On 2/22/21 2:38 PM, Philippe Mathieu-Daudé wrote:
> +#else /* !defined(TARGET_MIPS64) */
> +void mxu_translate_init(void)
> +{
> +    g_assert_not_reached();
> +}

This is suspect, see next patch.
The rest of it seems ok.

r~


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

* Re: [PATCH v3 09/10] target/mips: Simplify 64-bit ifdef'ry of MXU code
  2021-02-22 22:39 ` [PATCH v3 09/10] target/mips: Simplify 64-bit ifdef'ry of MXU code Philippe Mathieu-Daudé
@ 2021-02-24  1:48   ` Richard Henderson
  0 siblings, 0 replies; 21+ messages in thread
From: Richard Henderson @ 2021-02-24  1:48 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé, qemu-devel; +Cc: Aleksandar Rikalo, Aurelien Jarno

On 2/22/21 2:39 PM, Philippe Mathieu-Daudé wrote:
> +#else /* !defined(TARGET_MIPS64) */
> +
> +bool decode_ase_mxu(DisasContext *ctx, uint32_t insn)
> +{
> +    return false;

Also seems suspect, but harmless.

> -#if !defined(TARGET_MIPS64)
> -        if (ctx->insn_flags & ASE_MXU) {
> +        if ((TARGET_LONG_BITS == 32) && (ctx->insn_flags & ASE_MXU)) {
>              decode_opc_mxu(ctx, ctx->opcode);

(1) Unnecessary () around ==.

(2) The call to decode_opc_mxu should be eliminated by the compiler because of
the constant false test.  You can (a) retain the function above and omit the
new test, (b) add the new test and leave the function undefined, a diagnostic
link error, or you can re-declare the function with QEMU_ERROR.


> @@ -28081,9 +28085,7 @@ void mips_tcg_init(void)
>      cpu_llval = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, llval),
>                                     "llval");
>  
> -#if !defined(TARGET_MIPS64)
>      mxu_translate_init();
> -#endif /* !TARGET_MIPS64 */

This one won't be eliminated, and is an abort for MIPS64 per patch 8, so all
mips64 now aborts on startup.


r~


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

* Re: [PATCH v3 10/10] target/mips: Extract MXU code to new mxu_translate.c file
  2021-02-22 22:39 ` [PATCH v3 10/10] target/mips: Extract MXU code to new mxu_translate.c file Philippe Mathieu-Daudé
@ 2021-02-24  2:16   ` Richard Henderson
  0 siblings, 0 replies; 21+ messages in thread
From: Richard Henderson @ 2021-02-24  2:16 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé, qemu-devel; +Cc: Aleksandar Rikalo, Aurelien Jarno

On 2/22/21 2:39 PM, Philippe Mathieu-Daudé wrote:
> Extract 1600+ lines from the big translate.c into a new file.
> 
> Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> ---
>  target/mips/mxu_translate.c | 1625 +++++++++++++++++++++++++++++++++++
>  target/mips/translate.c     | 1613 ----------------------------------
>  target/mips/meson.build     |    1 +
>  3 files changed, 1626 insertions(+), 1613 deletions(-)
>  create mode 100644 target/mips/mxu_translate.c


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

r~



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

* Re: [PATCH v3 05/10] target/mips: Extract decode_ase_mxu() from decode_opc_mxu()
  2021-02-24  1:25   ` Richard Henderson
@ 2021-02-26  9:09     ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 21+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-02-26  9:09 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: Aleksandar Rikalo, Aurelien Jarno

On 2/24/21 2:25 AM, Richard Henderson wrote:
> On 2/22/21 2:38 PM, Philippe Mathieu-Daudé wrote:
>> To easily convert MXU code to decodetree, extract decode_ase_mxu()
>> from decode_opc_mxu(), making it return a boolean.
>> We will keep decode_opc_mxu() in the translate.c unit because it
>> calls gen_arith().
>>
>> Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
>> ---
>>  target/mips/translate.c | 45 ++++++++++++++++++++++++-----------------
>>  1 file changed, 26 insertions(+), 19 deletions(-)
> 
> I guess the split is fine until you can just call gen_mul() from a trans() from
> the mxu decodetree.

I expect mxu decodetree to not cover MUL and return false, so it is
handled in the base ISA decoder.

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

Thanks :)


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

end of thread, other threads:[~2021-02-26  9:11 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-02-22 22:38 [PATCH v3 00/10] target/mips: Extract MXU code to new mxu_translate.c file Philippe Mathieu-Daudé
2021-02-22 22:38 ` [PATCH v3 01/10] target/mips: Rewrite complex ifdef'ry Philippe Mathieu-Daudé
2021-02-24  1:21   ` Richard Henderson
2021-02-22 22:38 ` [PATCH v3 02/10] target/mips: Remove XBurst Media eXtension Unit dead code Philippe Mathieu-Daudé
2021-02-22 22:38 ` [PATCH v3 03/10] target/mips: Remove unused CPUMIPSState* from MXU functions Philippe Mathieu-Daudé
2021-02-24  1:22   ` Richard Henderson
2021-02-22 22:38 ` [PATCH v3 04/10] target/mips: Pass instruction opcode to decode_opc_mxu() Philippe Mathieu-Daudé
2021-02-24  1:22   ` Richard Henderson
2021-02-22 22:38 ` [PATCH v3 05/10] target/mips: Extract decode_ase_mxu() from decode_opc_mxu() Philippe Mathieu-Daudé
2021-02-24  1:25   ` Richard Henderson
2021-02-26  9:09     ` Philippe Mathieu-Daudé
2021-02-22 22:38 ` [PATCH v3 06/10] target/mips: Use OPC_MUL instead of OPC__MXU_MUL Philippe Mathieu-Daudé
2021-02-24  1:34   ` Richard Henderson
2021-02-22 22:38 ` [PATCH v3 07/10] target/mips: Introduce mxu_translate_init() helper Philippe Mathieu-Daudé
2021-02-24  1:36   ` Richard Henderson
2021-02-22 22:38 ` [PATCH v3 08/10] target/mips: Make mxu_translate_init() / decode_ase_mxu() proto public Philippe Mathieu-Daudé
2021-02-24  1:38   ` Richard Henderson
2021-02-22 22:39 ` [PATCH v3 09/10] target/mips: Simplify 64-bit ifdef'ry of MXU code Philippe Mathieu-Daudé
2021-02-24  1:48   ` Richard Henderson
2021-02-22 22:39 ` [PATCH v3 10/10] target/mips: Extract MXU code to new mxu_translate.c file Philippe Mathieu-Daudé
2021-02-24  2:16   ` Richard Henderson

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.