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_CODEGEN_MIPS_CONSTANTS_MIPS_H_ 6#define V8_CODEGEN_MIPS_CONSTANTS_MIPS_H_ 7#include "src/codegen/cpu-features.h" 8// UNIMPLEMENTED_ macro for MIPS. 9#ifdef DEBUG 10#define UNIMPLEMENTED_MIPS() \ 11 v8::internal::PrintF("%s, \tline %d: \tfunction %s not implemented. \n", \ 12 __FILE__, __LINE__, __func__) 13#else 14#define UNIMPLEMENTED_MIPS() 15#endif 16 17#define UNSUPPORTED_MIPS() v8::internal::PrintF("Unsupported instruction.\n") 18 19enum ArchVariants { 20 kMips32r1 = v8::internal::MIPSr1, 21 kMips32r2 = v8::internal::MIPSr2, 22 kMips32r6 = v8::internal::MIPSr6, 23 kLoongson 24}; 25 26#ifdef _MIPS_ARCH_MIPS32R2 27static const ArchVariants kArchVariant = kMips32r2; 28#elif _MIPS_ARCH_MIPS32R6 29static const ArchVariants kArchVariant = kMips32r6; 30#elif _MIPS_ARCH_LOONGSON 31// The loongson flag refers to the LOONGSON architectures based on MIPS-III, 32// which predates (and is a subset of) the mips32r2 and r1 architectures. 33static const ArchVariants kArchVariant = kLoongson; 34#elif _MIPS_ARCH_MIPS32RX 35// This flags referred to compatibility mode that creates universal code that 36// can run on any MIPS32 architecture revision. The dynamically generated code 37// by v8 is specialized for the MIPS host detected in runtime probing. 38static const ArchVariants kArchVariant = kMips32r1; 39#else 40static const ArchVariants kArchVariant = kMips32r1; 41#endif 42 43enum Endianness { kLittle, kBig }; 44 45#if defined(V8_TARGET_LITTLE_ENDIAN) 46static const Endianness kArchEndian = kLittle; 47#elif defined(V8_TARGET_BIG_ENDIAN) 48static const Endianness kArchEndian = kBig; 49#else 50#error Unknown endianness 51#endif 52 53enum FpuMode { kFP32, kFP64, kFPXX }; 54 55#if defined(FPU_MODE_FP32) 56static const FpuMode kFpuMode = kFP32; 57#elif defined(FPU_MODE_FP64) 58static const FpuMode kFpuMode = kFP64; 59#elif defined(FPU_MODE_FPXX) 60#if defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS32R6) 61static const FpuMode kFpuMode = kFPXX; 62#else 63#error "FPXX is supported only on Mips32R2 and Mips32R6" 64#endif 65#else 66static const FpuMode kFpuMode = kFP32; 67#endif 68 69#if defined(__mips_hard_float) && __mips_hard_float != 0 70// Use floating-point coprocessor instructions. This flag is raised when 71// -mhard-float is passed to the compiler. 72const bool IsMipsSoftFloatABI = false; 73#elif defined(__mips_soft_float) && __mips_soft_float != 0 74// This flag is raised when -msoft-float is passed to the compiler. 75// Although FPU is a base requirement for v8, soft-float ABI is used 76// on soft-float systems with FPU kernel emulation. 77const bool IsMipsSoftFloatABI = true; 78#else 79const bool IsMipsSoftFloatABI = true; 80#endif 81 82#if defined(V8_TARGET_LITTLE_ENDIAN) 83const uint32_t kHoleNanUpper32Offset = 4; 84const uint32_t kHoleNanLower32Offset = 0; 85#elif defined(V8_TARGET_BIG_ENDIAN) 86const uint32_t kHoleNanUpper32Offset = 0; 87const uint32_t kHoleNanLower32Offset = 4; 88#else 89#error Unknown endianness 90#endif 91 92constexpr bool IsFp64Mode() { return kFpuMode == kFP64; } 93constexpr bool IsFp32Mode() { return kFpuMode == kFP32; } 94constexpr bool IsFpxxMode() { return kFpuMode == kFPXX; } 95 96#ifndef _MIPS_ARCH_MIPS32RX 97constexpr bool IsMipsArchVariant(const ArchVariants check) { 98 return kArchVariant == check; 99} 100#else 101bool IsMipsArchVariant(const ArchVariants check) { 102 return CpuFeatures::IsSupported(static_cast<CpuFeature>(check)); 103} 104#endif 105 106#if defined(V8_TARGET_LITTLE_ENDIAN) 107const uint32_t kMipsLwrOffset = 0; 108const uint32_t kMipsLwlOffset = 3; 109const uint32_t kMipsSwrOffset = 0; 110const uint32_t kMipsSwlOffset = 3; 111#elif defined(V8_TARGET_BIG_ENDIAN) 112const uint32_t kMipsLwrOffset = 3; 113const uint32_t kMipsLwlOffset = 0; 114const uint32_t kMipsSwrOffset = 3; 115const uint32_t kMipsSwlOffset = 0; 116#else 117#error Unknown endianness 118#endif 119 120#if defined(V8_TARGET_LITTLE_ENDIAN) 121const uint32_t kLeastSignificantByteInInt32Offset = 0; 122#elif defined(V8_TARGET_BIG_ENDIAN) 123const uint32_t kLeastSignificantByteInInt32Offset = 3; 124#else 125#error Unknown endianness 126#endif 127 128#ifndef __STDC_FORMAT_MACROS 129#define __STDC_FORMAT_MACROS 130#endif 131#include <inttypes.h> 132 133// Defines constants and accessor classes to assemble, disassemble and 134// simulate MIPS32 instructions. 135// 136// See: MIPS32 Architecture For Programmers 137// Volume II: The MIPS32 Instruction Set 138// Try www.cs.cornell.edu/courses/cs3410/2008fa/MIPS_Vol2.pdf. 139 140namespace v8 { 141namespace internal { 142 143constexpr size_t kMaxPCRelativeCodeRangeInMB = 4096; 144 145// ----------------------------------------------------------------------------- 146// Registers and FPURegisters. 147 148// Number of general purpose registers. 149const int kNumRegisters = 32; 150const int kInvalidRegister = -1; 151 152// Number of registers with HI, LO, and pc. 153const int kNumSimuRegisters = 35; 154 155// In the simulator, the PC register is simulated as the 34th register. 156const int kPCRegister = 34; 157 158// Number coprocessor registers. 159const int kNumFPURegisters = 32; 160const int kInvalidFPURegister = -1; 161 162// Number of MSA registers 163const int kNumMSARegisters = 32; 164const int kInvalidMSARegister = -1; 165 166const int kInvalidMSAControlRegister = -1; 167const int kMSAIRRegister = 0; 168const int kMSACSRRegister = 1; 169const int kMSARegSize = 128; 170const int kMSALanesByte = kMSARegSize / 8; 171const int kMSALanesHalf = kMSARegSize / 16; 172const int kMSALanesWord = kMSARegSize / 32; 173const int kMSALanesDword = kMSARegSize / 64; 174 175// FPU (coprocessor 1) control registers. Currently only FCSR is implemented. 176const int kFCSRRegister = 31; 177const int kInvalidFPUControlRegister = -1; 178const uint32_t kFPUInvalidResult = static_cast<uint32_t>(1u << 31) - 1; 179const int32_t kFPUInvalidResultNegative = static_cast<int32_t>(1u << 31); 180const uint64_t kFPU64InvalidResult = 181 static_cast<uint64_t>(static_cast<uint64_t>(1) << 63) - 1; 182const int64_t kFPU64InvalidResultNegative = 183 static_cast<int64_t>(static_cast<uint64_t>(1) << 63); 184 185// FCSR constants. 186const uint32_t kFCSRInexactFlagBit = 2; 187const uint32_t kFCSRUnderflowFlagBit = 3; 188const uint32_t kFCSROverflowFlagBit = 4; 189const uint32_t kFCSRDivideByZeroFlagBit = 5; 190const uint32_t kFCSRInvalidOpFlagBit = 6; 191const uint32_t kFCSRNaN2008FlagBit = 18; 192 193const uint32_t kFCSRInexactFlagMask = 1 << kFCSRInexactFlagBit; 194const uint32_t kFCSRUnderflowFlagMask = 1 << kFCSRUnderflowFlagBit; 195const uint32_t kFCSROverflowFlagMask = 1 << kFCSROverflowFlagBit; 196const uint32_t kFCSRDivideByZeroFlagMask = 1 << kFCSRDivideByZeroFlagBit; 197const uint32_t kFCSRInvalidOpFlagMask = 1 << kFCSRInvalidOpFlagBit; 198const uint32_t kFCSRNaN2008FlagMask = 1 << kFCSRNaN2008FlagBit; 199 200const uint32_t kFCSRFlagMask = 201 kFCSRInexactFlagMask | kFCSRUnderflowFlagMask | kFCSROverflowFlagMask | 202 kFCSRDivideByZeroFlagMask | kFCSRInvalidOpFlagMask; 203 204const uint32_t kFCSRExceptionFlagMask = kFCSRFlagMask ^ kFCSRInexactFlagMask; 205 206const uint32_t kFCSRInexactCauseBit = 12; 207const uint32_t kFCSRUnderflowCauseBit = 13; 208const uint32_t kFCSROverflowCauseBit = 14; 209const uint32_t kFCSRDivideByZeroCauseBit = 15; 210const uint32_t kFCSRInvalidOpCauseBit = 16; 211const uint32_t kFCSRUnimplementedOpCauseBit = 17; 212 213const uint32_t kFCSRInexactCauseMask = 1 << kFCSRInexactCauseBit; 214const uint32_t kFCSRUnderflowCauseMask = 1 << kFCSRUnderflowCauseBit; 215const uint32_t kFCSROverflowCauseMask = 1 << kFCSROverflowCauseBit; 216const uint32_t kFCSRDivideByZeroCauseMask = 1 << kFCSRDivideByZeroCauseBit; 217const uint32_t kFCSRInvalidOpCauseMask = 1 << kFCSRInvalidOpCauseBit; 218const uint32_t kFCSRUnimplementedOpCauseMask = 1 219 << kFCSRUnimplementedOpCauseBit; 220 221const uint32_t kFCSRCauseMask = 222 kFCSRInexactCauseMask | kFCSRUnderflowCauseMask | kFCSROverflowCauseMask | 223 kFCSRDivideByZeroCauseMask | kFCSRInvalidOpCauseMask | 224 kFCSRUnimplementedOpCauseBit; 225 226// 'pref' instruction hints 227const int32_t kPrefHintLoad = 0; 228const int32_t kPrefHintStore = 1; 229const int32_t kPrefHintLoadStreamed = 4; 230const int32_t kPrefHintStoreStreamed = 5; 231const int32_t kPrefHintLoadRetained = 6; 232const int32_t kPrefHintStoreRetained = 7; 233const int32_t kPrefHintWritebackInvalidate = 25; 234const int32_t kPrefHintPrepareForStore = 30; 235 236// Actual value of root register is offset from the root array's start 237// to take advantage of negative displacement values. 238// TODO(sigurds): Choose best value. 239constexpr int kRootRegisterBias = 256; 240 241// Helper functions for converting between register numbers and names. 242class Registers { 243 public: 244 // Return the name of the register. 245 static const char* Name(int reg); 246 247 // Lookup the register number for the name provided. 248 static int Number(const char* name); 249 250 struct RegisterAlias { 251 int reg; 252 const char* name; 253 }; 254 255 static const int32_t kMaxValue = 0x7fffffff; 256 static const int32_t kMinValue = 0x80000000; 257 258 private: 259 static const char* names_[kNumSimuRegisters]; 260 static const RegisterAlias aliases_[]; 261}; 262 263// Helper functions for converting between register numbers and names. 264class FPURegisters { 265 public: 266 // Return the name of the register. 267 static const char* Name(int reg); 268 269 // Lookup the register number for the name provided. 270 static int Number(const char* name); 271 272 struct RegisterAlias { 273 int creg; 274 const char* name; 275 }; 276 277 private: 278 static const char* names_[kNumFPURegisters]; 279 static const RegisterAlias aliases_[]; 280}; 281 282// Helper functions for converting between register numbers and names. 283class MSARegisters { 284 public: 285 // Return the name of the register. 286 static const char* Name(int reg); 287 288 // Lookup the register number for the name provided. 289 static int Number(const char* name); 290 291 struct RegisterAlias { 292 int creg; 293 const char* name; 294 }; 295 296 private: 297 static const char* names_[kNumMSARegisters]; 298 static const RegisterAlias aliases_[]; 299}; 300 301// ----------------------------------------------------------------------------- 302// Instructions encoding constants. 303 304// On MIPS all instructions are 32 bits. 305using Instr = int32_t; 306 307// Special Software Interrupt codes when used in the presence of the MIPS 308// simulator. 309enum SoftwareInterruptCodes { 310 // Transition to C code. 311 call_rt_redirected = 0xfffff 312}; 313 314// On MIPS Simulator breakpoints can have different codes: 315// - Breaks between 0 and kMaxWatchpointCode are treated as simple watchpoints, 316// the simulator will run through them and print the registers. 317// - Breaks between kMaxWatchpointCode and kMaxStopCode are treated as stop() 318// instructions (see Assembler::stop()). 319// - Breaks larger than kMaxStopCode are simple breaks, dropping you into the 320// debugger. 321const uint32_t kMaxWatchpointCode = 31; 322const uint32_t kMaxStopCode = 127; 323STATIC_ASSERT(kMaxWatchpointCode < kMaxStopCode); 324 325// ----- Fields offset and length. 326const int kOpcodeShift = 26; 327const int kOpcodeBits = 6; 328const int kRsShift = 21; 329const int kRsBits = 5; 330const int kRtShift = 16; 331const int kRtBits = 5; 332const int kRdShift = 11; 333const int kRdBits = 5; 334const int kSaShift = 6; 335const int kSaBits = 5; 336const int kLsaSaBits = 2; 337const int kFunctionShift = 0; 338const int kFunctionBits = 6; 339const int kLuiShift = 16; 340const int kBp2Shift = 6; 341const int kBp2Bits = 2; 342const int kBaseShift = 21; 343const int kBaseBits = 5; 344const int kBit6Shift = 6; 345const int kBit6Bits = 1; 346 347const int kImm9Shift = 7; 348const int kImm9Bits = 9; 349const int kImm16Shift = 0; 350const int kImm16Bits = 16; 351const int kImm18Shift = 0; 352const int kImm18Bits = 18; 353const int kImm19Shift = 0; 354const int kImm19Bits = 19; 355const int kImm21Shift = 0; 356const int kImm21Bits = 21; 357const int kImm26Shift = 0; 358const int kImm26Bits = 26; 359const int kImm28Shift = 0; 360const int kImm28Bits = 28; 361const int kImm32Shift = 0; 362const int kImm32Bits = 32; 363const int kMsaImm8Shift = 16; 364const int kMsaImm8Bits = 8; 365const int kMsaImm5Shift = 16; 366const int kMsaImm5Bits = 5; 367const int kMsaImm10Shift = 11; 368const int kMsaImm10Bits = 10; 369const int kMsaImmMI10Shift = 16; 370const int kMsaImmMI10Bits = 10; 371 372// In branches and jumps immediate fields point to words, not bytes, 373// and are therefore shifted by 2. 374const int kImmFieldShift = 2; 375 376const int kFrBits = 5; 377const int kFrShift = 21; 378const int kFsShift = 11; 379const int kFsBits = 5; 380const int kFtShift = 16; 381const int kFtBits = 5; 382const int kFdShift = 6; 383const int kFdBits = 5; 384const int kFCccShift = 8; 385const int kFCccBits = 3; 386const int kFBccShift = 18; 387const int kFBccBits = 3; 388const int kFBtrueShift = 16; 389const int kFBtrueBits = 1; 390const int kWtBits = 5; 391const int kWtShift = 16; 392const int kWsBits = 5; 393const int kWsShift = 11; 394const int kWdBits = 5; 395const int kWdShift = 6; 396 397// ----- Miscellaneous useful masks. 398// Instruction bit masks. 399const int kOpcodeMask = ((1 << kOpcodeBits) - 1) << kOpcodeShift; 400const int kImm9Mask = ((1 << kImm9Bits) - 1) << kImm9Shift; 401const int kImm16Mask = ((1 << kImm16Bits) - 1) << kImm16Shift; 402const int kImm18Mask = ((1 << kImm18Bits) - 1) << kImm18Shift; 403const int kImm19Mask = ((1 << kImm19Bits) - 1) << kImm19Shift; 404const int kImm21Mask = ((1 << kImm21Bits) - 1) << kImm21Shift; 405const int kImm26Mask = ((1 << kImm26Bits) - 1) << kImm26Shift; 406const int kImm28Mask = ((1 << kImm28Bits) - 1) << kImm28Shift; 407const int kImm5Mask = ((1 << 5) - 1); 408const int kImm8Mask = ((1 << 8) - 1); 409const int kImm10Mask = ((1 << 10) - 1); 410const int kMsaI5I10Mask = ((7U << 23) | ((1 << 6) - 1)); 411const int kMsaI8Mask = ((3U << 24) | ((1 << 6) - 1)); 412const int kMsaI5Mask = ((7U << 23) | ((1 << 6) - 1)); 413const int kMsaMI10Mask = (15U << 2); 414const int kMsaBITMask = ((7U << 23) | ((1 << 6) - 1)); 415const int kMsaELMMask = (15U << 22); 416const int kMsaLongerELMMask = kMsaELMMask | (63U << 16); 417const int kMsa3RMask = ((7U << 23) | ((1 << 6) - 1)); 418const int kMsa3RFMask = ((15U << 22) | ((1 << 6) - 1)); 419const int kMsaVECMask = (23U << 21); 420const int kMsa2RMask = (7U << 18); 421const int kMsa2RFMask = (15U << 17); 422const int kRsFieldMask = ((1 << kRsBits) - 1) << kRsShift; 423const int kRtFieldMask = ((1 << kRtBits) - 1) << kRtShift; 424const int kRdFieldMask = ((1 << kRdBits) - 1) << kRdShift; 425const int kSaFieldMask = ((1 << kSaBits) - 1) << kSaShift; 426const int kFunctionFieldMask = ((1 << kFunctionBits) - 1) << kFunctionShift; 427// Misc masks. 428const int kHiMask = 0xffff << 16; 429const int kLoMask = 0xffff; 430const int kSignMask = 0x80000000; 431const int kJumpAddrMask = (1 << (kImm26Bits + kImmFieldShift)) - 1; 432 433// ----- MIPS Opcodes and Function Fields. 434// We use this presentation to stay close to the table representation in 435// MIPS32 Architecture For Programmers, Volume II: The MIPS32 Instruction Set. 436enum Opcode : uint32_t { 437 SPECIAL = 0U << kOpcodeShift, 438 REGIMM = 1U << kOpcodeShift, 439 440 J = ((0U << 3) + 2) << kOpcodeShift, 441 JAL = ((0U << 3) + 3) << kOpcodeShift, 442 BEQ = ((0U << 3) + 4) << kOpcodeShift, 443 BNE = ((0U << 3) + 5) << kOpcodeShift, 444 BLEZ = ((0U << 3) + 6) << kOpcodeShift, 445 BGTZ = ((0U << 3) + 7) << kOpcodeShift, 446 447 ADDI = ((1U << 3) + 0) << kOpcodeShift, 448 ADDIU = ((1U << 3) + 1) << kOpcodeShift, 449 SLTI = ((1U << 3) + 2) << kOpcodeShift, 450 SLTIU = ((1U << 3) + 3) << kOpcodeShift, 451 ANDI = ((1U << 3) + 4) << kOpcodeShift, 452 ORI = ((1U << 3) + 5) << kOpcodeShift, 453 XORI = ((1U << 3) + 6) << kOpcodeShift, 454 LUI = ((1U << 3) + 7) << kOpcodeShift, // LUI/AUI family. 455 456 BEQC = ((2U << 3) + 0) << kOpcodeShift, 457 COP1 = ((2U << 3) + 1) << kOpcodeShift, // Coprocessor 1 class. 458 BEQL = ((2U << 3) + 4) << kOpcodeShift, 459 BNEL = ((2U << 3) + 5) << kOpcodeShift, 460 BLEZL = ((2U << 3) + 6) << kOpcodeShift, 461 BGTZL = ((2U << 3) + 7) << kOpcodeShift, 462 463 DADDI = ((3U << 3) + 0) << kOpcodeShift, // This is also BNEC. 464 SPECIAL2 = ((3U << 3) + 4) << kOpcodeShift, 465 MSA = ((3U << 3) + 6) << kOpcodeShift, 466 SPECIAL3 = ((3U << 3) + 7) << kOpcodeShift, 467 468 LB = ((4U << 3) + 0) << kOpcodeShift, 469 LH = ((4U << 3) + 1) << kOpcodeShift, 470 LWL = ((4U << 3) + 2) << kOpcodeShift, 471 LW = ((4U << 3) + 3) << kOpcodeShift, 472 LBU = ((4U << 3) + 4) << kOpcodeShift, 473 LHU = ((4U << 3) + 5) << kOpcodeShift, 474 LWR = ((4U << 3) + 6) << kOpcodeShift, 475 SB = ((5U << 3) + 0) << kOpcodeShift, 476 SH = ((5U << 3) + 1) << kOpcodeShift, 477 SWL = ((5U << 3) + 2) << kOpcodeShift, 478 SW = ((5U << 3) + 3) << kOpcodeShift, 479 SWR = ((5U << 3) + 6) << kOpcodeShift, 480 481 LL = ((6U << 3) + 0) << kOpcodeShift, 482 LWC1 = ((6U << 3) + 1) << kOpcodeShift, 483 BC = ((6U << 3) + 2) << kOpcodeShift, 484 LDC1 = ((6U << 3) + 5) << kOpcodeShift, 485 POP66 = ((6U << 3) + 6) << kOpcodeShift, // beqzc, jic 486 487 PREF = ((6U << 3) + 3) << kOpcodeShift, 488 489 SC = ((7U << 3) + 0) << kOpcodeShift, 490 SWC1 = ((7U << 3) + 1) << kOpcodeShift, 491 BALC = ((7U << 3) + 2) << kOpcodeShift, 492 PCREL = ((7U << 3) + 3) << kOpcodeShift, 493 SDC1 = ((7U << 3) + 5) << kOpcodeShift, 494 POP76 = ((7U << 3) + 6) << kOpcodeShift, // bnezc, jialc 495 496 COP1X = ((1U << 4) + 3) << kOpcodeShift, 497 498 // New r6 instruction. 499 POP06 = BLEZ, // bgeuc/bleuc, blezalc, bgezalc 500 POP07 = BGTZ, // bltuc/bgtuc, bgtzalc, bltzalc 501 POP10 = ADDI, // beqzalc, bovc, beqc 502 POP26 = BLEZL, // bgezc, blezc, bgec/blec 503 POP27 = BGTZL, // bgtzc, bltzc, bltc/bgtc 504 POP30 = DADDI, // bnezalc, bnvc, bnec 505}; 506 507enum SecondaryField : uint32_t { 508 // SPECIAL Encoding of Function Field. 509 SLL = ((0U << 3) + 0), 510 MOVCI = ((0U << 3) + 1), 511 SRL = ((0U << 3) + 2), 512 SRA = ((0U << 3) + 3), 513 SLLV = ((0U << 3) + 4), 514 LSA = ((0U << 3) + 5), 515 SRLV = ((0U << 3) + 6), 516 SRAV = ((0U << 3) + 7), 517 518 JR = ((1U << 3) + 0), 519 JALR = ((1U << 3) + 1), 520 MOVZ = ((1U << 3) + 2), 521 MOVN = ((1U << 3) + 3), 522 BREAK = ((1U << 3) + 5), 523 SYNC = ((1U << 3) + 7), 524 525 MFHI = ((2U << 3) + 0), 526 CLZ_R6 = ((2U << 3) + 0), 527 CLO_R6 = ((2U << 3) + 1), 528 MFLO = ((2U << 3) + 2), 529 530 MULT = ((3U << 3) + 0), 531 MULTU = ((3U << 3) + 1), 532 DIV = ((3U << 3) + 2), 533 DIVU = ((3U << 3) + 3), 534 535 ADD = ((4U << 3) + 0), 536 ADDU = ((4U << 3) + 1), 537 SUB = ((4U << 3) + 2), 538 SUBU = ((4U << 3) + 3), 539 AND = ((4U << 3) + 4), 540 OR = ((4U << 3) + 5), 541 XOR = ((4U << 3) + 6), 542 NOR = ((4U << 3) + 7), 543 544 SLT = ((5U << 3) + 2), 545 SLTU = ((5U << 3) + 3), 546 547 TGE = ((6U << 3) + 0), 548 TGEU = ((6U << 3) + 1), 549 TLT = ((6U << 3) + 2), 550 TLTU = ((6U << 3) + 3), 551 TEQ = ((6U << 3) + 4), 552 SELEQZ_S = ((6U << 3) + 5), 553 TNE = ((6U << 3) + 6), 554 SELNEZ_S = ((6U << 3) + 7), 555 556 // Multiply integers in r6. 557 MUL_MUH = ((3U << 3) + 0), // MUL, MUH. 558 MUL_MUH_U = ((3U << 3) + 1), // MUL_U, MUH_U. 559 RINT = ((3U << 3) + 2), 560 561 MUL_OP = ((0U << 3) + 2), 562 MUH_OP = ((0U << 3) + 3), 563 DIV_OP = ((0U << 3) + 2), 564 MOD_OP = ((0U << 3) + 3), 565 566 DIV_MOD = ((3U << 3) + 2), 567 DIV_MOD_U = ((3U << 3) + 3), 568 569 // SPECIAL2 Encoding of Function Field. 570 MUL = ((0U << 3) + 2), 571 CLZ = ((4U << 3) + 0), 572 CLO = ((4U << 3) + 1), 573 574 // SPECIAL3 Encoding of Function Field. 575 EXT = ((0U << 3) + 0), 576 INS = ((0U << 3) + 4), 577 BSHFL = ((4U << 3) + 0), 578 SC_R6 = ((4U << 3) + 6), 579 LL_R6 = ((6U << 3) + 6), 580 581 // SPECIAL3 Encoding of sa Field. 582 BITSWAP = ((0U << 3) + 0), 583 ALIGN = ((0U << 3) + 2), 584 WSBH = ((0U << 3) + 2), 585 SEB = ((2U << 3) + 0), 586 SEH = ((3U << 3) + 0), 587 588 // REGIMM encoding of rt Field. 589 BLTZ = ((0U << 3) + 0) << 16, 590 BGEZ = ((0U << 3) + 1) << 16, 591 BLTZAL = ((2U << 3) + 0) << 16, 592 BGEZAL = ((2U << 3) + 1) << 16, 593 BGEZALL = ((2U << 3) + 3) << 16, 594 595 // COP1 Encoding of rs Field. 596 MFC1 = ((0U << 3) + 0) << 21, 597 CFC1 = ((0U << 3) + 2) << 21, 598 MFHC1 = ((0U << 3) + 3) << 21, 599 MTC1 = ((0U << 3) + 4) << 21, 600 CTC1 = ((0U << 3) + 6) << 21, 601 MTHC1 = ((0U << 3) + 7) << 21, 602 BC1 = ((1U << 3) + 0) << 21, 603 S = ((2U << 3) + 0) << 21, 604 D = ((2U << 3) + 1) << 21, 605 W = ((2U << 3) + 4) << 21, 606 L = ((2U << 3) + 5) << 21, 607 PS = ((2U << 3) + 6) << 21, 608 // COP1 Encoding of Function Field When rs=S. 609 610 ADD_S = ((0U << 3) + 0), 611 SUB_S = ((0U << 3) + 1), 612 MUL_S = ((0U << 3) + 2), 613 DIV_S = ((0U << 3) + 3), 614 ABS_S = ((0U << 3) + 5), 615 SQRT_S = ((0U << 3) + 4), 616 MOV_S = ((0U << 3) + 6), 617 NEG_S = ((0U << 3) + 7), 618 ROUND_L_S = ((1U << 3) + 0), 619 TRUNC_L_S = ((1U << 3) + 1), 620 CEIL_L_S = ((1U << 3) + 2), 621 FLOOR_L_S = ((1U << 3) + 3), 622 ROUND_W_S = ((1U << 3) + 4), 623 TRUNC_W_S = ((1U << 3) + 5), 624 CEIL_W_S = ((1U << 3) + 6), 625 FLOOR_W_S = ((1U << 3) + 7), 626 RECIP_S = ((2U << 3) + 5), 627 RSQRT_S = ((2U << 3) + 6), 628 MADDF_S = ((3U << 3) + 0), 629 MSUBF_S = ((3U << 3) + 1), 630 CLASS_S = ((3U << 3) + 3), 631 CVT_D_S = ((4U << 3) + 1), 632 CVT_W_S = ((4U << 3) + 4), 633 CVT_L_S = ((4U << 3) + 5), 634 CVT_PS_S = ((4U << 3) + 6), 635 636 // COP1 Encoding of Function Field When rs=D. 637 ADD_D = ((0U << 3) + 0), 638 SUB_D = ((0U << 3) + 1), 639 MUL_D = ((0U << 3) + 2), 640 DIV_D = ((0U << 3) + 3), 641 SQRT_D = ((0U << 3) + 4), 642 ABS_D = ((0U << 3) + 5), 643 MOV_D = ((0U << 3) + 6), 644 NEG_D = ((0U << 3) + 7), 645 ROUND_L_D = ((1U << 3) + 0), 646 TRUNC_L_D = ((1U << 3) + 1), 647 CEIL_L_D = ((1U << 3) + 2), 648 FLOOR_L_D = ((1U << 3) + 3), 649 ROUND_W_D = ((1U << 3) + 4), 650 TRUNC_W_D = ((1U << 3) + 5), 651 CEIL_W_D = ((1U << 3) + 6), 652 FLOOR_W_D = ((1U << 3) + 7), 653 RECIP_D = ((2U << 3) + 5), 654 RSQRT_D = ((2U << 3) + 6), 655 MADDF_D = ((3U << 3) + 0), 656 MSUBF_D = ((3U << 3) + 1), 657 CLASS_D = ((3U << 3) + 3), 658 MIN = ((3U << 3) + 4), 659 MINA = ((3U << 3) + 5), 660 MAX = ((3U << 3) + 6), 661 MAXA = ((3U << 3) + 7), 662 CVT_S_D = ((4U << 3) + 0), 663 CVT_W_D = ((4U << 3) + 4), 664 CVT_L_D = ((4U << 3) + 5), 665 C_F_D = ((6U << 3) + 0), 666 C_UN_D = ((6U << 3) + 1), 667 C_EQ_D = ((6U << 3) + 2), 668 C_UEQ_D = ((6U << 3) + 3), 669 C_OLT_D = ((6U << 3) + 4), 670 C_ULT_D = ((6U << 3) + 5), 671 C_OLE_D = ((6U << 3) + 6), 672 C_ULE_D = ((6U << 3) + 7), 673 674 // COP1 Encoding of Function Field When rs=W or L. 675 CVT_S_W = ((4U << 3) + 0), 676 CVT_D_W = ((4U << 3) + 1), 677 CVT_S_L = ((4U << 3) + 0), 678 CVT_D_L = ((4U << 3) + 1), 679 BC1EQZ = ((2U << 2) + 1) << 21, 680 BC1NEZ = ((3U << 2) + 1) << 21, 681 // COP1 CMP positive predicates Bit 5..4 = 00. 682 CMP_AF = ((0U << 3) + 0), 683 CMP_UN = ((0U << 3) + 1), 684 CMP_EQ = ((0U << 3) + 2), 685 CMP_UEQ = ((0U << 3) + 3), 686 CMP_LT = ((0U << 3) + 4), 687 CMP_ULT = ((0U << 3) + 5), 688 CMP_LE = ((0U << 3) + 6), 689 CMP_ULE = ((0U << 3) + 7), 690 CMP_SAF = ((1U << 3) + 0), 691 CMP_SUN = ((1U << 3) + 1), 692 CMP_SEQ = ((1U << 3) + 2), 693 CMP_SUEQ = ((1U << 3) + 3), 694 CMP_SSLT = ((1U << 3) + 4), 695 CMP_SSULT = ((1U << 3) + 5), 696 CMP_SLE = ((1U << 3) + 6), 697 CMP_SULE = ((1U << 3) + 7), 698 // COP1 CMP negative predicates Bit 5..4 = 01. 699 CMP_AT = ((2U << 3) + 0), // Reserved, not implemented. 700 CMP_OR = ((2U << 3) + 1), 701 CMP_UNE = ((2U << 3) + 2), 702 CMP_NE = ((2U << 3) + 3), 703 CMP_UGE = ((2U << 3) + 4), // Reserved, not implemented. 704 CMP_OGE = ((2U << 3) + 5), // Reserved, not implemented. 705 CMP_UGT = ((2U << 3) + 6), // Reserved, not implemented. 706 CMP_OGT = ((2U << 3) + 7), // Reserved, not implemented. 707 CMP_SAT = ((3U << 3) + 0), // Reserved, not implemented. 708 CMP_SOR = ((3U << 3) + 1), 709 CMP_SUNE = ((3U << 3) + 2), 710 CMP_SNE = ((3U << 3) + 3), 711 CMP_SUGE = ((3U << 3) + 4), // Reserved, not implemented. 712 CMP_SOGE = ((3U << 3) + 5), // Reserved, not implemented. 713 CMP_SUGT = ((3U << 3) + 6), // Reserved, not implemented. 714 CMP_SOGT = ((3U << 3) + 7), // Reserved, not implemented. 715 716 SEL = ((2U << 3) + 0), 717 MOVZ_C = ((2U << 3) + 2), 718 MOVN_C = ((2U << 3) + 3), 719 SELEQZ_C = ((2U << 3) + 4), // COP1 on FPR registers. 720 MOVF = ((2U << 3) + 1), // Function field for MOVT.fmt and MOVF.fmt 721 SELNEZ_C = ((2U << 3) + 7), // COP1 on FPR registers. 722 // COP1 Encoding of Function Field When rs=PS. 723 724 // COP1X Encoding of Function Field. 725 MADD_S = ((4U << 3) + 0), 726 MADD_D = ((4U << 3) + 1), 727 MSUB_S = ((5U << 3) + 0), 728 MSUB_D = ((5U << 3) + 1), 729 730 // PCREL Encoding of rt Field. 731 ADDIUPC = ((0U << 2) + 0), 732 LWPC = ((0U << 2) + 1), 733 AUIPC = ((3U << 3) + 6), 734 ALUIPC = ((3U << 3) + 7), 735 736 // POP66 Encoding of rs Field. 737 JIC = ((0U << 5) + 0), 738 739 // POP76 Encoding of rs Field. 740 JIALC = ((0U << 5) + 0), 741 742 // COP1 Encoding of rs Field for MSA Branch Instructions 743 BZ_V = (((1U << 3) + 3) << kRsShift), 744 BNZ_V = (((1U << 3) + 7) << kRsShift), 745 BZ_B = (((3U << 3) + 0) << kRsShift), 746 BZ_H = (((3U << 3) + 1) << kRsShift), 747 BZ_W = (((3U << 3) + 2) << kRsShift), 748 BZ_D = (((3U << 3) + 3) << kRsShift), 749 BNZ_B = (((3U << 3) + 4) << kRsShift), 750 BNZ_H = (((3U << 3) + 5) << kRsShift), 751 BNZ_W = (((3U << 3) + 6) << kRsShift), 752 BNZ_D = (((3U << 3) + 7) << kRsShift), 753 754 // MSA: Operation Field for MI10 Instruction Formats 755 MSA_LD = (8U << 2), 756 MSA_ST = (9U << 2), 757 LD_B = ((8U << 2) + 0), 758 LD_H = ((8U << 2) + 1), 759 LD_W = ((8U << 2) + 2), 760 LD_D = ((8U << 2) + 3), 761 ST_B = ((9U << 2) + 0), 762 ST_H = ((9U << 2) + 1), 763 ST_W = ((9U << 2) + 2), 764 ST_D = ((9U << 2) + 3), 765 766 // MSA: Operation Field for I5 Instruction Format 767 ADDVI = ((0U << 23) + 6), 768 SUBVI = ((1U << 23) + 6), 769 MAXI_S = ((2U << 23) + 6), 770 MAXI_U = ((3U << 23) + 6), 771 MINI_S = ((4U << 23) + 6), 772 MINI_U = ((5U << 23) + 6), 773 CEQI = ((0U << 23) + 7), 774 CLTI_S = ((2U << 23) + 7), 775 CLTI_U = ((3U << 23) + 7), 776 CLEI_S = ((4U << 23) + 7), 777 CLEI_U = ((5U << 23) + 7), 778 LDI = ((6U << 23) + 7), // I10 instruction format 779 I5_DF_b = (0U << 21), 780 I5_DF_h = (1U << 21), 781 I5_DF_w = (2U << 21), 782 I5_DF_d = (3U << 21), 783 784 // MSA: Operation Field for I8 Instruction Format 785 ANDI_B = ((0U << 24) + 0), 786 ORI_B = ((1U << 24) + 0), 787 NORI_B = ((2U << 24) + 0), 788 XORI_B = ((3U << 24) + 0), 789 BMNZI_B = ((0U << 24) + 1), 790 BMZI_B = ((1U << 24) + 1), 791 BSELI_B = ((2U << 24) + 1), 792 SHF_B = ((0U << 24) + 2), 793 SHF_H = ((1U << 24) + 2), 794 SHF_W = ((2U << 24) + 2), 795 796 MSA_VEC_2R_2RF_MINOR = ((3U << 3) + 6), 797 798 // MSA: Operation Field for VEC Instruction Formats 799 AND_V = (((0U << 2) + 0) << 21), 800 OR_V = (((0U << 2) + 1) << 21), 801 NOR_V = (((0U << 2) + 2) << 21), 802 XOR_V = (((0U << 2) + 3) << 21), 803 BMNZ_V = (((1U << 2) + 0) << 21), 804 BMZ_V = (((1U << 2) + 1) << 21), 805 BSEL_V = (((1U << 2) + 2) << 21), 806 807 // MSA: Operation Field for 2R Instruction Formats 808 MSA_2R_FORMAT = (((6U << 2) + 0) << 21), 809 FILL = (0U << 18), 810 PCNT = (1U << 18), 811 NLOC = (2U << 18), 812 NLZC = (3U << 18), 813 MSA_2R_DF_b = (0U << 16), 814 MSA_2R_DF_h = (1U << 16), 815 MSA_2R_DF_w = (2U << 16), 816 MSA_2R_DF_d = (3U << 16), 817 818 // MSA: Operation Field for 2RF Instruction Formats 819 MSA_2RF_FORMAT = (((6U << 2) + 1) << 21), 820 FCLASS = (0U << 17), 821 FTRUNC_S = (1U << 17), 822 FTRUNC_U = (2U << 17), 823 FSQRT = (3U << 17), 824 FRSQRT = (4U << 17), 825 FRCP = (5U << 17), 826 FRINT = (6U << 17), 827 FLOG2 = (7U << 17), 828 FEXUPL = (8U << 17), 829 FEXUPR = (9U << 17), 830 FFQL = (10U << 17), 831 FFQR = (11U << 17), 832 FTINT_S = (12U << 17), 833 FTINT_U = (13U << 17), 834 FFINT_S = (14U << 17), 835 FFINT_U = (15U << 17), 836 MSA_2RF_DF_w = (0U << 16), 837 MSA_2RF_DF_d = (1U << 16), 838 839 // MSA: Operation Field for 3R Instruction Format 840 SLL_MSA = ((0U << 23) + 13), 841 SRA_MSA = ((1U << 23) + 13), 842 SRL_MSA = ((2U << 23) + 13), 843 BCLR = ((3U << 23) + 13), 844 BSET = ((4U << 23) + 13), 845 BNEG = ((5U << 23) + 13), 846 BINSL = ((6U << 23) + 13), 847 BINSR = ((7U << 23) + 13), 848 ADDV = ((0U << 23) + 14), 849 SUBV = ((1U << 23) + 14), 850 MAX_S = ((2U << 23) + 14), 851 MAX_U = ((3U << 23) + 14), 852 MIN_S = ((4U << 23) + 14), 853 MIN_U = ((5U << 23) + 14), 854 MAX_A = ((6U << 23) + 14), 855 MIN_A = ((7U << 23) + 14), 856 CEQ = ((0U << 23) + 15), 857 CLT_S = ((2U << 23) + 15), 858 CLT_U = ((3U << 23) + 15), 859 CLE_S = ((4U << 23) + 15), 860 CLE_U = ((5U << 23) + 15), 861 ADD_A = ((0U << 23) + 16), 862 ADDS_A = ((1U << 23) + 16), 863 ADDS_S = ((2U << 23) + 16), 864 ADDS_U = ((3U << 23) + 16), 865 AVE_S = ((4U << 23) + 16), 866 AVE_U = ((5U << 23) + 16), 867 AVER_S = ((6U << 23) + 16), 868 AVER_U = ((7U << 23) + 16), 869 SUBS_S = ((0U << 23) + 17), 870 SUBS_U = ((1U << 23) + 17), 871 SUBSUS_U = ((2U << 23) + 17), 872 SUBSUU_S = ((3U << 23) + 17), 873 ASUB_S = ((4U << 23) + 17), 874 ASUB_U = ((5U << 23) + 17), 875 MULV = ((0U << 23) + 18), 876 MADDV = ((1U << 23) + 18), 877 MSUBV = ((2U << 23) + 18), 878 DIV_S_MSA = ((4U << 23) + 18), 879 DIV_U = ((5U << 23) + 18), 880 MOD_S = ((6U << 23) + 18), 881 MOD_U = ((7U << 23) + 18), 882 DOTP_S = ((0U << 23) + 19), 883 DOTP_U = ((1U << 23) + 19), 884 DPADD_S = ((2U << 23) + 19), 885 DPADD_U = ((3U << 23) + 19), 886 DPSUB_S = ((4U << 23) + 19), 887 DPSUB_U = ((5U << 23) + 19), 888 SLD = ((0U << 23) + 20), 889 SPLAT = ((1U << 23) + 20), 890 PCKEV = ((2U << 23) + 20), 891 PCKOD = ((3U << 23) + 20), 892 ILVL = ((4U << 23) + 20), 893 ILVR = ((5U << 23) + 20), 894 ILVEV = ((6U << 23) + 20), 895 ILVOD = ((7U << 23) + 20), 896 VSHF = ((0U << 23) + 21), 897 SRAR = ((1U << 23) + 21), 898 SRLR = ((2U << 23) + 21), 899 HADD_S = ((4U << 23) + 21), 900 HADD_U = ((5U << 23) + 21), 901 HSUB_S = ((6U << 23) + 21), 902 HSUB_U = ((7U << 23) + 21), 903 MSA_3R_DF_b = (0U << 21), 904 MSA_3R_DF_h = (1U << 21), 905 MSA_3R_DF_w = (2U << 21), 906 MSA_3R_DF_d = (3U << 21), 907 908 // MSA: Operation Field for 3RF Instruction Format 909 FCAF = ((0U << 22) + 26), 910 FCUN = ((1U << 22) + 26), 911 FCEQ = ((2U << 22) + 26), 912 FCUEQ = ((3U << 22) + 26), 913 FCLT = ((4U << 22) + 26), 914 FCULT = ((5U << 22) + 26), 915 FCLE = ((6U << 22) + 26), 916 FCULE = ((7U << 22) + 26), 917 FSAF = ((8U << 22) + 26), 918 FSUN = ((9U << 22) + 26), 919 FSEQ = ((10U << 22) + 26), 920 FSUEQ = ((11U << 22) + 26), 921 FSLT = ((12U << 22) + 26), 922 FSULT = ((13U << 22) + 26), 923 FSLE = ((14U << 22) + 26), 924 FSULE = ((15U << 22) + 26), 925 FADD = ((0U << 22) + 27), 926 FSUB = ((1U << 22) + 27), 927 FMUL = ((2U << 22) + 27), 928 FDIV = ((3U << 22) + 27), 929 FMADD = ((4U << 22) + 27), 930 FMSUB = ((5U << 22) + 27), 931 FEXP2 = ((7U << 22) + 27), 932 FEXDO = ((8U << 22) + 27), 933 FTQ = ((10U << 22) + 27), 934 FMIN = ((12U << 22) + 27), 935 FMIN_A = ((13U << 22) + 27), 936 FMAX = ((14U << 22) + 27), 937 FMAX_A = ((15U << 22) + 27), 938 FCOR = ((1U << 22) + 28), 939 FCUNE = ((2U << 22) + 28), 940 FCNE = ((3U << 22) + 28), 941 MUL_Q = ((4U << 22) + 28), 942 MADD_Q = ((5U << 22) + 28), 943 MSUB_Q = ((6U << 22) + 28), 944 FSOR = ((9U << 22) + 28), 945 FSUNE = ((10U << 22) + 28), 946 FSNE = ((11U << 22) + 28), 947 MULR_Q = ((12U << 22) + 28), 948 MADDR_Q = ((13U << 22) + 28), 949 MSUBR_Q = ((14U << 22) + 28), 950 951 // MSA: Operation Field for ELM Instruction Format 952 MSA_ELM_MINOR = ((3U << 3) + 1), 953 SLDI = (0U << 22), 954 CTCMSA = ((0U << 22) | (62U << 16)), 955 SPLATI = (1U << 22), 956 CFCMSA = ((1U << 22) | (62U << 16)), 957 COPY_S = (2U << 22), 958 MOVE_V = ((2U << 22) | (62U << 16)), 959 COPY_U = (3U << 22), 960 INSERT = (4U << 22), 961 INSVE = (5U << 22), 962 ELM_DF_B = ((0U << 4) << 16), 963 ELM_DF_H = ((4U << 3) << 16), 964 ELM_DF_W = ((12U << 2) << 16), 965 ELM_DF_D = ((28U << 1) << 16), 966 967 // MSA: Operation Field for BIT Instruction Format 968 SLLI = ((0U << 23) + 9), 969 SRAI = ((1U << 23) + 9), 970 SRLI = ((2U << 23) + 9), 971 BCLRI = ((3U << 23) + 9), 972 BSETI = ((4U << 23) + 9), 973 BNEGI = ((5U << 23) + 9), 974 BINSLI = ((6U << 23) + 9), 975 BINSRI = ((7U << 23) + 9), 976 SAT_S = ((0U << 23) + 10), 977 SAT_U = ((1U << 23) + 10), 978 SRARI = ((2U << 23) + 10), 979 SRLRI = ((3U << 23) + 10), 980 BIT_DF_b = ((14U << 3) << 16), 981 BIT_DF_h = ((6U << 4) << 16), 982 BIT_DF_w = ((2U << 5) << 16), 983 BIT_DF_d = ((0U << 6) << 16), 984 985 nullptrSF = 0U 986}; 987 988enum MSAMinorOpcode : uint32_t { 989 kMsaMinorUndefined = 0, 990 kMsaMinorI8, 991 kMsaMinorI5, 992 kMsaMinorI10, 993 kMsaMinorBIT, 994 kMsaMinor3R, 995 kMsaMinor3RF, 996 kMsaMinorELM, 997 kMsaMinorVEC, 998 kMsaMinor2R, 999 kMsaMinor2RF, 1000 kMsaMinorMI10 1001}; 1002 1003// ----- Emulated conditions. 1004// On MIPS we use this enum to abstract from conditional branch instructions. 1005// The 'U' prefix is used to specify unsigned comparisons. 1006// Opposite conditions must be paired as odd/even numbers 1007// because 'NegateCondition' function flips LSB to negate condition. 1008enum Condition { 1009 // Any value < 0 is considered no_condition. 1010 kNoCondition = -1, 1011 overflow = 0, 1012 no_overflow = 1, 1013 Uless = 2, 1014 Ugreater_equal = 3, 1015 Uless_equal = 4, 1016 Ugreater = 5, 1017 equal = 6, 1018 not_equal = 7, // Unordered or Not Equal. 1019 negative = 8, 1020 positive = 9, 1021 parity_even = 10, 1022 parity_odd = 11, 1023 less = 12, 1024 greater_equal = 13, 1025 less_equal = 14, 1026 greater = 15, 1027 ueq = 16, // Unordered or Equal. 1028 ogl = 17, // Ordered and Not Equal. 1029 cc_always = 18, 1030 1031 // Aliases. 1032 carry = Uless, 1033 not_carry = Ugreater_equal, 1034 zero = equal, 1035 eq = equal, 1036 not_zero = not_equal, 1037 ne = not_equal, 1038 nz = not_equal, 1039 sign = negative, 1040 not_sign = positive, 1041 mi = negative, 1042 pl = positive, 1043 hi = Ugreater, 1044 ls = Uless_equal, 1045 ge = greater_equal, 1046 lt = less, 1047 gt = greater, 1048 le = less_equal, 1049 hs = Ugreater_equal, 1050 lo = Uless, 1051 al = cc_always, 1052 ult = Uless, 1053 uge = Ugreater_equal, 1054 ule = Uless_equal, 1055 ugt = Ugreater, 1056 cc_default = kNoCondition 1057}; 1058 1059// Returns the equivalent of !cc. 1060// Negation of the default kNoCondition (-1) results in a non-default 1061// no_condition value (-2). As long as tests for no_condition check 1062// for condition < 0, this will work as expected. 1063inline Condition NegateCondition(Condition cc) { 1064 DCHECK(cc != cc_always); 1065 return static_cast<Condition>(cc ^ 1); 1066} 1067 1068inline Condition NegateFpuCondition(Condition cc) { 1069 DCHECK(cc != cc_always); 1070 switch (cc) { 1071 case ult: 1072 return ge; 1073 case ugt: 1074 return le; 1075 case uge: 1076 return lt; 1077 case ule: 1078 return gt; 1079 case lt: 1080 return uge; 1081 case gt: 1082 return ule; 1083 case ge: 1084 return ult; 1085 case le: 1086 return ugt; 1087 case eq: 1088 return ne; 1089 case ne: 1090 return eq; 1091 case ueq: 1092 return ogl; 1093 case ogl: 1094 return ueq; 1095 default: 1096 return cc; 1097 } 1098} 1099 1100enum MSABranchCondition { 1101 all_not_zero = 0, // Branch If All Elements Are Not Zero 1102 one_elem_not_zero, // Branch If At Least One Element of Any Format Is Not 1103 // Zero 1104 one_elem_zero, // Branch If At Least One Element Is Zero 1105 all_zero // Branch If All Elements of Any Format Are Zero 1106}; 1107 1108inline MSABranchCondition NegateMSABranchCondition(MSABranchCondition cond) { 1109 switch (cond) { 1110 case all_not_zero: 1111 return one_elem_zero; 1112 case one_elem_not_zero: 1113 return all_zero; 1114 case one_elem_zero: 1115 return all_not_zero; 1116 case all_zero: 1117 return one_elem_not_zero; 1118 default: 1119 return cond; 1120 } 1121} 1122 1123enum MSABranchDF { 1124 MSA_BRANCH_B = 0, 1125 MSA_BRANCH_H, 1126 MSA_BRANCH_W, 1127 MSA_BRANCH_D, 1128 MSA_BRANCH_V 1129}; 1130 1131// ----- Coprocessor conditions. 1132enum FPUCondition { 1133 kNoFPUCondition = -1, 1134 1135 F = 0x00, // False. 1136 UN = 0x01, // Unordered. 1137 EQ = 0x02, // Equal. 1138 UEQ = 0x03, // Unordered or Equal. 1139 OLT = 0x04, // Ordered or Less Than, on Mips release < 6. 1140 LT = 0x04, // Ordered or Less Than, on Mips release >= 6. 1141 ULT = 0x05, // Unordered or Less Than. 1142 OLE = 0x06, // Ordered or Less Than or Equal, on Mips release < 6. 1143 LE = 0x06, // Ordered or Less Than or Equal, on Mips release >= 6. 1144 ULE = 0x07, // Unordered or Less Than or Equal. 1145 1146 // Following constants are available on Mips release >= 6 only. 1147 ORD = 0x11, // Ordered, on Mips release >= 6. 1148 UNE = 0x12, // Not equal, on Mips release >= 6. 1149 NE = 0x13, // Ordered Greater Than or Less Than. on Mips >= 6 only. 1150}; 1151 1152// FPU rounding modes. 1153enum FPURoundingMode { 1154 RN = 0 << 0, // Round to Nearest. 1155 RZ = 1 << 0, // Round towards zero. 1156 RP = 2 << 0, // Round towards Plus Infinity. 1157 RM = 3 << 0, // Round towards Minus Infinity. 1158 1159 // Aliases. 1160 kRoundToNearest = RN, 1161 kRoundToZero = RZ, 1162 kRoundToPlusInf = RP, 1163 kRoundToMinusInf = RM, 1164 1165 mode_round = RN, 1166 mode_ceil = RP, 1167 mode_floor = RM, 1168 mode_trunc = RZ 1169}; 1170 1171const uint32_t kFPURoundingModeMask = 3 << 0; 1172 1173enum CheckForInexactConversion { 1174 kCheckForInexactConversion, 1175 kDontCheckForInexactConversion 1176}; 1177 1178enum class MaxMinKind : int { kMin = 0, kMax = 1 }; 1179 1180// ----------------------------------------------------------------------------- 1181// Hints. 1182 1183// Branch hints are not used on the MIPS. They are defined so that they can 1184// appear in shared function signatures, but will be ignored in MIPS 1185// implementations. 1186enum Hint { no_hint = 0 }; 1187 1188inline Hint NegateHint(Hint hint) { return no_hint; } 1189 1190// ----------------------------------------------------------------------------- 1191// Specific instructions, constants, and masks. 1192// These constants are declared in assembler-mips.cc, as they use named 1193// registers and other constants. 1194 1195// addiu(sp, sp, 4) aka Pop() operation or part of Pop(r) 1196// operations as post-increment of sp. 1197extern const Instr kPopInstruction; 1198// addiu(sp, sp, -4) part of Push(r) operation as pre-decrement of sp. 1199extern const Instr kPushInstruction; 1200// sw(r, MemOperand(sp, 0)) 1201extern const Instr kPushRegPattern; 1202// lw(r, MemOperand(sp, 0)) 1203extern const Instr kPopRegPattern; 1204extern const Instr kLwRegFpOffsetPattern; 1205extern const Instr kSwRegFpOffsetPattern; 1206extern const Instr kLwRegFpNegOffsetPattern; 1207extern const Instr kSwRegFpNegOffsetPattern; 1208// A mask for the Rt register for push, pop, lw, sw instructions. 1209extern const Instr kRtMask; 1210extern const Instr kLwSwInstrTypeMask; 1211extern const Instr kLwSwInstrArgumentMask; 1212extern const Instr kLwSwOffsetMask; 1213 1214// Break 0xfffff, reserved for redirected real time call. 1215const Instr rtCallRedirInstr = SPECIAL | BREAK | call_rt_redirected << 6; 1216// A nop instruction. (Encoding of sll 0 0 0). 1217const Instr nopInstr = 0; 1218 1219static constexpr uint64_t OpcodeToBitNumber(Opcode opcode) { 1220 return 1ULL << (static_cast<uint32_t>(opcode) >> kOpcodeShift); 1221} 1222 1223constexpr uint8_t kInstrSize = 4; 1224constexpr uint8_t kInstrSizeLog2 = 2; 1225 1226class InstructionBase { 1227 public: 1228 enum { 1229 // On MIPS PC cannot actually be directly accessed. We behave as if PC was 1230 // always the value of the current instruction being executed. 1231 kPCReadOffset = 0 1232 }; 1233 1234 // Instruction type. 1235 enum Type { kRegisterType, kImmediateType, kJumpType, kUnsupported = -1 }; 1236 1237 // Get the raw instruction bits. 1238 inline Instr InstructionBits() const { 1239 return *reinterpret_cast<const Instr*>(this); 1240 } 1241 1242 // Set the raw instruction bits to value. 1243 inline void SetInstructionBits(Instr value) { 1244 *reinterpret_cast<Instr*>(this) = value; 1245 } 1246 1247 // Read one particular bit out of the instruction bits. 1248 inline int Bit(int nr) const { return (InstructionBits() >> nr) & 1; } 1249 1250 // Read a bit field out of the instruction bits. 1251 inline int Bits(int hi, int lo) const { 1252 return (InstructionBits() >> lo) & ((2U << (hi - lo)) - 1); 1253 } 1254 1255 static constexpr uint64_t kOpcodeImmediateTypeMask = 1256 OpcodeToBitNumber(REGIMM) | OpcodeToBitNumber(BEQ) | 1257 OpcodeToBitNumber(BNE) | OpcodeToBitNumber(BLEZ) | 1258 OpcodeToBitNumber(BGTZ) | OpcodeToBitNumber(ADDI) | 1259 OpcodeToBitNumber(DADDI) | OpcodeToBitNumber(ADDIU) | 1260 OpcodeToBitNumber(SLTI) | OpcodeToBitNumber(SLTIU) | 1261 OpcodeToBitNumber(ANDI) | OpcodeToBitNumber(ORI) | 1262 OpcodeToBitNumber(XORI) | OpcodeToBitNumber(LUI) | 1263 OpcodeToBitNumber(BEQL) | OpcodeToBitNumber(BNEL) | 1264 OpcodeToBitNumber(BLEZL) | OpcodeToBitNumber(BGTZL) | 1265 OpcodeToBitNumber(POP66) | OpcodeToBitNumber(POP76) | 1266 OpcodeToBitNumber(LB) | OpcodeToBitNumber(LH) | OpcodeToBitNumber(LWL) | 1267 OpcodeToBitNumber(LW) | OpcodeToBitNumber(LBU) | OpcodeToBitNumber(LHU) | 1268 OpcodeToBitNumber(LWR) | OpcodeToBitNumber(SB) | OpcodeToBitNumber(SH) | 1269 OpcodeToBitNumber(SWL) | OpcodeToBitNumber(SW) | OpcodeToBitNumber(SWR) | 1270 OpcodeToBitNumber(LWC1) | OpcodeToBitNumber(LDC1) | 1271 OpcodeToBitNumber(SWC1) | OpcodeToBitNumber(SDC1) | 1272 OpcodeToBitNumber(PCREL) | OpcodeToBitNumber(BC) | 1273 OpcodeToBitNumber(BALC); 1274 1275#define FunctionFieldToBitNumber(function) (1ULL << function) 1276 1277 static const uint64_t kFunctionFieldRegisterTypeMask = 1278 FunctionFieldToBitNumber(JR) | FunctionFieldToBitNumber(JALR) | 1279 FunctionFieldToBitNumber(BREAK) | FunctionFieldToBitNumber(SLL) | 1280 FunctionFieldToBitNumber(SRL) | FunctionFieldToBitNumber(SRA) | 1281 FunctionFieldToBitNumber(SLLV) | FunctionFieldToBitNumber(SRLV) | 1282 FunctionFieldToBitNumber(SRAV) | FunctionFieldToBitNumber(LSA) | 1283 FunctionFieldToBitNumber(MFHI) | FunctionFieldToBitNumber(MFLO) | 1284 FunctionFieldToBitNumber(MULT) | FunctionFieldToBitNumber(MULTU) | 1285 FunctionFieldToBitNumber(DIV) | FunctionFieldToBitNumber(DIVU) | 1286 FunctionFieldToBitNumber(ADD) | FunctionFieldToBitNumber(ADDU) | 1287 FunctionFieldToBitNumber(SUB) | FunctionFieldToBitNumber(SUBU) | 1288 FunctionFieldToBitNumber(AND) | FunctionFieldToBitNumber(OR) | 1289 FunctionFieldToBitNumber(XOR) | FunctionFieldToBitNumber(NOR) | 1290 FunctionFieldToBitNumber(SLT) | FunctionFieldToBitNumber(SLTU) | 1291 FunctionFieldToBitNumber(TGE) | FunctionFieldToBitNumber(TGEU) | 1292 FunctionFieldToBitNumber(TLT) | FunctionFieldToBitNumber(TLTU) | 1293 FunctionFieldToBitNumber(TEQ) | FunctionFieldToBitNumber(TNE) | 1294 FunctionFieldToBitNumber(MOVZ) | FunctionFieldToBitNumber(MOVN) | 1295 FunctionFieldToBitNumber(MOVCI) | FunctionFieldToBitNumber(SELEQZ_S) | 1296 FunctionFieldToBitNumber(SELNEZ_S) | FunctionFieldToBitNumber(SYNC); 1297 1298 // Accessors for the different named fields used in the MIPS encoding. 1299 inline Opcode OpcodeValue() const { 1300 return static_cast<Opcode>( 1301 Bits(kOpcodeShift + kOpcodeBits - 1, kOpcodeShift)); 1302 } 1303 1304 inline int FunctionFieldRaw() const { 1305 return InstructionBits() & kFunctionFieldMask; 1306 } 1307 1308 // Return the fields at their original place in the instruction encoding. 1309 inline Opcode OpcodeFieldRaw() const { 1310 return static_cast<Opcode>(InstructionBits() & kOpcodeMask); 1311 } 1312 1313 // Safe to call within InstructionType(). 1314 inline int RsFieldRawNoAssert() const { 1315 return InstructionBits() & kRsFieldMask; 1316 } 1317 1318 inline int SaFieldRaw() const { return InstructionBits() & kSaFieldMask; } 1319 1320 // Get the encoding type of the instruction. 1321 inline Type InstructionType() const; 1322 1323 inline MSAMinorOpcode MSAMinorOpcodeField() const { 1324 int op = this->FunctionFieldRaw(); 1325 switch (op) { 1326 case 0: 1327 case 1: 1328 case 2: 1329 return kMsaMinorI8; 1330 case 6: 1331 return kMsaMinorI5; 1332 case 7: 1333 return (((this->InstructionBits() & kMsaI5I10Mask) == LDI) 1334 ? kMsaMinorI10 1335 : kMsaMinorI5); 1336 case 9: 1337 case 10: 1338 return kMsaMinorBIT; 1339 case 13: 1340 case 14: 1341 case 15: 1342 case 16: 1343 case 17: 1344 case 18: 1345 case 19: 1346 case 20: 1347 case 21: 1348 return kMsaMinor3R; 1349 case 25: 1350 return kMsaMinorELM; 1351 case 26: 1352 case 27: 1353 case 28: 1354 return kMsaMinor3RF; 1355 case 30: 1356 switch (this->RsFieldRawNoAssert()) { 1357 case MSA_2R_FORMAT: 1358 return kMsaMinor2R; 1359 case MSA_2RF_FORMAT: 1360 return kMsaMinor2RF; 1361 default: 1362 return kMsaMinorVEC; 1363 } 1364 break; 1365 case 32: 1366 case 33: 1367 case 34: 1368 case 35: 1369 case 36: 1370 case 37: 1371 case 38: 1372 case 39: 1373 return kMsaMinorMI10; 1374 default: 1375 return kMsaMinorUndefined; 1376 } 1377 } 1378 1379 protected: 1380 InstructionBase() {} 1381}; 1382 1383template <class T> 1384class InstructionGetters : public T { 1385 public: 1386 inline int RsValue() const { 1387 DCHECK(this->InstructionType() == InstructionBase::kRegisterType || 1388 this->InstructionType() == InstructionBase::kImmediateType); 1389 return InstructionBase::Bits(kRsShift + kRsBits - 1, kRsShift); 1390 } 1391 1392 inline int RtValue() const { 1393 DCHECK(this->InstructionType() == InstructionBase::kRegisterType || 1394 this->InstructionType() == InstructionBase::kImmediateType); 1395 return this->Bits(kRtShift + kRtBits - 1, kRtShift); 1396 } 1397 1398 inline int RdValue() const { 1399 DCHECK_EQ(this->InstructionType(), InstructionBase::kRegisterType); 1400 return this->Bits(kRdShift + kRdBits - 1, kRdShift); 1401 } 1402 1403 inline int BaseValue() const { 1404 DCHECK_EQ(this->InstructionType(), InstructionBase::kImmediateType); 1405 return this->Bits(kBaseShift + kBaseBits - 1, kBaseShift); 1406 } 1407 1408 inline int SaValue() const { 1409 DCHECK_EQ(this->InstructionType(), InstructionBase::kRegisterType); 1410 return this->Bits(kSaShift + kSaBits - 1, kSaShift); 1411 } 1412 1413 inline int LsaSaValue() const { 1414 DCHECK_EQ(this->InstructionType(), InstructionBase::kRegisterType); 1415 return this->Bits(kSaShift + kLsaSaBits - 1, kSaShift); 1416 } 1417 1418 inline int FunctionValue() const { 1419 DCHECK(this->InstructionType() == InstructionBase::kRegisterType || 1420 this->InstructionType() == InstructionBase::kImmediateType); 1421 return this->Bits(kFunctionShift + kFunctionBits - 1, kFunctionShift); 1422 } 1423 1424 inline int FdValue() const { 1425 return this->Bits(kFdShift + kFdBits - 1, kFdShift); 1426 } 1427 1428 inline int FsValue() const { 1429 return this->Bits(kFsShift + kFsBits - 1, kFsShift); 1430 } 1431 1432 inline int FtValue() const { 1433 return this->Bits(kFtShift + kFtBits - 1, kFtShift); 1434 } 1435 1436 inline int FrValue() const { 1437 return this->Bits(kFrShift + kFrBits - 1, kFrShift); 1438 } 1439 1440 inline int WdValue() const { 1441 return this->Bits(kWdShift + kWdBits - 1, kWdShift); 1442 } 1443 1444 inline int WsValue() const { 1445 return this->Bits(kWsShift + kWsBits - 1, kWsShift); 1446 } 1447 1448 inline int WtValue() const { 1449 return this->Bits(kWtShift + kWtBits - 1, kWtShift); 1450 } 1451 1452 inline int Bp2Value() const { 1453 DCHECK_EQ(this->InstructionType(), InstructionBase::kRegisterType); 1454 return this->Bits(kBp2Shift + kBp2Bits - 1, kBp2Shift); 1455 } 1456 1457 // Float Compare condition code instruction bits. 1458 inline int FCccValue() const { 1459 return this->Bits(kFCccShift + kFCccBits - 1, kFCccShift); 1460 } 1461 1462 // Float Branch condition code instruction bits. 1463 inline int FBccValue() const { 1464 return this->Bits(kFBccShift + kFBccBits - 1, kFBccShift); 1465 } 1466 1467 // Float Branch true/false instruction bit. 1468 inline int FBtrueValue() const { 1469 return this->Bits(kFBtrueShift + kFBtrueBits - 1, kFBtrueShift); 1470 } 1471 1472 // Return the fields at their original place in the instruction encoding. 1473 inline Opcode OpcodeFieldRaw() const { 1474 return static_cast<Opcode>(this->InstructionBits() & kOpcodeMask); 1475 } 1476 1477 inline int RsFieldRaw() const { 1478 DCHECK(this->InstructionType() == InstructionBase::kRegisterType || 1479 this->InstructionType() == InstructionBase::kImmediateType); 1480 return this->InstructionBits() & kRsFieldMask; 1481 } 1482 1483 inline int RtFieldRaw() const { 1484 DCHECK(this->InstructionType() == InstructionBase::kRegisterType || 1485 this->InstructionType() == InstructionBase::kImmediateType); 1486 return this->InstructionBits() & kRtFieldMask; 1487 } 1488 1489 inline int RdFieldRaw() const { 1490 DCHECK_EQ(this->InstructionType(), InstructionBase::kRegisterType); 1491 return this->InstructionBits() & kRdFieldMask; 1492 } 1493 1494 inline int SaFieldRaw() const { 1495 return this->InstructionBits() & kSaFieldMask; 1496 } 1497 1498 inline int FunctionFieldRaw() const { 1499 return this->InstructionBits() & kFunctionFieldMask; 1500 } 1501 1502 // Get the secondary field according to the opcode. 1503 inline int SecondaryValue() const { 1504 Opcode op = this->OpcodeFieldRaw(); 1505 switch (op) { 1506 case SPECIAL: 1507 case SPECIAL2: 1508 return FunctionValue(); 1509 case COP1: 1510 return RsValue(); 1511 case REGIMM: 1512 return RtValue(); 1513 default: 1514 return nullptrSF; 1515 } 1516 } 1517 1518 inline int32_t ImmValue(int bits) const { 1519 DCHECK_EQ(this->InstructionType(), InstructionBase::kImmediateType); 1520 return this->Bits(bits - 1, 0); 1521 } 1522 1523 inline int32_t Imm9Value() const { 1524 DCHECK_EQ(this->InstructionType(), InstructionBase::kImmediateType); 1525 return this->Bits(kImm9Shift + kImm9Bits - 1, kImm9Shift); 1526 } 1527 1528 inline int32_t Imm16Value() const { 1529 DCHECK_EQ(this->InstructionType(), InstructionBase::kImmediateType); 1530 return this->Bits(kImm16Shift + kImm16Bits - 1, kImm16Shift); 1531 } 1532 1533 inline int32_t Imm18Value() const { 1534 DCHECK_EQ(this->InstructionType(), InstructionBase::kImmediateType); 1535 return this->Bits(kImm18Shift + kImm18Bits - 1, kImm18Shift); 1536 } 1537 1538 inline int32_t Imm19Value() const { 1539 DCHECK_EQ(this->InstructionType(), InstructionBase::kImmediateType); 1540 return this->Bits(kImm19Shift + kImm19Bits - 1, kImm19Shift); 1541 } 1542 1543 inline int32_t Imm21Value() const { 1544 DCHECK_EQ(this->InstructionType(), InstructionBase::kImmediateType); 1545 return this->Bits(kImm21Shift + kImm21Bits - 1, kImm21Shift); 1546 } 1547 1548 inline int32_t Imm26Value() const { 1549 DCHECK((this->InstructionType() == InstructionBase::kJumpType) || 1550 (this->InstructionType() == InstructionBase::kImmediateType)); 1551 return this->Bits(kImm26Shift + kImm26Bits - 1, kImm26Shift); 1552 } 1553 1554 inline int32_t MsaImm8Value() const { 1555 DCHECK_EQ(this->InstructionType(), InstructionBase::kImmediateType); 1556 return this->Bits(kMsaImm8Shift + kMsaImm8Bits - 1, kMsaImm8Shift); 1557 } 1558 1559 inline int32_t MsaImm5Value() const { 1560 DCHECK_EQ(this->InstructionType(), InstructionBase::kImmediateType); 1561 return this->Bits(kMsaImm5Shift + kMsaImm5Bits - 1, kMsaImm5Shift); 1562 } 1563 1564 inline int32_t MsaImm10Value() const { 1565 DCHECK_EQ(this->InstructionType(), InstructionBase::kImmediateType); 1566 return this->Bits(kMsaImm10Shift + kMsaImm10Bits - 1, kMsaImm10Shift); 1567 } 1568 1569 inline int32_t MsaImmMI10Value() const { 1570 DCHECK_EQ(this->InstructionType(), InstructionBase::kImmediateType); 1571 return this->Bits(kMsaImmMI10Shift + kMsaImmMI10Bits - 1, kMsaImmMI10Shift); 1572 } 1573 1574 inline int32_t MsaBitDf() const { 1575 DCHECK_EQ(this->InstructionType(), InstructionBase::kImmediateType); 1576 int32_t df_m = this->Bits(22, 16); 1577 if (((df_m >> 6) & 1U) == 0) { 1578 return 3; 1579 } else if (((df_m >> 5) & 3U) == 2) { 1580 return 2; 1581 } else if (((df_m >> 4) & 7U) == 6) { 1582 return 1; 1583 } else if (((df_m >> 3) & 15U) == 14) { 1584 return 0; 1585 } else { 1586 return -1; 1587 } 1588 } 1589 1590 inline int32_t MsaBitMValue() const { 1591 DCHECK_EQ(this->InstructionType(), InstructionBase::kImmediateType); 1592 return this->Bits(16 + this->MsaBitDf() + 3, 16); 1593 } 1594 1595 inline int32_t MsaElmDf() const { 1596 DCHECK(this->InstructionType() == InstructionBase::kRegisterType || 1597 this->InstructionType() == InstructionBase::kImmediateType); 1598 int32_t df_n = this->Bits(21, 16); 1599 if (((df_n >> 4) & 3U) == 0) { 1600 return 0; 1601 } else if (((df_n >> 3) & 7U) == 4) { 1602 return 1; 1603 } else if (((df_n >> 2) & 15U) == 12) { 1604 return 2; 1605 } else if (((df_n >> 1) & 31U) == 28) { 1606 return 3; 1607 } else { 1608 return -1; 1609 } 1610 } 1611 1612 inline int32_t MsaElmNValue() const { 1613 DCHECK(this->InstructionType() == InstructionBase::kRegisterType || 1614 this->InstructionType() == InstructionBase::kImmediateType); 1615 return this->Bits(16 + 4 - this->MsaElmDf(), 16); 1616 } 1617 1618 static bool IsForbiddenAfterBranchInstr(Instr instr); 1619 1620 // Say if the instruction should not be used in a branch delay slot or 1621 // immediately after a compact branch. 1622 inline bool IsForbiddenAfterBranch() const { 1623 return IsForbiddenAfterBranchInstr(this->InstructionBits()); 1624 } 1625 1626 inline bool IsForbiddenInBranchDelay() const { 1627 return IsForbiddenAfterBranch(); 1628 } 1629 1630 // Say if the instruction 'links'. e.g. jal, bal. 1631 bool IsLinkingInstruction() const; 1632 // Say if the instruction is a break or a trap. 1633 bool IsTrap() const; 1634 1635 inline bool IsMSABranchInstr() const { 1636 if (this->OpcodeFieldRaw() == COP1) { 1637 switch (this->RsFieldRaw()) { 1638 case BZ_V: 1639 case BZ_B: 1640 case BZ_H: 1641 case BZ_W: 1642 case BZ_D: 1643 case BNZ_V: 1644 case BNZ_B: 1645 case BNZ_H: 1646 case BNZ_W: 1647 case BNZ_D: 1648 return true; 1649 default: 1650 return false; 1651 } 1652 } 1653 return false; 1654 } 1655 1656 inline bool IsMSAInstr() const { 1657 if (this->IsMSABranchInstr() || (this->OpcodeFieldRaw() == MSA)) 1658 return true; 1659 return false; 1660 } 1661}; 1662 1663class Instruction : public InstructionGetters<InstructionBase> { 1664 public: 1665 // Instructions are read of out a code stream. The only way to get a 1666 // reference to an instruction is to convert a pointer. There is no way 1667 // to allocate or create instances of class Instruction. 1668 // Use the At(pc) function to create references to Instruction. 1669 static Instruction* At(byte* pc) { 1670 return reinterpret_cast<Instruction*>(pc); 1671 } 1672 1673 private: 1674 // We need to prevent the creation of instances of class Instruction. 1675 DISALLOW_IMPLICIT_CONSTRUCTORS(Instruction); 1676}; 1677 1678// ----------------------------------------------------------------------------- 1679// MIPS assembly various constants. 1680 1681// C/C++ argument slots size. 1682const int kCArgSlotCount = 4; 1683const int kCArgsSlotsSize = kCArgSlotCount * kInstrSize; 1684 1685// JS argument slots size. 1686const int kJSArgsSlotsSize = 0 * kInstrSize; 1687 1688// Assembly builtins argument slots size. 1689const int kBArgsSlotsSize = 0 * kInstrSize; 1690 1691const int kBranchReturnOffset = 2 * kInstrSize; 1692 1693InstructionBase::Type InstructionBase::InstructionType() const { 1694 switch (OpcodeFieldRaw()) { 1695 case SPECIAL: 1696 if (FunctionFieldToBitNumber(FunctionFieldRaw()) & 1697 kFunctionFieldRegisterTypeMask) { 1698 return kRegisterType; 1699 } 1700 return kUnsupported; 1701 case SPECIAL2: 1702 switch (FunctionFieldRaw()) { 1703 case MUL: 1704 case CLZ: 1705 return kRegisterType; 1706 default: 1707 return kUnsupported; 1708 } 1709 break; 1710 case SPECIAL3: 1711 switch (FunctionFieldRaw()) { 1712 case INS: 1713 case EXT: 1714 return kRegisterType; 1715 case BSHFL: { 1716 int sa = SaFieldRaw() >> kSaShift; 1717 switch (sa) { 1718 case BITSWAP: 1719 case WSBH: 1720 case SEB: 1721 case SEH: 1722 return kRegisterType; 1723 } 1724 sa >>= kBp2Bits; 1725 switch (sa) { 1726 case ALIGN: 1727 return kRegisterType; 1728 default: 1729 return kUnsupported; 1730 } 1731 } 1732 case LL_R6: 1733 case SC_R6: { 1734 DCHECK(IsMipsArchVariant(kMips32r6)); 1735 return kImmediateType; 1736 } 1737 default: 1738 return kUnsupported; 1739 } 1740 break; 1741 case COP1: // Coprocessor instructions. 1742 switch (RsFieldRawNoAssert()) { 1743 case BC1: // Branch on coprocessor condition. 1744 case BC1EQZ: 1745 case BC1NEZ: 1746 return kImmediateType; 1747 // MSA Branch instructions 1748 case BZ_V: 1749 case BNZ_V: 1750 case BZ_B: 1751 case BZ_H: 1752 case BZ_W: 1753 case BZ_D: 1754 case BNZ_B: 1755 case BNZ_H: 1756 case BNZ_W: 1757 case BNZ_D: 1758 return kImmediateType; 1759 default: 1760 return kRegisterType; 1761 } 1762 break; 1763 case COP1X: 1764 return kRegisterType; 1765 1766 // 26 bits immediate type instructions. e.g.: j imm26. 1767 case J: 1768 case JAL: 1769 return kJumpType; 1770 1771 case MSA: 1772 switch (MSAMinorOpcodeField()) { 1773 case kMsaMinor3R: 1774 case kMsaMinor3RF: 1775 case kMsaMinorVEC: 1776 case kMsaMinor2R: 1777 case kMsaMinor2RF: 1778 return kRegisterType; 1779 case kMsaMinorELM: 1780 switch (InstructionBits() & kMsaLongerELMMask) { 1781 case CFCMSA: 1782 case CTCMSA: 1783 case MOVE_V: 1784 return kRegisterType; 1785 default: 1786 return kImmediateType; 1787 } 1788 default: 1789 return kImmediateType; 1790 } 1791 1792 default: 1793 return kImmediateType; 1794 } 1795} 1796 1797#undef OpcodeToBitNumber 1798#undef FunctionFieldToBitNumber 1799 1800// ----------------------------------------------------------------------------- 1801// Instructions. 1802 1803template <class P> 1804bool InstructionGetters<P>::IsLinkingInstruction() const { 1805 uint32_t op = this->OpcodeFieldRaw(); 1806 switch (op) { 1807 case JAL: 1808 return true; 1809 case POP76: 1810 if (this->RsFieldRawNoAssert() == JIALC) 1811 return true; // JIALC 1812 else 1813 return false; // BNEZC 1814 case REGIMM: 1815 switch (this->RtFieldRaw()) { 1816 case BGEZAL: 1817 case BLTZAL: 1818 return true; 1819 default: 1820 return false; 1821 } 1822 case SPECIAL: 1823 switch (this->FunctionFieldRaw()) { 1824 case JALR: 1825 return true; 1826 default: 1827 return false; 1828 } 1829 default: 1830 return false; 1831 } 1832} 1833 1834template <class P> 1835bool InstructionGetters<P>::IsTrap() const { 1836 if (this->OpcodeFieldRaw() != SPECIAL) { 1837 return false; 1838 } else { 1839 switch (this->FunctionFieldRaw()) { 1840 case BREAK: 1841 case TGE: 1842 case TGEU: 1843 case TLT: 1844 case TLTU: 1845 case TEQ: 1846 case TNE: 1847 return true; 1848 default: 1849 return false; 1850 } 1851 } 1852} 1853 1854// static 1855template <class T> 1856bool InstructionGetters<T>::IsForbiddenAfterBranchInstr(Instr instr) { 1857 Opcode opcode = static_cast<Opcode>(instr & kOpcodeMask); 1858 switch (opcode) { 1859 case J: 1860 case JAL: 1861 case BEQ: 1862 case BNE: 1863 case BLEZ: // POP06 bgeuc/bleuc, blezalc, bgezalc 1864 case BGTZ: // POP07 bltuc/bgtuc, bgtzalc, bltzalc 1865 case BEQL: 1866 case BNEL: 1867 case BLEZL: // POP26 bgezc, blezc, bgec/blec 1868 case BGTZL: // POP27 bgtzc, bltzc, bltc/bgtc 1869 case BC: 1870 case BALC: 1871 case POP10: // beqzalc, bovc, beqc 1872 case POP30: // bnezalc, bnvc, bnec 1873 case POP66: // beqzc, jic 1874 case POP76: // bnezc, jialc 1875 return true; 1876 case REGIMM: 1877 switch (instr & kRtFieldMask) { 1878 case BLTZ: 1879 case BGEZ: 1880 case BLTZAL: 1881 case BGEZAL: 1882 return true; 1883 default: 1884 return false; 1885 } 1886 break; 1887 case SPECIAL: 1888 switch (instr & kFunctionFieldMask) { 1889 case JR: 1890 case JALR: 1891 return true; 1892 default: 1893 return false; 1894 } 1895 break; 1896 case COP1: 1897 switch (instr & kRsFieldMask) { 1898 case BC1: 1899 case BC1EQZ: 1900 case BC1NEZ: 1901 case BZ_V: 1902 case BZ_B: 1903 case BZ_H: 1904 case BZ_W: 1905 case BZ_D: 1906 case BNZ_V: 1907 case BNZ_B: 1908 case BNZ_H: 1909 case BNZ_W: 1910 case BNZ_D: 1911 return true; 1912 break; 1913 default: 1914 return false; 1915 } 1916 break; 1917 default: 1918 return false; 1919 } 1920} 1921} // namespace internal 1922} // namespace v8 1923 1924#endif // V8_CODEGEN_MIPS_CONSTANTS_MIPS_H_ 1925