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