Commit 8ecede46 authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/amarkovic/tags/mips-queue-december-2018-v3' into staging



MIPS queue for December 2018 - v3

# gpg: Signature made Thu 03 Jan 2019 16:53:47 GMT
# gpg:                using RSA key D4972A8967F75A65
# gpg: Good signature from "Aleksandar Markovic <amarkovic@wavecomp.com>"
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 8526 FBF1 5DA3 811F 4A01  DD75 D497 2A89 67F7 5A65

* remotes/amarkovic/tags/mips-queue-december-2018-v3: (44 commits)
  tests/tcg: mips: Test R5900 three-operand MADDU1
  tests/tcg: mips: Test R5900 three-operand MADDU
  tests/tcg: mips: Test R5900 three-operand MADD1
  tests/tcg: mips: Test R5900 three-operand MADD
  disas: nanoMIPS: Add a note on documentation
  disas: nanoMIPS: Reorder declarations and definitions of gpr decoders
  disas: nanoMIPS: Comment the decoder of 'gpr1' gpr encoding type
  disas: nanoMIPS: Rename the decoder of 'gpr1' gpr encoding type
  disas: nanoMIPS: Comment the decoder of 'gpr2.reg2' gpr encoding type
  disas: nanoMIPS: Rename the decoder of 'gpr2.reg2' gpr encoding type
  disas: nanoMIPS: Comment the decoder of 'gpr2.reg1' gpr encoding type
  disas: nanoMIPS: Rename the decoder of 'gpr2.reg1' gpr encoding type
  disas: nanoMIPS: Comment the decoder of 'gpr4.zero' gpr encoding type
  disas: nanoMIPS: Rename the decoder of 'gpr4.zero' gpr encoding type
  disas: nanoMIPS: Comment the decoder of 'gpr4' gpr encoding type
  disas: nanoMIPS: Rename the decoder of 'gpr4' gpr encoding type
  disas: nanoMIPS: Comment the decoder of 'gpr3.src.store' gpr encoding type
  disas: nanoMIPS: Rename the decoder of 'gpr3.src.store' gpr encoding type
  disas: nanoMIPS: Comment the decoder of 'gpr3' gpr encoding type
  disas: nanoMIPS: Rename the decoder of 'gpr3' gpr encoding type
  ...

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 20d6c731 19749a21
Loading
Loading
Loading
Loading
+16 −5
Original line number Diff line number Diff line
@@ -205,21 +205,24 @@ F: disas/microblaze.c
MIPS
M: Aurelien Jarno <aurelien@aurel32.net>
M: Aleksandar Markovic <amarkovic@wavecomp.com>
R: Aleksandar Rikalo <arikalo@wavecomp.com>
R: Stefan Markovic <smarkovic@wavecomp.com>
S: Maintained
F: target/mips/
F: default-configs/*mips*
F: disas/mips.c
F: disas/nanomips.cpp
F: disas/nanomips.h
F: hw/intc/mips_gic.c
F: hw/mips/
F: hw/misc/mips_*
F: hw/intc/mips_gic.c
F: hw/timer/mips_gictimer.c
F: include/hw/intc/mips_gic.h
F: include/hw/mips/
F: include/hw/misc/mips_*
F: include/hw/intc/mips_gic.h
F: include/hw/timer/mips_gictimer.h
F: tests/tcg/mips/
F: disas/mips.c
F: disas/nanomips.h
F: disas/nanomips.cpp
K: ^Subject:.*(?i)mips

Moxie
M: Anthony Green <green@moxielogic.com>
@@ -361,6 +364,7 @@ F: target/arm/kvm.c

MIPS
M: James Hogan <jhogan@kernel.org>
R: Aleksandar Rikalo <arikalo@wavecomp.com>
R: Stefan Markovic <smarkovic@wavecomp.com>
S: Maintained
F: target/mips/kvm.c
@@ -870,6 +874,7 @@ MIPS Machines
-------------
Jazz
M: Hervé Poussineau <hpoussin@reactos.org>
R: Aleksandar Rikalo <arikalo@wavecomp.com>
R: Stefan Markovic <smarkovic@wavecomp.com>
S: Maintained
F: hw/mips/mips_jazz.c
@@ -878,12 +883,14 @@ F: hw/dma/rc4030.c

Malta
M: Aurelien Jarno <aurelien@aurel32.net>
R: Aleksandar Rikalo <arikalo@wavecomp.com>
R: Stefan Markovic <smarkovic@wavecomp.com>
S: Maintained
F: hw/mips/mips_malta.c

Mipssim
M: Aleksandar Markovic <amarkovic@wavecomp.com>
R: Aleksandar Rikalo <arikalo@wavecomp.com>
R: Stefan Markovic <smarkovic@wavecomp.com>
S: Odd Fixes
F: hw/mips/mips_mipssim.c
@@ -891,12 +898,14 @@ F: hw/net/mipsnet.c

R4000
M: Aurelien Jarno <aurelien@aurel32.net>
R: Aleksandar Rikalo <arikalo@wavecomp.com>
R: Stefan Markovic <smarkovic@wavecomp.com>
S: Maintained
F: hw/mips/mips_r4k.c

Fulong 2E
M: Aleksandar Markovic <amarkovic@wavecomp.com>
R: Aleksandar Rikalo <arikalo@wavecomp.com>
R: Stefan Markovic <smarkovic@wavecomp.com>
S: Odd Fixes
F: hw/mips/mips_fulong2e.c
@@ -906,6 +915,7 @@ F: include/hw/isa/vt82c686.h

Boston
M: Paul Burton <pburton@wavecomp.com>
R: Aleksandar Rikalo <arikalo@wavecomp.com>
R: Stefan Markovic <smarkovic@wavecomp.com>
S: Maintained
F: hw/core/loader-fit.c
@@ -2162,6 +2172,7 @@ F: disas/i386.c

MIPS target
M: Aurelien Jarno <aurelien@aurel32.net>
R: Aleksandar Rikalo <arikalo@wavecomp.com>
R: Stefan Markovic <smarkovic@wavecomp.com>
S: Maintained
F: tcg/mips/
+1077 −1078

File changed.

Preview size limit exceeded, changes collapsed.

+51 −74
Original line number Diff line number Diff line
/*
 *  Header file for nanoMIPS disassembler component of QEMU
 *
 *  Copyright (C) 2018  Wave Computing
 *  Copyright (C) 2018  Wave Computing, Inc.
 *  Copyright (C) 2018  Matthew Fortune <matthew.fortune@mips.com>
 *  Copyright (C) 2018  Aleksandar Markovic <aleksandar.markovic@wavecomp.com>
 *  Copyright (C) 2018  Aleksandar Markovic <amarkovic@wavecomp.com>
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  the Free Software Foundation, either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
@@ -17,6 +17,7 @@
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <https://www.gnu.org/licenses/>.
 *
 */

#ifndef NANOMIPS_DISASSEMBLER_H
@@ -24,14 +25,14 @@

#include <string>

typedef unsigned short uint16;
typedef unsigned int uint32;
typedef long long int64;
typedef unsigned long long uint64;
typedef int64_t int64;
typedef uint64_t uint64;
typedef uint32_t uint32;
typedef uint16_t uint16;

namespace img
{
    typedef unsigned long long address;
    typedef uint64_t address;
}


@@ -104,13 +105,14 @@ private:

    uint64 renumber_registers(uint64 index, uint64 *register_list,
                              size_t register_list_size);
    uint64 encode_gpr3(uint64 d);
    uint64 encode_gpr3_store(uint64 d);
    uint64 encode_rd1_from_rd(uint64 d);
    uint64 encode_gpr4_zero(uint64 d);
    uint64 encode_gpr4(uint64 d);
    uint64 encode_rd2_reg1(uint64 d);
    uint64 encode_rd2_reg2(uint64 d);

    uint64 decode_gpr_gpr4(uint64 d);
    uint64 decode_gpr_gpr4_zero(uint64 d);
    uint64 decode_gpr_gpr3(uint64 d);
    uint64 decode_gpr_gpr3_src_store(uint64 d);
    uint64 decode_gpr_gpr2_reg1(uint64 d);
    uint64 decode_gpr_gpr2_reg2(uint64 d);
    uint64 decode_gpr_gpr1(uint64 d);

    uint64 copy(uint64 d);
    int64 copy(int64 d);
@@ -142,20 +144,20 @@ private:
    std::string CPR(uint64 reg);
    std::string ADDRESS(uint64 value, int instruction_size);

    int64 extract_s_4_2_1_0(uint64 instruction);
    int64 extr_sil0il0bs8_il15il8bs1Tmsb8(uint64 instruction);
    int64 extr_sil0il10bs1_il1il1bs9Tmsb10(uint64 instruction);
    int64 extr_sil0il11bs1_il1il1bs10Tmsb11(uint64 instruction);
    int64 extr_sil0il14bs1_il1il1bs13Tmsb14(uint64 instruction);
    int64 extr_sil0il16bs16_il16il0bs16Tmsb31(uint64 instruction);
    int64 extr_sil0il21bs1_il1il1bs20Tmsb21(uint64 instruction);
    int64 extr_sil0il25bs1_il1il1bs24Tmsb25(uint64 instruction);
    int64 extr_sil0il31bs1_il2il21bs10_il12il12bs9Tmsb31(uint64 instruction);
    int64 extr_sil0il7bs1_il1il1bs6Tmsb7(uint64 instruction);
    int64 extr_sil11il0bs10Tmsb9(uint64 instruction);
    int64 extract_shift_21_20_19_18_17_16(uint64 instruction);
    int64 extr_sil2il2bs6_il15il8bs1Tmsb8(uint64 instruction);
    int64 extr_sil3il3bs5_il15il8bs1Tmsb8(uint64 instruction);
    int64 extract_s__se3_4_2_1_0(uint64 instruction);
    int64 extract_s__se7_0_6_5_4_3_2_1_s1(uint64 instruction);
    int64 extract_s__se8_15_7_6_5_4_3_s3(uint64 instruction);
    int64 extract_s__se8_15_7_6_5_4_3_2_s2(uint64 instruction);
    int64 extract_s__se8_15_7_6_5_4_3_2_1_0(uint64 instruction);
    int64 extract_s__se9_20_19_18_17_16_15_14_13_12_11(uint64 instruction);
    int64 extract_s__se10_0_9_8_7_6_5_4_3_2_1_s1(uint64 instruction);
    int64 extract_s__se11_0_10_9_8_7_6_5_4_3_2_1_0_s1(uint64 instruction);
    int64 extract_s__se14_0_13_to_1_s1(uint64 instruction);
    int64 extract_s__se21_0_20_to_1_s1(uint64 instruction);
    int64 extract_s__se25_0_24_to_1_s1(uint64 instruction);
    int64 extract_s__se31_15_to_0_31_to_16(uint64 instruction);
    int64 extract_s__se31_0_11_to_2_20_to_12_s12(uint64 instruction);
    int64 extract_shift__se5_21_20_19_18_17_16(uint64 instruction);

    uint64 extract_ac_13_12(uint64 instruction);
    uint64 extract_bit_16_15_14_13_12_11(uint64 instruction);
@@ -175,10 +177,10 @@ private:
    uint64 extract_ct_25_24_23_22_21(uint64 instruction);
    uint64 extract_eu_3_2_1_0(uint64 instruction);
    uint64 extract_eu_6_5_4_3_2_1_0(uint64 instruction);
    uint64 extract_fd_10_9_8_7_6(uint64 instruction);
    uint64 extract_fs_15_14_13_12_11(uint64 instruction);
    uint64 extract_fd_15_14_13_12_11(uint64 instruction);
    uint64 extract_fs_20_19_18_17_16(uint64 instruction);
    uint64 extract_ft_15_14_13_12_11(uint64 instruction);
    uint64 extract_ft_20_19_18_17_16(uint64 instruction);
    uint64 extract_ft_25_24_23_22_21(uint64 instruction);
    uint64 extract_gp_2(uint64 instruction);
    uint64 extract_hint_25_24_23_22_21(uint64 instruction);
    uint64 extract_hs_20_19_18_17_16(uint64 instruction);
@@ -190,7 +192,7 @@ private:
    uint64 extract_rdl_25_24(uint64 instruction);
    uint64 extract_rd2_3_8(uint64 instruction);
    uint64 extract_rd3_3_2_1(uint64 instruction);
    uint64 extract_rd_20_19_18_17_16(uint64 instruction);
    uint64 extract_rd_15_14_13_12_11(uint64 instruction);
    uint64 extract_rs3_6_5_4(uint64 instruction);
    uint64 extract_rs4_4_2_1_0(uint64 instruction);
    uint64 extract_rs_4_3_2_1_0(uint64 instruction);
@@ -217,7 +219,7 @@ private:
    uint64 extract_shift_20_19_18_17_16(uint64 instruction);
    uint64 extract_shift_10_9_8_7_6(uint64 instruction);
    uint64 extract_shiftx_11_10_9_8_7_6(uint64 instruction);
    uint64 extr_shiftxil7il1bs4Fmsb4(uint64 instruction);
    uint64 extract_shiftx_10_9_8_7__s1(uint64 instruction);
    uint64 extract_size_20_19_18_17_16(uint64 instruction);
    uint64 extract_stripe_6(uint64 instruction);
    uint64 extract_stype_20_19_18_17_16(uint64 instruction);
@@ -226,49 +228,24 @@ private:
    uint64 extract_u_15_to_0(uint64 instruction);
    uint64 extract_u_17_to_0(uint64 instruction);
    uint64 extract_u_1_0(uint64 instruction);
    uint64 extr_uil0il1bs4Fmsb4(uint64 instruction);
    uint64 extr_uil0il2bs3Fmsb4(uint64 instruction);
    uint64 extr_uil0il2bs4Fmsb5(uint64 instruction);
    uint64 extr_uil0il2bs5Fmsb6(uint64 instruction);
    uint64 extr_uil0il2bs6Fmsb7(uint64 instruction);
    uint64 extr_uil0il2bs7Fmsb8(uint64 instruction);
    uint64 extr_uil0il32bs32Fmsb63(uint64 instruction);
    uint64 extract_u_3_2_1_0__s1(uint64 instruction);
    uint64 extract_u_2_1_0__s2(uint64 instruction);
    uint64 extract_u_3_2_1_0__s2(uint64 instruction);
    uint64 extract_u_4_3_2_1_0__s2(uint64 instruction);
    uint64 extract_u_5_4_3_2_1_0__s2(uint64 instruction);
    uint64 extract_u_6_5_4_3_2_1_0__s2(uint64 instruction);
    uint64 extract_u_31_to_0__s32(uint64 instruction);
    uint64 extract_u_10(uint64 instruction);
    uint64 extract_u_17_16_15_14_13_12_11(uint64 instruction);
    uint64 extract_u_20_19_18_17_16_15_14_13(uint64 instruction);
    uint64 extr_uil1il1bs17Fmsb17(uint64 instruction);
    uint64 extr_uil1il1bs2Fmsb2(uint64 instruction);
    uint64 extr_uil2il2bs16Fmsb17(uint64 instruction);
    uint64 extr_uil2il2bs19Fmsb20(uint64 instruction);
    uint64 extr_uil3il3bs18Fmsb20(uint64 instruction);
    uint64 extr_uil3il3bs1_il8il2bs1Fmsb3(uint64 instruction);
    uint64 extr_uil3il3bs9Fmsb11(uint64 instruction);
    uint64 extr_uil4il4bs4Fmsb7(uint64 instruction);
    uint64 extr_xil0il0bs12Fmsb11(uint64 instruction);
    uint64 extr_xil0il0bs3_il4il0bs1Fmsb2(uint64 instruction);
    uint64 extr_xil10il0bs1Fmsb0(uint64 instruction);
    uint64 extr_xil10il0bs1_il11il0bs5Fmsb4(uint64 instruction);
    uint64 extr_xil10il0bs1_il14il0bs2Fmsb1(uint64 instruction);
    uint64 extr_xil10il0bs4_il22il0bs4Fmsb3(uint64 instruction);
    uint64 extr_xil10il0bs6Fmsb5(uint64 instruction);
    uint64 extr_xil11il0bs1Fmsb0(uint64 instruction);
    uint64 extr_xil11il0bs5Fmsb4(uint64 instruction);
    uint64 extr_xil12il0bs1Fmsb0(uint64 instruction);
    uint64 extr_xil14il0bs1_il15il0bs1Fmsb0(uint64 instruction);
    uint64 extr_xil14il0bs2Fmsb1(uint64 instruction);
    uint64 extr_xil15il0bs1Fmsb0(uint64 instruction);
    uint64 extr_xil16il0bs10Fmsb9(uint64 instruction);
    uint64 extr_xil16il0bs5Fmsb4(uint64 instruction);
    uint64 extr_xil17il0bs1Fmsb0(uint64 instruction);
    uint64 extr_xil17il0bs9Fmsb8(uint64 instruction);
    uint64 extr_xil21il0bs5Fmsb4(uint64 instruction);
    uint64 extr_xil24il0bs1Fmsb0(uint64 instruction);
    uint64 extr_xil2il0bs1_il15il0bs1Fmsb0(uint64 instruction);
    uint64 extr_xil6il0bs3Fmsb2(uint64 instruction);
    uint64 extr_xil6il0bs3_il10il0bs1Fmsb2(uint64 instruction);
    uint64 extr_xil9il0bs2Fmsb1(uint64 instruction);
    uint64 extr_xil9il0bs3Fmsb2(uint64 instruction);
    uint64 extr_xil9il0bs3_il16il0bs5Fmsb4(uint64 instruction);
    uint64 extract_u_17_to_1__s1(uint64 instruction);
    uint64 extract_u_2_1__s1(uint64 instruction);
    uint64 extract_u_17_to_2__s2(uint64 instruction);
    uint64 extract_u_20_to_2__s2(uint64 instruction);
    uint64 extract_u_20_to_3__s3(uint64 instruction);
    uint64 extract_u_3_8__s2(uint64 instruction);
    uint64 extract_u_11_10_9_8_7_6_5_4_3__s3(uint64 instruction);
    uint64 extract_u_7_6_5_4__s4(uint64 instruction);

    bool ADDIU_32__cond(uint64 instruction);
    bool ADDIU_RS5__cond(uint64 instruction);
+3 −2
Original line number Diff line number Diff line
@@ -99,9 +99,10 @@
 * those few cases by hand.
 *
 * Note that x32 is fully detected with __x86_64__ + _ILP32, and that for
 * Sparc we always force the use of sparcv9 in configure.
 * Sparc we always force the use of sparcv9 in configure. MIPS n32 (ILP32) &
 * n64 (LP64) ABIs are both detected using __mips64.
 */
#if defined(__x86_64__) || defined(__sparc__)
#if defined(__x86_64__) || defined(__sparc__) || defined(__mips64)
# define ATOMIC_REG_SIZE  8
#else
# define ATOMIC_REG_SIZE  sizeof(void *)
+883 −126
Original line number Diff line number Diff line
@@ -1399,10 +1399,12 @@ enum {
/*
 *
 *       AN OVERVIEW OF MXU EXTENSION INSTRUCTION SET
 *       ============================================
 *
 * MXU (full name: MIPS eXtension/enhanced Unit) is an SIMD extension of MIPS32
 *
 * 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.
@@ -1410,15 +1412,16 @@ enum {
 * 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
 * --------------------------------------------
 *     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 *  Registers:
 *  Register operands:
 *
 *   XRa, XRb, XRc, XRd - MXU registers
 *   Rb, Rc, Rd, Rs, Rt - general purpose MIPS registers
 *
 *  Subfields:
 *  Non-register operands:
 *
 *   aptn1 - 1-bit accumulate add/subtract pattern
 *   aptn2 - 2-bit accumulate add/subtract pattern
@@ -1430,19 +1433,10 @@ enum {
 *
 *  Prefixes:
 *
 *   <Operation parallel level><Operand size>
 *     S                         32
 *     D                         16
 *     Q                          8
 *
 *  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
 *   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:
 *
@@ -1486,6 +1480,19 @@ enum {
 *   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
 * -----------------------           ---------------------------
 *
@@ -1563,6 +1570,13 @@ enum {
 *  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
 *
@@ -1663,12 +1677,21 @@ enum {
 *          │                               20..18
 *          ├─ 100111 ─ OPC_MXU__POOL16 ─┬─ 000 ─ OPC_MXU_D32SARW
 *          │                            ├─ 001 ─ OPC_MXU_S32ALN
 *          ├─ 101000 ─ OPC_MXU_LXB      ├─ 010 ─ OPC_MXU_S32ALNI
 *          ├─ 101001 ─ <not assigned>   ├─ 011 ─ OPC_MXU_S32NOR
 *          ├─ 101010 ─ OPC_MXU_S16LDD   ├─ 100 ─ OPC_MXU_S32AND
 *          ├─ 101011 ─ OPC_MXU_S16STD   ├─ 101 ─ OPC_MXU_S32OR
 *          ├─ 101100 ─ OPC_MXU_S16LDI   ├─ 110 ─ OPC_MXU_S32XOR
 *          ├─ 101101 ─ OPC_MXU_S16SDI   └─ 111 ─ OPC_MXU_S32LUI
 *          │                            ├─ 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
@@ -1678,23 +1701,23 @@ enum {
 *          ├─ 110100 ─ OPC_MXU_Q16SLL   ├─ 010 ─ OPC_MXU_D32SARV
 *          ├─ 110101 ─ OPC_MXU_Q16SLR   ├─ 011 ─ OPC_MXU_Q16SLLV
 *          │                            ├─ 100 ─ OPC_MXU_Q16SLRV
 *          ├─ 110110 ─ OPC_MXU__POOL17 ─┴─ 101 ─ OPC_MXU_Q16SARV
 *          ├─ 110110 ─ OPC_MXU__POOL18 ─┴─ 101 ─ OPC_MXU_Q16SARV
 *          │
 *          ├─ 110111 ─ OPC_MXU_Q16SAR
 *          │                               23..22
 *          ├─ 111000 ─ OPC_MXU__POOL18 ─┬─ 00 ─ OPC_MXU_Q8MUL
 *          ├─ 111000 ─ OPC_MXU__POOL19 ─┬─ 00 ─ OPC_MXU_Q8MUL
 *          │                            └─ 01 ─ OPC_MXU_Q8MULSU
 *          │
 *          │                               20..18
 *          ├─ 111001 ─ OPC_MXU__POOL19 ─┬─ 000 ─ OPC_MXU_Q8MOVZ
 *          ├─ 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_S32MOV
 *          │                            └─ 101 ─ OPC_MXU_S32MOVN
 *          │
 *          │                               23..22
 *          ├─ 111010 ─ OPC_MXU__POOL20 ─┬─ 00 ─ OPC_MXU_Q8MAC
 *          ├─ 111010 ─ OPC_MXU__POOL21 ─┬─ 00 ─ OPC_MXU_Q8MAC
 *          │                            └─ 10 ─ OPC_MXU_Q8MACSU
 *          ├─ 111011 ─ OPC_MXU_Q16SCOP
 *          ├─ 111100 ─ OPC_MXU_Q8MADL
@@ -1706,7 +1729,7 @@ enum {
 * Compiled after:
 *
 *   "XBurst® Instruction Set Architecture MIPS eXtension/enhanced Unit
 *   Programming Manual", Ingenic Semiconductor Co, Ltd., 2017
 *   Programming Manual", Ingenic Semiconductor Co, Ltd., revision June 2, 2017
 */
enum {
@@ -1750,7 +1773,7 @@ enum {
    OPC_MXU_S8SDI    = 0x25,
    OPC_MXU__POOL15  = 0x26,
    OPC_MXU__POOL16  = 0x27,
    OPC_MXU_LXB      = 0x28,
    OPC_MXU__POOL17  = 0x28,
    /* not assigned 0x29 */
    OPC_MXU_S16LDD   = 0x2A,
    OPC_MXU_S16STD   = 0x2B,
@@ -1764,11 +1787,11 @@ enum {
    OPC_MXU_D32SAR   = 0x33,
    OPC_MXU_Q16SLL   = 0x34,
    OPC_MXU_Q16SLR   = 0x35,
    OPC_MXU__POOL17  = 0x36,
    OPC_MXU__POOL18  = 0x36,
    OPC_MXU_Q16SAR   = 0x37,
    OPC_MXU__POOL18  = 0x38,
    OPC_MXU__POOL19  = 0x39,
    OPC_MXU__POOL20  = 0x3A,
    OPC_MXU__POOL19  = 0x38,
    OPC_MXU__POOL20  = 0x39,
    OPC_MXU__POOL21  = 0x3A,
    OPC_MXU_Q16SCOP  = 0x3B,
    OPC_MXU_Q8MADL   = 0x3C,
    OPC_MXU_S32SFL   = 0x3D,
@@ -1930,16 +1953,27 @@ enum {
    OPC_MXU_D32SARW  = 0x00,
    OPC_MXU_S32ALN   = 0x01,
    OPC_MXU_S32ALNI  = 0x02,
    OPC_MXU_S32NOR   = 0x03,
    OPC_MXU_S32AND   = 0x04,
    OPC_MXU_S32OR    = 0x05,
    OPC_MXU_S32XOR   = 0x06,
    OPC_MXU_S32LUI   = 0x07,
    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,
@@ -1950,7 +1984,7 @@ enum {
};
/*
 * MXU pool 18
 * MXU pool 19
 */
enum {
    OPC_MXU_Q8MUL    = 0x00,
@@ -1958,7 +1992,7 @@ enum {
};
/*
 * MXU pool 19
 * MXU pool 20
 */
enum {
    OPC_MXU_Q8MOVZ   = 0x00,
@@ -1970,7 +2004,7 @@ enum {
};
/*
 * MXU pool 20
 * MXU pool 21
 */
enum {
    OPC_MXU_Q8MAC    = 0x00,
@@ -2421,9 +2455,11 @@ static TCGv_i32 fpu_fcr0, fpu_fcr31;
static TCGv_i64 fpu_f64[32];
static TCGv_i64 msa_wr_d[64];
#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"
@@ -2547,10 +2583,12 @@ static const char * const msaregnames[] = {
    "w30.d0", "w30.d1", "w31.d0", "w31.d1",
};
#if !defined(TARGET_MIPS64)
static const char * const mxuregnames[] = {
    "XR1",  "XR2",  "XR3",  "XR4",  "XR5",  "XR6",  "XR7",  "XR8",
    "XR9",  "XR10", "XR11", "XR12", "XR13", "XR14", "XR15", "MXU_CR",
};
#endif
#define LOG_DISAS(...)                                                        \
    do {                                                                      \
@@ -2633,6 +2671,7 @@ 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)
{
@@ -2661,6 +2700,7 @@ 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 */
@@ -4993,8 +5033,8 @@ static void gen_muldiv(DisasContext *ctx, uint32_t opc,
}
/*
 * These MULT and MULTU instructions implemented in for example the
 * Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core
 * These MULT[U] and MADD[U] instructions implemented in for example
 * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core
 * architectures are special three-operand variants with the syntax
 *
 *     MULT[U][1] rd, rs, rt
@@ -5003,6 +5043,14 @@ static void gen_muldiv(DisasContext *ctx, uint32_t opc,
 *
 *     (rd, LO, HI) <- rs * rt
 *
 * and
 *
 *     MADD[U][1] rd, rs, rt
 *
 * such that
 *
 *     (rd, LO, HI) <- (LO, HI) + rs * rt
 *
 * where the low-order 32-bits of the result is placed into both the
 * GPR rd and the special register LO. The high-order 32-bits of the
 * result is placed into the special register HI.
@@ -5059,8 +5107,54 @@ static void gen_mul_txx9(DisasContext *ctx, uint32_t opc,
            tcg_temp_free_i32(t3);
        }
        break;
    case MMI_OPC_MADD1:
        acc = 1;
        /* Fall through */
    case MMI_OPC_MADD:
        {
            TCGv_i64 t2 = tcg_temp_new_i64();
            TCGv_i64 t3 = tcg_temp_new_i64();
            tcg_gen_ext_tl_i64(t2, t0);
            tcg_gen_ext_tl_i64(t3, t1);
            tcg_gen_mul_i64(t2, t2, t3);
            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
            tcg_gen_add_i64(t2, t2, t3);
            tcg_temp_free_i64(t3);
            gen_move_low32(cpu_LO[acc], t2);
            gen_move_high32(cpu_HI[acc], t2);
            if (rd) {
                gen_move_low32(cpu_gpr[rd], t2);
            }
            tcg_temp_free_i64(t2);
        }
        break;
    case MMI_OPC_MADDU1:
        acc = 1;
        /* Fall through */
    case MMI_OPC_MADDU:
        {
            TCGv_i64 t2 = tcg_temp_new_i64();
            TCGv_i64 t3 = tcg_temp_new_i64();
            tcg_gen_ext32u_tl(t0, t0);
            tcg_gen_ext32u_tl(t1, t1);
            tcg_gen_extu_tl_i64(t2, t0);
            tcg_gen_extu_tl_i64(t3, t1);
            tcg_gen_mul_i64(t2, t2, t3);
            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
            tcg_gen_add_i64(t2, t2, t3);
            tcg_temp_free_i64(t3);
            gen_move_low32(cpu_LO[acc], t2);
            gen_move_high32(cpu_HI[acc], t2);
            if (rd) {
                gen_move_low32(cpu_gpr[rd], t2);
            }
            tcg_temp_free_i64(t2);
        }
        break;
    default:
        MIPS_INVAL("mul TXx9");
        MIPS_INVAL("mul/madd TXx9");
        generate_exception_end(ctx, EXCP_RI);
        goto out;
    }
@@ -24201,6 +24295,8 @@ static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
}
#if !defined(TARGET_MIPS64)
/* MXU accumulate add/subtract 1-bit pattern 'aptn1' */
#define MXU_APTN1_A    0
#define MXU_APTN1_S    1
@@ -24218,6 +24314,11 @@ static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
#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
@@ -24610,6 +24711,641 @@ static void gen_mxu_s32ldd_s32lddr(DisasContext *ctx)
}
/*
 *                 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.
 *
 *   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)
{
    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.
 *
 *   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)
{
    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.
 *
 *   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)
{
    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.
 *
 *   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)
{
    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.
 *
 *   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)
{
    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.
 *
 *   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)
{
    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);
        /* finaly 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);
        /* finaly 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.
 *
 *   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)
{
    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));
            /* finaly 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));
            /* finaly 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.
 *
 *   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)
{
    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
 * =======================
@@ -24631,34 +25367,16 @@ static void decode_opc_mxu__pool00(CPUMIPSState *env, DisasContext *ctx)
    switch (opcode) {
    case OPC_MXU_S32MAX:
        /* TODO: Implement emulation of S32MAX instruction. */
        MIPS_INVAL("OPC_MXU_S32MAX");
        generate_exception_end(ctx, EXCP_RI);
        break;
    case OPC_MXU_S32MIN:
        /* TODO: Implement emulation of S32MIN instruction. */
        MIPS_INVAL("OPC_MXU_S32MIN");
        generate_exception_end(ctx, EXCP_RI);
        gen_mxu_S32MAX_S32MIN(ctx);
        break;
    case OPC_MXU_D16MAX:
        /* TODO: Implement emulation of D16MAX instruction. */
        MIPS_INVAL("OPC_MXU_D16MAX");
        generate_exception_end(ctx, EXCP_RI);
        break;
    case OPC_MXU_D16MIN:
        /* TODO: Implement emulation of D16MIN instruction. */
        MIPS_INVAL("OPC_MXU_D16MIN");
        generate_exception_end(ctx, EXCP_RI);
        gen_mxu_D16MAX_D16MIN(ctx);
        break;
    case OPC_MXU_Q8MAX:
        /* TODO: Implement emulation of Q8MAX instruction. */
        MIPS_INVAL("OPC_MXU_Q8MAX");
        generate_exception_end(ctx, EXCP_RI);
        break;
    case OPC_MXU_Q8MIN:
        /* TODO: Implement emulation of Q8MIN instruction. */
        MIPS_INVAL("OPC_MXU_Q8MIN");
        generate_exception_end(ctx, EXCP_RI);
        gen_mxu_Q8MAX_Q8MIN(ctx);
        break;
    case OPC_MXU_Q8SLT:
        /* TODO: Implement emulation of Q8SLT instruction. */
@@ -25261,18 +25979,18 @@ static void decode_opc_mxu__pool15(CPUMIPSState *env, DisasContext *ctx)
 *  |  SPECIAL2 |  s3 |0 0|x x x|  XRc  |  XRb  |  XRa  |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|
 *  +-----------+---------+-----+-------+-------+-------+-----------+
 *
 *  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)
{
@@ -25290,33 +26008,70 @@ static void decode_opc_mxu__pool16(CPUMIPSState *env, DisasContext *ctx)
        generate_exception_end(ctx, EXCP_RI);
        break;
    case OPC_MXU_S32ALNI:
        /* TODO: Implement emulation of S32ALNI instruction. */
        MIPS_INVAL("OPC_MXU_S32ALNI");
        gen_mxu_S32ALNI(ctx);
        break;
    case OPC_MXU_S32LUI:
        /* TODO: Implement emulation of S32LUI instruction. */
        MIPS_INVAL("OPC_MXU_S32LUI");
        generate_exception_end(ctx, EXCP_RI);
        break;
    case OPC_MXU_S32NOR:
        /* TODO: Implement emulation of S32NOR instruction. */
        MIPS_INVAL("OPC_MXU_S32NOR");
        generate_exception_end(ctx, EXCP_RI);
        gen_mxu_S32NOR(ctx);
        break;
    case OPC_MXU_S32AND:
        /* TODO: Implement emulation of S32AND instruction. */
        MIPS_INVAL("OPC_MXU_S32AND");
        generate_exception_end(ctx, EXCP_RI);
        gen_mxu_S32AND(ctx);
        break;
    case OPC_MXU_S32OR:
        /* TODO: Implement emulation of S32OR instruction. */
        MIPS_INVAL("OPC_MXU_S32OR");
        generate_exception_end(ctx, EXCP_RI);
        gen_mxu_S32OR(ctx);
        break;
    case OPC_MXU_S32XOR:
        /* TODO: Implement emulation of S32XOR instruction. */
        MIPS_INVAL("OPC_MXU_S32XOR");
        gen_mxu_S32XOR(ctx);
        break;
    default:
        MIPS_INVAL("decode_opc_mxu");
        generate_exception_end(ctx, EXCP_RI);
        break;
    case OPC_MXU_S32LUI:
        /* TODO: Implement emulation of S32LUI instruction. */
        MIPS_INVAL("OPC_MXU_S32LUI");
    }
}
/*
 *
 * 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");
        generate_exception_end(ctx, EXCP_RI);
        break;
    case OPC_MXU_LXH:
        /* TODO: Implement emulation of LXH instruction. */
        MIPS_INVAL("OPC_MXU_LXH");
        generate_exception_end(ctx, EXCP_RI);
        break;
    case OPC_MXU_LXHU:
        /* TODO: Implement emulation of LXHU instruction. */
        MIPS_INVAL("OPC_MXU_LXHU");
        generate_exception_end(ctx, EXCP_RI);
        break;
    case OPC_MXU_LXB:
        /* TODO: Implement emulation of LXB instruction. */
        MIPS_INVAL("OPC_MXU_LXB");
        generate_exception_end(ctx, EXCP_RI);
        break;
    case OPC_MXU_LXBU:
        /* TODO: Implement emulation of LXBU instruction. */
        MIPS_INVAL("OPC_MXU_LXBU");
        generate_exception_end(ctx, EXCP_RI);
        break;
    default:
@@ -25325,18 +26080,17 @@ static void decode_opc_mxu__pool16(CPUMIPSState *env, DisasContext *ctx)
        break;
    }
}
/*
 *
 * Decode MXU pool17
 * 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__POOL17|
 *  |  SPECIAL2 |    rb   |x x x|  XRd  |  XRa  |0 0 0 0|MXU__POOL18|
 *  +-----------+---------+-----+-------+-------+-------+-----------+
 *
 */
static void decode_opc_mxu__pool17(CPUMIPSState *env, DisasContext *ctx)
static void decode_opc_mxu__pool18(CPUMIPSState *env, DisasContext *ctx)
{
    uint32_t opcode = extract32(ctx->opcode, 18, 3);
@@ -25380,15 +26134,15 @@ static void decode_opc_mxu__pool17(CPUMIPSState *env, DisasContext *ctx)
/*
 *
 * Decode MXU pool18
 * 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__POOL18|
 *  |  SPECIAL2 |0 0|x x|  XRd  |  XRc  |  XRb  |  XRa  |MXU__POOL19|
 *  +-----------+---+---+-------+-------+-------+-------+-----------+
 *
 */
static void decode_opc_mxu__pool18(CPUMIPSState *env, DisasContext *ctx)
static void decode_opc_mxu__pool19(CPUMIPSState *env, DisasContext *ctx)
{
    uint32_t opcode = extract32(ctx->opcode, 22, 2);
@@ -25406,15 +26160,15 @@ static void decode_opc_mxu__pool18(CPUMIPSState *env, DisasContext *ctx)
/*
 *
 * Decode MXU pool19
 * 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__POOL19|
 *  |  SPECIAL2 |0 0 0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL20|
 *  +-----------+---------+-----+-------+-------+-------+-----------+
 *
 */
static void decode_opc_mxu__pool19(CPUMIPSState *env, DisasContext *ctx)
static void decode_opc_mxu__pool20(CPUMIPSState *env, DisasContext *ctx)
{
    uint32_t opcode = extract32(ctx->opcode, 18, 3);
@@ -25458,15 +26212,15 @@ static void decode_opc_mxu__pool19(CPUMIPSState *env, DisasContext *ctx)
/*
 *
 * Decode MXU pool20
 * 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__POOL20|
 *  |  SPECIAL2 |an2|x x|  XRd  |  XRc  |  XRb  |  XRa  |MXU__POOL21|
 *  +-----------+---+---+-------+-------+-------+-------+-----------+
 *
 */
static void decode_opc_mxu__pool20(CPUMIPSState *env, DisasContext *ctx)
static void decode_opc_mxu__pool21(CPUMIPSState *env, DisasContext *ctx)
{
    uint32_t opcode = extract32(ctx->opcode, 22, 2);
@@ -25669,10 +26423,8 @@ static void decode_opc_mxu(CPUMIPSState *env, DisasContext *ctx)
        case OPC_MXU__POOL16:
            decode_opc_mxu__pool16(env, ctx);
            break;
        case OPC_MXU_LXB:
            /* TODO: Implement emulation of LXB instruction. */
            MIPS_INVAL("OPC_MXU_LXB");
            generate_exception_end(ctx, EXCP_RI);
        case OPC_MXU__POOL17:
            decode_opc_mxu__pool17(env, ctx);
            break;
        case OPC_MXU_S16LDD:
            /* TODO: Implement emulation of S16LDD instruction. */
@@ -25724,23 +26476,23 @@ static void decode_opc_mxu(CPUMIPSState *env, DisasContext *ctx)
            MIPS_INVAL("OPC_MXU_Q16SLR");
            generate_exception_end(ctx, EXCP_RI);
            break;
        case OPC_MXU__POOL17:
            decode_opc_mxu__pool17(env, ctx);
        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");
            generate_exception_end(ctx, EXCP_RI);
            break;
        case OPC_MXU__POOL18:
            decode_opc_mxu__pool18(env, 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");
@@ -25771,6 +26523,8 @@ static void decode_opc_mxu(CPUMIPSState *env, DisasContext *ctx)
    }
}
#endif /* !defined(TARGET_MIPS64) */
static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
{
@@ -26620,6 +27374,10 @@ static void decode_mmi(CPUMIPSState *env, DisasContext *ctx)
        break;
    case MMI_OPC_MULT1:
    case MMI_OPC_MULTU1:
    case MMI_OPC_MADD:
    case MMI_OPC_MADDU:
    case MMI_OPC_MADD1:
    case MMI_OPC_MADDU1:
        gen_mul_txx9(ctx, opc, rd, rs, rt);
        break;
    case MMI_OPC_DIV1:
@@ -26634,11 +27392,7 @@ static void decode_mmi(CPUMIPSState *env, DisasContext *ctx)
    case MMI_OPC_MFHI1:
        gen_HILO1_tx79(ctx, opc, rd);
        break;
    case MMI_OPC_MADD:          /* TODO: MMI_OPC_MADD */
    case MMI_OPC_MADDU:         /* TODO: MMI_OPC_MADDU */
    case MMI_OPC_PLZCW:         /* TODO: MMI_OPC_PLZCW */
    case MMI_OPC_MADD1:         /* TODO: MMI_OPC_MADD1 */
    case MMI_OPC_MADDU1:        /* TODO: MMI_OPC_MADDU1 */
    case MMI_OPC_PMFHL:         /* TODO: MMI_OPC_PMFHL */
    case MMI_OPC_PMTHL:         /* TODO: MMI_OPC_PMTHL */
    case MMI_OPC_PSLLH:         /* TODO: MMI_OPC_PSLLH */
@@ -28015,8 +28769,10 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
    case OPC_SPECIAL2:
        if ((ctx->insn_flags & INSN_R5900) && (ctx->insn_flags & ASE_MMI)) {
            decode_mmi(env, ctx);
#if !defined(TARGET_MIPS64)
        } else if (ctx->insn_flags & ASE_MXU) {
            decode_opc_mxu(env, ctx);
#endif
        } else {
            decode_opc_special2_legacy(env, ctx);
        }
@@ -29025,7 +29781,7 @@ void mips_tcg_init(void)
    fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
                                       offsetof(CPUMIPSState, active_fpu.fcr31),
                                       "fcr31");
#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,
@@ -29036,6 +29792,7 @@ void mips_tcg_init(void)
    mxu_CR = tcg_global_mem_new(cpu_env,
                                offsetof(CPUMIPSState, active_tc.mxu_cr),
                                mxuregnames[NUMBER_OF_MXU_REGISTERS - 1]);
#endif
}
#include "translate_init.inc.c"
Loading