1 /* 2 * MIPS emulation for QEMU - main 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 * Copyright (c) 2020 Philippe Mathieu-Daudé 10 * 11 * This library is free software; you can redistribute it and/or 12 * modify it under the terms of the GNU Lesser General Public 13 * License as published by the Free Software Foundation; either 14 * version 2.1 of the License, or (at your option) any later version. 15 * 16 * This library is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 * Lesser General Public License for more details. 20 * 21 * You should have received a copy of the GNU Lesser General Public 22 * License along with this library; if not, see <http://www.gnu.org/licenses/>. 23 */ 24 25 #include "qemu/osdep.h" 26 #include "cpu.h" 27 #include "internal.h" 28 #include "tcg/tcg-op.h" 29 #include "exec/translator.h" 30 #include "exec/helper-proto.h" 31 #include "exec/helper-gen.h" 32 #include "semihosting/semihost.h" 33 34 #include "trace.h" 35 #include "exec/log.h" 36 #include "qemu/qemu-print.h" 37 #include "fpu_helper.h" 38 #include "translate.h" 39 40 /* 41 * Many sysemu-only helpers are not reachable for user-only. 42 * Define stub generators here, so that we need not either sprinkle 43 * ifdefs through the translator, nor provide the helper function. 44 */ 45 #define STUB_HELPER(NAME, ...) \ 46 static inline void gen_helper_##NAME(__VA_ARGS__) \ 47 { g_assert_not_reached(); } 48 49 #ifdef CONFIG_USER_ONLY 50 STUB_HELPER(cache, TCGv_env env, TCGv val, TCGv_i32 reg) 51 #endif 52 53 enum { 54 /* indirect opcode tables */ 55 OPC_SPECIAL = (0x00 << 26), 56 OPC_REGIMM = (0x01 << 26), 57 OPC_CP0 = (0x10 << 26), 58 OPC_CP2 = (0x12 << 26), 59 OPC_CP3 = (0x13 << 26), 60 OPC_SPECIAL2 = (0x1C << 26), 61 OPC_SPECIAL3 = (0x1F << 26), 62 /* arithmetic with immediate */ 63 OPC_ADDI = (0x08 << 26), 64 OPC_ADDIU = (0x09 << 26), 65 OPC_SLTI = (0x0A << 26), 66 OPC_SLTIU = (0x0B << 26), 67 /* logic with immediate */ 68 OPC_ANDI = (0x0C << 26), 69 OPC_ORI = (0x0D << 26), 70 OPC_XORI = (0x0E << 26), 71 OPC_LUI = (0x0F << 26), 72 /* arithmetic with immediate */ 73 OPC_DADDI = (0x18 << 26), 74 OPC_DADDIU = (0x19 << 26), 75 /* Jump and branches */ 76 OPC_J = (0x02 << 26), 77 OPC_JAL = (0x03 << 26), 78 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */ 79 OPC_BEQL = (0x14 << 26), 80 OPC_BNE = (0x05 << 26), 81 OPC_BNEL = (0x15 << 26), 82 OPC_BLEZ = (0x06 << 26), 83 OPC_BLEZL = (0x16 << 26), 84 OPC_BGTZ = (0x07 << 26), 85 OPC_BGTZL = (0x17 << 26), 86 OPC_JALX = (0x1D << 26), 87 OPC_DAUI = (0x1D << 26), 88 /* Load and stores */ 89 OPC_LDL = (0x1A << 26), 90 OPC_LDR = (0x1B << 26), 91 OPC_LB = (0x20 << 26), 92 OPC_LH = (0x21 << 26), 93 OPC_LWL = (0x22 << 26), 94 OPC_LW = (0x23 << 26), 95 OPC_LWPC = OPC_LW | 0x5, 96 OPC_LBU = (0x24 << 26), 97 OPC_LHU = (0x25 << 26), 98 OPC_LWR = (0x26 << 26), 99 OPC_LWU = (0x27 << 26), 100 OPC_SB = (0x28 << 26), 101 OPC_SH = (0x29 << 26), 102 OPC_SWL = (0x2A << 26), 103 OPC_SW = (0x2B << 26), 104 OPC_SDL = (0x2C << 26), 105 OPC_SDR = (0x2D << 26), 106 OPC_SWR = (0x2E << 26), 107 OPC_LL = (0x30 << 26), 108 OPC_LLD = (0x34 << 26), 109 OPC_LD = (0x37 << 26), 110 OPC_LDPC = OPC_LD | 0x5, 111 OPC_SC = (0x38 << 26), 112 OPC_SCD = (0x3C << 26), 113 OPC_SD = (0x3F << 26), 114 /* Floating point load/store */ 115 OPC_LWC1 = (0x31 << 26), 116 OPC_LWC2 = (0x32 << 26), 117 OPC_LDC1 = (0x35 << 26), 118 OPC_LDC2 = (0x36 << 26), 119 OPC_SWC1 = (0x39 << 26), 120 OPC_SWC2 = (0x3A << 26), 121 OPC_SDC1 = (0x3D << 26), 122 OPC_SDC2 = (0x3E << 26), 123 /* Compact Branches */ 124 OPC_BLEZALC = (0x06 << 26), 125 OPC_BGEZALC = (0x06 << 26), 126 OPC_BGEUC = (0x06 << 26), 127 OPC_BGTZALC = (0x07 << 26), 128 OPC_BLTZALC = (0x07 << 26), 129 OPC_BLTUC = (0x07 << 26), 130 OPC_BOVC = (0x08 << 26), 131 OPC_BEQZALC = (0x08 << 26), 132 OPC_BEQC = (0x08 << 26), 133 OPC_BLEZC = (0x16 << 26), 134 OPC_BGEZC = (0x16 << 26), 135 OPC_BGEC = (0x16 << 26), 136 OPC_BGTZC = (0x17 << 26), 137 OPC_BLTZC = (0x17 << 26), 138 OPC_BLTC = (0x17 << 26), 139 OPC_BNVC = (0x18 << 26), 140 OPC_BNEZALC = (0x18 << 26), 141 OPC_BNEC = (0x18 << 26), 142 OPC_BC = (0x32 << 26), 143 OPC_BEQZC = (0x36 << 26), 144 OPC_JIC = (0x36 << 26), 145 OPC_BALC = (0x3A << 26), 146 OPC_BNEZC = (0x3E << 26), 147 OPC_JIALC = (0x3E << 26), 148 /* MDMX ASE specific */ 149 OPC_MDMX = (0x1E << 26), 150 /* Cache and prefetch */ 151 OPC_CACHE = (0x2F << 26), 152 OPC_PREF = (0x33 << 26), 153 /* PC-relative address computation / loads */ 154 OPC_PCREL = (0x3B << 26), 155 }; 156 157 /* PC-relative address computation / loads */ 158 #define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19))) 159 #define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16))) 160 enum { 161 /* Instructions determined by bits 19 and 20 */ 162 OPC_ADDIUPC = OPC_PCREL | (0 << 19), 163 R6_OPC_LWPC = OPC_PCREL | (1 << 19), 164 OPC_LWUPC = OPC_PCREL | (2 << 19), 165 166 /* Instructions determined by bits 16 ... 20 */ 167 OPC_AUIPC = OPC_PCREL | (0x1e << 16), 168 OPC_ALUIPC = OPC_PCREL | (0x1f << 16), 169 170 /* Other */ 171 R6_OPC_LDPC = OPC_PCREL | (6 << 18), 172 }; 173 174 /* MIPS special opcodes */ 175 #define MASK_SPECIAL(op) (MASK_OP_MAJOR(op) | (op & 0x3F)) 176 177 enum { 178 /* Shifts */ 179 OPC_SLL = 0x00 | OPC_SPECIAL, 180 /* NOP is SLL r0, r0, 0 */ 181 /* SSNOP is SLL r0, r0, 1 */ 182 /* EHB is SLL r0, r0, 3 */ 183 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */ 184 OPC_ROTR = OPC_SRL | (1 << 21), 185 OPC_SRA = 0x03 | OPC_SPECIAL, 186 OPC_SLLV = 0x04 | OPC_SPECIAL, 187 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */ 188 OPC_ROTRV = OPC_SRLV | (1 << 6), 189 OPC_SRAV = 0x07 | OPC_SPECIAL, 190 OPC_DSLLV = 0x14 | OPC_SPECIAL, 191 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */ 192 OPC_DROTRV = OPC_DSRLV | (1 << 6), 193 OPC_DSRAV = 0x17 | OPC_SPECIAL, 194 OPC_DSLL = 0x38 | OPC_SPECIAL, 195 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */ 196 OPC_DROTR = OPC_DSRL | (1 << 21), 197 OPC_DSRA = 0x3B | OPC_SPECIAL, 198 OPC_DSLL32 = 0x3C | OPC_SPECIAL, 199 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */ 200 OPC_DROTR32 = OPC_DSRL32 | (1 << 21), 201 OPC_DSRA32 = 0x3F | OPC_SPECIAL, 202 /* Multiplication / division */ 203 OPC_MULT = 0x18 | OPC_SPECIAL, 204 OPC_MULTU = 0x19 | OPC_SPECIAL, 205 OPC_DIV = 0x1A | OPC_SPECIAL, 206 OPC_DIVU = 0x1B | OPC_SPECIAL, 207 OPC_DMULT = 0x1C | OPC_SPECIAL, 208 OPC_DMULTU = 0x1D | OPC_SPECIAL, 209 OPC_DDIV = 0x1E | OPC_SPECIAL, 210 OPC_DDIVU = 0x1F | OPC_SPECIAL, 211 212 /* 2 registers arithmetic / logic */ 213 OPC_ADD = 0x20 | OPC_SPECIAL, 214 OPC_ADDU = 0x21 | OPC_SPECIAL, 215 OPC_SUB = 0x22 | OPC_SPECIAL, 216 OPC_SUBU = 0x23 | OPC_SPECIAL, 217 OPC_AND = 0x24 | OPC_SPECIAL, 218 OPC_OR = 0x25 | OPC_SPECIAL, 219 OPC_XOR = 0x26 | OPC_SPECIAL, 220 OPC_NOR = 0x27 | OPC_SPECIAL, 221 OPC_SLT = 0x2A | OPC_SPECIAL, 222 OPC_SLTU = 0x2B | OPC_SPECIAL, 223 OPC_DADD = 0x2C | OPC_SPECIAL, 224 OPC_DADDU = 0x2D | OPC_SPECIAL, 225 OPC_DSUB = 0x2E | OPC_SPECIAL, 226 OPC_DSUBU = 0x2F | OPC_SPECIAL, 227 /* Jumps */ 228 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */ 229 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */ 230 /* Traps */ 231 OPC_TGE = 0x30 | OPC_SPECIAL, 232 OPC_TGEU = 0x31 | OPC_SPECIAL, 233 OPC_TLT = 0x32 | OPC_SPECIAL, 234 OPC_TLTU = 0x33 | OPC_SPECIAL, 235 OPC_TEQ = 0x34 | OPC_SPECIAL, 236 OPC_TNE = 0x36 | OPC_SPECIAL, 237 /* HI / LO registers load & stores */ 238 OPC_MFHI = 0x10 | OPC_SPECIAL, 239 OPC_MTHI = 0x11 | OPC_SPECIAL, 240 OPC_MFLO = 0x12 | OPC_SPECIAL, 241 OPC_MTLO = 0x13 | OPC_SPECIAL, 242 /* Conditional moves */ 243 OPC_MOVZ = 0x0A | OPC_SPECIAL, 244 OPC_MOVN = 0x0B | OPC_SPECIAL, 245 246 OPC_SELEQZ = 0x35 | OPC_SPECIAL, 247 OPC_SELNEZ = 0x37 | OPC_SPECIAL, 248 249 OPC_MOVCI = 0x01 | OPC_SPECIAL, 250 251 /* Special */ 252 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */ 253 OPC_SYSCALL = 0x0C | OPC_SPECIAL, 254 OPC_BREAK = 0x0D | OPC_SPECIAL, 255 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */ 256 OPC_SYNC = 0x0F | OPC_SPECIAL, 257 258 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL, 259 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL, 260 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL, 261 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL, 262 }; 263 264 /* 265 * R6 Multiply and Divide instructions have the same opcode 266 * and function field as legacy OPC_MULT[U]/OPC_DIV[U] 267 */ 268 #define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op & (0x7ff))) 269 270 enum { 271 R6_OPC_MUL = OPC_MULT | (2 << 6), 272 R6_OPC_MUH = OPC_MULT | (3 << 6), 273 R6_OPC_MULU = OPC_MULTU | (2 << 6), 274 R6_OPC_MUHU = OPC_MULTU | (3 << 6), 275 R6_OPC_DIV = OPC_DIV | (2 << 6), 276 R6_OPC_MOD = OPC_DIV | (3 << 6), 277 R6_OPC_DIVU = OPC_DIVU | (2 << 6), 278 R6_OPC_MODU = OPC_DIVU | (3 << 6), 279 280 R6_OPC_DMUL = OPC_DMULT | (2 << 6), 281 R6_OPC_DMUH = OPC_DMULT | (3 << 6), 282 R6_OPC_DMULU = OPC_DMULTU | (2 << 6), 283 R6_OPC_DMUHU = OPC_DMULTU | (3 << 6), 284 R6_OPC_DDIV = OPC_DDIV | (2 << 6), 285 R6_OPC_DMOD = OPC_DDIV | (3 << 6), 286 R6_OPC_DDIVU = OPC_DDIVU | (2 << 6), 287 R6_OPC_DMODU = OPC_DDIVU | (3 << 6), 288 289 R6_OPC_CLZ = 0x10 | OPC_SPECIAL, 290 R6_OPC_CLO = 0x11 | OPC_SPECIAL, 291 R6_OPC_DCLZ = 0x12 | OPC_SPECIAL, 292 R6_OPC_DCLO = 0x13 | OPC_SPECIAL, 293 R6_OPC_SDBBP = 0x0e | OPC_SPECIAL, 294 }; 295 296 /* REGIMM (rt field) opcodes */ 297 #define MASK_REGIMM(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 16))) 298 299 enum { 300 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM, 301 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM, 302 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM, 303 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM, 304 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM, 305 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM, 306 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM, 307 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM, 308 OPC_TGEI = (0x08 << 16) | OPC_REGIMM, 309 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM, 310 OPC_TLTI = (0x0A << 16) | OPC_REGIMM, 311 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM, 312 OPC_TEQI = (0x0C << 16) | OPC_REGIMM, 313 OPC_TNEI = (0x0E << 16) | OPC_REGIMM, 314 OPC_SIGRIE = (0x17 << 16) | OPC_REGIMM, 315 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM, 316 317 OPC_DAHI = (0x06 << 16) | OPC_REGIMM, 318 OPC_DATI = (0x1e << 16) | OPC_REGIMM, 319 }; 320 321 /* Special2 opcodes */ 322 #define MASK_SPECIAL2(op) (MASK_OP_MAJOR(op) | (op & 0x3F)) 323 324 enum { 325 /* Multiply & xxx operations */ 326 OPC_MADD = 0x00 | OPC_SPECIAL2, 327 OPC_MADDU = 0x01 | OPC_SPECIAL2, 328 OPC_MUL = 0x02 | OPC_SPECIAL2, 329 OPC_MSUB = 0x04 | OPC_SPECIAL2, 330 OPC_MSUBU = 0x05 | OPC_SPECIAL2, 331 /* Loongson 2F */ 332 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2, 333 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2, 334 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2, 335 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2, 336 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2, 337 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2, 338 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2, 339 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2, 340 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2, 341 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2, 342 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2, 343 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2, 344 /* Misc */ 345 OPC_CLZ = 0x20 | OPC_SPECIAL2, 346 OPC_CLO = 0x21 | OPC_SPECIAL2, 347 OPC_DCLZ = 0x24 | OPC_SPECIAL2, 348 OPC_DCLO = 0x25 | OPC_SPECIAL2, 349 /* Special */ 350 OPC_SDBBP = 0x3F | OPC_SPECIAL2, 351 }; 352 353 /* Special3 opcodes */ 354 #define MASK_SPECIAL3(op) (MASK_OP_MAJOR(op) | (op & 0x3F)) 355 356 enum { 357 OPC_EXT = 0x00 | OPC_SPECIAL3, 358 OPC_DEXTM = 0x01 | OPC_SPECIAL3, 359 OPC_DEXTU = 0x02 | OPC_SPECIAL3, 360 OPC_DEXT = 0x03 | OPC_SPECIAL3, 361 OPC_INS = 0x04 | OPC_SPECIAL3, 362 OPC_DINSM = 0x05 | OPC_SPECIAL3, 363 OPC_DINSU = 0x06 | OPC_SPECIAL3, 364 OPC_DINS = 0x07 | OPC_SPECIAL3, 365 OPC_FORK = 0x08 | OPC_SPECIAL3, 366 OPC_YIELD = 0x09 | OPC_SPECIAL3, 367 OPC_BSHFL = 0x20 | OPC_SPECIAL3, 368 OPC_DBSHFL = 0x24 | OPC_SPECIAL3, 369 OPC_RDHWR = 0x3B | OPC_SPECIAL3, 370 OPC_GINV = 0x3D | OPC_SPECIAL3, 371 372 /* Loongson 2E */ 373 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3, 374 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3, 375 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3, 376 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3, 377 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3, 378 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3, 379 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3, 380 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3, 381 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3, 382 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3, 383 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3, 384 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3, 385 386 /* MIPS DSP Load */ 387 OPC_LX_DSP = 0x0A | OPC_SPECIAL3, 388 /* MIPS DSP Arithmetic */ 389 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3, 390 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3, 391 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3, 392 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3, 393 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */ 394 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */ 395 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3, 396 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3, 397 /* MIPS DSP GPR-Based Shift Sub-class */ 398 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3, 399 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3, 400 /* MIPS DSP Multiply Sub-class insns */ 401 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */ 402 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */ 403 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3, 404 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3, 405 /* DSP Bit/Manipulation Sub-class */ 406 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3, 407 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3, 408 /* MIPS DSP Append Sub-class */ 409 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3, 410 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3, 411 /* MIPS DSP Accumulator and DSPControl Access Sub-class */ 412 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3, 413 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3, 414 415 /* EVA */ 416 OPC_LWLE = 0x19 | OPC_SPECIAL3, 417 OPC_LWRE = 0x1A | OPC_SPECIAL3, 418 OPC_CACHEE = 0x1B | OPC_SPECIAL3, 419 OPC_SBE = 0x1C | OPC_SPECIAL3, 420 OPC_SHE = 0x1D | OPC_SPECIAL3, 421 OPC_SCE = 0x1E | OPC_SPECIAL3, 422 OPC_SWE = 0x1F | OPC_SPECIAL3, 423 OPC_SWLE = 0x21 | OPC_SPECIAL3, 424 OPC_SWRE = 0x22 | OPC_SPECIAL3, 425 OPC_PREFE = 0x23 | OPC_SPECIAL3, 426 OPC_LBUE = 0x28 | OPC_SPECIAL3, 427 OPC_LHUE = 0x29 | OPC_SPECIAL3, 428 OPC_LBE = 0x2C | OPC_SPECIAL3, 429 OPC_LHE = 0x2D | OPC_SPECIAL3, 430 OPC_LLE = 0x2E | OPC_SPECIAL3, 431 OPC_LWE = 0x2F | OPC_SPECIAL3, 432 433 /* R6 */ 434 R6_OPC_PREF = 0x35 | OPC_SPECIAL3, 435 R6_OPC_CACHE = 0x25 | OPC_SPECIAL3, 436 R6_OPC_LL = 0x36 | OPC_SPECIAL3, 437 R6_OPC_SC = 0x26 | OPC_SPECIAL3, 438 R6_OPC_LLD = 0x37 | OPC_SPECIAL3, 439 R6_OPC_SCD = 0x27 | OPC_SPECIAL3, 440 }; 441 442 /* Loongson EXT load/store quad word opcodes */ 443 #define MASK_LOONGSON_GSLSQ(op) (MASK_OP_MAJOR(op) | (op & 0x8020)) 444 enum { 445 OPC_GSLQ = 0x0020 | OPC_LWC2, 446 OPC_GSLQC1 = 0x8020 | OPC_LWC2, 447 OPC_GSSHFL = OPC_LWC2, 448 OPC_GSSQ = 0x0020 | OPC_SWC2, 449 OPC_GSSQC1 = 0x8020 | OPC_SWC2, 450 OPC_GSSHFS = OPC_SWC2, 451 }; 452 453 /* Loongson EXT shifted load/store opcodes */ 454 #define MASK_LOONGSON_GSSHFLS(op) (MASK_OP_MAJOR(op) | (op & 0xc03f)) 455 enum { 456 OPC_GSLWLC1 = 0x4 | OPC_GSSHFL, 457 OPC_GSLWRC1 = 0x5 | OPC_GSSHFL, 458 OPC_GSLDLC1 = 0x6 | OPC_GSSHFL, 459 OPC_GSLDRC1 = 0x7 | OPC_GSSHFL, 460 OPC_GSSWLC1 = 0x4 | OPC_GSSHFS, 461 OPC_GSSWRC1 = 0x5 | OPC_GSSHFS, 462 OPC_GSSDLC1 = 0x6 | OPC_GSSHFS, 463 OPC_GSSDRC1 = 0x7 | OPC_GSSHFS, 464 }; 465 466 /* Loongson EXT LDC2/SDC2 opcodes */ 467 #define MASK_LOONGSON_LSDC2(op) (MASK_OP_MAJOR(op) | (op & 0x7)) 468 469 enum { 470 OPC_GSLBX = 0x0 | OPC_LDC2, 471 OPC_GSLHX = 0x1 | OPC_LDC2, 472 OPC_GSLWX = 0x2 | OPC_LDC2, 473 OPC_GSLDX = 0x3 | OPC_LDC2, 474 OPC_GSLWXC1 = 0x6 | OPC_LDC2, 475 OPC_GSLDXC1 = 0x7 | OPC_LDC2, 476 OPC_GSSBX = 0x0 | OPC_SDC2, 477 OPC_GSSHX = 0x1 | OPC_SDC2, 478 OPC_GSSWX = 0x2 | OPC_SDC2, 479 OPC_GSSDX = 0x3 | OPC_SDC2, 480 OPC_GSSWXC1 = 0x6 | OPC_SDC2, 481 OPC_GSSDXC1 = 0x7 | OPC_SDC2, 482 }; 483 484 /* BSHFL opcodes */ 485 #define MASK_BSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 486 487 enum { 488 OPC_WSBH = (0x02 << 6) | OPC_BSHFL, 489 OPC_SEB = (0x10 << 6) | OPC_BSHFL, 490 OPC_SEH = (0x18 << 6) | OPC_BSHFL, 491 OPC_ALIGN = (0x08 << 6) | OPC_BSHFL, /* 010.bp (010.00 to 010.11) */ 492 OPC_ALIGN_1 = (0x09 << 6) | OPC_BSHFL, 493 OPC_ALIGN_2 = (0x0A << 6) | OPC_BSHFL, 494 OPC_ALIGN_3 = (0x0B << 6) | OPC_BSHFL, 495 OPC_BITSWAP = (0x00 << 6) | OPC_BSHFL /* 00000 */ 496 }; 497 498 /* DBSHFL opcodes */ 499 #define MASK_DBSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 500 501 enum { 502 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL, 503 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL, 504 OPC_DALIGN = (0x08 << 6) | OPC_DBSHFL, /* 01.bp (01.000 to 01.111) */ 505 OPC_DALIGN_1 = (0x09 << 6) | OPC_DBSHFL, 506 OPC_DALIGN_2 = (0x0A << 6) | OPC_DBSHFL, 507 OPC_DALIGN_3 = (0x0B << 6) | OPC_DBSHFL, 508 OPC_DALIGN_4 = (0x0C << 6) | OPC_DBSHFL, 509 OPC_DALIGN_5 = (0x0D << 6) | OPC_DBSHFL, 510 OPC_DALIGN_6 = (0x0E << 6) | OPC_DBSHFL, 511 OPC_DALIGN_7 = (0x0F << 6) | OPC_DBSHFL, 512 OPC_DBITSWAP = (0x00 << 6) | OPC_DBSHFL, /* 00000 */ 513 }; 514 515 /* MIPS DSP REGIMM opcodes */ 516 enum { 517 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM, 518 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM, 519 }; 520 521 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 522 /* MIPS DSP Load */ 523 enum { 524 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP, 525 OPC_LHX = (0x04 << 6) | OPC_LX_DSP, 526 OPC_LWX = (0x00 << 6) | OPC_LX_DSP, 527 OPC_LDX = (0x08 << 6) | OPC_LX_DSP, 528 }; 529 530 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 531 enum { 532 /* MIPS DSP Arithmetic Sub-class */ 533 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP, 534 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP, 535 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP, 536 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP, 537 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP, 538 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP, 539 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP, 540 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP, 541 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP, 542 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP, 543 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP, 544 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP, 545 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP, 546 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP, 547 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP, 548 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP, 549 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP, 550 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP, 551 /* MIPS DSP Multiply Sub-class insns */ 552 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP, 553 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP, 554 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP, 555 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP, 556 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP, 557 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP, 558 }; 559 560 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E 561 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 562 enum { 563 /* MIPS DSP Arithmetic Sub-class */ 564 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP, 565 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP, 566 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP, 567 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP, 568 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP, 569 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP, 570 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP, 571 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP, 572 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP, 573 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP, 574 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP, 575 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP, 576 /* MIPS DSP Multiply Sub-class insns */ 577 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP, 578 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP, 579 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP, 580 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP, 581 }; 582 583 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 584 enum { 585 /* MIPS DSP Arithmetic Sub-class */ 586 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP, 587 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP, 588 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP, 589 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP, 590 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP, 591 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP, 592 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP, 593 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP, 594 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP, 595 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP, 596 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP, 597 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP, 598 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP, 599 /* DSP Bit/Manipulation Sub-class */ 600 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP, 601 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP, 602 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP, 603 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP, 604 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP, 605 }; 606 607 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 608 enum { 609 /* MIPS DSP Arithmetic Sub-class */ 610 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP, 611 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP, 612 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP, 613 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP, 614 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP, 615 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP, 616 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP, 617 /* DSP Compare-Pick Sub-class */ 618 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP, 619 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP, 620 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP, 621 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP, 622 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP, 623 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP, 624 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP, 625 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP, 626 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP, 627 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP, 628 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP, 629 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP, 630 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP, 631 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP, 632 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP, 633 }; 634 635 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 636 enum { 637 /* MIPS DSP GPR-Based Shift Sub-class */ 638 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP, 639 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP, 640 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP, 641 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP, 642 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP, 643 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP, 644 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP, 645 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP, 646 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP, 647 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP, 648 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP, 649 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP, 650 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP, 651 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP, 652 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP, 653 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP, 654 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP, 655 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP, 656 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP, 657 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP, 658 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP, 659 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP, 660 }; 661 662 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 663 enum { 664 /* MIPS DSP Multiply Sub-class insns */ 665 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP, 666 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP, 667 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP, 668 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP, 669 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP, 670 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP, 671 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP, 672 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP, 673 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP, 674 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP, 675 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP, 676 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP, 677 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP, 678 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP, 679 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP, 680 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP, 681 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP, 682 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP, 683 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP, 684 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP, 685 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP, 686 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP, 687 }; 688 689 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 690 enum { 691 /* DSP Bit/Manipulation Sub-class */ 692 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP, 693 }; 694 695 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 696 enum { 697 /* MIPS DSP Append Sub-class */ 698 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP, 699 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP, 700 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP, 701 }; 702 703 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 704 enum { 705 /* MIPS DSP Accumulator and DSPControl Access Sub-class */ 706 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP, 707 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP, 708 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP, 709 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP, 710 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP, 711 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP, 712 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP, 713 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP, 714 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP, 715 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP, 716 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP, 717 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP, 718 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP, 719 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP, 720 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP, 721 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP, 722 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP, 723 }; 724 725 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 726 enum { 727 /* MIPS DSP Arithmetic Sub-class */ 728 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP, 729 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP, 730 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP, 731 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP, 732 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP, 733 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP, 734 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP, 735 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP, 736 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP, 737 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP, 738 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP, 739 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP, 740 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP, 741 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP, 742 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP, 743 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP, 744 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP, 745 /* DSP Bit/Manipulation Sub-class */ 746 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP, 747 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP, 748 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP, 749 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP, 750 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP, 751 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP, 752 }; 753 754 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 755 enum { 756 /* MIPS DSP Multiply Sub-class insns */ 757 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP, 758 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP, 759 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP, 760 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP, 761 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP, 762 /* MIPS DSP Arithmetic Sub-class */ 763 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP, 764 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP, 765 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP, 766 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP, 767 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP, 768 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP, 769 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP, 770 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP, 771 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP, 772 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP, 773 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP, 774 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP, 775 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP, 776 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP, 777 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP, 778 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP, 779 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP, 780 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP, 781 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP, 782 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP, 783 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP, 784 }; 785 786 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 787 enum { 788 /* DSP Compare-Pick Sub-class */ 789 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP, 790 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP, 791 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP, 792 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP, 793 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP, 794 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP, 795 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP, 796 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP, 797 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP, 798 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP, 799 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP, 800 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP, 801 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP, 802 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP, 803 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP, 804 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP, 805 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP, 806 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP, 807 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP, 808 /* MIPS DSP Arithmetic Sub-class */ 809 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP, 810 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP, 811 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP, 812 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP, 813 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP, 814 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP, 815 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP, 816 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP, 817 }; 818 819 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 820 enum { 821 /* DSP Append Sub-class */ 822 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP, 823 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP, 824 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP, 825 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP, 826 }; 827 828 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 829 enum { 830 /* MIPS DSP Accumulator and DSPControl Access Sub-class */ 831 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP, 832 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP, 833 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP, 834 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP, 835 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP, 836 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP, 837 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP, 838 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP, 839 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP, 840 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP, 841 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP, 842 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP, 843 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP, 844 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP, 845 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP, 846 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP, 847 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP, 848 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP, 849 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP, 850 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP, 851 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP, 852 }; 853 854 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 855 enum { 856 /* DSP Bit/Manipulation Sub-class */ 857 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP, 858 }; 859 860 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 861 enum { 862 /* MIPS DSP Multiply Sub-class insns */ 863 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP, 864 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP, 865 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP, 866 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP, 867 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP, 868 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP, 869 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP, 870 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP, 871 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP, 872 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP, 873 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP, 874 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP, 875 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP, 876 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP, 877 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP, 878 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP, 879 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP, 880 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP, 881 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP, 882 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP, 883 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP, 884 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP, 885 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP, 886 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP, 887 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP, 888 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP, 889 }; 890 891 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 892 enum { 893 /* MIPS DSP GPR-Based Shift Sub-class */ 894 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP, 895 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP, 896 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP, 897 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP, 898 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP, 899 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP, 900 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP, 901 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP, 902 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP, 903 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP, 904 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP, 905 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP, 906 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP, 907 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP, 908 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP, 909 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP, 910 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP, 911 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP, 912 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP, 913 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP, 914 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP, 915 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP, 916 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP, 917 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP, 918 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP, 919 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP, 920 }; 921 922 /* Coprocessor 0 (rs field) */ 923 #define MASK_CP0(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21))) 924 925 enum { 926 OPC_MFC0 = (0x00 << 21) | OPC_CP0, 927 OPC_DMFC0 = (0x01 << 21) | OPC_CP0, 928 OPC_MFHC0 = (0x02 << 21) | OPC_CP0, 929 OPC_MTC0 = (0x04 << 21) | OPC_CP0, 930 OPC_DMTC0 = (0x05 << 21) | OPC_CP0, 931 OPC_MTHC0 = (0x06 << 21) | OPC_CP0, 932 OPC_MFTR = (0x08 << 21) | OPC_CP0, 933 OPC_RDPGPR = (0x0A << 21) | OPC_CP0, 934 OPC_MFMC0 = (0x0B << 21) | OPC_CP0, 935 OPC_MTTR = (0x0C << 21) | OPC_CP0, 936 OPC_WRPGPR = (0x0E << 21) | OPC_CP0, 937 OPC_C0 = (0x10 << 21) | OPC_CP0, 938 OPC_C0_1 = (0x11 << 21) | OPC_CP0, 939 OPC_C0_2 = (0x12 << 21) | OPC_CP0, 940 OPC_C0_3 = (0x13 << 21) | OPC_CP0, 941 OPC_C0_4 = (0x14 << 21) | OPC_CP0, 942 OPC_C0_5 = (0x15 << 21) | OPC_CP0, 943 OPC_C0_6 = (0x16 << 21) | OPC_CP0, 944 OPC_C0_7 = (0x17 << 21) | OPC_CP0, 945 OPC_C0_8 = (0x18 << 21) | OPC_CP0, 946 OPC_C0_9 = (0x19 << 21) | OPC_CP0, 947 OPC_C0_A = (0x1A << 21) | OPC_CP0, 948 OPC_C0_B = (0x1B << 21) | OPC_CP0, 949 OPC_C0_C = (0x1C << 21) | OPC_CP0, 950 OPC_C0_D = (0x1D << 21) | OPC_CP0, 951 OPC_C0_E = (0x1E << 21) | OPC_CP0, 952 OPC_C0_F = (0x1F << 21) | OPC_CP0, 953 }; 954 955 /* MFMC0 opcodes */ 956 #define MASK_MFMC0(op) (MASK_CP0(op) | (op & 0xFFFF)) 957 958 enum { 959 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0, 960 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0, 961 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0, 962 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0, 963 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0, 964 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0, 965 OPC_DVP = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0, 966 OPC_EVP = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0, 967 }; 968 969 /* Coprocessor 0 (with rs == C0) */ 970 #define MASK_C0(op) (MASK_CP0(op) | (op & 0x3F)) 971 972 enum { 973 OPC_TLBR = 0x01 | OPC_C0, 974 OPC_TLBWI = 0x02 | OPC_C0, 975 OPC_TLBINV = 0x03 | OPC_C0, 976 OPC_TLBINVF = 0x04 | OPC_C0, 977 OPC_TLBWR = 0x06 | OPC_C0, 978 OPC_TLBP = 0x08 | OPC_C0, 979 OPC_RFE = 0x10 | OPC_C0, 980 OPC_ERET = 0x18 | OPC_C0, 981 OPC_DERET = 0x1F | OPC_C0, 982 OPC_WAIT = 0x20 | OPC_C0, 983 }; 984 985 #define MASK_CP2(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21))) 986 987 enum { 988 OPC_MFC2 = (0x00 << 21) | OPC_CP2, 989 OPC_DMFC2 = (0x01 << 21) | OPC_CP2, 990 OPC_CFC2 = (0x02 << 21) | OPC_CP2, 991 OPC_MFHC2 = (0x03 << 21) | OPC_CP2, 992 OPC_MTC2 = (0x04 << 21) | OPC_CP2, 993 OPC_DMTC2 = (0x05 << 21) | OPC_CP2, 994 OPC_CTC2 = (0x06 << 21) | OPC_CP2, 995 OPC_MTHC2 = (0x07 << 21) | OPC_CP2, 996 OPC_BC2 = (0x08 << 21) | OPC_CP2, 997 OPC_BC2EQZ = (0x09 << 21) | OPC_CP2, 998 OPC_BC2NEZ = (0x0D << 21) | OPC_CP2, 999 }; 1000 1001 #define MASK_LMMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F)) 1002 1003 enum { 1004 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2, 1005 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2, 1006 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2, 1007 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2, 1008 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2, 1009 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2, 1010 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2, 1011 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2, 1012 1013 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2, 1014 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2, 1015 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2, 1016 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2, 1017 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2, 1018 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2, 1019 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2, 1020 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2, 1021 1022 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2, 1023 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2, 1024 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2, 1025 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2, 1026 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2, 1027 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2, 1028 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2, 1029 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2, 1030 1031 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2, 1032 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2, 1033 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2, 1034 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2, 1035 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2, 1036 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2, 1037 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2, 1038 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2, 1039 1040 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2, 1041 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2, 1042 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2, 1043 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2, 1044 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2, 1045 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2, 1046 1047 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2, 1048 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2, 1049 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2, 1050 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2, 1051 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2, 1052 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2, 1053 1054 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2, 1055 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2, 1056 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2, 1057 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2, 1058 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2, 1059 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2, 1060 1061 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2, 1062 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2, 1063 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2, 1064 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2, 1065 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2, 1066 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2, 1067 1068 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2, 1069 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2, 1070 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2, 1071 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2, 1072 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2, 1073 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2, 1074 1075 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2, 1076 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2, 1077 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2, 1078 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2, 1079 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2, 1080 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2, 1081 1082 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2, 1083 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2, 1084 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2, 1085 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2, 1086 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2, 1087 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2, 1088 1089 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2, 1090 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2, 1091 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2, 1092 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2, 1093 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2, 1094 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2, 1095 }; 1096 1097 1098 #define MASK_CP3(op) (MASK_OP_MAJOR(op) | (op & 0x3F)) 1099 1100 enum { 1101 OPC_LWXC1 = 0x00 | OPC_CP3, 1102 OPC_LDXC1 = 0x01 | OPC_CP3, 1103 OPC_LUXC1 = 0x05 | OPC_CP3, 1104 OPC_SWXC1 = 0x08 | OPC_CP3, 1105 OPC_SDXC1 = 0x09 | OPC_CP3, 1106 OPC_SUXC1 = 0x0D | OPC_CP3, 1107 OPC_PREFX = 0x0F | OPC_CP3, 1108 OPC_ALNV_PS = 0x1E | OPC_CP3, 1109 OPC_MADD_S = 0x20 | OPC_CP3, 1110 OPC_MADD_D = 0x21 | OPC_CP3, 1111 OPC_MADD_PS = 0x26 | OPC_CP3, 1112 OPC_MSUB_S = 0x28 | OPC_CP3, 1113 OPC_MSUB_D = 0x29 | OPC_CP3, 1114 OPC_MSUB_PS = 0x2E | OPC_CP3, 1115 OPC_NMADD_S = 0x30 | OPC_CP3, 1116 OPC_NMADD_D = 0x31 | OPC_CP3, 1117 OPC_NMADD_PS = 0x36 | OPC_CP3, 1118 OPC_NMSUB_S = 0x38 | OPC_CP3, 1119 OPC_NMSUB_D = 0x39 | OPC_CP3, 1120 OPC_NMSUB_PS = 0x3E | OPC_CP3, 1121 }; 1122 1123 /* 1124 * MMI (MultiMedia Instruction) encodings 1125 * ====================================== 1126 * 1127 * MMI instructions encoding table keys: 1128 * 1129 * * This code is reserved for future use. An attempt to execute it 1130 * causes a Reserved Instruction exception. 1131 * % This code indicates an instruction class. The instruction word 1132 * must be further decoded by examining additional tables that show 1133 * the values for other instruction fields. 1134 * # This code is reserved for the unsupported instructions DMULT, 1135 * DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt 1136 * to execute it causes a Reserved Instruction exception. 1137 * 1138 * MMI instructions encoded by opcode field (MMI, LQ, SQ): 1139 * 1140 * 31 26 0 1141 * +--------+----------------------------------------+ 1142 * | opcode | | 1143 * +--------+----------------------------------------+ 1144 * 1145 * opcode bits 28..26 1146 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 1147 * 31..29 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111 1148 * -------+-------+-------+-------+-------+-------+-------+-------+------- 1149 * 0 000 |SPECIAL| REGIMM| J | JAL | BEQ | BNE | BLEZ | BGTZ 1150 * 1 001 | ADDI | ADDIU | SLTI | SLTIU | ANDI | ORI | XORI | LUI 1151 * 2 010 | COP0 | COP1 | * | * | BEQL | BNEL | BLEZL | BGTZL 1152 * 3 011 | DADDI | DADDIU| LDL | LDR | MMI% | * | LQ | SQ 1153 * 4 100 | LB | LH | LWL | LW | LBU | LHU | LWR | LWU 1154 * 5 101 | SB | SH | SWL | SW | SDL | SDR | SWR | CACHE 1155 * 6 110 | # | LWC1 | # | PREF | # | LDC1 | # | LD 1156 * 7 111 | # | SWC1 | # | * | # | SDC1 | # | SD 1157 */ 1158 1159 enum { 1160 MMI_OPC_CLASS_MMI = 0x1C << 26, /* Same as OPC_SPECIAL2 */ 1161 MMI_OPC_SQ = 0x1F << 26, /* Same as OPC_SPECIAL3 */ 1162 }; 1163 1164 /* 1165 * MMI instructions with opcode field = MMI: 1166 * 1167 * 31 26 5 0 1168 * +--------+-------------------------------+--------+ 1169 * | MMI | |function| 1170 * +--------+-------------------------------+--------+ 1171 * 1172 * function bits 2..0 1173 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 1174 * 5..3 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111 1175 * -------+-------+-------+-------+-------+-------+-------+-------+------- 1176 * 0 000 | MADD | MADDU | * | * | PLZCW | * | * | * 1177 * 1 001 | MMI0% | MMI2% | * | * | * | * | * | * 1178 * 2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 | * | * | * | * 1179 * 3 011 | MULT1 | MULTU1| DIV1 | DIVU1 | * | * | * | * 1180 * 4 100 | MADD1 | MADDU1| * | * | * | * | * | * 1181 * 5 101 | MMI1% | MMI3% | * | * | * | * | * | * 1182 * 6 110 | PMFHL | PMTHL | * | * | PSLLH | * | PSRLH | PSRAH 1183 * 7 111 | * | * | * | * | PSLLW | * | PSRLW | PSRAW 1184 */ 1185 1186 #define MASK_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F)) 1187 enum { 1188 MMI_OPC_MADD = 0x00 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADD */ 1189 MMI_OPC_MADDU = 0x01 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADDU */ 1190 MMI_OPC_MULT1 = 0x18 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MULT */ 1191 MMI_OPC_MULTU1 = 0x19 | MMI_OPC_CLASS_MMI, /* Same min. as OPC_MULTU */ 1192 MMI_OPC_DIV1 = 0x1A | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIV */ 1193 MMI_OPC_DIVU1 = 0x1B | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIVU */ 1194 MMI_OPC_MADD1 = 0x20 | MMI_OPC_CLASS_MMI, 1195 MMI_OPC_MADDU1 = 0x21 | MMI_OPC_CLASS_MMI, 1196 }; 1197 1198 /* global register indices */ 1199 TCGv cpu_gpr[32], cpu_PC; 1200 /* 1201 * For CPUs using 128-bit GPR registers, we put the lower halves in cpu_gpr[]) 1202 * and the upper halves in cpu_gpr_hi[]. 1203 */ 1204 TCGv_i64 cpu_gpr_hi[32]; 1205 TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC]; 1206 static TCGv cpu_dspctrl, btarget; 1207 TCGv bcond; 1208 static TCGv cpu_lladdr, cpu_llval; 1209 static TCGv_i32 hflags; 1210 TCGv_i32 fpu_fcr0, fpu_fcr31; 1211 TCGv_i64 fpu_f64[32]; 1212 1213 #include "exec/gen-icount.h" 1214 1215 static const char regnames_HI[][4] = { 1216 "HI0", "HI1", "HI2", "HI3", 1217 }; 1218 1219 static const char regnames_LO[][4] = { 1220 "LO0", "LO1", "LO2", "LO3", 1221 }; 1222 1223 /* General purpose registers moves. */ 1224 void gen_load_gpr(TCGv t, int reg) 1225 { 1226 assert(reg >= 0 && reg <= ARRAY_SIZE(cpu_gpr)); 1227 if (reg == 0) { 1228 tcg_gen_movi_tl(t, 0); 1229 } else { 1230 tcg_gen_mov_tl(t, cpu_gpr[reg]); 1231 } 1232 } 1233 1234 void gen_store_gpr(TCGv t, int reg) 1235 { 1236 assert(reg >= 0 && reg <= ARRAY_SIZE(cpu_gpr)); 1237 if (reg != 0) { 1238 tcg_gen_mov_tl(cpu_gpr[reg], t); 1239 } 1240 } 1241 1242 #if defined(TARGET_MIPS64) 1243 void gen_load_gpr_hi(TCGv_i64 t, int reg) 1244 { 1245 assert(reg >= 0 && reg <= ARRAY_SIZE(cpu_gpr_hi)); 1246 if (reg == 0) { 1247 tcg_gen_movi_i64(t, 0); 1248 } else { 1249 tcg_gen_mov_i64(t, cpu_gpr_hi[reg]); 1250 } 1251 } 1252 1253 void gen_store_gpr_hi(TCGv_i64 t, int reg) 1254 { 1255 assert(reg >= 0 && reg <= ARRAY_SIZE(cpu_gpr_hi)); 1256 if (reg != 0) { 1257 tcg_gen_mov_i64(cpu_gpr_hi[reg], t); 1258 } 1259 } 1260 #endif /* TARGET_MIPS64 */ 1261 1262 /* Moves to/from shadow registers. */ 1263 static inline void gen_load_srsgpr(int from, int to) 1264 { 1265 TCGv t0 = tcg_temp_new(); 1266 1267 if (from == 0) { 1268 tcg_gen_movi_tl(t0, 0); 1269 } else { 1270 TCGv_i32 t2 = tcg_temp_new_i32(); 1271 TCGv_ptr addr = tcg_temp_new_ptr(); 1272 1273 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl)); 1274 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS); 1275 tcg_gen_andi_i32(t2, t2, 0xf); 1276 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32); 1277 tcg_gen_ext_i32_ptr(addr, t2); 1278 tcg_gen_add_ptr(addr, cpu_env, addr); 1279 1280 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from); 1281 } 1282 gen_store_gpr(t0, to); 1283 } 1284 1285 static inline void gen_store_srsgpr(int from, int to) 1286 { 1287 if (to != 0) { 1288 TCGv t0 = tcg_temp_new(); 1289 TCGv_i32 t2 = tcg_temp_new_i32(); 1290 TCGv_ptr addr = tcg_temp_new_ptr(); 1291 1292 gen_load_gpr(t0, from); 1293 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl)); 1294 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS); 1295 tcg_gen_andi_i32(t2, t2, 0xf); 1296 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32); 1297 tcg_gen_ext_i32_ptr(addr, t2); 1298 tcg_gen_add_ptr(addr, cpu_env, addr); 1299 1300 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to); 1301 } 1302 } 1303 1304 /* Tests */ 1305 static inline void gen_save_pc(target_ulong pc) 1306 { 1307 tcg_gen_movi_tl(cpu_PC, pc); 1308 } 1309 1310 static inline void save_cpu_state(DisasContext *ctx, int do_save_pc) 1311 { 1312 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags); 1313 if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) { 1314 gen_save_pc(ctx->base.pc_next); 1315 ctx->saved_pc = ctx->base.pc_next; 1316 } 1317 if (ctx->hflags != ctx->saved_hflags) { 1318 tcg_gen_movi_i32(hflags, ctx->hflags); 1319 ctx->saved_hflags = ctx->hflags; 1320 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) { 1321 case MIPS_HFLAG_BR: 1322 break; 1323 case MIPS_HFLAG_BC: 1324 case MIPS_HFLAG_BL: 1325 case MIPS_HFLAG_B: 1326 tcg_gen_movi_tl(btarget, ctx->btarget); 1327 break; 1328 } 1329 } 1330 } 1331 1332 static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx) 1333 { 1334 ctx->saved_hflags = ctx->hflags; 1335 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) { 1336 case MIPS_HFLAG_BR: 1337 break; 1338 case MIPS_HFLAG_BC: 1339 case MIPS_HFLAG_BL: 1340 case MIPS_HFLAG_B: 1341 ctx->btarget = env->btarget; 1342 break; 1343 } 1344 } 1345 1346 void generate_exception_err(DisasContext *ctx, int excp, int err) 1347 { 1348 save_cpu_state(ctx, 1); 1349 gen_helper_raise_exception_err(cpu_env, tcg_constant_i32(excp), 1350 tcg_constant_i32(err)); 1351 ctx->base.is_jmp = DISAS_NORETURN; 1352 } 1353 1354 void generate_exception(DisasContext *ctx, int excp) 1355 { 1356 gen_helper_raise_exception(cpu_env, tcg_constant_i32(excp)); 1357 } 1358 1359 void generate_exception_end(DisasContext *ctx, int excp) 1360 { 1361 generate_exception_err(ctx, excp, 0); 1362 } 1363 1364 void generate_exception_break(DisasContext *ctx, int code) 1365 { 1366 #ifdef CONFIG_USER_ONLY 1367 /* Pass the break code along to cpu_loop. */ 1368 tcg_gen_st_i32(tcg_constant_i32(code), cpu_env, 1369 offsetof(CPUMIPSState, error_code)); 1370 #endif 1371 generate_exception_end(ctx, EXCP_BREAK); 1372 } 1373 1374 void gen_reserved_instruction(DisasContext *ctx) 1375 { 1376 generate_exception_end(ctx, EXCP_RI); 1377 } 1378 1379 /* Floating point register moves. */ 1380 void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg) 1381 { 1382 if (ctx->hflags & MIPS_HFLAG_FRE) { 1383 generate_exception(ctx, EXCP_RI); 1384 } 1385 tcg_gen_extrl_i64_i32(t, fpu_f64[reg]); 1386 } 1387 1388 void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg) 1389 { 1390 TCGv_i64 t64; 1391 if (ctx->hflags & MIPS_HFLAG_FRE) { 1392 generate_exception(ctx, EXCP_RI); 1393 } 1394 t64 = tcg_temp_new_i64(); 1395 tcg_gen_extu_i32_i64(t64, t); 1396 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32); 1397 } 1398 1399 static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg) 1400 { 1401 if (ctx->hflags & MIPS_HFLAG_F64) { 1402 tcg_gen_extrh_i64_i32(t, fpu_f64[reg]); 1403 } else { 1404 gen_load_fpr32(ctx, t, reg | 1); 1405 } 1406 } 1407 1408 static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg) 1409 { 1410 if (ctx->hflags & MIPS_HFLAG_F64) { 1411 TCGv_i64 t64 = tcg_temp_new_i64(); 1412 tcg_gen_extu_i32_i64(t64, t); 1413 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32); 1414 } else { 1415 gen_store_fpr32(ctx, t, reg | 1); 1416 } 1417 } 1418 1419 void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg) 1420 { 1421 if (ctx->hflags & MIPS_HFLAG_F64) { 1422 tcg_gen_mov_i64(t, fpu_f64[reg]); 1423 } else { 1424 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]); 1425 } 1426 } 1427 1428 void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg) 1429 { 1430 if (ctx->hflags & MIPS_HFLAG_F64) { 1431 tcg_gen_mov_i64(fpu_f64[reg], t); 1432 } else { 1433 TCGv_i64 t0; 1434 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32); 1435 t0 = tcg_temp_new_i64(); 1436 tcg_gen_shri_i64(t0, t, 32); 1437 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32); 1438 } 1439 } 1440 1441 int get_fp_bit(int cc) 1442 { 1443 if (cc) { 1444 return 24 + cc; 1445 } else { 1446 return 23; 1447 } 1448 } 1449 1450 /* Addresses computation */ 1451 void gen_op_addr_add(DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1) 1452 { 1453 tcg_gen_add_tl(ret, arg0, arg1); 1454 1455 #if defined(TARGET_MIPS64) 1456 if (ctx->hflags & MIPS_HFLAG_AWRAP) { 1457 tcg_gen_ext32s_i64(ret, ret); 1458 } 1459 #endif 1460 } 1461 1462 static inline void gen_op_addr_addi(DisasContext *ctx, TCGv ret, TCGv base, 1463 target_long ofs) 1464 { 1465 tcg_gen_addi_tl(ret, base, ofs); 1466 1467 #if defined(TARGET_MIPS64) 1468 if (ctx->hflags & MIPS_HFLAG_AWRAP) { 1469 tcg_gen_ext32s_i64(ret, ret); 1470 } 1471 #endif 1472 } 1473 1474 /* Addresses computation (translation time) */ 1475 static target_long addr_add(DisasContext *ctx, target_long base, 1476 target_long offset) 1477 { 1478 target_long sum = base + offset; 1479 1480 #if defined(TARGET_MIPS64) 1481 if (ctx->hflags & MIPS_HFLAG_AWRAP) { 1482 sum = (int32_t)sum; 1483 } 1484 #endif 1485 return sum; 1486 } 1487 1488 /* Sign-extract the low 32-bits to a target_long. */ 1489 void gen_move_low32(TCGv ret, TCGv_i64 arg) 1490 { 1491 #if defined(TARGET_MIPS64) 1492 tcg_gen_ext32s_i64(ret, arg); 1493 #else 1494 tcg_gen_extrl_i64_i32(ret, arg); 1495 #endif 1496 } 1497 1498 /* Sign-extract the high 32-bits to a target_long. */ 1499 void gen_move_high32(TCGv ret, TCGv_i64 arg) 1500 { 1501 #if defined(TARGET_MIPS64) 1502 tcg_gen_sari_i64(ret, arg, 32); 1503 #else 1504 tcg_gen_extrh_i64_i32(ret, arg); 1505 #endif 1506 } 1507 1508 bool check_cp0_enabled(DisasContext *ctx) 1509 { 1510 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) { 1511 generate_exception_end(ctx, EXCP_CpU); 1512 return false; 1513 } 1514 return true; 1515 } 1516 1517 void check_cp1_enabled(DisasContext *ctx) 1518 { 1519 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU))) { 1520 generate_exception_err(ctx, EXCP_CpU, 1); 1521 } 1522 } 1523 1524 /* 1525 * Verify that the processor is running with COP1X instructions enabled. 1526 * This is associated with the nabla symbol in the MIPS32 and MIPS64 1527 * opcode tables. 1528 */ 1529 void check_cop1x(DisasContext *ctx) 1530 { 1531 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X))) { 1532 gen_reserved_instruction(ctx); 1533 } 1534 } 1535 1536 /* 1537 * Verify that the processor is running with 64-bit floating-point 1538 * operations enabled. 1539 */ 1540 void check_cp1_64bitmode(DisasContext *ctx) 1541 { 1542 if (unlikely(~ctx->hflags & MIPS_HFLAG_F64)) { 1543 gen_reserved_instruction(ctx); 1544 } 1545 } 1546 1547 /* 1548 * Verify if floating point register is valid; an operation is not defined 1549 * if bit 0 of any register specification is set and the FR bit in the 1550 * Status register equals zero, since the register numbers specify an 1551 * even-odd pair of adjacent coprocessor general registers. When the FR bit 1552 * in the Status register equals one, both even and odd register numbers 1553 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers. 1554 * 1555 * Multiple 64 bit wide registers can be checked by calling 1556 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN); 1557 */ 1558 void check_cp1_registers(DisasContext *ctx, int regs) 1559 { 1560 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1))) { 1561 gen_reserved_instruction(ctx); 1562 } 1563 } 1564 1565 /* 1566 * Verify that the processor is running with DSP instructions enabled. 1567 * This is enabled by CP0 Status register MX(24) bit. 1568 */ 1569 static inline void check_dsp(DisasContext *ctx) 1570 { 1571 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) { 1572 if (ctx->insn_flags & ASE_DSP) { 1573 generate_exception_end(ctx, EXCP_DSPDIS); 1574 } else { 1575 gen_reserved_instruction(ctx); 1576 } 1577 } 1578 } 1579 1580 static inline void check_dsp_r2(DisasContext *ctx) 1581 { 1582 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R2))) { 1583 if (ctx->insn_flags & ASE_DSP) { 1584 generate_exception_end(ctx, EXCP_DSPDIS); 1585 } else { 1586 gen_reserved_instruction(ctx); 1587 } 1588 } 1589 } 1590 1591 static inline void check_dsp_r3(DisasContext *ctx) 1592 { 1593 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R3))) { 1594 if (ctx->insn_flags & ASE_DSP) { 1595 generate_exception_end(ctx, EXCP_DSPDIS); 1596 } else { 1597 gen_reserved_instruction(ctx); 1598 } 1599 } 1600 } 1601 1602 /* 1603 * This code generates a "reserved instruction" exception if the 1604 * CPU does not support the instruction set corresponding to flags. 1605 */ 1606 void check_insn(DisasContext *ctx, uint64_t flags) 1607 { 1608 if (unlikely(!(ctx->insn_flags & flags))) { 1609 gen_reserved_instruction(ctx); 1610 } 1611 } 1612 1613 /* 1614 * This code generates a "reserved instruction" exception if the 1615 * CPU has corresponding flag set which indicates that the instruction 1616 * has been removed. 1617 */ 1618 static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags) 1619 { 1620 if (unlikely(ctx->insn_flags & flags)) { 1621 gen_reserved_instruction(ctx); 1622 } 1623 } 1624 1625 /* 1626 * The Linux kernel traps certain reserved instruction exceptions to 1627 * emulate the corresponding instructions. QEMU is the kernel in user 1628 * mode, so those traps are emulated by accepting the instructions. 1629 * 1630 * A reserved instruction exception is generated for flagged CPUs if 1631 * QEMU runs in system mode. 1632 */ 1633 static inline void check_insn_opc_user_only(DisasContext *ctx, uint64_t flags) 1634 { 1635 #ifndef CONFIG_USER_ONLY 1636 check_insn_opc_removed(ctx, flags); 1637 #endif 1638 } 1639 1640 /* 1641 * This code generates a "reserved instruction" exception if the 1642 * CPU does not support 64-bit paired-single (PS) floating point data type. 1643 */ 1644 static inline void check_ps(DisasContext *ctx) 1645 { 1646 if (unlikely(!ctx->ps)) { 1647 generate_exception(ctx, EXCP_RI); 1648 } 1649 check_cp1_64bitmode(ctx); 1650 } 1651 1652 /* 1653 * This code generates a "reserved instruction" exception if cpu is not 1654 * 64-bit or 64-bit instructions are not enabled. 1655 */ 1656 void check_mips_64(DisasContext *ctx) 1657 { 1658 if (unlikely((TARGET_LONG_BITS != 64) || !(ctx->hflags & MIPS_HFLAG_64))) { 1659 gen_reserved_instruction(ctx); 1660 } 1661 } 1662 1663 #ifndef CONFIG_USER_ONLY 1664 static inline void check_mvh(DisasContext *ctx) 1665 { 1666 if (unlikely(!ctx->mvh)) { 1667 generate_exception(ctx, EXCP_RI); 1668 } 1669 } 1670 #endif 1671 1672 /* 1673 * This code generates a "reserved instruction" exception if the 1674 * Config5 XNP bit is set. 1675 */ 1676 static inline void check_xnp(DisasContext *ctx) 1677 { 1678 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_XNP))) { 1679 gen_reserved_instruction(ctx); 1680 } 1681 } 1682 1683 #ifndef CONFIG_USER_ONLY 1684 /* 1685 * This code generates a "reserved instruction" exception if the 1686 * Config3 PW bit is NOT set. 1687 */ 1688 static inline void check_pw(DisasContext *ctx) 1689 { 1690 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_PW)))) { 1691 gen_reserved_instruction(ctx); 1692 } 1693 } 1694 #endif 1695 1696 /* 1697 * This code generates a "reserved instruction" exception if the 1698 * Config3 MT bit is NOT set. 1699 */ 1700 static inline void check_mt(DisasContext *ctx) 1701 { 1702 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) { 1703 gen_reserved_instruction(ctx); 1704 } 1705 } 1706 1707 #ifndef CONFIG_USER_ONLY 1708 /* 1709 * This code generates a "coprocessor unusable" exception if CP0 is not 1710 * available, and, if that is not the case, generates a "reserved instruction" 1711 * exception if the Config5 MT bit is NOT set. This is needed for availability 1712 * control of some of MT ASE instructions. 1713 */ 1714 static inline void check_cp0_mt(DisasContext *ctx) 1715 { 1716 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) { 1717 generate_exception_end(ctx, EXCP_CpU); 1718 } else { 1719 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) { 1720 gen_reserved_instruction(ctx); 1721 } 1722 } 1723 } 1724 #endif 1725 1726 /* 1727 * This code generates a "reserved instruction" exception if the 1728 * Config5 NMS bit is set. 1729 */ 1730 static inline void check_nms(DisasContext *ctx) 1731 { 1732 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS))) { 1733 gen_reserved_instruction(ctx); 1734 } 1735 } 1736 1737 /* 1738 * This code generates a "reserved instruction" exception if the 1739 * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL, 1740 * Config2 TL, and Config5 L2C are unset. 1741 */ 1742 static inline void check_nms_dl_il_sl_tl_l2c(DisasContext *ctx) 1743 { 1744 if (unlikely((ctx->CP0_Config5 & (1 << CP0C5_NMS)) && 1745 !(ctx->CP0_Config1 & (1 << CP0C1_DL)) && 1746 !(ctx->CP0_Config1 & (1 << CP0C1_IL)) && 1747 !(ctx->CP0_Config2 & (1 << CP0C2_SL)) && 1748 !(ctx->CP0_Config2 & (1 << CP0C2_TL)) && 1749 !(ctx->CP0_Config5 & (1 << CP0C5_L2C)))) { 1750 gen_reserved_instruction(ctx); 1751 } 1752 } 1753 1754 /* 1755 * This code generates a "reserved instruction" exception if the 1756 * Config5 EVA bit is NOT set. 1757 */ 1758 static inline void check_eva(DisasContext *ctx) 1759 { 1760 if (unlikely(!(ctx->CP0_Config5 & (1 << CP0C5_EVA)))) { 1761 gen_reserved_instruction(ctx); 1762 } 1763 } 1764 1765 1766 /* 1767 * Define small wrappers for gen_load_fpr* so that we have a uniform 1768 * calling interface for 32 and 64-bit FPRs. No sense in changing 1769 * all callers for gen_load_fpr32 when we need the CTX parameter for 1770 * this one use. 1771 */ 1772 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y) 1773 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y) 1774 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \ 1775 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \ 1776 int ft, int fs, int cc) \ 1777 { \ 1778 TCGv_i##bits fp0 = tcg_temp_new_i##bits(); \ 1779 TCGv_i##bits fp1 = tcg_temp_new_i##bits(); \ 1780 switch (ifmt) { \ 1781 case FMT_PS: \ 1782 check_ps(ctx); \ 1783 break; \ 1784 case FMT_D: \ 1785 if (abs) { \ 1786 check_cop1x(ctx); \ 1787 } \ 1788 check_cp1_registers(ctx, fs | ft); \ 1789 break; \ 1790 case FMT_S: \ 1791 if (abs) { \ 1792 check_cop1x(ctx); \ 1793 } \ 1794 break; \ 1795 } \ 1796 gen_ldcmp_fpr##bits(ctx, fp0, fs); \ 1797 gen_ldcmp_fpr##bits(ctx, fp1, ft); \ 1798 switch (n) { \ 1799 case 0: \ 1800 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); \ 1801 break; \ 1802 case 1: \ 1803 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); \ 1804 break; \ 1805 case 2: \ 1806 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); \ 1807 break; \ 1808 case 3: \ 1809 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); \ 1810 break; \ 1811 case 4: \ 1812 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); \ 1813 break; \ 1814 case 5: \ 1815 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); \ 1816 break; \ 1817 case 6: \ 1818 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); \ 1819 break; \ 1820 case 7: \ 1821 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); \ 1822 break; \ 1823 case 8: \ 1824 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); \ 1825 break; \ 1826 case 9: \ 1827 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); \ 1828 break; \ 1829 case 10: \ 1830 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); \ 1831 break; \ 1832 case 11: \ 1833 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); \ 1834 break; \ 1835 case 12: \ 1836 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); \ 1837 break; \ 1838 case 13: \ 1839 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); \ 1840 break; \ 1841 case 14: \ 1842 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); \ 1843 break; \ 1844 case 15: \ 1845 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); \ 1846 break; \ 1847 default: \ 1848 abort(); \ 1849 } \ 1850 } 1851 1852 FOP_CONDS(, 0, d, FMT_D, 64) 1853 FOP_CONDS(abs, 1, d, FMT_D, 64) 1854 FOP_CONDS(, 0, s, FMT_S, 32) 1855 FOP_CONDS(abs, 1, s, FMT_S, 32) 1856 FOP_CONDS(, 0, ps, FMT_PS, 64) 1857 FOP_CONDS(abs, 1, ps, FMT_PS, 64) 1858 #undef FOP_CONDS 1859 1860 #define FOP_CONDNS(fmt, ifmt, bits, STORE) \ 1861 static inline void gen_r6_cmp_ ## fmt(DisasContext *ctx, int n, \ 1862 int ft, int fs, int fd) \ 1863 { \ 1864 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \ 1865 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \ 1866 if (ifmt == FMT_D) { \ 1867 check_cp1_registers(ctx, fs | ft | fd); \ 1868 } \ 1869 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \ 1870 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \ 1871 switch (n) { \ 1872 case 0: \ 1873 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \ 1874 break; \ 1875 case 1: \ 1876 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \ 1877 break; \ 1878 case 2: \ 1879 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \ 1880 break; \ 1881 case 3: \ 1882 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \ 1883 break; \ 1884 case 4: \ 1885 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \ 1886 break; \ 1887 case 5: \ 1888 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \ 1889 break; \ 1890 case 6: \ 1891 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \ 1892 break; \ 1893 case 7: \ 1894 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \ 1895 break; \ 1896 case 8: \ 1897 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \ 1898 break; \ 1899 case 9: \ 1900 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \ 1901 break; \ 1902 case 10: \ 1903 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \ 1904 break; \ 1905 case 11: \ 1906 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \ 1907 break; \ 1908 case 12: \ 1909 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \ 1910 break; \ 1911 case 13: \ 1912 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \ 1913 break; \ 1914 case 14: \ 1915 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \ 1916 break; \ 1917 case 15: \ 1918 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \ 1919 break; \ 1920 case 17: \ 1921 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \ 1922 break; \ 1923 case 18: \ 1924 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \ 1925 break; \ 1926 case 19: \ 1927 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \ 1928 break; \ 1929 case 25: \ 1930 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \ 1931 break; \ 1932 case 26: \ 1933 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \ 1934 break; \ 1935 case 27: \ 1936 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \ 1937 break; \ 1938 default: \ 1939 abort(); \ 1940 } \ 1941 STORE; \ 1942 } 1943 1944 FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd)) 1945 FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd)) 1946 #undef FOP_CONDNS 1947 #undef gen_ldcmp_fpr32 1948 #undef gen_ldcmp_fpr64 1949 1950 /* load/store instructions. */ 1951 #ifdef CONFIG_USER_ONLY 1952 #define OP_LD_ATOMIC(insn, memop) \ 1953 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \ 1954 DisasContext *ctx) \ 1955 { \ 1956 TCGv t0 = tcg_temp_new(); \ 1957 tcg_gen_mov_tl(t0, arg1); \ 1958 tcg_gen_qemu_ld_tl(ret, arg1, ctx->mem_idx, memop); \ 1959 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \ 1960 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \ 1961 } 1962 #else 1963 #define OP_LD_ATOMIC(insn, fname) \ 1964 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \ 1965 DisasContext *ctx) \ 1966 { \ 1967 gen_helper_##insn(ret, cpu_env, arg1, tcg_constant_i32(mem_idx)); \ 1968 } 1969 #endif 1970 OP_LD_ATOMIC(ll, MO_TESL); 1971 #if defined(TARGET_MIPS64) 1972 OP_LD_ATOMIC(lld, MO_TEUQ); 1973 #endif 1974 #undef OP_LD_ATOMIC 1975 1976 void gen_base_offset_addr(DisasContext *ctx, TCGv addr, int base, int offset) 1977 { 1978 if (base == 0) { 1979 tcg_gen_movi_tl(addr, offset); 1980 } else if (offset == 0) { 1981 gen_load_gpr(addr, base); 1982 } else { 1983 tcg_gen_movi_tl(addr, offset); 1984 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr); 1985 } 1986 } 1987 1988 static target_ulong pc_relative_pc(DisasContext *ctx) 1989 { 1990 target_ulong pc = ctx->base.pc_next; 1991 1992 if (ctx->hflags & MIPS_HFLAG_BMASK) { 1993 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4; 1994 1995 pc -= branch_bytes; 1996 } 1997 1998 pc &= ~(target_ulong)3; 1999 return pc; 2000 } 2001 2002 /* LWL or LDL, depending on MemOp. */ 2003 static void gen_lxl(DisasContext *ctx, TCGv reg, TCGv addr, 2004 int mem_idx, MemOp mop) 2005 { 2006 int sizem1 = memop_size(mop) - 1; 2007 TCGv t0 = tcg_temp_new(); 2008 TCGv t1 = tcg_temp_new(); 2009 2010 /* 2011 * Do a byte access to possibly trigger a page 2012 * fault with the unaligned address. 2013 */ 2014 tcg_gen_qemu_ld_tl(t1, addr, mem_idx, MO_UB); 2015 tcg_gen_andi_tl(t1, addr, sizem1); 2016 if (!cpu_is_bigendian(ctx)) { 2017 tcg_gen_xori_tl(t1, t1, sizem1); 2018 } 2019 tcg_gen_shli_tl(t1, t1, 3); 2020 tcg_gen_andi_tl(t0, addr, ~sizem1); 2021 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mop); 2022 tcg_gen_shl_tl(t0, t0, t1); 2023 tcg_gen_shl_tl(t1, tcg_constant_tl(-1), t1); 2024 tcg_gen_andc_tl(t1, reg, t1); 2025 tcg_gen_or_tl(reg, t0, t1); 2026 } 2027 2028 /* LWR or LDR, depending on MemOp. */ 2029 static void gen_lxr(DisasContext *ctx, TCGv reg, TCGv addr, 2030 int mem_idx, MemOp mop) 2031 { 2032 int size = memop_size(mop); 2033 int sizem1 = size - 1; 2034 TCGv t0 = tcg_temp_new(); 2035 TCGv t1 = tcg_temp_new(); 2036 2037 /* 2038 * Do a byte access to possibly trigger a page 2039 * fault with the unaligned address. 2040 */ 2041 tcg_gen_qemu_ld_tl(t1, addr, mem_idx, MO_UB); 2042 tcg_gen_andi_tl(t1, addr, sizem1); 2043 if (cpu_is_bigendian(ctx)) { 2044 tcg_gen_xori_tl(t1, t1, sizem1); 2045 } 2046 tcg_gen_shli_tl(t1, t1, 3); 2047 tcg_gen_andi_tl(t0, addr, ~sizem1); 2048 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mop); 2049 tcg_gen_shr_tl(t0, t0, t1); 2050 tcg_gen_xori_tl(t1, t1, size * 8 - 1); 2051 tcg_gen_shl_tl(t1, tcg_constant_tl(~1), t1); 2052 tcg_gen_and_tl(t1, reg, t1); 2053 tcg_gen_or_tl(reg, t0, t1); 2054 } 2055 2056 /* Load */ 2057 static void gen_ld(DisasContext *ctx, uint32_t opc, 2058 int rt, int base, int offset) 2059 { 2060 TCGv t0, t1; 2061 int mem_idx = ctx->mem_idx; 2062 2063 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F | 2064 INSN_LOONGSON3A)) { 2065 /* 2066 * Loongson CPU uses a load to zero register for prefetch. 2067 * We emulate it as a NOP. On other CPU we must perform the 2068 * actual memory access. 2069 */ 2070 return; 2071 } 2072 2073 t0 = tcg_temp_new(); 2074 gen_base_offset_addr(ctx, t0, base, offset); 2075 2076 switch (opc) { 2077 #if defined(TARGET_MIPS64) 2078 case OPC_LWU: 2079 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL | 2080 ctx->default_tcg_memop_mask); 2081 gen_store_gpr(t0, rt); 2082 break; 2083 case OPC_LD: 2084 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUQ | 2085 ctx->default_tcg_memop_mask); 2086 gen_store_gpr(t0, rt); 2087 break; 2088 case OPC_LLD: 2089 case R6_OPC_LLD: 2090 op_ld_lld(t0, t0, mem_idx, ctx); 2091 gen_store_gpr(t0, rt); 2092 break; 2093 case OPC_LDL: 2094 t1 = tcg_temp_new(); 2095 gen_load_gpr(t1, rt); 2096 gen_lxl(ctx, t1, t0, mem_idx, MO_TEUQ); 2097 gen_store_gpr(t1, rt); 2098 break; 2099 case OPC_LDR: 2100 t1 = tcg_temp_new(); 2101 gen_load_gpr(t1, rt); 2102 gen_lxr(ctx, t1, t0, mem_idx, MO_TEUQ); 2103 gen_store_gpr(t1, rt); 2104 break; 2105 case OPC_LDPC: 2106 t1 = tcg_constant_tl(pc_relative_pc(ctx)); 2107 gen_op_addr_add(ctx, t0, t0, t1); 2108 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUQ); 2109 gen_store_gpr(t0, rt); 2110 break; 2111 #endif 2112 case OPC_LWPC: 2113 t1 = tcg_constant_tl(pc_relative_pc(ctx)); 2114 gen_op_addr_add(ctx, t0, t0, t1); 2115 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL); 2116 gen_store_gpr(t0, rt); 2117 break; 2118 case OPC_LWE: 2119 mem_idx = MIPS_HFLAG_UM; 2120 /* fall through */ 2121 case OPC_LW: 2122 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL | 2123 ctx->default_tcg_memop_mask); 2124 gen_store_gpr(t0, rt); 2125 break; 2126 case OPC_LHE: 2127 mem_idx = MIPS_HFLAG_UM; 2128 /* fall through */ 2129 case OPC_LH: 2130 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW | 2131 ctx->default_tcg_memop_mask); 2132 gen_store_gpr(t0, rt); 2133 break; 2134 case OPC_LHUE: 2135 mem_idx = MIPS_HFLAG_UM; 2136 /* fall through */ 2137 case OPC_LHU: 2138 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW | 2139 ctx->default_tcg_memop_mask); 2140 gen_store_gpr(t0, rt); 2141 break; 2142 case OPC_LBE: 2143 mem_idx = MIPS_HFLAG_UM; 2144 /* fall through */ 2145 case OPC_LB: 2146 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB); 2147 gen_store_gpr(t0, rt); 2148 break; 2149 case OPC_LBUE: 2150 mem_idx = MIPS_HFLAG_UM; 2151 /* fall through */ 2152 case OPC_LBU: 2153 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB); 2154 gen_store_gpr(t0, rt); 2155 break; 2156 case OPC_LWLE: 2157 mem_idx = MIPS_HFLAG_UM; 2158 /* fall through */ 2159 case OPC_LWL: 2160 t1 = tcg_temp_new(); 2161 gen_load_gpr(t1, rt); 2162 gen_lxl(ctx, t1, t0, mem_idx, MO_TEUL); 2163 tcg_gen_ext32s_tl(t1, t1); 2164 gen_store_gpr(t1, rt); 2165 break; 2166 case OPC_LWRE: 2167 mem_idx = MIPS_HFLAG_UM; 2168 /* fall through */ 2169 case OPC_LWR: 2170 t1 = tcg_temp_new(); 2171 gen_load_gpr(t1, rt); 2172 gen_lxr(ctx, t1, t0, mem_idx, MO_TEUL); 2173 tcg_gen_ext32s_tl(t1, t1); 2174 gen_store_gpr(t1, rt); 2175 break; 2176 case OPC_LLE: 2177 mem_idx = MIPS_HFLAG_UM; 2178 /* fall through */ 2179 case OPC_LL: 2180 case R6_OPC_LL: 2181 op_ld_ll(t0, t0, mem_idx, ctx); 2182 gen_store_gpr(t0, rt); 2183 break; 2184 } 2185 } 2186 2187 /* Store */ 2188 static void gen_st(DisasContext *ctx, uint32_t opc, int rt, 2189 int base, int offset) 2190 { 2191 TCGv t0 = tcg_temp_new(); 2192 TCGv t1 = tcg_temp_new(); 2193 int mem_idx = ctx->mem_idx; 2194 2195 gen_base_offset_addr(ctx, t0, base, offset); 2196 gen_load_gpr(t1, rt); 2197 switch (opc) { 2198 #if defined(TARGET_MIPS64) 2199 case OPC_SD: 2200 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUQ | 2201 ctx->default_tcg_memop_mask); 2202 break; 2203 case OPC_SDL: 2204 gen_helper_0e2i(sdl, t1, t0, mem_idx); 2205 break; 2206 case OPC_SDR: 2207 gen_helper_0e2i(sdr, t1, t0, mem_idx); 2208 break; 2209 #endif 2210 case OPC_SWE: 2211 mem_idx = MIPS_HFLAG_UM; 2212 /* fall through */ 2213 case OPC_SW: 2214 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL | 2215 ctx->default_tcg_memop_mask); 2216 break; 2217 case OPC_SHE: 2218 mem_idx = MIPS_HFLAG_UM; 2219 /* fall through */ 2220 case OPC_SH: 2221 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW | 2222 ctx->default_tcg_memop_mask); 2223 break; 2224 case OPC_SBE: 2225 mem_idx = MIPS_HFLAG_UM; 2226 /* fall through */ 2227 case OPC_SB: 2228 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8); 2229 break; 2230 case OPC_SWLE: 2231 mem_idx = MIPS_HFLAG_UM; 2232 /* fall through */ 2233 case OPC_SWL: 2234 gen_helper_0e2i(swl, t1, t0, mem_idx); 2235 break; 2236 case OPC_SWRE: 2237 mem_idx = MIPS_HFLAG_UM; 2238 /* fall through */ 2239 case OPC_SWR: 2240 gen_helper_0e2i(swr, t1, t0, mem_idx); 2241 break; 2242 } 2243 } 2244 2245 2246 /* Store conditional */ 2247 static void gen_st_cond(DisasContext *ctx, int rt, int base, int offset, 2248 MemOp tcg_mo, bool eva) 2249 { 2250 TCGv addr, t0, val; 2251 TCGLabel *l1 = gen_new_label(); 2252 TCGLabel *done = gen_new_label(); 2253 2254 t0 = tcg_temp_new(); 2255 addr = tcg_temp_new(); 2256 /* compare the address against that of the preceding LL */ 2257 gen_base_offset_addr(ctx, addr, base, offset); 2258 tcg_gen_brcond_tl(TCG_COND_EQ, addr, cpu_lladdr, l1); 2259 tcg_gen_movi_tl(t0, 0); 2260 gen_store_gpr(t0, rt); 2261 tcg_gen_br(done); 2262 2263 gen_set_label(l1); 2264 /* generate cmpxchg */ 2265 val = tcg_temp_new(); 2266 gen_load_gpr(val, rt); 2267 tcg_gen_atomic_cmpxchg_tl(t0, cpu_lladdr, cpu_llval, val, 2268 eva ? MIPS_HFLAG_UM : ctx->mem_idx, tcg_mo); 2269 tcg_gen_setcond_tl(TCG_COND_EQ, t0, t0, cpu_llval); 2270 gen_store_gpr(t0, rt); 2271 2272 gen_set_label(done); 2273 } 2274 2275 /* Load and store */ 2276 static void gen_flt_ldst(DisasContext *ctx, uint32_t opc, int ft, 2277 TCGv t0) 2278 { 2279 /* 2280 * Don't do NOP if destination is zero: we must perform the actual 2281 * memory access. 2282 */ 2283 switch (opc) { 2284 case OPC_LWC1: 2285 { 2286 TCGv_i32 fp0 = tcg_temp_new_i32(); 2287 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL | 2288 ctx->default_tcg_memop_mask); 2289 gen_store_fpr32(ctx, fp0, ft); 2290 } 2291 break; 2292 case OPC_SWC1: 2293 { 2294 TCGv_i32 fp0 = tcg_temp_new_i32(); 2295 gen_load_fpr32(ctx, fp0, ft); 2296 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL | 2297 ctx->default_tcg_memop_mask); 2298 } 2299 break; 2300 case OPC_LDC1: 2301 { 2302 TCGv_i64 fp0 = tcg_temp_new_i64(); 2303 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEUQ | 2304 ctx->default_tcg_memop_mask); 2305 gen_store_fpr64(ctx, fp0, ft); 2306 } 2307 break; 2308 case OPC_SDC1: 2309 { 2310 TCGv_i64 fp0 = tcg_temp_new_i64(); 2311 gen_load_fpr64(ctx, fp0, ft); 2312 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEUQ | 2313 ctx->default_tcg_memop_mask); 2314 } 2315 break; 2316 default: 2317 MIPS_INVAL("flt_ldst"); 2318 gen_reserved_instruction(ctx); 2319 break; 2320 } 2321 } 2322 2323 static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt, 2324 int rs, int16_t imm) 2325 { 2326 TCGv t0 = tcg_temp_new(); 2327 2328 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) { 2329 check_cp1_enabled(ctx); 2330 switch (op) { 2331 case OPC_LDC1: 2332 case OPC_SDC1: 2333 check_insn(ctx, ISA_MIPS2); 2334 /* Fallthrough */ 2335 default: 2336 gen_base_offset_addr(ctx, t0, rs, imm); 2337 gen_flt_ldst(ctx, op, rt, t0); 2338 } 2339 } else { 2340 generate_exception_err(ctx, EXCP_CpU, 1); 2341 } 2342 } 2343 2344 /* Arithmetic with immediate operand */ 2345 static void gen_arith_imm(DisasContext *ctx, uint32_t opc, 2346 int rt, int rs, int imm) 2347 { 2348 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */ 2349 2350 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) { 2351 /* 2352 * If no destination, treat it as a NOP. 2353 * For addi, we must generate the overflow exception when needed. 2354 */ 2355 return; 2356 } 2357 switch (opc) { 2358 case OPC_ADDI: 2359 { 2360 TCGv t0 = tcg_temp_new(); 2361 TCGv t1 = tcg_temp_new(); 2362 TCGv t2 = tcg_temp_new(); 2363 TCGLabel *l1 = gen_new_label(); 2364 2365 gen_load_gpr(t1, rs); 2366 tcg_gen_addi_tl(t0, t1, uimm); 2367 tcg_gen_ext32s_tl(t0, t0); 2368 2369 tcg_gen_xori_tl(t1, t1, ~uimm); 2370 tcg_gen_xori_tl(t2, t0, uimm); 2371 tcg_gen_and_tl(t1, t1, t2); 2372 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2373 /* operands of same sign, result different sign */ 2374 generate_exception(ctx, EXCP_OVERFLOW); 2375 gen_set_label(l1); 2376 tcg_gen_ext32s_tl(t0, t0); 2377 gen_store_gpr(t0, rt); 2378 } 2379 break; 2380 case OPC_ADDIU: 2381 if (rs != 0) { 2382 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 2383 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 2384 } else { 2385 tcg_gen_movi_tl(cpu_gpr[rt], uimm); 2386 } 2387 break; 2388 #if defined(TARGET_MIPS64) 2389 case OPC_DADDI: 2390 { 2391 TCGv t0 = tcg_temp_new(); 2392 TCGv t1 = tcg_temp_new(); 2393 TCGv t2 = tcg_temp_new(); 2394 TCGLabel *l1 = gen_new_label(); 2395 2396 gen_load_gpr(t1, rs); 2397 tcg_gen_addi_tl(t0, t1, uimm); 2398 2399 tcg_gen_xori_tl(t1, t1, ~uimm); 2400 tcg_gen_xori_tl(t2, t0, uimm); 2401 tcg_gen_and_tl(t1, t1, t2); 2402 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2403 /* operands of same sign, result different sign */ 2404 generate_exception(ctx, EXCP_OVERFLOW); 2405 gen_set_label(l1); 2406 gen_store_gpr(t0, rt); 2407 } 2408 break; 2409 case OPC_DADDIU: 2410 if (rs != 0) { 2411 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 2412 } else { 2413 tcg_gen_movi_tl(cpu_gpr[rt], uimm); 2414 } 2415 break; 2416 #endif 2417 } 2418 } 2419 2420 /* Logic with immediate operand */ 2421 static void gen_logic_imm(DisasContext *ctx, uint32_t opc, 2422 int rt, int rs, int16_t imm) 2423 { 2424 target_ulong uimm; 2425 2426 if (rt == 0) { 2427 /* If no destination, treat it as a NOP. */ 2428 return; 2429 } 2430 uimm = (uint16_t)imm; 2431 switch (opc) { 2432 case OPC_ANDI: 2433 if (likely(rs != 0)) { 2434 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 2435 } else { 2436 tcg_gen_movi_tl(cpu_gpr[rt], 0); 2437 } 2438 break; 2439 case OPC_ORI: 2440 if (rs != 0) { 2441 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 2442 } else { 2443 tcg_gen_movi_tl(cpu_gpr[rt], uimm); 2444 } 2445 break; 2446 case OPC_XORI: 2447 if (likely(rs != 0)) { 2448 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 2449 } else { 2450 tcg_gen_movi_tl(cpu_gpr[rt], uimm); 2451 } 2452 break; 2453 case OPC_LUI: 2454 if (rs != 0 && (ctx->insn_flags & ISA_MIPS_R6)) { 2455 /* OPC_AUI */ 2456 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16); 2457 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 2458 } else { 2459 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16); 2460 } 2461 break; 2462 2463 default: 2464 break; 2465 } 2466 } 2467 2468 /* Set on less than with immediate operand */ 2469 static void gen_slt_imm(DisasContext *ctx, uint32_t opc, 2470 int rt, int rs, int16_t imm) 2471 { 2472 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */ 2473 TCGv t0; 2474 2475 if (rt == 0) { 2476 /* If no destination, treat it as a NOP. */ 2477 return; 2478 } 2479 t0 = tcg_temp_new(); 2480 gen_load_gpr(t0, rs); 2481 switch (opc) { 2482 case OPC_SLTI: 2483 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm); 2484 break; 2485 case OPC_SLTIU: 2486 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm); 2487 break; 2488 } 2489 } 2490 2491 /* Shifts with immediate operand */ 2492 static void gen_shift_imm(DisasContext *ctx, uint32_t opc, 2493 int rt, int rs, int16_t imm) 2494 { 2495 target_ulong uimm = ((uint16_t)imm) & 0x1f; 2496 TCGv t0; 2497 2498 if (rt == 0) { 2499 /* If no destination, treat it as a NOP. */ 2500 return; 2501 } 2502 2503 t0 = tcg_temp_new(); 2504 gen_load_gpr(t0, rs); 2505 switch (opc) { 2506 case OPC_SLL: 2507 tcg_gen_shli_tl(t0, t0, uimm); 2508 tcg_gen_ext32s_tl(cpu_gpr[rt], t0); 2509 break; 2510 case OPC_SRA: 2511 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm); 2512 break; 2513 case OPC_SRL: 2514 if (uimm != 0) { 2515 tcg_gen_ext32u_tl(t0, t0); 2516 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm); 2517 } else { 2518 tcg_gen_ext32s_tl(cpu_gpr[rt], t0); 2519 } 2520 break; 2521 case OPC_ROTR: 2522 if (uimm != 0) { 2523 TCGv_i32 t1 = tcg_temp_new_i32(); 2524 2525 tcg_gen_trunc_tl_i32(t1, t0); 2526 tcg_gen_rotri_i32(t1, t1, uimm); 2527 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1); 2528 } else { 2529 tcg_gen_ext32s_tl(cpu_gpr[rt], t0); 2530 } 2531 break; 2532 #if defined(TARGET_MIPS64) 2533 case OPC_DSLL: 2534 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm); 2535 break; 2536 case OPC_DSRA: 2537 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm); 2538 break; 2539 case OPC_DSRL: 2540 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm); 2541 break; 2542 case OPC_DROTR: 2543 if (uimm != 0) { 2544 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm); 2545 } else { 2546 tcg_gen_mov_tl(cpu_gpr[rt], t0); 2547 } 2548 break; 2549 case OPC_DSLL32: 2550 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32); 2551 break; 2552 case OPC_DSRA32: 2553 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32); 2554 break; 2555 case OPC_DSRL32: 2556 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32); 2557 break; 2558 case OPC_DROTR32: 2559 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32); 2560 break; 2561 #endif 2562 } 2563 } 2564 2565 /* Arithmetic */ 2566 static void gen_arith(DisasContext *ctx, uint32_t opc, 2567 int rd, int rs, int rt) 2568 { 2569 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB 2570 && opc != OPC_DADD && opc != OPC_DSUB) { 2571 /* 2572 * If no destination, treat it as a NOP. 2573 * For add & sub, we must generate the overflow exception when needed. 2574 */ 2575 return; 2576 } 2577 2578 switch (opc) { 2579 case OPC_ADD: 2580 { 2581 TCGv t0 = tcg_temp_new(); 2582 TCGv t1 = tcg_temp_new(); 2583 TCGv t2 = tcg_temp_new(); 2584 TCGLabel *l1 = gen_new_label(); 2585 2586 gen_load_gpr(t1, rs); 2587 gen_load_gpr(t2, rt); 2588 tcg_gen_add_tl(t0, t1, t2); 2589 tcg_gen_ext32s_tl(t0, t0); 2590 tcg_gen_xor_tl(t1, t1, t2); 2591 tcg_gen_xor_tl(t2, t0, t2); 2592 tcg_gen_andc_tl(t1, t2, t1); 2593 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2594 /* operands of same sign, result different sign */ 2595 generate_exception(ctx, EXCP_OVERFLOW); 2596 gen_set_label(l1); 2597 gen_store_gpr(t0, rd); 2598 } 2599 break; 2600 case OPC_ADDU: 2601 if (rs != 0 && rt != 0) { 2602 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2603 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 2604 } else if (rs == 0 && rt != 0) { 2605 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); 2606 } else if (rs != 0 && rt == 0) { 2607 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2608 } else { 2609 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2610 } 2611 break; 2612 case OPC_SUB: 2613 { 2614 TCGv t0 = tcg_temp_new(); 2615 TCGv t1 = tcg_temp_new(); 2616 TCGv t2 = tcg_temp_new(); 2617 TCGLabel *l1 = gen_new_label(); 2618 2619 gen_load_gpr(t1, rs); 2620 gen_load_gpr(t2, rt); 2621 tcg_gen_sub_tl(t0, t1, t2); 2622 tcg_gen_ext32s_tl(t0, t0); 2623 tcg_gen_xor_tl(t2, t1, t2); 2624 tcg_gen_xor_tl(t1, t0, t1); 2625 tcg_gen_and_tl(t1, t1, t2); 2626 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2627 /* 2628 * operands of different sign, first operand and the result 2629 * of different sign 2630 */ 2631 generate_exception(ctx, EXCP_OVERFLOW); 2632 gen_set_label(l1); 2633 gen_store_gpr(t0, rd); 2634 } 2635 break; 2636 case OPC_SUBU: 2637 if (rs != 0 && rt != 0) { 2638 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2639 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 2640 } else if (rs == 0 && rt != 0) { 2641 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]); 2642 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 2643 } else if (rs != 0 && rt == 0) { 2644 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2645 } else { 2646 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2647 } 2648 break; 2649 #if defined(TARGET_MIPS64) 2650 case OPC_DADD: 2651 { 2652 TCGv t0 = tcg_temp_new(); 2653 TCGv t1 = tcg_temp_new(); 2654 TCGv t2 = tcg_temp_new(); 2655 TCGLabel *l1 = gen_new_label(); 2656 2657 gen_load_gpr(t1, rs); 2658 gen_load_gpr(t2, rt); 2659 tcg_gen_add_tl(t0, t1, t2); 2660 tcg_gen_xor_tl(t1, t1, t2); 2661 tcg_gen_xor_tl(t2, t0, t2); 2662 tcg_gen_andc_tl(t1, t2, t1); 2663 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2664 /* operands of same sign, result different sign */ 2665 generate_exception(ctx, EXCP_OVERFLOW); 2666 gen_set_label(l1); 2667 gen_store_gpr(t0, rd); 2668 } 2669 break; 2670 case OPC_DADDU: 2671 if (rs != 0 && rt != 0) { 2672 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2673 } else if (rs == 0 && rt != 0) { 2674 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); 2675 } else if (rs != 0 && rt == 0) { 2676 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2677 } else { 2678 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2679 } 2680 break; 2681 case OPC_DSUB: 2682 { 2683 TCGv t0 = tcg_temp_new(); 2684 TCGv t1 = tcg_temp_new(); 2685 TCGv t2 = tcg_temp_new(); 2686 TCGLabel *l1 = gen_new_label(); 2687 2688 gen_load_gpr(t1, rs); 2689 gen_load_gpr(t2, rt); 2690 tcg_gen_sub_tl(t0, t1, t2); 2691 tcg_gen_xor_tl(t2, t1, t2); 2692 tcg_gen_xor_tl(t1, t0, t1); 2693 tcg_gen_and_tl(t1, t1, t2); 2694 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2695 /* 2696 * Operands of different sign, first operand and result different 2697 * sign. 2698 */ 2699 generate_exception(ctx, EXCP_OVERFLOW); 2700 gen_set_label(l1); 2701 gen_store_gpr(t0, rd); 2702 } 2703 break; 2704 case OPC_DSUBU: 2705 if (rs != 0 && rt != 0) { 2706 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2707 } else if (rs == 0 && rt != 0) { 2708 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]); 2709 } else if (rs != 0 && rt == 0) { 2710 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2711 } else { 2712 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2713 } 2714 break; 2715 #endif 2716 case OPC_MUL: 2717 if (likely(rs != 0 && rt != 0)) { 2718 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2719 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 2720 } else { 2721 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2722 } 2723 break; 2724 } 2725 } 2726 2727 /* Conditional move */ 2728 static void gen_cond_move(DisasContext *ctx, uint32_t opc, 2729 int rd, int rs, int rt) 2730 { 2731 TCGv t0, t1, t2; 2732 2733 if (rd == 0) { 2734 /* If no destination, treat it as a NOP. */ 2735 return; 2736 } 2737 2738 t0 = tcg_temp_new(); 2739 gen_load_gpr(t0, rt); 2740 t1 = tcg_constant_tl(0); 2741 t2 = tcg_temp_new(); 2742 gen_load_gpr(t2, rs); 2743 switch (opc) { 2744 case OPC_MOVN: 2745 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]); 2746 break; 2747 case OPC_MOVZ: 2748 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]); 2749 break; 2750 case OPC_SELNEZ: 2751 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1); 2752 break; 2753 case OPC_SELEQZ: 2754 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1); 2755 break; 2756 } 2757 } 2758 2759 /* Logic */ 2760 static void gen_logic(DisasContext *ctx, uint32_t opc, 2761 int rd, int rs, int rt) 2762 { 2763 if (rd == 0) { 2764 /* If no destination, treat it as a NOP. */ 2765 return; 2766 } 2767 2768 switch (opc) { 2769 case OPC_AND: 2770 if (likely(rs != 0 && rt != 0)) { 2771 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2772 } else { 2773 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2774 } 2775 break; 2776 case OPC_NOR: 2777 if (rs != 0 && rt != 0) { 2778 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2779 } else if (rs == 0 && rt != 0) { 2780 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]); 2781 } else if (rs != 0 && rt == 0) { 2782 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]); 2783 } else { 2784 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0)); 2785 } 2786 break; 2787 case OPC_OR: 2788 if (likely(rs != 0 && rt != 0)) { 2789 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2790 } else if (rs == 0 && rt != 0) { 2791 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); 2792 } else if (rs != 0 && rt == 0) { 2793 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2794 } else { 2795 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2796 } 2797 break; 2798 case OPC_XOR: 2799 if (likely(rs != 0 && rt != 0)) { 2800 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2801 } else if (rs == 0 && rt != 0) { 2802 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); 2803 } else if (rs != 0 && rt == 0) { 2804 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2805 } else { 2806 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2807 } 2808 break; 2809 } 2810 } 2811 2812 /* Set on lower than */ 2813 static void gen_slt(DisasContext *ctx, uint32_t opc, 2814 int rd, int rs, int rt) 2815 { 2816 TCGv t0, t1; 2817 2818 if (rd == 0) { 2819 /* If no destination, treat it as a NOP. */ 2820 return; 2821 } 2822 2823 t0 = tcg_temp_new(); 2824 t1 = tcg_temp_new(); 2825 gen_load_gpr(t0, rs); 2826 gen_load_gpr(t1, rt); 2827 switch (opc) { 2828 case OPC_SLT: 2829 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1); 2830 break; 2831 case OPC_SLTU: 2832 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1); 2833 break; 2834 } 2835 } 2836 2837 /* Shifts */ 2838 static void gen_shift(DisasContext *ctx, uint32_t opc, 2839 int rd, int rs, int rt) 2840 { 2841 TCGv t0, t1; 2842 2843 if (rd == 0) { 2844 /* 2845 * If no destination, treat it as a NOP. 2846 * For add & sub, we must generate the overflow exception when needed. 2847 */ 2848 return; 2849 } 2850 2851 t0 = tcg_temp_new(); 2852 t1 = tcg_temp_new(); 2853 gen_load_gpr(t0, rs); 2854 gen_load_gpr(t1, rt); 2855 switch (opc) { 2856 case OPC_SLLV: 2857 tcg_gen_andi_tl(t0, t0, 0x1f); 2858 tcg_gen_shl_tl(t0, t1, t0); 2859 tcg_gen_ext32s_tl(cpu_gpr[rd], t0); 2860 break; 2861 case OPC_SRAV: 2862 tcg_gen_andi_tl(t0, t0, 0x1f); 2863 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0); 2864 break; 2865 case OPC_SRLV: 2866 tcg_gen_ext32u_tl(t1, t1); 2867 tcg_gen_andi_tl(t0, t0, 0x1f); 2868 tcg_gen_shr_tl(t0, t1, t0); 2869 tcg_gen_ext32s_tl(cpu_gpr[rd], t0); 2870 break; 2871 case OPC_ROTRV: 2872 { 2873 TCGv_i32 t2 = tcg_temp_new_i32(); 2874 TCGv_i32 t3 = tcg_temp_new_i32(); 2875 2876 tcg_gen_trunc_tl_i32(t2, t0); 2877 tcg_gen_trunc_tl_i32(t3, t1); 2878 tcg_gen_andi_i32(t2, t2, 0x1f); 2879 tcg_gen_rotr_i32(t2, t3, t2); 2880 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 2881 } 2882 break; 2883 #if defined(TARGET_MIPS64) 2884 case OPC_DSLLV: 2885 tcg_gen_andi_tl(t0, t0, 0x3f); 2886 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0); 2887 break; 2888 case OPC_DSRAV: 2889 tcg_gen_andi_tl(t0, t0, 0x3f); 2890 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0); 2891 break; 2892 case OPC_DSRLV: 2893 tcg_gen_andi_tl(t0, t0, 0x3f); 2894 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0); 2895 break; 2896 case OPC_DROTRV: 2897 tcg_gen_andi_tl(t0, t0, 0x3f); 2898 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0); 2899 break; 2900 #endif 2901 } 2902 } 2903 2904 /* Arithmetic on HI/LO registers */ 2905 static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg) 2906 { 2907 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) { 2908 /* Treat as NOP. */ 2909 return; 2910 } 2911 2912 if (acc != 0) { 2913 check_dsp(ctx); 2914 } 2915 2916 switch (opc) { 2917 case OPC_MFHI: 2918 #if defined(TARGET_MIPS64) 2919 if (acc != 0) { 2920 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]); 2921 } else 2922 #endif 2923 { 2924 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]); 2925 } 2926 break; 2927 case OPC_MFLO: 2928 #if defined(TARGET_MIPS64) 2929 if (acc != 0) { 2930 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]); 2931 } else 2932 #endif 2933 { 2934 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]); 2935 } 2936 break; 2937 case OPC_MTHI: 2938 if (reg != 0) { 2939 #if defined(TARGET_MIPS64) 2940 if (acc != 0) { 2941 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]); 2942 } else 2943 #endif 2944 { 2945 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]); 2946 } 2947 } else { 2948 tcg_gen_movi_tl(cpu_HI[acc], 0); 2949 } 2950 break; 2951 case OPC_MTLO: 2952 if (reg != 0) { 2953 #if defined(TARGET_MIPS64) 2954 if (acc != 0) { 2955 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]); 2956 } else 2957 #endif 2958 { 2959 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]); 2960 } 2961 } else { 2962 tcg_gen_movi_tl(cpu_LO[acc], 0); 2963 } 2964 break; 2965 } 2966 } 2967 2968 static inline void gen_r6_ld(target_long addr, int reg, int memidx, 2969 MemOp memop) 2970 { 2971 TCGv t0 = tcg_temp_new(); 2972 tcg_gen_qemu_ld_tl(t0, tcg_constant_tl(addr), memidx, memop); 2973 gen_store_gpr(t0, reg); 2974 } 2975 2976 static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc, 2977 int rs) 2978 { 2979 target_long offset; 2980 target_long addr; 2981 2982 switch (MASK_OPC_PCREL_TOP2BITS(opc)) { 2983 case OPC_ADDIUPC: 2984 if (rs != 0) { 2985 offset = sextract32(ctx->opcode << 2, 0, 21); 2986 addr = addr_add(ctx, pc, offset); 2987 tcg_gen_movi_tl(cpu_gpr[rs], addr); 2988 } 2989 break; 2990 case R6_OPC_LWPC: 2991 offset = sextract32(ctx->opcode << 2, 0, 21); 2992 addr = addr_add(ctx, pc, offset); 2993 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL); 2994 break; 2995 #if defined(TARGET_MIPS64) 2996 case OPC_LWUPC: 2997 check_mips_64(ctx); 2998 offset = sextract32(ctx->opcode << 2, 0, 21); 2999 addr = addr_add(ctx, pc, offset); 3000 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL); 3001 break; 3002 #endif 3003 default: 3004 switch (MASK_OPC_PCREL_TOP5BITS(opc)) { 3005 case OPC_AUIPC: 3006 if (rs != 0) { 3007 offset = sextract32(ctx->opcode, 0, 16) << 16; 3008 addr = addr_add(ctx, pc, offset); 3009 tcg_gen_movi_tl(cpu_gpr[rs], addr); 3010 } 3011 break; 3012 case OPC_ALUIPC: 3013 if (rs != 0) { 3014 offset = sextract32(ctx->opcode, 0, 16) << 16; 3015 addr = ~0xFFFF & addr_add(ctx, pc, offset); 3016 tcg_gen_movi_tl(cpu_gpr[rs], addr); 3017 } 3018 break; 3019 #if defined(TARGET_MIPS64) 3020 case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */ 3021 case R6_OPC_LDPC + (1 << 16): 3022 case R6_OPC_LDPC + (2 << 16): 3023 case R6_OPC_LDPC + (3 << 16): 3024 check_mips_64(ctx); 3025 offset = sextract32(ctx->opcode << 3, 0, 21); 3026 addr = addr_add(ctx, (pc & ~0x7), offset); 3027 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUQ); 3028 break; 3029 #endif 3030 default: 3031 MIPS_INVAL("OPC_PCREL"); 3032 gen_reserved_instruction(ctx); 3033 break; 3034 } 3035 break; 3036 } 3037 } 3038 3039 static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt) 3040 { 3041 TCGv t0, t1; 3042 3043 if (rd == 0) { 3044 /* Treat as NOP. */ 3045 return; 3046 } 3047 3048 t0 = tcg_temp_new(); 3049 t1 = tcg_temp_new(); 3050 3051 gen_load_gpr(t0, rs); 3052 gen_load_gpr(t1, rt); 3053 3054 switch (opc) { 3055 case R6_OPC_DIV: 3056 { 3057 TCGv t2 = tcg_temp_new(); 3058 TCGv t3 = tcg_temp_new(); 3059 tcg_gen_ext32s_tl(t0, t0); 3060 tcg_gen_ext32s_tl(t1, t1); 3061 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); 3062 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); 3063 tcg_gen_and_tl(t2, t2, t3); 3064 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3065 tcg_gen_or_tl(t2, t2, t3); 3066 tcg_gen_movi_tl(t3, 0); 3067 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); 3068 tcg_gen_div_tl(cpu_gpr[rd], t0, t1); 3069 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3070 } 3071 break; 3072 case R6_OPC_MOD: 3073 { 3074 TCGv t2 = tcg_temp_new(); 3075 TCGv t3 = tcg_temp_new(); 3076 tcg_gen_ext32s_tl(t0, t0); 3077 tcg_gen_ext32s_tl(t1, t1); 3078 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); 3079 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); 3080 tcg_gen_and_tl(t2, t2, t3); 3081 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3082 tcg_gen_or_tl(t2, t2, t3); 3083 tcg_gen_movi_tl(t3, 0); 3084 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); 3085 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1); 3086 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3087 } 3088 break; 3089 case R6_OPC_DIVU: 3090 { 3091 TCGv t2 = tcg_constant_tl(0); 3092 TCGv t3 = tcg_constant_tl(1); 3093 tcg_gen_ext32u_tl(t0, t0); 3094 tcg_gen_ext32u_tl(t1, t1); 3095 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); 3096 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1); 3097 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3098 } 3099 break; 3100 case R6_OPC_MODU: 3101 { 3102 TCGv t2 = tcg_constant_tl(0); 3103 TCGv t3 = tcg_constant_tl(1); 3104 tcg_gen_ext32u_tl(t0, t0); 3105 tcg_gen_ext32u_tl(t1, t1); 3106 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); 3107 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1); 3108 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3109 } 3110 break; 3111 case R6_OPC_MUL: 3112 { 3113 TCGv_i32 t2 = tcg_temp_new_i32(); 3114 TCGv_i32 t3 = tcg_temp_new_i32(); 3115 tcg_gen_trunc_tl_i32(t2, t0); 3116 tcg_gen_trunc_tl_i32(t3, t1); 3117 tcg_gen_mul_i32(t2, t2, t3); 3118 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 3119 } 3120 break; 3121 case R6_OPC_MUH: 3122 { 3123 TCGv_i32 t2 = tcg_temp_new_i32(); 3124 TCGv_i32 t3 = tcg_temp_new_i32(); 3125 tcg_gen_trunc_tl_i32(t2, t0); 3126 tcg_gen_trunc_tl_i32(t3, t1); 3127 tcg_gen_muls2_i32(t2, t3, t2, t3); 3128 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3); 3129 } 3130 break; 3131 case R6_OPC_MULU: 3132 { 3133 TCGv_i32 t2 = tcg_temp_new_i32(); 3134 TCGv_i32 t3 = tcg_temp_new_i32(); 3135 tcg_gen_trunc_tl_i32(t2, t0); 3136 tcg_gen_trunc_tl_i32(t3, t1); 3137 tcg_gen_mul_i32(t2, t2, t3); 3138 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 3139 } 3140 break; 3141 case R6_OPC_MUHU: 3142 { 3143 TCGv_i32 t2 = tcg_temp_new_i32(); 3144 TCGv_i32 t3 = tcg_temp_new_i32(); 3145 tcg_gen_trunc_tl_i32(t2, t0); 3146 tcg_gen_trunc_tl_i32(t3, t1); 3147 tcg_gen_mulu2_i32(t2, t3, t2, t3); 3148 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3); 3149 } 3150 break; 3151 #if defined(TARGET_MIPS64) 3152 case R6_OPC_DDIV: 3153 { 3154 TCGv t2 = tcg_temp_new(); 3155 TCGv t3 = tcg_temp_new(); 3156 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63); 3157 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL); 3158 tcg_gen_and_tl(t2, t2, t3); 3159 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3160 tcg_gen_or_tl(t2, t2, t3); 3161 tcg_gen_movi_tl(t3, 0); 3162 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); 3163 tcg_gen_div_tl(cpu_gpr[rd], t0, t1); 3164 } 3165 break; 3166 case R6_OPC_DMOD: 3167 { 3168 TCGv t2 = tcg_temp_new(); 3169 TCGv t3 = tcg_temp_new(); 3170 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63); 3171 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL); 3172 tcg_gen_and_tl(t2, t2, t3); 3173 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3174 tcg_gen_or_tl(t2, t2, t3); 3175 tcg_gen_movi_tl(t3, 0); 3176 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); 3177 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1); 3178 } 3179 break; 3180 case R6_OPC_DDIVU: 3181 { 3182 TCGv t2 = tcg_constant_tl(0); 3183 TCGv t3 = tcg_constant_tl(1); 3184 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); 3185 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1); 3186 } 3187 break; 3188 case R6_OPC_DMODU: 3189 { 3190 TCGv t2 = tcg_constant_tl(0); 3191 TCGv t3 = tcg_constant_tl(1); 3192 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); 3193 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1); 3194 } 3195 break; 3196 case R6_OPC_DMUL: 3197 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1); 3198 break; 3199 case R6_OPC_DMUH: 3200 { 3201 TCGv t2 = tcg_temp_new(); 3202 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1); 3203 } 3204 break; 3205 case R6_OPC_DMULU: 3206 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1); 3207 break; 3208 case R6_OPC_DMUHU: 3209 { 3210 TCGv t2 = tcg_temp_new(); 3211 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1); 3212 } 3213 break; 3214 #endif 3215 default: 3216 MIPS_INVAL("r6 mul/div"); 3217 gen_reserved_instruction(ctx); 3218 break; 3219 } 3220 } 3221 3222 #if defined(TARGET_MIPS64) 3223 static void gen_div1_tx79(DisasContext *ctx, uint32_t opc, int rs, int rt) 3224 { 3225 TCGv t0, t1; 3226 3227 t0 = tcg_temp_new(); 3228 t1 = tcg_temp_new(); 3229 3230 gen_load_gpr(t0, rs); 3231 gen_load_gpr(t1, rt); 3232 3233 switch (opc) { 3234 case MMI_OPC_DIV1: 3235 { 3236 TCGv t2 = tcg_temp_new(); 3237 TCGv t3 = tcg_temp_new(); 3238 tcg_gen_ext32s_tl(t0, t0); 3239 tcg_gen_ext32s_tl(t1, t1); 3240 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); 3241 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); 3242 tcg_gen_and_tl(t2, t2, t3); 3243 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3244 tcg_gen_or_tl(t2, t2, t3); 3245 tcg_gen_movi_tl(t3, 0); 3246 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); 3247 tcg_gen_div_tl(cpu_LO[1], t0, t1); 3248 tcg_gen_rem_tl(cpu_HI[1], t0, t1); 3249 tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]); 3250 tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]); 3251 } 3252 break; 3253 case MMI_OPC_DIVU1: 3254 { 3255 TCGv t2 = tcg_constant_tl(0); 3256 TCGv t3 = tcg_constant_tl(1); 3257 tcg_gen_ext32u_tl(t0, t0); 3258 tcg_gen_ext32u_tl(t1, t1); 3259 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); 3260 tcg_gen_divu_tl(cpu_LO[1], t0, t1); 3261 tcg_gen_remu_tl(cpu_HI[1], t0, t1); 3262 tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]); 3263 tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]); 3264 } 3265 break; 3266 default: 3267 MIPS_INVAL("div1 TX79"); 3268 gen_reserved_instruction(ctx); 3269 break; 3270 } 3271 } 3272 #endif 3273 3274 static void gen_muldiv(DisasContext *ctx, uint32_t opc, 3275 int acc, int rs, int rt) 3276 { 3277 TCGv t0, t1; 3278 3279 t0 = tcg_temp_new(); 3280 t1 = tcg_temp_new(); 3281 3282 gen_load_gpr(t0, rs); 3283 gen_load_gpr(t1, rt); 3284 3285 if (acc != 0) { 3286 check_dsp(ctx); 3287 } 3288 3289 switch (opc) { 3290 case OPC_DIV: 3291 { 3292 TCGv t2 = tcg_temp_new(); 3293 TCGv t3 = tcg_temp_new(); 3294 tcg_gen_ext32s_tl(t0, t0); 3295 tcg_gen_ext32s_tl(t1, t1); 3296 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); 3297 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); 3298 tcg_gen_and_tl(t2, t2, t3); 3299 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3300 tcg_gen_or_tl(t2, t2, t3); 3301 tcg_gen_movi_tl(t3, 0); 3302 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); 3303 tcg_gen_div_tl(cpu_LO[acc], t0, t1); 3304 tcg_gen_rem_tl(cpu_HI[acc], t0, t1); 3305 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]); 3306 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]); 3307 } 3308 break; 3309 case OPC_DIVU: 3310 { 3311 TCGv t2 = tcg_constant_tl(0); 3312 TCGv t3 = tcg_constant_tl(1); 3313 tcg_gen_ext32u_tl(t0, t0); 3314 tcg_gen_ext32u_tl(t1, t1); 3315 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); 3316 tcg_gen_divu_tl(cpu_LO[acc], t0, t1); 3317 tcg_gen_remu_tl(cpu_HI[acc], t0, t1); 3318 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]); 3319 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]); 3320 } 3321 break; 3322 case OPC_MULT: 3323 { 3324 TCGv_i32 t2 = tcg_temp_new_i32(); 3325 TCGv_i32 t3 = tcg_temp_new_i32(); 3326 tcg_gen_trunc_tl_i32(t2, t0); 3327 tcg_gen_trunc_tl_i32(t3, t1); 3328 tcg_gen_muls2_i32(t2, t3, t2, t3); 3329 tcg_gen_ext_i32_tl(cpu_LO[acc], t2); 3330 tcg_gen_ext_i32_tl(cpu_HI[acc], t3); 3331 } 3332 break; 3333 case OPC_MULTU: 3334 { 3335 TCGv_i32 t2 = tcg_temp_new_i32(); 3336 TCGv_i32 t3 = tcg_temp_new_i32(); 3337 tcg_gen_trunc_tl_i32(t2, t0); 3338 tcg_gen_trunc_tl_i32(t3, t1); 3339 tcg_gen_mulu2_i32(t2, t3, t2, t3); 3340 tcg_gen_ext_i32_tl(cpu_LO[acc], t2); 3341 tcg_gen_ext_i32_tl(cpu_HI[acc], t3); 3342 } 3343 break; 3344 #if defined(TARGET_MIPS64) 3345 case OPC_DDIV: 3346 { 3347 TCGv t2 = tcg_temp_new(); 3348 TCGv t3 = tcg_temp_new(); 3349 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63); 3350 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL); 3351 tcg_gen_and_tl(t2, t2, t3); 3352 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3353 tcg_gen_or_tl(t2, t2, t3); 3354 tcg_gen_movi_tl(t3, 0); 3355 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); 3356 tcg_gen_div_tl(cpu_LO[acc], t0, t1); 3357 tcg_gen_rem_tl(cpu_HI[acc], t0, t1); 3358 } 3359 break; 3360 case OPC_DDIVU: 3361 { 3362 TCGv t2 = tcg_constant_tl(0); 3363 TCGv t3 = tcg_constant_tl(1); 3364 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); 3365 tcg_gen_divu_i64(cpu_LO[acc], t0, t1); 3366 tcg_gen_remu_i64(cpu_HI[acc], t0, t1); 3367 } 3368 break; 3369 case OPC_DMULT: 3370 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1); 3371 break; 3372 case OPC_DMULTU: 3373 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1); 3374 break; 3375 #endif 3376 case OPC_MADD: 3377 { 3378 TCGv_i64 t2 = tcg_temp_new_i64(); 3379 TCGv_i64 t3 = tcg_temp_new_i64(); 3380 3381 tcg_gen_ext_tl_i64(t2, t0); 3382 tcg_gen_ext_tl_i64(t3, t1); 3383 tcg_gen_mul_i64(t2, t2, t3); 3384 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3385 tcg_gen_add_i64(t2, t2, t3); 3386 gen_move_low32(cpu_LO[acc], t2); 3387 gen_move_high32(cpu_HI[acc], t2); 3388 } 3389 break; 3390 case OPC_MADDU: 3391 { 3392 TCGv_i64 t2 = tcg_temp_new_i64(); 3393 TCGv_i64 t3 = tcg_temp_new_i64(); 3394 3395 tcg_gen_ext32u_tl(t0, t0); 3396 tcg_gen_ext32u_tl(t1, t1); 3397 tcg_gen_extu_tl_i64(t2, t0); 3398 tcg_gen_extu_tl_i64(t3, t1); 3399 tcg_gen_mul_i64(t2, t2, t3); 3400 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3401 tcg_gen_add_i64(t2, t2, t3); 3402 gen_move_low32(cpu_LO[acc], t2); 3403 gen_move_high32(cpu_HI[acc], t2); 3404 } 3405 break; 3406 case OPC_MSUB: 3407 { 3408 TCGv_i64 t2 = tcg_temp_new_i64(); 3409 TCGv_i64 t3 = tcg_temp_new_i64(); 3410 3411 tcg_gen_ext_tl_i64(t2, t0); 3412 tcg_gen_ext_tl_i64(t3, t1); 3413 tcg_gen_mul_i64(t2, t2, t3); 3414 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3415 tcg_gen_sub_i64(t2, t3, t2); 3416 gen_move_low32(cpu_LO[acc], t2); 3417 gen_move_high32(cpu_HI[acc], t2); 3418 } 3419 break; 3420 case OPC_MSUBU: 3421 { 3422 TCGv_i64 t2 = tcg_temp_new_i64(); 3423 TCGv_i64 t3 = tcg_temp_new_i64(); 3424 3425 tcg_gen_ext32u_tl(t0, t0); 3426 tcg_gen_ext32u_tl(t1, t1); 3427 tcg_gen_extu_tl_i64(t2, t0); 3428 tcg_gen_extu_tl_i64(t3, t1); 3429 tcg_gen_mul_i64(t2, t2, t3); 3430 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3431 tcg_gen_sub_i64(t2, t3, t2); 3432 gen_move_low32(cpu_LO[acc], t2); 3433 gen_move_high32(cpu_HI[acc], t2); 3434 } 3435 break; 3436 default: 3437 MIPS_INVAL("mul/div"); 3438 gen_reserved_instruction(ctx); 3439 break; 3440 } 3441 } 3442 3443 /* 3444 * These MULT[U] and MADD[U] instructions implemented in for example 3445 * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core 3446 * architectures are special three-operand variants with the syntax 3447 * 3448 * MULT[U][1] rd, rs, rt 3449 * 3450 * such that 3451 * 3452 * (rd, LO, HI) <- rs * rt 3453 * 3454 * and 3455 * 3456 * MADD[U][1] rd, rs, rt 3457 * 3458 * such that 3459 * 3460 * (rd, LO, HI) <- (LO, HI) + rs * rt 3461 * 3462 * where the low-order 32-bits of the result is placed into both the 3463 * GPR rd and the special register LO. The high-order 32-bits of the 3464 * result is placed into the special register HI. 3465 * 3466 * If the GPR rd is omitted in assembly language, it is taken to be 0, 3467 * which is the zero register that always reads as 0. 3468 */ 3469 static void gen_mul_txx9(DisasContext *ctx, uint32_t opc, 3470 int rd, int rs, int rt) 3471 { 3472 TCGv t0 = tcg_temp_new(); 3473 TCGv t1 = tcg_temp_new(); 3474 int acc = 0; 3475 3476 gen_load_gpr(t0, rs); 3477 gen_load_gpr(t1, rt); 3478 3479 switch (opc) { 3480 case MMI_OPC_MULT1: 3481 acc = 1; 3482 /* Fall through */ 3483 case OPC_MULT: 3484 { 3485 TCGv_i32 t2 = tcg_temp_new_i32(); 3486 TCGv_i32 t3 = tcg_temp_new_i32(); 3487 tcg_gen_trunc_tl_i32(t2, t0); 3488 tcg_gen_trunc_tl_i32(t3, t1); 3489 tcg_gen_muls2_i32(t2, t3, t2, t3); 3490 if (rd) { 3491 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 3492 } 3493 tcg_gen_ext_i32_tl(cpu_LO[acc], t2); 3494 tcg_gen_ext_i32_tl(cpu_HI[acc], t3); 3495 } 3496 break; 3497 case MMI_OPC_MULTU1: 3498 acc = 1; 3499 /* Fall through */ 3500 case OPC_MULTU: 3501 { 3502 TCGv_i32 t2 = tcg_temp_new_i32(); 3503 TCGv_i32 t3 = tcg_temp_new_i32(); 3504 tcg_gen_trunc_tl_i32(t2, t0); 3505 tcg_gen_trunc_tl_i32(t3, t1); 3506 tcg_gen_mulu2_i32(t2, t3, t2, t3); 3507 if (rd) { 3508 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 3509 } 3510 tcg_gen_ext_i32_tl(cpu_LO[acc], t2); 3511 tcg_gen_ext_i32_tl(cpu_HI[acc], t3); 3512 } 3513 break; 3514 case MMI_OPC_MADD1: 3515 acc = 1; 3516 /* Fall through */ 3517 case MMI_OPC_MADD: 3518 { 3519 TCGv_i64 t2 = tcg_temp_new_i64(); 3520 TCGv_i64 t3 = tcg_temp_new_i64(); 3521 3522 tcg_gen_ext_tl_i64(t2, t0); 3523 tcg_gen_ext_tl_i64(t3, t1); 3524 tcg_gen_mul_i64(t2, t2, t3); 3525 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3526 tcg_gen_add_i64(t2, t2, t3); 3527 gen_move_low32(cpu_LO[acc], t2); 3528 gen_move_high32(cpu_HI[acc], t2); 3529 if (rd) { 3530 gen_move_low32(cpu_gpr[rd], t2); 3531 } 3532 } 3533 break; 3534 case MMI_OPC_MADDU1: 3535 acc = 1; 3536 /* Fall through */ 3537 case MMI_OPC_MADDU: 3538 { 3539 TCGv_i64 t2 = tcg_temp_new_i64(); 3540 TCGv_i64 t3 = tcg_temp_new_i64(); 3541 3542 tcg_gen_ext32u_tl(t0, t0); 3543 tcg_gen_ext32u_tl(t1, t1); 3544 tcg_gen_extu_tl_i64(t2, t0); 3545 tcg_gen_extu_tl_i64(t3, t1); 3546 tcg_gen_mul_i64(t2, t2, t3); 3547 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3548 tcg_gen_add_i64(t2, t2, t3); 3549 gen_move_low32(cpu_LO[acc], t2); 3550 gen_move_high32(cpu_HI[acc], t2); 3551 if (rd) { 3552 gen_move_low32(cpu_gpr[rd], t2); 3553 } 3554 } 3555 break; 3556 default: 3557 MIPS_INVAL("mul/madd TXx9"); 3558 gen_reserved_instruction(ctx); 3559 break; 3560 } 3561 } 3562 3563 static void gen_cl(DisasContext *ctx, uint32_t opc, 3564 int rd, int rs) 3565 { 3566 TCGv t0; 3567 3568 if (rd == 0) { 3569 /* Treat as NOP. */ 3570 return; 3571 } 3572 t0 = cpu_gpr[rd]; 3573 gen_load_gpr(t0, rs); 3574 3575 switch (opc) { 3576 case OPC_CLO: 3577 case R6_OPC_CLO: 3578 #if defined(TARGET_MIPS64) 3579 case OPC_DCLO: 3580 case R6_OPC_DCLO: 3581 #endif 3582 tcg_gen_not_tl(t0, t0); 3583 break; 3584 } 3585 3586 switch (opc) { 3587 case OPC_CLO: 3588 case R6_OPC_CLO: 3589 case OPC_CLZ: 3590 case R6_OPC_CLZ: 3591 tcg_gen_ext32u_tl(t0, t0); 3592 tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS); 3593 tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32); 3594 break; 3595 #if defined(TARGET_MIPS64) 3596 case OPC_DCLO: 3597 case R6_OPC_DCLO: 3598 case OPC_DCLZ: 3599 case R6_OPC_DCLZ: 3600 tcg_gen_clzi_i64(t0, t0, 64); 3601 break; 3602 #endif 3603 } 3604 } 3605 3606 /* Godson integer instructions */ 3607 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc, 3608 int rd, int rs, int rt) 3609 { 3610 TCGv t0, t1; 3611 3612 if (rd == 0) { 3613 /* Treat as NOP. */ 3614 return; 3615 } 3616 3617 t0 = tcg_temp_new(); 3618 t1 = tcg_temp_new(); 3619 gen_load_gpr(t0, rs); 3620 gen_load_gpr(t1, rt); 3621 3622 switch (opc) { 3623 case OPC_MULT_G_2E: 3624 case OPC_MULT_G_2F: 3625 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1); 3626 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3627 break; 3628 case OPC_MULTU_G_2E: 3629 case OPC_MULTU_G_2F: 3630 tcg_gen_ext32u_tl(t0, t0); 3631 tcg_gen_ext32u_tl(t1, t1); 3632 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1); 3633 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3634 break; 3635 case OPC_DIV_G_2E: 3636 case OPC_DIV_G_2F: 3637 { 3638 TCGLabel *l1 = gen_new_label(); 3639 TCGLabel *l2 = gen_new_label(); 3640 TCGLabel *l3 = gen_new_label(); 3641 tcg_gen_ext32s_tl(t0, t0); 3642 tcg_gen_ext32s_tl(t1, t1); 3643 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1); 3644 tcg_gen_movi_tl(cpu_gpr[rd], 0); 3645 tcg_gen_br(l3); 3646 gen_set_label(l1); 3647 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2); 3648 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2); 3649 tcg_gen_mov_tl(cpu_gpr[rd], t0); 3650 tcg_gen_br(l3); 3651 gen_set_label(l2); 3652 tcg_gen_div_tl(cpu_gpr[rd], t0, t1); 3653 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3654 gen_set_label(l3); 3655 } 3656 break; 3657 case OPC_DIVU_G_2E: 3658 case OPC_DIVU_G_2F: 3659 { 3660 TCGLabel *l1 = gen_new_label(); 3661 TCGLabel *l2 = gen_new_label(); 3662 tcg_gen_ext32u_tl(t0, t0); 3663 tcg_gen_ext32u_tl(t1, t1); 3664 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1); 3665 tcg_gen_movi_tl(cpu_gpr[rd], 0); 3666 tcg_gen_br(l2); 3667 gen_set_label(l1); 3668 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1); 3669 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3670 gen_set_label(l2); 3671 } 3672 break; 3673 case OPC_MOD_G_2E: 3674 case OPC_MOD_G_2F: 3675 { 3676 TCGLabel *l1 = gen_new_label(); 3677 TCGLabel *l2 = gen_new_label(); 3678 TCGLabel *l3 = gen_new_label(); 3679 tcg_gen_ext32u_tl(t0, t0); 3680 tcg_gen_ext32u_tl(t1, t1); 3681 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1); 3682 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2); 3683 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2); 3684 gen_set_label(l1); 3685 tcg_gen_movi_tl(cpu_gpr[rd], 0); 3686 tcg_gen_br(l3); 3687 gen_set_label(l2); 3688 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1); 3689 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3690 gen_set_label(l3); 3691 } 3692 break; 3693 case OPC_MODU_G_2E: 3694 case OPC_MODU_G_2F: 3695 { 3696 TCGLabel *l1 = gen_new_label(); 3697 TCGLabel *l2 = gen_new_label(); 3698 tcg_gen_ext32u_tl(t0, t0); 3699 tcg_gen_ext32u_tl(t1, t1); 3700 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1); 3701 tcg_gen_movi_tl(cpu_gpr[rd], 0); 3702 tcg_gen_br(l2); 3703 gen_set_label(l1); 3704 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1); 3705 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3706 gen_set_label(l2); 3707 } 3708 break; 3709 #if defined(TARGET_MIPS64) 3710 case OPC_DMULT_G_2E: 3711 case OPC_DMULT_G_2F: 3712 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1); 3713 break; 3714 case OPC_DMULTU_G_2E: 3715 case OPC_DMULTU_G_2F: 3716 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1); 3717 break; 3718 case OPC_DDIV_G_2E: 3719 case OPC_DDIV_G_2F: 3720 { 3721 TCGLabel *l1 = gen_new_label(); 3722 TCGLabel *l2 = gen_new_label(); 3723 TCGLabel *l3 = gen_new_label(); 3724 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1); 3725 tcg_gen_movi_tl(cpu_gpr[rd], 0); 3726 tcg_gen_br(l3); 3727 gen_set_label(l1); 3728 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2); 3729 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2); 3730 tcg_gen_mov_tl(cpu_gpr[rd], t0); 3731 tcg_gen_br(l3); 3732 gen_set_label(l2); 3733 tcg_gen_div_tl(cpu_gpr[rd], t0, t1); 3734 gen_set_label(l3); 3735 } 3736 break; 3737 case OPC_DDIVU_G_2E: 3738 case OPC_DDIVU_G_2F: 3739 { 3740 TCGLabel *l1 = gen_new_label(); 3741 TCGLabel *l2 = gen_new_label(); 3742 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1); 3743 tcg_gen_movi_tl(cpu_gpr[rd], 0); 3744 tcg_gen_br(l2); 3745 gen_set_label(l1); 3746 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1); 3747 gen_set_label(l2); 3748 } 3749 break; 3750 case OPC_DMOD_G_2E: 3751 case OPC_DMOD_G_2F: 3752 { 3753 TCGLabel *l1 = gen_new_label(); 3754 TCGLabel *l2 = gen_new_label(); 3755 TCGLabel *l3 = gen_new_label(); 3756 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1); 3757 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2); 3758 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2); 3759 gen_set_label(l1); 3760 tcg_gen_movi_tl(cpu_gpr[rd], 0); 3761 tcg_gen_br(l3); 3762 gen_set_label(l2); 3763 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1); 3764 gen_set_label(l3); 3765 } 3766 break; 3767 case OPC_DMODU_G_2E: 3768 case OPC_DMODU_G_2F: 3769 { 3770 TCGLabel *l1 = gen_new_label(); 3771 TCGLabel *l2 = gen_new_label(); 3772 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1); 3773 tcg_gen_movi_tl(cpu_gpr[rd], 0); 3774 tcg_gen_br(l2); 3775 gen_set_label(l1); 3776 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1); 3777 gen_set_label(l2); 3778 } 3779 break; 3780 #endif 3781 } 3782 } 3783 3784 /* Loongson multimedia instructions */ 3785 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt) 3786 { 3787 uint32_t opc, shift_max; 3788 TCGv_i64 t0, t1; 3789 TCGCond cond; 3790 3791 opc = MASK_LMMI(ctx->opcode); 3792 check_cp1_enabled(ctx); 3793 3794 t0 = tcg_temp_new_i64(); 3795 t1 = tcg_temp_new_i64(); 3796 gen_load_fpr64(ctx, t0, rs); 3797 gen_load_fpr64(ctx, t1, rt); 3798 3799 switch (opc) { 3800 case OPC_PADDSH: 3801 gen_helper_paddsh(t0, t0, t1); 3802 break; 3803 case OPC_PADDUSH: 3804 gen_helper_paddush(t0, t0, t1); 3805 break; 3806 case OPC_PADDH: 3807 gen_helper_paddh(t0, t0, t1); 3808 break; 3809 case OPC_PADDW: 3810 gen_helper_paddw(t0, t0, t1); 3811 break; 3812 case OPC_PADDSB: 3813 gen_helper_paddsb(t0, t0, t1); 3814 break; 3815 case OPC_PADDUSB: 3816 gen_helper_paddusb(t0, t0, t1); 3817 break; 3818 case OPC_PADDB: 3819 gen_helper_paddb(t0, t0, t1); 3820 break; 3821 3822 case OPC_PSUBSH: 3823 gen_helper_psubsh(t0, t0, t1); 3824 break; 3825 case OPC_PSUBUSH: 3826 gen_helper_psubush(t0, t0, t1); 3827 break; 3828 case OPC_PSUBH: 3829 gen_helper_psubh(t0, t0, t1); 3830 break; 3831 case OPC_PSUBW: 3832 gen_helper_psubw(t0, t0, t1); 3833 break; 3834 case OPC_PSUBSB: 3835 gen_helper_psubsb(t0, t0, t1); 3836 break; 3837 case OPC_PSUBUSB: 3838 gen_helper_psubusb(t0, t0, t1); 3839 break; 3840 case OPC_PSUBB: 3841 gen_helper_psubb(t0, t0, t1); 3842 break; 3843 3844 case OPC_PSHUFH: 3845 gen_helper_pshufh(t0, t0, t1); 3846 break; 3847 case OPC_PACKSSWH: 3848 gen_helper_packsswh(t0, t0, t1); 3849 break; 3850 case OPC_PACKSSHB: 3851 gen_helper_packsshb(t0, t0, t1); 3852 break; 3853 case OPC_PACKUSHB: 3854 gen_helper_packushb(t0, t0, t1); 3855 break; 3856 3857 case OPC_PUNPCKLHW: 3858 gen_helper_punpcklhw(t0, t0, t1); 3859 break; 3860 case OPC_PUNPCKHHW: 3861 gen_helper_punpckhhw(t0, t0, t1); 3862 break; 3863 case OPC_PUNPCKLBH: 3864 gen_helper_punpcklbh(t0, t0, t1); 3865 break; 3866 case OPC_PUNPCKHBH: 3867 gen_helper_punpckhbh(t0, t0, t1); 3868 break; 3869 case OPC_PUNPCKLWD: 3870 gen_helper_punpcklwd(t0, t0, t1); 3871 break; 3872 case OPC_PUNPCKHWD: 3873 gen_helper_punpckhwd(t0, t0, t1); 3874 break; 3875 3876 case OPC_PAVGH: 3877 gen_helper_pavgh(t0, t0, t1); 3878 break; 3879 case OPC_PAVGB: 3880 gen_helper_pavgb(t0, t0, t1); 3881 break; 3882 case OPC_PMAXSH: 3883 gen_helper_pmaxsh(t0, t0, t1); 3884 break; 3885 case OPC_PMINSH: 3886 gen_helper_pminsh(t0, t0, t1); 3887 break; 3888 case OPC_PMAXUB: 3889 gen_helper_pmaxub(t0, t0, t1); 3890 break; 3891 case OPC_PMINUB: 3892 gen_helper_pminub(t0, t0, t1); 3893 break; 3894 3895 case OPC_PCMPEQW: 3896 gen_helper_pcmpeqw(t0, t0, t1); 3897 break; 3898 case OPC_PCMPGTW: 3899 gen_helper_pcmpgtw(t0, t0, t1); 3900 break; 3901 case OPC_PCMPEQH: 3902 gen_helper_pcmpeqh(t0, t0, t1); 3903 break; 3904 case OPC_PCMPGTH: 3905 gen_helper_pcmpgth(t0, t0, t1); 3906 break; 3907 case OPC_PCMPEQB: 3908 gen_helper_pcmpeqb(t0, t0, t1); 3909 break; 3910 case OPC_PCMPGTB: 3911 gen_helper_pcmpgtb(t0, t0, t1); 3912 break; 3913 3914 case OPC_PSLLW: 3915 gen_helper_psllw(t0, t0, t1); 3916 break; 3917 case OPC_PSLLH: 3918 gen_helper_psllh(t0, t0, t1); 3919 break; 3920 case OPC_PSRLW: 3921 gen_helper_psrlw(t0, t0, t1); 3922 break; 3923 case OPC_PSRLH: 3924 gen_helper_psrlh(t0, t0, t1); 3925 break; 3926 case OPC_PSRAW: 3927 gen_helper_psraw(t0, t0, t1); 3928 break; 3929 case OPC_PSRAH: 3930 gen_helper_psrah(t0, t0, t1); 3931 break; 3932 3933 case OPC_PMULLH: 3934 gen_helper_pmullh(t0, t0, t1); 3935 break; 3936 case OPC_PMULHH: 3937 gen_helper_pmulhh(t0, t0, t1); 3938 break; 3939 case OPC_PMULHUH: 3940 gen_helper_pmulhuh(t0, t0, t1); 3941 break; 3942 case OPC_PMADDHW: 3943 gen_helper_pmaddhw(t0, t0, t1); 3944 break; 3945 3946 case OPC_PASUBUB: 3947 gen_helper_pasubub(t0, t0, t1); 3948 break; 3949 case OPC_BIADD: 3950 gen_helper_biadd(t0, t0); 3951 break; 3952 case OPC_PMOVMSKB: 3953 gen_helper_pmovmskb(t0, t0); 3954 break; 3955 3956 case OPC_PADDD: 3957 tcg_gen_add_i64(t0, t0, t1); 3958 break; 3959 case OPC_PSUBD: 3960 tcg_gen_sub_i64(t0, t0, t1); 3961 break; 3962 case OPC_XOR_CP2: 3963 tcg_gen_xor_i64(t0, t0, t1); 3964 break; 3965 case OPC_NOR_CP2: 3966 tcg_gen_nor_i64(t0, t0, t1); 3967 break; 3968 case OPC_AND_CP2: 3969 tcg_gen_and_i64(t0, t0, t1); 3970 break; 3971 case OPC_OR_CP2: 3972 tcg_gen_or_i64(t0, t0, t1); 3973 break; 3974 3975 case OPC_PANDN: 3976 tcg_gen_andc_i64(t0, t1, t0); 3977 break; 3978 3979 case OPC_PINSRH_0: 3980 tcg_gen_deposit_i64(t0, t0, t1, 0, 16); 3981 break; 3982 case OPC_PINSRH_1: 3983 tcg_gen_deposit_i64(t0, t0, t1, 16, 16); 3984 break; 3985 case OPC_PINSRH_2: 3986 tcg_gen_deposit_i64(t0, t0, t1, 32, 16); 3987 break; 3988 case OPC_PINSRH_3: 3989 tcg_gen_deposit_i64(t0, t0, t1, 48, 16); 3990 break; 3991 3992 case OPC_PEXTRH: 3993 tcg_gen_andi_i64(t1, t1, 3); 3994 tcg_gen_shli_i64(t1, t1, 4); 3995 tcg_gen_shr_i64(t0, t0, t1); 3996 tcg_gen_ext16u_i64(t0, t0); 3997 break; 3998 3999 case OPC_ADDU_CP2: 4000 tcg_gen_add_i64(t0, t0, t1); 4001 tcg_gen_ext32s_i64(t0, t0); 4002 break; 4003 case OPC_SUBU_CP2: 4004 tcg_gen_sub_i64(t0, t0, t1); 4005 tcg_gen_ext32s_i64(t0, t0); 4006 break; 4007 4008 case OPC_SLL_CP2: 4009 shift_max = 32; 4010 goto do_shift; 4011 case OPC_SRL_CP2: 4012 shift_max = 32; 4013 goto do_shift; 4014 case OPC_SRA_CP2: 4015 shift_max = 32; 4016 goto do_shift; 4017 case OPC_DSLL_CP2: 4018 shift_max = 64; 4019 goto do_shift; 4020 case OPC_DSRL_CP2: 4021 shift_max = 64; 4022 goto do_shift; 4023 case OPC_DSRA_CP2: 4024 shift_max = 64; 4025 goto do_shift; 4026 do_shift: 4027 /* Make sure shift count isn't TCG undefined behaviour. */ 4028 tcg_gen_andi_i64(t1, t1, shift_max - 1); 4029 4030 switch (opc) { 4031 case OPC_SLL_CP2: 4032 case OPC_DSLL_CP2: 4033 tcg_gen_shl_i64(t0, t0, t1); 4034 break; 4035 case OPC_SRA_CP2: 4036 case OPC_DSRA_CP2: 4037 /* 4038 * Since SRA is UndefinedResult without sign-extended inputs, 4039 * we can treat SRA and DSRA the same. 4040 */ 4041 tcg_gen_sar_i64(t0, t0, t1); 4042 break; 4043 case OPC_SRL_CP2: 4044 /* We want to shift in zeros for SRL; zero-extend first. */ 4045 tcg_gen_ext32u_i64(t0, t0); 4046 /* FALLTHRU */ 4047 case OPC_DSRL_CP2: 4048 tcg_gen_shr_i64(t0, t0, t1); 4049 break; 4050 } 4051 4052 if (shift_max == 32) { 4053 tcg_gen_ext32s_i64(t0, t0); 4054 } 4055 4056 /* Shifts larger than MAX produce zero. */ 4057 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max); 4058 tcg_gen_neg_i64(t1, t1); 4059 tcg_gen_and_i64(t0, t0, t1); 4060 break; 4061 4062 case OPC_ADD_CP2: 4063 case OPC_DADD_CP2: 4064 { 4065 TCGv_i64 t2 = tcg_temp_new_i64(); 4066 TCGLabel *lab = gen_new_label(); 4067 4068 tcg_gen_mov_i64(t2, t0); 4069 tcg_gen_add_i64(t0, t1, t2); 4070 if (opc == OPC_ADD_CP2) { 4071 tcg_gen_ext32s_i64(t0, t0); 4072 } 4073 tcg_gen_xor_i64(t1, t1, t2); 4074 tcg_gen_xor_i64(t2, t2, t0); 4075 tcg_gen_andc_i64(t1, t2, t1); 4076 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab); 4077 generate_exception(ctx, EXCP_OVERFLOW); 4078 gen_set_label(lab); 4079 break; 4080 } 4081 4082 case OPC_SUB_CP2: 4083 case OPC_DSUB_CP2: 4084 { 4085 TCGv_i64 t2 = tcg_temp_new_i64(); 4086 TCGLabel *lab = gen_new_label(); 4087 4088 tcg_gen_mov_i64(t2, t0); 4089 tcg_gen_sub_i64(t0, t1, t2); 4090 if (opc == OPC_SUB_CP2) { 4091 tcg_gen_ext32s_i64(t0, t0); 4092 } 4093 tcg_gen_xor_i64(t1, t1, t2); 4094 tcg_gen_xor_i64(t2, t2, t0); 4095 tcg_gen_and_i64(t1, t1, t2); 4096 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab); 4097 generate_exception(ctx, EXCP_OVERFLOW); 4098 gen_set_label(lab); 4099 break; 4100 } 4101 4102 case OPC_PMULUW: 4103 tcg_gen_ext32u_i64(t0, t0); 4104 tcg_gen_ext32u_i64(t1, t1); 4105 tcg_gen_mul_i64(t0, t0, t1); 4106 break; 4107 4108 case OPC_SEQU_CP2: 4109 case OPC_SEQ_CP2: 4110 cond = TCG_COND_EQ; 4111 goto do_cc_cond; 4112 break; 4113 case OPC_SLTU_CP2: 4114 cond = TCG_COND_LTU; 4115 goto do_cc_cond; 4116 break; 4117 case OPC_SLT_CP2: 4118 cond = TCG_COND_LT; 4119 goto do_cc_cond; 4120 break; 4121 case OPC_SLEU_CP2: 4122 cond = TCG_COND_LEU; 4123 goto do_cc_cond; 4124 break; 4125 case OPC_SLE_CP2: 4126 cond = TCG_COND_LE; 4127 do_cc_cond: 4128 { 4129 int cc = (ctx->opcode >> 8) & 0x7; 4130 TCGv_i64 t64 = tcg_temp_new_i64(); 4131 TCGv_i32 t32 = tcg_temp_new_i32(); 4132 4133 tcg_gen_setcond_i64(cond, t64, t0, t1); 4134 tcg_gen_extrl_i64_i32(t32, t64); 4135 tcg_gen_deposit_i32(fpu_fcr31, fpu_fcr31, t32, 4136 get_fp_bit(cc), 1); 4137 } 4138 return; 4139 default: 4140 MIPS_INVAL("loongson_cp2"); 4141 gen_reserved_instruction(ctx); 4142 return; 4143 } 4144 4145 gen_store_fpr64(ctx, t0, rd); 4146 } 4147 4148 static void gen_loongson_lswc2(DisasContext *ctx, int rt, 4149 int rs, int rd) 4150 { 4151 TCGv t0, t1; 4152 TCGv_i32 fp0; 4153 #if defined(TARGET_MIPS64) 4154 int lsq_rt1 = ctx->opcode & 0x1f; 4155 int lsq_offset = sextract32(ctx->opcode, 6, 9) << 4; 4156 #endif 4157 int shf_offset = sextract32(ctx->opcode, 6, 8); 4158 4159 t0 = tcg_temp_new(); 4160 4161 switch (MASK_LOONGSON_GSLSQ(ctx->opcode)) { 4162 #if defined(TARGET_MIPS64) 4163 case OPC_GSLQ: 4164 t1 = tcg_temp_new(); 4165 gen_base_offset_addr(ctx, t0, rs, lsq_offset); 4166 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEUQ | 4167 ctx->default_tcg_memop_mask); 4168 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8); 4169 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ | 4170 ctx->default_tcg_memop_mask); 4171 gen_store_gpr(t1, rt); 4172 gen_store_gpr(t0, lsq_rt1); 4173 break; 4174 case OPC_GSLQC1: 4175 check_cp1_enabled(ctx); 4176 t1 = tcg_temp_new(); 4177 gen_base_offset_addr(ctx, t0, rs, lsq_offset); 4178 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEUQ | 4179 ctx->default_tcg_memop_mask); 4180 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8); 4181 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ | 4182 ctx->default_tcg_memop_mask); 4183 gen_store_fpr64(ctx, t1, rt); 4184 gen_store_fpr64(ctx, t0, lsq_rt1); 4185 break; 4186 case OPC_GSSQ: 4187 t1 = tcg_temp_new(); 4188 gen_base_offset_addr(ctx, t0, rs, lsq_offset); 4189 gen_load_gpr(t1, rt); 4190 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUQ | 4191 ctx->default_tcg_memop_mask); 4192 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8); 4193 gen_load_gpr(t1, lsq_rt1); 4194 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUQ | 4195 ctx->default_tcg_memop_mask); 4196 break; 4197 case OPC_GSSQC1: 4198 check_cp1_enabled(ctx); 4199 t1 = tcg_temp_new(); 4200 gen_base_offset_addr(ctx, t0, rs, lsq_offset); 4201 gen_load_fpr64(ctx, t1, rt); 4202 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUQ | 4203 ctx->default_tcg_memop_mask); 4204 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8); 4205 gen_load_fpr64(ctx, t1, lsq_rt1); 4206 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUQ | 4207 ctx->default_tcg_memop_mask); 4208 break; 4209 #endif 4210 case OPC_GSSHFL: 4211 switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) { 4212 case OPC_GSLWLC1: 4213 check_cp1_enabled(ctx); 4214 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4215 fp0 = tcg_temp_new_i32(); 4216 gen_load_fpr32(ctx, fp0, rt); 4217 t1 = tcg_temp_new(); 4218 tcg_gen_ext_i32_tl(t1, fp0); 4219 gen_lxl(ctx, t1, t0, ctx->mem_idx, MO_TEUL); 4220 tcg_gen_trunc_tl_i32(fp0, t1); 4221 gen_store_fpr32(ctx, fp0, rt); 4222 break; 4223 case OPC_GSLWRC1: 4224 check_cp1_enabled(ctx); 4225 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4226 fp0 = tcg_temp_new_i32(); 4227 gen_load_fpr32(ctx, fp0, rt); 4228 t1 = tcg_temp_new(); 4229 tcg_gen_ext_i32_tl(t1, fp0); 4230 gen_lxr(ctx, t1, t0, ctx->mem_idx, MO_TEUL); 4231 tcg_gen_trunc_tl_i32(fp0, t1); 4232 gen_store_fpr32(ctx, fp0, rt); 4233 break; 4234 #if defined(TARGET_MIPS64) 4235 case OPC_GSLDLC1: 4236 check_cp1_enabled(ctx); 4237 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4238 t1 = tcg_temp_new(); 4239 gen_load_fpr64(ctx, t1, rt); 4240 gen_lxl(ctx, t1, t0, ctx->mem_idx, MO_TEUQ); 4241 gen_store_fpr64(ctx, t1, rt); 4242 break; 4243 case OPC_GSLDRC1: 4244 check_cp1_enabled(ctx); 4245 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4246 t1 = tcg_temp_new(); 4247 gen_load_fpr64(ctx, t1, rt); 4248 gen_lxr(ctx, t1, t0, ctx->mem_idx, MO_TEUQ); 4249 gen_store_fpr64(ctx, t1, rt); 4250 break; 4251 #endif 4252 default: 4253 MIPS_INVAL("loongson_gsshfl"); 4254 gen_reserved_instruction(ctx); 4255 break; 4256 } 4257 break; 4258 case OPC_GSSHFS: 4259 switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) { 4260 case OPC_GSSWLC1: 4261 check_cp1_enabled(ctx); 4262 t1 = tcg_temp_new(); 4263 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4264 fp0 = tcg_temp_new_i32(); 4265 gen_load_fpr32(ctx, fp0, rt); 4266 tcg_gen_ext_i32_tl(t1, fp0); 4267 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx); 4268 break; 4269 case OPC_GSSWRC1: 4270 check_cp1_enabled(ctx); 4271 t1 = tcg_temp_new(); 4272 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4273 fp0 = tcg_temp_new_i32(); 4274 gen_load_fpr32(ctx, fp0, rt); 4275 tcg_gen_ext_i32_tl(t1, fp0); 4276 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx); 4277 break; 4278 #if defined(TARGET_MIPS64) 4279 case OPC_GSSDLC1: 4280 check_cp1_enabled(ctx); 4281 t1 = tcg_temp_new(); 4282 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4283 gen_load_fpr64(ctx, t1, rt); 4284 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx); 4285 break; 4286 case OPC_GSSDRC1: 4287 check_cp1_enabled(ctx); 4288 t1 = tcg_temp_new(); 4289 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4290 gen_load_fpr64(ctx, t1, rt); 4291 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx); 4292 break; 4293 #endif 4294 default: 4295 MIPS_INVAL("loongson_gsshfs"); 4296 gen_reserved_instruction(ctx); 4297 break; 4298 } 4299 break; 4300 default: 4301 MIPS_INVAL("loongson_gslsq"); 4302 gen_reserved_instruction(ctx); 4303 break; 4304 } 4305 } 4306 4307 /* Loongson EXT LDC2/SDC2 */ 4308 static void gen_loongson_lsdc2(DisasContext *ctx, int rt, 4309 int rs, int rd) 4310 { 4311 int offset = sextract32(ctx->opcode, 3, 8); 4312 uint32_t opc = MASK_LOONGSON_LSDC2(ctx->opcode); 4313 TCGv t0, t1; 4314 TCGv_i32 fp0; 4315 4316 /* Pre-conditions */ 4317 switch (opc) { 4318 case OPC_GSLBX: 4319 case OPC_GSLHX: 4320 case OPC_GSLWX: 4321 case OPC_GSLDX: 4322 /* prefetch, implement as NOP */ 4323 if (rt == 0) { 4324 return; 4325 } 4326 break; 4327 case OPC_GSSBX: 4328 case OPC_GSSHX: 4329 case OPC_GSSWX: 4330 case OPC_GSSDX: 4331 break; 4332 case OPC_GSLWXC1: 4333 #if defined(TARGET_MIPS64) 4334 case OPC_GSLDXC1: 4335 #endif 4336 check_cp1_enabled(ctx); 4337 /* prefetch, implement as NOP */ 4338 if (rt == 0) { 4339 return; 4340 } 4341 break; 4342 case OPC_GSSWXC1: 4343 #if defined(TARGET_MIPS64) 4344 case OPC_GSSDXC1: 4345 #endif 4346 check_cp1_enabled(ctx); 4347 break; 4348 default: 4349 MIPS_INVAL("loongson_lsdc2"); 4350 gen_reserved_instruction(ctx); 4351 return; 4352 break; 4353 } 4354 4355 t0 = tcg_temp_new(); 4356 4357 gen_base_offset_addr(ctx, t0, rs, offset); 4358 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); 4359 4360 switch (opc) { 4361 case OPC_GSLBX: 4362 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB); 4363 gen_store_gpr(t0, rt); 4364 break; 4365 case OPC_GSLHX: 4366 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW | 4367 ctx->default_tcg_memop_mask); 4368 gen_store_gpr(t0, rt); 4369 break; 4370 case OPC_GSLWX: 4371 gen_base_offset_addr(ctx, t0, rs, offset); 4372 if (rd) { 4373 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); 4374 } 4375 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL | 4376 ctx->default_tcg_memop_mask); 4377 gen_store_gpr(t0, rt); 4378 break; 4379 #if defined(TARGET_MIPS64) 4380 case OPC_GSLDX: 4381 gen_base_offset_addr(ctx, t0, rs, offset); 4382 if (rd) { 4383 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); 4384 } 4385 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ | 4386 ctx->default_tcg_memop_mask); 4387 gen_store_gpr(t0, rt); 4388 break; 4389 #endif 4390 case OPC_GSLWXC1: 4391 gen_base_offset_addr(ctx, t0, rs, offset); 4392 if (rd) { 4393 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); 4394 } 4395 fp0 = tcg_temp_new_i32(); 4396 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL | 4397 ctx->default_tcg_memop_mask); 4398 gen_store_fpr32(ctx, fp0, rt); 4399 break; 4400 #if defined(TARGET_MIPS64) 4401 case OPC_GSLDXC1: 4402 gen_base_offset_addr(ctx, t0, rs, offset); 4403 if (rd) { 4404 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); 4405 } 4406 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ | 4407 ctx->default_tcg_memop_mask); 4408 gen_store_fpr64(ctx, t0, rt); 4409 break; 4410 #endif 4411 case OPC_GSSBX: 4412 t1 = tcg_temp_new(); 4413 gen_load_gpr(t1, rt); 4414 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_SB); 4415 break; 4416 case OPC_GSSHX: 4417 t1 = tcg_temp_new(); 4418 gen_load_gpr(t1, rt); 4419 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW | 4420 ctx->default_tcg_memop_mask); 4421 break; 4422 case OPC_GSSWX: 4423 t1 = tcg_temp_new(); 4424 gen_load_gpr(t1, rt); 4425 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL | 4426 ctx->default_tcg_memop_mask); 4427 break; 4428 #if defined(TARGET_MIPS64) 4429 case OPC_GSSDX: 4430 t1 = tcg_temp_new(); 4431 gen_load_gpr(t1, rt); 4432 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUQ | 4433 ctx->default_tcg_memop_mask); 4434 break; 4435 #endif 4436 case OPC_GSSWXC1: 4437 fp0 = tcg_temp_new_i32(); 4438 gen_load_fpr32(ctx, fp0, rt); 4439 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL | 4440 ctx->default_tcg_memop_mask); 4441 break; 4442 #if defined(TARGET_MIPS64) 4443 case OPC_GSSDXC1: 4444 t1 = tcg_temp_new(); 4445 gen_load_fpr64(ctx, t1, rt); 4446 tcg_gen_qemu_st_i64(t1, t0, ctx->mem_idx, MO_TEUQ | 4447 ctx->default_tcg_memop_mask); 4448 break; 4449 #endif 4450 default: 4451 break; 4452 } 4453 } 4454 4455 /* Traps */ 4456 static void gen_trap(DisasContext *ctx, uint32_t opc, 4457 int rs, int rt, int16_t imm, int code) 4458 { 4459 int cond; 4460 TCGv t0 = tcg_temp_new(); 4461 TCGv t1 = tcg_temp_new(); 4462 4463 cond = 0; 4464 /* Load needed operands */ 4465 switch (opc) { 4466 case OPC_TEQ: 4467 case OPC_TGE: 4468 case OPC_TGEU: 4469 case OPC_TLT: 4470 case OPC_TLTU: 4471 case OPC_TNE: 4472 /* Compare two registers */ 4473 if (rs != rt) { 4474 gen_load_gpr(t0, rs); 4475 gen_load_gpr(t1, rt); 4476 cond = 1; 4477 } 4478 break; 4479 case OPC_TEQI: 4480 case OPC_TGEI: 4481 case OPC_TGEIU: 4482 case OPC_TLTI: 4483 case OPC_TLTIU: 4484 case OPC_TNEI: 4485 /* Compare register to immediate */ 4486 if (rs != 0 || imm != 0) { 4487 gen_load_gpr(t0, rs); 4488 tcg_gen_movi_tl(t1, (int32_t)imm); 4489 cond = 1; 4490 } 4491 break; 4492 } 4493 if (cond == 0) { 4494 switch (opc) { 4495 case OPC_TEQ: /* rs == rs */ 4496 case OPC_TEQI: /* r0 == 0 */ 4497 case OPC_TGE: /* rs >= rs */ 4498 case OPC_TGEI: /* r0 >= 0 */ 4499 case OPC_TGEU: /* rs >= rs unsigned */ 4500 case OPC_TGEIU: /* r0 >= 0 unsigned */ 4501 /* Always trap */ 4502 #ifdef CONFIG_USER_ONLY 4503 /* Pass the break code along to cpu_loop. */ 4504 tcg_gen_st_i32(tcg_constant_i32(code), cpu_env, 4505 offsetof(CPUMIPSState, error_code)); 4506 #endif 4507 generate_exception_end(ctx, EXCP_TRAP); 4508 break; 4509 case OPC_TLT: /* rs < rs */ 4510 case OPC_TLTI: /* r0 < 0 */ 4511 case OPC_TLTU: /* rs < rs unsigned */ 4512 case OPC_TLTIU: /* r0 < 0 unsigned */ 4513 case OPC_TNE: /* rs != rs */ 4514 case OPC_TNEI: /* r0 != 0 */ 4515 /* Never trap: treat as NOP. */ 4516 break; 4517 } 4518 } else { 4519 TCGLabel *l1 = gen_new_label(); 4520 4521 switch (opc) { 4522 case OPC_TEQ: 4523 case OPC_TEQI: 4524 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1); 4525 break; 4526 case OPC_TGE: 4527 case OPC_TGEI: 4528 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1); 4529 break; 4530 case OPC_TGEU: 4531 case OPC_TGEIU: 4532 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1); 4533 break; 4534 case OPC_TLT: 4535 case OPC_TLTI: 4536 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1); 4537 break; 4538 case OPC_TLTU: 4539 case OPC_TLTIU: 4540 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1); 4541 break; 4542 case OPC_TNE: 4543 case OPC_TNEI: 4544 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1); 4545 break; 4546 } 4547 #ifdef CONFIG_USER_ONLY 4548 /* Pass the break code along to cpu_loop. */ 4549 tcg_gen_st_i32(tcg_constant_i32(code), cpu_env, 4550 offsetof(CPUMIPSState, error_code)); 4551 #endif 4552 /* Like save_cpu_state, only don't update saved values. */ 4553 if (ctx->base.pc_next != ctx->saved_pc) { 4554 gen_save_pc(ctx->base.pc_next); 4555 } 4556 if (ctx->hflags != ctx->saved_hflags) { 4557 tcg_gen_movi_i32(hflags, ctx->hflags); 4558 } 4559 generate_exception(ctx, EXCP_TRAP); 4560 gen_set_label(l1); 4561 } 4562 } 4563 4564 static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest) 4565 { 4566 if (translator_use_goto_tb(&ctx->base, dest)) { 4567 tcg_gen_goto_tb(n); 4568 gen_save_pc(dest); 4569 tcg_gen_exit_tb(ctx->base.tb, n); 4570 } else { 4571 gen_save_pc(dest); 4572 tcg_gen_lookup_and_goto_ptr(); 4573 } 4574 } 4575 4576 /* Branches (before delay slot) */ 4577 static void gen_compute_branch(DisasContext *ctx, uint32_t opc, 4578 int insn_bytes, 4579 int rs, int rt, int32_t offset, 4580 int delayslot_size) 4581 { 4582 target_ulong btgt = -1; 4583 int blink = 0; 4584 int bcond_compute = 0; 4585 TCGv t0 = tcg_temp_new(); 4586 TCGv t1 = tcg_temp_new(); 4587 4588 if (ctx->hflags & MIPS_HFLAG_BMASK) { 4589 #ifdef MIPS_DEBUG_DISAS 4590 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" 4591 TARGET_FMT_lx "\n", ctx->base.pc_next); 4592 #endif 4593 gen_reserved_instruction(ctx); 4594 goto out; 4595 } 4596 4597 /* Load needed operands */ 4598 switch (opc) { 4599 case OPC_BEQ: 4600 case OPC_BEQL: 4601 case OPC_BNE: 4602 case OPC_BNEL: 4603 /* Compare two registers */ 4604 if (rs != rt) { 4605 gen_load_gpr(t0, rs); 4606 gen_load_gpr(t1, rt); 4607 bcond_compute = 1; 4608 } 4609 btgt = ctx->base.pc_next + insn_bytes + offset; 4610 break; 4611 case OPC_BGEZ: 4612 case OPC_BGEZAL: 4613 case OPC_BGEZALL: 4614 case OPC_BGEZL: 4615 case OPC_BGTZ: 4616 case OPC_BGTZL: 4617 case OPC_BLEZ: 4618 case OPC_BLEZL: 4619 case OPC_BLTZ: 4620 case OPC_BLTZAL: 4621 case OPC_BLTZALL: 4622 case OPC_BLTZL: 4623 /* Compare to zero */ 4624 if (rs != 0) { 4625 gen_load_gpr(t0, rs); 4626 bcond_compute = 1; 4627 } 4628 btgt = ctx->base.pc_next + insn_bytes + offset; 4629 break; 4630 case OPC_BPOSGE32: 4631 #if defined(TARGET_MIPS64) 4632 case OPC_BPOSGE64: 4633 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F); 4634 #else 4635 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F); 4636 #endif 4637 bcond_compute = 1; 4638 btgt = ctx->base.pc_next + insn_bytes + offset; 4639 break; 4640 case OPC_J: 4641 case OPC_JAL: 4642 { 4643 /* Jump to immediate */ 4644 int jal_mask = ctx->hflags & MIPS_HFLAG_M16 ? 0xF8000000 4645 : 0xF0000000; 4646 btgt = ((ctx->base.pc_next + insn_bytes) & jal_mask) 4647 | (uint32_t)offset; 4648 break; 4649 } 4650 case OPC_JALX: 4651 /* Jump to immediate */ 4652 btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) | 4653 (uint32_t)offset; 4654 break; 4655 case OPC_JR: 4656 case OPC_JALR: 4657 /* Jump to register */ 4658 if (offset != 0 && offset != 16) { 4659 /* 4660 * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the 4661 * others are reserved. 4662 */ 4663 MIPS_INVAL("jump hint"); 4664 gen_reserved_instruction(ctx); 4665 goto out; 4666 } 4667 gen_load_gpr(btarget, rs); 4668 break; 4669 default: 4670 MIPS_INVAL("branch/jump"); 4671 gen_reserved_instruction(ctx); 4672 goto out; 4673 } 4674 if (bcond_compute == 0) { 4675 /* No condition to be computed */ 4676 switch (opc) { 4677 case OPC_BEQ: /* rx == rx */ 4678 case OPC_BEQL: /* rx == rx likely */ 4679 case OPC_BGEZ: /* 0 >= 0 */ 4680 case OPC_BGEZL: /* 0 >= 0 likely */ 4681 case OPC_BLEZ: /* 0 <= 0 */ 4682 case OPC_BLEZL: /* 0 <= 0 likely */ 4683 /* Always take */ 4684 ctx->hflags |= MIPS_HFLAG_B; 4685 break; 4686 case OPC_BGEZAL: /* 0 >= 0 */ 4687 case OPC_BGEZALL: /* 0 >= 0 likely */ 4688 /* Always take and link */ 4689 blink = 31; 4690 ctx->hflags |= MIPS_HFLAG_B; 4691 break; 4692 case OPC_BNE: /* rx != rx */ 4693 case OPC_BGTZ: /* 0 > 0 */ 4694 case OPC_BLTZ: /* 0 < 0 */ 4695 /* Treat as NOP. */ 4696 goto out; 4697 case OPC_BLTZAL: /* 0 < 0 */ 4698 /* 4699 * Handle as an unconditional branch to get correct delay 4700 * slot checking. 4701 */ 4702 blink = 31; 4703 btgt = ctx->base.pc_next + insn_bytes + delayslot_size; 4704 ctx->hflags |= MIPS_HFLAG_B; 4705 break; 4706 case OPC_BLTZALL: /* 0 < 0 likely */ 4707 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8); 4708 /* Skip the instruction in the delay slot */ 4709 ctx->base.pc_next += 4; 4710 goto out; 4711 case OPC_BNEL: /* rx != rx likely */ 4712 case OPC_BGTZL: /* 0 > 0 likely */ 4713 case OPC_BLTZL: /* 0 < 0 likely */ 4714 /* Skip the instruction in the delay slot */ 4715 ctx->base.pc_next += 4; 4716 goto out; 4717 case OPC_J: 4718 ctx->hflags |= MIPS_HFLAG_B; 4719 break; 4720 case OPC_JALX: 4721 ctx->hflags |= MIPS_HFLAG_BX; 4722 /* Fallthrough */ 4723 case OPC_JAL: 4724 blink = 31; 4725 ctx->hflags |= MIPS_HFLAG_B; 4726 break; 4727 case OPC_JR: 4728 ctx->hflags |= MIPS_HFLAG_BR; 4729 break; 4730 case OPC_JALR: 4731 blink = rt; 4732 ctx->hflags |= MIPS_HFLAG_BR; 4733 break; 4734 default: 4735 MIPS_INVAL("branch/jump"); 4736 gen_reserved_instruction(ctx); 4737 goto out; 4738 } 4739 } else { 4740 switch (opc) { 4741 case OPC_BEQ: 4742 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1); 4743 goto not_likely; 4744 case OPC_BEQL: 4745 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1); 4746 goto likely; 4747 case OPC_BNE: 4748 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1); 4749 goto not_likely; 4750 case OPC_BNEL: 4751 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1); 4752 goto likely; 4753 case OPC_BGEZ: 4754 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0); 4755 goto not_likely; 4756 case OPC_BGEZL: 4757 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0); 4758 goto likely; 4759 case OPC_BGEZAL: 4760 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0); 4761 blink = 31; 4762 goto not_likely; 4763 case OPC_BGEZALL: 4764 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0); 4765 blink = 31; 4766 goto likely; 4767 case OPC_BGTZ: 4768 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0); 4769 goto not_likely; 4770 case OPC_BGTZL: 4771 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0); 4772 goto likely; 4773 case OPC_BLEZ: 4774 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0); 4775 goto not_likely; 4776 case OPC_BLEZL: 4777 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0); 4778 goto likely; 4779 case OPC_BLTZ: 4780 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0); 4781 goto not_likely; 4782 case OPC_BLTZL: 4783 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0); 4784 goto likely; 4785 case OPC_BPOSGE32: 4786 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32); 4787 goto not_likely; 4788 #if defined(TARGET_MIPS64) 4789 case OPC_BPOSGE64: 4790 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64); 4791 goto not_likely; 4792 #endif 4793 case OPC_BLTZAL: 4794 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0); 4795 blink = 31; 4796 not_likely: 4797 ctx->hflags |= MIPS_HFLAG_BC; 4798 break; 4799 case OPC_BLTZALL: 4800 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0); 4801 blink = 31; 4802 likely: 4803 ctx->hflags |= MIPS_HFLAG_BL; 4804 break; 4805 default: 4806 MIPS_INVAL("conditional branch/jump"); 4807 gen_reserved_instruction(ctx); 4808 goto out; 4809 } 4810 } 4811 4812 ctx->btarget = btgt; 4813 4814 switch (delayslot_size) { 4815 case 2: 4816 ctx->hflags |= MIPS_HFLAG_BDS16; 4817 break; 4818 case 4: 4819 ctx->hflags |= MIPS_HFLAG_BDS32; 4820 break; 4821 } 4822 4823 if (blink > 0) { 4824 int post_delay = insn_bytes + delayslot_size; 4825 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16); 4826 4827 tcg_gen_movi_tl(cpu_gpr[blink], 4828 ctx->base.pc_next + post_delay + lowbit); 4829 } 4830 4831 out: 4832 if (insn_bytes == 2) { 4833 ctx->hflags |= MIPS_HFLAG_B16; 4834 } 4835 } 4836 4837 4838 /* special3 bitfield operations */ 4839 static void gen_bitops(DisasContext *ctx, uint32_t opc, int rt, 4840 int rs, int lsb, int msb) 4841 { 4842 TCGv t0 = tcg_temp_new(); 4843 TCGv t1 = tcg_temp_new(); 4844 4845 gen_load_gpr(t1, rs); 4846 switch (opc) { 4847 case OPC_EXT: 4848 if (lsb + msb > 31) { 4849 goto fail; 4850 } 4851 if (msb != 31) { 4852 tcg_gen_extract_tl(t0, t1, lsb, msb + 1); 4853 } else { 4854 /* 4855 * The two checks together imply that lsb == 0, 4856 * so this is a simple sign-extension. 4857 */ 4858 tcg_gen_ext32s_tl(t0, t1); 4859 } 4860 break; 4861 #if defined(TARGET_MIPS64) 4862 case OPC_DEXTU: 4863 lsb += 32; 4864 goto do_dext; 4865 case OPC_DEXTM: 4866 msb += 32; 4867 goto do_dext; 4868 case OPC_DEXT: 4869 do_dext: 4870 if (lsb + msb > 63) { 4871 goto fail; 4872 } 4873 tcg_gen_extract_tl(t0, t1, lsb, msb + 1); 4874 break; 4875 #endif 4876 case OPC_INS: 4877 if (lsb > msb) { 4878 goto fail; 4879 } 4880 gen_load_gpr(t0, rt); 4881 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1); 4882 tcg_gen_ext32s_tl(t0, t0); 4883 break; 4884 #if defined(TARGET_MIPS64) 4885 case OPC_DINSU: 4886 lsb += 32; 4887 /* FALLTHRU */ 4888 case OPC_DINSM: 4889 msb += 32; 4890 /* FALLTHRU */ 4891 case OPC_DINS: 4892 if (lsb > msb) { 4893 goto fail; 4894 } 4895 gen_load_gpr(t0, rt); 4896 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1); 4897 break; 4898 #endif 4899 default: 4900 fail: 4901 MIPS_INVAL("bitops"); 4902 gen_reserved_instruction(ctx); 4903 return; 4904 } 4905 gen_store_gpr(t0, rt); 4906 } 4907 4908 static void gen_bshfl(DisasContext *ctx, uint32_t op2, int rt, int rd) 4909 { 4910 TCGv t0; 4911 4912 if (rd == 0) { 4913 /* If no destination, treat it as a NOP. */ 4914 return; 4915 } 4916 4917 t0 = tcg_temp_new(); 4918 gen_load_gpr(t0, rt); 4919 switch (op2) { 4920 case OPC_WSBH: 4921 { 4922 TCGv t1 = tcg_temp_new(); 4923 TCGv t2 = tcg_constant_tl(0x00FF00FF); 4924 4925 tcg_gen_shri_tl(t1, t0, 8); 4926 tcg_gen_and_tl(t1, t1, t2); 4927 tcg_gen_and_tl(t0, t0, t2); 4928 tcg_gen_shli_tl(t0, t0, 8); 4929 tcg_gen_or_tl(t0, t0, t1); 4930 tcg_gen_ext32s_tl(cpu_gpr[rd], t0); 4931 } 4932 break; 4933 case OPC_SEB: 4934 tcg_gen_ext8s_tl(cpu_gpr[rd], t0); 4935 break; 4936 case OPC_SEH: 4937 tcg_gen_ext16s_tl(cpu_gpr[rd], t0); 4938 break; 4939 #if defined(TARGET_MIPS64) 4940 case OPC_DSBH: 4941 { 4942 TCGv t1 = tcg_temp_new(); 4943 TCGv t2 = tcg_constant_tl(0x00FF00FF00FF00FFULL); 4944 4945 tcg_gen_shri_tl(t1, t0, 8); 4946 tcg_gen_and_tl(t1, t1, t2); 4947 tcg_gen_and_tl(t0, t0, t2); 4948 tcg_gen_shli_tl(t0, t0, 8); 4949 tcg_gen_or_tl(cpu_gpr[rd], t0, t1); 4950 } 4951 break; 4952 case OPC_DSHD: 4953 { 4954 TCGv t1 = tcg_temp_new(); 4955 TCGv t2 = tcg_constant_tl(0x0000FFFF0000FFFFULL); 4956 4957 tcg_gen_shri_tl(t1, t0, 16); 4958 tcg_gen_and_tl(t1, t1, t2); 4959 tcg_gen_and_tl(t0, t0, t2); 4960 tcg_gen_shli_tl(t0, t0, 16); 4961 tcg_gen_or_tl(t0, t0, t1); 4962 tcg_gen_shri_tl(t1, t0, 32); 4963 tcg_gen_shli_tl(t0, t0, 32); 4964 tcg_gen_or_tl(cpu_gpr[rd], t0, t1); 4965 } 4966 break; 4967 #endif 4968 default: 4969 MIPS_INVAL("bsfhl"); 4970 gen_reserved_instruction(ctx); 4971 return; 4972 } 4973 } 4974 4975 static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs, 4976 int rt, int bits) 4977 { 4978 TCGv t0; 4979 if (rd == 0) { 4980 /* Treat as NOP. */ 4981 return; 4982 } 4983 t0 = tcg_temp_new(); 4984 if (bits == 0 || bits == wordsz) { 4985 if (bits == 0) { 4986 gen_load_gpr(t0, rt); 4987 } else { 4988 gen_load_gpr(t0, rs); 4989 } 4990 switch (wordsz) { 4991 case 32: 4992 tcg_gen_ext32s_tl(cpu_gpr[rd], t0); 4993 break; 4994 #if defined(TARGET_MIPS64) 4995 case 64: 4996 tcg_gen_mov_tl(cpu_gpr[rd], t0); 4997 break; 4998 #endif 4999 } 5000 } else { 5001 TCGv t1 = tcg_temp_new(); 5002 gen_load_gpr(t0, rt); 5003 gen_load_gpr(t1, rs); 5004 switch (wordsz) { 5005 case 32: 5006 { 5007 TCGv_i64 t2 = tcg_temp_new_i64(); 5008 tcg_gen_concat_tl_i64(t2, t1, t0); 5009 tcg_gen_shri_i64(t2, t2, 32 - bits); 5010 gen_move_low32(cpu_gpr[rd], t2); 5011 } 5012 break; 5013 #if defined(TARGET_MIPS64) 5014 case 64: 5015 tcg_gen_shli_tl(t0, t0, bits); 5016 tcg_gen_shri_tl(t1, t1, 64 - bits); 5017 tcg_gen_or_tl(cpu_gpr[rd], t1, t0); 5018 break; 5019 #endif 5020 } 5021 } 5022 } 5023 5024 void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt, int bp) 5025 { 5026 gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8); 5027 } 5028 5029 static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt) 5030 { 5031 TCGv t0; 5032 if (rd == 0) { 5033 /* Treat as NOP. */ 5034 return; 5035 } 5036 t0 = tcg_temp_new(); 5037 gen_load_gpr(t0, rt); 5038 switch (opc) { 5039 case OPC_BITSWAP: 5040 gen_helper_bitswap(cpu_gpr[rd], t0); 5041 break; 5042 #if defined(TARGET_MIPS64) 5043 case OPC_DBITSWAP: 5044 gen_helper_dbitswap(cpu_gpr[rd], t0); 5045 break; 5046 #endif 5047 } 5048 } 5049 5050 #ifndef CONFIG_USER_ONLY 5051 /* CP0 (MMU and control) */ 5052 static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off) 5053 { 5054 TCGv_i64 t0 = tcg_temp_new_i64(); 5055 TCGv_i64 t1 = tcg_temp_new_i64(); 5056 5057 tcg_gen_ext_tl_i64(t0, arg); 5058 tcg_gen_ld_i64(t1, cpu_env, off); 5059 #if defined(TARGET_MIPS64) 5060 tcg_gen_deposit_i64(t1, t1, t0, 30, 32); 5061 #else 5062 tcg_gen_concat32_i64(t1, t1, t0); 5063 #endif 5064 tcg_gen_st_i64(t1, cpu_env, off); 5065 } 5066 5067 static inline void gen_mthc0_store64(TCGv arg, target_ulong off) 5068 { 5069 TCGv_i64 t0 = tcg_temp_new_i64(); 5070 TCGv_i64 t1 = tcg_temp_new_i64(); 5071 5072 tcg_gen_ext_tl_i64(t0, arg); 5073 tcg_gen_ld_i64(t1, cpu_env, off); 5074 tcg_gen_concat32_i64(t1, t1, t0); 5075 tcg_gen_st_i64(t1, cpu_env, off); 5076 } 5077 5078 static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off) 5079 { 5080 TCGv_i64 t0 = tcg_temp_new_i64(); 5081 5082 tcg_gen_ld_i64(t0, cpu_env, off); 5083 #if defined(TARGET_MIPS64) 5084 tcg_gen_shri_i64(t0, t0, 30); 5085 #else 5086 tcg_gen_shri_i64(t0, t0, 32); 5087 #endif 5088 gen_move_low32(arg, t0); 5089 } 5090 5091 static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift) 5092 { 5093 TCGv_i64 t0 = tcg_temp_new_i64(); 5094 5095 tcg_gen_ld_i64(t0, cpu_env, off); 5096 tcg_gen_shri_i64(t0, t0, 32 + shift); 5097 gen_move_low32(arg, t0); 5098 } 5099 5100 static inline void gen_mfc0_load32(TCGv arg, target_ulong off) 5101 { 5102 TCGv_i32 t0 = tcg_temp_new_i32(); 5103 5104 tcg_gen_ld_i32(t0, cpu_env, off); 5105 tcg_gen_ext_i32_tl(arg, t0); 5106 } 5107 5108 static inline void gen_mfc0_load64(TCGv arg, target_ulong off) 5109 { 5110 tcg_gen_ld_tl(arg, cpu_env, off); 5111 tcg_gen_ext32s_tl(arg, arg); 5112 } 5113 5114 static inline void gen_mtc0_store32(TCGv arg, target_ulong off) 5115 { 5116 TCGv_i32 t0 = tcg_temp_new_i32(); 5117 5118 tcg_gen_trunc_tl_i32(t0, arg); 5119 tcg_gen_st_i32(t0, cpu_env, off); 5120 } 5121 5122 #define CP0_CHECK(c) \ 5123 do { \ 5124 if (!(c)) { \ 5125 goto cp0_unimplemented; \ 5126 } \ 5127 } while (0) 5128 5129 static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel) 5130 { 5131 const char *register_name = "invalid"; 5132 5133 switch (reg) { 5134 case CP0_REGISTER_02: 5135 switch (sel) { 5136 case 0: 5137 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA); 5138 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0)); 5139 register_name = "EntryLo0"; 5140 break; 5141 default: 5142 goto cp0_unimplemented; 5143 } 5144 break; 5145 case CP0_REGISTER_03: 5146 switch (sel) { 5147 case CP0_REG03__ENTRYLO1: 5148 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA); 5149 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1)); 5150 register_name = "EntryLo1"; 5151 break; 5152 default: 5153 goto cp0_unimplemented; 5154 } 5155 break; 5156 case CP0_REGISTER_09: 5157 switch (sel) { 5158 case CP0_REG09__SAAR: 5159 CP0_CHECK(ctx->saar); 5160 gen_helper_mfhc0_saar(arg, cpu_env); 5161 register_name = "SAAR"; 5162 break; 5163 default: 5164 goto cp0_unimplemented; 5165 } 5166 break; 5167 case CP0_REGISTER_17: 5168 switch (sel) { 5169 case CP0_REG17__LLADDR: 5170 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_LLAddr), 5171 ctx->CP0_LLAddr_shift); 5172 register_name = "LLAddr"; 5173 break; 5174 case CP0_REG17__MAAR: 5175 CP0_CHECK(ctx->mrp); 5176 gen_helper_mfhc0_maar(arg, cpu_env); 5177 register_name = "MAAR"; 5178 break; 5179 default: 5180 goto cp0_unimplemented; 5181 } 5182 break; 5183 case CP0_REGISTER_19: 5184 switch (sel) { 5185 case CP0_REG19__WATCHHI0: 5186 case CP0_REG19__WATCHHI1: 5187 case CP0_REG19__WATCHHI2: 5188 case CP0_REG19__WATCHHI3: 5189 case CP0_REG19__WATCHHI4: 5190 case CP0_REG19__WATCHHI5: 5191 case CP0_REG19__WATCHHI6: 5192 case CP0_REG19__WATCHHI7: 5193 /* upper 32 bits are only available when Config5MI != 0 */ 5194 CP0_CHECK(ctx->mi); 5195 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_WatchHi[sel]), 0); 5196 register_name = "WatchHi"; 5197 break; 5198 default: 5199 goto cp0_unimplemented; 5200 } 5201 break; 5202 case CP0_REGISTER_28: 5203 switch (sel) { 5204 case 0: 5205 case 2: 5206 case 4: 5207 case 6: 5208 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0); 5209 register_name = "TagLo"; 5210 break; 5211 default: 5212 goto cp0_unimplemented; 5213 } 5214 break; 5215 default: 5216 goto cp0_unimplemented; 5217 } 5218 trace_mips_translate_c0("mfhc0", register_name, reg, sel); 5219 return; 5220 5221 cp0_unimplemented: 5222 qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n", 5223 register_name, reg, sel); 5224 tcg_gen_movi_tl(arg, 0); 5225 } 5226 5227 static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel) 5228 { 5229 const char *register_name = "invalid"; 5230 uint64_t mask = ctx->PAMask >> 36; 5231 5232 switch (reg) { 5233 case CP0_REGISTER_02: 5234 switch (sel) { 5235 case 0: 5236 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA); 5237 tcg_gen_andi_tl(arg, arg, mask); 5238 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0)); 5239 register_name = "EntryLo0"; 5240 break; 5241 default: 5242 goto cp0_unimplemented; 5243 } 5244 break; 5245 case CP0_REGISTER_03: 5246 switch (sel) { 5247 case CP0_REG03__ENTRYLO1: 5248 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA); 5249 tcg_gen_andi_tl(arg, arg, mask); 5250 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1)); 5251 register_name = "EntryLo1"; 5252 break; 5253 default: 5254 goto cp0_unimplemented; 5255 } 5256 break; 5257 case CP0_REGISTER_09: 5258 switch (sel) { 5259 case CP0_REG09__SAAR: 5260 CP0_CHECK(ctx->saar); 5261 gen_helper_mthc0_saar(cpu_env, arg); 5262 register_name = "SAAR"; 5263 break; 5264 default: 5265 goto cp0_unimplemented; 5266 } 5267 break; 5268 case CP0_REGISTER_17: 5269 switch (sel) { 5270 case CP0_REG17__LLADDR: 5271 /* 5272 * LLAddr is read-only (the only exception is bit 0 if LLB is 5273 * supported); the CP0_LLAddr_rw_bitmask does not seem to be 5274 * relevant for modern MIPS cores supporting MTHC0, therefore 5275 * treating MTHC0 to LLAddr as NOP. 5276 */ 5277 register_name = "LLAddr"; 5278 break; 5279 case CP0_REG17__MAAR: 5280 CP0_CHECK(ctx->mrp); 5281 gen_helper_mthc0_maar(cpu_env, arg); 5282 register_name = "MAAR"; 5283 break; 5284 default: 5285 goto cp0_unimplemented; 5286 } 5287 break; 5288 case CP0_REGISTER_19: 5289 switch (sel) { 5290 case CP0_REG19__WATCHHI0: 5291 case CP0_REG19__WATCHHI1: 5292 case CP0_REG19__WATCHHI2: 5293 case CP0_REG19__WATCHHI3: 5294 case CP0_REG19__WATCHHI4: 5295 case CP0_REG19__WATCHHI5: 5296 case CP0_REG19__WATCHHI6: 5297 case CP0_REG19__WATCHHI7: 5298 /* upper 32 bits are only available when Config5MI != 0 */ 5299 CP0_CHECK(ctx->mi); 5300 gen_helper_0e1i(mthc0_watchhi, arg, sel); 5301 register_name = "WatchHi"; 5302 break; 5303 default: 5304 goto cp0_unimplemented; 5305 } 5306 break; 5307 case CP0_REGISTER_28: 5308 switch (sel) { 5309 case 0: 5310 case 2: 5311 case 4: 5312 case 6: 5313 tcg_gen_andi_tl(arg, arg, mask); 5314 gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo)); 5315 register_name = "TagLo"; 5316 break; 5317 default: 5318 goto cp0_unimplemented; 5319 } 5320 break; 5321 default: 5322 goto cp0_unimplemented; 5323 } 5324 trace_mips_translate_c0("mthc0", register_name, reg, sel); 5325 return; 5326 5327 cp0_unimplemented: 5328 qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n", 5329 register_name, reg, sel); 5330 } 5331 5332 static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg) 5333 { 5334 if (ctx->insn_flags & ISA_MIPS_R6) { 5335 tcg_gen_movi_tl(arg, 0); 5336 } else { 5337 tcg_gen_movi_tl(arg, ~0); 5338 } 5339 } 5340 5341 static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) 5342 { 5343 const char *register_name = "invalid"; 5344 5345 if (sel != 0) { 5346 check_insn(ctx, ISA_MIPS_R1); 5347 } 5348 5349 switch (reg) { 5350 case CP0_REGISTER_00: 5351 switch (sel) { 5352 case CP0_REG00__INDEX: 5353 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index)); 5354 register_name = "Index"; 5355 break; 5356 case CP0_REG00__MVPCONTROL: 5357 CP0_CHECK(ctx->insn_flags & ASE_MT); 5358 gen_helper_mfc0_mvpcontrol(arg, cpu_env); 5359 register_name = "MVPControl"; 5360 break; 5361 case CP0_REG00__MVPCONF0: 5362 CP0_CHECK(ctx->insn_flags & ASE_MT); 5363 gen_helper_mfc0_mvpconf0(arg, cpu_env); 5364 register_name = "MVPConf0"; 5365 break; 5366 case CP0_REG00__MVPCONF1: 5367 CP0_CHECK(ctx->insn_flags & ASE_MT); 5368 gen_helper_mfc0_mvpconf1(arg, cpu_env); 5369 register_name = "MVPConf1"; 5370 break; 5371 case CP0_REG00__VPCONTROL: 5372 CP0_CHECK(ctx->vp); 5373 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl)); 5374 register_name = "VPControl"; 5375 break; 5376 default: 5377 goto cp0_unimplemented; 5378 } 5379 break; 5380 case CP0_REGISTER_01: 5381 switch (sel) { 5382 case CP0_REG01__RANDOM: 5383 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 5384 gen_helper_mfc0_random(arg, cpu_env); 5385 register_name = "Random"; 5386 break; 5387 case CP0_REG01__VPECONTROL: 5388 CP0_CHECK(ctx->insn_flags & ASE_MT); 5389 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl)); 5390 register_name = "VPEControl"; 5391 break; 5392 case CP0_REG01__VPECONF0: 5393 CP0_CHECK(ctx->insn_flags & ASE_MT); 5394 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0)); 5395 register_name = "VPEConf0"; 5396 break; 5397 case CP0_REG01__VPECONF1: 5398 CP0_CHECK(ctx->insn_flags & ASE_MT); 5399 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1)); 5400 register_name = "VPEConf1"; 5401 break; 5402 case CP0_REG01__YQMASK: 5403 CP0_CHECK(ctx->insn_flags & ASE_MT); 5404 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask)); 5405 register_name = "YQMask"; 5406 break; 5407 case CP0_REG01__VPESCHEDULE: 5408 CP0_CHECK(ctx->insn_flags & ASE_MT); 5409 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule)); 5410 register_name = "VPESchedule"; 5411 break; 5412 case CP0_REG01__VPESCHEFBACK: 5413 CP0_CHECK(ctx->insn_flags & ASE_MT); 5414 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack)); 5415 register_name = "VPEScheFBack"; 5416 break; 5417 case CP0_REG01__VPEOPT: 5418 CP0_CHECK(ctx->insn_flags & ASE_MT); 5419 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt)); 5420 register_name = "VPEOpt"; 5421 break; 5422 default: 5423 goto cp0_unimplemented; 5424 } 5425 break; 5426 case CP0_REGISTER_02: 5427 switch (sel) { 5428 case CP0_REG02__ENTRYLO0: 5429 { 5430 TCGv_i64 tmp = tcg_temp_new_i64(); 5431 tcg_gen_ld_i64(tmp, cpu_env, 5432 offsetof(CPUMIPSState, CP0_EntryLo0)); 5433 #if defined(TARGET_MIPS64) 5434 if (ctx->rxi) { 5435 /* Move RI/XI fields to bits 31:30 */ 5436 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI); 5437 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2); 5438 } 5439 #endif 5440 gen_move_low32(arg, tmp); 5441 } 5442 register_name = "EntryLo0"; 5443 break; 5444 case CP0_REG02__TCSTATUS: 5445 CP0_CHECK(ctx->insn_flags & ASE_MT); 5446 gen_helper_mfc0_tcstatus(arg, cpu_env); 5447 register_name = "TCStatus"; 5448 break; 5449 case CP0_REG02__TCBIND: 5450 CP0_CHECK(ctx->insn_flags & ASE_MT); 5451 gen_helper_mfc0_tcbind(arg, cpu_env); 5452 register_name = "TCBind"; 5453 break; 5454 case CP0_REG02__TCRESTART: 5455 CP0_CHECK(ctx->insn_flags & ASE_MT); 5456 gen_helper_mfc0_tcrestart(arg, cpu_env); 5457 register_name = "TCRestart"; 5458 break; 5459 case CP0_REG02__TCHALT: 5460 CP0_CHECK(ctx->insn_flags & ASE_MT); 5461 gen_helper_mfc0_tchalt(arg, cpu_env); 5462 register_name = "TCHalt"; 5463 break; 5464 case CP0_REG02__TCCONTEXT: 5465 CP0_CHECK(ctx->insn_flags & ASE_MT); 5466 gen_helper_mfc0_tccontext(arg, cpu_env); 5467 register_name = "TCContext"; 5468 break; 5469 case CP0_REG02__TCSCHEDULE: 5470 CP0_CHECK(ctx->insn_flags & ASE_MT); 5471 gen_helper_mfc0_tcschedule(arg, cpu_env); 5472 register_name = "TCSchedule"; 5473 break; 5474 case CP0_REG02__TCSCHEFBACK: 5475 CP0_CHECK(ctx->insn_flags & ASE_MT); 5476 gen_helper_mfc0_tcschefback(arg, cpu_env); 5477 register_name = "TCScheFBack"; 5478 break; 5479 default: 5480 goto cp0_unimplemented; 5481 } 5482 break; 5483 case CP0_REGISTER_03: 5484 switch (sel) { 5485 case CP0_REG03__ENTRYLO1: 5486 { 5487 TCGv_i64 tmp = tcg_temp_new_i64(); 5488 tcg_gen_ld_i64(tmp, cpu_env, 5489 offsetof(CPUMIPSState, CP0_EntryLo1)); 5490 #if defined(TARGET_MIPS64) 5491 if (ctx->rxi) { 5492 /* Move RI/XI fields to bits 31:30 */ 5493 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI); 5494 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2); 5495 } 5496 #endif 5497 gen_move_low32(arg, tmp); 5498 } 5499 register_name = "EntryLo1"; 5500 break; 5501 case CP0_REG03__GLOBALNUM: 5502 CP0_CHECK(ctx->vp); 5503 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber)); 5504 register_name = "GlobalNumber"; 5505 break; 5506 default: 5507 goto cp0_unimplemented; 5508 } 5509 break; 5510 case CP0_REGISTER_04: 5511 switch (sel) { 5512 case CP0_REG04__CONTEXT: 5513 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context)); 5514 tcg_gen_ext32s_tl(arg, arg); 5515 register_name = "Context"; 5516 break; 5517 case CP0_REG04__CONTEXTCONFIG: 5518 /* SmartMIPS ASE */ 5519 /* gen_helper_mfc0_contextconfig(arg); */ 5520 register_name = "ContextConfig"; 5521 goto cp0_unimplemented; 5522 case CP0_REG04__USERLOCAL: 5523 CP0_CHECK(ctx->ulri); 5524 tcg_gen_ld_tl(arg, cpu_env, 5525 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 5526 tcg_gen_ext32s_tl(arg, arg); 5527 register_name = "UserLocal"; 5528 break; 5529 case CP0_REG04__MMID: 5530 CP0_CHECK(ctx->mi); 5531 gen_helper_mtc0_memorymapid(cpu_env, arg); 5532 register_name = "MMID"; 5533 break; 5534 default: 5535 goto cp0_unimplemented; 5536 } 5537 break; 5538 case CP0_REGISTER_05: 5539 switch (sel) { 5540 case CP0_REG05__PAGEMASK: 5541 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask)); 5542 register_name = "PageMask"; 5543 break; 5544 case CP0_REG05__PAGEGRAIN: 5545 check_insn(ctx, ISA_MIPS_R2); 5546 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain)); 5547 register_name = "PageGrain"; 5548 break; 5549 case CP0_REG05__SEGCTL0: 5550 CP0_CHECK(ctx->sc); 5551 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0)); 5552 tcg_gen_ext32s_tl(arg, arg); 5553 register_name = "SegCtl0"; 5554 break; 5555 case CP0_REG05__SEGCTL1: 5556 CP0_CHECK(ctx->sc); 5557 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1)); 5558 tcg_gen_ext32s_tl(arg, arg); 5559 register_name = "SegCtl1"; 5560 break; 5561 case CP0_REG05__SEGCTL2: 5562 CP0_CHECK(ctx->sc); 5563 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2)); 5564 tcg_gen_ext32s_tl(arg, arg); 5565 register_name = "SegCtl2"; 5566 break; 5567 case CP0_REG05__PWBASE: 5568 check_pw(ctx); 5569 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWBase)); 5570 register_name = "PWBase"; 5571 break; 5572 case CP0_REG05__PWFIELD: 5573 check_pw(ctx); 5574 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWField)); 5575 register_name = "PWField"; 5576 break; 5577 case CP0_REG05__PWSIZE: 5578 check_pw(ctx); 5579 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWSize)); 5580 register_name = "PWSize"; 5581 break; 5582 default: 5583 goto cp0_unimplemented; 5584 } 5585 break; 5586 case CP0_REGISTER_06: 5587 switch (sel) { 5588 case CP0_REG06__WIRED: 5589 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired)); 5590 register_name = "Wired"; 5591 break; 5592 case CP0_REG06__SRSCONF0: 5593 check_insn(ctx, ISA_MIPS_R2); 5594 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0)); 5595 register_name = "SRSConf0"; 5596 break; 5597 case CP0_REG06__SRSCONF1: 5598 check_insn(ctx, ISA_MIPS_R2); 5599 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1)); 5600 register_name = "SRSConf1"; 5601 break; 5602 case CP0_REG06__SRSCONF2: 5603 check_insn(ctx, ISA_MIPS_R2); 5604 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2)); 5605 register_name = "SRSConf2"; 5606 break; 5607 case CP0_REG06__SRSCONF3: 5608 check_insn(ctx, ISA_MIPS_R2); 5609 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3)); 5610 register_name = "SRSConf3"; 5611 break; 5612 case CP0_REG06__SRSCONF4: 5613 check_insn(ctx, ISA_MIPS_R2); 5614 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4)); 5615 register_name = "SRSConf4"; 5616 break; 5617 case CP0_REG06__PWCTL: 5618 check_pw(ctx); 5619 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl)); 5620 register_name = "PWCtl"; 5621 break; 5622 default: 5623 goto cp0_unimplemented; 5624 } 5625 break; 5626 case CP0_REGISTER_07: 5627 switch (sel) { 5628 case CP0_REG07__HWRENA: 5629 check_insn(ctx, ISA_MIPS_R2); 5630 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna)); 5631 register_name = "HWREna"; 5632 break; 5633 default: 5634 goto cp0_unimplemented; 5635 } 5636 break; 5637 case CP0_REGISTER_08: 5638 switch (sel) { 5639 case CP0_REG08__BADVADDR: 5640 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); 5641 tcg_gen_ext32s_tl(arg, arg); 5642 register_name = "BadVAddr"; 5643 break; 5644 case CP0_REG08__BADINSTR: 5645 CP0_CHECK(ctx->bi); 5646 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr)); 5647 register_name = "BadInstr"; 5648 break; 5649 case CP0_REG08__BADINSTRP: 5650 CP0_CHECK(ctx->bp); 5651 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP)); 5652 register_name = "BadInstrP"; 5653 break; 5654 case CP0_REG08__BADINSTRX: 5655 CP0_CHECK(ctx->bi); 5656 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX)); 5657 tcg_gen_andi_tl(arg, arg, ~0xffff); 5658 register_name = "BadInstrX"; 5659 break; 5660 default: 5661 goto cp0_unimplemented; 5662 } 5663 break; 5664 case CP0_REGISTER_09: 5665 switch (sel) { 5666 case CP0_REG09__COUNT: 5667 /* Mark as an IO operation because we read the time. */ 5668 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { 5669 gen_io_start(); 5670 } 5671 gen_helper_mfc0_count(arg, cpu_env); 5672 /* 5673 * Break the TB to be able to take timer interrupts immediately 5674 * after reading count. DISAS_STOP isn't sufficient, we need to 5675 * ensure we break completely out of translated code. 5676 */ 5677 gen_save_pc(ctx->base.pc_next + 4); 5678 ctx->base.is_jmp = DISAS_EXIT; 5679 register_name = "Count"; 5680 break; 5681 case CP0_REG09__SAARI: 5682 CP0_CHECK(ctx->saar); 5683 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI)); 5684 register_name = "SAARI"; 5685 break; 5686 case CP0_REG09__SAAR: 5687 CP0_CHECK(ctx->saar); 5688 gen_helper_mfc0_saar(arg, cpu_env); 5689 register_name = "SAAR"; 5690 break; 5691 default: 5692 goto cp0_unimplemented; 5693 } 5694 break; 5695 case CP0_REGISTER_10: 5696 switch (sel) { 5697 case CP0_REG10__ENTRYHI: 5698 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi)); 5699 tcg_gen_ext32s_tl(arg, arg); 5700 register_name = "EntryHi"; 5701 break; 5702 default: 5703 goto cp0_unimplemented; 5704 } 5705 break; 5706 case CP0_REGISTER_11: 5707 switch (sel) { 5708 case CP0_REG11__COMPARE: 5709 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare)); 5710 register_name = "Compare"; 5711 break; 5712 /* 6,7 are implementation dependent */ 5713 default: 5714 goto cp0_unimplemented; 5715 } 5716 break; 5717 case CP0_REGISTER_12: 5718 switch (sel) { 5719 case CP0_REG12__STATUS: 5720 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status)); 5721 register_name = "Status"; 5722 break; 5723 case CP0_REG12__INTCTL: 5724 check_insn(ctx, ISA_MIPS_R2); 5725 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl)); 5726 register_name = "IntCtl"; 5727 break; 5728 case CP0_REG12__SRSCTL: 5729 check_insn(ctx, ISA_MIPS_R2); 5730 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl)); 5731 register_name = "SRSCtl"; 5732 break; 5733 case CP0_REG12__SRSMAP: 5734 check_insn(ctx, ISA_MIPS_R2); 5735 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); 5736 register_name = "SRSMap"; 5737 break; 5738 default: 5739 goto cp0_unimplemented; 5740 } 5741 break; 5742 case CP0_REGISTER_13: 5743 switch (sel) { 5744 case CP0_REG13__CAUSE: 5745 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause)); 5746 register_name = "Cause"; 5747 break; 5748 default: 5749 goto cp0_unimplemented; 5750 } 5751 break; 5752 case CP0_REGISTER_14: 5753 switch (sel) { 5754 case CP0_REG14__EPC: 5755 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC)); 5756 tcg_gen_ext32s_tl(arg, arg); 5757 register_name = "EPC"; 5758 break; 5759 default: 5760 goto cp0_unimplemented; 5761 } 5762 break; 5763 case CP0_REGISTER_15: 5764 switch (sel) { 5765 case CP0_REG15__PRID: 5766 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid)); 5767 register_name = "PRid"; 5768 break; 5769 case CP0_REG15__EBASE: 5770 check_insn(ctx, ISA_MIPS_R2); 5771 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase)); 5772 tcg_gen_ext32s_tl(arg, arg); 5773 register_name = "EBase"; 5774 break; 5775 case CP0_REG15__CMGCRBASE: 5776 check_insn(ctx, ISA_MIPS_R2); 5777 CP0_CHECK(ctx->cmgcr); 5778 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase)); 5779 tcg_gen_ext32s_tl(arg, arg); 5780 register_name = "CMGCRBase"; 5781 break; 5782 default: 5783 goto cp0_unimplemented; 5784 } 5785 break; 5786 case CP0_REGISTER_16: 5787 switch (sel) { 5788 case CP0_REG16__CONFIG: 5789 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0)); 5790 register_name = "Config"; 5791 break; 5792 case CP0_REG16__CONFIG1: 5793 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1)); 5794 register_name = "Config1"; 5795 break; 5796 case CP0_REG16__CONFIG2: 5797 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2)); 5798 register_name = "Config2"; 5799 break; 5800 case CP0_REG16__CONFIG3: 5801 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3)); 5802 register_name = "Config3"; 5803 break; 5804 case CP0_REG16__CONFIG4: 5805 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4)); 5806 register_name = "Config4"; 5807 break; 5808 case CP0_REG16__CONFIG5: 5809 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5)); 5810 register_name = "Config5"; 5811 break; 5812 /* 6,7 are implementation dependent */ 5813 case CP0_REG16__CONFIG6: 5814 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6)); 5815 register_name = "Config6"; 5816 break; 5817 case CP0_REG16__CONFIG7: 5818 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7)); 5819 register_name = "Config7"; 5820 break; 5821 default: 5822 goto cp0_unimplemented; 5823 } 5824 break; 5825 case CP0_REGISTER_17: 5826 switch (sel) { 5827 case CP0_REG17__LLADDR: 5828 gen_helper_mfc0_lladdr(arg, cpu_env); 5829 register_name = "LLAddr"; 5830 break; 5831 case CP0_REG17__MAAR: 5832 CP0_CHECK(ctx->mrp); 5833 gen_helper_mfc0_maar(arg, cpu_env); 5834 register_name = "MAAR"; 5835 break; 5836 case CP0_REG17__MAARI: 5837 CP0_CHECK(ctx->mrp); 5838 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI)); 5839 register_name = "MAARI"; 5840 break; 5841 default: 5842 goto cp0_unimplemented; 5843 } 5844 break; 5845 case CP0_REGISTER_18: 5846 switch (sel) { 5847 case CP0_REG18__WATCHLO0: 5848 case CP0_REG18__WATCHLO1: 5849 case CP0_REG18__WATCHLO2: 5850 case CP0_REG18__WATCHLO3: 5851 case CP0_REG18__WATCHLO4: 5852 case CP0_REG18__WATCHLO5: 5853 case CP0_REG18__WATCHLO6: 5854 case CP0_REG18__WATCHLO7: 5855 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 5856 gen_helper_1e0i(mfc0_watchlo, arg, sel); 5857 register_name = "WatchLo"; 5858 break; 5859 default: 5860 goto cp0_unimplemented; 5861 } 5862 break; 5863 case CP0_REGISTER_19: 5864 switch (sel) { 5865 case CP0_REG19__WATCHHI0: 5866 case CP0_REG19__WATCHHI1: 5867 case CP0_REG19__WATCHHI2: 5868 case CP0_REG19__WATCHHI3: 5869 case CP0_REG19__WATCHHI4: 5870 case CP0_REG19__WATCHHI5: 5871 case CP0_REG19__WATCHHI6: 5872 case CP0_REG19__WATCHHI7: 5873 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 5874 gen_helper_1e0i(mfc0_watchhi, arg, sel); 5875 register_name = "WatchHi"; 5876 break; 5877 default: 5878 goto cp0_unimplemented; 5879 } 5880 break; 5881 case CP0_REGISTER_20: 5882 switch (sel) { 5883 case CP0_REG20__XCONTEXT: 5884 #if defined(TARGET_MIPS64) 5885 check_insn(ctx, ISA_MIPS3); 5886 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext)); 5887 tcg_gen_ext32s_tl(arg, arg); 5888 register_name = "XContext"; 5889 break; 5890 #endif 5891 default: 5892 goto cp0_unimplemented; 5893 } 5894 break; 5895 case CP0_REGISTER_21: 5896 /* Officially reserved, but sel 0 is used for R1x000 framemask */ 5897 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 5898 switch (sel) { 5899 case 0: 5900 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask)); 5901 register_name = "Framemask"; 5902 break; 5903 default: 5904 goto cp0_unimplemented; 5905 } 5906 break; 5907 case CP0_REGISTER_22: 5908 tcg_gen_movi_tl(arg, 0); /* unimplemented */ 5909 register_name = "'Diagnostic"; /* implementation dependent */ 5910 break; 5911 case CP0_REGISTER_23: 5912 switch (sel) { 5913 case CP0_REG23__DEBUG: 5914 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */ 5915 register_name = "Debug"; 5916 break; 5917 case CP0_REG23__TRACECONTROL: 5918 /* PDtrace support */ 5919 /* gen_helper_mfc0_tracecontrol(arg); */ 5920 register_name = "TraceControl"; 5921 goto cp0_unimplemented; 5922 case CP0_REG23__TRACECONTROL2: 5923 /* PDtrace support */ 5924 /* gen_helper_mfc0_tracecontrol2(arg); */ 5925 register_name = "TraceControl2"; 5926 goto cp0_unimplemented; 5927 case CP0_REG23__USERTRACEDATA1: 5928 /* PDtrace support */ 5929 /* gen_helper_mfc0_usertracedata1(arg);*/ 5930 register_name = "UserTraceData1"; 5931 goto cp0_unimplemented; 5932 case CP0_REG23__TRACEIBPC: 5933 /* PDtrace support */ 5934 /* gen_helper_mfc0_traceibpc(arg); */ 5935 register_name = "TraceIBPC"; 5936 goto cp0_unimplemented; 5937 case CP0_REG23__TRACEDBPC: 5938 /* PDtrace support */ 5939 /* gen_helper_mfc0_tracedbpc(arg); */ 5940 register_name = "TraceDBPC"; 5941 goto cp0_unimplemented; 5942 default: 5943 goto cp0_unimplemented; 5944 } 5945 break; 5946 case CP0_REGISTER_24: 5947 switch (sel) { 5948 case CP0_REG24__DEPC: 5949 /* EJTAG support */ 5950 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC)); 5951 tcg_gen_ext32s_tl(arg, arg); 5952 register_name = "DEPC"; 5953 break; 5954 default: 5955 goto cp0_unimplemented; 5956 } 5957 break; 5958 case CP0_REGISTER_25: 5959 switch (sel) { 5960 case CP0_REG25__PERFCTL0: 5961 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0)); 5962 register_name = "Performance0"; 5963 break; 5964 case CP0_REG25__PERFCNT0: 5965 /* gen_helper_mfc0_performance1(arg); */ 5966 register_name = "Performance1"; 5967 goto cp0_unimplemented; 5968 case CP0_REG25__PERFCTL1: 5969 /* gen_helper_mfc0_performance2(arg); */ 5970 register_name = "Performance2"; 5971 goto cp0_unimplemented; 5972 case CP0_REG25__PERFCNT1: 5973 /* gen_helper_mfc0_performance3(arg); */ 5974 register_name = "Performance3"; 5975 goto cp0_unimplemented; 5976 case CP0_REG25__PERFCTL2: 5977 /* gen_helper_mfc0_performance4(arg); */ 5978 register_name = "Performance4"; 5979 goto cp0_unimplemented; 5980 case CP0_REG25__PERFCNT2: 5981 /* gen_helper_mfc0_performance5(arg); */ 5982 register_name = "Performance5"; 5983 goto cp0_unimplemented; 5984 case CP0_REG25__PERFCTL3: 5985 /* gen_helper_mfc0_performance6(arg); */ 5986 register_name = "Performance6"; 5987 goto cp0_unimplemented; 5988 case CP0_REG25__PERFCNT3: 5989 /* gen_helper_mfc0_performance7(arg); */ 5990 register_name = "Performance7"; 5991 goto cp0_unimplemented; 5992 default: 5993 goto cp0_unimplemented; 5994 } 5995 break; 5996 case CP0_REGISTER_26: 5997 switch (sel) { 5998 case CP0_REG26__ERRCTL: 5999 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl)); 6000 register_name = "ErrCtl"; 6001 break; 6002 default: 6003 goto cp0_unimplemented; 6004 } 6005 break; 6006 case CP0_REGISTER_27: 6007 switch (sel) { 6008 case CP0_REG27__CACHERR: 6009 tcg_gen_movi_tl(arg, 0); /* unimplemented */ 6010 register_name = "CacheErr"; 6011 break; 6012 default: 6013 goto cp0_unimplemented; 6014 } 6015 break; 6016 case CP0_REGISTER_28: 6017 switch (sel) { 6018 case CP0_REG28__TAGLO: 6019 case CP0_REG28__TAGLO1: 6020 case CP0_REG28__TAGLO2: 6021 case CP0_REG28__TAGLO3: 6022 { 6023 TCGv_i64 tmp = tcg_temp_new_i64(); 6024 tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo)); 6025 gen_move_low32(arg, tmp); 6026 } 6027 register_name = "TagLo"; 6028 break; 6029 case CP0_REG28__DATALO: 6030 case CP0_REG28__DATALO1: 6031 case CP0_REG28__DATALO2: 6032 case CP0_REG28__DATALO3: 6033 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo)); 6034 register_name = "DataLo"; 6035 break; 6036 default: 6037 goto cp0_unimplemented; 6038 } 6039 break; 6040 case CP0_REGISTER_29: 6041 switch (sel) { 6042 case CP0_REG29__TAGHI: 6043 case CP0_REG29__TAGHI1: 6044 case CP0_REG29__TAGHI2: 6045 case CP0_REG29__TAGHI3: 6046 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi)); 6047 register_name = "TagHi"; 6048 break; 6049 case CP0_REG29__DATAHI: 6050 case CP0_REG29__DATAHI1: 6051 case CP0_REG29__DATAHI2: 6052 case CP0_REG29__DATAHI3: 6053 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi)); 6054 register_name = "DataHi"; 6055 break; 6056 default: 6057 goto cp0_unimplemented; 6058 } 6059 break; 6060 case CP0_REGISTER_30: 6061 switch (sel) { 6062 case CP0_REG30__ERROREPC: 6063 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC)); 6064 tcg_gen_ext32s_tl(arg, arg); 6065 register_name = "ErrorEPC"; 6066 break; 6067 default: 6068 goto cp0_unimplemented; 6069 } 6070 break; 6071 case CP0_REGISTER_31: 6072 switch (sel) { 6073 case CP0_REG31__DESAVE: 6074 /* EJTAG support */ 6075 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); 6076 register_name = "DESAVE"; 6077 break; 6078 case CP0_REG31__KSCRATCH1: 6079 case CP0_REG31__KSCRATCH2: 6080 case CP0_REG31__KSCRATCH3: 6081 case CP0_REG31__KSCRATCH4: 6082 case CP0_REG31__KSCRATCH5: 6083 case CP0_REG31__KSCRATCH6: 6084 CP0_CHECK(ctx->kscrexist & (1 << sel)); 6085 tcg_gen_ld_tl(arg, cpu_env, 6086 offsetof(CPUMIPSState, CP0_KScratch[sel - 2])); 6087 tcg_gen_ext32s_tl(arg, arg); 6088 register_name = "KScratch"; 6089 break; 6090 default: 6091 goto cp0_unimplemented; 6092 } 6093 break; 6094 default: 6095 goto cp0_unimplemented; 6096 } 6097 trace_mips_translate_c0("mfc0", register_name, reg, sel); 6098 return; 6099 6100 cp0_unimplemented: 6101 qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n", 6102 register_name, reg, sel); 6103 gen_mfc0_unimplemented(ctx, arg); 6104 } 6105 6106 static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) 6107 { 6108 const char *register_name = "invalid"; 6109 6110 if (sel != 0) { 6111 check_insn(ctx, ISA_MIPS_R1); 6112 } 6113 6114 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { 6115 gen_io_start(); 6116 } 6117 6118 switch (reg) { 6119 case CP0_REGISTER_00: 6120 switch (sel) { 6121 case CP0_REG00__INDEX: 6122 gen_helper_mtc0_index(cpu_env, arg); 6123 register_name = "Index"; 6124 break; 6125 case CP0_REG00__MVPCONTROL: 6126 CP0_CHECK(ctx->insn_flags & ASE_MT); 6127 gen_helper_mtc0_mvpcontrol(cpu_env, arg); 6128 register_name = "MVPControl"; 6129 break; 6130 case CP0_REG00__MVPCONF0: 6131 CP0_CHECK(ctx->insn_flags & ASE_MT); 6132 /* ignored */ 6133 register_name = "MVPConf0"; 6134 break; 6135 case CP0_REG00__MVPCONF1: 6136 CP0_CHECK(ctx->insn_flags & ASE_MT); 6137 /* ignored */ 6138 register_name = "MVPConf1"; 6139 break; 6140 case CP0_REG00__VPCONTROL: 6141 CP0_CHECK(ctx->vp); 6142 /* ignored */ 6143 register_name = "VPControl"; 6144 break; 6145 default: 6146 goto cp0_unimplemented; 6147 } 6148 break; 6149 case CP0_REGISTER_01: 6150 switch (sel) { 6151 case CP0_REG01__RANDOM: 6152 /* ignored */ 6153 register_name = "Random"; 6154 break; 6155 case CP0_REG01__VPECONTROL: 6156 CP0_CHECK(ctx->insn_flags & ASE_MT); 6157 gen_helper_mtc0_vpecontrol(cpu_env, arg); 6158 register_name = "VPEControl"; 6159 break; 6160 case CP0_REG01__VPECONF0: 6161 CP0_CHECK(ctx->insn_flags & ASE_MT); 6162 gen_helper_mtc0_vpeconf0(cpu_env, arg); 6163 register_name = "VPEConf0"; 6164 break; 6165 case CP0_REG01__VPECONF1: 6166 CP0_CHECK(ctx->insn_flags & ASE_MT); 6167 gen_helper_mtc0_vpeconf1(cpu_env, arg); 6168 register_name = "VPEConf1"; 6169 break; 6170 case CP0_REG01__YQMASK: 6171 CP0_CHECK(ctx->insn_flags & ASE_MT); 6172 gen_helper_mtc0_yqmask(cpu_env, arg); 6173 register_name = "YQMask"; 6174 break; 6175 case CP0_REG01__VPESCHEDULE: 6176 CP0_CHECK(ctx->insn_flags & ASE_MT); 6177 tcg_gen_st_tl(arg, cpu_env, 6178 offsetof(CPUMIPSState, CP0_VPESchedule)); 6179 register_name = "VPESchedule"; 6180 break; 6181 case CP0_REG01__VPESCHEFBACK: 6182 CP0_CHECK(ctx->insn_flags & ASE_MT); 6183 tcg_gen_st_tl(arg, cpu_env, 6184 offsetof(CPUMIPSState, CP0_VPEScheFBack)); 6185 register_name = "VPEScheFBack"; 6186 break; 6187 case CP0_REG01__VPEOPT: 6188 CP0_CHECK(ctx->insn_flags & ASE_MT); 6189 gen_helper_mtc0_vpeopt(cpu_env, arg); 6190 register_name = "VPEOpt"; 6191 break; 6192 default: 6193 goto cp0_unimplemented; 6194 } 6195 break; 6196 case CP0_REGISTER_02: 6197 switch (sel) { 6198 case CP0_REG02__ENTRYLO0: 6199 gen_helper_mtc0_entrylo0(cpu_env, arg); 6200 register_name = "EntryLo0"; 6201 break; 6202 case CP0_REG02__TCSTATUS: 6203 CP0_CHECK(ctx->insn_flags & ASE_MT); 6204 gen_helper_mtc0_tcstatus(cpu_env, arg); 6205 register_name = "TCStatus"; 6206 break; 6207 case CP0_REG02__TCBIND: 6208 CP0_CHECK(ctx->insn_flags & ASE_MT); 6209 gen_helper_mtc0_tcbind(cpu_env, arg); 6210 register_name = "TCBind"; 6211 break; 6212 case CP0_REG02__TCRESTART: 6213 CP0_CHECK(ctx->insn_flags & ASE_MT); 6214 gen_helper_mtc0_tcrestart(cpu_env, arg); 6215 register_name = "TCRestart"; 6216 break; 6217 case CP0_REG02__TCHALT: 6218 CP0_CHECK(ctx->insn_flags & ASE_MT); 6219 gen_helper_mtc0_tchalt(cpu_env, arg); 6220 register_name = "TCHalt"; 6221 break; 6222 case CP0_REG02__TCCONTEXT: 6223 CP0_CHECK(ctx->insn_flags & ASE_MT); 6224 gen_helper_mtc0_tccontext(cpu_env, arg); 6225 register_name = "TCContext"; 6226 break; 6227 case CP0_REG02__TCSCHEDULE: 6228 CP0_CHECK(ctx->insn_flags & ASE_MT); 6229 gen_helper_mtc0_tcschedule(cpu_env, arg); 6230 register_name = "TCSchedule"; 6231 break; 6232 case CP0_REG02__TCSCHEFBACK: 6233 CP0_CHECK(ctx->insn_flags & ASE_MT); 6234 gen_helper_mtc0_tcschefback(cpu_env, arg); 6235 register_name = "TCScheFBack"; 6236 break; 6237 default: 6238 goto cp0_unimplemented; 6239 } 6240 break; 6241 case CP0_REGISTER_03: 6242 switch (sel) { 6243 case CP0_REG03__ENTRYLO1: 6244 gen_helper_mtc0_entrylo1(cpu_env, arg); 6245 register_name = "EntryLo1"; 6246 break; 6247 case CP0_REG03__GLOBALNUM: 6248 CP0_CHECK(ctx->vp); 6249 /* ignored */ 6250 register_name = "GlobalNumber"; 6251 break; 6252 default: 6253 goto cp0_unimplemented; 6254 } 6255 break; 6256 case CP0_REGISTER_04: 6257 switch (sel) { 6258 case CP0_REG04__CONTEXT: 6259 gen_helper_mtc0_context(cpu_env, arg); 6260 register_name = "Context"; 6261 break; 6262 case CP0_REG04__CONTEXTCONFIG: 6263 /* SmartMIPS ASE */ 6264 /* gen_helper_mtc0_contextconfig(arg); */ 6265 register_name = "ContextConfig"; 6266 goto cp0_unimplemented; 6267 case CP0_REG04__USERLOCAL: 6268 CP0_CHECK(ctx->ulri); 6269 tcg_gen_st_tl(arg, cpu_env, 6270 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 6271 register_name = "UserLocal"; 6272 break; 6273 case CP0_REG04__MMID: 6274 CP0_CHECK(ctx->mi); 6275 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID)); 6276 register_name = "MMID"; 6277 break; 6278 default: 6279 goto cp0_unimplemented; 6280 } 6281 break; 6282 case CP0_REGISTER_05: 6283 switch (sel) { 6284 case CP0_REG05__PAGEMASK: 6285 gen_helper_mtc0_pagemask(cpu_env, arg); 6286 register_name = "PageMask"; 6287 break; 6288 case CP0_REG05__PAGEGRAIN: 6289 check_insn(ctx, ISA_MIPS_R2); 6290 gen_helper_mtc0_pagegrain(cpu_env, arg); 6291 register_name = "PageGrain"; 6292 ctx->base.is_jmp = DISAS_STOP; 6293 break; 6294 case CP0_REG05__SEGCTL0: 6295 CP0_CHECK(ctx->sc); 6296 gen_helper_mtc0_segctl0(cpu_env, arg); 6297 register_name = "SegCtl0"; 6298 break; 6299 case CP0_REG05__SEGCTL1: 6300 CP0_CHECK(ctx->sc); 6301 gen_helper_mtc0_segctl1(cpu_env, arg); 6302 register_name = "SegCtl1"; 6303 break; 6304 case CP0_REG05__SEGCTL2: 6305 CP0_CHECK(ctx->sc); 6306 gen_helper_mtc0_segctl2(cpu_env, arg); 6307 register_name = "SegCtl2"; 6308 break; 6309 case CP0_REG05__PWBASE: 6310 check_pw(ctx); 6311 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_PWBase)); 6312 register_name = "PWBase"; 6313 break; 6314 case CP0_REG05__PWFIELD: 6315 check_pw(ctx); 6316 gen_helper_mtc0_pwfield(cpu_env, arg); 6317 register_name = "PWField"; 6318 break; 6319 case CP0_REG05__PWSIZE: 6320 check_pw(ctx); 6321 gen_helper_mtc0_pwsize(cpu_env, arg); 6322 register_name = "PWSize"; 6323 break; 6324 default: 6325 goto cp0_unimplemented; 6326 } 6327 break; 6328 case CP0_REGISTER_06: 6329 switch (sel) { 6330 case CP0_REG06__WIRED: 6331 gen_helper_mtc0_wired(cpu_env, arg); 6332 register_name = "Wired"; 6333 break; 6334 case CP0_REG06__SRSCONF0: 6335 check_insn(ctx, ISA_MIPS_R2); 6336 gen_helper_mtc0_srsconf0(cpu_env, arg); 6337 register_name = "SRSConf0"; 6338 break; 6339 case CP0_REG06__SRSCONF1: 6340 check_insn(ctx, ISA_MIPS_R2); 6341 gen_helper_mtc0_srsconf1(cpu_env, arg); 6342 register_name = "SRSConf1"; 6343 break; 6344 case CP0_REG06__SRSCONF2: 6345 check_insn(ctx, ISA_MIPS_R2); 6346 gen_helper_mtc0_srsconf2(cpu_env, arg); 6347 register_name = "SRSConf2"; 6348 break; 6349 case CP0_REG06__SRSCONF3: 6350 check_insn(ctx, ISA_MIPS_R2); 6351 gen_helper_mtc0_srsconf3(cpu_env, arg); 6352 register_name = "SRSConf3"; 6353 break; 6354 case CP0_REG06__SRSCONF4: 6355 check_insn(ctx, ISA_MIPS_R2); 6356 gen_helper_mtc0_srsconf4(cpu_env, arg); 6357 register_name = "SRSConf4"; 6358 break; 6359 case CP0_REG06__PWCTL: 6360 check_pw(ctx); 6361 gen_helper_mtc0_pwctl(cpu_env, arg); 6362 register_name = "PWCtl"; 6363 break; 6364 default: 6365 goto cp0_unimplemented; 6366 } 6367 break; 6368 case CP0_REGISTER_07: 6369 switch (sel) { 6370 case CP0_REG07__HWRENA: 6371 check_insn(ctx, ISA_MIPS_R2); 6372 gen_helper_mtc0_hwrena(cpu_env, arg); 6373 ctx->base.is_jmp = DISAS_STOP; 6374 register_name = "HWREna"; 6375 break; 6376 default: 6377 goto cp0_unimplemented; 6378 } 6379 break; 6380 case CP0_REGISTER_08: 6381 switch (sel) { 6382 case CP0_REG08__BADVADDR: 6383 /* ignored */ 6384 register_name = "BadVAddr"; 6385 break; 6386 case CP0_REG08__BADINSTR: 6387 /* ignored */ 6388 register_name = "BadInstr"; 6389 break; 6390 case CP0_REG08__BADINSTRP: 6391 /* ignored */ 6392 register_name = "BadInstrP"; 6393 break; 6394 case CP0_REG08__BADINSTRX: 6395 /* ignored */ 6396 register_name = "BadInstrX"; 6397 break; 6398 default: 6399 goto cp0_unimplemented; 6400 } 6401 break; 6402 case CP0_REGISTER_09: 6403 switch (sel) { 6404 case CP0_REG09__COUNT: 6405 gen_helper_mtc0_count(cpu_env, arg); 6406 register_name = "Count"; 6407 break; 6408 case CP0_REG09__SAARI: 6409 CP0_CHECK(ctx->saar); 6410 gen_helper_mtc0_saari(cpu_env, arg); 6411 register_name = "SAARI"; 6412 break; 6413 case CP0_REG09__SAAR: 6414 CP0_CHECK(ctx->saar); 6415 gen_helper_mtc0_saar(cpu_env, arg); 6416 register_name = "SAAR"; 6417 break; 6418 default: 6419 goto cp0_unimplemented; 6420 } 6421 break; 6422 case CP0_REGISTER_10: 6423 switch (sel) { 6424 case CP0_REG10__ENTRYHI: 6425 gen_helper_mtc0_entryhi(cpu_env, arg); 6426 register_name = "EntryHi"; 6427 break; 6428 default: 6429 goto cp0_unimplemented; 6430 } 6431 break; 6432 case CP0_REGISTER_11: 6433 switch (sel) { 6434 case CP0_REG11__COMPARE: 6435 gen_helper_mtc0_compare(cpu_env, arg); 6436 register_name = "Compare"; 6437 break; 6438 /* 6,7 are implementation dependent */ 6439 default: 6440 goto cp0_unimplemented; 6441 } 6442 break; 6443 case CP0_REGISTER_12: 6444 switch (sel) { 6445 case CP0_REG12__STATUS: 6446 save_cpu_state(ctx, 1); 6447 gen_helper_mtc0_status(cpu_env, arg); 6448 /* DISAS_STOP isn't good enough here, hflags may have changed. */ 6449 gen_save_pc(ctx->base.pc_next + 4); 6450 ctx->base.is_jmp = DISAS_EXIT; 6451 register_name = "Status"; 6452 break; 6453 case CP0_REG12__INTCTL: 6454 check_insn(ctx, ISA_MIPS_R2); 6455 gen_helper_mtc0_intctl(cpu_env, arg); 6456 /* Stop translation as we may have switched the execution mode */ 6457 ctx->base.is_jmp = DISAS_STOP; 6458 register_name = "IntCtl"; 6459 break; 6460 case CP0_REG12__SRSCTL: 6461 check_insn(ctx, ISA_MIPS_R2); 6462 gen_helper_mtc0_srsctl(cpu_env, arg); 6463 /* Stop translation as we may have switched the execution mode */ 6464 ctx->base.is_jmp = DISAS_STOP; 6465 register_name = "SRSCtl"; 6466 break; 6467 case CP0_REG12__SRSMAP: 6468 check_insn(ctx, ISA_MIPS_R2); 6469 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); 6470 /* Stop translation as we may have switched the execution mode */ 6471 ctx->base.is_jmp = DISAS_STOP; 6472 register_name = "SRSMap"; 6473 break; 6474 default: 6475 goto cp0_unimplemented; 6476 } 6477 break; 6478 case CP0_REGISTER_13: 6479 switch (sel) { 6480 case CP0_REG13__CAUSE: 6481 save_cpu_state(ctx, 1); 6482 gen_helper_mtc0_cause(cpu_env, arg); 6483 /* 6484 * Stop translation as we may have triggered an interrupt. 6485 * DISAS_STOP isn't sufficient, we need to ensure we break out of 6486 * translated code to check for pending interrupts. 6487 */ 6488 gen_save_pc(ctx->base.pc_next + 4); 6489 ctx->base.is_jmp = DISAS_EXIT; 6490 register_name = "Cause"; 6491 break; 6492 default: 6493 goto cp0_unimplemented; 6494 } 6495 break; 6496 case CP0_REGISTER_14: 6497 switch (sel) { 6498 case CP0_REG14__EPC: 6499 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC)); 6500 register_name = "EPC"; 6501 break; 6502 default: 6503 goto cp0_unimplemented; 6504 } 6505 break; 6506 case CP0_REGISTER_15: 6507 switch (sel) { 6508 case CP0_REG15__PRID: 6509 /* ignored */ 6510 register_name = "PRid"; 6511 break; 6512 case CP0_REG15__EBASE: 6513 check_insn(ctx, ISA_MIPS_R2); 6514 gen_helper_mtc0_ebase(cpu_env, arg); 6515 register_name = "EBase"; 6516 break; 6517 default: 6518 goto cp0_unimplemented; 6519 } 6520 break; 6521 case CP0_REGISTER_16: 6522 switch (sel) { 6523 case CP0_REG16__CONFIG: 6524 gen_helper_mtc0_config0(cpu_env, arg); 6525 register_name = "Config"; 6526 /* Stop translation as we may have switched the execution mode */ 6527 ctx->base.is_jmp = DISAS_STOP; 6528 break; 6529 case CP0_REG16__CONFIG1: 6530 /* ignored, read only */ 6531 register_name = "Config1"; 6532 break; 6533 case CP0_REG16__CONFIG2: 6534 gen_helper_mtc0_config2(cpu_env, arg); 6535 register_name = "Config2"; 6536 /* Stop translation as we may have switched the execution mode */ 6537 ctx->base.is_jmp = DISAS_STOP; 6538 break; 6539 case CP0_REG16__CONFIG3: 6540 gen_helper_mtc0_config3(cpu_env, arg); 6541 register_name = "Config3"; 6542 /* Stop translation as we may have switched the execution mode */ 6543 ctx->base.is_jmp = DISAS_STOP; 6544 break; 6545 case CP0_REG16__CONFIG4: 6546 gen_helper_mtc0_config4(cpu_env, arg); 6547 register_name = "Config4"; 6548 ctx->base.is_jmp = DISAS_STOP; 6549 break; 6550 case CP0_REG16__CONFIG5: 6551 gen_helper_mtc0_config5(cpu_env, arg); 6552 register_name = "Config5"; 6553 /* Stop translation as we may have switched the execution mode */ 6554 ctx->base.is_jmp = DISAS_STOP; 6555 break; 6556 /* 6,7 are implementation dependent */ 6557 case CP0_REG16__CONFIG6: 6558 /* ignored */ 6559 register_name = "Config6"; 6560 break; 6561 case CP0_REG16__CONFIG7: 6562 /* ignored */ 6563 register_name = "Config7"; 6564 break; 6565 default: 6566 register_name = "Invalid config selector"; 6567 goto cp0_unimplemented; 6568 } 6569 break; 6570 case CP0_REGISTER_17: 6571 switch (sel) { 6572 case CP0_REG17__LLADDR: 6573 gen_helper_mtc0_lladdr(cpu_env, arg); 6574 register_name = "LLAddr"; 6575 break; 6576 case CP0_REG17__MAAR: 6577 CP0_CHECK(ctx->mrp); 6578 gen_helper_mtc0_maar(cpu_env, arg); 6579 register_name = "MAAR"; 6580 break; 6581 case CP0_REG17__MAARI: 6582 CP0_CHECK(ctx->mrp); 6583 gen_helper_mtc0_maari(cpu_env, arg); 6584 register_name = "MAARI"; 6585 break; 6586 default: 6587 goto cp0_unimplemented; 6588 } 6589 break; 6590 case CP0_REGISTER_18: 6591 switch (sel) { 6592 case CP0_REG18__WATCHLO0: 6593 case CP0_REG18__WATCHLO1: 6594 case CP0_REG18__WATCHLO2: 6595 case CP0_REG18__WATCHLO3: 6596 case CP0_REG18__WATCHLO4: 6597 case CP0_REG18__WATCHLO5: 6598 case CP0_REG18__WATCHLO6: 6599 case CP0_REG18__WATCHLO7: 6600 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 6601 gen_helper_0e1i(mtc0_watchlo, arg, sel); 6602 register_name = "WatchLo"; 6603 break; 6604 default: 6605 goto cp0_unimplemented; 6606 } 6607 break; 6608 case CP0_REGISTER_19: 6609 switch (sel) { 6610 case CP0_REG19__WATCHHI0: 6611 case CP0_REG19__WATCHHI1: 6612 case CP0_REG19__WATCHHI2: 6613 case CP0_REG19__WATCHHI3: 6614 case CP0_REG19__WATCHHI4: 6615 case CP0_REG19__WATCHHI5: 6616 case CP0_REG19__WATCHHI6: 6617 case CP0_REG19__WATCHHI7: 6618 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 6619 gen_helper_0e1i(mtc0_watchhi, arg, sel); 6620 register_name = "WatchHi"; 6621 break; 6622 default: 6623 goto cp0_unimplemented; 6624 } 6625 break; 6626 case CP0_REGISTER_20: 6627 switch (sel) { 6628 case CP0_REG20__XCONTEXT: 6629 #if defined(TARGET_MIPS64) 6630 check_insn(ctx, ISA_MIPS3); 6631 gen_helper_mtc0_xcontext(cpu_env, arg); 6632 register_name = "XContext"; 6633 break; 6634 #endif 6635 default: 6636 goto cp0_unimplemented; 6637 } 6638 break; 6639 case CP0_REGISTER_21: 6640 /* Officially reserved, but sel 0 is used for R1x000 framemask */ 6641 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 6642 switch (sel) { 6643 case 0: 6644 gen_helper_mtc0_framemask(cpu_env, arg); 6645 register_name = "Framemask"; 6646 break; 6647 default: 6648 goto cp0_unimplemented; 6649 } 6650 break; 6651 case CP0_REGISTER_22: 6652 /* ignored */ 6653 register_name = "Diagnostic"; /* implementation dependent */ 6654 break; 6655 case CP0_REGISTER_23: 6656 switch (sel) { 6657 case CP0_REG23__DEBUG: 6658 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */ 6659 /* DISAS_STOP isn't good enough here, hflags may have changed. */ 6660 gen_save_pc(ctx->base.pc_next + 4); 6661 ctx->base.is_jmp = DISAS_EXIT; 6662 register_name = "Debug"; 6663 break; 6664 case CP0_REG23__TRACECONTROL: 6665 /* PDtrace support */ 6666 /* gen_helper_mtc0_tracecontrol(cpu_env, arg); */ 6667 register_name = "TraceControl"; 6668 /* Stop translation as we may have switched the execution mode */ 6669 ctx->base.is_jmp = DISAS_STOP; 6670 goto cp0_unimplemented; 6671 case CP0_REG23__TRACECONTROL2: 6672 /* PDtrace support */ 6673 /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */ 6674 register_name = "TraceControl2"; 6675 /* Stop translation as we may have switched the execution mode */ 6676 ctx->base.is_jmp = DISAS_STOP; 6677 goto cp0_unimplemented; 6678 case CP0_REG23__USERTRACEDATA1: 6679 /* Stop translation as we may have switched the execution mode */ 6680 ctx->base.is_jmp = DISAS_STOP; 6681 /* PDtrace support */ 6682 /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/ 6683 register_name = "UserTraceData"; 6684 /* Stop translation as we may have switched the execution mode */ 6685 ctx->base.is_jmp = DISAS_STOP; 6686 goto cp0_unimplemented; 6687 case CP0_REG23__TRACEIBPC: 6688 /* PDtrace support */ 6689 /* gen_helper_mtc0_traceibpc(cpu_env, arg); */ 6690 /* Stop translation as we may have switched the execution mode */ 6691 ctx->base.is_jmp = DISAS_STOP; 6692 register_name = "TraceIBPC"; 6693 goto cp0_unimplemented; 6694 case CP0_REG23__TRACEDBPC: 6695 /* PDtrace support */ 6696 /* gen_helper_mtc0_tracedbpc(cpu_env, arg); */ 6697 /* Stop translation as we may have switched the execution mode */ 6698 ctx->base.is_jmp = DISAS_STOP; 6699 register_name = "TraceDBPC"; 6700 goto cp0_unimplemented; 6701 default: 6702 goto cp0_unimplemented; 6703 } 6704 break; 6705 case CP0_REGISTER_24: 6706 switch (sel) { 6707 case CP0_REG24__DEPC: 6708 /* EJTAG support */ 6709 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC)); 6710 register_name = "DEPC"; 6711 break; 6712 default: 6713 goto cp0_unimplemented; 6714 } 6715 break; 6716 case CP0_REGISTER_25: 6717 switch (sel) { 6718 case CP0_REG25__PERFCTL0: 6719 gen_helper_mtc0_performance0(cpu_env, arg); 6720 register_name = "Performance0"; 6721 break; 6722 case CP0_REG25__PERFCNT0: 6723 /* gen_helper_mtc0_performance1(arg); */ 6724 register_name = "Performance1"; 6725 goto cp0_unimplemented; 6726 case CP0_REG25__PERFCTL1: 6727 /* gen_helper_mtc0_performance2(arg); */ 6728 register_name = "Performance2"; 6729 goto cp0_unimplemented; 6730 case CP0_REG25__PERFCNT1: 6731 /* gen_helper_mtc0_performance3(arg); */ 6732 register_name = "Performance3"; 6733 goto cp0_unimplemented; 6734 case CP0_REG25__PERFCTL2: 6735 /* gen_helper_mtc0_performance4(arg); */ 6736 register_name = "Performance4"; 6737 goto cp0_unimplemented; 6738 case CP0_REG25__PERFCNT2: 6739 /* gen_helper_mtc0_performance5(arg); */ 6740 register_name = "Performance5"; 6741 goto cp0_unimplemented; 6742 case CP0_REG25__PERFCTL3: 6743 /* gen_helper_mtc0_performance6(arg); */ 6744 register_name = "Performance6"; 6745 goto cp0_unimplemented; 6746 case CP0_REG25__PERFCNT3: 6747 /* gen_helper_mtc0_performance7(arg); */ 6748 register_name = "Performance7"; 6749 goto cp0_unimplemented; 6750 default: 6751 goto cp0_unimplemented; 6752 } 6753 break; 6754 case CP0_REGISTER_26: 6755 switch (sel) { 6756 case CP0_REG26__ERRCTL: 6757 gen_helper_mtc0_errctl(cpu_env, arg); 6758 ctx->base.is_jmp = DISAS_STOP; 6759 register_name = "ErrCtl"; 6760 break; 6761 default: 6762 goto cp0_unimplemented; 6763 } 6764 break; 6765 case CP0_REGISTER_27: 6766 switch (sel) { 6767 case CP0_REG27__CACHERR: 6768 /* ignored */ 6769 register_name = "CacheErr"; 6770 break; 6771 default: 6772 goto cp0_unimplemented; 6773 } 6774 break; 6775 case CP0_REGISTER_28: 6776 switch (sel) { 6777 case CP0_REG28__TAGLO: 6778 case CP0_REG28__TAGLO1: 6779 case CP0_REG28__TAGLO2: 6780 case CP0_REG28__TAGLO3: 6781 gen_helper_mtc0_taglo(cpu_env, arg); 6782 register_name = "TagLo"; 6783 break; 6784 case CP0_REG28__DATALO: 6785 case CP0_REG28__DATALO1: 6786 case CP0_REG28__DATALO2: 6787 case CP0_REG28__DATALO3: 6788 gen_helper_mtc0_datalo(cpu_env, arg); 6789 register_name = "DataLo"; 6790 break; 6791 default: 6792 goto cp0_unimplemented; 6793 } 6794 break; 6795 case CP0_REGISTER_29: 6796 switch (sel) { 6797 case CP0_REG29__TAGHI: 6798 case CP0_REG29__TAGHI1: 6799 case CP0_REG29__TAGHI2: 6800 case CP0_REG29__TAGHI3: 6801 gen_helper_mtc0_taghi(cpu_env, arg); 6802 register_name = "TagHi"; 6803 break; 6804 case CP0_REG29__DATAHI: 6805 case CP0_REG29__DATAHI1: 6806 case CP0_REG29__DATAHI2: 6807 case CP0_REG29__DATAHI3: 6808 gen_helper_mtc0_datahi(cpu_env, arg); 6809 register_name = "DataHi"; 6810 break; 6811 default: 6812 register_name = "invalid sel"; 6813 goto cp0_unimplemented; 6814 } 6815 break; 6816 case CP0_REGISTER_30: 6817 switch (sel) { 6818 case CP0_REG30__ERROREPC: 6819 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC)); 6820 register_name = "ErrorEPC"; 6821 break; 6822 default: 6823 goto cp0_unimplemented; 6824 } 6825 break; 6826 case CP0_REGISTER_31: 6827 switch (sel) { 6828 case CP0_REG31__DESAVE: 6829 /* EJTAG support */ 6830 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); 6831 register_name = "DESAVE"; 6832 break; 6833 case CP0_REG31__KSCRATCH1: 6834 case CP0_REG31__KSCRATCH2: 6835 case CP0_REG31__KSCRATCH3: 6836 case CP0_REG31__KSCRATCH4: 6837 case CP0_REG31__KSCRATCH5: 6838 case CP0_REG31__KSCRATCH6: 6839 CP0_CHECK(ctx->kscrexist & (1 << sel)); 6840 tcg_gen_st_tl(arg, cpu_env, 6841 offsetof(CPUMIPSState, CP0_KScratch[sel - 2])); 6842 register_name = "KScratch"; 6843 break; 6844 default: 6845 goto cp0_unimplemented; 6846 } 6847 break; 6848 default: 6849 goto cp0_unimplemented; 6850 } 6851 trace_mips_translate_c0("mtc0", register_name, reg, sel); 6852 6853 /* For simplicity assume that all writes can cause interrupts. */ 6854 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { 6855 /* 6856 * DISAS_STOP isn't sufficient, we need to ensure we break out of 6857 * translated code to check for pending interrupts. 6858 */ 6859 gen_save_pc(ctx->base.pc_next + 4); 6860 ctx->base.is_jmp = DISAS_EXIT; 6861 } 6862 return; 6863 6864 cp0_unimplemented: 6865 qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n", 6866 register_name, reg, sel); 6867 } 6868 6869 #if defined(TARGET_MIPS64) 6870 static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) 6871 { 6872 const char *register_name = "invalid"; 6873 6874 if (sel != 0) { 6875 check_insn(ctx, ISA_MIPS_R1); 6876 } 6877 6878 switch (reg) { 6879 case CP0_REGISTER_00: 6880 switch (sel) { 6881 case CP0_REG00__INDEX: 6882 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index)); 6883 register_name = "Index"; 6884 break; 6885 case CP0_REG00__MVPCONTROL: 6886 CP0_CHECK(ctx->insn_flags & ASE_MT); 6887 gen_helper_mfc0_mvpcontrol(arg, cpu_env); 6888 register_name = "MVPControl"; 6889 break; 6890 case CP0_REG00__MVPCONF0: 6891 CP0_CHECK(ctx->insn_flags & ASE_MT); 6892 gen_helper_mfc0_mvpconf0(arg, cpu_env); 6893 register_name = "MVPConf0"; 6894 break; 6895 case CP0_REG00__MVPCONF1: 6896 CP0_CHECK(ctx->insn_flags & ASE_MT); 6897 gen_helper_mfc0_mvpconf1(arg, cpu_env); 6898 register_name = "MVPConf1"; 6899 break; 6900 case CP0_REG00__VPCONTROL: 6901 CP0_CHECK(ctx->vp); 6902 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl)); 6903 register_name = "VPControl"; 6904 break; 6905 default: 6906 goto cp0_unimplemented; 6907 } 6908 break; 6909 case CP0_REGISTER_01: 6910 switch (sel) { 6911 case CP0_REG01__RANDOM: 6912 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 6913 gen_helper_mfc0_random(arg, cpu_env); 6914 register_name = "Random"; 6915 break; 6916 case CP0_REG01__VPECONTROL: 6917 CP0_CHECK(ctx->insn_flags & ASE_MT); 6918 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl)); 6919 register_name = "VPEControl"; 6920 break; 6921 case CP0_REG01__VPECONF0: 6922 CP0_CHECK(ctx->insn_flags & ASE_MT); 6923 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0)); 6924 register_name = "VPEConf0"; 6925 break; 6926 case CP0_REG01__VPECONF1: 6927 CP0_CHECK(ctx->insn_flags & ASE_MT); 6928 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1)); 6929 register_name = "VPEConf1"; 6930 break; 6931 case CP0_REG01__YQMASK: 6932 CP0_CHECK(ctx->insn_flags & ASE_MT); 6933 tcg_gen_ld_tl(arg, cpu_env, 6934 offsetof(CPUMIPSState, CP0_YQMask)); 6935 register_name = "YQMask"; 6936 break; 6937 case CP0_REG01__VPESCHEDULE: 6938 CP0_CHECK(ctx->insn_flags & ASE_MT); 6939 tcg_gen_ld_tl(arg, cpu_env, 6940 offsetof(CPUMIPSState, CP0_VPESchedule)); 6941 register_name = "VPESchedule"; 6942 break; 6943 case CP0_REG01__VPESCHEFBACK: 6944 CP0_CHECK(ctx->insn_flags & ASE_MT); 6945 tcg_gen_ld_tl(arg, cpu_env, 6946 offsetof(CPUMIPSState, CP0_VPEScheFBack)); 6947 register_name = "VPEScheFBack"; 6948 break; 6949 case CP0_REG01__VPEOPT: 6950 CP0_CHECK(ctx->insn_flags & ASE_MT); 6951 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt)); 6952 register_name = "VPEOpt"; 6953 break; 6954 default: 6955 goto cp0_unimplemented; 6956 } 6957 break; 6958 case CP0_REGISTER_02: 6959 switch (sel) { 6960 case CP0_REG02__ENTRYLO0: 6961 tcg_gen_ld_tl(arg, cpu_env, 6962 offsetof(CPUMIPSState, CP0_EntryLo0)); 6963 register_name = "EntryLo0"; 6964 break; 6965 case CP0_REG02__TCSTATUS: 6966 CP0_CHECK(ctx->insn_flags & ASE_MT); 6967 gen_helper_mfc0_tcstatus(arg, cpu_env); 6968 register_name = "TCStatus"; 6969 break; 6970 case CP0_REG02__TCBIND: 6971 CP0_CHECK(ctx->insn_flags & ASE_MT); 6972 gen_helper_mfc0_tcbind(arg, cpu_env); 6973 register_name = "TCBind"; 6974 break; 6975 case CP0_REG02__TCRESTART: 6976 CP0_CHECK(ctx->insn_flags & ASE_MT); 6977 gen_helper_dmfc0_tcrestart(arg, cpu_env); 6978 register_name = "TCRestart"; 6979 break; 6980 case CP0_REG02__TCHALT: 6981 CP0_CHECK(ctx->insn_flags & ASE_MT); 6982 gen_helper_dmfc0_tchalt(arg, cpu_env); 6983 register_name = "TCHalt"; 6984 break; 6985 case CP0_REG02__TCCONTEXT: 6986 CP0_CHECK(ctx->insn_flags & ASE_MT); 6987 gen_helper_dmfc0_tccontext(arg, cpu_env); 6988 register_name = "TCContext"; 6989 break; 6990 case CP0_REG02__TCSCHEDULE: 6991 CP0_CHECK(ctx->insn_flags & ASE_MT); 6992 gen_helper_dmfc0_tcschedule(arg, cpu_env); 6993 register_name = "TCSchedule"; 6994 break; 6995 case CP0_REG02__TCSCHEFBACK: 6996 CP0_CHECK(ctx->insn_flags & ASE_MT); 6997 gen_helper_dmfc0_tcschefback(arg, cpu_env); 6998 register_name = "TCScheFBack"; 6999 break; 7000 default: 7001 goto cp0_unimplemented; 7002 } 7003 break; 7004 case CP0_REGISTER_03: 7005 switch (sel) { 7006 case CP0_REG03__ENTRYLO1: 7007 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1)); 7008 register_name = "EntryLo1"; 7009 break; 7010 case CP0_REG03__GLOBALNUM: 7011 CP0_CHECK(ctx->vp); 7012 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber)); 7013 register_name = "GlobalNumber"; 7014 break; 7015 default: 7016 goto cp0_unimplemented; 7017 } 7018 break; 7019 case CP0_REGISTER_04: 7020 switch (sel) { 7021 case CP0_REG04__CONTEXT: 7022 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context)); 7023 register_name = "Context"; 7024 break; 7025 case CP0_REG04__CONTEXTCONFIG: 7026 /* SmartMIPS ASE */ 7027 /* gen_helper_dmfc0_contextconfig(arg); */ 7028 register_name = "ContextConfig"; 7029 goto cp0_unimplemented; 7030 case CP0_REG04__USERLOCAL: 7031 CP0_CHECK(ctx->ulri); 7032 tcg_gen_ld_tl(arg, cpu_env, 7033 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 7034 register_name = "UserLocal"; 7035 break; 7036 case CP0_REG04__MMID: 7037 CP0_CHECK(ctx->mi); 7038 gen_helper_mtc0_memorymapid(cpu_env, arg); 7039 register_name = "MMID"; 7040 break; 7041 default: 7042 goto cp0_unimplemented; 7043 } 7044 break; 7045 case CP0_REGISTER_05: 7046 switch (sel) { 7047 case CP0_REG05__PAGEMASK: 7048 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask)); 7049 register_name = "PageMask"; 7050 break; 7051 case CP0_REG05__PAGEGRAIN: 7052 check_insn(ctx, ISA_MIPS_R2); 7053 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain)); 7054 register_name = "PageGrain"; 7055 break; 7056 case CP0_REG05__SEGCTL0: 7057 CP0_CHECK(ctx->sc); 7058 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0)); 7059 register_name = "SegCtl0"; 7060 break; 7061 case CP0_REG05__SEGCTL1: 7062 CP0_CHECK(ctx->sc); 7063 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1)); 7064 register_name = "SegCtl1"; 7065 break; 7066 case CP0_REG05__SEGCTL2: 7067 CP0_CHECK(ctx->sc); 7068 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2)); 7069 register_name = "SegCtl2"; 7070 break; 7071 case CP0_REG05__PWBASE: 7072 check_pw(ctx); 7073 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase)); 7074 register_name = "PWBase"; 7075 break; 7076 case CP0_REG05__PWFIELD: 7077 check_pw(ctx); 7078 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWField)); 7079 register_name = "PWField"; 7080 break; 7081 case CP0_REG05__PWSIZE: 7082 check_pw(ctx); 7083 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWSize)); 7084 register_name = "PWSize"; 7085 break; 7086 default: 7087 goto cp0_unimplemented; 7088 } 7089 break; 7090 case CP0_REGISTER_06: 7091 switch (sel) { 7092 case CP0_REG06__WIRED: 7093 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired)); 7094 register_name = "Wired"; 7095 break; 7096 case CP0_REG06__SRSCONF0: 7097 check_insn(ctx, ISA_MIPS_R2); 7098 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0)); 7099 register_name = "SRSConf0"; 7100 break; 7101 case CP0_REG06__SRSCONF1: 7102 check_insn(ctx, ISA_MIPS_R2); 7103 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1)); 7104 register_name = "SRSConf1"; 7105 break; 7106 case CP0_REG06__SRSCONF2: 7107 check_insn(ctx, ISA_MIPS_R2); 7108 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2)); 7109 register_name = "SRSConf2"; 7110 break; 7111 case CP0_REG06__SRSCONF3: 7112 check_insn(ctx, ISA_MIPS_R2); 7113 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3)); 7114 register_name = "SRSConf3"; 7115 break; 7116 case CP0_REG06__SRSCONF4: 7117 check_insn(ctx, ISA_MIPS_R2); 7118 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4)); 7119 register_name = "SRSConf4"; 7120 break; 7121 case CP0_REG06__PWCTL: 7122 check_pw(ctx); 7123 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl)); 7124 register_name = "PWCtl"; 7125 break; 7126 default: 7127 goto cp0_unimplemented; 7128 } 7129 break; 7130 case CP0_REGISTER_07: 7131 switch (sel) { 7132 case CP0_REG07__HWRENA: 7133 check_insn(ctx, ISA_MIPS_R2); 7134 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna)); 7135 register_name = "HWREna"; 7136 break; 7137 default: 7138 goto cp0_unimplemented; 7139 } 7140 break; 7141 case CP0_REGISTER_08: 7142 switch (sel) { 7143 case CP0_REG08__BADVADDR: 7144 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); 7145 register_name = "BadVAddr"; 7146 break; 7147 case CP0_REG08__BADINSTR: 7148 CP0_CHECK(ctx->bi); 7149 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr)); 7150 register_name = "BadInstr"; 7151 break; 7152 case CP0_REG08__BADINSTRP: 7153 CP0_CHECK(ctx->bp); 7154 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP)); 7155 register_name = "BadInstrP"; 7156 break; 7157 case CP0_REG08__BADINSTRX: 7158 CP0_CHECK(ctx->bi); 7159 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX)); 7160 tcg_gen_andi_tl(arg, arg, ~0xffff); 7161 register_name = "BadInstrX"; 7162 break; 7163 default: 7164 goto cp0_unimplemented; 7165 } 7166 break; 7167 case CP0_REGISTER_09: 7168 switch (sel) { 7169 case CP0_REG09__COUNT: 7170 /* Mark as an IO operation because we read the time. */ 7171 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { 7172 gen_io_start(); 7173 } 7174 gen_helper_mfc0_count(arg, cpu_env); 7175 /* 7176 * Break the TB to be able to take timer interrupts immediately 7177 * after reading count. DISAS_STOP isn't sufficient, we need to 7178 * ensure we break completely out of translated code. 7179 */ 7180 gen_save_pc(ctx->base.pc_next + 4); 7181 ctx->base.is_jmp = DISAS_EXIT; 7182 register_name = "Count"; 7183 break; 7184 case CP0_REG09__SAARI: 7185 CP0_CHECK(ctx->saar); 7186 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI)); 7187 register_name = "SAARI"; 7188 break; 7189 case CP0_REG09__SAAR: 7190 CP0_CHECK(ctx->saar); 7191 gen_helper_dmfc0_saar(arg, cpu_env); 7192 register_name = "SAAR"; 7193 break; 7194 default: 7195 goto cp0_unimplemented; 7196 } 7197 break; 7198 case CP0_REGISTER_10: 7199 switch (sel) { 7200 case CP0_REG10__ENTRYHI: 7201 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi)); 7202 register_name = "EntryHi"; 7203 break; 7204 default: 7205 goto cp0_unimplemented; 7206 } 7207 break; 7208 case CP0_REGISTER_11: 7209 switch (sel) { 7210 case CP0_REG11__COMPARE: 7211 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare)); 7212 register_name = "Compare"; 7213 break; 7214 /* 6,7 are implementation dependent */ 7215 default: 7216 goto cp0_unimplemented; 7217 } 7218 break; 7219 case CP0_REGISTER_12: 7220 switch (sel) { 7221 case CP0_REG12__STATUS: 7222 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status)); 7223 register_name = "Status"; 7224 break; 7225 case CP0_REG12__INTCTL: 7226 check_insn(ctx, ISA_MIPS_R2); 7227 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl)); 7228 register_name = "IntCtl"; 7229 break; 7230 case CP0_REG12__SRSCTL: 7231 check_insn(ctx, ISA_MIPS_R2); 7232 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl)); 7233 register_name = "SRSCtl"; 7234 break; 7235 case CP0_REG12__SRSMAP: 7236 check_insn(ctx, ISA_MIPS_R2); 7237 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); 7238 register_name = "SRSMap"; 7239 break; 7240 default: 7241 goto cp0_unimplemented; 7242 } 7243 break; 7244 case CP0_REGISTER_13: 7245 switch (sel) { 7246 case CP0_REG13__CAUSE: 7247 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause)); 7248 register_name = "Cause"; 7249 break; 7250 default: 7251 goto cp0_unimplemented; 7252 } 7253 break; 7254 case CP0_REGISTER_14: 7255 switch (sel) { 7256 case CP0_REG14__EPC: 7257 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC)); 7258 register_name = "EPC"; 7259 break; 7260 default: 7261 goto cp0_unimplemented; 7262 } 7263 break; 7264 case CP0_REGISTER_15: 7265 switch (sel) { 7266 case CP0_REG15__PRID: 7267 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid)); 7268 register_name = "PRid"; 7269 break; 7270 case CP0_REG15__EBASE: 7271 check_insn(ctx, ISA_MIPS_R2); 7272 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase)); 7273 register_name = "EBase"; 7274 break; 7275 case CP0_REG15__CMGCRBASE: 7276 check_insn(ctx, ISA_MIPS_R2); 7277 CP0_CHECK(ctx->cmgcr); 7278 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase)); 7279 register_name = "CMGCRBase"; 7280 break; 7281 default: 7282 goto cp0_unimplemented; 7283 } 7284 break; 7285 case CP0_REGISTER_16: 7286 switch (sel) { 7287 case CP0_REG16__CONFIG: 7288 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0)); 7289 register_name = "Config"; 7290 break; 7291 case CP0_REG16__CONFIG1: 7292 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1)); 7293 register_name = "Config1"; 7294 break; 7295 case CP0_REG16__CONFIG2: 7296 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2)); 7297 register_name = "Config2"; 7298 break; 7299 case CP0_REG16__CONFIG3: 7300 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3)); 7301 register_name = "Config3"; 7302 break; 7303 case CP0_REG16__CONFIG4: 7304 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4)); 7305 register_name = "Config4"; 7306 break; 7307 case CP0_REG16__CONFIG5: 7308 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5)); 7309 register_name = "Config5"; 7310 break; 7311 /* 6,7 are implementation dependent */ 7312 case CP0_REG16__CONFIG6: 7313 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6)); 7314 register_name = "Config6"; 7315 break; 7316 case CP0_REG16__CONFIG7: 7317 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7)); 7318 register_name = "Config7"; 7319 break; 7320 default: 7321 goto cp0_unimplemented; 7322 } 7323 break; 7324 case CP0_REGISTER_17: 7325 switch (sel) { 7326 case CP0_REG17__LLADDR: 7327 gen_helper_dmfc0_lladdr(arg, cpu_env); 7328 register_name = "LLAddr"; 7329 break; 7330 case CP0_REG17__MAAR: 7331 CP0_CHECK(ctx->mrp); 7332 gen_helper_dmfc0_maar(arg, cpu_env); 7333 register_name = "MAAR"; 7334 break; 7335 case CP0_REG17__MAARI: 7336 CP0_CHECK(ctx->mrp); 7337 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI)); 7338 register_name = "MAARI"; 7339 break; 7340 default: 7341 goto cp0_unimplemented; 7342 } 7343 break; 7344 case CP0_REGISTER_18: 7345 switch (sel) { 7346 case CP0_REG18__WATCHLO0: 7347 case CP0_REG18__WATCHLO1: 7348 case CP0_REG18__WATCHLO2: 7349 case CP0_REG18__WATCHLO3: 7350 case CP0_REG18__WATCHLO4: 7351 case CP0_REG18__WATCHLO5: 7352 case CP0_REG18__WATCHLO6: 7353 case CP0_REG18__WATCHLO7: 7354 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 7355 gen_helper_1e0i(dmfc0_watchlo, arg, sel); 7356 register_name = "WatchLo"; 7357 break; 7358 default: 7359 goto cp0_unimplemented; 7360 } 7361 break; 7362 case CP0_REGISTER_19: 7363 switch (sel) { 7364 case CP0_REG19__WATCHHI0: 7365 case CP0_REG19__WATCHHI1: 7366 case CP0_REG19__WATCHHI2: 7367 case CP0_REG19__WATCHHI3: 7368 case CP0_REG19__WATCHHI4: 7369 case CP0_REG19__WATCHHI5: 7370 case CP0_REG19__WATCHHI6: 7371 case CP0_REG19__WATCHHI7: 7372 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 7373 gen_helper_1e0i(dmfc0_watchhi, arg, sel); 7374 register_name = "WatchHi"; 7375 break; 7376 default: 7377 goto cp0_unimplemented; 7378 } 7379 break; 7380 case CP0_REGISTER_20: 7381 switch (sel) { 7382 case CP0_REG20__XCONTEXT: 7383 check_insn(ctx, ISA_MIPS3); 7384 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext)); 7385 register_name = "XContext"; 7386 break; 7387 default: 7388 goto cp0_unimplemented; 7389 } 7390 break; 7391 case CP0_REGISTER_21: 7392 /* Officially reserved, but sel 0 is used for R1x000 framemask */ 7393 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 7394 switch (sel) { 7395 case 0: 7396 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask)); 7397 register_name = "Framemask"; 7398 break; 7399 default: 7400 goto cp0_unimplemented; 7401 } 7402 break; 7403 case CP0_REGISTER_22: 7404 tcg_gen_movi_tl(arg, 0); /* unimplemented */ 7405 register_name = "'Diagnostic"; /* implementation dependent */ 7406 break; 7407 case CP0_REGISTER_23: 7408 switch (sel) { 7409 case CP0_REG23__DEBUG: 7410 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */ 7411 register_name = "Debug"; 7412 break; 7413 case CP0_REG23__TRACECONTROL: 7414 /* PDtrace support */ 7415 /* gen_helper_dmfc0_tracecontrol(arg, cpu_env); */ 7416 register_name = "TraceControl"; 7417 goto cp0_unimplemented; 7418 case CP0_REG23__TRACECONTROL2: 7419 /* PDtrace support */ 7420 /* gen_helper_dmfc0_tracecontrol2(arg, cpu_env); */ 7421 register_name = "TraceControl2"; 7422 goto cp0_unimplemented; 7423 case CP0_REG23__USERTRACEDATA1: 7424 /* PDtrace support */ 7425 /* gen_helper_dmfc0_usertracedata1(arg, cpu_env);*/ 7426 register_name = "UserTraceData1"; 7427 goto cp0_unimplemented; 7428 case CP0_REG23__TRACEIBPC: 7429 /* PDtrace support */ 7430 /* gen_helper_dmfc0_traceibpc(arg, cpu_env); */ 7431 register_name = "TraceIBPC"; 7432 goto cp0_unimplemented; 7433 case CP0_REG23__TRACEDBPC: 7434 /* PDtrace support */ 7435 /* gen_helper_dmfc0_tracedbpc(arg, cpu_env); */ 7436 register_name = "TraceDBPC"; 7437 goto cp0_unimplemented; 7438 default: 7439 goto cp0_unimplemented; 7440 } 7441 break; 7442 case CP0_REGISTER_24: 7443 switch (sel) { 7444 case CP0_REG24__DEPC: 7445 /* EJTAG support */ 7446 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC)); 7447 register_name = "DEPC"; 7448 break; 7449 default: 7450 goto cp0_unimplemented; 7451 } 7452 break; 7453 case CP0_REGISTER_25: 7454 switch (sel) { 7455 case CP0_REG25__PERFCTL0: 7456 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0)); 7457 register_name = "Performance0"; 7458 break; 7459 case CP0_REG25__PERFCNT0: 7460 /* gen_helper_dmfc0_performance1(arg); */ 7461 register_name = "Performance1"; 7462 goto cp0_unimplemented; 7463 case CP0_REG25__PERFCTL1: 7464 /* gen_helper_dmfc0_performance2(arg); */ 7465 register_name = "Performance2"; 7466 goto cp0_unimplemented; 7467 case CP0_REG25__PERFCNT1: 7468 /* gen_helper_dmfc0_performance3(arg); */ 7469 register_name = "Performance3"; 7470 goto cp0_unimplemented; 7471 case CP0_REG25__PERFCTL2: 7472 /* gen_helper_dmfc0_performance4(arg); */ 7473 register_name = "Performance4"; 7474 goto cp0_unimplemented; 7475 case CP0_REG25__PERFCNT2: 7476 /* gen_helper_dmfc0_performance5(arg); */ 7477 register_name = "Performance5"; 7478 goto cp0_unimplemented; 7479 case CP0_REG25__PERFCTL3: 7480 /* gen_helper_dmfc0_performance6(arg); */ 7481 register_name = "Performance6"; 7482 goto cp0_unimplemented; 7483 case CP0_REG25__PERFCNT3: 7484 /* gen_helper_dmfc0_performance7(arg); */ 7485 register_name = "Performance7"; 7486 goto cp0_unimplemented; 7487 default: 7488 goto cp0_unimplemented; 7489 } 7490 break; 7491 case CP0_REGISTER_26: 7492 switch (sel) { 7493 case CP0_REG26__ERRCTL: 7494 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl)); 7495 register_name = "ErrCtl"; 7496 break; 7497 default: 7498 goto cp0_unimplemented; 7499 } 7500 break; 7501 case CP0_REGISTER_27: 7502 switch (sel) { 7503 /* ignored */ 7504 case CP0_REG27__CACHERR: 7505 tcg_gen_movi_tl(arg, 0); /* unimplemented */ 7506 register_name = "CacheErr"; 7507 break; 7508 default: 7509 goto cp0_unimplemented; 7510 } 7511 break; 7512 case CP0_REGISTER_28: 7513 switch (sel) { 7514 case CP0_REG28__TAGLO: 7515 case CP0_REG28__TAGLO1: 7516 case CP0_REG28__TAGLO2: 7517 case CP0_REG28__TAGLO3: 7518 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo)); 7519 register_name = "TagLo"; 7520 break; 7521 case CP0_REG28__DATALO: 7522 case CP0_REG28__DATALO1: 7523 case CP0_REG28__DATALO2: 7524 case CP0_REG28__DATALO3: 7525 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo)); 7526 register_name = "DataLo"; 7527 break; 7528 default: 7529 goto cp0_unimplemented; 7530 } 7531 break; 7532 case CP0_REGISTER_29: 7533 switch (sel) { 7534 case CP0_REG29__TAGHI: 7535 case CP0_REG29__TAGHI1: 7536 case CP0_REG29__TAGHI2: 7537 case CP0_REG29__TAGHI3: 7538 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi)); 7539 register_name = "TagHi"; 7540 break; 7541 case CP0_REG29__DATAHI: 7542 case CP0_REG29__DATAHI1: 7543 case CP0_REG29__DATAHI2: 7544 case CP0_REG29__DATAHI3: 7545 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi)); 7546 register_name = "DataHi"; 7547 break; 7548 default: 7549 goto cp0_unimplemented; 7550 } 7551 break; 7552 case CP0_REGISTER_30: 7553 switch (sel) { 7554 case CP0_REG30__ERROREPC: 7555 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC)); 7556 register_name = "ErrorEPC"; 7557 break; 7558 default: 7559 goto cp0_unimplemented; 7560 } 7561 break; 7562 case CP0_REGISTER_31: 7563 switch (sel) { 7564 case CP0_REG31__DESAVE: 7565 /* EJTAG support */ 7566 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); 7567 register_name = "DESAVE"; 7568 break; 7569 case CP0_REG31__KSCRATCH1: 7570 case CP0_REG31__KSCRATCH2: 7571 case CP0_REG31__KSCRATCH3: 7572 case CP0_REG31__KSCRATCH4: 7573 case CP0_REG31__KSCRATCH5: 7574 case CP0_REG31__KSCRATCH6: 7575 CP0_CHECK(ctx->kscrexist & (1 << sel)); 7576 tcg_gen_ld_tl(arg, cpu_env, 7577 offsetof(CPUMIPSState, CP0_KScratch[sel - 2])); 7578 register_name = "KScratch"; 7579 break; 7580 default: 7581 goto cp0_unimplemented; 7582 } 7583 break; 7584 default: 7585 goto cp0_unimplemented; 7586 } 7587 trace_mips_translate_c0("dmfc0", register_name, reg, sel); 7588 return; 7589 7590 cp0_unimplemented: 7591 qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n", 7592 register_name, reg, sel); 7593 gen_mfc0_unimplemented(ctx, arg); 7594 } 7595 7596 static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) 7597 { 7598 const char *register_name = "invalid"; 7599 7600 if (sel != 0) { 7601 check_insn(ctx, ISA_MIPS_R1); 7602 } 7603 7604 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { 7605 gen_io_start(); 7606 } 7607 7608 switch (reg) { 7609 case CP0_REGISTER_00: 7610 switch (sel) { 7611 case CP0_REG00__INDEX: 7612 gen_helper_mtc0_index(cpu_env, arg); 7613 register_name = "Index"; 7614 break; 7615 case CP0_REG00__MVPCONTROL: 7616 CP0_CHECK(ctx->insn_flags & ASE_MT); 7617 gen_helper_mtc0_mvpcontrol(cpu_env, arg); 7618 register_name = "MVPControl"; 7619 break; 7620 case CP0_REG00__MVPCONF0: 7621 CP0_CHECK(ctx->insn_flags & ASE_MT); 7622 /* ignored */ 7623 register_name = "MVPConf0"; 7624 break; 7625 case CP0_REG00__MVPCONF1: 7626 CP0_CHECK(ctx->insn_flags & ASE_MT); 7627 /* ignored */ 7628 register_name = "MVPConf1"; 7629 break; 7630 case CP0_REG00__VPCONTROL: 7631 CP0_CHECK(ctx->vp); 7632 /* ignored */ 7633 register_name = "VPControl"; 7634 break; 7635 default: 7636 goto cp0_unimplemented; 7637 } 7638 break; 7639 case CP0_REGISTER_01: 7640 switch (sel) { 7641 case CP0_REG01__RANDOM: 7642 /* ignored */ 7643 register_name = "Random"; 7644 break; 7645 case CP0_REG01__VPECONTROL: 7646 CP0_CHECK(ctx->insn_flags & ASE_MT); 7647 gen_helper_mtc0_vpecontrol(cpu_env, arg); 7648 register_name = "VPEControl"; 7649 break; 7650 case CP0_REG01__VPECONF0: 7651 CP0_CHECK(ctx->insn_flags & ASE_MT); 7652 gen_helper_mtc0_vpeconf0(cpu_env, arg); 7653 register_name = "VPEConf0"; 7654 break; 7655 case CP0_REG01__VPECONF1: 7656 CP0_CHECK(ctx->insn_flags & ASE_MT); 7657 gen_helper_mtc0_vpeconf1(cpu_env, arg); 7658 register_name = "VPEConf1"; 7659 break; 7660 case CP0_REG01__YQMASK: 7661 CP0_CHECK(ctx->insn_flags & ASE_MT); 7662 gen_helper_mtc0_yqmask(cpu_env, arg); 7663 register_name = "YQMask"; 7664 break; 7665 case CP0_REG01__VPESCHEDULE: 7666 CP0_CHECK(ctx->insn_flags & ASE_MT); 7667 tcg_gen_st_tl(arg, cpu_env, 7668 offsetof(CPUMIPSState, CP0_VPESchedule)); 7669 register_name = "VPESchedule"; 7670 break; 7671 case CP0_REG01__VPESCHEFBACK: 7672 CP0_CHECK(ctx->insn_flags & ASE_MT); 7673 tcg_gen_st_tl(arg, cpu_env, 7674 offsetof(CPUMIPSState, CP0_VPEScheFBack)); 7675 register_name = "VPEScheFBack"; 7676 break; 7677 case CP0_REG01__VPEOPT: 7678 CP0_CHECK(ctx->insn_flags & ASE_MT); 7679 gen_helper_mtc0_vpeopt(cpu_env, arg); 7680 register_name = "VPEOpt"; 7681 break; 7682 default: 7683 goto cp0_unimplemented; 7684 } 7685 break; 7686 case CP0_REGISTER_02: 7687 switch (sel) { 7688 case CP0_REG02__ENTRYLO0: 7689 gen_helper_dmtc0_entrylo0(cpu_env, arg); 7690 register_name = "EntryLo0"; 7691 break; 7692 case CP0_REG02__TCSTATUS: 7693 CP0_CHECK(ctx->insn_flags & ASE_MT); 7694 gen_helper_mtc0_tcstatus(cpu_env, arg); 7695 register_name = "TCStatus"; 7696 break; 7697 case CP0_REG02__TCBIND: 7698 CP0_CHECK(ctx->insn_flags & ASE_MT); 7699 gen_helper_mtc0_tcbind(cpu_env, arg); 7700 register_name = "TCBind"; 7701 break; 7702 case CP0_REG02__TCRESTART: 7703 CP0_CHECK(ctx->insn_flags & ASE_MT); 7704 gen_helper_mtc0_tcrestart(cpu_env, arg); 7705 register_name = "TCRestart"; 7706 break; 7707 case CP0_REG02__TCHALT: 7708 CP0_CHECK(ctx->insn_flags & ASE_MT); 7709 gen_helper_mtc0_tchalt(cpu_env, arg); 7710 register_name = "TCHalt"; 7711 break; 7712 case CP0_REG02__TCCONTEXT: 7713 CP0_CHECK(ctx->insn_flags & ASE_MT); 7714 gen_helper_mtc0_tccontext(cpu_env, arg); 7715 register_name = "TCContext"; 7716 break; 7717 case CP0_REG02__TCSCHEDULE: 7718 CP0_CHECK(ctx->insn_flags & ASE_MT); 7719 gen_helper_mtc0_tcschedule(cpu_env, arg); 7720 register_name = "TCSchedule"; 7721 break; 7722 case CP0_REG02__TCSCHEFBACK: 7723 CP0_CHECK(ctx->insn_flags & ASE_MT); 7724 gen_helper_mtc0_tcschefback(cpu_env, arg); 7725 register_name = "TCScheFBack"; 7726 break; 7727 default: 7728 goto cp0_unimplemented; 7729 } 7730 break; 7731 case CP0_REGISTER_03: 7732 switch (sel) { 7733 case CP0_REG03__ENTRYLO1: 7734 gen_helper_dmtc0_entrylo1(cpu_env, arg); 7735 register_name = "EntryLo1"; 7736 break; 7737 case CP0_REG03__GLOBALNUM: 7738 CP0_CHECK(ctx->vp); 7739 /* ignored */ 7740 register_name = "GlobalNumber"; 7741 break; 7742 default: 7743 goto cp0_unimplemented; 7744 } 7745 break; 7746 case CP0_REGISTER_04: 7747 switch (sel) { 7748 case CP0_REG04__CONTEXT: 7749 gen_helper_mtc0_context(cpu_env, arg); 7750 register_name = "Context"; 7751 break; 7752 case CP0_REG04__CONTEXTCONFIG: 7753 /* SmartMIPS ASE */ 7754 /* gen_helper_dmtc0_contextconfig(arg); */ 7755 register_name = "ContextConfig"; 7756 goto cp0_unimplemented; 7757 case CP0_REG04__USERLOCAL: 7758 CP0_CHECK(ctx->ulri); 7759 tcg_gen_st_tl(arg, cpu_env, 7760 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 7761 register_name = "UserLocal"; 7762 break; 7763 case CP0_REG04__MMID: 7764 CP0_CHECK(ctx->mi); 7765 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID)); 7766 register_name = "MMID"; 7767 break; 7768 default: 7769 goto cp0_unimplemented; 7770 } 7771 break; 7772 case CP0_REGISTER_05: 7773 switch (sel) { 7774 case CP0_REG05__PAGEMASK: 7775 gen_helper_mtc0_pagemask(cpu_env, arg); 7776 register_name = "PageMask"; 7777 break; 7778 case CP0_REG05__PAGEGRAIN: 7779 check_insn(ctx, ISA_MIPS_R2); 7780 gen_helper_mtc0_pagegrain(cpu_env, arg); 7781 register_name = "PageGrain"; 7782 break; 7783 case CP0_REG05__SEGCTL0: 7784 CP0_CHECK(ctx->sc); 7785 gen_helper_mtc0_segctl0(cpu_env, arg); 7786 register_name = "SegCtl0"; 7787 break; 7788 case CP0_REG05__SEGCTL1: 7789 CP0_CHECK(ctx->sc); 7790 gen_helper_mtc0_segctl1(cpu_env, arg); 7791 register_name = "SegCtl1"; 7792 break; 7793 case CP0_REG05__SEGCTL2: 7794 CP0_CHECK(ctx->sc); 7795 gen_helper_mtc0_segctl2(cpu_env, arg); 7796 register_name = "SegCtl2"; 7797 break; 7798 case CP0_REG05__PWBASE: 7799 check_pw(ctx); 7800 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase)); 7801 register_name = "PWBase"; 7802 break; 7803 case CP0_REG05__PWFIELD: 7804 check_pw(ctx); 7805 gen_helper_mtc0_pwfield(cpu_env, arg); 7806 register_name = "PWField"; 7807 break; 7808 case CP0_REG05__PWSIZE: 7809 check_pw(ctx); 7810 gen_helper_mtc0_pwsize(cpu_env, arg); 7811 register_name = "PWSize"; 7812 break; 7813 default: 7814 goto cp0_unimplemented; 7815 } 7816 break; 7817 case CP0_REGISTER_06: 7818 switch (sel) { 7819 case CP0_REG06__WIRED: 7820 gen_helper_mtc0_wired(cpu_env, arg); 7821 register_name = "Wired"; 7822 break; 7823 case CP0_REG06__SRSCONF0: 7824 check_insn(ctx, ISA_MIPS_R2); 7825 gen_helper_mtc0_srsconf0(cpu_env, arg); 7826 register_name = "SRSConf0"; 7827 break; 7828 case CP0_REG06__SRSCONF1: 7829 check_insn(ctx, ISA_MIPS_R2); 7830 gen_helper_mtc0_srsconf1(cpu_env, arg); 7831 register_name = "SRSConf1"; 7832 break; 7833 case CP0_REG06__SRSCONF2: 7834 check_insn(ctx, ISA_MIPS_R2); 7835 gen_helper_mtc0_srsconf2(cpu_env, arg); 7836 register_name = "SRSConf2"; 7837 break; 7838 case CP0_REG06__SRSCONF3: 7839 check_insn(ctx, ISA_MIPS_R2); 7840 gen_helper_mtc0_srsconf3(cpu_env, arg); 7841 register_name = "SRSConf3"; 7842 break; 7843 case CP0_REG06__SRSCONF4: 7844 check_insn(ctx, ISA_MIPS_R2); 7845 gen_helper_mtc0_srsconf4(cpu_env, arg); 7846 register_name = "SRSConf4"; 7847 break; 7848 case CP0_REG06__PWCTL: 7849 check_pw(ctx); 7850 gen_helper_mtc0_pwctl(cpu_env, arg); 7851 register_name = "PWCtl"; 7852 break; 7853 default: 7854 goto cp0_unimplemented; 7855 } 7856 break; 7857 case CP0_REGISTER_07: 7858 switch (sel) { 7859 case CP0_REG07__HWRENA: 7860 check_insn(ctx, ISA_MIPS_R2); 7861 gen_helper_mtc0_hwrena(cpu_env, arg); 7862 ctx->base.is_jmp = DISAS_STOP; 7863 register_name = "HWREna"; 7864 break; 7865 default: 7866 goto cp0_unimplemented; 7867 } 7868 break; 7869 case CP0_REGISTER_08: 7870 switch (sel) { 7871 case CP0_REG08__BADVADDR: 7872 /* ignored */ 7873 register_name = "BadVAddr"; 7874 break; 7875 case CP0_REG08__BADINSTR: 7876 /* ignored */ 7877 register_name = "BadInstr"; 7878 break; 7879 case CP0_REG08__BADINSTRP: 7880 /* ignored */ 7881 register_name = "BadInstrP"; 7882 break; 7883 case CP0_REG08__BADINSTRX: 7884 /* ignored */ 7885 register_name = "BadInstrX"; 7886 break; 7887 default: 7888 goto cp0_unimplemented; 7889 } 7890 break; 7891 case CP0_REGISTER_09: 7892 switch (sel) { 7893 case CP0_REG09__COUNT: 7894 gen_helper_mtc0_count(cpu_env, arg); 7895 register_name = "Count"; 7896 break; 7897 case CP0_REG09__SAARI: 7898 CP0_CHECK(ctx->saar); 7899 gen_helper_mtc0_saari(cpu_env, arg); 7900 register_name = "SAARI"; 7901 break; 7902 case CP0_REG09__SAAR: 7903 CP0_CHECK(ctx->saar); 7904 gen_helper_mtc0_saar(cpu_env, arg); 7905 register_name = "SAAR"; 7906 break; 7907 default: 7908 goto cp0_unimplemented; 7909 } 7910 /* Stop translation as we may have switched the execution mode */ 7911 ctx->base.is_jmp = DISAS_STOP; 7912 break; 7913 case CP0_REGISTER_10: 7914 switch (sel) { 7915 case CP0_REG10__ENTRYHI: 7916 gen_helper_mtc0_entryhi(cpu_env, arg); 7917 register_name = "EntryHi"; 7918 break; 7919 default: 7920 goto cp0_unimplemented; 7921 } 7922 break; 7923 case CP0_REGISTER_11: 7924 switch (sel) { 7925 case CP0_REG11__COMPARE: 7926 gen_helper_mtc0_compare(cpu_env, arg); 7927 register_name = "Compare"; 7928 break; 7929 /* 6,7 are implementation dependent */ 7930 default: 7931 goto cp0_unimplemented; 7932 } 7933 /* Stop translation as we may have switched the execution mode */ 7934 ctx->base.is_jmp = DISAS_STOP; 7935 break; 7936 case CP0_REGISTER_12: 7937 switch (sel) { 7938 case CP0_REG12__STATUS: 7939 save_cpu_state(ctx, 1); 7940 gen_helper_mtc0_status(cpu_env, arg); 7941 /* DISAS_STOP isn't good enough here, hflags may have changed. */ 7942 gen_save_pc(ctx->base.pc_next + 4); 7943 ctx->base.is_jmp = DISAS_EXIT; 7944 register_name = "Status"; 7945 break; 7946 case CP0_REG12__INTCTL: 7947 check_insn(ctx, ISA_MIPS_R2); 7948 gen_helper_mtc0_intctl(cpu_env, arg); 7949 /* Stop translation as we may have switched the execution mode */ 7950 ctx->base.is_jmp = DISAS_STOP; 7951 register_name = "IntCtl"; 7952 break; 7953 case CP0_REG12__SRSCTL: 7954 check_insn(ctx, ISA_MIPS_R2); 7955 gen_helper_mtc0_srsctl(cpu_env, arg); 7956 /* Stop translation as we may have switched the execution mode */ 7957 ctx->base.is_jmp = DISAS_STOP; 7958 register_name = "SRSCtl"; 7959 break; 7960 case CP0_REG12__SRSMAP: 7961 check_insn(ctx, ISA_MIPS_R2); 7962 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); 7963 /* Stop translation as we may have switched the execution mode */ 7964 ctx->base.is_jmp = DISAS_STOP; 7965 register_name = "SRSMap"; 7966 break; 7967 default: 7968 goto cp0_unimplemented; 7969 } 7970 break; 7971 case CP0_REGISTER_13: 7972 switch (sel) { 7973 case CP0_REG13__CAUSE: 7974 save_cpu_state(ctx, 1); 7975 gen_helper_mtc0_cause(cpu_env, arg); 7976 /* 7977 * Stop translation as we may have triggered an interrupt. 7978 * DISAS_STOP isn't sufficient, we need to ensure we break out of 7979 * translated code to check for pending interrupts. 7980 */ 7981 gen_save_pc(ctx->base.pc_next + 4); 7982 ctx->base.is_jmp = DISAS_EXIT; 7983 register_name = "Cause"; 7984 break; 7985 default: 7986 goto cp0_unimplemented; 7987 } 7988 break; 7989 case CP0_REGISTER_14: 7990 switch (sel) { 7991 case CP0_REG14__EPC: 7992 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC)); 7993 register_name = "EPC"; 7994 break; 7995 default: 7996 goto cp0_unimplemented; 7997 } 7998 break; 7999 case CP0_REGISTER_15: 8000 switch (sel) { 8001 case CP0_REG15__PRID: 8002 /* ignored */ 8003 register_name = "PRid"; 8004 break; 8005 case CP0_REG15__EBASE: 8006 check_insn(ctx, ISA_MIPS_R2); 8007 gen_helper_mtc0_ebase(cpu_env, arg); 8008 register_name = "EBase"; 8009 break; 8010 default: 8011 goto cp0_unimplemented; 8012 } 8013 break; 8014 case CP0_REGISTER_16: 8015 switch (sel) { 8016 case CP0_REG16__CONFIG: 8017 gen_helper_mtc0_config0(cpu_env, arg); 8018 register_name = "Config"; 8019 /* Stop translation as we may have switched the execution mode */ 8020 ctx->base.is_jmp = DISAS_STOP; 8021 break; 8022 case CP0_REG16__CONFIG1: 8023 /* ignored, read only */ 8024 register_name = "Config1"; 8025 break; 8026 case CP0_REG16__CONFIG2: 8027 gen_helper_mtc0_config2(cpu_env, arg); 8028 register_name = "Config2"; 8029 /* Stop translation as we may have switched the execution mode */ 8030 ctx->base.is_jmp = DISAS_STOP; 8031 break; 8032 case CP0_REG16__CONFIG3: 8033 gen_helper_mtc0_config3(cpu_env, arg); 8034 register_name = "Config3"; 8035 /* Stop translation as we may have switched the execution mode */ 8036 ctx->base.is_jmp = DISAS_STOP; 8037 break; 8038 case CP0_REG16__CONFIG4: 8039 /* currently ignored */ 8040 register_name = "Config4"; 8041 break; 8042 case CP0_REG16__CONFIG5: 8043 gen_helper_mtc0_config5(cpu_env, arg); 8044 register_name = "Config5"; 8045 /* Stop translation as we may have switched the execution mode */ 8046 ctx->base.is_jmp = DISAS_STOP; 8047 break; 8048 /* 6,7 are implementation dependent */ 8049 default: 8050 register_name = "Invalid config selector"; 8051 goto cp0_unimplemented; 8052 } 8053 break; 8054 case CP0_REGISTER_17: 8055 switch (sel) { 8056 case CP0_REG17__LLADDR: 8057 gen_helper_mtc0_lladdr(cpu_env, arg); 8058 register_name = "LLAddr"; 8059 break; 8060 case CP0_REG17__MAAR: 8061 CP0_CHECK(ctx->mrp); 8062 gen_helper_mtc0_maar(cpu_env, arg); 8063 register_name = "MAAR"; 8064 break; 8065 case CP0_REG17__MAARI: 8066 CP0_CHECK(ctx->mrp); 8067 gen_helper_mtc0_maari(cpu_env, arg); 8068 register_name = "MAARI"; 8069 break; 8070 default: 8071 goto cp0_unimplemented; 8072 } 8073 break; 8074 case CP0_REGISTER_18: 8075 switch (sel) { 8076 case CP0_REG18__WATCHLO0: 8077 case CP0_REG18__WATCHLO1: 8078 case CP0_REG18__WATCHLO2: 8079 case CP0_REG18__WATCHLO3: 8080 case CP0_REG18__WATCHLO4: 8081 case CP0_REG18__WATCHLO5: 8082 case CP0_REG18__WATCHLO6: 8083 case CP0_REG18__WATCHLO7: 8084 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 8085 gen_helper_0e1i(mtc0_watchlo, arg, sel); 8086 register_name = "WatchLo"; 8087 break; 8088 default: 8089 goto cp0_unimplemented; 8090 } 8091 break; 8092 case CP0_REGISTER_19: 8093 switch (sel) { 8094 case CP0_REG19__WATCHHI0: 8095 case CP0_REG19__WATCHHI1: 8096 case CP0_REG19__WATCHHI2: 8097 case CP0_REG19__WATCHHI3: 8098 case CP0_REG19__WATCHHI4: 8099 case CP0_REG19__WATCHHI5: 8100 case CP0_REG19__WATCHHI6: 8101 case CP0_REG19__WATCHHI7: 8102 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 8103 gen_helper_0e1i(mtc0_watchhi, arg, sel); 8104 register_name = "WatchHi"; 8105 break; 8106 default: 8107 goto cp0_unimplemented; 8108 } 8109 break; 8110 case CP0_REGISTER_20: 8111 switch (sel) { 8112 case CP0_REG20__XCONTEXT: 8113 check_insn(ctx, ISA_MIPS3); 8114 gen_helper_mtc0_xcontext(cpu_env, arg); 8115 register_name = "XContext"; 8116 break; 8117 default: 8118 goto cp0_unimplemented; 8119 } 8120 break; 8121 case CP0_REGISTER_21: 8122 /* Officially reserved, but sel 0 is used for R1x000 framemask */ 8123 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 8124 switch (sel) { 8125 case 0: 8126 gen_helper_mtc0_framemask(cpu_env, arg); 8127 register_name = "Framemask"; 8128 break; 8129 default: 8130 goto cp0_unimplemented; 8131 } 8132 break; 8133 case CP0_REGISTER_22: 8134 /* ignored */ 8135 register_name = "Diagnostic"; /* implementation dependent */ 8136 break; 8137 case CP0_REGISTER_23: 8138 switch (sel) { 8139 case CP0_REG23__DEBUG: 8140 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */ 8141 /* DISAS_STOP isn't good enough here, hflags may have changed. */ 8142 gen_save_pc(ctx->base.pc_next + 4); 8143 ctx->base.is_jmp = DISAS_EXIT; 8144 register_name = "Debug"; 8145 break; 8146 case CP0_REG23__TRACECONTROL: 8147 /* PDtrace support */ 8148 /* gen_helper_mtc0_tracecontrol(cpu_env, arg); */ 8149 /* Stop translation as we may have switched the execution mode */ 8150 ctx->base.is_jmp = DISAS_STOP; 8151 register_name = "TraceControl"; 8152 goto cp0_unimplemented; 8153 case CP0_REG23__TRACECONTROL2: 8154 /* PDtrace support */ 8155 /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */ 8156 /* Stop translation as we may have switched the execution mode */ 8157 ctx->base.is_jmp = DISAS_STOP; 8158 register_name = "TraceControl2"; 8159 goto cp0_unimplemented; 8160 case CP0_REG23__USERTRACEDATA1: 8161 /* PDtrace support */ 8162 /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/ 8163 /* Stop translation as we may have switched the execution mode */ 8164 ctx->base.is_jmp = DISAS_STOP; 8165 register_name = "UserTraceData1"; 8166 goto cp0_unimplemented; 8167 case CP0_REG23__TRACEIBPC: 8168 /* PDtrace support */ 8169 /* gen_helper_mtc0_traceibpc(cpu_env, arg); */ 8170 /* Stop translation as we may have switched the execution mode */ 8171 ctx->base.is_jmp = DISAS_STOP; 8172 register_name = "TraceIBPC"; 8173 goto cp0_unimplemented; 8174 case CP0_REG23__TRACEDBPC: 8175 /* PDtrace support */ 8176 /* gen_helper_mtc0_tracedbpc(cpu_env, arg); */ 8177 /* Stop translation as we may have switched the execution mode */ 8178 ctx->base.is_jmp = DISAS_STOP; 8179 register_name = "TraceDBPC"; 8180 goto cp0_unimplemented; 8181 default: 8182 goto cp0_unimplemented; 8183 } 8184 break; 8185 case CP0_REGISTER_24: 8186 switch (sel) { 8187 case CP0_REG24__DEPC: 8188 /* EJTAG support */ 8189 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC)); 8190 register_name = "DEPC"; 8191 break; 8192 default: 8193 goto cp0_unimplemented; 8194 } 8195 break; 8196 case CP0_REGISTER_25: 8197 switch (sel) { 8198 case CP0_REG25__PERFCTL0: 8199 gen_helper_mtc0_performance0(cpu_env, arg); 8200 register_name = "Performance0"; 8201 break; 8202 case CP0_REG25__PERFCNT0: 8203 /* gen_helper_mtc0_performance1(cpu_env, arg); */ 8204 register_name = "Performance1"; 8205 goto cp0_unimplemented; 8206 case CP0_REG25__PERFCTL1: 8207 /* gen_helper_mtc0_performance2(cpu_env, arg); */ 8208 register_name = "Performance2"; 8209 goto cp0_unimplemented; 8210 case CP0_REG25__PERFCNT1: 8211 /* gen_helper_mtc0_performance3(cpu_env, arg); */ 8212 register_name = "Performance3"; 8213 goto cp0_unimplemented; 8214 case CP0_REG25__PERFCTL2: 8215 /* gen_helper_mtc0_performance4(cpu_env, arg); */ 8216 register_name = "Performance4"; 8217 goto cp0_unimplemented; 8218 case CP0_REG25__PERFCNT2: 8219 /* gen_helper_mtc0_performance5(cpu_env, arg); */ 8220 register_name = "Performance5"; 8221 goto cp0_unimplemented; 8222 case CP0_REG25__PERFCTL3: 8223 /* gen_helper_mtc0_performance6(cpu_env, arg); */ 8224 register_name = "Performance6"; 8225 goto cp0_unimplemented; 8226 case CP0_REG25__PERFCNT3: 8227 /* gen_helper_mtc0_performance7(cpu_env, arg); */ 8228 register_name = "Performance7"; 8229 goto cp0_unimplemented; 8230 default: 8231 goto cp0_unimplemented; 8232 } 8233 break; 8234 case CP0_REGISTER_26: 8235 switch (sel) { 8236 case CP0_REG26__ERRCTL: 8237 gen_helper_mtc0_errctl(cpu_env, arg); 8238 ctx->base.is_jmp = DISAS_STOP; 8239 register_name = "ErrCtl"; 8240 break; 8241 default: 8242 goto cp0_unimplemented; 8243 } 8244 break; 8245 case CP0_REGISTER_27: 8246 switch (sel) { 8247 case CP0_REG27__CACHERR: 8248 /* ignored */ 8249 register_name = "CacheErr"; 8250 break; 8251 default: 8252 goto cp0_unimplemented; 8253 } 8254 break; 8255 case CP0_REGISTER_28: 8256 switch (sel) { 8257 case CP0_REG28__TAGLO: 8258 case CP0_REG28__TAGLO1: 8259 case CP0_REG28__TAGLO2: 8260 case CP0_REG28__TAGLO3: 8261 gen_helper_mtc0_taglo(cpu_env, arg); 8262 register_name = "TagLo"; 8263 break; 8264 case CP0_REG28__DATALO: 8265 case CP0_REG28__DATALO1: 8266 case CP0_REG28__DATALO2: 8267 case CP0_REG28__DATALO3: 8268 gen_helper_mtc0_datalo(cpu_env, arg); 8269 register_name = "DataLo"; 8270 break; 8271 default: 8272 goto cp0_unimplemented; 8273 } 8274 break; 8275 case CP0_REGISTER_29: 8276 switch (sel) { 8277 case CP0_REG29__TAGHI: 8278 case CP0_REG29__TAGHI1: 8279 case CP0_REG29__TAGHI2: 8280 case CP0_REG29__TAGHI3: 8281 gen_helper_mtc0_taghi(cpu_env, arg); 8282 register_name = "TagHi"; 8283 break; 8284 case CP0_REG29__DATAHI: 8285 case CP0_REG29__DATAHI1: 8286 case CP0_REG29__DATAHI2: 8287 case CP0_REG29__DATAHI3: 8288 gen_helper_mtc0_datahi(cpu_env, arg); 8289 register_name = "DataHi"; 8290 break; 8291 default: 8292 register_name = "invalid sel"; 8293 goto cp0_unimplemented; 8294 } 8295 break; 8296 case CP0_REGISTER_30: 8297 switch (sel) { 8298 case CP0_REG30__ERROREPC: 8299 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC)); 8300 register_name = "ErrorEPC"; 8301 break; 8302 default: 8303 goto cp0_unimplemented; 8304 } 8305 break; 8306 case CP0_REGISTER_31: 8307 switch (sel) { 8308 case CP0_REG31__DESAVE: 8309 /* EJTAG support */ 8310 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); 8311 register_name = "DESAVE"; 8312 break; 8313 case CP0_REG31__KSCRATCH1: 8314 case CP0_REG31__KSCRATCH2: 8315 case CP0_REG31__KSCRATCH3: 8316 case CP0_REG31__KSCRATCH4: 8317 case CP0_REG31__KSCRATCH5: 8318 case CP0_REG31__KSCRATCH6: 8319 CP0_CHECK(ctx->kscrexist & (1 << sel)); 8320 tcg_gen_st_tl(arg, cpu_env, 8321 offsetof(CPUMIPSState, CP0_KScratch[sel - 2])); 8322 register_name = "KScratch"; 8323 break; 8324 default: 8325 goto cp0_unimplemented; 8326 } 8327 break; 8328 default: 8329 goto cp0_unimplemented; 8330 } 8331 trace_mips_translate_c0("dmtc0", register_name, reg, sel); 8332 8333 /* For simplicity assume that all writes can cause interrupts. */ 8334 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { 8335 /* 8336 * DISAS_STOP isn't sufficient, we need to ensure we break out of 8337 * translated code to check for pending interrupts. 8338 */ 8339 gen_save_pc(ctx->base.pc_next + 4); 8340 ctx->base.is_jmp = DISAS_EXIT; 8341 } 8342 return; 8343 8344 cp0_unimplemented: 8345 qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n", 8346 register_name, reg, sel); 8347 } 8348 #endif /* TARGET_MIPS64 */ 8349 8350 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd, 8351 int u, int sel, int h) 8352 { 8353 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); 8354 TCGv t0 = tcg_temp_new(); 8355 8356 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 && 8357 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) != 8358 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) { 8359 tcg_gen_movi_tl(t0, -1); 8360 } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) > 8361 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) { 8362 tcg_gen_movi_tl(t0, -1); 8363 } else if (u == 0) { 8364 switch (rt) { 8365 case 1: 8366 switch (sel) { 8367 case 1: 8368 gen_helper_mftc0_vpecontrol(t0, cpu_env); 8369 break; 8370 case 2: 8371 gen_helper_mftc0_vpeconf0(t0, cpu_env); 8372 break; 8373 default: 8374 goto die; 8375 break; 8376 } 8377 break; 8378 case 2: 8379 switch (sel) { 8380 case 1: 8381 gen_helper_mftc0_tcstatus(t0, cpu_env); 8382 break; 8383 case 2: 8384 gen_helper_mftc0_tcbind(t0, cpu_env); 8385 break; 8386 case 3: 8387 gen_helper_mftc0_tcrestart(t0, cpu_env); 8388 break; 8389 case 4: 8390 gen_helper_mftc0_tchalt(t0, cpu_env); 8391 break; 8392 case 5: 8393 gen_helper_mftc0_tccontext(t0, cpu_env); 8394 break; 8395 case 6: 8396 gen_helper_mftc0_tcschedule(t0, cpu_env); 8397 break; 8398 case 7: 8399 gen_helper_mftc0_tcschefback(t0, cpu_env); 8400 break; 8401 default: 8402 gen_mfc0(ctx, t0, rt, sel); 8403 break; 8404 } 8405 break; 8406 case 10: 8407 switch (sel) { 8408 case 0: 8409 gen_helper_mftc0_entryhi(t0, cpu_env); 8410 break; 8411 default: 8412 gen_mfc0(ctx, t0, rt, sel); 8413 break; 8414 } 8415 break; 8416 case 12: 8417 switch (sel) { 8418 case 0: 8419 gen_helper_mftc0_status(t0, cpu_env); 8420 break; 8421 default: 8422 gen_mfc0(ctx, t0, rt, sel); 8423 break; 8424 } 8425 break; 8426 case 13: 8427 switch (sel) { 8428 case 0: 8429 gen_helper_mftc0_cause(t0, cpu_env); 8430 break; 8431 default: 8432 goto die; 8433 break; 8434 } 8435 break; 8436 case 14: 8437 switch (sel) { 8438 case 0: 8439 gen_helper_mftc0_epc(t0, cpu_env); 8440 break; 8441 default: 8442 goto die; 8443 break; 8444 } 8445 break; 8446 case 15: 8447 switch (sel) { 8448 case 1: 8449 gen_helper_mftc0_ebase(t0, cpu_env); 8450 break; 8451 default: 8452 goto die; 8453 break; 8454 } 8455 break; 8456 case 16: 8457 switch (sel) { 8458 case 0: 8459 case 1: 8460 case 2: 8461 case 3: 8462 case 4: 8463 case 5: 8464 case 6: 8465 case 7: 8466 gen_helper_mftc0_configx(t0, cpu_env, tcg_constant_tl(sel)); 8467 break; 8468 default: 8469 goto die; 8470 break; 8471 } 8472 break; 8473 case 23: 8474 switch (sel) { 8475 case 0: 8476 gen_helper_mftc0_debug(t0, cpu_env); 8477 break; 8478 default: 8479 gen_mfc0(ctx, t0, rt, sel); 8480 break; 8481 } 8482 break; 8483 default: 8484 gen_mfc0(ctx, t0, rt, sel); 8485 } 8486 } else { 8487 switch (sel) { 8488 /* GPR registers. */ 8489 case 0: 8490 gen_helper_1e0i(mftgpr, t0, rt); 8491 break; 8492 /* Auxiliary CPU registers */ 8493 case 1: 8494 switch (rt) { 8495 case 0: 8496 gen_helper_1e0i(mftlo, t0, 0); 8497 break; 8498 case 1: 8499 gen_helper_1e0i(mfthi, t0, 0); 8500 break; 8501 case 2: 8502 gen_helper_1e0i(mftacx, t0, 0); 8503 break; 8504 case 4: 8505 gen_helper_1e0i(mftlo, t0, 1); 8506 break; 8507 case 5: 8508 gen_helper_1e0i(mfthi, t0, 1); 8509 break; 8510 case 6: 8511 gen_helper_1e0i(mftacx, t0, 1); 8512 break; 8513 case 8: 8514 gen_helper_1e0i(mftlo, t0, 2); 8515 break; 8516 case 9: 8517 gen_helper_1e0i(mfthi, t0, 2); 8518 break; 8519 case 10: 8520 gen_helper_1e0i(mftacx, t0, 2); 8521 break; 8522 case 12: 8523 gen_helper_1e0i(mftlo, t0, 3); 8524 break; 8525 case 13: 8526 gen_helper_1e0i(mfthi, t0, 3); 8527 break; 8528 case 14: 8529 gen_helper_1e0i(mftacx, t0, 3); 8530 break; 8531 case 16: 8532 gen_helper_mftdsp(t0, cpu_env); 8533 break; 8534 default: 8535 goto die; 8536 } 8537 break; 8538 /* Floating point (COP1). */ 8539 case 2: 8540 /* XXX: For now we support only a single FPU context. */ 8541 if (h == 0) { 8542 TCGv_i32 fp0 = tcg_temp_new_i32(); 8543 8544 gen_load_fpr32(ctx, fp0, rt); 8545 tcg_gen_ext_i32_tl(t0, fp0); 8546 } else { 8547 TCGv_i32 fp0 = tcg_temp_new_i32(); 8548 8549 gen_load_fpr32h(ctx, fp0, rt); 8550 tcg_gen_ext_i32_tl(t0, fp0); 8551 } 8552 break; 8553 case 3: 8554 /* XXX: For now we support only a single FPU context. */ 8555 gen_helper_1e0i(cfc1, t0, rt); 8556 break; 8557 /* COP2: Not implemented. */ 8558 case 4: 8559 case 5: 8560 /* fall through */ 8561 default: 8562 goto die; 8563 } 8564 } 8565 trace_mips_translate_tr("mftr", rt, u, sel, h); 8566 gen_store_gpr(t0, rd); 8567 return; 8568 8569 die: 8570 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h); 8571 gen_reserved_instruction(ctx); 8572 } 8573 8574 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt, 8575 int u, int sel, int h) 8576 { 8577 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); 8578 TCGv t0 = tcg_temp_new(); 8579 8580 gen_load_gpr(t0, rt); 8581 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 && 8582 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) != 8583 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) { 8584 /* NOP */ 8585 ; 8586 } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) > 8587 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) { 8588 /* NOP */ 8589 ; 8590 } else if (u == 0) { 8591 switch (rd) { 8592 case 1: 8593 switch (sel) { 8594 case 1: 8595 gen_helper_mttc0_vpecontrol(cpu_env, t0); 8596 break; 8597 case 2: 8598 gen_helper_mttc0_vpeconf0(cpu_env, t0); 8599 break; 8600 default: 8601 goto die; 8602 break; 8603 } 8604 break; 8605 case 2: 8606 switch (sel) { 8607 case 1: 8608 gen_helper_mttc0_tcstatus(cpu_env, t0); 8609 break; 8610 case 2: 8611 gen_helper_mttc0_tcbind(cpu_env, t0); 8612 break; 8613 case 3: 8614 gen_helper_mttc0_tcrestart(cpu_env, t0); 8615 break; 8616 case 4: 8617 gen_helper_mttc0_tchalt(cpu_env, t0); 8618 break; 8619 case 5: 8620 gen_helper_mttc0_tccontext(cpu_env, t0); 8621 break; 8622 case 6: 8623 gen_helper_mttc0_tcschedule(cpu_env, t0); 8624 break; 8625 case 7: 8626 gen_helper_mttc0_tcschefback(cpu_env, t0); 8627 break; 8628 default: 8629 gen_mtc0(ctx, t0, rd, sel); 8630 break; 8631 } 8632 break; 8633 case 10: 8634 switch (sel) { 8635 case 0: 8636 gen_helper_mttc0_entryhi(cpu_env, t0); 8637 break; 8638 default: 8639 gen_mtc0(ctx, t0, rd, sel); 8640 break; 8641 } 8642 break; 8643 case 12: 8644 switch (sel) { 8645 case 0: 8646 gen_helper_mttc0_status(cpu_env, t0); 8647 break; 8648 default: 8649 gen_mtc0(ctx, t0, rd, sel); 8650 break; 8651 } 8652 break; 8653 case 13: 8654 switch (sel) { 8655 case 0: 8656 gen_helper_mttc0_cause(cpu_env, t0); 8657 break; 8658 default: 8659 goto die; 8660 break; 8661 } 8662 break; 8663 case 15: 8664 switch (sel) { 8665 case 1: 8666 gen_helper_mttc0_ebase(cpu_env, t0); 8667 break; 8668 default: 8669 goto die; 8670 break; 8671 } 8672 break; 8673 case 23: 8674 switch (sel) { 8675 case 0: 8676 gen_helper_mttc0_debug(cpu_env, t0); 8677 break; 8678 default: 8679 gen_mtc0(ctx, t0, rd, sel); 8680 break; 8681 } 8682 break; 8683 default: 8684 gen_mtc0(ctx, t0, rd, sel); 8685 } 8686 } else { 8687 switch (sel) { 8688 /* GPR registers. */ 8689 case 0: 8690 gen_helper_0e1i(mttgpr, t0, rd); 8691 break; 8692 /* Auxiliary CPU registers */ 8693 case 1: 8694 switch (rd) { 8695 case 0: 8696 gen_helper_0e1i(mttlo, t0, 0); 8697 break; 8698 case 1: 8699 gen_helper_0e1i(mtthi, t0, 0); 8700 break; 8701 case 2: 8702 gen_helper_0e1i(mttacx, t0, 0); 8703 break; 8704 case 4: 8705 gen_helper_0e1i(mttlo, t0, 1); 8706 break; 8707 case 5: 8708 gen_helper_0e1i(mtthi, t0, 1); 8709 break; 8710 case 6: 8711 gen_helper_0e1i(mttacx, t0, 1); 8712 break; 8713 case 8: 8714 gen_helper_0e1i(mttlo, t0, 2); 8715 break; 8716 case 9: 8717 gen_helper_0e1i(mtthi, t0, 2); 8718 break; 8719 case 10: 8720 gen_helper_0e1i(mttacx, t0, 2); 8721 break; 8722 case 12: 8723 gen_helper_0e1i(mttlo, t0, 3); 8724 break; 8725 case 13: 8726 gen_helper_0e1i(mtthi, t0, 3); 8727 break; 8728 case 14: 8729 gen_helper_0e1i(mttacx, t0, 3); 8730 break; 8731 case 16: 8732 gen_helper_mttdsp(cpu_env, t0); 8733 break; 8734 default: 8735 goto die; 8736 } 8737 break; 8738 /* Floating point (COP1). */ 8739 case 2: 8740 /* XXX: For now we support only a single FPU context. */ 8741 if (h == 0) { 8742 TCGv_i32 fp0 = tcg_temp_new_i32(); 8743 8744 tcg_gen_trunc_tl_i32(fp0, t0); 8745 gen_store_fpr32(ctx, fp0, rd); 8746 } else { 8747 TCGv_i32 fp0 = tcg_temp_new_i32(); 8748 8749 tcg_gen_trunc_tl_i32(fp0, t0); 8750 gen_store_fpr32h(ctx, fp0, rd); 8751 } 8752 break; 8753 case 3: 8754 /* XXX: For now we support only a single FPU context. */ 8755 gen_helper_0e2i(ctc1, t0, tcg_constant_i32(rd), rt); 8756 /* Stop translation as we may have changed hflags */ 8757 ctx->base.is_jmp = DISAS_STOP; 8758 break; 8759 /* COP2: Not implemented. */ 8760 case 4: 8761 case 5: 8762 /* fall through */ 8763 default: 8764 goto die; 8765 } 8766 } 8767 trace_mips_translate_tr("mttr", rd, u, sel, h); 8768 return; 8769 8770 die: 8771 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h); 8772 gen_reserved_instruction(ctx); 8773 } 8774 8775 static void gen_cp0(CPUMIPSState *env, DisasContext *ctx, uint32_t opc, 8776 int rt, int rd) 8777 { 8778 const char *opn = "ldst"; 8779 8780 check_cp0_enabled(ctx); 8781 switch (opc) { 8782 case OPC_MFC0: 8783 if (rt == 0) { 8784 /* Treat as NOP. */ 8785 return; 8786 } 8787 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7); 8788 opn = "mfc0"; 8789 break; 8790 case OPC_MTC0: 8791 { 8792 TCGv t0 = tcg_temp_new(); 8793 8794 gen_load_gpr(t0, rt); 8795 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7); 8796 } 8797 opn = "mtc0"; 8798 break; 8799 #if defined(TARGET_MIPS64) 8800 case OPC_DMFC0: 8801 check_insn(ctx, ISA_MIPS3); 8802 if (rt == 0) { 8803 /* Treat as NOP. */ 8804 return; 8805 } 8806 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7); 8807 opn = "dmfc0"; 8808 break; 8809 case OPC_DMTC0: 8810 check_insn(ctx, ISA_MIPS3); 8811 { 8812 TCGv t0 = tcg_temp_new(); 8813 8814 gen_load_gpr(t0, rt); 8815 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7); 8816 } 8817 opn = "dmtc0"; 8818 break; 8819 #endif 8820 case OPC_MFHC0: 8821 check_mvh(ctx); 8822 if (rt == 0) { 8823 /* Treat as NOP. */ 8824 return; 8825 } 8826 gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7); 8827 opn = "mfhc0"; 8828 break; 8829 case OPC_MTHC0: 8830 check_mvh(ctx); 8831 { 8832 TCGv t0 = tcg_temp_new(); 8833 gen_load_gpr(t0, rt); 8834 gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7); 8835 } 8836 opn = "mthc0"; 8837 break; 8838 case OPC_MFTR: 8839 check_cp0_enabled(ctx); 8840 if (rd == 0) { 8841 /* Treat as NOP. */ 8842 return; 8843 } 8844 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1, 8845 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1); 8846 opn = "mftr"; 8847 break; 8848 case OPC_MTTR: 8849 check_cp0_enabled(ctx); 8850 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1, 8851 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1); 8852 opn = "mttr"; 8853 break; 8854 case OPC_TLBWI: 8855 opn = "tlbwi"; 8856 if (!env->tlb->helper_tlbwi) { 8857 goto die; 8858 } 8859 gen_helper_tlbwi(cpu_env); 8860 break; 8861 case OPC_TLBINV: 8862 opn = "tlbinv"; 8863 if (ctx->ie >= 2) { 8864 if (!env->tlb->helper_tlbinv) { 8865 goto die; 8866 } 8867 gen_helper_tlbinv(cpu_env); 8868 } /* treat as nop if TLBINV not supported */ 8869 break; 8870 case OPC_TLBINVF: 8871 opn = "tlbinvf"; 8872 if (ctx->ie >= 2) { 8873 if (!env->tlb->helper_tlbinvf) { 8874 goto die; 8875 } 8876 gen_helper_tlbinvf(cpu_env); 8877 } /* treat as nop if TLBINV not supported */ 8878 break; 8879 case OPC_TLBWR: 8880 opn = "tlbwr"; 8881 if (!env->tlb->helper_tlbwr) { 8882 goto die; 8883 } 8884 gen_helper_tlbwr(cpu_env); 8885 break; 8886 case OPC_TLBP: 8887 opn = "tlbp"; 8888 if (!env->tlb->helper_tlbp) { 8889 goto die; 8890 } 8891 gen_helper_tlbp(cpu_env); 8892 break; 8893 case OPC_TLBR: 8894 opn = "tlbr"; 8895 if (!env->tlb->helper_tlbr) { 8896 goto die; 8897 } 8898 gen_helper_tlbr(cpu_env); 8899 break; 8900 case OPC_ERET: /* OPC_ERETNC */ 8901 if ((ctx->insn_flags & ISA_MIPS_R6) && 8902 (ctx->hflags & MIPS_HFLAG_BMASK)) { 8903 goto die; 8904 } else { 8905 int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6; 8906 if (ctx->opcode & (1 << bit_shift)) { 8907 /* OPC_ERETNC */ 8908 opn = "eretnc"; 8909 check_insn(ctx, ISA_MIPS_R5); 8910 gen_helper_eretnc(cpu_env); 8911 } else { 8912 /* OPC_ERET */ 8913 opn = "eret"; 8914 check_insn(ctx, ISA_MIPS2); 8915 gen_helper_eret(cpu_env); 8916 } 8917 ctx->base.is_jmp = DISAS_EXIT; 8918 } 8919 break; 8920 case OPC_DERET: 8921 opn = "deret"; 8922 check_insn(ctx, ISA_MIPS_R1); 8923 if ((ctx->insn_flags & ISA_MIPS_R6) && 8924 (ctx->hflags & MIPS_HFLAG_BMASK)) { 8925 goto die; 8926 } 8927 if (!(ctx->hflags & MIPS_HFLAG_DM)) { 8928 MIPS_INVAL(opn); 8929 gen_reserved_instruction(ctx); 8930 } else { 8931 gen_helper_deret(cpu_env); 8932 ctx->base.is_jmp = DISAS_EXIT; 8933 } 8934 break; 8935 case OPC_WAIT: 8936 opn = "wait"; 8937 check_insn(ctx, ISA_MIPS3 | ISA_MIPS_R1); 8938 if ((ctx->insn_flags & ISA_MIPS_R6) && 8939 (ctx->hflags & MIPS_HFLAG_BMASK)) { 8940 goto die; 8941 } 8942 /* If we get an exception, we want to restart at next instruction */ 8943 ctx->base.pc_next += 4; 8944 save_cpu_state(ctx, 1); 8945 ctx->base.pc_next -= 4; 8946 gen_helper_wait(cpu_env); 8947 ctx->base.is_jmp = DISAS_NORETURN; 8948 break; 8949 default: 8950 die: 8951 MIPS_INVAL(opn); 8952 gen_reserved_instruction(ctx); 8953 return; 8954 } 8955 (void)opn; /* avoid a compiler warning */ 8956 } 8957 #endif /* !CONFIG_USER_ONLY */ 8958 8959 /* CP1 Branches (before delay slot) */ 8960 static void gen_compute_branch1(DisasContext *ctx, uint32_t op, 8961 int32_t cc, int32_t offset) 8962 { 8963 target_ulong btarget; 8964 TCGv_i32 t0 = tcg_temp_new_i32(); 8965 8966 if ((ctx->insn_flags & ISA_MIPS_R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) { 8967 gen_reserved_instruction(ctx); 8968 return; 8969 } 8970 8971 if (cc != 0) { 8972 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1); 8973 } 8974 8975 btarget = ctx->base.pc_next + 4 + offset; 8976 8977 switch (op) { 8978 case OPC_BC1F: 8979 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 8980 tcg_gen_not_i32(t0, t0); 8981 tcg_gen_andi_i32(t0, t0, 1); 8982 tcg_gen_extu_i32_tl(bcond, t0); 8983 goto not_likely; 8984 case OPC_BC1FL: 8985 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 8986 tcg_gen_not_i32(t0, t0); 8987 tcg_gen_andi_i32(t0, t0, 1); 8988 tcg_gen_extu_i32_tl(bcond, t0); 8989 goto likely; 8990 case OPC_BC1T: 8991 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 8992 tcg_gen_andi_i32(t0, t0, 1); 8993 tcg_gen_extu_i32_tl(bcond, t0); 8994 goto not_likely; 8995 case OPC_BC1TL: 8996 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 8997 tcg_gen_andi_i32(t0, t0, 1); 8998 tcg_gen_extu_i32_tl(bcond, t0); 8999 likely: 9000 ctx->hflags |= MIPS_HFLAG_BL; 9001 break; 9002 case OPC_BC1FANY2: 9003 { 9004 TCGv_i32 t1 = tcg_temp_new_i32(); 9005 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 9006 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1)); 9007 tcg_gen_nand_i32(t0, t0, t1); 9008 tcg_gen_andi_i32(t0, t0, 1); 9009 tcg_gen_extu_i32_tl(bcond, t0); 9010 } 9011 goto not_likely; 9012 case OPC_BC1TANY2: 9013 { 9014 TCGv_i32 t1 = tcg_temp_new_i32(); 9015 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 9016 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1)); 9017 tcg_gen_or_i32(t0, t0, t1); 9018 tcg_gen_andi_i32(t0, t0, 1); 9019 tcg_gen_extu_i32_tl(bcond, t0); 9020 } 9021 goto not_likely; 9022 case OPC_BC1FANY4: 9023 { 9024 TCGv_i32 t1 = tcg_temp_new_i32(); 9025 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 9026 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1)); 9027 tcg_gen_and_i32(t0, t0, t1); 9028 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2)); 9029 tcg_gen_and_i32(t0, t0, t1); 9030 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3)); 9031 tcg_gen_nand_i32(t0, t0, t1); 9032 tcg_gen_andi_i32(t0, t0, 1); 9033 tcg_gen_extu_i32_tl(bcond, t0); 9034 } 9035 goto not_likely; 9036 case OPC_BC1TANY4: 9037 { 9038 TCGv_i32 t1 = tcg_temp_new_i32(); 9039 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 9040 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1)); 9041 tcg_gen_or_i32(t0, t0, t1); 9042 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2)); 9043 tcg_gen_or_i32(t0, t0, t1); 9044 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3)); 9045 tcg_gen_or_i32(t0, t0, t1); 9046 tcg_gen_andi_i32(t0, t0, 1); 9047 tcg_gen_extu_i32_tl(bcond, t0); 9048 } 9049 not_likely: 9050 ctx->hflags |= MIPS_HFLAG_BC; 9051 break; 9052 default: 9053 MIPS_INVAL("cp1 cond branch"); 9054 gen_reserved_instruction(ctx); 9055 return; 9056 } 9057 ctx->btarget = btarget; 9058 ctx->hflags |= MIPS_HFLAG_BDS32; 9059 } 9060 9061 /* R6 CP1 Branches */ 9062 static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op, 9063 int32_t ft, int32_t offset, 9064 int delayslot_size) 9065 { 9066 target_ulong btarget; 9067 TCGv_i64 t0 = tcg_temp_new_i64(); 9068 9069 if (ctx->hflags & MIPS_HFLAG_BMASK) { 9070 #ifdef MIPS_DEBUG_DISAS 9071 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx 9072 "\n", ctx->base.pc_next); 9073 #endif 9074 gen_reserved_instruction(ctx); 9075 return; 9076 } 9077 9078 gen_load_fpr64(ctx, t0, ft); 9079 tcg_gen_andi_i64(t0, t0, 1); 9080 9081 btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 9082 9083 switch (op) { 9084 case OPC_BC1EQZ: 9085 tcg_gen_xori_i64(t0, t0, 1); 9086 ctx->hflags |= MIPS_HFLAG_BC; 9087 break; 9088 case OPC_BC1NEZ: 9089 /* t0 already set */ 9090 ctx->hflags |= MIPS_HFLAG_BC; 9091 break; 9092 default: 9093 MIPS_INVAL("cp1 cond branch"); 9094 gen_reserved_instruction(ctx); 9095 return; 9096 } 9097 9098 tcg_gen_trunc_i64_tl(bcond, t0); 9099 9100 ctx->btarget = btarget; 9101 9102 switch (delayslot_size) { 9103 case 2: 9104 ctx->hflags |= MIPS_HFLAG_BDS16; 9105 break; 9106 case 4: 9107 ctx->hflags |= MIPS_HFLAG_BDS32; 9108 break; 9109 } 9110 } 9111 9112 /* Coprocessor 1 (FPU) */ 9113 9114 #define FOP(func, fmt) (((fmt) << 21) | (func)) 9115 9116 enum fopcode { 9117 OPC_ADD_S = FOP(0, FMT_S), 9118 OPC_SUB_S = FOP(1, FMT_S), 9119 OPC_MUL_S = FOP(2, FMT_S), 9120 OPC_DIV_S = FOP(3, FMT_S), 9121 OPC_SQRT_S = FOP(4, FMT_S), 9122 OPC_ABS_S = FOP(5, FMT_S), 9123 OPC_MOV_S = FOP(6, FMT_S), 9124 OPC_NEG_S = FOP(7, FMT_S), 9125 OPC_ROUND_L_S = FOP(8, FMT_S), 9126 OPC_TRUNC_L_S = FOP(9, FMT_S), 9127 OPC_CEIL_L_S = FOP(10, FMT_S), 9128 OPC_FLOOR_L_S = FOP(11, FMT_S), 9129 OPC_ROUND_W_S = FOP(12, FMT_S), 9130 OPC_TRUNC_W_S = FOP(13, FMT_S), 9131 OPC_CEIL_W_S = FOP(14, FMT_S), 9132 OPC_FLOOR_W_S = FOP(15, FMT_S), 9133 OPC_SEL_S = FOP(16, FMT_S), 9134 OPC_MOVCF_S = FOP(17, FMT_S), 9135 OPC_MOVZ_S = FOP(18, FMT_S), 9136 OPC_MOVN_S = FOP(19, FMT_S), 9137 OPC_SELEQZ_S = FOP(20, FMT_S), 9138 OPC_RECIP_S = FOP(21, FMT_S), 9139 OPC_RSQRT_S = FOP(22, FMT_S), 9140 OPC_SELNEZ_S = FOP(23, FMT_S), 9141 OPC_MADDF_S = FOP(24, FMT_S), 9142 OPC_MSUBF_S = FOP(25, FMT_S), 9143 OPC_RINT_S = FOP(26, FMT_S), 9144 OPC_CLASS_S = FOP(27, FMT_S), 9145 OPC_MIN_S = FOP(28, FMT_S), 9146 OPC_RECIP2_S = FOP(28, FMT_S), 9147 OPC_MINA_S = FOP(29, FMT_S), 9148 OPC_RECIP1_S = FOP(29, FMT_S), 9149 OPC_MAX_S = FOP(30, FMT_S), 9150 OPC_RSQRT1_S = FOP(30, FMT_S), 9151 OPC_MAXA_S = FOP(31, FMT_S), 9152 OPC_RSQRT2_S = FOP(31, FMT_S), 9153 OPC_CVT_D_S = FOP(33, FMT_S), 9154 OPC_CVT_W_S = FOP(36, FMT_S), 9155 OPC_CVT_L_S = FOP(37, FMT_S), 9156 OPC_CVT_PS_S = FOP(38, FMT_S), 9157 OPC_CMP_F_S = FOP(48, FMT_S), 9158 OPC_CMP_UN_S = FOP(49, FMT_S), 9159 OPC_CMP_EQ_S = FOP(50, FMT_S), 9160 OPC_CMP_UEQ_S = FOP(51, FMT_S), 9161 OPC_CMP_OLT_S = FOP(52, FMT_S), 9162 OPC_CMP_ULT_S = FOP(53, FMT_S), 9163 OPC_CMP_OLE_S = FOP(54, FMT_S), 9164 OPC_CMP_ULE_S = FOP(55, FMT_S), 9165 OPC_CMP_SF_S = FOP(56, FMT_S), 9166 OPC_CMP_NGLE_S = FOP(57, FMT_S), 9167 OPC_CMP_SEQ_S = FOP(58, FMT_S), 9168 OPC_CMP_NGL_S = FOP(59, FMT_S), 9169 OPC_CMP_LT_S = FOP(60, FMT_S), 9170 OPC_CMP_NGE_S = FOP(61, FMT_S), 9171 OPC_CMP_LE_S = FOP(62, FMT_S), 9172 OPC_CMP_NGT_S = FOP(63, FMT_S), 9173 9174 OPC_ADD_D = FOP(0, FMT_D), 9175 OPC_SUB_D = FOP(1, FMT_D), 9176 OPC_MUL_D = FOP(2, FMT_D), 9177 OPC_DIV_D = FOP(3, FMT_D), 9178 OPC_SQRT_D = FOP(4, FMT_D), 9179 OPC_ABS_D = FOP(5, FMT_D), 9180 OPC_MOV_D = FOP(6, FMT_D), 9181 OPC_NEG_D = FOP(7, FMT_D), 9182 OPC_ROUND_L_D = FOP(8, FMT_D), 9183 OPC_TRUNC_L_D = FOP(9, FMT_D), 9184 OPC_CEIL_L_D = FOP(10, FMT_D), 9185 OPC_FLOOR_L_D = FOP(11, FMT_D), 9186 OPC_ROUND_W_D = FOP(12, FMT_D), 9187 OPC_TRUNC_W_D = FOP(13, FMT_D), 9188 OPC_CEIL_W_D = FOP(14, FMT_D), 9189 OPC_FLOOR_W_D = FOP(15, FMT_D), 9190 OPC_SEL_D = FOP(16, FMT_D), 9191 OPC_MOVCF_D = FOP(17, FMT_D), 9192 OPC_MOVZ_D = FOP(18, FMT_D), 9193 OPC_MOVN_D = FOP(19, FMT_D), 9194 OPC_SELEQZ_D = FOP(20, FMT_D), 9195 OPC_RECIP_D = FOP(21, FMT_D), 9196 OPC_RSQRT_D = FOP(22, FMT_D), 9197 OPC_SELNEZ_D = FOP(23, FMT_D), 9198 OPC_MADDF_D = FOP(24, FMT_D), 9199 OPC_MSUBF_D = FOP(25, FMT_D), 9200 OPC_RINT_D = FOP(26, FMT_D), 9201 OPC_CLASS_D = FOP(27, FMT_D), 9202 OPC_MIN_D = FOP(28, FMT_D), 9203 OPC_RECIP2_D = FOP(28, FMT_D), 9204 OPC_MINA_D = FOP(29, FMT_D), 9205 OPC_RECIP1_D = FOP(29, FMT_D), 9206 OPC_MAX_D = FOP(30, FMT_D), 9207 OPC_RSQRT1_D = FOP(30, FMT_D), 9208 OPC_MAXA_D = FOP(31, FMT_D), 9209 OPC_RSQRT2_D = FOP(31, FMT_D), 9210 OPC_CVT_S_D = FOP(32, FMT_D), 9211 OPC_CVT_W_D = FOP(36, FMT_D), 9212 OPC_CVT_L_D = FOP(37, FMT_D), 9213 OPC_CMP_F_D = FOP(48, FMT_D), 9214 OPC_CMP_UN_D = FOP(49, FMT_D), 9215 OPC_CMP_EQ_D = FOP(50, FMT_D), 9216 OPC_CMP_UEQ_D = FOP(51, FMT_D), 9217 OPC_CMP_OLT_D = FOP(52, FMT_D), 9218 OPC_CMP_ULT_D = FOP(53, FMT_D), 9219 OPC_CMP_OLE_D = FOP(54, FMT_D), 9220 OPC_CMP_ULE_D = FOP(55, FMT_D), 9221 OPC_CMP_SF_D = FOP(56, FMT_D), 9222 OPC_CMP_NGLE_D = FOP(57, FMT_D), 9223 OPC_CMP_SEQ_D = FOP(58, FMT_D), 9224 OPC_CMP_NGL_D = FOP(59, FMT_D), 9225 OPC_CMP_LT_D = FOP(60, FMT_D), 9226 OPC_CMP_NGE_D = FOP(61, FMT_D), 9227 OPC_CMP_LE_D = FOP(62, FMT_D), 9228 OPC_CMP_NGT_D = FOP(63, FMT_D), 9229 9230 OPC_CVT_S_W = FOP(32, FMT_W), 9231 OPC_CVT_D_W = FOP(33, FMT_W), 9232 OPC_CVT_S_L = FOP(32, FMT_L), 9233 OPC_CVT_D_L = FOP(33, FMT_L), 9234 OPC_CVT_PS_PW = FOP(38, FMT_W), 9235 9236 OPC_ADD_PS = FOP(0, FMT_PS), 9237 OPC_SUB_PS = FOP(1, FMT_PS), 9238 OPC_MUL_PS = FOP(2, FMT_PS), 9239 OPC_DIV_PS = FOP(3, FMT_PS), 9240 OPC_ABS_PS = FOP(5, FMT_PS), 9241 OPC_MOV_PS = FOP(6, FMT_PS), 9242 OPC_NEG_PS = FOP(7, FMT_PS), 9243 OPC_MOVCF_PS = FOP(17, FMT_PS), 9244 OPC_MOVZ_PS = FOP(18, FMT_PS), 9245 OPC_MOVN_PS = FOP(19, FMT_PS), 9246 OPC_ADDR_PS = FOP(24, FMT_PS), 9247 OPC_MULR_PS = FOP(26, FMT_PS), 9248 OPC_RECIP2_PS = FOP(28, FMT_PS), 9249 OPC_RECIP1_PS = FOP(29, FMT_PS), 9250 OPC_RSQRT1_PS = FOP(30, FMT_PS), 9251 OPC_RSQRT2_PS = FOP(31, FMT_PS), 9252 9253 OPC_CVT_S_PU = FOP(32, FMT_PS), 9254 OPC_CVT_PW_PS = FOP(36, FMT_PS), 9255 OPC_CVT_S_PL = FOP(40, FMT_PS), 9256 OPC_PLL_PS = FOP(44, FMT_PS), 9257 OPC_PLU_PS = FOP(45, FMT_PS), 9258 OPC_PUL_PS = FOP(46, FMT_PS), 9259 OPC_PUU_PS = FOP(47, FMT_PS), 9260 OPC_CMP_F_PS = FOP(48, FMT_PS), 9261 OPC_CMP_UN_PS = FOP(49, FMT_PS), 9262 OPC_CMP_EQ_PS = FOP(50, FMT_PS), 9263 OPC_CMP_UEQ_PS = FOP(51, FMT_PS), 9264 OPC_CMP_OLT_PS = FOP(52, FMT_PS), 9265 OPC_CMP_ULT_PS = FOP(53, FMT_PS), 9266 OPC_CMP_OLE_PS = FOP(54, FMT_PS), 9267 OPC_CMP_ULE_PS = FOP(55, FMT_PS), 9268 OPC_CMP_SF_PS = FOP(56, FMT_PS), 9269 OPC_CMP_NGLE_PS = FOP(57, FMT_PS), 9270 OPC_CMP_SEQ_PS = FOP(58, FMT_PS), 9271 OPC_CMP_NGL_PS = FOP(59, FMT_PS), 9272 OPC_CMP_LT_PS = FOP(60, FMT_PS), 9273 OPC_CMP_NGE_PS = FOP(61, FMT_PS), 9274 OPC_CMP_LE_PS = FOP(62, FMT_PS), 9275 OPC_CMP_NGT_PS = FOP(63, FMT_PS), 9276 }; 9277 9278 enum r6_f_cmp_op { 9279 R6_OPC_CMP_AF_S = FOP(0, FMT_W), 9280 R6_OPC_CMP_UN_S = FOP(1, FMT_W), 9281 R6_OPC_CMP_EQ_S = FOP(2, FMT_W), 9282 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W), 9283 R6_OPC_CMP_LT_S = FOP(4, FMT_W), 9284 R6_OPC_CMP_ULT_S = FOP(5, FMT_W), 9285 R6_OPC_CMP_LE_S = FOP(6, FMT_W), 9286 R6_OPC_CMP_ULE_S = FOP(7, FMT_W), 9287 R6_OPC_CMP_SAF_S = FOP(8, FMT_W), 9288 R6_OPC_CMP_SUN_S = FOP(9, FMT_W), 9289 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W), 9290 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W), 9291 R6_OPC_CMP_SLT_S = FOP(12, FMT_W), 9292 R6_OPC_CMP_SULT_S = FOP(13, FMT_W), 9293 R6_OPC_CMP_SLE_S = FOP(14, FMT_W), 9294 R6_OPC_CMP_SULE_S = FOP(15, FMT_W), 9295 R6_OPC_CMP_OR_S = FOP(17, FMT_W), 9296 R6_OPC_CMP_UNE_S = FOP(18, FMT_W), 9297 R6_OPC_CMP_NE_S = FOP(19, FMT_W), 9298 R6_OPC_CMP_SOR_S = FOP(25, FMT_W), 9299 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W), 9300 R6_OPC_CMP_SNE_S = FOP(27, FMT_W), 9301 9302 R6_OPC_CMP_AF_D = FOP(0, FMT_L), 9303 R6_OPC_CMP_UN_D = FOP(1, FMT_L), 9304 R6_OPC_CMP_EQ_D = FOP(2, FMT_L), 9305 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L), 9306 R6_OPC_CMP_LT_D = FOP(4, FMT_L), 9307 R6_OPC_CMP_ULT_D = FOP(5, FMT_L), 9308 R6_OPC_CMP_LE_D = FOP(6, FMT_L), 9309 R6_OPC_CMP_ULE_D = FOP(7, FMT_L), 9310 R6_OPC_CMP_SAF_D = FOP(8, FMT_L), 9311 R6_OPC_CMP_SUN_D = FOP(9, FMT_L), 9312 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L), 9313 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L), 9314 R6_OPC_CMP_SLT_D = FOP(12, FMT_L), 9315 R6_OPC_CMP_SULT_D = FOP(13, FMT_L), 9316 R6_OPC_CMP_SLE_D = FOP(14, FMT_L), 9317 R6_OPC_CMP_SULE_D = FOP(15, FMT_L), 9318 R6_OPC_CMP_OR_D = FOP(17, FMT_L), 9319 R6_OPC_CMP_UNE_D = FOP(18, FMT_L), 9320 R6_OPC_CMP_NE_D = FOP(19, FMT_L), 9321 R6_OPC_CMP_SOR_D = FOP(25, FMT_L), 9322 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L), 9323 R6_OPC_CMP_SNE_D = FOP(27, FMT_L), 9324 }; 9325 9326 static void gen_cp1(DisasContext *ctx, uint32_t opc, int rt, int fs) 9327 { 9328 TCGv t0 = tcg_temp_new(); 9329 9330 switch (opc) { 9331 case OPC_MFC1: 9332 { 9333 TCGv_i32 fp0 = tcg_temp_new_i32(); 9334 9335 gen_load_fpr32(ctx, fp0, fs); 9336 tcg_gen_ext_i32_tl(t0, fp0); 9337 } 9338 gen_store_gpr(t0, rt); 9339 break; 9340 case OPC_MTC1: 9341 gen_load_gpr(t0, rt); 9342 { 9343 TCGv_i32 fp0 = tcg_temp_new_i32(); 9344 9345 tcg_gen_trunc_tl_i32(fp0, t0); 9346 gen_store_fpr32(ctx, fp0, fs); 9347 } 9348 break; 9349 case OPC_CFC1: 9350 gen_helper_1e0i(cfc1, t0, fs); 9351 gen_store_gpr(t0, rt); 9352 break; 9353 case OPC_CTC1: 9354 gen_load_gpr(t0, rt); 9355 save_cpu_state(ctx, 0); 9356 gen_helper_0e2i(ctc1, t0, tcg_constant_i32(fs), rt); 9357 /* Stop translation as we may have changed hflags */ 9358 ctx->base.is_jmp = DISAS_STOP; 9359 break; 9360 #if defined(TARGET_MIPS64) 9361 case OPC_DMFC1: 9362 gen_load_fpr64(ctx, t0, fs); 9363 gen_store_gpr(t0, rt); 9364 break; 9365 case OPC_DMTC1: 9366 gen_load_gpr(t0, rt); 9367 gen_store_fpr64(ctx, t0, fs); 9368 break; 9369 #endif 9370 case OPC_MFHC1: 9371 { 9372 TCGv_i32 fp0 = tcg_temp_new_i32(); 9373 9374 gen_load_fpr32h(ctx, fp0, fs); 9375 tcg_gen_ext_i32_tl(t0, fp0); 9376 } 9377 gen_store_gpr(t0, rt); 9378 break; 9379 case OPC_MTHC1: 9380 gen_load_gpr(t0, rt); 9381 { 9382 TCGv_i32 fp0 = tcg_temp_new_i32(); 9383 9384 tcg_gen_trunc_tl_i32(fp0, t0); 9385 gen_store_fpr32h(ctx, fp0, fs); 9386 } 9387 break; 9388 default: 9389 MIPS_INVAL("cp1 move"); 9390 gen_reserved_instruction(ctx); 9391 return; 9392 } 9393 } 9394 9395 static void gen_movci(DisasContext *ctx, int rd, int rs, int cc, int tf) 9396 { 9397 TCGLabel *l1; 9398 TCGCond cond; 9399 TCGv_i32 t0; 9400 9401 if (rd == 0) { 9402 /* Treat as NOP. */ 9403 return; 9404 } 9405 9406 if (tf) { 9407 cond = TCG_COND_EQ; 9408 } else { 9409 cond = TCG_COND_NE; 9410 } 9411 9412 l1 = gen_new_label(); 9413 t0 = tcg_temp_new_i32(); 9414 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc)); 9415 tcg_gen_brcondi_i32(cond, t0, 0, l1); 9416 gen_load_gpr(cpu_gpr[rd], rs); 9417 gen_set_label(l1); 9418 } 9419 9420 static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc, 9421 int tf) 9422 { 9423 int cond; 9424 TCGv_i32 t0 = tcg_temp_new_i32(); 9425 TCGLabel *l1 = gen_new_label(); 9426 9427 if (tf) { 9428 cond = TCG_COND_EQ; 9429 } else { 9430 cond = TCG_COND_NE; 9431 } 9432 9433 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc)); 9434 tcg_gen_brcondi_i32(cond, t0, 0, l1); 9435 gen_load_fpr32(ctx, t0, fs); 9436 gen_store_fpr32(ctx, t0, fd); 9437 gen_set_label(l1); 9438 } 9439 9440 static inline void gen_movcf_d(DisasContext *ctx, int fs, int fd, int cc, 9441 int tf) 9442 { 9443 int cond; 9444 TCGv_i32 t0 = tcg_temp_new_i32(); 9445 TCGv_i64 fp0; 9446 TCGLabel *l1 = gen_new_label(); 9447 9448 if (tf) { 9449 cond = TCG_COND_EQ; 9450 } else { 9451 cond = TCG_COND_NE; 9452 } 9453 9454 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc)); 9455 tcg_gen_brcondi_i32(cond, t0, 0, l1); 9456 fp0 = tcg_temp_new_i64(); 9457 gen_load_fpr64(ctx, fp0, fs); 9458 gen_store_fpr64(ctx, fp0, fd); 9459 gen_set_label(l1); 9460 } 9461 9462 static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd, 9463 int cc, int tf) 9464 { 9465 int cond; 9466 TCGv_i32 t0 = tcg_temp_new_i32(); 9467 TCGLabel *l1 = gen_new_label(); 9468 TCGLabel *l2 = gen_new_label(); 9469 9470 if (tf) { 9471 cond = TCG_COND_EQ; 9472 } else { 9473 cond = TCG_COND_NE; 9474 } 9475 9476 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc)); 9477 tcg_gen_brcondi_i32(cond, t0, 0, l1); 9478 gen_load_fpr32(ctx, t0, fs); 9479 gen_store_fpr32(ctx, t0, fd); 9480 gen_set_label(l1); 9481 9482 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc + 1)); 9483 tcg_gen_brcondi_i32(cond, t0, 0, l2); 9484 gen_load_fpr32h(ctx, t0, fs); 9485 gen_store_fpr32h(ctx, t0, fd); 9486 gen_set_label(l2); 9487 } 9488 9489 static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft, 9490 int fs) 9491 { 9492 TCGv_i32 t1 = tcg_constant_i32(0); 9493 TCGv_i32 fp0 = tcg_temp_new_i32(); 9494 TCGv_i32 fp1 = tcg_temp_new_i32(); 9495 TCGv_i32 fp2 = tcg_temp_new_i32(); 9496 gen_load_fpr32(ctx, fp0, fd); 9497 gen_load_fpr32(ctx, fp1, ft); 9498 gen_load_fpr32(ctx, fp2, fs); 9499 9500 switch (op1) { 9501 case OPC_SEL_S: 9502 tcg_gen_andi_i32(fp0, fp0, 1); 9503 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2); 9504 break; 9505 case OPC_SELEQZ_S: 9506 tcg_gen_andi_i32(fp1, fp1, 1); 9507 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1); 9508 break; 9509 case OPC_SELNEZ_S: 9510 tcg_gen_andi_i32(fp1, fp1, 1); 9511 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1); 9512 break; 9513 default: 9514 MIPS_INVAL("gen_sel_s"); 9515 gen_reserved_instruction(ctx); 9516 break; 9517 } 9518 9519 gen_store_fpr32(ctx, fp0, fd); 9520 } 9521 9522 static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft, 9523 int fs) 9524 { 9525 TCGv_i64 t1 = tcg_constant_i64(0); 9526 TCGv_i64 fp0 = tcg_temp_new_i64(); 9527 TCGv_i64 fp1 = tcg_temp_new_i64(); 9528 TCGv_i64 fp2 = tcg_temp_new_i64(); 9529 gen_load_fpr64(ctx, fp0, fd); 9530 gen_load_fpr64(ctx, fp1, ft); 9531 gen_load_fpr64(ctx, fp2, fs); 9532 9533 switch (op1) { 9534 case OPC_SEL_D: 9535 tcg_gen_andi_i64(fp0, fp0, 1); 9536 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2); 9537 break; 9538 case OPC_SELEQZ_D: 9539 tcg_gen_andi_i64(fp1, fp1, 1); 9540 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1); 9541 break; 9542 case OPC_SELNEZ_D: 9543 tcg_gen_andi_i64(fp1, fp1, 1); 9544 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1); 9545 break; 9546 default: 9547 MIPS_INVAL("gen_sel_d"); 9548 gen_reserved_instruction(ctx); 9549 break; 9550 } 9551 9552 gen_store_fpr64(ctx, fp0, fd); 9553 } 9554 9555 static void gen_farith(DisasContext *ctx, enum fopcode op1, 9556 int ft, int fs, int fd, int cc) 9557 { 9558 uint32_t func = ctx->opcode & 0x3f; 9559 switch (op1) { 9560 case OPC_ADD_S: 9561 { 9562 TCGv_i32 fp0 = tcg_temp_new_i32(); 9563 TCGv_i32 fp1 = tcg_temp_new_i32(); 9564 9565 gen_load_fpr32(ctx, fp0, fs); 9566 gen_load_fpr32(ctx, fp1, ft); 9567 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1); 9568 gen_store_fpr32(ctx, fp0, fd); 9569 } 9570 break; 9571 case OPC_SUB_S: 9572 { 9573 TCGv_i32 fp0 = tcg_temp_new_i32(); 9574 TCGv_i32 fp1 = tcg_temp_new_i32(); 9575 9576 gen_load_fpr32(ctx, fp0, fs); 9577 gen_load_fpr32(ctx, fp1, ft); 9578 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1); 9579 gen_store_fpr32(ctx, fp0, fd); 9580 } 9581 break; 9582 case OPC_MUL_S: 9583 { 9584 TCGv_i32 fp0 = tcg_temp_new_i32(); 9585 TCGv_i32 fp1 = tcg_temp_new_i32(); 9586 9587 gen_load_fpr32(ctx, fp0, fs); 9588 gen_load_fpr32(ctx, fp1, ft); 9589 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1); 9590 gen_store_fpr32(ctx, fp0, fd); 9591 } 9592 break; 9593 case OPC_DIV_S: 9594 { 9595 TCGv_i32 fp0 = tcg_temp_new_i32(); 9596 TCGv_i32 fp1 = tcg_temp_new_i32(); 9597 9598 gen_load_fpr32(ctx, fp0, fs); 9599 gen_load_fpr32(ctx, fp1, ft); 9600 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1); 9601 gen_store_fpr32(ctx, fp0, fd); 9602 } 9603 break; 9604 case OPC_SQRT_S: 9605 { 9606 TCGv_i32 fp0 = tcg_temp_new_i32(); 9607 9608 gen_load_fpr32(ctx, fp0, fs); 9609 gen_helper_float_sqrt_s(fp0, cpu_env, fp0); 9610 gen_store_fpr32(ctx, fp0, fd); 9611 } 9612 break; 9613 case OPC_ABS_S: 9614 { 9615 TCGv_i32 fp0 = tcg_temp_new_i32(); 9616 9617 gen_load_fpr32(ctx, fp0, fs); 9618 if (ctx->abs2008) { 9619 tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL); 9620 } else { 9621 gen_helper_float_abs_s(fp0, fp0); 9622 } 9623 gen_store_fpr32(ctx, fp0, fd); 9624 } 9625 break; 9626 case OPC_MOV_S: 9627 { 9628 TCGv_i32 fp0 = tcg_temp_new_i32(); 9629 9630 gen_load_fpr32(ctx, fp0, fs); 9631 gen_store_fpr32(ctx, fp0, fd); 9632 } 9633 break; 9634 case OPC_NEG_S: 9635 { 9636 TCGv_i32 fp0 = tcg_temp_new_i32(); 9637 9638 gen_load_fpr32(ctx, fp0, fs); 9639 if (ctx->abs2008) { 9640 tcg_gen_xori_i32(fp0, fp0, 1UL << 31); 9641 } else { 9642 gen_helper_float_chs_s(fp0, fp0); 9643 } 9644 gen_store_fpr32(ctx, fp0, fd); 9645 } 9646 break; 9647 case OPC_ROUND_L_S: 9648 check_cp1_64bitmode(ctx); 9649 { 9650 TCGv_i32 fp32 = tcg_temp_new_i32(); 9651 TCGv_i64 fp64 = tcg_temp_new_i64(); 9652 9653 gen_load_fpr32(ctx, fp32, fs); 9654 if (ctx->nan2008) { 9655 gen_helper_float_round_2008_l_s(fp64, cpu_env, fp32); 9656 } else { 9657 gen_helper_float_round_l_s(fp64, cpu_env, fp32); 9658 } 9659 gen_store_fpr64(ctx, fp64, fd); 9660 } 9661 break; 9662 case OPC_TRUNC_L_S: 9663 check_cp1_64bitmode(ctx); 9664 { 9665 TCGv_i32 fp32 = tcg_temp_new_i32(); 9666 TCGv_i64 fp64 = tcg_temp_new_i64(); 9667 9668 gen_load_fpr32(ctx, fp32, fs); 9669 if (ctx->nan2008) { 9670 gen_helper_float_trunc_2008_l_s(fp64, cpu_env, fp32); 9671 } else { 9672 gen_helper_float_trunc_l_s(fp64, cpu_env, fp32); 9673 } 9674 gen_store_fpr64(ctx, fp64, fd); 9675 } 9676 break; 9677 case OPC_CEIL_L_S: 9678 check_cp1_64bitmode(ctx); 9679 { 9680 TCGv_i32 fp32 = tcg_temp_new_i32(); 9681 TCGv_i64 fp64 = tcg_temp_new_i64(); 9682 9683 gen_load_fpr32(ctx, fp32, fs); 9684 if (ctx->nan2008) { 9685 gen_helper_float_ceil_2008_l_s(fp64, cpu_env, fp32); 9686 } else { 9687 gen_helper_float_ceil_l_s(fp64, cpu_env, fp32); 9688 } 9689 gen_store_fpr64(ctx, fp64, fd); 9690 } 9691 break; 9692 case OPC_FLOOR_L_S: 9693 check_cp1_64bitmode(ctx); 9694 { 9695 TCGv_i32 fp32 = tcg_temp_new_i32(); 9696 TCGv_i64 fp64 = tcg_temp_new_i64(); 9697 9698 gen_load_fpr32(ctx, fp32, fs); 9699 if (ctx->nan2008) { 9700 gen_helper_float_floor_2008_l_s(fp64, cpu_env, fp32); 9701 } else { 9702 gen_helper_float_floor_l_s(fp64, cpu_env, fp32); 9703 } 9704 gen_store_fpr64(ctx, fp64, fd); 9705 } 9706 break; 9707 case OPC_ROUND_W_S: 9708 { 9709 TCGv_i32 fp0 = tcg_temp_new_i32(); 9710 9711 gen_load_fpr32(ctx, fp0, fs); 9712 if (ctx->nan2008) { 9713 gen_helper_float_round_2008_w_s(fp0, cpu_env, fp0); 9714 } else { 9715 gen_helper_float_round_w_s(fp0, cpu_env, fp0); 9716 } 9717 gen_store_fpr32(ctx, fp0, fd); 9718 } 9719 break; 9720 case OPC_TRUNC_W_S: 9721 { 9722 TCGv_i32 fp0 = tcg_temp_new_i32(); 9723 9724 gen_load_fpr32(ctx, fp0, fs); 9725 if (ctx->nan2008) { 9726 gen_helper_float_trunc_2008_w_s(fp0, cpu_env, fp0); 9727 } else { 9728 gen_helper_float_trunc_w_s(fp0, cpu_env, fp0); 9729 } 9730 gen_store_fpr32(ctx, fp0, fd); 9731 } 9732 break; 9733 case OPC_CEIL_W_S: 9734 { 9735 TCGv_i32 fp0 = tcg_temp_new_i32(); 9736 9737 gen_load_fpr32(ctx, fp0, fs); 9738 if (ctx->nan2008) { 9739 gen_helper_float_ceil_2008_w_s(fp0, cpu_env, fp0); 9740 } else { 9741 gen_helper_float_ceil_w_s(fp0, cpu_env, fp0); 9742 } 9743 gen_store_fpr32(ctx, fp0, fd); 9744 } 9745 break; 9746 case OPC_FLOOR_W_S: 9747 { 9748 TCGv_i32 fp0 = tcg_temp_new_i32(); 9749 9750 gen_load_fpr32(ctx, fp0, fs); 9751 if (ctx->nan2008) { 9752 gen_helper_float_floor_2008_w_s(fp0, cpu_env, fp0); 9753 } else { 9754 gen_helper_float_floor_w_s(fp0, cpu_env, fp0); 9755 } 9756 gen_store_fpr32(ctx, fp0, fd); 9757 } 9758 break; 9759 case OPC_SEL_S: 9760 check_insn(ctx, ISA_MIPS_R6); 9761 gen_sel_s(ctx, op1, fd, ft, fs); 9762 break; 9763 case OPC_SELEQZ_S: 9764 check_insn(ctx, ISA_MIPS_R6); 9765 gen_sel_s(ctx, op1, fd, ft, fs); 9766 break; 9767 case OPC_SELNEZ_S: 9768 check_insn(ctx, ISA_MIPS_R6); 9769 gen_sel_s(ctx, op1, fd, ft, fs); 9770 break; 9771 case OPC_MOVCF_S: 9772 check_insn_opc_removed(ctx, ISA_MIPS_R6); 9773 gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1); 9774 break; 9775 case OPC_MOVZ_S: 9776 check_insn_opc_removed(ctx, ISA_MIPS_R6); 9777 { 9778 TCGLabel *l1 = gen_new_label(); 9779 TCGv_i32 fp0; 9780 9781 if (ft != 0) { 9782 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1); 9783 } 9784 fp0 = tcg_temp_new_i32(); 9785 gen_load_fpr32(ctx, fp0, fs); 9786 gen_store_fpr32(ctx, fp0, fd); 9787 gen_set_label(l1); 9788 } 9789 break; 9790 case OPC_MOVN_S: 9791 check_insn_opc_removed(ctx, ISA_MIPS_R6); 9792 { 9793 TCGLabel *l1 = gen_new_label(); 9794 TCGv_i32 fp0; 9795 9796 if (ft != 0) { 9797 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1); 9798 fp0 = tcg_temp_new_i32(); 9799 gen_load_fpr32(ctx, fp0, fs); 9800 gen_store_fpr32(ctx, fp0, fd); 9801 gen_set_label(l1); 9802 } 9803 } 9804 break; 9805 case OPC_RECIP_S: 9806 { 9807 TCGv_i32 fp0 = tcg_temp_new_i32(); 9808 9809 gen_load_fpr32(ctx, fp0, fs); 9810 gen_helper_float_recip_s(fp0, cpu_env, fp0); 9811 gen_store_fpr32(ctx, fp0, fd); 9812 } 9813 break; 9814 case OPC_RSQRT_S: 9815 { 9816 TCGv_i32 fp0 = tcg_temp_new_i32(); 9817 9818 gen_load_fpr32(ctx, fp0, fs); 9819 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0); 9820 gen_store_fpr32(ctx, fp0, fd); 9821 } 9822 break; 9823 case OPC_MADDF_S: 9824 check_insn(ctx, ISA_MIPS_R6); 9825 { 9826 TCGv_i32 fp0 = tcg_temp_new_i32(); 9827 TCGv_i32 fp1 = tcg_temp_new_i32(); 9828 TCGv_i32 fp2 = tcg_temp_new_i32(); 9829 gen_load_fpr32(ctx, fp0, fs); 9830 gen_load_fpr32(ctx, fp1, ft); 9831 gen_load_fpr32(ctx, fp2, fd); 9832 gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2); 9833 gen_store_fpr32(ctx, fp2, fd); 9834 } 9835 break; 9836 case OPC_MSUBF_S: 9837 check_insn(ctx, ISA_MIPS_R6); 9838 { 9839 TCGv_i32 fp0 = tcg_temp_new_i32(); 9840 TCGv_i32 fp1 = tcg_temp_new_i32(); 9841 TCGv_i32 fp2 = tcg_temp_new_i32(); 9842 gen_load_fpr32(ctx, fp0, fs); 9843 gen_load_fpr32(ctx, fp1, ft); 9844 gen_load_fpr32(ctx, fp2, fd); 9845 gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2); 9846 gen_store_fpr32(ctx, fp2, fd); 9847 } 9848 break; 9849 case OPC_RINT_S: 9850 check_insn(ctx, ISA_MIPS_R6); 9851 { 9852 TCGv_i32 fp0 = tcg_temp_new_i32(); 9853 gen_load_fpr32(ctx, fp0, fs); 9854 gen_helper_float_rint_s(fp0, cpu_env, fp0); 9855 gen_store_fpr32(ctx, fp0, fd); 9856 } 9857 break; 9858 case OPC_CLASS_S: 9859 check_insn(ctx, ISA_MIPS_R6); 9860 { 9861 TCGv_i32 fp0 = tcg_temp_new_i32(); 9862 gen_load_fpr32(ctx, fp0, fs); 9863 gen_helper_float_class_s(fp0, cpu_env, fp0); 9864 gen_store_fpr32(ctx, fp0, fd); 9865 } 9866 break; 9867 case OPC_MIN_S: /* OPC_RECIP2_S */ 9868 if (ctx->insn_flags & ISA_MIPS_R6) { 9869 /* OPC_MIN_S */ 9870 TCGv_i32 fp0 = tcg_temp_new_i32(); 9871 TCGv_i32 fp1 = tcg_temp_new_i32(); 9872 TCGv_i32 fp2 = tcg_temp_new_i32(); 9873 gen_load_fpr32(ctx, fp0, fs); 9874 gen_load_fpr32(ctx, fp1, ft); 9875 gen_helper_float_min_s(fp2, cpu_env, fp0, fp1); 9876 gen_store_fpr32(ctx, fp2, fd); 9877 } else { 9878 /* OPC_RECIP2_S */ 9879 check_cp1_64bitmode(ctx); 9880 { 9881 TCGv_i32 fp0 = tcg_temp_new_i32(); 9882 TCGv_i32 fp1 = tcg_temp_new_i32(); 9883 9884 gen_load_fpr32(ctx, fp0, fs); 9885 gen_load_fpr32(ctx, fp1, ft); 9886 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1); 9887 gen_store_fpr32(ctx, fp0, fd); 9888 } 9889 } 9890 break; 9891 case OPC_MINA_S: /* OPC_RECIP1_S */ 9892 if (ctx->insn_flags & ISA_MIPS_R6) { 9893 /* OPC_MINA_S */ 9894 TCGv_i32 fp0 = tcg_temp_new_i32(); 9895 TCGv_i32 fp1 = tcg_temp_new_i32(); 9896 TCGv_i32 fp2 = tcg_temp_new_i32(); 9897 gen_load_fpr32(ctx, fp0, fs); 9898 gen_load_fpr32(ctx, fp1, ft); 9899 gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1); 9900 gen_store_fpr32(ctx, fp2, fd); 9901 } else { 9902 /* OPC_RECIP1_S */ 9903 check_cp1_64bitmode(ctx); 9904 { 9905 TCGv_i32 fp0 = tcg_temp_new_i32(); 9906 9907 gen_load_fpr32(ctx, fp0, fs); 9908 gen_helper_float_recip1_s(fp0, cpu_env, fp0); 9909 gen_store_fpr32(ctx, fp0, fd); 9910 } 9911 } 9912 break; 9913 case OPC_MAX_S: /* OPC_RSQRT1_S */ 9914 if (ctx->insn_flags & ISA_MIPS_R6) { 9915 /* OPC_MAX_S */ 9916 TCGv_i32 fp0 = tcg_temp_new_i32(); 9917 TCGv_i32 fp1 = tcg_temp_new_i32(); 9918 gen_load_fpr32(ctx, fp0, fs); 9919 gen_load_fpr32(ctx, fp1, ft); 9920 gen_helper_float_max_s(fp1, cpu_env, fp0, fp1); 9921 gen_store_fpr32(ctx, fp1, fd); 9922 } else { 9923 /* OPC_RSQRT1_S */ 9924 check_cp1_64bitmode(ctx); 9925 { 9926 TCGv_i32 fp0 = tcg_temp_new_i32(); 9927 9928 gen_load_fpr32(ctx, fp0, fs); 9929 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0); 9930 gen_store_fpr32(ctx, fp0, fd); 9931 } 9932 } 9933 break; 9934 case OPC_MAXA_S: /* OPC_RSQRT2_S */ 9935 if (ctx->insn_flags & ISA_MIPS_R6) { 9936 /* OPC_MAXA_S */ 9937 TCGv_i32 fp0 = tcg_temp_new_i32(); 9938 TCGv_i32 fp1 = tcg_temp_new_i32(); 9939 gen_load_fpr32(ctx, fp0, fs); 9940 gen_load_fpr32(ctx, fp1, ft); 9941 gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1); 9942 gen_store_fpr32(ctx, fp1, fd); 9943 } else { 9944 /* OPC_RSQRT2_S */ 9945 check_cp1_64bitmode(ctx); 9946 { 9947 TCGv_i32 fp0 = tcg_temp_new_i32(); 9948 TCGv_i32 fp1 = tcg_temp_new_i32(); 9949 9950 gen_load_fpr32(ctx, fp0, fs); 9951 gen_load_fpr32(ctx, fp1, ft); 9952 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1); 9953 gen_store_fpr32(ctx, fp0, fd); 9954 } 9955 } 9956 break; 9957 case OPC_CVT_D_S: 9958 check_cp1_registers(ctx, fd); 9959 { 9960 TCGv_i32 fp32 = tcg_temp_new_i32(); 9961 TCGv_i64 fp64 = tcg_temp_new_i64(); 9962 9963 gen_load_fpr32(ctx, fp32, fs); 9964 gen_helper_float_cvtd_s(fp64, cpu_env, fp32); 9965 gen_store_fpr64(ctx, fp64, fd); 9966 } 9967 break; 9968 case OPC_CVT_W_S: 9969 { 9970 TCGv_i32 fp0 = tcg_temp_new_i32(); 9971 9972 gen_load_fpr32(ctx, fp0, fs); 9973 if (ctx->nan2008) { 9974 gen_helper_float_cvt_2008_w_s(fp0, cpu_env, fp0); 9975 } else { 9976 gen_helper_float_cvt_w_s(fp0, cpu_env, fp0); 9977 } 9978 gen_store_fpr32(ctx, fp0, fd); 9979 } 9980 break; 9981 case OPC_CVT_L_S: 9982 check_cp1_64bitmode(ctx); 9983 { 9984 TCGv_i32 fp32 = tcg_temp_new_i32(); 9985 TCGv_i64 fp64 = tcg_temp_new_i64(); 9986 9987 gen_load_fpr32(ctx, fp32, fs); 9988 if (ctx->nan2008) { 9989 gen_helper_float_cvt_2008_l_s(fp64, cpu_env, fp32); 9990 } else { 9991 gen_helper_float_cvt_l_s(fp64, cpu_env, fp32); 9992 } 9993 gen_store_fpr64(ctx, fp64, fd); 9994 } 9995 break; 9996 case OPC_CVT_PS_S: 9997 check_ps(ctx); 9998 { 9999 TCGv_i64 fp64 = tcg_temp_new_i64(); 10000 TCGv_i32 fp32_0 = tcg_temp_new_i32(); 10001 TCGv_i32 fp32_1 = tcg_temp_new_i32(); 10002 10003 gen_load_fpr32(ctx, fp32_0, fs); 10004 gen_load_fpr32(ctx, fp32_1, ft); 10005 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0); 10006 gen_store_fpr64(ctx, fp64, fd); 10007 } 10008 break; 10009 case OPC_CMP_F_S: 10010 case OPC_CMP_UN_S: 10011 case OPC_CMP_EQ_S: 10012 case OPC_CMP_UEQ_S: 10013 case OPC_CMP_OLT_S: 10014 case OPC_CMP_ULT_S: 10015 case OPC_CMP_OLE_S: 10016 case OPC_CMP_ULE_S: 10017 case OPC_CMP_SF_S: 10018 case OPC_CMP_NGLE_S: 10019 case OPC_CMP_SEQ_S: 10020 case OPC_CMP_NGL_S: 10021 case OPC_CMP_LT_S: 10022 case OPC_CMP_NGE_S: 10023 case OPC_CMP_LE_S: 10024 case OPC_CMP_NGT_S: 10025 check_insn_opc_removed(ctx, ISA_MIPS_R6); 10026 if (ctx->opcode & (1 << 6)) { 10027 gen_cmpabs_s(ctx, func - 48, ft, fs, cc); 10028 } else { 10029 gen_cmp_s(ctx, func - 48, ft, fs, cc); 10030 } 10031 break; 10032 case OPC_ADD_D: 10033 check_cp1_registers(ctx, fs | ft | fd); 10034 { 10035 TCGv_i64 fp0 = tcg_temp_new_i64(); 10036 TCGv_i64 fp1 = tcg_temp_new_i64(); 10037 10038 gen_load_fpr64(ctx, fp0, fs); 10039 gen_load_fpr64(ctx, fp1, ft); 10040 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1); 10041 gen_store_fpr64(ctx, fp0, fd); 10042 } 10043 break; 10044 case OPC_SUB_D: 10045 check_cp1_registers(ctx, fs | ft | fd); 10046 { 10047 TCGv_i64 fp0 = tcg_temp_new_i64(); 10048 TCGv_i64 fp1 = tcg_temp_new_i64(); 10049 10050 gen_load_fpr64(ctx, fp0, fs); 10051 gen_load_fpr64(ctx, fp1, ft); 10052 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1); 10053 gen_store_fpr64(ctx, fp0, fd); 10054 } 10055 break; 10056 case OPC_MUL_D: 10057 check_cp1_registers(ctx, fs | ft | fd); 10058 { 10059 TCGv_i64 fp0 = tcg_temp_new_i64(); 10060 TCGv_i64 fp1 = tcg_temp_new_i64(); 10061 10062 gen_load_fpr64(ctx, fp0, fs); 10063 gen_load_fpr64(ctx, fp1, ft); 10064 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1); 10065 gen_store_fpr64(ctx, fp0, fd); 10066 } 10067 break; 10068 case OPC_DIV_D: 10069 check_cp1_registers(ctx, fs | ft | fd); 10070 { 10071 TCGv_i64 fp0 = tcg_temp_new_i64(); 10072 TCGv_i64 fp1 = tcg_temp_new_i64(); 10073 10074 gen_load_fpr64(ctx, fp0, fs); 10075 gen_load_fpr64(ctx, fp1, ft); 10076 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1); 10077 gen_store_fpr64(ctx, fp0, fd); 10078 } 10079 break; 10080 case OPC_SQRT_D: 10081 check_cp1_registers(ctx, fs | fd); 10082 { 10083 TCGv_i64 fp0 = tcg_temp_new_i64(); 10084 10085 gen_load_fpr64(ctx, fp0, fs); 10086 gen_helper_float_sqrt_d(fp0, cpu_env, fp0); 10087 gen_store_fpr64(ctx, fp0, fd); 10088 } 10089 break; 10090 case OPC_ABS_D: 10091 check_cp1_registers(ctx, fs | fd); 10092 { 10093 TCGv_i64 fp0 = tcg_temp_new_i64(); 10094 10095 gen_load_fpr64(ctx, fp0, fs); 10096 if (ctx->abs2008) { 10097 tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL); 10098 } else { 10099 gen_helper_float_abs_d(fp0, fp0); 10100 } 10101 gen_store_fpr64(ctx, fp0, fd); 10102 } 10103 break; 10104 case OPC_MOV_D: 10105 check_cp1_registers(ctx, fs | fd); 10106 { 10107 TCGv_i64 fp0 = tcg_temp_new_i64(); 10108 10109 gen_load_fpr64(ctx, fp0, fs); 10110 gen_store_fpr64(ctx, fp0, fd); 10111 } 10112 break; 10113 case OPC_NEG_D: 10114 check_cp1_registers(ctx, fs | fd); 10115 { 10116 TCGv_i64 fp0 = tcg_temp_new_i64(); 10117 10118 gen_load_fpr64(ctx, fp0, fs); 10119 if (ctx->abs2008) { 10120 tcg_gen_xori_i64(fp0, fp0, 1ULL << 63); 10121 } else { 10122 gen_helper_float_chs_d(fp0, fp0); 10123 } 10124 gen_store_fpr64(ctx, fp0, fd); 10125 } 10126 break; 10127 case OPC_ROUND_L_D: 10128 check_cp1_64bitmode(ctx); 10129 { 10130 TCGv_i64 fp0 = tcg_temp_new_i64(); 10131 10132 gen_load_fpr64(ctx, fp0, fs); 10133 if (ctx->nan2008) { 10134 gen_helper_float_round_2008_l_d(fp0, cpu_env, fp0); 10135 } else { 10136 gen_helper_float_round_l_d(fp0, cpu_env, fp0); 10137 } 10138 gen_store_fpr64(ctx, fp0, fd); 10139 } 10140 break; 10141 case OPC_TRUNC_L_D: 10142 check_cp1_64bitmode(ctx); 10143 { 10144 TCGv_i64 fp0 = tcg_temp_new_i64(); 10145 10146 gen_load_fpr64(ctx, fp0, fs); 10147 if (ctx->nan2008) { 10148 gen_helper_float_trunc_2008_l_d(fp0, cpu_env, fp0); 10149 } else { 10150 gen_helper_float_trunc_l_d(fp0, cpu_env, fp0); 10151 } 10152 gen_store_fpr64(ctx, fp0, fd); 10153 } 10154 break; 10155 case OPC_CEIL_L_D: 10156 check_cp1_64bitmode(ctx); 10157 { 10158 TCGv_i64 fp0 = tcg_temp_new_i64(); 10159 10160 gen_load_fpr64(ctx, fp0, fs); 10161 if (ctx->nan2008) { 10162 gen_helper_float_ceil_2008_l_d(fp0, cpu_env, fp0); 10163 } else { 10164 gen_helper_float_ceil_l_d(fp0, cpu_env, fp0); 10165 } 10166 gen_store_fpr64(ctx, fp0, fd); 10167 } 10168 break; 10169 case OPC_FLOOR_L_D: 10170 check_cp1_64bitmode(ctx); 10171 { 10172 TCGv_i64 fp0 = tcg_temp_new_i64(); 10173 10174 gen_load_fpr64(ctx, fp0, fs); 10175 if (ctx->nan2008) { 10176 gen_helper_float_floor_2008_l_d(fp0, cpu_env, fp0); 10177 } else { 10178 gen_helper_float_floor_l_d(fp0, cpu_env, fp0); 10179 } 10180 gen_store_fpr64(ctx, fp0, fd); 10181 } 10182 break; 10183 case OPC_ROUND_W_D: 10184 check_cp1_registers(ctx, fs); 10185 { 10186 TCGv_i32 fp32 = tcg_temp_new_i32(); 10187 TCGv_i64 fp64 = tcg_temp_new_i64(); 10188 10189 gen_load_fpr64(ctx, fp64, fs); 10190 if (ctx->nan2008) { 10191 gen_helper_float_round_2008_w_d(fp32, cpu_env, fp64); 10192 } else { 10193 gen_helper_float_round_w_d(fp32, cpu_env, fp64); 10194 } 10195 gen_store_fpr32(ctx, fp32, fd); 10196 } 10197 break; 10198 case OPC_TRUNC_W_D: 10199 check_cp1_registers(ctx, fs); 10200 { 10201 TCGv_i32 fp32 = tcg_temp_new_i32(); 10202 TCGv_i64 fp64 = tcg_temp_new_i64(); 10203 10204 gen_load_fpr64(ctx, fp64, fs); 10205 if (ctx->nan2008) { 10206 gen_helper_float_trunc_2008_w_d(fp32, cpu_env, fp64); 10207 } else { 10208 gen_helper_float_trunc_w_d(fp32, cpu_env, fp64); 10209 } 10210 gen_store_fpr32(ctx, fp32, fd); 10211 } 10212 break; 10213 case OPC_CEIL_W_D: 10214 check_cp1_registers(ctx, fs); 10215 { 10216 TCGv_i32 fp32 = tcg_temp_new_i32(); 10217 TCGv_i64 fp64 = tcg_temp_new_i64(); 10218 10219 gen_load_fpr64(ctx, fp64, fs); 10220 if (ctx->nan2008) { 10221 gen_helper_float_ceil_2008_w_d(fp32, cpu_env, fp64); 10222 } else { 10223 gen_helper_float_ceil_w_d(fp32, cpu_env, fp64); 10224 } 10225 gen_store_fpr32(ctx, fp32, fd); 10226 } 10227 break; 10228 case OPC_FLOOR_W_D: 10229 check_cp1_registers(ctx, fs); 10230 { 10231 TCGv_i32 fp32 = tcg_temp_new_i32(); 10232 TCGv_i64 fp64 = tcg_temp_new_i64(); 10233 10234 gen_load_fpr64(ctx, fp64, fs); 10235 if (ctx->nan2008) { 10236 gen_helper_float_floor_2008_w_d(fp32, cpu_env, fp64); 10237 } else { 10238 gen_helper_float_floor_w_d(fp32, cpu_env, fp64); 10239 } 10240 gen_store_fpr32(ctx, fp32, fd); 10241 } 10242 break; 10243 case OPC_SEL_D: 10244 check_insn(ctx, ISA_MIPS_R6); 10245 gen_sel_d(ctx, op1, fd, ft, fs); 10246 break; 10247 case OPC_SELEQZ_D: 10248 check_insn(ctx, ISA_MIPS_R6); 10249 gen_sel_d(ctx, op1, fd, ft, fs); 10250 break; 10251 case OPC_SELNEZ_D: 10252 check_insn(ctx, ISA_MIPS_R6); 10253 gen_sel_d(ctx, op1, fd, ft, fs); 10254 break; 10255 case OPC_MOVCF_D: 10256 check_insn_opc_removed(ctx, ISA_MIPS_R6); 10257 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1); 10258 break; 10259 case OPC_MOVZ_D: 10260 check_insn_opc_removed(ctx, ISA_MIPS_R6); 10261 { 10262 TCGLabel *l1 = gen_new_label(); 10263 TCGv_i64 fp0; 10264 10265 if (ft != 0) { 10266 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1); 10267 } 10268 fp0 = tcg_temp_new_i64(); 10269 gen_load_fpr64(ctx, fp0, fs); 10270 gen_store_fpr64(ctx, fp0, fd); 10271 gen_set_label(l1); 10272 } 10273 break; 10274 case OPC_MOVN_D: 10275 check_insn_opc_removed(ctx, ISA_MIPS_R6); 10276 { 10277 TCGLabel *l1 = gen_new_label(); 10278 TCGv_i64 fp0; 10279 10280 if (ft != 0) { 10281 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1); 10282 fp0 = tcg_temp_new_i64(); 10283 gen_load_fpr64(ctx, fp0, fs); 10284 gen_store_fpr64(ctx, fp0, fd); 10285 gen_set_label(l1); 10286 } 10287 } 10288 break; 10289 case OPC_RECIP_D: 10290 check_cp1_registers(ctx, fs | fd); 10291 { 10292 TCGv_i64 fp0 = tcg_temp_new_i64(); 10293 10294 gen_load_fpr64(ctx, fp0, fs); 10295 gen_helper_float_recip_d(fp0, cpu_env, fp0); 10296 gen_store_fpr64(ctx, fp0, fd); 10297 } 10298 break; 10299 case OPC_RSQRT_D: 10300 check_cp1_registers(ctx, fs | fd); 10301 { 10302 TCGv_i64 fp0 = tcg_temp_new_i64(); 10303 10304 gen_load_fpr64(ctx, fp0, fs); 10305 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0); 10306 gen_store_fpr64(ctx, fp0, fd); 10307 } 10308 break; 10309 case OPC_MADDF_D: 10310 check_insn(ctx, ISA_MIPS_R6); 10311 { 10312 TCGv_i64 fp0 = tcg_temp_new_i64(); 10313 TCGv_i64 fp1 = tcg_temp_new_i64(); 10314 TCGv_i64 fp2 = tcg_temp_new_i64(); 10315 gen_load_fpr64(ctx, fp0, fs); 10316 gen_load_fpr64(ctx, fp1, ft); 10317 gen_load_fpr64(ctx, fp2, fd); 10318 gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2); 10319 gen_store_fpr64(ctx, fp2, fd); 10320 } 10321 break; 10322 case OPC_MSUBF_D: 10323 check_insn(ctx, ISA_MIPS_R6); 10324 { 10325 TCGv_i64 fp0 = tcg_temp_new_i64(); 10326 TCGv_i64 fp1 = tcg_temp_new_i64(); 10327 TCGv_i64 fp2 = tcg_temp_new_i64(); 10328 gen_load_fpr64(ctx, fp0, fs); 10329 gen_load_fpr64(ctx, fp1, ft); 10330 gen_load_fpr64(ctx, fp2, fd); 10331 gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2); 10332 gen_store_fpr64(ctx, fp2, fd); 10333 } 10334 break; 10335 case OPC_RINT_D: 10336 check_insn(ctx, ISA_MIPS_R6); 10337 { 10338 TCGv_i64 fp0 = tcg_temp_new_i64(); 10339 gen_load_fpr64(ctx, fp0, fs); 10340 gen_helper_float_rint_d(fp0, cpu_env, fp0); 10341 gen_store_fpr64(ctx, fp0, fd); 10342 } 10343 break; 10344 case OPC_CLASS_D: 10345 check_insn(ctx, ISA_MIPS_R6); 10346 { 10347 TCGv_i64 fp0 = tcg_temp_new_i64(); 10348 gen_load_fpr64(ctx, fp0, fs); 10349 gen_helper_float_class_d(fp0, cpu_env, fp0); 10350 gen_store_fpr64(ctx, fp0, fd); 10351 } 10352 break; 10353 case OPC_MIN_D: /* OPC_RECIP2_D */ 10354 if (ctx->insn_flags & ISA_MIPS_R6) { 10355 /* OPC_MIN_D */ 10356 TCGv_i64 fp0 = tcg_temp_new_i64(); 10357 TCGv_i64 fp1 = tcg_temp_new_i64(); 10358 gen_load_fpr64(ctx, fp0, fs); 10359 gen_load_fpr64(ctx, fp1, ft); 10360 gen_helper_float_min_d(fp1, cpu_env, fp0, fp1); 10361 gen_store_fpr64(ctx, fp1, fd); 10362 } else { 10363 /* OPC_RECIP2_D */ 10364 check_cp1_64bitmode(ctx); 10365 { 10366 TCGv_i64 fp0 = tcg_temp_new_i64(); 10367 TCGv_i64 fp1 = tcg_temp_new_i64(); 10368 10369 gen_load_fpr64(ctx, fp0, fs); 10370 gen_load_fpr64(ctx, fp1, ft); 10371 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1); 10372 gen_store_fpr64(ctx, fp0, fd); 10373 } 10374 } 10375 break; 10376 case OPC_MINA_D: /* OPC_RECIP1_D */ 10377 if (ctx->insn_flags & ISA_MIPS_R6) { 10378 /* OPC_MINA_D */ 10379 TCGv_i64 fp0 = tcg_temp_new_i64(); 10380 TCGv_i64 fp1 = tcg_temp_new_i64(); 10381 gen_load_fpr64(ctx, fp0, fs); 10382 gen_load_fpr64(ctx, fp1, ft); 10383 gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1); 10384 gen_store_fpr64(ctx, fp1, fd); 10385 } else { 10386 /* OPC_RECIP1_D */ 10387 check_cp1_64bitmode(ctx); 10388 { 10389 TCGv_i64 fp0 = tcg_temp_new_i64(); 10390 10391 gen_load_fpr64(ctx, fp0, fs); 10392 gen_helper_float_recip1_d(fp0, cpu_env, fp0); 10393 gen_store_fpr64(ctx, fp0, fd); 10394 } 10395 } 10396 break; 10397 case OPC_MAX_D: /* OPC_RSQRT1_D */ 10398 if (ctx->insn_flags & ISA_MIPS_R6) { 10399 /* OPC_MAX_D */ 10400 TCGv_i64 fp0 = tcg_temp_new_i64(); 10401 TCGv_i64 fp1 = tcg_temp_new_i64(); 10402 gen_load_fpr64(ctx, fp0, fs); 10403 gen_load_fpr64(ctx, fp1, ft); 10404 gen_helper_float_max_d(fp1, cpu_env, fp0, fp1); 10405 gen_store_fpr64(ctx, fp1, fd); 10406 } else { 10407 /* OPC_RSQRT1_D */ 10408 check_cp1_64bitmode(ctx); 10409 { 10410 TCGv_i64 fp0 = tcg_temp_new_i64(); 10411 10412 gen_load_fpr64(ctx, fp0, fs); 10413 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0); 10414 gen_store_fpr64(ctx, fp0, fd); 10415 } 10416 } 10417 break; 10418 case OPC_MAXA_D: /* OPC_RSQRT2_D */ 10419 if (ctx->insn_flags & ISA_MIPS_R6) { 10420 /* OPC_MAXA_D */ 10421 TCGv_i64 fp0 = tcg_temp_new_i64(); 10422 TCGv_i64 fp1 = tcg_temp_new_i64(); 10423 gen_load_fpr64(ctx, fp0, fs); 10424 gen_load_fpr64(ctx, fp1, ft); 10425 gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1); 10426 gen_store_fpr64(ctx, fp1, fd); 10427 } else { 10428 /* OPC_RSQRT2_D */ 10429 check_cp1_64bitmode(ctx); 10430 { 10431 TCGv_i64 fp0 = tcg_temp_new_i64(); 10432 TCGv_i64 fp1 = tcg_temp_new_i64(); 10433 10434 gen_load_fpr64(ctx, fp0, fs); 10435 gen_load_fpr64(ctx, fp1, ft); 10436 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1); 10437 gen_store_fpr64(ctx, fp0, fd); 10438 } 10439 } 10440 break; 10441 case OPC_CMP_F_D: 10442 case OPC_CMP_UN_D: 10443 case OPC_CMP_EQ_D: 10444 case OPC_CMP_UEQ_D: 10445 case OPC_CMP_OLT_D: 10446 case OPC_CMP_ULT_D: 10447 case OPC_CMP_OLE_D: 10448 case OPC_CMP_ULE_D: 10449 case OPC_CMP_SF_D: 10450 case OPC_CMP_NGLE_D: 10451 case OPC_CMP_SEQ_D: 10452 case OPC_CMP_NGL_D: 10453 case OPC_CMP_LT_D: 10454 case OPC_CMP_NGE_D: 10455 case OPC_CMP_LE_D: 10456 case OPC_CMP_NGT_D: 10457 check_insn_opc_removed(ctx, ISA_MIPS_R6); 10458 if (ctx->opcode & (1 << 6)) { 10459 gen_cmpabs_d(ctx, func - 48, ft, fs, cc); 10460 } else { 10461 gen_cmp_d(ctx, func - 48, ft, fs, cc); 10462 } 10463 break; 10464 case OPC_CVT_S_D: 10465 check_cp1_registers(ctx, fs); 10466 { 10467 TCGv_i32 fp32 = tcg_temp_new_i32(); 10468 TCGv_i64 fp64 = tcg_temp_new_i64(); 10469 10470 gen_load_fpr64(ctx, fp64, fs); 10471 gen_helper_float_cvts_d(fp32, cpu_env, fp64); 10472 gen_store_fpr32(ctx, fp32, fd); 10473 } 10474 break; 10475 case OPC_CVT_W_D: 10476 check_cp1_registers(ctx, fs); 10477 { 10478 TCGv_i32 fp32 = tcg_temp_new_i32(); 10479 TCGv_i64 fp64 = tcg_temp_new_i64(); 10480 10481 gen_load_fpr64(ctx, fp64, fs); 10482 if (ctx->nan2008) { 10483 gen_helper_float_cvt_2008_w_d(fp32, cpu_env, fp64); 10484 } else { 10485 gen_helper_float_cvt_w_d(fp32, cpu_env, fp64); 10486 } 10487 gen_store_fpr32(ctx, fp32, fd); 10488 } 10489 break; 10490 case OPC_CVT_L_D: 10491 check_cp1_64bitmode(ctx); 10492 { 10493 TCGv_i64 fp0 = tcg_temp_new_i64(); 10494 10495 gen_load_fpr64(ctx, fp0, fs); 10496 if (ctx->nan2008) { 10497 gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0); 10498 } else { 10499 gen_helper_float_cvt_l_d(fp0, cpu_env, fp0); 10500 } 10501 gen_store_fpr64(ctx, fp0, fd); 10502 } 10503 break; 10504 case OPC_CVT_S_W: 10505 { 10506 TCGv_i32 fp0 = tcg_temp_new_i32(); 10507 10508 gen_load_fpr32(ctx, fp0, fs); 10509 gen_helper_float_cvts_w(fp0, cpu_env, fp0); 10510 gen_store_fpr32(ctx, fp0, fd); 10511 } 10512 break; 10513 case OPC_CVT_D_W: 10514 check_cp1_registers(ctx, fd); 10515 { 10516 TCGv_i32 fp32 = tcg_temp_new_i32(); 10517 TCGv_i64 fp64 = tcg_temp_new_i64(); 10518 10519 gen_load_fpr32(ctx, fp32, fs); 10520 gen_helper_float_cvtd_w(fp64, cpu_env, fp32); 10521 gen_store_fpr64(ctx, fp64, fd); 10522 } 10523 break; 10524 case OPC_CVT_S_L: 10525 check_cp1_64bitmode(ctx); 10526 { 10527 TCGv_i32 fp32 = tcg_temp_new_i32(); 10528 TCGv_i64 fp64 = tcg_temp_new_i64(); 10529 10530 gen_load_fpr64(ctx, fp64, fs); 10531 gen_helper_float_cvts_l(fp32, cpu_env, fp64); 10532 gen_store_fpr32(ctx, fp32, fd); 10533 } 10534 break; 10535 case OPC_CVT_D_L: 10536 check_cp1_64bitmode(ctx); 10537 { 10538 TCGv_i64 fp0 = tcg_temp_new_i64(); 10539 10540 gen_load_fpr64(ctx, fp0, fs); 10541 gen_helper_float_cvtd_l(fp0, cpu_env, fp0); 10542 gen_store_fpr64(ctx, fp0, fd); 10543 } 10544 break; 10545 case OPC_CVT_PS_PW: 10546 check_ps(ctx); 10547 { 10548 TCGv_i64 fp0 = tcg_temp_new_i64(); 10549 10550 gen_load_fpr64(ctx, fp0, fs); 10551 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0); 10552 gen_store_fpr64(ctx, fp0, fd); 10553 } 10554 break; 10555 case OPC_ADD_PS: 10556 check_ps(ctx); 10557 { 10558 TCGv_i64 fp0 = tcg_temp_new_i64(); 10559 TCGv_i64 fp1 = tcg_temp_new_i64(); 10560 10561 gen_load_fpr64(ctx, fp0, fs); 10562 gen_load_fpr64(ctx, fp1, ft); 10563 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1); 10564 gen_store_fpr64(ctx, fp0, fd); 10565 } 10566 break; 10567 case OPC_SUB_PS: 10568 check_ps(ctx); 10569 { 10570 TCGv_i64 fp0 = tcg_temp_new_i64(); 10571 TCGv_i64 fp1 = tcg_temp_new_i64(); 10572 10573 gen_load_fpr64(ctx, fp0, fs); 10574 gen_load_fpr64(ctx, fp1, ft); 10575 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1); 10576 gen_store_fpr64(ctx, fp0, fd); 10577 } 10578 break; 10579 case OPC_MUL_PS: 10580 check_ps(ctx); 10581 { 10582 TCGv_i64 fp0 = tcg_temp_new_i64(); 10583 TCGv_i64 fp1 = tcg_temp_new_i64(); 10584 10585 gen_load_fpr64(ctx, fp0, fs); 10586 gen_load_fpr64(ctx, fp1, ft); 10587 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1); 10588 gen_store_fpr64(ctx, fp0, fd); 10589 } 10590 break; 10591 case OPC_ABS_PS: 10592 check_ps(ctx); 10593 { 10594 TCGv_i64 fp0 = tcg_temp_new_i64(); 10595 10596 gen_load_fpr64(ctx, fp0, fs); 10597 gen_helper_float_abs_ps(fp0, fp0); 10598 gen_store_fpr64(ctx, fp0, fd); 10599 } 10600 break; 10601 case OPC_MOV_PS: 10602 check_ps(ctx); 10603 { 10604 TCGv_i64 fp0 = tcg_temp_new_i64(); 10605 10606 gen_load_fpr64(ctx, fp0, fs); 10607 gen_store_fpr64(ctx, fp0, fd); 10608 } 10609 break; 10610 case OPC_NEG_PS: 10611 check_ps(ctx); 10612 { 10613 TCGv_i64 fp0 = tcg_temp_new_i64(); 10614 10615 gen_load_fpr64(ctx, fp0, fs); 10616 gen_helper_float_chs_ps(fp0, fp0); 10617 gen_store_fpr64(ctx, fp0, fd); 10618 } 10619 break; 10620 case OPC_MOVCF_PS: 10621 check_ps(ctx); 10622 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1); 10623 break; 10624 case OPC_MOVZ_PS: 10625 check_ps(ctx); 10626 { 10627 TCGLabel *l1 = gen_new_label(); 10628 TCGv_i64 fp0; 10629 10630 if (ft != 0) { 10631 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1); 10632 } 10633 fp0 = tcg_temp_new_i64(); 10634 gen_load_fpr64(ctx, fp0, fs); 10635 gen_store_fpr64(ctx, fp0, fd); 10636 gen_set_label(l1); 10637 } 10638 break; 10639 case OPC_MOVN_PS: 10640 check_ps(ctx); 10641 { 10642 TCGLabel *l1 = gen_new_label(); 10643 TCGv_i64 fp0; 10644 10645 if (ft != 0) { 10646 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1); 10647 fp0 = tcg_temp_new_i64(); 10648 gen_load_fpr64(ctx, fp0, fs); 10649 gen_store_fpr64(ctx, fp0, fd); 10650 gen_set_label(l1); 10651 } 10652 } 10653 break; 10654 case OPC_ADDR_PS: 10655 check_ps(ctx); 10656 { 10657 TCGv_i64 fp0 = tcg_temp_new_i64(); 10658 TCGv_i64 fp1 = tcg_temp_new_i64(); 10659 10660 gen_load_fpr64(ctx, fp0, ft); 10661 gen_load_fpr64(ctx, fp1, fs); 10662 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1); 10663 gen_store_fpr64(ctx, fp0, fd); 10664 } 10665 break; 10666 case OPC_MULR_PS: 10667 check_ps(ctx); 10668 { 10669 TCGv_i64 fp0 = tcg_temp_new_i64(); 10670 TCGv_i64 fp1 = tcg_temp_new_i64(); 10671 10672 gen_load_fpr64(ctx, fp0, ft); 10673 gen_load_fpr64(ctx, fp1, fs); 10674 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1); 10675 gen_store_fpr64(ctx, fp0, fd); 10676 } 10677 break; 10678 case OPC_RECIP2_PS: 10679 check_ps(ctx); 10680 { 10681 TCGv_i64 fp0 = tcg_temp_new_i64(); 10682 TCGv_i64 fp1 = tcg_temp_new_i64(); 10683 10684 gen_load_fpr64(ctx, fp0, fs); 10685 gen_load_fpr64(ctx, fp1, ft); 10686 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1); 10687 gen_store_fpr64(ctx, fp0, fd); 10688 } 10689 break; 10690 case OPC_RECIP1_PS: 10691 check_ps(ctx); 10692 { 10693 TCGv_i64 fp0 = tcg_temp_new_i64(); 10694 10695 gen_load_fpr64(ctx, fp0, fs); 10696 gen_helper_float_recip1_ps(fp0, cpu_env, fp0); 10697 gen_store_fpr64(ctx, fp0, fd); 10698 } 10699 break; 10700 case OPC_RSQRT1_PS: 10701 check_ps(ctx); 10702 { 10703 TCGv_i64 fp0 = tcg_temp_new_i64(); 10704 10705 gen_load_fpr64(ctx, fp0, fs); 10706 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0); 10707 gen_store_fpr64(ctx, fp0, fd); 10708 } 10709 break; 10710 case OPC_RSQRT2_PS: 10711 check_ps(ctx); 10712 { 10713 TCGv_i64 fp0 = tcg_temp_new_i64(); 10714 TCGv_i64 fp1 = tcg_temp_new_i64(); 10715 10716 gen_load_fpr64(ctx, fp0, fs); 10717 gen_load_fpr64(ctx, fp1, ft); 10718 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1); 10719 gen_store_fpr64(ctx, fp0, fd); 10720 } 10721 break; 10722 case OPC_CVT_S_PU: 10723 check_cp1_64bitmode(ctx); 10724 { 10725 TCGv_i32 fp0 = tcg_temp_new_i32(); 10726 10727 gen_load_fpr32h(ctx, fp0, fs); 10728 gen_helper_float_cvts_pu(fp0, cpu_env, fp0); 10729 gen_store_fpr32(ctx, fp0, fd); 10730 } 10731 break; 10732 case OPC_CVT_PW_PS: 10733 check_ps(ctx); 10734 { 10735 TCGv_i64 fp0 = tcg_temp_new_i64(); 10736 10737 gen_load_fpr64(ctx, fp0, fs); 10738 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0); 10739 gen_store_fpr64(ctx, fp0, fd); 10740 } 10741 break; 10742 case OPC_CVT_S_PL: 10743 check_cp1_64bitmode(ctx); 10744 { 10745 TCGv_i32 fp0 = tcg_temp_new_i32(); 10746 10747 gen_load_fpr32(ctx, fp0, fs); 10748 gen_helper_float_cvts_pl(fp0, cpu_env, fp0); 10749 gen_store_fpr32(ctx, fp0, fd); 10750 } 10751 break; 10752 case OPC_PLL_PS: 10753 check_ps(ctx); 10754 { 10755 TCGv_i32 fp0 = tcg_temp_new_i32(); 10756 TCGv_i32 fp1 = tcg_temp_new_i32(); 10757 10758 gen_load_fpr32(ctx, fp0, fs); 10759 gen_load_fpr32(ctx, fp1, ft); 10760 gen_store_fpr32h(ctx, fp0, fd); 10761 gen_store_fpr32(ctx, fp1, fd); 10762 } 10763 break; 10764 case OPC_PLU_PS: 10765 check_ps(ctx); 10766 { 10767 TCGv_i32 fp0 = tcg_temp_new_i32(); 10768 TCGv_i32 fp1 = tcg_temp_new_i32(); 10769 10770 gen_load_fpr32(ctx, fp0, fs); 10771 gen_load_fpr32h(ctx, fp1, ft); 10772 gen_store_fpr32(ctx, fp1, fd); 10773 gen_store_fpr32h(ctx, fp0, fd); 10774 } 10775 break; 10776 case OPC_PUL_PS: 10777 check_ps(ctx); 10778 { 10779 TCGv_i32 fp0 = tcg_temp_new_i32(); 10780 TCGv_i32 fp1 = tcg_temp_new_i32(); 10781 10782 gen_load_fpr32h(ctx, fp0, fs); 10783 gen_load_fpr32(ctx, fp1, ft); 10784 gen_store_fpr32(ctx, fp1, fd); 10785 gen_store_fpr32h(ctx, fp0, fd); 10786 } 10787 break; 10788 case OPC_PUU_PS: 10789 check_ps(ctx); 10790 { 10791 TCGv_i32 fp0 = tcg_temp_new_i32(); 10792 TCGv_i32 fp1 = tcg_temp_new_i32(); 10793 10794 gen_load_fpr32h(ctx, fp0, fs); 10795 gen_load_fpr32h(ctx, fp1, ft); 10796 gen_store_fpr32(ctx, fp1, fd); 10797 gen_store_fpr32h(ctx, fp0, fd); 10798 } 10799 break; 10800 case OPC_CMP_F_PS: 10801 case OPC_CMP_UN_PS: 10802 case OPC_CMP_EQ_PS: 10803 case OPC_CMP_UEQ_PS: 10804 case OPC_CMP_OLT_PS: 10805 case OPC_CMP_ULT_PS: 10806 case OPC_CMP_OLE_PS: 10807 case OPC_CMP_ULE_PS: 10808 case OPC_CMP_SF_PS: 10809 case OPC_CMP_NGLE_PS: 10810 case OPC_CMP_SEQ_PS: 10811 case OPC_CMP_NGL_PS: 10812 case OPC_CMP_LT_PS: 10813 case OPC_CMP_NGE_PS: 10814 case OPC_CMP_LE_PS: 10815 case OPC_CMP_NGT_PS: 10816 if (ctx->opcode & (1 << 6)) { 10817 gen_cmpabs_ps(ctx, func - 48, ft, fs, cc); 10818 } else { 10819 gen_cmp_ps(ctx, func - 48, ft, fs, cc); 10820 } 10821 break; 10822 default: 10823 MIPS_INVAL("farith"); 10824 gen_reserved_instruction(ctx); 10825 return; 10826 } 10827 } 10828 10829 /* Coprocessor 3 (FPU) */ 10830 static void gen_flt3_ldst(DisasContext *ctx, uint32_t opc, 10831 int fd, int fs, int base, int index) 10832 { 10833 TCGv t0 = tcg_temp_new(); 10834 10835 if (base == 0) { 10836 gen_load_gpr(t0, index); 10837 } else if (index == 0) { 10838 gen_load_gpr(t0, base); 10839 } else { 10840 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]); 10841 } 10842 /* 10843 * Don't do NOP if destination is zero: we must perform the actual 10844 * memory access. 10845 */ 10846 switch (opc) { 10847 case OPC_LWXC1: 10848 check_cop1x(ctx); 10849 { 10850 TCGv_i32 fp0 = tcg_temp_new_i32(); 10851 10852 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL); 10853 tcg_gen_trunc_tl_i32(fp0, t0); 10854 gen_store_fpr32(ctx, fp0, fd); 10855 } 10856 break; 10857 case OPC_LDXC1: 10858 check_cop1x(ctx); 10859 check_cp1_registers(ctx, fd); 10860 { 10861 TCGv_i64 fp0 = tcg_temp_new_i64(); 10862 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEUQ); 10863 gen_store_fpr64(ctx, fp0, fd); 10864 } 10865 break; 10866 case OPC_LUXC1: 10867 check_cp1_64bitmode(ctx); 10868 tcg_gen_andi_tl(t0, t0, ~0x7); 10869 { 10870 TCGv_i64 fp0 = tcg_temp_new_i64(); 10871 10872 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEUQ); 10873 gen_store_fpr64(ctx, fp0, fd); 10874 } 10875 break; 10876 case OPC_SWXC1: 10877 check_cop1x(ctx); 10878 { 10879 TCGv_i32 fp0 = tcg_temp_new_i32(); 10880 gen_load_fpr32(ctx, fp0, fs); 10881 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL); 10882 } 10883 break; 10884 case OPC_SDXC1: 10885 check_cop1x(ctx); 10886 check_cp1_registers(ctx, fs); 10887 { 10888 TCGv_i64 fp0 = tcg_temp_new_i64(); 10889 gen_load_fpr64(ctx, fp0, fs); 10890 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEUQ); 10891 } 10892 break; 10893 case OPC_SUXC1: 10894 check_cp1_64bitmode(ctx); 10895 tcg_gen_andi_tl(t0, t0, ~0x7); 10896 { 10897 TCGv_i64 fp0 = tcg_temp_new_i64(); 10898 gen_load_fpr64(ctx, fp0, fs); 10899 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEUQ); 10900 } 10901 break; 10902 } 10903 } 10904 10905 static void gen_flt3_arith(DisasContext *ctx, uint32_t opc, 10906 int fd, int fr, int fs, int ft) 10907 { 10908 switch (opc) { 10909 case OPC_ALNV_PS: 10910 check_ps(ctx); 10911 { 10912 TCGv t0 = tcg_temp_new(); 10913 TCGv_i32 fp = tcg_temp_new_i32(); 10914 TCGv_i32 fph = tcg_temp_new_i32(); 10915 TCGLabel *l1 = gen_new_label(); 10916 TCGLabel *l2 = gen_new_label(); 10917 10918 gen_load_gpr(t0, fr); 10919 tcg_gen_andi_tl(t0, t0, 0x7); 10920 10921 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1); 10922 gen_load_fpr32(ctx, fp, fs); 10923 gen_load_fpr32h(ctx, fph, fs); 10924 gen_store_fpr32(ctx, fp, fd); 10925 gen_store_fpr32h(ctx, fph, fd); 10926 tcg_gen_br(l2); 10927 gen_set_label(l1); 10928 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2); 10929 if (cpu_is_bigendian(ctx)) { 10930 gen_load_fpr32(ctx, fp, fs); 10931 gen_load_fpr32h(ctx, fph, ft); 10932 gen_store_fpr32h(ctx, fp, fd); 10933 gen_store_fpr32(ctx, fph, fd); 10934 } else { 10935 gen_load_fpr32h(ctx, fph, fs); 10936 gen_load_fpr32(ctx, fp, ft); 10937 gen_store_fpr32(ctx, fph, fd); 10938 gen_store_fpr32h(ctx, fp, fd); 10939 } 10940 gen_set_label(l2); 10941 } 10942 break; 10943 case OPC_MADD_S: 10944 check_cop1x(ctx); 10945 { 10946 TCGv_i32 fp0 = tcg_temp_new_i32(); 10947 TCGv_i32 fp1 = tcg_temp_new_i32(); 10948 TCGv_i32 fp2 = tcg_temp_new_i32(); 10949 10950 gen_load_fpr32(ctx, fp0, fs); 10951 gen_load_fpr32(ctx, fp1, ft); 10952 gen_load_fpr32(ctx, fp2, fr); 10953 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2); 10954 gen_store_fpr32(ctx, fp2, fd); 10955 } 10956 break; 10957 case OPC_MADD_D: 10958 check_cop1x(ctx); 10959 check_cp1_registers(ctx, fd | fs | ft | fr); 10960 { 10961 TCGv_i64 fp0 = tcg_temp_new_i64(); 10962 TCGv_i64 fp1 = tcg_temp_new_i64(); 10963 TCGv_i64 fp2 = tcg_temp_new_i64(); 10964 10965 gen_load_fpr64(ctx, fp0, fs); 10966 gen_load_fpr64(ctx, fp1, ft); 10967 gen_load_fpr64(ctx, fp2, fr); 10968 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2); 10969 gen_store_fpr64(ctx, fp2, fd); 10970 } 10971 break; 10972 case OPC_MADD_PS: 10973 check_ps(ctx); 10974 { 10975 TCGv_i64 fp0 = tcg_temp_new_i64(); 10976 TCGv_i64 fp1 = tcg_temp_new_i64(); 10977 TCGv_i64 fp2 = tcg_temp_new_i64(); 10978 10979 gen_load_fpr64(ctx, fp0, fs); 10980 gen_load_fpr64(ctx, fp1, ft); 10981 gen_load_fpr64(ctx, fp2, fr); 10982 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2); 10983 gen_store_fpr64(ctx, fp2, fd); 10984 } 10985 break; 10986 case OPC_MSUB_S: 10987 check_cop1x(ctx); 10988 { 10989 TCGv_i32 fp0 = tcg_temp_new_i32(); 10990 TCGv_i32 fp1 = tcg_temp_new_i32(); 10991 TCGv_i32 fp2 = tcg_temp_new_i32(); 10992 10993 gen_load_fpr32(ctx, fp0, fs); 10994 gen_load_fpr32(ctx, fp1, ft); 10995 gen_load_fpr32(ctx, fp2, fr); 10996 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2); 10997 gen_store_fpr32(ctx, fp2, fd); 10998 } 10999 break; 11000 case OPC_MSUB_D: 11001 check_cop1x(ctx); 11002 check_cp1_registers(ctx, fd | fs | ft | fr); 11003 { 11004 TCGv_i64 fp0 = tcg_temp_new_i64(); 11005 TCGv_i64 fp1 = tcg_temp_new_i64(); 11006 TCGv_i64 fp2 = tcg_temp_new_i64(); 11007 11008 gen_load_fpr64(ctx, fp0, fs); 11009 gen_load_fpr64(ctx, fp1, ft); 11010 gen_load_fpr64(ctx, fp2, fr); 11011 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2); 11012 gen_store_fpr64(ctx, fp2, fd); 11013 } 11014 break; 11015 case OPC_MSUB_PS: 11016 check_ps(ctx); 11017 { 11018 TCGv_i64 fp0 = tcg_temp_new_i64(); 11019 TCGv_i64 fp1 = tcg_temp_new_i64(); 11020 TCGv_i64 fp2 = tcg_temp_new_i64(); 11021 11022 gen_load_fpr64(ctx, fp0, fs); 11023 gen_load_fpr64(ctx, fp1, ft); 11024 gen_load_fpr64(ctx, fp2, fr); 11025 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2); 11026 gen_store_fpr64(ctx, fp2, fd); 11027 } 11028 break; 11029 case OPC_NMADD_S: 11030 check_cop1x(ctx); 11031 { 11032 TCGv_i32 fp0 = tcg_temp_new_i32(); 11033 TCGv_i32 fp1 = tcg_temp_new_i32(); 11034 TCGv_i32 fp2 = tcg_temp_new_i32(); 11035 11036 gen_load_fpr32(ctx, fp0, fs); 11037 gen_load_fpr32(ctx, fp1, ft); 11038 gen_load_fpr32(ctx, fp2, fr); 11039 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2); 11040 gen_store_fpr32(ctx, fp2, fd); 11041 } 11042 break; 11043 case OPC_NMADD_D: 11044 check_cop1x(ctx); 11045 check_cp1_registers(ctx, fd | fs | ft | fr); 11046 { 11047 TCGv_i64 fp0 = tcg_temp_new_i64(); 11048 TCGv_i64 fp1 = tcg_temp_new_i64(); 11049 TCGv_i64 fp2 = tcg_temp_new_i64(); 11050 11051 gen_load_fpr64(ctx, fp0, fs); 11052 gen_load_fpr64(ctx, fp1, ft); 11053 gen_load_fpr64(ctx, fp2, fr); 11054 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2); 11055 gen_store_fpr64(ctx, fp2, fd); 11056 } 11057 break; 11058 case OPC_NMADD_PS: 11059 check_ps(ctx); 11060 { 11061 TCGv_i64 fp0 = tcg_temp_new_i64(); 11062 TCGv_i64 fp1 = tcg_temp_new_i64(); 11063 TCGv_i64 fp2 = tcg_temp_new_i64(); 11064 11065 gen_load_fpr64(ctx, fp0, fs); 11066 gen_load_fpr64(ctx, fp1, ft); 11067 gen_load_fpr64(ctx, fp2, fr); 11068 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2); 11069 gen_store_fpr64(ctx, fp2, fd); 11070 } 11071 break; 11072 case OPC_NMSUB_S: 11073 check_cop1x(ctx); 11074 { 11075 TCGv_i32 fp0 = tcg_temp_new_i32(); 11076 TCGv_i32 fp1 = tcg_temp_new_i32(); 11077 TCGv_i32 fp2 = tcg_temp_new_i32(); 11078 11079 gen_load_fpr32(ctx, fp0, fs); 11080 gen_load_fpr32(ctx, fp1, ft); 11081 gen_load_fpr32(ctx, fp2, fr); 11082 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2); 11083 gen_store_fpr32(ctx, fp2, fd); 11084 } 11085 break; 11086 case OPC_NMSUB_D: 11087 check_cop1x(ctx); 11088 check_cp1_registers(ctx, fd | fs | ft | fr); 11089 { 11090 TCGv_i64 fp0 = tcg_temp_new_i64(); 11091 TCGv_i64 fp1 = tcg_temp_new_i64(); 11092 TCGv_i64 fp2 = tcg_temp_new_i64(); 11093 11094 gen_load_fpr64(ctx, fp0, fs); 11095 gen_load_fpr64(ctx, fp1, ft); 11096 gen_load_fpr64(ctx, fp2, fr); 11097 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2); 11098 gen_store_fpr64(ctx, fp2, fd); 11099 } 11100 break; 11101 case OPC_NMSUB_PS: 11102 check_ps(ctx); 11103 { 11104 TCGv_i64 fp0 = tcg_temp_new_i64(); 11105 TCGv_i64 fp1 = tcg_temp_new_i64(); 11106 TCGv_i64 fp2 = tcg_temp_new_i64(); 11107 11108 gen_load_fpr64(ctx, fp0, fs); 11109 gen_load_fpr64(ctx, fp1, ft); 11110 gen_load_fpr64(ctx, fp2, fr); 11111 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2); 11112 gen_store_fpr64(ctx, fp2, fd); 11113 } 11114 break; 11115 default: 11116 MIPS_INVAL("flt3_arith"); 11117 gen_reserved_instruction(ctx); 11118 return; 11119 } 11120 } 11121 11122 void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel) 11123 { 11124 TCGv t0; 11125 11126 #if !defined(CONFIG_USER_ONLY) 11127 /* 11128 * The Linux kernel will emulate rdhwr if it's not supported natively. 11129 * Therefore only check the ISA in system mode. 11130 */ 11131 check_insn(ctx, ISA_MIPS_R2); 11132 #endif 11133 t0 = tcg_temp_new(); 11134 11135 switch (rd) { 11136 case 0: 11137 gen_helper_rdhwr_cpunum(t0, cpu_env); 11138 gen_store_gpr(t0, rt); 11139 break; 11140 case 1: 11141 gen_helper_rdhwr_synci_step(t0, cpu_env); 11142 gen_store_gpr(t0, rt); 11143 break; 11144 case 2: 11145 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { 11146 gen_io_start(); 11147 } 11148 gen_helper_rdhwr_cc(t0, cpu_env); 11149 gen_store_gpr(t0, rt); 11150 /* 11151 * Break the TB to be able to take timer interrupts immediately 11152 * after reading count. DISAS_STOP isn't sufficient, we need to ensure 11153 * we break completely out of translated code. 11154 */ 11155 gen_save_pc(ctx->base.pc_next + 4); 11156 ctx->base.is_jmp = DISAS_EXIT; 11157 break; 11158 case 3: 11159 gen_helper_rdhwr_ccres(t0, cpu_env); 11160 gen_store_gpr(t0, rt); 11161 break; 11162 case 4: 11163 check_insn(ctx, ISA_MIPS_R6); 11164 if (sel != 0) { 11165 /* 11166 * Performance counter registers are not implemented other than 11167 * control register 0. 11168 */ 11169 generate_exception(ctx, EXCP_RI); 11170 } 11171 gen_helper_rdhwr_performance(t0, cpu_env); 11172 gen_store_gpr(t0, rt); 11173 break; 11174 case 5: 11175 check_insn(ctx, ISA_MIPS_R6); 11176 gen_helper_rdhwr_xnp(t0, cpu_env); 11177 gen_store_gpr(t0, rt); 11178 break; 11179 case 29: 11180 #if defined(CONFIG_USER_ONLY) 11181 tcg_gen_ld_tl(t0, cpu_env, 11182 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 11183 gen_store_gpr(t0, rt); 11184 break; 11185 #else 11186 if ((ctx->hflags & MIPS_HFLAG_CP0) || 11187 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) { 11188 tcg_gen_ld_tl(t0, cpu_env, 11189 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 11190 gen_store_gpr(t0, rt); 11191 } else { 11192 gen_reserved_instruction(ctx); 11193 } 11194 break; 11195 #endif 11196 default: /* Invalid */ 11197 MIPS_INVAL("rdhwr"); 11198 gen_reserved_instruction(ctx); 11199 break; 11200 } 11201 } 11202 11203 static inline void clear_branch_hflags(DisasContext *ctx) 11204 { 11205 ctx->hflags &= ~MIPS_HFLAG_BMASK; 11206 if (ctx->base.is_jmp == DISAS_NEXT) { 11207 save_cpu_state(ctx, 0); 11208 } else { 11209 /* 11210 * It is not safe to save ctx->hflags as hflags may be changed 11211 * in execution time by the instruction in delay / forbidden slot. 11212 */ 11213 tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK); 11214 } 11215 } 11216 11217 static void gen_branch(DisasContext *ctx, int insn_bytes) 11218 { 11219 if (ctx->hflags & MIPS_HFLAG_BMASK) { 11220 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK; 11221 /* Branches completion */ 11222 clear_branch_hflags(ctx); 11223 ctx->base.is_jmp = DISAS_NORETURN; 11224 /* FIXME: Need to clear can_do_io. */ 11225 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) { 11226 case MIPS_HFLAG_FBNSLOT: 11227 gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes); 11228 break; 11229 case MIPS_HFLAG_B: 11230 /* unconditional branch */ 11231 if (proc_hflags & MIPS_HFLAG_BX) { 11232 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16); 11233 } 11234 gen_goto_tb(ctx, 0, ctx->btarget); 11235 break; 11236 case MIPS_HFLAG_BL: 11237 /* blikely taken case */ 11238 gen_goto_tb(ctx, 0, ctx->btarget); 11239 break; 11240 case MIPS_HFLAG_BC: 11241 /* Conditional branch */ 11242 { 11243 TCGLabel *l1 = gen_new_label(); 11244 11245 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1); 11246 gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes); 11247 gen_set_label(l1); 11248 gen_goto_tb(ctx, 0, ctx->btarget); 11249 } 11250 break; 11251 case MIPS_HFLAG_BR: 11252 /* unconditional branch to register */ 11253 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) { 11254 TCGv t0 = tcg_temp_new(); 11255 TCGv_i32 t1 = tcg_temp_new_i32(); 11256 11257 tcg_gen_andi_tl(t0, btarget, 0x1); 11258 tcg_gen_trunc_tl_i32(t1, t0); 11259 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16); 11260 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT); 11261 tcg_gen_or_i32(hflags, hflags, t1); 11262 11263 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1); 11264 } else { 11265 tcg_gen_mov_tl(cpu_PC, btarget); 11266 } 11267 tcg_gen_lookup_and_goto_ptr(); 11268 break; 11269 default: 11270 LOG_DISAS("unknown branch 0x%x\n", proc_hflags); 11271 gen_reserved_instruction(ctx); 11272 } 11273 } 11274 } 11275 11276 /* Compact Branches */ 11277 static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc, 11278 int rs, int rt, int32_t offset) 11279 { 11280 int bcond_compute = 0; 11281 TCGv t0 = tcg_temp_new(); 11282 TCGv t1 = tcg_temp_new(); 11283 int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0; 11284 11285 if (ctx->hflags & MIPS_HFLAG_BMASK) { 11286 #ifdef MIPS_DEBUG_DISAS 11287 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx 11288 "\n", ctx->base.pc_next); 11289 #endif 11290 gen_reserved_instruction(ctx); 11291 return; 11292 } 11293 11294 /* Load needed operands and calculate btarget */ 11295 switch (opc) { 11296 /* compact branch */ 11297 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */ 11298 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */ 11299 gen_load_gpr(t0, rs); 11300 gen_load_gpr(t1, rt); 11301 bcond_compute = 1; 11302 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 11303 if (rs <= rt && rs == 0) { 11304 /* OPC_BEQZALC, OPC_BNEZALC */ 11305 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit); 11306 } 11307 break; 11308 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */ 11309 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */ 11310 gen_load_gpr(t0, rs); 11311 gen_load_gpr(t1, rt); 11312 bcond_compute = 1; 11313 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 11314 break; 11315 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */ 11316 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */ 11317 if (rs == 0 || rs == rt) { 11318 /* OPC_BLEZALC, OPC_BGEZALC */ 11319 /* OPC_BGTZALC, OPC_BLTZALC */ 11320 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit); 11321 } 11322 gen_load_gpr(t0, rs); 11323 gen_load_gpr(t1, rt); 11324 bcond_compute = 1; 11325 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 11326 break; 11327 case OPC_BC: 11328 case OPC_BALC: 11329 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 11330 break; 11331 case OPC_BEQZC: 11332 case OPC_BNEZC: 11333 if (rs != 0) { 11334 /* OPC_BEQZC, OPC_BNEZC */ 11335 gen_load_gpr(t0, rs); 11336 bcond_compute = 1; 11337 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 11338 } else { 11339 /* OPC_JIC, OPC_JIALC */ 11340 TCGv tbase = tcg_temp_new(); 11341 TCGv toffset = tcg_constant_tl(offset); 11342 11343 gen_load_gpr(tbase, rt); 11344 gen_op_addr_add(ctx, btarget, tbase, toffset); 11345 } 11346 break; 11347 default: 11348 MIPS_INVAL("Compact branch/jump"); 11349 gen_reserved_instruction(ctx); 11350 return; 11351 } 11352 11353 if (bcond_compute == 0) { 11354 /* Unconditional compact branch */ 11355 switch (opc) { 11356 case OPC_JIALC: 11357 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit); 11358 /* Fallthrough */ 11359 case OPC_JIC: 11360 ctx->hflags |= MIPS_HFLAG_BR; 11361 break; 11362 case OPC_BALC: 11363 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit); 11364 /* Fallthrough */ 11365 case OPC_BC: 11366 ctx->hflags |= MIPS_HFLAG_B; 11367 break; 11368 default: 11369 MIPS_INVAL("Compact branch/jump"); 11370 gen_reserved_instruction(ctx); 11371 return; 11372 } 11373 11374 /* Generating branch here as compact branches don't have delay slot */ 11375 gen_branch(ctx, 4); 11376 } else { 11377 /* Conditional compact branch */ 11378 TCGLabel *fs = gen_new_label(); 11379 save_cpu_state(ctx, 0); 11380 11381 switch (opc) { 11382 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */ 11383 if (rs == 0 && rt != 0) { 11384 /* OPC_BLEZALC */ 11385 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs); 11386 } else if (rs != 0 && rt != 0 && rs == rt) { 11387 /* OPC_BGEZALC */ 11388 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs); 11389 } else { 11390 /* OPC_BGEUC */ 11391 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs); 11392 } 11393 break; 11394 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */ 11395 if (rs == 0 && rt != 0) { 11396 /* OPC_BGTZALC */ 11397 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs); 11398 } else if (rs != 0 && rt != 0 && rs == rt) { 11399 /* OPC_BLTZALC */ 11400 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs); 11401 } else { 11402 /* OPC_BLTUC */ 11403 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs); 11404 } 11405 break; 11406 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */ 11407 if (rs == 0 && rt != 0) { 11408 /* OPC_BLEZC */ 11409 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs); 11410 } else if (rs != 0 && rt != 0 && rs == rt) { 11411 /* OPC_BGEZC */ 11412 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs); 11413 } else { 11414 /* OPC_BGEC */ 11415 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs); 11416 } 11417 break; 11418 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */ 11419 if (rs == 0 && rt != 0) { 11420 /* OPC_BGTZC */ 11421 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs); 11422 } else if (rs != 0 && rt != 0 && rs == rt) { 11423 /* OPC_BLTZC */ 11424 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs); 11425 } else { 11426 /* OPC_BLTC */ 11427 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs); 11428 } 11429 break; 11430 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */ 11431 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */ 11432 if (rs >= rt) { 11433 /* OPC_BOVC, OPC_BNVC */ 11434 TCGv t2 = tcg_temp_new(); 11435 TCGv t3 = tcg_temp_new(); 11436 TCGv t4 = tcg_temp_new(); 11437 TCGv input_overflow = tcg_temp_new(); 11438 11439 gen_load_gpr(t0, rs); 11440 gen_load_gpr(t1, rt); 11441 tcg_gen_ext32s_tl(t2, t0); 11442 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0); 11443 tcg_gen_ext32s_tl(t3, t1); 11444 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1); 11445 tcg_gen_or_tl(input_overflow, input_overflow, t4); 11446 11447 tcg_gen_add_tl(t4, t2, t3); 11448 tcg_gen_ext32s_tl(t4, t4); 11449 tcg_gen_xor_tl(t2, t2, t3); 11450 tcg_gen_xor_tl(t3, t4, t3); 11451 tcg_gen_andc_tl(t2, t3, t2); 11452 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0); 11453 tcg_gen_or_tl(t4, t4, input_overflow); 11454 if (opc == OPC_BOVC) { 11455 /* OPC_BOVC */ 11456 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs); 11457 } else { 11458 /* OPC_BNVC */ 11459 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs); 11460 } 11461 } else if (rs < rt && rs == 0) { 11462 /* OPC_BEQZALC, OPC_BNEZALC */ 11463 if (opc == OPC_BEQZALC) { 11464 /* OPC_BEQZALC */ 11465 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs); 11466 } else { 11467 /* OPC_BNEZALC */ 11468 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs); 11469 } 11470 } else { 11471 /* OPC_BEQC, OPC_BNEC */ 11472 if (opc == OPC_BEQC) { 11473 /* OPC_BEQC */ 11474 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs); 11475 } else { 11476 /* OPC_BNEC */ 11477 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs); 11478 } 11479 } 11480 break; 11481 case OPC_BEQZC: 11482 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs); 11483 break; 11484 case OPC_BNEZC: 11485 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs); 11486 break; 11487 default: 11488 MIPS_INVAL("Compact conditional branch/jump"); 11489 gen_reserved_instruction(ctx); 11490 return; 11491 } 11492 11493 /* Generating branch here as compact branches don't have delay slot */ 11494 gen_goto_tb(ctx, 1, ctx->btarget); 11495 gen_set_label(fs); 11496 11497 ctx->hflags |= MIPS_HFLAG_FBNSLOT; 11498 } 11499 } 11500 11501 void gen_addiupc(DisasContext *ctx, int rx, int imm, 11502 int is_64_bit, int extended) 11503 { 11504 TCGv t0; 11505 11506 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) { 11507 gen_reserved_instruction(ctx); 11508 return; 11509 } 11510 11511 t0 = tcg_temp_new(); 11512 11513 tcg_gen_movi_tl(t0, pc_relative_pc(ctx)); 11514 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm); 11515 if (!is_64_bit) { 11516 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]); 11517 } 11518 } 11519 11520 static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base, 11521 int16_t offset) 11522 { 11523 TCGv_i32 t0 = tcg_constant_i32(op); 11524 TCGv t1 = tcg_temp_new(); 11525 gen_base_offset_addr(ctx, t1, base, offset); 11526 gen_helper_cache(cpu_env, t1, t0); 11527 } 11528 11529 static inline bool is_uhi(DisasContext *ctx, int sdbbp_code) 11530 { 11531 #ifdef CONFIG_USER_ONLY 11532 return false; 11533 #else 11534 bool is_user = (ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM; 11535 return semihosting_enabled(is_user) && sdbbp_code == 1; 11536 #endif 11537 } 11538 11539 void gen_ldxs(DisasContext *ctx, int base, int index, int rd) 11540 { 11541 TCGv t0 = tcg_temp_new(); 11542 TCGv t1 = tcg_temp_new(); 11543 11544 gen_load_gpr(t0, base); 11545 11546 if (index != 0) { 11547 gen_load_gpr(t1, index); 11548 tcg_gen_shli_tl(t1, t1, 2); 11549 gen_op_addr_add(ctx, t0, t1, t0); 11550 } 11551 11552 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); 11553 gen_store_gpr(t1, rd); 11554 } 11555 11556 static void gen_sync(int stype) 11557 { 11558 TCGBar tcg_mo = TCG_BAR_SC; 11559 11560 switch (stype) { 11561 case 0x4: /* SYNC_WMB */ 11562 tcg_mo |= TCG_MO_ST_ST; 11563 break; 11564 case 0x10: /* SYNC_MB */ 11565 tcg_mo |= TCG_MO_ALL; 11566 break; 11567 case 0x11: /* SYNC_ACQUIRE */ 11568 tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST; 11569 break; 11570 case 0x12: /* SYNC_RELEASE */ 11571 tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST; 11572 break; 11573 case 0x13: /* SYNC_RMB */ 11574 tcg_mo |= TCG_MO_LD_LD; 11575 break; 11576 default: 11577 tcg_mo |= TCG_MO_ALL; 11578 break; 11579 } 11580 11581 tcg_gen_mb(tcg_mo); 11582 } 11583 11584 /* ISA extensions (ASEs) */ 11585 11586 /* MIPS16 extension to MIPS32 */ 11587 #include "mips16e_translate.c.inc" 11588 11589 /* microMIPS extension to MIPS32/MIPS64 */ 11590 11591 /* 11592 * Values for microMIPS fmt field. Variable-width, depending on which 11593 * formats the instruction supports. 11594 */ 11595 enum { 11596 FMT_SD_S = 0, 11597 FMT_SD_D = 1, 11598 11599 FMT_SDPS_S = 0, 11600 FMT_SDPS_D = 1, 11601 FMT_SDPS_PS = 2, 11602 11603 FMT_SWL_S = 0, 11604 FMT_SWL_W = 1, 11605 FMT_SWL_L = 2, 11606 11607 FMT_DWL_D = 0, 11608 FMT_DWL_W = 1, 11609 FMT_DWL_L = 2 11610 }; 11611 11612 #include "micromips_translate.c.inc" 11613 11614 #include "nanomips_translate.c.inc" 11615 11616 /* MIPSDSP functions. */ 11617 11618 /* Indexed load is not for DSP only */ 11619 static void gen_mips_lx(DisasContext *ctx, uint32_t opc, 11620 int rd, int base, int offset) 11621 { 11622 TCGv t0; 11623 11624 if (!(ctx->insn_flags & INSN_OCTEON)) { 11625 check_dsp(ctx); 11626 } 11627 t0 = tcg_temp_new(); 11628 11629 if (base == 0) { 11630 gen_load_gpr(t0, offset); 11631 } else if (offset == 0) { 11632 gen_load_gpr(t0, base); 11633 } else { 11634 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]); 11635 } 11636 11637 switch (opc) { 11638 case OPC_LBUX: 11639 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB); 11640 gen_store_gpr(t0, rd); 11641 break; 11642 case OPC_LHX: 11643 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW); 11644 gen_store_gpr(t0, rd); 11645 break; 11646 case OPC_LWX: 11647 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL); 11648 gen_store_gpr(t0, rd); 11649 break; 11650 #if defined(TARGET_MIPS64) 11651 case OPC_LDX: 11652 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ); 11653 gen_store_gpr(t0, rd); 11654 break; 11655 #endif 11656 } 11657 } 11658 11659 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2, 11660 int ret, int v1, int v2) 11661 { 11662 TCGv v1_t; 11663 TCGv v2_t; 11664 11665 if (ret == 0) { 11666 /* Treat as NOP. */ 11667 return; 11668 } 11669 11670 v1_t = tcg_temp_new(); 11671 v2_t = tcg_temp_new(); 11672 11673 gen_load_gpr(v1_t, v1); 11674 gen_load_gpr(v2_t, v2); 11675 11676 switch (op1) { 11677 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */ 11678 case OPC_MULT_G_2E: 11679 check_dsp_r2(ctx); 11680 switch (op2) { 11681 case OPC_ADDUH_QB: 11682 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t); 11683 break; 11684 case OPC_ADDUH_R_QB: 11685 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t); 11686 break; 11687 case OPC_ADDQH_PH: 11688 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t); 11689 break; 11690 case OPC_ADDQH_R_PH: 11691 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t); 11692 break; 11693 case OPC_ADDQH_W: 11694 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t); 11695 break; 11696 case OPC_ADDQH_R_W: 11697 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t); 11698 break; 11699 case OPC_SUBUH_QB: 11700 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t); 11701 break; 11702 case OPC_SUBUH_R_QB: 11703 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t); 11704 break; 11705 case OPC_SUBQH_PH: 11706 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t); 11707 break; 11708 case OPC_SUBQH_R_PH: 11709 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t); 11710 break; 11711 case OPC_SUBQH_W: 11712 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t); 11713 break; 11714 case OPC_SUBQH_R_W: 11715 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t); 11716 break; 11717 } 11718 break; 11719 case OPC_ABSQ_S_PH_DSP: 11720 switch (op2) { 11721 case OPC_ABSQ_S_QB: 11722 check_dsp_r2(ctx); 11723 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env); 11724 break; 11725 case OPC_ABSQ_S_PH: 11726 check_dsp(ctx); 11727 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env); 11728 break; 11729 case OPC_ABSQ_S_W: 11730 check_dsp(ctx); 11731 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env); 11732 break; 11733 case OPC_PRECEQ_W_PHL: 11734 check_dsp(ctx); 11735 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000); 11736 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]); 11737 break; 11738 case OPC_PRECEQ_W_PHR: 11739 check_dsp(ctx); 11740 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF); 11741 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16); 11742 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]); 11743 break; 11744 case OPC_PRECEQU_PH_QBL: 11745 check_dsp(ctx); 11746 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t); 11747 break; 11748 case OPC_PRECEQU_PH_QBR: 11749 check_dsp(ctx); 11750 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t); 11751 break; 11752 case OPC_PRECEQU_PH_QBLA: 11753 check_dsp(ctx); 11754 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t); 11755 break; 11756 case OPC_PRECEQU_PH_QBRA: 11757 check_dsp(ctx); 11758 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t); 11759 break; 11760 case OPC_PRECEU_PH_QBL: 11761 check_dsp(ctx); 11762 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t); 11763 break; 11764 case OPC_PRECEU_PH_QBR: 11765 check_dsp(ctx); 11766 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t); 11767 break; 11768 case OPC_PRECEU_PH_QBLA: 11769 check_dsp(ctx); 11770 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t); 11771 break; 11772 case OPC_PRECEU_PH_QBRA: 11773 check_dsp(ctx); 11774 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t); 11775 break; 11776 } 11777 break; 11778 case OPC_ADDU_QB_DSP: 11779 switch (op2) { 11780 case OPC_ADDQ_PH: 11781 check_dsp(ctx); 11782 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 11783 break; 11784 case OPC_ADDQ_S_PH: 11785 check_dsp(ctx); 11786 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 11787 break; 11788 case OPC_ADDQ_S_W: 11789 check_dsp(ctx); 11790 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env); 11791 break; 11792 case OPC_ADDU_QB: 11793 check_dsp(ctx); 11794 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env); 11795 break; 11796 case OPC_ADDU_S_QB: 11797 check_dsp(ctx); 11798 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env); 11799 break; 11800 case OPC_ADDU_PH: 11801 check_dsp_r2(ctx); 11802 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 11803 break; 11804 case OPC_ADDU_S_PH: 11805 check_dsp_r2(ctx); 11806 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 11807 break; 11808 case OPC_SUBQ_PH: 11809 check_dsp(ctx); 11810 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 11811 break; 11812 case OPC_SUBQ_S_PH: 11813 check_dsp(ctx); 11814 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 11815 break; 11816 case OPC_SUBQ_S_W: 11817 check_dsp(ctx); 11818 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env); 11819 break; 11820 case OPC_SUBU_QB: 11821 check_dsp(ctx); 11822 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env); 11823 break; 11824 case OPC_SUBU_S_QB: 11825 check_dsp(ctx); 11826 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env); 11827 break; 11828 case OPC_SUBU_PH: 11829 check_dsp_r2(ctx); 11830 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 11831 break; 11832 case OPC_SUBU_S_PH: 11833 check_dsp_r2(ctx); 11834 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 11835 break; 11836 case OPC_ADDSC: 11837 check_dsp(ctx); 11838 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env); 11839 break; 11840 case OPC_ADDWC: 11841 check_dsp(ctx); 11842 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env); 11843 break; 11844 case OPC_MODSUB: 11845 check_dsp(ctx); 11846 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t); 11847 break; 11848 case OPC_RADDU_W_QB: 11849 check_dsp(ctx); 11850 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t); 11851 break; 11852 } 11853 break; 11854 case OPC_CMPU_EQ_QB_DSP: 11855 switch (op2) { 11856 case OPC_PRECR_QB_PH: 11857 check_dsp_r2(ctx); 11858 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t); 11859 break; 11860 case OPC_PRECRQ_QB_PH: 11861 check_dsp(ctx); 11862 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t); 11863 break; 11864 case OPC_PRECR_SRA_PH_W: 11865 check_dsp_r2(ctx); 11866 { 11867 TCGv_i32 sa_t = tcg_constant_i32(v2); 11868 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t, 11869 cpu_gpr[ret]); 11870 break; 11871 } 11872 case OPC_PRECR_SRA_R_PH_W: 11873 check_dsp_r2(ctx); 11874 { 11875 TCGv_i32 sa_t = tcg_constant_i32(v2); 11876 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t, 11877 cpu_gpr[ret]); 11878 break; 11879 } 11880 case OPC_PRECRQ_PH_W: 11881 check_dsp(ctx); 11882 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t); 11883 break; 11884 case OPC_PRECRQ_RS_PH_W: 11885 check_dsp(ctx); 11886 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env); 11887 break; 11888 case OPC_PRECRQU_S_QB_PH: 11889 check_dsp(ctx); 11890 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 11891 break; 11892 } 11893 break; 11894 #ifdef TARGET_MIPS64 11895 case OPC_ABSQ_S_QH_DSP: 11896 switch (op2) { 11897 case OPC_PRECEQ_L_PWL: 11898 check_dsp(ctx); 11899 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull); 11900 break; 11901 case OPC_PRECEQ_L_PWR: 11902 check_dsp(ctx); 11903 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32); 11904 break; 11905 case OPC_PRECEQ_PW_QHL: 11906 check_dsp(ctx); 11907 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t); 11908 break; 11909 case OPC_PRECEQ_PW_QHR: 11910 check_dsp(ctx); 11911 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t); 11912 break; 11913 case OPC_PRECEQ_PW_QHLA: 11914 check_dsp(ctx); 11915 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t); 11916 break; 11917 case OPC_PRECEQ_PW_QHRA: 11918 check_dsp(ctx); 11919 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t); 11920 break; 11921 case OPC_PRECEQU_QH_OBL: 11922 check_dsp(ctx); 11923 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t); 11924 break; 11925 case OPC_PRECEQU_QH_OBR: 11926 check_dsp(ctx); 11927 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t); 11928 break; 11929 case OPC_PRECEQU_QH_OBLA: 11930 check_dsp(ctx); 11931 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t); 11932 break; 11933 case OPC_PRECEQU_QH_OBRA: 11934 check_dsp(ctx); 11935 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t); 11936 break; 11937 case OPC_PRECEU_QH_OBL: 11938 check_dsp(ctx); 11939 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t); 11940 break; 11941 case OPC_PRECEU_QH_OBR: 11942 check_dsp(ctx); 11943 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t); 11944 break; 11945 case OPC_PRECEU_QH_OBLA: 11946 check_dsp(ctx); 11947 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t); 11948 break; 11949 case OPC_PRECEU_QH_OBRA: 11950 check_dsp(ctx); 11951 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t); 11952 break; 11953 case OPC_ABSQ_S_OB: 11954 check_dsp_r2(ctx); 11955 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env); 11956 break; 11957 case OPC_ABSQ_S_PW: 11958 check_dsp(ctx); 11959 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env); 11960 break; 11961 case OPC_ABSQ_S_QH: 11962 check_dsp(ctx); 11963 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env); 11964 break; 11965 } 11966 break; 11967 case OPC_ADDU_OB_DSP: 11968 switch (op2) { 11969 case OPC_RADDU_L_OB: 11970 check_dsp(ctx); 11971 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t); 11972 break; 11973 case OPC_SUBQ_PW: 11974 check_dsp(ctx); 11975 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env); 11976 break; 11977 case OPC_SUBQ_S_PW: 11978 check_dsp(ctx); 11979 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env); 11980 break; 11981 case OPC_SUBQ_QH: 11982 check_dsp(ctx); 11983 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 11984 break; 11985 case OPC_SUBQ_S_QH: 11986 check_dsp(ctx); 11987 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 11988 break; 11989 case OPC_SUBU_OB: 11990 check_dsp(ctx); 11991 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); 11992 break; 11993 case OPC_SUBU_S_OB: 11994 check_dsp(ctx); 11995 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); 11996 break; 11997 case OPC_SUBU_QH: 11998 check_dsp_r2(ctx); 11999 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12000 break; 12001 case OPC_SUBU_S_QH: 12002 check_dsp_r2(ctx); 12003 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12004 break; 12005 case OPC_SUBUH_OB: 12006 check_dsp_r2(ctx); 12007 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t); 12008 break; 12009 case OPC_SUBUH_R_OB: 12010 check_dsp_r2(ctx); 12011 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t); 12012 break; 12013 case OPC_ADDQ_PW: 12014 check_dsp(ctx); 12015 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12016 break; 12017 case OPC_ADDQ_S_PW: 12018 check_dsp(ctx); 12019 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12020 break; 12021 case OPC_ADDQ_QH: 12022 check_dsp(ctx); 12023 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12024 break; 12025 case OPC_ADDQ_S_QH: 12026 check_dsp(ctx); 12027 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12028 break; 12029 case OPC_ADDU_OB: 12030 check_dsp(ctx); 12031 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12032 break; 12033 case OPC_ADDU_S_OB: 12034 check_dsp(ctx); 12035 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12036 break; 12037 case OPC_ADDU_QH: 12038 check_dsp_r2(ctx); 12039 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12040 break; 12041 case OPC_ADDU_S_QH: 12042 check_dsp_r2(ctx); 12043 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12044 break; 12045 case OPC_ADDUH_OB: 12046 check_dsp_r2(ctx); 12047 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t); 12048 break; 12049 case OPC_ADDUH_R_OB: 12050 check_dsp_r2(ctx); 12051 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t); 12052 break; 12053 } 12054 break; 12055 case OPC_CMPU_EQ_OB_DSP: 12056 switch (op2) { 12057 case OPC_PRECR_OB_QH: 12058 check_dsp_r2(ctx); 12059 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t); 12060 break; 12061 case OPC_PRECR_SRA_QH_PW: 12062 check_dsp_r2(ctx); 12063 { 12064 TCGv_i32 ret_t = tcg_constant_i32(ret); 12065 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t); 12066 break; 12067 } 12068 case OPC_PRECR_SRA_R_QH_PW: 12069 check_dsp_r2(ctx); 12070 { 12071 TCGv_i32 sa_v = tcg_constant_i32(ret); 12072 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v); 12073 break; 12074 } 12075 case OPC_PRECRQ_OB_QH: 12076 check_dsp(ctx); 12077 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t); 12078 break; 12079 case OPC_PRECRQ_PW_L: 12080 check_dsp(ctx); 12081 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t); 12082 break; 12083 case OPC_PRECRQ_QH_PW: 12084 check_dsp(ctx); 12085 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t); 12086 break; 12087 case OPC_PRECRQ_RS_QH_PW: 12088 check_dsp(ctx); 12089 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12090 break; 12091 case OPC_PRECRQU_S_OB_QH: 12092 check_dsp(ctx); 12093 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12094 break; 12095 } 12096 break; 12097 #endif 12098 } 12099 } 12100 12101 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc, 12102 int ret, int v1, int v2) 12103 { 12104 uint32_t op2; 12105 TCGv t0; 12106 TCGv v1_t; 12107 TCGv v2_t; 12108 12109 if (ret == 0) { 12110 /* Treat as NOP. */ 12111 return; 12112 } 12113 12114 t0 = tcg_temp_new(); 12115 v1_t = tcg_temp_new(); 12116 v2_t = tcg_temp_new(); 12117 12118 tcg_gen_movi_tl(t0, v1); 12119 gen_load_gpr(v1_t, v1); 12120 gen_load_gpr(v2_t, v2); 12121 12122 switch (opc) { 12123 case OPC_SHLL_QB_DSP: 12124 { 12125 op2 = MASK_SHLL_QB(ctx->opcode); 12126 switch (op2) { 12127 case OPC_SHLL_QB: 12128 check_dsp(ctx); 12129 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env); 12130 break; 12131 case OPC_SHLLV_QB: 12132 check_dsp(ctx); 12133 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12134 break; 12135 case OPC_SHLL_PH: 12136 check_dsp(ctx); 12137 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env); 12138 break; 12139 case OPC_SHLLV_PH: 12140 check_dsp(ctx); 12141 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12142 break; 12143 case OPC_SHLL_S_PH: 12144 check_dsp(ctx); 12145 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env); 12146 break; 12147 case OPC_SHLLV_S_PH: 12148 check_dsp(ctx); 12149 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12150 break; 12151 case OPC_SHLL_S_W: 12152 check_dsp(ctx); 12153 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env); 12154 break; 12155 case OPC_SHLLV_S_W: 12156 check_dsp(ctx); 12157 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12158 break; 12159 case OPC_SHRL_QB: 12160 check_dsp(ctx); 12161 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t); 12162 break; 12163 case OPC_SHRLV_QB: 12164 check_dsp(ctx); 12165 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t); 12166 break; 12167 case OPC_SHRL_PH: 12168 check_dsp_r2(ctx); 12169 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t); 12170 break; 12171 case OPC_SHRLV_PH: 12172 check_dsp_r2(ctx); 12173 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t); 12174 break; 12175 case OPC_SHRA_QB: 12176 check_dsp_r2(ctx); 12177 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t); 12178 break; 12179 case OPC_SHRA_R_QB: 12180 check_dsp_r2(ctx); 12181 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t); 12182 break; 12183 case OPC_SHRAV_QB: 12184 check_dsp_r2(ctx); 12185 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t); 12186 break; 12187 case OPC_SHRAV_R_QB: 12188 check_dsp_r2(ctx); 12189 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t); 12190 break; 12191 case OPC_SHRA_PH: 12192 check_dsp(ctx); 12193 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t); 12194 break; 12195 case OPC_SHRA_R_PH: 12196 check_dsp(ctx); 12197 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t); 12198 break; 12199 case OPC_SHRAV_PH: 12200 check_dsp(ctx); 12201 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t); 12202 break; 12203 case OPC_SHRAV_R_PH: 12204 check_dsp(ctx); 12205 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t); 12206 break; 12207 case OPC_SHRA_R_W: 12208 check_dsp(ctx); 12209 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t); 12210 break; 12211 case OPC_SHRAV_R_W: 12212 check_dsp(ctx); 12213 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t); 12214 break; 12215 default: /* Invalid */ 12216 MIPS_INVAL("MASK SHLL.QB"); 12217 gen_reserved_instruction(ctx); 12218 break; 12219 } 12220 break; 12221 } 12222 #ifdef TARGET_MIPS64 12223 case OPC_SHLL_OB_DSP: 12224 op2 = MASK_SHLL_OB(ctx->opcode); 12225 switch (op2) { 12226 case OPC_SHLL_PW: 12227 check_dsp(ctx); 12228 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env); 12229 break; 12230 case OPC_SHLLV_PW: 12231 check_dsp(ctx); 12232 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env); 12233 break; 12234 case OPC_SHLL_S_PW: 12235 check_dsp(ctx); 12236 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env); 12237 break; 12238 case OPC_SHLLV_S_PW: 12239 check_dsp(ctx); 12240 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env); 12241 break; 12242 case OPC_SHLL_OB: 12243 check_dsp(ctx); 12244 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env); 12245 break; 12246 case OPC_SHLLV_OB: 12247 check_dsp(ctx); 12248 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env); 12249 break; 12250 case OPC_SHLL_QH: 12251 check_dsp(ctx); 12252 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env); 12253 break; 12254 case OPC_SHLLV_QH: 12255 check_dsp(ctx); 12256 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env); 12257 break; 12258 case OPC_SHLL_S_QH: 12259 check_dsp(ctx); 12260 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env); 12261 break; 12262 case OPC_SHLLV_S_QH: 12263 check_dsp(ctx); 12264 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env); 12265 break; 12266 case OPC_SHRA_OB: 12267 check_dsp_r2(ctx); 12268 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0); 12269 break; 12270 case OPC_SHRAV_OB: 12271 check_dsp_r2(ctx); 12272 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t); 12273 break; 12274 case OPC_SHRA_R_OB: 12275 check_dsp_r2(ctx); 12276 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0); 12277 break; 12278 case OPC_SHRAV_R_OB: 12279 check_dsp_r2(ctx); 12280 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t); 12281 break; 12282 case OPC_SHRA_PW: 12283 check_dsp(ctx); 12284 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0); 12285 break; 12286 case OPC_SHRAV_PW: 12287 check_dsp(ctx); 12288 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t); 12289 break; 12290 case OPC_SHRA_R_PW: 12291 check_dsp(ctx); 12292 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0); 12293 break; 12294 case OPC_SHRAV_R_PW: 12295 check_dsp(ctx); 12296 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t); 12297 break; 12298 case OPC_SHRA_QH: 12299 check_dsp(ctx); 12300 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0); 12301 break; 12302 case OPC_SHRAV_QH: 12303 check_dsp(ctx); 12304 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t); 12305 break; 12306 case OPC_SHRA_R_QH: 12307 check_dsp(ctx); 12308 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0); 12309 break; 12310 case OPC_SHRAV_R_QH: 12311 check_dsp(ctx); 12312 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t); 12313 break; 12314 case OPC_SHRL_OB: 12315 check_dsp(ctx); 12316 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0); 12317 break; 12318 case OPC_SHRLV_OB: 12319 check_dsp(ctx); 12320 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t); 12321 break; 12322 case OPC_SHRL_QH: 12323 check_dsp_r2(ctx); 12324 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0); 12325 break; 12326 case OPC_SHRLV_QH: 12327 check_dsp_r2(ctx); 12328 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t); 12329 break; 12330 default: /* Invalid */ 12331 MIPS_INVAL("MASK SHLL.OB"); 12332 gen_reserved_instruction(ctx); 12333 break; 12334 } 12335 break; 12336 #endif 12337 } 12338 } 12339 12340 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2, 12341 int ret, int v1, int v2, int check_ret) 12342 { 12343 TCGv_i32 t0; 12344 TCGv v1_t; 12345 TCGv v2_t; 12346 12347 if ((ret == 0) && (check_ret == 1)) { 12348 /* Treat as NOP. */ 12349 return; 12350 } 12351 12352 t0 = tcg_temp_new_i32(); 12353 v1_t = tcg_temp_new(); 12354 v2_t = tcg_temp_new(); 12355 12356 tcg_gen_movi_i32(t0, ret); 12357 gen_load_gpr(v1_t, v1); 12358 gen_load_gpr(v2_t, v2); 12359 12360 switch (op1) { 12361 /* 12362 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have 12363 * the same mask and op1. 12364 */ 12365 case OPC_MULT_G_2E: 12366 check_dsp_r2(ctx); 12367 switch (op2) { 12368 case OPC_MUL_PH: 12369 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12370 break; 12371 case OPC_MUL_S_PH: 12372 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12373 break; 12374 case OPC_MULQ_S_W: 12375 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12376 break; 12377 case OPC_MULQ_RS_W: 12378 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12379 break; 12380 } 12381 break; 12382 case OPC_DPA_W_PH_DSP: 12383 switch (op2) { 12384 case OPC_DPAU_H_QBL: 12385 check_dsp(ctx); 12386 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env); 12387 break; 12388 case OPC_DPAU_H_QBR: 12389 check_dsp(ctx); 12390 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env); 12391 break; 12392 case OPC_DPSU_H_QBL: 12393 check_dsp(ctx); 12394 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env); 12395 break; 12396 case OPC_DPSU_H_QBR: 12397 check_dsp(ctx); 12398 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env); 12399 break; 12400 case OPC_DPA_W_PH: 12401 check_dsp_r2(ctx); 12402 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env); 12403 break; 12404 case OPC_DPAX_W_PH: 12405 check_dsp_r2(ctx); 12406 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env); 12407 break; 12408 case OPC_DPAQ_S_W_PH: 12409 check_dsp(ctx); 12410 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env); 12411 break; 12412 case OPC_DPAQX_S_W_PH: 12413 check_dsp_r2(ctx); 12414 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env); 12415 break; 12416 case OPC_DPAQX_SA_W_PH: 12417 check_dsp_r2(ctx); 12418 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env); 12419 break; 12420 case OPC_DPS_W_PH: 12421 check_dsp_r2(ctx); 12422 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env); 12423 break; 12424 case OPC_DPSX_W_PH: 12425 check_dsp_r2(ctx); 12426 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env); 12427 break; 12428 case OPC_DPSQ_S_W_PH: 12429 check_dsp(ctx); 12430 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env); 12431 break; 12432 case OPC_DPSQX_S_W_PH: 12433 check_dsp_r2(ctx); 12434 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env); 12435 break; 12436 case OPC_DPSQX_SA_W_PH: 12437 check_dsp_r2(ctx); 12438 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env); 12439 break; 12440 case OPC_MULSAQ_S_W_PH: 12441 check_dsp(ctx); 12442 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env); 12443 break; 12444 case OPC_DPAQ_SA_L_W: 12445 check_dsp(ctx); 12446 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env); 12447 break; 12448 case OPC_DPSQ_SA_L_W: 12449 check_dsp(ctx); 12450 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env); 12451 break; 12452 case OPC_MAQ_S_W_PHL: 12453 check_dsp(ctx); 12454 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env); 12455 break; 12456 case OPC_MAQ_S_W_PHR: 12457 check_dsp(ctx); 12458 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env); 12459 break; 12460 case OPC_MAQ_SA_W_PHL: 12461 check_dsp(ctx); 12462 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env); 12463 break; 12464 case OPC_MAQ_SA_W_PHR: 12465 check_dsp(ctx); 12466 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env); 12467 break; 12468 case OPC_MULSA_W_PH: 12469 check_dsp_r2(ctx); 12470 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env); 12471 break; 12472 } 12473 break; 12474 #ifdef TARGET_MIPS64 12475 case OPC_DPAQ_W_QH_DSP: 12476 { 12477 int ac = ret & 0x03; 12478 tcg_gen_movi_i32(t0, ac); 12479 12480 switch (op2) { 12481 case OPC_DMADD: 12482 check_dsp(ctx); 12483 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env); 12484 break; 12485 case OPC_DMADDU: 12486 check_dsp(ctx); 12487 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env); 12488 break; 12489 case OPC_DMSUB: 12490 check_dsp(ctx); 12491 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env); 12492 break; 12493 case OPC_DMSUBU: 12494 check_dsp(ctx); 12495 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env); 12496 break; 12497 case OPC_DPA_W_QH: 12498 check_dsp_r2(ctx); 12499 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env); 12500 break; 12501 case OPC_DPAQ_S_W_QH: 12502 check_dsp(ctx); 12503 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env); 12504 break; 12505 case OPC_DPAQ_SA_L_PW: 12506 check_dsp(ctx); 12507 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env); 12508 break; 12509 case OPC_DPAU_H_OBL: 12510 check_dsp(ctx); 12511 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env); 12512 break; 12513 case OPC_DPAU_H_OBR: 12514 check_dsp(ctx); 12515 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env); 12516 break; 12517 case OPC_DPS_W_QH: 12518 check_dsp_r2(ctx); 12519 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env); 12520 break; 12521 case OPC_DPSQ_S_W_QH: 12522 check_dsp(ctx); 12523 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env); 12524 break; 12525 case OPC_DPSQ_SA_L_PW: 12526 check_dsp(ctx); 12527 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env); 12528 break; 12529 case OPC_DPSU_H_OBL: 12530 check_dsp(ctx); 12531 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env); 12532 break; 12533 case OPC_DPSU_H_OBR: 12534 check_dsp(ctx); 12535 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env); 12536 break; 12537 case OPC_MAQ_S_L_PWL: 12538 check_dsp(ctx); 12539 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env); 12540 break; 12541 case OPC_MAQ_S_L_PWR: 12542 check_dsp(ctx); 12543 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env); 12544 break; 12545 case OPC_MAQ_S_W_QHLL: 12546 check_dsp(ctx); 12547 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env); 12548 break; 12549 case OPC_MAQ_SA_W_QHLL: 12550 check_dsp(ctx); 12551 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env); 12552 break; 12553 case OPC_MAQ_S_W_QHLR: 12554 check_dsp(ctx); 12555 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env); 12556 break; 12557 case OPC_MAQ_SA_W_QHLR: 12558 check_dsp(ctx); 12559 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env); 12560 break; 12561 case OPC_MAQ_S_W_QHRL: 12562 check_dsp(ctx); 12563 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env); 12564 break; 12565 case OPC_MAQ_SA_W_QHRL: 12566 check_dsp(ctx); 12567 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env); 12568 break; 12569 case OPC_MAQ_S_W_QHRR: 12570 check_dsp(ctx); 12571 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env); 12572 break; 12573 case OPC_MAQ_SA_W_QHRR: 12574 check_dsp(ctx); 12575 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env); 12576 break; 12577 case OPC_MULSAQ_S_L_PW: 12578 check_dsp(ctx); 12579 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env); 12580 break; 12581 case OPC_MULSAQ_S_W_QH: 12582 check_dsp(ctx); 12583 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env); 12584 break; 12585 } 12586 } 12587 break; 12588 #endif 12589 case OPC_ADDU_QB_DSP: 12590 switch (op2) { 12591 case OPC_MULEU_S_PH_QBL: 12592 check_dsp(ctx); 12593 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12594 break; 12595 case OPC_MULEU_S_PH_QBR: 12596 check_dsp(ctx); 12597 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12598 break; 12599 case OPC_MULQ_RS_PH: 12600 check_dsp(ctx); 12601 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12602 break; 12603 case OPC_MULEQ_S_W_PHL: 12604 check_dsp(ctx); 12605 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12606 break; 12607 case OPC_MULEQ_S_W_PHR: 12608 check_dsp(ctx); 12609 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12610 break; 12611 case OPC_MULQ_S_PH: 12612 check_dsp_r2(ctx); 12613 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12614 break; 12615 } 12616 break; 12617 #ifdef TARGET_MIPS64 12618 case OPC_ADDU_OB_DSP: 12619 switch (op2) { 12620 case OPC_MULEQ_S_PW_QHL: 12621 check_dsp(ctx); 12622 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12623 break; 12624 case OPC_MULEQ_S_PW_QHR: 12625 check_dsp(ctx); 12626 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12627 break; 12628 case OPC_MULEU_S_QH_OBL: 12629 check_dsp(ctx); 12630 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12631 break; 12632 case OPC_MULEU_S_QH_OBR: 12633 check_dsp(ctx); 12634 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12635 break; 12636 case OPC_MULQ_RS_QH: 12637 check_dsp(ctx); 12638 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12639 break; 12640 } 12641 break; 12642 #endif 12643 } 12644 } 12645 12646 static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2, 12647 int ret, int val) 12648 { 12649 int16_t imm; 12650 TCGv t0; 12651 TCGv val_t; 12652 12653 if (ret == 0) { 12654 /* Treat as NOP. */ 12655 return; 12656 } 12657 12658 t0 = tcg_temp_new(); 12659 val_t = tcg_temp_new(); 12660 gen_load_gpr(val_t, val); 12661 12662 switch (op1) { 12663 case OPC_ABSQ_S_PH_DSP: 12664 switch (op2) { 12665 case OPC_BITREV: 12666 check_dsp(ctx); 12667 gen_helper_bitrev(cpu_gpr[ret], val_t); 12668 break; 12669 case OPC_REPL_QB: 12670 check_dsp(ctx); 12671 { 12672 target_long result; 12673 imm = (ctx->opcode >> 16) & 0xFF; 12674 result = (uint32_t)imm << 24 | 12675 (uint32_t)imm << 16 | 12676 (uint32_t)imm << 8 | 12677 (uint32_t)imm; 12678 result = (int32_t)result; 12679 tcg_gen_movi_tl(cpu_gpr[ret], result); 12680 } 12681 break; 12682 case OPC_REPLV_QB: 12683 check_dsp(ctx); 12684 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t); 12685 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8); 12686 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 12687 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16); 12688 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 12689 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]); 12690 break; 12691 case OPC_REPL_PH: 12692 check_dsp(ctx); 12693 { 12694 imm = (ctx->opcode >> 16) & 0x03FF; 12695 imm = (int16_t)(imm << 6) >> 6; 12696 tcg_gen_movi_tl(cpu_gpr[ret], \ 12697 (target_long)((int32_t)imm << 16 | \ 12698 (uint16_t)imm)); 12699 } 12700 break; 12701 case OPC_REPLV_PH: 12702 check_dsp(ctx); 12703 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t); 12704 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16); 12705 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 12706 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]); 12707 break; 12708 } 12709 break; 12710 #ifdef TARGET_MIPS64 12711 case OPC_ABSQ_S_QH_DSP: 12712 switch (op2) { 12713 case OPC_REPL_OB: 12714 check_dsp(ctx); 12715 { 12716 target_long temp; 12717 12718 imm = (ctx->opcode >> 16) & 0xFF; 12719 temp = ((uint64_t)imm << 8) | (uint64_t)imm; 12720 temp = (temp << 16) | temp; 12721 temp = (temp << 32) | temp; 12722 tcg_gen_movi_tl(cpu_gpr[ret], temp); 12723 break; 12724 } 12725 case OPC_REPL_PW: 12726 check_dsp(ctx); 12727 { 12728 target_long temp; 12729 12730 imm = (ctx->opcode >> 16) & 0x03FF; 12731 imm = (int16_t)(imm << 6) >> 6; 12732 temp = ((target_long)imm << 32) \ 12733 | ((target_long)imm & 0xFFFFFFFF); 12734 tcg_gen_movi_tl(cpu_gpr[ret], temp); 12735 break; 12736 } 12737 case OPC_REPL_QH: 12738 check_dsp(ctx); 12739 { 12740 target_long temp; 12741 12742 imm = (ctx->opcode >> 16) & 0x03FF; 12743 imm = (int16_t)(imm << 6) >> 6; 12744 12745 temp = ((uint64_t)(uint16_t)imm << 48) | 12746 ((uint64_t)(uint16_t)imm << 32) | 12747 ((uint64_t)(uint16_t)imm << 16) | 12748 (uint64_t)(uint16_t)imm; 12749 tcg_gen_movi_tl(cpu_gpr[ret], temp); 12750 break; 12751 } 12752 case OPC_REPLV_OB: 12753 check_dsp(ctx); 12754 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t); 12755 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8); 12756 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 12757 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16); 12758 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 12759 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32); 12760 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 12761 break; 12762 case OPC_REPLV_PW: 12763 check_dsp(ctx); 12764 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t); 12765 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32); 12766 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 12767 break; 12768 case OPC_REPLV_QH: 12769 check_dsp(ctx); 12770 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t); 12771 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16); 12772 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 12773 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32); 12774 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 12775 break; 12776 } 12777 break; 12778 #endif 12779 } 12780 } 12781 12782 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx, 12783 uint32_t op1, uint32_t op2, 12784 int ret, int v1, int v2, int check_ret) 12785 { 12786 TCGv t1; 12787 TCGv v1_t; 12788 TCGv v2_t; 12789 12790 if ((ret == 0) && (check_ret == 1)) { 12791 /* Treat as NOP. */ 12792 return; 12793 } 12794 12795 t1 = tcg_temp_new(); 12796 v1_t = tcg_temp_new(); 12797 v2_t = tcg_temp_new(); 12798 12799 gen_load_gpr(v1_t, v1); 12800 gen_load_gpr(v2_t, v2); 12801 12802 switch (op1) { 12803 case OPC_CMPU_EQ_QB_DSP: 12804 switch (op2) { 12805 case OPC_CMPU_EQ_QB: 12806 check_dsp(ctx); 12807 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env); 12808 break; 12809 case OPC_CMPU_LT_QB: 12810 check_dsp(ctx); 12811 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env); 12812 break; 12813 case OPC_CMPU_LE_QB: 12814 check_dsp(ctx); 12815 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env); 12816 break; 12817 case OPC_CMPGU_EQ_QB: 12818 check_dsp(ctx); 12819 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t); 12820 break; 12821 case OPC_CMPGU_LT_QB: 12822 check_dsp(ctx); 12823 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t); 12824 break; 12825 case OPC_CMPGU_LE_QB: 12826 check_dsp(ctx); 12827 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t); 12828 break; 12829 case OPC_CMPGDU_EQ_QB: 12830 check_dsp_r2(ctx); 12831 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t); 12832 tcg_gen_mov_tl(cpu_gpr[ret], t1); 12833 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF); 12834 tcg_gen_shli_tl(t1, t1, 24); 12835 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1); 12836 break; 12837 case OPC_CMPGDU_LT_QB: 12838 check_dsp_r2(ctx); 12839 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t); 12840 tcg_gen_mov_tl(cpu_gpr[ret], t1); 12841 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF); 12842 tcg_gen_shli_tl(t1, t1, 24); 12843 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1); 12844 break; 12845 case OPC_CMPGDU_LE_QB: 12846 check_dsp_r2(ctx); 12847 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t); 12848 tcg_gen_mov_tl(cpu_gpr[ret], t1); 12849 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF); 12850 tcg_gen_shli_tl(t1, t1, 24); 12851 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1); 12852 break; 12853 case OPC_CMP_EQ_PH: 12854 check_dsp(ctx); 12855 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env); 12856 break; 12857 case OPC_CMP_LT_PH: 12858 check_dsp(ctx); 12859 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env); 12860 break; 12861 case OPC_CMP_LE_PH: 12862 check_dsp(ctx); 12863 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env); 12864 break; 12865 case OPC_PICK_QB: 12866 check_dsp(ctx); 12867 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12868 break; 12869 case OPC_PICK_PH: 12870 check_dsp(ctx); 12871 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12872 break; 12873 case OPC_PACKRL_PH: 12874 check_dsp(ctx); 12875 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t); 12876 break; 12877 } 12878 break; 12879 #ifdef TARGET_MIPS64 12880 case OPC_CMPU_EQ_OB_DSP: 12881 switch (op2) { 12882 case OPC_CMP_EQ_PW: 12883 check_dsp(ctx); 12884 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env); 12885 break; 12886 case OPC_CMP_LT_PW: 12887 check_dsp(ctx); 12888 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env); 12889 break; 12890 case OPC_CMP_LE_PW: 12891 check_dsp(ctx); 12892 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env); 12893 break; 12894 case OPC_CMP_EQ_QH: 12895 check_dsp(ctx); 12896 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env); 12897 break; 12898 case OPC_CMP_LT_QH: 12899 check_dsp(ctx); 12900 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env); 12901 break; 12902 case OPC_CMP_LE_QH: 12903 check_dsp(ctx); 12904 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env); 12905 break; 12906 case OPC_CMPGDU_EQ_OB: 12907 check_dsp_r2(ctx); 12908 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12909 break; 12910 case OPC_CMPGDU_LT_OB: 12911 check_dsp_r2(ctx); 12912 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12913 break; 12914 case OPC_CMPGDU_LE_OB: 12915 check_dsp_r2(ctx); 12916 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12917 break; 12918 case OPC_CMPGU_EQ_OB: 12919 check_dsp(ctx); 12920 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t); 12921 break; 12922 case OPC_CMPGU_LT_OB: 12923 check_dsp(ctx); 12924 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t); 12925 break; 12926 case OPC_CMPGU_LE_OB: 12927 check_dsp(ctx); 12928 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t); 12929 break; 12930 case OPC_CMPU_EQ_OB: 12931 check_dsp(ctx); 12932 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env); 12933 break; 12934 case OPC_CMPU_LT_OB: 12935 check_dsp(ctx); 12936 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env); 12937 break; 12938 case OPC_CMPU_LE_OB: 12939 check_dsp(ctx); 12940 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env); 12941 break; 12942 case OPC_PACKRL_PW: 12943 check_dsp(ctx); 12944 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t); 12945 break; 12946 case OPC_PICK_OB: 12947 check_dsp(ctx); 12948 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12949 break; 12950 case OPC_PICK_PW: 12951 check_dsp(ctx); 12952 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12953 break; 12954 case OPC_PICK_QH: 12955 check_dsp(ctx); 12956 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12957 break; 12958 } 12959 break; 12960 #endif 12961 } 12962 } 12963 12964 static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx, 12965 uint32_t op1, int rt, int rs, int sa) 12966 { 12967 TCGv t0; 12968 12969 check_dsp_r2(ctx); 12970 12971 if (rt == 0) { 12972 /* Treat as NOP. */ 12973 return; 12974 } 12975 12976 t0 = tcg_temp_new(); 12977 gen_load_gpr(t0, rs); 12978 12979 switch (op1) { 12980 case OPC_APPEND_DSP: 12981 switch (MASK_APPEND(ctx->opcode)) { 12982 case OPC_APPEND: 12983 if (sa != 0) { 12984 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa); 12985 } 12986 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 12987 break; 12988 case OPC_PREPEND: 12989 if (sa != 0) { 12990 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]); 12991 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa); 12992 tcg_gen_shli_tl(t0, t0, 32 - sa); 12993 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0); 12994 } 12995 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 12996 break; 12997 case OPC_BALIGN: 12998 sa &= 3; 12999 if (sa != 0 && sa != 2) { 13000 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa); 13001 tcg_gen_ext32u_tl(t0, t0); 13002 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa)); 13003 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0); 13004 } 13005 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 13006 break; 13007 default: /* Invalid */ 13008 MIPS_INVAL("MASK APPEND"); 13009 gen_reserved_instruction(ctx); 13010 break; 13011 } 13012 break; 13013 #ifdef TARGET_MIPS64 13014 case OPC_DAPPEND_DSP: 13015 switch (MASK_DAPPEND(ctx->opcode)) { 13016 case OPC_DAPPEND: 13017 if (sa != 0) { 13018 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa); 13019 } 13020 break; 13021 case OPC_PREPENDD: 13022 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa); 13023 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa)); 13024 tcg_gen_or_tl(cpu_gpr[rt], t0, t0); 13025 break; 13026 case OPC_PREPENDW: 13027 if (sa != 0) { 13028 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa); 13029 tcg_gen_shli_tl(t0, t0, 64 - sa); 13030 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0); 13031 } 13032 break; 13033 case OPC_DBALIGN: 13034 sa &= 7; 13035 if (sa != 0 && sa != 2 && sa != 4) { 13036 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa); 13037 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa)); 13038 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0); 13039 } 13040 break; 13041 default: /* Invalid */ 13042 MIPS_INVAL("MASK DAPPEND"); 13043 gen_reserved_instruction(ctx); 13044 break; 13045 } 13046 break; 13047 #endif 13048 } 13049 } 13050 13051 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2, 13052 int ret, int v1, int v2, int check_ret) 13053 13054 { 13055 TCGv t0; 13056 TCGv t1; 13057 TCGv v1_t; 13058 int16_t imm; 13059 13060 if ((ret == 0) && (check_ret == 1)) { 13061 /* Treat as NOP. */ 13062 return; 13063 } 13064 13065 t0 = tcg_temp_new(); 13066 t1 = tcg_temp_new(); 13067 v1_t = tcg_temp_new(); 13068 13069 gen_load_gpr(v1_t, v1); 13070 13071 switch (op1) { 13072 case OPC_EXTR_W_DSP: 13073 check_dsp(ctx); 13074 switch (op2) { 13075 case OPC_EXTR_W: 13076 tcg_gen_movi_tl(t0, v2); 13077 tcg_gen_movi_tl(t1, v1); 13078 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env); 13079 break; 13080 case OPC_EXTR_R_W: 13081 tcg_gen_movi_tl(t0, v2); 13082 tcg_gen_movi_tl(t1, v1); 13083 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env); 13084 break; 13085 case OPC_EXTR_RS_W: 13086 tcg_gen_movi_tl(t0, v2); 13087 tcg_gen_movi_tl(t1, v1); 13088 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env); 13089 break; 13090 case OPC_EXTR_S_H: 13091 tcg_gen_movi_tl(t0, v2); 13092 tcg_gen_movi_tl(t1, v1); 13093 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env); 13094 break; 13095 case OPC_EXTRV_S_H: 13096 tcg_gen_movi_tl(t0, v2); 13097 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env); 13098 break; 13099 case OPC_EXTRV_W: 13100 tcg_gen_movi_tl(t0, v2); 13101 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env); 13102 break; 13103 case OPC_EXTRV_R_W: 13104 tcg_gen_movi_tl(t0, v2); 13105 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env); 13106 break; 13107 case OPC_EXTRV_RS_W: 13108 tcg_gen_movi_tl(t0, v2); 13109 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env); 13110 break; 13111 case OPC_EXTP: 13112 tcg_gen_movi_tl(t0, v2); 13113 tcg_gen_movi_tl(t1, v1); 13114 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env); 13115 break; 13116 case OPC_EXTPV: 13117 tcg_gen_movi_tl(t0, v2); 13118 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env); 13119 break; 13120 case OPC_EXTPDP: 13121 tcg_gen_movi_tl(t0, v2); 13122 tcg_gen_movi_tl(t1, v1); 13123 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env); 13124 break; 13125 case OPC_EXTPDPV: 13126 tcg_gen_movi_tl(t0, v2); 13127 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env); 13128 break; 13129 case OPC_SHILO: 13130 imm = (ctx->opcode >> 20) & 0x3F; 13131 tcg_gen_movi_tl(t0, ret); 13132 tcg_gen_movi_tl(t1, imm); 13133 gen_helper_shilo(t0, t1, cpu_env); 13134 break; 13135 case OPC_SHILOV: 13136 tcg_gen_movi_tl(t0, ret); 13137 gen_helper_shilo(t0, v1_t, cpu_env); 13138 break; 13139 case OPC_MTHLIP: 13140 tcg_gen_movi_tl(t0, ret); 13141 gen_helper_mthlip(t0, v1_t, cpu_env); 13142 break; 13143 case OPC_WRDSP: 13144 imm = (ctx->opcode >> 11) & 0x3FF; 13145 tcg_gen_movi_tl(t0, imm); 13146 gen_helper_wrdsp(v1_t, t0, cpu_env); 13147 break; 13148 case OPC_RDDSP: 13149 imm = (ctx->opcode >> 16) & 0x03FF; 13150 tcg_gen_movi_tl(t0, imm); 13151 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env); 13152 break; 13153 } 13154 break; 13155 #ifdef TARGET_MIPS64 13156 case OPC_DEXTR_W_DSP: 13157 check_dsp(ctx); 13158 switch (op2) { 13159 case OPC_DMTHLIP: 13160 tcg_gen_movi_tl(t0, ret); 13161 gen_helper_dmthlip(v1_t, t0, cpu_env); 13162 break; 13163 case OPC_DSHILO: 13164 { 13165 int shift = (ctx->opcode >> 19) & 0x7F; 13166 int ac = (ctx->opcode >> 11) & 0x03; 13167 tcg_gen_movi_tl(t0, shift); 13168 tcg_gen_movi_tl(t1, ac); 13169 gen_helper_dshilo(t0, t1, cpu_env); 13170 break; 13171 } 13172 case OPC_DSHILOV: 13173 { 13174 int ac = (ctx->opcode >> 11) & 0x03; 13175 tcg_gen_movi_tl(t0, ac); 13176 gen_helper_dshilo(v1_t, t0, cpu_env); 13177 break; 13178 } 13179 case OPC_DEXTP: 13180 tcg_gen_movi_tl(t0, v2); 13181 tcg_gen_movi_tl(t1, v1); 13182 13183 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env); 13184 break; 13185 case OPC_DEXTPV: 13186 tcg_gen_movi_tl(t0, v2); 13187 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env); 13188 break; 13189 case OPC_DEXTPDP: 13190 tcg_gen_movi_tl(t0, v2); 13191 tcg_gen_movi_tl(t1, v1); 13192 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env); 13193 break; 13194 case OPC_DEXTPDPV: 13195 tcg_gen_movi_tl(t0, v2); 13196 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env); 13197 break; 13198 case OPC_DEXTR_L: 13199 tcg_gen_movi_tl(t0, v2); 13200 tcg_gen_movi_tl(t1, v1); 13201 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env); 13202 break; 13203 case OPC_DEXTR_R_L: 13204 tcg_gen_movi_tl(t0, v2); 13205 tcg_gen_movi_tl(t1, v1); 13206 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env); 13207 break; 13208 case OPC_DEXTR_RS_L: 13209 tcg_gen_movi_tl(t0, v2); 13210 tcg_gen_movi_tl(t1, v1); 13211 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env); 13212 break; 13213 case OPC_DEXTR_W: 13214 tcg_gen_movi_tl(t0, v2); 13215 tcg_gen_movi_tl(t1, v1); 13216 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env); 13217 break; 13218 case OPC_DEXTR_R_W: 13219 tcg_gen_movi_tl(t0, v2); 13220 tcg_gen_movi_tl(t1, v1); 13221 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env); 13222 break; 13223 case OPC_DEXTR_RS_W: 13224 tcg_gen_movi_tl(t0, v2); 13225 tcg_gen_movi_tl(t1, v1); 13226 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env); 13227 break; 13228 case OPC_DEXTR_S_H: 13229 tcg_gen_movi_tl(t0, v2); 13230 tcg_gen_movi_tl(t1, v1); 13231 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env); 13232 break; 13233 case OPC_DEXTRV_S_H: 13234 tcg_gen_movi_tl(t0, v2); 13235 gen_helper_dextr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env); 13236 break; 13237 case OPC_DEXTRV_L: 13238 tcg_gen_movi_tl(t0, v2); 13239 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env); 13240 break; 13241 case OPC_DEXTRV_R_L: 13242 tcg_gen_movi_tl(t0, v2); 13243 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env); 13244 break; 13245 case OPC_DEXTRV_RS_L: 13246 tcg_gen_movi_tl(t0, v2); 13247 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env); 13248 break; 13249 case OPC_DEXTRV_W: 13250 tcg_gen_movi_tl(t0, v2); 13251 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env); 13252 break; 13253 case OPC_DEXTRV_R_W: 13254 tcg_gen_movi_tl(t0, v2); 13255 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env); 13256 break; 13257 case OPC_DEXTRV_RS_W: 13258 tcg_gen_movi_tl(t0, v2); 13259 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env); 13260 break; 13261 } 13262 break; 13263 #endif 13264 } 13265 } 13266 13267 /* End MIPSDSP functions. */ 13268 13269 static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx) 13270 { 13271 int rs, rt, rd, sa; 13272 uint32_t op1, op2; 13273 13274 rs = (ctx->opcode >> 21) & 0x1f; 13275 rt = (ctx->opcode >> 16) & 0x1f; 13276 rd = (ctx->opcode >> 11) & 0x1f; 13277 sa = (ctx->opcode >> 6) & 0x1f; 13278 13279 op1 = MASK_SPECIAL(ctx->opcode); 13280 switch (op1) { 13281 case OPC_MULT: 13282 case OPC_MULTU: 13283 case OPC_DIV: 13284 case OPC_DIVU: 13285 op2 = MASK_R6_MULDIV(ctx->opcode); 13286 switch (op2) { 13287 case R6_OPC_MUL: 13288 case R6_OPC_MUH: 13289 case R6_OPC_MULU: 13290 case R6_OPC_MUHU: 13291 case R6_OPC_DIV: 13292 case R6_OPC_MOD: 13293 case R6_OPC_DIVU: 13294 case R6_OPC_MODU: 13295 gen_r6_muldiv(ctx, op2, rd, rs, rt); 13296 break; 13297 default: 13298 MIPS_INVAL("special_r6 muldiv"); 13299 gen_reserved_instruction(ctx); 13300 break; 13301 } 13302 break; 13303 case OPC_SELEQZ: 13304 case OPC_SELNEZ: 13305 gen_cond_move(ctx, op1, rd, rs, rt); 13306 break; 13307 case R6_OPC_CLO: 13308 case R6_OPC_CLZ: 13309 if (rt == 0 && sa == 1) { 13310 /* 13311 * Major opcode and function field is shared with preR6 MFHI/MTHI. 13312 * We need additionally to check other fields. 13313 */ 13314 gen_cl(ctx, op1, rd, rs); 13315 } else { 13316 gen_reserved_instruction(ctx); 13317 } 13318 break; 13319 case R6_OPC_SDBBP: 13320 if (is_uhi(ctx, extract32(ctx->opcode, 6, 20))) { 13321 ctx->base.is_jmp = DISAS_SEMIHOST; 13322 } else { 13323 if (ctx->hflags & MIPS_HFLAG_SBRI) { 13324 gen_reserved_instruction(ctx); 13325 } else { 13326 generate_exception_end(ctx, EXCP_DBp); 13327 } 13328 } 13329 break; 13330 #if defined(TARGET_MIPS64) 13331 case R6_OPC_DCLO: 13332 case R6_OPC_DCLZ: 13333 if (rt == 0 && sa == 1) { 13334 /* 13335 * Major opcode and function field is shared with preR6 MFHI/MTHI. 13336 * We need additionally to check other fields. 13337 */ 13338 check_mips_64(ctx); 13339 gen_cl(ctx, op1, rd, rs); 13340 } else { 13341 gen_reserved_instruction(ctx); 13342 } 13343 break; 13344 case OPC_DMULT: 13345 case OPC_DMULTU: 13346 case OPC_DDIV: 13347 case OPC_DDIVU: 13348 13349 op2 = MASK_R6_MULDIV(ctx->opcode); 13350 switch (op2) { 13351 case R6_OPC_DMUL: 13352 case R6_OPC_DMUH: 13353 case R6_OPC_DMULU: 13354 case R6_OPC_DMUHU: 13355 case R6_OPC_DDIV: 13356 case R6_OPC_DMOD: 13357 case R6_OPC_DDIVU: 13358 case R6_OPC_DMODU: 13359 check_mips_64(ctx); 13360 gen_r6_muldiv(ctx, op2, rd, rs, rt); 13361 break; 13362 default: 13363 MIPS_INVAL("special_r6 muldiv"); 13364 gen_reserved_instruction(ctx); 13365 break; 13366 } 13367 break; 13368 #endif 13369 default: /* Invalid */ 13370 MIPS_INVAL("special_r6"); 13371 gen_reserved_instruction(ctx); 13372 break; 13373 } 13374 } 13375 13376 static void decode_opc_special_tx79(CPUMIPSState *env, DisasContext *ctx) 13377 { 13378 int rs = extract32(ctx->opcode, 21, 5); 13379 int rt = extract32(ctx->opcode, 16, 5); 13380 int rd = extract32(ctx->opcode, 11, 5); 13381 uint32_t op1 = MASK_SPECIAL(ctx->opcode); 13382 13383 switch (op1) { 13384 case OPC_MOVN: /* Conditional move */ 13385 case OPC_MOVZ: 13386 gen_cond_move(ctx, op1, rd, rs, rt); 13387 break; 13388 case OPC_MFHI: /* Move from HI/LO */ 13389 case OPC_MFLO: 13390 gen_HILO(ctx, op1, 0, rd); 13391 break; 13392 case OPC_MTHI: 13393 case OPC_MTLO: /* Move to HI/LO */ 13394 gen_HILO(ctx, op1, 0, rs); 13395 break; 13396 case OPC_MULT: 13397 case OPC_MULTU: 13398 gen_mul_txx9(ctx, op1, rd, rs, rt); 13399 break; 13400 case OPC_DIV: 13401 case OPC_DIVU: 13402 gen_muldiv(ctx, op1, 0, rs, rt); 13403 break; 13404 #if defined(TARGET_MIPS64) 13405 case OPC_DMULT: 13406 case OPC_DMULTU: 13407 case OPC_DDIV: 13408 case OPC_DDIVU: 13409 check_insn_opc_user_only(ctx, INSN_R5900); 13410 gen_muldiv(ctx, op1, 0, rs, rt); 13411 break; 13412 #endif 13413 case OPC_JR: 13414 gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4); 13415 break; 13416 default: /* Invalid */ 13417 MIPS_INVAL("special_tx79"); 13418 gen_reserved_instruction(ctx); 13419 break; 13420 } 13421 } 13422 13423 static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx) 13424 { 13425 int rs, rt, rd; 13426 uint32_t op1; 13427 13428 rs = (ctx->opcode >> 21) & 0x1f; 13429 rt = (ctx->opcode >> 16) & 0x1f; 13430 rd = (ctx->opcode >> 11) & 0x1f; 13431 13432 op1 = MASK_SPECIAL(ctx->opcode); 13433 switch (op1) { 13434 case OPC_MOVN: /* Conditional move */ 13435 case OPC_MOVZ: 13436 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1 | 13437 INSN_LOONGSON2E | INSN_LOONGSON2F); 13438 gen_cond_move(ctx, op1, rd, rs, rt); 13439 break; 13440 case OPC_MFHI: /* Move from HI/LO */ 13441 case OPC_MFLO: 13442 gen_HILO(ctx, op1, rs & 3, rd); 13443 break; 13444 case OPC_MTHI: 13445 case OPC_MTLO: /* Move to HI/LO */ 13446 gen_HILO(ctx, op1, rd & 3, rs); 13447 break; 13448 case OPC_MOVCI: 13449 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1); 13450 if (env->CP0_Config1 & (1 << CP0C1_FP)) { 13451 check_cp1_enabled(ctx); 13452 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7, 13453 (ctx->opcode >> 16) & 1); 13454 } else { 13455 generate_exception_err(ctx, EXCP_CpU, 1); 13456 } 13457 break; 13458 case OPC_MULT: 13459 case OPC_MULTU: 13460 gen_muldiv(ctx, op1, rd & 3, rs, rt); 13461 break; 13462 case OPC_DIV: 13463 case OPC_DIVU: 13464 gen_muldiv(ctx, op1, 0, rs, rt); 13465 break; 13466 #if defined(TARGET_MIPS64) 13467 case OPC_DMULT: 13468 case OPC_DMULTU: 13469 case OPC_DDIV: 13470 case OPC_DDIVU: 13471 check_insn(ctx, ISA_MIPS3); 13472 check_mips_64(ctx); 13473 gen_muldiv(ctx, op1, 0, rs, rt); 13474 break; 13475 #endif 13476 case OPC_JR: 13477 gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4); 13478 break; 13479 case OPC_SPIM: 13480 #ifdef MIPS_STRICT_STANDARD 13481 MIPS_INVAL("SPIM"); 13482 gen_reserved_instruction(ctx); 13483 #else 13484 /* Implemented as RI exception for now. */ 13485 MIPS_INVAL("spim (unofficial)"); 13486 gen_reserved_instruction(ctx); 13487 #endif 13488 break; 13489 default: /* Invalid */ 13490 MIPS_INVAL("special_legacy"); 13491 gen_reserved_instruction(ctx); 13492 break; 13493 } 13494 } 13495 13496 static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx) 13497 { 13498 int rs, rt, rd, sa; 13499 uint32_t op1; 13500 13501 rs = (ctx->opcode >> 21) & 0x1f; 13502 rt = (ctx->opcode >> 16) & 0x1f; 13503 rd = (ctx->opcode >> 11) & 0x1f; 13504 sa = (ctx->opcode >> 6) & 0x1f; 13505 13506 op1 = MASK_SPECIAL(ctx->opcode); 13507 switch (op1) { 13508 case OPC_SLL: /* Shift with immediate */ 13509 if (sa == 5 && rd == 0 && 13510 rs == 0 && rt == 0) { /* PAUSE */ 13511 if ((ctx->insn_flags & ISA_MIPS_R6) && 13512 (ctx->hflags & MIPS_HFLAG_BMASK)) { 13513 gen_reserved_instruction(ctx); 13514 break; 13515 } 13516 } 13517 /* Fallthrough */ 13518 case OPC_SRA: 13519 gen_shift_imm(ctx, op1, rd, rt, sa); 13520 break; 13521 case OPC_SRL: 13522 switch ((ctx->opcode >> 21) & 0x1f) { 13523 case 1: 13524 /* rotr is decoded as srl on non-R2 CPUs */ 13525 if (ctx->insn_flags & ISA_MIPS_R2) { 13526 op1 = OPC_ROTR; 13527 } 13528 /* Fallthrough */ 13529 case 0: 13530 gen_shift_imm(ctx, op1, rd, rt, sa); 13531 break; 13532 default: 13533 gen_reserved_instruction(ctx); 13534 break; 13535 } 13536 break; 13537 case OPC_ADD: 13538 case OPC_ADDU: 13539 case OPC_SUB: 13540 case OPC_SUBU: 13541 gen_arith(ctx, op1, rd, rs, rt); 13542 break; 13543 case OPC_SLLV: /* Shifts */ 13544 case OPC_SRAV: 13545 gen_shift(ctx, op1, rd, rs, rt); 13546 break; 13547 case OPC_SRLV: 13548 switch ((ctx->opcode >> 6) & 0x1f) { 13549 case 1: 13550 /* rotrv is decoded as srlv on non-R2 CPUs */ 13551 if (ctx->insn_flags & ISA_MIPS_R2) { 13552 op1 = OPC_ROTRV; 13553 } 13554 /* Fallthrough */ 13555 case 0: 13556 gen_shift(ctx, op1, rd, rs, rt); 13557 break; 13558 default: 13559 gen_reserved_instruction(ctx); 13560 break; 13561 } 13562 break; 13563 case OPC_SLT: /* Set on less than */ 13564 case OPC_SLTU: 13565 gen_slt(ctx, op1, rd, rs, rt); 13566 break; 13567 case OPC_AND: /* Logic*/ 13568 case OPC_OR: 13569 case OPC_NOR: 13570 case OPC_XOR: 13571 gen_logic(ctx, op1, rd, rs, rt); 13572 break; 13573 case OPC_JALR: 13574 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4); 13575 break; 13576 case OPC_TGE: /* Traps */ 13577 case OPC_TGEU: 13578 case OPC_TLT: 13579 case OPC_TLTU: 13580 case OPC_TEQ: 13581 case OPC_TNE: 13582 check_insn(ctx, ISA_MIPS2); 13583 gen_trap(ctx, op1, rs, rt, -1, extract32(ctx->opcode, 6, 10)); 13584 break; 13585 case OPC_PMON: 13586 /* Pmon entry point, also R4010 selsl */ 13587 #ifdef MIPS_STRICT_STANDARD 13588 MIPS_INVAL("PMON / selsl"); 13589 gen_reserved_instruction(ctx); 13590 #else 13591 gen_helper_pmon(cpu_env, tcg_constant_i32(sa)); 13592 #endif 13593 break; 13594 case OPC_SYSCALL: 13595 generate_exception_end(ctx, EXCP_SYSCALL); 13596 break; 13597 case OPC_BREAK: 13598 generate_exception_break(ctx, extract32(ctx->opcode, 6, 20)); 13599 break; 13600 case OPC_SYNC: 13601 check_insn(ctx, ISA_MIPS2); 13602 gen_sync(extract32(ctx->opcode, 6, 5)); 13603 break; 13604 13605 #if defined(TARGET_MIPS64) 13606 /* MIPS64 specific opcodes */ 13607 case OPC_DSLL: 13608 case OPC_DSRA: 13609 case OPC_DSLL32: 13610 case OPC_DSRA32: 13611 check_insn(ctx, ISA_MIPS3); 13612 check_mips_64(ctx); 13613 gen_shift_imm(ctx, op1, rd, rt, sa); 13614 break; 13615 case OPC_DSRL: 13616 switch ((ctx->opcode >> 21) & 0x1f) { 13617 case 1: 13618 /* drotr is decoded as dsrl on non-R2 CPUs */ 13619 if (ctx->insn_flags & ISA_MIPS_R2) { 13620 op1 = OPC_DROTR; 13621 } 13622 /* Fallthrough */ 13623 case 0: 13624 check_insn(ctx, ISA_MIPS3); 13625 check_mips_64(ctx); 13626 gen_shift_imm(ctx, op1, rd, rt, sa); 13627 break; 13628 default: 13629 gen_reserved_instruction(ctx); 13630 break; 13631 } 13632 break; 13633 case OPC_DSRL32: 13634 switch ((ctx->opcode >> 21) & 0x1f) { 13635 case 1: 13636 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */ 13637 if (ctx->insn_flags & ISA_MIPS_R2) { 13638 op1 = OPC_DROTR32; 13639 } 13640 /* Fallthrough */ 13641 case 0: 13642 check_insn(ctx, ISA_MIPS3); 13643 check_mips_64(ctx); 13644 gen_shift_imm(ctx, op1, rd, rt, sa); 13645 break; 13646 default: 13647 gen_reserved_instruction(ctx); 13648 break; 13649 } 13650 break; 13651 case OPC_DADD: 13652 case OPC_DADDU: 13653 case OPC_DSUB: 13654 case OPC_DSUBU: 13655 check_insn(ctx, ISA_MIPS3); 13656 check_mips_64(ctx); 13657 gen_arith(ctx, op1, rd, rs, rt); 13658 break; 13659 case OPC_DSLLV: 13660 case OPC_DSRAV: 13661 check_insn(ctx, ISA_MIPS3); 13662 check_mips_64(ctx); 13663 gen_shift(ctx, op1, rd, rs, rt); 13664 break; 13665 case OPC_DSRLV: 13666 switch ((ctx->opcode >> 6) & 0x1f) { 13667 case 1: 13668 /* drotrv is decoded as dsrlv on non-R2 CPUs */ 13669 if (ctx->insn_flags & ISA_MIPS_R2) { 13670 op1 = OPC_DROTRV; 13671 } 13672 /* Fallthrough */ 13673 case 0: 13674 check_insn(ctx, ISA_MIPS3); 13675 check_mips_64(ctx); 13676 gen_shift(ctx, op1, rd, rs, rt); 13677 break; 13678 default: 13679 gen_reserved_instruction(ctx); 13680 break; 13681 } 13682 break; 13683 #endif 13684 default: 13685 if (ctx->insn_flags & ISA_MIPS_R6) { 13686 decode_opc_special_r6(env, ctx); 13687 } else if (ctx->insn_flags & INSN_R5900) { 13688 decode_opc_special_tx79(env, ctx); 13689 } else { 13690 decode_opc_special_legacy(env, ctx); 13691 } 13692 } 13693 } 13694 13695 13696 static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx) 13697 { 13698 int rs, rt, rd; 13699 uint32_t op1; 13700 13701 rs = (ctx->opcode >> 21) & 0x1f; 13702 rt = (ctx->opcode >> 16) & 0x1f; 13703 rd = (ctx->opcode >> 11) & 0x1f; 13704 13705 op1 = MASK_SPECIAL2(ctx->opcode); 13706 switch (op1) { 13707 case OPC_MADD: /* Multiply and add/sub */ 13708 case OPC_MADDU: 13709 case OPC_MSUB: 13710 case OPC_MSUBU: 13711 check_insn(ctx, ISA_MIPS_R1); 13712 gen_muldiv(ctx, op1, rd & 3, rs, rt); 13713 break; 13714 case OPC_MUL: 13715 gen_arith(ctx, op1, rd, rs, rt); 13716 break; 13717 case OPC_DIV_G_2F: 13718 case OPC_DIVU_G_2F: 13719 case OPC_MULT_G_2F: 13720 case OPC_MULTU_G_2F: 13721 case OPC_MOD_G_2F: 13722 case OPC_MODU_G_2F: 13723 check_insn(ctx, INSN_LOONGSON2F | ASE_LEXT); 13724 gen_loongson_integer(ctx, op1, rd, rs, rt); 13725 break; 13726 case OPC_CLO: 13727 case OPC_CLZ: 13728 check_insn(ctx, ISA_MIPS_R1); 13729 gen_cl(ctx, op1, rd, rs); 13730 break; 13731 case OPC_SDBBP: 13732 if (is_uhi(ctx, extract32(ctx->opcode, 6, 20))) { 13733 ctx->base.is_jmp = DISAS_SEMIHOST; 13734 } else { 13735 /* 13736 * XXX: not clear which exception should be raised 13737 * when in debug mode... 13738 */ 13739 check_insn(ctx, ISA_MIPS_R1); 13740 generate_exception_end(ctx, EXCP_DBp); 13741 } 13742 break; 13743 #if defined(TARGET_MIPS64) 13744 case OPC_DCLO: 13745 case OPC_DCLZ: 13746 check_insn(ctx, ISA_MIPS_R1); 13747 check_mips_64(ctx); 13748 gen_cl(ctx, op1, rd, rs); 13749 break; 13750 case OPC_DMULT_G_2F: 13751 case OPC_DMULTU_G_2F: 13752 case OPC_DDIV_G_2F: 13753 case OPC_DDIVU_G_2F: 13754 case OPC_DMOD_G_2F: 13755 case OPC_DMODU_G_2F: 13756 check_insn(ctx, INSN_LOONGSON2F | ASE_LEXT); 13757 gen_loongson_integer(ctx, op1, rd, rs, rt); 13758 break; 13759 #endif 13760 default: /* Invalid */ 13761 MIPS_INVAL("special2_legacy"); 13762 gen_reserved_instruction(ctx); 13763 break; 13764 } 13765 } 13766 13767 static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx) 13768 { 13769 int rs, rt, rd, sa; 13770 uint32_t op1, op2; 13771 int16_t imm; 13772 13773 rs = (ctx->opcode >> 21) & 0x1f; 13774 rt = (ctx->opcode >> 16) & 0x1f; 13775 rd = (ctx->opcode >> 11) & 0x1f; 13776 sa = (ctx->opcode >> 6) & 0x1f; 13777 imm = (int16_t)ctx->opcode >> 7; 13778 13779 op1 = MASK_SPECIAL3(ctx->opcode); 13780 switch (op1) { 13781 case R6_OPC_PREF: 13782 if (rt >= 24) { 13783 /* hint codes 24-31 are reserved and signal RI */ 13784 gen_reserved_instruction(ctx); 13785 } 13786 /* Treat as NOP. */ 13787 break; 13788 case R6_OPC_CACHE: 13789 check_cp0_enabled(ctx); 13790 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) { 13791 gen_cache_operation(ctx, rt, rs, imm); 13792 } 13793 break; 13794 case R6_OPC_SC: 13795 gen_st_cond(ctx, rt, rs, imm, MO_TESL, false); 13796 break; 13797 case R6_OPC_LL: 13798 gen_ld(ctx, op1, rt, rs, imm); 13799 break; 13800 case OPC_BSHFL: 13801 { 13802 if (rd == 0) { 13803 /* Treat as NOP. */ 13804 break; 13805 } 13806 op2 = MASK_BSHFL(ctx->opcode); 13807 switch (op2) { 13808 case OPC_ALIGN: 13809 case OPC_ALIGN_1: 13810 case OPC_ALIGN_2: 13811 case OPC_ALIGN_3: 13812 gen_align(ctx, 32, rd, rs, rt, sa & 3); 13813 break; 13814 case OPC_BITSWAP: 13815 gen_bitswap(ctx, op2, rd, rt); 13816 break; 13817 } 13818 } 13819 break; 13820 #ifndef CONFIG_USER_ONLY 13821 case OPC_GINV: 13822 if (unlikely(ctx->gi <= 1)) { 13823 gen_reserved_instruction(ctx); 13824 } 13825 check_cp0_enabled(ctx); 13826 switch ((ctx->opcode >> 6) & 3) { 13827 case 0: /* GINVI */ 13828 /* Treat as NOP. */ 13829 break; 13830 case 2: /* GINVT */ 13831 gen_helper_0e1i(ginvt, cpu_gpr[rs], extract32(ctx->opcode, 8, 2)); 13832 break; 13833 default: 13834 gen_reserved_instruction(ctx); 13835 break; 13836 } 13837 break; 13838 #endif 13839 #if defined(TARGET_MIPS64) 13840 case R6_OPC_SCD: 13841 gen_st_cond(ctx, rt, rs, imm, MO_TEUQ, false); 13842 break; 13843 case R6_OPC_LLD: 13844 gen_ld(ctx, op1, rt, rs, imm); 13845 break; 13846 case OPC_DBSHFL: 13847 check_mips_64(ctx); 13848 { 13849 if (rd == 0) { 13850 /* Treat as NOP. */ 13851 break; 13852 } 13853 op2 = MASK_DBSHFL(ctx->opcode); 13854 switch (op2) { 13855 case OPC_DALIGN: 13856 case OPC_DALIGN_1: 13857 case OPC_DALIGN_2: 13858 case OPC_DALIGN_3: 13859 case OPC_DALIGN_4: 13860 case OPC_DALIGN_5: 13861 case OPC_DALIGN_6: 13862 case OPC_DALIGN_7: 13863 gen_align(ctx, 64, rd, rs, rt, sa & 7); 13864 break; 13865 case OPC_DBITSWAP: 13866 gen_bitswap(ctx, op2, rd, rt); 13867 break; 13868 } 13869 13870 } 13871 break; 13872 #endif 13873 default: /* Invalid */ 13874 MIPS_INVAL("special3_r6"); 13875 gen_reserved_instruction(ctx); 13876 break; 13877 } 13878 } 13879 13880 static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx) 13881 { 13882 int rs, rt, rd; 13883 uint32_t op1, op2; 13884 13885 rs = (ctx->opcode >> 21) & 0x1f; 13886 rt = (ctx->opcode >> 16) & 0x1f; 13887 rd = (ctx->opcode >> 11) & 0x1f; 13888 13889 op1 = MASK_SPECIAL3(ctx->opcode); 13890 switch (op1) { 13891 case OPC_DIV_G_2E: 13892 case OPC_DIVU_G_2E: 13893 case OPC_MOD_G_2E: 13894 case OPC_MODU_G_2E: 13895 case OPC_MULT_G_2E: 13896 case OPC_MULTU_G_2E: 13897 /* 13898 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have 13899 * the same mask and op1. 13900 */ 13901 if ((ctx->insn_flags & ASE_DSP_R2) && (op1 == OPC_MULT_G_2E)) { 13902 op2 = MASK_ADDUH_QB(ctx->opcode); 13903 switch (op2) { 13904 case OPC_ADDUH_QB: 13905 case OPC_ADDUH_R_QB: 13906 case OPC_ADDQH_PH: 13907 case OPC_ADDQH_R_PH: 13908 case OPC_ADDQH_W: 13909 case OPC_ADDQH_R_W: 13910 case OPC_SUBUH_QB: 13911 case OPC_SUBUH_R_QB: 13912 case OPC_SUBQH_PH: 13913 case OPC_SUBQH_R_PH: 13914 case OPC_SUBQH_W: 13915 case OPC_SUBQH_R_W: 13916 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 13917 break; 13918 case OPC_MUL_PH: 13919 case OPC_MUL_S_PH: 13920 case OPC_MULQ_S_W: 13921 case OPC_MULQ_RS_W: 13922 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1); 13923 break; 13924 default: 13925 MIPS_INVAL("MASK ADDUH.QB"); 13926 gen_reserved_instruction(ctx); 13927 break; 13928 } 13929 } else if (ctx->insn_flags & INSN_LOONGSON2E) { 13930 gen_loongson_integer(ctx, op1, rd, rs, rt); 13931 } else { 13932 gen_reserved_instruction(ctx); 13933 } 13934 break; 13935 case OPC_LX_DSP: 13936 op2 = MASK_LX(ctx->opcode); 13937 switch (op2) { 13938 #if defined(TARGET_MIPS64) 13939 case OPC_LDX: 13940 #endif 13941 case OPC_LBUX: 13942 case OPC_LHX: 13943 case OPC_LWX: 13944 gen_mips_lx(ctx, op2, rd, rs, rt); 13945 break; 13946 default: /* Invalid */ 13947 MIPS_INVAL("MASK LX"); 13948 gen_reserved_instruction(ctx); 13949 break; 13950 } 13951 break; 13952 case OPC_ABSQ_S_PH_DSP: 13953 op2 = MASK_ABSQ_S_PH(ctx->opcode); 13954 switch (op2) { 13955 case OPC_ABSQ_S_QB: 13956 case OPC_ABSQ_S_PH: 13957 case OPC_ABSQ_S_W: 13958 case OPC_PRECEQ_W_PHL: 13959 case OPC_PRECEQ_W_PHR: 13960 case OPC_PRECEQU_PH_QBL: 13961 case OPC_PRECEQU_PH_QBR: 13962 case OPC_PRECEQU_PH_QBLA: 13963 case OPC_PRECEQU_PH_QBRA: 13964 case OPC_PRECEU_PH_QBL: 13965 case OPC_PRECEU_PH_QBR: 13966 case OPC_PRECEU_PH_QBLA: 13967 case OPC_PRECEU_PH_QBRA: 13968 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 13969 break; 13970 case OPC_BITREV: 13971 case OPC_REPL_QB: 13972 case OPC_REPLV_QB: 13973 case OPC_REPL_PH: 13974 case OPC_REPLV_PH: 13975 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt); 13976 break; 13977 default: 13978 MIPS_INVAL("MASK ABSQ_S.PH"); 13979 gen_reserved_instruction(ctx); 13980 break; 13981 } 13982 break; 13983 case OPC_ADDU_QB_DSP: 13984 op2 = MASK_ADDU_QB(ctx->opcode); 13985 switch (op2) { 13986 case OPC_ADDQ_PH: 13987 case OPC_ADDQ_S_PH: 13988 case OPC_ADDQ_S_W: 13989 case OPC_ADDU_QB: 13990 case OPC_ADDU_S_QB: 13991 case OPC_ADDU_PH: 13992 case OPC_ADDU_S_PH: 13993 case OPC_SUBQ_PH: 13994 case OPC_SUBQ_S_PH: 13995 case OPC_SUBQ_S_W: 13996 case OPC_SUBU_QB: 13997 case OPC_SUBU_S_QB: 13998 case OPC_SUBU_PH: 13999 case OPC_SUBU_S_PH: 14000 case OPC_ADDSC: 14001 case OPC_ADDWC: 14002 case OPC_MODSUB: 14003 case OPC_RADDU_W_QB: 14004 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 14005 break; 14006 case OPC_MULEU_S_PH_QBL: 14007 case OPC_MULEU_S_PH_QBR: 14008 case OPC_MULQ_RS_PH: 14009 case OPC_MULEQ_S_W_PHL: 14010 case OPC_MULEQ_S_W_PHR: 14011 case OPC_MULQ_S_PH: 14012 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1); 14013 break; 14014 default: /* Invalid */ 14015 MIPS_INVAL("MASK ADDU.QB"); 14016 gen_reserved_instruction(ctx); 14017 break; 14018 14019 } 14020 break; 14021 case OPC_CMPU_EQ_QB_DSP: 14022 op2 = MASK_CMPU_EQ_QB(ctx->opcode); 14023 switch (op2) { 14024 case OPC_PRECR_SRA_PH_W: 14025 case OPC_PRECR_SRA_R_PH_W: 14026 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd); 14027 break; 14028 case OPC_PRECR_QB_PH: 14029 case OPC_PRECRQ_QB_PH: 14030 case OPC_PRECRQ_PH_W: 14031 case OPC_PRECRQ_RS_PH_W: 14032 case OPC_PRECRQU_S_QB_PH: 14033 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 14034 break; 14035 case OPC_CMPU_EQ_QB: 14036 case OPC_CMPU_LT_QB: 14037 case OPC_CMPU_LE_QB: 14038 case OPC_CMP_EQ_PH: 14039 case OPC_CMP_LT_PH: 14040 case OPC_CMP_LE_PH: 14041 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0); 14042 break; 14043 case OPC_CMPGU_EQ_QB: 14044 case OPC_CMPGU_LT_QB: 14045 case OPC_CMPGU_LE_QB: 14046 case OPC_CMPGDU_EQ_QB: 14047 case OPC_CMPGDU_LT_QB: 14048 case OPC_CMPGDU_LE_QB: 14049 case OPC_PICK_QB: 14050 case OPC_PICK_PH: 14051 case OPC_PACKRL_PH: 14052 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1); 14053 break; 14054 default: /* Invalid */ 14055 MIPS_INVAL("MASK CMPU.EQ.QB"); 14056 gen_reserved_instruction(ctx); 14057 break; 14058 } 14059 break; 14060 case OPC_SHLL_QB_DSP: 14061 gen_mipsdsp_shift(ctx, op1, rd, rs, rt); 14062 break; 14063 case OPC_DPA_W_PH_DSP: 14064 op2 = MASK_DPA_W_PH(ctx->opcode); 14065 switch (op2) { 14066 case OPC_DPAU_H_QBL: 14067 case OPC_DPAU_H_QBR: 14068 case OPC_DPSU_H_QBL: 14069 case OPC_DPSU_H_QBR: 14070 case OPC_DPA_W_PH: 14071 case OPC_DPAX_W_PH: 14072 case OPC_DPAQ_S_W_PH: 14073 case OPC_DPAQX_S_W_PH: 14074 case OPC_DPAQX_SA_W_PH: 14075 case OPC_DPS_W_PH: 14076 case OPC_DPSX_W_PH: 14077 case OPC_DPSQ_S_W_PH: 14078 case OPC_DPSQX_S_W_PH: 14079 case OPC_DPSQX_SA_W_PH: 14080 case OPC_MULSAQ_S_W_PH: 14081 case OPC_DPAQ_SA_L_W: 14082 case OPC_DPSQ_SA_L_W: 14083 case OPC_MAQ_S_W_PHL: 14084 case OPC_MAQ_S_W_PHR: 14085 case OPC_MAQ_SA_W_PHL: 14086 case OPC_MAQ_SA_W_PHR: 14087 case OPC_MULSA_W_PH: 14088 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0); 14089 break; 14090 default: /* Invalid */ 14091 MIPS_INVAL("MASK DPAW.PH"); 14092 gen_reserved_instruction(ctx); 14093 break; 14094 } 14095 break; 14096 case OPC_INSV_DSP: 14097 op2 = MASK_INSV(ctx->opcode); 14098 switch (op2) { 14099 case OPC_INSV: 14100 check_dsp(ctx); 14101 { 14102 TCGv t0, t1; 14103 14104 if (rt == 0) { 14105 break; 14106 } 14107 14108 t0 = tcg_temp_new(); 14109 t1 = tcg_temp_new(); 14110 14111 gen_load_gpr(t0, rt); 14112 gen_load_gpr(t1, rs); 14113 14114 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0); 14115 break; 14116 } 14117 default: /* Invalid */ 14118 MIPS_INVAL("MASK INSV"); 14119 gen_reserved_instruction(ctx); 14120 break; 14121 } 14122 break; 14123 case OPC_APPEND_DSP: 14124 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd); 14125 break; 14126 case OPC_EXTR_W_DSP: 14127 op2 = MASK_EXTR_W(ctx->opcode); 14128 switch (op2) { 14129 case OPC_EXTR_W: 14130 case OPC_EXTR_R_W: 14131 case OPC_EXTR_RS_W: 14132 case OPC_EXTR_S_H: 14133 case OPC_EXTRV_S_H: 14134 case OPC_EXTRV_W: 14135 case OPC_EXTRV_R_W: 14136 case OPC_EXTRV_RS_W: 14137 case OPC_EXTP: 14138 case OPC_EXTPV: 14139 case OPC_EXTPDP: 14140 case OPC_EXTPDPV: 14141 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1); 14142 break; 14143 case OPC_RDDSP: 14144 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1); 14145 break; 14146 case OPC_SHILO: 14147 case OPC_SHILOV: 14148 case OPC_MTHLIP: 14149 case OPC_WRDSP: 14150 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0); 14151 break; 14152 default: /* Invalid */ 14153 MIPS_INVAL("MASK EXTR.W"); 14154 gen_reserved_instruction(ctx); 14155 break; 14156 } 14157 break; 14158 #if defined(TARGET_MIPS64) 14159 case OPC_DDIV_G_2E: 14160 case OPC_DDIVU_G_2E: 14161 case OPC_DMULT_G_2E: 14162 case OPC_DMULTU_G_2E: 14163 case OPC_DMOD_G_2E: 14164 case OPC_DMODU_G_2E: 14165 check_insn(ctx, INSN_LOONGSON2E); 14166 gen_loongson_integer(ctx, op1, rd, rs, rt); 14167 break; 14168 case OPC_ABSQ_S_QH_DSP: 14169 op2 = MASK_ABSQ_S_QH(ctx->opcode); 14170 switch (op2) { 14171 case OPC_PRECEQ_L_PWL: 14172 case OPC_PRECEQ_L_PWR: 14173 case OPC_PRECEQ_PW_QHL: 14174 case OPC_PRECEQ_PW_QHR: 14175 case OPC_PRECEQ_PW_QHLA: 14176 case OPC_PRECEQ_PW_QHRA: 14177 case OPC_PRECEQU_QH_OBL: 14178 case OPC_PRECEQU_QH_OBR: 14179 case OPC_PRECEQU_QH_OBLA: 14180 case OPC_PRECEQU_QH_OBRA: 14181 case OPC_PRECEU_QH_OBL: 14182 case OPC_PRECEU_QH_OBR: 14183 case OPC_PRECEU_QH_OBLA: 14184 case OPC_PRECEU_QH_OBRA: 14185 case OPC_ABSQ_S_OB: 14186 case OPC_ABSQ_S_PW: 14187 case OPC_ABSQ_S_QH: 14188 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 14189 break; 14190 case OPC_REPL_OB: 14191 case OPC_REPL_PW: 14192 case OPC_REPL_QH: 14193 case OPC_REPLV_OB: 14194 case OPC_REPLV_PW: 14195 case OPC_REPLV_QH: 14196 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt); 14197 break; 14198 default: /* Invalid */ 14199 MIPS_INVAL("MASK ABSQ_S.QH"); 14200 gen_reserved_instruction(ctx); 14201 break; 14202 } 14203 break; 14204 case OPC_ADDU_OB_DSP: 14205 op2 = MASK_ADDU_OB(ctx->opcode); 14206 switch (op2) { 14207 case OPC_RADDU_L_OB: 14208 case OPC_SUBQ_PW: 14209 case OPC_SUBQ_S_PW: 14210 case OPC_SUBQ_QH: 14211 case OPC_SUBQ_S_QH: 14212 case OPC_SUBU_OB: 14213 case OPC_SUBU_S_OB: 14214 case OPC_SUBU_QH: 14215 case OPC_SUBU_S_QH: 14216 case OPC_SUBUH_OB: 14217 case OPC_SUBUH_R_OB: 14218 case OPC_ADDQ_PW: 14219 case OPC_ADDQ_S_PW: 14220 case OPC_ADDQ_QH: 14221 case OPC_ADDQ_S_QH: 14222 case OPC_ADDU_OB: 14223 case OPC_ADDU_S_OB: 14224 case OPC_ADDU_QH: 14225 case OPC_ADDU_S_QH: 14226 case OPC_ADDUH_OB: 14227 case OPC_ADDUH_R_OB: 14228 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 14229 break; 14230 case OPC_MULEQ_S_PW_QHL: 14231 case OPC_MULEQ_S_PW_QHR: 14232 case OPC_MULEU_S_QH_OBL: 14233 case OPC_MULEU_S_QH_OBR: 14234 case OPC_MULQ_RS_QH: 14235 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1); 14236 break; 14237 default: /* Invalid */ 14238 MIPS_INVAL("MASK ADDU.OB"); 14239 gen_reserved_instruction(ctx); 14240 break; 14241 } 14242 break; 14243 case OPC_CMPU_EQ_OB_DSP: 14244 op2 = MASK_CMPU_EQ_OB(ctx->opcode); 14245 switch (op2) { 14246 case OPC_PRECR_SRA_QH_PW: 14247 case OPC_PRECR_SRA_R_QH_PW: 14248 /* Return value is rt. */ 14249 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd); 14250 break; 14251 case OPC_PRECR_OB_QH: 14252 case OPC_PRECRQ_OB_QH: 14253 case OPC_PRECRQ_PW_L: 14254 case OPC_PRECRQ_QH_PW: 14255 case OPC_PRECRQ_RS_QH_PW: 14256 case OPC_PRECRQU_S_OB_QH: 14257 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 14258 break; 14259 case OPC_CMPU_EQ_OB: 14260 case OPC_CMPU_LT_OB: 14261 case OPC_CMPU_LE_OB: 14262 case OPC_CMP_EQ_QH: 14263 case OPC_CMP_LT_QH: 14264 case OPC_CMP_LE_QH: 14265 case OPC_CMP_EQ_PW: 14266 case OPC_CMP_LT_PW: 14267 case OPC_CMP_LE_PW: 14268 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0); 14269 break; 14270 case OPC_CMPGDU_EQ_OB: 14271 case OPC_CMPGDU_LT_OB: 14272 case OPC_CMPGDU_LE_OB: 14273 case OPC_CMPGU_EQ_OB: 14274 case OPC_CMPGU_LT_OB: 14275 case OPC_CMPGU_LE_OB: 14276 case OPC_PACKRL_PW: 14277 case OPC_PICK_OB: 14278 case OPC_PICK_PW: 14279 case OPC_PICK_QH: 14280 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1); 14281 break; 14282 default: /* Invalid */ 14283 MIPS_INVAL("MASK CMPU_EQ.OB"); 14284 gen_reserved_instruction(ctx); 14285 break; 14286 } 14287 break; 14288 case OPC_DAPPEND_DSP: 14289 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd); 14290 break; 14291 case OPC_DEXTR_W_DSP: 14292 op2 = MASK_DEXTR_W(ctx->opcode); 14293 switch (op2) { 14294 case OPC_DEXTP: 14295 case OPC_DEXTPDP: 14296 case OPC_DEXTPDPV: 14297 case OPC_DEXTPV: 14298 case OPC_DEXTR_L: 14299 case OPC_DEXTR_R_L: 14300 case OPC_DEXTR_RS_L: 14301 case OPC_DEXTR_W: 14302 case OPC_DEXTR_R_W: 14303 case OPC_DEXTR_RS_W: 14304 case OPC_DEXTR_S_H: 14305 case OPC_DEXTRV_L: 14306 case OPC_DEXTRV_R_L: 14307 case OPC_DEXTRV_RS_L: 14308 case OPC_DEXTRV_S_H: 14309 case OPC_DEXTRV_W: 14310 case OPC_DEXTRV_R_W: 14311 case OPC_DEXTRV_RS_W: 14312 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1); 14313 break; 14314 case OPC_DMTHLIP: 14315 case OPC_DSHILO: 14316 case OPC_DSHILOV: 14317 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0); 14318 break; 14319 default: /* Invalid */ 14320 MIPS_INVAL("MASK EXTR.W"); 14321 gen_reserved_instruction(ctx); 14322 break; 14323 } 14324 break; 14325 case OPC_DPAQ_W_QH_DSP: 14326 op2 = MASK_DPAQ_W_QH(ctx->opcode); 14327 switch (op2) { 14328 case OPC_DPAU_H_OBL: 14329 case OPC_DPAU_H_OBR: 14330 case OPC_DPSU_H_OBL: 14331 case OPC_DPSU_H_OBR: 14332 case OPC_DPA_W_QH: 14333 case OPC_DPAQ_S_W_QH: 14334 case OPC_DPS_W_QH: 14335 case OPC_DPSQ_S_W_QH: 14336 case OPC_MULSAQ_S_W_QH: 14337 case OPC_DPAQ_SA_L_PW: 14338 case OPC_DPSQ_SA_L_PW: 14339 case OPC_MULSAQ_S_L_PW: 14340 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0); 14341 break; 14342 case OPC_MAQ_S_W_QHLL: 14343 case OPC_MAQ_S_W_QHLR: 14344 case OPC_MAQ_S_W_QHRL: 14345 case OPC_MAQ_S_W_QHRR: 14346 case OPC_MAQ_SA_W_QHLL: 14347 case OPC_MAQ_SA_W_QHLR: 14348 case OPC_MAQ_SA_W_QHRL: 14349 case OPC_MAQ_SA_W_QHRR: 14350 case OPC_MAQ_S_L_PWL: 14351 case OPC_MAQ_S_L_PWR: 14352 case OPC_DMADD: 14353 case OPC_DMADDU: 14354 case OPC_DMSUB: 14355 case OPC_DMSUBU: 14356 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0); 14357 break; 14358 default: /* Invalid */ 14359 MIPS_INVAL("MASK DPAQ.W.QH"); 14360 gen_reserved_instruction(ctx); 14361 break; 14362 } 14363 break; 14364 case OPC_DINSV_DSP: 14365 op2 = MASK_INSV(ctx->opcode); 14366 switch (op2) { 14367 case OPC_DINSV: 14368 { 14369 TCGv t0, t1; 14370 14371 check_dsp(ctx); 14372 14373 if (rt == 0) { 14374 break; 14375 } 14376 14377 t0 = tcg_temp_new(); 14378 t1 = tcg_temp_new(); 14379 14380 gen_load_gpr(t0, rt); 14381 gen_load_gpr(t1, rs); 14382 14383 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0); 14384 break; 14385 } 14386 default: /* Invalid */ 14387 MIPS_INVAL("MASK DINSV"); 14388 gen_reserved_instruction(ctx); 14389 break; 14390 } 14391 break; 14392 case OPC_SHLL_OB_DSP: 14393 gen_mipsdsp_shift(ctx, op1, rd, rs, rt); 14394 break; 14395 #endif 14396 default: /* Invalid */ 14397 MIPS_INVAL("special3_legacy"); 14398 gen_reserved_instruction(ctx); 14399 break; 14400 } 14401 } 14402 14403 14404 #if defined(TARGET_MIPS64) 14405 14406 static void decode_mmi(CPUMIPSState *env, DisasContext *ctx) 14407 { 14408 uint32_t opc = MASK_MMI(ctx->opcode); 14409 int rs = extract32(ctx->opcode, 21, 5); 14410 int rt = extract32(ctx->opcode, 16, 5); 14411 int rd = extract32(ctx->opcode, 11, 5); 14412 14413 switch (opc) { 14414 case MMI_OPC_MULT1: 14415 case MMI_OPC_MULTU1: 14416 case MMI_OPC_MADD: 14417 case MMI_OPC_MADDU: 14418 case MMI_OPC_MADD1: 14419 case MMI_OPC_MADDU1: 14420 gen_mul_txx9(ctx, opc, rd, rs, rt); 14421 break; 14422 case MMI_OPC_DIV1: 14423 case MMI_OPC_DIVU1: 14424 gen_div1_tx79(ctx, opc, rs, rt); 14425 break; 14426 default: 14427 MIPS_INVAL("TX79 MMI class"); 14428 gen_reserved_instruction(ctx); 14429 break; 14430 } 14431 } 14432 14433 static void gen_mmi_sq(DisasContext *ctx, int base, int rt, int offset) 14434 { 14435 gen_reserved_instruction(ctx); /* TODO: MMI_OPC_SQ */ 14436 } 14437 14438 /* 14439 * The TX79-specific instruction Store Quadword 14440 * 14441 * +--------+-------+-------+------------------------+ 14442 * | 011111 | base | rt | offset | SQ 14443 * +--------+-------+-------+------------------------+ 14444 * 6 5 5 16 14445 * 14446 * has the same opcode as the Read Hardware Register instruction 14447 * 14448 * +--------+-------+-------+-------+-------+--------+ 14449 * | 011111 | 00000 | rt | rd | 00000 | 111011 | RDHWR 14450 * +--------+-------+-------+-------+-------+--------+ 14451 * 6 5 5 5 5 6 14452 * 14453 * that is required, trapped and emulated by the Linux kernel. However, all 14454 * RDHWR encodings yield address error exceptions on the TX79 since the SQ 14455 * offset is odd. Therefore all valid SQ instructions can execute normally. 14456 * In user mode, QEMU must verify the upper and lower 11 bits to distinguish 14457 * between SQ and RDHWR, as the Linux kernel does. 14458 */ 14459 static void decode_mmi_sq(CPUMIPSState *env, DisasContext *ctx) 14460 { 14461 int base = extract32(ctx->opcode, 21, 5); 14462 int rt = extract32(ctx->opcode, 16, 5); 14463 int offset = extract32(ctx->opcode, 0, 16); 14464 14465 #ifdef CONFIG_USER_ONLY 14466 uint32_t op1 = MASK_SPECIAL3(ctx->opcode); 14467 uint32_t op2 = extract32(ctx->opcode, 6, 5); 14468 14469 if (base == 0 && op2 == 0 && op1 == OPC_RDHWR) { 14470 int rd = extract32(ctx->opcode, 11, 5); 14471 14472 gen_rdhwr(ctx, rt, rd, 0); 14473 return; 14474 } 14475 #endif 14476 14477 gen_mmi_sq(ctx, base, rt, offset); 14478 } 14479 14480 #endif 14481 14482 static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx) 14483 { 14484 int rs, rt, rd, sa; 14485 uint32_t op1, op2; 14486 int16_t imm; 14487 14488 rs = (ctx->opcode >> 21) & 0x1f; 14489 rt = (ctx->opcode >> 16) & 0x1f; 14490 rd = (ctx->opcode >> 11) & 0x1f; 14491 sa = (ctx->opcode >> 6) & 0x1f; 14492 imm = sextract32(ctx->opcode, 7, 9); 14493 14494 op1 = MASK_SPECIAL3(ctx->opcode); 14495 14496 /* 14497 * EVA loads and stores overlap Loongson 2E instructions decoded by 14498 * decode_opc_special3_legacy(), so be careful to allow their decoding when 14499 * EVA is absent. 14500 */ 14501 if (ctx->eva) { 14502 switch (op1) { 14503 case OPC_LWLE: 14504 case OPC_LWRE: 14505 case OPC_LBUE: 14506 case OPC_LHUE: 14507 case OPC_LBE: 14508 case OPC_LHE: 14509 case OPC_LLE: 14510 case OPC_LWE: 14511 check_cp0_enabled(ctx); 14512 gen_ld(ctx, op1, rt, rs, imm); 14513 return; 14514 case OPC_SWLE: 14515 case OPC_SWRE: 14516 case OPC_SBE: 14517 case OPC_SHE: 14518 case OPC_SWE: 14519 check_cp0_enabled(ctx); 14520 gen_st(ctx, op1, rt, rs, imm); 14521 return; 14522 case OPC_SCE: 14523 check_cp0_enabled(ctx); 14524 gen_st_cond(ctx, rt, rs, imm, MO_TESL, true); 14525 return; 14526 case OPC_CACHEE: 14527 check_eva(ctx); 14528 check_cp0_enabled(ctx); 14529 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) { 14530 gen_cache_operation(ctx, rt, rs, imm); 14531 } 14532 return; 14533 case OPC_PREFE: 14534 check_cp0_enabled(ctx); 14535 /* Treat as NOP. */ 14536 return; 14537 } 14538 } 14539 14540 switch (op1) { 14541 case OPC_EXT: 14542 case OPC_INS: 14543 check_insn(ctx, ISA_MIPS_R2); 14544 gen_bitops(ctx, op1, rt, rs, sa, rd); 14545 break; 14546 case OPC_BSHFL: 14547 op2 = MASK_BSHFL(ctx->opcode); 14548 switch (op2) { 14549 case OPC_ALIGN: 14550 case OPC_ALIGN_1: 14551 case OPC_ALIGN_2: 14552 case OPC_ALIGN_3: 14553 case OPC_BITSWAP: 14554 check_insn(ctx, ISA_MIPS_R6); 14555 decode_opc_special3_r6(env, ctx); 14556 break; 14557 default: 14558 check_insn(ctx, ISA_MIPS_R2); 14559 gen_bshfl(ctx, op2, rt, rd); 14560 break; 14561 } 14562 break; 14563 #if defined(TARGET_MIPS64) 14564 case OPC_DEXTM: 14565 case OPC_DEXTU: 14566 case OPC_DEXT: 14567 case OPC_DINSM: 14568 case OPC_DINSU: 14569 case OPC_DINS: 14570 check_insn(ctx, ISA_MIPS_R2); 14571 check_mips_64(ctx); 14572 gen_bitops(ctx, op1, rt, rs, sa, rd); 14573 break; 14574 case OPC_DBSHFL: 14575 op2 = MASK_DBSHFL(ctx->opcode); 14576 switch (op2) { 14577 case OPC_DALIGN: 14578 case OPC_DALIGN_1: 14579 case OPC_DALIGN_2: 14580 case OPC_DALIGN_3: 14581 case OPC_DALIGN_4: 14582 case OPC_DALIGN_5: 14583 case OPC_DALIGN_6: 14584 case OPC_DALIGN_7: 14585 case OPC_DBITSWAP: 14586 check_insn(ctx, ISA_MIPS_R6); 14587 decode_opc_special3_r6(env, ctx); 14588 break; 14589 default: 14590 check_insn(ctx, ISA_MIPS_R2); 14591 check_mips_64(ctx); 14592 op2 = MASK_DBSHFL(ctx->opcode); 14593 gen_bshfl(ctx, op2, rt, rd); 14594 break; 14595 } 14596 break; 14597 #endif 14598 case OPC_RDHWR: 14599 gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3)); 14600 break; 14601 case OPC_FORK: 14602 check_mt(ctx); 14603 { 14604 TCGv t0 = tcg_temp_new(); 14605 TCGv t1 = tcg_temp_new(); 14606 14607 gen_load_gpr(t0, rt); 14608 gen_load_gpr(t1, rs); 14609 gen_helper_fork(t0, t1); 14610 } 14611 break; 14612 case OPC_YIELD: 14613 check_mt(ctx); 14614 { 14615 TCGv t0 = tcg_temp_new(); 14616 14617 gen_load_gpr(t0, rs); 14618 gen_helper_yield(t0, cpu_env, t0); 14619 gen_store_gpr(t0, rd); 14620 } 14621 break; 14622 default: 14623 if (ctx->insn_flags & ISA_MIPS_R6) { 14624 decode_opc_special3_r6(env, ctx); 14625 } else { 14626 decode_opc_special3_legacy(env, ctx); 14627 } 14628 } 14629 } 14630 14631 static bool decode_opc_legacy(CPUMIPSState *env, DisasContext *ctx) 14632 { 14633 int32_t offset; 14634 int rs, rt, rd, sa; 14635 uint32_t op, op1; 14636 int16_t imm; 14637 14638 op = MASK_OP_MAJOR(ctx->opcode); 14639 rs = (ctx->opcode >> 21) & 0x1f; 14640 rt = (ctx->opcode >> 16) & 0x1f; 14641 rd = (ctx->opcode >> 11) & 0x1f; 14642 sa = (ctx->opcode >> 6) & 0x1f; 14643 imm = (int16_t)ctx->opcode; 14644 switch (op) { 14645 case OPC_SPECIAL: 14646 decode_opc_special(env, ctx); 14647 break; 14648 case OPC_SPECIAL2: 14649 #if defined(TARGET_MIPS64) 14650 if ((ctx->insn_flags & INSN_R5900) && (ctx->insn_flags & ASE_MMI)) { 14651 decode_mmi(env, ctx); 14652 break; 14653 } 14654 #endif 14655 if (TARGET_LONG_BITS == 32 && (ctx->insn_flags & ASE_MXU)) { 14656 if (MASK_SPECIAL2(ctx->opcode) == OPC_MUL) { 14657 gen_arith(ctx, OPC_MUL, rd, rs, rt); 14658 } else { 14659 decode_ase_mxu(ctx, ctx->opcode); 14660 } 14661 break; 14662 } 14663 decode_opc_special2_legacy(env, ctx); 14664 break; 14665 case OPC_SPECIAL3: 14666 #if defined(TARGET_MIPS64) 14667 if (ctx->insn_flags & INSN_R5900) { 14668 decode_mmi_sq(env, ctx); /* MMI_OPC_SQ */ 14669 } else { 14670 decode_opc_special3(env, ctx); 14671 } 14672 #else 14673 decode_opc_special3(env, ctx); 14674 #endif 14675 break; 14676 case OPC_REGIMM: 14677 op1 = MASK_REGIMM(ctx->opcode); 14678 switch (op1) { 14679 case OPC_BLTZL: /* REGIMM branches */ 14680 case OPC_BGEZL: 14681 case OPC_BLTZALL: 14682 case OPC_BGEZALL: 14683 check_insn(ctx, ISA_MIPS2); 14684 check_insn_opc_removed(ctx, ISA_MIPS_R6); 14685 /* Fallthrough */ 14686 case OPC_BLTZ: 14687 case OPC_BGEZ: 14688 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4); 14689 break; 14690 case OPC_BLTZAL: 14691 case OPC_BGEZAL: 14692 if (ctx->insn_flags & ISA_MIPS_R6) { 14693 if (rs == 0) { 14694 /* OPC_NAL, OPC_BAL */ 14695 gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4); 14696 } else { 14697 gen_reserved_instruction(ctx); 14698 } 14699 } else { 14700 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4); 14701 } 14702 break; 14703 case OPC_TGEI: /* REGIMM traps */ 14704 case OPC_TGEIU: 14705 case OPC_TLTI: 14706 case OPC_TLTIU: 14707 case OPC_TEQI: 14708 case OPC_TNEI: 14709 check_insn(ctx, ISA_MIPS2); 14710 check_insn_opc_removed(ctx, ISA_MIPS_R6); 14711 gen_trap(ctx, op1, rs, -1, imm, 0); 14712 break; 14713 case OPC_SIGRIE: 14714 check_insn(ctx, ISA_MIPS_R6); 14715 gen_reserved_instruction(ctx); 14716 break; 14717 case OPC_SYNCI: 14718 check_insn(ctx, ISA_MIPS_R2); 14719 /* 14720 * Break the TB to be able to sync copied instructions 14721 * immediately. 14722 */ 14723 ctx->base.is_jmp = DISAS_STOP; 14724 break; 14725 case OPC_BPOSGE32: /* MIPS DSP branch */ 14726 #if defined(TARGET_MIPS64) 14727 case OPC_BPOSGE64: 14728 #endif 14729 check_dsp(ctx); 14730 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4); 14731 break; 14732 #if defined(TARGET_MIPS64) 14733 case OPC_DAHI: 14734 check_insn(ctx, ISA_MIPS_R6); 14735 check_mips_64(ctx); 14736 if (rs != 0) { 14737 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32); 14738 } 14739 break; 14740 case OPC_DATI: 14741 check_insn(ctx, ISA_MIPS_R6); 14742 check_mips_64(ctx); 14743 if (rs != 0) { 14744 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48); 14745 } 14746 break; 14747 #endif 14748 default: /* Invalid */ 14749 MIPS_INVAL("regimm"); 14750 gen_reserved_instruction(ctx); 14751 break; 14752 } 14753 break; 14754 case OPC_CP0: 14755 check_cp0_enabled(ctx); 14756 op1 = MASK_CP0(ctx->opcode); 14757 switch (op1) { 14758 case OPC_MFC0: 14759 case OPC_MTC0: 14760 case OPC_MFTR: 14761 case OPC_MTTR: 14762 case OPC_MFHC0: 14763 case OPC_MTHC0: 14764 #if defined(TARGET_MIPS64) 14765 case OPC_DMFC0: 14766 case OPC_DMTC0: 14767 #endif 14768 #ifndef CONFIG_USER_ONLY 14769 gen_cp0(env, ctx, op1, rt, rd); 14770 #endif /* !CONFIG_USER_ONLY */ 14771 break; 14772 case OPC_C0: 14773 case OPC_C0_1: 14774 case OPC_C0_2: 14775 case OPC_C0_3: 14776 case OPC_C0_4: 14777 case OPC_C0_5: 14778 case OPC_C0_6: 14779 case OPC_C0_7: 14780 case OPC_C0_8: 14781 case OPC_C0_9: 14782 case OPC_C0_A: 14783 case OPC_C0_B: 14784 case OPC_C0_C: 14785 case OPC_C0_D: 14786 case OPC_C0_E: 14787 case OPC_C0_F: 14788 #ifndef CONFIG_USER_ONLY 14789 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd); 14790 #endif /* !CONFIG_USER_ONLY */ 14791 break; 14792 case OPC_MFMC0: 14793 #ifndef CONFIG_USER_ONLY 14794 { 14795 uint32_t op2; 14796 TCGv t0 = tcg_temp_new(); 14797 14798 op2 = MASK_MFMC0(ctx->opcode); 14799 switch (op2) { 14800 case OPC_DMT: 14801 check_cp0_mt(ctx); 14802 gen_helper_dmt(t0); 14803 gen_store_gpr(t0, rt); 14804 break; 14805 case OPC_EMT: 14806 check_cp0_mt(ctx); 14807 gen_helper_emt(t0); 14808 gen_store_gpr(t0, rt); 14809 break; 14810 case OPC_DVPE: 14811 check_cp0_mt(ctx); 14812 gen_helper_dvpe(t0, cpu_env); 14813 gen_store_gpr(t0, rt); 14814 break; 14815 case OPC_EVPE: 14816 check_cp0_mt(ctx); 14817 gen_helper_evpe(t0, cpu_env); 14818 gen_store_gpr(t0, rt); 14819 break; 14820 case OPC_DVP: 14821 check_insn(ctx, ISA_MIPS_R6); 14822 if (ctx->vp) { 14823 gen_helper_dvp(t0, cpu_env); 14824 gen_store_gpr(t0, rt); 14825 } 14826 break; 14827 case OPC_EVP: 14828 check_insn(ctx, ISA_MIPS_R6); 14829 if (ctx->vp) { 14830 gen_helper_evp(t0, cpu_env); 14831 gen_store_gpr(t0, rt); 14832 } 14833 break; 14834 case OPC_DI: 14835 check_insn(ctx, ISA_MIPS_R2); 14836 save_cpu_state(ctx, 1); 14837 gen_helper_di(t0, cpu_env); 14838 gen_store_gpr(t0, rt); 14839 /* 14840 * Stop translation as we may have switched 14841 * the execution mode. 14842 */ 14843 ctx->base.is_jmp = DISAS_STOP; 14844 break; 14845 case OPC_EI: 14846 check_insn(ctx, ISA_MIPS_R2); 14847 save_cpu_state(ctx, 1); 14848 gen_helper_ei(t0, cpu_env); 14849 gen_store_gpr(t0, rt); 14850 /* 14851 * DISAS_STOP isn't sufficient, we need to ensure we break 14852 * out of translated code to check for pending interrupts. 14853 */ 14854 gen_save_pc(ctx->base.pc_next + 4); 14855 ctx->base.is_jmp = DISAS_EXIT; 14856 break; 14857 default: /* Invalid */ 14858 MIPS_INVAL("mfmc0"); 14859 gen_reserved_instruction(ctx); 14860 break; 14861 } 14862 } 14863 #endif /* !CONFIG_USER_ONLY */ 14864 break; 14865 case OPC_RDPGPR: 14866 check_insn(ctx, ISA_MIPS_R2); 14867 gen_load_srsgpr(rt, rd); 14868 break; 14869 case OPC_WRPGPR: 14870 check_insn(ctx, ISA_MIPS_R2); 14871 gen_store_srsgpr(rt, rd); 14872 break; 14873 default: 14874 MIPS_INVAL("cp0"); 14875 gen_reserved_instruction(ctx); 14876 break; 14877 } 14878 break; 14879 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */ 14880 if (ctx->insn_flags & ISA_MIPS_R6) { 14881 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */ 14882 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 14883 } else { 14884 /* OPC_ADDI */ 14885 /* Arithmetic with immediate opcode */ 14886 gen_arith_imm(ctx, op, rt, rs, imm); 14887 } 14888 break; 14889 case OPC_ADDIU: 14890 gen_arith_imm(ctx, op, rt, rs, imm); 14891 break; 14892 case OPC_SLTI: /* Set on less than with immediate opcode */ 14893 case OPC_SLTIU: 14894 gen_slt_imm(ctx, op, rt, rs, imm); 14895 break; 14896 case OPC_ANDI: /* Arithmetic with immediate opcode */ 14897 case OPC_LUI: /* OPC_AUI */ 14898 case OPC_ORI: 14899 case OPC_XORI: 14900 gen_logic_imm(ctx, op, rt, rs, imm); 14901 break; 14902 case OPC_J: /* Jump */ 14903 case OPC_JAL: 14904 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2; 14905 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4); 14906 break; 14907 /* Branch */ 14908 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */ 14909 if (ctx->insn_flags & ISA_MIPS_R6) { 14910 if (rt == 0) { 14911 gen_reserved_instruction(ctx); 14912 break; 14913 } 14914 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */ 14915 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 14916 } else { 14917 /* OPC_BLEZL */ 14918 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); 14919 } 14920 break; 14921 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */ 14922 if (ctx->insn_flags & ISA_MIPS_R6) { 14923 if (rt == 0) { 14924 gen_reserved_instruction(ctx); 14925 break; 14926 } 14927 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */ 14928 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 14929 } else { 14930 /* OPC_BGTZL */ 14931 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); 14932 } 14933 break; 14934 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */ 14935 if (rt == 0) { 14936 /* OPC_BLEZ */ 14937 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); 14938 } else { 14939 check_insn(ctx, ISA_MIPS_R6); 14940 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */ 14941 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 14942 } 14943 break; 14944 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */ 14945 if (rt == 0) { 14946 /* OPC_BGTZ */ 14947 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); 14948 } else { 14949 check_insn(ctx, ISA_MIPS_R6); 14950 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */ 14951 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 14952 } 14953 break; 14954 case OPC_BEQL: 14955 case OPC_BNEL: 14956 check_insn(ctx, ISA_MIPS2); 14957 check_insn_opc_removed(ctx, ISA_MIPS_R6); 14958 /* Fallthrough */ 14959 case OPC_BEQ: 14960 case OPC_BNE: 14961 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); 14962 break; 14963 case OPC_LL: /* Load and stores */ 14964 check_insn(ctx, ISA_MIPS2); 14965 if (ctx->insn_flags & INSN_R5900) { 14966 check_insn_opc_user_only(ctx, INSN_R5900); 14967 } 14968 /* Fallthrough */ 14969 case OPC_LWL: 14970 case OPC_LWR: 14971 case OPC_LB: 14972 case OPC_LH: 14973 case OPC_LW: 14974 case OPC_LWPC: 14975 case OPC_LBU: 14976 case OPC_LHU: 14977 gen_ld(ctx, op, rt, rs, imm); 14978 break; 14979 case OPC_SWL: 14980 case OPC_SWR: 14981 case OPC_SB: 14982 case OPC_SH: 14983 case OPC_SW: 14984 gen_st(ctx, op, rt, rs, imm); 14985 break; 14986 case OPC_SC: 14987 check_insn(ctx, ISA_MIPS2); 14988 if (ctx->insn_flags & INSN_R5900) { 14989 check_insn_opc_user_only(ctx, INSN_R5900); 14990 } 14991 gen_st_cond(ctx, rt, rs, imm, MO_TESL, false); 14992 break; 14993 case OPC_CACHE: 14994 check_cp0_enabled(ctx); 14995 check_insn(ctx, ISA_MIPS3 | ISA_MIPS_R1); 14996 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) { 14997 gen_cache_operation(ctx, rt, rs, imm); 14998 } 14999 /* Treat as NOP. */ 15000 break; 15001 case OPC_PREF: 15002 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1 | INSN_R5900); 15003 /* Treat as NOP. */ 15004 break; 15005 15006 /* Floating point (COP1). */ 15007 case OPC_LWC1: 15008 case OPC_LDC1: 15009 case OPC_SWC1: 15010 case OPC_SDC1: 15011 gen_cop1_ldst(ctx, op, rt, rs, imm); 15012 break; 15013 15014 case OPC_CP1: 15015 op1 = MASK_CP1(ctx->opcode); 15016 15017 switch (op1) { 15018 case OPC_MFHC1: 15019 case OPC_MTHC1: 15020 check_cp1_enabled(ctx); 15021 check_insn(ctx, ISA_MIPS_R2); 15022 /* fall through */ 15023 case OPC_MFC1: 15024 case OPC_CFC1: 15025 case OPC_MTC1: 15026 case OPC_CTC1: 15027 check_cp1_enabled(ctx); 15028 gen_cp1(ctx, op1, rt, rd); 15029 break; 15030 #if defined(TARGET_MIPS64) 15031 case OPC_DMFC1: 15032 case OPC_DMTC1: 15033 check_cp1_enabled(ctx); 15034 check_insn(ctx, ISA_MIPS3); 15035 check_mips_64(ctx); 15036 gen_cp1(ctx, op1, rt, rd); 15037 break; 15038 #endif 15039 case OPC_BC1EQZ: /* OPC_BC1ANY2 */ 15040 check_cp1_enabled(ctx); 15041 if (ctx->insn_flags & ISA_MIPS_R6) { 15042 /* OPC_BC1EQZ */ 15043 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode), 15044 rt, imm << 2, 4); 15045 } else { 15046 /* OPC_BC1ANY2 */ 15047 check_cop1x(ctx); 15048 check_insn(ctx, ASE_MIPS3D); 15049 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode), 15050 (rt >> 2) & 0x7, imm << 2); 15051 } 15052 break; 15053 case OPC_BC1NEZ: 15054 check_cp1_enabled(ctx); 15055 check_insn(ctx, ISA_MIPS_R6); 15056 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode), 15057 rt, imm << 2, 4); 15058 break; 15059 case OPC_BC1ANY4: 15060 check_cp1_enabled(ctx); 15061 check_insn_opc_removed(ctx, ISA_MIPS_R6); 15062 check_cop1x(ctx); 15063 check_insn(ctx, ASE_MIPS3D); 15064 /* fall through */ 15065 case OPC_BC1: 15066 check_cp1_enabled(ctx); 15067 check_insn_opc_removed(ctx, ISA_MIPS_R6); 15068 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode), 15069 (rt >> 2) & 0x7, imm << 2); 15070 break; 15071 case OPC_PS_FMT: 15072 check_ps(ctx); 15073 /* fall through */ 15074 case OPC_S_FMT: 15075 case OPC_D_FMT: 15076 check_cp1_enabled(ctx); 15077 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa, 15078 (imm >> 8) & 0x7); 15079 break; 15080 case OPC_W_FMT: 15081 case OPC_L_FMT: 15082 { 15083 int r6_op = ctx->opcode & FOP(0x3f, 0x1f); 15084 check_cp1_enabled(ctx); 15085 if (ctx->insn_flags & ISA_MIPS_R6) { 15086 switch (r6_op) { 15087 case R6_OPC_CMP_AF_S: 15088 case R6_OPC_CMP_UN_S: 15089 case R6_OPC_CMP_EQ_S: 15090 case R6_OPC_CMP_UEQ_S: 15091 case R6_OPC_CMP_LT_S: 15092 case R6_OPC_CMP_ULT_S: 15093 case R6_OPC_CMP_LE_S: 15094 case R6_OPC_CMP_ULE_S: 15095 case R6_OPC_CMP_SAF_S: 15096 case R6_OPC_CMP_SUN_S: 15097 case R6_OPC_CMP_SEQ_S: 15098 case R6_OPC_CMP_SEUQ_S: 15099 case R6_OPC_CMP_SLT_S: 15100 case R6_OPC_CMP_SULT_S: 15101 case R6_OPC_CMP_SLE_S: 15102 case R6_OPC_CMP_SULE_S: 15103 case R6_OPC_CMP_OR_S: 15104 case R6_OPC_CMP_UNE_S: 15105 case R6_OPC_CMP_NE_S: 15106 case R6_OPC_CMP_SOR_S: 15107 case R6_OPC_CMP_SUNE_S: 15108 case R6_OPC_CMP_SNE_S: 15109 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa); 15110 break; 15111 case R6_OPC_CMP_AF_D: 15112 case R6_OPC_CMP_UN_D: 15113 case R6_OPC_CMP_EQ_D: 15114 case R6_OPC_CMP_UEQ_D: 15115 case R6_OPC_CMP_LT_D: 15116 case R6_OPC_CMP_ULT_D: 15117 case R6_OPC_CMP_LE_D: 15118 case R6_OPC_CMP_ULE_D: 15119 case R6_OPC_CMP_SAF_D: 15120 case R6_OPC_CMP_SUN_D: 15121 case R6_OPC_CMP_SEQ_D: 15122 case R6_OPC_CMP_SEUQ_D: 15123 case R6_OPC_CMP_SLT_D: 15124 case R6_OPC_CMP_SULT_D: 15125 case R6_OPC_CMP_SLE_D: 15126 case R6_OPC_CMP_SULE_D: 15127 case R6_OPC_CMP_OR_D: 15128 case R6_OPC_CMP_UNE_D: 15129 case R6_OPC_CMP_NE_D: 15130 case R6_OPC_CMP_SOR_D: 15131 case R6_OPC_CMP_SUNE_D: 15132 case R6_OPC_CMP_SNE_D: 15133 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa); 15134 break; 15135 default: 15136 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), 15137 rt, rd, sa, (imm >> 8) & 0x7); 15138 15139 break; 15140 } 15141 } else { 15142 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa, 15143 (imm >> 8) & 0x7); 15144 } 15145 break; 15146 } 15147 default: 15148 MIPS_INVAL("cp1"); 15149 gen_reserved_instruction(ctx); 15150 break; 15151 } 15152 break; 15153 15154 /* Compact branches [R6] and COP2 [non-R6] */ 15155 case OPC_BC: /* OPC_LWC2 */ 15156 case OPC_BALC: /* OPC_SWC2 */ 15157 if (ctx->insn_flags & ISA_MIPS_R6) { 15158 /* OPC_BC, OPC_BALC */ 15159 gen_compute_compact_branch(ctx, op, 0, 0, 15160 sextract32(ctx->opcode << 2, 0, 28)); 15161 } else if (ctx->insn_flags & ASE_LEXT) { 15162 gen_loongson_lswc2(ctx, rt, rs, rd); 15163 } else { 15164 /* OPC_LWC2, OPC_SWC2 */ 15165 /* COP2: Not implemented. */ 15166 generate_exception_err(ctx, EXCP_CpU, 2); 15167 } 15168 break; 15169 case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */ 15170 case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */ 15171 if (ctx->insn_flags & ISA_MIPS_R6) { 15172 if (rs != 0) { 15173 /* OPC_BEQZC, OPC_BNEZC */ 15174 gen_compute_compact_branch(ctx, op, rs, 0, 15175 sextract32(ctx->opcode << 2, 0, 23)); 15176 } else { 15177 /* OPC_JIC, OPC_JIALC */ 15178 gen_compute_compact_branch(ctx, op, 0, rt, imm); 15179 } 15180 } else if (ctx->insn_flags & ASE_LEXT) { 15181 gen_loongson_lsdc2(ctx, rt, rs, rd); 15182 } else { 15183 /* OPC_LWC2, OPC_SWC2 */ 15184 /* COP2: Not implemented. */ 15185 generate_exception_err(ctx, EXCP_CpU, 2); 15186 } 15187 break; 15188 case OPC_CP2: 15189 check_insn(ctx, ASE_LMMI); 15190 /* Note that these instructions use different fields. */ 15191 gen_loongson_multimedia(ctx, sa, rd, rt); 15192 break; 15193 15194 case OPC_CP3: 15195 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) { 15196 check_cp1_enabled(ctx); 15197 op1 = MASK_CP3(ctx->opcode); 15198 switch (op1) { 15199 case OPC_LUXC1: 15200 case OPC_SUXC1: 15201 check_insn(ctx, ISA_MIPS5 | ISA_MIPS_R2); 15202 /* Fallthrough */ 15203 case OPC_LWXC1: 15204 case OPC_LDXC1: 15205 case OPC_SWXC1: 15206 case OPC_SDXC1: 15207 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2); 15208 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt); 15209 break; 15210 case OPC_PREFX: 15211 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2); 15212 /* Treat as NOP. */ 15213 break; 15214 case OPC_ALNV_PS: 15215 check_insn(ctx, ISA_MIPS5 | ISA_MIPS_R2); 15216 /* Fallthrough */ 15217 case OPC_MADD_S: 15218 case OPC_MADD_D: 15219 case OPC_MADD_PS: 15220 case OPC_MSUB_S: 15221 case OPC_MSUB_D: 15222 case OPC_MSUB_PS: 15223 case OPC_NMADD_S: 15224 case OPC_NMADD_D: 15225 case OPC_NMADD_PS: 15226 case OPC_NMSUB_S: 15227 case OPC_NMSUB_D: 15228 case OPC_NMSUB_PS: 15229 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2); 15230 gen_flt3_arith(ctx, op1, sa, rs, rd, rt); 15231 break; 15232 default: 15233 MIPS_INVAL("cp3"); 15234 gen_reserved_instruction(ctx); 15235 break; 15236 } 15237 } else { 15238 generate_exception_err(ctx, EXCP_CpU, 1); 15239 } 15240 break; 15241 15242 #if defined(TARGET_MIPS64) 15243 /* MIPS64 opcodes */ 15244 case OPC_LLD: 15245 if (ctx->insn_flags & INSN_R5900) { 15246 check_insn_opc_user_only(ctx, INSN_R5900); 15247 } 15248 /* fall through */ 15249 case OPC_LDL: 15250 case OPC_LDR: 15251 case OPC_LWU: 15252 case OPC_LD: 15253 check_insn(ctx, ISA_MIPS3); 15254 check_mips_64(ctx); 15255 gen_ld(ctx, op, rt, rs, imm); 15256 break; 15257 case OPC_SDL: 15258 case OPC_SDR: 15259 case OPC_SD: 15260 check_insn(ctx, ISA_MIPS3); 15261 check_mips_64(ctx); 15262 gen_st(ctx, op, rt, rs, imm); 15263 break; 15264 case OPC_SCD: 15265 check_insn(ctx, ISA_MIPS3); 15266 if (ctx->insn_flags & INSN_R5900) { 15267 check_insn_opc_user_only(ctx, INSN_R5900); 15268 } 15269 check_mips_64(ctx); 15270 gen_st_cond(ctx, rt, rs, imm, MO_TEUQ, false); 15271 break; 15272 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */ 15273 if (ctx->insn_flags & ISA_MIPS_R6) { 15274 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */ 15275 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 15276 } else { 15277 /* OPC_DADDI */ 15278 check_insn(ctx, ISA_MIPS3); 15279 check_mips_64(ctx); 15280 gen_arith_imm(ctx, op, rt, rs, imm); 15281 } 15282 break; 15283 case OPC_DADDIU: 15284 check_insn(ctx, ISA_MIPS3); 15285 check_mips_64(ctx); 15286 gen_arith_imm(ctx, op, rt, rs, imm); 15287 break; 15288 #else 15289 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */ 15290 if (ctx->insn_flags & ISA_MIPS_R6) { 15291 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 15292 } else { 15293 MIPS_INVAL("major opcode"); 15294 gen_reserved_instruction(ctx); 15295 } 15296 break; 15297 #endif 15298 case OPC_DAUI: /* OPC_JALX */ 15299 if (ctx->insn_flags & ISA_MIPS_R6) { 15300 #if defined(TARGET_MIPS64) 15301 /* OPC_DAUI */ 15302 check_mips_64(ctx); 15303 if (rs == 0) { 15304 generate_exception(ctx, EXCP_RI); 15305 } else if (rt != 0) { 15306 TCGv t0 = tcg_temp_new(); 15307 gen_load_gpr(t0, rs); 15308 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16); 15309 } 15310 #else 15311 gen_reserved_instruction(ctx); 15312 MIPS_INVAL("major opcode"); 15313 #endif 15314 } else { 15315 /* OPC_JALX */ 15316 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS); 15317 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2; 15318 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4); 15319 } 15320 break; 15321 case OPC_MDMX: 15322 /* MDMX: Not implemented. */ 15323 break; 15324 case OPC_PCREL: 15325 check_insn(ctx, ISA_MIPS_R6); 15326 gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs); 15327 break; 15328 default: /* Invalid */ 15329 MIPS_INVAL("major opcode"); 15330 return false; 15331 } 15332 return true; 15333 } 15334 15335 static void decode_opc(CPUMIPSState *env, DisasContext *ctx) 15336 { 15337 /* make sure instructions are on a word boundary */ 15338 if (ctx->base.pc_next & 0x3) { 15339 env->CP0_BadVAddr = ctx->base.pc_next; 15340 generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL); 15341 return; 15342 } 15343 15344 /* Handle blikely not taken case */ 15345 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) { 15346 TCGLabel *l1 = gen_new_label(); 15347 15348 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1); 15349 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK); 15350 gen_goto_tb(ctx, 1, ctx->base.pc_next + 4); 15351 gen_set_label(l1); 15352 } 15353 15354 /* Transition to the auto-generated decoder. */ 15355 15356 /* Vendor specific extensions */ 15357 if (cpu_supports_isa(env, INSN_R5900) && decode_ext_txx9(ctx, ctx->opcode)) { 15358 return; 15359 } 15360 if (cpu_supports_isa(env, INSN_VR54XX) && decode_ext_vr54xx(ctx, ctx->opcode)) { 15361 return; 15362 } 15363 #if defined(TARGET_MIPS64) 15364 if (cpu_supports_isa(env, INSN_OCTEON) && decode_ext_octeon(ctx, ctx->opcode)) { 15365 return; 15366 } 15367 #endif 15368 15369 /* ISA extensions */ 15370 if (ase_msa_available(env) && decode_ase_msa(ctx, ctx->opcode)) { 15371 return; 15372 } 15373 15374 /* ISA (from latest to oldest) */ 15375 if (cpu_supports_isa(env, ISA_MIPS_R6) && decode_isa_rel6(ctx, ctx->opcode)) { 15376 return; 15377 } 15378 15379 if (decode_opc_legacy(env, ctx)) { 15380 return; 15381 } 15382 15383 gen_reserved_instruction(ctx); 15384 } 15385 15386 static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) 15387 { 15388 DisasContext *ctx = container_of(dcbase, DisasContext, base); 15389 CPUMIPSState *env = cs->env_ptr; 15390 15391 ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK; 15392 ctx->saved_pc = -1; 15393 ctx->insn_flags = env->insn_flags; 15394 ctx->CP0_Config0 = env->CP0_Config0; 15395 ctx->CP0_Config1 = env->CP0_Config1; 15396 ctx->CP0_Config2 = env->CP0_Config2; 15397 ctx->CP0_Config3 = env->CP0_Config3; 15398 ctx->CP0_Config5 = env->CP0_Config5; 15399 ctx->btarget = 0; 15400 ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff; 15401 ctx->rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1; 15402 ctx->ie = (env->CP0_Config4 >> CP0C4_IE) & 3; 15403 ctx->bi = (env->CP0_Config3 >> CP0C3_BI) & 1; 15404 ctx->bp = (env->CP0_Config3 >> CP0C3_BP) & 1; 15405 ctx->PAMask = env->PAMask; 15406 ctx->mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1; 15407 ctx->eva = (env->CP0_Config5 >> CP0C5_EVA) & 1; 15408 ctx->sc = (env->CP0_Config3 >> CP0C3_SC) & 1; 15409 ctx->CP0_LLAddr_shift = env->CP0_LLAddr_shift; 15410 ctx->cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1; 15411 /* Restore delay slot state from the tb context. */ 15412 ctx->hflags = (uint32_t)ctx->base.tb->flags; /* FIXME: maybe use 64 bits? */ 15413 ctx->ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1; 15414 ctx->ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) || 15415 (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)); 15416 ctx->vp = (env->CP0_Config5 >> CP0C5_VP) & 1; 15417 ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1; 15418 ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1; 15419 ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1; 15420 ctx->mi = (env->CP0_Config5 >> CP0C5_MI) & 1; 15421 ctx->gi = (env->CP0_Config5 >> CP0C5_GI) & 3; 15422 restore_cpu_state(env, ctx); 15423 #ifdef CONFIG_USER_ONLY 15424 ctx->mem_idx = MIPS_HFLAG_UM; 15425 #else 15426 ctx->mem_idx = hflags_mmu_index(ctx->hflags); 15427 #endif 15428 ctx->default_tcg_memop_mask = (!(ctx->insn_flags & ISA_NANOMIPS32) && 15429 (ctx->insn_flags & (ISA_MIPS_R6 | 15430 INSN_LOONGSON3A))) ? MO_UNALN : MO_ALIGN; 15431 15432 /* 15433 * Execute a branch and its delay slot as a single instruction. 15434 * This is what GDB expects and is consistent with what the 15435 * hardware does (e.g. if a delay slot instruction faults, the 15436 * reported PC is the PC of the branch). 15437 */ 15438 if (ctx->base.singlestep_enabled && (ctx->hflags & MIPS_HFLAG_BMASK)) { 15439 ctx->base.max_insns = 2; 15440 } 15441 15442 LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx, 15443 ctx->hflags); 15444 } 15445 15446 static void mips_tr_tb_start(DisasContextBase *dcbase, CPUState *cs) 15447 { 15448 } 15449 15450 static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs) 15451 { 15452 DisasContext *ctx = container_of(dcbase, DisasContext, base); 15453 15454 tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK, 15455 ctx->btarget); 15456 } 15457 15458 static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) 15459 { 15460 CPUMIPSState *env = cs->env_ptr; 15461 DisasContext *ctx = container_of(dcbase, DisasContext, base); 15462 int insn_bytes; 15463 int is_slot; 15464 15465 is_slot = ctx->hflags & MIPS_HFLAG_BMASK; 15466 if (ctx->insn_flags & ISA_NANOMIPS32) { 15467 ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next); 15468 insn_bytes = decode_isa_nanomips(env, ctx); 15469 } else if (!(ctx->hflags & MIPS_HFLAG_M16)) { 15470 ctx->opcode = translator_ldl(env, &ctx->base, ctx->base.pc_next); 15471 insn_bytes = 4; 15472 decode_opc(env, ctx); 15473 } else if (ctx->insn_flags & ASE_MICROMIPS) { 15474 ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next); 15475 insn_bytes = decode_isa_micromips(env, ctx); 15476 } else if (ctx->insn_flags & ASE_MIPS16) { 15477 ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next); 15478 insn_bytes = decode_ase_mips16e(env, ctx); 15479 } else { 15480 gen_reserved_instruction(ctx); 15481 g_assert(ctx->base.is_jmp == DISAS_NORETURN); 15482 return; 15483 } 15484 15485 if (ctx->hflags & MIPS_HFLAG_BMASK) { 15486 if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 | 15487 MIPS_HFLAG_FBNSLOT))) { 15488 /* 15489 * Force to generate branch as there is neither delay nor 15490 * forbidden slot. 15491 */ 15492 is_slot = 1; 15493 } 15494 if ((ctx->hflags & MIPS_HFLAG_M16) && 15495 (ctx->hflags & MIPS_HFLAG_FBNSLOT)) { 15496 /* 15497 * Force to generate branch as microMIPS R6 doesn't restrict 15498 * branches in the forbidden slot. 15499 */ 15500 is_slot = 1; 15501 } 15502 } 15503 if (is_slot) { 15504 gen_branch(ctx, insn_bytes); 15505 } 15506 if (ctx->base.is_jmp == DISAS_SEMIHOST) { 15507 generate_exception_err(ctx, EXCP_SEMIHOST, insn_bytes); 15508 } 15509 ctx->base.pc_next += insn_bytes; 15510 15511 if (ctx->base.is_jmp != DISAS_NEXT) { 15512 return; 15513 } 15514 15515 /* 15516 * End the TB on (most) page crossings. 15517 * See mips_tr_init_disas_context about single-stepping a branch 15518 * together with its delay slot. 15519 */ 15520 if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE 15521 && !ctx->base.singlestep_enabled) { 15522 ctx->base.is_jmp = DISAS_TOO_MANY; 15523 } 15524 } 15525 15526 static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs) 15527 { 15528 DisasContext *ctx = container_of(dcbase, DisasContext, base); 15529 15530 switch (ctx->base.is_jmp) { 15531 case DISAS_STOP: 15532 gen_save_pc(ctx->base.pc_next); 15533 tcg_gen_lookup_and_goto_ptr(); 15534 break; 15535 case DISAS_NEXT: 15536 case DISAS_TOO_MANY: 15537 save_cpu_state(ctx, 0); 15538 gen_goto_tb(ctx, 0, ctx->base.pc_next); 15539 break; 15540 case DISAS_EXIT: 15541 tcg_gen_exit_tb(NULL, 0); 15542 break; 15543 case DISAS_NORETURN: 15544 break; 15545 default: 15546 g_assert_not_reached(); 15547 } 15548 } 15549 15550 static void mips_tr_disas_log(const DisasContextBase *dcbase, 15551 CPUState *cs, FILE *logfile) 15552 { 15553 fprintf(logfile, "IN: %s\n", lookup_symbol(dcbase->pc_first)); 15554 target_disas(logfile, cs, dcbase->pc_first, dcbase->tb->size); 15555 } 15556 15557 static const TranslatorOps mips_tr_ops = { 15558 .init_disas_context = mips_tr_init_disas_context, 15559 .tb_start = mips_tr_tb_start, 15560 .insn_start = mips_tr_insn_start, 15561 .translate_insn = mips_tr_translate_insn, 15562 .tb_stop = mips_tr_tb_stop, 15563 .disas_log = mips_tr_disas_log, 15564 }; 15565 15566 void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns, 15567 target_ulong pc, void *host_pc) 15568 { 15569 DisasContext ctx; 15570 15571 translator_loop(cs, tb, max_insns, pc, host_pc, &mips_tr_ops, &ctx.base); 15572 } 15573 15574 void mips_tcg_init(void) 15575 { 15576 int i; 15577 15578 cpu_gpr[0] = NULL; 15579 for (i = 1; i < 32; i++) 15580 cpu_gpr[i] = tcg_global_mem_new(cpu_env, 15581 offsetof(CPUMIPSState, 15582 active_tc.gpr[i]), 15583 regnames[i]); 15584 #if defined(TARGET_MIPS64) 15585 cpu_gpr_hi[0] = NULL; 15586 15587 for (unsigned i = 1; i < 32; i++) { 15588 g_autofree char *rname = g_strdup_printf("%s[hi]", regnames[i]); 15589 15590 cpu_gpr_hi[i] = tcg_global_mem_new_i64(cpu_env, 15591 offsetof(CPUMIPSState, 15592 active_tc.gpr_hi[i]), 15593 rname); 15594 } 15595 #endif /* !TARGET_MIPS64 */ 15596 for (i = 0; i < 32; i++) { 15597 int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]); 15598 15599 fpu_f64[i] = tcg_global_mem_new_i64(cpu_env, off, fregnames[i]); 15600 } 15601 msa_translate_init(); 15602 cpu_PC = tcg_global_mem_new(cpu_env, 15603 offsetof(CPUMIPSState, active_tc.PC), "PC"); 15604 for (i = 0; i < MIPS_DSP_ACC; i++) { 15605 cpu_HI[i] = tcg_global_mem_new(cpu_env, 15606 offsetof(CPUMIPSState, active_tc.HI[i]), 15607 regnames_HI[i]); 15608 cpu_LO[i] = tcg_global_mem_new(cpu_env, 15609 offsetof(CPUMIPSState, active_tc.LO[i]), 15610 regnames_LO[i]); 15611 } 15612 cpu_dspctrl = tcg_global_mem_new(cpu_env, 15613 offsetof(CPUMIPSState, 15614 active_tc.DSPControl), 15615 "DSPControl"); 15616 bcond = tcg_global_mem_new(cpu_env, 15617 offsetof(CPUMIPSState, bcond), "bcond"); 15618 btarget = tcg_global_mem_new(cpu_env, 15619 offsetof(CPUMIPSState, btarget), "btarget"); 15620 hflags = tcg_global_mem_new_i32(cpu_env, 15621 offsetof(CPUMIPSState, hflags), "hflags"); 15622 15623 fpu_fcr0 = tcg_global_mem_new_i32(cpu_env, 15624 offsetof(CPUMIPSState, active_fpu.fcr0), 15625 "fcr0"); 15626 fpu_fcr31 = tcg_global_mem_new_i32(cpu_env, 15627 offsetof(CPUMIPSState, active_fpu.fcr31), 15628 "fcr31"); 15629 cpu_lladdr = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, lladdr), 15630 "lladdr"); 15631 cpu_llval = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, llval), 15632 "llval"); 15633 15634 if (TARGET_LONG_BITS == 32) { 15635 mxu_translate_init(); 15636 } 15637 } 15638 15639 void mips_restore_state_to_opc(CPUState *cs, 15640 const TranslationBlock *tb, 15641 const uint64_t *data) 15642 { 15643 MIPSCPU *cpu = MIPS_CPU(cs); 15644 CPUMIPSState *env = &cpu->env; 15645 15646 env->active_tc.PC = data[0]; 15647 env->hflags &= ~MIPS_HFLAG_BMASK; 15648 env->hflags |= data[1]; 15649 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) { 15650 case MIPS_HFLAG_BR: 15651 break; 15652 case MIPS_HFLAG_BC: 15653 case MIPS_HFLAG_BL: 15654 case MIPS_HFLAG_B: 15655 env->btarget = data[2]; 15656 break; 15657 } 15658 } 15659