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