• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  #include "src/base/logging.h"
9  #include "src/base/macros.h"
10  #include "src/globals.h"
11  
12  // UNIMPLEMENTED_ macro for MIPS.
13  #ifdef DEBUG
14  #define UNIMPLEMENTED_MIPS()                                                  \
15    v8::internal::PrintF("%s, \tline %d: \tfunction %s not implemented. \n",    \
16                         __FILE__, __LINE__, __func__)
17  #else
18  #define UNIMPLEMENTED_MIPS()
19  #endif
20  
21  #define UNSUPPORTED_MIPS() v8::internal::PrintF("Unsupported instruction.\n")
22  
23  enum ArchVariants {
24    kMips64r2,
25    kMips64r6
26  };
27  
28  
29  #ifdef _MIPS_ARCH_MIPS64R2
30    static const ArchVariants kArchVariant = kMips64r2;
31  #elif  _MIPS_ARCH_MIPS64R6
32    static const ArchVariants kArchVariant = kMips64r6;
33  #else
34    static const ArchVariants kArchVariant = kMips64r2;
35  #endif
36  
37  
38    enum Endianness { kLittle, kBig };
39  
40  #if defined(V8_TARGET_LITTLE_ENDIAN)
41    static const Endianness kArchEndian = kLittle;
42  #elif defined(V8_TARGET_BIG_ENDIAN)
43    static const Endianness kArchEndian = kBig;
44  #else
45  #error Unknown endianness
46  #endif
47  
48  // TODO(plind): consider deriving ABI from compiler flags or build system.
49  
50  // ABI-dependent definitions are made with #define in simulator-mips64.h,
51  // so the ABI choice must be available to the pre-processor. However, in all
52  // other cases, we should use the enum AbiVariants with normal if statements.
53  
54  #define MIPS_ABI_N64 1
55  // #define MIPS_ABI_O32 1
56  
57  // The only supported Abi's are O32, and n64.
58  enum AbiVariants {
59    kO32,
60    kN64  // Use upper case N for 'n64' ABI to conform to style standard.
61  };
62  
63  #ifdef MIPS_ABI_N64
64  static const AbiVariants kMipsAbi = kN64;
65  #else
66  static const AbiVariants kMipsAbi = kO32;
67  #endif
68  
69  
70  // TODO(plind): consider renaming these ...
71  #if(defined(__mips_hard_float) && __mips_hard_float != 0)
72  // Use floating-point coprocessor instructions. This flag is raised when
73  // -mhard-float is passed to the compiler.
74  const bool IsMipsSoftFloatABI = false;
75  #elif(defined(__mips_soft_float) && __mips_soft_float != 0)
76  // This flag is raised when -msoft-float is passed to the compiler.
77  // Although FPU is a base requirement for v8, soft-float ABI is used
78  // on soft-float systems with FPU kernel emulation.
79  const bool IsMipsSoftFloatABI = true;
80  #else
81  const bool IsMipsSoftFloatABI = true;
82  #endif
83  
84  
85  #ifndef __STDC_FORMAT_MACROS
86  #define __STDC_FORMAT_MACROS
87  #endif
88  #include <inttypes.h>
89  
90  
91  // Defines constants and accessor classes to assemble, disassemble and
92  // simulate MIPS32 instructions.
93  //
94  // See: MIPS32 Architecture For Programmers
95  //      Volume II: The MIPS32 Instruction Set
96  // Try www.cs.cornell.edu/courses/cs3410/2008fa/MIPS_Vol2.pdf.
97  
98  namespace v8 {
99  namespace internal {
100  
101  // -----------------------------------------------------------------------------
102  // Registers and FPURegisters.
103  
104  // Number of general purpose registers.
105  const int kNumRegisters = 32;
106  const int kInvalidRegister = -1;
107  
108  // Number of registers with HI, LO, and pc.
109  const int kNumSimuRegisters = 35;
110  
111  // In the simulator, the PC register is simulated as the 34th register.
112  const int kPCRegister = 34;
113  
114  // Number coprocessor registers.
115  const int kNumFPURegisters = 32;
116  const int kInvalidFPURegister = -1;
117  
118  // FPU (coprocessor 1) control registers. Currently only FCSR is implemented.
119  const int kFCSRRegister = 31;
120  const int kInvalidFPUControlRegister = -1;
121  const uint32_t kFPUInvalidResult = static_cast<uint32_t>(1 << 31) - 1;
122  const int32_t kFPUInvalidResultNegative = static_cast<int32_t>(1 << 31);
123  const uint64_t kFPU64InvalidResult =
124      static_cast<uint64_t>(static_cast<uint64_t>(1) << 63) - 1;
125  const int64_t kFPU64InvalidResultNegative =
126      static_cast<int64_t>(static_cast<uint64_t>(1) << 63);
127  
128  // FCSR constants.
129  const uint32_t kFCSRInexactFlagBit = 2;
130  const uint32_t kFCSRUnderflowFlagBit = 3;
131  const uint32_t kFCSROverflowFlagBit = 4;
132  const uint32_t kFCSRDivideByZeroFlagBit = 5;
133  const uint32_t kFCSRInvalidOpFlagBit = 6;
134  const uint32_t kFCSRNaN2008FlagBit = 18;
135  
136  const uint32_t kFCSRInexactFlagMask = 1 << kFCSRInexactFlagBit;
137  const uint32_t kFCSRUnderflowFlagMask = 1 << kFCSRUnderflowFlagBit;
138  const uint32_t kFCSROverflowFlagMask = 1 << kFCSROverflowFlagBit;
139  const uint32_t kFCSRDivideByZeroFlagMask = 1 << kFCSRDivideByZeroFlagBit;
140  const uint32_t kFCSRInvalidOpFlagMask = 1 << kFCSRInvalidOpFlagBit;
141  const uint32_t kFCSRNaN2008FlagMask = 1 << kFCSRNaN2008FlagBit;
142  
143  const uint32_t kFCSRFlagMask =
144      kFCSRInexactFlagMask |
145      kFCSRUnderflowFlagMask |
146      kFCSROverflowFlagMask |
147      kFCSRDivideByZeroFlagMask |
148      kFCSRInvalidOpFlagMask;
149  
150  const uint32_t kFCSRExceptionFlagMask = kFCSRFlagMask ^ kFCSRInexactFlagMask;
151  
152  // 'pref' instruction hints
153  const int32_t kPrefHintLoad = 0;
154  const int32_t kPrefHintStore = 1;
155  const int32_t kPrefHintLoadStreamed = 4;
156  const int32_t kPrefHintStoreStreamed = 5;
157  const int32_t kPrefHintLoadRetained = 6;
158  const int32_t kPrefHintStoreRetained = 7;
159  const int32_t kPrefHintWritebackInvalidate = 25;
160  const int32_t kPrefHintPrepareForStore = 30;
161  
162  // Helper functions for converting between register numbers and names.
163  class Registers {
164   public:
165    // Return the name of the register.
166    static const char* Name(int reg);
167  
168    // Lookup the register number for the name provided.
169    static int Number(const char* name);
170  
171    struct RegisterAlias {
172      int reg;
173      const char* name;
174    };
175  
176    static const int64_t kMaxValue = 0x7fffffffffffffffl;
177    static const int64_t kMinValue = 0x8000000000000000l;
178  
179   private:
180    static const char* names_[kNumSimuRegisters];
181    static const RegisterAlias aliases_[];
182  };
183  
184  // Helper functions for converting between register numbers and names.
185  class FPURegisters {
186   public:
187    // Return the name of the register.
188    static const char* Name(int reg);
189  
190    // Lookup the register number for the name provided.
191    static int Number(const char* name);
192  
193    struct RegisterAlias {
194      int creg;
195      const char* name;
196    };
197  
198   private:
199    static const char* names_[kNumFPURegisters];
200    static const RegisterAlias aliases_[];
201  };
202  
203  
204  // -----------------------------------------------------------------------------
205  // Instructions encoding constants.
206  
207  // On MIPS all instructions are 32 bits.
208  typedef int32_t Instr;
209  
210  // Special Software Interrupt codes when used in the presence of the MIPS
211  // simulator.
212  enum SoftwareInterruptCodes {
213    // Transition to C code.
214    call_rt_redirected = 0xfffff
215  };
216  
217  // On MIPS Simulator breakpoints can have different codes:
218  // - Breaks between 0 and kMaxWatchpointCode are treated as simple watchpoints,
219  //   the simulator will run through them and print the registers.
220  // - Breaks between kMaxWatchpointCode and kMaxStopCode are treated as stop()
221  //   instructions (see Assembler::stop()).
222  // - Breaks larger than kMaxStopCode are simple breaks, dropping you into the
223  //   debugger.
224  const uint32_t kMaxWatchpointCode = 31;
225  const uint32_t kMaxStopCode = 127;
226  STATIC_ASSERT(kMaxWatchpointCode < kMaxStopCode);
227  
228  
229  // ----- Fields offset and length.
230  const int kOpcodeShift   = 26;
231  const int kOpcodeBits    = 6;
232  const int kRsShift       = 21;
233  const int kRsBits        = 5;
234  const int kRtShift       = 16;
235  const int kRtBits        = 5;
236  const int kRdShift       = 11;
237  const int kRdBits        = 5;
238  const int kSaShift       = 6;
239  const int kSaBits        = 5;
240  const int kLsaSaBits = 2;
241  const int kFunctionShift = 0;
242  const int kFunctionBits  = 6;
243  const int kLuiShift      = 16;
244  const int kBp2Shift = 6;
245  const int kBp2Bits = 2;
246  const int kBp3Shift = 6;
247  const int kBp3Bits = 3;
248  
249  const int kImm16Shift = 0;
250  const int kImm16Bits  = 16;
251  const int kImm18Shift = 0;
252  const int kImm18Bits = 18;
253  const int kImm19Shift = 0;
254  const int kImm19Bits = 19;
255  const int kImm21Shift = 0;
256  const int kImm21Bits  = 21;
257  const int kImm26Shift = 0;
258  const int kImm26Bits  = 26;
259  const int kImm28Shift = 0;
260  const int kImm28Bits  = 28;
261  const int kImm32Shift = 0;
262  const int kImm32Bits  = 32;
263  
264  // In branches and jumps immediate fields point to words, not bytes,
265  // and are therefore shifted by 2.
266  const int kImmFieldShift = 2;
267  
268  const int kFrBits        = 5;
269  const int kFrShift       = 21;
270  const int kFsShift       = 11;
271  const int kFsBits        = 5;
272  const int kFtShift       = 16;
273  const int kFtBits        = 5;
274  const int kFdShift       = 6;
275  const int kFdBits        = 5;
276  const int kFCccShift     = 8;
277  const int kFCccBits      = 3;
278  const int kFBccShift     = 18;
279  const int kFBccBits      = 3;
280  const int kFBtrueShift   = 16;
281  const int kFBtrueBits    = 1;
282  
283  // ----- Miscellaneous useful masks.
284  // Instruction bit masks.
285  const int  kOpcodeMask   = ((1 << kOpcodeBits) - 1) << kOpcodeShift;
286  const int  kImm16Mask    = ((1 << kImm16Bits) - 1) << kImm16Shift;
287  const int kImm18Mask = ((1 << kImm18Bits) - 1) << kImm18Shift;
288  const int kImm19Mask = ((1 << kImm19Bits) - 1) << kImm19Shift;
289  const int kImm21Mask = ((1 << kImm21Bits) - 1) << kImm21Shift;
290  const int  kImm26Mask    = ((1 << kImm26Bits) - 1) << kImm26Shift;
291  const int  kImm28Mask    = ((1 << kImm28Bits) - 1) << kImm28Shift;
292  const int  kRsFieldMask  = ((1 << kRsBits) - 1) << kRsShift;
293  const int  kRtFieldMask  = ((1 << kRtBits) - 1) << kRtShift;
294  const int  kRdFieldMask  = ((1 << kRdBits) - 1) << kRdShift;
295  const int  kSaFieldMask  = ((1 << kSaBits) - 1) << kSaShift;
296  const int  kFunctionFieldMask = ((1 << kFunctionBits) - 1) << kFunctionShift;
297  // Misc masks.
298  const int  kHiMask       =   0xffff << 16;
299  const int  kLoMask       =   0xffff;
300  const int  kSignMask     =   0x80000000;
301  const int  kJumpAddrMask = (1 << (kImm26Bits + kImmFieldShift)) - 1;
302  const int64_t  kHi16MaskOf64 =   (int64_t)0xffff << 48;
303  const int64_t  kSe16MaskOf64 =   (int64_t)0xffff << 32;
304  const int64_t  kTh16MaskOf64 =   (int64_t)0xffff << 16;
305  const int32_t kJalRawMark = 0x00000000;
306  const int32_t kJRawMark = 0xf0000000;
307  const int32_t kJumpRawMask = 0xf0000000;
308  
309  // ----- MIPS Opcodes and Function Fields.
310  // We use this presentation to stay close to the table representation in
311  // MIPS32 Architecture For Programmers, Volume II: The MIPS32 Instruction Set.
312  enum Opcode : uint32_t {
313    SPECIAL = 0U << kOpcodeShift,
314    REGIMM = 1U << kOpcodeShift,
315  
316    J = ((0U << 3) + 2) << kOpcodeShift,
317    JAL = ((0U << 3) + 3) << kOpcodeShift,
318    BEQ = ((0U << 3) + 4) << kOpcodeShift,
319    BNE = ((0U << 3) + 5) << kOpcodeShift,
320    BLEZ = ((0U << 3) + 6) << kOpcodeShift,
321    BGTZ = ((0U << 3) + 7) << kOpcodeShift,
322  
323    ADDI = ((1U << 3) + 0) << kOpcodeShift,
324    ADDIU = ((1U << 3) + 1) << kOpcodeShift,
325    SLTI = ((1U << 3) + 2) << kOpcodeShift,
326    SLTIU = ((1U << 3) + 3) << kOpcodeShift,
327    ANDI = ((1U << 3) + 4) << kOpcodeShift,
328    ORI = ((1U << 3) + 5) << kOpcodeShift,
329    XORI = ((1U << 3) + 6) << kOpcodeShift,
330    LUI = ((1U << 3) + 7) << kOpcodeShift,  // LUI/AUI family.
331    DAUI = ((3U << 3) + 5) << kOpcodeShift,
332  
333    BEQC = ((2U << 3) + 0) << kOpcodeShift,
334    COP1 = ((2U << 3) + 1) << kOpcodeShift,  // Coprocessor 1 class.
335    BEQL = ((2U << 3) + 4) << kOpcodeShift,
336    BNEL = ((2U << 3) + 5) << kOpcodeShift,
337    BLEZL = ((2U << 3) + 6) << kOpcodeShift,
338    BGTZL = ((2U << 3) + 7) << kOpcodeShift,
339  
340    DADDI = ((3U << 3) + 0) << kOpcodeShift,  // This is also BNEC.
341    DADDIU = ((3U << 3) + 1) << kOpcodeShift,
342    LDL = ((3U << 3) + 2) << kOpcodeShift,
343    LDR = ((3U << 3) + 3) << kOpcodeShift,
344    SPECIAL2 = ((3U << 3) + 4) << kOpcodeShift,
345    SPECIAL3 = ((3U << 3) + 7) << kOpcodeShift,
346  
347    LB = ((4U << 3) + 0) << kOpcodeShift,
348    LH = ((4U << 3) + 1) << kOpcodeShift,
349    LWL = ((4U << 3) + 2) << kOpcodeShift,
350    LW = ((4U << 3) + 3) << kOpcodeShift,
351    LBU = ((4U << 3) + 4) << kOpcodeShift,
352    LHU = ((4U << 3) + 5) << kOpcodeShift,
353    LWR = ((4U << 3) + 6) << kOpcodeShift,
354    LWU = ((4U << 3) + 7) << kOpcodeShift,
355  
356    SB = ((5U << 3) + 0) << kOpcodeShift,
357    SH = ((5U << 3) + 1) << kOpcodeShift,
358    SWL = ((5U << 3) + 2) << kOpcodeShift,
359    SW = ((5U << 3) + 3) << kOpcodeShift,
360    SDL = ((5U << 3) + 4) << kOpcodeShift,
361    SDR = ((5U << 3) + 5) << kOpcodeShift,
362    SWR = ((5U << 3) + 6) << kOpcodeShift,
363  
364    LWC1 = ((6U << 3) + 1) << kOpcodeShift,
365    BC = ((6U << 3) + 2) << kOpcodeShift,
366    LLD = ((6U << 3) + 4) << kOpcodeShift,
367    LDC1 = ((6U << 3) + 5) << kOpcodeShift,
368    POP66 = ((6U << 3) + 6) << kOpcodeShift,
369    LD = ((6U << 3) + 7) << kOpcodeShift,
370  
371    PREF = ((6U << 3) + 3) << kOpcodeShift,
372  
373    SWC1 = ((7U << 3) + 1) << kOpcodeShift,
374    BALC = ((7U << 3) + 2) << kOpcodeShift,
375    PCREL = ((7U << 3) + 3) << kOpcodeShift,
376    SCD = ((7U << 3) + 4) << kOpcodeShift,
377    SDC1 = ((7U << 3) + 5) << kOpcodeShift,
378    POP76 = ((7U << 3) + 6) << kOpcodeShift,
379    SD = ((7U << 3) + 7) << kOpcodeShift,
380  
381    COP1X = ((1U << 4) + 3) << kOpcodeShift,
382  
383    // New r6 instruction.
384    POP06 = BLEZ,   // bgeuc/bleuc, blezalc, bgezalc
385    POP07 = BGTZ,   // bltuc/bgtuc, bgtzalc, bltzalc
386    POP10 = ADDI,   // beqzalc, bovc, beqc
387    POP26 = BLEZL,  // bgezc, blezc, bgec/blec
388    POP27 = BGTZL,  // bgtzc, bltzc, bltc/bgtc
389    POP30 = DADDI,  // bnezalc, bnvc, bnec
390  };
391  
392  enum SecondaryField : uint32_t {
393    // SPECIAL Encoding of Function Field.
394    SLL = ((0U << 3) + 0),
395    MOVCI = ((0U << 3) + 1),
396    SRL = ((0U << 3) + 2),
397    SRA = ((0U << 3) + 3),
398    SLLV = ((0U << 3) + 4),
399    LSA = ((0U << 3) + 5),
400    SRLV = ((0U << 3) + 6),
401    SRAV = ((0U << 3) + 7),
402  
403    JR = ((1U << 3) + 0),
404    JALR = ((1U << 3) + 1),
405    MOVZ = ((1U << 3) + 2),
406    MOVN = ((1U << 3) + 3),
407    BREAK = ((1U << 3) + 5),
408  
409    MFHI = ((2U << 3) + 0),
410    CLZ_R6 = ((2U << 3) + 0),
411    CLO_R6 = ((2U << 3) + 1),
412    MFLO = ((2U << 3) + 2),
413    DCLZ_R6 = ((2U << 3) + 2),
414    DCLO_R6 = ((2U << 3) + 3),
415    DSLLV = ((2U << 3) + 4),
416    DLSA = ((2U << 3) + 5),
417    DSRLV = ((2U << 3) + 6),
418    DSRAV = ((2U << 3) + 7),
419  
420    MULT = ((3U << 3) + 0),
421    MULTU = ((3U << 3) + 1),
422    DIV = ((3U << 3) + 2),
423    DIVU = ((3U << 3) + 3),
424    DMULT = ((3U << 3) + 4),
425    DMULTU = ((3U << 3) + 5),
426    DDIV = ((3U << 3) + 6),
427    DDIVU = ((3U << 3) + 7),
428  
429    ADD = ((4U << 3) + 0),
430    ADDU = ((4U << 3) + 1),
431    SUB = ((4U << 3) + 2),
432    SUBU = ((4U << 3) + 3),
433    AND = ((4U << 3) + 4),
434    OR = ((4U << 3) + 5),
435    XOR = ((4U << 3) + 6),
436    NOR = ((4U << 3) + 7),
437  
438    SLT = ((5U << 3) + 2),
439    SLTU = ((5U << 3) + 3),
440    DADD = ((5U << 3) + 4),
441    DADDU = ((5U << 3) + 5),
442    DSUB = ((5U << 3) + 6),
443    DSUBU = ((5U << 3) + 7),
444  
445    TGE = ((6U << 3) + 0),
446    TGEU = ((6U << 3) + 1),
447    TLT = ((6U << 3) + 2),
448    TLTU = ((6U << 3) + 3),
449    TEQ = ((6U << 3) + 4),
450    SELEQZ_S = ((6U << 3) + 5),
451    TNE = ((6U << 3) + 6),
452    SELNEZ_S = ((6U << 3) + 7),
453  
454    DSLL = ((7U << 3) + 0),
455    DSRL = ((7U << 3) + 2),
456    DSRA = ((7U << 3) + 3),
457    DSLL32 = ((7U << 3) + 4),
458    DSRL32 = ((7U << 3) + 6),
459    DSRA32 = ((7U << 3) + 7),
460  
461    // Multiply integers in r6.
462    MUL_MUH = ((3U << 3) + 0),      // MUL, MUH.
463    MUL_MUH_U = ((3U << 3) + 1),    // MUL_U, MUH_U.
464    D_MUL_MUH = ((7U << 2) + 0),    // DMUL, DMUH.
465    D_MUL_MUH_U = ((7U << 2) + 1),  // DMUL_U, DMUH_U.
466    RINT = ((3U << 3) + 2),
467  
468    MUL_OP = ((0U << 3) + 2),
469    MUH_OP = ((0U << 3) + 3),
470    DIV_OP = ((0U << 3) + 2),
471    MOD_OP = ((0U << 3) + 3),
472  
473    DIV_MOD = ((3U << 3) + 2),
474    DIV_MOD_U = ((3U << 3) + 3),
475    D_DIV_MOD = ((3U << 3) + 6),
476    D_DIV_MOD_U = ((3U << 3) + 7),
477  
478    // drotr in special4?
479  
480    // SPECIAL2 Encoding of Function Field.
481    MUL = ((0U << 3) + 2),
482    CLZ = ((4U << 3) + 0),
483    CLO = ((4U << 3) + 1),
484    DCLZ = ((4U << 3) + 4),
485    DCLO = ((4U << 3) + 5),
486  
487    // SPECIAL3 Encoding of Function Field.
488    EXT = ((0U << 3) + 0),
489    DEXTM = ((0U << 3) + 1),
490    DEXTU = ((0U << 3) + 2),
491    DEXT = ((0U << 3) + 3),
492    INS = ((0U << 3) + 4),
493    DINSM = ((0U << 3) + 5),
494    DINSU = ((0U << 3) + 6),
495    DINS = ((0U << 3) + 7),
496  
497    BSHFL = ((4U << 3) + 0),
498    DBSHFL = ((4U << 3) + 4),
499  
500    // SPECIAL3 Encoding of sa Field.
501    BITSWAP = ((0U << 3) + 0),
502    ALIGN = ((0U << 3) + 2),
503    WSBH = ((0U << 3) + 2),
504    SEB = ((2U << 3) + 0),
505    SEH = ((3U << 3) + 0),
506  
507    DBITSWAP = ((0U << 3) + 0),
508    DALIGN = ((0U << 3) + 1),
509    DBITSWAP_SA = ((0U << 3) + 0) << kSaShift,
510    DSBH = ((0U << 3) + 2),
511    DSHD = ((0U << 3) + 5),
512  
513    // REGIMM  encoding of rt Field.
514    BLTZ = ((0U << 3) + 0) << 16,
515    BGEZ = ((0U << 3) + 1) << 16,
516    BLTZAL = ((2U << 3) + 0) << 16,
517    BGEZAL = ((2U << 3) + 1) << 16,
518    BGEZALL = ((2U << 3) + 3) << 16,
519    DAHI = ((0U << 3) + 6) << 16,
520    DATI = ((3U << 3) + 6) << 16,
521  
522    // COP1 Encoding of rs Field.
523    MFC1 = ((0U << 3) + 0) << 21,
524    DMFC1 = ((0U << 3) + 1) << 21,
525    CFC1 = ((0U << 3) + 2) << 21,
526    MFHC1 = ((0U << 3) + 3) << 21,
527    MTC1 = ((0U << 3) + 4) << 21,
528    DMTC1 = ((0U << 3) + 5) << 21,
529    CTC1 = ((0U << 3) + 6) << 21,
530    MTHC1 = ((0U << 3) + 7) << 21,
531    BC1 = ((1U << 3) + 0) << 21,
532    S = ((2U << 3) + 0) << 21,
533    D = ((2U << 3) + 1) << 21,
534    W = ((2U << 3) + 4) << 21,
535    L = ((2U << 3) + 5) << 21,
536    PS = ((2U << 3) + 6) << 21,
537    // COP1 Encoding of Function Field When rs=S.
538  
539    ADD_S = ((0U << 3) + 0),
540    SUB_S = ((0U << 3) + 1),
541    MUL_S = ((0U << 3) + 2),
542    DIV_S = ((0U << 3) + 3),
543    ABS_S = ((0U << 3) + 5),
544    SQRT_S = ((0U << 3) + 4),
545    MOV_S = ((0U << 3) + 6),
546    NEG_S = ((0U << 3) + 7),
547    ROUND_L_S = ((1U << 3) + 0),
548    TRUNC_L_S = ((1U << 3) + 1),
549    CEIL_L_S = ((1U << 3) + 2),
550    FLOOR_L_S = ((1U << 3) + 3),
551    ROUND_W_S = ((1U << 3) + 4),
552    TRUNC_W_S = ((1U << 3) + 5),
553    CEIL_W_S = ((1U << 3) + 6),
554    FLOOR_W_S = ((1U << 3) + 7),
555    RECIP_S = ((2U << 3) + 5),
556    RSQRT_S = ((2U << 3) + 6),
557    CLASS_S = ((3U << 3) + 3),
558    CVT_D_S = ((4U << 3) + 1),
559    CVT_W_S = ((4U << 3) + 4),
560    CVT_L_S = ((4U << 3) + 5),
561    CVT_PS_S = ((4U << 3) + 6),
562    // COP1 Encoding of Function Field When rs=D.
563    ADD_D = ((0U << 3) + 0),
564    SUB_D = ((0U << 3) + 1),
565    MUL_D = ((0U << 3) + 2),
566    DIV_D = ((0U << 3) + 3),
567    SQRT_D = ((0U << 3) + 4),
568    ABS_D = ((0U << 3) + 5),
569    MOV_D = ((0U << 3) + 6),
570    NEG_D = ((0U << 3) + 7),
571    ROUND_L_D = ((1U << 3) + 0),
572    TRUNC_L_D = ((1U << 3) + 1),
573    CEIL_L_D = ((1U << 3) + 2),
574    FLOOR_L_D = ((1U << 3) + 3),
575    ROUND_W_D = ((1U << 3) + 4),
576    TRUNC_W_D = ((1U << 3) + 5),
577    CEIL_W_D = ((1U << 3) + 6),
578    FLOOR_W_D = ((1U << 3) + 7),
579    RECIP_D = ((2U << 3) + 5),
580    RSQRT_D = ((2U << 3) + 6),
581    CLASS_D = ((3U << 3) + 3),
582    MIN = ((3U << 3) + 4),
583    MINA = ((3U << 3) + 5),
584    MAX = ((3U << 3) + 6),
585    MAXA = ((3U << 3) + 7),
586    CVT_S_D = ((4U << 3) + 0),
587    CVT_W_D = ((4U << 3) + 4),
588    CVT_L_D = ((4U << 3) + 5),
589    C_F_D = ((6U << 3) + 0),
590    C_UN_D = ((6U << 3) + 1),
591    C_EQ_D = ((6U << 3) + 2),
592    C_UEQ_D = ((6U << 3) + 3),
593    C_OLT_D = ((6U << 3) + 4),
594    C_ULT_D = ((6U << 3) + 5),
595    C_OLE_D = ((6U << 3) + 6),
596    C_ULE_D = ((6U << 3) + 7),
597  
598    // COP1 Encoding of Function Field When rs=W or L.
599    CVT_S_W = ((4U << 3) + 0),
600    CVT_D_W = ((4U << 3) + 1),
601    CVT_S_L = ((4U << 3) + 0),
602    CVT_D_L = ((4U << 3) + 1),
603    BC1EQZ = ((2U << 2) + 1) << 21,
604    BC1NEZ = ((3U << 2) + 1) << 21,
605    // COP1 CMP positive predicates Bit 5..4 = 00.
606    CMP_AF = ((0U << 3) + 0),
607    CMP_UN = ((0U << 3) + 1),
608    CMP_EQ = ((0U << 3) + 2),
609    CMP_UEQ = ((0U << 3) + 3),
610    CMP_LT = ((0U << 3) + 4),
611    CMP_ULT = ((0U << 3) + 5),
612    CMP_LE = ((0U << 3) + 6),
613    CMP_ULE = ((0U << 3) + 7),
614    CMP_SAF = ((1U << 3) + 0),
615    CMP_SUN = ((1U << 3) + 1),
616    CMP_SEQ = ((1U << 3) + 2),
617    CMP_SUEQ = ((1U << 3) + 3),
618    CMP_SSLT = ((1U << 3) + 4),
619    CMP_SSULT = ((1U << 3) + 5),
620    CMP_SLE = ((1U << 3) + 6),
621    CMP_SULE = ((1U << 3) + 7),
622    // COP1 CMP negative predicates Bit 5..4 = 01.
623    CMP_AT = ((2U << 3) + 0),  // Reserved, not implemented.
624    CMP_OR = ((2U << 3) + 1),
625    CMP_UNE = ((2U << 3) + 2),
626    CMP_NE = ((2U << 3) + 3),
627    CMP_UGE = ((2U << 3) + 4),  // Reserved, not implemented.
628    CMP_OGE = ((2U << 3) + 5),  // Reserved, not implemented.
629    CMP_UGT = ((2U << 3) + 6),  // Reserved, not implemented.
630    CMP_OGT = ((2U << 3) + 7),  // Reserved, not implemented.
631    CMP_SAT = ((3U << 3) + 0),  // Reserved, not implemented.
632    CMP_SOR = ((3U << 3) + 1),
633    CMP_SUNE = ((3U << 3) + 2),
634    CMP_SNE = ((3U << 3) + 3),
635    CMP_SUGE = ((3U << 3) + 4),  // Reserved, not implemented.
636    CMP_SOGE = ((3U << 3) + 5),  // Reserved, not implemented.
637    CMP_SUGT = ((3U << 3) + 6),  // Reserved, not implemented.
638    CMP_SOGT = ((3U << 3) + 7),  // Reserved, not implemented.
639  
640    SEL = ((2U << 3) + 0),
641    MOVF = ((2U << 3) + 1),      // Function field for MOVT.fmt and MOVF.fmt
642    MOVZ_C = ((2U << 3) + 2),    // COP1 on FPR registers.
643    MOVN_C = ((2U << 3) + 3),    // COP1 on FPR registers.
644    SELEQZ_C = ((2U << 3) + 4),  // COP1 on FPR registers.
645    SELNEZ_C = ((2U << 3) + 7),  // COP1 on FPR registers.
646  
647    // COP1 Encoding of Function Field When rs=PS.
648    // COP1X Encoding of Function Field.
649    MADD_D = ((4U << 3) + 1),
650  
651    // PCREL Encoding of rt Field.
652    ADDIUPC = ((0U << 2) + 0),
653    LWPC = ((0U << 2) + 1),
654    LWUPC = ((0U << 2) + 2),
655    LDPC = ((0U << 3) + 6),
656    // reserved ((1U << 3) + 6),
657    AUIPC = ((3U << 3) + 6),
658    ALUIPC = ((3U << 3) + 7),
659  
660    // POP66 Encoding of rs Field.
661    JIC = ((0U << 5) + 0),
662  
663    // POP76 Encoding of rs Field.
664    JIALC = ((0U << 5) + 0),
665  
666    NULLSF = 0U
667  };
668  
669  
670  // ----- Emulated conditions.
671  // On MIPS we use this enum to abstract from conditional branch instructions.
672  // The 'U' prefix is used to specify unsigned comparisons.
673  // Opposite conditions must be paired as odd/even numbers
674  // because 'NegateCondition' function flips LSB to negate condition.
675  enum Condition {
676    // Any value < 0 is considered no_condition.
677    kNoCondition = -1,
678    overflow = 0,
679    no_overflow = 1,
680    Uless = 2,
681    Ugreater_equal = 3,
682    Uless_equal = 4,
683    Ugreater = 5,
684    equal = 6,
685    not_equal = 7,  // Unordered or Not Equal.
686    negative = 8,
687    positive = 9,
688    parity_even = 10,
689    parity_odd = 11,
690    less = 12,
691    greater_equal = 13,
692    less_equal = 14,
693    greater = 15,
694    ueq = 16,  // Unordered or Equal.
695    ogl = 17,  // Ordered and Not Equal.
696    cc_always = 18,
697  
698    // Aliases.
699    carry = Uless,
700    not_carry = Ugreater_equal,
701    zero = equal,
702    eq = equal,
703    not_zero = not_equal,
704    ne = not_equal,
705    nz = not_equal,
706    sign = negative,
707    not_sign = positive,
708    mi = negative,
709    pl = positive,
710    hi = Ugreater,
711    ls = Uless_equal,
712    ge = greater_equal,
713    lt = less,
714    gt = greater,
715    le = less_equal,
716    hs = Ugreater_equal,
717    lo = Uless,
718    al = cc_always,
719    ult = Uless,
720    uge = Ugreater_equal,
721    ule = Uless_equal,
722    ugt = Ugreater,
723    cc_default = kNoCondition
724  };
725  
726  
727  // Returns the equivalent of !cc.
728  // Negation of the default kNoCondition (-1) results in a non-default
729  // no_condition value (-2). As long as tests for no_condition check
730  // for condition < 0, this will work as expected.
NegateCondition(Condition cc)731  inline Condition NegateCondition(Condition cc) {
732    DCHECK(cc != cc_always);
733    return static_cast<Condition>(cc ^ 1);
734  }
735  
736  
NegateFpuCondition(Condition cc)737  inline Condition NegateFpuCondition(Condition cc) {
738    DCHECK(cc != cc_always);
739    switch (cc) {
740      case ult:
741        return ge;
742      case ugt:
743        return le;
744      case uge:
745        return lt;
746      case ule:
747        return gt;
748      case lt:
749        return uge;
750      case gt:
751        return ule;
752      case ge:
753        return ult;
754      case le:
755        return ugt;
756      case eq:
757        return ne;
758      case ne:
759        return eq;
760      case ueq:
761        return ogl;
762      case ogl:
763        return ueq;
764      default:
765        return cc;
766    }
767  }
768  
769  
770  // Commute a condition such that {a cond b == b cond' a}.
CommuteCondition(Condition cc)771  inline Condition CommuteCondition(Condition cc) {
772    switch (cc) {
773      case Uless:
774        return Ugreater;
775      case Ugreater:
776        return Uless;
777      case Ugreater_equal:
778        return Uless_equal;
779      case Uless_equal:
780        return Ugreater_equal;
781      case less:
782        return greater;
783      case greater:
784        return less;
785      case greater_equal:
786        return less_equal;
787      case less_equal:
788        return greater_equal;
789      default:
790        return cc;
791    }
792  }
793  
794  
795  // ----- Coprocessor conditions.
796  enum FPUCondition {
797    kNoFPUCondition = -1,
798  
799    F = 0x00,    // False.
800    UN = 0x01,   // Unordered.
801    EQ = 0x02,   // Equal.
802    UEQ = 0x03,  // Unordered or Equal.
803    OLT = 0x04,  // Ordered or Less Than, on Mips release < 6.
804    LT = 0x04,   // Ordered or Less Than, on Mips release >= 6.
805    ULT = 0x05,  // Unordered or Less Than.
806    OLE = 0x06,  // Ordered or Less Than or Equal, on Mips release < 6.
807    LE = 0x06,   // Ordered or Less Than or Equal, on Mips release >= 6.
808    ULE = 0x07,  // Unordered or Less Than or Equal.
809  
810    // Following constants are available on Mips release >= 6 only.
811    ORD = 0x11,  // Ordered, on Mips release >= 6.
812    UNE = 0x12,  // Not equal, on Mips release >= 6.
813    NE = 0x13,   // Ordered Greater Than or Less Than. on Mips >= 6 only.
814  };
815  
816  
817  // FPU rounding modes.
818  enum FPURoundingMode {
819    RN = 0 << 0,  // Round to Nearest.
820    RZ = 1 << 0,  // Round towards zero.
821    RP = 2 << 0,  // Round towards Plus Infinity.
822    RM = 3 << 0,  // Round towards Minus Infinity.
823  
824    // Aliases.
825    kRoundToNearest = RN,
826    kRoundToZero = RZ,
827    kRoundToPlusInf = RP,
828    kRoundToMinusInf = RM,
829  
830    mode_round = RN,
831    mode_ceil = RP,
832    mode_floor = RM,
833    mode_trunc = RZ
834  };
835  
836  const uint32_t kFPURoundingModeMask = 3 << 0;
837  
838  enum CheckForInexactConversion {
839    kCheckForInexactConversion,
840    kDontCheckForInexactConversion
841  };
842  
843  
844  // -----------------------------------------------------------------------------
845  // Hints.
846  
847  // Branch hints are not used on the MIPS.  They are defined so that they can
848  // appear in shared function signatures, but will be ignored in MIPS
849  // implementations.
850  enum Hint {
851    no_hint = 0
852  };
853  
854  
NegateHint(Hint hint)855  inline Hint NegateHint(Hint hint) {
856    return no_hint;
857  }
858  
859  
860  // -----------------------------------------------------------------------------
861  // Specific instructions, constants, and masks.
862  // These constants are declared in assembler-mips.cc, as they use named
863  // registers and other constants.
864  
865  // addiu(sp, sp, 4) aka Pop() operation or part of Pop(r)
866  // operations as post-increment of sp.
867  extern const Instr kPopInstruction;
868  // addiu(sp, sp, -4) part of Push(r) operation as pre-decrement of sp.
869  extern const Instr kPushInstruction;
870  // sw(r, MemOperand(sp, 0))
871  extern const Instr kPushRegPattern;
872  // lw(r, MemOperand(sp, 0))
873  extern const Instr kPopRegPattern;
874  extern const Instr kLwRegFpOffsetPattern;
875  extern const Instr kSwRegFpOffsetPattern;
876  extern const Instr kLwRegFpNegOffsetPattern;
877  extern const Instr kSwRegFpNegOffsetPattern;
878  // A mask for the Rt register for push, pop, lw, sw instructions.
879  extern const Instr kRtMask;
880  extern const Instr kLwSwInstrTypeMask;
881  extern const Instr kLwSwInstrArgumentMask;
882  extern const Instr kLwSwOffsetMask;
883  
884  // Break 0xfffff, reserved for redirected real time call.
885  const Instr rtCallRedirInstr = SPECIAL | BREAK | call_rt_redirected << 6;
886  // A nop instruction. (Encoding of sll 0 0 0).
887  const Instr nopInstr = 0;
888  
OpcodeToBitNumber(Opcode opcode)889  static constexpr uint64_t OpcodeToBitNumber(Opcode opcode) {
890    return 1ULL << (static_cast<uint32_t>(opcode) >> kOpcodeShift);
891  }
892  
893  
894  class Instruction {
895   public:
896    enum {
897      kInstrSize = 4,
898      kInstrSizeLog2 = 2,
899      // On MIPS PC cannot actually be directly accessed. We behave as if PC was
900      // always the value of the current instruction being executed.
901      kPCReadOffset = 0
902    };
903  
904    // Get the raw instruction bits.
InstructionBits()905    inline Instr InstructionBits() const {
906      return *reinterpret_cast<const Instr*>(this);
907    }
908  
909    // Set the raw instruction bits to value.
SetInstructionBits(Instr value)910    inline void SetInstructionBits(Instr value) {
911      *reinterpret_cast<Instr*>(this) = value;
912    }
913  
914    // Read one particular bit out of the instruction bits.
Bit(int nr)915    inline int Bit(int nr) const {
916      return (InstructionBits() >> nr) & 1;
917    }
918  
919    // Read a bit field out of the instruction bits.
Bits(int hi,int lo)920    inline int Bits(int hi, int lo) const {
921      return (InstructionBits() >> lo) & ((2U << (hi - lo)) - 1);
922    }
923  
924    // Instruction type.
925    enum Type {
926      kRegisterType,
927      kImmediateType,
928      kJumpType,
929      kUnsupported = -1
930    };
931  
932    enum TypeChecks { NORMAL, EXTRA };
933  
934  
935    static constexpr uint64_t kOpcodeImmediateTypeMask =
936        OpcodeToBitNumber(REGIMM) | OpcodeToBitNumber(BEQ) |
937        OpcodeToBitNumber(BNE) | OpcodeToBitNumber(BLEZ) |
938        OpcodeToBitNumber(BGTZ) | OpcodeToBitNumber(ADDI) |
939        OpcodeToBitNumber(DADDI) | OpcodeToBitNumber(ADDIU) |
940        OpcodeToBitNumber(DADDIU) | OpcodeToBitNumber(SLTI) |
941        OpcodeToBitNumber(SLTIU) | OpcodeToBitNumber(ANDI) |
942        OpcodeToBitNumber(ORI) | OpcodeToBitNumber(XORI) |
943        OpcodeToBitNumber(LUI) | OpcodeToBitNumber(BEQL) |
944        OpcodeToBitNumber(BNEL) | OpcodeToBitNumber(BLEZL) |
945        OpcodeToBitNumber(BGTZL) | OpcodeToBitNumber(POP66) |
946        OpcodeToBitNumber(POP76) | OpcodeToBitNumber(LB) | OpcodeToBitNumber(LH) |
947        OpcodeToBitNumber(LWL) | OpcodeToBitNumber(LW) | OpcodeToBitNumber(LWU) |
948        OpcodeToBitNumber(LD) | OpcodeToBitNumber(LBU) | OpcodeToBitNumber(LHU) |
949        OpcodeToBitNumber(LWR) | OpcodeToBitNumber(SB) | OpcodeToBitNumber(SH) |
950        OpcodeToBitNumber(SWL) | OpcodeToBitNumber(SW) | OpcodeToBitNumber(SD) |
951        OpcodeToBitNumber(SWR) | OpcodeToBitNumber(LWC1) |
952        OpcodeToBitNumber(LDC1) | OpcodeToBitNumber(SWC1) |
953        OpcodeToBitNumber(SDC1) | OpcodeToBitNumber(PCREL) |
954        OpcodeToBitNumber(DAUI) | OpcodeToBitNumber(BC) | OpcodeToBitNumber(BALC);
955  
956  #define FunctionFieldToBitNumber(function) (1ULL << function)
957  
958    // On r6, DCLZ_R6 aliases to existing MFLO.
959    static const uint64_t kFunctionFieldRegisterTypeMask =
960        FunctionFieldToBitNumber(JR) | FunctionFieldToBitNumber(JALR) |
961        FunctionFieldToBitNumber(BREAK) | FunctionFieldToBitNumber(SLL) |
962        FunctionFieldToBitNumber(DSLL) | FunctionFieldToBitNumber(DSLL32) |
963        FunctionFieldToBitNumber(SRL) | FunctionFieldToBitNumber(DSRL) |
964        FunctionFieldToBitNumber(DSRL32) | FunctionFieldToBitNumber(SRA) |
965        FunctionFieldToBitNumber(DSRA) | FunctionFieldToBitNumber(DSRA32) |
966        FunctionFieldToBitNumber(SLLV) | FunctionFieldToBitNumber(DSLLV) |
967        FunctionFieldToBitNumber(SRLV) | FunctionFieldToBitNumber(DSRLV) |
968        FunctionFieldToBitNumber(SRAV) | FunctionFieldToBitNumber(DSRAV) |
969        FunctionFieldToBitNumber(LSA) | FunctionFieldToBitNumber(DLSA) |
970        FunctionFieldToBitNumber(MFHI) | FunctionFieldToBitNumber(MFLO) |
971        FunctionFieldToBitNumber(MULT) | FunctionFieldToBitNumber(DMULT) |
972        FunctionFieldToBitNumber(MULTU) | FunctionFieldToBitNumber(DMULTU) |
973        FunctionFieldToBitNumber(DIV) | FunctionFieldToBitNumber(DDIV) |
974        FunctionFieldToBitNumber(DIVU) | FunctionFieldToBitNumber(DDIVU) |
975        FunctionFieldToBitNumber(ADD) | FunctionFieldToBitNumber(DADD) |
976        FunctionFieldToBitNumber(ADDU) | FunctionFieldToBitNumber(DADDU) |
977        FunctionFieldToBitNumber(SUB) | FunctionFieldToBitNumber(DSUB) |
978        FunctionFieldToBitNumber(SUBU) | FunctionFieldToBitNumber(DSUBU) |
979        FunctionFieldToBitNumber(AND) | FunctionFieldToBitNumber(OR) |
980        FunctionFieldToBitNumber(XOR) | FunctionFieldToBitNumber(NOR) |
981        FunctionFieldToBitNumber(SLT) | FunctionFieldToBitNumber(SLTU) |
982        FunctionFieldToBitNumber(TGE) | FunctionFieldToBitNumber(TGEU) |
983        FunctionFieldToBitNumber(TLT) | FunctionFieldToBitNumber(TLTU) |
984        FunctionFieldToBitNumber(TEQ) | FunctionFieldToBitNumber(TNE) |
985        FunctionFieldToBitNumber(MOVZ) | FunctionFieldToBitNumber(MOVN) |
986        FunctionFieldToBitNumber(MOVCI) | FunctionFieldToBitNumber(SELEQZ_S) |
987        FunctionFieldToBitNumber(SELNEZ_S);
988  
989  
990    // Get the encoding type of the instruction.
991    inline Type InstructionType(TypeChecks checks = NORMAL) const;
992  
993  
994    // Accessors for the different named fields used in the MIPS encoding.
OpcodeValue()995    inline Opcode OpcodeValue() const {
996      return static_cast<Opcode>(
997          Bits(kOpcodeShift + kOpcodeBits - 1, kOpcodeShift));
998    }
999  
RsValue()1000    inline int RsValue() const {
1001      DCHECK(InstructionType() == kRegisterType ||
1002             InstructionType() == kImmediateType);
1003      return Bits(kRsShift + kRsBits - 1, kRsShift);
1004    }
1005  
RtValue()1006    inline int RtValue() const {
1007      DCHECK(InstructionType() == kRegisterType ||
1008             InstructionType() == kImmediateType);
1009      return Bits(kRtShift + kRtBits - 1, kRtShift);
1010    }
1011  
RdValue()1012    inline int RdValue() const {
1013      DCHECK(InstructionType() == kRegisterType);
1014      return Bits(kRdShift + kRdBits - 1, kRdShift);
1015    }
1016  
SaValue()1017    inline int SaValue() const {
1018      DCHECK(InstructionType() == kRegisterType);
1019      return Bits(kSaShift + kSaBits - 1, kSaShift);
1020    }
1021  
LsaSaValue()1022    inline int LsaSaValue() const {
1023      DCHECK(InstructionType() == kRegisterType);
1024      return Bits(kSaShift + kLsaSaBits - 1, kSaShift);
1025    }
1026  
FunctionValue()1027    inline int FunctionValue() const {
1028      DCHECK(InstructionType() == kRegisterType ||
1029             InstructionType() == kImmediateType);
1030      return Bits(kFunctionShift + kFunctionBits - 1, kFunctionShift);
1031    }
1032  
FdValue()1033    inline int FdValue() const {
1034      return Bits(kFdShift + kFdBits - 1, kFdShift);
1035    }
1036  
FsValue()1037    inline int FsValue() const {
1038      return Bits(kFsShift + kFsBits - 1, kFsShift);
1039    }
1040  
FtValue()1041    inline int FtValue() const {
1042      return Bits(kFtShift + kFtBits - 1, kFtShift);
1043    }
1044  
FrValue()1045    inline int FrValue() const {
1046      return Bits(kFrShift + kFrBits -1, kFrShift);
1047    }
1048  
Bp2Value()1049    inline int Bp2Value() const {
1050      DCHECK(InstructionType() == kRegisterType);
1051      return Bits(kBp2Shift + kBp2Bits - 1, kBp2Shift);
1052    }
1053  
Bp3Value()1054    inline int Bp3Value() const {
1055      DCHECK(InstructionType() == kRegisterType);
1056      return Bits(kBp3Shift + kBp3Bits - 1, kBp3Shift);
1057    }
1058  
1059    // Float Compare condition code instruction bits.
FCccValue()1060    inline int FCccValue() const {
1061      return Bits(kFCccShift + kFCccBits - 1, kFCccShift);
1062    }
1063  
1064    // Float Branch condition code instruction bits.
FBccValue()1065    inline int FBccValue() const {
1066      return Bits(kFBccShift + kFBccBits - 1, kFBccShift);
1067    }
1068  
1069    // Float Branch true/false instruction bit.
FBtrueValue()1070    inline int FBtrueValue() const {
1071      return Bits(kFBtrueShift + kFBtrueBits - 1, kFBtrueShift);
1072    }
1073  
1074    // Return the fields at their original place in the instruction encoding.
OpcodeFieldRaw()1075    inline Opcode OpcodeFieldRaw() const {
1076      return static_cast<Opcode>(InstructionBits() & kOpcodeMask);
1077    }
1078  
RsFieldRaw()1079    inline int RsFieldRaw() const {
1080      DCHECK(InstructionType() == kRegisterType ||
1081             InstructionType() == kImmediateType);
1082      return InstructionBits() & kRsFieldMask;
1083    }
1084  
1085    // Same as above function, but safe to call within InstructionType().
RsFieldRawNoAssert()1086    inline int RsFieldRawNoAssert() const {
1087      return InstructionBits() & kRsFieldMask;
1088    }
1089  
RtFieldRaw()1090    inline int RtFieldRaw() const {
1091      DCHECK(InstructionType() == kRegisterType ||
1092             InstructionType() == kImmediateType);
1093      return InstructionBits() & kRtFieldMask;
1094    }
1095  
RdFieldRaw()1096    inline int RdFieldRaw() const {
1097      DCHECK(InstructionType() == kRegisterType);
1098      return InstructionBits() & kRdFieldMask;
1099    }
1100  
SaFieldRaw()1101    inline int SaFieldRaw() const {
1102      return InstructionBits() & kSaFieldMask;
1103    }
1104  
FunctionFieldRaw()1105    inline int FunctionFieldRaw() const {
1106      return InstructionBits() & kFunctionFieldMask;
1107    }
1108  
1109    // Get the secondary field according to the opcode.
SecondaryValue()1110    inline int SecondaryValue() const {
1111      Opcode op = OpcodeFieldRaw();
1112      switch (op) {
1113        case SPECIAL:
1114        case SPECIAL2:
1115          return FunctionValue();
1116        case COP1:
1117          return RsValue();
1118        case REGIMM:
1119          return RtValue();
1120        default:
1121          return NULLSF;
1122      }
1123    }
1124  
ImmValue(int bits)1125    inline int32_t ImmValue(int bits) const {
1126      DCHECK(InstructionType() == kImmediateType);
1127      return Bits(bits - 1, 0);
1128    }
1129  
Imm16Value()1130    inline int32_t Imm16Value() const {
1131      DCHECK(InstructionType() == kImmediateType);
1132      return Bits(kImm16Shift + kImm16Bits - 1, kImm16Shift);
1133    }
1134  
Imm18Value()1135    inline int32_t Imm18Value() const {
1136      DCHECK(InstructionType() == kImmediateType);
1137      return Bits(kImm18Shift + kImm18Bits - 1, kImm18Shift);
1138    }
1139  
Imm19Value()1140    inline int32_t Imm19Value() const {
1141      DCHECK(InstructionType() == kImmediateType);
1142      return Bits(kImm19Shift + kImm19Bits - 1, kImm19Shift);
1143    }
1144  
Imm21Value()1145    inline int32_t Imm21Value() const {
1146      DCHECK(InstructionType() == kImmediateType);
1147      return Bits(kImm21Shift + kImm21Bits - 1, kImm21Shift);
1148    }
1149  
Imm26Value()1150    inline int32_t Imm26Value() const {
1151      DCHECK((InstructionType() == kJumpType) ||
1152             (InstructionType() == kImmediateType));
1153      return Bits(kImm26Shift + kImm26Bits - 1, kImm26Shift);
1154    }
1155  
1156    static bool IsForbiddenAfterBranchInstr(Instr instr);
1157  
1158    // Say if the instruction should not be used in a branch delay slot or
1159    // immediately after a compact branch.
IsForbiddenAfterBranch()1160    inline bool IsForbiddenAfterBranch() const {
1161      return IsForbiddenAfterBranchInstr(InstructionBits());
1162    }
1163  
1164    // Say if the instruction 'links'. e.g. jal, bal.
1165    bool IsLinkingInstruction() const;
1166    // Say if the instruction is a break or a trap.
1167    bool IsTrap() const;
1168  
1169    // Instructions are read of out a code stream. The only way to get a
1170    // reference to an instruction is to convert a pointer. There is no way
1171    // to allocate or create instances of class Instruction.
1172    // Use the At(pc) function to create references to Instruction.
At(byte * pc)1173    static Instruction* At(byte* pc) {
1174      return reinterpret_cast<Instruction*>(pc);
1175    }
1176  
1177   private:
1178    // We need to prevent the creation of instances of class Instruction.
1179    DISALLOW_IMPLICIT_CONSTRUCTORS(Instruction);
1180  };
1181  
1182  
1183  // -----------------------------------------------------------------------------
1184  // MIPS assembly various constants.
1185  
1186  // C/C++ argument slots size.
1187  const int kCArgSlotCount = (kMipsAbi == kN64) ? 0 : 4;
1188  
1189  // TODO(plind): below should be based on kPointerSize
1190  // TODO(plind): find all usages and remove the needless instructions for n64.
1191  const int kCArgsSlotsSize = kCArgSlotCount * Instruction::kInstrSize * 2;
1192  
1193  const int kInvalidStackOffset = -1;
1194  const int kBranchReturnOffset = 2 * Instruction::kInstrSize;
1195  
1196  
InstructionType(TypeChecks checks)1197  Instruction::Type Instruction::InstructionType(TypeChecks checks) const {
1198    if (checks == EXTRA) {
1199      if (OpcodeToBitNumber(OpcodeFieldRaw()) & kOpcodeImmediateTypeMask) {
1200        return kImmediateType;
1201      }
1202    }
1203    switch (OpcodeFieldRaw()) {
1204      case SPECIAL:
1205        if (checks == EXTRA) {
1206          if (FunctionFieldToBitNumber(FunctionFieldRaw()) &
1207              kFunctionFieldRegisterTypeMask) {
1208            return kRegisterType;
1209          } else {
1210            return kUnsupported;
1211          }
1212        } else {
1213          return kRegisterType;
1214        }
1215        break;
1216      case SPECIAL2:
1217        switch (FunctionFieldRaw()) {
1218          case MUL:
1219          case CLZ:
1220          case DCLZ:
1221            return kRegisterType;
1222          default:
1223            return kUnsupported;
1224        }
1225        break;
1226      case SPECIAL3:
1227        switch (FunctionFieldRaw()) {
1228          case INS:
1229          case EXT:
1230          case DEXT:
1231          case DEXTM:
1232          case DEXTU:
1233            return kRegisterType;
1234          case BSHFL: {
1235            int sa = SaFieldRaw() >> kSaShift;
1236            switch (sa) {
1237              case BITSWAP:
1238                return kRegisterType;
1239              case WSBH:
1240              case SEB:
1241              case SEH:
1242                return kUnsupported;
1243            }
1244            sa >>= kBp2Bits;
1245            switch (sa) {
1246              case ALIGN:
1247                return kRegisterType;
1248              default:
1249                return kUnsupported;
1250            }
1251          }
1252          case DBSHFL: {
1253            int sa = SaFieldRaw() >> kSaShift;
1254            switch (sa) {
1255              case DBITSWAP:
1256                return kRegisterType;
1257              case DSBH:
1258              case DSHD:
1259                return kUnsupported;
1260            }
1261            sa = SaFieldRaw() >> kSaShift;
1262            sa >>= kBp3Bits;
1263            switch (sa) {
1264              case DALIGN:
1265                return kRegisterType;
1266              default:
1267                return kUnsupported;
1268            }
1269          }
1270          default:
1271            return kUnsupported;
1272        }
1273        break;
1274      case COP1:  // Coprocessor instructions.
1275        switch (RsFieldRawNoAssert()) {
1276          case BC1:  // Branch on coprocessor condition.
1277          case BC1EQZ:
1278          case BC1NEZ:
1279            return kImmediateType;
1280          default:
1281            return kRegisterType;
1282        }
1283        break;
1284      case COP1X:
1285        return kRegisterType;
1286  
1287      // 26 bits immediate type instructions. e.g.: j imm26.
1288      case J:
1289      case JAL:
1290        return kJumpType;
1291  
1292      default:
1293        if (checks == NORMAL) {
1294          return kImmediateType;
1295        } else {
1296          return kUnsupported;
1297        }
1298    }
1299    return kUnsupported;
1300  }
1301  
1302  #undef OpcodeToBitNumber
1303  #undef FunctionFieldToBitNumber
1304  }  // namespace internal
1305  }  // namespace v8
1306  
1307  #endif    // #ifndef V8_MIPS_CONSTANTS_H_
1308