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 23enum 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 49// TODO(plind): consider renaming these ... 50#if(defined(__mips_hard_float) && __mips_hard_float != 0) 51// Use floating-point coprocessor instructions. This flag is raised when 52// -mhard-float is passed to the compiler. 53const bool IsMipsSoftFloatABI = false; 54#elif(defined(__mips_soft_float) && __mips_soft_float != 0) 55// This flag is raised when -msoft-float is passed to the compiler. 56// Although FPU is a base requirement for v8, soft-float ABI is used 57// on soft-float systems with FPU kernel emulation. 58const bool IsMipsSoftFloatABI = true; 59#else 60const bool IsMipsSoftFloatABI = true; 61#endif 62 63#if defined(V8_TARGET_LITTLE_ENDIAN) 64const uint32_t kMipsLwrOffset = 0; 65const uint32_t kMipsLwlOffset = 3; 66const uint32_t kMipsSwrOffset = 0; 67const uint32_t kMipsSwlOffset = 3; 68const uint32_t kMipsLdrOffset = 0; 69const uint32_t kMipsLdlOffset = 7; 70const uint32_t kMipsSdrOffset = 0; 71const uint32_t kMipsSdlOffset = 7; 72#elif defined(V8_TARGET_BIG_ENDIAN) 73const uint32_t kMipsLwrOffset = 3; 74const uint32_t kMipsLwlOffset = 0; 75const uint32_t kMipsSwrOffset = 3; 76const uint32_t kMipsSwlOffset = 0; 77const uint32_t kMipsLdrOffset = 7; 78const uint32_t kMipsLdlOffset = 0; 79const uint32_t kMipsSdrOffset = 7; 80const uint32_t kMipsSdlOffset = 0; 81#else 82#error Unknown endianness 83#endif 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 98namespace v8 { 99namespace internal { 100 101// ----------------------------------------------------------------------------- 102// Registers and FPURegisters. 103 104// Number of general purpose registers. 105const int kNumRegisters = 32; 106const int kInvalidRegister = -1; 107 108// Number of registers with HI, LO, and pc. 109const int kNumSimuRegisters = 35; 110 111// In the simulator, the PC register is simulated as the 34th register. 112const int kPCRegister = 34; 113 114// Number coprocessor registers. 115const int kNumFPURegisters = 32; 116const int kInvalidFPURegister = -1; 117 118// FPU (coprocessor 1) control registers. Currently only FCSR is implemented. 119const int kFCSRRegister = 31; 120const int kInvalidFPUControlRegister = -1; 121const uint32_t kFPUInvalidResult = static_cast<uint32_t>(1 << 31) - 1; 122const int32_t kFPUInvalidResultNegative = static_cast<int32_t>(1 << 31); 123const uint64_t kFPU64InvalidResult = 124 static_cast<uint64_t>(static_cast<uint64_t>(1) << 63) - 1; 125const int64_t kFPU64InvalidResultNegative = 126 static_cast<int64_t>(static_cast<uint64_t>(1) << 63); 127 128// FCSR constants. 129const uint32_t kFCSRInexactFlagBit = 2; 130const uint32_t kFCSRUnderflowFlagBit = 3; 131const uint32_t kFCSROverflowFlagBit = 4; 132const uint32_t kFCSRDivideByZeroFlagBit = 5; 133const uint32_t kFCSRInvalidOpFlagBit = 6; 134const uint32_t kFCSRNaN2008FlagBit = 18; 135 136const uint32_t kFCSRInexactFlagMask = 1 << kFCSRInexactFlagBit; 137const uint32_t kFCSRUnderflowFlagMask = 1 << kFCSRUnderflowFlagBit; 138const uint32_t kFCSROverflowFlagMask = 1 << kFCSROverflowFlagBit; 139const uint32_t kFCSRDivideByZeroFlagMask = 1 << kFCSRDivideByZeroFlagBit; 140const uint32_t kFCSRInvalidOpFlagMask = 1 << kFCSRInvalidOpFlagBit; 141const uint32_t kFCSRNaN2008FlagMask = 1 << kFCSRNaN2008FlagBit; 142 143const uint32_t kFCSRFlagMask = 144 kFCSRInexactFlagMask | 145 kFCSRUnderflowFlagMask | 146 kFCSROverflowFlagMask | 147 kFCSRDivideByZeroFlagMask | 148 kFCSRInvalidOpFlagMask; 149 150const uint32_t kFCSRExceptionFlagMask = kFCSRFlagMask ^ kFCSRInexactFlagMask; 151 152// 'pref' instruction hints 153const int32_t kPrefHintLoad = 0; 154const int32_t kPrefHintStore = 1; 155const int32_t kPrefHintLoadStreamed = 4; 156const int32_t kPrefHintStoreStreamed = 5; 157const int32_t kPrefHintLoadRetained = 6; 158const int32_t kPrefHintStoreRetained = 7; 159const int32_t kPrefHintWritebackInvalidate = 25; 160const int32_t kPrefHintPrepareForStore = 30; 161 162// Helper functions for converting between register numbers and names. 163class 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. 185class 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. 208typedef int32_t Instr; 209 210// Special Software Interrupt codes when used in the presence of the MIPS 211// simulator. 212enum 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. 224const uint32_t kMaxWatchpointCode = 31; 225const uint32_t kMaxStopCode = 127; 226STATIC_ASSERT(kMaxWatchpointCode < kMaxStopCode); 227 228 229// ----- Fields offset and length. 230const int kOpcodeShift = 26; 231const int kOpcodeBits = 6; 232const int kRsShift = 21; 233const int kRsBits = 5; 234const int kRtShift = 16; 235const int kRtBits = 5; 236const int kRdShift = 11; 237const int kRdBits = 5; 238const int kSaShift = 6; 239const int kSaBits = 5; 240const int kLsaSaBits = 2; 241const int kFunctionShift = 0; 242const int kFunctionBits = 6; 243const int kLuiShift = 16; 244const int kBp2Shift = 6; 245const int kBp2Bits = 2; 246const int kBp3Shift = 6; 247const int kBp3Bits = 3; 248 249const int kImm16Shift = 0; 250const int kImm16Bits = 16; 251const int kImm18Shift = 0; 252const int kImm18Bits = 18; 253const int kImm19Shift = 0; 254const int kImm19Bits = 19; 255const int kImm21Shift = 0; 256const int kImm21Bits = 21; 257const int kImm26Shift = 0; 258const int kImm26Bits = 26; 259const int kImm28Shift = 0; 260const int kImm28Bits = 28; 261const int kImm32Shift = 0; 262const int kImm32Bits = 32; 263 264// In branches and jumps immediate fields point to words, not bytes, 265// and are therefore shifted by 2. 266const int kImmFieldShift = 2; 267 268const int kFrBits = 5; 269const int kFrShift = 21; 270const int kFsShift = 11; 271const int kFsBits = 5; 272const int kFtShift = 16; 273const int kFtBits = 5; 274const int kFdShift = 6; 275const int kFdBits = 5; 276const int kFCccShift = 8; 277const int kFCccBits = 3; 278const int kFBccShift = 18; 279const int kFBccBits = 3; 280const int kFBtrueShift = 16; 281const int kFBtrueBits = 1; 282 283// ----- Miscellaneous useful masks. 284// Instruction bit masks. 285const int kOpcodeMask = ((1 << kOpcodeBits) - 1) << kOpcodeShift; 286const int kImm16Mask = ((1 << kImm16Bits) - 1) << kImm16Shift; 287const int kImm18Mask = ((1 << kImm18Bits) - 1) << kImm18Shift; 288const int kImm19Mask = ((1 << kImm19Bits) - 1) << kImm19Shift; 289const int kImm21Mask = ((1 << kImm21Bits) - 1) << kImm21Shift; 290const int kImm26Mask = ((1 << kImm26Bits) - 1) << kImm26Shift; 291const int kImm28Mask = ((1 << kImm28Bits) - 1) << kImm28Shift; 292const int kRsFieldMask = ((1 << kRsBits) - 1) << kRsShift; 293const int kRtFieldMask = ((1 << kRtBits) - 1) << kRtShift; 294const int kRdFieldMask = ((1 << kRdBits) - 1) << kRdShift; 295const int kSaFieldMask = ((1 << kSaBits) - 1) << kSaShift; 296const int kFunctionFieldMask = ((1 << kFunctionBits) - 1) << kFunctionShift; 297// Misc masks. 298const int kHiMask = 0xffff << 16; 299const int kLoMask = 0xffff; 300const int kSignMask = 0x80000000; 301const int kJumpAddrMask = (1 << (kImm26Bits + kImmFieldShift)) - 1; 302const int64_t kHi16MaskOf64 = (int64_t)0xffff << 48; 303const int64_t kSe16MaskOf64 = (int64_t)0xffff << 32; 304const int64_t kTh16MaskOf64 = (int64_t)0xffff << 16; 305const int32_t kJalRawMark = 0x00000000; 306const int32_t kJRawMark = 0xf0000000; 307const 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. 312enum 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 392enum 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 SYNC = ((1U << 3) + 7), 409 410 MFHI = ((2U << 3) + 0), 411 CLZ_R6 = ((2U << 3) + 0), 412 CLO_R6 = ((2U << 3) + 1), 413 MFLO = ((2U << 3) + 2), 414 DCLZ_R6 = ((2U << 3) + 2), 415 DCLO_R6 = ((2U << 3) + 3), 416 DSLLV = ((2U << 3) + 4), 417 DLSA = ((2U << 3) + 5), 418 DSRLV = ((2U << 3) + 6), 419 DSRAV = ((2U << 3) + 7), 420 421 MULT = ((3U << 3) + 0), 422 MULTU = ((3U << 3) + 1), 423 DIV = ((3U << 3) + 2), 424 DIVU = ((3U << 3) + 3), 425 DMULT = ((3U << 3) + 4), 426 DMULTU = ((3U << 3) + 5), 427 DDIV = ((3U << 3) + 6), 428 DDIVU = ((3U << 3) + 7), 429 430 ADD = ((4U << 3) + 0), 431 ADDU = ((4U << 3) + 1), 432 SUB = ((4U << 3) + 2), 433 SUBU = ((4U << 3) + 3), 434 AND = ((4U << 3) + 4), 435 OR = ((4U << 3) + 5), 436 XOR = ((4U << 3) + 6), 437 NOR = ((4U << 3) + 7), 438 439 SLT = ((5U << 3) + 2), 440 SLTU = ((5U << 3) + 3), 441 DADD = ((5U << 3) + 4), 442 DADDU = ((5U << 3) + 5), 443 DSUB = ((5U << 3) + 6), 444 DSUBU = ((5U << 3) + 7), 445 446 TGE = ((6U << 3) + 0), 447 TGEU = ((6U << 3) + 1), 448 TLT = ((6U << 3) + 2), 449 TLTU = ((6U << 3) + 3), 450 TEQ = ((6U << 3) + 4), 451 SELEQZ_S = ((6U << 3) + 5), 452 TNE = ((6U << 3) + 6), 453 SELNEZ_S = ((6U << 3) + 7), 454 455 DSLL = ((7U << 3) + 0), 456 DSRL = ((7U << 3) + 2), 457 DSRA = ((7U << 3) + 3), 458 DSLL32 = ((7U << 3) + 4), 459 DSRL32 = ((7U << 3) + 6), 460 DSRA32 = ((7U << 3) + 7), 461 462 // Multiply integers in r6. 463 MUL_MUH = ((3U << 3) + 0), // MUL, MUH. 464 MUL_MUH_U = ((3U << 3) + 1), // MUL_U, MUH_U. 465 D_MUL_MUH = ((7U << 2) + 0), // DMUL, DMUH. 466 D_MUL_MUH_U = ((7U << 2) + 1), // DMUL_U, DMUH_U. 467 RINT = ((3U << 3) + 2), 468 469 MUL_OP = ((0U << 3) + 2), 470 MUH_OP = ((0U << 3) + 3), 471 DIV_OP = ((0U << 3) + 2), 472 MOD_OP = ((0U << 3) + 3), 473 474 DIV_MOD = ((3U << 3) + 2), 475 DIV_MOD_U = ((3U << 3) + 3), 476 D_DIV_MOD = ((3U << 3) + 6), 477 D_DIV_MOD_U = ((3U << 3) + 7), 478 479 // drotr in special4? 480 481 // SPECIAL2 Encoding of Function Field. 482 MUL = ((0U << 3) + 2), 483 CLZ = ((4U << 3) + 0), 484 CLO = ((4U << 3) + 1), 485 DCLZ = ((4U << 3) + 4), 486 DCLO = ((4U << 3) + 5), 487 488 // SPECIAL3 Encoding of Function Field. 489 EXT = ((0U << 3) + 0), 490 DEXTM = ((0U << 3) + 1), 491 DEXTU = ((0U << 3) + 2), 492 DEXT = ((0U << 3) + 3), 493 INS = ((0U << 3) + 4), 494 DINSM = ((0U << 3) + 5), 495 DINSU = ((0U << 3) + 6), 496 DINS = ((0U << 3) + 7), 497 498 BSHFL = ((4U << 3) + 0), 499 DBSHFL = ((4U << 3) + 4), 500 501 // SPECIAL3 Encoding of sa Field. 502 BITSWAP = ((0U << 3) + 0), 503 ALIGN = ((0U << 3) + 2), 504 WSBH = ((0U << 3) + 2), 505 SEB = ((2U << 3) + 0), 506 SEH = ((3U << 3) + 0), 507 508 DBITSWAP = ((0U << 3) + 0), 509 DALIGN = ((0U << 3) + 1), 510 DBITSWAP_SA = ((0U << 3) + 0) << kSaShift, 511 DSBH = ((0U << 3) + 2), 512 DSHD = ((0U << 3) + 5), 513 514 // REGIMM encoding of rt Field. 515 BLTZ = ((0U << 3) + 0) << 16, 516 BGEZ = ((0U << 3) + 1) << 16, 517 BLTZAL = ((2U << 3) + 0) << 16, 518 BGEZAL = ((2U << 3) + 1) << 16, 519 BGEZALL = ((2U << 3) + 3) << 16, 520 DAHI = ((0U << 3) + 6) << 16, 521 DATI = ((3U << 3) + 6) << 16, 522 523 // COP1 Encoding of rs Field. 524 MFC1 = ((0U << 3) + 0) << 21, 525 DMFC1 = ((0U << 3) + 1) << 21, 526 CFC1 = ((0U << 3) + 2) << 21, 527 MFHC1 = ((0U << 3) + 3) << 21, 528 MTC1 = ((0U << 3) + 4) << 21, 529 DMTC1 = ((0U << 3) + 5) << 21, 530 CTC1 = ((0U << 3) + 6) << 21, 531 MTHC1 = ((0U << 3) + 7) << 21, 532 BC1 = ((1U << 3) + 0) << 21, 533 S = ((2U << 3) + 0) << 21, 534 D = ((2U << 3) + 1) << 21, 535 W = ((2U << 3) + 4) << 21, 536 L = ((2U << 3) + 5) << 21, 537 PS = ((2U << 3) + 6) << 21, 538 // COP1 Encoding of Function Field When rs=S. 539 540 ADD_S = ((0U << 3) + 0), 541 SUB_S = ((0U << 3) + 1), 542 MUL_S = ((0U << 3) + 2), 543 DIV_S = ((0U << 3) + 3), 544 ABS_S = ((0U << 3) + 5), 545 SQRT_S = ((0U << 3) + 4), 546 MOV_S = ((0U << 3) + 6), 547 NEG_S = ((0U << 3) + 7), 548 ROUND_L_S = ((1U << 3) + 0), 549 TRUNC_L_S = ((1U << 3) + 1), 550 CEIL_L_S = ((1U << 3) + 2), 551 FLOOR_L_S = ((1U << 3) + 3), 552 ROUND_W_S = ((1U << 3) + 4), 553 TRUNC_W_S = ((1U << 3) + 5), 554 CEIL_W_S = ((1U << 3) + 6), 555 FLOOR_W_S = ((1U << 3) + 7), 556 RECIP_S = ((2U << 3) + 5), 557 RSQRT_S = ((2U << 3) + 6), 558 CLASS_S = ((3U << 3) + 3), 559 CVT_D_S = ((4U << 3) + 1), 560 CVT_W_S = ((4U << 3) + 4), 561 CVT_L_S = ((4U << 3) + 5), 562 CVT_PS_S = ((4U << 3) + 6), 563 // COP1 Encoding of Function Field When rs=D. 564 ADD_D = ((0U << 3) + 0), 565 SUB_D = ((0U << 3) + 1), 566 MUL_D = ((0U << 3) + 2), 567 DIV_D = ((0U << 3) + 3), 568 SQRT_D = ((0U << 3) + 4), 569 ABS_D = ((0U << 3) + 5), 570 MOV_D = ((0U << 3) + 6), 571 NEG_D = ((0U << 3) + 7), 572 ROUND_L_D = ((1U << 3) + 0), 573 TRUNC_L_D = ((1U << 3) + 1), 574 CEIL_L_D = ((1U << 3) + 2), 575 FLOOR_L_D = ((1U << 3) + 3), 576 ROUND_W_D = ((1U << 3) + 4), 577 TRUNC_W_D = ((1U << 3) + 5), 578 CEIL_W_D = ((1U << 3) + 6), 579 FLOOR_W_D = ((1U << 3) + 7), 580 RECIP_D = ((2U << 3) + 5), 581 RSQRT_D = ((2U << 3) + 6), 582 CLASS_D = ((3U << 3) + 3), 583 MIN = ((3U << 3) + 4), 584 MINA = ((3U << 3) + 5), 585 MAX = ((3U << 3) + 6), 586 MAXA = ((3U << 3) + 7), 587 CVT_S_D = ((4U << 3) + 0), 588 CVT_W_D = ((4U << 3) + 4), 589 CVT_L_D = ((4U << 3) + 5), 590 C_F_D = ((6U << 3) + 0), 591 C_UN_D = ((6U << 3) + 1), 592 C_EQ_D = ((6U << 3) + 2), 593 C_UEQ_D = ((6U << 3) + 3), 594 C_OLT_D = ((6U << 3) + 4), 595 C_ULT_D = ((6U << 3) + 5), 596 C_OLE_D = ((6U << 3) + 6), 597 C_ULE_D = ((6U << 3) + 7), 598 599 // COP1 Encoding of Function Field When rs=W or L. 600 CVT_S_W = ((4U << 3) + 0), 601 CVT_D_W = ((4U << 3) + 1), 602 CVT_S_L = ((4U << 3) + 0), 603 CVT_D_L = ((4U << 3) + 1), 604 BC1EQZ = ((2U << 2) + 1) << 21, 605 BC1NEZ = ((3U << 2) + 1) << 21, 606 // COP1 CMP positive predicates Bit 5..4 = 00. 607 CMP_AF = ((0U << 3) + 0), 608 CMP_UN = ((0U << 3) + 1), 609 CMP_EQ = ((0U << 3) + 2), 610 CMP_UEQ = ((0U << 3) + 3), 611 CMP_LT = ((0U << 3) + 4), 612 CMP_ULT = ((0U << 3) + 5), 613 CMP_LE = ((0U << 3) + 6), 614 CMP_ULE = ((0U << 3) + 7), 615 CMP_SAF = ((1U << 3) + 0), 616 CMP_SUN = ((1U << 3) + 1), 617 CMP_SEQ = ((1U << 3) + 2), 618 CMP_SUEQ = ((1U << 3) + 3), 619 CMP_SSLT = ((1U << 3) + 4), 620 CMP_SSULT = ((1U << 3) + 5), 621 CMP_SLE = ((1U << 3) + 6), 622 CMP_SULE = ((1U << 3) + 7), 623 // COP1 CMP negative predicates Bit 5..4 = 01. 624 CMP_AT = ((2U << 3) + 0), // Reserved, not implemented. 625 CMP_OR = ((2U << 3) + 1), 626 CMP_UNE = ((2U << 3) + 2), 627 CMP_NE = ((2U << 3) + 3), 628 CMP_UGE = ((2U << 3) + 4), // Reserved, not implemented. 629 CMP_OGE = ((2U << 3) + 5), // Reserved, not implemented. 630 CMP_UGT = ((2U << 3) + 6), // Reserved, not implemented. 631 CMP_OGT = ((2U << 3) + 7), // Reserved, not implemented. 632 CMP_SAT = ((3U << 3) + 0), // Reserved, not implemented. 633 CMP_SOR = ((3U << 3) + 1), 634 CMP_SUNE = ((3U << 3) + 2), 635 CMP_SNE = ((3U << 3) + 3), 636 CMP_SUGE = ((3U << 3) + 4), // Reserved, not implemented. 637 CMP_SOGE = ((3U << 3) + 5), // Reserved, not implemented. 638 CMP_SUGT = ((3U << 3) + 6), // Reserved, not implemented. 639 CMP_SOGT = ((3U << 3) + 7), // Reserved, not implemented. 640 641 SEL = ((2U << 3) + 0), 642 MOVF = ((2U << 3) + 1), // Function field for MOVT.fmt and MOVF.fmt 643 MOVZ_C = ((2U << 3) + 2), // COP1 on FPR registers. 644 MOVN_C = ((2U << 3) + 3), // COP1 on FPR registers. 645 SELEQZ_C = ((2U << 3) + 4), // COP1 on FPR registers. 646 SELNEZ_C = ((2U << 3) + 7), // COP1 on FPR registers. 647 648 // COP1 Encoding of Function Field When rs=PS. 649 // COP1X Encoding of Function Field. 650 MADD_D = ((4U << 3) + 1), 651 652 // PCREL Encoding of rt Field. 653 ADDIUPC = ((0U << 2) + 0), 654 LWPC = ((0U << 2) + 1), 655 LWUPC = ((0U << 2) + 2), 656 LDPC = ((0U << 3) + 6), 657 // reserved ((1U << 3) + 6), 658 AUIPC = ((3U << 3) + 6), 659 ALUIPC = ((3U << 3) + 7), 660 661 // POP66 Encoding of rs Field. 662 JIC = ((0U << 5) + 0), 663 664 // POP76 Encoding of rs Field. 665 JIALC = ((0U << 5) + 0), 666 667 NULLSF = 0U 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. 675enum 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. 731inline Condition NegateCondition(Condition cc) { 732 DCHECK(cc != cc_always); 733 return static_cast<Condition>(cc ^ 1); 734} 735 736 737inline 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}. 771inline 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. 796enum 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. 818enum 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 836const uint32_t kFPURoundingModeMask = 3 << 0; 837 838enum CheckForInexactConversion { 839 kCheckForInexactConversion, 840 kDontCheckForInexactConversion 841}; 842 843enum class MaxMinKind : int { kMin = 0, kMax = 1 }; 844 845// ----------------------------------------------------------------------------- 846// Hints. 847 848// Branch hints are not used on the MIPS. They are defined so that they can 849// appear in shared function signatures, but will be ignored in MIPS 850// implementations. 851enum Hint { 852 no_hint = 0 853}; 854 855 856inline Hint NegateHint(Hint hint) { 857 return no_hint; 858} 859 860 861// ----------------------------------------------------------------------------- 862// Specific instructions, constants, and masks. 863// These constants are declared in assembler-mips.cc, as they use named 864// registers and other constants. 865 866// addiu(sp, sp, 4) aka Pop() operation or part of Pop(r) 867// operations as post-increment of sp. 868extern const Instr kPopInstruction; 869// addiu(sp, sp, -4) part of Push(r) operation as pre-decrement of sp. 870extern const Instr kPushInstruction; 871// sw(r, MemOperand(sp, 0)) 872extern const Instr kPushRegPattern; 873// lw(r, MemOperand(sp, 0)) 874extern const Instr kPopRegPattern; 875extern const Instr kLwRegFpOffsetPattern; 876extern const Instr kSwRegFpOffsetPattern; 877extern const Instr kLwRegFpNegOffsetPattern; 878extern const Instr kSwRegFpNegOffsetPattern; 879// A mask for the Rt register for push, pop, lw, sw instructions. 880extern const Instr kRtMask; 881extern const Instr kLwSwInstrTypeMask; 882extern const Instr kLwSwInstrArgumentMask; 883extern const Instr kLwSwOffsetMask; 884 885// Break 0xfffff, reserved for redirected real time call. 886const Instr rtCallRedirInstr = SPECIAL | BREAK | call_rt_redirected << 6; 887// A nop instruction. (Encoding of sll 0 0 0). 888const Instr nopInstr = 0; 889 890static constexpr uint64_t OpcodeToBitNumber(Opcode opcode) { 891 return 1ULL << (static_cast<uint32_t>(opcode) >> kOpcodeShift); 892} 893 894 895class Instruction { 896 public: 897 enum { 898 kInstrSize = 4, 899 kInstrSizeLog2 = 2, 900 // On MIPS PC cannot actually be directly accessed. We behave as if PC was 901 // always the value of the current instruction being executed. 902 kPCReadOffset = 0 903 }; 904 905 // Get the raw instruction bits. 906 inline Instr InstructionBits() const { 907 return *reinterpret_cast<const Instr*>(this); 908 } 909 910 // Set the raw instruction bits to value. 911 inline void SetInstructionBits(Instr value) { 912 *reinterpret_cast<Instr*>(this) = value; 913 } 914 915 // Read one particular bit out of the instruction bits. 916 inline int Bit(int nr) const { 917 return (InstructionBits() >> nr) & 1; 918 } 919 920 // Read a bit field out of the instruction bits. 921 inline int Bits(int hi, int lo) const { 922 return (InstructionBits() >> lo) & ((2U << (hi - lo)) - 1); 923 } 924 925 // Instruction type. 926 enum Type { 927 kRegisterType, 928 kImmediateType, 929 kJumpType, 930 kUnsupported = -1 931 }; 932 933 enum TypeChecks { NORMAL, EXTRA }; 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(LDL) | OpcodeToBitNumber(LDR) | OpcodeToBitNumber(LWR) | 950 OpcodeToBitNumber(SDL) | OpcodeToBitNumber(SB) | OpcodeToBitNumber(SH) | 951 OpcodeToBitNumber(SWL) | OpcodeToBitNumber(SW) | OpcodeToBitNumber(SD) | 952 OpcodeToBitNumber(SWR) | OpcodeToBitNumber(SDR) | 953 OpcodeToBitNumber(LWC1) | OpcodeToBitNumber(LDC1) | 954 OpcodeToBitNumber(SWC1) | OpcodeToBitNumber(SDC1) | 955 OpcodeToBitNumber(PCREL) | OpcodeToBitNumber(DAUI) | 956 OpcodeToBitNumber(BC) | OpcodeToBitNumber(BALC); 957 958#define FunctionFieldToBitNumber(function) (1ULL << function) 959 960 // On r6, DCLZ_R6 aliases to existing MFLO. 961 static const uint64_t kFunctionFieldRegisterTypeMask = 962 FunctionFieldToBitNumber(JR) | FunctionFieldToBitNumber(JALR) | 963 FunctionFieldToBitNumber(BREAK) | FunctionFieldToBitNumber(SLL) | 964 FunctionFieldToBitNumber(DSLL) | FunctionFieldToBitNumber(DSLL32) | 965 FunctionFieldToBitNumber(SRL) | FunctionFieldToBitNumber(DSRL) | 966 FunctionFieldToBitNumber(DSRL32) | FunctionFieldToBitNumber(SRA) | 967 FunctionFieldToBitNumber(DSRA) | FunctionFieldToBitNumber(DSRA32) | 968 FunctionFieldToBitNumber(SLLV) | FunctionFieldToBitNumber(DSLLV) | 969 FunctionFieldToBitNumber(SRLV) | FunctionFieldToBitNumber(DSRLV) | 970 FunctionFieldToBitNumber(SRAV) | FunctionFieldToBitNumber(DSRAV) | 971 FunctionFieldToBitNumber(LSA) | FunctionFieldToBitNumber(DLSA) | 972 FunctionFieldToBitNumber(MFHI) | FunctionFieldToBitNumber(MFLO) | 973 FunctionFieldToBitNumber(MULT) | FunctionFieldToBitNumber(DMULT) | 974 FunctionFieldToBitNumber(MULTU) | FunctionFieldToBitNumber(DMULTU) | 975 FunctionFieldToBitNumber(DIV) | FunctionFieldToBitNumber(DDIV) | 976 FunctionFieldToBitNumber(DIVU) | FunctionFieldToBitNumber(DDIVU) | 977 FunctionFieldToBitNumber(ADD) | FunctionFieldToBitNumber(DADD) | 978 FunctionFieldToBitNumber(ADDU) | FunctionFieldToBitNumber(DADDU) | 979 FunctionFieldToBitNumber(SUB) | FunctionFieldToBitNumber(DSUB) | 980 FunctionFieldToBitNumber(SUBU) | FunctionFieldToBitNumber(DSUBU) | 981 FunctionFieldToBitNumber(AND) | FunctionFieldToBitNumber(OR) | 982 FunctionFieldToBitNumber(XOR) | FunctionFieldToBitNumber(NOR) | 983 FunctionFieldToBitNumber(SLT) | FunctionFieldToBitNumber(SLTU) | 984 FunctionFieldToBitNumber(TGE) | FunctionFieldToBitNumber(TGEU) | 985 FunctionFieldToBitNumber(TLT) | FunctionFieldToBitNumber(TLTU) | 986 FunctionFieldToBitNumber(TEQ) | FunctionFieldToBitNumber(TNE) | 987 FunctionFieldToBitNumber(MOVZ) | FunctionFieldToBitNumber(MOVN) | 988 FunctionFieldToBitNumber(MOVCI) | FunctionFieldToBitNumber(SELEQZ_S) | 989 FunctionFieldToBitNumber(SELNEZ_S) | FunctionFieldToBitNumber(SYNC); 990 991 // Get the encoding type of the instruction. 992 inline Type InstructionType(TypeChecks checks = NORMAL) const; 993 994 995 // Accessors for the different named fields used in the MIPS encoding. 996 inline Opcode OpcodeValue() const { 997 return static_cast<Opcode>( 998 Bits(kOpcodeShift + kOpcodeBits - 1, kOpcodeShift)); 999 } 1000 1001 inline int RsValue() const { 1002 DCHECK(InstructionType() == kRegisterType || 1003 InstructionType() == kImmediateType); 1004 return Bits(kRsShift + kRsBits - 1, kRsShift); 1005 } 1006 1007 inline int RtValue() const { 1008 DCHECK(InstructionType() == kRegisterType || 1009 InstructionType() == kImmediateType); 1010 return Bits(kRtShift + kRtBits - 1, kRtShift); 1011 } 1012 1013 inline int RdValue() const { 1014 DCHECK(InstructionType() == kRegisterType); 1015 return Bits(kRdShift + kRdBits - 1, kRdShift); 1016 } 1017 1018 inline int SaValue() const { 1019 DCHECK(InstructionType() == kRegisterType); 1020 return Bits(kSaShift + kSaBits - 1, kSaShift); 1021 } 1022 1023 inline int LsaSaValue() const { 1024 DCHECK(InstructionType() == kRegisterType); 1025 return Bits(kSaShift + kLsaSaBits - 1, kSaShift); 1026 } 1027 1028 inline int FunctionValue() const { 1029 DCHECK(InstructionType() == kRegisterType || 1030 InstructionType() == kImmediateType); 1031 return Bits(kFunctionShift + kFunctionBits - 1, kFunctionShift); 1032 } 1033 1034 inline int FdValue() const { 1035 return Bits(kFdShift + kFdBits - 1, kFdShift); 1036 } 1037 1038 inline int FsValue() const { 1039 return Bits(kFsShift + kFsBits - 1, kFsShift); 1040 } 1041 1042 inline int FtValue() const { 1043 return Bits(kFtShift + kFtBits - 1, kFtShift); 1044 } 1045 1046 inline int FrValue() const { 1047 return Bits(kFrShift + kFrBits -1, kFrShift); 1048 } 1049 1050 inline int Bp2Value() const { 1051 DCHECK(InstructionType() == kRegisterType); 1052 return Bits(kBp2Shift + kBp2Bits - 1, kBp2Shift); 1053 } 1054 1055 inline int Bp3Value() const { 1056 DCHECK(InstructionType() == kRegisterType); 1057 return Bits(kBp3Shift + kBp3Bits - 1, kBp3Shift); 1058 } 1059 1060 // Float Compare condition code instruction bits. 1061 inline int FCccValue() const { 1062 return Bits(kFCccShift + kFCccBits - 1, kFCccShift); 1063 } 1064 1065 // Float Branch condition code instruction bits. 1066 inline int FBccValue() const { 1067 return Bits(kFBccShift + kFBccBits - 1, kFBccShift); 1068 } 1069 1070 // Float Branch true/false instruction bit. 1071 inline int FBtrueValue() const { 1072 return Bits(kFBtrueShift + kFBtrueBits - 1, kFBtrueShift); 1073 } 1074 1075 // Return the fields at their original place in the instruction encoding. 1076 inline Opcode OpcodeFieldRaw() const { 1077 return static_cast<Opcode>(InstructionBits() & kOpcodeMask); 1078 } 1079 1080 inline int RsFieldRaw() const { 1081 DCHECK(InstructionType() == kRegisterType || 1082 InstructionType() == kImmediateType); 1083 return InstructionBits() & kRsFieldMask; 1084 } 1085 1086 // Same as above function, but safe to call within InstructionType(). 1087 inline int RsFieldRawNoAssert() const { 1088 return InstructionBits() & kRsFieldMask; 1089 } 1090 1091 inline int RtFieldRaw() const { 1092 DCHECK(InstructionType() == kRegisterType || 1093 InstructionType() == kImmediateType); 1094 return InstructionBits() & kRtFieldMask; 1095 } 1096 1097 inline int RdFieldRaw() const { 1098 DCHECK(InstructionType() == kRegisterType); 1099 return InstructionBits() & kRdFieldMask; 1100 } 1101 1102 inline int SaFieldRaw() const { 1103 return InstructionBits() & kSaFieldMask; 1104 } 1105 1106 inline int FunctionFieldRaw() const { 1107 return InstructionBits() & kFunctionFieldMask; 1108 } 1109 1110 // Get the secondary field according to the opcode. 1111 inline int SecondaryValue() const { 1112 Opcode op = OpcodeFieldRaw(); 1113 switch (op) { 1114 case SPECIAL: 1115 case SPECIAL2: 1116 return FunctionValue(); 1117 case COP1: 1118 return RsValue(); 1119 case REGIMM: 1120 return RtValue(); 1121 default: 1122 return NULLSF; 1123 } 1124 } 1125 1126 inline int32_t ImmValue(int bits) const { 1127 DCHECK(InstructionType() == kImmediateType); 1128 return Bits(bits - 1, 0); 1129 } 1130 1131 inline int32_t Imm16Value() const { 1132 DCHECK(InstructionType() == kImmediateType); 1133 return Bits(kImm16Shift + kImm16Bits - 1, kImm16Shift); 1134 } 1135 1136 inline int32_t Imm18Value() const { 1137 DCHECK(InstructionType() == kImmediateType); 1138 return Bits(kImm18Shift + kImm18Bits - 1, kImm18Shift); 1139 } 1140 1141 inline int32_t Imm19Value() const { 1142 DCHECK(InstructionType() == kImmediateType); 1143 return Bits(kImm19Shift + kImm19Bits - 1, kImm19Shift); 1144 } 1145 1146 inline int32_t Imm21Value() const { 1147 DCHECK(InstructionType() == kImmediateType); 1148 return Bits(kImm21Shift + kImm21Bits - 1, kImm21Shift); 1149 } 1150 1151 inline int32_t Imm26Value() const { 1152 DCHECK((InstructionType() == kJumpType) || 1153 (InstructionType() == kImmediateType)); 1154 return Bits(kImm26Shift + kImm26Bits - 1, kImm26Shift); 1155 } 1156 1157 static bool IsForbiddenAfterBranchInstr(Instr instr); 1158 1159 // Say if the instruction should not be used in a branch delay slot or 1160 // immediately after a compact branch. 1161 inline bool IsForbiddenAfterBranch() const { 1162 return IsForbiddenAfterBranchInstr(InstructionBits()); 1163 } 1164 1165 // Say if the instruction 'links'. e.g. jal, bal. 1166 bool IsLinkingInstruction() const; 1167 // Say if the instruction is a break or a trap. 1168 bool IsTrap() const; 1169 1170 // Instructions are read of out a code stream. The only way to get a 1171 // reference to an instruction is to convert a pointer. There is no way 1172 // to allocate or create instances of class Instruction. 1173 // Use the At(pc) function to create references to Instruction. 1174 static Instruction* At(byte* pc) { 1175 return reinterpret_cast<Instruction*>(pc); 1176 } 1177 1178 private: 1179 // We need to prevent the creation of instances of class Instruction. 1180 DISALLOW_IMPLICIT_CONSTRUCTORS(Instruction); 1181}; 1182 1183 1184// ----------------------------------------------------------------------------- 1185// MIPS assembly various constants. 1186 1187// C/C++ argument slots size. 1188const int kCArgSlotCount = 0; 1189 1190// TODO(plind): below should be based on kPointerSize 1191// TODO(plind): find all usages and remove the needless instructions for n64. 1192const int kCArgsSlotsSize = kCArgSlotCount * Instruction::kInstrSize * 2; 1193 1194const int kInvalidStackOffset = -1; 1195const int kBranchReturnOffset = 2 * Instruction::kInstrSize; 1196 1197 1198Instruction::Type Instruction::InstructionType(TypeChecks checks) const { 1199 if (checks == EXTRA) { 1200 if (OpcodeToBitNumber(OpcodeFieldRaw()) & kOpcodeImmediateTypeMask) { 1201 return kImmediateType; 1202 } 1203 } 1204 switch (OpcodeFieldRaw()) { 1205 case SPECIAL: 1206 if (checks == EXTRA) { 1207 if (FunctionFieldToBitNumber(FunctionFieldRaw()) & 1208 kFunctionFieldRegisterTypeMask) { 1209 return kRegisterType; 1210 } else { 1211 return kUnsupported; 1212 } 1213 } else { 1214 return kRegisterType; 1215 } 1216 break; 1217 case SPECIAL2: 1218 switch (FunctionFieldRaw()) { 1219 case MUL: 1220 case CLZ: 1221 case DCLZ: 1222 return kRegisterType; 1223 default: 1224 return kUnsupported; 1225 } 1226 break; 1227 case SPECIAL3: 1228 switch (FunctionFieldRaw()) { 1229 case INS: 1230 case DINS: 1231 case EXT: 1232 case DEXT: 1233 case DEXTM: 1234 case DEXTU: 1235 return kRegisterType; 1236 case BSHFL: { 1237 int sa = SaFieldRaw() >> kSaShift; 1238 switch (sa) { 1239 case BITSWAP: 1240 case WSBH: 1241 case SEB: 1242 case SEH: 1243 return kRegisterType; 1244 } 1245 sa >>= kBp2Bits; 1246 switch (sa) { 1247 case ALIGN: 1248 return kRegisterType; 1249 default: 1250 return kUnsupported; 1251 } 1252 } 1253 case DBSHFL: { 1254 int sa = SaFieldRaw() >> kSaShift; 1255 switch (sa) { 1256 case DBITSWAP: 1257 case DSBH: 1258 case DSHD: 1259 return kRegisterType; 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