cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

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
    357enum {
    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 */
    373enum {
    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 */
    385enum {
    386    OPC_MXU_S32LDD   = 0x00,
    387    OPC_MXU_S32LDDR  = 0x01,
    388};
    389
    390/*
    391 * MXU pool 16
    392 */
    393enum {
    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 */
    404enum {
    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 */
    447static TCGv mxu_gpr[NUMBER_OF_MXU_REGISTERS - 1];
    448static TCGv mxu_CR;
    449
    450static const char mxuregnames[][4] = {
    451    "XR1",  "XR2",  "XR3",  "XR4",  "XR5",  "XR6",  "XR7",  "XR8",
    452    "XR9",  "XR10", "XR11", "XR12", "XR13", "XR14", "XR15", "XCR",
    453};
    454
    455void 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. */
    469static 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
    478static 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. */
    486static inline void gen_load_mxu_cr(TCGv t)
    487{
    488    tcg_gen_mov_tl(t, mxu_CR);
    489}
    490
    491static 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 */
    500static 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 */
    523static 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 */
    547static 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 */
    624static 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 */
    678static 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 */
    755static 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 */
    839static 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 */
    881static 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 */
    917static 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 */
    947static 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 */
    983static 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 */
   1032static 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 */
   1082static 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 */
   1179static 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 */
   1288static 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
   1468static 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
   1492static 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
   1508static 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
   1535static 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
   1551bool 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}