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