qemu/target/mips/tcg/mxu_translate.c
<<
>>
Prefs
   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
 518/*
 519 * S32M2I XRa, rb - Register move from XRF to GRF
 520 */
 521static void gen_mxu_s32m2i(DisasContext *ctx)
 522{
 523    TCGv t0;
 524    uint32_t XRa, Rb;
 525
 526    t0 = tcg_temp_new();
 527
 528    XRa = extract32(ctx->opcode, 6, 5);
 529    Rb = extract32(ctx->opcode, 16, 5);
 530
 531    if (XRa <= 15) {
 532        gen_load_mxu_gpr(t0, XRa);
 533    } else if (XRa == 16) {
 534        gen_load_mxu_cr(t0);
 535    }
 536
 537    gen_store_gpr(t0, Rb);
 538}
 539
 540/*
 541 * S8LDD XRa, Rb, s8, optn3 - Load a byte from memory to XRF
 542 */
 543static void gen_mxu_s8ldd(DisasContext *ctx)
 544{
 545    TCGv t0, t1;
 546    uint32_t XRa, Rb, s8, optn3;
 547
 548    t0 = tcg_temp_new();
 549    t1 = tcg_temp_new();
 550
 551    XRa = extract32(ctx->opcode, 6, 4);
 552    s8 = extract32(ctx->opcode, 10, 8);
 553    optn3 = extract32(ctx->opcode, 18, 3);
 554    Rb = extract32(ctx->opcode, 21, 5);
 555
 556    gen_load_gpr(t0, Rb);
 557    tcg_gen_addi_tl(t0, t0, (int8_t)s8);
 558
 559    switch (optn3) {
 560    /* XRa[7:0] = tmp8 */
 561    case MXU_OPTN3_PTN0:
 562        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
 563        gen_load_mxu_gpr(t0, XRa);
 564        tcg_gen_deposit_tl(t0, t0, t1, 0, 8);
 565        break;
 566    /* XRa[15:8] = tmp8 */
 567    case MXU_OPTN3_PTN1:
 568        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
 569        gen_load_mxu_gpr(t0, XRa);
 570        tcg_gen_deposit_tl(t0, t0, t1, 8, 8);
 571        break;
 572    /* XRa[23:16] = tmp8 */
 573    case MXU_OPTN3_PTN2:
 574        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
 575        gen_load_mxu_gpr(t0, XRa);
 576        tcg_gen_deposit_tl(t0, t0, t1, 16, 8);
 577        break;
 578    /* XRa[31:24] = tmp8 */
 579    case MXU_OPTN3_PTN3:
 580        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
 581        gen_load_mxu_gpr(t0, XRa);
 582        tcg_gen_deposit_tl(t0, t0, t1, 24, 8);
 583        break;
 584    /* XRa = {8'b0, tmp8, 8'b0, tmp8} */
 585    case MXU_OPTN3_PTN4:
 586        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
 587        tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
 588        break;
 589    /* XRa = {tmp8, 8'b0, tmp8, 8'b0} */
 590    case MXU_OPTN3_PTN5:
 591        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
 592        tcg_gen_shli_tl(t1, t1, 8);
 593        tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
 594        break;
 595    /* XRa = {{8{sign of tmp8}}, tmp8, {8{sign of tmp8}}, tmp8} */
 596    case MXU_OPTN3_PTN6:
 597        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_SB);
 598        tcg_gen_mov_tl(t0, t1);
 599        tcg_gen_andi_tl(t0, t0, 0xFF00FFFF);
 600        tcg_gen_shli_tl(t1, t1, 16);
 601        tcg_gen_or_tl(t0, t0, t1);
 602        break;
 603    /* XRa = {tmp8, tmp8, tmp8, tmp8} */
 604    case MXU_OPTN3_PTN7:
 605        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
 606        tcg_gen_deposit_tl(t1, t1, t1, 8, 8);
 607        tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
 608        break;
 609    }
 610
 611    gen_store_mxu_gpr(t0, XRa);
 612}
 613
 614/*
 615 * D16MUL XRa, XRb, XRc, XRd, optn2 - Signed 16 bit pattern multiplication
 616 */
 617static void gen_mxu_d16mul(DisasContext *ctx)
 618{
 619    TCGv t0, t1, t2, t3;
 620    uint32_t XRa, XRb, XRc, XRd, optn2;
 621
 622    t0 = tcg_temp_new();
 623    t1 = tcg_temp_new();
 624    t2 = tcg_temp_new();
 625    t3 = tcg_temp_new();
 626
 627    XRa = extract32(ctx->opcode, 6, 4);
 628    XRb = extract32(ctx->opcode, 10, 4);
 629    XRc = extract32(ctx->opcode, 14, 4);
 630    XRd = extract32(ctx->opcode, 18, 4);
 631    optn2 = extract32(ctx->opcode, 22, 2);
 632
 633    gen_load_mxu_gpr(t1, XRb);
 634    tcg_gen_sextract_tl(t0, t1, 0, 16);
 635    tcg_gen_sextract_tl(t1, t1, 16, 16);
 636    gen_load_mxu_gpr(t3, XRc);
 637    tcg_gen_sextract_tl(t2, t3, 0, 16);
 638    tcg_gen_sextract_tl(t3, t3, 16, 16);
 639
 640    switch (optn2) {
 641    case MXU_OPTN2_WW: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
 642        tcg_gen_mul_tl(t3, t1, t3);
 643        tcg_gen_mul_tl(t2, t0, t2);
 644        break;
 645    case MXU_OPTN2_LW: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
 646        tcg_gen_mul_tl(t3, t0, t3);
 647        tcg_gen_mul_tl(t2, t0, t2);
 648        break;
 649    case MXU_OPTN2_HW: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
 650        tcg_gen_mul_tl(t3, t1, t3);
 651        tcg_gen_mul_tl(t2, t1, t2);
 652        break;
 653    case MXU_OPTN2_XW: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
 654        tcg_gen_mul_tl(t3, t0, t3);
 655        tcg_gen_mul_tl(t2, t1, t2);
 656        break;
 657    }
 658    gen_store_mxu_gpr(t3, XRa);
 659    gen_store_mxu_gpr(t2, XRd);
 660}
 661
 662/*
 663 * D16MAC XRa, XRb, XRc, XRd, aptn2, optn2 - Signed 16 bit pattern multiply
 664 *                                           and accumulate
 665 */
 666static void gen_mxu_d16mac(DisasContext *ctx)
 667{
 668    TCGv t0, t1, t2, t3;
 669    uint32_t XRa, XRb, XRc, XRd, optn2, aptn2;
 670
 671    t0 = tcg_temp_new();
 672    t1 = tcg_temp_new();
 673    t2 = tcg_temp_new();
 674    t3 = tcg_temp_new();
 675
 676    XRa = extract32(ctx->opcode, 6, 4);
 677    XRb = extract32(ctx->opcode, 10, 4);
 678    XRc = extract32(ctx->opcode, 14, 4);
 679    XRd = extract32(ctx->opcode, 18, 4);
 680    optn2 = extract32(ctx->opcode, 22, 2);
 681    aptn2 = extract32(ctx->opcode, 24, 2);
 682
 683    gen_load_mxu_gpr(t1, XRb);
 684    tcg_gen_sextract_tl(t0, t1, 0, 16);
 685    tcg_gen_sextract_tl(t1, t1, 16, 16);
 686
 687    gen_load_mxu_gpr(t3, XRc);
 688    tcg_gen_sextract_tl(t2, t3, 0, 16);
 689    tcg_gen_sextract_tl(t3, t3, 16, 16);
 690
 691    switch (optn2) {
 692    case MXU_OPTN2_WW: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
 693        tcg_gen_mul_tl(t3, t1, t3);
 694        tcg_gen_mul_tl(t2, t0, t2);
 695        break;
 696    case MXU_OPTN2_LW: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
 697        tcg_gen_mul_tl(t3, t0, t3);
 698        tcg_gen_mul_tl(t2, t0, t2);
 699        break;
 700    case MXU_OPTN2_HW: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
 701        tcg_gen_mul_tl(t3, t1, t3);
 702        tcg_gen_mul_tl(t2, t1, t2);
 703        break;
 704    case MXU_OPTN2_XW: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
 705        tcg_gen_mul_tl(t3, t0, t3);
 706        tcg_gen_mul_tl(t2, t1, t2);
 707        break;
 708    }
 709    gen_load_mxu_gpr(t0, XRa);
 710    gen_load_mxu_gpr(t1, XRd);
 711
 712    switch (aptn2) {
 713    case MXU_APTN2_AA:
 714        tcg_gen_add_tl(t3, t0, t3);
 715        tcg_gen_add_tl(t2, t1, t2);
 716        break;
 717    case MXU_APTN2_AS:
 718        tcg_gen_add_tl(t3, t0, t3);
 719        tcg_gen_sub_tl(t2, t1, t2);
 720        break;
 721    case MXU_APTN2_SA:
 722        tcg_gen_sub_tl(t3, t0, t3);
 723        tcg_gen_add_tl(t2, t1, t2);
 724        break;
 725    case MXU_APTN2_SS:
 726        tcg_gen_sub_tl(t3, t0, t3);
 727        tcg_gen_sub_tl(t2, t1, t2);
 728        break;
 729    }
 730    gen_store_mxu_gpr(t3, XRa);
 731    gen_store_mxu_gpr(t2, XRd);
 732}
 733
 734/*
 735 * Q8MUL   XRa, XRb, XRc, XRd - Parallel unsigned 8 bit pattern multiply
 736 * Q8MULSU XRa, XRb, XRc, XRd - Parallel signed 8 bit pattern multiply
 737 */
 738static void gen_mxu_q8mul_q8mulsu(DisasContext *ctx)
 739{
 740    TCGv t0, t1, t2, t3, t4, t5, t6, t7;
 741    uint32_t XRa, XRb, XRc, XRd, sel;
 742
 743    t0 = tcg_temp_new();
 744    t1 = tcg_temp_new();
 745    t2 = tcg_temp_new();
 746    t3 = tcg_temp_new();
 747    t4 = tcg_temp_new();
 748    t5 = tcg_temp_new();
 749    t6 = tcg_temp_new();
 750    t7 = tcg_temp_new();
 751
 752    XRa = extract32(ctx->opcode, 6, 4);
 753    XRb = extract32(ctx->opcode, 10, 4);
 754    XRc = extract32(ctx->opcode, 14, 4);
 755    XRd = extract32(ctx->opcode, 18, 4);
 756    sel = extract32(ctx->opcode, 22, 2);
 757
 758    gen_load_mxu_gpr(t3, XRb);
 759    gen_load_mxu_gpr(t7, XRc);
 760
 761    if (sel == 0x2) {
 762        /* Q8MULSU */
 763        tcg_gen_ext8s_tl(t0, t3);
 764        tcg_gen_shri_tl(t3, t3, 8);
 765        tcg_gen_ext8s_tl(t1, t3);
 766        tcg_gen_shri_tl(t3, t3, 8);
 767        tcg_gen_ext8s_tl(t2, t3);
 768        tcg_gen_shri_tl(t3, t3, 8);
 769        tcg_gen_ext8s_tl(t3, t3);
 770    } else {
 771        /* Q8MUL */
 772        tcg_gen_ext8u_tl(t0, t3);
 773        tcg_gen_shri_tl(t3, t3, 8);
 774        tcg_gen_ext8u_tl(t1, t3);
 775        tcg_gen_shri_tl(t3, t3, 8);
 776        tcg_gen_ext8u_tl(t2, t3);
 777        tcg_gen_shri_tl(t3, t3, 8);
 778        tcg_gen_ext8u_tl(t3, t3);
 779    }
 780
 781    tcg_gen_ext8u_tl(t4, t7);
 782    tcg_gen_shri_tl(t7, t7, 8);
 783    tcg_gen_ext8u_tl(t5, t7);
 784    tcg_gen_shri_tl(t7, t7, 8);
 785    tcg_gen_ext8u_tl(t6, t7);
 786    tcg_gen_shri_tl(t7, t7, 8);
 787    tcg_gen_ext8u_tl(t7, t7);
 788
 789    tcg_gen_mul_tl(t0, t0, t4);
 790    tcg_gen_mul_tl(t1, t1, t5);
 791    tcg_gen_mul_tl(t2, t2, t6);
 792    tcg_gen_mul_tl(t3, t3, t7);
 793
 794    tcg_gen_andi_tl(t0, t0, 0xFFFF);
 795    tcg_gen_andi_tl(t1, t1, 0xFFFF);
 796    tcg_gen_andi_tl(t2, t2, 0xFFFF);
 797    tcg_gen_andi_tl(t3, t3, 0xFFFF);
 798
 799    tcg_gen_shli_tl(t1, t1, 16);
 800    tcg_gen_shli_tl(t3, t3, 16);
 801
 802    tcg_gen_or_tl(t0, t0, t1);
 803    tcg_gen_or_tl(t1, t2, t3);
 804
 805    gen_store_mxu_gpr(t0, XRd);
 806    gen_store_mxu_gpr(t1, XRa);
 807}
 808
 809/*
 810 * S32LDD  XRa, Rb, S12 - Load a word from memory to XRF
 811 * S32LDDR XRa, Rb, S12 - Load a word from memory to XRF, reversed byte seq.
 812 */
 813static void gen_mxu_s32ldd_s32lddr(DisasContext *ctx)
 814{
 815    TCGv t0, t1;
 816    uint32_t XRa, Rb, s12, sel;
 817
 818    t0 = tcg_temp_new();
 819    t1 = tcg_temp_new();
 820
 821    XRa = extract32(ctx->opcode, 6, 4);
 822    s12 = extract32(ctx->opcode, 10, 10);
 823    sel = extract32(ctx->opcode, 20, 1);
 824    Rb = extract32(ctx->opcode, 21, 5);
 825
 826    gen_load_gpr(t0, Rb);
 827
 828    tcg_gen_movi_tl(t1, s12);
 829    tcg_gen_shli_tl(t1, t1, 2);
 830    if (s12 & 0x200) {
 831        tcg_gen_ori_tl(t1, t1, 0xFFFFF000);
 832    }
 833    tcg_gen_add_tl(t1, t0, t1);
 834    tcg_gen_qemu_ld_tl(t1, t1, ctx->mem_idx, MO_TESL ^ (sel * MO_BSWAP));
 835
 836    gen_store_mxu_gpr(t1, XRa);
 837}
 838
 839
 840/*
 841 *                 MXU instruction category: logic
 842 *                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 843 *
 844 *               S32NOR    S32AND    S32OR    S32XOR
 845 */
 846
 847/*
 848 *  S32NOR XRa, XRb, XRc
 849 *    Update XRa with the result of logical bitwise 'nor' operation
 850 *    applied to the content of XRb and XRc.
 851 */
 852static void gen_mxu_S32NOR(DisasContext *ctx)
 853{
 854    uint32_t pad, XRc, XRb, XRa;
 855
 856    pad = extract32(ctx->opcode, 21, 5);
 857    XRc = extract32(ctx->opcode, 14, 4);
 858    XRb = extract32(ctx->opcode, 10, 4);
 859    XRa = extract32(ctx->opcode,  6, 4);
 860
 861    if (unlikely(pad != 0)) {
 862        /* opcode padding incorrect -> do nothing */
 863    } else if (unlikely(XRa == 0)) {
 864        /* destination is zero register -> do nothing */
 865    } else if (unlikely((XRb == 0) && (XRc == 0))) {
 866        /* both operands zero registers -> just set destination to all 1s */
 867        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0xFFFFFFFF);
 868    } else if (unlikely(XRb == 0)) {
 869        /* XRb zero register -> just set destination to the negation of XRc */
 870        tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
 871    } else if (unlikely(XRc == 0)) {
 872        /* XRa zero register -> just set destination to the negation of XRb */
 873        tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
 874    } else if (unlikely(XRb == XRc)) {
 875        /* both operands same -> just set destination to the negation of XRb */
 876        tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
 877    } else {
 878        /* the most general case */
 879        tcg_gen_nor_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
 880    }
 881}
 882
 883/*
 884 *  S32AND XRa, XRb, XRc
 885 *    Update XRa with the result of logical bitwise 'and' operation
 886 *    applied to the content of XRb and XRc.
 887 */
 888static void gen_mxu_S32AND(DisasContext *ctx)
 889{
 890    uint32_t pad, XRc, XRb, XRa;
 891
 892    pad = extract32(ctx->opcode, 21, 5);
 893    XRc = extract32(ctx->opcode, 14, 4);
 894    XRb = extract32(ctx->opcode, 10, 4);
 895    XRa = extract32(ctx->opcode,  6, 4);
 896
 897    if (unlikely(pad != 0)) {
 898        /* opcode padding incorrect -> do nothing */
 899    } else if (unlikely(XRa == 0)) {
 900        /* destination is zero register -> do nothing */
 901    } else if (unlikely((XRb == 0) || (XRc == 0))) {
 902        /* one of operands zero register -> just set destination to all 0s */
 903        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
 904    } else if (unlikely(XRb == XRc)) {
 905        /* both operands same -> just set destination to one of them */
 906        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
 907    } else {
 908        /* the most general case */
 909        tcg_gen_and_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
 910    }
 911}
 912
 913/*
 914 *  S32OR XRa, XRb, XRc
 915 *    Update XRa with the result of logical bitwise 'or' operation
 916 *    applied to the content of XRb and XRc.
 917 */
 918static void gen_mxu_S32OR(DisasContext *ctx)
 919{
 920    uint32_t pad, XRc, XRb, XRa;
 921
 922    pad = extract32(ctx->opcode, 21, 5);
 923    XRc = extract32(ctx->opcode, 14, 4);
 924    XRb = extract32(ctx->opcode, 10, 4);
 925    XRa = extract32(ctx->opcode,  6, 4);
 926
 927    if (unlikely(pad != 0)) {
 928        /* opcode padding incorrect -> do nothing */
 929    } else if (unlikely(XRa == 0)) {
 930        /* destination is zero register -> do nothing */
 931    } else if (unlikely((XRb == 0) && (XRc == 0))) {
 932        /* both operands zero registers -> just set destination to all 0s */
 933        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
 934    } else if (unlikely(XRb == 0)) {
 935        /* XRb zero register -> just set destination to the content of XRc */
 936        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
 937    } else if (unlikely(XRc == 0)) {
 938        /* XRc zero register -> just set destination to the content of XRb */
 939        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
 940    } else if (unlikely(XRb == XRc)) {
 941        /* both operands same -> just set destination to one of them */
 942        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
 943    } else {
 944        /* the most general case */
 945        tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
 946    }
 947}
 948
 949/*
 950 *  S32XOR XRa, XRb, XRc
 951 *    Update XRa with the result of logical bitwise 'xor' operation
 952 *    applied to the content of XRb and XRc.
 953 */
 954static void gen_mxu_S32XOR(DisasContext *ctx)
 955{
 956    uint32_t pad, XRc, XRb, XRa;
 957
 958    pad = extract32(ctx->opcode, 21, 5);
 959    XRc = extract32(ctx->opcode, 14, 4);
 960    XRb = extract32(ctx->opcode, 10, 4);
 961    XRa = extract32(ctx->opcode,  6, 4);
 962
 963    if (unlikely(pad != 0)) {
 964        /* opcode padding incorrect -> do nothing */
 965    } else if (unlikely(XRa == 0)) {
 966        /* destination is zero register -> do nothing */
 967    } else if (unlikely((XRb == 0) && (XRc == 0))) {
 968        /* both operands zero registers -> just set destination to all 0s */
 969        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
 970    } else if (unlikely(XRb == 0)) {
 971        /* XRb zero register -> just set destination to the content of XRc */
 972        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
 973    } else if (unlikely(XRc == 0)) {
 974        /* XRc zero register -> just set destination to the content of XRb */
 975        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
 976    } else if (unlikely(XRb == XRc)) {
 977        /* both operands same -> just set destination to all 0s */
 978        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
 979    } else {
 980        /* the most general case */
 981        tcg_gen_xor_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
 982    }
 983}
 984
 985
 986/*
 987 *                   MXU instruction category max/min
 988 *                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 989 *
 990 *                     S32MAX     D16MAX     Q8MAX
 991 *                     S32MIN     D16MIN     Q8MIN
 992 */
 993
 994/*
 995 *  S32MAX XRa, XRb, XRc
 996 *    Update XRa with the maximum of signed 32-bit integers contained
 997 *    in XRb and XRc.
 998 *
 999 *  S32MIN XRa, XRb, XRc
1000 *    Update XRa with the minimum of signed 32-bit integers contained
1001 *    in XRb and XRc.
1002 */
1003static void gen_mxu_S32MAX_S32MIN(DisasContext *ctx)
1004{
1005    uint32_t pad, opc, XRc, XRb, XRa;
1006
1007    pad = extract32(ctx->opcode, 21, 5);
1008    opc = extract32(ctx->opcode, 18, 3);
1009    XRc = extract32(ctx->opcode, 14, 4);
1010    XRb = extract32(ctx->opcode, 10, 4);
1011    XRa = extract32(ctx->opcode,  6, 4);
1012
1013    if (unlikely(pad != 0)) {
1014        /* opcode padding incorrect -> do nothing */
1015    } else if (unlikely(XRa == 0)) {
1016        /* destination is zero register -> do nothing */
1017    } else if (unlikely((XRb == 0) && (XRc == 0))) {
1018        /* both operands zero registers -> just set destination to zero */
1019        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
1020    } else if (unlikely((XRb == 0) || (XRc == 0))) {
1021        /* exactly one operand is zero register - find which one is not...*/
1022        uint32_t XRx = XRb ? XRb : XRc;
1023        /* ...and do max/min operation with one operand 0 */
1024        if (opc == OPC_MXU_S32MAX) {
1025            tcg_gen_smax_i32(mxu_gpr[XRa - 1], mxu_gpr[XRx - 1], 0);
1026        } else {
1027            tcg_gen_smin_i32(mxu_gpr[XRa - 1], mxu_gpr[XRx - 1], 0);
1028        }
1029    } else if (unlikely(XRb == XRc)) {
1030        /* both operands same -> just set destination to one of them */
1031        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
1032    } else {
1033        /* the most general case */
1034        if (opc == OPC_MXU_S32MAX) {
1035            tcg_gen_smax_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1],
1036                                               mxu_gpr[XRc - 1]);
1037        } else {
1038            tcg_gen_smin_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1],
1039                                               mxu_gpr[XRc - 1]);
1040        }
1041    }
1042}
1043
1044/*
1045 *  D16MAX
1046 *    Update XRa with the 16-bit-wise maximums of signed integers
1047 *    contained in XRb and XRc.
1048 *
1049 *  D16MIN
1050 *    Update XRa with the 16-bit-wise minimums of signed integers
1051 *    contained in XRb and XRc.
1052 */
1053static void gen_mxu_D16MAX_D16MIN(DisasContext *ctx)
1054{
1055    uint32_t pad, opc, XRc, XRb, XRa;
1056
1057    pad = extract32(ctx->opcode, 21, 5);
1058    opc = extract32(ctx->opcode, 18, 3);
1059    XRc = extract32(ctx->opcode, 14, 4);
1060    XRb = extract32(ctx->opcode, 10, 4);
1061    XRa = extract32(ctx->opcode,  6, 4);
1062
1063    if (unlikely(pad != 0)) {
1064        /* opcode padding incorrect -> do nothing */
1065    } else if (unlikely(XRa == 0)) {
1066        /* destination is zero register -> do nothing */
1067    } else if (unlikely((XRb == 0) && (XRc == 0))) {
1068        /* both operands zero registers -> just set destination to zero */
1069        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
1070    } else if (unlikely((XRb == 0) || (XRc == 0))) {
1071        /* exactly one operand is zero register - find which one is not...*/
1072        uint32_t XRx = XRb ? XRb : XRc;
1073        /* ...and do half-word-wise max/min with one operand 0 */
1074        TCGv_i32 t0 = tcg_temp_new();
1075        TCGv_i32 t1 = tcg_constant_i32(0);
1076
1077        /* the left half-word first */
1078        tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFFFF0000);
1079        if (opc == OPC_MXU_D16MAX) {
1080            tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
1081        } else {
1082            tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
1083        }
1084
1085        /* the right half-word */
1086        tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0x0000FFFF);
1087        /* move half-words to the leftmost position */
1088        tcg_gen_shli_i32(t0, t0, 16);
1089        /* t0 will be max/min of t0 and t1 */
1090        if (opc == OPC_MXU_D16MAX) {
1091            tcg_gen_smax_i32(t0, t0, t1);
1092        } else {
1093            tcg_gen_smin_i32(t0, t0, t1);
1094        }
1095        /* return resulting half-words to its original position */
1096        tcg_gen_shri_i32(t0, t0, 16);
1097        /* finally update the destination */
1098        tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
1099    } else if (unlikely(XRb == XRc)) {
1100        /* both operands same -> just set destination to one of them */
1101        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
1102    } else {
1103        /* the most general case */
1104        TCGv_i32 t0 = tcg_temp_new();
1105        TCGv_i32 t1 = tcg_temp_new();
1106
1107        /* the left half-word first */
1108        tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFFFF0000);
1109        tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFF0000);
1110        if (opc == OPC_MXU_D16MAX) {
1111            tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
1112        } else {
1113            tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
1114        }
1115
1116        /* the right half-word */
1117        tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x0000FFFF);
1118        tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0x0000FFFF);
1119        /* move half-words to the leftmost position */
1120        tcg_gen_shli_i32(t0, t0, 16);
1121        tcg_gen_shli_i32(t1, t1, 16);
1122        /* t0 will be max/min of t0 and t1 */
1123        if (opc == OPC_MXU_D16MAX) {
1124            tcg_gen_smax_i32(t0, t0, t1);
1125        } else {
1126            tcg_gen_smin_i32(t0, t0, t1);
1127        }
1128        /* return resulting half-words to its original position */
1129        tcg_gen_shri_i32(t0, t0, 16);
1130        /* finally update the destination */
1131        tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
1132    }
1133}
1134
1135/*
1136 *  Q8MAX
1137 *    Update XRa with the 8-bit-wise maximums of signed integers
1138 *    contained in XRb and XRc.
1139 *
1140 *  Q8MIN
1141 *    Update XRa with the 8-bit-wise minimums of signed integers
1142 *    contained in XRb and XRc.
1143 */
1144static void gen_mxu_Q8MAX_Q8MIN(DisasContext *ctx)
1145{
1146    uint32_t pad, opc, XRc, XRb, XRa;
1147
1148    pad = extract32(ctx->opcode, 21, 5);
1149    opc = extract32(ctx->opcode, 18, 3);
1150    XRc = extract32(ctx->opcode, 14, 4);
1151    XRb = extract32(ctx->opcode, 10, 4);
1152    XRa = extract32(ctx->opcode,  6, 4);
1153
1154    if (unlikely(pad != 0)) {
1155        /* opcode padding incorrect -> do nothing */
1156    } else if (unlikely(XRa == 0)) {
1157        /* destination is zero register -> do nothing */
1158    } else if (unlikely((XRb == 0) && (XRc == 0))) {
1159        /* both operands zero registers -> just set destination to zero */
1160        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
1161    } else if (unlikely((XRb == 0) || (XRc == 0))) {
1162        /* exactly one operand is zero register - make it be the first...*/
1163        uint32_t XRx = XRb ? XRb : XRc;
1164        /* ...and do byte-wise max/min with one operand 0 */
1165        TCGv_i32 t0 = tcg_temp_new();
1166        TCGv_i32 t1 = tcg_constant_i32(0);
1167        int32_t i;
1168
1169        /* the leftmost byte (byte 3) first */
1170        tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFF000000);
1171        if (opc == OPC_MXU_Q8MAX) {
1172            tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
1173        } else {
1174            tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
1175        }
1176
1177        /* bytes 2, 1, 0 */
1178        for (i = 2; i >= 0; i--) {
1179            /* extract the byte */
1180            tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFF << (8 * i));
1181            /* move the byte to the leftmost position */
1182            tcg_gen_shli_i32(t0, t0, 8 * (3 - i));
1183            /* t0 will be max/min of t0 and t1 */
1184            if (opc == OPC_MXU_Q8MAX) {
1185                tcg_gen_smax_i32(t0, t0, t1);
1186            } else {
1187                tcg_gen_smin_i32(t0, t0, t1);
1188            }
1189            /* return resulting byte to its original position */
1190            tcg_gen_shri_i32(t0, t0, 8 * (3 - i));
1191            /* finally update the destination */
1192            tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
1193        }
1194    } else if (unlikely(XRb == XRc)) {
1195        /* both operands same -> just set destination to one of them */
1196        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
1197    } else {
1198        /* the most general case */
1199        TCGv_i32 t0 = tcg_temp_new();
1200        TCGv_i32 t1 = tcg_temp_new();
1201        int32_t i;
1202
1203        /* the leftmost bytes (bytes 3) first */
1204        tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFF000000);
1205        tcg_gen_andi_i32(t1, mxu_gpr[XRc - 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 corresponding bytes */
1215            tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFF << (8 * i));
1216            tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF << (8 * i));
1217            /* move the bytes to the leftmost position */
1218            tcg_gen_shli_i32(t0, t0, 8 * (3 - i));
1219            tcg_gen_shli_i32(t1, t1, 8 * (3 - i));
1220            /* t0 will be max/min of t0 and t1 */
1221            if (opc == OPC_MXU_Q8MAX) {
1222                tcg_gen_smax_i32(t0, t0, t1);
1223            } else {
1224                tcg_gen_smin_i32(t0, t0, t1);
1225            }
1226            /* return resulting byte to its original position */
1227            tcg_gen_shri_i32(t0, t0, 8 * (3 - i));
1228            /* finally update the destination */
1229            tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
1230        }
1231    }
1232}
1233
1234
1235/*
1236 *                 MXU instruction category: align
1237 *                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1238 *
1239 *                       S32ALN     S32ALNI
1240 */
1241
1242/*
1243 *  S32ALNI XRc, XRb, XRa, optn3
1244 *    Arrange bytes from XRb and XRc according to one of five sets of
1245 *    rules determined by optn3, and place the result in XRa.
1246 */
1247static void gen_mxu_S32ALNI(DisasContext *ctx)
1248{
1249    uint32_t optn3, pad, XRc, XRb, XRa;
1250
1251    optn3 = extract32(ctx->opcode,  23, 3);
1252    pad   = extract32(ctx->opcode,  21, 2);
1253    XRc   = extract32(ctx->opcode, 14, 4);
1254    XRb   = extract32(ctx->opcode, 10, 4);
1255    XRa   = extract32(ctx->opcode,  6, 4);
1256
1257    if (unlikely(pad != 0)) {
1258        /* opcode padding incorrect -> do nothing */
1259    } else if (unlikely(XRa == 0)) {
1260        /* destination is zero register -> do nothing */
1261    } else if (unlikely((XRb == 0) && (XRc == 0))) {
1262        /* both operands zero registers -> just set destination to all 0s */
1263        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
1264    } else if (unlikely(XRb == 0)) {
1265        /* XRb zero register -> just appropriatelly shift XRc into XRa */
1266        switch (optn3) {
1267        case MXU_OPTN3_PTN0:
1268            tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
1269            break;
1270        case MXU_OPTN3_PTN1:
1271        case MXU_OPTN3_PTN2:
1272        case MXU_OPTN3_PTN3:
1273            tcg_gen_shri_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1],
1274                             8 * (4 - optn3));
1275            break;
1276        case MXU_OPTN3_PTN4:
1277            tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
1278            break;
1279        }
1280    } else if (unlikely(XRc == 0)) {
1281        /* XRc zero register -> just appropriatelly shift XRb into XRa */
1282        switch (optn3) {
1283        case MXU_OPTN3_PTN0:
1284            tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
1285            break;
1286        case MXU_OPTN3_PTN1:
1287        case MXU_OPTN3_PTN2:
1288        case MXU_OPTN3_PTN3:
1289            tcg_gen_shri_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], 8 * optn3);
1290            break;
1291        case MXU_OPTN3_PTN4:
1292            tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
1293            break;
1294        }
1295    } else if (unlikely(XRb == XRc)) {
1296        /* both operands same -> just rotation or moving from any of them */
1297        switch (optn3) {
1298        case MXU_OPTN3_PTN0:
1299        case MXU_OPTN3_PTN4:
1300            tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
1301            break;
1302        case MXU_OPTN3_PTN1:
1303        case MXU_OPTN3_PTN2:
1304        case MXU_OPTN3_PTN3:
1305            tcg_gen_rotli_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], 8 * optn3);
1306            break;
1307        }
1308    } else {
1309        /* the most general case */
1310        switch (optn3) {
1311        case MXU_OPTN3_PTN0:
1312            {
1313                /*                                         */
1314                /*         XRb                XRc          */
1315                /*  +---------------+                      */
1316                /*  | A   B   C   D |    E   F   G   H     */
1317                /*  +-------+-------+                      */
1318                /*          |                              */
1319                /*         XRa                             */
1320                /*                                         */
1321
1322                tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
1323            }
1324            break;
1325        case MXU_OPTN3_PTN1:
1326            {
1327                /*                                         */
1328                /*         XRb                 XRc         */
1329                /*      +-------------------+              */
1330                /*    A | B   C   D       E | F   G   H    */
1331                /*      +---------+---------+              */
1332                /*                |                        */
1333                /*               XRa                       */
1334                /*                                         */
1335
1336                TCGv_i32 t0 = tcg_temp_new();
1337                TCGv_i32 t1 = tcg_temp_new();
1338
1339                tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x00FFFFFF);
1340                tcg_gen_shli_i32(t0, t0, 8);
1341
1342                tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF000000);
1343                tcg_gen_shri_i32(t1, t1, 24);
1344
1345                tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
1346            }
1347            break;
1348        case MXU_OPTN3_PTN2:
1349            {
1350                /*                                         */
1351                /*         XRb                 XRc         */
1352                /*          +-------------------+          */
1353                /*    A   B | C   D       E   F | G   H    */
1354                /*          +---------+---------+          */
1355                /*                    |                    */
1356                /*                   XRa                   */
1357                /*                                         */
1358
1359                TCGv_i32 t0 = tcg_temp_new();
1360                TCGv_i32 t1 = tcg_temp_new();
1361
1362                tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x0000FFFF);
1363                tcg_gen_shli_i32(t0, t0, 16);
1364
1365                tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFF0000);
1366                tcg_gen_shri_i32(t1, t1, 16);
1367
1368                tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
1369            }
1370            break;
1371        case MXU_OPTN3_PTN3:
1372            {
1373                /*                                         */
1374                /*         XRb                 XRc         */
1375                /*              +-------------------+      */
1376                /*    A   B   C | D       E   F   G | H    */
1377                /*              +---------+---------+      */
1378                /*                        |                */
1379                /*                       XRa               */
1380                /*                                         */
1381
1382                TCGv_i32 t0 = tcg_temp_new();
1383                TCGv_i32 t1 = tcg_temp_new();
1384
1385                tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x000000FF);
1386                tcg_gen_shli_i32(t0, t0, 24);
1387
1388                tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFFFF00);
1389                tcg_gen_shri_i32(t1, t1, 8);
1390
1391                tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
1392            }
1393            break;
1394        case MXU_OPTN3_PTN4:
1395            {
1396                /*                                         */
1397                /*         XRb                 XRc         */
1398                /*                     +---------------+   */
1399                /*    A   B   C   D    | E   F   G   H |   */
1400                /*                     +-------+-------+   */
1401                /*                             |           */
1402                /*                            XRa          */
1403                /*                                         */
1404
1405                tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
1406            }
1407            break;
1408        }
1409    }
1410}
1411
1412
1413/*
1414 * Decoding engine for MXU
1415 * =======================
1416 */
1417
1418static void decode_opc_mxu__pool00(DisasContext *ctx)
1419{
1420    uint32_t opcode = extract32(ctx->opcode, 18, 3);
1421
1422    switch (opcode) {
1423    case OPC_MXU_S32MAX:
1424    case OPC_MXU_S32MIN:
1425        gen_mxu_S32MAX_S32MIN(ctx);
1426        break;
1427    case OPC_MXU_D16MAX:
1428    case OPC_MXU_D16MIN:
1429        gen_mxu_D16MAX_D16MIN(ctx);
1430        break;
1431    case OPC_MXU_Q8MAX:
1432    case OPC_MXU_Q8MIN:
1433        gen_mxu_Q8MAX_Q8MIN(ctx);
1434        break;
1435    default:
1436        MIPS_INVAL("decode_opc_mxu");
1437        gen_reserved_instruction(ctx);
1438        break;
1439    }
1440}
1441
1442static void decode_opc_mxu__pool04(DisasContext *ctx)
1443{
1444    uint32_t opcode = extract32(ctx->opcode, 20, 1);
1445
1446    switch (opcode) {
1447    case OPC_MXU_S32LDD:
1448    case OPC_MXU_S32LDDR:
1449        gen_mxu_s32ldd_s32lddr(ctx);
1450        break;
1451    default:
1452        MIPS_INVAL("decode_opc_mxu");
1453        gen_reserved_instruction(ctx);
1454        break;
1455    }
1456}
1457
1458static void decode_opc_mxu__pool16(DisasContext *ctx)
1459{
1460    uint32_t opcode = extract32(ctx->opcode, 18, 3);
1461
1462    switch (opcode) {
1463    case OPC_MXU_S32ALNI:
1464        gen_mxu_S32ALNI(ctx);
1465        break;
1466    case OPC_MXU_S32NOR:
1467        gen_mxu_S32NOR(ctx);
1468        break;
1469    case OPC_MXU_S32AND:
1470        gen_mxu_S32AND(ctx);
1471        break;
1472    case OPC_MXU_S32OR:
1473        gen_mxu_S32OR(ctx);
1474        break;
1475    case OPC_MXU_S32XOR:
1476        gen_mxu_S32XOR(ctx);
1477        break;
1478    default:
1479        MIPS_INVAL("decode_opc_mxu");
1480        gen_reserved_instruction(ctx);
1481        break;
1482    }
1483}
1484
1485static void decode_opc_mxu__pool19(DisasContext *ctx)
1486{
1487    uint32_t opcode = extract32(ctx->opcode, 22, 2);
1488
1489    switch (opcode) {
1490    case OPC_MXU_Q8MUL:
1491    case OPC_MXU_Q8MULSU:
1492        gen_mxu_q8mul_q8mulsu(ctx);
1493        break;
1494    default:
1495        MIPS_INVAL("decode_opc_mxu");
1496        gen_reserved_instruction(ctx);
1497        break;
1498    }
1499}
1500
1501bool decode_ase_mxu(DisasContext *ctx, uint32_t insn)
1502{
1503    uint32_t opcode = extract32(insn, 0, 6);
1504
1505    if (opcode == OPC_MXU_S32M2I) {
1506        gen_mxu_s32m2i(ctx);
1507        return true;
1508    }
1509
1510    if (opcode == OPC_MXU_S32I2M) {
1511        gen_mxu_s32i2m(ctx);
1512        return true;
1513    }
1514
1515    {
1516        TCGv t_mxu_cr = tcg_temp_new();
1517        TCGLabel *l_exit = gen_new_label();
1518
1519        gen_load_mxu_cr(t_mxu_cr);
1520        tcg_gen_andi_tl(t_mxu_cr, t_mxu_cr, MXU_CR_MXU_EN);
1521        tcg_gen_brcondi_tl(TCG_COND_NE, t_mxu_cr, MXU_CR_MXU_EN, l_exit);
1522
1523        switch (opcode) {
1524        case OPC_MXU__POOL00:
1525            decode_opc_mxu__pool00(ctx);
1526            break;
1527        case OPC_MXU_D16MUL:
1528            gen_mxu_d16mul(ctx);
1529            break;
1530        case OPC_MXU_D16MAC:
1531            gen_mxu_d16mac(ctx);
1532            break;
1533        case OPC_MXU__POOL04:
1534            decode_opc_mxu__pool04(ctx);
1535            break;
1536        case OPC_MXU_S8LDD:
1537            gen_mxu_s8ldd(ctx);
1538            break;
1539        case OPC_MXU__POOL16:
1540            decode_opc_mxu__pool16(ctx);
1541            break;
1542        case OPC_MXU__POOL19:
1543            decode_opc_mxu__pool19(ctx);
1544            break;
1545        default:
1546            MIPS_INVAL("decode_opc_mxu");
1547            gen_reserved_instruction(ctx);
1548        }
1549
1550        gen_set_label(l_exit);
1551    }
1552
1553    return true;
1554}
1555