qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

mxu_translate.c (56063B)


      1 /*
      2  *  Ingenic XBurst Media eXtension Unit (MXU) translation routines.
      3  *
      4  *  Copyright (c) 2004-2005 Jocelyn Mayer
      5  *  Copyright (c) 2006 Marius Groeger (FPU operations)
      6  *  Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
      7  *  Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
      8  *  Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support)
      9  *
     10  * SPDX-License-Identifier: LGPL-2.1-or-later
     11  *
     12  * Datasheet:
     13  *
     14  *   "XBurst® Instruction Set Architecture MIPS eXtension/enhanced Unit
     15  *   Programming Manual", Ingenic Semiconductor Co, Ltd., revision June 2, 2017
     16  */
     17 
     18 #include "qemu/osdep.h"
     19 #include "tcg/tcg-op.h"
     20 #include "exec/helper-gen.h"
     21 #include "translate.h"
     22 
     23 /*
     24  *
     25  *       AN OVERVIEW OF MXU EXTENSION INSTRUCTION SET
     26  *       ============================================
     27  *
     28  *
     29  * MXU (full name: MIPS eXtension/enhanced Unit) is a SIMD extension of MIPS32
     30  * instructions set. It is designed to fit the needs of signal, graphical and
     31  * video processing applications. MXU instruction set is used in Xburst family
     32  * of microprocessors by Ingenic.
     33  *
     34  * MXU unit contains 17 registers called X0-X16. X0 is always zero, and X16 is
     35  * the control register.
     36  *
     37  *
     38  *     The notation used in MXU assembler mnemonics
     39  *     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     40  *
     41  *  Register operands:
     42  *
     43  *   XRa, XRb, XRc, XRd - MXU registers
     44  *   Rb, Rc, Rd, Rs, Rt - general purpose MIPS registers
     45  *
     46  *  Non-register operands:
     47  *
     48  *   aptn1 - 1-bit accumulate add/subtract pattern
     49  *   aptn2 - 2-bit accumulate add/subtract pattern
     50  *   eptn2 - 2-bit execute add/subtract pattern
     51  *   optn2 - 2-bit operand pattern
     52  *   optn3 - 3-bit operand pattern
     53  *   sft4  - 4-bit shift amount
     54  *   strd2 - 2-bit stride amount
     55  *
     56  *  Prefixes:
     57  *
     58  *   Level of parallelism:                Operand size:
     59  *    S - single operation at a time       32 - word
     60  *    D - two operations in parallel       16 - half word
     61  *    Q - four operations in parallel       8 - byte
     62  *
     63  *  Operations:
     64  *
     65  *   ADD   - Add or subtract
     66  *   ADDC  - Add with carry-in
     67  *   ACC   - Accumulate
     68  *   ASUM  - Sum together then accumulate (add or subtract)
     69  *   ASUMC - Sum together then accumulate (add or subtract) with carry-in
     70  *   AVG   - Average between 2 operands
     71  *   ABD   - Absolute difference
     72  *   ALN   - Align data
     73  *   AND   - Logical bitwise 'and' operation
     74  *   CPS   - Copy sign
     75  *   EXTR  - Extract bits
     76  *   I2M   - Move from GPR register to MXU register
     77  *   LDD   - Load data from memory to XRF
     78  *   LDI   - Load data from memory to XRF (and increase the address base)
     79  *   LUI   - Load unsigned immediate
     80  *   MUL   - Multiply
     81  *   MULU  - Unsigned multiply
     82  *   MADD  - 64-bit operand add 32x32 product
     83  *   MSUB  - 64-bit operand subtract 32x32 product
     84  *   MAC   - Multiply and accumulate (add or subtract)
     85  *   MAD   - Multiply and add or subtract
     86  *   MAX   - Maximum between 2 operands
     87  *   MIN   - Minimum between 2 operands
     88  *   M2I   - Move from MXU register to GPR register
     89  *   MOVZ  - Move if zero
     90  *   MOVN  - Move if non-zero
     91  *   NOR   - Logical bitwise 'nor' operation
     92  *   OR    - Logical bitwise 'or' operation
     93  *   STD   - Store data from XRF to memory
     94  *   SDI   - Store data from XRF to memory (and increase the address base)
     95  *   SLT   - Set of less than comparison
     96  *   SAD   - Sum of absolute differences
     97  *   SLL   - Logical shift left
     98  *   SLR   - Logical shift right
     99  *   SAR   - Arithmetic shift right
    100  *   SAT   - Saturation
    101  *   SFL   - Shuffle
    102  *   SCOP  - Calculate x’s scope (-1, means x<0; 0, means x==0; 1, means x>0)
    103  *   XOR   - Logical bitwise 'exclusive or' operation
    104  *
    105  *  Suffixes:
    106  *
    107  *   E - Expand results
    108  *   F - Fixed point multiplication
    109  *   L - Low part result
    110  *   R - Doing rounding
    111  *   V - Variable instead of immediate
    112  *   W - Combine above L and V
    113  *
    114  *
    115  *     The list of MXU instructions grouped by functionality
    116  *     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    117  *
    118  * Load/Store instructions           Multiplication instructions
    119  * -----------------------           ---------------------------
    120  *
    121  *  S32LDD XRa, Rb, s12               S32MADD XRa, XRd, Rs, Rt
    122  *  S32STD XRa, Rb, s12               S32MADDU XRa, XRd, Rs, Rt
    123  *  S32LDDV XRa, Rb, rc, strd2        S32MSUB XRa, XRd, Rs, Rt
    124  *  S32STDV XRa, Rb, rc, strd2        S32MSUBU XRa, XRd, Rs, Rt
    125  *  S32LDI XRa, Rb, s12               S32MUL XRa, XRd, Rs, Rt
    126  *  S32SDI XRa, Rb, s12               S32MULU XRa, XRd, Rs, Rt
    127  *  S32LDIV XRa, Rb, rc, strd2        D16MUL XRa, XRb, XRc, XRd, optn2
    128  *  S32SDIV XRa, Rb, rc, strd2        D16MULE XRa, XRb, XRc, optn2
    129  *  S32LDDR XRa, Rb, s12              D16MULF XRa, XRb, XRc, optn2
    130  *  S32STDR XRa, Rb, s12              D16MAC XRa, XRb, XRc, XRd, aptn2, optn2
    131  *  S32LDDVR XRa, Rb, rc, strd2       D16MACE XRa, XRb, XRc, XRd, aptn2, optn2
    132  *  S32STDVR XRa, Rb, rc, strd2       D16MACF XRa, XRb, XRc, XRd, aptn2, optn2
    133  *  S32LDIR XRa, Rb, s12              D16MADL XRa, XRb, XRc, XRd, aptn2, optn2
    134  *  S32SDIR XRa, Rb, s12              S16MAD XRa, XRb, XRc, XRd, aptn1, optn2
    135  *  S32LDIVR XRa, Rb, rc, strd2       Q8MUL XRa, XRb, XRc, XRd
    136  *  S32SDIVR XRa, Rb, rc, strd2       Q8MULSU XRa, XRb, XRc, XRd
    137  *  S16LDD XRa, Rb, s10, eptn2        Q8MAC XRa, XRb, XRc, XRd, aptn2
    138  *  S16STD XRa, Rb, s10, eptn2        Q8MACSU XRa, XRb, XRc, XRd, aptn2
    139  *  S16LDI XRa, Rb, s10, eptn2        Q8MADL XRa, XRb, XRc, XRd, aptn2
    140  *  S16SDI XRa, Rb, s10, eptn2
    141  *  S8LDD XRa, Rb, s8, eptn3
    142  *  S8STD XRa, Rb, s8, eptn3         Addition and subtraction instructions
    143  *  S8LDI XRa, Rb, s8, eptn3         -------------------------------------
    144  *  S8SDI XRa, Rb, s8, eptn3
    145  *  LXW Rd, Rs, Rt, strd2             D32ADD XRa, XRb, XRc, XRd, eptn2
    146  *  LXH Rd, Rs, Rt, strd2             D32ADDC XRa, XRb, XRc, XRd
    147  *  LXHU Rd, Rs, Rt, strd2            D32ACC XRa, XRb, XRc, XRd, eptn2
    148  *  LXB Rd, Rs, Rt, strd2             D32ACCM XRa, XRb, XRc, XRd, eptn2
    149  *  LXBU Rd, Rs, Rt, strd2            D32ASUM XRa, XRb, XRc, XRd, eptn2
    150  *                                    S32CPS XRa, XRb, XRc
    151  *                                    Q16ADD XRa, XRb, XRc, XRd, eptn2, optn2
    152  * Comparison instructions            Q16ACC XRa, XRb, XRc, XRd, eptn2
    153  * -----------------------            Q16ACCM XRa, XRb, XRc, XRd, eptn2
    154  *                                    D16ASUM XRa, XRb, XRc, XRd, eptn2
    155  *  S32MAX XRa, XRb, XRc              D16CPS XRa, XRb,
    156  *  S32MIN XRa, XRb, XRc              D16AVG XRa, XRb, XRc
    157  *  S32SLT XRa, XRb, XRc              D16AVGR XRa, XRb, XRc
    158  *  S32MOVZ XRa, XRb, XRc             Q8ADD XRa, XRb, XRc, eptn2
    159  *  S32MOVN XRa, XRb, XRc             Q8ADDE XRa, XRb, XRc, XRd, eptn2
    160  *  D16MAX XRa, XRb, XRc              Q8ACCE XRa, XRb, XRc, XRd, eptn2
    161  *  D16MIN XRa, XRb, XRc              Q8ABD XRa, XRb, XRc
    162  *  D16SLT XRa, XRb, XRc              Q8SAD XRa, XRb, XRc, XRd
    163  *  D16MOVZ XRa, XRb, XRc             Q8AVG XRa, XRb, XRc
    164  *  D16MOVN XRa, XRb, XRc             Q8AVGR XRa, XRb, XRc
    165  *  Q8MAX XRa, XRb, XRc               D8SUM XRa, XRb, XRc, XRd
    166  *  Q8MIN XRa, XRb, XRc               D8SUMC XRa, XRb, XRc, XRd
    167  *  Q8SLT XRa, XRb, XRc
    168  *  Q8SLTU XRa, XRb, XRc
    169  *  Q8MOVZ XRa, XRb, XRc             Shift instructions
    170  *  Q8MOVN XRa, XRb, XRc             ------------------
    171  *
    172  *                                    D32SLL XRa, XRb, XRc, XRd, sft4
    173  * Bitwise instructions               D32SLR XRa, XRb, XRc, XRd, sft4
    174  * --------------------               D32SAR XRa, XRb, XRc, XRd, sft4
    175  *                                    D32SARL XRa, XRb, XRc, sft4
    176  *  S32NOR XRa, XRb, XRc              D32SLLV XRa, XRb, Rb
    177  *  S32AND XRa, XRb, XRc              D32SLRV XRa, XRb, Rb
    178  *  S32XOR XRa, XRb, XRc              D32SARV XRa, XRb, Rb
    179  *  S32OR XRa, XRb, XRc               D32SARW XRa, XRb, XRc, Rb
    180  *                                    Q16SLL XRa, XRb, XRc, XRd, sft4
    181  *                                    Q16SLR XRa, XRb, XRc, XRd, sft4
    182  * Miscellaneous instructions         Q16SAR XRa, XRb, XRc, XRd, sft4
    183  * -------------------------          Q16SLLV XRa, XRb, Rb
    184  *                                    Q16SLRV XRa, XRb, Rb
    185  *  S32SFL XRa, XRb, XRc, XRd, optn2  Q16SARV XRa, XRb, Rb
    186  *  S32ALN XRa, XRb, XRc, Rb
    187  *  S32ALNI XRa, XRb, XRc, s3
    188  *  S32LUI XRa, s8, optn3            Move instructions
    189  *  S32EXTR XRa, XRb, Rb, bits5      -----------------
    190  *  S32EXTRV XRa, XRb, Rs, Rt
    191  *  Q16SCOP XRa, XRb, XRc, XRd        S32M2I XRa, Rb
    192  *  Q16SAT XRa, XRb, XRc              S32I2M XRa, Rb
    193  *
    194  *
    195  *     The opcode organization of MXU instructions
    196  *     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    197  *
    198  * The bits 31..26 of all MXU instructions are equal to 0x1C (also referred
    199  * as opcode SPECIAL2 in the base MIPS ISA). The organization and meaning of
    200  * other bits up to the instruction level is as follows:
    201  *
    202  *              bits
    203  *             05..00
    204  *
    205  *          ┌─ 000000 ─ OPC_MXU_S32MADD
    206  *          ├─ 000001 ─ OPC_MXU_S32MADDU
    207  *          ├─ 000010 ─ <not assigned>   (non-MXU OPC_MUL)
    208  *          │
    209  *          │                               20..18
    210  *          ├─ 000011 ─ OPC_MXU__POOL00 ─┬─ 000 ─ OPC_MXU_S32MAX
    211  *          │                            ├─ 001 ─ OPC_MXU_S32MIN
    212  *          │                            ├─ 010 ─ OPC_MXU_D16MAX
    213  *          │                            ├─ 011 ─ OPC_MXU_D16MIN
    214  *          │                            ├─ 100 ─ OPC_MXU_Q8MAX
    215  *          │                            ├─ 101 ─ OPC_MXU_Q8MIN
    216  *          │                            ├─ 110 ─ OPC_MXU_Q8SLT
    217  *          │                            └─ 111 ─ OPC_MXU_Q8SLTU
    218  *          ├─ 000100 ─ OPC_MXU_S32MSUB
    219  *          ├─ 000101 ─ OPC_MXU_S32MSUBU    20..18
    220  *          ├─ 000110 ─ OPC_MXU__POOL01 ─┬─ 000 ─ OPC_MXU_S32SLT
    221  *          │                            ├─ 001 ─ OPC_MXU_D16SLT
    222  *          │                            ├─ 010 ─ OPC_MXU_D16AVG
    223  *          │                            ├─ 011 ─ OPC_MXU_D16AVGR
    224  *          │                            ├─ 100 ─ OPC_MXU_Q8AVG
    225  *          │                            ├─ 101 ─ OPC_MXU_Q8AVGR
    226  *          │                            └─ 111 ─ OPC_MXU_Q8ADD
    227  *          │
    228  *          │                               20..18
    229  *          ├─ 000111 ─ OPC_MXU__POOL02 ─┬─ 000 ─ OPC_MXU_S32CPS
    230  *          │                            ├─ 010 ─ OPC_MXU_D16CPS
    231  *          │                            ├─ 100 ─ OPC_MXU_Q8ABD
    232  *          │                            └─ 110 ─ OPC_MXU_Q16SAT
    233  *          ├─ 001000 ─ OPC_MXU_D16MUL
    234  *          │                               25..24
    235  *          ├─ 001001 ─ OPC_MXU__POOL03 ─┬─ 00 ─ OPC_MXU_D16MULF
    236  *          │                            └─ 01 ─ OPC_MXU_D16MULE
    237  *          ├─ 001010 ─ OPC_MXU_D16MAC
    238  *          ├─ 001011 ─ OPC_MXU_D16MACF
    239  *          ├─ 001100 ─ OPC_MXU_D16MADL
    240  *          ├─ 001101 ─ OPC_MXU_S16MAD
    241  *          ├─ 001110 ─ OPC_MXU_Q16ADD
    242  *          ├─ 001111 ─ OPC_MXU_D16MACE     23
    243  *          │                            ┌─ 0 ─ OPC_MXU_S32LDD
    244  *          ├─ 010000 ─ OPC_MXU__POOL04 ─┴─ 1 ─ OPC_MXU_S32LDDR
    245  *          │
    246  *          │                               23
    247  *          ├─ 010001 ─ OPC_MXU__POOL05 ─┬─ 0 ─ OPC_MXU_S32STD
    248  *          │                            └─ 1 ─ OPC_MXU_S32STDR
    249  *          │
    250  *          │                               13..10
    251  *          ├─ 010010 ─ OPC_MXU__POOL06 ─┬─ 0000 ─ OPC_MXU_S32LDDV
    252  *          │                            └─ 0001 ─ OPC_MXU_S32LDDVR
    253  *          │
    254  *          │                               13..10
    255  *          ├─ 010011 ─ OPC_MXU__POOL07 ─┬─ 0000 ─ OPC_MXU_S32STDV
    256  *          │                            └─ 0001 ─ OPC_MXU_S32STDVR
    257  *          │
    258  *          │                               23
    259  *          ├─ 010100 ─ OPC_MXU__POOL08 ─┬─ 0 ─ OPC_MXU_S32LDI
    260  *          │                            └─ 1 ─ OPC_MXU_S32LDIR
    261  *          │
    262  *          │                               23
    263  *          ├─ 010101 ─ OPC_MXU__POOL09 ─┬─ 0 ─ OPC_MXU_S32SDI
    264  *          │                            └─ 1 ─ OPC_MXU_S32SDIR
    265  *          │
    266  *          │                               13..10
    267  *          ├─ 010110 ─ OPC_MXU__POOL10 ─┬─ 0000 ─ OPC_MXU_S32LDIV
    268  *          │                            └─ 0001 ─ OPC_MXU_S32LDIVR
    269  *          │
    270  *          │                               13..10
    271  *          ├─ 010111 ─ OPC_MXU__POOL11 ─┬─ 0000 ─ OPC_MXU_S32SDIV
    272  *          │                            └─ 0001 ─ OPC_MXU_S32SDIVR
    273  *          ├─ 011000 ─ OPC_MXU_D32ADD
    274  *          │                               23..22
    275  *   MXU    ├─ 011001 ─ OPC_MXU__POOL12 ─┬─ 00 ─ OPC_MXU_D32ACC
    276  * opcodes ─┤                            ├─ 01 ─ OPC_MXU_D32ACCM
    277  *          │                            └─ 10 ─ OPC_MXU_D32ASUM
    278  *          ├─ 011010 ─ <not assigned>
    279  *          │                               23..22
    280  *          ├─ 011011 ─ OPC_MXU__POOL13 ─┬─ 00 ─ OPC_MXU_Q16ACC
    281  *          │                            ├─ 01 ─ OPC_MXU_Q16ACCM
    282  *          │                            └─ 10 ─ OPC_MXU_Q16ASUM
    283  *          │
    284  *          │                               23..22
    285  *          ├─ 011100 ─ OPC_MXU__POOL14 ─┬─ 00 ─ OPC_MXU_Q8ADDE
    286  *          │                            ├─ 01 ─ OPC_MXU_D8SUM
    287  *          ├─ 011101 ─ OPC_MXU_Q8ACCE   └─ 10 ─ OPC_MXU_D8SUMC
    288  *          ├─ 011110 ─ <not assigned>
    289  *          ├─ 011111 ─ <not assigned>
    290  *          ├─ 100000 ─ <not assigned>   (overlaps with CLZ)
    291  *          ├─ 100001 ─ <not assigned>   (overlaps with CLO)
    292  *          ├─ 100010 ─ OPC_MXU_S8LDD
    293  *          ├─ 100011 ─ OPC_MXU_S8STD       15..14
    294  *          ├─ 100100 ─ OPC_MXU_S8LDI    ┌─ 00 ─ OPC_MXU_S32MUL
    295  *          ├─ 100101 ─ OPC_MXU_S8SDI    ├─ 00 ─ OPC_MXU_S32MULU
    296  *          │                            ├─ 00 ─ OPC_MXU_S32EXTR
    297  *          ├─ 100110 ─ OPC_MXU__POOL15 ─┴─ 00 ─ OPC_MXU_S32EXTRV
    298  *          │
    299  *          │                               20..18
    300  *          ├─ 100111 ─ OPC_MXU__POOL16 ─┬─ 000 ─ OPC_MXU_D32SARW
    301  *          │                            ├─ 001 ─ OPC_MXU_S32ALN
    302  *          │                            ├─ 010 ─ OPC_MXU_S32ALNI
    303  *          │                            ├─ 011 ─ OPC_MXU_S32LUI
    304  *          │                            ├─ 100 ─ OPC_MXU_S32NOR
    305  *          │                            ├─ 101 ─ OPC_MXU_S32AND
    306  *          │                            ├─ 110 ─ OPC_MXU_S32OR
    307  *          │                            └─ 111 ─ OPC_MXU_S32XOR
    308  *          │
    309  *          │                               7..5
    310  *          ├─ 101000 ─ OPC_MXU__POOL17 ─┬─ 000 ─ OPC_MXU_LXB
    311  *          │                            ├─ 001 ─ OPC_MXU_LXH
    312  *          ├─ 101001 ─ <not assigned>   ├─ 011 ─ OPC_MXU_LXW
    313  *          ├─ 101010 ─ OPC_MXU_S16LDD   ├─ 100 ─ OPC_MXU_LXBU
    314  *          ├─ 101011 ─ OPC_MXU_S16STD   └─ 101 ─ OPC_MXU_LXHU
    315  *          ├─ 101100 ─ OPC_MXU_S16LDI
    316  *          ├─ 101101 ─ OPC_MXU_S16SDI
    317  *          ├─ 101110 ─ OPC_MXU_S32M2I
    318  *          ├─ 101111 ─ OPC_MXU_S32I2M
    319  *          ├─ 110000 ─ OPC_MXU_D32SLL
    320  *          ├─ 110001 ─ OPC_MXU_D32SLR      20..18
    321  *          ├─ 110010 ─ OPC_MXU_D32SARL  ┌─ 000 ─ OPC_MXU_D32SLLV
    322  *          ├─ 110011 ─ OPC_MXU_D32SAR   ├─ 001 ─ OPC_MXU_D32SLRV
    323  *          ├─ 110100 ─ OPC_MXU_Q16SLL   ├─ 010 ─ OPC_MXU_D32SARV
    324  *          ├─ 110101 ─ OPC_MXU_Q16SLR   ├─ 011 ─ OPC_MXU_Q16SLLV
    325  *          │                            ├─ 100 ─ OPC_MXU_Q16SLRV
    326  *          ├─ 110110 ─ OPC_MXU__POOL18 ─┴─ 101 ─ OPC_MXU_Q16SARV
    327  *          │
    328  *          ├─ 110111 ─ OPC_MXU_Q16SAR
    329  *          │                               23..22
    330  *          ├─ 111000 ─ OPC_MXU__POOL19 ─┬─ 00 ─ OPC_MXU_Q8MUL
    331  *          │                            └─ 01 ─ OPC_MXU_Q8MULSU
    332  *          │
    333  *          │                               20..18
    334  *          ├─ 111001 ─ OPC_MXU__POOL20 ─┬─ 000 ─ OPC_MXU_Q8MOVZ
    335  *          │                            ├─ 001 ─ OPC_MXU_Q8MOVN
    336  *          │                            ├─ 010 ─ OPC_MXU_D16MOVZ
    337  *          │                            ├─ 011 ─ OPC_MXU_D16MOVN
    338  *          │                            ├─ 100 ─ OPC_MXU_S32MOVZ
    339  *          │                            └─ 101 ─ OPC_MXU_S32MOVN
    340  *          │
    341  *          │                               23..22
    342  *          ├─ 111010 ─ OPC_MXU__POOL21 ─┬─ 00 ─ OPC_MXU_Q8MAC
    343  *          │                            └─ 10 ─ OPC_MXU_Q8MACSU
    344  *          ├─ 111011 ─ OPC_MXU_Q16SCOP
    345  *          ├─ 111100 ─ OPC_MXU_Q8MADL
    346  *          ├─ 111101 ─ OPC_MXU_S32SFL
    347  *          ├─ 111110 ─ OPC_MXU_Q8SAD
    348  *          └─ 111111 ─ <not assigned>   (overlaps with SDBBP)
    349  *
    350  *
    351  * Compiled after:
    352  *
    353  *   "XBurst® Instruction Set Architecture MIPS eXtension/enhanced Unit
    354  *   Programming Manual", Ingenic Semiconductor Co, Ltd., revision June 2, 2017
    355  */
    356 
    357 enum {
    358     OPC_MXU__POOL00  = 0x03,
    359     OPC_MXU_D16MUL   = 0x08,
    360     OPC_MXU_D16MAC   = 0x0A,
    361     OPC_MXU__POOL04  = 0x10,
    362     OPC_MXU_S8LDD    = 0x22,
    363     OPC_MXU__POOL16  = 0x27,
    364     OPC_MXU_S32M2I   = 0x2E,
    365     OPC_MXU_S32I2M   = 0x2F,
    366     OPC_MXU__POOL19  = 0x38,
    367 };
    368 
    369 
    370 /*
    371  * MXU pool 00
    372  */
    373 enum {
    374     OPC_MXU_S32MAX   = 0x00,
    375     OPC_MXU_S32MIN   = 0x01,
    376     OPC_MXU_D16MAX   = 0x02,
    377     OPC_MXU_D16MIN   = 0x03,
    378     OPC_MXU_Q8MAX    = 0x04,
    379     OPC_MXU_Q8MIN    = 0x05,
    380 };
    381 
    382 /*
    383  * MXU pool 04
    384  */
    385 enum {
    386     OPC_MXU_S32LDD   = 0x00,
    387     OPC_MXU_S32LDDR  = 0x01,
    388 };
    389 
    390 /*
    391  * MXU pool 16
    392  */
    393 enum {
    394     OPC_MXU_S32ALNI  = 0x02,
    395     OPC_MXU_S32NOR   = 0x04,
    396     OPC_MXU_S32AND   = 0x05,
    397     OPC_MXU_S32OR    = 0x06,
    398     OPC_MXU_S32XOR   = 0x07,
    399 };
    400 
    401 /*
    402  * MXU pool 19
    403  */
    404 enum {
    405     OPC_MXU_Q8MUL    = 0x00,
    406     OPC_MXU_Q8MULSU  = 0x01,
    407 };
    408 
    409 /* MXU accumulate add/subtract 1-bit pattern 'aptn1' */
    410 #define MXU_APTN1_A    0
    411 #define MXU_APTN1_S    1
    412 
    413 /* MXU accumulate add/subtract 2-bit pattern 'aptn2' */
    414 #define MXU_APTN2_AA    0
    415 #define MXU_APTN2_AS    1
    416 #define MXU_APTN2_SA    2
    417 #define MXU_APTN2_SS    3
    418 
    419 /* MXU execute add/subtract 2-bit pattern 'eptn2' */
    420 #define MXU_EPTN2_AA    0
    421 #define MXU_EPTN2_AS    1
    422 #define MXU_EPTN2_SA    2
    423 #define MXU_EPTN2_SS    3
    424 
    425 /* MXU operand getting pattern 'optn2' */
    426 #define MXU_OPTN2_PTN0  0
    427 #define MXU_OPTN2_PTN1  1
    428 #define MXU_OPTN2_PTN2  2
    429 #define MXU_OPTN2_PTN3  3
    430 /* alternative naming scheme for 'optn2' */
    431 #define MXU_OPTN2_WW    0
    432 #define MXU_OPTN2_LW    1
    433 #define MXU_OPTN2_HW    2
    434 #define MXU_OPTN2_XW    3
    435 
    436 /* MXU operand getting pattern 'optn3' */
    437 #define MXU_OPTN3_PTN0  0
    438 #define MXU_OPTN3_PTN1  1
    439 #define MXU_OPTN3_PTN2  2
    440 #define MXU_OPTN3_PTN3  3
    441 #define MXU_OPTN3_PTN4  4
    442 #define MXU_OPTN3_PTN5  5
    443 #define MXU_OPTN3_PTN6  6
    444 #define MXU_OPTN3_PTN7  7
    445 
    446 /* MXU registers */
    447 static TCGv mxu_gpr[NUMBER_OF_MXU_REGISTERS - 1];
    448 static TCGv mxu_CR;
    449 
    450 static const char mxuregnames[][4] = {
    451     "XR1",  "XR2",  "XR3",  "XR4",  "XR5",  "XR6",  "XR7",  "XR8",
    452     "XR9",  "XR10", "XR11", "XR12", "XR13", "XR14", "XR15", "XCR",
    453 };
    454 
    455 void mxu_translate_init(void)
    456 {
    457     for (unsigned i = 0; i < NUMBER_OF_MXU_REGISTERS - 1; i++) {
    458         mxu_gpr[i] = tcg_global_mem_new(cpu_env,
    459                                         offsetof(CPUMIPSState, active_tc.mxu_gpr[i]),
    460                                         mxuregnames[i]);
    461     }
    462 
    463     mxu_CR = tcg_global_mem_new(cpu_env,
    464                                 offsetof(CPUMIPSState, active_tc.mxu_cr),
    465                                 mxuregnames[NUMBER_OF_MXU_REGISTERS - 1]);
    466 }
    467 
    468 /* MXU General purpose registers moves. */
    469 static inline void gen_load_mxu_gpr(TCGv t, unsigned int reg)
    470 {
    471     if (reg == 0) {
    472         tcg_gen_movi_tl(t, 0);
    473     } else if (reg <= 15) {
    474         tcg_gen_mov_tl(t, mxu_gpr[reg - 1]);
    475     }
    476 }
    477 
    478 static inline void gen_store_mxu_gpr(TCGv t, unsigned int reg)
    479 {
    480     if (reg > 0 && reg <= 15) {
    481         tcg_gen_mov_tl(mxu_gpr[reg - 1], t);
    482     }
    483 }
    484 
    485 /* MXU control register moves. */
    486 static inline void gen_load_mxu_cr(TCGv t)
    487 {
    488     tcg_gen_mov_tl(t, mxu_CR);
    489 }
    490 
    491 static inline void gen_store_mxu_cr(TCGv t)
    492 {
    493     /* TODO: Add handling of RW rules for MXU_CR. */
    494     tcg_gen_mov_tl(mxu_CR, t);
    495 }
    496 
    497 /*
    498  * S32I2M XRa, rb - Register move from GRF to XRF
    499  */
    500 static void gen_mxu_s32i2m(DisasContext *ctx)
    501 {
    502     TCGv t0;
    503     uint32_t XRa, Rb;
    504 
    505     t0 = tcg_temp_new();
    506 
    507     XRa = extract32(ctx->opcode, 6, 5);
    508     Rb = extract32(ctx->opcode, 16, 5);
    509 
    510     gen_load_gpr(t0, Rb);
    511     if (XRa <= 15) {
    512         gen_store_mxu_gpr(t0, XRa);
    513     } else if (XRa == 16) {
    514         gen_store_mxu_cr(t0);
    515     }
    516 
    517     tcg_temp_free(t0);
    518 }
    519 
    520 /*
    521  * S32M2I XRa, rb - Register move from XRF to GRF
    522  */
    523 static void gen_mxu_s32m2i(DisasContext *ctx)
    524 {
    525     TCGv t0;
    526     uint32_t XRa, Rb;
    527 
    528     t0 = tcg_temp_new();
    529 
    530     XRa = extract32(ctx->opcode, 6, 5);
    531     Rb = extract32(ctx->opcode, 16, 5);
    532 
    533     if (XRa <= 15) {
    534         gen_load_mxu_gpr(t0, XRa);
    535     } else if (XRa == 16) {
    536         gen_load_mxu_cr(t0);
    537     }
    538 
    539     gen_store_gpr(t0, Rb);
    540 
    541     tcg_temp_free(t0);
    542 }
    543 
    544 /*
    545  * S8LDD XRa, Rb, s8, optn3 - Load a byte from memory to XRF
    546  */
    547 static void gen_mxu_s8ldd(DisasContext *ctx)
    548 {
    549     TCGv t0, t1;
    550     uint32_t XRa, Rb, s8, optn3;
    551 
    552     t0 = tcg_temp_new();
    553     t1 = tcg_temp_new();
    554 
    555     XRa = extract32(ctx->opcode, 6, 4);
    556     s8 = extract32(ctx->opcode, 10, 8);
    557     optn3 = extract32(ctx->opcode, 18, 3);
    558     Rb = extract32(ctx->opcode, 21, 5);
    559 
    560     gen_load_gpr(t0, Rb);
    561     tcg_gen_addi_tl(t0, t0, (int8_t)s8);
    562 
    563     switch (optn3) {
    564     /* XRa[7:0] = tmp8 */
    565     case MXU_OPTN3_PTN0:
    566         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
    567         gen_load_mxu_gpr(t0, XRa);
    568         tcg_gen_deposit_tl(t0, t0, t1, 0, 8);
    569         break;
    570     /* XRa[15:8] = tmp8 */
    571     case MXU_OPTN3_PTN1:
    572         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
    573         gen_load_mxu_gpr(t0, XRa);
    574         tcg_gen_deposit_tl(t0, t0, t1, 8, 8);
    575         break;
    576     /* XRa[23:16] = tmp8 */
    577     case MXU_OPTN3_PTN2:
    578         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
    579         gen_load_mxu_gpr(t0, XRa);
    580         tcg_gen_deposit_tl(t0, t0, t1, 16, 8);
    581         break;
    582     /* XRa[31:24] = tmp8 */
    583     case MXU_OPTN3_PTN3:
    584         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
    585         gen_load_mxu_gpr(t0, XRa);
    586         tcg_gen_deposit_tl(t0, t0, t1, 24, 8);
    587         break;
    588     /* XRa = {8'b0, tmp8, 8'b0, tmp8} */
    589     case MXU_OPTN3_PTN4:
    590         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
    591         tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
    592         break;
    593     /* XRa = {tmp8, 8'b0, tmp8, 8'b0} */
    594     case MXU_OPTN3_PTN5:
    595         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
    596         tcg_gen_shli_tl(t1, t1, 8);
    597         tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
    598         break;
    599     /* XRa = {{8{sign of tmp8}}, tmp8, {8{sign of tmp8}}, tmp8} */
    600     case MXU_OPTN3_PTN6:
    601         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_SB);
    602         tcg_gen_mov_tl(t0, t1);
    603         tcg_gen_andi_tl(t0, t0, 0xFF00FFFF);
    604         tcg_gen_shli_tl(t1, t1, 16);
    605         tcg_gen_or_tl(t0, t0, t1);
    606         break;
    607     /* XRa = {tmp8, tmp8, tmp8, tmp8} */
    608     case MXU_OPTN3_PTN7:
    609         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
    610         tcg_gen_deposit_tl(t1, t1, t1, 8, 8);
    611         tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
    612         break;
    613     }
    614 
    615     gen_store_mxu_gpr(t0, XRa);
    616 
    617     tcg_temp_free(t0);
    618     tcg_temp_free(t1);
    619 }
    620 
    621 /*
    622  * D16MUL XRa, XRb, XRc, XRd, optn2 - Signed 16 bit pattern multiplication
    623  */
    624 static void gen_mxu_d16mul(DisasContext *ctx)
    625 {
    626     TCGv t0, t1, t2, t3;
    627     uint32_t XRa, XRb, XRc, XRd, optn2;
    628 
    629     t0 = tcg_temp_new();
    630     t1 = tcg_temp_new();
    631     t2 = tcg_temp_new();
    632     t3 = tcg_temp_new();
    633 
    634     XRa = extract32(ctx->opcode, 6, 4);
    635     XRb = extract32(ctx->opcode, 10, 4);
    636     XRc = extract32(ctx->opcode, 14, 4);
    637     XRd = extract32(ctx->opcode, 18, 4);
    638     optn2 = extract32(ctx->opcode, 22, 2);
    639 
    640     gen_load_mxu_gpr(t1, XRb);
    641     tcg_gen_sextract_tl(t0, t1, 0, 16);
    642     tcg_gen_sextract_tl(t1, t1, 16, 16);
    643     gen_load_mxu_gpr(t3, XRc);
    644     tcg_gen_sextract_tl(t2, t3, 0, 16);
    645     tcg_gen_sextract_tl(t3, t3, 16, 16);
    646 
    647     switch (optn2) {
    648     case MXU_OPTN2_WW: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
    649         tcg_gen_mul_tl(t3, t1, t3);
    650         tcg_gen_mul_tl(t2, t0, t2);
    651         break;
    652     case MXU_OPTN2_LW: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
    653         tcg_gen_mul_tl(t3, t0, t3);
    654         tcg_gen_mul_tl(t2, t0, t2);
    655         break;
    656     case MXU_OPTN2_HW: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
    657         tcg_gen_mul_tl(t3, t1, t3);
    658         tcg_gen_mul_tl(t2, t1, t2);
    659         break;
    660     case MXU_OPTN2_XW: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
    661         tcg_gen_mul_tl(t3, t0, t3);
    662         tcg_gen_mul_tl(t2, t1, t2);
    663         break;
    664     }
    665     gen_store_mxu_gpr(t3, XRa);
    666     gen_store_mxu_gpr(t2, XRd);
    667 
    668     tcg_temp_free(t0);
    669     tcg_temp_free(t1);
    670     tcg_temp_free(t2);
    671     tcg_temp_free(t3);
    672 }
    673 
    674 /*
    675  * D16MAC XRa, XRb, XRc, XRd, aptn2, optn2 - Signed 16 bit pattern multiply
    676  *                                           and accumulate
    677  */
    678 static void gen_mxu_d16mac(DisasContext *ctx)
    679 {
    680     TCGv t0, t1, t2, t3;
    681     uint32_t XRa, XRb, XRc, XRd, optn2, aptn2;
    682 
    683     t0 = tcg_temp_new();
    684     t1 = tcg_temp_new();
    685     t2 = tcg_temp_new();
    686     t3 = tcg_temp_new();
    687 
    688     XRa = extract32(ctx->opcode, 6, 4);
    689     XRb = extract32(ctx->opcode, 10, 4);
    690     XRc = extract32(ctx->opcode, 14, 4);
    691     XRd = extract32(ctx->opcode, 18, 4);
    692     optn2 = extract32(ctx->opcode, 22, 2);
    693     aptn2 = extract32(ctx->opcode, 24, 2);
    694 
    695     gen_load_mxu_gpr(t1, XRb);
    696     tcg_gen_sextract_tl(t0, t1, 0, 16);
    697     tcg_gen_sextract_tl(t1, t1, 16, 16);
    698 
    699     gen_load_mxu_gpr(t3, XRc);
    700     tcg_gen_sextract_tl(t2, t3, 0, 16);
    701     tcg_gen_sextract_tl(t3, t3, 16, 16);
    702 
    703     switch (optn2) {
    704     case MXU_OPTN2_WW: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
    705         tcg_gen_mul_tl(t3, t1, t3);
    706         tcg_gen_mul_tl(t2, t0, t2);
    707         break;
    708     case MXU_OPTN2_LW: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
    709         tcg_gen_mul_tl(t3, t0, t3);
    710         tcg_gen_mul_tl(t2, t0, t2);
    711         break;
    712     case MXU_OPTN2_HW: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
    713         tcg_gen_mul_tl(t3, t1, t3);
    714         tcg_gen_mul_tl(t2, t1, t2);
    715         break;
    716     case MXU_OPTN2_XW: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
    717         tcg_gen_mul_tl(t3, t0, t3);
    718         tcg_gen_mul_tl(t2, t1, t2);
    719         break;
    720     }
    721     gen_load_mxu_gpr(t0, XRa);
    722     gen_load_mxu_gpr(t1, XRd);
    723 
    724     switch (aptn2) {
    725     case MXU_APTN2_AA:
    726         tcg_gen_add_tl(t3, t0, t3);
    727         tcg_gen_add_tl(t2, t1, t2);
    728         break;
    729     case MXU_APTN2_AS:
    730         tcg_gen_add_tl(t3, t0, t3);
    731         tcg_gen_sub_tl(t2, t1, t2);
    732         break;
    733     case MXU_APTN2_SA:
    734         tcg_gen_sub_tl(t3, t0, t3);
    735         tcg_gen_add_tl(t2, t1, t2);
    736         break;
    737     case MXU_APTN2_SS:
    738         tcg_gen_sub_tl(t3, t0, t3);
    739         tcg_gen_sub_tl(t2, t1, t2);
    740         break;
    741     }
    742     gen_store_mxu_gpr(t3, XRa);
    743     gen_store_mxu_gpr(t2, XRd);
    744 
    745     tcg_temp_free(t0);
    746     tcg_temp_free(t1);
    747     tcg_temp_free(t2);
    748     tcg_temp_free(t3);
    749 }
    750 
    751 /*
    752  * Q8MUL   XRa, XRb, XRc, XRd - Parallel unsigned 8 bit pattern multiply
    753  * Q8MULSU XRa, XRb, XRc, XRd - Parallel signed 8 bit pattern multiply
    754  */
    755 static void gen_mxu_q8mul_q8mulsu(DisasContext *ctx)
    756 {
    757     TCGv t0, t1, t2, t3, t4, t5, t6, t7;
    758     uint32_t XRa, XRb, XRc, XRd, sel;
    759 
    760     t0 = tcg_temp_new();
    761     t1 = tcg_temp_new();
    762     t2 = tcg_temp_new();
    763     t3 = tcg_temp_new();
    764     t4 = tcg_temp_new();
    765     t5 = tcg_temp_new();
    766     t6 = tcg_temp_new();
    767     t7 = tcg_temp_new();
    768 
    769     XRa = extract32(ctx->opcode, 6, 4);
    770     XRb = extract32(ctx->opcode, 10, 4);
    771     XRc = extract32(ctx->opcode, 14, 4);
    772     XRd = extract32(ctx->opcode, 18, 4);
    773     sel = extract32(ctx->opcode, 22, 2);
    774 
    775     gen_load_mxu_gpr(t3, XRb);
    776     gen_load_mxu_gpr(t7, XRc);
    777 
    778     if (sel == 0x2) {
    779         /* Q8MULSU */
    780         tcg_gen_ext8s_tl(t0, t3);
    781         tcg_gen_shri_tl(t3, t3, 8);
    782         tcg_gen_ext8s_tl(t1, t3);
    783         tcg_gen_shri_tl(t3, t3, 8);
    784         tcg_gen_ext8s_tl(t2, t3);
    785         tcg_gen_shri_tl(t3, t3, 8);
    786         tcg_gen_ext8s_tl(t3, t3);
    787     } else {
    788         /* Q8MUL */
    789         tcg_gen_ext8u_tl(t0, t3);
    790         tcg_gen_shri_tl(t3, t3, 8);
    791         tcg_gen_ext8u_tl(t1, t3);
    792         tcg_gen_shri_tl(t3, t3, 8);
    793         tcg_gen_ext8u_tl(t2, t3);
    794         tcg_gen_shri_tl(t3, t3, 8);
    795         tcg_gen_ext8u_tl(t3, t3);
    796     }
    797 
    798     tcg_gen_ext8u_tl(t4, t7);
    799     tcg_gen_shri_tl(t7, t7, 8);
    800     tcg_gen_ext8u_tl(t5, t7);
    801     tcg_gen_shri_tl(t7, t7, 8);
    802     tcg_gen_ext8u_tl(t6, t7);
    803     tcg_gen_shri_tl(t7, t7, 8);
    804     tcg_gen_ext8u_tl(t7, t7);
    805 
    806     tcg_gen_mul_tl(t0, t0, t4);
    807     tcg_gen_mul_tl(t1, t1, t5);
    808     tcg_gen_mul_tl(t2, t2, t6);
    809     tcg_gen_mul_tl(t3, t3, t7);
    810 
    811     tcg_gen_andi_tl(t0, t0, 0xFFFF);
    812     tcg_gen_andi_tl(t1, t1, 0xFFFF);
    813     tcg_gen_andi_tl(t2, t2, 0xFFFF);
    814     tcg_gen_andi_tl(t3, t3, 0xFFFF);
    815 
    816     tcg_gen_shli_tl(t1, t1, 16);
    817     tcg_gen_shli_tl(t3, t3, 16);
    818 
    819     tcg_gen_or_tl(t0, t0, t1);
    820     tcg_gen_or_tl(t1, t2, t3);
    821 
    822     gen_store_mxu_gpr(t0, XRd);
    823     gen_store_mxu_gpr(t1, XRa);
    824 
    825     tcg_temp_free(t0);
    826     tcg_temp_free(t1);
    827     tcg_temp_free(t2);
    828     tcg_temp_free(t3);
    829     tcg_temp_free(t4);
    830     tcg_temp_free(t5);
    831     tcg_temp_free(t6);
    832     tcg_temp_free(t7);
    833 }
    834 
    835 /*
    836  * S32LDD  XRa, Rb, S12 - Load a word from memory to XRF
    837  * S32LDDR XRa, Rb, S12 - Load a word from memory to XRF, reversed byte seq.
    838  */
    839 static void gen_mxu_s32ldd_s32lddr(DisasContext *ctx)
    840 {
    841     TCGv t0, t1;
    842     uint32_t XRa, Rb, s12, sel;
    843 
    844     t0 = tcg_temp_new();
    845     t1 = tcg_temp_new();
    846 
    847     XRa = extract32(ctx->opcode, 6, 4);
    848     s12 = extract32(ctx->opcode, 10, 10);
    849     sel = extract32(ctx->opcode, 20, 1);
    850     Rb = extract32(ctx->opcode, 21, 5);
    851 
    852     gen_load_gpr(t0, Rb);
    853 
    854     tcg_gen_movi_tl(t1, s12);
    855     tcg_gen_shli_tl(t1, t1, 2);
    856     if (s12 & 0x200) {
    857         tcg_gen_ori_tl(t1, t1, 0xFFFFF000);
    858     }
    859     tcg_gen_add_tl(t1, t0, t1);
    860     tcg_gen_qemu_ld_tl(t1, t1, ctx->mem_idx, MO_TESL ^ (sel * MO_BSWAP));
    861 
    862     gen_store_mxu_gpr(t1, XRa);
    863 
    864     tcg_temp_free(t0);
    865     tcg_temp_free(t1);
    866 }
    867 
    868 
    869 /*
    870  *                 MXU instruction category: logic
    871  *                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    872  *
    873  *               S32NOR    S32AND    S32OR    S32XOR
    874  */
    875 
    876 /*
    877  *  S32NOR XRa, XRb, XRc
    878  *    Update XRa with the result of logical bitwise 'nor' operation
    879  *    applied to the content of XRb and XRc.
    880  */
    881 static void gen_mxu_S32NOR(DisasContext *ctx)
    882 {
    883     uint32_t pad, XRc, XRb, XRa;
    884 
    885     pad = extract32(ctx->opcode, 21, 5);
    886     XRc = extract32(ctx->opcode, 14, 4);
    887     XRb = extract32(ctx->opcode, 10, 4);
    888     XRa = extract32(ctx->opcode,  6, 4);
    889 
    890     if (unlikely(pad != 0)) {
    891         /* opcode padding incorrect -> do nothing */
    892     } else if (unlikely(XRa == 0)) {
    893         /* destination is zero register -> do nothing */
    894     } else if (unlikely((XRb == 0) && (XRc == 0))) {
    895         /* both operands zero registers -> just set destination to all 1s */
    896         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0xFFFFFFFF);
    897     } else if (unlikely(XRb == 0)) {
    898         /* XRb zero register -> just set destination to the negation of XRc */
    899         tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
    900     } else if (unlikely(XRc == 0)) {
    901         /* XRa zero register -> just set destination to the negation of XRb */
    902         tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
    903     } else if (unlikely(XRb == XRc)) {
    904         /* both operands same -> just set destination to the negation of XRb */
    905         tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
    906     } else {
    907         /* the most general case */
    908         tcg_gen_nor_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
    909     }
    910 }
    911 
    912 /*
    913  *  S32AND XRa, XRb, XRc
    914  *    Update XRa with the result of logical bitwise 'and' operation
    915  *    applied to the content of XRb and XRc.
    916  */
    917 static void gen_mxu_S32AND(DisasContext *ctx)
    918 {
    919     uint32_t pad, XRc, XRb, XRa;
    920 
    921     pad = extract32(ctx->opcode, 21, 5);
    922     XRc = extract32(ctx->opcode, 14, 4);
    923     XRb = extract32(ctx->opcode, 10, 4);
    924     XRa = extract32(ctx->opcode,  6, 4);
    925 
    926     if (unlikely(pad != 0)) {
    927         /* opcode padding incorrect -> do nothing */
    928     } else if (unlikely(XRa == 0)) {
    929         /* destination is zero register -> do nothing */
    930     } else if (unlikely((XRb == 0) || (XRc == 0))) {
    931         /* one of operands zero register -> just set destination to all 0s */
    932         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
    933     } else if (unlikely(XRb == XRc)) {
    934         /* both operands same -> just set destination to one of them */
    935         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
    936     } else {
    937         /* the most general case */
    938         tcg_gen_and_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
    939     }
    940 }
    941 
    942 /*
    943  *  S32OR XRa, XRb, XRc
    944  *    Update XRa with the result of logical bitwise 'or' operation
    945  *    applied to the content of XRb and XRc.
    946  */
    947 static void gen_mxu_S32OR(DisasContext *ctx)
    948 {
    949     uint32_t pad, XRc, XRb, XRa;
    950 
    951     pad = extract32(ctx->opcode, 21, 5);
    952     XRc = extract32(ctx->opcode, 14, 4);
    953     XRb = extract32(ctx->opcode, 10, 4);
    954     XRa = extract32(ctx->opcode,  6, 4);
    955 
    956     if (unlikely(pad != 0)) {
    957         /* opcode padding incorrect -> do nothing */
    958     } else if (unlikely(XRa == 0)) {
    959         /* destination is zero register -> do nothing */
    960     } else if (unlikely((XRb == 0) && (XRc == 0))) {
    961         /* both operands zero registers -> just set destination to all 0s */
    962         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
    963     } else if (unlikely(XRb == 0)) {
    964         /* XRb zero register -> just set destination to the content of XRc */
    965         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
    966     } else if (unlikely(XRc == 0)) {
    967         /* XRc zero register -> just set destination to the content of XRb */
    968         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
    969     } else if (unlikely(XRb == XRc)) {
    970         /* both operands same -> just set destination to one of them */
    971         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
    972     } else {
    973         /* the most general case */
    974         tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
    975     }
    976 }
    977 
    978 /*
    979  *  S32XOR XRa, XRb, XRc
    980  *    Update XRa with the result of logical bitwise 'xor' operation
    981  *    applied to the content of XRb and XRc.
    982  */
    983 static void gen_mxu_S32XOR(DisasContext *ctx)
    984 {
    985     uint32_t pad, XRc, XRb, XRa;
    986 
    987     pad = extract32(ctx->opcode, 21, 5);
    988     XRc = extract32(ctx->opcode, 14, 4);
    989     XRb = extract32(ctx->opcode, 10, 4);
    990     XRa = extract32(ctx->opcode,  6, 4);
    991 
    992     if (unlikely(pad != 0)) {
    993         /* opcode padding incorrect -> do nothing */
    994     } else if (unlikely(XRa == 0)) {
    995         /* destination is zero register -> do nothing */
    996     } else if (unlikely((XRb == 0) && (XRc == 0))) {
    997         /* both operands zero registers -> just set destination to all 0s */
    998         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
    999     } else if (unlikely(XRb == 0)) {
   1000         /* XRb zero register -> just set destination to the content of XRc */
   1001         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
   1002     } else if (unlikely(XRc == 0)) {
   1003         /* XRc zero register -> just set destination to the content of XRb */
   1004         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
   1005     } else if (unlikely(XRb == XRc)) {
   1006         /* both operands same -> just set destination to all 0s */
   1007         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
   1008     } else {
   1009         /* the most general case */
   1010         tcg_gen_xor_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
   1011     }
   1012 }
   1013 
   1014 
   1015 /*
   1016  *                   MXU instruction category max/min
   1017  *                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1018  *
   1019  *                     S32MAX     D16MAX     Q8MAX
   1020  *                     S32MIN     D16MIN     Q8MIN
   1021  */
   1022 
   1023 /*
   1024  *  S32MAX XRa, XRb, XRc
   1025  *    Update XRa with the maximum of signed 32-bit integers contained
   1026  *    in XRb and XRc.
   1027  *
   1028  *  S32MIN XRa, XRb, XRc
   1029  *    Update XRa with the minimum of signed 32-bit integers contained
   1030  *    in XRb and XRc.
   1031  */
   1032 static void gen_mxu_S32MAX_S32MIN(DisasContext *ctx)
   1033 {
   1034     uint32_t pad, opc, XRc, XRb, XRa;
   1035 
   1036     pad = extract32(ctx->opcode, 21, 5);
   1037     opc = extract32(ctx->opcode, 18, 3);
   1038     XRc = extract32(ctx->opcode, 14, 4);
   1039     XRb = extract32(ctx->opcode, 10, 4);
   1040     XRa = extract32(ctx->opcode,  6, 4);
   1041 
   1042     if (unlikely(pad != 0)) {
   1043         /* opcode padding incorrect -> do nothing */
   1044     } else if (unlikely(XRa == 0)) {
   1045         /* destination is zero register -> do nothing */
   1046     } else if (unlikely((XRb == 0) && (XRc == 0))) {
   1047         /* both operands zero registers -> just set destination to zero */
   1048         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
   1049     } else if (unlikely((XRb == 0) || (XRc == 0))) {
   1050         /* exactly one operand is zero register - find which one is not...*/
   1051         uint32_t XRx = XRb ? XRb : XRc;
   1052         /* ...and do max/min operation with one operand 0 */
   1053         if (opc == OPC_MXU_S32MAX) {
   1054             tcg_gen_smax_i32(mxu_gpr[XRa - 1], mxu_gpr[XRx - 1], 0);
   1055         } else {
   1056             tcg_gen_smin_i32(mxu_gpr[XRa - 1], mxu_gpr[XRx - 1], 0);
   1057         }
   1058     } else if (unlikely(XRb == XRc)) {
   1059         /* both operands same -> just set destination to one of them */
   1060         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
   1061     } else {
   1062         /* the most general case */
   1063         if (opc == OPC_MXU_S32MAX) {
   1064             tcg_gen_smax_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1],
   1065                                                mxu_gpr[XRc - 1]);
   1066         } else {
   1067             tcg_gen_smin_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1],
   1068                                                mxu_gpr[XRc - 1]);
   1069         }
   1070     }
   1071 }
   1072 
   1073 /*
   1074  *  D16MAX
   1075  *    Update XRa with the 16-bit-wise maximums of signed integers
   1076  *    contained in XRb and XRc.
   1077  *
   1078  *  D16MIN
   1079  *    Update XRa with the 16-bit-wise minimums of signed integers
   1080  *    contained in XRb and XRc.
   1081  */
   1082 static void gen_mxu_D16MAX_D16MIN(DisasContext *ctx)
   1083 {
   1084     uint32_t pad, opc, XRc, XRb, XRa;
   1085 
   1086     pad = extract32(ctx->opcode, 21, 5);
   1087     opc = extract32(ctx->opcode, 18, 3);
   1088     XRc = extract32(ctx->opcode, 14, 4);
   1089     XRb = extract32(ctx->opcode, 10, 4);
   1090     XRa = extract32(ctx->opcode,  6, 4);
   1091 
   1092     if (unlikely(pad != 0)) {
   1093         /* opcode padding incorrect -> do nothing */
   1094     } else if (unlikely(XRa == 0)) {
   1095         /* destination is zero register -> do nothing */
   1096     } else if (unlikely((XRb == 0) && (XRc == 0))) {
   1097         /* both operands zero registers -> just set destination to zero */
   1098         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
   1099     } else if (unlikely((XRb == 0) || (XRc == 0))) {
   1100         /* exactly one operand is zero register - find which one is not...*/
   1101         uint32_t XRx = XRb ? XRb : XRc;
   1102         /* ...and do half-word-wise max/min with one operand 0 */
   1103         TCGv_i32 t0 = tcg_temp_new();
   1104         TCGv_i32 t1 = tcg_const_i32(0);
   1105 
   1106         /* the left half-word first */
   1107         tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFFFF0000);
   1108         if (opc == OPC_MXU_D16MAX) {
   1109             tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
   1110         } else {
   1111             tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
   1112         }
   1113 
   1114         /* the right half-word */
   1115         tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0x0000FFFF);
   1116         /* move half-words to the leftmost position */
   1117         tcg_gen_shli_i32(t0, t0, 16);
   1118         /* t0 will be max/min of t0 and t1 */
   1119         if (opc == OPC_MXU_D16MAX) {
   1120             tcg_gen_smax_i32(t0, t0, t1);
   1121         } else {
   1122             tcg_gen_smin_i32(t0, t0, t1);
   1123         }
   1124         /* return resulting half-words to its original position */
   1125         tcg_gen_shri_i32(t0, t0, 16);
   1126         /* finally update the destination */
   1127         tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
   1128 
   1129         tcg_temp_free(t1);
   1130         tcg_temp_free(t0);
   1131     } else if (unlikely(XRb == XRc)) {
   1132         /* both operands same -> just set destination to one of them */
   1133         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
   1134     } else {
   1135         /* the most general case */
   1136         TCGv_i32 t0 = tcg_temp_new();
   1137         TCGv_i32 t1 = tcg_temp_new();
   1138 
   1139         /* the left half-word first */
   1140         tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFFFF0000);
   1141         tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFF0000);
   1142         if (opc == OPC_MXU_D16MAX) {
   1143             tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
   1144         } else {
   1145             tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
   1146         }
   1147 
   1148         /* the right half-word */
   1149         tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x0000FFFF);
   1150         tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0x0000FFFF);
   1151         /* move half-words to the leftmost position */
   1152         tcg_gen_shli_i32(t0, t0, 16);
   1153         tcg_gen_shli_i32(t1, t1, 16);
   1154         /* t0 will be max/min of t0 and t1 */
   1155         if (opc == OPC_MXU_D16MAX) {
   1156             tcg_gen_smax_i32(t0, t0, t1);
   1157         } else {
   1158             tcg_gen_smin_i32(t0, t0, t1);
   1159         }
   1160         /* return resulting half-words to its original position */
   1161         tcg_gen_shri_i32(t0, t0, 16);
   1162         /* finally update the destination */
   1163         tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
   1164 
   1165         tcg_temp_free(t1);
   1166         tcg_temp_free(t0);
   1167     }
   1168 }
   1169 
   1170 /*
   1171  *  Q8MAX
   1172  *    Update XRa with the 8-bit-wise maximums of signed integers
   1173  *    contained in XRb and XRc.
   1174  *
   1175  *  Q8MIN
   1176  *    Update XRa with the 8-bit-wise minimums of signed integers
   1177  *    contained in XRb and XRc.
   1178  */
   1179 static void gen_mxu_Q8MAX_Q8MIN(DisasContext *ctx)
   1180 {
   1181     uint32_t pad, opc, XRc, XRb, XRa;
   1182 
   1183     pad = extract32(ctx->opcode, 21, 5);
   1184     opc = extract32(ctx->opcode, 18, 3);
   1185     XRc = extract32(ctx->opcode, 14, 4);
   1186     XRb = extract32(ctx->opcode, 10, 4);
   1187     XRa = extract32(ctx->opcode,  6, 4);
   1188 
   1189     if (unlikely(pad != 0)) {
   1190         /* opcode padding incorrect -> do nothing */
   1191     } else if (unlikely(XRa == 0)) {
   1192         /* destination is zero register -> do nothing */
   1193     } else if (unlikely((XRb == 0) && (XRc == 0))) {
   1194         /* both operands zero registers -> just set destination to zero */
   1195         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
   1196     } else if (unlikely((XRb == 0) || (XRc == 0))) {
   1197         /* exactly one operand is zero register - make it be the first...*/
   1198         uint32_t XRx = XRb ? XRb : XRc;
   1199         /* ...and do byte-wise max/min with one operand 0 */
   1200         TCGv_i32 t0 = tcg_temp_new();
   1201         TCGv_i32 t1 = tcg_const_i32(0);
   1202         int32_t i;
   1203 
   1204         /* the leftmost byte (byte 3) first */
   1205         tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFF000000);
   1206         if (opc == OPC_MXU_Q8MAX) {
   1207             tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
   1208         } else {
   1209             tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
   1210         }
   1211 
   1212         /* bytes 2, 1, 0 */
   1213         for (i = 2; i >= 0; i--) {
   1214             /* extract the byte */
   1215             tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFF << (8 * i));
   1216             /* move the byte to the leftmost position */
   1217             tcg_gen_shli_i32(t0, t0, 8 * (3 - i));
   1218             /* t0 will be max/min of t0 and t1 */
   1219             if (opc == OPC_MXU_Q8MAX) {
   1220                 tcg_gen_smax_i32(t0, t0, t1);
   1221             } else {
   1222                 tcg_gen_smin_i32(t0, t0, t1);
   1223             }
   1224             /* return resulting byte to its original position */
   1225             tcg_gen_shri_i32(t0, t0, 8 * (3 - i));
   1226             /* finally update the destination */
   1227             tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
   1228         }
   1229 
   1230         tcg_temp_free(t1);
   1231         tcg_temp_free(t0);
   1232     } else if (unlikely(XRb == XRc)) {
   1233         /* both operands same -> just set destination to one of them */
   1234         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
   1235     } else {
   1236         /* the most general case */
   1237         TCGv_i32 t0 = tcg_temp_new();
   1238         TCGv_i32 t1 = tcg_temp_new();
   1239         int32_t i;
   1240 
   1241         /* the leftmost bytes (bytes 3) first */
   1242         tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFF000000);
   1243         tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF000000);
   1244         if (opc == OPC_MXU_Q8MAX) {
   1245             tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
   1246         } else {
   1247             tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
   1248         }
   1249 
   1250         /* bytes 2, 1, 0 */
   1251         for (i = 2; i >= 0; i--) {
   1252             /* extract corresponding bytes */
   1253             tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFF << (8 * i));
   1254             tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF << (8 * i));
   1255             /* move the bytes to the leftmost position */
   1256             tcg_gen_shli_i32(t0, t0, 8 * (3 - i));
   1257             tcg_gen_shli_i32(t1, t1, 8 * (3 - i));
   1258             /* t0 will be max/min of t0 and t1 */
   1259             if (opc == OPC_MXU_Q8MAX) {
   1260                 tcg_gen_smax_i32(t0, t0, t1);
   1261             } else {
   1262                 tcg_gen_smin_i32(t0, t0, t1);
   1263             }
   1264             /* return resulting byte to its original position */
   1265             tcg_gen_shri_i32(t0, t0, 8 * (3 - i));
   1266             /* finally update the destination */
   1267             tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
   1268         }
   1269 
   1270         tcg_temp_free(t1);
   1271         tcg_temp_free(t0);
   1272     }
   1273 }
   1274 
   1275 
   1276 /*
   1277  *                 MXU instruction category: align
   1278  *                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1279  *
   1280  *                       S32ALN     S32ALNI
   1281  */
   1282 
   1283 /*
   1284  *  S32ALNI XRc, XRb, XRa, optn3
   1285  *    Arrange bytes from XRb and XRc according to one of five sets of
   1286  *    rules determined by optn3, and place the result in XRa.
   1287  */
   1288 static void gen_mxu_S32ALNI(DisasContext *ctx)
   1289 {
   1290     uint32_t optn3, pad, XRc, XRb, XRa;
   1291 
   1292     optn3 = extract32(ctx->opcode,  23, 3);
   1293     pad   = extract32(ctx->opcode,  21, 2);
   1294     XRc   = extract32(ctx->opcode, 14, 4);
   1295     XRb   = extract32(ctx->opcode, 10, 4);
   1296     XRa   = extract32(ctx->opcode,  6, 4);
   1297 
   1298     if (unlikely(pad != 0)) {
   1299         /* opcode padding incorrect -> do nothing */
   1300     } else if (unlikely(XRa == 0)) {
   1301         /* destination is zero register -> do nothing */
   1302     } else if (unlikely((XRb == 0) && (XRc == 0))) {
   1303         /* both operands zero registers -> just set destination to all 0s */
   1304         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
   1305     } else if (unlikely(XRb == 0)) {
   1306         /* XRb zero register -> just appropriatelly shift XRc into XRa */
   1307         switch (optn3) {
   1308         case MXU_OPTN3_PTN0:
   1309             tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
   1310             break;
   1311         case MXU_OPTN3_PTN1:
   1312         case MXU_OPTN3_PTN2:
   1313         case MXU_OPTN3_PTN3:
   1314             tcg_gen_shri_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1],
   1315                              8 * (4 - optn3));
   1316             break;
   1317         case MXU_OPTN3_PTN4:
   1318             tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
   1319             break;
   1320         }
   1321     } else if (unlikely(XRc == 0)) {
   1322         /* XRc zero register -> just appropriatelly shift XRb into XRa */
   1323         switch (optn3) {
   1324         case MXU_OPTN3_PTN0:
   1325             tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
   1326             break;
   1327         case MXU_OPTN3_PTN1:
   1328         case MXU_OPTN3_PTN2:
   1329         case MXU_OPTN3_PTN3:
   1330             tcg_gen_shri_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], 8 * optn3);
   1331             break;
   1332         case MXU_OPTN3_PTN4:
   1333             tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
   1334             break;
   1335         }
   1336     } else if (unlikely(XRb == XRc)) {
   1337         /* both operands same -> just rotation or moving from any of them */
   1338         switch (optn3) {
   1339         case MXU_OPTN3_PTN0:
   1340         case MXU_OPTN3_PTN4:
   1341             tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
   1342             break;
   1343         case MXU_OPTN3_PTN1:
   1344         case MXU_OPTN3_PTN2:
   1345         case MXU_OPTN3_PTN3:
   1346             tcg_gen_rotli_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], 8 * optn3);
   1347             break;
   1348         }
   1349     } else {
   1350         /* the most general case */
   1351         switch (optn3) {
   1352         case MXU_OPTN3_PTN0:
   1353             {
   1354                 /*                                         */
   1355                 /*         XRb                XRc          */
   1356                 /*  +---------------+                      */
   1357                 /*  | A   B   C   D |    E   F   G   H     */
   1358                 /*  +-------+-------+                      */
   1359                 /*          |                              */
   1360                 /*         XRa                             */
   1361                 /*                                         */
   1362 
   1363                 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
   1364             }
   1365             break;
   1366         case MXU_OPTN3_PTN1:
   1367             {
   1368                 /*                                         */
   1369                 /*         XRb                 XRc         */
   1370                 /*      +-------------------+              */
   1371                 /*    A | B   C   D       E | F   G   H    */
   1372                 /*      +---------+---------+              */
   1373                 /*                |                        */
   1374                 /*               XRa                       */
   1375                 /*                                         */
   1376 
   1377                 TCGv_i32 t0 = tcg_temp_new();
   1378                 TCGv_i32 t1 = tcg_temp_new();
   1379 
   1380                 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x00FFFFFF);
   1381                 tcg_gen_shli_i32(t0, t0, 8);
   1382 
   1383                 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF000000);
   1384                 tcg_gen_shri_i32(t1, t1, 24);
   1385 
   1386                 tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
   1387 
   1388                 tcg_temp_free(t1);
   1389                 tcg_temp_free(t0);
   1390             }
   1391             break;
   1392         case MXU_OPTN3_PTN2:
   1393             {
   1394                 /*                                         */
   1395                 /*         XRb                 XRc         */
   1396                 /*          +-------------------+          */
   1397                 /*    A   B | C   D       E   F | G   H    */
   1398                 /*          +---------+---------+          */
   1399                 /*                    |                    */
   1400                 /*                   XRa                   */
   1401                 /*                                         */
   1402 
   1403                 TCGv_i32 t0 = tcg_temp_new();
   1404                 TCGv_i32 t1 = tcg_temp_new();
   1405 
   1406                 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x0000FFFF);
   1407                 tcg_gen_shli_i32(t0, t0, 16);
   1408 
   1409                 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFF0000);
   1410                 tcg_gen_shri_i32(t1, t1, 16);
   1411 
   1412                 tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
   1413 
   1414                 tcg_temp_free(t1);
   1415                 tcg_temp_free(t0);
   1416             }
   1417             break;
   1418         case MXU_OPTN3_PTN3:
   1419             {
   1420                 /*                                         */
   1421                 /*         XRb                 XRc         */
   1422                 /*              +-------------------+      */
   1423                 /*    A   B   C | D       E   F   G | H    */
   1424                 /*              +---------+---------+      */
   1425                 /*                        |                */
   1426                 /*                       XRa               */
   1427                 /*                                         */
   1428 
   1429                 TCGv_i32 t0 = tcg_temp_new();
   1430                 TCGv_i32 t1 = tcg_temp_new();
   1431 
   1432                 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x000000FF);
   1433                 tcg_gen_shli_i32(t0, t0, 24);
   1434 
   1435                 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFFFF00);
   1436                 tcg_gen_shri_i32(t1, t1, 8);
   1437 
   1438                 tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
   1439 
   1440                 tcg_temp_free(t1);
   1441                 tcg_temp_free(t0);
   1442             }
   1443             break;
   1444         case MXU_OPTN3_PTN4:
   1445             {
   1446                 /*                                         */
   1447                 /*         XRb                 XRc         */
   1448                 /*                     +---------------+   */
   1449                 /*    A   B   C   D    | E   F   G   H |   */
   1450                 /*                     +-------+-------+   */
   1451                 /*                             |           */
   1452                 /*                            XRa          */
   1453                 /*                                         */
   1454 
   1455                 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
   1456             }
   1457             break;
   1458         }
   1459     }
   1460 }
   1461 
   1462 
   1463 /*
   1464  * Decoding engine for MXU
   1465  * =======================
   1466  */
   1467 
   1468 static void decode_opc_mxu__pool00(DisasContext *ctx)
   1469 {
   1470     uint32_t opcode = extract32(ctx->opcode, 18, 3);
   1471 
   1472     switch (opcode) {
   1473     case OPC_MXU_S32MAX:
   1474     case OPC_MXU_S32MIN:
   1475         gen_mxu_S32MAX_S32MIN(ctx);
   1476         break;
   1477     case OPC_MXU_D16MAX:
   1478     case OPC_MXU_D16MIN:
   1479         gen_mxu_D16MAX_D16MIN(ctx);
   1480         break;
   1481     case OPC_MXU_Q8MAX:
   1482     case OPC_MXU_Q8MIN:
   1483         gen_mxu_Q8MAX_Q8MIN(ctx);
   1484         break;
   1485     default:
   1486         MIPS_INVAL("decode_opc_mxu");
   1487         gen_reserved_instruction(ctx);
   1488         break;
   1489     }
   1490 }
   1491 
   1492 static void decode_opc_mxu__pool04(DisasContext *ctx)
   1493 {
   1494     uint32_t opcode = extract32(ctx->opcode, 20, 1);
   1495 
   1496     switch (opcode) {
   1497     case OPC_MXU_S32LDD:
   1498     case OPC_MXU_S32LDDR:
   1499         gen_mxu_s32ldd_s32lddr(ctx);
   1500         break;
   1501     default:
   1502         MIPS_INVAL("decode_opc_mxu");
   1503         gen_reserved_instruction(ctx);
   1504         break;
   1505     }
   1506 }
   1507 
   1508 static void decode_opc_mxu__pool16(DisasContext *ctx)
   1509 {
   1510     uint32_t opcode = extract32(ctx->opcode, 18, 3);
   1511 
   1512     switch (opcode) {
   1513     case OPC_MXU_S32ALNI:
   1514         gen_mxu_S32ALNI(ctx);
   1515         break;
   1516     case OPC_MXU_S32NOR:
   1517         gen_mxu_S32NOR(ctx);
   1518         break;
   1519     case OPC_MXU_S32AND:
   1520         gen_mxu_S32AND(ctx);
   1521         break;
   1522     case OPC_MXU_S32OR:
   1523         gen_mxu_S32OR(ctx);
   1524         break;
   1525     case OPC_MXU_S32XOR:
   1526         gen_mxu_S32XOR(ctx);
   1527         break;
   1528     default:
   1529         MIPS_INVAL("decode_opc_mxu");
   1530         gen_reserved_instruction(ctx);
   1531         break;
   1532     }
   1533 }
   1534 
   1535 static void decode_opc_mxu__pool19(DisasContext *ctx)
   1536 {
   1537     uint32_t opcode = extract32(ctx->opcode, 22, 2);
   1538 
   1539     switch (opcode) {
   1540     case OPC_MXU_Q8MUL:
   1541     case OPC_MXU_Q8MULSU:
   1542         gen_mxu_q8mul_q8mulsu(ctx);
   1543         break;
   1544     default:
   1545         MIPS_INVAL("decode_opc_mxu");
   1546         gen_reserved_instruction(ctx);
   1547         break;
   1548     }
   1549 }
   1550 
   1551 bool decode_ase_mxu(DisasContext *ctx, uint32_t insn)
   1552 {
   1553     uint32_t opcode = extract32(insn, 0, 6);
   1554 
   1555     if (opcode == OPC_MXU_S32M2I) {
   1556         gen_mxu_s32m2i(ctx);
   1557         return true;
   1558     }
   1559 
   1560     if (opcode == OPC_MXU_S32I2M) {
   1561         gen_mxu_s32i2m(ctx);
   1562         return true;
   1563     }
   1564 
   1565     {
   1566         TCGv t_mxu_cr = tcg_temp_new();
   1567         TCGLabel *l_exit = gen_new_label();
   1568 
   1569         gen_load_mxu_cr(t_mxu_cr);
   1570         tcg_gen_andi_tl(t_mxu_cr, t_mxu_cr, MXU_CR_MXU_EN);
   1571         tcg_gen_brcondi_tl(TCG_COND_NE, t_mxu_cr, MXU_CR_MXU_EN, l_exit);
   1572 
   1573         switch (opcode) {
   1574         case OPC_MXU__POOL00:
   1575             decode_opc_mxu__pool00(ctx);
   1576             break;
   1577         case OPC_MXU_D16MUL:
   1578             gen_mxu_d16mul(ctx);
   1579             break;
   1580         case OPC_MXU_D16MAC:
   1581             gen_mxu_d16mac(ctx);
   1582             break;
   1583         case OPC_MXU__POOL04:
   1584             decode_opc_mxu__pool04(ctx);
   1585             break;
   1586         case OPC_MXU_S8LDD:
   1587             gen_mxu_s8ldd(ctx);
   1588             break;
   1589         case OPC_MXU__POOL16:
   1590             decode_opc_mxu__pool16(ctx);
   1591             break;
   1592         case OPC_MXU__POOL19:
   1593             decode_opc_mxu__pool19(ctx);
   1594             break;
   1595         default:
   1596             MIPS_INVAL("decode_opc_mxu");
   1597             gen_reserved_instruction(ctx);
   1598         }
   1599 
   1600         gen_set_label(l_exit);
   1601         tcg_temp_free(t_mxu_cr);
   1602     }
   1603 
   1604     return true;
   1605 }