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