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 19 enum 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 43 enum 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 56 enum 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. 75 const 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. 80 const bool IsMipsSoftFloatABI = true; 81 #else 82 const bool IsMipsSoftFloatABI = true; 83 #endif 84 85 #if defined(V8_TARGET_LITTLE_ENDIAN) 86 const uint32_t kHoleNanUpper32Offset = 4; 87 const uint32_t kHoleNanLower32Offset = 0; 88 #elif defined(V8_TARGET_BIG_ENDIAN) 89 const uint32_t kHoleNanUpper32Offset = 0; 90 const 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(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 122 namespace v8 { 123 namespace internal { 124 125 // ----------------------------------------------------------------------------- 126 // Registers and FPURegisters. 127 128 // Number of general purpose registers. 129 const int kNumRegisters = 32; 130 const int kInvalidRegister = -1; 131 132 // Number of registers with HI, LO, and pc. 133 const int kNumSimuRegisters = 35; 134 135 // In the simulator, the PC register is simulated as the 34th register. 136 const int kPCRegister = 34; 137 138 // Number coprocessor registers. 139 const int kNumFPURegisters = 32; 140 const int kInvalidFPURegister = -1; 141 142 // FPU (coprocessor 1) control registers. Currently only FCSR is implemented. 143 const int kFCSRRegister = 31; 144 const int kInvalidFPUControlRegister = -1; 145 const uint32_t kFPUInvalidResult = static_cast<uint32_t>(1 << 31) - 1; 146 const uint64_t kFPU64InvalidResult = 147 static_cast<uint64_t>(static_cast<uint64_t>(1) << 63) - 1; 148 149 // FCSR constants. 150 const uint32_t kFCSRInexactFlagBit = 2; 151 const uint32_t kFCSRUnderflowFlagBit = 3; 152 const uint32_t kFCSROverflowFlagBit = 4; 153 const uint32_t kFCSRDivideByZeroFlagBit = 5; 154 const uint32_t kFCSRInvalidOpFlagBit = 6; 155 156 const uint32_t kFCSRInexactFlagMask = 1 << kFCSRInexactFlagBit; 157 const uint32_t kFCSRUnderflowFlagMask = 1 << kFCSRUnderflowFlagBit; 158 const uint32_t kFCSROverflowFlagMask = 1 << kFCSROverflowFlagBit; 159 const uint32_t kFCSRDivideByZeroFlagMask = 1 << kFCSRDivideByZeroFlagBit; 160 const uint32_t kFCSRInvalidOpFlagMask = 1 << kFCSRInvalidOpFlagBit; 161 162 const uint32_t kFCSRFlagMask = 163 kFCSRInexactFlagMask | 164 kFCSRUnderflowFlagMask | 165 kFCSROverflowFlagMask | 166 kFCSRDivideByZeroFlagMask | 167 kFCSRInvalidOpFlagMask; 168 169 const uint32_t kFCSRExceptionFlagMask = kFCSRFlagMask ^ kFCSRInexactFlagMask; 170 171 // 'pref' instruction hints 172 const int32_t kPrefHintLoad = 0; 173 const int32_t kPrefHintStore = 1; 174 const int32_t kPrefHintLoadStreamed = 4; 175 const int32_t kPrefHintStoreStreamed = 5; 176 const int32_t kPrefHintLoadRetained = 6; 177 const int32_t kPrefHintStoreRetained = 7; 178 const int32_t kPrefHintWritebackInvalidate = 25; 179 const int32_t kPrefHintPrepareForStore = 30; 180 181 // Helper functions for converting between register numbers and names. 182 class 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. 204 class 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. 227 typedef int32_t Instr; 228 229 // Special Software Interrupt codes when used in the presence of the MIPS 230 // simulator. 231 enum 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. 243 const uint32_t kMaxWatchpointCode = 31; 244 const uint32_t kMaxStopCode = 127; 245 STATIC_ASSERT(kMaxWatchpointCode < kMaxStopCode); 246 247 248 // ----- Fields offset and length. 249 const int kOpcodeShift = 26; 250 const int kOpcodeBits = 6; 251 const int kRsShift = 21; 252 const int kRsBits = 5; 253 const int kRtShift = 16; 254 const int kRtBits = 5; 255 const int kRdShift = 11; 256 const int kRdBits = 5; 257 const int kSaShift = 6; 258 const int kSaBits = 5; 259 const int kFunctionShift = 0; 260 const int kFunctionBits = 6; 261 const int kLuiShift = 16; 262 263 const int kImm16Shift = 0; 264 const int kImm16Bits = 16; 265 const int kImm21Shift = 0; 266 const int kImm21Bits = 21; 267 const int kImm26Shift = 0; 268 const int kImm26Bits = 26; 269 const int kImm28Shift = 0; 270 const int kImm28Bits = 28; 271 const int kImm32Shift = 0; 272 const int kImm32Bits = 32; 273 274 // In branches and jumps immediate fields point to words, not bytes, 275 // and are therefore shifted by 2. 276 const int kImmFieldShift = 2; 277 278 const int kFrBits = 5; 279 const int kFrShift = 21; 280 const int kFsShift = 11; 281 const int kFsBits = 5; 282 const int kFtShift = 16; 283 const int kFtBits = 5; 284 const int kFdShift = 6; 285 const int kFdBits = 5; 286 const int kFCccShift = 8; 287 const int kFCccBits = 3; 288 const int kFBccShift = 18; 289 const int kFBccBits = 3; 290 const int kFBtrueShift = 16; 291 const int kFBtrueBits = 1; 292 293 // ----- Miscellaneous useful masks. 294 // Instruction bit masks. 295 const int kOpcodeMask = ((1 << kOpcodeBits) - 1) << kOpcodeShift; 296 const int kImm16Mask = ((1 << kImm16Bits) - 1) << kImm16Shift; 297 const int kImm26Mask = ((1 << kImm26Bits) - 1) << kImm26Shift; 298 const int kImm28Mask = ((1 << kImm28Bits) - 1) << kImm28Shift; 299 const int kRsFieldMask = ((1 << kRsBits) - 1) << kRsShift; 300 const int kRtFieldMask = ((1 << kRtBits) - 1) << kRtShift; 301 const int kRdFieldMask = ((1 << kRdBits) - 1) << kRdShift; 302 const int kSaFieldMask = ((1 << kSaBits) - 1) << kSaShift; 303 const int kFunctionFieldMask = ((1 << kFunctionBits) - 1) << kFunctionShift; 304 // Misc masks. 305 const int kHiMask = 0xffff << 16; 306 const int kLoMask = 0xffff; 307 const int kSignMask = 0x80000000; 308 const 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. 313 enum 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 370 enum 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. 561 enum 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. 616 inline 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}. 623 inline 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. 648 enum 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. 663 enum 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 676 const uint32_t kFPURoundingModeMask = 3 << 0; 677 678 enum 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. 690 enum Hint { 691 no_hint = 0 692 }; 693 694 695 inline 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. 707 extern const Instr kPopInstruction; 708 // addiu(sp, sp, -4) part of Push(r) operation as pre-decrement of sp. 709 extern const Instr kPushInstruction; 710 // sw(r, MemOperand(sp, 0)) 711 extern const Instr kPushRegPattern; 712 // lw(r, MemOperand(sp, 0)) 713 extern const Instr kPopRegPattern; 714 extern const Instr kLwRegFpOffsetPattern; 715 extern const Instr kSwRegFpOffsetPattern; 716 extern const Instr kLwRegFpNegOffsetPattern; 717 extern const Instr kSwRegFpNegOffsetPattern; 718 // A mask for the Rt register for push, pop, lw, sw instructions. 719 extern const Instr kRtMask; 720 extern const Instr kLwSwInstrTypeMask; 721 extern const Instr kLwSwInstrArgumentMask; 722 extern const Instr kLwSwOffsetMask; 723 724 // Break 0xfffff, reserved for redirected real time call. 725 const Instr rtCallRedirInstr = SPECIAL | BREAK | call_rt_redirected << 6; 726 // A nop instruction. (Encoding of sll 0 0 0). 727 const Instr nopInstr = 0; 728 729 class 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. 928 const int kCArgSlotCount = 4; 929 const int kCArgsSlotsSize = kCArgSlotCount * Instruction::kInstrSize; 930 // JS argument slots size. 931 const int kJSArgsSlotsSize = 0 * Instruction::kInstrSize; 932 // Assembly builtins argument slots size. 933 const int kBArgsSlotsSize = 0 * Instruction::kInstrSize; 934 935 const int kBranchReturnOffset = 2 * Instruction::kInstrSize; 936 937 } } // namespace v8::internal 938 939 #endif // #ifndef V8_MIPS_CONSTANTS_H_ 940