13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved. 23100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// Redistribution and use in source and binary forms, with or without 33100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// modification, are permitted provided that the following conditions are 43100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// met: 53100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// 63100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// * Redistributions of source code must retain the above copyright 73100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// notice, this list of conditions and the following disclaimer. 83100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// * Redistributions in binary form must reproduce the above 93100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// copyright notice, this list of conditions and the following 103100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// disclaimer in the documentation and/or other materials provided 113100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// with the distribution. 123100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// * Neither the name of Google Inc. nor the names of its 133100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// contributors may be used to endorse or promote products derived 143100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// from this software without specific prior written permission. 153100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// 163100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 173100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 183100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 193100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 203100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 213100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 223100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 233100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 243100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 253100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 263100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 273100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 283100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu#ifndef V8_MIPS_CONSTANTS_H_ 293100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu#define V8_MIPS_CONSTANTS_H_ 303100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 313100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// UNIMPLEMENTED_ macro for MIPS. 3244f0eee88ff00398ff7f715fab053374d808c90dSteve Block#ifdef DEBUG 333100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu#define UNIMPLEMENTED_MIPS() \ 343100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu v8::internal::PrintF("%s, \tline %d: \tfunction %s not implemented. \n", \ 353100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu __FILE__, __LINE__, __func__) 3644f0eee88ff00398ff7f715fab053374d808c90dSteve Block#else 3744f0eee88ff00398ff7f715fab053374d808c90dSteve Block#define UNIMPLEMENTED_MIPS() 3844f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif 3944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 403100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu#define UNSUPPORTED_MIPS() v8::internal::PrintF("Unsupported instruction.\n") 413100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochenum ArchVariants { 433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch kMips32r2, 443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch kMips32r1, 453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch kLoongson 463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}; 473100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 4844f0eee88ff00398ff7f715fab053374d808c90dSteve Block#ifdef _MIPS_ARCH_MIPS32R2 493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static const ArchVariants kArchVariant = kMips32r2; 503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#elif _MIPS_ARCH_LOONGSON 513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// The loongson flag refers to the LOONGSON architectures based on MIPS-III, 523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// which predates (and is a subset of) the mips32r2 and r1 architectures. 533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static const ArchVariants kArchVariant = kLoongson; 5444f0eee88ff00398ff7f715fab053374d808c90dSteve Block#else 553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static const ArchVariants kArchVariant = kMips32r1; 5644f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif 5744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 5844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 59257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#if(defined(__mips_hard_float) && __mips_hard_float != 0) 60257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// Use floating-point coprocessor instructions. This flag is raised when 61257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// -mhard-float is passed to the compiler. 623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst bool IsMipsSoftFloatABI = false; 63257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#elif(defined(__mips_soft_float) && __mips_soft_float != 0) 64257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// Not using floating-point coprocessor instructions. This flag is raised when 65257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// -msoft-float is passed to the compiler. 663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst bool IsMipsSoftFloatABI = true; 67257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#else 683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst bool IsMipsSoftFloatABI = true; 69257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#endif 70257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 71257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 723100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// Defines constants and accessor classes to assemble, disassemble and 733100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// simulate MIPS32 instructions. 743100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// 753100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// See: MIPS32 Architecture For Programmers 763100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// Volume II: The MIPS32 Instruction Set 773100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// Try www.cs.cornell.edu/courses/cs3410/2008fa/MIPS_Vol2.pdf. 783100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 7944f0eee88ff00398ff7f715fab053374d808c90dSteve Blocknamespace v8 { 8044f0eee88ff00398ff7f715fab053374d808c90dSteve Blocknamespace internal { 813100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 823100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// ----------------------------------------------------------------------------- 83257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// Registers and FPURegisters. 843100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 853100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// Number of general purpose registers. 863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kNumRegisters = 32; 873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kInvalidRegister = -1; 883100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 893100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// Number of registers with HI, LO, and pc. 903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kNumSimuRegisters = 35; 913100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 923100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// In the simulator, the PC register is simulated as the 34th register. 933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kPCRegister = 34; 943100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 953100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// Number coprocessor registers. 963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kNumFPURegisters = 32; 973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kInvalidFPURegister = -1; 983100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 9944f0eee88ff00398ff7f715fab053374d808c90dSteve Block// FPU (coprocessor 1) control registers. Currently only FCSR is implemented. 1003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kFCSRRegister = 31; 1013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kInvalidFPUControlRegister = -1; 1023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst uint32_t kFPUInvalidResult = (uint32_t) (1 << 31) - 1; 10344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 10444f0eee88ff00398ff7f715fab053374d808c90dSteve Block// FCSR constants. 1053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst uint32_t kFCSRInexactFlagBit = 2; 1063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst uint32_t kFCSRUnderflowFlagBit = 3; 1073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst uint32_t kFCSROverflowFlagBit = 4; 1083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst uint32_t kFCSRDivideByZeroFlagBit = 5; 1093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst uint32_t kFCSRInvalidOpFlagBit = 6; 1103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst uint32_t kFCSRInexactFlagMask = 1 << kFCSRInexactFlagBit; 1123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst uint32_t kFCSRUnderflowFlagMask = 1 << kFCSRUnderflowFlagBit; 1133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst uint32_t kFCSROverflowFlagMask = 1 << kFCSROverflowFlagBit; 1143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst uint32_t kFCSRDivideByZeroFlagMask = 1 << kFCSRDivideByZeroFlagBit; 1153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst uint32_t kFCSRInvalidOpFlagMask = 1 << kFCSRInvalidOpFlagBit; 1163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst uint32_t kFCSRFlagMask = 1183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch kFCSRInexactFlagMask | 1193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch kFCSRUnderflowFlagMask | 1203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch kFCSROverflowFlagMask | 1213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch kFCSRDivideByZeroFlagMask | 1223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch kFCSRInvalidOpFlagMask; 1233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst uint32_t kFCSRExceptionFlagMask = kFCSRFlagMask ^ kFCSRInexactFlagMask; 12544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 1263100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// Helper functions for converting between register numbers and names. 1273100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuclass Registers { 1283100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu public: 1293100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Return the name of the register. 1303100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu static const char* Name(int reg); 1313100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 1323100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Lookup the register number for the name provided. 1333100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu static int Number(const char* name); 1343100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 1353100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu struct RegisterAlias { 1363100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu int reg; 1373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const char* name; 1383100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu }; 1393100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 1403100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu static const int32_t kMaxValue = 0x7fffffff; 1413100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu static const int32_t kMinValue = 0x80000000; 1423100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 1433100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu private: 1443100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu static const char* names_[kNumSimuRegisters]; 1453100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu static const RegisterAlias aliases_[]; 1463100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}; 1473100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 1483100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// Helper functions for converting between register numbers and names. 14944f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass FPURegisters { 1503100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu public: 1513100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Return the name of the register. 1523100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu static const char* Name(int reg); 1533100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 1543100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Lookup the register number for the name provided. 1553100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu static int Number(const char* name); 1563100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 1573100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu struct RegisterAlias { 1583100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu int creg; 1593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const char* name; 1603100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu }; 1613100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 1623100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu private: 16344f0eee88ff00398ff7f715fab053374d808c90dSteve Block static const char* names_[kNumFPURegisters]; 1643100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu static const RegisterAlias aliases_[]; 1653100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}; 1663100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 1673100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 1683100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// ----------------------------------------------------------------------------- 1693100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// Instructions encoding constants. 1703100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 1713100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// On MIPS all instructions are 32 bits. 1723100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescutypedef int32_t Instr; 1733100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 1743100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// Special Software Interrupt codes when used in the presence of the MIPS 1753100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// simulator. 1763100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuenum SoftwareInterruptCodes { 1773100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Transition to C code. 1783100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu call_rt_redirected = 0xfffff 1793100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}; 1803100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 1813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// On MIPS Simulator breakpoints can have different codes: 1823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// - Breaks between 0 and kMaxWatchpointCode are treated as simple watchpoints, 1833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// the simulator will run through them and print the registers. 1843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// - Breaks between kMaxWatchpointCode and kMaxStopCode are treated as stop() 1853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// instructions (see Assembler::stop()). 1863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// - Breaks larger than kMaxStopCode are simple breaks, dropping you into the 1873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// debugger. 1883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst uint32_t kMaxWatchpointCode = 31; 1893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst uint32_t kMaxStopCode = 127; 1903fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochSTATIC_ASSERT(kMaxWatchpointCode < kMaxStopCode); 1913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1933100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// ----- Fields offset and length. 1943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kOpcodeShift = 26; 1953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kOpcodeBits = 6; 1963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kRsShift = 21; 1973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kRsBits = 5; 1983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kRtShift = 16; 1993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kRtBits = 5; 2003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kRdShift = 11; 2013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kRdBits = 5; 2023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kSaShift = 6; 2033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kSaBits = 5; 2043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kFunctionShift = 0; 2053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kFunctionBits = 6; 2063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kLuiShift = 16; 2073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kImm16Shift = 0; 2093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kImm16Bits = 16; 2103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kImm26Shift = 0; 2113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kImm26Bits = 26; 2123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kImm28Shift = 0; 2133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kImm28Bits = 28; 2143100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 215589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch// In branches and jumps immediate fields point to words, not bytes, 216589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch// and are therefore shifted by 2. 2173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kImmFieldShift = 2; 2183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kFsShift = 11; 2203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kFsBits = 5; 2213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kFtShift = 16; 2223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kFtBits = 5; 2233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kFdShift = 6; 2243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kFdBits = 5; 2253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kFCccShift = 8; 2263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kFCccBits = 3; 2273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kFBccShift = 18; 2283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kFBccBits = 3; 2293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kFBtrueShift = 16; 2303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kFBtrueBits = 1; 2313100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 232257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// ----- Miscellaneous useful masks. 2333100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// Instruction bit masks. 2343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kOpcodeMask = ((1 << kOpcodeBits) - 1) << kOpcodeShift; 2353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kImm16Mask = ((1 << kImm16Bits) - 1) << kImm16Shift; 2363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kImm26Mask = ((1 << kImm26Bits) - 1) << kImm26Shift; 2373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kImm28Mask = ((1 << kImm28Bits) - 1) << kImm28Shift; 2383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kRsFieldMask = ((1 << kRsBits) - 1) << kRsShift; 2393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kRtFieldMask = ((1 << kRtBits) - 1) << kRtShift; 2403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kRdFieldMask = ((1 << kRdBits) - 1) << kRdShift; 2413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kSaFieldMask = ((1 << kSaBits) - 1) << kSaShift; 2423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kFunctionFieldMask = ((1 << kFunctionBits) - 1) << kFunctionShift; 2433100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// Misc masks. 2443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kHiMask = 0xffff << 16; 2453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kLoMask = 0xffff; 2463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kSignMask = 0x80000000; 2473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kJumpAddrMask = (1 << (kImm26Bits + kImmFieldShift)) - 1; 2483100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 2493100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// ----- MIPS Opcodes and Function Fields. 2503100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// We use this presentation to stay close to the table representation in 2513100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// MIPS32 Architecture For Programmers, Volume II: The MIPS32 Instruction Set. 2523100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuenum Opcode { 2533100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu SPECIAL = 0 << kOpcodeShift, 2543100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu REGIMM = 1 << kOpcodeShift, 2553100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 2563100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu J = ((0 << 3) + 2) << kOpcodeShift, 2573100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu JAL = ((0 << 3) + 3) << kOpcodeShift, 2583100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu BEQ = ((0 << 3) + 4) << kOpcodeShift, 2593100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu BNE = ((0 << 3) + 5) << kOpcodeShift, 2603100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu BLEZ = ((0 << 3) + 6) << kOpcodeShift, 2613100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu BGTZ = ((0 << 3) + 7) << kOpcodeShift, 2623100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 2633100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu ADDI = ((1 << 3) + 0) << kOpcodeShift, 2643100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu ADDIU = ((1 << 3) + 1) << kOpcodeShift, 2653100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu SLTI = ((1 << 3) + 2) << kOpcodeShift, 2663100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu SLTIU = ((1 << 3) + 3) << kOpcodeShift, 2673100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu ANDI = ((1 << 3) + 4) << kOpcodeShift, 2683100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu ORI = ((1 << 3) + 5) << kOpcodeShift, 2693100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu XORI = ((1 << 3) + 6) << kOpcodeShift, 2703100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu LUI = ((1 << 3) + 7) << kOpcodeShift, 2713100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 272257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch COP1 = ((2 << 3) + 1) << kOpcodeShift, // Coprocessor 1 class. 2733100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu BEQL = ((2 << 3) + 4) << kOpcodeShift, 2743100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu BNEL = ((2 << 3) + 5) << kOpcodeShift, 2753100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu BLEZL = ((2 << 3) + 6) << kOpcodeShift, 2763100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu BGTZL = ((2 << 3) + 7) << kOpcodeShift, 2773100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 2783100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu SPECIAL2 = ((3 << 3) + 4) << kOpcodeShift, 27944f0eee88ff00398ff7f715fab053374d808c90dSteve Block SPECIAL3 = ((3 << 3) + 7) << kOpcodeShift, 2803100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 2813100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu LB = ((4 << 3) + 0) << kOpcodeShift, 28244f0eee88ff00398ff7f715fab053374d808c90dSteve Block LH = ((4 << 3) + 1) << kOpcodeShift, 28344f0eee88ff00398ff7f715fab053374d808c90dSteve Block LWL = ((4 << 3) + 2) << kOpcodeShift, 2843100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu LW = ((4 << 3) + 3) << kOpcodeShift, 2853100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu LBU = ((4 << 3) + 4) << kOpcodeShift, 28644f0eee88ff00398ff7f715fab053374d808c90dSteve Block LHU = ((4 << 3) + 5) << kOpcodeShift, 28744f0eee88ff00398ff7f715fab053374d808c90dSteve Block LWR = ((4 << 3) + 6) << kOpcodeShift, 2883100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu SB = ((5 << 3) + 0) << kOpcodeShift, 28944f0eee88ff00398ff7f715fab053374d808c90dSteve Block SH = ((5 << 3) + 1) << kOpcodeShift, 29044f0eee88ff00398ff7f715fab053374d808c90dSteve Block SWL = ((5 << 3) + 2) << kOpcodeShift, 2913100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu SW = ((5 << 3) + 3) << kOpcodeShift, 29244f0eee88ff00398ff7f715fab053374d808c90dSteve Block SWR = ((5 << 3) + 6) << kOpcodeShift, 2933100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 2943100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu LWC1 = ((6 << 3) + 1) << kOpcodeShift, 2953100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu LDC1 = ((6 << 3) + 5) << kOpcodeShift, 2963100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 2973100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu SWC1 = ((7 << 3) + 1) << kOpcodeShift, 2983100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu SDC1 = ((7 << 3) + 5) << kOpcodeShift 2993100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}; 3003100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 3013100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuenum SecondaryField { 3023100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // SPECIAL Encoding of Function Field. 3033100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu SLL = ((0 << 3) + 0), 304589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch MOVCI = ((0 << 3) + 1), 3053100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu SRL = ((0 << 3) + 2), 3063100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu SRA = ((0 << 3) + 3), 3073100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu SLLV = ((0 << 3) + 4), 3083100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu SRLV = ((0 << 3) + 6), 3093100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu SRAV = ((0 << 3) + 7), 3103100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 3113100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu JR = ((1 << 3) + 0), 3123100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu JALR = ((1 << 3) + 1), 31344f0eee88ff00398ff7f715fab053374d808c90dSteve Block MOVZ = ((1 << 3) + 2), 31444f0eee88ff00398ff7f715fab053374d808c90dSteve Block MOVN = ((1 << 3) + 3), 3153100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu BREAK = ((1 << 3) + 5), 3163100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 3173100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu MFHI = ((2 << 3) + 0), 3183100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu MFLO = ((2 << 3) + 2), 3193100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 3203100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu MULT = ((3 << 3) + 0), 3213100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu MULTU = ((3 << 3) + 1), 3223100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu DIV = ((3 << 3) + 2), 3233100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu DIVU = ((3 << 3) + 3), 3243100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 3253100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu ADD = ((4 << 3) + 0), 3263100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu ADDU = ((4 << 3) + 1), 3273100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu SUB = ((4 << 3) + 2), 3283100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu SUBU = ((4 << 3) + 3), 3293100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu AND = ((4 << 3) + 4), 3303100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu OR = ((4 << 3) + 5), 3313100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu XOR = ((4 << 3) + 6), 3323100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu NOR = ((4 << 3) + 7), 3333100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 3343100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu SLT = ((5 << 3) + 2), 3353100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu SLTU = ((5 << 3) + 3), 3363100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 3373100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu TGE = ((6 << 3) + 0), 3383100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu TGEU = ((6 << 3) + 1), 3393100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu TLT = ((6 << 3) + 2), 3403100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu TLTU = ((6 << 3) + 3), 3413100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu TEQ = ((6 << 3) + 4), 3423100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu TNE = ((6 << 3) + 6), 3433100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 3443100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // SPECIAL2 Encoding of Function Field. 3453100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu MUL = ((0 << 3) + 2), 34644f0eee88ff00398ff7f715fab053374d808c90dSteve Block CLZ = ((4 << 3) + 0), 34744f0eee88ff00398ff7f715fab053374d808c90dSteve Block CLO = ((4 << 3) + 1), 34844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 34944f0eee88ff00398ff7f715fab053374d808c90dSteve Block // SPECIAL3 Encoding of Function Field. 35044f0eee88ff00398ff7f715fab053374d808c90dSteve Block EXT = ((0 << 3) + 0), 35144f0eee88ff00398ff7f715fab053374d808c90dSteve Block INS = ((0 << 3) + 4), 3523100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 3533100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // REGIMM encoding of rt Field. 3543100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu BLTZ = ((0 << 3) + 0) << 16, 3553100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu BGEZ = ((0 << 3) + 1) << 16, 3563100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu BLTZAL = ((2 << 3) + 0) << 16, 3573100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu BGEZAL = ((2 << 3) + 1) << 16, 3583100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 3593100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // COP1 Encoding of rs Field. 3603100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu MFC1 = ((0 << 3) + 0) << 21, 36144f0eee88ff00398ff7f715fab053374d808c90dSteve Block CFC1 = ((0 << 3) + 2) << 21, 3623100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu MFHC1 = ((0 << 3) + 3) << 21, 3633100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu MTC1 = ((0 << 3) + 4) << 21, 36444f0eee88ff00398ff7f715fab053374d808c90dSteve Block CTC1 = ((0 << 3) + 6) << 21, 3653100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu MTHC1 = ((0 << 3) + 7) << 21, 3663100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu BC1 = ((1 << 3) + 0) << 21, 3673100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu S = ((2 << 3) + 0) << 21, 3683100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu D = ((2 << 3) + 1) << 21, 3693100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu W = ((2 << 3) + 4) << 21, 3703100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu L = ((2 << 3) + 5) << 21, 3713100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu PS = ((2 << 3) + 6) << 21, 3723100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // COP1 Encoding of Function Field When rs=S. 37344f0eee88ff00398ff7f715fab053374d808c90dSteve Block ROUND_L_S = ((1 << 3) + 0), 37444f0eee88ff00398ff7f715fab053374d808c90dSteve Block TRUNC_L_S = ((1 << 3) + 1), 37544f0eee88ff00398ff7f715fab053374d808c90dSteve Block CEIL_L_S = ((1 << 3) + 2), 37644f0eee88ff00398ff7f715fab053374d808c90dSteve Block FLOOR_L_S = ((1 << 3) + 3), 37744f0eee88ff00398ff7f715fab053374d808c90dSteve Block ROUND_W_S = ((1 << 3) + 4), 37844f0eee88ff00398ff7f715fab053374d808c90dSteve Block TRUNC_W_S = ((1 << 3) + 5), 37944f0eee88ff00398ff7f715fab053374d808c90dSteve Block CEIL_W_S = ((1 << 3) + 6), 38044f0eee88ff00398ff7f715fab053374d808c90dSteve Block FLOOR_W_S = ((1 << 3) + 7), 3813100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu CVT_D_S = ((4 << 3) + 1), 3823100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu CVT_W_S = ((4 << 3) + 4), 3833100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu CVT_L_S = ((4 << 3) + 5), 3843100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu CVT_PS_S = ((4 << 3) + 6), 3853100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // COP1 Encoding of Function Field When rs=D. 38644f0eee88ff00398ff7f715fab053374d808c90dSteve Block ADD_D = ((0 << 3) + 0), 38744f0eee88ff00398ff7f715fab053374d808c90dSteve Block SUB_D = ((0 << 3) + 1), 38844f0eee88ff00398ff7f715fab053374d808c90dSteve Block MUL_D = ((0 << 3) + 2), 38944f0eee88ff00398ff7f715fab053374d808c90dSteve Block DIV_D = ((0 << 3) + 3), 39044f0eee88ff00398ff7f715fab053374d808c90dSteve Block SQRT_D = ((0 << 3) + 4), 39144f0eee88ff00398ff7f715fab053374d808c90dSteve Block ABS_D = ((0 << 3) + 5), 39244f0eee88ff00398ff7f715fab053374d808c90dSteve Block MOV_D = ((0 << 3) + 6), 39344f0eee88ff00398ff7f715fab053374d808c90dSteve Block NEG_D = ((0 << 3) + 7), 39444f0eee88ff00398ff7f715fab053374d808c90dSteve Block ROUND_L_D = ((1 << 3) + 0), 39544f0eee88ff00398ff7f715fab053374d808c90dSteve Block TRUNC_L_D = ((1 << 3) + 1), 39644f0eee88ff00398ff7f715fab053374d808c90dSteve Block CEIL_L_D = ((1 << 3) + 2), 39744f0eee88ff00398ff7f715fab053374d808c90dSteve Block FLOOR_L_D = ((1 << 3) + 3), 39844f0eee88ff00398ff7f715fab053374d808c90dSteve Block ROUND_W_D = ((1 << 3) + 4), 39944f0eee88ff00398ff7f715fab053374d808c90dSteve Block TRUNC_W_D = ((1 << 3) + 5), 40044f0eee88ff00398ff7f715fab053374d808c90dSteve Block CEIL_W_D = ((1 << 3) + 6), 40144f0eee88ff00398ff7f715fab053374d808c90dSteve Block FLOOR_W_D = ((1 << 3) + 7), 4023100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu CVT_S_D = ((4 << 3) + 0), 4033100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu CVT_W_D = ((4 << 3) + 4), 4043100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu CVT_L_D = ((4 << 3) + 5), 40544f0eee88ff00398ff7f715fab053374d808c90dSteve Block C_F_D = ((6 << 3) + 0), 40644f0eee88ff00398ff7f715fab053374d808c90dSteve Block C_UN_D = ((6 << 3) + 1), 40744f0eee88ff00398ff7f715fab053374d808c90dSteve Block C_EQ_D = ((6 << 3) + 2), 40844f0eee88ff00398ff7f715fab053374d808c90dSteve Block C_UEQ_D = ((6 << 3) + 3), 40944f0eee88ff00398ff7f715fab053374d808c90dSteve Block C_OLT_D = ((6 << 3) + 4), 41044f0eee88ff00398ff7f715fab053374d808c90dSteve Block C_ULT_D = ((6 << 3) + 5), 41144f0eee88ff00398ff7f715fab053374d808c90dSteve Block C_OLE_D = ((6 << 3) + 6), 41244f0eee88ff00398ff7f715fab053374d808c90dSteve Block C_ULE_D = ((6 << 3) + 7), 4133100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // COP1 Encoding of Function Field When rs=W or L. 4143100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu CVT_S_W = ((4 << 3) + 0), 4153100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu CVT_D_W = ((4 << 3) + 1), 4163100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu CVT_S_L = ((4 << 3) + 0), 4173100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu CVT_D_L = ((4 << 3) + 1), 4183100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // COP1 Encoding of Function Field When rs=PS. 4193100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 4203100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu NULLSF = 0 4213100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}; 4223100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 4233100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 4243100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// ----- Emulated conditions. 4253100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// On MIPS we use this enum to abstract from conditionnal branch instructions. 4263100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// the 'U' prefix is used to specify unsigned comparisons. 4273100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuenum Condition { 4283100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Any value < 0 is considered no_condition. 42944f0eee88ff00398ff7f715fab053374d808c90dSteve Block kNoCondition = -1, 4303100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 4313100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu overflow = 0, 4323100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu no_overflow = 1, 4333100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Uless = 2, 4343100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Ugreater_equal= 3, 4353100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu equal = 4, 4363100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu not_equal = 5, 4373100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Uless_equal = 6, 4383100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Ugreater = 7, 4393100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu negative = 8, 4403100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu positive = 9, 4413100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu parity_even = 10, 4423100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu parity_odd = 11, 4433100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu less = 12, 4443100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu greater_equal = 13, 4453100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu less_equal = 14, 4463100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu greater = 15, 4473100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 4483100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu cc_always = 16, 4493100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 450257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Aliases. 4513100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu carry = Uless, 4523100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu not_carry = Ugreater_equal, 4533100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu zero = equal, 4543100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu eq = equal, 4553100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu not_zero = not_equal, 4563100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu ne = not_equal, 45744f0eee88ff00398ff7f715fab053374d808c90dSteve Block nz = not_equal, 4583100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu sign = negative, 4593100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu not_sign = positive, 46044f0eee88ff00398ff7f715fab053374d808c90dSteve Block mi = negative, 46144f0eee88ff00398ff7f715fab053374d808c90dSteve Block pl = positive, 46244f0eee88ff00398ff7f715fab053374d808c90dSteve Block hi = Ugreater, 46344f0eee88ff00398ff7f715fab053374d808c90dSteve Block ls = Uless_equal, 46444f0eee88ff00398ff7f715fab053374d808c90dSteve Block ge = greater_equal, 46544f0eee88ff00398ff7f715fab053374d808c90dSteve Block lt = less, 46644f0eee88ff00398ff7f715fab053374d808c90dSteve Block gt = greater, 46744f0eee88ff00398ff7f715fab053374d808c90dSteve Block le = less_equal, 46844f0eee88ff00398ff7f715fab053374d808c90dSteve Block hs = Ugreater_equal, 46944f0eee88ff00398ff7f715fab053374d808c90dSteve Block lo = Uless, 47044f0eee88ff00398ff7f715fab053374d808c90dSteve Block al = cc_always, 47144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 47244f0eee88ff00398ff7f715fab053374d808c90dSteve Block cc_default = kNoCondition 4733100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}; 4743100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 47544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 47644f0eee88ff00398ff7f715fab053374d808c90dSteve Block// Returns the equivalent of !cc. 47744f0eee88ff00398ff7f715fab053374d808c90dSteve Block// Negation of the default kNoCondition (-1) results in a non-default 47844f0eee88ff00398ff7f715fab053374d808c90dSteve Block// no_condition value (-2). As long as tests for no_condition check 47944f0eee88ff00398ff7f715fab053374d808c90dSteve Block// for condition < 0, this will work as expected. 48044f0eee88ff00398ff7f715fab053374d808c90dSteve Blockinline Condition NegateCondition(Condition cc) { 48144f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(cc != cc_always); 48244f0eee88ff00398ff7f715fab053374d808c90dSteve Block return static_cast<Condition>(cc ^ 1); 48344f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 48444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 48544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 48644f0eee88ff00398ff7f715fab053374d808c90dSteve Blockinline Condition ReverseCondition(Condition cc) { 48744f0eee88ff00398ff7f715fab053374d808c90dSteve Block switch (cc) { 48844f0eee88ff00398ff7f715fab053374d808c90dSteve Block case Uless: 48944f0eee88ff00398ff7f715fab053374d808c90dSteve Block return Ugreater; 49044f0eee88ff00398ff7f715fab053374d808c90dSteve Block case Ugreater: 49144f0eee88ff00398ff7f715fab053374d808c90dSteve Block return Uless; 49244f0eee88ff00398ff7f715fab053374d808c90dSteve Block case Ugreater_equal: 49344f0eee88ff00398ff7f715fab053374d808c90dSteve Block return Uless_equal; 49444f0eee88ff00398ff7f715fab053374d808c90dSteve Block case Uless_equal: 49544f0eee88ff00398ff7f715fab053374d808c90dSteve Block return Ugreater_equal; 49644f0eee88ff00398ff7f715fab053374d808c90dSteve Block case less: 49744f0eee88ff00398ff7f715fab053374d808c90dSteve Block return greater; 49844f0eee88ff00398ff7f715fab053374d808c90dSteve Block case greater: 49944f0eee88ff00398ff7f715fab053374d808c90dSteve Block return less; 50044f0eee88ff00398ff7f715fab053374d808c90dSteve Block case greater_equal: 50144f0eee88ff00398ff7f715fab053374d808c90dSteve Block return less_equal; 50244f0eee88ff00398ff7f715fab053374d808c90dSteve Block case less_equal: 50344f0eee88ff00398ff7f715fab053374d808c90dSteve Block return greater_equal; 50444f0eee88ff00398ff7f715fab053374d808c90dSteve Block default: 50544f0eee88ff00398ff7f715fab053374d808c90dSteve Block return cc; 50644f0eee88ff00398ff7f715fab053374d808c90dSteve Block }; 50744f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 50844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 50944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 5103100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// ----- Coprocessor conditions. 5113100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuenum FPUCondition { 512589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch kNoFPUCondition = -1, 513589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 514589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch F = 0, // False. 515589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch UN = 1, // Unordered. 516589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch EQ = 2, // Equal. 517589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch UEQ = 3, // Unordered or Equal. 518589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch OLT = 4, // Ordered or Less Than. 519589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch ULT = 5, // Unordered or Less Than. 520589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch OLE = 6, // Ordered or Less Than or Equal. 521589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch ULE = 7 // Unordered or Less Than or Equal. 522589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch}; 523589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 524589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 525589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch// FPU rounding modes. 526589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochenum FPURoundingMode { 527589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch RN = 0 << 0, // Round to Nearest. 528589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch RZ = 1 << 0, // Round towards zero. 529589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch RP = 2 << 0, // Round towards Plus Infinity. 530589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch RM = 3 << 0, // Round towards Minus Infinity. 531589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 532589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // Aliases. 533589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch kRoundToNearest = RN, 534589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch kRoundToZero = RZ, 535589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch kRoundToPlusInf = RP, 536589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch kRoundToMinusInf = RM 537589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch}; 538589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 5393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst uint32_t kFPURoundingModeMask = 3 << 0; 540589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 541589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochenum CheckForInexactConversion { 542589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch kCheckForInexactConversion, 543589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch kDontCheckForInexactConversion 5443100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}; 5453100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 5463100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 54744f0eee88ff00398ff7f715fab053374d808c90dSteve Block// ----------------------------------------------------------------------------- 54844f0eee88ff00398ff7f715fab053374d808c90dSteve Block// Hints. 54944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 55044f0eee88ff00398ff7f715fab053374d808c90dSteve Block// Branch hints are not used on the MIPS. They are defined so that they can 55144f0eee88ff00398ff7f715fab053374d808c90dSteve Block// appear in shared function signatures, but will be ignored in MIPS 55244f0eee88ff00398ff7f715fab053374d808c90dSteve Block// implementations. 55344f0eee88ff00398ff7f715fab053374d808c90dSteve Blockenum Hint { 55444f0eee88ff00398ff7f715fab053374d808c90dSteve Block no_hint = 0 55544f0eee88ff00398ff7f715fab053374d808c90dSteve Block}; 55644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 55744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 55844f0eee88ff00398ff7f715fab053374d808c90dSteve Blockinline Hint NegateHint(Hint hint) { 55944f0eee88ff00398ff7f715fab053374d808c90dSteve Block return no_hint; 56044f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 56144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 56244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 56344f0eee88ff00398ff7f715fab053374d808c90dSteve Block// ----------------------------------------------------------------------------- 56444f0eee88ff00398ff7f715fab053374d808c90dSteve Block// Specific instructions, constants, and masks. 56544f0eee88ff00398ff7f715fab053374d808c90dSteve Block// These constants are declared in assembler-mips.cc, as they use named 56644f0eee88ff00398ff7f715fab053374d808c90dSteve Block// registers and other constants. 56744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 56844f0eee88ff00398ff7f715fab053374d808c90dSteve Block// addiu(sp, sp, 4) aka Pop() operation or part of Pop(r) 56944f0eee88ff00398ff7f715fab053374d808c90dSteve Block// operations as post-increment of sp. 57044f0eee88ff00398ff7f715fab053374d808c90dSteve Blockextern const Instr kPopInstruction; 57144f0eee88ff00398ff7f715fab053374d808c90dSteve Block// addiu(sp, sp, -4) part of Push(r) operation as pre-decrement of sp. 57244f0eee88ff00398ff7f715fab053374d808c90dSteve Blockextern const Instr kPushInstruction; 57344f0eee88ff00398ff7f715fab053374d808c90dSteve Block// sw(r, MemOperand(sp, 0)) 57444f0eee88ff00398ff7f715fab053374d808c90dSteve Blockextern const Instr kPushRegPattern; 575257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// lw(r, MemOperand(sp, 0)) 57644f0eee88ff00398ff7f715fab053374d808c90dSteve Blockextern const Instr kPopRegPattern; 57744f0eee88ff00398ff7f715fab053374d808c90dSteve Blockextern const Instr kLwRegFpOffsetPattern; 57844f0eee88ff00398ff7f715fab053374d808c90dSteve Blockextern const Instr kSwRegFpOffsetPattern; 57944f0eee88ff00398ff7f715fab053374d808c90dSteve Blockextern const Instr kLwRegFpNegOffsetPattern; 58044f0eee88ff00398ff7f715fab053374d808c90dSteve Blockextern const Instr kSwRegFpNegOffsetPattern; 58144f0eee88ff00398ff7f715fab053374d808c90dSteve Block// A mask for the Rt register for push, pop, lw, sw instructions. 58244f0eee88ff00398ff7f715fab053374d808c90dSteve Blockextern const Instr kRtMask; 58344f0eee88ff00398ff7f715fab053374d808c90dSteve Blockextern const Instr kLwSwInstrTypeMask; 58444f0eee88ff00398ff7f715fab053374d808c90dSteve Blockextern const Instr kLwSwInstrArgumentMask; 58544f0eee88ff00398ff7f715fab053374d808c90dSteve Blockextern const Instr kLwSwOffsetMask; 58644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 5873100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// Break 0xfffff, reserved for redirected real time call. 5883100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuconst Instr rtCallRedirInstr = SPECIAL | BREAK | call_rt_redirected << 6; 5893100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// A nop instruction. (Encoding of sll 0 0 0). 5903100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuconst Instr nopInstr = 0; 5913100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 5923100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuclass Instruction { 5933100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu public: 5943100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu enum { 59544f0eee88ff00398ff7f715fab053374d808c90dSteve Block kInstrSize = 4, 59644f0eee88ff00398ff7f715fab053374d808c90dSteve Block kInstrSizeLog2 = 2, 5973100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // On MIPS PC cannot actually be directly accessed. We behave as if PC was 59844f0eee88ff00398ff7f715fab053374d808c90dSteve Block // always the value of the current instruction being executed. 5993100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu kPCReadOffset = 0 6003100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu }; 6013100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 6023100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Get the raw instruction bits. 6033100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu inline Instr InstructionBits() const { 6043100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu return *reinterpret_cast<const Instr*>(this); 6053100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 6063100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 6073100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Set the raw instruction bits to value. 6083100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu inline void SetInstructionBits(Instr value) { 6093100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu *reinterpret_cast<Instr*>(this) = value; 6103100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 6113100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 6123100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Read one particular bit out of the instruction bits. 6133100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu inline int Bit(int nr) const { 6143100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu return (InstructionBits() >> nr) & 1; 6153100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 6163100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 6173100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Read a bit field out of the instruction bits. 6183100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu inline int Bits(int hi, int lo) const { 6193100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu return (InstructionBits() >> lo) & ((2 << (hi - lo)) - 1); 6203100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 6213100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 6223100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Instruction type. 6233100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu enum Type { 6243100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu kRegisterType, 6253100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu kImmediateType, 6263100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu kJumpType, 6273100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu kUnsupported = -1 6283100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu }; 6293100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 6303100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Get the encoding type of the instruction. 6313100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Type InstructionType() const; 6323100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 6333100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 6343100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Accessors for the different named fields used in the MIPS encoding. 63544f0eee88ff00398ff7f715fab053374d808c90dSteve Block inline Opcode OpcodeValue() const { 6363100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu return static_cast<Opcode>( 6373100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Bits(kOpcodeShift + kOpcodeBits - 1, kOpcodeShift)); 6383100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 6393100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 64044f0eee88ff00398ff7f715fab053374d808c90dSteve Block inline int RsValue() const { 6413100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu ASSERT(InstructionType() == kRegisterType || 6423100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu InstructionType() == kImmediateType); 6433100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu return Bits(kRsShift + kRsBits - 1, kRsShift); 6443100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 6453100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 64644f0eee88ff00398ff7f715fab053374d808c90dSteve Block inline int RtValue() const { 6473100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu ASSERT(InstructionType() == kRegisterType || 6483100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu InstructionType() == kImmediateType); 6493100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu return Bits(kRtShift + kRtBits - 1, kRtShift); 6503100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 6513100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 65244f0eee88ff00398ff7f715fab053374d808c90dSteve Block inline int RdValue() const { 6533100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu ASSERT(InstructionType() == kRegisterType); 6543100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu return Bits(kRdShift + kRdBits - 1, kRdShift); 6553100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 6563100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 65744f0eee88ff00398ff7f715fab053374d808c90dSteve Block inline int SaValue() const { 6583100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu ASSERT(InstructionType() == kRegisterType); 6593100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu return Bits(kSaShift + kSaBits - 1, kSaShift); 6603100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 6613100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 66244f0eee88ff00398ff7f715fab053374d808c90dSteve Block inline int FunctionValue() const { 6633100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu ASSERT(InstructionType() == kRegisterType || 6643100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu InstructionType() == kImmediateType); 6653100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu return Bits(kFunctionShift + kFunctionBits - 1, kFunctionShift); 6663100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 6673100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 66844f0eee88ff00398ff7f715fab053374d808c90dSteve Block inline int FdValue() const { 66944f0eee88ff00398ff7f715fab053374d808c90dSteve Block return Bits(kFdShift + kFdBits - 1, kFdShift); 67044f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 67144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 67244f0eee88ff00398ff7f715fab053374d808c90dSteve Block inline int FsValue() const { 67344f0eee88ff00398ff7f715fab053374d808c90dSteve Block return Bits(kFsShift + kFsBits - 1, kFsShift); 67444f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 67544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 67644f0eee88ff00398ff7f715fab053374d808c90dSteve Block inline int FtValue() const { 67744f0eee88ff00398ff7f715fab053374d808c90dSteve Block return Bits(kFtShift + kFtBits - 1, kFtShift); 6783100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 6793100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 68044f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Float Compare condition code instruction bits. 68144f0eee88ff00398ff7f715fab053374d808c90dSteve Block inline int FCccValue() const { 68244f0eee88ff00398ff7f715fab053374d808c90dSteve Block return Bits(kFCccShift + kFCccBits - 1, kFCccShift); 68344f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 68444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 68544f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Float Branch condition code instruction bits. 68644f0eee88ff00398ff7f715fab053374d808c90dSteve Block inline int FBccValue() const { 68744f0eee88ff00398ff7f715fab053374d808c90dSteve Block return Bits(kFBccShift + kFBccBits - 1, kFBccShift); 68844f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 68944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 69044f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Float Branch true/false instruction bit. 69144f0eee88ff00398ff7f715fab053374d808c90dSteve Block inline int FBtrueValue() const { 69244f0eee88ff00398ff7f715fab053374d808c90dSteve Block return Bits(kFBtrueShift + kFBtrueBits - 1, kFBtrueShift); 6933100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 6943100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 6953100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Return the fields at their original place in the instruction encoding. 6963100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu inline Opcode OpcodeFieldRaw() const { 6973100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu return static_cast<Opcode>(InstructionBits() & kOpcodeMask); 6983100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 6993100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 7003100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu inline int RsFieldRaw() const { 7013100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu ASSERT(InstructionType() == kRegisterType || 7023100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu InstructionType() == kImmediateType); 7033100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu return InstructionBits() & kRsFieldMask; 7043100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 7053100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 70644f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Same as above function, but safe to call within InstructionType(). 70744f0eee88ff00398ff7f715fab053374d808c90dSteve Block inline int RsFieldRawNoAssert() const { 70844f0eee88ff00398ff7f715fab053374d808c90dSteve Block return InstructionBits() & kRsFieldMask; 70944f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 71044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 7113100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu inline int RtFieldRaw() const { 7123100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu ASSERT(InstructionType() == kRegisterType || 7133100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu InstructionType() == kImmediateType); 7143100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu return InstructionBits() & kRtFieldMask; 7153100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 7163100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 7173100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu inline int RdFieldRaw() const { 7183100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu ASSERT(InstructionType() == kRegisterType); 7193100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu return InstructionBits() & kRdFieldMask; 7203100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 7213100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 7223100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu inline int SaFieldRaw() const { 7233100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu ASSERT(InstructionType() == kRegisterType); 7243100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu return InstructionBits() & kSaFieldMask; 7253100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 7263100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 7273100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu inline int FunctionFieldRaw() const { 7283100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu return InstructionBits() & kFunctionFieldMask; 7293100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 7303100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 7313100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Get the secondary field according to the opcode. 73244f0eee88ff00398ff7f715fab053374d808c90dSteve Block inline int SecondaryValue() const { 7333100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Opcode op = OpcodeFieldRaw(); 7343100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu switch (op) { 7353100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu case SPECIAL: 7363100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu case SPECIAL2: 73744f0eee88ff00398ff7f715fab053374d808c90dSteve Block return FunctionValue(); 7383100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu case COP1: 73944f0eee88ff00398ff7f715fab053374d808c90dSteve Block return RsValue(); 7403100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu case REGIMM: 74144f0eee88ff00398ff7f715fab053374d808c90dSteve Block return RtValue(); 7423100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu default: 7433100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu return NULLSF; 7443100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 7453100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 7463100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 74744f0eee88ff00398ff7f715fab053374d808c90dSteve Block inline int32_t Imm16Value() const { 7483100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu ASSERT(InstructionType() == kImmediateType); 7493100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu return Bits(kImm16Shift + kImm16Bits - 1, kImm16Shift); 7503100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 7513100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 75244f0eee88ff00398ff7f715fab053374d808c90dSteve Block inline int32_t Imm26Value() const { 7533100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu ASSERT(InstructionType() == kJumpType); 754589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch return Bits(kImm26Shift + kImm26Bits - 1, kImm26Shift); 7553100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 7563100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 7573100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Say if the instruction should not be used in a branch delay slot. 75844f0eee88ff00398ff7f715fab053374d808c90dSteve Block bool IsForbiddenInBranchDelay() const; 7593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Say if the instruction 'links'. e.g. jal, bal. 76044f0eee88ff00398ff7f715fab053374d808c90dSteve Block bool IsLinkingInstruction() const; 7613100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Say if the instruction is a break or a trap. 76244f0eee88ff00398ff7f715fab053374d808c90dSteve Block bool IsTrap() const; 7633100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 7643100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Instructions are read of out a code stream. The only way to get a 7653100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // reference to an instruction is to convert a pointer. There is no way 7663100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // to allocate or create instances of class Instruction. 7673100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Use the At(pc) function to create references to Instruction. 768257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static Instruction* At(byte* pc) { 7693100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu return reinterpret_cast<Instruction*>(pc); 7703100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 7713100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 7723100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu private: 7733100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // We need to prevent the creation of instances of class Instruction. 7743100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu DISALLOW_IMPLICIT_CONSTRUCTORS(Instruction); 7753100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}; 7763100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 7773100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 7783100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// ----------------------------------------------------------------------------- 7793100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// MIPS assembly various constants. 7803100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 78144f0eee88ff00398ff7f715fab053374d808c90dSteve Block// C/C++ argument slots size. 7823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kCArgSlotCount = 4; 7833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kCArgsSlotsSize = kCArgSlotCount * Instruction::kInstrSize; 78444f0eee88ff00398ff7f715fab053374d808c90dSteve Block// JS argument slots size. 7853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kJSArgsSlotsSize = 0 * Instruction::kInstrSize; 78644f0eee88ff00398ff7f715fab053374d808c90dSteve Block// Assembly builtins argument slots size. 7873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kBArgsSlotsSize = 0 * Instruction::kInstrSize; 7883100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 7893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kBranchReturnOffset = 2 * Instruction::kInstrSize; 7903100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 7913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kDoubleAlignmentBits = 3; 7923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kDoubleAlignment = (1 << kDoubleAlignmentBits); 7933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kDoubleAlignmentMask = kDoubleAlignment - 1; 7943100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 7953100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 79644f0eee88ff00398ff7f715fab053374d808c90dSteve Block} } // namespace v8::internal 7973100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 7983100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu#endif // #ifndef V8_MIPS_CONSTANTS_H_ 799