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