1 // Copyright 2012 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef V8_MIPS_CONSTANTS_H_ 6 #define V8_MIPS_CONSTANTS_H_ 7 8 #include "src/base/logging.h" 9 #include "src/base/macros.h" 10 #include "src/globals.h" 11 12 // UNIMPLEMENTED_ macro for MIPS. 13 #ifdef DEBUG 14 #define UNIMPLEMENTED_MIPS() \ 15 v8::internal::PrintF("%s, \tline %d: \tfunction %s not implemented. \n", \ 16 __FILE__, __LINE__, __func__) 17 #else 18 #define UNIMPLEMENTED_MIPS() 19 #endif 20 21 #define UNSUPPORTED_MIPS() v8::internal::PrintF("Unsupported instruction.\n") 22 23 enum ArchVariants { 24 kMips64r2, 25 kMips64r6 26 }; 27 28 29 #ifdef _MIPS_ARCH_MIPS64R2 30 static const ArchVariants kArchVariant = kMips64r2; 31 #elif _MIPS_ARCH_MIPS64R6 32 static const ArchVariants kArchVariant = kMips64r6; 33 #else 34 static const ArchVariants kArchVariant = kMips64r2; 35 #endif 36 37 38 enum Endianness { kLittle, kBig }; 39 40 #if defined(V8_TARGET_LITTLE_ENDIAN) 41 static const Endianness kArchEndian = kLittle; 42 #elif defined(V8_TARGET_BIG_ENDIAN) 43 static const Endianness kArchEndian = kBig; 44 #else 45 #error Unknown endianness 46 #endif 47 48 // TODO(plind): consider deriving ABI from compiler flags or build system. 49 50 // ABI-dependent definitions are made with #define in simulator-mips64.h, 51 // so the ABI choice must be available to the pre-processor. However, in all 52 // other cases, we should use the enum AbiVariants with normal if statements. 53 54 #define MIPS_ABI_N64 1 55 // #define MIPS_ABI_O32 1 56 57 // The only supported Abi's are O32, and n64. 58 enum AbiVariants { 59 kO32, 60 kN64 // Use upper case N for 'n64' ABI to conform to style standard. 61 }; 62 63 #ifdef MIPS_ABI_N64 64 static const AbiVariants kMipsAbi = kN64; 65 #else 66 static const AbiVariants kMipsAbi = kO32; 67 #endif 68 69 70 // TODO(plind): consider renaming these ... 71 #if(defined(__mips_hard_float) && __mips_hard_float != 0) 72 // Use floating-point coprocessor instructions. This flag is raised when 73 // -mhard-float is passed to the compiler. 74 const bool IsMipsSoftFloatABI = false; 75 #elif(defined(__mips_soft_float) && __mips_soft_float != 0) 76 // This flag is raised when -msoft-float is passed to the compiler. 77 // Although FPU is a base requirement for v8, soft-float ABI is used 78 // on soft-float systems with FPU kernel emulation. 79 const bool IsMipsSoftFloatABI = true; 80 #else 81 const bool IsMipsSoftFloatABI = true; 82 #endif 83 84 85 #ifndef __STDC_FORMAT_MACROS 86 #define __STDC_FORMAT_MACROS 87 #endif 88 #include <inttypes.h> 89 90 91 // Defines constants and accessor classes to assemble, disassemble and 92 // simulate MIPS32 instructions. 93 // 94 // See: MIPS32 Architecture For Programmers 95 // Volume II: The MIPS32 Instruction Set 96 // Try www.cs.cornell.edu/courses/cs3410/2008fa/MIPS_Vol2.pdf. 97 98 namespace v8 { 99 namespace internal { 100 101 // ----------------------------------------------------------------------------- 102 // Registers and FPURegisters. 103 104 // Number of general purpose registers. 105 const int kNumRegisters = 32; 106 const int kInvalidRegister = -1; 107 108 // Number of registers with HI, LO, and pc. 109 const int kNumSimuRegisters = 35; 110 111 // In the simulator, the PC register is simulated as the 34th register. 112 const int kPCRegister = 34; 113 114 // Number coprocessor registers. 115 const int kNumFPURegisters = 32; 116 const int kInvalidFPURegister = -1; 117 118 // FPU (coprocessor 1) control registers. Currently only FCSR is implemented. 119 const int kFCSRRegister = 31; 120 const int kInvalidFPUControlRegister = -1; 121 const uint32_t kFPUInvalidResult = static_cast<uint32_t>(1 << 31) - 1; 122 const int32_t kFPUInvalidResultNegative = static_cast<int32_t>(1 << 31); 123 const uint64_t kFPU64InvalidResult = 124 static_cast<uint64_t>(static_cast<uint64_t>(1) << 63) - 1; 125 const int64_t kFPU64InvalidResultNegative = 126 static_cast<int64_t>(static_cast<uint64_t>(1) << 63); 127 128 // FCSR constants. 129 const uint32_t kFCSRInexactFlagBit = 2; 130 const uint32_t kFCSRUnderflowFlagBit = 3; 131 const uint32_t kFCSROverflowFlagBit = 4; 132 const uint32_t kFCSRDivideByZeroFlagBit = 5; 133 const uint32_t kFCSRInvalidOpFlagBit = 6; 134 const uint32_t kFCSRNaN2008FlagBit = 18; 135 136 const uint32_t kFCSRInexactFlagMask = 1 << kFCSRInexactFlagBit; 137 const uint32_t kFCSRUnderflowFlagMask = 1 << kFCSRUnderflowFlagBit; 138 const uint32_t kFCSROverflowFlagMask = 1 << kFCSROverflowFlagBit; 139 const uint32_t kFCSRDivideByZeroFlagMask = 1 << kFCSRDivideByZeroFlagBit; 140 const uint32_t kFCSRInvalidOpFlagMask = 1 << kFCSRInvalidOpFlagBit; 141 const uint32_t kFCSRNaN2008FlagMask = 1 << kFCSRNaN2008FlagBit; 142 143 const uint32_t kFCSRFlagMask = 144 kFCSRInexactFlagMask | 145 kFCSRUnderflowFlagMask | 146 kFCSROverflowFlagMask | 147 kFCSRDivideByZeroFlagMask | 148 kFCSRInvalidOpFlagMask; 149 150 const uint32_t kFCSRExceptionFlagMask = kFCSRFlagMask ^ kFCSRInexactFlagMask; 151 152 // 'pref' instruction hints 153 const int32_t kPrefHintLoad = 0; 154 const int32_t kPrefHintStore = 1; 155 const int32_t kPrefHintLoadStreamed = 4; 156 const int32_t kPrefHintStoreStreamed = 5; 157 const int32_t kPrefHintLoadRetained = 6; 158 const int32_t kPrefHintStoreRetained = 7; 159 const int32_t kPrefHintWritebackInvalidate = 25; 160 const int32_t kPrefHintPrepareForStore = 30; 161 162 // Helper functions for converting between register numbers and names. 163 class Registers { 164 public: 165 // Return the name of the register. 166 static const char* Name(int reg); 167 168 // Lookup the register number for the name provided. 169 static int Number(const char* name); 170 171 struct RegisterAlias { 172 int reg; 173 const char* name; 174 }; 175 176 static const int64_t kMaxValue = 0x7fffffffffffffffl; 177 static const int64_t kMinValue = 0x8000000000000000l; 178 179 private: 180 static const char* names_[kNumSimuRegisters]; 181 static const RegisterAlias aliases_[]; 182 }; 183 184 // Helper functions for converting between register numbers and names. 185 class FPURegisters { 186 public: 187 // Return the name of the register. 188 static const char* Name(int reg); 189 190 // Lookup the register number for the name provided. 191 static int Number(const char* name); 192 193 struct RegisterAlias { 194 int creg; 195 const char* name; 196 }; 197 198 private: 199 static const char* names_[kNumFPURegisters]; 200 static const RegisterAlias aliases_[]; 201 }; 202 203 204 // ----------------------------------------------------------------------------- 205 // Instructions encoding constants. 206 207 // On MIPS all instructions are 32 bits. 208 typedef int32_t Instr; 209 210 // Special Software Interrupt codes when used in the presence of the MIPS 211 // simulator. 212 enum SoftwareInterruptCodes { 213 // Transition to C code. 214 call_rt_redirected = 0xfffff 215 }; 216 217 // On MIPS Simulator breakpoints can have different codes: 218 // - Breaks between 0 and kMaxWatchpointCode are treated as simple watchpoints, 219 // the simulator will run through them and print the registers. 220 // - Breaks between kMaxWatchpointCode and kMaxStopCode are treated as stop() 221 // instructions (see Assembler::stop()). 222 // - Breaks larger than kMaxStopCode are simple breaks, dropping you into the 223 // debugger. 224 const uint32_t kMaxWatchpointCode = 31; 225 const uint32_t kMaxStopCode = 127; 226 STATIC_ASSERT(kMaxWatchpointCode < kMaxStopCode); 227 228 229 // ----- Fields offset and length. 230 const int kOpcodeShift = 26; 231 const int kOpcodeBits = 6; 232 const int kRsShift = 21; 233 const int kRsBits = 5; 234 const int kRtShift = 16; 235 const int kRtBits = 5; 236 const int kRdShift = 11; 237 const int kRdBits = 5; 238 const int kSaShift = 6; 239 const int kSaBits = 5; 240 const int kLsaSaBits = 2; 241 const int kFunctionShift = 0; 242 const int kFunctionBits = 6; 243 const int kLuiShift = 16; 244 const int kBp2Shift = 6; 245 const int kBp2Bits = 2; 246 const int kBp3Shift = 6; 247 const int kBp3Bits = 3; 248 249 const int kImm16Shift = 0; 250 const int kImm16Bits = 16; 251 const int kImm18Shift = 0; 252 const int kImm18Bits = 18; 253 const int kImm19Shift = 0; 254 const int kImm19Bits = 19; 255 const int kImm21Shift = 0; 256 const int kImm21Bits = 21; 257 const int kImm26Shift = 0; 258 const int kImm26Bits = 26; 259 const int kImm28Shift = 0; 260 const int kImm28Bits = 28; 261 const int kImm32Shift = 0; 262 const int kImm32Bits = 32; 263 264 // In branches and jumps immediate fields point to words, not bytes, 265 // and are therefore shifted by 2. 266 const int kImmFieldShift = 2; 267 268 const int kFrBits = 5; 269 const int kFrShift = 21; 270 const int kFsShift = 11; 271 const int kFsBits = 5; 272 const int kFtShift = 16; 273 const int kFtBits = 5; 274 const int kFdShift = 6; 275 const int kFdBits = 5; 276 const int kFCccShift = 8; 277 const int kFCccBits = 3; 278 const int kFBccShift = 18; 279 const int kFBccBits = 3; 280 const int kFBtrueShift = 16; 281 const int kFBtrueBits = 1; 282 283 // ----- Miscellaneous useful masks. 284 // Instruction bit masks. 285 const int kOpcodeMask = ((1 << kOpcodeBits) - 1) << kOpcodeShift; 286 const int kImm16Mask = ((1 << kImm16Bits) - 1) << kImm16Shift; 287 const int kImm18Mask = ((1 << kImm18Bits) - 1) << kImm18Shift; 288 const int kImm19Mask = ((1 << kImm19Bits) - 1) << kImm19Shift; 289 const int kImm21Mask = ((1 << kImm21Bits) - 1) << kImm21Shift; 290 const int kImm26Mask = ((1 << kImm26Bits) - 1) << kImm26Shift; 291 const int kImm28Mask = ((1 << kImm28Bits) - 1) << kImm28Shift; 292 const int kRsFieldMask = ((1 << kRsBits) - 1) << kRsShift; 293 const int kRtFieldMask = ((1 << kRtBits) - 1) << kRtShift; 294 const int kRdFieldMask = ((1 << kRdBits) - 1) << kRdShift; 295 const int kSaFieldMask = ((1 << kSaBits) - 1) << kSaShift; 296 const int kFunctionFieldMask = ((1 << kFunctionBits) - 1) << kFunctionShift; 297 // Misc masks. 298 const int kHiMask = 0xffff << 16; 299 const int kLoMask = 0xffff; 300 const int kSignMask = 0x80000000; 301 const int kJumpAddrMask = (1 << (kImm26Bits + kImmFieldShift)) - 1; 302 const int64_t kHi16MaskOf64 = (int64_t)0xffff << 48; 303 const int64_t kSe16MaskOf64 = (int64_t)0xffff << 32; 304 const int64_t kTh16MaskOf64 = (int64_t)0xffff << 16; 305 const int32_t kJalRawMark = 0x00000000; 306 const int32_t kJRawMark = 0xf0000000; 307 const int32_t kJumpRawMask = 0xf0000000; 308 309 // ----- MIPS Opcodes and Function Fields. 310 // We use this presentation to stay close to the table representation in 311 // MIPS32 Architecture For Programmers, Volume II: The MIPS32 Instruction Set. 312 enum Opcode : uint32_t { 313 SPECIAL = 0U << kOpcodeShift, 314 REGIMM = 1U << kOpcodeShift, 315 316 J = ((0U << 3) + 2) << kOpcodeShift, 317 JAL = ((0U << 3) + 3) << kOpcodeShift, 318 BEQ = ((0U << 3) + 4) << kOpcodeShift, 319 BNE = ((0U << 3) + 5) << kOpcodeShift, 320 BLEZ = ((0U << 3) + 6) << kOpcodeShift, 321 BGTZ = ((0U << 3) + 7) << kOpcodeShift, 322 323 ADDI = ((1U << 3) + 0) << kOpcodeShift, 324 ADDIU = ((1U << 3) + 1) << kOpcodeShift, 325 SLTI = ((1U << 3) + 2) << kOpcodeShift, 326 SLTIU = ((1U << 3) + 3) << kOpcodeShift, 327 ANDI = ((1U << 3) + 4) << kOpcodeShift, 328 ORI = ((1U << 3) + 5) << kOpcodeShift, 329 XORI = ((1U << 3) + 6) << kOpcodeShift, 330 LUI = ((1U << 3) + 7) << kOpcodeShift, // LUI/AUI family. 331 DAUI = ((3U << 3) + 5) << kOpcodeShift, 332 333 BEQC = ((2U << 3) + 0) << kOpcodeShift, 334 COP1 = ((2U << 3) + 1) << kOpcodeShift, // Coprocessor 1 class. 335 BEQL = ((2U << 3) + 4) << kOpcodeShift, 336 BNEL = ((2U << 3) + 5) << kOpcodeShift, 337 BLEZL = ((2U << 3) + 6) << kOpcodeShift, 338 BGTZL = ((2U << 3) + 7) << kOpcodeShift, 339 340 DADDI = ((3U << 3) + 0) << kOpcodeShift, // This is also BNEC. 341 DADDIU = ((3U << 3) + 1) << kOpcodeShift, 342 LDL = ((3U << 3) + 2) << kOpcodeShift, 343 LDR = ((3U << 3) + 3) << kOpcodeShift, 344 SPECIAL2 = ((3U << 3) + 4) << kOpcodeShift, 345 SPECIAL3 = ((3U << 3) + 7) << kOpcodeShift, 346 347 LB = ((4U << 3) + 0) << kOpcodeShift, 348 LH = ((4U << 3) + 1) << kOpcodeShift, 349 LWL = ((4U << 3) + 2) << kOpcodeShift, 350 LW = ((4U << 3) + 3) << kOpcodeShift, 351 LBU = ((4U << 3) + 4) << kOpcodeShift, 352 LHU = ((4U << 3) + 5) << kOpcodeShift, 353 LWR = ((4U << 3) + 6) << kOpcodeShift, 354 LWU = ((4U << 3) + 7) << kOpcodeShift, 355 356 SB = ((5U << 3) + 0) << kOpcodeShift, 357 SH = ((5U << 3) + 1) << kOpcodeShift, 358 SWL = ((5U << 3) + 2) << kOpcodeShift, 359 SW = ((5U << 3) + 3) << kOpcodeShift, 360 SDL = ((5U << 3) + 4) << kOpcodeShift, 361 SDR = ((5U << 3) + 5) << kOpcodeShift, 362 SWR = ((5U << 3) + 6) << kOpcodeShift, 363 364 LWC1 = ((6U << 3) + 1) << kOpcodeShift, 365 BC = ((6U << 3) + 2) << kOpcodeShift, 366 LLD = ((6U << 3) + 4) << kOpcodeShift, 367 LDC1 = ((6U << 3) + 5) << kOpcodeShift, 368 POP66 = ((6U << 3) + 6) << kOpcodeShift, 369 LD = ((6U << 3) + 7) << kOpcodeShift, 370 371 PREF = ((6U << 3) + 3) << kOpcodeShift, 372 373 SWC1 = ((7U << 3) + 1) << kOpcodeShift, 374 BALC = ((7U << 3) + 2) << kOpcodeShift, 375 PCREL = ((7U << 3) + 3) << kOpcodeShift, 376 SCD = ((7U << 3) + 4) << kOpcodeShift, 377 SDC1 = ((7U << 3) + 5) << kOpcodeShift, 378 POP76 = ((7U << 3) + 6) << kOpcodeShift, 379 SD = ((7U << 3) + 7) << kOpcodeShift, 380 381 COP1X = ((1U << 4) + 3) << kOpcodeShift, 382 383 // New r6 instruction. 384 POP06 = BLEZ, // bgeuc/bleuc, blezalc, bgezalc 385 POP07 = BGTZ, // bltuc/bgtuc, bgtzalc, bltzalc 386 POP10 = ADDI, // beqzalc, bovc, beqc 387 POP26 = BLEZL, // bgezc, blezc, bgec/blec 388 POP27 = BGTZL, // bgtzc, bltzc, bltc/bgtc 389 POP30 = DADDI, // bnezalc, bnvc, bnec 390 }; 391 392 enum SecondaryField : uint32_t { 393 // SPECIAL Encoding of Function Field. 394 SLL = ((0U << 3) + 0), 395 MOVCI = ((0U << 3) + 1), 396 SRL = ((0U << 3) + 2), 397 SRA = ((0U << 3) + 3), 398 SLLV = ((0U << 3) + 4), 399 LSA = ((0U << 3) + 5), 400 SRLV = ((0U << 3) + 6), 401 SRAV = ((0U << 3) + 7), 402 403 JR = ((1U << 3) + 0), 404 JALR = ((1U << 3) + 1), 405 MOVZ = ((1U << 3) + 2), 406 MOVN = ((1U << 3) + 3), 407 BREAK = ((1U << 3) + 5), 408 409 MFHI = ((2U << 3) + 0), 410 CLZ_R6 = ((2U << 3) + 0), 411 CLO_R6 = ((2U << 3) + 1), 412 MFLO = ((2U << 3) + 2), 413 DCLZ_R6 = ((2U << 3) + 2), 414 DCLO_R6 = ((2U << 3) + 3), 415 DSLLV = ((2U << 3) + 4), 416 DLSA = ((2U << 3) + 5), 417 DSRLV = ((2U << 3) + 6), 418 DSRAV = ((2U << 3) + 7), 419 420 MULT = ((3U << 3) + 0), 421 MULTU = ((3U << 3) + 1), 422 DIV = ((3U << 3) + 2), 423 DIVU = ((3U << 3) + 3), 424 DMULT = ((3U << 3) + 4), 425 DMULTU = ((3U << 3) + 5), 426 DDIV = ((3U << 3) + 6), 427 DDIVU = ((3U << 3) + 7), 428 429 ADD = ((4U << 3) + 0), 430 ADDU = ((4U << 3) + 1), 431 SUB = ((4U << 3) + 2), 432 SUBU = ((4U << 3) + 3), 433 AND = ((4U << 3) + 4), 434 OR = ((4U << 3) + 5), 435 XOR = ((4U << 3) + 6), 436 NOR = ((4U << 3) + 7), 437 438 SLT = ((5U << 3) + 2), 439 SLTU = ((5U << 3) + 3), 440 DADD = ((5U << 3) + 4), 441 DADDU = ((5U << 3) + 5), 442 DSUB = ((5U << 3) + 6), 443 DSUBU = ((5U << 3) + 7), 444 445 TGE = ((6U << 3) + 0), 446 TGEU = ((6U << 3) + 1), 447 TLT = ((6U << 3) + 2), 448 TLTU = ((6U << 3) + 3), 449 TEQ = ((6U << 3) + 4), 450 SELEQZ_S = ((6U << 3) + 5), 451 TNE = ((6U << 3) + 6), 452 SELNEZ_S = ((6U << 3) + 7), 453 454 DSLL = ((7U << 3) + 0), 455 DSRL = ((7U << 3) + 2), 456 DSRA = ((7U << 3) + 3), 457 DSLL32 = ((7U << 3) + 4), 458 DSRL32 = ((7U << 3) + 6), 459 DSRA32 = ((7U << 3) + 7), 460 461 // Multiply integers in r6. 462 MUL_MUH = ((3U << 3) + 0), // MUL, MUH. 463 MUL_MUH_U = ((3U << 3) + 1), // MUL_U, MUH_U. 464 D_MUL_MUH = ((7U << 2) + 0), // DMUL, DMUH. 465 D_MUL_MUH_U = ((7U << 2) + 1), // DMUL_U, DMUH_U. 466 RINT = ((3U << 3) + 2), 467 468 MUL_OP = ((0U << 3) + 2), 469 MUH_OP = ((0U << 3) + 3), 470 DIV_OP = ((0U << 3) + 2), 471 MOD_OP = ((0U << 3) + 3), 472 473 DIV_MOD = ((3U << 3) + 2), 474 DIV_MOD_U = ((3U << 3) + 3), 475 D_DIV_MOD = ((3U << 3) + 6), 476 D_DIV_MOD_U = ((3U << 3) + 7), 477 478 // drotr in special4? 479 480 // SPECIAL2 Encoding of Function Field. 481 MUL = ((0U << 3) + 2), 482 CLZ = ((4U << 3) + 0), 483 CLO = ((4U << 3) + 1), 484 DCLZ = ((4U << 3) + 4), 485 DCLO = ((4U << 3) + 5), 486 487 // SPECIAL3 Encoding of Function Field. 488 EXT = ((0U << 3) + 0), 489 DEXTM = ((0U << 3) + 1), 490 DEXTU = ((0U << 3) + 2), 491 DEXT = ((0U << 3) + 3), 492 INS = ((0U << 3) + 4), 493 DINSM = ((0U << 3) + 5), 494 DINSU = ((0U << 3) + 6), 495 DINS = ((0U << 3) + 7), 496 497 BSHFL = ((4U << 3) + 0), 498 DBSHFL = ((4U << 3) + 4), 499 500 // SPECIAL3 Encoding of sa Field. 501 BITSWAP = ((0U << 3) + 0), 502 ALIGN = ((0U << 3) + 2), 503 WSBH = ((0U << 3) + 2), 504 SEB = ((2U << 3) + 0), 505 SEH = ((3U << 3) + 0), 506 507 DBITSWAP = ((0U << 3) + 0), 508 DALIGN = ((0U << 3) + 1), 509 DBITSWAP_SA = ((0U << 3) + 0) << kSaShift, 510 DSBH = ((0U << 3) + 2), 511 DSHD = ((0U << 3) + 5), 512 513 // REGIMM encoding of rt Field. 514 BLTZ = ((0U << 3) + 0) << 16, 515 BGEZ = ((0U << 3) + 1) << 16, 516 BLTZAL = ((2U << 3) + 0) << 16, 517 BGEZAL = ((2U << 3) + 1) << 16, 518 BGEZALL = ((2U << 3) + 3) << 16, 519 DAHI = ((0U << 3) + 6) << 16, 520 DATI = ((3U << 3) + 6) << 16, 521 522 // COP1 Encoding of rs Field. 523 MFC1 = ((0U << 3) + 0) << 21, 524 DMFC1 = ((0U << 3) + 1) << 21, 525 CFC1 = ((0U << 3) + 2) << 21, 526 MFHC1 = ((0U << 3) + 3) << 21, 527 MTC1 = ((0U << 3) + 4) << 21, 528 DMTC1 = ((0U << 3) + 5) << 21, 529 CTC1 = ((0U << 3) + 6) << 21, 530 MTHC1 = ((0U << 3) + 7) << 21, 531 BC1 = ((1U << 3) + 0) << 21, 532 S = ((2U << 3) + 0) << 21, 533 D = ((2U << 3) + 1) << 21, 534 W = ((2U << 3) + 4) << 21, 535 L = ((2U << 3) + 5) << 21, 536 PS = ((2U << 3) + 6) << 21, 537 // COP1 Encoding of Function Field When rs=S. 538 539 ADD_S = ((0U << 3) + 0), 540 SUB_S = ((0U << 3) + 1), 541 MUL_S = ((0U << 3) + 2), 542 DIV_S = ((0U << 3) + 3), 543 ABS_S = ((0U << 3) + 5), 544 SQRT_S = ((0U << 3) + 4), 545 MOV_S = ((0U << 3) + 6), 546 NEG_S = ((0U << 3) + 7), 547 ROUND_L_S = ((1U << 3) + 0), 548 TRUNC_L_S = ((1U << 3) + 1), 549 CEIL_L_S = ((1U << 3) + 2), 550 FLOOR_L_S = ((1U << 3) + 3), 551 ROUND_W_S = ((1U << 3) + 4), 552 TRUNC_W_S = ((1U << 3) + 5), 553 CEIL_W_S = ((1U << 3) + 6), 554 FLOOR_W_S = ((1U << 3) + 7), 555 RECIP_S = ((2U << 3) + 5), 556 RSQRT_S = ((2U << 3) + 6), 557 CLASS_S = ((3U << 3) + 3), 558 CVT_D_S = ((4U << 3) + 1), 559 CVT_W_S = ((4U << 3) + 4), 560 CVT_L_S = ((4U << 3) + 5), 561 CVT_PS_S = ((4U << 3) + 6), 562 // COP1 Encoding of Function Field When rs=D. 563 ADD_D = ((0U << 3) + 0), 564 SUB_D = ((0U << 3) + 1), 565 MUL_D = ((0U << 3) + 2), 566 DIV_D = ((0U << 3) + 3), 567 SQRT_D = ((0U << 3) + 4), 568 ABS_D = ((0U << 3) + 5), 569 MOV_D = ((0U << 3) + 6), 570 NEG_D = ((0U << 3) + 7), 571 ROUND_L_D = ((1U << 3) + 0), 572 TRUNC_L_D = ((1U << 3) + 1), 573 CEIL_L_D = ((1U << 3) + 2), 574 FLOOR_L_D = ((1U << 3) + 3), 575 ROUND_W_D = ((1U << 3) + 4), 576 TRUNC_W_D = ((1U << 3) + 5), 577 CEIL_W_D = ((1U << 3) + 6), 578 FLOOR_W_D = ((1U << 3) + 7), 579 RECIP_D = ((2U << 3) + 5), 580 RSQRT_D = ((2U << 3) + 6), 581 CLASS_D = ((3U << 3) + 3), 582 MIN = ((3U << 3) + 4), 583 MINA = ((3U << 3) + 5), 584 MAX = ((3U << 3) + 6), 585 MAXA = ((3U << 3) + 7), 586 CVT_S_D = ((4U << 3) + 0), 587 CVT_W_D = ((4U << 3) + 4), 588 CVT_L_D = ((4U << 3) + 5), 589 C_F_D = ((6U << 3) + 0), 590 C_UN_D = ((6U << 3) + 1), 591 C_EQ_D = ((6U << 3) + 2), 592 C_UEQ_D = ((6U << 3) + 3), 593 C_OLT_D = ((6U << 3) + 4), 594 C_ULT_D = ((6U << 3) + 5), 595 C_OLE_D = ((6U << 3) + 6), 596 C_ULE_D = ((6U << 3) + 7), 597 598 // COP1 Encoding of Function Field When rs=W or L. 599 CVT_S_W = ((4U << 3) + 0), 600 CVT_D_W = ((4U << 3) + 1), 601 CVT_S_L = ((4U << 3) + 0), 602 CVT_D_L = ((4U << 3) + 1), 603 BC1EQZ = ((2U << 2) + 1) << 21, 604 BC1NEZ = ((3U << 2) + 1) << 21, 605 // COP1 CMP positive predicates Bit 5..4 = 00. 606 CMP_AF = ((0U << 3) + 0), 607 CMP_UN = ((0U << 3) + 1), 608 CMP_EQ = ((0U << 3) + 2), 609 CMP_UEQ = ((0U << 3) + 3), 610 CMP_LT = ((0U << 3) + 4), 611 CMP_ULT = ((0U << 3) + 5), 612 CMP_LE = ((0U << 3) + 6), 613 CMP_ULE = ((0U << 3) + 7), 614 CMP_SAF = ((1U << 3) + 0), 615 CMP_SUN = ((1U << 3) + 1), 616 CMP_SEQ = ((1U << 3) + 2), 617 CMP_SUEQ = ((1U << 3) + 3), 618 CMP_SSLT = ((1U << 3) + 4), 619 CMP_SSULT = ((1U << 3) + 5), 620 CMP_SLE = ((1U << 3) + 6), 621 CMP_SULE = ((1U << 3) + 7), 622 // COP1 CMP negative predicates Bit 5..4 = 01. 623 CMP_AT = ((2U << 3) + 0), // Reserved, not implemented. 624 CMP_OR = ((2U << 3) + 1), 625 CMP_UNE = ((2U << 3) + 2), 626 CMP_NE = ((2U << 3) + 3), 627 CMP_UGE = ((2U << 3) + 4), // Reserved, not implemented. 628 CMP_OGE = ((2U << 3) + 5), // Reserved, not implemented. 629 CMP_UGT = ((2U << 3) + 6), // Reserved, not implemented. 630 CMP_OGT = ((2U << 3) + 7), // Reserved, not implemented. 631 CMP_SAT = ((3U << 3) + 0), // Reserved, not implemented. 632 CMP_SOR = ((3U << 3) + 1), 633 CMP_SUNE = ((3U << 3) + 2), 634 CMP_SNE = ((3U << 3) + 3), 635 CMP_SUGE = ((3U << 3) + 4), // Reserved, not implemented. 636 CMP_SOGE = ((3U << 3) + 5), // Reserved, not implemented. 637 CMP_SUGT = ((3U << 3) + 6), // Reserved, not implemented. 638 CMP_SOGT = ((3U << 3) + 7), // Reserved, not implemented. 639 640 SEL = ((2U << 3) + 0), 641 MOVF = ((2U << 3) + 1), // Function field for MOVT.fmt and MOVF.fmt 642 MOVZ_C = ((2U << 3) + 2), // COP1 on FPR registers. 643 MOVN_C = ((2U << 3) + 3), // COP1 on FPR registers. 644 SELEQZ_C = ((2U << 3) + 4), // COP1 on FPR registers. 645 SELNEZ_C = ((2U << 3) + 7), // COP1 on FPR registers. 646 647 // COP1 Encoding of Function Field When rs=PS. 648 // COP1X Encoding of Function Field. 649 MADD_D = ((4U << 3) + 1), 650 651 // PCREL Encoding of rt Field. 652 ADDIUPC = ((0U << 2) + 0), 653 LWPC = ((0U << 2) + 1), 654 LWUPC = ((0U << 2) + 2), 655 LDPC = ((0U << 3) + 6), 656 // reserved ((1U << 3) + 6), 657 AUIPC = ((3U << 3) + 6), 658 ALUIPC = ((3U << 3) + 7), 659 660 // POP66 Encoding of rs Field. 661 JIC = ((0U << 5) + 0), 662 663 // POP76 Encoding of rs Field. 664 JIALC = ((0U << 5) + 0), 665 666 NULLSF = 0U 667 }; 668 669 670 // ----- Emulated conditions. 671 // On MIPS we use this enum to abstract from conditional branch instructions. 672 // The 'U' prefix is used to specify unsigned comparisons. 673 // Opposite conditions must be paired as odd/even numbers 674 // because 'NegateCondition' function flips LSB to negate condition. 675 enum Condition { 676 // Any value < 0 is considered no_condition. 677 kNoCondition = -1, 678 overflow = 0, 679 no_overflow = 1, 680 Uless = 2, 681 Ugreater_equal = 3, 682 Uless_equal = 4, 683 Ugreater = 5, 684 equal = 6, 685 not_equal = 7, // Unordered or Not Equal. 686 negative = 8, 687 positive = 9, 688 parity_even = 10, 689 parity_odd = 11, 690 less = 12, 691 greater_equal = 13, 692 less_equal = 14, 693 greater = 15, 694 ueq = 16, // Unordered or Equal. 695 ogl = 17, // Ordered and Not Equal. 696 cc_always = 18, 697 698 // Aliases. 699 carry = Uless, 700 not_carry = Ugreater_equal, 701 zero = equal, 702 eq = equal, 703 not_zero = not_equal, 704 ne = not_equal, 705 nz = not_equal, 706 sign = negative, 707 not_sign = positive, 708 mi = negative, 709 pl = positive, 710 hi = Ugreater, 711 ls = Uless_equal, 712 ge = greater_equal, 713 lt = less, 714 gt = greater, 715 le = less_equal, 716 hs = Ugreater_equal, 717 lo = Uless, 718 al = cc_always, 719 ult = Uless, 720 uge = Ugreater_equal, 721 ule = Uless_equal, 722 ugt = Ugreater, 723 cc_default = kNoCondition 724 }; 725 726 727 // Returns the equivalent of !cc. 728 // Negation of the default kNoCondition (-1) results in a non-default 729 // no_condition value (-2). As long as tests for no_condition check 730 // for condition < 0, this will work as expected. NegateCondition(Condition cc)731 inline Condition NegateCondition(Condition cc) { 732 DCHECK(cc != cc_always); 733 return static_cast<Condition>(cc ^ 1); 734 } 735 736 NegateFpuCondition(Condition cc)737 inline Condition NegateFpuCondition(Condition cc) { 738 DCHECK(cc != cc_always); 739 switch (cc) { 740 case ult: 741 return ge; 742 case ugt: 743 return le; 744 case uge: 745 return lt; 746 case ule: 747 return gt; 748 case lt: 749 return uge; 750 case gt: 751 return ule; 752 case ge: 753 return ult; 754 case le: 755 return ugt; 756 case eq: 757 return ne; 758 case ne: 759 return eq; 760 case ueq: 761 return ogl; 762 case ogl: 763 return ueq; 764 default: 765 return cc; 766 } 767 } 768 769 770 // Commute a condition such that {a cond b == b cond' a}. CommuteCondition(Condition cc)771 inline Condition CommuteCondition(Condition cc) { 772 switch (cc) { 773 case Uless: 774 return Ugreater; 775 case Ugreater: 776 return Uless; 777 case Ugreater_equal: 778 return Uless_equal; 779 case Uless_equal: 780 return Ugreater_equal; 781 case less: 782 return greater; 783 case greater: 784 return less; 785 case greater_equal: 786 return less_equal; 787 case less_equal: 788 return greater_equal; 789 default: 790 return cc; 791 } 792 } 793 794 795 // ----- Coprocessor conditions. 796 enum FPUCondition { 797 kNoFPUCondition = -1, 798 799 F = 0x00, // False. 800 UN = 0x01, // Unordered. 801 EQ = 0x02, // Equal. 802 UEQ = 0x03, // Unordered or Equal. 803 OLT = 0x04, // Ordered or Less Than, on Mips release < 6. 804 LT = 0x04, // Ordered or Less Than, on Mips release >= 6. 805 ULT = 0x05, // Unordered or Less Than. 806 OLE = 0x06, // Ordered or Less Than or Equal, on Mips release < 6. 807 LE = 0x06, // Ordered or Less Than or Equal, on Mips release >= 6. 808 ULE = 0x07, // Unordered or Less Than or Equal. 809 810 // Following constants are available on Mips release >= 6 only. 811 ORD = 0x11, // Ordered, on Mips release >= 6. 812 UNE = 0x12, // Not equal, on Mips release >= 6. 813 NE = 0x13, // Ordered Greater Than or Less Than. on Mips >= 6 only. 814 }; 815 816 817 // FPU rounding modes. 818 enum FPURoundingMode { 819 RN = 0 << 0, // Round to Nearest. 820 RZ = 1 << 0, // Round towards zero. 821 RP = 2 << 0, // Round towards Plus Infinity. 822 RM = 3 << 0, // Round towards Minus Infinity. 823 824 // Aliases. 825 kRoundToNearest = RN, 826 kRoundToZero = RZ, 827 kRoundToPlusInf = RP, 828 kRoundToMinusInf = RM, 829 830 mode_round = RN, 831 mode_ceil = RP, 832 mode_floor = RM, 833 mode_trunc = RZ 834 }; 835 836 const uint32_t kFPURoundingModeMask = 3 << 0; 837 838 enum CheckForInexactConversion { 839 kCheckForInexactConversion, 840 kDontCheckForInexactConversion 841 }; 842 843 844 // ----------------------------------------------------------------------------- 845 // Hints. 846 847 // Branch hints are not used on the MIPS. They are defined so that they can 848 // appear in shared function signatures, but will be ignored in MIPS 849 // implementations. 850 enum Hint { 851 no_hint = 0 852 }; 853 854 NegateHint(Hint hint)855 inline Hint NegateHint(Hint hint) { 856 return no_hint; 857 } 858 859 860 // ----------------------------------------------------------------------------- 861 // Specific instructions, constants, and masks. 862 // These constants are declared in assembler-mips.cc, as they use named 863 // registers and other constants. 864 865 // addiu(sp, sp, 4) aka Pop() operation or part of Pop(r) 866 // operations as post-increment of sp. 867 extern const Instr kPopInstruction; 868 // addiu(sp, sp, -4) part of Push(r) operation as pre-decrement of sp. 869 extern const Instr kPushInstruction; 870 // sw(r, MemOperand(sp, 0)) 871 extern const Instr kPushRegPattern; 872 // lw(r, MemOperand(sp, 0)) 873 extern const Instr kPopRegPattern; 874 extern const Instr kLwRegFpOffsetPattern; 875 extern const Instr kSwRegFpOffsetPattern; 876 extern const Instr kLwRegFpNegOffsetPattern; 877 extern const Instr kSwRegFpNegOffsetPattern; 878 // A mask for the Rt register for push, pop, lw, sw instructions. 879 extern const Instr kRtMask; 880 extern const Instr kLwSwInstrTypeMask; 881 extern const Instr kLwSwInstrArgumentMask; 882 extern const Instr kLwSwOffsetMask; 883 884 // Break 0xfffff, reserved for redirected real time call. 885 const Instr rtCallRedirInstr = SPECIAL | BREAK | call_rt_redirected << 6; 886 // A nop instruction. (Encoding of sll 0 0 0). 887 const Instr nopInstr = 0; 888 OpcodeToBitNumber(Opcode opcode)889 static constexpr uint64_t OpcodeToBitNumber(Opcode opcode) { 890 return 1ULL << (static_cast<uint32_t>(opcode) >> kOpcodeShift); 891 } 892 893 894 class Instruction { 895 public: 896 enum { 897 kInstrSize = 4, 898 kInstrSizeLog2 = 2, 899 // On MIPS PC cannot actually be directly accessed. We behave as if PC was 900 // always the value of the current instruction being executed. 901 kPCReadOffset = 0 902 }; 903 904 // Get the raw instruction bits. InstructionBits()905 inline Instr InstructionBits() const { 906 return *reinterpret_cast<const Instr*>(this); 907 } 908 909 // Set the raw instruction bits to value. SetInstructionBits(Instr value)910 inline void SetInstructionBits(Instr value) { 911 *reinterpret_cast<Instr*>(this) = value; 912 } 913 914 // Read one particular bit out of the instruction bits. Bit(int nr)915 inline int Bit(int nr) const { 916 return (InstructionBits() >> nr) & 1; 917 } 918 919 // Read a bit field out of the instruction bits. Bits(int hi,int lo)920 inline int Bits(int hi, int lo) const { 921 return (InstructionBits() >> lo) & ((2U << (hi - lo)) - 1); 922 } 923 924 // Instruction type. 925 enum Type { 926 kRegisterType, 927 kImmediateType, 928 kJumpType, 929 kUnsupported = -1 930 }; 931 932 enum TypeChecks { NORMAL, EXTRA }; 933 934 935 static constexpr uint64_t kOpcodeImmediateTypeMask = 936 OpcodeToBitNumber(REGIMM) | OpcodeToBitNumber(BEQ) | 937 OpcodeToBitNumber(BNE) | OpcodeToBitNumber(BLEZ) | 938 OpcodeToBitNumber(BGTZ) | OpcodeToBitNumber(ADDI) | 939 OpcodeToBitNumber(DADDI) | OpcodeToBitNumber(ADDIU) | 940 OpcodeToBitNumber(DADDIU) | OpcodeToBitNumber(SLTI) | 941 OpcodeToBitNumber(SLTIU) | OpcodeToBitNumber(ANDI) | 942 OpcodeToBitNumber(ORI) | OpcodeToBitNumber(XORI) | 943 OpcodeToBitNumber(LUI) | OpcodeToBitNumber(BEQL) | 944 OpcodeToBitNumber(BNEL) | OpcodeToBitNumber(BLEZL) | 945 OpcodeToBitNumber(BGTZL) | OpcodeToBitNumber(POP66) | 946 OpcodeToBitNumber(POP76) | OpcodeToBitNumber(LB) | OpcodeToBitNumber(LH) | 947 OpcodeToBitNumber(LWL) | OpcodeToBitNumber(LW) | OpcodeToBitNumber(LWU) | 948 OpcodeToBitNumber(LD) | OpcodeToBitNumber(LBU) | OpcodeToBitNumber(LHU) | 949 OpcodeToBitNumber(LWR) | OpcodeToBitNumber(SB) | OpcodeToBitNumber(SH) | 950 OpcodeToBitNumber(SWL) | OpcodeToBitNumber(SW) | OpcodeToBitNumber(SD) | 951 OpcodeToBitNumber(SWR) | OpcodeToBitNumber(LWC1) | 952 OpcodeToBitNumber(LDC1) | OpcodeToBitNumber(SWC1) | 953 OpcodeToBitNumber(SDC1) | OpcodeToBitNumber(PCREL) | 954 OpcodeToBitNumber(DAUI) | OpcodeToBitNumber(BC) | OpcodeToBitNumber(BALC); 955 956 #define FunctionFieldToBitNumber(function) (1ULL << function) 957 958 // On r6, DCLZ_R6 aliases to existing MFLO. 959 static const uint64_t kFunctionFieldRegisterTypeMask = 960 FunctionFieldToBitNumber(JR) | FunctionFieldToBitNumber(JALR) | 961 FunctionFieldToBitNumber(BREAK) | FunctionFieldToBitNumber(SLL) | 962 FunctionFieldToBitNumber(DSLL) | FunctionFieldToBitNumber(DSLL32) | 963 FunctionFieldToBitNumber(SRL) | FunctionFieldToBitNumber(DSRL) | 964 FunctionFieldToBitNumber(DSRL32) | FunctionFieldToBitNumber(SRA) | 965 FunctionFieldToBitNumber(DSRA) | FunctionFieldToBitNumber(DSRA32) | 966 FunctionFieldToBitNumber(SLLV) | FunctionFieldToBitNumber(DSLLV) | 967 FunctionFieldToBitNumber(SRLV) | FunctionFieldToBitNumber(DSRLV) | 968 FunctionFieldToBitNumber(SRAV) | FunctionFieldToBitNumber(DSRAV) | 969 FunctionFieldToBitNumber(LSA) | FunctionFieldToBitNumber(DLSA) | 970 FunctionFieldToBitNumber(MFHI) | FunctionFieldToBitNumber(MFLO) | 971 FunctionFieldToBitNumber(MULT) | FunctionFieldToBitNumber(DMULT) | 972 FunctionFieldToBitNumber(MULTU) | FunctionFieldToBitNumber(DMULTU) | 973 FunctionFieldToBitNumber(DIV) | FunctionFieldToBitNumber(DDIV) | 974 FunctionFieldToBitNumber(DIVU) | FunctionFieldToBitNumber(DDIVU) | 975 FunctionFieldToBitNumber(ADD) | FunctionFieldToBitNumber(DADD) | 976 FunctionFieldToBitNumber(ADDU) | FunctionFieldToBitNumber(DADDU) | 977 FunctionFieldToBitNumber(SUB) | FunctionFieldToBitNumber(DSUB) | 978 FunctionFieldToBitNumber(SUBU) | FunctionFieldToBitNumber(DSUBU) | 979 FunctionFieldToBitNumber(AND) | FunctionFieldToBitNumber(OR) | 980 FunctionFieldToBitNumber(XOR) | FunctionFieldToBitNumber(NOR) | 981 FunctionFieldToBitNumber(SLT) | FunctionFieldToBitNumber(SLTU) | 982 FunctionFieldToBitNumber(TGE) | FunctionFieldToBitNumber(TGEU) | 983 FunctionFieldToBitNumber(TLT) | FunctionFieldToBitNumber(TLTU) | 984 FunctionFieldToBitNumber(TEQ) | FunctionFieldToBitNumber(TNE) | 985 FunctionFieldToBitNumber(MOVZ) | FunctionFieldToBitNumber(MOVN) | 986 FunctionFieldToBitNumber(MOVCI) | FunctionFieldToBitNumber(SELEQZ_S) | 987 FunctionFieldToBitNumber(SELNEZ_S); 988 989 990 // Get the encoding type of the instruction. 991 inline Type InstructionType(TypeChecks checks = NORMAL) const; 992 993 994 // Accessors for the different named fields used in the MIPS encoding. OpcodeValue()995 inline Opcode OpcodeValue() const { 996 return static_cast<Opcode>( 997 Bits(kOpcodeShift + kOpcodeBits - 1, kOpcodeShift)); 998 } 999 RsValue()1000 inline int RsValue() const { 1001 DCHECK(InstructionType() == kRegisterType || 1002 InstructionType() == kImmediateType); 1003 return Bits(kRsShift + kRsBits - 1, kRsShift); 1004 } 1005 RtValue()1006 inline int RtValue() const { 1007 DCHECK(InstructionType() == kRegisterType || 1008 InstructionType() == kImmediateType); 1009 return Bits(kRtShift + kRtBits - 1, kRtShift); 1010 } 1011 RdValue()1012 inline int RdValue() const { 1013 DCHECK(InstructionType() == kRegisterType); 1014 return Bits(kRdShift + kRdBits - 1, kRdShift); 1015 } 1016 SaValue()1017 inline int SaValue() const { 1018 DCHECK(InstructionType() == kRegisterType); 1019 return Bits(kSaShift + kSaBits - 1, kSaShift); 1020 } 1021 LsaSaValue()1022 inline int LsaSaValue() const { 1023 DCHECK(InstructionType() == kRegisterType); 1024 return Bits(kSaShift + kLsaSaBits - 1, kSaShift); 1025 } 1026 FunctionValue()1027 inline int FunctionValue() const { 1028 DCHECK(InstructionType() == kRegisterType || 1029 InstructionType() == kImmediateType); 1030 return Bits(kFunctionShift + kFunctionBits - 1, kFunctionShift); 1031 } 1032 FdValue()1033 inline int FdValue() const { 1034 return Bits(kFdShift + kFdBits - 1, kFdShift); 1035 } 1036 FsValue()1037 inline int FsValue() const { 1038 return Bits(kFsShift + kFsBits - 1, kFsShift); 1039 } 1040 FtValue()1041 inline int FtValue() const { 1042 return Bits(kFtShift + kFtBits - 1, kFtShift); 1043 } 1044 FrValue()1045 inline int FrValue() const { 1046 return Bits(kFrShift + kFrBits -1, kFrShift); 1047 } 1048 Bp2Value()1049 inline int Bp2Value() const { 1050 DCHECK(InstructionType() == kRegisterType); 1051 return Bits(kBp2Shift + kBp2Bits - 1, kBp2Shift); 1052 } 1053 Bp3Value()1054 inline int Bp3Value() const { 1055 DCHECK(InstructionType() == kRegisterType); 1056 return Bits(kBp3Shift + kBp3Bits - 1, kBp3Shift); 1057 } 1058 1059 // Float Compare condition code instruction bits. FCccValue()1060 inline int FCccValue() const { 1061 return Bits(kFCccShift + kFCccBits - 1, kFCccShift); 1062 } 1063 1064 // Float Branch condition code instruction bits. FBccValue()1065 inline int FBccValue() const { 1066 return Bits(kFBccShift + kFBccBits - 1, kFBccShift); 1067 } 1068 1069 // Float Branch true/false instruction bit. FBtrueValue()1070 inline int FBtrueValue() const { 1071 return Bits(kFBtrueShift + kFBtrueBits - 1, kFBtrueShift); 1072 } 1073 1074 // Return the fields at their original place in the instruction encoding. OpcodeFieldRaw()1075 inline Opcode OpcodeFieldRaw() const { 1076 return static_cast<Opcode>(InstructionBits() & kOpcodeMask); 1077 } 1078 RsFieldRaw()1079 inline int RsFieldRaw() const { 1080 DCHECK(InstructionType() == kRegisterType || 1081 InstructionType() == kImmediateType); 1082 return InstructionBits() & kRsFieldMask; 1083 } 1084 1085 // Same as above function, but safe to call within InstructionType(). RsFieldRawNoAssert()1086 inline int RsFieldRawNoAssert() const { 1087 return InstructionBits() & kRsFieldMask; 1088 } 1089 RtFieldRaw()1090 inline int RtFieldRaw() const { 1091 DCHECK(InstructionType() == kRegisterType || 1092 InstructionType() == kImmediateType); 1093 return InstructionBits() & kRtFieldMask; 1094 } 1095 RdFieldRaw()1096 inline int RdFieldRaw() const { 1097 DCHECK(InstructionType() == kRegisterType); 1098 return InstructionBits() & kRdFieldMask; 1099 } 1100 SaFieldRaw()1101 inline int SaFieldRaw() const { 1102 return InstructionBits() & kSaFieldMask; 1103 } 1104 FunctionFieldRaw()1105 inline int FunctionFieldRaw() const { 1106 return InstructionBits() & kFunctionFieldMask; 1107 } 1108 1109 // Get the secondary field according to the opcode. SecondaryValue()1110 inline int SecondaryValue() const { 1111 Opcode op = OpcodeFieldRaw(); 1112 switch (op) { 1113 case SPECIAL: 1114 case SPECIAL2: 1115 return FunctionValue(); 1116 case COP1: 1117 return RsValue(); 1118 case REGIMM: 1119 return RtValue(); 1120 default: 1121 return NULLSF; 1122 } 1123 } 1124 ImmValue(int bits)1125 inline int32_t ImmValue(int bits) const { 1126 DCHECK(InstructionType() == kImmediateType); 1127 return Bits(bits - 1, 0); 1128 } 1129 Imm16Value()1130 inline int32_t Imm16Value() const { 1131 DCHECK(InstructionType() == kImmediateType); 1132 return Bits(kImm16Shift + kImm16Bits - 1, kImm16Shift); 1133 } 1134 Imm18Value()1135 inline int32_t Imm18Value() const { 1136 DCHECK(InstructionType() == kImmediateType); 1137 return Bits(kImm18Shift + kImm18Bits - 1, kImm18Shift); 1138 } 1139 Imm19Value()1140 inline int32_t Imm19Value() const { 1141 DCHECK(InstructionType() == kImmediateType); 1142 return Bits(kImm19Shift + kImm19Bits - 1, kImm19Shift); 1143 } 1144 Imm21Value()1145 inline int32_t Imm21Value() const { 1146 DCHECK(InstructionType() == kImmediateType); 1147 return Bits(kImm21Shift + kImm21Bits - 1, kImm21Shift); 1148 } 1149 Imm26Value()1150 inline int32_t Imm26Value() const { 1151 DCHECK((InstructionType() == kJumpType) || 1152 (InstructionType() == kImmediateType)); 1153 return Bits(kImm26Shift + kImm26Bits - 1, kImm26Shift); 1154 } 1155 1156 static bool IsForbiddenAfterBranchInstr(Instr instr); 1157 1158 // Say if the instruction should not be used in a branch delay slot or 1159 // immediately after a compact branch. IsForbiddenAfterBranch()1160 inline bool IsForbiddenAfterBranch() const { 1161 return IsForbiddenAfterBranchInstr(InstructionBits()); 1162 } 1163 1164 // Say if the instruction 'links'. e.g. jal, bal. 1165 bool IsLinkingInstruction() const; 1166 // Say if the instruction is a break or a trap. 1167 bool IsTrap() const; 1168 1169 // Instructions are read of out a code stream. The only way to get a 1170 // reference to an instruction is to convert a pointer. There is no way 1171 // to allocate or create instances of class Instruction. 1172 // Use the At(pc) function to create references to Instruction. At(byte * pc)1173 static Instruction* At(byte* pc) { 1174 return reinterpret_cast<Instruction*>(pc); 1175 } 1176 1177 private: 1178 // We need to prevent the creation of instances of class Instruction. 1179 DISALLOW_IMPLICIT_CONSTRUCTORS(Instruction); 1180 }; 1181 1182 1183 // ----------------------------------------------------------------------------- 1184 // MIPS assembly various constants. 1185 1186 // C/C++ argument slots size. 1187 const int kCArgSlotCount = (kMipsAbi == kN64) ? 0 : 4; 1188 1189 // TODO(plind): below should be based on kPointerSize 1190 // TODO(plind): find all usages and remove the needless instructions for n64. 1191 const int kCArgsSlotsSize = kCArgSlotCount * Instruction::kInstrSize * 2; 1192 1193 const int kInvalidStackOffset = -1; 1194 const int kBranchReturnOffset = 2 * Instruction::kInstrSize; 1195 1196 InstructionType(TypeChecks checks)1197 Instruction::Type Instruction::InstructionType(TypeChecks checks) const { 1198 if (checks == EXTRA) { 1199 if (OpcodeToBitNumber(OpcodeFieldRaw()) & kOpcodeImmediateTypeMask) { 1200 return kImmediateType; 1201 } 1202 } 1203 switch (OpcodeFieldRaw()) { 1204 case SPECIAL: 1205 if (checks == EXTRA) { 1206 if (FunctionFieldToBitNumber(FunctionFieldRaw()) & 1207 kFunctionFieldRegisterTypeMask) { 1208 return kRegisterType; 1209 } else { 1210 return kUnsupported; 1211 } 1212 } else { 1213 return kRegisterType; 1214 } 1215 break; 1216 case SPECIAL2: 1217 switch (FunctionFieldRaw()) { 1218 case MUL: 1219 case CLZ: 1220 case DCLZ: 1221 return kRegisterType; 1222 default: 1223 return kUnsupported; 1224 } 1225 break; 1226 case SPECIAL3: 1227 switch (FunctionFieldRaw()) { 1228 case INS: 1229 case EXT: 1230 case DEXT: 1231 case DEXTM: 1232 case DEXTU: 1233 return kRegisterType; 1234 case BSHFL: { 1235 int sa = SaFieldRaw() >> kSaShift; 1236 switch (sa) { 1237 case BITSWAP: 1238 return kRegisterType; 1239 case WSBH: 1240 case SEB: 1241 case SEH: 1242 return kUnsupported; 1243 } 1244 sa >>= kBp2Bits; 1245 switch (sa) { 1246 case ALIGN: 1247 return kRegisterType; 1248 default: 1249 return kUnsupported; 1250 } 1251 } 1252 case DBSHFL: { 1253 int sa = SaFieldRaw() >> kSaShift; 1254 switch (sa) { 1255 case DBITSWAP: 1256 return kRegisterType; 1257 case DSBH: 1258 case DSHD: 1259 return kUnsupported; 1260 } 1261 sa = SaFieldRaw() >> kSaShift; 1262 sa >>= kBp3Bits; 1263 switch (sa) { 1264 case DALIGN: 1265 return kRegisterType; 1266 default: 1267 return kUnsupported; 1268 } 1269 } 1270 default: 1271 return kUnsupported; 1272 } 1273 break; 1274 case COP1: // Coprocessor instructions. 1275 switch (RsFieldRawNoAssert()) { 1276 case BC1: // Branch on coprocessor condition. 1277 case BC1EQZ: 1278 case BC1NEZ: 1279 return kImmediateType; 1280 default: 1281 return kRegisterType; 1282 } 1283 break; 1284 case COP1X: 1285 return kRegisterType; 1286 1287 // 26 bits immediate type instructions. e.g.: j imm26. 1288 case J: 1289 case JAL: 1290 return kJumpType; 1291 1292 default: 1293 if (checks == NORMAL) { 1294 return kImmediateType; 1295 } else { 1296 return kUnsupported; 1297 } 1298 } 1299 return kUnsupported; 1300 } 1301 1302 #undef OpcodeToBitNumber 1303 #undef FunctionFieldToBitNumber 1304 } // namespace internal 1305 } // namespace v8 1306 1307 #endif // #ifndef V8_MIPS_CONSTANTS_H_ 1308