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