constants-mips.h revision 18a7ebb96c51b556b3e71ebdefae0b5c7639102f
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#include "src/globals.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 27 static const ArchVariants kArchVariant = kMips32r2; 28#elif _MIPS_ARCH_MIPS32R6 29 static 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. 33 static 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. 38 static const ArchVariants kArchVariant = kMips32r1; 39#else 40 static const ArchVariants kArchVariant = kMips32r1; 41#endif 42 43enum Endianness { 44 kLittle, 45 kBig 46}; 47 48#if defined(V8_TARGET_LITTLE_ENDIAN) 49 static const Endianness kArchEndian = kLittle; 50#elif defined(V8_TARGET_BIG_ENDIAN) 51 static const Endianness kArchEndian = kBig; 52#else 53#error Unknown endianness 54#endif 55 56enum FpuMode { 57 kFP32, 58 kFP64, 59 kFPXX 60}; 61 62#if defined(FPU_MODE_FP32) 63 static const FpuMode kFpuMode = kFP32; 64#elif defined(FPU_MODE_FP64) 65 static const FpuMode kFpuMode = kFP64; 66#elif defined(FPU_MODE_FPXX) 67 static const FpuMode kFpuMode = kFPXX; 68#else 69 static const FpuMode kFpuMode = kFP32; 70#endif 71 72#if(defined(__mips_hard_float) && __mips_hard_float != 0) 73// Use floating-point coprocessor instructions. This flag is raised when 74// -mhard-float is passed to the compiler. 75const bool IsMipsSoftFloatABI = false; 76#elif(defined(__mips_soft_float) && __mips_soft_float != 0) 77// This flag is raised when -msoft-float is passed to the compiler. 78// Although FPU is a base requirement for v8, soft-float ABI is used 79// on soft-float systems with FPU kernel emulation. 80const bool IsMipsSoftFloatABI = true; 81#else 82const bool IsMipsSoftFloatABI = true; 83#endif 84 85#if defined(V8_TARGET_LITTLE_ENDIAN) 86const uint32_t kHoleNanUpper32Offset = 4; 87const uint32_t kHoleNanLower32Offset = 0; 88#elif defined(V8_TARGET_BIG_ENDIAN) 89const uint32_t kHoleNanUpper32Offset = 0; 90const uint32_t kHoleNanLower32Offset = 4; 91#else 92#error Unknown endianness 93#endif 94 95#ifndef FPU_MODE_FPXX 96#define IsFp64Mode() \ 97 (kFpuMode == kFP64) 98#else 99#define IsFp64Mode() \ 100 (CpuFeatures::IsSupported(FP64FPU)) 101#endif 102 103#ifndef _MIPS_ARCH_MIPS32RX 104#define IsMipsArchVariant(check) \ 105 (kArchVariant == check) 106#else 107#define IsMipsArchVariant(check) \ 108 (CpuFeatures::IsSupported(static_cast<CpuFeature>(check))) 109#endif 110 111 112#define __STDC_FORMAT_MACROS 113#include <inttypes.h> 114 115// Defines constants and accessor classes to assemble, disassemble and 116// simulate MIPS32 instructions. 117// 118// See: MIPS32 Architecture For Programmers 119// Volume II: The MIPS32 Instruction Set 120// Try www.cs.cornell.edu/courses/cs3410/2008fa/MIPS_Vol2.pdf. 121 122namespace v8 { 123namespace internal { 124 125// ----------------------------------------------------------------------------- 126// Registers and FPURegisters. 127 128// Number of general purpose registers. 129const int kNumRegisters = 32; 130const int kInvalidRegister = -1; 131 132// Number of registers with HI, LO, and pc. 133const int kNumSimuRegisters = 35; 134 135// In the simulator, the PC register is simulated as the 34th register. 136const int kPCRegister = 34; 137 138// Number coprocessor registers. 139const int kNumFPURegisters = 32; 140const int kInvalidFPURegister = -1; 141 142// FPU (coprocessor 1) control registers. Currently only FCSR is implemented. 143const int kFCSRRegister = 31; 144const int kInvalidFPUControlRegister = -1; 145const uint32_t kFPUInvalidResult = static_cast<uint32_t>(1 << 31) - 1; 146const uint64_t kFPU64InvalidResult = 147 static_cast<uint64_t>(static_cast<uint64_t>(1) << 63) - 1; 148 149// FCSR constants. 150const uint32_t kFCSRInexactFlagBit = 2; 151const uint32_t kFCSRUnderflowFlagBit = 3; 152const uint32_t kFCSROverflowFlagBit = 4; 153const uint32_t kFCSRDivideByZeroFlagBit = 5; 154const uint32_t kFCSRInvalidOpFlagBit = 6; 155 156const uint32_t kFCSRInexactFlagMask = 1 << kFCSRInexactFlagBit; 157const uint32_t kFCSRUnderflowFlagMask = 1 << kFCSRUnderflowFlagBit; 158const uint32_t kFCSROverflowFlagMask = 1 << kFCSROverflowFlagBit; 159const uint32_t kFCSRDivideByZeroFlagMask = 1 << kFCSRDivideByZeroFlagBit; 160const uint32_t kFCSRInvalidOpFlagMask = 1 << kFCSRInvalidOpFlagBit; 161 162const uint32_t kFCSRFlagMask = 163 kFCSRInexactFlagMask | 164 kFCSRUnderflowFlagMask | 165 kFCSROverflowFlagMask | 166 kFCSRDivideByZeroFlagMask | 167 kFCSRInvalidOpFlagMask; 168 169const uint32_t kFCSRExceptionFlagMask = kFCSRFlagMask ^ kFCSRInexactFlagMask; 170 171// 'pref' instruction hints 172const int32_t kPrefHintLoad = 0; 173const int32_t kPrefHintStore = 1; 174const int32_t kPrefHintLoadStreamed = 4; 175const int32_t kPrefHintStoreStreamed = 5; 176const int32_t kPrefHintLoadRetained = 6; 177const int32_t kPrefHintStoreRetained = 7; 178const int32_t kPrefHintWritebackInvalidate = 25; 179const int32_t kPrefHintPrepareForStore = 30; 180 181// Helper functions for converting between register numbers and names. 182class Registers { 183 public: 184 // Return the name of the register. 185 static const char* Name(int reg); 186 187 // Lookup the register number for the name provided. 188 static int Number(const char* name); 189 190 struct RegisterAlias { 191 int reg; 192 const char* name; 193 }; 194 195 static const int32_t kMaxValue = 0x7fffffff; 196 static const int32_t kMinValue = 0x80000000; 197 198 private: 199 static const char* names_[kNumSimuRegisters]; 200 static const RegisterAlias aliases_[]; 201}; 202 203// Helper functions for converting between register numbers and names. 204class FPURegisters { 205 public: 206 // Return the name of the register. 207 static const char* Name(int reg); 208 209 // Lookup the register number for the name provided. 210 static int Number(const char* name); 211 212 struct RegisterAlias { 213 int creg; 214 const char* name; 215 }; 216 217 private: 218 static const char* names_[kNumFPURegisters]; 219 static const RegisterAlias aliases_[]; 220}; 221 222 223// ----------------------------------------------------------------------------- 224// Instructions encoding constants. 225 226// On MIPS all instructions are 32 bits. 227typedef int32_t Instr; 228 229// Special Software Interrupt codes when used in the presence of the MIPS 230// simulator. 231enum SoftwareInterruptCodes { 232 // Transition to C code. 233 call_rt_redirected = 0xfffff 234}; 235 236// On MIPS Simulator breakpoints can have different codes: 237// - Breaks between 0 and kMaxWatchpointCode are treated as simple watchpoints, 238// the simulator will run through them and print the registers. 239// - Breaks between kMaxWatchpointCode and kMaxStopCode are treated as stop() 240// instructions (see Assembler::stop()). 241// - Breaks larger than kMaxStopCode are simple breaks, dropping you into the 242// debugger. 243const uint32_t kMaxWatchpointCode = 31; 244const uint32_t kMaxStopCode = 127; 245STATIC_ASSERT(kMaxWatchpointCode < kMaxStopCode); 246 247 248// ----- Fields offset and length. 249const int kOpcodeShift = 26; 250const int kOpcodeBits = 6; 251const int kRsShift = 21; 252const int kRsBits = 5; 253const int kRtShift = 16; 254const int kRtBits = 5; 255const int kRdShift = 11; 256const int kRdBits = 5; 257const int kSaShift = 6; 258const int kSaBits = 5; 259const int kFunctionShift = 0; 260const int kFunctionBits = 6; 261const int kLuiShift = 16; 262 263const int kImm16Shift = 0; 264const int kImm16Bits = 16; 265const int kImm21Shift = 0; 266const int kImm21Bits = 21; 267const int kImm26Shift = 0; 268const int kImm26Bits = 26; 269const int kImm28Shift = 0; 270const int kImm28Bits = 28; 271const int kImm32Shift = 0; 272const int kImm32Bits = 32; 273 274// In branches and jumps immediate fields point to words, not bytes, 275// and are therefore shifted by 2. 276const int kImmFieldShift = 2; 277 278const int kFrBits = 5; 279const int kFrShift = 21; 280const int kFsShift = 11; 281const int kFsBits = 5; 282const int kFtShift = 16; 283const int kFtBits = 5; 284const int kFdShift = 6; 285const int kFdBits = 5; 286const int kFCccShift = 8; 287const int kFCccBits = 3; 288const int kFBccShift = 18; 289const int kFBccBits = 3; 290const int kFBtrueShift = 16; 291const int kFBtrueBits = 1; 292 293// ----- Miscellaneous useful masks. 294// Instruction bit masks. 295const int kOpcodeMask = ((1 << kOpcodeBits) - 1) << kOpcodeShift; 296const int kImm16Mask = ((1 << kImm16Bits) - 1) << kImm16Shift; 297const int kImm26Mask = ((1 << kImm26Bits) - 1) << kImm26Shift; 298const int kImm28Mask = ((1 << kImm28Bits) - 1) << kImm28Shift; 299const int kRsFieldMask = ((1 << kRsBits) - 1) << kRsShift; 300const int kRtFieldMask = ((1 << kRtBits) - 1) << kRtShift; 301const int kRdFieldMask = ((1 << kRdBits) - 1) << kRdShift; 302const int kSaFieldMask = ((1 << kSaBits) - 1) << kSaShift; 303const int kFunctionFieldMask = ((1 << kFunctionBits) - 1) << kFunctionShift; 304// Misc masks. 305const int kHiMask = 0xffff << 16; 306const int kLoMask = 0xffff; 307const int kSignMask = 0x80000000; 308const int kJumpAddrMask = (1 << (kImm26Bits + kImmFieldShift)) - 1; 309 310// ----- MIPS Opcodes and Function Fields. 311// We use this presentation to stay close to the table representation in 312// MIPS32 Architecture For Programmers, Volume II: The MIPS32 Instruction Set. 313enum Opcode { 314 SPECIAL = 0 << kOpcodeShift, 315 REGIMM = 1 << kOpcodeShift, 316 317 J = ((0 << 3) + 2) << kOpcodeShift, 318 JAL = ((0 << 3) + 3) << kOpcodeShift, 319 BEQ = ((0 << 3) + 4) << kOpcodeShift, 320 BNE = ((0 << 3) + 5) << kOpcodeShift, 321 BLEZ = ((0 << 3) + 6) << kOpcodeShift, 322 BGTZ = ((0 << 3) + 7) << kOpcodeShift, 323 324 ADDI = ((1 << 3) + 0) << kOpcodeShift, 325 ADDIU = ((1 << 3) + 1) << kOpcodeShift, 326 SLTI = ((1 << 3) + 2) << kOpcodeShift, 327 SLTIU = ((1 << 3) + 3) << kOpcodeShift, 328 ANDI = ((1 << 3) + 4) << kOpcodeShift, 329 ORI = ((1 << 3) + 5) << kOpcodeShift, 330 XORI = ((1 << 3) + 6) << kOpcodeShift, 331 LUI = ((1 << 3) + 7) << kOpcodeShift, // LUI/AUI family. 332 333 BEQC = ((2 << 3) + 0) << kOpcodeShift, 334 COP1 = ((2 << 3) + 1) << kOpcodeShift, // Coprocessor 1 class. 335 BEQL = ((2 << 3) + 4) << kOpcodeShift, 336 BNEL = ((2 << 3) + 5) << kOpcodeShift, 337 BLEZL = ((2 << 3) + 6) << kOpcodeShift, 338 BGTZL = ((2 << 3) + 7) << kOpcodeShift, 339 340 DADDI = ((3 << 3) + 0) << kOpcodeShift, // This is also BNEC. 341 SPECIAL2 = ((3 << 3) + 4) << kOpcodeShift, 342 SPECIAL3 = ((3 << 3) + 7) << kOpcodeShift, 343 344 LB = ((4 << 3) + 0) << kOpcodeShift, 345 LH = ((4 << 3) + 1) << kOpcodeShift, 346 LWL = ((4 << 3) + 2) << kOpcodeShift, 347 LW = ((4 << 3) + 3) << kOpcodeShift, 348 LBU = ((4 << 3) + 4) << kOpcodeShift, 349 LHU = ((4 << 3) + 5) << kOpcodeShift, 350 LWR = ((4 << 3) + 6) << kOpcodeShift, 351 SB = ((5 << 3) + 0) << kOpcodeShift, 352 SH = ((5 << 3) + 1) << kOpcodeShift, 353 SWL = ((5 << 3) + 2) << kOpcodeShift, 354 SW = ((5 << 3) + 3) << kOpcodeShift, 355 SWR = ((5 << 3) + 6) << kOpcodeShift, 356 357 LWC1 = ((6 << 3) + 1) << kOpcodeShift, 358 LDC1 = ((6 << 3) + 5) << kOpcodeShift, 359 BEQZC = ((6 << 3) + 6) << kOpcodeShift, 360 361 PREF = ((6 << 3) + 3) << kOpcodeShift, 362 363 SWC1 = ((7 << 3) + 1) << kOpcodeShift, 364 SDC1 = ((7 << 3) + 5) << kOpcodeShift, 365 BNEZC = ((7 << 3) + 6) << kOpcodeShift, 366 367 COP1X = ((1 << 4) + 3) << kOpcodeShift 368}; 369 370enum SecondaryField { 371 // SPECIAL Encoding of Function Field. 372 SLL = ((0 << 3) + 0), 373 MOVCI = ((0 << 3) + 1), 374 SRL = ((0 << 3) + 2), 375 SRA = ((0 << 3) + 3), 376 SLLV = ((0 << 3) + 4), 377 SRLV = ((0 << 3) + 6), 378 SRAV = ((0 << 3) + 7), 379 380 JR = ((1 << 3) + 0), 381 JALR = ((1 << 3) + 1), 382 MOVZ = ((1 << 3) + 2), 383 MOVN = ((1 << 3) + 3), 384 BREAK = ((1 << 3) + 5), 385 386 MFHI = ((2 << 3) + 0), 387 CLZ_R6 = ((2 << 3) + 0), 388 CLO_R6 = ((2 << 3) + 1), 389 MFLO = ((2 << 3) + 2), 390 391 MULT = ((3 << 3) + 0), 392 MULTU = ((3 << 3) + 1), 393 DIV = ((3 << 3) + 2), 394 DIVU = ((3 << 3) + 3), 395 396 ADD = ((4 << 3) + 0), 397 ADDU = ((4 << 3) + 1), 398 SUB = ((4 << 3) + 2), 399 SUBU = ((4 << 3) + 3), 400 AND = ((4 << 3) + 4), 401 OR = ((4 << 3) + 5), 402 XOR = ((4 << 3) + 6), 403 NOR = ((4 << 3) + 7), 404 405 SLT = ((5 << 3) + 2), 406 SLTU = ((5 << 3) + 3), 407 408 TGE = ((6 << 3) + 0), 409 TGEU = ((6 << 3) + 1), 410 TLT = ((6 << 3) + 2), 411 TLTU = ((6 << 3) + 3), 412 TEQ = ((6 << 3) + 4), 413 SELEQZ_S = ((6 << 3) + 5), 414 TNE = ((6 << 3) + 6), 415 SELNEZ_S = ((6 << 3) + 7), 416 417 // Multiply integers in r6. 418 MUL_MUH = ((3 << 3) + 0), // MUL, MUH. 419 MUL_MUH_U = ((3 << 3) + 1), // MUL_U, MUH_U. 420 421 MUL_OP = ((0 << 3) + 2), 422 MUH_OP = ((0 << 3) + 3), 423 DIV_OP = ((0 << 3) + 2), 424 MOD_OP = ((0 << 3) + 3), 425 426 DIV_MOD = ((3 << 3) + 2), 427 DIV_MOD_U = ((3 << 3) + 3), 428 429 // SPECIAL2 Encoding of Function Field. 430 MUL = ((0 << 3) + 2), 431 CLZ = ((4 << 3) + 0), 432 CLO = ((4 << 3) + 1), 433 434 // SPECIAL3 Encoding of Function Field. 435 EXT = ((0 << 3) + 0), 436 INS = ((0 << 3) + 4), 437 438 // REGIMM encoding of rt Field. 439 BLTZ = ((0 << 3) + 0) << 16, 440 BGEZ = ((0 << 3) + 1) << 16, 441 BLTZAL = ((2 << 3) + 0) << 16, 442 BGEZAL = ((2 << 3) + 1) << 16, 443 BGEZALL = ((2 << 3) + 3) << 16, 444 445 // COP1 Encoding of rs Field. 446 MFC1 = ((0 << 3) + 0) << 21, 447 CFC1 = ((0 << 3) + 2) << 21, 448 MFHC1 = ((0 << 3) + 3) << 21, 449 MTC1 = ((0 << 3) + 4) << 21, 450 CTC1 = ((0 << 3) + 6) << 21, 451 MTHC1 = ((0 << 3) + 7) << 21, 452 BC1 = ((1 << 3) + 0) << 21, 453 S = ((2 << 3) + 0) << 21, 454 D = ((2 << 3) + 1) << 21, 455 W = ((2 << 3) + 4) << 21, 456 L = ((2 << 3) + 5) << 21, 457 PS = ((2 << 3) + 6) << 21, 458 // COP1 Encoding of Function Field When rs=S. 459 ROUND_L_S = ((1 << 3) + 0), 460 TRUNC_L_S = ((1 << 3) + 1), 461 CEIL_L_S = ((1 << 3) + 2), 462 FLOOR_L_S = ((1 << 3) + 3), 463 ROUND_W_S = ((1 << 3) + 4), 464 TRUNC_W_S = ((1 << 3) + 5), 465 CEIL_W_S = ((1 << 3) + 6), 466 FLOOR_W_S = ((1 << 3) + 7), 467 CVT_D_S = ((4 << 3) + 1), 468 CVT_W_S = ((4 << 3) + 4), 469 CVT_L_S = ((4 << 3) + 5), 470 CVT_PS_S = ((4 << 3) + 6), 471 // COP1 Encoding of Function Field When rs=D. 472 ADD_D = ((0 << 3) + 0), 473 SUB_D = ((0 << 3) + 1), 474 MUL_D = ((0 << 3) + 2), 475 DIV_D = ((0 << 3) + 3), 476 SQRT_D = ((0 << 3) + 4), 477 ABS_D = ((0 << 3) + 5), 478 MOV_D = ((0 << 3) + 6), 479 NEG_D = ((0 << 3) + 7), 480 ROUND_L_D = ((1 << 3) + 0), 481 TRUNC_L_D = ((1 << 3) + 1), 482 CEIL_L_D = ((1 << 3) + 2), 483 FLOOR_L_D = ((1 << 3) + 3), 484 ROUND_W_D = ((1 << 3) + 4), 485 TRUNC_W_D = ((1 << 3) + 5), 486 CEIL_W_D = ((1 << 3) + 6), 487 FLOOR_W_D = ((1 << 3) + 7), 488 MIN = ((3 << 3) + 4), 489 MINA = ((3 << 3) + 5), 490 MAX = ((3 << 3) + 6), 491 MAXA = ((3 << 3) + 7), 492 CVT_S_D = ((4 << 3) + 0), 493 CVT_W_D = ((4 << 3) + 4), 494 CVT_L_D = ((4 << 3) + 5), 495 C_F_D = ((6 << 3) + 0), 496 C_UN_D = ((6 << 3) + 1), 497 C_EQ_D = ((6 << 3) + 2), 498 C_UEQ_D = ((6 << 3) + 3), 499 C_OLT_D = ((6 << 3) + 4), 500 C_ULT_D = ((6 << 3) + 5), 501 C_OLE_D = ((6 << 3) + 6), 502 C_ULE_D = ((6 << 3) + 7), 503 // COP1 Encoding of Function Field When rs=W or L. 504 CVT_S_W = ((4 << 3) + 0), 505 CVT_D_W = ((4 << 3) + 1), 506 CVT_S_L = ((4 << 3) + 0), 507 CVT_D_L = ((4 << 3) + 1), 508 BC1EQZ = ((2 << 2) + 1) << 21, 509 BC1NEZ = ((3 << 2) + 1) << 21, 510 // COP1 CMP positive predicates Bit 5..4 = 00. 511 CMP_AF = ((0 << 3) + 0), 512 CMP_UN = ((0 << 3) + 1), 513 CMP_EQ = ((0 << 3) + 2), 514 CMP_UEQ = ((0 << 3) + 3), 515 CMP_LT = ((0 << 3) + 4), 516 CMP_ULT = ((0 << 3) + 5), 517 CMP_LE = ((0 << 3) + 6), 518 CMP_ULE = ((0 << 3) + 7), 519 CMP_SAF = ((1 << 3) + 0), 520 CMP_SUN = ((1 << 3) + 1), 521 CMP_SEQ = ((1 << 3) + 2), 522 CMP_SUEQ = ((1 << 3) + 3), 523 CMP_SSLT = ((1 << 3) + 4), 524 CMP_SSULT = ((1 << 3) + 5), 525 CMP_SLE = ((1 << 3) + 6), 526 CMP_SULE = ((1 << 3) + 7), 527 // COP1 CMP negative predicates Bit 5..4 = 01. 528 CMP_AT = ((2 << 3) + 0), // Reserved, not implemented. 529 CMP_OR = ((2 << 3) + 1), 530 CMP_UNE = ((2 << 3) + 2), 531 CMP_NE = ((2 << 3) + 3), 532 CMP_UGE = ((2 << 3) + 4), // Reserved, not implemented. 533 CMP_OGE = ((2 << 3) + 5), // Reserved, not implemented. 534 CMP_UGT = ((2 << 3) + 6), // Reserved, not implemented. 535 CMP_OGT = ((2 << 3) + 7), // Reserved, not implemented. 536 CMP_SAT = ((3 << 3) + 0), // Reserved, not implemented. 537 CMP_SOR = ((3 << 3) + 1), 538 CMP_SUNE = ((3 << 3) + 2), 539 CMP_SNE = ((3 << 3) + 3), 540 CMP_SUGE = ((3 << 3) + 4), // Reserved, not implemented. 541 CMP_SOGE = ((3 << 3) + 5), // Reserved, not implemented. 542 CMP_SUGT = ((3 << 3) + 6), // Reserved, not implemented. 543 CMP_SOGT = ((3 << 3) + 7), // Reserved, not implemented. 544 545 SEL = ((2 << 3) + 0), 546 SELEQZ_C = ((2 << 3) + 4), // COP1 on FPR registers. 547 SELNEZ_C = ((2 << 3) + 7), // COP1 on FPR registers. 548 // COP1 Encoding of Function Field When rs=PS. 549 // COP1X Encoding of Function Field. 550 MADD_D = ((4 << 3) + 1), 551 552 NULLSF = 0 553}; 554 555 556// ----- Emulated conditions. 557// On MIPS we use this enum to abstract from conditionnal branch instructions. 558// The 'U' prefix is used to specify unsigned comparisons. 559// Oppposite conditions must be paired as odd/even numbers 560// because 'NegateCondition' function flips LSB to negate condition. 561enum Condition { 562 // Any value < 0 is considered no_condition. 563 kNoCondition = -1, 564 565 overflow = 0, 566 no_overflow = 1, 567 Uless = 2, 568 Ugreater_equal= 3, 569 equal = 4, 570 not_equal = 5, 571 Uless_equal = 6, 572 Ugreater = 7, 573 negative = 8, 574 positive = 9, 575 parity_even = 10, 576 parity_odd = 11, 577 less = 12, 578 greater_equal = 13, 579 less_equal = 14, 580 greater = 15, 581 ueq = 16, // Unordered or Equal. 582 nue = 17, // Not (Unordered or Equal). 583 584 cc_always = 18, 585 586 // Aliases. 587 carry = Uless, 588 not_carry = Ugreater_equal, 589 zero = equal, 590 eq = equal, 591 not_zero = not_equal, 592 ne = not_equal, 593 nz = not_equal, 594 sign = negative, 595 not_sign = positive, 596 mi = negative, 597 pl = positive, 598 hi = Ugreater, 599 ls = Uless_equal, 600 ge = greater_equal, 601 lt = less, 602 gt = greater, 603 le = less_equal, 604 hs = Ugreater_equal, 605 lo = Uless, 606 al = cc_always, 607 608 cc_default = kNoCondition 609}; 610 611 612// Returns the equivalent of !cc. 613// Negation of the default kNoCondition (-1) results in a non-default 614// no_condition value (-2). As long as tests for no_condition check 615// for condition < 0, this will work as expected. 616inline Condition NegateCondition(Condition cc) { 617 DCHECK(cc != cc_always); 618 return static_cast<Condition>(cc ^ 1); 619} 620 621 622// Commute a condition such that {a cond b == b cond' a}. 623inline Condition CommuteCondition(Condition cc) { 624 switch (cc) { 625 case Uless: 626 return Ugreater; 627 case Ugreater: 628 return Uless; 629 case Ugreater_equal: 630 return Uless_equal; 631 case Uless_equal: 632 return Ugreater_equal; 633 case less: 634 return greater; 635 case greater: 636 return less; 637 case greater_equal: 638 return less_equal; 639 case less_equal: 640 return greater_equal; 641 default: 642 return cc; 643 } 644} 645 646 647// ----- Coprocessor conditions. 648enum FPUCondition { 649 kNoFPUCondition = -1, 650 651 F = 0, // False. 652 UN = 1, // Unordered. 653 EQ = 2, // Equal. 654 UEQ = 3, // Unordered or Equal. 655 OLT = 4, // Ordered or Less Than. 656 ULT = 5, // Unordered or Less Than. 657 OLE = 6, // Ordered or Less Than or Equal. 658 ULE = 7 // Unordered or Less Than or Equal. 659}; 660 661 662// FPU rounding modes. 663enum FPURoundingMode { 664 RN = 0 << 0, // Round to Nearest. 665 RZ = 1 << 0, // Round towards zero. 666 RP = 2 << 0, // Round towards Plus Infinity. 667 RM = 3 << 0, // Round towards Minus Infinity. 668 669 // Aliases. 670 kRoundToNearest = RN, 671 kRoundToZero = RZ, 672 kRoundToPlusInf = RP, 673 kRoundToMinusInf = RM 674}; 675 676const uint32_t kFPURoundingModeMask = 3 << 0; 677 678enum CheckForInexactConversion { 679 kCheckForInexactConversion, 680 kDontCheckForInexactConversion 681}; 682 683 684// ----------------------------------------------------------------------------- 685// Hints. 686 687// Branch hints are not used on the MIPS. They are defined so that they can 688// appear in shared function signatures, but will be ignored in MIPS 689// implementations. 690enum Hint { 691 no_hint = 0 692}; 693 694 695inline Hint NegateHint(Hint hint) { 696 return no_hint; 697} 698 699 700// ----------------------------------------------------------------------------- 701// Specific instructions, constants, and masks. 702// These constants are declared in assembler-mips.cc, as they use named 703// registers and other constants. 704 705// addiu(sp, sp, 4) aka Pop() operation or part of Pop(r) 706// operations as post-increment of sp. 707extern const Instr kPopInstruction; 708// addiu(sp, sp, -4) part of Push(r) operation as pre-decrement of sp. 709extern const Instr kPushInstruction; 710// sw(r, MemOperand(sp, 0)) 711extern const Instr kPushRegPattern; 712// lw(r, MemOperand(sp, 0)) 713extern const Instr kPopRegPattern; 714extern const Instr kLwRegFpOffsetPattern; 715extern const Instr kSwRegFpOffsetPattern; 716extern const Instr kLwRegFpNegOffsetPattern; 717extern const Instr kSwRegFpNegOffsetPattern; 718// A mask for the Rt register for push, pop, lw, sw instructions. 719extern const Instr kRtMask; 720extern const Instr kLwSwInstrTypeMask; 721extern const Instr kLwSwInstrArgumentMask; 722extern const Instr kLwSwOffsetMask; 723 724// Break 0xfffff, reserved for redirected real time call. 725const Instr rtCallRedirInstr = SPECIAL | BREAK | call_rt_redirected << 6; 726// A nop instruction. (Encoding of sll 0 0 0). 727const Instr nopInstr = 0; 728 729class Instruction { 730 public: 731 enum { 732 kInstrSize = 4, 733 kInstrSizeLog2 = 2, 734 // On MIPS PC cannot actually be directly accessed. We behave as if PC was 735 // always the value of the current instruction being executed. 736 kPCReadOffset = 0 737 }; 738 739 // Get the raw instruction bits. 740 inline Instr InstructionBits() const { 741 return *reinterpret_cast<const Instr*>(this); 742 } 743 744 // Set the raw instruction bits to value. 745 inline void SetInstructionBits(Instr value) { 746 *reinterpret_cast<Instr*>(this) = value; 747 } 748 749 // Read one particular bit out of the instruction bits. 750 inline int Bit(int nr) const { 751 return (InstructionBits() >> nr) & 1; 752 } 753 754 // Read a bit field out of the instruction bits. 755 inline int Bits(int hi, int lo) const { 756 return (InstructionBits() >> lo) & ((2 << (hi - lo)) - 1); 757 } 758 759 // Instruction type. 760 enum Type { 761 kRegisterType, 762 kImmediateType, 763 kJumpType, 764 kUnsupported = -1 765 }; 766 767 // Get the encoding type of the instruction. 768 Type InstructionType() const; 769 770 771 // Accessors for the different named fields used in the MIPS encoding. 772 inline Opcode OpcodeValue() const { 773 return static_cast<Opcode>( 774 Bits(kOpcodeShift + kOpcodeBits - 1, kOpcodeShift)); 775 } 776 777 inline int RsValue() const { 778 DCHECK(InstructionType() == kRegisterType || 779 InstructionType() == kImmediateType); 780 return Bits(kRsShift + kRsBits - 1, kRsShift); 781 } 782 783 inline int RtValue() const { 784 DCHECK(InstructionType() == kRegisterType || 785 InstructionType() == kImmediateType); 786 return Bits(kRtShift + kRtBits - 1, kRtShift); 787 } 788 789 inline int RdValue() const { 790 DCHECK(InstructionType() == kRegisterType); 791 return Bits(kRdShift + kRdBits - 1, kRdShift); 792 } 793 794 inline int SaValue() const { 795 DCHECK(InstructionType() == kRegisterType); 796 return Bits(kSaShift + kSaBits - 1, kSaShift); 797 } 798 799 inline int FunctionValue() const { 800 DCHECK(InstructionType() == kRegisterType || 801 InstructionType() == kImmediateType); 802 return Bits(kFunctionShift + kFunctionBits - 1, kFunctionShift); 803 } 804 805 inline int FdValue() const { 806 return Bits(kFdShift + kFdBits - 1, kFdShift); 807 } 808 809 inline int FsValue() const { 810 return Bits(kFsShift + kFsBits - 1, kFsShift); 811 } 812 813 inline int FtValue() const { 814 return Bits(kFtShift + kFtBits - 1, kFtShift); 815 } 816 817 inline int FrValue() const { 818 return Bits(kFrShift + kFrBits -1, kFrShift); 819 } 820 821 // Float Compare condition code instruction bits. 822 inline int FCccValue() const { 823 return Bits(kFCccShift + kFCccBits - 1, kFCccShift); 824 } 825 826 // Float Branch condition code instruction bits. 827 inline int FBccValue() const { 828 return Bits(kFBccShift + kFBccBits - 1, kFBccShift); 829 } 830 831 // Float Branch true/false instruction bit. 832 inline int FBtrueValue() const { 833 return Bits(kFBtrueShift + kFBtrueBits - 1, kFBtrueShift); 834 } 835 836 // Return the fields at their original place in the instruction encoding. 837 inline Opcode OpcodeFieldRaw() const { 838 return static_cast<Opcode>(InstructionBits() & kOpcodeMask); 839 } 840 841 inline int RsFieldRaw() const { 842 DCHECK(InstructionType() == kRegisterType || 843 InstructionType() == kImmediateType); 844 return InstructionBits() & kRsFieldMask; 845 } 846 847 // Same as above function, but safe to call within InstructionType(). 848 inline int RsFieldRawNoAssert() const { 849 return InstructionBits() & kRsFieldMask; 850 } 851 852 inline int RtFieldRaw() const { 853 DCHECK(InstructionType() == kRegisterType || 854 InstructionType() == kImmediateType); 855 return InstructionBits() & kRtFieldMask; 856 } 857 858 inline int RdFieldRaw() const { 859 DCHECK(InstructionType() == kRegisterType); 860 return InstructionBits() & kRdFieldMask; 861 } 862 863 inline int SaFieldRaw() const { 864 DCHECK(InstructionType() == kRegisterType); 865 return InstructionBits() & kSaFieldMask; 866 } 867 868 inline int FunctionFieldRaw() const { 869 return InstructionBits() & kFunctionFieldMask; 870 } 871 872 // Get the secondary field according to the opcode. 873 inline int SecondaryValue() const { 874 Opcode op = OpcodeFieldRaw(); 875 switch (op) { 876 case SPECIAL: 877 case SPECIAL2: 878 return FunctionValue(); 879 case COP1: 880 return RsValue(); 881 case REGIMM: 882 return RtValue(); 883 default: 884 return NULLSF; 885 } 886 } 887 888 inline int32_t Imm16Value() const { 889 DCHECK(InstructionType() == kImmediateType); 890 return Bits(kImm16Shift + kImm16Bits - 1, kImm16Shift); 891 } 892 893 inline int32_t Imm21Value() const { 894 DCHECK(InstructionType() == kImmediateType); 895 return Bits(kImm21Shift + kImm21Bits - 1, kImm21Shift); 896 } 897 898 inline int32_t Imm26Value() const { 899 DCHECK(InstructionType() == kJumpType); 900 return Bits(kImm26Shift + kImm26Bits - 1, kImm26Shift); 901 } 902 903 // Say if the instruction should not be used in a branch delay slot. 904 bool IsForbiddenInBranchDelay() const; 905 // Say if the instruction 'links'. e.g. jal, bal. 906 bool IsLinkingInstruction() const; 907 // Say if the instruction is a break or a trap. 908 bool IsTrap() const; 909 910 // Instructions are read of out a code stream. The only way to get a 911 // reference to an instruction is to convert a pointer. There is no way 912 // to allocate or create instances of class Instruction. 913 // Use the At(pc) function to create references to Instruction. 914 static Instruction* At(byte* pc) { 915 return reinterpret_cast<Instruction*>(pc); 916 } 917 918 private: 919 // We need to prevent the creation of instances of class Instruction. 920 DISALLOW_IMPLICIT_CONSTRUCTORS(Instruction); 921}; 922 923 924// ----------------------------------------------------------------------------- 925// MIPS assembly various constants. 926 927// C/C++ argument slots size. 928const int kCArgSlotCount = 4; 929const int kCArgsSlotsSize = kCArgSlotCount * Instruction::kInstrSize; 930// JS argument slots size. 931const int kJSArgsSlotsSize = 0 * Instruction::kInstrSize; 932// Assembly builtins argument slots size. 933const int kBArgsSlotsSize = 0 * Instruction::kInstrSize; 934 935const int kBranchReturnOffset = 2 * Instruction::kInstrSize; 936 937} } // namespace v8::internal 938 939#endif // #ifndef V8_MIPS_CONSTANTS_H_ 940