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    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}
1606