1 /* 2 * MIPS32 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 * 8 * This library is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU Lesser General Public 10 * License as published by the Free Software Foundation; either 11 * version 2 of the License, or (at your option) any later version. 12 * 13 * This library is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * Lesser General Public License for more details. 17 * 18 * You should have received a copy of the GNU Lesser General Public 19 * License along with this library; if not, see <http://www.gnu.org/licenses/>. 20 */ 21 22 #include <stdarg.h> 23 #include <stdlib.h> 24 #include <stdio.h> 25 #include <string.h> 26 #include <inttypes.h> 27 28 #include "cpu.h" 29 #include "disas/disas.h" 30 #include "tcg-op.h" 31 #include "qemu-common.h" 32 33 #include "helper.h" 34 #define GEN_HELPER 1 35 #include "helper.h" 36 37 //#define MIPS_DEBUG_DISAS 38 //#define MIPS_DEBUG_SIGN_EXTENSIONS 39 40 /* MIPS major opcodes */ 41 #define MASK_OP_MAJOR(op) (op & (0x3F << 26)) 42 43 enum { 44 /* indirect opcode tables */ 45 OPC_SPECIAL = (0x00 << 26), 46 OPC_REGIMM = (0x01 << 26), 47 OPC_CP0 = (0x10 << 26), 48 OPC_CP1 = (0x11 << 26), 49 OPC_CP2 = (0x12 << 26), 50 OPC_CP3 = (0x13 << 26), 51 OPC_SPECIAL2 = (0x1C << 26), 52 OPC_SPECIAL3 = (0x1F << 26), 53 /* arithmetic with immediate */ 54 OPC_ADDI = (0x08 << 26), 55 OPC_ADDIU = (0x09 << 26), 56 OPC_SLTI = (0x0A << 26), 57 OPC_SLTIU = (0x0B << 26), 58 /* logic with immediate */ 59 OPC_ANDI = (0x0C << 26), 60 OPC_ORI = (0x0D << 26), 61 OPC_XORI = (0x0E << 26), 62 OPC_LUI = (0x0F << 26), 63 /* arithmetic with immediate */ 64 OPC_DADDI = (0x18 << 26), 65 OPC_DADDIU = (0x19 << 26), 66 /* Jump and branches */ 67 OPC_J = (0x02 << 26), 68 OPC_JAL = (0x03 << 26), 69 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */ 70 OPC_BEQL = (0x14 << 26), 71 OPC_BNE = (0x05 << 26), 72 OPC_BNEL = (0x15 << 26), 73 OPC_BLEZ = (0x06 << 26), 74 OPC_BLEZL = (0x16 << 26), 75 OPC_BGTZ = (0x07 << 26), 76 OPC_BGTZL = (0x17 << 26), 77 OPC_JALX = (0x1D << 26), /* MIPS 16 only */ 78 /* Load and stores */ 79 OPC_LDL = (0x1A << 26), 80 OPC_LDR = (0x1B << 26), 81 OPC_LB = (0x20 << 26), 82 OPC_LH = (0x21 << 26), 83 OPC_LWL = (0x22 << 26), 84 OPC_LW = (0x23 << 26), 85 OPC_LBU = (0x24 << 26), 86 OPC_LHU = (0x25 << 26), 87 OPC_LWR = (0x26 << 26), 88 OPC_LWU = (0x27 << 26), 89 OPC_SB = (0x28 << 26), 90 OPC_SH = (0x29 << 26), 91 OPC_SWL = (0x2A << 26), 92 OPC_SW = (0x2B << 26), 93 OPC_SDL = (0x2C << 26), 94 OPC_SDR = (0x2D << 26), 95 OPC_SWR = (0x2E << 26), 96 OPC_LL = (0x30 << 26), 97 OPC_LLD = (0x34 << 26), 98 OPC_LD = (0x37 << 26), 99 OPC_SC = (0x38 << 26), 100 OPC_SCD = (0x3C << 26), 101 OPC_SD = (0x3F << 26), 102 /* Floating point load/store */ 103 OPC_LWC1 = (0x31 << 26), 104 OPC_LWC2 = (0x32 << 26), 105 OPC_LDC1 = (0x35 << 26), 106 OPC_LDC2 = (0x36 << 26), 107 OPC_SWC1 = (0x39 << 26), 108 OPC_SWC2 = (0x3A << 26), 109 OPC_SDC1 = (0x3D << 26), 110 OPC_SDC2 = (0x3E << 26), 111 /* MDMX ASE specific */ 112 OPC_MDMX = (0x1E << 26), 113 /* Cache and prefetch */ 114 OPC_CACHE = (0x2F << 26), 115 OPC_PREF = (0x33 << 26), 116 /* Reserved major opcode */ 117 OPC_MAJOR3B_RESERVED = (0x3B << 26), 118 }; 119 120 /* MIPS special opcodes */ 121 #define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F) 122 123 enum { 124 /* Shifts */ 125 OPC_SLL = 0x00 | OPC_SPECIAL, 126 /* NOP is SLL r0, r0, 0 */ 127 /* SSNOP is SLL r0, r0, 1 */ 128 /* EHB is SLL r0, r0, 3 */ 129 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */ 130 OPC_SRA = 0x03 | OPC_SPECIAL, 131 OPC_SLLV = 0x04 | OPC_SPECIAL, 132 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */ 133 OPC_SRAV = 0x07 | OPC_SPECIAL, 134 OPC_DSLLV = 0x14 | OPC_SPECIAL, 135 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */ 136 OPC_DSRAV = 0x17 | OPC_SPECIAL, 137 OPC_DSLL = 0x38 | OPC_SPECIAL, 138 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */ 139 OPC_DSRA = 0x3B | OPC_SPECIAL, 140 OPC_DSLL32 = 0x3C | OPC_SPECIAL, 141 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */ 142 OPC_DSRA32 = 0x3F | OPC_SPECIAL, 143 /* Multiplication / division */ 144 OPC_MULT = 0x18 | OPC_SPECIAL, 145 OPC_MULTU = 0x19 | OPC_SPECIAL, 146 OPC_DIV = 0x1A | OPC_SPECIAL, 147 OPC_DIVU = 0x1B | OPC_SPECIAL, 148 OPC_DMULT = 0x1C | OPC_SPECIAL, 149 OPC_DMULTU = 0x1D | OPC_SPECIAL, 150 OPC_DDIV = 0x1E | OPC_SPECIAL, 151 OPC_DDIVU = 0x1F | OPC_SPECIAL, 152 /* 2 registers arithmetic / logic */ 153 OPC_ADD = 0x20 | OPC_SPECIAL, 154 OPC_ADDU = 0x21 | OPC_SPECIAL, 155 OPC_SUB = 0x22 | OPC_SPECIAL, 156 OPC_SUBU = 0x23 | OPC_SPECIAL, 157 OPC_AND = 0x24 | OPC_SPECIAL, 158 OPC_OR = 0x25 | OPC_SPECIAL, 159 OPC_XOR = 0x26 | OPC_SPECIAL, 160 OPC_NOR = 0x27 | OPC_SPECIAL, 161 OPC_SLT = 0x2A | OPC_SPECIAL, 162 OPC_SLTU = 0x2B | OPC_SPECIAL, 163 OPC_DADD = 0x2C | OPC_SPECIAL, 164 OPC_DADDU = 0x2D | OPC_SPECIAL, 165 OPC_DSUB = 0x2E | OPC_SPECIAL, 166 OPC_DSUBU = 0x2F | OPC_SPECIAL, 167 /* Jumps */ 168 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */ 169 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */ 170 /* Traps */ 171 OPC_TGE = 0x30 | OPC_SPECIAL, 172 OPC_TGEU = 0x31 | OPC_SPECIAL, 173 OPC_TLT = 0x32 | OPC_SPECIAL, 174 OPC_TLTU = 0x33 | OPC_SPECIAL, 175 OPC_TEQ = 0x34 | OPC_SPECIAL, 176 OPC_TNE = 0x36 | OPC_SPECIAL, 177 /* HI / LO registers load & stores */ 178 OPC_MFHI = 0x10 | OPC_SPECIAL, 179 OPC_MTHI = 0x11 | OPC_SPECIAL, 180 OPC_MFLO = 0x12 | OPC_SPECIAL, 181 OPC_MTLO = 0x13 | OPC_SPECIAL, 182 /* Conditional moves */ 183 OPC_MOVZ = 0x0A | OPC_SPECIAL, 184 OPC_MOVN = 0x0B | OPC_SPECIAL, 185 186 OPC_MOVCI = 0x01 | OPC_SPECIAL, 187 188 /* Special */ 189 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */ 190 OPC_SYSCALL = 0x0C | OPC_SPECIAL, 191 OPC_BREAK = 0x0D | OPC_SPECIAL, 192 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */ 193 OPC_SYNC = 0x0F | OPC_SPECIAL, 194 195 OPC_SPECIAL15_RESERVED = 0x15 | OPC_SPECIAL, 196 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL, 197 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL, 198 OPC_SPECIAL35_RESERVED = 0x35 | OPC_SPECIAL, 199 OPC_SPECIAL37_RESERVED = 0x37 | OPC_SPECIAL, 200 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL, 201 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL, 202 }; 203 204 /* Multiplication variants of the vr54xx. */ 205 #define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6)) 206 207 enum { 208 OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT, 209 OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU, 210 OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT, 211 OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU, 212 OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT, 213 OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU, 214 OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT, 215 OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU, 216 OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT, 217 OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU, 218 OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT, 219 OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU, 220 OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT, 221 OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU, 222 }; 223 224 /* REGIMM (rt field) opcodes */ 225 #define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16)) 226 227 enum { 228 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM, 229 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM, 230 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM, 231 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM, 232 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM, 233 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM, 234 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM, 235 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM, 236 OPC_TGEI = (0x08 << 16) | OPC_REGIMM, 237 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM, 238 OPC_TLTI = (0x0A << 16) | OPC_REGIMM, 239 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM, 240 OPC_TEQI = (0x0C << 16) | OPC_REGIMM, 241 OPC_TNEI = (0x0E << 16) | OPC_REGIMM, 242 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM, 243 }; 244 245 /* Special2 opcodes */ 246 #define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F) 247 248 enum { 249 /* Multiply & xxx operations */ 250 OPC_MADD = 0x00 | OPC_SPECIAL2, 251 OPC_MADDU = 0x01 | OPC_SPECIAL2, 252 OPC_MUL = 0x02 | OPC_SPECIAL2, 253 OPC_MSUB = 0x04 | OPC_SPECIAL2, 254 OPC_MSUBU = 0x05 | OPC_SPECIAL2, 255 /* Misc */ 256 OPC_CLZ = 0x20 | OPC_SPECIAL2, 257 OPC_CLO = 0x21 | OPC_SPECIAL2, 258 OPC_DCLZ = 0x24 | OPC_SPECIAL2, 259 OPC_DCLO = 0x25 | OPC_SPECIAL2, 260 /* Special */ 261 OPC_SDBBP = 0x3F | OPC_SPECIAL2, 262 }; 263 264 /* Special3 opcodes */ 265 #define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F) 266 267 enum { 268 OPC_EXT = 0x00 | OPC_SPECIAL3, 269 OPC_DEXTM = 0x01 | OPC_SPECIAL3, 270 OPC_DEXTU = 0x02 | OPC_SPECIAL3, 271 OPC_DEXT = 0x03 | OPC_SPECIAL3, 272 OPC_INS = 0x04 | OPC_SPECIAL3, 273 OPC_DINSM = 0x05 | OPC_SPECIAL3, 274 OPC_DINSU = 0x06 | OPC_SPECIAL3, 275 OPC_DINS = 0x07 | OPC_SPECIAL3, 276 OPC_FORK = 0x08 | OPC_SPECIAL3, 277 OPC_YIELD = 0x09 | OPC_SPECIAL3, 278 OPC_BSHFL = 0x20 | OPC_SPECIAL3, 279 OPC_DBSHFL = 0x24 | OPC_SPECIAL3, 280 OPC_RDHWR = 0x3B | OPC_SPECIAL3, 281 }; 282 283 /* BSHFL opcodes */ 284 #define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6)) 285 286 enum { 287 OPC_WSBH = (0x02 << 6) | OPC_BSHFL, 288 OPC_SEB = (0x10 << 6) | OPC_BSHFL, 289 OPC_SEH = (0x18 << 6) | OPC_BSHFL, 290 }; 291 292 /* DBSHFL opcodes */ 293 #define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6)) 294 295 enum { 296 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL, 297 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL, 298 }; 299 300 /* Coprocessor 0 (rs field) */ 301 #define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21)) 302 303 enum { 304 OPC_MFC0 = (0x00 << 21) | OPC_CP0, 305 OPC_DMFC0 = (0x01 << 21) | OPC_CP0, 306 OPC_MTC0 = (0x04 << 21) | OPC_CP0, 307 OPC_DMTC0 = (0x05 << 21) | OPC_CP0, 308 OPC_MFTR = (0x08 << 21) | OPC_CP0, 309 OPC_RDPGPR = (0x0A << 21) | OPC_CP0, 310 OPC_MFMC0 = (0x0B << 21) | OPC_CP0, 311 OPC_MTTR = (0x0C << 21) | OPC_CP0, 312 OPC_WRPGPR = (0x0E << 21) | OPC_CP0, 313 OPC_C0 = (0x10 << 21) | OPC_CP0, 314 OPC_C0_FIRST = (0x10 << 21) | OPC_CP0, 315 OPC_C0_LAST = (0x1F << 21) | OPC_CP0, 316 }; 317 318 /* MFMC0 opcodes */ 319 #define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF) 320 321 enum { 322 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0, 323 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0, 324 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0, 325 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0, 326 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0, 327 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0, 328 }; 329 330 /* Coprocessor 0 (with rs == C0) */ 331 #define MASK_C0(op) MASK_CP0(op) | (op & 0x3F) 332 333 enum { 334 OPC_TLBR = 0x01 | OPC_C0, 335 OPC_TLBWI = 0x02 | OPC_C0, 336 OPC_TLBWR = 0x06 | OPC_C0, 337 OPC_TLBP = 0x08 | OPC_C0, 338 OPC_RFE = 0x10 | OPC_C0, 339 OPC_ERET = 0x18 | OPC_C0, 340 OPC_DERET = 0x1F | OPC_C0, 341 OPC_WAIT = 0x20 | OPC_C0, 342 }; 343 344 /* Coprocessor 1 (rs field) */ 345 #define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21)) 346 347 enum { 348 OPC_MFC1 = (0x00 << 21) | OPC_CP1, 349 OPC_DMFC1 = (0x01 << 21) | OPC_CP1, 350 OPC_CFC1 = (0x02 << 21) | OPC_CP1, 351 OPC_MFHC1 = (0x03 << 21) | OPC_CP1, 352 OPC_MTC1 = (0x04 << 21) | OPC_CP1, 353 OPC_DMTC1 = (0x05 << 21) | OPC_CP1, 354 OPC_CTC1 = (0x06 << 21) | OPC_CP1, 355 OPC_MTHC1 = (0x07 << 21) | OPC_CP1, 356 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */ 357 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1, 358 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1, 359 OPC_S_FMT = (0x10 << 21) | OPC_CP1, /* 16: fmt=single fp */ 360 OPC_D_FMT = (0x11 << 21) | OPC_CP1, /* 17: fmt=double fp */ 361 OPC_E_FMT = (0x12 << 21) | OPC_CP1, /* 18: fmt=extended fp */ 362 OPC_Q_FMT = (0x13 << 21) | OPC_CP1, /* 19: fmt=quad fp */ 363 OPC_W_FMT = (0x14 << 21) | OPC_CP1, /* 20: fmt=32bit fixed */ 364 OPC_L_FMT = (0x15 << 21) | OPC_CP1, /* 21: fmt=64bit fixed */ 365 OPC_PS_FMT = (0x16 << 21) | OPC_CP1, /* 22: fmt=paired single fp */ 366 }; 367 368 #define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F) 369 #define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16)) 370 371 enum { 372 OPC_BC1F = (0x00 << 16) | OPC_BC1, 373 OPC_BC1T = (0x01 << 16) | OPC_BC1, 374 OPC_BC1FL = (0x02 << 16) | OPC_BC1, 375 OPC_BC1TL = (0x03 << 16) | OPC_BC1, 376 }; 377 378 enum { 379 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2, 380 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2, 381 }; 382 383 enum { 384 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4, 385 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4, 386 }; 387 388 #define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21)) 389 390 enum { 391 OPC_MFC2 = (0x00 << 21) | OPC_CP2, 392 OPC_DMFC2 = (0x01 << 21) | OPC_CP2, 393 OPC_CFC2 = (0x02 << 21) | OPC_CP2, 394 OPC_MFHC2 = (0x03 << 21) | OPC_CP2, 395 OPC_MTC2 = (0x04 << 21) | OPC_CP2, 396 OPC_DMTC2 = (0x05 << 21) | OPC_CP2, 397 OPC_CTC2 = (0x06 << 21) | OPC_CP2, 398 OPC_MTHC2 = (0x07 << 21) | OPC_CP2, 399 OPC_BC2 = (0x08 << 21) | OPC_CP2, 400 }; 401 402 #define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F) 403 404 enum { 405 OPC_LWXC1 = 0x00 | OPC_CP3, 406 OPC_LDXC1 = 0x01 | OPC_CP3, 407 OPC_LUXC1 = 0x05 | OPC_CP3, 408 OPC_SWXC1 = 0x08 | OPC_CP3, 409 OPC_SDXC1 = 0x09 | OPC_CP3, 410 OPC_SUXC1 = 0x0D | OPC_CP3, 411 OPC_PREFX = 0x0F | OPC_CP3, 412 OPC_ALNV_PS = 0x1E | OPC_CP3, 413 OPC_MADD_S = 0x20 | OPC_CP3, 414 OPC_MADD_D = 0x21 | OPC_CP3, 415 OPC_MADD_PS = 0x26 | OPC_CP3, 416 OPC_MSUB_S = 0x28 | OPC_CP3, 417 OPC_MSUB_D = 0x29 | OPC_CP3, 418 OPC_MSUB_PS = 0x2E | OPC_CP3, 419 OPC_NMADD_S = 0x30 | OPC_CP3, 420 OPC_NMADD_D = 0x31 | OPC_CP3, 421 OPC_NMADD_PS= 0x36 | OPC_CP3, 422 OPC_NMSUB_S = 0x38 | OPC_CP3, 423 OPC_NMSUB_D = 0x39 | OPC_CP3, 424 OPC_NMSUB_PS= 0x3E | OPC_CP3, 425 }; 426 427 /* global register indices */ 428 static TCGv_ptr cpu_env; 429 static TCGv cpu_gpr[32], cpu_PC; 430 static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC], cpu_ACX[MIPS_DSP_ACC]; 431 static TCGv cpu_dspctrl, btarget, bcond; 432 static TCGv_i32 hflags; 433 static TCGv_i32 fpu_fcr0, fpu_fcr31; 434 435 static uint32_t gen_opc_hflags[OPC_BUF_SIZE]; 436 437 #include "exec/gen-icount.h" 438 439 #define gen_helper_0i(name, arg) do { \ 440 TCGv_i32 helper_tmp = tcg_const_i32(arg); \ 441 gen_helper_##name(helper_tmp); \ 442 tcg_temp_free_i32(helper_tmp); \ 443 } while(0) 444 445 #define gen_helper_1i(name, arg1, arg2) do { \ 446 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \ 447 gen_helper_##name(arg1, helper_tmp); \ 448 tcg_temp_free_i32(helper_tmp); \ 449 } while(0) 450 451 #define gen_helper_2i(name, arg1, arg2, arg3) do { \ 452 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \ 453 gen_helper_##name(arg1, arg2, helper_tmp); \ 454 tcg_temp_free_i32(helper_tmp); \ 455 } while(0) 456 457 #define gen_helper_3i(name, arg1, arg2, arg3, arg4) do { \ 458 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \ 459 gen_helper_##name(arg1, arg2, arg3, helper_tmp); \ 460 tcg_temp_free_i32(helper_tmp); \ 461 } while(0) 462 463 #define gen_helper_4i(name, arg1, arg2, arg3, arg4, arg5) do { \ 464 TCGv_i32 helper_tmp = tcg_const_i32(arg5); \ 465 gen_helper_##name(arg1, arg2, arg3, arg4, helper_tmp); \ 466 tcg_temp_free_i32(helper_tmp); \ 467 } while(0) 468 469 typedef struct DisasContext { 470 struct TranslationBlock *tb; 471 target_ulong pc, saved_pc; 472 uint32_t opcode; 473 int singlestep_enabled; 474 /* Routine used to access memory */ 475 int mem_idx; 476 uint32_t hflags, saved_hflags; 477 int bstate; 478 target_ulong btarget; 479 } DisasContext; 480 481 enum { 482 BS_NONE = 0, /* We go out of the TB without reaching a branch or an 483 * exception condition */ 484 BS_STOP = 1, /* We want to stop translation for any reason */ 485 BS_BRANCH = 2, /* We reached a branch condition */ 486 BS_EXCP = 3, /* We reached an exception condition */ 487 }; 488 489 static const char *regnames[] = 490 { "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3", 491 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", 492 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", 493 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", }; 494 495 static const char *regnames_HI[] = 496 { "HI0", "HI1", "HI2", "HI3", }; 497 498 static const char *regnames_LO[] = 499 { "LO0", "LO1", "LO2", "LO3", }; 500 501 static const char *regnames_ACX[] = 502 { "ACX0", "ACX1", "ACX2", "ACX3", }; 503 504 static const char *fregnames[] = 505 { "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", 506 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", 507 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", 508 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", }; 509 510 #ifdef MIPS_DEBUG_DISAS 511 #define MIPS_DEBUG(fmt, ...) \ 512 qemu_log_mask(CPU_LOG_TB_IN_ASM, \ 513 TARGET_FMT_lx ": %08x " fmt "\n", \ 514 ctx->pc, ctx->opcode , ## __VA_ARGS__) 515 #define LOG_DISAS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__) 516 #else 517 #define MIPS_DEBUG(fmt, ...) do { } while(0) 518 #define LOG_DISAS(...) do { } while (0) 519 #endif 520 521 #define MIPS_INVAL(op) \ 522 do { \ 523 MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \ 524 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F)); \ 525 } while (0) 526 527 /* General purpose registers moves. */ 528 static inline void gen_load_gpr (TCGv t, int reg) 529 { 530 if (reg == 0) 531 tcg_gen_movi_tl(t, 0); 532 else 533 tcg_gen_mov_tl(t, cpu_gpr[reg]); 534 } 535 536 static inline void gen_store_gpr (TCGv t, int reg) 537 { 538 if (reg != 0) 539 tcg_gen_mov_tl(cpu_gpr[reg], t); 540 } 541 542 /* Moves to/from ACX register. */ 543 static inline void gen_load_ACX (TCGv t, int reg) 544 { 545 tcg_gen_mov_tl(t, cpu_ACX[reg]); 546 } 547 548 static inline void gen_store_ACX (TCGv t, int reg) 549 { 550 tcg_gen_mov_tl(cpu_ACX[reg], t); 551 } 552 553 /* Moves to/from shadow registers. */ 554 static inline void gen_load_srsgpr (int from, int to) 555 { 556 TCGv t0 = tcg_temp_new(); 557 558 if (from == 0) 559 tcg_gen_movi_tl(t0, 0); 560 else { 561 TCGv_i32 t2 = tcg_temp_new_i32(); 562 TCGv_ptr addr = tcg_temp_new_ptr(); 563 564 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl)); 565 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS); 566 tcg_gen_andi_i32(t2, t2, 0xf); 567 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32); 568 tcg_gen_ext_i32_ptr(addr, t2); 569 tcg_gen_add_ptr(addr, cpu_env, addr); 570 571 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from); 572 tcg_temp_free_ptr(addr); 573 tcg_temp_free_i32(t2); 574 } 575 gen_store_gpr(t0, to); 576 tcg_temp_free(t0); 577 } 578 579 static inline void gen_store_srsgpr (int from, int to) 580 { 581 if (to != 0) { 582 TCGv t0 = tcg_temp_new(); 583 TCGv_i32 t2 = tcg_temp_new_i32(); 584 TCGv_ptr addr = tcg_temp_new_ptr(); 585 586 gen_load_gpr(t0, from); 587 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl)); 588 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS); 589 tcg_gen_andi_i32(t2, t2, 0xf); 590 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32); 591 tcg_gen_ext_i32_ptr(addr, t2); 592 tcg_gen_add_ptr(addr, cpu_env, addr); 593 594 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to); 595 tcg_temp_free_ptr(addr); 596 tcg_temp_free_i32(t2); 597 tcg_temp_free(t0); 598 } 599 } 600 601 /* Floating point register moves. */ 602 static inline void gen_load_fpr32 (TCGv_i32 t, int reg) 603 { 604 tcg_gen_ld_i32(t, cpu_env, offsetof(CPUMIPSState, active_fpu.fpr[reg].w[FP_ENDIAN_IDX])); 605 } 606 607 static inline void gen_store_fpr32 (TCGv_i32 t, int reg) 608 { 609 tcg_gen_st_i32(t, cpu_env, offsetof(CPUMIPSState, active_fpu.fpr[reg].w[FP_ENDIAN_IDX])); 610 } 611 612 static inline void gen_load_fpr32h (TCGv_i32 t, int reg) 613 { 614 tcg_gen_ld_i32(t, cpu_env, offsetof(CPUMIPSState, active_fpu.fpr[reg].w[!FP_ENDIAN_IDX])); 615 } 616 617 static inline void gen_store_fpr32h (TCGv_i32 t, int reg) 618 { 619 tcg_gen_st_i32(t, cpu_env, offsetof(CPUMIPSState, active_fpu.fpr[reg].w[!FP_ENDIAN_IDX])); 620 } 621 622 static inline void gen_load_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg) 623 { 624 if (ctx->hflags & MIPS_HFLAG_F64) { 625 tcg_gen_ld_i64(t, cpu_env, offsetof(CPUMIPSState, active_fpu.fpr[reg].d)); 626 } else { 627 TCGv_i32 t0 = tcg_temp_new_i32(); 628 TCGv_i32 t1 = tcg_temp_new_i32(); 629 gen_load_fpr32(t0, reg & ~1); 630 gen_load_fpr32(t1, reg | 1); 631 tcg_gen_concat_i32_i64(t, t0, t1); 632 tcg_temp_free_i32(t0); 633 tcg_temp_free_i32(t1); 634 } 635 } 636 637 static inline void gen_store_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg) 638 { 639 if (ctx->hflags & MIPS_HFLAG_F64) { 640 tcg_gen_st_i64(t, cpu_env, offsetof(CPUMIPSState, active_fpu.fpr[reg].d)); 641 } else { 642 TCGv_i64 t0 = tcg_temp_new_i64(); 643 TCGv_i32 t1 = tcg_temp_new_i32(); 644 tcg_gen_trunc_i64_i32(t1, t); 645 gen_store_fpr32(t1, reg & ~1); 646 tcg_gen_shri_i64(t0, t, 32); 647 tcg_gen_trunc_i64_i32(t1, t0); 648 gen_store_fpr32(t1, reg | 1); 649 tcg_temp_free_i32(t1); 650 tcg_temp_free_i64(t0); 651 } 652 } 653 654 static inline int get_fp_bit (int cc) 655 { 656 if (cc) 657 return 24 + cc; 658 else 659 return 23; 660 } 661 662 #define FOP_CONDS(type, fmt, bits) \ 663 static inline void gen_cmp ## type ## _ ## fmt(int n, TCGv_i##bits a, \ 664 TCGv_i##bits b, int cc) \ 665 { \ 666 switch (n) { \ 667 case 0: gen_helper_3i(cmp ## type ## _ ## fmt ## _f, cpu_env, a, b, cc); break;\ 668 case 1: gen_helper_3i(cmp ## type ## _ ## fmt ## _un, cpu_env, a, b, cc); break;\ 669 case 2: gen_helper_3i(cmp ## type ## _ ## fmt ## _eq, cpu_env, a, b, cc); break;\ 670 case 3: gen_helper_3i(cmp ## type ## _ ## fmt ## _ueq, cpu_env, a, b, cc); break;\ 671 case 4: gen_helper_3i(cmp ## type ## _ ## fmt ## _olt, cpu_env, a, b, cc); break;\ 672 case 5: gen_helper_3i(cmp ## type ## _ ## fmt ## _ult, cpu_env, a, b, cc); break;\ 673 case 6: gen_helper_3i(cmp ## type ## _ ## fmt ## _ole, cpu_env, a, b, cc); break;\ 674 case 7: gen_helper_3i(cmp ## type ## _ ## fmt ## _ule, cpu_env, a, b, cc); break;\ 675 case 8: gen_helper_3i(cmp ## type ## _ ## fmt ## _sf, cpu_env, a, b, cc); break;\ 676 case 9: gen_helper_3i(cmp ## type ## _ ## fmt ## _ngle, cpu_env, a, b, cc); break;\ 677 case 10: gen_helper_3i(cmp ## type ## _ ## fmt ## _seq, cpu_env, a, b, cc); break;\ 678 case 11: gen_helper_3i(cmp ## type ## _ ## fmt ## _ngl, cpu_env, a, b, cc); break;\ 679 case 12: gen_helper_3i(cmp ## type ## _ ## fmt ## _lt, cpu_env, a, b, cc); break;\ 680 case 13: gen_helper_3i(cmp ## type ## _ ## fmt ## _nge, cpu_env, a, b, cc); break;\ 681 case 14: gen_helper_3i(cmp ## type ## _ ## fmt ## _le, cpu_env, a, b, cc); break;\ 682 case 15: gen_helper_3i(cmp ## type ## _ ## fmt ## _ngt, cpu_env, a, b, cc); break;\ 683 default: abort(); \ 684 } \ 685 } 686 687 FOP_CONDS(, d, 64) 688 FOP_CONDS(abs, d, 64) 689 FOP_CONDS(, s, 32) 690 FOP_CONDS(abs, s, 32) 691 FOP_CONDS(, ps, 64) 692 FOP_CONDS(abs, ps, 64) 693 #undef FOP_CONDS 694 695 /* Tests */ 696 #define OP_COND(name, cond) \ 697 static inline void glue(gen_op_, name) (TCGv ret, TCGv t0, TCGv t1) \ 698 { \ 699 int l1 = gen_new_label(); \ 700 int l2 = gen_new_label(); \ 701 \ 702 tcg_gen_brcond_tl(cond, t0, t1, l1); \ 703 tcg_gen_movi_tl(ret, 0); \ 704 tcg_gen_br(l2); \ 705 gen_set_label(l1); \ 706 tcg_gen_movi_tl(ret, 1); \ 707 gen_set_label(l2); \ 708 } 709 OP_COND(eq, TCG_COND_EQ); 710 OP_COND(ne, TCG_COND_NE); 711 OP_COND(ge, TCG_COND_GE); 712 OP_COND(geu, TCG_COND_GEU); 713 OP_COND(lt, TCG_COND_LT); 714 OP_COND(ltu, TCG_COND_LTU); 715 #undef OP_COND 716 717 #define OP_CONDI(name, cond) \ 718 static inline void glue(gen_op_, name) (TCGv ret, TCGv t0, target_ulong val) \ 719 { \ 720 int l1 = gen_new_label(); \ 721 int l2 = gen_new_label(); \ 722 \ 723 tcg_gen_brcondi_tl(cond, t0, val, l1); \ 724 tcg_gen_movi_tl(ret, 0); \ 725 tcg_gen_br(l2); \ 726 gen_set_label(l1); \ 727 tcg_gen_movi_tl(ret, 1); \ 728 gen_set_label(l2); \ 729 } 730 OP_CONDI(lti, TCG_COND_LT); 731 OP_CONDI(ltiu, TCG_COND_LTU); 732 #undef OP_CONDI 733 734 #define OP_CONDZ(name, cond) \ 735 static inline void glue(gen_op_, name) (TCGv ret, TCGv t0) \ 736 { \ 737 int l1 = gen_new_label(); \ 738 int l2 = gen_new_label(); \ 739 \ 740 tcg_gen_brcondi_tl(cond, t0, 0, l1); \ 741 tcg_gen_movi_tl(ret, 0); \ 742 tcg_gen_br(l2); \ 743 gen_set_label(l1); \ 744 tcg_gen_movi_tl(ret, 1); \ 745 gen_set_label(l2); \ 746 } 747 OP_CONDZ(gez, TCG_COND_GE); 748 OP_CONDZ(gtz, TCG_COND_GT); 749 OP_CONDZ(lez, TCG_COND_LE); 750 OP_CONDZ(ltz, TCG_COND_LT); 751 #undef OP_CONDZ 752 753 static inline void gen_save_pc(target_ulong pc) 754 { 755 tcg_gen_movi_tl(cpu_PC, pc); 756 } 757 758 static inline void save_cpu_state (DisasContext *ctx, int do_save_pc) 759 { 760 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags); 761 if (do_save_pc && ctx->pc != ctx->saved_pc) { 762 gen_save_pc(ctx->pc); 763 ctx->saved_pc = ctx->pc; 764 } 765 if (ctx->hflags != ctx->saved_hflags) { 766 tcg_gen_movi_i32(hflags, ctx->hflags); 767 ctx->saved_hflags = ctx->hflags; 768 switch (ctx->hflags & MIPS_HFLAG_BMASK) { 769 case MIPS_HFLAG_BR: 770 break; 771 case MIPS_HFLAG_BC: 772 case MIPS_HFLAG_BL: 773 case MIPS_HFLAG_B: 774 tcg_gen_movi_tl(btarget, ctx->btarget); 775 break; 776 } 777 } 778 } 779 780 static inline void restore_cpu_state (CPUMIPSState *env, DisasContext *ctx) 781 { 782 ctx->saved_hflags = ctx->hflags; 783 switch (ctx->hflags & MIPS_HFLAG_BMASK) { 784 case MIPS_HFLAG_BR: 785 break; 786 case MIPS_HFLAG_BC: 787 case MIPS_HFLAG_BL: 788 case MIPS_HFLAG_B: 789 ctx->btarget = env->btarget; 790 break; 791 } 792 } 793 794 static inline void 795 generate_exception_err (DisasContext *ctx, int excp, int err) 796 { 797 TCGv_i32 texcp = tcg_const_i32(excp); 798 TCGv_i32 terr = tcg_const_i32(err); 799 save_cpu_state(ctx, 1); 800 gen_helper_raise_exception_err(cpu_env, texcp, terr); 801 tcg_temp_free_i32(terr); 802 tcg_temp_free_i32(texcp); 803 } 804 805 static inline void 806 generate_exception (DisasContext *ctx, int excp) 807 { 808 save_cpu_state(ctx, 1); 809 gen_helper_1i(raise_exception, cpu_env, excp); 810 } 811 812 /* Addresses computation */ 813 static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1) 814 { 815 tcg_gen_add_tl(ret, arg0, arg1); 816 817 #if defined(TARGET_MIPS64) 818 /* For compatibility with 32-bit code, data reference in user mode 819 with Status_UX = 0 should be casted to 32-bit and sign extended. 820 See the MIPS64 PRA manual, section 4.10. */ 821 if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) && 822 !(ctx->hflags & MIPS_HFLAG_UX)) { 823 tcg_gen_ext32s_i64(ret, ret); 824 } 825 #endif 826 } 827 828 static inline void check_cp0_enabled(DisasContext *ctx) 829 { 830 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) 831 generate_exception_err(ctx, EXCP_CpU, 0); 832 } 833 834 static inline void check_cp1_enabled(DisasContext *ctx) 835 { 836 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU))) 837 generate_exception_err(ctx, EXCP_CpU, 1); 838 } 839 840 /* Verify that the processor is running with COP1X instructions enabled. 841 This is associated with the nabla symbol in the MIPS32 and MIPS64 842 opcode tables. */ 843 844 static inline void check_cop1x(DisasContext *ctx) 845 { 846 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X))) 847 generate_exception(ctx, EXCP_RI); 848 } 849 850 /* Verify that the processor is running with 64-bit floating-point 851 operations enabled. */ 852 853 static inline void check_cp1_64bitmode(DisasContext *ctx) 854 { 855 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X))) 856 generate_exception(ctx, EXCP_RI); 857 } 858 859 /* 860 * Verify if floating point register is valid; an operation is not defined 861 * if bit 0 of any register specification is set and the FR bit in the 862 * Status register equals zero, since the register numbers specify an 863 * even-odd pair of adjacent coprocessor general registers. When the FR bit 864 * in the Status register equals one, both even and odd register numbers 865 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers. 866 * 867 * Multiple 64 bit wide registers can be checked by calling 868 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN); 869 */ 870 static inline void check_cp1_registers(DisasContext *ctx, int regs) 871 { 872 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1))) 873 generate_exception(ctx, EXCP_RI); 874 } 875 876 /* This code generates a "reserved instruction" exception if the 877 CPU does not support the instruction set corresponding to flags. */ 878 static inline void check_insn(CPUMIPSState *env, DisasContext *ctx, int flags) 879 { 880 if (unlikely(!(env->insn_flags & flags))) 881 generate_exception(ctx, EXCP_RI); 882 } 883 884 /* This code generates a "reserved instruction" exception if 64-bit 885 instructions are not enabled. */ 886 static inline void check_mips_64(DisasContext *ctx) 887 { 888 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64))) 889 generate_exception(ctx, EXCP_RI); 890 } 891 892 /* load/store instructions. */ 893 #define OP_LD(insn,fname) \ 894 static inline void op_ldst_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \ 895 { \ 896 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \ 897 } 898 OP_LD(lb,ld8s); 899 OP_LD(lbu,ld8u); 900 OP_LD(lh,ld16s); 901 OP_LD(lhu,ld16u); 902 OP_LD(lw,ld32s); 903 #if defined(TARGET_MIPS64) 904 OP_LD(lwu,ld32u); 905 OP_LD(ld,ld64); 906 #endif 907 #undef OP_LD 908 909 #define OP_ST(insn,fname) \ 910 static inline void op_ldst_##insn(TCGv arg1, TCGv arg2, DisasContext *ctx) \ 911 { \ 912 tcg_gen_qemu_##fname(arg1, arg2, ctx->mem_idx); \ 913 } 914 OP_ST(sb,st8); 915 OP_ST(sh,st16); 916 OP_ST(sw,st32); 917 #if defined(TARGET_MIPS64) 918 OP_ST(sd,st64); 919 #endif 920 #undef OP_ST 921 922 #ifdef CONFIG_USER_ONLY 923 #define OP_LD_ATOMIC(insn,fname) \ 924 static inline void op_ldst_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \ 925 { \ 926 TCGv t0 = tcg_temp_new(); \ 927 tcg_gen_mov_tl(t0, arg1); \ 928 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \ 929 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \ 930 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \ 931 tcg_temp_free(t0); \ 932 } 933 #else 934 #define OP_LD_ATOMIC(insn,fname) \ 935 static inline void op_ldst_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \ 936 { \ 937 gen_helper_3i(insn, ret, cpu_env, arg1, ctx->mem_idx); \ 938 } 939 #endif 940 OP_LD_ATOMIC(ll,ld32s); 941 #if defined(TARGET_MIPS64) 942 OP_LD_ATOMIC(lld,ld64); 943 #endif 944 #undef OP_LD_ATOMIC 945 946 #ifdef CONFIG_USER_ONLY 947 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \ 948 static inline void op_ldst_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \ 949 { \ 950 TCGv t0 = tcg_temp_new(); \ 951 int l1 = gen_new_label(); \ 952 int l2 = gen_new_label(); \ 953 \ 954 tcg_gen_andi_tl(t0, arg2, almask); \ 955 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \ 956 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \ 957 generate_exception(ctx, EXCP_AdES); \ 958 gen_set_label(l1); \ 959 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \ 960 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \ 961 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \ 962 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \ 963 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \ 964 gen_helper_1i(raise_exception, cpu_env, EXCP_SC); \ 965 gen_set_label(l2); \ 966 tcg_gen_movi_tl(t0, 0); \ 967 gen_store_gpr(t0, rt); \ 968 tcg_temp_free(t0); \ 969 } 970 #else 971 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \ 972 static inline void op_ldst_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \ 973 { \ 974 TCGv t0 = tcg_temp_new(); \ 975 gen_helper_4i(insn, t0, cpu_env, arg1, arg2, ctx->mem_idx); \ 976 gen_store_gpr(t0, rt); \ 977 tcg_temp_free(t0); \ 978 } 979 #endif 980 OP_ST_ATOMIC(sc,st32,ld32s,0x3); 981 #if defined(TARGET_MIPS64) 982 OP_ST_ATOMIC(scd,st64,ld64,0x7); 983 #endif 984 #undef OP_ST_ATOMIC 985 986 /* Load and store */ 987 static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt, 988 int base, int16_t offset) 989 { 990 const char * __attribute__((unused)) opn = "ldst"; 991 TCGv t0 = tcg_temp_new(); 992 TCGv t1 = tcg_temp_new(); 993 994 if (base == 0) { 995 tcg_gen_movi_tl(t0, offset); 996 } else if (offset == 0) { 997 gen_load_gpr(t0, base); 998 } else { 999 tcg_gen_movi_tl(t0, offset); 1000 gen_op_addr_add(ctx, t0, cpu_gpr[base], t0); 1001 } 1002 /* Don't do NOP if destination is zero: we must perform the actual 1003 memory access. */ 1004 switch (opc) { 1005 #if defined(TARGET_MIPS64) 1006 case OPC_LWU: 1007 save_cpu_state(ctx, 0); 1008 op_ldst_lwu(t0, t0, ctx); 1009 gen_store_gpr(t0, rt); 1010 opn = "lwu"; 1011 break; 1012 case OPC_LD: 1013 save_cpu_state(ctx, 0); 1014 op_ldst_ld(t0, t0, ctx); 1015 gen_store_gpr(t0, rt); 1016 opn = "ld"; 1017 break; 1018 case OPC_LLD: 1019 save_cpu_state(ctx, 0); 1020 op_ldst_lld(t0, t0, ctx); 1021 gen_store_gpr(t0, rt); 1022 opn = "lld"; 1023 break; 1024 case OPC_SD: 1025 save_cpu_state(ctx, 0); 1026 gen_load_gpr(t1, rt); 1027 op_ldst_sd(t1, t0, ctx); 1028 opn = "sd"; 1029 break; 1030 case OPC_LDL: 1031 save_cpu_state(ctx, 1); 1032 gen_load_gpr(t1, rt); 1033 gen_helper_4i(ldl, t1, cpu_env, t1, t0, ctx->mem_idx); 1034 gen_store_gpr(t1, rt); 1035 opn = "ldl"; 1036 break; 1037 case OPC_SDL: 1038 save_cpu_state(ctx, 1); 1039 gen_load_gpr(t1, rt); 1040 gen_helper_3i(sdl, cpu_env, t1, t0, ctx->mem_idx); 1041 opn = "sdl"; 1042 break; 1043 case OPC_LDR: 1044 save_cpu_state(ctx, 1); 1045 gen_load_gpr(t1, rt); 1046 gen_helper_4i(ldr, t1, cpu_env, t1, t0, ctx->mem_idx); 1047 gen_store_gpr(t1, rt); 1048 opn = "ldr"; 1049 break; 1050 case OPC_SDR: 1051 save_cpu_state(ctx, 1); 1052 gen_load_gpr(t1, rt); 1053 gen_helper_3i(sdr, cpu_env, t1, t0, ctx->mem_idx); 1054 opn = "sdr"; 1055 break; 1056 #endif 1057 case OPC_LW: 1058 save_cpu_state(ctx, 0); 1059 op_ldst_lw(t0, t0, ctx); 1060 gen_store_gpr(t0, rt); 1061 opn = "lw"; 1062 break; 1063 case OPC_SW: 1064 save_cpu_state(ctx, 0); 1065 gen_load_gpr(t1, rt); 1066 op_ldst_sw(t1, t0, ctx); 1067 opn = "sw"; 1068 break; 1069 case OPC_LH: 1070 save_cpu_state(ctx, 0); 1071 op_ldst_lh(t0, t0, ctx); 1072 gen_store_gpr(t0, rt); 1073 opn = "lh"; 1074 break; 1075 case OPC_SH: 1076 save_cpu_state(ctx, 0); 1077 gen_load_gpr(t1, rt); 1078 op_ldst_sh(t1, t0, ctx); 1079 opn = "sh"; 1080 break; 1081 case OPC_LHU: 1082 save_cpu_state(ctx, 0); 1083 op_ldst_lhu(t0, t0, ctx); 1084 gen_store_gpr(t0, rt); 1085 opn = "lhu"; 1086 break; 1087 case OPC_LB: 1088 save_cpu_state(ctx, 0); 1089 op_ldst_lb(t0, t0, ctx); 1090 gen_store_gpr(t0, rt); 1091 opn = "lb"; 1092 break; 1093 case OPC_SB: 1094 save_cpu_state(ctx, 0); 1095 gen_load_gpr(t1, rt); 1096 op_ldst_sb(t1, t0, ctx); 1097 opn = "sb"; 1098 break; 1099 case OPC_LBU: 1100 save_cpu_state(ctx, 0); 1101 op_ldst_lbu(t0, t0, ctx); 1102 gen_store_gpr(t0, rt); 1103 opn = "lbu"; 1104 break; 1105 case OPC_LWL: 1106 save_cpu_state(ctx, 1); 1107 gen_load_gpr(t1, rt); 1108 gen_helper_4i(lwl, t1, cpu_env, t1, t0, ctx->mem_idx); 1109 gen_store_gpr(t1, rt); 1110 opn = "lwl"; 1111 break; 1112 case OPC_SWL: 1113 save_cpu_state(ctx, 1); 1114 gen_load_gpr(t1, rt); 1115 gen_helper_3i(swl, cpu_env, t1, t0, ctx->mem_idx); 1116 opn = "swl"; 1117 break; 1118 case OPC_LWR: 1119 save_cpu_state(ctx, 1); 1120 gen_load_gpr(t1, rt); 1121 gen_helper_4i(lwr, t1, cpu_env, t1, t0, ctx->mem_idx); 1122 gen_store_gpr(t1, rt); 1123 opn = "lwr"; 1124 break; 1125 case OPC_SWR: 1126 save_cpu_state(ctx, 1); 1127 gen_load_gpr(t1, rt); 1128 gen_helper_3i(swr, cpu_env, t1, t0, ctx->mem_idx); 1129 opn = "swr"; 1130 break; 1131 case OPC_LL: 1132 save_cpu_state(ctx, 1); 1133 op_ldst_ll(t0, t0, ctx); 1134 gen_store_gpr(t0, rt); 1135 opn = "ll"; 1136 break; 1137 } 1138 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]); 1139 tcg_temp_free(t0); 1140 tcg_temp_free(t1); 1141 } 1142 1143 /* Store conditional */ 1144 static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt, 1145 int base, int16_t offset) 1146 { 1147 const char * __attribute__((unused)) opn = "st_cond"; 1148 TCGv t0, t1; 1149 1150 t0 = tcg_temp_local_new(); 1151 1152 if (base == 0) { 1153 tcg_gen_movi_tl(t0, offset); 1154 } else if (offset == 0) { 1155 gen_load_gpr(t0, base); 1156 } else { 1157 tcg_gen_movi_tl(t0, offset); 1158 gen_op_addr_add(ctx, t0, cpu_gpr[base], t0); 1159 } 1160 /* Don't do NOP if destination is zero: we must perform the actual 1161 memory access. */ 1162 1163 t1 = tcg_temp_local_new(); 1164 gen_load_gpr(t1, rt); 1165 switch (opc) { 1166 #if defined(TARGET_MIPS64) 1167 case OPC_SCD: 1168 save_cpu_state(ctx, 0); 1169 op_ldst_scd(t1, t0, rt, ctx); 1170 opn = "scd"; 1171 break; 1172 #endif 1173 case OPC_SC: 1174 save_cpu_state(ctx, 1); 1175 op_ldst_sc(t1, t0, rt, ctx); 1176 opn = "sc"; 1177 break; 1178 } 1179 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]); 1180 tcg_temp_free(t1); 1181 tcg_temp_free(t0); 1182 } 1183 1184 /* Load and store */ 1185 static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft, 1186 int base, int16_t offset) 1187 { 1188 const char * __attribute__((unused)) opn = "flt_ldst"; 1189 TCGv t0 = tcg_temp_new(); 1190 1191 if (base == 0) { 1192 tcg_gen_movi_tl(t0, offset); 1193 } else if (offset == 0) { 1194 gen_load_gpr(t0, base); 1195 } else { 1196 tcg_gen_movi_tl(t0, offset); 1197 gen_op_addr_add(ctx, t0, cpu_gpr[base], t0); 1198 } 1199 /* Don't do NOP if destination is zero: we must perform the actual 1200 memory access. */ 1201 switch (opc) { 1202 case OPC_LWC1: 1203 { 1204 TCGv_i32 fp0 = tcg_temp_new_i32(); 1205 1206 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx); 1207 tcg_gen_trunc_tl_i32(fp0, t0); 1208 gen_store_fpr32(fp0, ft); 1209 tcg_temp_free_i32(fp0); 1210 } 1211 opn = "lwc1"; 1212 break; 1213 case OPC_SWC1: 1214 { 1215 TCGv_i32 fp0 = tcg_temp_new_i32(); 1216 TCGv t1 = tcg_temp_new(); 1217 1218 gen_load_fpr32(fp0, ft); 1219 tcg_gen_extu_i32_tl(t1, fp0); 1220 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx); 1221 tcg_temp_free(t1); 1222 tcg_temp_free_i32(fp0); 1223 } 1224 opn = "swc1"; 1225 break; 1226 case OPC_LDC1: 1227 { 1228 TCGv_i64 fp0 = tcg_temp_new_i64(); 1229 1230 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx); 1231 gen_store_fpr64(ctx, fp0, ft); 1232 tcg_temp_free_i64(fp0); 1233 } 1234 opn = "ldc1"; 1235 break; 1236 case OPC_SDC1: 1237 { 1238 TCGv_i64 fp0 = tcg_temp_new_i64(); 1239 1240 gen_load_fpr64(ctx, fp0, ft); 1241 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx); 1242 tcg_temp_free_i64(fp0); 1243 } 1244 opn = "sdc1"; 1245 break; 1246 default: 1247 MIPS_INVAL(opn); 1248 generate_exception(ctx, EXCP_RI); 1249 goto out; 1250 } 1251 MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]); 1252 out: 1253 tcg_temp_free(t0); 1254 } 1255 1256 /* Arithmetic with immediate operand */ 1257 static void gen_arith_imm (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, 1258 int rt, int rs, int16_t imm) 1259 { 1260 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */ 1261 const char * __attribute__((unused)) opn = "imm arith"; 1262 1263 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) { 1264 /* If no destination, treat it as a NOP. 1265 For addi, we must generate the overflow exception when needed. */ 1266 MIPS_DEBUG("NOP"); 1267 return; 1268 } 1269 switch (opc) { 1270 case OPC_ADDI: 1271 { 1272 TCGv t0 = tcg_temp_local_new(); 1273 TCGv t1 = tcg_temp_new(); 1274 TCGv t2 = tcg_temp_new(); 1275 int l1 = gen_new_label(); 1276 1277 gen_load_gpr(t1, rs); 1278 tcg_gen_addi_tl(t0, t1, uimm); 1279 tcg_gen_ext32s_tl(t0, t0); 1280 1281 tcg_gen_xori_tl(t1, t1, ~uimm); 1282 tcg_gen_xori_tl(t2, t0, uimm); 1283 tcg_gen_and_tl(t1, t1, t2); 1284 tcg_temp_free(t2); 1285 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 1286 tcg_temp_free(t1); 1287 /* operands of same sign, result different sign */ 1288 generate_exception(ctx, EXCP_OVERFLOW); 1289 gen_set_label(l1); 1290 tcg_gen_ext32s_tl(t0, t0); 1291 gen_store_gpr(t0, rt); 1292 tcg_temp_free(t0); 1293 } 1294 opn = "addi"; 1295 break; 1296 case OPC_ADDIU: 1297 if (rs != 0) { 1298 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 1299 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 1300 } else { 1301 tcg_gen_movi_tl(cpu_gpr[rt], uimm); 1302 } 1303 opn = "addiu"; 1304 break; 1305 #if defined(TARGET_MIPS64) 1306 case OPC_DADDI: 1307 { 1308 TCGv t0 = tcg_temp_local_new(); 1309 TCGv t1 = tcg_temp_new(); 1310 TCGv t2 = tcg_temp_new(); 1311 int l1 = gen_new_label(); 1312 1313 gen_load_gpr(t1, rs); 1314 tcg_gen_addi_tl(t0, t1, uimm); 1315 1316 tcg_gen_xori_tl(t1, t1, ~uimm); 1317 tcg_gen_xori_tl(t2, t0, uimm); 1318 tcg_gen_and_tl(t1, t1, t2); 1319 tcg_temp_free(t2); 1320 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 1321 tcg_temp_free(t1); 1322 /* operands of same sign, result different sign */ 1323 generate_exception(ctx, EXCP_OVERFLOW); 1324 gen_set_label(l1); 1325 gen_store_gpr(t0, rt); 1326 tcg_temp_free(t0); 1327 } 1328 opn = "daddi"; 1329 break; 1330 case OPC_DADDIU: 1331 if (rs != 0) { 1332 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 1333 } else { 1334 tcg_gen_movi_tl(cpu_gpr[rt], uimm); 1335 } 1336 opn = "daddiu"; 1337 break; 1338 #endif 1339 } 1340 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm); 1341 } 1342 1343 /* Logic with immediate operand */ 1344 static void gen_logic_imm (CPUMIPSState *env, uint32_t opc, int rt, int rs, int16_t imm) 1345 { 1346 target_ulong uimm; 1347 const char * __attribute__((unused)) opn = "imm logic"; 1348 1349 if (rt == 0) { 1350 /* If no destination, treat it as a NOP. */ 1351 MIPS_DEBUG("NOP"); 1352 return; 1353 } 1354 uimm = (uint16_t)imm; 1355 switch (opc) { 1356 case OPC_ANDI: 1357 if (likely(rs != 0)) 1358 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 1359 else 1360 tcg_gen_movi_tl(cpu_gpr[rt], 0); 1361 opn = "andi"; 1362 break; 1363 case OPC_ORI: 1364 if (rs != 0) 1365 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 1366 else 1367 tcg_gen_movi_tl(cpu_gpr[rt], uimm); 1368 opn = "ori"; 1369 break; 1370 case OPC_XORI: 1371 if (likely(rs != 0)) 1372 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 1373 else 1374 tcg_gen_movi_tl(cpu_gpr[rt], uimm); 1375 opn = "xori"; 1376 break; 1377 case OPC_LUI: 1378 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16); 1379 opn = "lui"; 1380 break; 1381 } 1382 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm); 1383 } 1384 1385 /* Set on less than with immediate operand */ 1386 static void gen_slt_imm (CPUMIPSState *env, uint32_t opc, int rt, int rs, int16_t imm) 1387 { 1388 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */ 1389 const char * __attribute__((unused)) opn = "imm arith"; 1390 TCGv t0; 1391 1392 if (rt == 0) { 1393 /* If no destination, treat it as a NOP. */ 1394 MIPS_DEBUG("NOP"); 1395 return; 1396 } 1397 t0 = tcg_temp_new(); 1398 gen_load_gpr(t0, rs); 1399 switch (opc) { 1400 case OPC_SLTI: 1401 gen_op_lti(cpu_gpr[rt], t0, uimm); 1402 opn = "slti"; 1403 break; 1404 case OPC_SLTIU: 1405 gen_op_ltiu(cpu_gpr[rt], t0, uimm); 1406 opn = "sltiu"; 1407 break; 1408 } 1409 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm); 1410 tcg_temp_free(t0); 1411 } 1412 1413 /* Shifts with immediate operand */ 1414 static void gen_shift_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc, 1415 int rt, int rs, int16_t imm) 1416 { 1417 target_ulong uimm = ((uint16_t)imm) & 0x1f; 1418 const char* __attribute__((unused)) opn = "imm shift"; 1419 TCGv t0; 1420 1421 if (rt == 0) { 1422 /* If no destination, treat it as a NOP. */ 1423 MIPS_DEBUG("NOP"); 1424 return; 1425 } 1426 1427 t0 = tcg_temp_new(); 1428 gen_load_gpr(t0, rs); 1429 switch (opc) { 1430 case OPC_SLL: 1431 tcg_gen_shli_tl(t0, t0, uimm); 1432 tcg_gen_ext32s_tl(cpu_gpr[rt], t0); 1433 opn = "sll"; 1434 break; 1435 case OPC_SRA: 1436 tcg_gen_ext32s_tl(t0, t0); 1437 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm); 1438 opn = "sra"; 1439 break; 1440 case OPC_SRL: 1441 switch ((ctx->opcode >> 21) & 0x1f) { 1442 case 0: 1443 if (uimm != 0) { 1444 tcg_gen_ext32u_tl(t0, t0); 1445 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm); 1446 } else { 1447 tcg_gen_ext32s_tl(cpu_gpr[rt], t0); 1448 } 1449 opn = "srl"; 1450 break; 1451 case 1: 1452 /* rotr is decoded as srl on non-R2 CPUs */ 1453 if (env->insn_flags & ISA_MIPS32R2) { 1454 if (uimm != 0) { 1455 TCGv_i32 t1 = tcg_temp_new_i32(); 1456 1457 tcg_gen_trunc_tl_i32(t1, t0); 1458 tcg_gen_rotri_i32(t1, t1, uimm); 1459 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1); 1460 tcg_temp_free_i32(t1); 1461 } else { 1462 tcg_gen_ext32s_tl(cpu_gpr[rt], t0); 1463 } 1464 opn = "rotr"; 1465 } else { 1466 if (uimm != 0) { 1467 tcg_gen_ext32u_tl(t0, t0); 1468 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm); 1469 } else { 1470 tcg_gen_ext32s_tl(cpu_gpr[rt], t0); 1471 } 1472 opn = "srl"; 1473 } 1474 break; 1475 default: 1476 MIPS_INVAL("invalid srl flag"); 1477 generate_exception(ctx, EXCP_RI); 1478 break; 1479 } 1480 break; 1481 #if defined(TARGET_MIPS64) 1482 case OPC_DSLL: 1483 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm); 1484 opn = "dsll"; 1485 break; 1486 case OPC_DSRA: 1487 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm); 1488 opn = "dsra"; 1489 break; 1490 case OPC_DSRL: 1491 switch ((ctx->opcode >> 21) & 0x1f) { 1492 case 0: 1493 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm); 1494 opn = "dsrl"; 1495 break; 1496 case 1: 1497 /* drotr is decoded as dsrl on non-R2 CPUs */ 1498 if (env->insn_flags & ISA_MIPS32R2) { 1499 if (uimm != 0) { 1500 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm); 1501 } else { 1502 tcg_gen_mov_tl(cpu_gpr[rt], t0); 1503 } 1504 opn = "drotr"; 1505 } else { 1506 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm); 1507 opn = "dsrl"; 1508 } 1509 break; 1510 default: 1511 MIPS_INVAL("invalid dsrl flag"); 1512 generate_exception(ctx, EXCP_RI); 1513 break; 1514 } 1515 break; 1516 case OPC_DSLL32: 1517 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32); 1518 opn = "dsll32"; 1519 break; 1520 case OPC_DSRA32: 1521 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32); 1522 opn = "dsra32"; 1523 break; 1524 case OPC_DSRL32: 1525 switch ((ctx->opcode >> 21) & 0x1f) { 1526 case 0: 1527 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32); 1528 opn = "dsrl32"; 1529 break; 1530 case 1: 1531 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */ 1532 if (env->insn_flags & ISA_MIPS32R2) { 1533 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32); 1534 opn = "drotr32"; 1535 } else { 1536 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32); 1537 opn = "dsrl32"; 1538 } 1539 break; 1540 default: 1541 MIPS_INVAL("invalid dsrl32 flag"); 1542 generate_exception(ctx, EXCP_RI); 1543 break; 1544 } 1545 break; 1546 #endif 1547 } 1548 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm); 1549 tcg_temp_free(t0); 1550 } 1551 1552 /* Arithmetic */ 1553 static void gen_arith (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, 1554 int rd, int rs, int rt) 1555 { 1556 const char* __attribute__((unused)) opn = "arith"; 1557 1558 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB 1559 && opc != OPC_DADD && opc != OPC_DSUB) { 1560 /* If no destination, treat it as a NOP. 1561 For add & sub, we must generate the overflow exception when needed. */ 1562 MIPS_DEBUG("NOP"); 1563 return; 1564 } 1565 1566 switch (opc) { 1567 case OPC_ADD: 1568 { 1569 TCGv t0 = tcg_temp_local_new(); 1570 TCGv t1 = tcg_temp_new(); 1571 TCGv t2 = tcg_temp_new(); 1572 int l1 = gen_new_label(); 1573 1574 gen_load_gpr(t1, rs); 1575 gen_load_gpr(t2, rt); 1576 tcg_gen_add_tl(t0, t1, t2); 1577 tcg_gen_ext32s_tl(t0, t0); 1578 tcg_gen_xor_tl(t1, t1, t2); 1579 tcg_gen_not_tl(t1, t1); 1580 tcg_gen_xor_tl(t2, t0, t2); 1581 tcg_gen_and_tl(t1, t1, t2); 1582 tcg_temp_free(t2); 1583 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 1584 tcg_temp_free(t1); 1585 /* operands of same sign, result different sign */ 1586 generate_exception(ctx, EXCP_OVERFLOW); 1587 gen_set_label(l1); 1588 gen_store_gpr(t0, rd); 1589 tcg_temp_free(t0); 1590 } 1591 opn = "add"; 1592 break; 1593 case OPC_ADDU: 1594 if (rs != 0 && rt != 0) { 1595 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 1596 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 1597 } else if (rs == 0 && rt != 0) { 1598 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); 1599 } else if (rs != 0 && rt == 0) { 1600 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 1601 } else { 1602 tcg_gen_movi_tl(cpu_gpr[rd], 0); 1603 } 1604 opn = "addu"; 1605 break; 1606 case OPC_SUB: 1607 { 1608 TCGv t0 = tcg_temp_local_new(); 1609 TCGv t1 = tcg_temp_new(); 1610 TCGv t2 = tcg_temp_new(); 1611 int l1 = gen_new_label(); 1612 1613 gen_load_gpr(t1, rs); 1614 gen_load_gpr(t2, rt); 1615 tcg_gen_sub_tl(t0, t1, t2); 1616 tcg_gen_ext32s_tl(t0, t0); 1617 tcg_gen_xor_tl(t2, t1, t2); 1618 tcg_gen_xor_tl(t1, t0, t1); 1619 tcg_gen_and_tl(t1, t1, t2); 1620 tcg_temp_free(t2); 1621 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 1622 tcg_temp_free(t1); 1623 /* operands of different sign, first operand and result different sign */ 1624 generate_exception(ctx, EXCP_OVERFLOW); 1625 gen_set_label(l1); 1626 gen_store_gpr(t0, rd); 1627 tcg_temp_free(t0); 1628 } 1629 opn = "sub"; 1630 break; 1631 case OPC_SUBU: 1632 if (rs != 0 && rt != 0) { 1633 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 1634 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 1635 } else if (rs == 0 && rt != 0) { 1636 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]); 1637 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 1638 } else if (rs != 0 && rt == 0) { 1639 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 1640 } else { 1641 tcg_gen_movi_tl(cpu_gpr[rd], 0); 1642 } 1643 opn = "subu"; 1644 break; 1645 #if defined(TARGET_MIPS64) 1646 case OPC_DADD: 1647 { 1648 TCGv t0 = tcg_temp_local_new(); 1649 TCGv t1 = tcg_temp_new(); 1650 TCGv t2 = tcg_temp_new(); 1651 int l1 = gen_new_label(); 1652 1653 gen_load_gpr(t1, rs); 1654 gen_load_gpr(t2, rt); 1655 tcg_gen_add_tl(t0, t1, t2); 1656 tcg_gen_xor_tl(t1, t1, t2); 1657 tcg_gen_not_tl(t1, t1); 1658 tcg_gen_xor_tl(t2, t0, t2); 1659 tcg_gen_and_tl(t1, t1, t2); 1660 tcg_temp_free(t2); 1661 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 1662 tcg_temp_free(t1); 1663 /* operands of same sign, result different sign */ 1664 generate_exception(ctx, EXCP_OVERFLOW); 1665 gen_set_label(l1); 1666 gen_store_gpr(t0, rd); 1667 tcg_temp_free(t0); 1668 } 1669 opn = "dadd"; 1670 break; 1671 case OPC_DADDU: 1672 if (rs != 0 && rt != 0) { 1673 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 1674 } else if (rs == 0 && rt != 0) { 1675 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); 1676 } else if (rs != 0 && rt == 0) { 1677 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 1678 } else { 1679 tcg_gen_movi_tl(cpu_gpr[rd], 0); 1680 } 1681 opn = "daddu"; 1682 break; 1683 case OPC_DSUB: 1684 { 1685 TCGv t0 = tcg_temp_local_new(); 1686 TCGv t1 = tcg_temp_new(); 1687 TCGv t2 = tcg_temp_new(); 1688 int l1 = gen_new_label(); 1689 1690 gen_load_gpr(t1, rs); 1691 gen_load_gpr(t2, rt); 1692 tcg_gen_sub_tl(t0, t1, t2); 1693 tcg_gen_xor_tl(t2, t1, t2); 1694 tcg_gen_xor_tl(t1, t0, t1); 1695 tcg_gen_and_tl(t1, t1, t2); 1696 tcg_temp_free(t2); 1697 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 1698 tcg_temp_free(t1); 1699 /* operands of different sign, first operand and result different sign */ 1700 generate_exception(ctx, EXCP_OVERFLOW); 1701 gen_set_label(l1); 1702 gen_store_gpr(t0, rd); 1703 tcg_temp_free(t0); 1704 } 1705 opn = "dsub"; 1706 break; 1707 case OPC_DSUBU: 1708 if (rs != 0 && rt != 0) { 1709 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 1710 } else if (rs == 0 && rt != 0) { 1711 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]); 1712 } else if (rs != 0 && rt == 0) { 1713 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 1714 } else { 1715 tcg_gen_movi_tl(cpu_gpr[rd], 0); 1716 } 1717 opn = "dsubu"; 1718 break; 1719 #endif 1720 case OPC_MUL: 1721 if (likely(rs != 0 && rt != 0)) { 1722 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 1723 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 1724 } else { 1725 tcg_gen_movi_tl(cpu_gpr[rd], 0); 1726 } 1727 opn = "mul"; 1728 break; 1729 } 1730 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]); 1731 } 1732 1733 /* Conditional move */ 1734 static void gen_cond_move (CPUMIPSState *env, uint32_t opc, int rd, int rs, int rt) 1735 { 1736 const char* __attribute__((unused)) opn = "cond move"; 1737 int l1; 1738 1739 if (rd == 0) { 1740 /* If no destination, treat it as a NOP. 1741 For add & sub, we must generate the overflow exception when needed. */ 1742 MIPS_DEBUG("NOP"); 1743 return; 1744 } 1745 1746 l1 = gen_new_label(); 1747 switch (opc) { 1748 case OPC_MOVN: 1749 if (likely(rt != 0)) 1750 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rt], 0, l1); 1751 else 1752 tcg_gen_br(l1); 1753 opn = "movn"; 1754 break; 1755 case OPC_MOVZ: 1756 if (likely(rt != 0)) 1757 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[rt], 0, l1); 1758 opn = "movz"; 1759 break; 1760 } 1761 if (rs != 0) 1762 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 1763 else 1764 tcg_gen_movi_tl(cpu_gpr[rd], 0); 1765 gen_set_label(l1); 1766 1767 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]); 1768 } 1769 1770 /* Logic */ 1771 static void gen_logic (CPUMIPSState *env, uint32_t opc, int rd, int rs, int rt) 1772 { 1773 const char* __attribute__((unused)) opn = "logic"; 1774 1775 if (rd == 0) { 1776 /* If no destination, treat it as a NOP. */ 1777 MIPS_DEBUG("NOP"); 1778 return; 1779 } 1780 1781 switch (opc) { 1782 case OPC_AND: 1783 if (likely(rs != 0 && rt != 0)) { 1784 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 1785 } else { 1786 tcg_gen_movi_tl(cpu_gpr[rd], 0); 1787 } 1788 opn = "and"; 1789 break; 1790 case OPC_NOR: 1791 if (rs != 0 && rt != 0) { 1792 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 1793 } else if (rs == 0 && rt != 0) { 1794 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]); 1795 } else if (rs != 0 && rt == 0) { 1796 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]); 1797 } else { 1798 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0)); 1799 } 1800 opn = "nor"; 1801 break; 1802 case OPC_OR: 1803 if (likely(rs != 0 && rt != 0)) { 1804 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 1805 } else if (rs == 0 && rt != 0) { 1806 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); 1807 } else if (rs != 0 && rt == 0) { 1808 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 1809 } else { 1810 tcg_gen_movi_tl(cpu_gpr[rd], 0); 1811 } 1812 opn = "or"; 1813 break; 1814 case OPC_XOR: 1815 if (likely(rs != 0 && rt != 0)) { 1816 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 1817 } else if (rs == 0 && rt != 0) { 1818 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); 1819 } else if (rs != 0 && rt == 0) { 1820 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 1821 } else { 1822 tcg_gen_movi_tl(cpu_gpr[rd], 0); 1823 } 1824 opn = "xor"; 1825 break; 1826 } 1827 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]); 1828 } 1829 1830 /* Set on lower than */ 1831 static void gen_slt (CPUMIPSState *env, uint32_t opc, int rd, int rs, int rt) 1832 { 1833 const char* __attribute__((unused)) opn = "slt"; 1834 TCGv t0, t1; 1835 1836 if (rd == 0) { 1837 /* If no destination, treat it as a NOP. */ 1838 MIPS_DEBUG("NOP"); 1839 return; 1840 } 1841 1842 t0 = tcg_temp_new(); 1843 t1 = tcg_temp_new(); 1844 gen_load_gpr(t0, rs); 1845 gen_load_gpr(t1, rt); 1846 switch (opc) { 1847 case OPC_SLT: 1848 gen_op_lt(cpu_gpr[rd], t0, t1); 1849 opn = "slt"; 1850 break; 1851 case OPC_SLTU: 1852 gen_op_ltu(cpu_gpr[rd], t0, t1); 1853 opn = "sltu"; 1854 break; 1855 } 1856 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]); 1857 tcg_temp_free(t0); 1858 tcg_temp_free(t1); 1859 } 1860 1861 /* Shifts */ 1862 static void gen_shift (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, 1863 int rd, int rs, int rt) 1864 { 1865 const char* __attribute__((unused)) opn = "shifts"; 1866 TCGv t0, t1; 1867 1868 if (rd == 0) { 1869 /* If no destination, treat it as a NOP. 1870 For add & sub, we must generate the overflow exception when needed. */ 1871 MIPS_DEBUG("NOP"); 1872 return; 1873 } 1874 1875 t0 = tcg_temp_new(); 1876 t1 = tcg_temp_new(); 1877 gen_load_gpr(t0, rs); 1878 gen_load_gpr(t1, rt); 1879 switch (opc) { 1880 case OPC_SLLV: 1881 tcg_gen_andi_tl(t0, t0, 0x1f); 1882 tcg_gen_shl_tl(t0, t1, t0); 1883 tcg_gen_ext32s_tl(cpu_gpr[rd], t0); 1884 opn = "sllv"; 1885 break; 1886 case OPC_SRAV: 1887 tcg_gen_ext32s_tl(t1, t1); 1888 tcg_gen_andi_tl(t0, t0, 0x1f); 1889 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0); 1890 opn = "srav"; 1891 break; 1892 case OPC_SRLV: 1893 switch ((ctx->opcode >> 6) & 0x1f) { 1894 case 0: 1895 tcg_gen_ext32u_tl(t1, t1); 1896 tcg_gen_andi_tl(t0, t0, 0x1f); 1897 tcg_gen_shr_tl(t0, t1, t0); 1898 tcg_gen_ext32s_tl(cpu_gpr[rd], t0); 1899 opn = "srlv"; 1900 break; 1901 case 1: 1902 /* rotrv is decoded as srlv on non-R2 CPUs */ 1903 if (env->insn_flags & ISA_MIPS32R2) { 1904 TCGv_i32 t2 = tcg_temp_new_i32(); 1905 TCGv_i32 t3 = tcg_temp_new_i32(); 1906 1907 tcg_gen_trunc_tl_i32(t2, t0); 1908 tcg_gen_trunc_tl_i32(t3, t1); 1909 tcg_gen_andi_i32(t2, t2, 0x1f); 1910 tcg_gen_rotr_i32(t2, t3, t2); 1911 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 1912 tcg_temp_free_i32(t2); 1913 tcg_temp_free_i32(t3); 1914 opn = "rotrv"; 1915 } else { 1916 tcg_gen_ext32u_tl(t1, t1); 1917 tcg_gen_andi_tl(t0, t0, 0x1f); 1918 tcg_gen_shr_tl(t0, t1, t0); 1919 tcg_gen_ext32s_tl(cpu_gpr[rd], t0); 1920 opn = "srlv"; 1921 } 1922 break; 1923 default: 1924 MIPS_INVAL("invalid srlv flag"); 1925 generate_exception(ctx, EXCP_RI); 1926 break; 1927 } 1928 break; 1929 #if defined(TARGET_MIPS64) 1930 case OPC_DSLLV: 1931 tcg_gen_andi_tl(t0, t0, 0x3f); 1932 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0); 1933 opn = "dsllv"; 1934 break; 1935 case OPC_DSRAV: 1936 tcg_gen_andi_tl(t0, t0, 0x3f); 1937 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0); 1938 opn = "dsrav"; 1939 break; 1940 case OPC_DSRLV: 1941 switch ((ctx->opcode >> 6) & 0x1f) { 1942 case 0: 1943 tcg_gen_andi_tl(t0, t0, 0x3f); 1944 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0); 1945 opn = "dsrlv"; 1946 break; 1947 case 1: 1948 /* drotrv is decoded as dsrlv on non-R2 CPUs */ 1949 if (env->insn_flags & ISA_MIPS32R2) { 1950 tcg_gen_andi_tl(t0, t0, 0x3f); 1951 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0); 1952 opn = "drotrv"; 1953 } else { 1954 tcg_gen_andi_tl(t0, t0, 0x3f); 1955 tcg_gen_shr_tl(t0, t1, t0); 1956 opn = "dsrlv"; 1957 } 1958 break; 1959 default: 1960 MIPS_INVAL("invalid dsrlv flag"); 1961 generate_exception(ctx, EXCP_RI); 1962 break; 1963 } 1964 break; 1965 #endif 1966 } 1967 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]); 1968 tcg_temp_free(t0); 1969 tcg_temp_free(t1); 1970 } 1971 1972 /* Arithmetic on HI/LO registers */ 1973 static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg) 1974 { 1975 const char* __attribute__((unused)) opn = "hilo"; 1976 1977 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) { 1978 /* Treat as NOP. */ 1979 MIPS_DEBUG("NOP"); 1980 return; 1981 } 1982 switch (opc) { 1983 case OPC_MFHI: 1984 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[0]); 1985 opn = "mfhi"; 1986 break; 1987 case OPC_MFLO: 1988 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[0]); 1989 opn = "mflo"; 1990 break; 1991 case OPC_MTHI: 1992 if (reg != 0) 1993 tcg_gen_mov_tl(cpu_HI[0], cpu_gpr[reg]); 1994 else 1995 tcg_gen_movi_tl(cpu_HI[0], 0); 1996 opn = "mthi"; 1997 break; 1998 case OPC_MTLO: 1999 if (reg != 0) 2000 tcg_gen_mov_tl(cpu_LO[0], cpu_gpr[reg]); 2001 else 2002 tcg_gen_movi_tl(cpu_LO[0], 0); 2003 opn = "mtlo"; 2004 break; 2005 } 2006 MIPS_DEBUG("%s %s", opn, regnames[reg]); 2007 } 2008 2009 static void gen_muldiv (DisasContext *ctx, uint32_t opc, 2010 int rs, int rt) 2011 { 2012 const char* __attribute__((unused)) opn = "mul/div"; 2013 TCGv t0, t1; 2014 2015 switch (opc) { 2016 case OPC_DIV: 2017 case OPC_DIVU: 2018 #if defined(TARGET_MIPS64) 2019 case OPC_DDIV: 2020 case OPC_DDIVU: 2021 #endif 2022 t0 = tcg_temp_local_new(); 2023 t1 = tcg_temp_local_new(); 2024 break; 2025 default: 2026 t0 = tcg_temp_new(); 2027 t1 = tcg_temp_new(); 2028 break; 2029 } 2030 2031 gen_load_gpr(t0, rs); 2032 gen_load_gpr(t1, rt); 2033 switch (opc) { 2034 case OPC_DIV: 2035 { 2036 int l1 = gen_new_label(); 2037 int l2 = gen_new_label(); 2038 2039 tcg_gen_ext32s_tl(t0, t0); 2040 tcg_gen_ext32s_tl(t1, t1); 2041 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1); 2042 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2); 2043 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2); 2044 2045 tcg_gen_mov_tl(cpu_LO[0], t0); 2046 tcg_gen_movi_tl(cpu_HI[0], 0); 2047 tcg_gen_br(l1); 2048 gen_set_label(l2); 2049 tcg_gen_div_tl(cpu_LO[0], t0, t1); 2050 tcg_gen_rem_tl(cpu_HI[0], t0, t1); 2051 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]); 2052 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]); 2053 gen_set_label(l1); 2054 } 2055 opn = "div"; 2056 break; 2057 case OPC_DIVU: 2058 { 2059 int l1 = gen_new_label(); 2060 2061 tcg_gen_ext32u_tl(t0, t0); 2062 tcg_gen_ext32u_tl(t1, t1); 2063 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1); 2064 tcg_gen_divu_tl(cpu_LO[0], t0, t1); 2065 tcg_gen_remu_tl(cpu_HI[0], t0, t1); 2066 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]); 2067 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]); 2068 gen_set_label(l1); 2069 } 2070 opn = "divu"; 2071 break; 2072 case OPC_MULT: 2073 { 2074 TCGv_i64 t2 = tcg_temp_new_i64(); 2075 TCGv_i64 t3 = tcg_temp_new_i64(); 2076 2077 tcg_gen_ext_tl_i64(t2, t0); 2078 tcg_gen_ext_tl_i64(t3, t1); 2079 tcg_gen_mul_i64(t2, t2, t3); 2080 tcg_temp_free_i64(t3); 2081 tcg_gen_trunc_i64_tl(t0, t2); 2082 tcg_gen_shri_i64(t2, t2, 32); 2083 tcg_gen_trunc_i64_tl(t1, t2); 2084 tcg_temp_free_i64(t2); 2085 tcg_gen_ext32s_tl(cpu_LO[0], t0); 2086 tcg_gen_ext32s_tl(cpu_HI[0], t1); 2087 } 2088 opn = "mult"; 2089 break; 2090 case OPC_MULTU: 2091 { 2092 TCGv_i64 t2 = tcg_temp_new_i64(); 2093 TCGv_i64 t3 = tcg_temp_new_i64(); 2094 2095 tcg_gen_ext32u_tl(t0, t0); 2096 tcg_gen_ext32u_tl(t1, t1); 2097 tcg_gen_extu_tl_i64(t2, t0); 2098 tcg_gen_extu_tl_i64(t3, t1); 2099 tcg_gen_mul_i64(t2, t2, t3); 2100 tcg_temp_free_i64(t3); 2101 tcg_gen_trunc_i64_tl(t0, t2); 2102 tcg_gen_shri_i64(t2, t2, 32); 2103 tcg_gen_trunc_i64_tl(t1, t2); 2104 tcg_temp_free_i64(t2); 2105 tcg_gen_ext32s_tl(cpu_LO[0], t0); 2106 tcg_gen_ext32s_tl(cpu_HI[0], t1); 2107 } 2108 opn = "multu"; 2109 break; 2110 #if defined(TARGET_MIPS64) 2111 case OPC_DDIV: 2112 { 2113 int l1 = gen_new_label(); 2114 int l2 = gen_new_label(); 2115 2116 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1); 2117 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2); 2118 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2); 2119 tcg_gen_mov_tl(cpu_LO[0], t0); 2120 tcg_gen_movi_tl(cpu_HI[0], 0); 2121 tcg_gen_br(l1); 2122 gen_set_label(l2); 2123 tcg_gen_div_i64(cpu_LO[0], t0, t1); 2124 tcg_gen_rem_i64(cpu_HI[0], t0, t1); 2125 gen_set_label(l1); 2126 } 2127 opn = "ddiv"; 2128 break; 2129 case OPC_DDIVU: 2130 { 2131 int l1 = gen_new_label(); 2132 2133 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1); 2134 tcg_gen_divu_i64(cpu_LO[0], t0, t1); 2135 tcg_gen_remu_i64(cpu_HI[0], t0, t1); 2136 gen_set_label(l1); 2137 } 2138 opn = "ddivu"; 2139 break; 2140 case OPC_DMULT: 2141 gen_helper_dmult(t0, t1); 2142 opn = "dmult"; 2143 break; 2144 case OPC_DMULTU: 2145 gen_helper_dmultu(t0, t1); 2146 opn = "dmultu"; 2147 break; 2148 #endif 2149 case OPC_MADD: 2150 { 2151 TCGv_i64 t2 = tcg_temp_new_i64(); 2152 TCGv_i64 t3 = tcg_temp_new_i64(); 2153 2154 tcg_gen_ext_tl_i64(t2, t0); 2155 tcg_gen_ext_tl_i64(t3, t1); 2156 tcg_gen_mul_i64(t2, t2, t3); 2157 tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]); 2158 tcg_gen_add_i64(t2, t2, t3); 2159 tcg_temp_free_i64(t3); 2160 tcg_gen_trunc_i64_tl(t0, t2); 2161 tcg_gen_shri_i64(t2, t2, 32); 2162 tcg_gen_trunc_i64_tl(t1, t2); 2163 tcg_temp_free_i64(t2); 2164 tcg_gen_ext32s_tl(cpu_LO[0], t0); 2165 tcg_gen_ext32s_tl(cpu_HI[0], t1); 2166 } 2167 opn = "madd"; 2168 break; 2169 case OPC_MADDU: 2170 { 2171 TCGv_i64 t2 = tcg_temp_new_i64(); 2172 TCGv_i64 t3 = tcg_temp_new_i64(); 2173 2174 tcg_gen_ext32u_tl(t0, t0); 2175 tcg_gen_ext32u_tl(t1, t1); 2176 tcg_gen_extu_tl_i64(t2, t0); 2177 tcg_gen_extu_tl_i64(t3, t1); 2178 tcg_gen_mul_i64(t2, t2, t3); 2179 tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]); 2180 tcg_gen_add_i64(t2, t2, t3); 2181 tcg_temp_free_i64(t3); 2182 tcg_gen_trunc_i64_tl(t0, t2); 2183 tcg_gen_shri_i64(t2, t2, 32); 2184 tcg_gen_trunc_i64_tl(t1, t2); 2185 tcg_temp_free_i64(t2); 2186 tcg_gen_ext32s_tl(cpu_LO[0], t0); 2187 tcg_gen_ext32s_tl(cpu_HI[0], t1); 2188 } 2189 opn = "maddu"; 2190 break; 2191 case OPC_MSUB: 2192 { 2193 TCGv_i64 t2 = tcg_temp_new_i64(); 2194 TCGv_i64 t3 = tcg_temp_new_i64(); 2195 2196 tcg_gen_ext_tl_i64(t2, t0); 2197 tcg_gen_ext_tl_i64(t3, t1); 2198 tcg_gen_mul_i64(t2, t2, t3); 2199 tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]); 2200 tcg_gen_sub_i64(t2, t3, t2); 2201 tcg_temp_free_i64(t3); 2202 tcg_gen_trunc_i64_tl(t0, t2); 2203 tcg_gen_shri_i64(t2, t2, 32); 2204 tcg_gen_trunc_i64_tl(t1, t2); 2205 tcg_temp_free_i64(t2); 2206 tcg_gen_ext32s_tl(cpu_LO[0], t0); 2207 tcg_gen_ext32s_tl(cpu_HI[0], t1); 2208 } 2209 opn = "msub"; 2210 break; 2211 case OPC_MSUBU: 2212 { 2213 TCGv_i64 t2 = tcg_temp_new_i64(); 2214 TCGv_i64 t3 = tcg_temp_new_i64(); 2215 2216 tcg_gen_ext32u_tl(t0, t0); 2217 tcg_gen_ext32u_tl(t1, t1); 2218 tcg_gen_extu_tl_i64(t2, t0); 2219 tcg_gen_extu_tl_i64(t3, t1); 2220 tcg_gen_mul_i64(t2, t2, t3); 2221 tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]); 2222 tcg_gen_sub_i64(t2, t3, t2); 2223 tcg_temp_free_i64(t3); 2224 tcg_gen_trunc_i64_tl(t0, t2); 2225 tcg_gen_shri_i64(t2, t2, 32); 2226 tcg_gen_trunc_i64_tl(t1, t2); 2227 tcg_temp_free_i64(t2); 2228 tcg_gen_ext32s_tl(cpu_LO[0], t0); 2229 tcg_gen_ext32s_tl(cpu_HI[0], t1); 2230 } 2231 opn = "msubu"; 2232 break; 2233 default: 2234 MIPS_INVAL(opn); 2235 generate_exception(ctx, EXCP_RI); 2236 goto out; 2237 } 2238 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]); 2239 out: 2240 tcg_temp_free(t0); 2241 tcg_temp_free(t1); 2242 } 2243 2244 static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc, 2245 int rd, int rs, int rt) 2246 { 2247 const char* __attribute__((unused)) opn = "mul vr54xx"; 2248 TCGv t0 = tcg_temp_new(); 2249 TCGv t1 = tcg_temp_new(); 2250 2251 gen_load_gpr(t0, rs); 2252 gen_load_gpr(t1, rt); 2253 2254 switch (opc) { 2255 case OPC_VR54XX_MULS: 2256 gen_helper_muls(t0, cpu_env, t0, t1); 2257 opn = "muls"; 2258 break; 2259 case OPC_VR54XX_MULSU: 2260 gen_helper_mulsu(t0, cpu_env, t0, t1); 2261 opn = "mulsu"; 2262 break; 2263 case OPC_VR54XX_MACC: 2264 gen_helper_macc(t0, cpu_env, t0, t1); 2265 opn = "macc"; 2266 break; 2267 case OPC_VR54XX_MACCU: 2268 gen_helper_maccu(t0, cpu_env, t0, t1); 2269 opn = "maccu"; 2270 break; 2271 case OPC_VR54XX_MSAC: 2272 gen_helper_msac(t0, cpu_env, t0, t1); 2273 opn = "msac"; 2274 break; 2275 case OPC_VR54XX_MSACU: 2276 gen_helper_msacu(t0, cpu_env, t0, t1); 2277 opn = "msacu"; 2278 break; 2279 case OPC_VR54XX_MULHI: 2280 gen_helper_mulhi(t0, cpu_env, t0, t1); 2281 opn = "mulhi"; 2282 break; 2283 case OPC_VR54XX_MULHIU: 2284 gen_helper_mulhiu(t0, cpu_env, t0, t1); 2285 opn = "mulhiu"; 2286 break; 2287 case OPC_VR54XX_MULSHI: 2288 gen_helper_mulshi(t0, cpu_env, t0, t1); 2289 opn = "mulshi"; 2290 break; 2291 case OPC_VR54XX_MULSHIU: 2292 gen_helper_mulshiu(t0, cpu_env, t0, t1); 2293 opn = "mulshiu"; 2294 break; 2295 case OPC_VR54XX_MACCHI: 2296 gen_helper_macchi(t0, cpu_env, t0, t1); 2297 opn = "macchi"; 2298 break; 2299 case OPC_VR54XX_MACCHIU: 2300 gen_helper_macchiu(t0, cpu_env, t0, t1); 2301 opn = "macchiu"; 2302 break; 2303 case OPC_VR54XX_MSACHI: 2304 gen_helper_msachi(t0, cpu_env, t0, t1); 2305 opn = "msachi"; 2306 break; 2307 case OPC_VR54XX_MSACHIU: 2308 gen_helper_msachiu(t0, cpu_env, t0, t1); 2309 opn = "msachiu"; 2310 break; 2311 default: 2312 MIPS_INVAL("mul vr54xx"); 2313 generate_exception(ctx, EXCP_RI); 2314 goto out; 2315 } 2316 gen_store_gpr(t0, rd); 2317 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]); 2318 2319 out: 2320 tcg_temp_free(t0); 2321 tcg_temp_free(t1); 2322 } 2323 2324 static void gen_cl (DisasContext *ctx, uint32_t opc, 2325 int rd, int rs) 2326 { 2327 const char* __attribute__((unused)) opn = "CLx"; 2328 TCGv t0; 2329 2330 if (rd == 0) { 2331 /* Treat as NOP. */ 2332 MIPS_DEBUG("NOP"); 2333 return; 2334 } 2335 t0 = tcg_temp_new(); 2336 gen_load_gpr(t0, rs); 2337 switch (opc) { 2338 case OPC_CLO: 2339 gen_helper_clo(cpu_gpr[rd], t0); 2340 opn = "clo"; 2341 break; 2342 case OPC_CLZ: 2343 gen_helper_clz(cpu_gpr[rd], t0); 2344 opn = "clz"; 2345 break; 2346 #if defined(TARGET_MIPS64) 2347 case OPC_DCLO: 2348 gen_helper_dclo(cpu_gpr[rd], t0); 2349 opn = "dclo"; 2350 break; 2351 case OPC_DCLZ: 2352 gen_helper_dclz(cpu_gpr[rd], t0); 2353 opn = "dclz"; 2354 break; 2355 #endif 2356 } 2357 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]); 2358 tcg_temp_free(t0); 2359 } 2360 2361 /* Traps */ 2362 static void gen_trap (DisasContext *ctx, uint32_t opc, 2363 int rs, int rt, int16_t imm) 2364 { 2365 int cond; 2366 TCGv t0 = tcg_temp_new(); 2367 TCGv t1 = tcg_temp_new(); 2368 2369 cond = 0; 2370 /* Load needed operands */ 2371 switch (opc) { 2372 case OPC_TEQ: 2373 case OPC_TGE: 2374 case OPC_TGEU: 2375 case OPC_TLT: 2376 case OPC_TLTU: 2377 case OPC_TNE: 2378 /* Compare two registers */ 2379 if (rs != rt) { 2380 gen_load_gpr(t0, rs); 2381 gen_load_gpr(t1, rt); 2382 cond = 1; 2383 } 2384 break; 2385 case OPC_TEQI: 2386 case OPC_TGEI: 2387 case OPC_TGEIU: 2388 case OPC_TLTI: 2389 case OPC_TLTIU: 2390 case OPC_TNEI: 2391 /* Compare register to immediate */ 2392 if (rs != 0 || imm != 0) { 2393 gen_load_gpr(t0, rs); 2394 tcg_gen_movi_tl(t1, (int32_t)imm); 2395 cond = 1; 2396 } 2397 break; 2398 } 2399 if (cond == 0) { 2400 switch (opc) { 2401 case OPC_TEQ: /* rs == rs */ 2402 case OPC_TEQI: /* r0 == 0 */ 2403 case OPC_TGE: /* rs >= rs */ 2404 case OPC_TGEI: /* r0 >= 0 */ 2405 case OPC_TGEU: /* rs >= rs unsigned */ 2406 case OPC_TGEIU: /* r0 >= 0 unsigned */ 2407 /* Always trap */ 2408 generate_exception(ctx, EXCP_TRAP); 2409 break; 2410 case OPC_TLT: /* rs < rs */ 2411 case OPC_TLTI: /* r0 < 0 */ 2412 case OPC_TLTU: /* rs < rs unsigned */ 2413 case OPC_TLTIU: /* r0 < 0 unsigned */ 2414 case OPC_TNE: /* rs != rs */ 2415 case OPC_TNEI: /* r0 != 0 */ 2416 /* Never trap: treat as NOP. */ 2417 break; 2418 } 2419 } else { 2420 int l1 = gen_new_label(); 2421 2422 switch (opc) { 2423 case OPC_TEQ: 2424 case OPC_TEQI: 2425 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1); 2426 break; 2427 case OPC_TGE: 2428 case OPC_TGEI: 2429 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1); 2430 break; 2431 case OPC_TGEU: 2432 case OPC_TGEIU: 2433 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1); 2434 break; 2435 case OPC_TLT: 2436 case OPC_TLTI: 2437 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1); 2438 break; 2439 case OPC_TLTU: 2440 case OPC_TLTIU: 2441 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1); 2442 break; 2443 case OPC_TNE: 2444 case OPC_TNEI: 2445 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1); 2446 break; 2447 } 2448 generate_exception(ctx, EXCP_TRAP); 2449 gen_set_label(l1); 2450 } 2451 tcg_temp_free(t0); 2452 tcg_temp_free(t1); 2453 } 2454 2455 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest) 2456 { 2457 TranslationBlock *tb; 2458 tb = ctx->tb; 2459 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) && 2460 likely(!ctx->singlestep_enabled)) { 2461 tcg_gen_goto_tb(n); 2462 gen_save_pc(dest); 2463 tcg_gen_exit_tb((long)tb + n); 2464 } else { 2465 gen_save_pc(dest); 2466 if (ctx->singlestep_enabled) { 2467 save_cpu_state(ctx, 0); 2468 gen_helper_1i(raise_exception, cpu_env, EXCP_DEBUG); 2469 } 2470 tcg_gen_exit_tb(0); 2471 } 2472 } 2473 2474 /* Branches (before delay slot) */ 2475 static void gen_compute_branch (DisasContext *ctx, uint32_t opc, 2476 int rs, int rt, int32_t offset) 2477 { 2478 target_ulong btgt = -1; 2479 int blink = 0; 2480 int bcond_compute = 0; 2481 TCGv t0 = tcg_temp_new(); 2482 TCGv t1 = tcg_temp_new(); 2483 2484 if (ctx->hflags & MIPS_HFLAG_BMASK) { 2485 #ifdef MIPS_DEBUG_DISAS 2486 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc); 2487 #endif 2488 generate_exception(ctx, EXCP_RI); 2489 goto out; 2490 } 2491 2492 /* Load needed operands */ 2493 switch (opc) { 2494 case OPC_BEQ: 2495 case OPC_BEQL: 2496 case OPC_BNE: 2497 case OPC_BNEL: 2498 /* Compare two registers */ 2499 if (rs != rt) { 2500 gen_load_gpr(t0, rs); 2501 gen_load_gpr(t1, rt); 2502 bcond_compute = 1; 2503 } 2504 btgt = ctx->pc + 4 + offset; 2505 break; 2506 case OPC_BGEZ: 2507 case OPC_BGEZAL: 2508 case OPC_BGEZALL: 2509 case OPC_BGEZL: 2510 case OPC_BGTZ: 2511 case OPC_BGTZL: 2512 case OPC_BLEZ: 2513 case OPC_BLEZL: 2514 case OPC_BLTZ: 2515 case OPC_BLTZAL: 2516 case OPC_BLTZALL: 2517 case OPC_BLTZL: 2518 /* Compare to zero */ 2519 if (rs != 0) { 2520 gen_load_gpr(t0, rs); 2521 bcond_compute = 1; 2522 } 2523 btgt = ctx->pc + 4 + offset; 2524 break; 2525 case OPC_J: 2526 case OPC_JAL: 2527 /* Jump to immediate */ 2528 btgt = ((ctx->pc + 4) & (int32_t)0xF0000000) | (uint32_t)offset; 2529 break; 2530 case OPC_JR: 2531 case OPC_JALR: 2532 /* Jump to register */ 2533 if (offset != 0 && offset != 16) { 2534 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the 2535 others are reserved. */ 2536 MIPS_INVAL("jump hint"); 2537 generate_exception(ctx, EXCP_RI); 2538 goto out; 2539 } 2540 gen_load_gpr(btarget, rs); 2541 break; 2542 default: 2543 MIPS_INVAL("branch/jump"); 2544 generate_exception(ctx, EXCP_RI); 2545 goto out; 2546 } 2547 if (bcond_compute == 0) { 2548 /* No condition to be computed */ 2549 switch (opc) { 2550 case OPC_BEQ: /* rx == rx */ 2551 case OPC_BEQL: /* rx == rx likely */ 2552 case OPC_BGEZ: /* 0 >= 0 */ 2553 case OPC_BGEZL: /* 0 >= 0 likely */ 2554 case OPC_BLEZ: /* 0 <= 0 */ 2555 case OPC_BLEZL: /* 0 <= 0 likely */ 2556 /* Always take */ 2557 ctx->hflags |= MIPS_HFLAG_B; 2558 MIPS_DEBUG("balways"); 2559 break; 2560 case OPC_BGEZAL: /* 0 >= 0 */ 2561 case OPC_BGEZALL: /* 0 >= 0 likely */ 2562 /* Always take and link */ 2563 blink = 31; 2564 ctx->hflags |= MIPS_HFLAG_B; 2565 MIPS_DEBUG("balways and link"); 2566 break; 2567 case OPC_BNE: /* rx != rx */ 2568 case OPC_BGTZ: /* 0 > 0 */ 2569 case OPC_BLTZ: /* 0 < 0 */ 2570 /* Treat as NOP. */ 2571 MIPS_DEBUG("bnever (NOP)"); 2572 goto out; 2573 case OPC_BLTZAL: /* 0 < 0 */ 2574 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8); 2575 MIPS_DEBUG("bnever and link"); 2576 goto out; 2577 case OPC_BLTZALL: /* 0 < 0 likely */ 2578 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8); 2579 /* Skip the instruction in the delay slot */ 2580 MIPS_DEBUG("bnever, link and skip"); 2581 ctx->pc += 4; 2582 goto out; 2583 case OPC_BNEL: /* rx != rx likely */ 2584 case OPC_BGTZL: /* 0 > 0 likely */ 2585 case OPC_BLTZL: /* 0 < 0 likely */ 2586 /* Skip the instruction in the delay slot */ 2587 MIPS_DEBUG("bnever and skip"); 2588 ctx->pc += 4; 2589 goto out; 2590 case OPC_J: 2591 ctx->hflags |= MIPS_HFLAG_B; 2592 MIPS_DEBUG("j " TARGET_FMT_lx, btgt); 2593 break; 2594 case OPC_JAL: 2595 blink = 31; 2596 ctx->hflags |= MIPS_HFLAG_B; 2597 MIPS_DEBUG("jal " TARGET_FMT_lx, btgt); 2598 break; 2599 case OPC_JR: 2600 ctx->hflags |= MIPS_HFLAG_BR; 2601 MIPS_DEBUG("jr %s", regnames[rs]); 2602 break; 2603 case OPC_JALR: 2604 blink = rt; 2605 ctx->hflags |= MIPS_HFLAG_BR; 2606 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]); 2607 break; 2608 default: 2609 MIPS_INVAL("branch/jump"); 2610 generate_exception(ctx, EXCP_RI); 2611 goto out; 2612 } 2613 } else { 2614 switch (opc) { 2615 case OPC_BEQ: 2616 gen_op_eq(bcond, t0, t1); 2617 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx, 2618 regnames[rs], regnames[rt], btgt); 2619 goto not_likely; 2620 case OPC_BEQL: 2621 gen_op_eq(bcond, t0, t1); 2622 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx, 2623 regnames[rs], regnames[rt], btgt); 2624 goto likely; 2625 case OPC_BNE: 2626 gen_op_ne(bcond, t0, t1); 2627 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx, 2628 regnames[rs], regnames[rt], btgt); 2629 goto not_likely; 2630 case OPC_BNEL: 2631 gen_op_ne(bcond, t0, t1); 2632 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx, 2633 regnames[rs], regnames[rt], btgt); 2634 goto likely; 2635 case OPC_BGEZ: 2636 gen_op_gez(bcond, t0); 2637 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt); 2638 goto not_likely; 2639 case OPC_BGEZL: 2640 gen_op_gez(bcond, t0); 2641 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt); 2642 goto likely; 2643 case OPC_BGEZAL: 2644 gen_op_gez(bcond, t0); 2645 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt); 2646 blink = 31; 2647 goto not_likely; 2648 case OPC_BGEZALL: 2649 gen_op_gez(bcond, t0); 2650 blink = 31; 2651 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt); 2652 goto likely; 2653 case OPC_BGTZ: 2654 gen_op_gtz(bcond, t0); 2655 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt); 2656 goto not_likely; 2657 case OPC_BGTZL: 2658 gen_op_gtz(bcond, t0); 2659 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt); 2660 goto likely; 2661 case OPC_BLEZ: 2662 gen_op_lez(bcond, t0); 2663 MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt); 2664 goto not_likely; 2665 case OPC_BLEZL: 2666 gen_op_lez(bcond, t0); 2667 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt); 2668 goto likely; 2669 case OPC_BLTZ: 2670 gen_op_ltz(bcond, t0); 2671 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt); 2672 goto not_likely; 2673 case OPC_BLTZL: 2674 gen_op_ltz(bcond, t0); 2675 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt); 2676 goto likely; 2677 case OPC_BLTZAL: 2678 gen_op_ltz(bcond, t0); 2679 blink = 31; 2680 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt); 2681 not_likely: 2682 ctx->hflags |= MIPS_HFLAG_BC; 2683 break; 2684 case OPC_BLTZALL: 2685 gen_op_ltz(bcond, t0); 2686 blink = 31; 2687 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt); 2688 likely: 2689 ctx->hflags |= MIPS_HFLAG_BL; 2690 break; 2691 default: 2692 MIPS_INVAL("conditional branch/jump"); 2693 generate_exception(ctx, EXCP_RI); 2694 goto out; 2695 } 2696 } 2697 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx, 2698 blink, ctx->hflags, btgt); 2699 2700 ctx->btarget = btgt; 2701 if (blink > 0) { 2702 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + 8); 2703 } 2704 2705 out: 2706 tcg_temp_free(t0); 2707 tcg_temp_free(t1); 2708 } 2709 2710 /* special3 bitfield operations */ 2711 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt, 2712 int rs, int lsb, int msb) 2713 { 2714 TCGv t0 = tcg_temp_new(); 2715 TCGv t1 = tcg_temp_new(); 2716 target_ulong mask; 2717 2718 gen_load_gpr(t1, rs); 2719 switch (opc) { 2720 case OPC_EXT: 2721 if (lsb + msb > 31) 2722 goto fail; 2723 tcg_gen_shri_tl(t0, t1, lsb); 2724 if (msb != 31) { 2725 tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1); 2726 } else { 2727 tcg_gen_ext32s_tl(t0, t0); 2728 } 2729 break; 2730 #if defined(TARGET_MIPS64) 2731 case OPC_DEXTM: 2732 tcg_gen_shri_tl(t0, t1, lsb); 2733 if (msb != 31) { 2734 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1); 2735 } 2736 break; 2737 case OPC_DEXTU: 2738 tcg_gen_shri_tl(t0, t1, lsb + 32); 2739 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1); 2740 break; 2741 case OPC_DEXT: 2742 tcg_gen_shri_tl(t0, t1, lsb); 2743 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1); 2744 break; 2745 #endif 2746 case OPC_INS: 2747 if (lsb > msb) 2748 goto fail; 2749 mask = ((msb - lsb + 1 < 32) ? ((1 << (msb - lsb + 1)) - 1) : ~0) << lsb; 2750 gen_load_gpr(t0, rt); 2751 tcg_gen_andi_tl(t0, t0, ~mask); 2752 tcg_gen_shli_tl(t1, t1, lsb); 2753 tcg_gen_andi_tl(t1, t1, mask); 2754 tcg_gen_or_tl(t0, t0, t1); 2755 tcg_gen_ext32s_tl(t0, t0); 2756 break; 2757 #if defined(TARGET_MIPS64) 2758 case OPC_DINSM: 2759 if (lsb > msb) 2760 goto fail; 2761 mask = ((msb - lsb + 1 + 32 < 64) ? ((1ULL << (msb - lsb + 1 + 32)) - 1) : ~0ULL) << lsb; 2762 gen_load_gpr(t0, rt); 2763 tcg_gen_andi_tl(t0, t0, ~mask); 2764 tcg_gen_shli_tl(t1, t1, lsb); 2765 tcg_gen_andi_tl(t1, t1, mask); 2766 tcg_gen_or_tl(t0, t0, t1); 2767 break; 2768 case OPC_DINSU: 2769 if (lsb > msb) 2770 goto fail; 2771 mask = ((1ULL << (msb - lsb + 1)) - 1) << (lsb + 32); 2772 gen_load_gpr(t0, rt); 2773 tcg_gen_andi_tl(t0, t0, ~mask); 2774 tcg_gen_shli_tl(t1, t1, lsb + 32); 2775 tcg_gen_andi_tl(t1, t1, mask); 2776 tcg_gen_or_tl(t0, t0, t1); 2777 break; 2778 case OPC_DINS: 2779 if (lsb > msb) 2780 goto fail; 2781 gen_load_gpr(t0, rt); 2782 mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb; 2783 gen_load_gpr(t0, rt); 2784 tcg_gen_andi_tl(t0, t0, ~mask); 2785 tcg_gen_shli_tl(t1, t1, lsb); 2786 tcg_gen_andi_tl(t1, t1, mask); 2787 tcg_gen_or_tl(t0, t0, t1); 2788 break; 2789 #endif 2790 default: 2791 fail: 2792 MIPS_INVAL("bitops"); 2793 generate_exception(ctx, EXCP_RI); 2794 tcg_temp_free(t0); 2795 tcg_temp_free(t1); 2796 return; 2797 } 2798 gen_store_gpr(t0, rt); 2799 tcg_temp_free(t0); 2800 tcg_temp_free(t1); 2801 } 2802 2803 static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd) 2804 { 2805 TCGv t0; 2806 2807 if (rd == 0) { 2808 /* If no destination, treat it as a NOP. */ 2809 MIPS_DEBUG("NOP"); 2810 return; 2811 } 2812 2813 t0 = tcg_temp_new(); 2814 gen_load_gpr(t0, rt); 2815 switch (op2) { 2816 case OPC_WSBH: 2817 { 2818 TCGv t1 = tcg_temp_new(); 2819 2820 tcg_gen_shri_tl(t1, t0, 8); 2821 tcg_gen_andi_tl(t1, t1, 0x00FF00FF); 2822 tcg_gen_shli_tl(t0, t0, 8); 2823 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF); 2824 tcg_gen_or_tl(t0, t0, t1); 2825 tcg_temp_free(t1); 2826 tcg_gen_ext32s_tl(cpu_gpr[rd], t0); 2827 } 2828 break; 2829 case OPC_SEB: 2830 tcg_gen_ext8s_tl(cpu_gpr[rd], t0); 2831 break; 2832 case OPC_SEH: 2833 tcg_gen_ext16s_tl(cpu_gpr[rd], t0); 2834 break; 2835 #if defined(TARGET_MIPS64) 2836 case OPC_DSBH: 2837 { 2838 TCGv t1 = tcg_temp_new(); 2839 2840 tcg_gen_shri_tl(t1, t0, 8); 2841 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL); 2842 tcg_gen_shli_tl(t0, t0, 8); 2843 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL); 2844 tcg_gen_or_tl(cpu_gpr[rd], t0, t1); 2845 tcg_temp_free(t1); 2846 } 2847 break; 2848 case OPC_DSHD: 2849 { 2850 TCGv t1 = tcg_temp_new(); 2851 2852 tcg_gen_shri_tl(t1, t0, 16); 2853 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL); 2854 tcg_gen_shli_tl(t0, t0, 16); 2855 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL); 2856 tcg_gen_or_tl(t0, t0, t1); 2857 tcg_gen_shri_tl(t1, t0, 32); 2858 tcg_gen_shli_tl(t0, t0, 32); 2859 tcg_gen_or_tl(cpu_gpr[rd], t0, t1); 2860 tcg_temp_free(t1); 2861 } 2862 break; 2863 #endif 2864 default: 2865 MIPS_INVAL("bsfhl"); 2866 generate_exception(ctx, EXCP_RI); 2867 tcg_temp_free(t0); 2868 return; 2869 } 2870 tcg_temp_free(t0); 2871 } 2872 2873 #ifndef CONFIG_USER_ONLY 2874 /* CP0 (MMU and control) */ 2875 static inline void gen_mfc0_load32 (TCGv arg, target_ulong off) 2876 { 2877 TCGv_i32 t0 = tcg_temp_new_i32(); 2878 2879 tcg_gen_ld_i32(t0, cpu_env, off); 2880 tcg_gen_ext_i32_tl(arg, t0); 2881 tcg_temp_free_i32(t0); 2882 } 2883 2884 static inline void gen_mfc0_load64 (TCGv arg, target_ulong off) 2885 { 2886 tcg_gen_ld_tl(arg, cpu_env, off); 2887 tcg_gen_ext32s_tl(arg, arg); 2888 } 2889 2890 static inline void gen_mtc0_store32 (TCGv arg, target_ulong off) 2891 { 2892 TCGv_i32 t0 = tcg_temp_new_i32(); 2893 2894 tcg_gen_trunc_tl_i32(t0, arg); 2895 tcg_gen_st_i32(t0, cpu_env, off); 2896 tcg_temp_free_i32(t0); 2897 } 2898 2899 static inline void gen_mtc0_store64 (TCGv arg, target_ulong off) 2900 { 2901 tcg_gen_ext32s_tl(arg, arg); 2902 tcg_gen_st_tl(arg, cpu_env, off); 2903 } 2904 2905 static void gen_mfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel) 2906 { 2907 const char * __attribute__((unused)) rn = "invalid"; 2908 2909 if (sel != 0) 2910 check_insn(env, ctx, ISA_MIPS32); 2911 2912 switch (reg) { 2913 case 0: 2914 switch (sel) { 2915 case 0: 2916 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index)); 2917 rn = "Index"; 2918 break; 2919 case 1: 2920 check_insn(env, ctx, ASE_MT); 2921 gen_helper_mfc0_mvpcontrol(arg, cpu_env); 2922 rn = "MVPControl"; 2923 break; 2924 case 2: 2925 check_insn(env, ctx, ASE_MT); 2926 gen_helper_mfc0_mvpconf0(arg, cpu_env); 2927 rn = "MVPConf0"; 2928 break; 2929 case 3: 2930 check_insn(env, ctx, ASE_MT); 2931 gen_helper_mfc0_mvpconf1(arg, cpu_env); 2932 rn = "MVPConf1"; 2933 break; 2934 default: 2935 goto die; 2936 } 2937 break; 2938 case 1: 2939 switch (sel) { 2940 case 0: 2941 gen_helper_mfc0_random(arg, cpu_env); 2942 rn = "Random"; 2943 break; 2944 case 1: 2945 check_insn(env, ctx, ASE_MT); 2946 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl)); 2947 rn = "VPEControl"; 2948 break; 2949 case 2: 2950 check_insn(env, ctx, ASE_MT); 2951 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0)); 2952 rn = "VPEConf0"; 2953 break; 2954 case 3: 2955 check_insn(env, ctx, ASE_MT); 2956 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1)); 2957 rn = "VPEConf1"; 2958 break; 2959 case 4: 2960 check_insn(env, ctx, ASE_MT); 2961 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask)); 2962 rn = "YQMask"; 2963 break; 2964 case 5: 2965 check_insn(env, ctx, ASE_MT); 2966 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule)); 2967 rn = "VPESchedule"; 2968 break; 2969 case 6: 2970 check_insn(env, ctx, ASE_MT); 2971 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack)); 2972 rn = "VPEScheFBack"; 2973 break; 2974 case 7: 2975 check_insn(env, ctx, ASE_MT); 2976 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt)); 2977 rn = "VPEOpt"; 2978 break; 2979 default: 2980 goto die; 2981 } 2982 break; 2983 case 2: 2984 switch (sel) { 2985 case 0: 2986 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0)); 2987 tcg_gen_ext32s_tl(arg, arg); 2988 rn = "EntryLo0"; 2989 break; 2990 case 1: 2991 check_insn(env, ctx, ASE_MT); 2992 gen_helper_mfc0_tcstatus(arg, cpu_env); 2993 rn = "TCStatus"; 2994 break; 2995 case 2: 2996 check_insn(env, ctx, ASE_MT); 2997 gen_helper_mfc0_tcbind(arg, cpu_env); 2998 rn = "TCBind"; 2999 break; 3000 case 3: 3001 check_insn(env, ctx, ASE_MT); 3002 gen_helper_mfc0_tcrestart(arg, cpu_env); 3003 rn = "TCRestart"; 3004 break; 3005 case 4: 3006 check_insn(env, ctx, ASE_MT); 3007 gen_helper_mfc0_tchalt(arg, cpu_env); 3008 rn = "TCHalt"; 3009 break; 3010 case 5: 3011 check_insn(env, ctx, ASE_MT); 3012 gen_helper_mfc0_tccontext(arg, cpu_env); 3013 rn = "TCContext"; 3014 break; 3015 case 6: 3016 check_insn(env, ctx, ASE_MT); 3017 gen_helper_mfc0_tcschedule(arg, cpu_env); 3018 rn = "TCSchedule"; 3019 break; 3020 case 7: 3021 check_insn(env, ctx, ASE_MT); 3022 gen_helper_mfc0_tcschefback(arg, cpu_env); 3023 rn = "TCScheFBack"; 3024 break; 3025 default: 3026 goto die; 3027 } 3028 break; 3029 case 3: 3030 switch (sel) { 3031 case 0: 3032 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1)); 3033 tcg_gen_ext32s_tl(arg, arg); 3034 rn = "EntryLo1"; 3035 break; 3036 default: 3037 goto die; 3038 } 3039 break; 3040 case 4: 3041 switch (sel) { 3042 case 0: 3043 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context)); 3044 tcg_gen_ext32s_tl(arg, arg); 3045 rn = "Context"; 3046 break; 3047 case 1: 3048 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */ 3049 rn = "ContextConfig"; 3050 // break; 3051 default: 3052 goto die; 3053 } 3054 break; 3055 case 5: 3056 switch (sel) { 3057 case 0: 3058 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask)); 3059 rn = "PageMask"; 3060 break; 3061 case 1: 3062 check_insn(env, ctx, ISA_MIPS32R2); 3063 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain)); 3064 rn = "PageGrain"; 3065 break; 3066 default: 3067 goto die; 3068 } 3069 break; 3070 case 6: 3071 switch (sel) { 3072 case 0: 3073 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired)); 3074 rn = "Wired"; 3075 break; 3076 case 1: 3077 check_insn(env, ctx, ISA_MIPS32R2); 3078 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0)); 3079 rn = "SRSConf0"; 3080 break; 3081 case 2: 3082 check_insn(env, ctx, ISA_MIPS32R2); 3083 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1)); 3084 rn = "SRSConf1"; 3085 break; 3086 case 3: 3087 check_insn(env, ctx, ISA_MIPS32R2); 3088 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2)); 3089 rn = "SRSConf2"; 3090 break; 3091 case 4: 3092 check_insn(env, ctx, ISA_MIPS32R2); 3093 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3)); 3094 rn = "SRSConf3"; 3095 break; 3096 case 5: 3097 check_insn(env, ctx, ISA_MIPS32R2); 3098 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4)); 3099 rn = "SRSConf4"; 3100 break; 3101 default: 3102 goto die; 3103 } 3104 break; 3105 case 7: 3106 switch (sel) { 3107 case 0: 3108 check_insn(env, ctx, ISA_MIPS32R2); 3109 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna)); 3110 rn = "HWREna"; 3111 break; 3112 default: 3113 goto die; 3114 } 3115 break; 3116 case 8: 3117 switch (sel) { 3118 case 0: 3119 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); 3120 tcg_gen_ext32s_tl(arg, arg); 3121 rn = "BadVAddr"; 3122 break; 3123 default: 3124 goto die; 3125 } 3126 break; 3127 case 9: 3128 switch (sel) { 3129 case 0: 3130 /* Mark as an IO operation because we read the time. */ 3131 if (use_icount) 3132 gen_io_start(); 3133 gen_helper_mfc0_count(arg, cpu_env); 3134 if (use_icount) { 3135 gen_io_end(); 3136 ctx->bstate = BS_STOP; 3137 } 3138 rn = "Count"; 3139 break; 3140 /* 6,7 are implementation dependent */ 3141 default: 3142 goto die; 3143 } 3144 break; 3145 case 10: 3146 switch (sel) { 3147 case 0: 3148 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi)); 3149 tcg_gen_ext32s_tl(arg, arg); 3150 rn = "EntryHi"; 3151 break; 3152 default: 3153 goto die; 3154 } 3155 break; 3156 case 11: 3157 switch (sel) { 3158 case 0: 3159 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare)); 3160 rn = "Compare"; 3161 break; 3162 /* 6,7 are implementation dependent */ 3163 default: 3164 goto die; 3165 } 3166 break; 3167 case 12: 3168 switch (sel) { 3169 case 0: 3170 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status)); 3171 rn = "Status"; 3172 break; 3173 case 1: 3174 check_insn(env, ctx, ISA_MIPS32R2); 3175 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl)); 3176 rn = "IntCtl"; 3177 break; 3178 case 2: 3179 check_insn(env, ctx, ISA_MIPS32R2); 3180 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl)); 3181 rn = "SRSCtl"; 3182 break; 3183 case 3: 3184 check_insn(env, ctx, ISA_MIPS32R2); 3185 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); 3186 rn = "SRSMap"; 3187 break; 3188 default: 3189 goto die; 3190 } 3191 break; 3192 case 13: 3193 switch (sel) { 3194 case 0: 3195 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause)); 3196 rn = "Cause"; 3197 break; 3198 default: 3199 goto die; 3200 } 3201 break; 3202 case 14: 3203 switch (sel) { 3204 case 0: 3205 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC)); 3206 tcg_gen_ext32s_tl(arg, arg); 3207 rn = "EPC"; 3208 break; 3209 default: 3210 goto die; 3211 } 3212 break; 3213 case 15: 3214 switch (sel) { 3215 case 0: 3216 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid)); 3217 rn = "PRid"; 3218 break; 3219 case 1: 3220 check_insn(env, ctx, ISA_MIPS32R2); 3221 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase)); 3222 rn = "EBase"; 3223 break; 3224 default: 3225 goto die; 3226 } 3227 break; 3228 case 16: 3229 switch (sel) { 3230 case 0: 3231 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0)); 3232 rn = "Config"; 3233 break; 3234 case 1: 3235 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1)); 3236 rn = "Config1"; 3237 break; 3238 case 2: 3239 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2)); 3240 rn = "Config2"; 3241 break; 3242 case 3: 3243 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3)); 3244 rn = "Config3"; 3245 break; 3246 /* 4,5 are reserved */ 3247 /* 6,7 are implementation dependent */ 3248 case 6: 3249 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6)); 3250 rn = "Config6"; 3251 break; 3252 case 7: 3253 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7)); 3254 rn = "Config7"; 3255 break; 3256 default: 3257 goto die; 3258 } 3259 break; 3260 case 17: 3261 switch (sel) { 3262 case 0: 3263 gen_helper_mfc0_lladdr(arg, cpu_env); 3264 rn = "LLAddr"; 3265 break; 3266 default: 3267 goto die; 3268 } 3269 break; 3270 case 18: 3271 switch (sel) { 3272 case 0 ... 7: 3273 gen_helper_2i(mfc0_watchlo, arg, cpu_env, sel); 3274 rn = "WatchLo"; 3275 break; 3276 default: 3277 goto die; 3278 } 3279 break; 3280 case 19: 3281 switch (sel) { 3282 case 0 ...7: 3283 gen_helper_2i(mfc0_watchhi, arg, cpu_env, sel); 3284 rn = "WatchHi"; 3285 break; 3286 default: 3287 goto die; 3288 } 3289 break; 3290 case 20: 3291 switch (sel) { 3292 case 0: 3293 #if defined(TARGET_MIPS64) 3294 check_insn(env, ctx, ISA_MIPS3); 3295 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext)); 3296 tcg_gen_ext32s_tl(arg, arg); 3297 rn = "XContext"; 3298 break; 3299 #endif 3300 default: 3301 goto die; 3302 } 3303 break; 3304 case 21: 3305 /* Officially reserved, but sel 0 is used for R1x000 framemask */ 3306 switch (sel) { 3307 case 0: 3308 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask)); 3309 rn = "Framemask"; 3310 break; 3311 default: 3312 goto die; 3313 } 3314 break; 3315 case 22: 3316 tcg_gen_movi_tl(arg, 0); /* unimplemented */ 3317 rn = "'Diagnostic"; /* implementation dependent */ 3318 break; 3319 case 23: 3320 switch (sel) { 3321 case 0: 3322 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */ 3323 rn = "Debug"; 3324 break; 3325 case 1: 3326 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */ 3327 rn = "TraceControl"; 3328 // break; 3329 case 2: 3330 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */ 3331 rn = "TraceControl2"; 3332 // break; 3333 case 3: 3334 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */ 3335 rn = "UserTraceData"; 3336 // break; 3337 case 4: 3338 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */ 3339 rn = "TraceBPC"; 3340 // break; 3341 default: 3342 goto die; 3343 } 3344 break; 3345 case 24: 3346 switch (sel) { 3347 case 0: 3348 /* EJTAG support */ 3349 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC)); 3350 tcg_gen_ext32s_tl(arg, arg); 3351 rn = "DEPC"; 3352 break; 3353 default: 3354 goto die; 3355 } 3356 break; 3357 case 25: 3358 switch (sel) { 3359 case 0: 3360 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0)); 3361 rn = "Performance0"; 3362 break; 3363 case 1: 3364 // gen_helper_mfc0_performance1(arg); 3365 rn = "Performance1"; 3366 // break; 3367 case 2: 3368 // gen_helper_mfc0_performance2(arg); 3369 rn = "Performance2"; 3370 // break; 3371 case 3: 3372 // gen_helper_mfc0_performance3(arg); 3373 rn = "Performance3"; 3374 // break; 3375 case 4: 3376 // gen_helper_mfc0_performance4(arg); 3377 rn = "Performance4"; 3378 // break; 3379 case 5: 3380 // gen_helper_mfc0_performance5(arg); 3381 rn = "Performance5"; 3382 // break; 3383 case 6: 3384 // gen_helper_mfc0_performance6(arg); 3385 rn = "Performance6"; 3386 // break; 3387 case 7: 3388 // gen_helper_mfc0_performance7(arg); 3389 rn = "Performance7"; 3390 // break; 3391 default: 3392 goto die; 3393 } 3394 break; 3395 case 26: 3396 tcg_gen_movi_tl(arg, 0); /* unimplemented */ 3397 rn = "ECC"; 3398 break; 3399 case 27: 3400 switch (sel) { 3401 case 0 ... 3: 3402 tcg_gen_movi_tl(arg, 0); /* unimplemented */ 3403 rn = "CacheErr"; 3404 break; 3405 default: 3406 goto die; 3407 } 3408 break; 3409 case 28: 3410 switch (sel) { 3411 case 0: 3412 case 2: 3413 case 4: 3414 case 6: 3415 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo)); 3416 rn = "TagLo"; 3417 break; 3418 case 1: 3419 case 3: 3420 case 5: 3421 case 7: 3422 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo)); 3423 rn = "DataLo"; 3424 break; 3425 default: 3426 goto die; 3427 } 3428 break; 3429 case 29: 3430 switch (sel) { 3431 case 0: 3432 case 2: 3433 case 4: 3434 case 6: 3435 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi)); 3436 rn = "TagHi"; 3437 break; 3438 case 1: 3439 case 3: 3440 case 5: 3441 case 7: 3442 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi)); 3443 rn = "DataHi"; 3444 break; 3445 default: 3446 goto die; 3447 } 3448 break; 3449 case 30: 3450 switch (sel) { 3451 case 0: 3452 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC)); 3453 tcg_gen_ext32s_tl(arg, arg); 3454 rn = "ErrorEPC"; 3455 break; 3456 default: 3457 goto die; 3458 } 3459 break; 3460 case 31: 3461 switch (sel) { 3462 case 0: 3463 /* EJTAG support */ 3464 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); 3465 rn = "DESAVE"; 3466 break; 3467 default: 3468 goto die; 3469 } 3470 break; 3471 default: 3472 goto die; 3473 } 3474 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel); 3475 return; 3476 3477 die: 3478 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel); 3479 generate_exception(ctx, EXCP_RI); 3480 } 3481 3482 static void gen_mtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel) 3483 { 3484 const char * __attribute__((unused)) rn = "invalid"; 3485 3486 if (sel != 0) 3487 check_insn(env, ctx, ISA_MIPS32); 3488 3489 if (use_icount) 3490 gen_io_start(); 3491 3492 switch (reg) { 3493 case 0: 3494 switch (sel) { 3495 case 0: 3496 gen_helper_mtc0_index(cpu_env, arg); 3497 rn = "Index"; 3498 break; 3499 case 1: 3500 check_insn(env, ctx, ASE_MT); 3501 gen_helper_mtc0_mvpcontrol(cpu_env, arg); 3502 rn = "MVPControl"; 3503 break; 3504 case 2: 3505 check_insn(env, ctx, ASE_MT); 3506 /* ignored */ 3507 rn = "MVPConf0"; 3508 break; 3509 case 3: 3510 check_insn(env, ctx, ASE_MT); 3511 /* ignored */ 3512 rn = "MVPConf1"; 3513 break; 3514 default: 3515 goto die; 3516 } 3517 break; 3518 case 1: 3519 switch (sel) { 3520 case 0: 3521 /* ignored */ 3522 rn = "Random"; 3523 break; 3524 case 1: 3525 check_insn(env, ctx, ASE_MT); 3526 gen_helper_mtc0_vpecontrol(cpu_env, arg); 3527 rn = "VPEControl"; 3528 break; 3529 case 2: 3530 check_insn(env, ctx, ASE_MT); 3531 gen_helper_mtc0_vpeconf0(cpu_env, arg); 3532 rn = "VPEConf0"; 3533 break; 3534 case 3: 3535 check_insn(env, ctx, ASE_MT); 3536 gen_helper_mtc0_vpeconf1(cpu_env, arg); 3537 rn = "VPEConf1"; 3538 break; 3539 case 4: 3540 check_insn(env, ctx, ASE_MT); 3541 gen_helper_mtc0_yqmask(cpu_env, arg); 3542 rn = "YQMask"; 3543 break; 3544 case 5: 3545 check_insn(env, ctx, ASE_MT); 3546 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPESchedule)); 3547 rn = "VPESchedule"; 3548 break; 3549 case 6: 3550 check_insn(env, ctx, ASE_MT); 3551 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack)); 3552 rn = "VPEScheFBack"; 3553 break; 3554 case 7: 3555 check_insn(env, ctx, ASE_MT); 3556 gen_helper_mtc0_vpeopt(cpu_env, arg); 3557 rn = "VPEOpt"; 3558 break; 3559 default: 3560 goto die; 3561 } 3562 break; 3563 case 2: 3564 switch (sel) { 3565 case 0: 3566 gen_helper_mtc0_entrylo0(cpu_env, arg); 3567 rn = "EntryLo0"; 3568 break; 3569 case 1: 3570 check_insn(env, ctx, ASE_MT); 3571 gen_helper_mtc0_tcstatus(cpu_env, arg); 3572 rn = "TCStatus"; 3573 break; 3574 case 2: 3575 check_insn(env, ctx, ASE_MT); 3576 gen_helper_mtc0_tcbind(cpu_env, arg); 3577 rn = "TCBind"; 3578 break; 3579 case 3: 3580 check_insn(env, ctx, ASE_MT); 3581 gen_helper_mtc0_tcrestart(cpu_env, arg); 3582 rn = "TCRestart"; 3583 break; 3584 case 4: 3585 check_insn(env, ctx, ASE_MT); 3586 gen_helper_mtc0_tchalt(cpu_env, arg); 3587 rn = "TCHalt"; 3588 break; 3589 case 5: 3590 check_insn(env, ctx, ASE_MT); 3591 gen_helper_mtc0_tccontext(cpu_env, arg); 3592 rn = "TCContext"; 3593 break; 3594 case 6: 3595 check_insn(env, ctx, ASE_MT); 3596 gen_helper_mtc0_tcschedule(cpu_env, arg); 3597 rn = "TCSchedule"; 3598 break; 3599 case 7: 3600 check_insn(env, ctx, ASE_MT); 3601 gen_helper_mtc0_tcschefback(cpu_env, arg); 3602 rn = "TCScheFBack"; 3603 break; 3604 default: 3605 goto die; 3606 } 3607 break; 3608 case 3: 3609 switch (sel) { 3610 case 0: 3611 gen_helper_mtc0_entrylo1(cpu_env, arg); 3612 rn = "EntryLo1"; 3613 break; 3614 default: 3615 goto die; 3616 } 3617 break; 3618 case 4: 3619 switch (sel) { 3620 case 0: 3621 gen_helper_mtc0_context(cpu_env, arg); 3622 rn = "Context"; 3623 break; 3624 case 1: 3625 // gen_helper_mtc0_contextconfig(arg); /* SmartMIPS ASE */ 3626 rn = "ContextConfig"; 3627 // break; 3628 default: 3629 goto die; 3630 } 3631 break; 3632 case 5: 3633 switch (sel) { 3634 case 0: 3635 gen_helper_mtc0_pagemask(cpu_env, arg); 3636 rn = "PageMask"; 3637 break; 3638 case 1: 3639 check_insn(env, ctx, ISA_MIPS32R2); 3640 gen_helper_mtc0_pagegrain(cpu_env, arg); 3641 rn = "PageGrain"; 3642 break; 3643 default: 3644 goto die; 3645 } 3646 break; 3647 case 6: 3648 switch (sel) { 3649 case 0: 3650 gen_helper_mtc0_wired(cpu_env, arg); 3651 rn = "Wired"; 3652 break; 3653 case 1: 3654 check_insn(env, ctx, ISA_MIPS32R2); 3655 gen_helper_mtc0_srsconf0(cpu_env, arg); 3656 rn = "SRSConf0"; 3657 break; 3658 case 2: 3659 check_insn(env, ctx, ISA_MIPS32R2); 3660 gen_helper_mtc0_srsconf1(cpu_env, arg); 3661 rn = "SRSConf1"; 3662 break; 3663 case 3: 3664 check_insn(env, ctx, ISA_MIPS32R2); 3665 gen_helper_mtc0_srsconf2(cpu_env, arg); 3666 rn = "SRSConf2"; 3667 break; 3668 case 4: 3669 check_insn(env, ctx, ISA_MIPS32R2); 3670 gen_helper_mtc0_srsconf3(cpu_env, arg); 3671 rn = "SRSConf3"; 3672 break; 3673 case 5: 3674 check_insn(env, ctx, ISA_MIPS32R2); 3675 gen_helper_mtc0_srsconf4(cpu_env, arg); 3676 rn = "SRSConf4"; 3677 break; 3678 default: 3679 goto die; 3680 } 3681 break; 3682 case 7: 3683 switch (sel) { 3684 case 0: 3685 check_insn(env, ctx, ISA_MIPS32R2); 3686 gen_helper_mtc0_hwrena(cpu_env, arg); 3687 rn = "HWREna"; 3688 break; 3689 default: 3690 goto die; 3691 } 3692 break; 3693 case 8: 3694 /* ignored */ 3695 rn = "BadVAddr"; 3696 break; 3697 case 9: 3698 switch (sel) { 3699 case 0: 3700 gen_helper_mtc0_count(cpu_env, arg); 3701 rn = "Count"; 3702 break; 3703 /* 6,7 are implementation dependent */ 3704 default: 3705 goto die; 3706 } 3707 break; 3708 case 10: 3709 switch (sel) { 3710 case 0: 3711 gen_helper_mtc0_entryhi(cpu_env, arg); 3712 rn = "EntryHi"; 3713 break; 3714 default: 3715 goto die; 3716 } 3717 break; 3718 case 11: 3719 switch (sel) { 3720 case 0: 3721 gen_helper_mtc0_compare(cpu_env, arg); 3722 rn = "Compare"; 3723 break; 3724 /* 6,7 are implementation dependent */ 3725 default: 3726 goto die; 3727 } 3728 break; 3729 case 12: 3730 switch (sel) { 3731 case 0: 3732 save_cpu_state(ctx, 1); 3733 gen_helper_mtc0_status(cpu_env, arg); 3734 /* BS_STOP isn't good enough here, hflags may have changed. */ 3735 gen_save_pc(ctx->pc + 4); 3736 ctx->bstate = BS_EXCP; 3737 rn = "Status"; 3738 break; 3739 case 1: 3740 check_insn(env, ctx, ISA_MIPS32R2); 3741 gen_helper_mtc0_intctl(cpu_env, arg); 3742 /* Stop translation as we may have switched the execution mode */ 3743 ctx->bstate = BS_STOP; 3744 rn = "IntCtl"; 3745 break; 3746 case 2: 3747 check_insn(env, ctx, ISA_MIPS32R2); 3748 gen_helper_mtc0_srsctl(cpu_env, arg); 3749 /* Stop translation as we may have switched the execution mode */ 3750 ctx->bstate = BS_STOP; 3751 rn = "SRSCtl"; 3752 break; 3753 case 3: 3754 check_insn(env, ctx, ISA_MIPS32R2); 3755 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); 3756 /* Stop translation as we may have switched the execution mode */ 3757 ctx->bstate = BS_STOP; 3758 rn = "SRSMap"; 3759 break; 3760 default: 3761 goto die; 3762 } 3763 break; 3764 case 13: 3765 switch (sel) { 3766 case 0: 3767 save_cpu_state(ctx, 1); 3768 gen_helper_mtc0_cause(cpu_env, arg); 3769 rn = "Cause"; 3770 break; 3771 default: 3772 goto die; 3773 } 3774 break; 3775 case 14: 3776 switch (sel) { 3777 case 0: 3778 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_EPC)); 3779 rn = "EPC"; 3780 break; 3781 default: 3782 goto die; 3783 } 3784 break; 3785 case 15: 3786 switch (sel) { 3787 case 0: 3788 /* ignored */ 3789 rn = "PRid"; 3790 break; 3791 case 1: 3792 check_insn(env, ctx, ISA_MIPS32R2); 3793 gen_helper_mtc0_ebase(cpu_env, arg); 3794 rn = "EBase"; 3795 break; 3796 default: 3797 goto die; 3798 } 3799 break; 3800 case 16: 3801 switch (sel) { 3802 case 0: 3803 gen_helper_mtc0_config0(cpu_env, arg); 3804 rn = "Config"; 3805 /* Stop translation as we may have switched the execution mode */ 3806 ctx->bstate = BS_STOP; 3807 break; 3808 case 1: 3809 /* ignored, read only */ 3810 rn = "Config1"; 3811 break; 3812 case 2: 3813 gen_helper_mtc0_config2(cpu_env, arg); 3814 rn = "Config2"; 3815 /* Stop translation as we may have switched the execution mode */ 3816 ctx->bstate = BS_STOP; 3817 break; 3818 case 3: 3819 /* ignored, read only */ 3820 rn = "Config3"; 3821 break; 3822 /* 4,5 are reserved */ 3823 /* 6,7 are implementation dependent */ 3824 case 6: 3825 /* ignored */ 3826 rn = "Config6"; 3827 break; 3828 case 7: 3829 /* ignored */ 3830 rn = "Config7"; 3831 break; 3832 default: 3833 rn = "Invalid config selector"; 3834 goto die; 3835 } 3836 break; 3837 case 17: 3838 switch (sel) { 3839 case 0: 3840 gen_helper_mtc0_lladdr(cpu_env, arg); 3841 rn = "LLAddr"; 3842 break; 3843 default: 3844 goto die; 3845 } 3846 break; 3847 case 18: 3848 switch (sel) { 3849 case 0 ... 7: 3850 gen_helper_2i(mtc0_watchlo, cpu_env, arg, sel); 3851 rn = "WatchLo"; 3852 break; 3853 default: 3854 goto die; 3855 } 3856 break; 3857 case 19: 3858 switch (sel) { 3859 case 0 ... 7: 3860 gen_helper_2i(mtc0_watchhi, cpu_env, arg, sel); 3861 rn = "WatchHi"; 3862 break; 3863 default: 3864 goto die; 3865 } 3866 break; 3867 case 20: 3868 switch (sel) { 3869 case 0: 3870 #if defined(TARGET_MIPS64) 3871 check_insn(env, ctx, ISA_MIPS3); 3872 gen_helper_mtc0_xcontext(cpu_env, arg); 3873 rn = "XContext"; 3874 break; 3875 #endif 3876 default: 3877 goto die; 3878 } 3879 break; 3880 case 21: 3881 /* Officially reserved, but sel 0 is used for R1x000 framemask */ 3882 switch (sel) { 3883 case 0: 3884 gen_helper_mtc0_framemask(cpu_env, arg); 3885 rn = "Framemask"; 3886 break; 3887 default: 3888 goto die; 3889 } 3890 break; 3891 case 22: 3892 /* ignored */ 3893 rn = "Diagnostic"; /* implementation dependent */ 3894 break; 3895 case 23: 3896 switch (sel) { 3897 case 0: 3898 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */ 3899 /* BS_STOP isn't good enough here, hflags may have changed. */ 3900 gen_save_pc(ctx->pc + 4); 3901 ctx->bstate = BS_EXCP; 3902 rn = "Debug"; 3903 break; 3904 case 1: 3905 // gen_helper_mtc0_tracecontrol(arg); /* PDtrace support */ 3906 rn = "TraceControl"; 3907 /* Stop translation as we may have switched the execution mode */ 3908 ctx->bstate = BS_STOP; 3909 // break; 3910 case 2: 3911 // gen_helper_mtc0_tracecontrol2(arg); /* PDtrace support */ 3912 rn = "TraceControl2"; 3913 /* Stop translation as we may have switched the execution mode */ 3914 ctx->bstate = BS_STOP; 3915 // break; 3916 case 3: 3917 /* Stop translation as we may have switched the execution mode */ 3918 ctx->bstate = BS_STOP; 3919 // gen_helper_mtc0_usertracedata(arg); /* PDtrace support */ 3920 rn = "UserTraceData"; 3921 /* Stop translation as we may have switched the execution mode */ 3922 ctx->bstate = BS_STOP; 3923 // break; 3924 case 4: 3925 // gen_helper_mtc0_tracebpc(arg); /* PDtrace support */ 3926 /* Stop translation as we may have switched the execution mode */ 3927 ctx->bstate = BS_STOP; 3928 rn = "TraceBPC"; 3929 // break; 3930 default: 3931 goto die; 3932 } 3933 break; 3934 case 24: 3935 switch (sel) { 3936 case 0: 3937 /* EJTAG support */ 3938 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_DEPC)); 3939 rn = "DEPC"; 3940 break; 3941 default: 3942 goto die; 3943 } 3944 break; 3945 case 25: 3946 switch (sel) { 3947 case 0: 3948 gen_helper_mtc0_performance0(cpu_env, arg); 3949 rn = "Performance0"; 3950 break; 3951 case 1: 3952 // gen_helper_mtc0_performance1(cpu_env, arg); 3953 rn = "Performance1"; 3954 // break; 3955 case 2: 3956 // gen_helper_mtc0_performance2(cpu_env, arg); 3957 rn = "Performance2"; 3958 // break; 3959 case 3: 3960 // gen_helper_mtc0_performance3(cpu_env, arg); 3961 rn = "Performance3"; 3962 // break; 3963 case 4: 3964 // gen_helper_mtc0_performance4(cpu_env, arg); 3965 rn = "Performance4"; 3966 // break; 3967 case 5: 3968 // gen_helper_mtc0_performance5(cpu_env, arg); 3969 rn = "Performance5"; 3970 // break; 3971 case 6: 3972 // gen_helper_mtc0_performance6(cpu_env, arg); 3973 rn = "Performance6"; 3974 // break; 3975 case 7: 3976 // gen_helper_mtc0_performance7(cpu_env, arg); 3977 rn = "Performance7"; 3978 // break; 3979 default: 3980 goto die; 3981 } 3982 break; 3983 case 26: 3984 /* ignored */ 3985 rn = "ECC"; 3986 break; 3987 case 27: 3988 switch (sel) { 3989 case 0 ... 3: 3990 /* ignored */ 3991 rn = "CacheErr"; 3992 break; 3993 default: 3994 goto die; 3995 } 3996 break; 3997 case 28: 3998 switch (sel) { 3999 case 0: 4000 case 2: 4001 case 4: 4002 case 6: 4003 gen_helper_mtc0_taglo(cpu_env, arg); 4004 rn = "TagLo"; 4005 break; 4006 case 1: 4007 case 3: 4008 case 5: 4009 case 7: 4010 gen_helper_mtc0_datalo(cpu_env, arg); 4011 rn = "DataLo"; 4012 break; 4013 default: 4014 goto die; 4015 } 4016 break; 4017 case 29: 4018 switch (sel) { 4019 case 0: 4020 case 2: 4021 case 4: 4022 case 6: 4023 gen_helper_mtc0_taghi(cpu_env, arg); 4024 rn = "TagHi"; 4025 break; 4026 case 1: 4027 case 3: 4028 case 5: 4029 case 7: 4030 gen_helper_mtc0_datahi(cpu_env, arg); 4031 rn = "DataHi"; 4032 break; 4033 default: 4034 rn = "invalid sel"; 4035 goto die; 4036 } 4037 break; 4038 case 30: 4039 switch (sel) { 4040 case 0: 4041 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_ErrorEPC)); 4042 rn = "ErrorEPC"; 4043 break; 4044 default: 4045 goto die; 4046 } 4047 break; 4048 case 31: 4049 switch (sel) { 4050 case 0: 4051 /* EJTAG support */ 4052 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); 4053 rn = "DESAVE"; 4054 break; 4055 default: 4056 goto die; 4057 } 4058 /* Stop translation as we may have switched the execution mode */ 4059 ctx->bstate = BS_STOP; 4060 break; 4061 default: 4062 goto die; 4063 } 4064 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel); 4065 /* For simplicity assume that all writes can cause interrupts. */ 4066 if (use_icount) { 4067 gen_io_end(); 4068 ctx->bstate = BS_STOP; 4069 } 4070 return; 4071 4072 die: 4073 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel); 4074 generate_exception(ctx, EXCP_RI); 4075 } 4076 4077 #if defined(TARGET_MIPS64) 4078 static void gen_dmfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel) 4079 { 4080 const char *rn = "invalid"; 4081 4082 if (sel != 0) 4083 check_insn(env, ctx, ISA_MIPS64); 4084 4085 switch (reg) { 4086 case 0: 4087 switch (sel) { 4088 case 0: 4089 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index)); 4090 rn = "Index"; 4091 break; 4092 case 1: 4093 check_insn(env, ctx, ASE_MT); 4094 gen_helper_mfc0_mvpcontrol(arg); 4095 rn = "MVPControl"; 4096 break; 4097 case 2: 4098 check_insn(env, ctx, ASE_MT); 4099 gen_helper_mfc0_mvpconf0(arg); 4100 rn = "MVPConf0"; 4101 break; 4102 case 3: 4103 check_insn(env, ctx, ASE_MT); 4104 gen_helper_mfc0_mvpconf1(arg); 4105 rn = "MVPConf1"; 4106 break; 4107 default: 4108 goto die; 4109 } 4110 break; 4111 case 1: 4112 switch (sel) { 4113 case 0: 4114 gen_helper_mfc0_random(arg); 4115 rn = "Random"; 4116 break; 4117 case 1: 4118 check_insn(env, ctx, ASE_MT); 4119 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl)); 4120 rn = "VPEControl"; 4121 break; 4122 case 2: 4123 check_insn(env, ctx, ASE_MT); 4124 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0)); 4125 rn = "VPEConf0"; 4126 break; 4127 case 3: 4128 check_insn(env, ctx, ASE_MT); 4129 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1)); 4130 rn = "VPEConf1"; 4131 break; 4132 case 4: 4133 check_insn(env, ctx, ASE_MT); 4134 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask)); 4135 rn = "YQMask"; 4136 break; 4137 case 5: 4138 check_insn(env, ctx, ASE_MT); 4139 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule)); 4140 rn = "VPESchedule"; 4141 break; 4142 case 6: 4143 check_insn(env, ctx, ASE_MT); 4144 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack)); 4145 rn = "VPEScheFBack"; 4146 break; 4147 case 7: 4148 check_insn(env, ctx, ASE_MT); 4149 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt)); 4150 rn = "VPEOpt"; 4151 break; 4152 default: 4153 goto die; 4154 } 4155 break; 4156 case 2: 4157 switch (sel) { 4158 case 0: 4159 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0)); 4160 rn = "EntryLo0"; 4161 break; 4162 case 1: 4163 check_insn(env, ctx, ASE_MT); 4164 gen_helper_mfc0_tcstatus(arg); 4165 rn = "TCStatus"; 4166 break; 4167 case 2: 4168 check_insn(env, ctx, ASE_MT); 4169 gen_helper_mfc0_tcbind(arg); 4170 rn = "TCBind"; 4171 break; 4172 case 3: 4173 check_insn(env, ctx, ASE_MT); 4174 gen_helper_dmfc0_tcrestart(arg, cpu_env); 4175 rn = "TCRestart"; 4176 break; 4177 case 4: 4178 check_insn(env, ctx, ASE_MT); 4179 gen_helper_dmfc0_tchalt(arg, cpu_env); 4180 rn = "TCHalt"; 4181 break; 4182 case 5: 4183 check_insn(env, ctx, ASE_MT); 4184 gen_helper_dmfc0_tccontext(arg, cpu_env); 4185 rn = "TCContext"; 4186 break; 4187 case 6: 4188 check_insn(env, ctx, ASE_MT); 4189 gen_helper_dmfc0_tcschedule(arg, cpu_env); 4190 rn = "TCSchedule"; 4191 break; 4192 case 7: 4193 check_insn(env, ctx, ASE_MT); 4194 gen_helper_dmfc0_tcschefback(arg, cpu_env); 4195 rn = "TCScheFBack"; 4196 break; 4197 default: 4198 goto die; 4199 } 4200 break; 4201 case 3: 4202 switch (sel) { 4203 case 0: 4204 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1)); 4205 rn = "EntryLo1"; 4206 break; 4207 default: 4208 goto die; 4209 } 4210 break; 4211 case 4: 4212 switch (sel) { 4213 case 0: 4214 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context)); 4215 rn = "Context"; 4216 break; 4217 case 1: 4218 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */ 4219 rn = "ContextConfig"; 4220 // break; 4221 default: 4222 goto die; 4223 } 4224 break; 4225 case 5: 4226 switch (sel) { 4227 case 0: 4228 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask)); 4229 rn = "PageMask"; 4230 break; 4231 case 1: 4232 check_insn(env, ctx, ISA_MIPS32R2); 4233 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain)); 4234 rn = "PageGrain"; 4235 break; 4236 default: 4237 goto die; 4238 } 4239 break; 4240 case 6: 4241 switch (sel) { 4242 case 0: 4243 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired)); 4244 rn = "Wired"; 4245 break; 4246 case 1: 4247 check_insn(env, ctx, ISA_MIPS32R2); 4248 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0)); 4249 rn = "SRSConf0"; 4250 break; 4251 case 2: 4252 check_insn(env, ctx, ISA_MIPS32R2); 4253 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1)); 4254 rn = "SRSConf1"; 4255 break; 4256 case 3: 4257 check_insn(env, ctx, ISA_MIPS32R2); 4258 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2)); 4259 rn = "SRSConf2"; 4260 break; 4261 case 4: 4262 check_insn(env, ctx, ISA_MIPS32R2); 4263 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3)); 4264 rn = "SRSConf3"; 4265 break; 4266 case 5: 4267 check_insn(env, ctx, ISA_MIPS32R2); 4268 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4)); 4269 rn = "SRSConf4"; 4270 break; 4271 default: 4272 goto die; 4273 } 4274 break; 4275 case 7: 4276 switch (sel) { 4277 case 0: 4278 check_insn(env, ctx, ISA_MIPS32R2); 4279 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna)); 4280 rn = "HWREna"; 4281 break; 4282 default: 4283 goto die; 4284 } 4285 break; 4286 case 8: 4287 switch (sel) { 4288 case 0: 4289 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); 4290 rn = "BadVAddr"; 4291 break; 4292 default: 4293 goto die; 4294 } 4295 break; 4296 case 9: 4297 switch (sel) { 4298 case 0: 4299 /* Mark as an IO operation because we read the time. */ 4300 if (use_icount) 4301 gen_io_start(); 4302 gen_helper_mfc0_count(arg); 4303 if (use_icount) { 4304 gen_io_end(); 4305 ctx->bstate = BS_STOP; 4306 } 4307 rn = "Count"; 4308 break; 4309 /* 6,7 are implementation dependent */ 4310 default: 4311 goto die; 4312 } 4313 break; 4314 case 10: 4315 switch (sel) { 4316 case 0: 4317 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi)); 4318 rn = "EntryHi"; 4319 break; 4320 default: 4321 goto die; 4322 } 4323 break; 4324 case 11: 4325 switch (sel) { 4326 case 0: 4327 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare)); 4328 rn = "Compare"; 4329 break; 4330 /* 6,7 are implementation dependent */ 4331 default: 4332 goto die; 4333 } 4334 break; 4335 case 12: 4336 switch (sel) { 4337 case 0: 4338 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status)); 4339 rn = "Status"; 4340 break; 4341 case 1: 4342 check_insn(env, ctx, ISA_MIPS32R2); 4343 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl)); 4344 rn = "IntCtl"; 4345 break; 4346 case 2: 4347 check_insn(env, ctx, ISA_MIPS32R2); 4348 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl)); 4349 rn = "SRSCtl"; 4350 break; 4351 case 3: 4352 check_insn(env, ctx, ISA_MIPS32R2); 4353 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); 4354 rn = "SRSMap"; 4355 break; 4356 default: 4357 goto die; 4358 } 4359 break; 4360 case 13: 4361 switch (sel) { 4362 case 0: 4363 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause)); 4364 rn = "Cause"; 4365 break; 4366 default: 4367 goto die; 4368 } 4369 break; 4370 case 14: 4371 switch (sel) { 4372 case 0: 4373 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC)); 4374 rn = "EPC"; 4375 break; 4376 default: 4377 goto die; 4378 } 4379 break; 4380 case 15: 4381 switch (sel) { 4382 case 0: 4383 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid)); 4384 rn = "PRid"; 4385 break; 4386 case 1: 4387 check_insn(env, ctx, ISA_MIPS32R2); 4388 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase)); 4389 rn = "EBase"; 4390 break; 4391 default: 4392 goto die; 4393 } 4394 break; 4395 case 16: 4396 switch (sel) { 4397 case 0: 4398 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0)); 4399 rn = "Config"; 4400 break; 4401 case 1: 4402 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1)); 4403 rn = "Config1"; 4404 break; 4405 case 2: 4406 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2)); 4407 rn = "Config2"; 4408 break; 4409 case 3: 4410 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3)); 4411 rn = "Config3"; 4412 break; 4413 /* 6,7 are implementation dependent */ 4414 case 6: 4415 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6)); 4416 rn = "Config6"; 4417 break; 4418 case 7: 4419 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7)); 4420 rn = "Config7"; 4421 break; 4422 default: 4423 goto die; 4424 } 4425 break; 4426 case 17: 4427 switch (sel) { 4428 case 0: 4429 gen_helper_dmfc0_lladdr(arg, cpu_env); 4430 rn = "LLAddr"; 4431 break; 4432 default: 4433 goto die; 4434 } 4435 break; 4436 case 18: 4437 switch (sel) { 4438 case 0 ... 7: 4439 gen_helper_1i(dmfc0_watchlo, arg, sel); 4440 rn = "WatchLo"; 4441 break; 4442 default: 4443 goto die; 4444 } 4445 break; 4446 case 19: 4447 switch (sel) { 4448 case 0 ... 7: 4449 gen_helper_1i(mfc0_watchhi, arg, sel); 4450 rn = "WatchHi"; 4451 break; 4452 default: 4453 goto die; 4454 } 4455 break; 4456 case 20: 4457 switch (sel) { 4458 case 0: 4459 check_insn(env, ctx, ISA_MIPS3); 4460 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext)); 4461 rn = "XContext"; 4462 break; 4463 default: 4464 goto die; 4465 } 4466 break; 4467 case 21: 4468 /* Officially reserved, but sel 0 is used for R1x000 framemask */ 4469 switch (sel) { 4470 case 0: 4471 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask)); 4472 rn = "Framemask"; 4473 break; 4474 default: 4475 goto die; 4476 } 4477 break; 4478 case 22: 4479 tcg_gen_movi_tl(arg, 0); /* unimplemented */ 4480 rn = "'Diagnostic"; /* implementation dependent */ 4481 break; 4482 case 23: 4483 switch (sel) { 4484 case 0: 4485 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */ 4486 rn = "Debug"; 4487 break; 4488 case 1: 4489 // gen_helper_dmfc0_tracecontrol(arg); /* PDtrace support */ 4490 rn = "TraceControl"; 4491 // break; 4492 case 2: 4493 // gen_helper_dmfc0_tracecontrol2(arg); /* PDtrace support */ 4494 rn = "TraceControl2"; 4495 // break; 4496 case 3: 4497 // gen_helper_dmfc0_usertracedata(arg); /* PDtrace support */ 4498 rn = "UserTraceData"; 4499 // break; 4500 case 4: 4501 // gen_helper_dmfc0_tracebpc(arg); /* PDtrace support */ 4502 rn = "TraceBPC"; 4503 // break; 4504 default: 4505 goto die; 4506 } 4507 break; 4508 case 24: 4509 switch (sel) { 4510 case 0: 4511 /* EJTAG support */ 4512 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC)); 4513 rn = "DEPC"; 4514 break; 4515 default: 4516 goto die; 4517 } 4518 break; 4519 case 25: 4520 switch (sel) { 4521 case 0: 4522 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0)); 4523 rn = "Performance0"; 4524 break; 4525 case 1: 4526 // gen_helper_dmfc0_performance1(arg); 4527 rn = "Performance1"; 4528 // break; 4529 case 2: 4530 // gen_helper_dmfc0_performance2(arg); 4531 rn = "Performance2"; 4532 // break; 4533 case 3: 4534 // gen_helper_dmfc0_performance3(arg); 4535 rn = "Performance3"; 4536 // break; 4537 case 4: 4538 // gen_helper_dmfc0_performance4(arg); 4539 rn = "Performance4"; 4540 // break; 4541 case 5: 4542 // gen_helper_dmfc0_performance5(arg); 4543 rn = "Performance5"; 4544 // break; 4545 case 6: 4546 // gen_helper_dmfc0_performance6(arg); 4547 rn = "Performance6"; 4548 // break; 4549 case 7: 4550 // gen_helper_dmfc0_performance7(arg); 4551 rn = "Performance7"; 4552 // break; 4553 default: 4554 goto die; 4555 } 4556 break; 4557 case 26: 4558 tcg_gen_movi_tl(arg, 0); /* unimplemented */ 4559 rn = "ECC"; 4560 break; 4561 case 27: 4562 switch (sel) { 4563 /* ignored */ 4564 case 0 ... 3: 4565 tcg_gen_movi_tl(arg, 0); /* unimplemented */ 4566 rn = "CacheErr"; 4567 break; 4568 default: 4569 goto die; 4570 } 4571 break; 4572 case 28: 4573 switch (sel) { 4574 case 0: 4575 case 2: 4576 case 4: 4577 case 6: 4578 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo)); 4579 rn = "TagLo"; 4580 break; 4581 case 1: 4582 case 3: 4583 case 5: 4584 case 7: 4585 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo)); 4586 rn = "DataLo"; 4587 break; 4588 default: 4589 goto die; 4590 } 4591 break; 4592 case 29: 4593 switch (sel) { 4594 case 0: 4595 case 2: 4596 case 4: 4597 case 6: 4598 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi)); 4599 rn = "TagHi"; 4600 break; 4601 case 1: 4602 case 3: 4603 case 5: 4604 case 7: 4605 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi)); 4606 rn = "DataHi"; 4607 break; 4608 default: 4609 goto die; 4610 } 4611 break; 4612 case 30: 4613 switch (sel) { 4614 case 0: 4615 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC)); 4616 rn = "ErrorEPC"; 4617 break; 4618 default: 4619 goto die; 4620 } 4621 break; 4622 case 31: 4623 switch (sel) { 4624 case 0: 4625 /* EJTAG support */ 4626 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); 4627 rn = "DESAVE"; 4628 break; 4629 default: 4630 goto die; 4631 } 4632 break; 4633 default: 4634 goto die; 4635 } 4636 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel); 4637 return; 4638 4639 die: 4640 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel); 4641 generate_exception(ctx, EXCP_RI); 4642 } 4643 4644 static void gen_dmtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel) 4645 { 4646 const char *rn = "invalid"; 4647 4648 if (sel != 0) 4649 check_insn(env, ctx, ISA_MIPS64); 4650 4651 if (use_icount) 4652 gen_io_start(); 4653 4654 switch (reg) { 4655 case 0: 4656 switch (sel) { 4657 case 0: 4658 gen_helper_mtc0_index(cpu_env, arg); 4659 rn = "Index"; 4660 break; 4661 case 1: 4662 check_insn(env, ctx, ASE_MT); 4663 gen_helper_mtc0_mvpcontrol(cpu_env, arg); 4664 rn = "MVPControl"; 4665 break; 4666 case 2: 4667 check_insn(env, ctx, ASE_MT); 4668 /* ignored */ 4669 rn = "MVPConf0"; 4670 break; 4671 case 3: 4672 check_insn(env, ctx, ASE_MT); 4673 /* ignored */ 4674 rn = "MVPConf1"; 4675 break; 4676 default: 4677 goto die; 4678 } 4679 break; 4680 case 1: 4681 switch (sel) { 4682 case 0: 4683 /* ignored */ 4684 rn = "Random"; 4685 break; 4686 case 1: 4687 check_insn(env, ctx, ASE_MT); 4688 gen_helper_mtc0_vpecontrol(cpu_env, arg); 4689 rn = "VPEControl"; 4690 break; 4691 case 2: 4692 check_insn(env, ctx, ASE_MT); 4693 gen_helper_mtc0_vpeconf0(cpu_env, arg); 4694 rn = "VPEConf0"; 4695 break; 4696 case 3: 4697 check_insn(env, ctx, ASE_MT); 4698 gen_helper_mtc0_vpeconf1(cpu_env, arg); 4699 rn = "VPEConf1"; 4700 break; 4701 case 4: 4702 check_insn(env, ctx, ASE_MT); 4703 gen_helper_mtc0_yqmask(cpu_env, arg); 4704 rn = "YQMask"; 4705 break; 4706 case 5: 4707 check_insn(env, ctx, ASE_MT); 4708 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule)); 4709 rn = "VPESchedule"; 4710 break; 4711 case 6: 4712 check_insn(env, ctx, ASE_MT); 4713 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack)); 4714 rn = "VPEScheFBack"; 4715 break; 4716 case 7: 4717 check_insn(env, ctx, ASE_MT); 4718 gen_helper_mtc0_vpeopt(cpu_env, arg); 4719 rn = "VPEOpt"; 4720 break; 4721 default: 4722 goto die; 4723 } 4724 break; 4725 case 2: 4726 switch (sel) { 4727 case 0: 4728 gen_helper_mtc0_entrylo0(cpu_env, arg); 4729 rn = "EntryLo0"; 4730 break; 4731 case 1: 4732 check_insn(env, ctx, ASE_MT); 4733 gen_helper_mtc0_tcstatus(cpu_env, arg); 4734 rn = "TCStatus"; 4735 break; 4736 case 2: 4737 check_insn(env, ctx, ASE_MT); 4738 gen_helper_mtc0_tcbind(cpu_env, arg); 4739 rn = "TCBind"; 4740 break; 4741 case 3: 4742 check_insn(env, ctx, ASE_MT); 4743 gen_helper_mtc0_tcrestart(cpu_env, arg); 4744 rn = "TCRestart"; 4745 break; 4746 case 4: 4747 check_insn(env, ctx, ASE_MT); 4748 gen_helper_mtc0_tchalt(cpu_env, arg); 4749 rn = "TCHalt"; 4750 break; 4751 case 5: 4752 check_insn(env, ctx, ASE_MT); 4753 gen_helper_mtc0_tccontext(cpu_env, arg); 4754 rn = "TCContext"; 4755 break; 4756 case 6: 4757 check_insn(env, ctx, ASE_MT); 4758 gen_helper_mtc0_tcschedule(cpu_env, arg); 4759 rn = "TCSchedule"; 4760 break; 4761 case 7: 4762 check_insn(env, ctx, ASE_MT); 4763 gen_helper_mtc0_tcschefback(cpu_env, arg); 4764 rn = "TCScheFBack"; 4765 break; 4766 default: 4767 goto die; 4768 } 4769 break; 4770 case 3: 4771 switch (sel) { 4772 case 0: 4773 gen_helper_mtc0_entrylo1(cpu_env, arg); 4774 rn = "EntryLo1"; 4775 break; 4776 default: 4777 goto die; 4778 } 4779 break; 4780 case 4: 4781 switch (sel) { 4782 case 0: 4783 gen_helper_mtc0_context(cpu_env, arg); 4784 rn = "Context"; 4785 break; 4786 case 1: 4787 // gen_helper_mtc0_contextconfig(arg); /* SmartMIPS ASE */ 4788 rn = "ContextConfig"; 4789 // break; 4790 default: 4791 goto die; 4792 } 4793 break; 4794 case 5: 4795 switch (sel) { 4796 case 0: 4797 gen_helper_mtc0_pagemask(cpu_env, arg); 4798 rn = "PageMask"; 4799 break; 4800 case 1: 4801 check_insn(env, ctx, ISA_MIPS32R2); 4802 gen_helper_mtc0_pagegrain(cpu_env, arg); 4803 rn = "PageGrain"; 4804 break; 4805 default: 4806 goto die; 4807 } 4808 break; 4809 case 6: 4810 switch (sel) { 4811 case 0: 4812 gen_helper_mtc0_wired(cpu_env, arg); 4813 rn = "Wired"; 4814 break; 4815 case 1: 4816 check_insn(env, ctx, ISA_MIPS32R2); 4817 gen_helper_mtc0_srsconf0(cpu_env, arg); 4818 rn = "SRSConf0"; 4819 break; 4820 case 2: 4821 check_insn(env, ctx, ISA_MIPS32R2); 4822 gen_helper_mtc0_srsconf1(cpu_env, arg); 4823 rn = "SRSConf1"; 4824 break; 4825 case 3: 4826 check_insn(env, ctx, ISA_MIPS32R2); 4827 gen_helper_mtc0_srsconf2(cpu_env, arg); 4828 rn = "SRSConf2"; 4829 break; 4830 case 4: 4831 check_insn(env, ctx, ISA_MIPS32R2); 4832 gen_helper_mtc0_srsconf3(cpu_env, arg); 4833 rn = "SRSConf3"; 4834 break; 4835 case 5: 4836 check_insn(env, ctx, ISA_MIPS32R2); 4837 gen_helper_mtc0_srsconf4(cpu_env, arg); 4838 rn = "SRSConf4"; 4839 break; 4840 default: 4841 goto die; 4842 } 4843 break; 4844 case 7: 4845 switch (sel) { 4846 case 0: 4847 check_insn(env, ctx, ISA_MIPS32R2); 4848 gen_helper_mtc0_hwrena(cpu_env, arg); 4849 rn = "HWREna"; 4850 break; 4851 default: 4852 goto die; 4853 } 4854 break; 4855 case 8: 4856 /* ignored */ 4857 rn = "BadVAddr"; 4858 break; 4859 case 9: 4860 switch (sel) { 4861 case 0: 4862 gen_helper_mtc0_count(cpu_env, arg); 4863 rn = "Count"; 4864 break; 4865 /* 6,7 are implementation dependent */ 4866 default: 4867 goto die; 4868 } 4869 /* Stop translation as we may have switched the execution mode */ 4870 ctx->bstate = BS_STOP; 4871 break; 4872 case 10: 4873 switch (sel) { 4874 case 0: 4875 gen_helper_mtc0_entryhi(cpu_env, arg); 4876 rn = "EntryHi"; 4877 break; 4878 default: 4879 goto die; 4880 } 4881 break; 4882 case 11: 4883 switch (sel) { 4884 case 0: 4885 gen_helper_mtc0_compare(cpu_env, arg); 4886 rn = "Compare"; 4887 break; 4888 /* 6,7 are implementation dependent */ 4889 default: 4890 goto die; 4891 } 4892 /* Stop translation as we may have switched the execution mode */ 4893 ctx->bstate = BS_STOP; 4894 break; 4895 case 12: 4896 switch (sel) { 4897 case 0: 4898 save_cpu_state(ctx, 1); 4899 gen_helper_mtc0_status(cpu_env, arg); 4900 /* BS_STOP isn't good enough here, hflags may have changed. */ 4901 gen_save_pc(ctx->pc + 4); 4902 ctx->bstate = BS_EXCP; 4903 rn = "Status"; 4904 break; 4905 case 1: 4906 check_insn(env, ctx, ISA_MIPS32R2); 4907 gen_helper_mtc0_intctl(cpu_env, arg); 4908 /* Stop translation as we may have switched the execution mode */ 4909 ctx->bstate = BS_STOP; 4910 rn = "IntCtl"; 4911 break; 4912 case 2: 4913 check_insn(env, ctx, ISA_MIPS32R2); 4914 gen_helper_mtc0_srsctl(cpu_env, arg); 4915 /* Stop translation as we may have switched the execution mode */ 4916 ctx->bstate = BS_STOP; 4917 rn = "SRSCtl"; 4918 break; 4919 case 3: 4920 check_insn(env, ctx, ISA_MIPS32R2); 4921 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); 4922 /* Stop translation as we may have switched the execution mode */ 4923 ctx->bstate = BS_STOP; 4924 rn = "SRSMap"; 4925 break; 4926 default: 4927 goto die; 4928 } 4929 break; 4930 case 13: 4931 switch (sel) { 4932 case 0: 4933 save_cpu_state(ctx, 1); 4934 gen_helper_mtc0_cause(cpu_env, arg); 4935 rn = "Cause"; 4936 break; 4937 default: 4938 goto die; 4939 } 4940 break; 4941 case 14: 4942 switch (sel) { 4943 case 0: 4944 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC)); 4945 rn = "EPC"; 4946 break; 4947 default: 4948 goto die; 4949 } 4950 break; 4951 case 15: 4952 switch (sel) { 4953 case 0: 4954 /* ignored */ 4955 rn = "PRid"; 4956 break; 4957 case 1: 4958 check_insn(env, ctx, ISA_MIPS32R2); 4959 gen_helper_mtc0_ebase(cpu_env, arg); 4960 rn = "EBase"; 4961 break; 4962 default: 4963 goto die; 4964 } 4965 break; 4966 case 16: 4967 switch (sel) { 4968 case 0: 4969 gen_helper_mtc0_config0(cpu_env, arg); 4970 rn = "Config"; 4971 /* Stop translation as we may have switched the execution mode */ 4972 ctx->bstate = BS_STOP; 4973 break; 4974 case 1: 4975 /* ignored, read only */ 4976 rn = "Config1"; 4977 break; 4978 case 2: 4979 gen_helper_mtc0_config2(cpu_env, arg); 4980 rn = "Config2"; 4981 /* Stop translation as we may have switched the execution mode */ 4982 ctx->bstate = BS_STOP; 4983 break; 4984 case 3: 4985 /* ignored */ 4986 rn = "Config3"; 4987 break; 4988 /* 6,7 are implementation dependent */ 4989 default: 4990 rn = "Invalid config selector"; 4991 goto die; 4992 } 4993 break; 4994 case 17: 4995 switch (sel) { 4996 case 0: 4997 gen_helper_mtc0_lladdr(cpu_env, arg); 4998 rn = "LLAddr"; 4999 break; 5000 default: 5001 goto die; 5002 } 5003 break; 5004 case 18: 5005 switch (sel) { 5006 case 0 ... 7: 5007 gen_helper_2i(mtc0_watchlo, cpu_env, arg, sel); 5008 rn = "WatchLo"; 5009 break; 5010 default: 5011 goto die; 5012 } 5013 break; 5014 case 19: 5015 switch (sel) { 5016 case 0 ... 7: 5017 gen_helper_2i(mtc0_watchhi, cpu_env, arg, sel); 5018 rn = "WatchHi"; 5019 break; 5020 default: 5021 goto die; 5022 } 5023 break; 5024 case 20: 5025 switch (sel) { 5026 case 0: 5027 check_insn(env, ctx, ISA_MIPS3); 5028 gen_helper_mtc0_xcontext(cpu_env, arg); 5029 rn = "XContext"; 5030 break; 5031 default: 5032 goto die; 5033 } 5034 break; 5035 case 21: 5036 /* Officially reserved, but sel 0 is used for R1x000 framemask */ 5037 switch (sel) { 5038 case 0: 5039 gen_helper_mtc0_framemask(cpu_env, arg); 5040 rn = "Framemask"; 5041 break; 5042 default: 5043 goto die; 5044 } 5045 break; 5046 case 22: 5047 /* ignored */ 5048 rn = "Diagnostic"; /* implementation dependent */ 5049 break; 5050 case 23: 5051 switch (sel) { 5052 case 0: 5053 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */ 5054 /* BS_STOP isn't good enough here, hflags may have changed. */ 5055 gen_save_pc(ctx->pc + 4); 5056 ctx->bstate = BS_EXCP; 5057 rn = "Debug"; 5058 break; 5059 case 1: 5060 // gen_helper_mtc0_tracecontrol(arg); /* PDtrace support */ 5061 /* Stop translation as we may have switched the execution mode */ 5062 ctx->bstate = BS_STOP; 5063 rn = "TraceControl"; 5064 // break; 5065 case 2: 5066 // gen_helper_mtc0_tracecontrol2(arg); /* PDtrace support */ 5067 /* Stop translation as we may have switched the execution mode */ 5068 ctx->bstate = BS_STOP; 5069 rn = "TraceControl2"; 5070 // break; 5071 case 3: 5072 // gen_helper_mtc0_usertracedata(arg); /* PDtrace support */ 5073 /* Stop translation as we may have switched the execution mode */ 5074 ctx->bstate = BS_STOP; 5075 rn = "UserTraceData"; 5076 // break; 5077 case 4: 5078 // gen_helper_mtc0_tracebpc(arg); /* PDtrace support */ 5079 /* Stop translation as we may have switched the execution mode */ 5080 ctx->bstate = BS_STOP; 5081 rn = "TraceBPC"; 5082 // break; 5083 default: 5084 goto die; 5085 } 5086 break; 5087 case 24: 5088 switch (sel) { 5089 case 0: 5090 /* EJTAG support */ 5091 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC)); 5092 rn = "DEPC"; 5093 break; 5094 default: 5095 goto die; 5096 } 5097 break; 5098 case 25: 5099 switch (sel) { 5100 case 0: 5101 gen_helper_mtc0_performance0(cpu_env, arg); 5102 rn = "Performance0"; 5103 break; 5104 case 1: 5105 // gen_helper_mtc0_performance1(cpu_env, arg); 5106 rn = "Performance1"; 5107 // break; 5108 case 2: 5109 // gen_helper_mtc0_performance2(cpu_env, arg); 5110 rn = "Performance2"; 5111 // break; 5112 case 3: 5113 // gen_helper_mtc0_performance3(cpu_env, arg); 5114 rn = "Performance3"; 5115 // break; 5116 case 4: 5117 // gen_helper_mtc0_performance4(cpu_env, arg); 5118 rn = "Performance4"; 5119 // break; 5120 case 5: 5121 // gen_helper_mtc0_performance5(cpu_env, arg); 5122 rn = "Performance5"; 5123 // break; 5124 case 6: 5125 // gen_helper_mtc0_performance6(cpu_env, arg); 5126 rn = "Performance6"; 5127 // break; 5128 case 7: 5129 // gen_helper_mtc0_performance7(cpu_env, arg); 5130 rn = "Performance7"; 5131 // break; 5132 default: 5133 goto die; 5134 } 5135 break; 5136 case 26: 5137 /* ignored */ 5138 rn = "ECC"; 5139 break; 5140 case 27: 5141 switch (sel) { 5142 case 0 ... 3: 5143 /* ignored */ 5144 rn = "CacheErr"; 5145 break; 5146 default: 5147 goto die; 5148 } 5149 break; 5150 case 28: 5151 switch (sel) { 5152 case 0: 5153 case 2: 5154 case 4: 5155 case 6: 5156 gen_helper_mtc0_taglo(cpu_env, arg); 5157 rn = "TagLo"; 5158 break; 5159 case 1: 5160 case 3: 5161 case 5: 5162 case 7: 5163 gen_helper_mtc0_datalo(cpu_env, arg); 5164 rn = "DataLo"; 5165 break; 5166 default: 5167 goto die; 5168 } 5169 break; 5170 case 29: 5171 switch (sel) { 5172 case 0: 5173 case 2: 5174 case 4: 5175 case 6: 5176 gen_helper_mtc0_taghi(cpu_env, arg); 5177 rn = "TagHi"; 5178 break; 5179 case 1: 5180 case 3: 5181 case 5: 5182 case 7: 5183 gen_helper_mtc0_datahi(cpu_env, arg); 5184 rn = "DataHi"; 5185 break; 5186 default: 5187 rn = "invalid sel"; 5188 goto die; 5189 } 5190 break; 5191 case 30: 5192 switch (sel) { 5193 case 0: 5194 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC)); 5195 rn = "ErrorEPC"; 5196 break; 5197 default: 5198 goto die; 5199 } 5200 break; 5201 case 31: 5202 switch (sel) { 5203 case 0: 5204 /* EJTAG support */ 5205 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); 5206 rn = "DESAVE"; 5207 break; 5208 default: 5209 goto die; 5210 } 5211 /* Stop translation as we may have switched the execution mode */ 5212 ctx->bstate = BS_STOP; 5213 break; 5214 default: 5215 goto die; 5216 } 5217 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel); 5218 /* For simplicity assume that all writes can cause interrupts. */ 5219 if (use_icount) { 5220 gen_io_end(); 5221 ctx->bstate = BS_STOP; 5222 } 5223 return; 5224 5225 die: 5226 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel); 5227 generate_exception(ctx, EXCP_RI); 5228 } 5229 #endif /* TARGET_MIPS64 */ 5230 5231 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd, 5232 int u, int sel, int h) 5233 { 5234 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); 5235 TCGv t0 = tcg_temp_local_new(); 5236 5237 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 && 5238 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) != 5239 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) 5240 tcg_gen_movi_tl(t0, -1); 5241 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) > 5242 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) 5243 tcg_gen_movi_tl(t0, -1); 5244 else if (u == 0) { 5245 switch (rt) { 5246 case 2: 5247 switch (sel) { 5248 case 1: 5249 gen_helper_mftc0_tcstatus(t0, cpu_env); 5250 break; 5251 case 2: 5252 gen_helper_mftc0_tcbind(t0, cpu_env); 5253 break; 5254 case 3: 5255 gen_helper_mftc0_tcrestart(t0, cpu_env); 5256 break; 5257 case 4: 5258 gen_helper_mftc0_tchalt(t0, cpu_env); 5259 break; 5260 case 5: 5261 gen_helper_mftc0_tccontext(t0, cpu_env); 5262 break; 5263 case 6: 5264 gen_helper_mftc0_tcschedule(t0, cpu_env); 5265 break; 5266 case 7: 5267 gen_helper_mftc0_tcschefback(t0, cpu_env); 5268 break; 5269 default: 5270 gen_mfc0(env, ctx, t0, rt, sel); 5271 break; 5272 } 5273 break; 5274 case 10: 5275 switch (sel) { 5276 case 0: 5277 gen_helper_mftc0_entryhi(t0, cpu_env); 5278 break; 5279 default: 5280 gen_mfc0(env, ctx, t0, rt, sel); 5281 break; 5282 } 5283 case 12: 5284 switch (sel) { 5285 case 0: 5286 gen_helper_mftc0_status(t0, cpu_env); 5287 break; 5288 default: 5289 gen_mfc0(env, ctx, t0, rt, sel); 5290 break; 5291 } 5292 case 23: 5293 switch (sel) { 5294 case 0: 5295 gen_helper_mftc0_debug(t0, cpu_env); 5296 break; 5297 default: 5298 gen_mfc0(env, ctx, t0, rt, sel); 5299 break; 5300 } 5301 break; 5302 default: 5303 gen_mfc0(env, ctx, t0, rt, sel); 5304 } 5305 } else switch (sel) { 5306 /* GPR registers. */ 5307 case 0: 5308 gen_helper_2i(mftgpr, t0, cpu_env, rt); 5309 break; 5310 /* Auxiliary CPU registers */ 5311 case 1: 5312 switch (rt) { 5313 case 0: 5314 gen_helper_2i(mftlo, t0, cpu_env, 0); 5315 break; 5316 case 1: 5317 gen_helper_2i(mfthi, t0, cpu_env, 0); 5318 break; 5319 case 2: 5320 gen_helper_2i(mftacx, t0, cpu_env, 0); 5321 break; 5322 case 4: 5323 gen_helper_2i(mftlo, t0, cpu_env, 1); 5324 break; 5325 case 5: 5326 gen_helper_2i(mfthi, t0, cpu_env, 1); 5327 break; 5328 case 6: 5329 gen_helper_2i(mftacx, t0, cpu_env, 1); 5330 break; 5331 case 8: 5332 gen_helper_2i(mftlo, t0, cpu_env, 2); 5333 break; 5334 case 9: 5335 gen_helper_2i(mfthi, t0, cpu_env, 2); 5336 break; 5337 case 10: 5338 gen_helper_2i(mftacx, t0, cpu_env, 2); 5339 break; 5340 case 12: 5341 gen_helper_2i(mftlo, t0, cpu_env, 3); 5342 break; 5343 case 13: 5344 gen_helper_2i(mfthi, t0, cpu_env, 3); 5345 break; 5346 case 14: 5347 gen_helper_2i(mftacx, t0, cpu_env, 3); 5348 break; 5349 case 16: 5350 gen_helper_mftdsp(t0, cpu_env); 5351 break; 5352 default: 5353 goto die; 5354 } 5355 break; 5356 /* Floating point (COP1). */ 5357 case 2: 5358 /* XXX: For now we support only a single FPU context. */ 5359 if (h == 0) { 5360 TCGv_i32 fp0 = tcg_temp_new_i32(); 5361 5362 gen_load_fpr32(fp0, rt); 5363 tcg_gen_ext_i32_tl(t0, fp0); 5364 tcg_temp_free_i32(fp0); 5365 } else { 5366 TCGv_i32 fp0 = tcg_temp_new_i32(); 5367 5368 gen_load_fpr32h(fp0, rt); 5369 tcg_gen_ext_i32_tl(t0, fp0); 5370 tcg_temp_free_i32(fp0); 5371 } 5372 break; 5373 case 3: 5374 /* XXX: For now we support only a single FPU context. */ 5375 gen_helper_2i(cfc1, t0, cpu_env, rt); 5376 break; 5377 /* COP2: Not implemented. */ 5378 case 4: 5379 case 5: 5380 /* fall through */ 5381 default: 5382 goto die; 5383 } 5384 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h); 5385 gen_store_gpr(t0, rd); 5386 tcg_temp_free(t0); 5387 return; 5388 5389 die: 5390 tcg_temp_free(t0); 5391 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h); 5392 generate_exception(ctx, EXCP_RI); 5393 } 5394 5395 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt, 5396 int u, int sel, int h) 5397 { 5398 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); 5399 TCGv t0 = tcg_temp_local_new(); 5400 5401 gen_load_gpr(t0, rt); 5402 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 && 5403 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) != 5404 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) 5405 /* NOP */ ; 5406 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) > 5407 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) 5408 /* NOP */ ; 5409 else if (u == 0) { 5410 switch (rd) { 5411 case 2: 5412 switch (sel) { 5413 case 1: 5414 gen_helper_mttc0_tcstatus(cpu_env, t0); 5415 break; 5416 case 2: 5417 gen_helper_mttc0_tcbind(cpu_env, t0); 5418 break; 5419 case 3: 5420 gen_helper_mttc0_tcrestart(cpu_env, t0); 5421 break; 5422 case 4: 5423 gen_helper_mttc0_tchalt(cpu_env, t0); 5424 break; 5425 case 5: 5426 gen_helper_mttc0_tccontext(cpu_env, t0); 5427 break; 5428 case 6: 5429 gen_helper_mttc0_tcschedule(cpu_env, t0); 5430 break; 5431 case 7: 5432 gen_helper_mttc0_tcschefback(cpu_env, t0); 5433 break; 5434 default: 5435 gen_mtc0(env, ctx, t0, rd, sel); 5436 break; 5437 } 5438 break; 5439 case 10: 5440 switch (sel) { 5441 case 0: 5442 gen_helper_mttc0_entryhi(cpu_env, t0); 5443 break; 5444 default: 5445 gen_mtc0(env, ctx, t0, rd, sel); 5446 break; 5447 } 5448 case 12: 5449 switch (sel) { 5450 case 0: 5451 gen_helper_mttc0_status(cpu_env, t0); 5452 break; 5453 default: 5454 gen_mtc0(env, ctx, t0, rd, sel); 5455 break; 5456 } 5457 case 23: 5458 switch (sel) { 5459 case 0: 5460 gen_helper_mttc0_debug(cpu_env, t0); 5461 break; 5462 default: 5463 gen_mtc0(env, ctx, t0, rd, sel); 5464 break; 5465 } 5466 break; 5467 default: 5468 gen_mtc0(env, ctx, t0, rd, sel); 5469 } 5470 } else switch (sel) { 5471 /* GPR registers. */ 5472 case 0: 5473 gen_helper_2i(mttgpr, cpu_env, t0, rd); 5474 break; 5475 /* Auxiliary CPU registers */ 5476 case 1: 5477 switch (rd) { 5478 case 0: 5479 gen_helper_2i(mttlo, cpu_env, t0, 0); 5480 break; 5481 case 1: 5482 gen_helper_2i(mtthi, cpu_env, t0, 0); 5483 break; 5484 case 2: 5485 gen_helper_2i(mttacx, cpu_env, t0, 0); 5486 break; 5487 case 4: 5488 gen_helper_2i(mttlo, cpu_env, t0, 1); 5489 break; 5490 case 5: 5491 gen_helper_2i(mtthi, cpu_env, t0, 1); 5492 break; 5493 case 6: 5494 gen_helper_2i(mttacx, cpu_env, t0, 1); 5495 break; 5496 case 8: 5497 gen_helper_2i(mttlo, cpu_env, t0, 2); 5498 break; 5499 case 9: 5500 gen_helper_2i(mtthi, cpu_env, t0, 2); 5501 break; 5502 case 10: 5503 gen_helper_2i(mttacx, cpu_env, t0, 2); 5504 break; 5505 case 12: 5506 gen_helper_2i(mttlo, cpu_env, t0, 3); 5507 break; 5508 case 13: 5509 gen_helper_2i(mtthi, cpu_env, t0, 3); 5510 break; 5511 case 14: 5512 gen_helper_2i(mttacx, cpu_env, t0, 3); 5513 break; 5514 case 16: 5515 gen_helper_mttdsp(cpu_env, t0); 5516 break; 5517 default: 5518 goto die; 5519 } 5520 break; 5521 /* Floating point (COP1). */ 5522 case 2: 5523 /* XXX: For now we support only a single FPU context. */ 5524 if (h == 0) { 5525 TCGv_i32 fp0 = tcg_temp_new_i32(); 5526 5527 tcg_gen_trunc_tl_i32(fp0, t0); 5528 gen_store_fpr32(fp0, rd); 5529 tcg_temp_free_i32(fp0); 5530 } else { 5531 TCGv_i32 fp0 = tcg_temp_new_i32(); 5532 5533 tcg_gen_trunc_tl_i32(fp0, t0); 5534 gen_store_fpr32h(fp0, rd); 5535 tcg_temp_free_i32(fp0); 5536 } 5537 break; 5538 case 3: 5539 /* XXX: For now we support only a single FPU context. */ 5540 gen_helper_2i(ctc1, cpu_env, t0, rd); 5541 break; 5542 /* COP2: Not implemented. */ 5543 case 4: 5544 case 5: 5545 /* fall through */ 5546 default: 5547 goto die; 5548 } 5549 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h); 5550 tcg_temp_free(t0); 5551 return; 5552 5553 die: 5554 tcg_temp_free(t0); 5555 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h); 5556 generate_exception(ctx, EXCP_RI); 5557 } 5558 5559 static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd) 5560 { 5561 const char* __attribute__((unused)) opn = "ldst"; 5562 5563 switch (opc) { 5564 case OPC_MFC0: 5565 if (rt == 0) { 5566 /* Treat as NOP. */ 5567 return; 5568 } 5569 gen_mfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7); 5570 opn = "mfc0"; 5571 break; 5572 case OPC_MTC0: 5573 { 5574 TCGv t0 = tcg_temp_new(); 5575 5576 gen_load_gpr(t0, rt); 5577 gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7); 5578 tcg_temp_free(t0); 5579 } 5580 opn = "mtc0"; 5581 break; 5582 #if defined(TARGET_MIPS64) 5583 case OPC_DMFC0: 5584 check_insn(env, ctx, ISA_MIPS3); 5585 if (rt == 0) { 5586 /* Treat as NOP. */ 5587 return; 5588 } 5589 gen_dmfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7); 5590 opn = "dmfc0"; 5591 break; 5592 case OPC_DMTC0: 5593 check_insn(env, ctx, ISA_MIPS3); 5594 { 5595 TCGv t0 = tcg_temp_new(); 5596 5597 gen_load_gpr(t0, rt); 5598 gen_dmtc0(env, ctx, t0, rd, ctx->opcode & 0x7); 5599 tcg_temp_free(t0); 5600 } 5601 opn = "dmtc0"; 5602 break; 5603 #endif 5604 case OPC_MFTR: 5605 check_insn(env, ctx, ASE_MT); 5606 if (rd == 0) { 5607 /* Treat as NOP. */ 5608 return; 5609 } 5610 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1, 5611 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1); 5612 opn = "mftr"; 5613 break; 5614 case OPC_MTTR: 5615 check_insn(env, ctx, ASE_MT); 5616 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1, 5617 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1); 5618 opn = "mttr"; 5619 break; 5620 case OPC_TLBWI: 5621 opn = "tlbwi"; 5622 if (!env->tlb->helper_tlbwi) 5623 goto die; 5624 gen_helper_tlbwi(cpu_env); 5625 break; 5626 case OPC_TLBWR: 5627 opn = "tlbwr"; 5628 if (!env->tlb->helper_tlbwr) 5629 goto die; 5630 gen_helper_tlbwr(cpu_env); 5631 break; 5632 case OPC_TLBP: 5633 opn = "tlbp"; 5634 if (!env->tlb->helper_tlbp) 5635 goto die; 5636 gen_helper_tlbp(cpu_env); 5637 break; 5638 case OPC_TLBR: 5639 opn = "tlbr"; 5640 if (!env->tlb->helper_tlbr) 5641 goto die; 5642 gen_helper_tlbr(cpu_env); 5643 break; 5644 case OPC_ERET: 5645 opn = "eret"; 5646 check_insn(env, ctx, ISA_MIPS2); 5647 gen_helper_eret(cpu_env); 5648 ctx->bstate = BS_EXCP; 5649 break; 5650 case OPC_DERET: 5651 opn = "deret"; 5652 check_insn(env, ctx, ISA_MIPS32); 5653 if (!(ctx->hflags & MIPS_HFLAG_DM)) { 5654 MIPS_INVAL(opn); 5655 generate_exception(ctx, EXCP_RI); 5656 } else { 5657 gen_helper_deret(cpu_env); 5658 ctx->bstate = BS_EXCP; 5659 } 5660 break; 5661 case OPC_WAIT: 5662 opn = "wait"; 5663 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32); 5664 /* If we get an exception, we want to restart at next instruction */ 5665 ctx->pc += 4; 5666 save_cpu_state(ctx, 1); 5667 ctx->pc -= 4; 5668 gen_helper_wait(cpu_env); 5669 ctx->bstate = BS_EXCP; 5670 break; 5671 default: 5672 die: 5673 MIPS_INVAL(opn); 5674 generate_exception(ctx, EXCP_RI); 5675 return; 5676 } 5677 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd); 5678 } 5679 #endif /* !CONFIG_USER_ONLY */ 5680 5681 /* CP1 Branches (before delay slot) */ 5682 static void gen_compute_branch1 (CPUMIPSState *env, DisasContext *ctx, uint32_t op, 5683 int32_t cc, int32_t offset) 5684 { 5685 target_ulong btarget; 5686 const char* __attribute__((unused)) opn = "cp1 cond branch"; 5687 TCGv_i32 t0 = tcg_temp_new_i32(); 5688 5689 if (cc != 0) 5690 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32); 5691 5692 btarget = ctx->pc + 4 + offset; 5693 5694 switch (op) { 5695 case OPC_BC1F: 5696 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 5697 tcg_gen_not_i32(t0, t0); 5698 tcg_gen_andi_i32(t0, t0, 1); 5699 tcg_gen_extu_i32_tl(bcond, t0); 5700 opn = "bc1f"; 5701 goto not_likely; 5702 case OPC_BC1FL: 5703 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 5704 tcg_gen_not_i32(t0, t0); 5705 tcg_gen_andi_i32(t0, t0, 1); 5706 tcg_gen_extu_i32_tl(bcond, t0); 5707 opn = "bc1fl"; 5708 goto likely; 5709 case OPC_BC1T: 5710 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 5711 tcg_gen_andi_i32(t0, t0, 1); 5712 tcg_gen_extu_i32_tl(bcond, t0); 5713 opn = "bc1t"; 5714 goto not_likely; 5715 case OPC_BC1TL: 5716 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 5717 tcg_gen_andi_i32(t0, t0, 1); 5718 tcg_gen_extu_i32_tl(bcond, t0); 5719 opn = "bc1tl"; 5720 likely: 5721 ctx->hflags |= MIPS_HFLAG_BL; 5722 break; 5723 case OPC_BC1FANY2: 5724 { 5725 TCGv_i32 t1 = tcg_temp_new_i32(); 5726 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 5727 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1)); 5728 tcg_gen_or_i32(t0, t0, t1); 5729 tcg_temp_free_i32(t1); 5730 tcg_gen_not_i32(t0, t0); 5731 tcg_gen_andi_i32(t0, t0, 1); 5732 tcg_gen_extu_i32_tl(bcond, t0); 5733 } 5734 opn = "bc1any2f"; 5735 goto not_likely; 5736 case OPC_BC1TANY2: 5737 { 5738 TCGv_i32 t1 = tcg_temp_new_i32(); 5739 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 5740 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1)); 5741 tcg_gen_or_i32(t0, t0, t1); 5742 tcg_temp_free_i32(t1); 5743 tcg_gen_andi_i32(t0, t0, 1); 5744 tcg_gen_extu_i32_tl(bcond, t0); 5745 } 5746 opn = "bc1any2t"; 5747 goto not_likely; 5748 case OPC_BC1FANY4: 5749 { 5750 TCGv_i32 t1 = tcg_temp_new_i32(); 5751 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 5752 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1)); 5753 tcg_gen_or_i32(t0, t0, t1); 5754 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2)); 5755 tcg_gen_or_i32(t0, t0, t1); 5756 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3)); 5757 tcg_gen_or_i32(t0, t0, t1); 5758 tcg_temp_free_i32(t1); 5759 tcg_gen_not_i32(t0, t0); 5760 tcg_gen_andi_i32(t0, t0, 1); 5761 tcg_gen_extu_i32_tl(bcond, t0); 5762 } 5763 opn = "bc1any4f"; 5764 goto not_likely; 5765 case OPC_BC1TANY4: 5766 { 5767 TCGv_i32 t1 = tcg_temp_new_i32(); 5768 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 5769 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1)); 5770 tcg_gen_or_i32(t0, t0, t1); 5771 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2)); 5772 tcg_gen_or_i32(t0, t0, t1); 5773 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3)); 5774 tcg_gen_or_i32(t0, t0, t1); 5775 tcg_temp_free_i32(t1); 5776 tcg_gen_andi_i32(t0, t0, 1); 5777 tcg_gen_extu_i32_tl(bcond, t0); 5778 } 5779 opn = "bc1any4t"; 5780 not_likely: 5781 ctx->hflags |= MIPS_HFLAG_BC; 5782 break; 5783 default: 5784 MIPS_INVAL(opn); 5785 generate_exception (ctx, EXCP_RI); 5786 goto out; 5787 } 5788 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn, 5789 ctx->hflags, btarget); 5790 ctx->btarget = btarget; 5791 5792 out: 5793 tcg_temp_free_i32(t0); 5794 } 5795 5796 /* Coprocessor 1 (FPU) */ 5797 5798 #define FOP(func, fmt) (((fmt) << 21) | (func)) 5799 5800 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs) 5801 { 5802 const char* __attribute__((unused)) opn = "cp1 move"; 5803 TCGv t0 = tcg_temp_new(); 5804 5805 switch (opc) { 5806 case OPC_MFC1: 5807 { 5808 TCGv_i32 fp0 = tcg_temp_new_i32(); 5809 5810 gen_load_fpr32(fp0, fs); 5811 tcg_gen_ext_i32_tl(t0, fp0); 5812 tcg_temp_free_i32(fp0); 5813 } 5814 gen_store_gpr(t0, rt); 5815 opn = "mfc1"; 5816 break; 5817 case OPC_MTC1: 5818 gen_load_gpr(t0, rt); 5819 { 5820 TCGv_i32 fp0 = tcg_temp_new_i32(); 5821 5822 tcg_gen_trunc_tl_i32(fp0, t0); 5823 gen_store_fpr32(fp0, fs); 5824 tcg_temp_free_i32(fp0); 5825 } 5826 opn = "mtc1"; 5827 break; 5828 case OPC_CFC1: 5829 gen_helper_2i(cfc1, t0, cpu_env, fs); 5830 gen_store_gpr(t0, rt); 5831 opn = "cfc1"; 5832 break; 5833 case OPC_CTC1: 5834 gen_load_gpr(t0, rt); 5835 gen_helper_2i(ctc1, cpu_env, t0, fs); 5836 opn = "ctc1"; 5837 break; 5838 #if defined(TARGET_MIPS64) 5839 case OPC_DMFC1: 5840 gen_load_fpr64(ctx, t0, fs); 5841 gen_store_gpr(t0, rt); 5842 opn = "dmfc1"; 5843 break; 5844 case OPC_DMTC1: 5845 gen_load_gpr(t0, rt); 5846 gen_store_fpr64(ctx, t0, fs); 5847 opn = "dmtc1"; 5848 break; 5849 #endif 5850 case OPC_MFHC1: 5851 { 5852 TCGv_i32 fp0 = tcg_temp_new_i32(); 5853 5854 gen_load_fpr32h(fp0, fs); 5855 tcg_gen_ext_i32_tl(t0, fp0); 5856 tcg_temp_free_i32(fp0); 5857 } 5858 gen_store_gpr(t0, rt); 5859 opn = "mfhc1"; 5860 break; 5861 case OPC_MTHC1: 5862 gen_load_gpr(t0, rt); 5863 { 5864 TCGv_i32 fp0 = tcg_temp_new_i32(); 5865 5866 tcg_gen_trunc_tl_i32(fp0, t0); 5867 gen_store_fpr32h(fp0, fs); 5868 tcg_temp_free_i32(fp0); 5869 } 5870 opn = "mthc1"; 5871 break; 5872 default: 5873 MIPS_INVAL(opn); 5874 generate_exception (ctx, EXCP_RI); 5875 goto out; 5876 } 5877 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]); 5878 5879 out: 5880 tcg_temp_free(t0); 5881 } 5882 5883 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf) 5884 { 5885 int l1; 5886 TCGCond cond; 5887 TCGv_i32 t0; 5888 5889 if (rd == 0) { 5890 /* Treat as NOP. */ 5891 return; 5892 } 5893 5894 if (tf) 5895 cond = TCG_COND_EQ; 5896 else 5897 cond = TCG_COND_NE; 5898 5899 l1 = gen_new_label(); 5900 t0 = tcg_temp_new_i32(); 5901 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc)); 5902 tcg_gen_brcondi_i32(cond, t0, 0, l1); 5903 tcg_temp_free_i32(t0); 5904 if (rs == 0) { 5905 tcg_gen_movi_tl(cpu_gpr[rd], 0); 5906 } else { 5907 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 5908 } 5909 gen_set_label(l1); 5910 } 5911 5912 static inline void gen_movcf_s (int fs, int fd, int cc, int tf) 5913 { 5914 int cond; 5915 TCGv_i32 t0 = tcg_temp_new_i32(); 5916 int l1 = gen_new_label(); 5917 5918 if (tf) 5919 cond = TCG_COND_EQ; 5920 else 5921 cond = TCG_COND_NE; 5922 5923 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc)); 5924 tcg_gen_brcondi_i32(cond, t0, 0, l1); 5925 gen_load_fpr32(t0, fs); 5926 gen_store_fpr32(t0, fd); 5927 gen_set_label(l1); 5928 tcg_temp_free_i32(t0); 5929 } 5930 5931 static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf) 5932 { 5933 int cond; 5934 TCGv_i32 t0 = tcg_temp_new_i32(); 5935 TCGv_i64 fp0; 5936 int l1 = gen_new_label(); 5937 5938 if (tf) 5939 cond = TCG_COND_EQ; 5940 else 5941 cond = TCG_COND_NE; 5942 5943 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc)); 5944 tcg_gen_brcondi_i32(cond, t0, 0, l1); 5945 tcg_temp_free_i32(t0); 5946 fp0 = tcg_temp_new_i64(); 5947 gen_load_fpr64(ctx, fp0, fs); 5948 gen_store_fpr64(ctx, fp0, fd); 5949 tcg_temp_free_i64(fp0); 5950 gen_set_label(l1); 5951 } 5952 5953 static inline void gen_movcf_ps (int fs, int fd, int cc, int tf) 5954 { 5955 int cond; 5956 TCGv_i32 t0 = tcg_temp_new_i32(); 5957 int l1 = gen_new_label(); 5958 int l2 = gen_new_label(); 5959 5960 if (tf) 5961 cond = TCG_COND_EQ; 5962 else 5963 cond = TCG_COND_NE; 5964 5965 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc)); 5966 tcg_gen_brcondi_i32(cond, t0, 0, l1); 5967 gen_load_fpr32(t0, fs); 5968 gen_store_fpr32(t0, fd); 5969 gen_set_label(l1); 5970 5971 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1)); 5972 tcg_gen_brcondi_i32(cond, t0, 0, l2); 5973 gen_load_fpr32h(t0, fs); 5974 gen_store_fpr32h(t0, fd); 5975 tcg_temp_free_i32(t0); 5976 gen_set_label(l2); 5977 } 5978 5979 5980 static void gen_farith (DisasContext *ctx, uint32_t op1, 5981 int ft, int fs, int fd, int cc) 5982 { 5983 const char* __attribute__((unused)) opn = "farith"; 5984 const char *condnames[] = { 5985 "c.f", 5986 "c.un", 5987 "c.eq", 5988 "c.ueq", 5989 "c.olt", 5990 "c.ult", 5991 "c.ole", 5992 "c.ule", 5993 "c.sf", 5994 "c.ngle", 5995 "c.seq", 5996 "c.ngl", 5997 "c.lt", 5998 "c.nge", 5999 "c.le", 6000 "c.ngt", 6001 }; 6002 const char *condnames_abs[] = { 6003 "cabs.f", 6004 "cabs.un", 6005 "cabs.eq", 6006 "cabs.ueq", 6007 "cabs.olt", 6008 "cabs.ult", 6009 "cabs.ole", 6010 "cabs.ule", 6011 "cabs.sf", 6012 "cabs.ngle", 6013 "cabs.seq", 6014 "cabs.ngl", 6015 "cabs.lt", 6016 "cabs.nge", 6017 "cabs.le", 6018 "cabs.ngt", 6019 }; 6020 enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP; 6021 uint32_t func = ctx->opcode & 0x3f; 6022 6023 switch (ctx->opcode & FOP(0x3f, 0x1f)) { 6024 case FOP(0, 16): 6025 { 6026 TCGv_i32 fp0 = tcg_temp_new_i32(); 6027 TCGv_i32 fp1 = tcg_temp_new_i32(); 6028 6029 gen_load_fpr32(fp0, fs); 6030 gen_load_fpr32(fp1, ft); 6031 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1); 6032 tcg_temp_free_i32(fp1); 6033 gen_store_fpr32(fp0, fd); 6034 tcg_temp_free_i32(fp0); 6035 } 6036 opn = "add.s"; 6037 optype = BINOP; 6038 break; 6039 case FOP(1, 16): 6040 { 6041 TCGv_i32 fp0 = tcg_temp_new_i32(); 6042 TCGv_i32 fp1 = tcg_temp_new_i32(); 6043 6044 gen_load_fpr32(fp0, fs); 6045 gen_load_fpr32(fp1, ft); 6046 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1); 6047 tcg_temp_free_i32(fp1); 6048 gen_store_fpr32(fp0, fd); 6049 tcg_temp_free_i32(fp0); 6050 } 6051 opn = "sub.s"; 6052 optype = BINOP; 6053 break; 6054 case FOP(2, 16): 6055 { 6056 TCGv_i32 fp0 = tcg_temp_new_i32(); 6057 TCGv_i32 fp1 = tcg_temp_new_i32(); 6058 6059 gen_load_fpr32(fp0, fs); 6060 gen_load_fpr32(fp1, ft); 6061 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1); 6062 tcg_temp_free_i32(fp1); 6063 gen_store_fpr32(fp0, fd); 6064 tcg_temp_free_i32(fp0); 6065 } 6066 opn = "mul.s"; 6067 optype = BINOP; 6068 break; 6069 case FOP(3, 16): 6070 { 6071 TCGv_i32 fp0 = tcg_temp_new_i32(); 6072 TCGv_i32 fp1 = tcg_temp_new_i32(); 6073 6074 gen_load_fpr32(fp0, fs); 6075 gen_load_fpr32(fp1, ft); 6076 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1); 6077 tcg_temp_free_i32(fp1); 6078 gen_store_fpr32(fp0, fd); 6079 tcg_temp_free_i32(fp0); 6080 } 6081 opn = "div.s"; 6082 optype = BINOP; 6083 break; 6084 case FOP(4, 16): 6085 { 6086 TCGv_i32 fp0 = tcg_temp_new_i32(); 6087 6088 gen_load_fpr32(fp0, fs); 6089 gen_helper_float_sqrt_s(fp0, cpu_env, fp0); 6090 gen_store_fpr32(fp0, fd); 6091 tcg_temp_free_i32(fp0); 6092 } 6093 opn = "sqrt.s"; 6094 break; 6095 case FOP(5, 16): 6096 { 6097 TCGv_i32 fp0 = tcg_temp_new_i32(); 6098 6099 gen_load_fpr32(fp0, fs); 6100 gen_helper_float_abs_s(fp0, fp0); 6101 gen_store_fpr32(fp0, fd); 6102 tcg_temp_free_i32(fp0); 6103 } 6104 opn = "abs.s"; 6105 break; 6106 case FOP(6, 16): 6107 { 6108 TCGv_i32 fp0 = tcg_temp_new_i32(); 6109 6110 gen_load_fpr32(fp0, fs); 6111 gen_store_fpr32(fp0, fd); 6112 tcg_temp_free_i32(fp0); 6113 } 6114 opn = "mov.s"; 6115 break; 6116 case FOP(7, 16): 6117 { 6118 TCGv_i32 fp0 = tcg_temp_new_i32(); 6119 6120 gen_load_fpr32(fp0, fs); 6121 gen_helper_float_chs_s(fp0, fp0); 6122 gen_store_fpr32(fp0, fd); 6123 tcg_temp_free_i32(fp0); 6124 } 6125 opn = "neg.s"; 6126 break; 6127 case FOP(8, 16): 6128 check_cp1_64bitmode(ctx); 6129 { 6130 TCGv_i32 fp32 = tcg_temp_new_i32(); 6131 TCGv_i64 fp64 = tcg_temp_new_i64(); 6132 6133 gen_load_fpr32(fp32, fs); 6134 gen_helper_float_roundl_s(fp64, cpu_env, fp32); 6135 tcg_temp_free_i32(fp32); 6136 gen_store_fpr64(ctx, fp64, fd); 6137 tcg_temp_free_i64(fp64); 6138 } 6139 opn = "round.l.s"; 6140 break; 6141 case FOP(9, 16): 6142 check_cp1_64bitmode(ctx); 6143 { 6144 TCGv_i32 fp32 = tcg_temp_new_i32(); 6145 TCGv_i64 fp64 = tcg_temp_new_i64(); 6146 6147 gen_load_fpr32(fp32, fs); 6148 gen_helper_float_truncl_s(fp64, cpu_env, fp32); 6149 tcg_temp_free_i32(fp32); 6150 gen_store_fpr64(ctx, fp64, fd); 6151 tcg_temp_free_i64(fp64); 6152 } 6153 opn = "trunc.l.s"; 6154 break; 6155 case FOP(10, 16): 6156 check_cp1_64bitmode(ctx); 6157 { 6158 TCGv_i32 fp32 = tcg_temp_new_i32(); 6159 TCGv_i64 fp64 = tcg_temp_new_i64(); 6160 6161 gen_load_fpr32(fp32, fs); 6162 gen_helper_float_ceill_s(fp64, cpu_env, fp32); 6163 tcg_temp_free_i32(fp32); 6164 gen_store_fpr64(ctx, fp64, fd); 6165 tcg_temp_free_i64(fp64); 6166 } 6167 opn = "ceil.l.s"; 6168 break; 6169 case FOP(11, 16): 6170 check_cp1_64bitmode(ctx); 6171 { 6172 TCGv_i32 fp32 = tcg_temp_new_i32(); 6173 TCGv_i64 fp64 = tcg_temp_new_i64(); 6174 6175 gen_load_fpr32(fp32, fs); 6176 gen_helper_float_floorl_s(fp64, cpu_env, fp32); 6177 tcg_temp_free_i32(fp32); 6178 gen_store_fpr64(ctx, fp64, fd); 6179 tcg_temp_free_i64(fp64); 6180 } 6181 opn = "floor.l.s"; 6182 break; 6183 case FOP(12, 16): 6184 { 6185 TCGv_i32 fp0 = tcg_temp_new_i32(); 6186 6187 gen_load_fpr32(fp0, fs); 6188 gen_helper_float_roundw_s(fp0, cpu_env, fp0); 6189 gen_store_fpr32(fp0, fd); 6190 tcg_temp_free_i32(fp0); 6191 } 6192 opn = "round.w.s"; 6193 break; 6194 case FOP(13, 16): 6195 { 6196 TCGv_i32 fp0 = tcg_temp_new_i32(); 6197 6198 gen_load_fpr32(fp0, fs); 6199 gen_helper_float_truncw_s(fp0, cpu_env, fp0); 6200 gen_store_fpr32(fp0, fd); 6201 tcg_temp_free_i32(fp0); 6202 } 6203 opn = "trunc.w.s"; 6204 break; 6205 case FOP(14, 16): 6206 { 6207 TCGv_i32 fp0 = tcg_temp_new_i32(); 6208 6209 gen_load_fpr32(fp0, fs); 6210 gen_helper_float_ceilw_s(fp0, cpu_env, fp0); 6211 gen_store_fpr32(fp0, fd); 6212 tcg_temp_free_i32(fp0); 6213 } 6214 opn = "ceil.w.s"; 6215 break; 6216 case FOP(15, 16): 6217 { 6218 TCGv_i32 fp0 = tcg_temp_new_i32(); 6219 6220 gen_load_fpr32(fp0, fs); 6221 gen_helper_float_floorw_s(fp0, cpu_env, fp0); 6222 gen_store_fpr32(fp0, fd); 6223 tcg_temp_free_i32(fp0); 6224 } 6225 opn = "floor.w.s"; 6226 break; 6227 case FOP(17, 16): 6228 gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1); 6229 opn = "movcf.s"; 6230 break; 6231 case FOP(18, 16): 6232 { 6233 int l1 = gen_new_label(); 6234 TCGv_i32 fp0; 6235 6236 if (ft != 0) { 6237 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1); 6238 } 6239 fp0 = tcg_temp_new_i32(); 6240 gen_load_fpr32(fp0, fs); 6241 gen_store_fpr32(fp0, fd); 6242 tcg_temp_free_i32(fp0); 6243 gen_set_label(l1); 6244 } 6245 opn = "movz.s"; 6246 break; 6247 case FOP(19, 16): 6248 { 6249 int l1 = gen_new_label(); 6250 TCGv_i32 fp0; 6251 6252 if (ft != 0) { 6253 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1); 6254 fp0 = tcg_temp_new_i32(); 6255 gen_load_fpr32(fp0, fs); 6256 gen_store_fpr32(fp0, fd); 6257 tcg_temp_free_i32(fp0); 6258 gen_set_label(l1); 6259 } 6260 } 6261 opn = "movn.s"; 6262 break; 6263 case FOP(21, 16): 6264 check_cop1x(ctx); 6265 { 6266 TCGv_i32 fp0 = tcg_temp_new_i32(); 6267 6268 gen_load_fpr32(fp0, fs); 6269 gen_helper_float_recip_s(fp0, cpu_env, fp0); 6270 gen_store_fpr32(fp0, fd); 6271 tcg_temp_free_i32(fp0); 6272 } 6273 opn = "recip.s"; 6274 break; 6275 case FOP(22, 16): 6276 check_cop1x(ctx); 6277 { 6278 TCGv_i32 fp0 = tcg_temp_new_i32(); 6279 6280 gen_load_fpr32(fp0, fs); 6281 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0); 6282 gen_store_fpr32(fp0, fd); 6283 tcg_temp_free_i32(fp0); 6284 } 6285 opn = "rsqrt.s"; 6286 break; 6287 case FOP(28, 16): 6288 check_cp1_64bitmode(ctx); 6289 { 6290 TCGv_i32 fp0 = tcg_temp_new_i32(); 6291 TCGv_i32 fp1 = tcg_temp_new_i32(); 6292 6293 gen_load_fpr32(fp0, fs); 6294 gen_load_fpr32(fp1, fd); 6295 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1); 6296 tcg_temp_free_i32(fp1); 6297 gen_store_fpr32(fp0, fd); 6298 tcg_temp_free_i32(fp0); 6299 } 6300 opn = "recip2.s"; 6301 break; 6302 case FOP(29, 16): 6303 check_cp1_64bitmode(ctx); 6304 { 6305 TCGv_i32 fp0 = tcg_temp_new_i32(); 6306 6307 gen_load_fpr32(fp0, fs); 6308 gen_helper_float_recip1_s(fp0, cpu_env, fp0); 6309 gen_store_fpr32(fp0, fd); 6310 tcg_temp_free_i32(fp0); 6311 } 6312 opn = "recip1.s"; 6313 break; 6314 case FOP(30, 16): 6315 check_cp1_64bitmode(ctx); 6316 { 6317 TCGv_i32 fp0 = tcg_temp_new_i32(); 6318 6319 gen_load_fpr32(fp0, fs); 6320 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0); 6321 gen_store_fpr32(fp0, fd); 6322 tcg_temp_free_i32(fp0); 6323 } 6324 opn = "rsqrt1.s"; 6325 break; 6326 case FOP(31, 16): 6327 check_cp1_64bitmode(ctx); 6328 { 6329 TCGv_i32 fp0 = tcg_temp_new_i32(); 6330 TCGv_i32 fp1 = tcg_temp_new_i32(); 6331 6332 gen_load_fpr32(fp0, fs); 6333 gen_load_fpr32(fp1, ft); 6334 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1); 6335 tcg_temp_free_i32(fp1); 6336 gen_store_fpr32(fp0, fd); 6337 tcg_temp_free_i32(fp0); 6338 } 6339 opn = "rsqrt2.s"; 6340 break; 6341 case FOP(33, 16): 6342 check_cp1_registers(ctx, fd); 6343 { 6344 TCGv_i32 fp32 = tcg_temp_new_i32(); 6345 TCGv_i64 fp64 = tcg_temp_new_i64(); 6346 6347 gen_load_fpr32(fp32, fs); 6348 gen_helper_float_cvtd_s(fp64, cpu_env, fp32); 6349 tcg_temp_free_i32(fp32); 6350 gen_store_fpr64(ctx, fp64, fd); 6351 tcg_temp_free_i64(fp64); 6352 } 6353 opn = "cvt.d.s"; 6354 break; 6355 case FOP(36, 16): 6356 { 6357 TCGv_i32 fp0 = tcg_temp_new_i32(); 6358 6359 gen_load_fpr32(fp0, fs); 6360 gen_helper_float_cvtw_s(fp0, cpu_env, fp0); 6361 gen_store_fpr32(fp0, fd); 6362 tcg_temp_free_i32(fp0); 6363 } 6364 opn = "cvt.w.s"; 6365 break; 6366 case FOP(37, 16): 6367 check_cp1_64bitmode(ctx); 6368 { 6369 TCGv_i32 fp32 = tcg_temp_new_i32(); 6370 TCGv_i64 fp64 = tcg_temp_new_i64(); 6371 6372 gen_load_fpr32(fp32, fs); 6373 gen_helper_float_cvtl_s(fp64, cpu_env, fp32); 6374 tcg_temp_free_i32(fp32); 6375 gen_store_fpr64(ctx, fp64, fd); 6376 tcg_temp_free_i64(fp64); 6377 } 6378 opn = "cvt.l.s"; 6379 break; 6380 case FOP(38, 16): 6381 check_cp1_64bitmode(ctx); 6382 { 6383 TCGv_i64 fp64 = tcg_temp_new_i64(); 6384 TCGv_i32 fp32_0 = tcg_temp_new_i32(); 6385 TCGv_i32 fp32_1 = tcg_temp_new_i32(); 6386 6387 gen_load_fpr32(fp32_0, fs); 6388 gen_load_fpr32(fp32_1, ft); 6389 tcg_gen_concat_i32_i64(fp64, fp32_0, fp32_1); 6390 tcg_temp_free_i32(fp32_1); 6391 tcg_temp_free_i32(fp32_0); 6392 gen_store_fpr64(ctx, fp64, fd); 6393 tcg_temp_free_i64(fp64); 6394 } 6395 opn = "cvt.ps.s"; 6396 break; 6397 case FOP(48, 16): 6398 case FOP(49, 16): 6399 case FOP(50, 16): 6400 case FOP(51, 16): 6401 case FOP(52, 16): 6402 case FOP(53, 16): 6403 case FOP(54, 16): 6404 case FOP(55, 16): 6405 case FOP(56, 16): 6406 case FOP(57, 16): 6407 case FOP(58, 16): 6408 case FOP(59, 16): 6409 case FOP(60, 16): 6410 case FOP(61, 16): 6411 case FOP(62, 16): 6412 case FOP(63, 16): 6413 { 6414 TCGv_i32 fp0 = tcg_temp_new_i32(); 6415 TCGv_i32 fp1 = tcg_temp_new_i32(); 6416 6417 gen_load_fpr32(fp0, fs); 6418 gen_load_fpr32(fp1, ft); 6419 if (ctx->opcode & (1 << 6)) { 6420 check_cop1x(ctx); 6421 gen_cmpabs_s(func-48, fp0, fp1, cc); 6422 opn = condnames_abs[func-48]; 6423 } else { 6424 gen_cmp_s(func-48, fp0, fp1, cc); 6425 opn = condnames[func-48]; 6426 } 6427 tcg_temp_free_i32(fp0); 6428 tcg_temp_free_i32(fp1); 6429 } 6430 break; 6431 case FOP(0, 17): 6432 check_cp1_registers(ctx, fs | ft | fd); 6433 { 6434 TCGv_i64 fp0 = tcg_temp_new_i64(); 6435 TCGv_i64 fp1 = tcg_temp_new_i64(); 6436 6437 gen_load_fpr64(ctx, fp0, fs); 6438 gen_load_fpr64(ctx, fp1, ft); 6439 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1); 6440 tcg_temp_free_i64(fp1); 6441 gen_store_fpr64(ctx, fp0, fd); 6442 tcg_temp_free_i64(fp0); 6443 } 6444 opn = "add.d"; 6445 optype = BINOP; 6446 break; 6447 case FOP(1, 17): 6448 check_cp1_registers(ctx, fs | ft | fd); 6449 { 6450 TCGv_i64 fp0 = tcg_temp_new_i64(); 6451 TCGv_i64 fp1 = tcg_temp_new_i64(); 6452 6453 gen_load_fpr64(ctx, fp0, fs); 6454 gen_load_fpr64(ctx, fp1, ft); 6455 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1); 6456 tcg_temp_free_i64(fp1); 6457 gen_store_fpr64(ctx, fp0, fd); 6458 tcg_temp_free_i64(fp0); 6459 } 6460 opn = "sub.d"; 6461 optype = BINOP; 6462 break; 6463 case FOP(2, 17): 6464 check_cp1_registers(ctx, fs | ft | fd); 6465 { 6466 TCGv_i64 fp0 = tcg_temp_new_i64(); 6467 TCGv_i64 fp1 = tcg_temp_new_i64(); 6468 6469 gen_load_fpr64(ctx, fp0, fs); 6470 gen_load_fpr64(ctx, fp1, ft); 6471 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1); 6472 tcg_temp_free_i64(fp1); 6473 gen_store_fpr64(ctx, fp0, fd); 6474 tcg_temp_free_i64(fp0); 6475 } 6476 opn = "mul.d"; 6477 optype = BINOP; 6478 break; 6479 case FOP(3, 17): 6480 check_cp1_registers(ctx, fs | ft | fd); 6481 { 6482 TCGv_i64 fp0 = tcg_temp_new_i64(); 6483 TCGv_i64 fp1 = tcg_temp_new_i64(); 6484 6485 gen_load_fpr64(ctx, fp0, fs); 6486 gen_load_fpr64(ctx, fp1, ft); 6487 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1); 6488 tcg_temp_free_i64(fp1); 6489 gen_store_fpr64(ctx, fp0, fd); 6490 tcg_temp_free_i64(fp0); 6491 } 6492 opn = "div.d"; 6493 optype = BINOP; 6494 break; 6495 case FOP(4, 17): 6496 check_cp1_registers(ctx, fs | fd); 6497 { 6498 TCGv_i64 fp0 = tcg_temp_new_i64(); 6499 6500 gen_load_fpr64(ctx, fp0, fs); 6501 gen_helper_float_sqrt_d(fp0, cpu_env, fp0); 6502 gen_store_fpr64(ctx, fp0, fd); 6503 tcg_temp_free_i64(fp0); 6504 } 6505 opn = "sqrt.d"; 6506 break; 6507 case FOP(5, 17): 6508 check_cp1_registers(ctx, fs | fd); 6509 { 6510 TCGv_i64 fp0 = tcg_temp_new_i64(); 6511 6512 gen_load_fpr64(ctx, fp0, fs); 6513 gen_helper_float_abs_d(fp0, fp0); 6514 gen_store_fpr64(ctx, fp0, fd); 6515 tcg_temp_free_i64(fp0); 6516 } 6517 opn = "abs.d"; 6518 break; 6519 case FOP(6, 17): 6520 check_cp1_registers(ctx, fs | fd); 6521 { 6522 TCGv_i64 fp0 = tcg_temp_new_i64(); 6523 6524 gen_load_fpr64(ctx, fp0, fs); 6525 gen_store_fpr64(ctx, fp0, fd); 6526 tcg_temp_free_i64(fp0); 6527 } 6528 opn = "mov.d"; 6529 break; 6530 case FOP(7, 17): 6531 check_cp1_registers(ctx, fs | fd); 6532 { 6533 TCGv_i64 fp0 = tcg_temp_new_i64(); 6534 6535 gen_load_fpr64(ctx, fp0, fs); 6536 gen_helper_float_chs_d(fp0, fp0); 6537 gen_store_fpr64(ctx, fp0, fd); 6538 tcg_temp_free_i64(fp0); 6539 } 6540 opn = "neg.d"; 6541 break; 6542 case FOP(8, 17): 6543 check_cp1_64bitmode(ctx); 6544 { 6545 TCGv_i64 fp0 = tcg_temp_new_i64(); 6546 6547 gen_load_fpr64(ctx, fp0, fs); 6548 gen_helper_float_roundl_d(fp0, cpu_env, fp0); 6549 gen_store_fpr64(ctx, fp0, fd); 6550 tcg_temp_free_i64(fp0); 6551 } 6552 opn = "round.l.d"; 6553 break; 6554 case FOP(9, 17): 6555 check_cp1_64bitmode(ctx); 6556 { 6557 TCGv_i64 fp0 = tcg_temp_new_i64(); 6558 6559 gen_load_fpr64(ctx, fp0, fs); 6560 gen_helper_float_truncl_d(fp0, cpu_env, fp0); 6561 gen_store_fpr64(ctx, fp0, fd); 6562 tcg_temp_free_i64(fp0); 6563 } 6564 opn = "trunc.l.d"; 6565 break; 6566 case FOP(10, 17): 6567 check_cp1_64bitmode(ctx); 6568 { 6569 TCGv_i64 fp0 = tcg_temp_new_i64(); 6570 6571 gen_load_fpr64(ctx, fp0, fs); 6572 gen_helper_float_ceill_d(fp0, cpu_env, fp0); 6573 gen_store_fpr64(ctx, fp0, fd); 6574 tcg_temp_free_i64(fp0); 6575 } 6576 opn = "ceil.l.d"; 6577 break; 6578 case FOP(11, 17): 6579 check_cp1_64bitmode(ctx); 6580 { 6581 TCGv_i64 fp0 = tcg_temp_new_i64(); 6582 6583 gen_load_fpr64(ctx, fp0, fs); 6584 gen_helper_float_floorl_d(fp0, cpu_env, fp0); 6585 gen_store_fpr64(ctx, fp0, fd); 6586 tcg_temp_free_i64(fp0); 6587 } 6588 opn = "floor.l.d"; 6589 break; 6590 case FOP(12, 17): 6591 check_cp1_registers(ctx, fs); 6592 { 6593 TCGv_i32 fp32 = tcg_temp_new_i32(); 6594 TCGv_i64 fp64 = tcg_temp_new_i64(); 6595 6596 gen_load_fpr64(ctx, fp64, fs); 6597 gen_helper_float_roundw_d(fp32, cpu_env, fp64); 6598 tcg_temp_free_i64(fp64); 6599 gen_store_fpr32(fp32, fd); 6600 tcg_temp_free_i32(fp32); 6601 } 6602 opn = "round.w.d"; 6603 break; 6604 case FOP(13, 17): 6605 check_cp1_registers(ctx, fs); 6606 { 6607 TCGv_i32 fp32 = tcg_temp_new_i32(); 6608 TCGv_i64 fp64 = tcg_temp_new_i64(); 6609 6610 gen_load_fpr64(ctx, fp64, fs); 6611 gen_helper_float_truncw_d(fp32, cpu_env, fp64); 6612 tcg_temp_free_i64(fp64); 6613 gen_store_fpr32(fp32, fd); 6614 tcg_temp_free_i32(fp32); 6615 } 6616 opn = "trunc.w.d"; 6617 break; 6618 case FOP(14, 17): 6619 check_cp1_registers(ctx, fs); 6620 { 6621 TCGv_i32 fp32 = tcg_temp_new_i32(); 6622 TCGv_i64 fp64 = tcg_temp_new_i64(); 6623 6624 gen_load_fpr64(ctx, fp64, fs); 6625 gen_helper_float_ceilw_d(fp32, cpu_env, fp64); 6626 tcg_temp_free_i64(fp64); 6627 gen_store_fpr32(fp32, fd); 6628 tcg_temp_free_i32(fp32); 6629 } 6630 opn = "ceil.w.d"; 6631 break; 6632 case FOP(15, 17): 6633 check_cp1_registers(ctx, fs); 6634 { 6635 TCGv_i32 fp32 = tcg_temp_new_i32(); 6636 TCGv_i64 fp64 = tcg_temp_new_i64(); 6637 6638 gen_load_fpr64(ctx, fp64, fs); 6639 gen_helper_float_floorw_d(fp32, cpu_env, fp64); 6640 tcg_temp_free_i64(fp64); 6641 gen_store_fpr32(fp32, fd); 6642 tcg_temp_free_i32(fp32); 6643 } 6644 opn = "floor.w.d"; 6645 break; 6646 case FOP(17, 17): 6647 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1); 6648 opn = "movcf.d"; 6649 break; 6650 case FOP(18, 17): 6651 { 6652 int l1 = gen_new_label(); 6653 TCGv_i64 fp0; 6654 6655 if (ft != 0) { 6656 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1); 6657 } 6658 fp0 = tcg_temp_new_i64(); 6659 gen_load_fpr64(ctx, fp0, fs); 6660 gen_store_fpr64(ctx, fp0, fd); 6661 tcg_temp_free_i64(fp0); 6662 gen_set_label(l1); 6663 } 6664 opn = "movz.d"; 6665 break; 6666 case FOP(19, 17): 6667 { 6668 int l1 = gen_new_label(); 6669 TCGv_i64 fp0; 6670 6671 if (ft != 0) { 6672 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1); 6673 fp0 = tcg_temp_new_i64(); 6674 gen_load_fpr64(ctx, fp0, fs); 6675 gen_store_fpr64(ctx, fp0, fd); 6676 tcg_temp_free_i64(fp0); 6677 gen_set_label(l1); 6678 } 6679 } 6680 opn = "movn.d"; 6681 break; 6682 case FOP(21, 17): 6683 check_cp1_64bitmode(ctx); 6684 { 6685 TCGv_i64 fp0 = tcg_temp_new_i64(); 6686 6687 gen_load_fpr64(ctx, fp0, fs); 6688 gen_helper_float_recip_d(fp0, cpu_env, fp0); 6689 gen_store_fpr64(ctx, fp0, fd); 6690 tcg_temp_free_i64(fp0); 6691 } 6692 opn = "recip.d"; 6693 break; 6694 case FOP(22, 17): 6695 check_cp1_64bitmode(ctx); 6696 { 6697 TCGv_i64 fp0 = tcg_temp_new_i64(); 6698 6699 gen_load_fpr64(ctx, fp0, fs); 6700 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0); 6701 gen_store_fpr64(ctx, fp0, fd); 6702 tcg_temp_free_i64(fp0); 6703 } 6704 opn = "rsqrt.d"; 6705 break; 6706 case FOP(28, 17): 6707 check_cp1_64bitmode(ctx); 6708 { 6709 TCGv_i64 fp0 = tcg_temp_new_i64(); 6710 TCGv_i64 fp1 = tcg_temp_new_i64(); 6711 6712 gen_load_fpr64(ctx, fp0, fs); 6713 gen_load_fpr64(ctx, fp1, ft); 6714 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1); 6715 tcg_temp_free_i64(fp1); 6716 gen_store_fpr64(ctx, fp0, fd); 6717 tcg_temp_free_i64(fp0); 6718 } 6719 opn = "recip2.d"; 6720 break; 6721 case FOP(29, 17): 6722 check_cp1_64bitmode(ctx); 6723 { 6724 TCGv_i64 fp0 = tcg_temp_new_i64(); 6725 6726 gen_load_fpr64(ctx, fp0, fs); 6727 gen_helper_float_recip1_d(fp0, cpu_env, fp0); 6728 gen_store_fpr64(ctx, fp0, fd); 6729 tcg_temp_free_i64(fp0); 6730 } 6731 opn = "recip1.d"; 6732 break; 6733 case FOP(30, 17): 6734 check_cp1_64bitmode(ctx); 6735 { 6736 TCGv_i64 fp0 = tcg_temp_new_i64(); 6737 6738 gen_load_fpr64(ctx, fp0, fs); 6739 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0); 6740 gen_store_fpr64(ctx, fp0, fd); 6741 tcg_temp_free_i64(fp0); 6742 } 6743 opn = "rsqrt1.d"; 6744 break; 6745 case FOP(31, 17): 6746 check_cp1_64bitmode(ctx); 6747 { 6748 TCGv_i64 fp0 = tcg_temp_new_i64(); 6749 TCGv_i64 fp1 = tcg_temp_new_i64(); 6750 6751 gen_load_fpr64(ctx, fp0, fs); 6752 gen_load_fpr64(ctx, fp1, ft); 6753 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1); 6754 tcg_temp_free_i64(fp1); 6755 gen_store_fpr64(ctx, fp0, fd); 6756 tcg_temp_free_i64(fp0); 6757 } 6758 opn = "rsqrt2.d"; 6759 break; 6760 case FOP(48, 17): 6761 case FOP(49, 17): 6762 case FOP(50, 17): 6763 case FOP(51, 17): 6764 case FOP(52, 17): 6765 case FOP(53, 17): 6766 case FOP(54, 17): 6767 case FOP(55, 17): 6768 case FOP(56, 17): 6769 case FOP(57, 17): 6770 case FOP(58, 17): 6771 case FOP(59, 17): 6772 case FOP(60, 17): 6773 case FOP(61, 17): 6774 case FOP(62, 17): 6775 case FOP(63, 17): 6776 { 6777 TCGv_i64 fp0 = tcg_temp_new_i64(); 6778 TCGv_i64 fp1 = tcg_temp_new_i64(); 6779 6780 gen_load_fpr64(ctx, fp0, fs); 6781 gen_load_fpr64(ctx, fp1, ft); 6782 if (ctx->opcode & (1 << 6)) { 6783 check_cop1x(ctx); 6784 check_cp1_registers(ctx, fs | ft); 6785 gen_cmpabs_d(func-48, fp0, fp1, cc); 6786 opn = condnames_abs[func-48]; 6787 } else { 6788 check_cp1_registers(ctx, fs | ft); 6789 gen_cmp_d(func-48, fp0, fp1, cc); 6790 opn = condnames[func-48]; 6791 } 6792 tcg_temp_free_i64(fp0); 6793 tcg_temp_free_i64(fp1); 6794 } 6795 break; 6796 case FOP(32, 17): 6797 check_cp1_registers(ctx, fs); 6798 { 6799 TCGv_i32 fp32 = tcg_temp_new_i32(); 6800 TCGv_i64 fp64 = tcg_temp_new_i64(); 6801 6802 gen_load_fpr64(ctx, fp64, fs); 6803 gen_helper_float_cvts_d(fp32, cpu_env, fp64); 6804 tcg_temp_free_i64(fp64); 6805 gen_store_fpr32(fp32, fd); 6806 tcg_temp_free_i32(fp32); 6807 } 6808 opn = "cvt.s.d"; 6809 break; 6810 case FOP(36, 17): 6811 check_cp1_registers(ctx, fs); 6812 { 6813 TCGv_i32 fp32 = tcg_temp_new_i32(); 6814 TCGv_i64 fp64 = tcg_temp_new_i64(); 6815 6816 gen_load_fpr64(ctx, fp64, fs); 6817 gen_helper_float_cvtw_d(fp32, cpu_env, fp64); 6818 tcg_temp_free_i64(fp64); 6819 gen_store_fpr32(fp32, fd); 6820 tcg_temp_free_i32(fp32); 6821 } 6822 opn = "cvt.w.d"; 6823 break; 6824 case FOP(37, 17): 6825 check_cp1_64bitmode(ctx); 6826 { 6827 TCGv_i64 fp0 = tcg_temp_new_i64(); 6828 6829 gen_load_fpr64(ctx, fp0, fs); 6830 gen_helper_float_cvtl_d(fp0, cpu_env, fp0); 6831 gen_store_fpr64(ctx, fp0, fd); 6832 tcg_temp_free_i64(fp0); 6833 } 6834 opn = "cvt.l.d"; 6835 break; 6836 case FOP(32, 20): 6837 { 6838 TCGv_i32 fp0 = tcg_temp_new_i32(); 6839 6840 gen_load_fpr32(fp0, fs); 6841 gen_helper_float_cvts_w(fp0, cpu_env, fp0); 6842 gen_store_fpr32(fp0, fd); 6843 tcg_temp_free_i32(fp0); 6844 } 6845 opn = "cvt.s.w"; 6846 break; 6847 case FOP(33, 20): 6848 check_cp1_registers(ctx, fd); 6849 { 6850 TCGv_i32 fp32 = tcg_temp_new_i32(); 6851 TCGv_i64 fp64 = tcg_temp_new_i64(); 6852 6853 gen_load_fpr32(fp32, fs); 6854 gen_helper_float_cvtd_w(fp64, cpu_env, fp32); 6855 tcg_temp_free_i32(fp32); 6856 gen_store_fpr64(ctx, fp64, fd); 6857 tcg_temp_free_i64(fp64); 6858 } 6859 opn = "cvt.d.w"; 6860 break; 6861 case FOP(32, 21): 6862 check_cp1_64bitmode(ctx); 6863 { 6864 TCGv_i32 fp32 = tcg_temp_new_i32(); 6865 TCGv_i64 fp64 = tcg_temp_new_i64(); 6866 6867 gen_load_fpr64(ctx, fp64, fs); 6868 gen_helper_float_cvts_l(fp32, cpu_env, fp64); 6869 tcg_temp_free_i64(fp64); 6870 gen_store_fpr32(fp32, fd); 6871 tcg_temp_free_i32(fp32); 6872 } 6873 opn = "cvt.s.l"; 6874 break; 6875 case FOP(33, 21): 6876 check_cp1_64bitmode(ctx); 6877 { 6878 TCGv_i64 fp0 = tcg_temp_new_i64(); 6879 6880 gen_load_fpr64(ctx, fp0, fs); 6881 gen_helper_float_cvtd_l(fp0, cpu_env, fp0); 6882 gen_store_fpr64(ctx, fp0, fd); 6883 tcg_temp_free_i64(fp0); 6884 } 6885 opn = "cvt.d.l"; 6886 break; 6887 case FOP(38, 20): 6888 check_cp1_64bitmode(ctx); 6889 { 6890 TCGv_i64 fp0 = tcg_temp_new_i64(); 6891 6892 gen_load_fpr64(ctx, fp0, fs); 6893 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0); 6894 gen_store_fpr64(ctx, fp0, fd); 6895 tcg_temp_free_i64(fp0); 6896 } 6897 opn = "cvt.ps.pw"; 6898 break; 6899 case FOP(0, 22): 6900 check_cp1_64bitmode(ctx); 6901 { 6902 TCGv_i64 fp0 = tcg_temp_new_i64(); 6903 TCGv_i64 fp1 = tcg_temp_new_i64(); 6904 6905 gen_load_fpr64(ctx, fp0, fs); 6906 gen_load_fpr64(ctx, fp1, ft); 6907 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1); 6908 tcg_temp_free_i64(fp1); 6909 gen_store_fpr64(ctx, fp0, fd); 6910 tcg_temp_free_i64(fp0); 6911 } 6912 opn = "add.ps"; 6913 break; 6914 case FOP(1, 22): 6915 check_cp1_64bitmode(ctx); 6916 { 6917 TCGv_i64 fp0 = tcg_temp_new_i64(); 6918 TCGv_i64 fp1 = tcg_temp_new_i64(); 6919 6920 gen_load_fpr64(ctx, fp0, fs); 6921 gen_load_fpr64(ctx, fp1, ft); 6922 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1); 6923 tcg_temp_free_i64(fp1); 6924 gen_store_fpr64(ctx, fp0, fd); 6925 tcg_temp_free_i64(fp0); 6926 } 6927 opn = "sub.ps"; 6928 break; 6929 case FOP(2, 22): 6930 check_cp1_64bitmode(ctx); 6931 { 6932 TCGv_i64 fp0 = tcg_temp_new_i64(); 6933 TCGv_i64 fp1 = tcg_temp_new_i64(); 6934 6935 gen_load_fpr64(ctx, fp0, fs); 6936 gen_load_fpr64(ctx, fp1, ft); 6937 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1); 6938 tcg_temp_free_i64(fp1); 6939 gen_store_fpr64(ctx, fp0, fd); 6940 tcg_temp_free_i64(fp0); 6941 } 6942 opn = "mul.ps"; 6943 break; 6944 case FOP(5, 22): 6945 check_cp1_64bitmode(ctx); 6946 { 6947 TCGv_i64 fp0 = tcg_temp_new_i64(); 6948 6949 gen_load_fpr64(ctx, fp0, fs); 6950 gen_helper_float_abs_ps(fp0, fp0); 6951 gen_store_fpr64(ctx, fp0, fd); 6952 tcg_temp_free_i64(fp0); 6953 } 6954 opn = "abs.ps"; 6955 break; 6956 case FOP(6, 22): 6957 check_cp1_64bitmode(ctx); 6958 { 6959 TCGv_i64 fp0 = tcg_temp_new_i64(); 6960 6961 gen_load_fpr64(ctx, fp0, fs); 6962 gen_store_fpr64(ctx, fp0, fd); 6963 tcg_temp_free_i64(fp0); 6964 } 6965 opn = "mov.ps"; 6966 break; 6967 case FOP(7, 22): 6968 check_cp1_64bitmode(ctx); 6969 { 6970 TCGv_i64 fp0 = tcg_temp_new_i64(); 6971 6972 gen_load_fpr64(ctx, fp0, fs); 6973 gen_helper_float_chs_ps(fp0, fp0); 6974 gen_store_fpr64(ctx, fp0, fd); 6975 tcg_temp_free_i64(fp0); 6976 } 6977 opn = "neg.ps"; 6978 break; 6979 case FOP(17, 22): 6980 check_cp1_64bitmode(ctx); 6981 gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1); 6982 opn = "movcf.ps"; 6983 break; 6984 case FOP(18, 22): 6985 check_cp1_64bitmode(ctx); 6986 { 6987 int l1 = gen_new_label(); 6988 TCGv_i64 fp0; 6989 6990 if (ft != 0) 6991 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1); 6992 fp0 = tcg_temp_new_i64(); 6993 gen_load_fpr64(ctx, fp0, fs); 6994 gen_store_fpr64(ctx, fp0, fd); 6995 tcg_temp_free_i64(fp0); 6996 gen_set_label(l1); 6997 } 6998 opn = "movz.ps"; 6999 break; 7000 case FOP(19, 22): 7001 check_cp1_64bitmode(ctx); 7002 { 7003 int l1 = gen_new_label(); 7004 TCGv_i64 fp0; 7005 7006 if (ft != 0) { 7007 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1); 7008 fp0 = tcg_temp_new_i64(); 7009 gen_load_fpr64(ctx, fp0, fs); 7010 gen_store_fpr64(ctx, fp0, fd); 7011 tcg_temp_free_i64(fp0); 7012 gen_set_label(l1); 7013 } 7014 } 7015 opn = "movn.ps"; 7016 break; 7017 case FOP(24, 22): 7018 check_cp1_64bitmode(ctx); 7019 { 7020 TCGv_i64 fp0 = tcg_temp_new_i64(); 7021 TCGv_i64 fp1 = tcg_temp_new_i64(); 7022 7023 gen_load_fpr64(ctx, fp0, ft); 7024 gen_load_fpr64(ctx, fp1, fs); 7025 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1); 7026 tcg_temp_free_i64(fp1); 7027 gen_store_fpr64(ctx, fp0, fd); 7028 tcg_temp_free_i64(fp0); 7029 } 7030 opn = "addr.ps"; 7031 break; 7032 case FOP(26, 22): 7033 check_cp1_64bitmode(ctx); 7034 { 7035 TCGv_i64 fp0 = tcg_temp_new_i64(); 7036 TCGv_i64 fp1 = tcg_temp_new_i64(); 7037 7038 gen_load_fpr64(ctx, fp0, ft); 7039 gen_load_fpr64(ctx, fp1, fs); 7040 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1); 7041 tcg_temp_free_i64(fp1); 7042 gen_store_fpr64(ctx, fp0, fd); 7043 tcg_temp_free_i64(fp0); 7044 } 7045 opn = "mulr.ps"; 7046 break; 7047 case FOP(28, 22): 7048 check_cp1_64bitmode(ctx); 7049 { 7050 TCGv_i64 fp0 = tcg_temp_new_i64(); 7051 TCGv_i64 fp1 = tcg_temp_new_i64(); 7052 7053 gen_load_fpr64(ctx, fp0, fs); 7054 gen_load_fpr64(ctx, fp1, fd); 7055 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1); 7056 tcg_temp_free_i64(fp1); 7057 gen_store_fpr64(ctx, fp0, fd); 7058 tcg_temp_free_i64(fp0); 7059 } 7060 opn = "recip2.ps"; 7061 break; 7062 case FOP(29, 22): 7063 check_cp1_64bitmode(ctx); 7064 { 7065 TCGv_i64 fp0 = tcg_temp_new_i64(); 7066 7067 gen_load_fpr64(ctx, fp0, fs); 7068 gen_helper_float_recip1_ps(fp0, cpu_env, fp0); 7069 gen_store_fpr64(ctx, fp0, fd); 7070 tcg_temp_free_i64(fp0); 7071 } 7072 opn = "recip1.ps"; 7073 break; 7074 case FOP(30, 22): 7075 check_cp1_64bitmode(ctx); 7076 { 7077 TCGv_i64 fp0 = tcg_temp_new_i64(); 7078 7079 gen_load_fpr64(ctx, fp0, fs); 7080 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0); 7081 gen_store_fpr64(ctx, fp0, fd); 7082 tcg_temp_free_i64(fp0); 7083 } 7084 opn = "rsqrt1.ps"; 7085 break; 7086 case FOP(31, 22): 7087 check_cp1_64bitmode(ctx); 7088 { 7089 TCGv_i64 fp0 = tcg_temp_new_i64(); 7090 TCGv_i64 fp1 = tcg_temp_new_i64(); 7091 7092 gen_load_fpr64(ctx, fp0, fs); 7093 gen_load_fpr64(ctx, fp1, ft); 7094 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1); 7095 tcg_temp_free_i64(fp1); 7096 gen_store_fpr64(ctx, fp0, fd); 7097 tcg_temp_free_i64(fp0); 7098 } 7099 opn = "rsqrt2.ps"; 7100 break; 7101 case FOP(32, 22): 7102 check_cp1_64bitmode(ctx); 7103 { 7104 TCGv_i32 fp0 = tcg_temp_new_i32(); 7105 7106 gen_load_fpr32h(fp0, fs); 7107 gen_helper_float_cvts_pu(fp0, cpu_env, fp0); 7108 gen_store_fpr32(fp0, fd); 7109 tcg_temp_free_i32(fp0); 7110 } 7111 opn = "cvt.s.pu"; 7112 break; 7113 case FOP(36, 22): 7114 check_cp1_64bitmode(ctx); 7115 { 7116 TCGv_i64 fp0 = tcg_temp_new_i64(); 7117 7118 gen_load_fpr64(ctx, fp0, fs); 7119 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0); 7120 gen_store_fpr64(ctx, fp0, fd); 7121 tcg_temp_free_i64(fp0); 7122 } 7123 opn = "cvt.pw.ps"; 7124 break; 7125 case FOP(40, 22): 7126 check_cp1_64bitmode(ctx); 7127 { 7128 TCGv_i32 fp0 = tcg_temp_new_i32(); 7129 7130 gen_load_fpr32(fp0, fs); 7131 gen_helper_float_cvts_pl(fp0, cpu_env, fp0); 7132 gen_store_fpr32(fp0, fd); 7133 tcg_temp_free_i32(fp0); 7134 } 7135 opn = "cvt.s.pl"; 7136 break; 7137 case FOP(44, 22): 7138 check_cp1_64bitmode(ctx); 7139 { 7140 TCGv_i32 fp0 = tcg_temp_new_i32(); 7141 TCGv_i32 fp1 = tcg_temp_new_i32(); 7142 7143 gen_load_fpr32(fp0, fs); 7144 gen_load_fpr32(fp1, ft); 7145 gen_store_fpr32h(fp0, fd); 7146 gen_store_fpr32(fp1, fd); 7147 tcg_temp_free_i32(fp0); 7148 tcg_temp_free_i32(fp1); 7149 } 7150 opn = "pll.ps"; 7151 break; 7152 case FOP(45, 22): 7153 check_cp1_64bitmode(ctx); 7154 { 7155 TCGv_i32 fp0 = tcg_temp_new_i32(); 7156 TCGv_i32 fp1 = tcg_temp_new_i32(); 7157 7158 gen_load_fpr32(fp0, fs); 7159 gen_load_fpr32h(fp1, ft); 7160 gen_store_fpr32(fp1, fd); 7161 gen_store_fpr32h(fp0, fd); 7162 tcg_temp_free_i32(fp0); 7163 tcg_temp_free_i32(fp1); 7164 } 7165 opn = "plu.ps"; 7166 break; 7167 case FOP(46, 22): 7168 check_cp1_64bitmode(ctx); 7169 { 7170 TCGv_i32 fp0 = tcg_temp_new_i32(); 7171 TCGv_i32 fp1 = tcg_temp_new_i32(); 7172 7173 gen_load_fpr32h(fp0, fs); 7174 gen_load_fpr32(fp1, ft); 7175 gen_store_fpr32(fp1, fd); 7176 gen_store_fpr32h(fp0, fd); 7177 tcg_temp_free_i32(fp0); 7178 tcg_temp_free_i32(fp1); 7179 } 7180 opn = "pul.ps"; 7181 break; 7182 case FOP(47, 22): 7183 check_cp1_64bitmode(ctx); 7184 { 7185 TCGv_i32 fp0 = tcg_temp_new_i32(); 7186 TCGv_i32 fp1 = tcg_temp_new_i32(); 7187 7188 gen_load_fpr32h(fp0, fs); 7189 gen_load_fpr32h(fp1, ft); 7190 gen_store_fpr32(fp1, fd); 7191 gen_store_fpr32h(fp0, fd); 7192 tcg_temp_free_i32(fp0); 7193 tcg_temp_free_i32(fp1); 7194 } 7195 opn = "puu.ps"; 7196 break; 7197 case FOP(48, 22): 7198 case FOP(49, 22): 7199 case FOP(50, 22): 7200 case FOP(51, 22): 7201 case FOP(52, 22): 7202 case FOP(53, 22): 7203 case FOP(54, 22): 7204 case FOP(55, 22): 7205 case FOP(56, 22): 7206 case FOP(57, 22): 7207 case FOP(58, 22): 7208 case FOP(59, 22): 7209 case FOP(60, 22): 7210 case FOP(61, 22): 7211 case FOP(62, 22): 7212 case FOP(63, 22): 7213 check_cp1_64bitmode(ctx); 7214 { 7215 TCGv_i64 fp0 = tcg_temp_new_i64(); 7216 TCGv_i64 fp1 = tcg_temp_new_i64(); 7217 7218 gen_load_fpr64(ctx, fp0, fs); 7219 gen_load_fpr64(ctx, fp1, ft); 7220 if (ctx->opcode & (1 << 6)) { 7221 gen_cmpabs_ps(func-48, fp0, fp1, cc); 7222 opn = condnames_abs[func-48]; 7223 } else { 7224 gen_cmp_ps(func-48, fp0, fp1, cc); 7225 opn = condnames[func-48]; 7226 } 7227 tcg_temp_free_i64(fp0); 7228 tcg_temp_free_i64(fp1); 7229 } 7230 break; 7231 default: 7232 MIPS_INVAL(opn); 7233 generate_exception (ctx, EXCP_RI); 7234 return; 7235 } 7236 switch (optype) { 7237 case BINOP: 7238 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]); 7239 break; 7240 case CMPOP: 7241 MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]); 7242 break; 7243 default: 7244 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]); 7245 break; 7246 } 7247 } 7248 7249 /* Coprocessor 3 (FPU) */ 7250 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc, 7251 int fd, int fs, int base, int index) 7252 { 7253 const char* __attribute__((unused)) opn = "extended float load/store"; 7254 int __attribute__((unused)) store = 0; 7255 TCGv t0 = tcg_temp_new(); 7256 7257 if (base == 0) { 7258 gen_load_gpr(t0, index); 7259 } else if (index == 0) { 7260 gen_load_gpr(t0, base); 7261 } else { 7262 gen_load_gpr(t0, index); 7263 gen_op_addr_add(ctx, t0, cpu_gpr[base], t0); 7264 } 7265 /* Don't do NOP if destination is zero: we must perform the actual 7266 memory access. */ 7267 save_cpu_state(ctx, 0); 7268 switch (opc) { 7269 case OPC_LWXC1: 7270 check_cop1x(ctx); 7271 { 7272 TCGv_i32 fp0 = tcg_temp_new_i32(); 7273 7274 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx); 7275 tcg_gen_trunc_tl_i32(fp0, t0); 7276 gen_store_fpr32(fp0, fd); 7277 tcg_temp_free_i32(fp0); 7278 } 7279 opn = "lwxc1"; 7280 break; 7281 case OPC_LDXC1: 7282 check_cop1x(ctx); 7283 check_cp1_registers(ctx, fd); 7284 { 7285 TCGv_i64 fp0 = tcg_temp_new_i64(); 7286 7287 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx); 7288 gen_store_fpr64(ctx, fp0, fd); 7289 tcg_temp_free_i64(fp0); 7290 } 7291 opn = "ldxc1"; 7292 break; 7293 case OPC_LUXC1: 7294 check_cp1_64bitmode(ctx); 7295 tcg_gen_andi_tl(t0, t0, ~0x7); 7296 { 7297 TCGv_i64 fp0 = tcg_temp_new_i64(); 7298 7299 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx); 7300 gen_store_fpr64(ctx, fp0, fd); 7301 tcg_temp_free_i64(fp0); 7302 } 7303 opn = "luxc1"; 7304 break; 7305 case OPC_SWXC1: 7306 check_cop1x(ctx); 7307 { 7308 TCGv_i32 fp0 = tcg_temp_new_i32(); 7309 TCGv t1 = tcg_temp_new(); 7310 7311 gen_load_fpr32(fp0, fs); 7312 tcg_gen_extu_i32_tl(t1, fp0); 7313 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx); 7314 tcg_temp_free_i32(fp0); 7315 tcg_temp_free(t1); 7316 } 7317 opn = "swxc1"; 7318 store = 1; 7319 break; 7320 case OPC_SDXC1: 7321 check_cop1x(ctx); 7322 check_cp1_registers(ctx, fs); 7323 { 7324 TCGv_i64 fp0 = tcg_temp_new_i64(); 7325 7326 gen_load_fpr64(ctx, fp0, fs); 7327 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx); 7328 tcg_temp_free_i64(fp0); 7329 } 7330 opn = "sdxc1"; 7331 store = 1; 7332 break; 7333 case OPC_SUXC1: 7334 check_cp1_64bitmode(ctx); 7335 tcg_gen_andi_tl(t0, t0, ~0x7); 7336 { 7337 TCGv_i64 fp0 = tcg_temp_new_i64(); 7338 7339 gen_load_fpr64(ctx, fp0, fs); 7340 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx); 7341 tcg_temp_free_i64(fp0); 7342 } 7343 opn = "suxc1"; 7344 store = 1; 7345 break; 7346 } 7347 tcg_temp_free(t0); 7348 MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd], 7349 regnames[index], regnames[base]); 7350 } 7351 7352 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, 7353 int fd, int fr, int fs, int ft) 7354 { 7355 const char* __attribute__((unused)) opn = "flt3_arith"; 7356 7357 switch (opc) { 7358 case OPC_ALNV_PS: 7359 check_cp1_64bitmode(ctx); 7360 { 7361 TCGv t0 = tcg_temp_local_new(); 7362 TCGv_i32 fp = tcg_temp_new_i32(); 7363 TCGv_i32 fph = tcg_temp_new_i32(); 7364 int l1 = gen_new_label(); 7365 int l2 = gen_new_label(); 7366 7367 gen_load_gpr(t0, fr); 7368 tcg_gen_andi_tl(t0, t0, 0x7); 7369 7370 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1); 7371 gen_load_fpr32(fp, fs); 7372 gen_load_fpr32h(fph, fs); 7373 gen_store_fpr32(fp, fd); 7374 gen_store_fpr32h(fph, fd); 7375 tcg_gen_br(l2); 7376 gen_set_label(l1); 7377 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2); 7378 tcg_temp_free(t0); 7379 #ifdef TARGET_WORDS_BIGENDIAN 7380 gen_load_fpr32(fp, fs); 7381 gen_load_fpr32h(fph, ft); 7382 gen_store_fpr32h(fp, fd); 7383 gen_store_fpr32(fph, fd); 7384 #else 7385 gen_load_fpr32h(fph, fs); 7386 gen_load_fpr32(fp, ft); 7387 gen_store_fpr32(fph, fd); 7388 gen_store_fpr32h(fp, fd); 7389 #endif 7390 gen_set_label(l2); 7391 tcg_temp_free_i32(fp); 7392 tcg_temp_free_i32(fph); 7393 } 7394 opn = "alnv.ps"; 7395 break; 7396 case OPC_MADD_S: 7397 check_cop1x(ctx); 7398 { 7399 TCGv_i32 fp0 = tcg_temp_new_i32(); 7400 TCGv_i32 fp1 = tcg_temp_new_i32(); 7401 TCGv_i32 fp2 = tcg_temp_new_i32(); 7402 7403 gen_load_fpr32(fp0, fs); 7404 gen_load_fpr32(fp1, ft); 7405 gen_load_fpr32(fp2, fr); 7406 gen_helper_float_muladd_s(fp2, cpu_env, fp0, fp1, fp2); 7407 tcg_temp_free_i32(fp0); 7408 tcg_temp_free_i32(fp1); 7409 gen_store_fpr32(fp2, fd); 7410 tcg_temp_free_i32(fp2); 7411 } 7412 opn = "madd.s"; 7413 break; 7414 case OPC_MADD_D: 7415 check_cop1x(ctx); 7416 check_cp1_registers(ctx, fd | fs | ft | fr); 7417 { 7418 TCGv_i64 fp0 = tcg_temp_new_i64(); 7419 TCGv_i64 fp1 = tcg_temp_new_i64(); 7420 TCGv_i64 fp2 = tcg_temp_new_i64(); 7421 7422 gen_load_fpr64(ctx, fp0, fs); 7423 gen_load_fpr64(ctx, fp1, ft); 7424 gen_load_fpr64(ctx, fp2, fr); 7425 gen_helper_float_muladd_d(fp2, cpu_env, fp0, fp1, fp2); 7426 tcg_temp_free_i64(fp0); 7427 tcg_temp_free_i64(fp1); 7428 gen_store_fpr64(ctx, fp2, fd); 7429 tcg_temp_free_i64(fp2); 7430 } 7431 opn = "madd.d"; 7432 break; 7433 case OPC_MADD_PS: 7434 check_cp1_64bitmode(ctx); 7435 { 7436 TCGv_i64 fp0 = tcg_temp_new_i64(); 7437 TCGv_i64 fp1 = tcg_temp_new_i64(); 7438 TCGv_i64 fp2 = tcg_temp_new_i64(); 7439 7440 gen_load_fpr64(ctx, fp0, fs); 7441 gen_load_fpr64(ctx, fp1, ft); 7442 gen_load_fpr64(ctx, fp2, fr); 7443 gen_helper_float_muladd_ps(fp2, cpu_env, fp0, fp1, fp2); 7444 tcg_temp_free_i64(fp0); 7445 tcg_temp_free_i64(fp1); 7446 gen_store_fpr64(ctx, fp2, fd); 7447 tcg_temp_free_i64(fp2); 7448 } 7449 opn = "madd.ps"; 7450 break; 7451 case OPC_MSUB_S: 7452 check_cop1x(ctx); 7453 { 7454 TCGv_i32 fp0 = tcg_temp_new_i32(); 7455 TCGv_i32 fp1 = tcg_temp_new_i32(); 7456 TCGv_i32 fp2 = tcg_temp_new_i32(); 7457 7458 gen_load_fpr32(fp0, fs); 7459 gen_load_fpr32(fp1, ft); 7460 gen_load_fpr32(fp2, fr); 7461 gen_helper_float_mulsub_s(fp2, cpu_env, fp0, fp1, fp2); 7462 tcg_temp_free_i32(fp0); 7463 tcg_temp_free_i32(fp1); 7464 gen_store_fpr32(fp2, fd); 7465 tcg_temp_free_i32(fp2); 7466 } 7467 opn = "msub.s"; 7468 break; 7469 case OPC_MSUB_D: 7470 check_cop1x(ctx); 7471 check_cp1_registers(ctx, fd | fs | ft | fr); 7472 { 7473 TCGv_i64 fp0 = tcg_temp_new_i64(); 7474 TCGv_i64 fp1 = tcg_temp_new_i64(); 7475 TCGv_i64 fp2 = tcg_temp_new_i64(); 7476 7477 gen_load_fpr64(ctx, fp0, fs); 7478 gen_load_fpr64(ctx, fp1, ft); 7479 gen_load_fpr64(ctx, fp2, fr); 7480 gen_helper_float_mulsub_d(fp2, cpu_env, fp0, fp1, fp2); 7481 tcg_temp_free_i64(fp0); 7482 tcg_temp_free_i64(fp1); 7483 gen_store_fpr64(ctx, fp2, fd); 7484 tcg_temp_free_i64(fp2); 7485 } 7486 opn = "msub.d"; 7487 break; 7488 case OPC_MSUB_PS: 7489 check_cp1_64bitmode(ctx); 7490 { 7491 TCGv_i64 fp0 = tcg_temp_new_i64(); 7492 TCGv_i64 fp1 = tcg_temp_new_i64(); 7493 TCGv_i64 fp2 = tcg_temp_new_i64(); 7494 7495 gen_load_fpr64(ctx, fp0, fs); 7496 gen_load_fpr64(ctx, fp1, ft); 7497 gen_load_fpr64(ctx, fp2, fr); 7498 gen_helper_float_mulsub_ps(fp2, cpu_env, fp0, fp1, fp2); 7499 tcg_temp_free_i64(fp0); 7500 tcg_temp_free_i64(fp1); 7501 gen_store_fpr64(ctx, fp2, fd); 7502 tcg_temp_free_i64(fp2); 7503 } 7504 opn = "msub.ps"; 7505 break; 7506 case OPC_NMADD_S: 7507 check_cop1x(ctx); 7508 { 7509 TCGv_i32 fp0 = tcg_temp_new_i32(); 7510 TCGv_i32 fp1 = tcg_temp_new_i32(); 7511 TCGv_i32 fp2 = tcg_temp_new_i32(); 7512 7513 gen_load_fpr32(fp0, fs); 7514 gen_load_fpr32(fp1, ft); 7515 gen_load_fpr32(fp2, fr); 7516 gen_helper_float_nmuladd_s(fp2, cpu_env, fp0, fp1, fp2); 7517 tcg_temp_free_i32(fp0); 7518 tcg_temp_free_i32(fp1); 7519 gen_store_fpr32(fp2, fd); 7520 tcg_temp_free_i32(fp2); 7521 } 7522 opn = "nmadd.s"; 7523 break; 7524 case OPC_NMADD_D: 7525 check_cop1x(ctx); 7526 check_cp1_registers(ctx, fd | fs | ft | fr); 7527 { 7528 TCGv_i64 fp0 = tcg_temp_new_i64(); 7529 TCGv_i64 fp1 = tcg_temp_new_i64(); 7530 TCGv_i64 fp2 = tcg_temp_new_i64(); 7531 7532 gen_load_fpr64(ctx, fp0, fs); 7533 gen_load_fpr64(ctx, fp1, ft); 7534 gen_load_fpr64(ctx, fp2, fr); 7535 gen_helper_float_nmuladd_d(fp2, cpu_env, fp0, fp1, fp2); 7536 tcg_temp_free_i64(fp0); 7537 tcg_temp_free_i64(fp1); 7538 gen_store_fpr64(ctx, fp2, fd); 7539 tcg_temp_free_i64(fp2); 7540 } 7541 opn = "nmadd.d"; 7542 break; 7543 case OPC_NMADD_PS: 7544 check_cp1_64bitmode(ctx); 7545 { 7546 TCGv_i64 fp0 = tcg_temp_new_i64(); 7547 TCGv_i64 fp1 = tcg_temp_new_i64(); 7548 TCGv_i64 fp2 = tcg_temp_new_i64(); 7549 7550 gen_load_fpr64(ctx, fp0, fs); 7551 gen_load_fpr64(ctx, fp1, ft); 7552 gen_load_fpr64(ctx, fp2, fr); 7553 gen_helper_float_nmuladd_ps(fp2, cpu_env, fp0, fp1, fp2); 7554 tcg_temp_free_i64(fp0); 7555 tcg_temp_free_i64(fp1); 7556 gen_store_fpr64(ctx, fp2, fd); 7557 tcg_temp_free_i64(fp2); 7558 } 7559 opn = "nmadd.ps"; 7560 break; 7561 case OPC_NMSUB_S: 7562 check_cop1x(ctx); 7563 { 7564 TCGv_i32 fp0 = tcg_temp_new_i32(); 7565 TCGv_i32 fp1 = tcg_temp_new_i32(); 7566 TCGv_i32 fp2 = tcg_temp_new_i32(); 7567 7568 gen_load_fpr32(fp0, fs); 7569 gen_load_fpr32(fp1, ft); 7570 gen_load_fpr32(fp2, fr); 7571 gen_helper_float_nmulsub_s(fp2, cpu_env, fp0, fp1, fp2); 7572 tcg_temp_free_i32(fp0); 7573 tcg_temp_free_i32(fp1); 7574 gen_store_fpr32(fp2, fd); 7575 tcg_temp_free_i32(fp2); 7576 } 7577 opn = "nmsub.s"; 7578 break; 7579 case OPC_NMSUB_D: 7580 check_cop1x(ctx); 7581 check_cp1_registers(ctx, fd | fs | ft | fr); 7582 { 7583 TCGv_i64 fp0 = tcg_temp_new_i64(); 7584 TCGv_i64 fp1 = tcg_temp_new_i64(); 7585 TCGv_i64 fp2 = tcg_temp_new_i64(); 7586 7587 gen_load_fpr64(ctx, fp0, fs); 7588 gen_load_fpr64(ctx, fp1, ft); 7589 gen_load_fpr64(ctx, fp2, fr); 7590 gen_helper_float_nmulsub_d(fp2, cpu_env, fp0, fp1, fp2); 7591 tcg_temp_free_i64(fp0); 7592 tcg_temp_free_i64(fp1); 7593 gen_store_fpr64(ctx, fp2, fd); 7594 tcg_temp_free_i64(fp2); 7595 } 7596 opn = "nmsub.d"; 7597 break; 7598 case OPC_NMSUB_PS: 7599 check_cp1_64bitmode(ctx); 7600 { 7601 TCGv_i64 fp0 = tcg_temp_new_i64(); 7602 TCGv_i64 fp1 = tcg_temp_new_i64(); 7603 TCGv_i64 fp2 = tcg_temp_new_i64(); 7604 7605 gen_load_fpr64(ctx, fp0, fs); 7606 gen_load_fpr64(ctx, fp1, ft); 7607 gen_load_fpr64(ctx, fp2, fr); 7608 gen_helper_float_nmulsub_ps(fp2, cpu_env, fp0, fp1, fp2); 7609 tcg_temp_free_i64(fp0); 7610 tcg_temp_free_i64(fp1); 7611 gen_store_fpr64(ctx, fp2, fd); 7612 tcg_temp_free_i64(fp2); 7613 } 7614 opn = "nmsub.ps"; 7615 break; 7616 default: 7617 MIPS_INVAL(opn); 7618 generate_exception (ctx, EXCP_RI); 7619 return; 7620 } 7621 MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr], 7622 fregnames[fs], fregnames[ft]); 7623 } 7624 7625 /* ISA extensions (ASEs) */ 7626 /* MIPS16 extension to MIPS32 */ 7627 /* SmartMIPS extension to MIPS32 */ 7628 7629 #if defined(TARGET_MIPS64) 7630 7631 /* MDMX extension to MIPS64 */ 7632 7633 #endif 7634 7635 static void decode_opc (CPUMIPSState *env, DisasContext *ctx) 7636 { 7637 int32_t offset; 7638 int rs, rt, rd, sa; 7639 uint32_t op, op1, op2; 7640 int16_t imm; 7641 7642 /* make sure instructions are on a word boundary */ 7643 if (ctx->pc & 0x3) { 7644 env->CP0_BadVAddr = ctx->pc; 7645 generate_exception(ctx, EXCP_AdEL); 7646 return; 7647 } 7648 7649 /* Handle blikely not taken case */ 7650 if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) { 7651 int l1 = gen_new_label(); 7652 7653 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4); 7654 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1); 7655 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK); 7656 gen_goto_tb(ctx, 1, ctx->pc + 4); 7657 gen_set_label(l1); 7658 } 7659 7660 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) 7661 tcg_gen_debug_insn_start(ctx->pc); 7662 7663 op = MASK_OP_MAJOR(ctx->opcode); 7664 rs = (ctx->opcode >> 21) & 0x1f; 7665 rt = (ctx->opcode >> 16) & 0x1f; 7666 rd = (ctx->opcode >> 11) & 0x1f; 7667 sa = (ctx->opcode >> 6) & 0x1f; 7668 imm = (int16_t)ctx->opcode; 7669 switch (op) { 7670 case OPC_SPECIAL: 7671 op1 = MASK_SPECIAL(ctx->opcode); 7672 switch (op1) { 7673 case OPC_SLL: /* Shift with immediate */ 7674 case OPC_SRA: 7675 case OPC_SRL: 7676 gen_shift_imm(env, ctx, op1, rd, rt, sa); 7677 break; 7678 case OPC_MOVN: /* Conditional move */ 7679 case OPC_MOVZ: 7680 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32); 7681 gen_cond_move(env, op1, rd, rs, rt); 7682 break; 7683 case OPC_ADD ... OPC_SUBU: 7684 gen_arith(env, ctx, op1, rd, rs, rt); 7685 break; 7686 case OPC_SLLV: /* Shifts */ 7687 case OPC_SRLV: 7688 case OPC_SRAV: 7689 gen_shift(env, ctx, op1, rd, rs, rt); 7690 break; 7691 case OPC_SLT: /* Set on less than */ 7692 case OPC_SLTU: 7693 gen_slt(env, op1, rd, rs, rt); 7694 break; 7695 case OPC_AND: /* Logic*/ 7696 case OPC_OR: 7697 case OPC_NOR: 7698 case OPC_XOR: 7699 gen_logic(env, op1, rd, rs, rt); 7700 break; 7701 case OPC_MULT ... OPC_DIVU: 7702 if (sa) { 7703 check_insn(env, ctx, INSN_VR54XX); 7704 op1 = MASK_MUL_VR54XX(ctx->opcode); 7705 gen_mul_vr54xx(ctx, op1, rd, rs, rt); 7706 } else 7707 gen_muldiv(ctx, op1, rs, rt); 7708 break; 7709 case OPC_JR ... OPC_JALR: 7710 gen_compute_branch(ctx, op1, rs, rd, sa); 7711 return; 7712 case OPC_TGE ... OPC_TEQ: /* Traps */ 7713 case OPC_TNE: 7714 gen_trap(ctx, op1, rs, rt, -1); 7715 break; 7716 case OPC_MFHI: /* Move from HI/LO */ 7717 case OPC_MFLO: 7718 gen_HILO(ctx, op1, rd); 7719 break; 7720 case OPC_MTHI: 7721 case OPC_MTLO: /* Move to HI/LO */ 7722 gen_HILO(ctx, op1, rs); 7723 break; 7724 case OPC_PMON: /* Pmon entry point, also R4010 selsl */ 7725 #ifdef MIPS_STRICT_STANDARD 7726 MIPS_INVAL("PMON / selsl"); 7727 generate_exception(ctx, EXCP_RI); 7728 #else 7729 gen_helper_1i(pmon, cpu_env, sa); 7730 #endif 7731 break; 7732 case OPC_SYSCALL: 7733 generate_exception(ctx, EXCP_SYSCALL); 7734 ctx->bstate = BS_STOP; 7735 break; 7736 case OPC_BREAK: 7737 generate_exception(ctx, EXCP_BREAK); 7738 break; 7739 case OPC_SPIM: 7740 #ifdef MIPS_STRICT_STANDARD 7741 MIPS_INVAL("SPIM"); 7742 generate_exception(ctx, EXCP_RI); 7743 #else 7744 /* Implemented as RI exception for now. */ 7745 MIPS_INVAL("spim (unofficial)"); 7746 generate_exception(ctx, EXCP_RI); 7747 #endif 7748 break; 7749 case OPC_SYNC: 7750 /* Treat as NOP. */ 7751 break; 7752 7753 case OPC_MOVCI: 7754 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32); 7755 if (env->CP0_Config1 & (1 << CP0C1_FP)) { 7756 check_cp1_enabled(ctx); 7757 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7, 7758 (ctx->opcode >> 16) & 1); 7759 } else { 7760 generate_exception_err(ctx, EXCP_CpU, 1); 7761 } 7762 break; 7763 7764 #if defined(TARGET_MIPS64) 7765 /* MIPS64 specific opcodes */ 7766 case OPC_DSLL: 7767 case OPC_DSRA: 7768 case OPC_DSRL: 7769 case OPC_DSLL32: 7770 case OPC_DSRA32: 7771 case OPC_DSRL32: 7772 check_insn(env, ctx, ISA_MIPS3); 7773 check_mips_64(ctx); 7774 gen_shift_imm(env, ctx, op1, rd, rt, sa); 7775 break; 7776 case OPC_DADD ... OPC_DSUBU: 7777 check_insn(env, ctx, ISA_MIPS3); 7778 check_mips_64(ctx); 7779 gen_arith(env, ctx, op1, rd, rs, rt); 7780 break; 7781 case OPC_DSLLV: 7782 case OPC_DSRAV: 7783 case OPC_DSRLV: 7784 check_insn(env, ctx, ISA_MIPS3); 7785 check_mips_64(ctx); 7786 gen_shift(env, ctx, op1, rd, rs, rt); 7787 break; 7788 case OPC_DMULT ... OPC_DDIVU: 7789 check_insn(env, ctx, ISA_MIPS3); 7790 check_mips_64(ctx); 7791 gen_muldiv(ctx, op1, rs, rt); 7792 break; 7793 #endif 7794 default: /* Invalid */ 7795 MIPS_INVAL("special"); 7796 generate_exception(ctx, EXCP_RI); 7797 break; 7798 } 7799 break; 7800 case OPC_SPECIAL2: 7801 op1 = MASK_SPECIAL2(ctx->opcode); 7802 switch (op1) { 7803 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */ 7804 case OPC_MSUB ... OPC_MSUBU: 7805 check_insn(env, ctx, ISA_MIPS32); 7806 gen_muldiv(ctx, op1, rs, rt); 7807 break; 7808 case OPC_MUL: 7809 gen_arith(env, ctx, op1, rd, rs, rt); 7810 break; 7811 case OPC_CLO: 7812 case OPC_CLZ: 7813 check_insn(env, ctx, ISA_MIPS32); 7814 gen_cl(ctx, op1, rd, rs); 7815 break; 7816 case OPC_SDBBP: 7817 /* XXX: not clear which exception should be raised 7818 * when in debug mode... 7819 */ 7820 check_insn(env, ctx, ISA_MIPS32); 7821 if (!(ctx->hflags & MIPS_HFLAG_DM)) { 7822 generate_exception(ctx, EXCP_DBp); 7823 } else { 7824 generate_exception(ctx, EXCP_DBp); 7825 } 7826 /* Treat as NOP. */ 7827 break; 7828 #if defined(TARGET_MIPS64) 7829 case OPC_DCLO: 7830 case OPC_DCLZ: 7831 check_insn(env, ctx, ISA_MIPS64); 7832 check_mips_64(ctx); 7833 gen_cl(ctx, op1, rd, rs); 7834 break; 7835 #endif 7836 default: /* Invalid */ 7837 MIPS_INVAL("special2"); 7838 generate_exception(ctx, EXCP_RI); 7839 break; 7840 } 7841 break; 7842 case OPC_SPECIAL3: 7843 op1 = MASK_SPECIAL3(ctx->opcode); 7844 switch (op1) { 7845 case OPC_EXT: 7846 case OPC_INS: 7847 check_insn(env, ctx, ISA_MIPS32R2); 7848 gen_bitops(ctx, op1, rt, rs, sa, rd); 7849 break; 7850 case OPC_BSHFL: 7851 check_insn(env, ctx, ISA_MIPS32R2); 7852 op2 = MASK_BSHFL(ctx->opcode); 7853 gen_bshfl(ctx, op2, rt, rd); 7854 break; 7855 case OPC_RDHWR: 7856 check_insn(env, ctx, ISA_MIPS32R2); 7857 { 7858 TCGv t0 = tcg_temp_new(); 7859 7860 switch (rd) { 7861 case 0: 7862 save_cpu_state(ctx, 1); 7863 gen_helper_rdhwr_cpunum(t0, cpu_env); 7864 gen_store_gpr(t0, rt); 7865 break; 7866 case 1: 7867 save_cpu_state(ctx, 1); 7868 gen_helper_rdhwr_synci_step(t0, cpu_env); 7869 gen_store_gpr(t0, rt); 7870 break; 7871 case 2: 7872 save_cpu_state(ctx, 1); 7873 gen_helper_rdhwr_cc(t0, cpu_env); 7874 gen_store_gpr(t0, rt); 7875 break; 7876 case 3: 7877 save_cpu_state(ctx, 1); 7878 gen_helper_rdhwr_ccres(t0, cpu_env); 7879 gen_store_gpr(t0, rt); 7880 break; 7881 case 29: 7882 #if defined(CONFIG_USER_ONLY) 7883 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, tls_value)); 7884 gen_store_gpr(t0, rt); 7885 break; 7886 #else 7887 /* XXX: Some CPUs implement this in hardware. 7888 Not supported yet. */ 7889 #endif 7890 default: /* Invalid */ 7891 MIPS_INVAL("rdhwr"); 7892 generate_exception(ctx, EXCP_RI); 7893 break; 7894 } 7895 tcg_temp_free(t0); 7896 } 7897 break; 7898 case OPC_FORK: 7899 check_insn(env, ctx, ASE_MT); 7900 { 7901 TCGv t0 = tcg_temp_new(); 7902 TCGv t1 = tcg_temp_new(); 7903 7904 gen_load_gpr(t0, rt); 7905 gen_load_gpr(t1, rs); 7906 gen_helper_fork(t0, t1); 7907 tcg_temp_free(t0); 7908 tcg_temp_free(t1); 7909 } 7910 break; 7911 case OPC_YIELD: 7912 check_insn(env, ctx, ASE_MT); 7913 { 7914 TCGv t0 = tcg_temp_new(); 7915 7916 save_cpu_state(ctx, 1); 7917 gen_load_gpr(t0, rs); 7918 gen_helper_yield(t0, cpu_env, t0); 7919 gen_store_gpr(t0, rd); 7920 tcg_temp_free(t0); 7921 } 7922 break; 7923 #if defined(TARGET_MIPS64) 7924 case OPC_DEXTM ... OPC_DEXT: 7925 case OPC_DINSM ... OPC_DINS: 7926 check_insn(env, ctx, ISA_MIPS64R2); 7927 check_mips_64(ctx); 7928 gen_bitops(ctx, op1, rt, rs, sa, rd); 7929 break; 7930 case OPC_DBSHFL: 7931 check_insn(env, ctx, ISA_MIPS64R2); 7932 check_mips_64(ctx); 7933 op2 = MASK_DBSHFL(ctx->opcode); 7934 gen_bshfl(ctx, op2, rt, rd); 7935 break; 7936 #endif 7937 default: /* Invalid */ 7938 MIPS_INVAL("special3"); 7939 generate_exception(ctx, EXCP_RI); 7940 break; 7941 } 7942 break; 7943 case OPC_REGIMM: 7944 op1 = MASK_REGIMM(ctx->opcode); 7945 switch (op1) { 7946 case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */ 7947 case OPC_BLTZAL ... OPC_BGEZALL: 7948 gen_compute_branch(ctx, op1, rs, -1, imm << 2); 7949 return; 7950 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */ 7951 case OPC_TNEI: 7952 gen_trap(ctx, op1, rs, -1, imm); 7953 break; 7954 case OPC_SYNCI: 7955 check_insn(env, ctx, ISA_MIPS32R2); 7956 /* Treat as NOP. */ 7957 break; 7958 default: /* Invalid */ 7959 MIPS_INVAL("regimm"); 7960 generate_exception(ctx, EXCP_RI); 7961 break; 7962 } 7963 break; 7964 case OPC_CP0: 7965 check_cp0_enabled(ctx); 7966 op1 = MASK_CP0(ctx->opcode); 7967 switch (op1) { 7968 case OPC_MFC0: 7969 case OPC_MTC0: 7970 case OPC_MFTR: 7971 case OPC_MTTR: 7972 #if defined(TARGET_MIPS64) 7973 case OPC_DMFC0: 7974 case OPC_DMTC0: 7975 #endif 7976 #ifndef CONFIG_USER_ONLY 7977 gen_cp0(env, ctx, op1, rt, rd); 7978 #endif /* !CONFIG_USER_ONLY */ 7979 break; 7980 case OPC_C0_FIRST ... OPC_C0_LAST: 7981 #ifndef CONFIG_USER_ONLY 7982 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd); 7983 #endif /* !CONFIG_USER_ONLY */ 7984 break; 7985 case OPC_MFMC0: 7986 #ifndef CONFIG_USER_ONLY 7987 { 7988 TCGv t0 = tcg_temp_new(); 7989 7990 op2 = MASK_MFMC0(ctx->opcode); 7991 switch (op2) { 7992 case OPC_DMT: 7993 check_insn(env, ctx, ASE_MT); 7994 gen_helper_dmt(t0); 7995 gen_store_gpr(t0, rt); 7996 break; 7997 case OPC_EMT: 7998 check_insn(env, ctx, ASE_MT); 7999 gen_helper_emt(t0); 8000 gen_store_gpr(t0, rt); 8001 break; 8002 case OPC_DVPE: 8003 check_insn(env, ctx, ASE_MT); 8004 gen_helper_dvpe(t0, cpu_env); 8005 gen_store_gpr(t0, rt); 8006 break; 8007 case OPC_EVPE: 8008 check_insn(env, ctx, ASE_MT); 8009 gen_helper_evpe(t0, cpu_env); 8010 gen_store_gpr(t0, rt); 8011 break; 8012 case OPC_DI: 8013 check_insn(env, ctx, ISA_MIPS32R2); 8014 save_cpu_state(ctx, 1); 8015 gen_helper_di(t0, cpu_env); 8016 gen_store_gpr(t0, rt); 8017 /* Stop translation as we may have switched the execution mode */ 8018 ctx->bstate = BS_STOP; 8019 break; 8020 case OPC_EI: 8021 check_insn(env, ctx, ISA_MIPS32R2); 8022 save_cpu_state(ctx, 1); 8023 gen_helper_ei(t0, cpu_env); 8024 gen_store_gpr(t0, rt); 8025 /* Stop translation as we may have switched the execution mode */ 8026 ctx->bstate = BS_STOP; 8027 break; 8028 default: /* Invalid */ 8029 MIPS_INVAL("mfmc0"); 8030 generate_exception(ctx, EXCP_RI); 8031 break; 8032 } 8033 tcg_temp_free(t0); 8034 } 8035 #endif /* !CONFIG_USER_ONLY */ 8036 break; 8037 case OPC_RDPGPR: 8038 check_insn(env, ctx, ISA_MIPS32R2); 8039 gen_load_srsgpr(rt, rd); 8040 break; 8041 case OPC_WRPGPR: 8042 check_insn(env, ctx, ISA_MIPS32R2); 8043 gen_store_srsgpr(rt, rd); 8044 break; 8045 default: 8046 MIPS_INVAL("cp0"); 8047 generate_exception(ctx, EXCP_RI); 8048 break; 8049 } 8050 break; 8051 case OPC_ADDI: /* Arithmetic with immediate opcode */ 8052 case OPC_ADDIU: 8053 gen_arith_imm(env, ctx, op, rt, rs, imm); 8054 break; 8055 case OPC_SLTI: /* Set on less than with immediate opcode */ 8056 case OPC_SLTIU: 8057 gen_slt_imm(env, op, rt, rs, imm); 8058 break; 8059 case OPC_ANDI: /* Arithmetic with immediate opcode */ 8060 case OPC_LUI: 8061 case OPC_ORI: 8062 case OPC_XORI: 8063 gen_logic_imm(env, op, rt, rs, imm); 8064 break; 8065 case OPC_J ... OPC_JAL: /* Jump */ 8066 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2; 8067 gen_compute_branch(ctx, op, rs, rt, offset); 8068 return; 8069 case OPC_BEQ ... OPC_BGTZ: /* Branch */ 8070 case OPC_BEQL ... OPC_BGTZL: 8071 gen_compute_branch(ctx, op, rs, rt, imm << 2); 8072 return; 8073 case OPC_LB ... OPC_LWR: /* Load and stores */ 8074 case OPC_SB ... OPC_SW: 8075 case OPC_SWR: 8076 case OPC_LL: 8077 gen_ldst(ctx, op, rt, rs, imm); 8078 break; 8079 case OPC_SC: 8080 gen_st_cond(ctx, op, rt, rs, imm); 8081 break; 8082 case OPC_CACHE: 8083 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32); 8084 /* Treat as NOP. */ 8085 break; 8086 case OPC_PREF: 8087 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32); 8088 /* Treat as NOP. */ 8089 break; 8090 8091 /* Floating point (COP1). */ 8092 case OPC_LWC1: 8093 case OPC_LDC1: 8094 case OPC_SWC1: 8095 case OPC_SDC1: 8096 if (env->CP0_Config1 & (1 << CP0C1_FP)) { 8097 check_cp1_enabled(ctx); 8098 gen_flt_ldst(ctx, op, rt, rs, imm); 8099 } else { 8100 generate_exception_err(ctx, EXCP_CpU, 1); 8101 } 8102 break; 8103 8104 case OPC_CP1: 8105 if (env->CP0_Config1 & (1 << CP0C1_FP)) { 8106 check_cp1_enabled(ctx); 8107 op1 = MASK_CP1(ctx->opcode); 8108 switch (op1) { 8109 case OPC_MFHC1: 8110 case OPC_MTHC1: 8111 check_insn(env, ctx, ISA_MIPS32R2); 8112 case OPC_MFC1: 8113 case OPC_CFC1: 8114 case OPC_MTC1: 8115 case OPC_CTC1: 8116 gen_cp1(ctx, op1, rt, rd); 8117 break; 8118 #if defined(TARGET_MIPS64) 8119 case OPC_DMFC1: 8120 case OPC_DMTC1: 8121 check_insn(env, ctx, ISA_MIPS3); 8122 gen_cp1(ctx, op1, rt, rd); 8123 break; 8124 #endif 8125 case OPC_BC1ANY2: 8126 case OPC_BC1ANY4: 8127 check_cop1x(ctx); 8128 check_insn(env, ctx, ASE_MIPS3D); 8129 /* fall through */ 8130 case OPC_BC1: 8131 gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode), 8132 (rt >> 2) & 0x7, imm << 2); 8133 return; 8134 case OPC_S_FMT: 8135 case OPC_D_FMT: 8136 case OPC_W_FMT: 8137 case OPC_L_FMT: 8138 case OPC_PS_FMT: 8139 gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa, 8140 (imm >> 8) & 0x7); 8141 break; 8142 default: 8143 MIPS_INVAL("cp1"); 8144 generate_exception (ctx, EXCP_RI); 8145 break; 8146 } 8147 } else { 8148 generate_exception_err(ctx, EXCP_CpU, 1); 8149 } 8150 break; 8151 8152 /* COP2. */ 8153 case OPC_LWC2: 8154 case OPC_LDC2: 8155 case OPC_SWC2: 8156 case OPC_SDC2: 8157 case OPC_CP2: 8158 /* COP2: Not implemented. */ 8159 generate_exception_err(ctx, EXCP_CpU, 2); 8160 break; 8161 8162 case OPC_CP3: 8163 if (env->CP0_Config1 & (1 << CP0C1_FP)) { 8164 check_cp1_enabled(ctx); 8165 op1 = MASK_CP3(ctx->opcode); 8166 switch (op1) { 8167 case OPC_LWXC1: 8168 case OPC_LDXC1: 8169 case OPC_LUXC1: 8170 case OPC_SWXC1: 8171 case OPC_SDXC1: 8172 case OPC_SUXC1: 8173 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt); 8174 break; 8175 case OPC_PREFX: 8176 /* Treat as NOP. */ 8177 break; 8178 case OPC_ALNV_PS: 8179 case OPC_MADD_S: 8180 case OPC_MADD_D: 8181 case OPC_MADD_PS: 8182 case OPC_MSUB_S: 8183 case OPC_MSUB_D: 8184 case OPC_MSUB_PS: 8185 case OPC_NMADD_S: 8186 case OPC_NMADD_D: 8187 case OPC_NMADD_PS: 8188 case OPC_NMSUB_S: 8189 case OPC_NMSUB_D: 8190 case OPC_NMSUB_PS: 8191 gen_flt3_arith(ctx, op1, sa, rs, rd, rt); 8192 break; 8193 default: 8194 MIPS_INVAL("cp3"); 8195 generate_exception (ctx, EXCP_RI); 8196 break; 8197 } 8198 } else { 8199 generate_exception_err(ctx, EXCP_CpU, 1); 8200 } 8201 break; 8202 8203 #if defined(TARGET_MIPS64) 8204 /* MIPS64 opcodes */ 8205 case OPC_LWU: 8206 case OPC_LDL ... OPC_LDR: 8207 case OPC_SDL ... OPC_SDR: 8208 case OPC_LLD: 8209 case OPC_LD: 8210 case OPC_SD: 8211 check_insn(env, ctx, ISA_MIPS3); 8212 check_mips_64(ctx); 8213 gen_ldst(ctx, op, rt, rs, imm); 8214 break; 8215 case OPC_SCD: 8216 check_insn(env, ctx, ISA_MIPS3); 8217 check_mips_64(ctx); 8218 gen_st_cond(ctx, op, rt, rs, imm); 8219 break; 8220 case OPC_DADDI: 8221 case OPC_DADDIU: 8222 check_insn(env, ctx, ISA_MIPS3); 8223 check_mips_64(ctx); 8224 gen_arith_imm(env, ctx, op, rt, rs, imm); 8225 break; 8226 #endif 8227 case OPC_JALX: 8228 check_insn(env, ctx, ASE_MIPS16); 8229 /* MIPS16: Not implemented. */ 8230 case OPC_MDMX: 8231 check_insn(env, ctx, ASE_MDMX); 8232 /* MDMX: Not implemented. */ 8233 default: /* Invalid */ 8234 MIPS_INVAL("major opcode"); 8235 generate_exception(ctx, EXCP_RI); 8236 break; 8237 } 8238 if (ctx->hflags & MIPS_HFLAG_BMASK) { 8239 int hflags = ctx->hflags & MIPS_HFLAG_BMASK; 8240 /* Branches completion */ 8241 ctx->hflags &= ~MIPS_HFLAG_BMASK; 8242 ctx->bstate = BS_BRANCH; 8243 save_cpu_state(ctx, 0); 8244 /* FIXME: Need to clear can_do_io. */ 8245 switch (hflags) { 8246 case MIPS_HFLAG_B: 8247 /* unconditional branch */ 8248 MIPS_DEBUG("unconditional branch"); 8249 gen_goto_tb(ctx, 0, ctx->btarget); 8250 break; 8251 case MIPS_HFLAG_BL: 8252 /* blikely taken case */ 8253 MIPS_DEBUG("blikely branch taken"); 8254 gen_goto_tb(ctx, 0, ctx->btarget); 8255 break; 8256 case MIPS_HFLAG_BC: 8257 /* Conditional branch */ 8258 MIPS_DEBUG("conditional branch"); 8259 { 8260 int l1 = gen_new_label(); 8261 8262 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1); 8263 gen_goto_tb(ctx, 1, ctx->pc + 4); 8264 gen_set_label(l1); 8265 gen_goto_tb(ctx, 0, ctx->btarget); 8266 } 8267 break; 8268 case MIPS_HFLAG_BR: 8269 /* unconditional branch to register */ 8270 MIPS_DEBUG("branch to register"); 8271 tcg_gen_mov_tl(cpu_PC, btarget); 8272 if (ctx->singlestep_enabled) { 8273 save_cpu_state(ctx, 0); 8274 gen_helper_1i(raise_exception, cpu_env, EXCP_DEBUG); 8275 } 8276 tcg_gen_exit_tb(0); 8277 break; 8278 default: 8279 MIPS_DEBUG("unknown branch"); 8280 break; 8281 } 8282 } 8283 } 8284 8285 static inline void 8286 gen_intermediate_code_internal (CPUMIPSState *env, TranslationBlock *tb, 8287 int search_pc) 8288 { 8289 DisasContext ctx; 8290 target_ulong pc_start; 8291 uint16_t *gen_opc_end; 8292 CPUBreakpoint *bp; 8293 int j, lj = -1; 8294 int num_insns; 8295 int max_insns; 8296 8297 if (search_pc) 8298 qemu_log("search pc %d\n", search_pc); 8299 8300 pc_start = tb->pc; 8301 gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE; 8302 ctx.pc = pc_start; 8303 ctx.saved_pc = -1; 8304 ctx.singlestep_enabled = ENV_GET_CPU(env)->singlestep_enabled; 8305 ctx.tb = tb; 8306 ctx.bstate = BS_NONE; 8307 /* Restore delay slot state from the tb context. */ 8308 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */ 8309 restore_cpu_state(env, &ctx); 8310 #ifdef CONFIG_USER_ONLY 8311 ctx.mem_idx = MIPS_HFLAG_UM; 8312 #else 8313 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU; 8314 #endif 8315 num_insns = 0; 8316 max_insns = tb->cflags & CF_COUNT_MASK; 8317 if (max_insns == 0) 8318 max_insns = CF_COUNT_MASK; 8319 #ifdef DEBUG_DISAS 8320 qemu_log_mask(CPU_LOG_TB_CPU, "------------------------------------------------\n"); 8321 /* FIXME: This may print out stale hflags from env... */ 8322 log_cpu_state_mask(CPU_LOG_TB_CPU, ENV_GET_CPU(env), 0); 8323 #endif 8324 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags); 8325 gen_icount_start(); 8326 while (ctx.bstate == BS_NONE) { 8327 if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) { 8328 QTAILQ_FOREACH(bp, &env->breakpoints, entry) { 8329 if (bp->pc == ctx.pc) { 8330 save_cpu_state(&ctx, 1); 8331 ctx.bstate = BS_BRANCH; 8332 gen_helper_1i(raise_exception, cpu_env, EXCP_DEBUG); 8333 /* Include the breakpoint location or the tb won't 8334 * be flushed when it must be. */ 8335 ctx.pc += 4; 8336 goto done_generating; 8337 } 8338 } 8339 } 8340 8341 if (search_pc) { 8342 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf; 8343 if (lj < j) { 8344 lj++; 8345 while (lj < j) 8346 tcg_ctx.gen_opc_instr_start[lj++] = 0; 8347 } 8348 tcg_ctx.gen_opc_pc[lj] = ctx.pc; 8349 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK; 8350 tcg_ctx.gen_opc_instr_start[lj] = 1; 8351 tcg_ctx.gen_opc_icount[lj] = num_insns; 8352 } 8353 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO)) 8354 gen_io_start(); 8355 ctx.opcode = cpu_ldl_code(env, ctx.pc); 8356 decode_opc(env, &ctx); 8357 ctx.pc += 4; 8358 num_insns++; 8359 8360 /* Execute a branch and its delay slot as a single instruction. 8361 This is what GDB expects and is consistent with what the 8362 hardware does (e.g. if a delay slot instruction faults, the 8363 reported PC is the PC of the branch). */ 8364 if (ENV_GET_CPU(env)->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0) 8365 break; 8366 8367 /* Do not split a branch instruction and its delay slot into two 8368 TB's when a page boundary is crossed. This causes TB's to be 8369 invalidated incorrectly if branch target is patched. */ 8370 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0 && (ctx.hflags & MIPS_HFLAG_BMASK) == 0) 8371 break; 8372 8373 if (tcg_ctx.gen_opc_ptr >= gen_opc_end) 8374 break; 8375 8376 if (num_insns >= max_insns) 8377 break; 8378 8379 if (singlestep) 8380 break; 8381 } 8382 if (tb->cflags & CF_LAST_IO) 8383 gen_io_end(); 8384 if (ENV_GET_CPU(env)->singlestep_enabled && ctx.bstate != BS_BRANCH) { 8385 save_cpu_state(&ctx, ctx.bstate == BS_NONE); 8386 gen_helper_1i(raise_exception, cpu_env, EXCP_DEBUG); 8387 } else { 8388 switch (ctx.bstate) { 8389 case BS_STOP: 8390 gen_helper_interrupt_restart(cpu_env); 8391 gen_goto_tb(&ctx, 0, ctx.pc); 8392 break; 8393 case BS_NONE: 8394 save_cpu_state(&ctx, 0); 8395 gen_goto_tb(&ctx, 0, ctx.pc); 8396 break; 8397 case BS_EXCP: 8398 gen_helper_interrupt_restart(cpu_env); 8399 tcg_gen_exit_tb(0); 8400 break; 8401 case BS_BRANCH: 8402 default: 8403 break; 8404 } 8405 } 8406 done_generating: 8407 gen_icount_end(tb, num_insns); 8408 *tcg_ctx.gen_opc_ptr = INDEX_op_end; 8409 if (search_pc) { 8410 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf; 8411 lj++; 8412 while (lj <= j) 8413 tcg_ctx.gen_opc_instr_start[lj++] = 0; 8414 } else { 8415 tb->size = ctx.pc - pc_start; 8416 tb->icount = num_insns; 8417 } 8418 #ifdef DEBUG_DISAS 8419 LOG_DISAS("\n"); 8420 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) { 8421 qemu_log("IN: %s\n", lookup_symbol(pc_start)); 8422 log_target_disas(env, pc_start, ctx.pc - pc_start, 0); 8423 qemu_log("\n"); 8424 } 8425 qemu_log_mask(CPU_LOG_TB_CPU, "---------------- %d %08x\n", ctx.bstate, ctx.hflags); 8426 #endif 8427 } 8428 8429 void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb) 8430 { 8431 gen_intermediate_code_internal(env, tb, 0); 8432 } 8433 8434 void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb) 8435 { 8436 gen_intermediate_code_internal(env, tb, 1); 8437 } 8438 8439 static void fpu_dump_state(CPUMIPSState *env, FILE *f, 8440 int (*fpu_fprintf)(FILE *f, const char *fmt, ...), 8441 int flags) 8442 { 8443 int i; 8444 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64); 8445 8446 #define printfpr(fp) \ 8447 do { \ 8448 if (is_fpu64) \ 8449 fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu: %13g\n", \ 8450 (fp)->w[FP_ENDIAN_IDX], (fp)->d, (fp)->fd, \ 8451 (fp)->fs[FP_ENDIAN_IDX], (fp)->fs[!FP_ENDIAN_IDX]); \ 8452 else { \ 8453 fpr_t tmp; \ 8454 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \ 8455 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \ 8456 fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu:%13g\n", \ 8457 tmp.w[FP_ENDIAN_IDX], tmp.d, tmp.fd, \ 8458 tmp.fs[FP_ENDIAN_IDX], tmp.fs[!FP_ENDIAN_IDX]); \ 8459 } \ 8460 } while(0) 8461 8462 8463 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%08x(0x%02x)\n", 8464 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64, env->active_fpu.fp_status, 8465 get_float_exception_flags(&env->active_fpu.fp_status)); 8466 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) { 8467 fpu_fprintf(f, "%3s: ", fregnames[i]); 8468 printfpr(&env->active_fpu.fpr[i]); 8469 } 8470 8471 #undef printfpr 8472 } 8473 8474 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS) 8475 /* Debug help: The architecture requires 32bit code to maintain proper 8476 sign-extended values on 64bit machines. */ 8477 8478 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff)) 8479 8480 static void 8481 cpu_mips_check_sign_extensions (CPUMIPSState *env, FILE *f, 8482 int (*cpu_fprintf)(FILE *f, const char *fmt, ...), 8483 int flags) 8484 { 8485 int i; 8486 8487 if (!SIGN_EXT_P(env->active_tc.PC)) 8488 cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC); 8489 if (!SIGN_EXT_P(env->active_tc.HI[0])) 8490 cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]); 8491 if (!SIGN_EXT_P(env->active_tc.LO[0])) 8492 cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]); 8493 if (!SIGN_EXT_P(env->btarget)) 8494 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget); 8495 8496 for (i = 0; i < 32; i++) { 8497 if (!SIGN_EXT_P(env->active_tc.gpr[i])) 8498 cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]); 8499 } 8500 8501 if (!SIGN_EXT_P(env->CP0_EPC)) 8502 cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC); 8503 if (!SIGN_EXT_P(env->lladdr)) 8504 cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr); 8505 } 8506 #endif 8507 8508 void cpu_dump_state (CPUState *cpu, FILE *f, 8509 int (*cpu_fprintf)(FILE *f, const char *fmt, ...), 8510 int flags) 8511 { 8512 CPUMIPSState *env = cpu->env_ptr; 8513 int i; 8514 8515 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx " %d\n", 8516 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0], 8517 env->hflags, env->btarget, env->bcond); 8518 for (i = 0; i < 32; i++) { 8519 if ((i & 3) == 0) 8520 cpu_fprintf(f, "GPR%02d:", i); 8521 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]); 8522 if ((i & 3) == 3) 8523 cpu_fprintf(f, "\n"); 8524 } 8525 8526 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n", 8527 env->CP0_Status, env->CP0_Cause, env->CP0_EPC); 8528 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n", 8529 env->CP0_Config0, env->CP0_Config1, env->lladdr); 8530 if (env->hflags & MIPS_HFLAG_FPU) 8531 fpu_dump_state(env, f, cpu_fprintf, flags); 8532 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS) 8533 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags); 8534 #endif 8535 } 8536 8537 static void mips_tcg_init(void) 8538 { 8539 int i; 8540 static int inited; 8541 8542 /* Initialize various static tables. */ 8543 if (inited) 8544 return; 8545 8546 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env"); 8547 TCGV_UNUSED(cpu_gpr[0]); 8548 for (i = 1; i < 32; i++) 8549 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0, 8550 offsetof(CPUMIPSState, active_tc.gpr[i]), 8551 regnames[i]); 8552 cpu_PC = tcg_global_mem_new(TCG_AREG0, 8553 offsetof(CPUMIPSState, active_tc.PC), "PC"); 8554 for (i = 0; i < MIPS_DSP_ACC; i++) { 8555 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0, 8556 offsetof(CPUMIPSState, active_tc.HI[i]), 8557 regnames_HI[i]); 8558 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0, 8559 offsetof(CPUMIPSState, active_tc.LO[i]), 8560 regnames_LO[i]); 8561 cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0, 8562 offsetof(CPUMIPSState, active_tc.ACX[i]), 8563 regnames_ACX[i]); 8564 } 8565 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0, 8566 offsetof(CPUMIPSState, active_tc.DSPControl), 8567 "DSPControl"); 8568 bcond = tcg_global_mem_new(TCG_AREG0, 8569 offsetof(CPUMIPSState, bcond), "bcond"); 8570 btarget = tcg_global_mem_new(TCG_AREG0, 8571 offsetof(CPUMIPSState, btarget), "btarget"); 8572 hflags = tcg_global_mem_new_i32(TCG_AREG0, 8573 offsetof(CPUMIPSState, hflags), "hflags"); 8574 8575 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0, 8576 offsetof(CPUMIPSState, active_fpu.fcr0), 8577 "fcr0"); 8578 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0, 8579 offsetof(CPUMIPSState, active_fpu.fcr31), 8580 "fcr31"); 8581 inited = 1; 8582 } 8583 8584 #include "translate_init.c" 8585 8586 CPUMIPSState *cpu_mips_init (const char *cpu_model) 8587 { 8588 MIPSCPU *mips_cpu; 8589 CPUMIPSState *env; 8590 CPUState *cpu; 8591 const mips_def_t *def; 8592 8593 def = cpu_mips_find_by_name(cpu_model); 8594 if (!def) 8595 return NULL; 8596 mips_cpu = g_malloc0(sizeof(MIPSCPU)); 8597 env = &mips_cpu->env; 8598 ENV_GET_CPU(env)->env_ptr = env; 8599 8600 cpu = ENV_GET_CPU(env); 8601 env->cpu_model = def; 8602 cpu->cpu_model_str = cpu_model; 8603 8604 cpu_exec_init(env); 8605 #ifndef CONFIG_USER_ONLY 8606 mmu_init(env, def); 8607 #endif 8608 mvp_init(env, def); 8609 mips_tcg_init(); 8610 cpu_reset(cpu); 8611 qemu_init_vcpu(cpu); 8612 return env; 8613 } 8614 8615 void cpu_reset(CPUState *cpu) 8616 { 8617 CPUMIPSState *env = cpu->env_ptr; 8618 8619 if (qemu_loglevel_mask(CPU_LOG_RESET)) { 8620 qemu_log("CPU Reset (CPU %d)\n", cpu->cpu_index); 8621 log_cpu_state(cpu, 0); 8622 } 8623 8624 memset(env, 0, offsetof(CPUMIPSState, breakpoints)); 8625 tlb_flush(env, 1); 8626 8627 /* Reset registers to their default values */ 8628 env->CP0_PRid = env->cpu_model->CP0_PRid; 8629 env->CP0_Config0 = env->cpu_model->CP0_Config0; 8630 #ifdef TARGET_WORDS_BIGENDIAN 8631 env->CP0_Config0 |= (1 << CP0C0_BE); 8632 #endif 8633 env->CP0_Config1 = env->cpu_model->CP0_Config1; 8634 env->CP0_Config2 = env->cpu_model->CP0_Config2; 8635 env->CP0_Config3 = env->cpu_model->CP0_Config3; 8636 env->CP0_Config6 = env->cpu_model->CP0_Config6; 8637 env->CP0_Config7 = env->cpu_model->CP0_Config7; 8638 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask 8639 << env->cpu_model->CP0_LLAddr_shift; 8640 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift; 8641 env->SYNCI_Step = env->cpu_model->SYNCI_Step; 8642 env->CCRes = env->cpu_model->CCRes; 8643 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask; 8644 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask; 8645 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl; 8646 env->current_tc = 0; 8647 env->SEGBITS = env->cpu_model->SEGBITS; 8648 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1); 8649 #if defined(TARGET_MIPS64) 8650 if (env->cpu_model->insn_flags & ISA_MIPS3) { 8651 env->SEGMask |= 3ULL << 62; 8652 } 8653 #endif 8654 env->PABITS = env->cpu_model->PABITS; 8655 env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1); 8656 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask; 8657 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0; 8658 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask; 8659 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1; 8660 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask; 8661 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2; 8662 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask; 8663 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3; 8664 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask; 8665 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4; 8666 env->insn_flags = env->cpu_model->insn_flags; 8667 8668 fpu_init(env, env->cpu_model); 8669 8670 #if defined(CONFIG_USER_ONLY) 8671 env->hflags = MIPS_HFLAG_UM; 8672 /* Enable access to the SYNCI_Step register. */ 8673 env->CP0_HWREna |= (1 << 1); 8674 if (env->CP0_Config1 & (1 << CP0C1_FP)) { 8675 env->hflags |= MIPS_HFLAG_FPU; 8676 } 8677 #ifdef TARGET_MIPS64 8678 if (env->active_fpu.fcr0 & (1 << FCR0_F64)) { 8679 env->hflags |= MIPS_HFLAG_F64; 8680 } 8681 #endif 8682 #else 8683 if (env->hflags & MIPS_HFLAG_BMASK) { 8684 /* If the exception was raised from a delay slot, 8685 come back to the jump. */ 8686 env->CP0_ErrorEPC = env->active_tc.PC - 4; 8687 } else { 8688 env->CP0_ErrorEPC = env->active_tc.PC; 8689 } 8690 env->active_tc.PC = (int32_t)0xBFC00000; 8691 env->CP0_Random = env->tlb->nb_tlb - 1; 8692 env->CP0_Wired = 0; 8693 /* SMP not implemented */ 8694 env->CP0_EBase = 0x80000000; 8695 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL); 8696 /* vectored interrupts not implemented, timer on int 7, 8697 no performance counters. */ 8698 env->CP0_IntCtl = 0xe0000000; 8699 { 8700 int i; 8701 8702 for (i = 0; i < 7; i++) { 8703 env->CP0_WatchLo[i] = 0; 8704 env->CP0_WatchHi[i] = 0x80000000; 8705 } 8706 env->CP0_WatchLo[7] = 0; 8707 env->CP0_WatchHi[7] = 0; 8708 } 8709 /* Count register increments in debug mode, EJTAG version 1 */ 8710 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER); 8711 env->hflags = MIPS_HFLAG_CP0; 8712 #endif 8713 #if defined(TARGET_MIPS64) 8714 if (env->cpu_model->insn_flags & ISA_MIPS3) { 8715 env->hflags |= MIPS_HFLAG_64; 8716 } 8717 #endif 8718 env->exception_index = EXCP_NONE; 8719 } 8720 8721 void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos) 8722 { 8723 env->active_tc.PC = tcg_ctx.gen_opc_pc[pc_pos]; 8724 env->hflags &= ~MIPS_HFLAG_BMASK; 8725 env->hflags |= gen_opc_hflags[pc_pos]; 8726 } 8727