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_CODEGEN_MIPS_CONSTANTS_MIPS_H_
6 #define V8_CODEGEN_MIPS_CONSTANTS_MIPS_H_
7 #include "src/codegen/cpu-features.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 { kLittle, kBig };
44 
45 #if defined(V8_TARGET_LITTLE_ENDIAN)
46 static const Endianness kArchEndian = kLittle;
47 #elif defined(V8_TARGET_BIG_ENDIAN)
48 static const Endianness kArchEndian = kBig;
49 #else
50 #error Unknown endianness
51 #endif
52 
53 enum FpuMode { kFP32, kFP64, kFPXX };
54 
55 #if defined(FPU_MODE_FP32)
56 static const FpuMode kFpuMode = kFP32;
57 #elif defined(FPU_MODE_FP64)
58 static const FpuMode kFpuMode = kFP64;
59 #elif defined(FPU_MODE_FPXX)
60 #if defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS32R6)
61 static const FpuMode kFpuMode = kFPXX;
62 #else
63 #error "FPXX is supported only on Mips32R2 and Mips32R6"
64 #endif
65 #else
66 static const FpuMode kFpuMode = kFP32;
67 #endif
68 
69 #if defined(__mips_hard_float) && __mips_hard_float != 0
70 // Use floating-point coprocessor instructions. This flag is raised when
71 // -mhard-float is passed to the compiler.
72 const bool IsMipsSoftFloatABI = false;
73 #elif defined(__mips_soft_float) && __mips_soft_float != 0
74 // This flag is raised when -msoft-float is passed to the compiler.
75 // Although FPU is a base requirement for v8, soft-float ABI is used
76 // on soft-float systems with FPU kernel emulation.
77 const bool IsMipsSoftFloatABI = true;
78 #else
79 const bool IsMipsSoftFloatABI = true;
80 #endif
81 
82 #if defined(V8_TARGET_LITTLE_ENDIAN)
83 const uint32_t kHoleNanUpper32Offset = 4;
84 const uint32_t kHoleNanLower32Offset = 0;
85 #elif defined(V8_TARGET_BIG_ENDIAN)
86 const uint32_t kHoleNanUpper32Offset = 0;
87 const uint32_t kHoleNanLower32Offset = 4;
88 #else
89 #error Unknown endianness
90 #endif
91 
IsFp64Mode()92 constexpr bool IsFp64Mode() { return kFpuMode == kFP64; }
IsFp32Mode()93 constexpr bool IsFp32Mode() { return kFpuMode == kFP32; }
IsFpxxMode()94 constexpr bool IsFpxxMode() { return kFpuMode == kFPXX; }
95 
96 #ifndef _MIPS_ARCH_MIPS32RX
IsMipsArchVariant(const ArchVariants check)97 constexpr bool IsMipsArchVariant(const ArchVariants check) {
98   return kArchVariant == check;
99 }
100 #else
IsMipsArchVariant(const ArchVariants check)101 bool IsMipsArchVariant(const ArchVariants check) {
102   return CpuFeatures::IsSupported(static_cast<CpuFeature>(check));
103 }
104 #endif
105 
106 #if defined(V8_TARGET_LITTLE_ENDIAN)
107 const uint32_t kMipsLwrOffset = 0;
108 const uint32_t kMipsLwlOffset = 3;
109 const uint32_t kMipsSwrOffset = 0;
110 const uint32_t kMipsSwlOffset = 3;
111 #elif defined(V8_TARGET_BIG_ENDIAN)
112 const uint32_t kMipsLwrOffset = 3;
113 const uint32_t kMipsLwlOffset = 0;
114 const uint32_t kMipsSwrOffset = 3;
115 const uint32_t kMipsSwlOffset = 0;
116 #else
117 #error Unknown endianness
118 #endif
119 
120 #if defined(V8_TARGET_LITTLE_ENDIAN)
121 const uint32_t kLeastSignificantByteInInt32Offset = 0;
122 #elif defined(V8_TARGET_BIG_ENDIAN)
123 const uint32_t kLeastSignificantByteInInt32Offset = 3;
124 #else
125 #error Unknown endianness
126 #endif
127 
128 #ifndef __STDC_FORMAT_MACROS
129 #define __STDC_FORMAT_MACROS
130 #endif
131 #include <inttypes.h>
132 
133 // Defines constants and accessor classes to assemble, disassemble and
134 // simulate MIPS32 instructions.
135 //
136 // See: MIPS32 Architecture For Programmers
137 //      Volume II: The MIPS32 Instruction Set
138 // Try www.cs.cornell.edu/courses/cs3410/2008fa/MIPS_Vol2.pdf.
139 
140 namespace v8 {
141 namespace internal {
142 
143 constexpr size_t kMaxPCRelativeCodeRangeInMB = 4096;
144 
145 // -----------------------------------------------------------------------------
146 // Registers and FPURegisters.
147 
148 // Number of general purpose registers.
149 const int kNumRegisters = 32;
150 const int kInvalidRegister = -1;
151 
152 // Number of registers with HI, LO, and pc.
153 const int kNumSimuRegisters = 35;
154 
155 // In the simulator, the PC register is simulated as the 34th register.
156 const int kPCRegister = 34;
157 
158 // Number coprocessor registers.
159 const int kNumFPURegisters = 32;
160 const int kInvalidFPURegister = -1;
161 
162 // Number of MSA registers
163 const int kNumMSARegisters = 32;
164 const int kInvalidMSARegister = -1;
165 
166 const int kInvalidMSAControlRegister = -1;
167 const int kMSAIRRegister = 0;
168 const int kMSACSRRegister = 1;
169 const int kMSARegSize = 128;
170 const int kMSALanesByte = kMSARegSize / 8;
171 const int kMSALanesHalf = kMSARegSize / 16;
172 const int kMSALanesWord = kMSARegSize / 32;
173 const int kMSALanesDword = kMSARegSize / 64;
174 
175 // FPU (coprocessor 1) control registers. Currently only FCSR is implemented.
176 const int kFCSRRegister = 31;
177 const int kInvalidFPUControlRegister = -1;
178 const uint32_t kFPUInvalidResult = static_cast<uint32_t>(1u << 31) - 1;
179 const int32_t kFPUInvalidResultNegative = static_cast<int32_t>(1u << 31);
180 const uint64_t kFPU64InvalidResult =
181     static_cast<uint64_t>(static_cast<uint64_t>(1) << 63) - 1;
182 const int64_t kFPU64InvalidResultNegative =
183     static_cast<int64_t>(static_cast<uint64_t>(1) << 63);
184 
185 // FCSR constants.
186 const uint32_t kFCSRInexactFlagBit = 2;
187 const uint32_t kFCSRUnderflowFlagBit = 3;
188 const uint32_t kFCSROverflowFlagBit = 4;
189 const uint32_t kFCSRDivideByZeroFlagBit = 5;
190 const uint32_t kFCSRInvalidOpFlagBit = 6;
191 const uint32_t kFCSRNaN2008FlagBit = 18;
192 
193 const uint32_t kFCSRInexactFlagMask = 1 << kFCSRInexactFlagBit;
194 const uint32_t kFCSRUnderflowFlagMask = 1 << kFCSRUnderflowFlagBit;
195 const uint32_t kFCSROverflowFlagMask = 1 << kFCSROverflowFlagBit;
196 const uint32_t kFCSRDivideByZeroFlagMask = 1 << kFCSRDivideByZeroFlagBit;
197 const uint32_t kFCSRInvalidOpFlagMask = 1 << kFCSRInvalidOpFlagBit;
198 const uint32_t kFCSRNaN2008FlagMask = 1 << kFCSRNaN2008FlagBit;
199 
200 const uint32_t kFCSRFlagMask =
201     kFCSRInexactFlagMask | kFCSRUnderflowFlagMask | kFCSROverflowFlagMask |
202     kFCSRDivideByZeroFlagMask | kFCSRInvalidOpFlagMask;
203 
204 const uint32_t kFCSRExceptionFlagMask = kFCSRFlagMask ^ kFCSRInexactFlagMask;
205 
206 // 'pref' instruction hints
207 const int32_t kPrefHintLoad = 0;
208 const int32_t kPrefHintStore = 1;
209 const int32_t kPrefHintLoadStreamed = 4;
210 const int32_t kPrefHintStoreStreamed = 5;
211 const int32_t kPrefHintLoadRetained = 6;
212 const int32_t kPrefHintStoreRetained = 7;
213 const int32_t kPrefHintWritebackInvalidate = 25;
214 const int32_t kPrefHintPrepareForStore = 30;
215 
216 // Actual value of root register is offset from the root array's start
217 // to take advantage of negative displacement values.
218 // TODO(sigurds): Choose best value.
219 constexpr int kRootRegisterBias = 256;
220 
221 // Helper functions for converting between register numbers and names.
222 class Registers {
223  public:
224   // Return the name of the register.
225   static const char* Name(int reg);
226 
227   // Lookup the register number for the name provided.
228   static int Number(const char* name);
229 
230   struct RegisterAlias {
231     int reg;
232     const char* name;
233   };
234 
235   static const int32_t kMaxValue = 0x7fffffff;
236   static const int32_t kMinValue = 0x80000000;
237 
238  private:
239   static const char* names_[kNumSimuRegisters];
240   static const RegisterAlias aliases_[];
241 };
242 
243 // Helper functions for converting between register numbers and names.
244 class FPURegisters {
245  public:
246   // Return the name of the register.
247   static const char* Name(int reg);
248 
249   // Lookup the register number for the name provided.
250   static int Number(const char* name);
251 
252   struct RegisterAlias {
253     int creg;
254     const char* name;
255   };
256 
257  private:
258   static const char* names_[kNumFPURegisters];
259   static const RegisterAlias aliases_[];
260 };
261 
262 // Helper functions for converting between register numbers and names.
263 class MSARegisters {
264  public:
265   // Return the name of the register.
266   static const char* Name(int reg);
267 
268   // Lookup the register number for the name provided.
269   static int Number(const char* name);
270 
271   struct RegisterAlias {
272     int creg;
273     const char* name;
274   };
275 
276  private:
277   static const char* names_[kNumMSARegisters];
278   static const RegisterAlias aliases_[];
279 };
280 
281 // -----------------------------------------------------------------------------
282 // Instructions encoding constants.
283 
284 // On MIPS all instructions are 32 bits.
285 using Instr = int32_t;
286 
287 // Special Software Interrupt codes when used in the presence of the MIPS
288 // simulator.
289 enum SoftwareInterruptCodes {
290   // Transition to C code.
291   call_rt_redirected = 0xfffff
292 };
293 
294 // On MIPS Simulator breakpoints can have different codes:
295 // - Breaks between 0 and kMaxWatchpointCode are treated as simple watchpoints,
296 //   the simulator will run through them and print the registers.
297 // - Breaks between kMaxWatchpointCode and kMaxStopCode are treated as stop()
298 //   instructions (see Assembler::stop()).
299 // - Breaks larger than kMaxStopCode are simple breaks, dropping you into the
300 //   debugger.
301 const uint32_t kMaxWatchpointCode = 31;
302 const uint32_t kMaxStopCode = 127;
303 STATIC_ASSERT(kMaxWatchpointCode < kMaxStopCode);
304 
305 // ----- Fields offset and length.
306 const int kOpcodeShift = 26;
307 const int kOpcodeBits = 6;
308 const int kRsShift = 21;
309 const int kRsBits = 5;
310 const int kRtShift = 16;
311 const int kRtBits = 5;
312 const int kRdShift = 11;
313 const int kRdBits = 5;
314 const int kSaShift = 6;
315 const int kSaBits = 5;
316 const int kLsaSaBits = 2;
317 const int kFunctionShift = 0;
318 const int kFunctionBits = 6;
319 const int kLuiShift = 16;
320 const int kBp2Shift = 6;
321 const int kBp2Bits = 2;
322 const int kBaseShift = 21;
323 const int kBaseBits = 5;
324 const int kBit6Shift = 6;
325 const int kBit6Bits = 1;
326 
327 const int kImm9Shift = 7;
328 const int kImm9Bits = 9;
329 const int kImm16Shift = 0;
330 const int kImm16Bits = 16;
331 const int kImm18Shift = 0;
332 const int kImm18Bits = 18;
333 const int kImm19Shift = 0;
334 const int kImm19Bits = 19;
335 const int kImm21Shift = 0;
336 const int kImm21Bits = 21;
337 const int kImm26Shift = 0;
338 const int kImm26Bits = 26;
339 const int kImm28Shift = 0;
340 const int kImm28Bits = 28;
341 const int kImm32Shift = 0;
342 const int kImm32Bits = 32;
343 const int kMsaImm8Shift = 16;
344 const int kMsaImm8Bits = 8;
345 const int kMsaImm5Shift = 16;
346 const int kMsaImm5Bits = 5;
347 const int kMsaImm10Shift = 11;
348 const int kMsaImm10Bits = 10;
349 const int kMsaImmMI10Shift = 16;
350 const int kMsaImmMI10Bits = 10;
351 
352 // In branches and jumps immediate fields point to words, not bytes,
353 // and are therefore shifted by 2.
354 const int kImmFieldShift = 2;
355 
356 const int kFrBits = 5;
357 const int kFrShift = 21;
358 const int kFsShift = 11;
359 const int kFsBits = 5;
360 const int kFtShift = 16;
361 const int kFtBits = 5;
362 const int kFdShift = 6;
363 const int kFdBits = 5;
364 const int kFCccShift = 8;
365 const int kFCccBits = 3;
366 const int kFBccShift = 18;
367 const int kFBccBits = 3;
368 const int kFBtrueShift = 16;
369 const int kFBtrueBits = 1;
370 const int kWtBits = 5;
371 const int kWtShift = 16;
372 const int kWsBits = 5;
373 const int kWsShift = 11;
374 const int kWdBits = 5;
375 const int kWdShift = 6;
376 
377 // ----- Miscellaneous useful masks.
378 // Instruction bit masks.
379 const int kOpcodeMask = ((1 << kOpcodeBits) - 1) << kOpcodeShift;
380 const int kImm9Mask = ((1 << kImm9Bits) - 1) << kImm9Shift;
381 const int kImm16Mask = ((1 << kImm16Bits) - 1) << kImm16Shift;
382 const int kImm18Mask = ((1 << kImm18Bits) - 1) << kImm18Shift;
383 const int kImm19Mask = ((1 << kImm19Bits) - 1) << kImm19Shift;
384 const int kImm21Mask = ((1 << kImm21Bits) - 1) << kImm21Shift;
385 const int kImm26Mask = ((1 << kImm26Bits) - 1) << kImm26Shift;
386 const int kImm28Mask = ((1 << kImm28Bits) - 1) << kImm28Shift;
387 const int kImm5Mask = ((1 << 5) - 1);
388 const int kImm8Mask = ((1 << 8) - 1);
389 const int kImm10Mask = ((1 << 10) - 1);
390 const int kMsaI5I10Mask = ((7U << 23) | ((1 << 6) - 1));
391 const int kMsaI8Mask = ((3U << 24) | ((1 << 6) - 1));
392 const int kMsaI5Mask = ((7U << 23) | ((1 << 6) - 1));
393 const int kMsaMI10Mask = (15U << 2);
394 const int kMsaBITMask = ((7U << 23) | ((1 << 6) - 1));
395 const int kMsaELMMask = (15U << 22);
396 const int kMsaLongerELMMask = kMsaELMMask | (63U << 16);
397 const int kMsa3RMask = ((7U << 23) | ((1 << 6) - 1));
398 const int kMsa3RFMask = ((15U << 22) | ((1 << 6) - 1));
399 const int kMsaVECMask = (23U << 21);
400 const int kMsa2RMask = (7U << 18);
401 const int kMsa2RFMask = (15U << 17);
402 const int kRsFieldMask = ((1 << kRsBits) - 1) << kRsShift;
403 const int kRtFieldMask = ((1 << kRtBits) - 1) << kRtShift;
404 const int kRdFieldMask = ((1 << kRdBits) - 1) << kRdShift;
405 const int kSaFieldMask = ((1 << kSaBits) - 1) << kSaShift;
406 const int kFunctionFieldMask = ((1 << kFunctionBits) - 1) << kFunctionShift;
407 // Misc masks.
408 const int kHiMask = 0xffff << 16;
409 const int kLoMask = 0xffff;
410 const int kSignMask = 0x80000000;
411 const int kJumpAddrMask = (1 << (kImm26Bits + kImmFieldShift)) - 1;
412 
413 // ----- MIPS Opcodes and Function Fields.
414 // We use this presentation to stay close to the table representation in
415 // MIPS32 Architecture For Programmers, Volume II: The MIPS32 Instruction Set.
416 enum Opcode : uint32_t {
417   SPECIAL = 0U << kOpcodeShift,
418   REGIMM = 1U << kOpcodeShift,
419 
420   J = ((0U << 3) + 2) << kOpcodeShift,
421   JAL = ((0U << 3) + 3) << kOpcodeShift,
422   BEQ = ((0U << 3) + 4) << kOpcodeShift,
423   BNE = ((0U << 3) + 5) << kOpcodeShift,
424   BLEZ = ((0U << 3) + 6) << kOpcodeShift,
425   BGTZ = ((0U << 3) + 7) << kOpcodeShift,
426 
427   ADDI = ((1U << 3) + 0) << kOpcodeShift,
428   ADDIU = ((1U << 3) + 1) << kOpcodeShift,
429   SLTI = ((1U << 3) + 2) << kOpcodeShift,
430   SLTIU = ((1U << 3) + 3) << kOpcodeShift,
431   ANDI = ((1U << 3) + 4) << kOpcodeShift,
432   ORI = ((1U << 3) + 5) << kOpcodeShift,
433   XORI = ((1U << 3) + 6) << kOpcodeShift,
434   LUI = ((1U << 3) + 7) << kOpcodeShift,  // LUI/AUI family.
435 
436   BEQC = ((2U << 3) + 0) << kOpcodeShift,
437   COP1 = ((2U << 3) + 1) << kOpcodeShift,  // Coprocessor 1 class.
438   BEQL = ((2U << 3) + 4) << kOpcodeShift,
439   BNEL = ((2U << 3) + 5) << kOpcodeShift,
440   BLEZL = ((2U << 3) + 6) << kOpcodeShift,
441   BGTZL = ((2U << 3) + 7) << kOpcodeShift,
442 
443   DADDI = ((3U << 3) + 0) << kOpcodeShift,  // This is also BNEC.
444   SPECIAL2 = ((3U << 3) + 4) << kOpcodeShift,
445   MSA = ((3U << 3) + 6) << kOpcodeShift,
446   SPECIAL3 = ((3U << 3) + 7) << kOpcodeShift,
447 
448   LB = ((4U << 3) + 0) << kOpcodeShift,
449   LH = ((4U << 3) + 1) << kOpcodeShift,
450   LWL = ((4U << 3) + 2) << kOpcodeShift,
451   LW = ((4U << 3) + 3) << kOpcodeShift,
452   LBU = ((4U << 3) + 4) << kOpcodeShift,
453   LHU = ((4U << 3) + 5) << kOpcodeShift,
454   LWR = ((4U << 3) + 6) << kOpcodeShift,
455   SB = ((5U << 3) + 0) << kOpcodeShift,
456   SH = ((5U << 3) + 1) << kOpcodeShift,
457   SWL = ((5U << 3) + 2) << kOpcodeShift,
458   SW = ((5U << 3) + 3) << kOpcodeShift,
459   SWR = ((5U << 3) + 6) << kOpcodeShift,
460 
461   LL = ((6U << 3) + 0) << kOpcodeShift,
462   LWC1 = ((6U << 3) + 1) << kOpcodeShift,
463   BC = ((6U << 3) + 2) << kOpcodeShift,
464   LDC1 = ((6U << 3) + 5) << kOpcodeShift,
465   POP66 = ((6U << 3) + 6) << kOpcodeShift,  // beqzc, jic
466 
467   PREF = ((6U << 3) + 3) << kOpcodeShift,
468 
469   SC = ((7U << 3) + 0) << kOpcodeShift,
470   SWC1 = ((7U << 3) + 1) << kOpcodeShift,
471   BALC = ((7U << 3) + 2) << kOpcodeShift,
472   PCREL = ((7U << 3) + 3) << kOpcodeShift,
473   SDC1 = ((7U << 3) + 5) << kOpcodeShift,
474   POP76 = ((7U << 3) + 6) << kOpcodeShift,  // bnezc, jialc
475 
476   COP1X = ((1U << 4) + 3) << kOpcodeShift,
477 
478   // New r6 instruction.
479   POP06 = BLEZ,   // bgeuc/bleuc, blezalc, bgezalc
480   POP07 = BGTZ,   // bltuc/bgtuc, bgtzalc, bltzalc
481   POP10 = ADDI,   // beqzalc, bovc, beqc
482   POP26 = BLEZL,  // bgezc, blezc, bgec/blec
483   POP27 = BGTZL,  // bgtzc, bltzc, bltc/bgtc
484   POP30 = DADDI,  // bnezalc, bnvc, bnec
485 };
486 
487 enum SecondaryField : uint32_t {
488   // SPECIAL Encoding of Function Field.
489   SLL = ((0U << 3) + 0),
490   MOVCI = ((0U << 3) + 1),
491   SRL = ((0U << 3) + 2),
492   SRA = ((0U << 3) + 3),
493   SLLV = ((0U << 3) + 4),
494   LSA = ((0U << 3) + 5),
495   SRLV = ((0U << 3) + 6),
496   SRAV = ((0U << 3) + 7),
497 
498   JR = ((1U << 3) + 0),
499   JALR = ((1U << 3) + 1),
500   MOVZ = ((1U << 3) + 2),
501   MOVN = ((1U << 3) + 3),
502   BREAK = ((1U << 3) + 5),
503   SYNC = ((1U << 3) + 7),
504 
505   MFHI = ((2U << 3) + 0),
506   CLZ_R6 = ((2U << 3) + 0),
507   CLO_R6 = ((2U << 3) + 1),
508   MFLO = ((2U << 3) + 2),
509 
510   MULT = ((3U << 3) + 0),
511   MULTU = ((3U << 3) + 1),
512   DIV = ((3U << 3) + 2),
513   DIVU = ((3U << 3) + 3),
514 
515   ADD = ((4U << 3) + 0),
516   ADDU = ((4U << 3) + 1),
517   SUB = ((4U << 3) + 2),
518   SUBU = ((4U << 3) + 3),
519   AND = ((4U << 3) + 4),
520   OR = ((4U << 3) + 5),
521   XOR = ((4U << 3) + 6),
522   NOR = ((4U << 3) + 7),
523 
524   SLT = ((5U << 3) + 2),
525   SLTU = ((5U << 3) + 3),
526 
527   TGE = ((6U << 3) + 0),
528   TGEU = ((6U << 3) + 1),
529   TLT = ((6U << 3) + 2),
530   TLTU = ((6U << 3) + 3),
531   TEQ = ((6U << 3) + 4),
532   SELEQZ_S = ((6U << 3) + 5),
533   TNE = ((6U << 3) + 6),
534   SELNEZ_S = ((6U << 3) + 7),
535 
536   // Multiply integers in r6.
537   MUL_MUH = ((3U << 3) + 0),    // MUL, MUH.
538   MUL_MUH_U = ((3U << 3) + 1),  // MUL_U, MUH_U.
539   RINT = ((3U << 3) + 2),
540 
541   MUL_OP = ((0U << 3) + 2),
542   MUH_OP = ((0U << 3) + 3),
543   DIV_OP = ((0U << 3) + 2),
544   MOD_OP = ((0U << 3) + 3),
545 
546   DIV_MOD = ((3U << 3) + 2),
547   DIV_MOD_U = ((3U << 3) + 3),
548 
549   // SPECIAL2 Encoding of Function Field.
550   MUL = ((0U << 3) + 2),
551   CLZ = ((4U << 3) + 0),
552   CLO = ((4U << 3) + 1),
553 
554   // SPECIAL3 Encoding of Function Field.
555   EXT = ((0U << 3) + 0),
556   INS = ((0U << 3) + 4),
557   BSHFL = ((4U << 3) + 0),
558   SC_R6 = ((4U << 3) + 6),
559   LL_R6 = ((6U << 3) + 6),
560 
561   // SPECIAL3 Encoding of sa Field.
562   BITSWAP = ((0U << 3) + 0),
563   ALIGN = ((0U << 3) + 2),
564   WSBH = ((0U << 3) + 2),
565   SEB = ((2U << 3) + 0),
566   SEH = ((3U << 3) + 0),
567 
568   // REGIMM  encoding of rt Field.
569   BLTZ = ((0U << 3) + 0) << 16,
570   BGEZ = ((0U << 3) + 1) << 16,
571   BLTZAL = ((2U << 3) + 0) << 16,
572   BGEZAL = ((2U << 3) + 1) << 16,
573   BGEZALL = ((2U << 3) + 3) << 16,
574 
575   // COP1 Encoding of rs Field.
576   MFC1 = ((0U << 3) + 0) << 21,
577   CFC1 = ((0U << 3) + 2) << 21,
578   MFHC1 = ((0U << 3) + 3) << 21,
579   MTC1 = ((0U << 3) + 4) << 21,
580   CTC1 = ((0U << 3) + 6) << 21,
581   MTHC1 = ((0U << 3) + 7) << 21,
582   BC1 = ((1U << 3) + 0) << 21,
583   S = ((2U << 3) + 0) << 21,
584   D = ((2U << 3) + 1) << 21,
585   W = ((2U << 3) + 4) << 21,
586   L = ((2U << 3) + 5) << 21,
587   PS = ((2U << 3) + 6) << 21,
588   // COP1 Encoding of Function Field When rs=S.
589 
590   ADD_S = ((0U << 3) + 0),
591   SUB_S = ((0U << 3) + 1),
592   MUL_S = ((0U << 3) + 2),
593   DIV_S = ((0U << 3) + 3),
594   ABS_S = ((0U << 3) + 5),
595   SQRT_S = ((0U << 3) + 4),
596   MOV_S = ((0U << 3) + 6),
597   NEG_S = ((0U << 3) + 7),
598   ROUND_L_S = ((1U << 3) + 0),
599   TRUNC_L_S = ((1U << 3) + 1),
600   CEIL_L_S = ((1U << 3) + 2),
601   FLOOR_L_S = ((1U << 3) + 3),
602   ROUND_W_S = ((1U << 3) + 4),
603   TRUNC_W_S = ((1U << 3) + 5),
604   CEIL_W_S = ((1U << 3) + 6),
605   FLOOR_W_S = ((1U << 3) + 7),
606   RECIP_S = ((2U << 3) + 5),
607   RSQRT_S = ((2U << 3) + 6),
608   MADDF_S = ((3U << 3) + 0),
609   MSUBF_S = ((3U << 3) + 1),
610   CLASS_S = ((3U << 3) + 3),
611   CVT_D_S = ((4U << 3) + 1),
612   CVT_W_S = ((4U << 3) + 4),
613   CVT_L_S = ((4U << 3) + 5),
614   CVT_PS_S = ((4U << 3) + 6),
615 
616   // COP1 Encoding of Function Field When rs=D.
617   ADD_D = ((0U << 3) + 0),
618   SUB_D = ((0U << 3) + 1),
619   MUL_D = ((0U << 3) + 2),
620   DIV_D = ((0U << 3) + 3),
621   SQRT_D = ((0U << 3) + 4),
622   ABS_D = ((0U << 3) + 5),
623   MOV_D = ((0U << 3) + 6),
624   NEG_D = ((0U << 3) + 7),
625   ROUND_L_D = ((1U << 3) + 0),
626   TRUNC_L_D = ((1U << 3) + 1),
627   CEIL_L_D = ((1U << 3) + 2),
628   FLOOR_L_D = ((1U << 3) + 3),
629   ROUND_W_D = ((1U << 3) + 4),
630   TRUNC_W_D = ((1U << 3) + 5),
631   CEIL_W_D = ((1U << 3) + 6),
632   FLOOR_W_D = ((1U << 3) + 7),
633   RECIP_D = ((2U << 3) + 5),
634   RSQRT_D = ((2U << 3) + 6),
635   MADDF_D = ((3U << 3) + 0),
636   MSUBF_D = ((3U << 3) + 1),
637   CLASS_D = ((3U << 3) + 3),
638   MIN = ((3U << 3) + 4),
639   MINA = ((3U << 3) + 5),
640   MAX = ((3U << 3) + 6),
641   MAXA = ((3U << 3) + 7),
642   CVT_S_D = ((4U << 3) + 0),
643   CVT_W_D = ((4U << 3) + 4),
644   CVT_L_D = ((4U << 3) + 5),
645   C_F_D = ((6U << 3) + 0),
646   C_UN_D = ((6U << 3) + 1),
647   C_EQ_D = ((6U << 3) + 2),
648   C_UEQ_D = ((6U << 3) + 3),
649   C_OLT_D = ((6U << 3) + 4),
650   C_ULT_D = ((6U << 3) + 5),
651   C_OLE_D = ((6U << 3) + 6),
652   C_ULE_D = ((6U << 3) + 7),
653 
654   // COP1 Encoding of Function Field When rs=W or L.
655   CVT_S_W = ((4U << 3) + 0),
656   CVT_D_W = ((4U << 3) + 1),
657   CVT_S_L = ((4U << 3) + 0),
658   CVT_D_L = ((4U << 3) + 1),
659   BC1EQZ = ((2U << 2) + 1) << 21,
660   BC1NEZ = ((3U << 2) + 1) << 21,
661   // COP1 CMP positive predicates Bit 5..4 = 00.
662   CMP_AF = ((0U << 3) + 0),
663   CMP_UN = ((0U << 3) + 1),
664   CMP_EQ = ((0U << 3) + 2),
665   CMP_UEQ = ((0U << 3) + 3),
666   CMP_LT = ((0U << 3) + 4),
667   CMP_ULT = ((0U << 3) + 5),
668   CMP_LE = ((0U << 3) + 6),
669   CMP_ULE = ((0U << 3) + 7),
670   CMP_SAF = ((1U << 3) + 0),
671   CMP_SUN = ((1U << 3) + 1),
672   CMP_SEQ = ((1U << 3) + 2),
673   CMP_SUEQ = ((1U << 3) + 3),
674   CMP_SSLT = ((1U << 3) + 4),
675   CMP_SSULT = ((1U << 3) + 5),
676   CMP_SLE = ((1U << 3) + 6),
677   CMP_SULE = ((1U << 3) + 7),
678   // COP1 CMP negative predicates Bit 5..4 = 01.
679   CMP_AT = ((2U << 3) + 0),  // Reserved, not implemented.
680   CMP_OR = ((2U << 3) + 1),
681   CMP_UNE = ((2U << 3) + 2),
682   CMP_NE = ((2U << 3) + 3),
683   CMP_UGE = ((2U << 3) + 4),  // Reserved, not implemented.
684   CMP_OGE = ((2U << 3) + 5),  // Reserved, not implemented.
685   CMP_UGT = ((2U << 3) + 6),  // Reserved, not implemented.
686   CMP_OGT = ((2U << 3) + 7),  // Reserved, not implemented.
687   CMP_SAT = ((3U << 3) + 0),  // Reserved, not implemented.
688   CMP_SOR = ((3U << 3) + 1),
689   CMP_SUNE = ((3U << 3) + 2),
690   CMP_SNE = ((3U << 3) + 3),
691   CMP_SUGE = ((3U << 3) + 4),  // Reserved, not implemented.
692   CMP_SOGE = ((3U << 3) + 5),  // Reserved, not implemented.
693   CMP_SUGT = ((3U << 3) + 6),  // Reserved, not implemented.
694   CMP_SOGT = ((3U << 3) + 7),  // Reserved, not implemented.
695 
696   SEL = ((2U << 3) + 0),
697   MOVZ_C = ((2U << 3) + 2),
698   MOVN_C = ((2U << 3) + 3),
699   SELEQZ_C = ((2U << 3) + 4),  // COP1 on FPR registers.
700   MOVF = ((2U << 3) + 1),      // Function field for MOVT.fmt and MOVF.fmt
701   SELNEZ_C = ((2U << 3) + 7),  // COP1 on FPR registers.
702                                // COP1 Encoding of Function Field When rs=PS.
703 
704   // COP1X Encoding of Function Field.
705   MADD_S = ((4U << 3) + 0),
706   MADD_D = ((4U << 3) + 1),
707   MSUB_S = ((5U << 3) + 0),
708   MSUB_D = ((5U << 3) + 1),
709 
710   // PCREL Encoding of rt Field.
711   ADDIUPC = ((0U << 2) + 0),
712   LWPC = ((0U << 2) + 1),
713   AUIPC = ((3U << 3) + 6),
714   ALUIPC = ((3U << 3) + 7),
715 
716   // POP66 Encoding of rs Field.
717   JIC = ((0U << 5) + 0),
718 
719   // POP76 Encoding of rs Field.
720   JIALC = ((0U << 5) + 0),
721 
722   // COP1 Encoding of rs Field for MSA Branch Instructions
723   BZ_V = (((1U << 3) + 3) << kRsShift),
724   BNZ_V = (((1U << 3) + 7) << kRsShift),
725   BZ_B = (((3U << 3) + 0) << kRsShift),
726   BZ_H = (((3U << 3) + 1) << kRsShift),
727   BZ_W = (((3U << 3) + 2) << kRsShift),
728   BZ_D = (((3U << 3) + 3) << kRsShift),
729   BNZ_B = (((3U << 3) + 4) << kRsShift),
730   BNZ_H = (((3U << 3) + 5) << kRsShift),
731   BNZ_W = (((3U << 3) + 6) << kRsShift),
732   BNZ_D = (((3U << 3) + 7) << kRsShift),
733 
734   // MSA: Operation Field for MI10 Instruction Formats
735   MSA_LD = (8U << 2),
736   MSA_ST = (9U << 2),
737   LD_B = ((8U << 2) + 0),
738   LD_H = ((8U << 2) + 1),
739   LD_W = ((8U << 2) + 2),
740   LD_D = ((8U << 2) + 3),
741   ST_B = ((9U << 2) + 0),
742   ST_H = ((9U << 2) + 1),
743   ST_W = ((9U << 2) + 2),
744   ST_D = ((9U << 2) + 3),
745 
746   // MSA: Operation Field for I5 Instruction Format
747   ADDVI = ((0U << 23) + 6),
748   SUBVI = ((1U << 23) + 6),
749   MAXI_S = ((2U << 23) + 6),
750   MAXI_U = ((3U << 23) + 6),
751   MINI_S = ((4U << 23) + 6),
752   MINI_U = ((5U << 23) + 6),
753   CEQI = ((0U << 23) + 7),
754   CLTI_S = ((2U << 23) + 7),
755   CLTI_U = ((3U << 23) + 7),
756   CLEI_S = ((4U << 23) + 7),
757   CLEI_U = ((5U << 23) + 7),
758   LDI = ((6U << 23) + 7),  // I10 instruction format
759   I5_DF_b = (0U << 21),
760   I5_DF_h = (1U << 21),
761   I5_DF_w = (2U << 21),
762   I5_DF_d = (3U << 21),
763 
764   // MSA: Operation Field for I8 Instruction Format
765   ANDI_B = ((0U << 24) + 0),
766   ORI_B = ((1U << 24) + 0),
767   NORI_B = ((2U << 24) + 0),
768   XORI_B = ((3U << 24) + 0),
769   BMNZI_B = ((0U << 24) + 1),
770   BMZI_B = ((1U << 24) + 1),
771   BSELI_B = ((2U << 24) + 1),
772   SHF_B = ((0U << 24) + 2),
773   SHF_H = ((1U << 24) + 2),
774   SHF_W = ((2U << 24) + 2),
775 
776   MSA_VEC_2R_2RF_MINOR = ((3U << 3) + 6),
777 
778   // MSA: Operation Field for VEC Instruction Formats
779   AND_V = (((0U << 2) + 0) << 21),
780   OR_V = (((0U << 2) + 1) << 21),
781   NOR_V = (((0U << 2) + 2) << 21),
782   XOR_V = (((0U << 2) + 3) << 21),
783   BMNZ_V = (((1U << 2) + 0) << 21),
784   BMZ_V = (((1U << 2) + 1) << 21),
785   BSEL_V = (((1U << 2) + 2) << 21),
786 
787   // MSA: Operation Field for 2R Instruction Formats
788   MSA_2R_FORMAT = (((6U << 2) + 0) << 21),
789   FILL = (0U << 18),
790   PCNT = (1U << 18),
791   NLOC = (2U << 18),
792   NLZC = (3U << 18),
793   MSA_2R_DF_b = (0U << 16),
794   MSA_2R_DF_h = (1U << 16),
795   MSA_2R_DF_w = (2U << 16),
796   MSA_2R_DF_d = (3U << 16),
797 
798   // MSA: Operation Field for 2RF Instruction Formats
799   MSA_2RF_FORMAT = (((6U << 2) + 1) << 21),
800   FCLASS = (0U << 17),
801   FTRUNC_S = (1U << 17),
802   FTRUNC_U = (2U << 17),
803   FSQRT = (3U << 17),
804   FRSQRT = (4U << 17),
805   FRCP = (5U << 17),
806   FRINT = (6U << 17),
807   FLOG2 = (7U << 17),
808   FEXUPL = (8U << 17),
809   FEXUPR = (9U << 17),
810   FFQL = (10U << 17),
811   FFQR = (11U << 17),
812   FTINT_S = (12U << 17),
813   FTINT_U = (13U << 17),
814   FFINT_S = (14U << 17),
815   FFINT_U = (15U << 17),
816   MSA_2RF_DF_w = (0U << 16),
817   MSA_2RF_DF_d = (1U << 16),
818 
819   // MSA: Operation Field for 3R Instruction Format
820   SLL_MSA = ((0U << 23) + 13),
821   SRA_MSA = ((1U << 23) + 13),
822   SRL_MSA = ((2U << 23) + 13),
823   BCLR = ((3U << 23) + 13),
824   BSET = ((4U << 23) + 13),
825   BNEG = ((5U << 23) + 13),
826   BINSL = ((6U << 23) + 13),
827   BINSR = ((7U << 23) + 13),
828   ADDV = ((0U << 23) + 14),
829   SUBV = ((1U << 23) + 14),
830   MAX_S = ((2U << 23) + 14),
831   MAX_U = ((3U << 23) + 14),
832   MIN_S = ((4U << 23) + 14),
833   MIN_U = ((5U << 23) + 14),
834   MAX_A = ((6U << 23) + 14),
835   MIN_A = ((7U << 23) + 14),
836   CEQ = ((0U << 23) + 15),
837   CLT_S = ((2U << 23) + 15),
838   CLT_U = ((3U << 23) + 15),
839   CLE_S = ((4U << 23) + 15),
840   CLE_U = ((5U << 23) + 15),
841   ADD_A = ((0U << 23) + 16),
842   ADDS_A = ((1U << 23) + 16),
843   ADDS_S = ((2U << 23) + 16),
844   ADDS_U = ((3U << 23) + 16),
845   AVE_S = ((4U << 23) + 16),
846   AVE_U = ((5U << 23) + 16),
847   AVER_S = ((6U << 23) + 16),
848   AVER_U = ((7U << 23) + 16),
849   SUBS_S = ((0U << 23) + 17),
850   SUBS_U = ((1U << 23) + 17),
851   SUBSUS_U = ((2U << 23) + 17),
852   SUBSUU_S = ((3U << 23) + 17),
853   ASUB_S = ((4U << 23) + 17),
854   ASUB_U = ((5U << 23) + 17),
855   MULV = ((0U << 23) + 18),
856   MADDV = ((1U << 23) + 18),
857   MSUBV = ((2U << 23) + 18),
858   DIV_S_MSA = ((4U << 23) + 18),
859   DIV_U = ((5U << 23) + 18),
860   MOD_S = ((6U << 23) + 18),
861   MOD_U = ((7U << 23) + 18),
862   DOTP_S = ((0U << 23) + 19),
863   DOTP_U = ((1U << 23) + 19),
864   DPADD_S = ((2U << 23) + 19),
865   DPADD_U = ((3U << 23) + 19),
866   DPSUB_S = ((4U << 23) + 19),
867   DPSUB_U = ((5U << 23) + 19),
868   SLD = ((0U << 23) + 20),
869   SPLAT = ((1U << 23) + 20),
870   PCKEV = ((2U << 23) + 20),
871   PCKOD = ((3U << 23) + 20),
872   ILVL = ((4U << 23) + 20),
873   ILVR = ((5U << 23) + 20),
874   ILVEV = ((6U << 23) + 20),
875   ILVOD = ((7U << 23) + 20),
876   VSHF = ((0U << 23) + 21),
877   SRAR = ((1U << 23) + 21),
878   SRLR = ((2U << 23) + 21),
879   HADD_S = ((4U << 23) + 21),
880   HADD_U = ((5U << 23) + 21),
881   HSUB_S = ((6U << 23) + 21),
882   HSUB_U = ((7U << 23) + 21),
883   MSA_3R_DF_b = (0U << 21),
884   MSA_3R_DF_h = (1U << 21),
885   MSA_3R_DF_w = (2U << 21),
886   MSA_3R_DF_d = (3U << 21),
887 
888   // MSA: Operation Field for 3RF Instruction Format
889   FCAF = ((0U << 22) + 26),
890   FCUN = ((1U << 22) + 26),
891   FCEQ = ((2U << 22) + 26),
892   FCUEQ = ((3U << 22) + 26),
893   FCLT = ((4U << 22) + 26),
894   FCULT = ((5U << 22) + 26),
895   FCLE = ((6U << 22) + 26),
896   FCULE = ((7U << 22) + 26),
897   FSAF = ((8U << 22) + 26),
898   FSUN = ((9U << 22) + 26),
899   FSEQ = ((10U << 22) + 26),
900   FSUEQ = ((11U << 22) + 26),
901   FSLT = ((12U << 22) + 26),
902   FSULT = ((13U << 22) + 26),
903   FSLE = ((14U << 22) + 26),
904   FSULE = ((15U << 22) + 26),
905   FADD = ((0U << 22) + 27),
906   FSUB = ((1U << 22) + 27),
907   FMUL = ((2U << 22) + 27),
908   FDIV = ((3U << 22) + 27),
909   FMADD = ((4U << 22) + 27),
910   FMSUB = ((5U << 22) + 27),
911   FEXP2 = ((7U << 22) + 27),
912   FEXDO = ((8U << 22) + 27),
913   FTQ = ((10U << 22) + 27),
914   FMIN = ((12U << 22) + 27),
915   FMIN_A = ((13U << 22) + 27),
916   FMAX = ((14U << 22) + 27),
917   FMAX_A = ((15U << 22) + 27),
918   FCOR = ((1U << 22) + 28),
919   FCUNE = ((2U << 22) + 28),
920   FCNE = ((3U << 22) + 28),
921   MUL_Q = ((4U << 22) + 28),
922   MADD_Q = ((5U << 22) + 28),
923   MSUB_Q = ((6U << 22) + 28),
924   FSOR = ((9U << 22) + 28),
925   FSUNE = ((10U << 22) + 28),
926   FSNE = ((11U << 22) + 28),
927   MULR_Q = ((12U << 22) + 28),
928   MADDR_Q = ((13U << 22) + 28),
929   MSUBR_Q = ((14U << 22) + 28),
930 
931   // MSA: Operation Field for ELM Instruction Format
932   MSA_ELM_MINOR = ((3U << 3) + 1),
933   SLDI = (0U << 22),
934   CTCMSA = ((0U << 22) | (62U << 16)),
935   SPLATI = (1U << 22),
936   CFCMSA = ((1U << 22) | (62U << 16)),
937   COPY_S = (2U << 22),
938   MOVE_V = ((2U << 22) | (62U << 16)),
939   COPY_U = (3U << 22),
940   INSERT = (4U << 22),
941   INSVE = (5U << 22),
942   ELM_DF_B = ((0U << 4) << 16),
943   ELM_DF_H = ((4U << 3) << 16),
944   ELM_DF_W = ((12U << 2) << 16),
945   ELM_DF_D = ((28U << 1) << 16),
946 
947   // MSA: Operation Field for BIT Instruction Format
948   SLLI = ((0U << 23) + 9),
949   SRAI = ((1U << 23) + 9),
950   SRLI = ((2U << 23) + 9),
951   BCLRI = ((3U << 23) + 9),
952   BSETI = ((4U << 23) + 9),
953   BNEGI = ((5U << 23) + 9),
954   BINSLI = ((6U << 23) + 9),
955   BINSRI = ((7U << 23) + 9),
956   SAT_S = ((0U << 23) + 10),
957   SAT_U = ((1U << 23) + 10),
958   SRARI = ((2U << 23) + 10),
959   SRLRI = ((3U << 23) + 10),
960   BIT_DF_b = ((14U << 3) << 16),
961   BIT_DF_h = ((6U << 4) << 16),
962   BIT_DF_w = ((2U << 5) << 16),
963   BIT_DF_d = ((0U << 6) << 16),
964 
965   nullptrSF = 0U
966 };
967 
968 enum MSAMinorOpcode : uint32_t {
969   kMsaMinorUndefined = 0,
970   kMsaMinorI8,
971   kMsaMinorI5,
972   kMsaMinorI10,
973   kMsaMinorBIT,
974   kMsaMinor3R,
975   kMsaMinor3RF,
976   kMsaMinorELM,
977   kMsaMinorVEC,
978   kMsaMinor2R,
979   kMsaMinor2RF,
980   kMsaMinorMI10
981 };
982 
983 // ----- Emulated conditions.
984 // On MIPS we use this enum to abstract from conditional branch instructions.
985 // The 'U' prefix is used to specify unsigned comparisons.
986 // Opposite conditions must be paired as odd/even numbers
987 // because 'NegateCondition' function flips LSB to negate condition.
988 enum Condition {
989   // Any value < 0 is considered no_condition.
990   kNoCondition = -1,
991   overflow = 0,
992   no_overflow = 1,
993   Uless = 2,
994   Ugreater_equal = 3,
995   Uless_equal = 4,
996   Ugreater = 5,
997   equal = 6,
998   not_equal = 7,  // Unordered or Not Equal.
999   negative = 8,
1000   positive = 9,
1001   parity_even = 10,
1002   parity_odd = 11,
1003   less = 12,
1004   greater_equal = 13,
1005   less_equal = 14,
1006   greater = 15,
1007   ueq = 16,  // Unordered or Equal.
1008   ogl = 17,  // Ordered and Not Equal.
1009   cc_always = 18,
1010 
1011   // Aliases.
1012   carry = Uless,
1013   not_carry = Ugreater_equal,
1014   zero = equal,
1015   eq = equal,
1016   not_zero = not_equal,
1017   ne = not_equal,
1018   nz = not_equal,
1019   sign = negative,
1020   not_sign = positive,
1021   mi = negative,
1022   pl = positive,
1023   hi = Ugreater,
1024   ls = Uless_equal,
1025   ge = greater_equal,
1026   lt = less,
1027   gt = greater,
1028   le = less_equal,
1029   hs = Ugreater_equal,
1030   lo = Uless,
1031   al = cc_always,
1032   ult = Uless,
1033   uge = Ugreater_equal,
1034   ule = Uless_equal,
1035   ugt = Ugreater,
1036   cc_default = kNoCondition
1037 };
1038 
1039 // Returns the equivalent of !cc.
1040 // Negation of the default kNoCondition (-1) results in a non-default
1041 // no_condition value (-2). As long as tests for no_condition check
1042 // for condition < 0, this will work as expected.
NegateCondition(Condition cc)1043 inline Condition NegateCondition(Condition cc) {
1044   DCHECK(cc != cc_always);
1045   return static_cast<Condition>(cc ^ 1);
1046 }
1047 
NegateFpuCondition(Condition cc)1048 inline Condition NegateFpuCondition(Condition cc) {
1049   DCHECK(cc != cc_always);
1050   switch (cc) {
1051     case ult:
1052       return ge;
1053     case ugt:
1054       return le;
1055     case uge:
1056       return lt;
1057     case ule:
1058       return gt;
1059     case lt:
1060       return uge;
1061     case gt:
1062       return ule;
1063     case ge:
1064       return ult;
1065     case le:
1066       return ugt;
1067     case eq:
1068       return ne;
1069     case ne:
1070       return eq;
1071     case ueq:
1072       return ogl;
1073     case ogl:
1074       return ueq;
1075     default:
1076       return cc;
1077   }
1078 }
1079 
1080 enum MSABranchCondition {
1081   all_not_zero = 0,   // Branch If All Elements Are Not Zero
1082   one_elem_not_zero,  // Branch If At Least One Element of Any Format Is Not
1083                       // Zero
1084   one_elem_zero,      // Branch If At Least One Element Is Zero
1085   all_zero            // Branch If All Elements of Any Format Are Zero
1086 };
1087 
NegateMSABranchCondition(MSABranchCondition cond)1088 inline MSABranchCondition NegateMSABranchCondition(MSABranchCondition cond) {
1089   switch (cond) {
1090     case all_not_zero:
1091       return one_elem_zero;
1092     case one_elem_not_zero:
1093       return all_zero;
1094     case one_elem_zero:
1095       return all_not_zero;
1096     case all_zero:
1097       return one_elem_not_zero;
1098     default:
1099       return cond;
1100   }
1101 }
1102 
1103 enum MSABranchDF {
1104   MSA_BRANCH_B = 0,
1105   MSA_BRANCH_H,
1106   MSA_BRANCH_W,
1107   MSA_BRANCH_D,
1108   MSA_BRANCH_V
1109 };
1110 
1111 // ----- Coprocessor conditions.
1112 enum FPUCondition {
1113   kNoFPUCondition = -1,
1114 
1115   F = 0x00,    // False.
1116   UN = 0x01,   // Unordered.
1117   EQ = 0x02,   // Equal.
1118   UEQ = 0x03,  // Unordered or Equal.
1119   OLT = 0x04,  // Ordered or Less Than, on Mips release < 6.
1120   LT = 0x04,   // Ordered or Less Than, on Mips release >= 6.
1121   ULT = 0x05,  // Unordered or Less Than.
1122   OLE = 0x06,  // Ordered or Less Than or Equal, on Mips release < 6.
1123   LE = 0x06,   // Ordered or Less Than or Equal, on Mips release >= 6.
1124   ULE = 0x07,  // Unordered or Less Than or Equal.
1125 
1126   // Following constants are available on Mips release >= 6 only.
1127   ORD = 0x11,  // Ordered, on Mips release >= 6.
1128   UNE = 0x12,  // Not equal, on Mips release >= 6.
1129   NE = 0x13,   // Ordered Greater Than or Less Than. on Mips >= 6 only.
1130 };
1131 
1132 // FPU rounding modes.
1133 enum FPURoundingMode {
1134   RN = 0 << 0,  // Round to Nearest.
1135   RZ = 1 << 0,  // Round towards zero.
1136   RP = 2 << 0,  // Round towards Plus Infinity.
1137   RM = 3 << 0,  // Round towards Minus Infinity.
1138 
1139   // Aliases.
1140   kRoundToNearest = RN,
1141   kRoundToZero = RZ,
1142   kRoundToPlusInf = RP,
1143   kRoundToMinusInf = RM,
1144 
1145   mode_round = RN,
1146   mode_ceil = RP,
1147   mode_floor = RM,
1148   mode_trunc = RZ
1149 };
1150 
1151 const uint32_t kFPURoundingModeMask = 3 << 0;
1152 
1153 enum CheckForInexactConversion {
1154   kCheckForInexactConversion,
1155   kDontCheckForInexactConversion
1156 };
1157 
1158 enum class MaxMinKind : int { kMin = 0, kMax = 1 };
1159 
1160 // -----------------------------------------------------------------------------
1161 // Hints.
1162 
1163 // Branch hints are not used on the MIPS.  They are defined so that they can
1164 // appear in shared function signatures, but will be ignored in MIPS
1165 // implementations.
1166 enum Hint { no_hint = 0 };
1167 
NegateHint(Hint hint)1168 inline Hint NegateHint(Hint hint) { return no_hint; }
1169 
1170 // -----------------------------------------------------------------------------
1171 // Specific instructions, constants, and masks.
1172 // These constants are declared in assembler-mips.cc, as they use named
1173 // registers and other constants.
1174 
1175 // addiu(sp, sp, 4) aka Pop() operation or part of Pop(r)
1176 // operations as post-increment of sp.
1177 extern const Instr kPopInstruction;
1178 // addiu(sp, sp, -4) part of Push(r) operation as pre-decrement of sp.
1179 extern const Instr kPushInstruction;
1180 // sw(r, MemOperand(sp, 0))
1181 extern const Instr kPushRegPattern;
1182 // lw(r, MemOperand(sp, 0))
1183 extern const Instr kPopRegPattern;
1184 extern const Instr kLwRegFpOffsetPattern;
1185 extern const Instr kSwRegFpOffsetPattern;
1186 extern const Instr kLwRegFpNegOffsetPattern;
1187 extern const Instr kSwRegFpNegOffsetPattern;
1188 // A mask for the Rt register for push, pop, lw, sw instructions.
1189 extern const Instr kRtMask;
1190 extern const Instr kLwSwInstrTypeMask;
1191 extern const Instr kLwSwInstrArgumentMask;
1192 extern const Instr kLwSwOffsetMask;
1193 
1194 // Break 0xfffff, reserved for redirected real time call.
1195 const Instr rtCallRedirInstr = SPECIAL | BREAK | call_rt_redirected << 6;
1196 // A nop instruction. (Encoding of sll 0 0 0).
1197 const Instr nopInstr = 0;
1198 
OpcodeToBitNumber(Opcode opcode)1199 static constexpr uint64_t OpcodeToBitNumber(Opcode opcode) {
1200   return 1ULL << (static_cast<uint32_t>(opcode) >> kOpcodeShift);
1201 }
1202 
1203 constexpr uint8_t kInstrSize = 4;
1204 constexpr uint8_t kInstrSizeLog2 = 2;
1205 
1206 class InstructionBase {
1207  public:
1208   enum {
1209     // On MIPS PC cannot actually be directly accessed. We behave as if PC was
1210     // always the value of the current instruction being executed.
1211     kPCReadOffset = 0
1212   };
1213 
1214   // Instruction type.
1215   enum Type { kRegisterType, kImmediateType, kJumpType, kUnsupported = -1 };
1216 
1217   // Get the raw instruction bits.
InstructionBits()1218   inline Instr InstructionBits() const {
1219     return *reinterpret_cast<const Instr*>(this);
1220   }
1221 
1222   // Set the raw instruction bits to value.
SetInstructionBits(Instr value)1223   inline void SetInstructionBits(Instr value) {
1224     *reinterpret_cast<Instr*>(this) = value;
1225   }
1226 
1227   // Read one particular bit out of the instruction bits.
Bit(int nr)1228   inline int Bit(int nr) const { return (InstructionBits() >> nr) & 1; }
1229 
1230   // Read a bit field out of the instruction bits.
Bits(int hi,int lo)1231   inline int Bits(int hi, int lo) const {
1232     return (InstructionBits() >> lo) & ((2U << (hi - lo)) - 1);
1233   }
1234 
1235   static constexpr uint64_t kOpcodeImmediateTypeMask =
1236       OpcodeToBitNumber(REGIMM) | OpcodeToBitNumber(BEQ) |
1237       OpcodeToBitNumber(BNE) | OpcodeToBitNumber(BLEZ) |
1238       OpcodeToBitNumber(BGTZ) | OpcodeToBitNumber(ADDI) |
1239       OpcodeToBitNumber(DADDI) | OpcodeToBitNumber(ADDIU) |
1240       OpcodeToBitNumber(SLTI) | OpcodeToBitNumber(SLTIU) |
1241       OpcodeToBitNumber(ANDI) | OpcodeToBitNumber(ORI) |
1242       OpcodeToBitNumber(XORI) | OpcodeToBitNumber(LUI) |
1243       OpcodeToBitNumber(BEQL) | OpcodeToBitNumber(BNEL) |
1244       OpcodeToBitNumber(BLEZL) | OpcodeToBitNumber(BGTZL) |
1245       OpcodeToBitNumber(POP66) | OpcodeToBitNumber(POP76) |
1246       OpcodeToBitNumber(LB) | OpcodeToBitNumber(LH) | OpcodeToBitNumber(LWL) |
1247       OpcodeToBitNumber(LW) | OpcodeToBitNumber(LBU) | OpcodeToBitNumber(LHU) |
1248       OpcodeToBitNumber(LWR) | OpcodeToBitNumber(SB) | OpcodeToBitNumber(SH) |
1249       OpcodeToBitNumber(SWL) | OpcodeToBitNumber(SW) | OpcodeToBitNumber(SWR) |
1250       OpcodeToBitNumber(LWC1) | OpcodeToBitNumber(LDC1) |
1251       OpcodeToBitNumber(SWC1) | OpcodeToBitNumber(SDC1) |
1252       OpcodeToBitNumber(PCREL) | OpcodeToBitNumber(BC) |
1253       OpcodeToBitNumber(BALC);
1254 
1255 #define FunctionFieldToBitNumber(function) (1ULL << function)
1256 
1257   static const uint64_t kFunctionFieldRegisterTypeMask =
1258       FunctionFieldToBitNumber(JR) | FunctionFieldToBitNumber(JALR) |
1259       FunctionFieldToBitNumber(BREAK) | FunctionFieldToBitNumber(SLL) |
1260       FunctionFieldToBitNumber(SRL) | FunctionFieldToBitNumber(SRA) |
1261       FunctionFieldToBitNumber(SLLV) | FunctionFieldToBitNumber(SRLV) |
1262       FunctionFieldToBitNumber(SRAV) | FunctionFieldToBitNumber(LSA) |
1263       FunctionFieldToBitNumber(MFHI) | FunctionFieldToBitNumber(MFLO) |
1264       FunctionFieldToBitNumber(MULT) | FunctionFieldToBitNumber(MULTU) |
1265       FunctionFieldToBitNumber(DIV) | FunctionFieldToBitNumber(DIVU) |
1266       FunctionFieldToBitNumber(ADD) | FunctionFieldToBitNumber(ADDU) |
1267       FunctionFieldToBitNumber(SUB) | FunctionFieldToBitNumber(SUBU) |
1268       FunctionFieldToBitNumber(AND) | FunctionFieldToBitNumber(OR) |
1269       FunctionFieldToBitNumber(XOR) | FunctionFieldToBitNumber(NOR) |
1270       FunctionFieldToBitNumber(SLT) | FunctionFieldToBitNumber(SLTU) |
1271       FunctionFieldToBitNumber(TGE) | FunctionFieldToBitNumber(TGEU) |
1272       FunctionFieldToBitNumber(TLT) | FunctionFieldToBitNumber(TLTU) |
1273       FunctionFieldToBitNumber(TEQ) | FunctionFieldToBitNumber(TNE) |
1274       FunctionFieldToBitNumber(MOVZ) | FunctionFieldToBitNumber(MOVN) |
1275       FunctionFieldToBitNumber(MOVCI) | FunctionFieldToBitNumber(SELEQZ_S) |
1276       FunctionFieldToBitNumber(SELNEZ_S) | FunctionFieldToBitNumber(SYNC);
1277 
1278   // Accessors for the different named fields used in the MIPS encoding.
OpcodeValue()1279   inline Opcode OpcodeValue() const {
1280     return static_cast<Opcode>(
1281         Bits(kOpcodeShift + kOpcodeBits - 1, kOpcodeShift));
1282   }
1283 
FunctionFieldRaw()1284   inline int FunctionFieldRaw() const {
1285     return InstructionBits() & kFunctionFieldMask;
1286   }
1287 
1288   // Return the fields at their original place in the instruction encoding.
OpcodeFieldRaw()1289   inline Opcode OpcodeFieldRaw() const {
1290     return static_cast<Opcode>(InstructionBits() & kOpcodeMask);
1291   }
1292 
1293   // Safe to call within InstructionType().
RsFieldRawNoAssert()1294   inline int RsFieldRawNoAssert() const {
1295     return InstructionBits() & kRsFieldMask;
1296   }
1297 
SaFieldRaw()1298   inline int SaFieldRaw() const { return InstructionBits() & kSaFieldMask; }
1299 
1300   // Get the encoding type of the instruction.
1301   inline Type InstructionType() const;
1302 
MSAMinorOpcodeField()1303   inline MSAMinorOpcode MSAMinorOpcodeField() const {
1304     int op = this->FunctionFieldRaw();
1305     switch (op) {
1306       case 0:
1307       case 1:
1308       case 2:
1309         return kMsaMinorI8;
1310       case 6:
1311         return kMsaMinorI5;
1312       case 7:
1313         return (((this->InstructionBits() & kMsaI5I10Mask) == LDI)
1314                     ? kMsaMinorI10
1315                     : kMsaMinorI5);
1316       case 9:
1317       case 10:
1318         return kMsaMinorBIT;
1319       case 13:
1320       case 14:
1321       case 15:
1322       case 16:
1323       case 17:
1324       case 18:
1325       case 19:
1326       case 20:
1327       case 21:
1328         return kMsaMinor3R;
1329       case 25:
1330         return kMsaMinorELM;
1331       case 26:
1332       case 27:
1333       case 28:
1334         return kMsaMinor3RF;
1335       case 30:
1336         switch (this->RsFieldRawNoAssert()) {
1337           case MSA_2R_FORMAT:
1338             return kMsaMinor2R;
1339           case MSA_2RF_FORMAT:
1340             return kMsaMinor2RF;
1341           default:
1342             return kMsaMinorVEC;
1343         }
1344         break;
1345       case 32:
1346       case 33:
1347       case 34:
1348       case 35:
1349       case 36:
1350       case 37:
1351       case 38:
1352       case 39:
1353         return kMsaMinorMI10;
1354       default:
1355         return kMsaMinorUndefined;
1356     }
1357   }
1358 
1359  protected:
InstructionBase()1360   InstructionBase() {}
1361 };
1362 
1363 template <class T>
1364 class InstructionGetters : public T {
1365  public:
RsValue()1366   inline int RsValue() const {
1367     DCHECK(this->InstructionType() == InstructionBase::kRegisterType ||
1368            this->InstructionType() == InstructionBase::kImmediateType);
1369     return InstructionBase::Bits(kRsShift + kRsBits - 1, kRsShift);
1370   }
1371 
RtValue()1372   inline int RtValue() const {
1373     DCHECK(this->InstructionType() == InstructionBase::kRegisterType ||
1374            this->InstructionType() == InstructionBase::kImmediateType);
1375     return this->Bits(kRtShift + kRtBits - 1, kRtShift);
1376   }
1377 
RdValue()1378   inline int RdValue() const {
1379     DCHECK_EQ(this->InstructionType(), InstructionBase::kRegisterType);
1380     return this->Bits(kRdShift + kRdBits - 1, kRdShift);
1381   }
1382 
BaseValue()1383   inline int BaseValue() const {
1384     DCHECK_EQ(this->InstructionType(), InstructionBase::kImmediateType);
1385     return this->Bits(kBaseShift + kBaseBits - 1, kBaseShift);
1386   }
1387 
SaValue()1388   inline int SaValue() const {
1389     DCHECK_EQ(this->InstructionType(), InstructionBase::kRegisterType);
1390     return this->Bits(kSaShift + kSaBits - 1, kSaShift);
1391   }
1392 
LsaSaValue()1393   inline int LsaSaValue() const {
1394     DCHECK_EQ(this->InstructionType(), InstructionBase::kRegisterType);
1395     return this->Bits(kSaShift + kLsaSaBits - 1, kSaShift);
1396   }
1397 
FunctionValue()1398   inline int FunctionValue() const {
1399     DCHECK(this->InstructionType() == InstructionBase::kRegisterType ||
1400            this->InstructionType() == InstructionBase::kImmediateType);
1401     return this->Bits(kFunctionShift + kFunctionBits - 1, kFunctionShift);
1402   }
1403 
FdValue()1404   inline int FdValue() const {
1405     return this->Bits(kFdShift + kFdBits - 1, kFdShift);
1406   }
1407 
FsValue()1408   inline int FsValue() const {
1409     return this->Bits(kFsShift + kFsBits - 1, kFsShift);
1410   }
1411 
FtValue()1412   inline int FtValue() const {
1413     return this->Bits(kFtShift + kFtBits - 1, kFtShift);
1414   }
1415 
FrValue()1416   inline int FrValue() const {
1417     return this->Bits(kFrShift + kFrBits - 1, kFrShift);
1418   }
1419 
WdValue()1420   inline int WdValue() const {
1421     return this->Bits(kWdShift + kWdBits - 1, kWdShift);
1422   }
1423 
WsValue()1424   inline int WsValue() const {
1425     return this->Bits(kWsShift + kWsBits - 1, kWsShift);
1426   }
1427 
WtValue()1428   inline int WtValue() const {
1429     return this->Bits(kWtShift + kWtBits - 1, kWtShift);
1430   }
1431 
Bp2Value()1432   inline int Bp2Value() const {
1433     DCHECK_EQ(this->InstructionType(), InstructionBase::kRegisterType);
1434     return this->Bits(kBp2Shift + kBp2Bits - 1, kBp2Shift);
1435   }
1436 
1437   // Float Compare condition code instruction bits.
FCccValue()1438   inline int FCccValue() const {
1439     return this->Bits(kFCccShift + kFCccBits - 1, kFCccShift);
1440   }
1441 
1442   // Float Branch condition code instruction bits.
FBccValue()1443   inline int FBccValue() const {
1444     return this->Bits(kFBccShift + kFBccBits - 1, kFBccShift);
1445   }
1446 
1447   // Float Branch true/false instruction bit.
FBtrueValue()1448   inline int FBtrueValue() const {
1449     return this->Bits(kFBtrueShift + kFBtrueBits - 1, kFBtrueShift);
1450   }
1451 
1452   // Return the fields at their original place in the instruction encoding.
OpcodeFieldRaw()1453   inline Opcode OpcodeFieldRaw() const {
1454     return static_cast<Opcode>(this->InstructionBits() & kOpcodeMask);
1455   }
1456 
RsFieldRaw()1457   inline int RsFieldRaw() const {
1458     DCHECK(this->InstructionType() == InstructionBase::kRegisterType ||
1459            this->InstructionType() == InstructionBase::kImmediateType);
1460     return this->InstructionBits() & kRsFieldMask;
1461   }
1462 
RtFieldRaw()1463   inline int RtFieldRaw() const {
1464     DCHECK(this->InstructionType() == InstructionBase::kRegisterType ||
1465            this->InstructionType() == InstructionBase::kImmediateType);
1466     return this->InstructionBits() & kRtFieldMask;
1467   }
1468 
RdFieldRaw()1469   inline int RdFieldRaw() const {
1470     DCHECK_EQ(this->InstructionType(), InstructionBase::kRegisterType);
1471     return this->InstructionBits() & kRdFieldMask;
1472   }
1473 
SaFieldRaw()1474   inline int SaFieldRaw() const {
1475     return this->InstructionBits() & kSaFieldMask;
1476   }
1477 
FunctionFieldRaw()1478   inline int FunctionFieldRaw() const {
1479     return this->InstructionBits() & kFunctionFieldMask;
1480   }
1481 
1482   // Get the secondary field according to the opcode.
SecondaryValue()1483   inline int SecondaryValue() const {
1484     Opcode op = this->OpcodeFieldRaw();
1485     switch (op) {
1486       case SPECIAL:
1487       case SPECIAL2:
1488         return FunctionValue();
1489       case COP1:
1490         return RsValue();
1491       case REGIMM:
1492         return RtValue();
1493       default:
1494         return nullptrSF;
1495     }
1496   }
1497 
ImmValue(int bits)1498   inline int32_t ImmValue(int bits) const {
1499     DCHECK_EQ(this->InstructionType(), InstructionBase::kImmediateType);
1500     return this->Bits(bits - 1, 0);
1501   }
1502 
Imm9Value()1503   inline int32_t Imm9Value() const {
1504     DCHECK_EQ(this->InstructionType(), InstructionBase::kImmediateType);
1505     return this->Bits(kImm9Shift + kImm9Bits - 1, kImm9Shift);
1506   }
1507 
Imm16Value()1508   inline int32_t Imm16Value() const {
1509     DCHECK_EQ(this->InstructionType(), InstructionBase::kImmediateType);
1510     return this->Bits(kImm16Shift + kImm16Bits - 1, kImm16Shift);
1511   }
1512 
Imm18Value()1513   inline int32_t Imm18Value() const {
1514     DCHECK_EQ(this->InstructionType(), InstructionBase::kImmediateType);
1515     return this->Bits(kImm18Shift + kImm18Bits - 1, kImm18Shift);
1516   }
1517 
Imm19Value()1518   inline int32_t Imm19Value() const {
1519     DCHECK_EQ(this->InstructionType(), InstructionBase::kImmediateType);
1520     return this->Bits(kImm19Shift + kImm19Bits - 1, kImm19Shift);
1521   }
1522 
Imm21Value()1523   inline int32_t Imm21Value() const {
1524     DCHECK_EQ(this->InstructionType(), InstructionBase::kImmediateType);
1525     return this->Bits(kImm21Shift + kImm21Bits - 1, kImm21Shift);
1526   }
1527 
Imm26Value()1528   inline int32_t Imm26Value() const {
1529     DCHECK((this->InstructionType() == InstructionBase::kJumpType) ||
1530            (this->InstructionType() == InstructionBase::kImmediateType));
1531     return this->Bits(kImm26Shift + kImm26Bits - 1, kImm26Shift);
1532   }
1533 
MsaImm8Value()1534   inline int32_t MsaImm8Value() const {
1535     DCHECK_EQ(this->InstructionType(), InstructionBase::kImmediateType);
1536     return this->Bits(kMsaImm8Shift + kMsaImm8Bits - 1, kMsaImm8Shift);
1537   }
1538 
MsaImm5Value()1539   inline int32_t MsaImm5Value() const {
1540     DCHECK_EQ(this->InstructionType(), InstructionBase::kImmediateType);
1541     return this->Bits(kMsaImm5Shift + kMsaImm5Bits - 1, kMsaImm5Shift);
1542   }
1543 
MsaImm10Value()1544   inline int32_t MsaImm10Value() const {
1545     DCHECK_EQ(this->InstructionType(), InstructionBase::kImmediateType);
1546     return this->Bits(kMsaImm10Shift + kMsaImm10Bits - 1, kMsaImm10Shift);
1547   }
1548 
MsaImmMI10Value()1549   inline int32_t MsaImmMI10Value() const {
1550     DCHECK_EQ(this->InstructionType(), InstructionBase::kImmediateType);
1551     return this->Bits(kMsaImmMI10Shift + kMsaImmMI10Bits - 1, kMsaImmMI10Shift);
1552   }
1553 
MsaBitDf()1554   inline int32_t MsaBitDf() const {
1555     DCHECK_EQ(this->InstructionType(), InstructionBase::kImmediateType);
1556     int32_t df_m = this->Bits(22, 16);
1557     if (((df_m >> 6) & 1U) == 0) {
1558       return 3;
1559     } else if (((df_m >> 5) & 3U) == 2) {
1560       return 2;
1561     } else if (((df_m >> 4) & 7U) == 6) {
1562       return 1;
1563     } else if (((df_m >> 3) & 15U) == 14) {
1564       return 0;
1565     } else {
1566       return -1;
1567     }
1568   }
1569 
MsaBitMValue()1570   inline int32_t MsaBitMValue() const {
1571     DCHECK_EQ(this->InstructionType(), InstructionBase::kImmediateType);
1572     return this->Bits(16 + this->MsaBitDf() + 3, 16);
1573   }
1574 
MsaElmDf()1575   inline int32_t MsaElmDf() const {
1576     DCHECK(this->InstructionType() == InstructionBase::kRegisterType ||
1577            this->InstructionType() == InstructionBase::kImmediateType);
1578     int32_t df_n = this->Bits(21, 16);
1579     if (((df_n >> 4) & 3U) == 0) {
1580       return 0;
1581     } else if (((df_n >> 3) & 7U) == 4) {
1582       return 1;
1583     } else if (((df_n >> 2) & 15U) == 12) {
1584       return 2;
1585     } else if (((df_n >> 1) & 31U) == 28) {
1586       return 3;
1587     } else {
1588       return -1;
1589     }
1590   }
1591 
MsaElmNValue()1592   inline int32_t MsaElmNValue() const {
1593     DCHECK(this->InstructionType() == InstructionBase::kRegisterType ||
1594            this->InstructionType() == InstructionBase::kImmediateType);
1595     return this->Bits(16 + 4 - this->MsaElmDf(), 16);
1596   }
1597 
1598   static bool IsForbiddenAfterBranchInstr(Instr instr);
1599 
1600   // Say if the instruction should not be used in a branch delay slot or
1601   // immediately after a compact branch.
IsForbiddenAfterBranch()1602   inline bool IsForbiddenAfterBranch() const {
1603     return IsForbiddenAfterBranchInstr(this->InstructionBits());
1604   }
1605 
IsForbiddenInBranchDelay()1606   inline bool IsForbiddenInBranchDelay() const {
1607     return IsForbiddenAfterBranch();
1608   }
1609 
1610   // Say if the instruction 'links'. e.g. jal, bal.
1611   bool IsLinkingInstruction() const;
1612   // Say if the instruction is a break or a trap.
1613   bool IsTrap() const;
1614 
IsMSABranchInstr()1615   inline bool IsMSABranchInstr() const {
1616     if (this->OpcodeFieldRaw() == COP1) {
1617       switch (this->RsFieldRaw()) {
1618         case BZ_V:
1619         case BZ_B:
1620         case BZ_H:
1621         case BZ_W:
1622         case BZ_D:
1623         case BNZ_V:
1624         case BNZ_B:
1625         case BNZ_H:
1626         case BNZ_W:
1627         case BNZ_D:
1628           return true;
1629         default:
1630           return false;
1631       }
1632     }
1633     return false;
1634   }
1635 
IsMSAInstr()1636   inline bool IsMSAInstr() const {
1637     if (this->IsMSABranchInstr() || (this->OpcodeFieldRaw() == MSA))
1638       return true;
1639     return false;
1640   }
1641 };
1642 
1643 class Instruction : public InstructionGetters<InstructionBase> {
1644  public:
1645   // Instructions are read of out a code stream. The only way to get a
1646   // reference to an instruction is to convert a pointer. There is no way
1647   // to allocate or create instances of class Instruction.
1648   // Use the At(pc) function to create references to Instruction.
At(byte * pc)1649   static Instruction* At(byte* pc) {
1650     return reinterpret_cast<Instruction*>(pc);
1651   }
1652 
1653  private:
1654   // We need to prevent the creation of instances of class Instruction.
1655   DISALLOW_IMPLICIT_CONSTRUCTORS(Instruction);
1656 };
1657 
1658 // -----------------------------------------------------------------------------
1659 // MIPS assembly various constants.
1660 
1661 // C/C++ argument slots size.
1662 const int kCArgSlotCount = 4;
1663 const int kCArgsSlotsSize = kCArgSlotCount * kInstrSize;
1664 
1665 // JS argument slots size.
1666 const int kJSArgsSlotsSize = 0 * kInstrSize;
1667 
1668 // Assembly builtins argument slots size.
1669 const int kBArgsSlotsSize = 0 * kInstrSize;
1670 
1671 const int kBranchReturnOffset = 2 * kInstrSize;
1672 
InstructionType()1673 InstructionBase::Type InstructionBase::InstructionType() const {
1674   switch (OpcodeFieldRaw()) {
1675     case SPECIAL:
1676       if (FunctionFieldToBitNumber(FunctionFieldRaw()) &
1677           kFunctionFieldRegisterTypeMask) {
1678         return kRegisterType;
1679       }
1680       return kUnsupported;
1681     case SPECIAL2:
1682       switch (FunctionFieldRaw()) {
1683         case MUL:
1684         case CLZ:
1685           return kRegisterType;
1686         default:
1687           return kUnsupported;
1688       }
1689       break;
1690     case SPECIAL3:
1691       switch (FunctionFieldRaw()) {
1692         case INS:
1693         case EXT:
1694           return kRegisterType;
1695         case BSHFL: {
1696           int sa = SaFieldRaw() >> kSaShift;
1697           switch (sa) {
1698             case BITSWAP:
1699             case WSBH:
1700             case SEB:
1701             case SEH:
1702               return kRegisterType;
1703           }
1704           sa >>= kBp2Bits;
1705           switch (sa) {
1706             case ALIGN:
1707               return kRegisterType;
1708             default:
1709               return kUnsupported;
1710           }
1711         }
1712         case LL_R6:
1713         case SC_R6: {
1714           DCHECK(IsMipsArchVariant(kMips32r6));
1715           return kImmediateType;
1716         }
1717         default:
1718           return kUnsupported;
1719       }
1720       break;
1721     case COP1:  // Coprocessor instructions.
1722       switch (RsFieldRawNoAssert()) {
1723         case BC1:  // Branch on coprocessor condition.
1724         case BC1EQZ:
1725         case BC1NEZ:
1726           return kImmediateType;
1727         // MSA Branch instructions
1728         case BZ_V:
1729         case BNZ_V:
1730         case BZ_B:
1731         case BZ_H:
1732         case BZ_W:
1733         case BZ_D:
1734         case BNZ_B:
1735         case BNZ_H:
1736         case BNZ_W:
1737         case BNZ_D:
1738           return kImmediateType;
1739         default:
1740           return kRegisterType;
1741       }
1742       break;
1743     case COP1X:
1744       return kRegisterType;
1745 
1746     // 26 bits immediate type instructions. e.g.: j imm26.
1747     case J:
1748     case JAL:
1749       return kJumpType;
1750 
1751     case MSA:
1752       switch (MSAMinorOpcodeField()) {
1753         case kMsaMinor3R:
1754         case kMsaMinor3RF:
1755         case kMsaMinorVEC:
1756         case kMsaMinor2R:
1757         case kMsaMinor2RF:
1758           return kRegisterType;
1759         case kMsaMinorELM:
1760           switch (InstructionBits() & kMsaLongerELMMask) {
1761             case CFCMSA:
1762             case CTCMSA:
1763             case MOVE_V:
1764               return kRegisterType;
1765             default:
1766               return kImmediateType;
1767           }
1768         default:
1769           return kImmediateType;
1770       }
1771 
1772     default:
1773       return kImmediateType;
1774   }
1775 }
1776 
1777 #undef OpcodeToBitNumber
1778 #undef FunctionFieldToBitNumber
1779 
1780 // -----------------------------------------------------------------------------
1781 // Instructions.
1782 
1783 template <class P>
IsLinkingInstruction()1784 bool InstructionGetters<P>::IsLinkingInstruction() const {
1785   uint32_t op = this->OpcodeFieldRaw();
1786   switch (op) {
1787     case JAL:
1788       return true;
1789     case POP76:
1790       if (this->RsFieldRawNoAssert() == JIALC)
1791         return true;  // JIALC
1792       else
1793         return false;  // BNEZC
1794     case REGIMM:
1795       switch (this->RtFieldRaw()) {
1796         case BGEZAL:
1797         case BLTZAL:
1798           return true;
1799         default:
1800           return false;
1801       }
1802     case SPECIAL:
1803       switch (this->FunctionFieldRaw()) {
1804         case JALR:
1805           return true;
1806         default:
1807           return false;
1808       }
1809     default:
1810       return false;
1811   }
1812 }
1813 
1814 template <class P>
IsTrap()1815 bool InstructionGetters<P>::IsTrap() const {
1816   if (this->OpcodeFieldRaw() != SPECIAL) {
1817     return false;
1818   } else {
1819     switch (this->FunctionFieldRaw()) {
1820       case BREAK:
1821       case TGE:
1822       case TGEU:
1823       case TLT:
1824       case TLTU:
1825       case TEQ:
1826       case TNE:
1827         return true;
1828       default:
1829         return false;
1830     }
1831   }
1832 }
1833 
1834 // static
1835 template <class T>
IsForbiddenAfterBranchInstr(Instr instr)1836 bool InstructionGetters<T>::IsForbiddenAfterBranchInstr(Instr instr) {
1837   Opcode opcode = static_cast<Opcode>(instr & kOpcodeMask);
1838   switch (opcode) {
1839     case J:
1840     case JAL:
1841     case BEQ:
1842     case BNE:
1843     case BLEZ:  // POP06 bgeuc/bleuc, blezalc, bgezalc
1844     case BGTZ:  // POP07 bltuc/bgtuc, bgtzalc, bltzalc
1845     case BEQL:
1846     case BNEL:
1847     case BLEZL:  // POP26 bgezc, blezc, bgec/blec
1848     case BGTZL:  // POP27 bgtzc, bltzc, bltc/bgtc
1849     case BC:
1850     case BALC:
1851     case POP10:  // beqzalc, bovc, beqc
1852     case POP30:  // bnezalc, bnvc, bnec
1853     case POP66:  // beqzc, jic
1854     case POP76:  // bnezc, jialc
1855       return true;
1856     case REGIMM:
1857       switch (instr & kRtFieldMask) {
1858         case BLTZ:
1859         case BGEZ:
1860         case BLTZAL:
1861         case BGEZAL:
1862           return true;
1863         default:
1864           return false;
1865       }
1866       break;
1867     case SPECIAL:
1868       switch (instr & kFunctionFieldMask) {
1869         case JR:
1870         case JALR:
1871           return true;
1872         default:
1873           return false;
1874       }
1875       break;
1876     case COP1:
1877       switch (instr & kRsFieldMask) {
1878         case BC1:
1879         case BC1EQZ:
1880         case BC1NEZ:
1881         case BZ_V:
1882         case BZ_B:
1883         case BZ_H:
1884         case BZ_W:
1885         case BZ_D:
1886         case BNZ_V:
1887         case BNZ_B:
1888         case BNZ_H:
1889         case BNZ_W:
1890         case BNZ_D:
1891           return true;
1892           break;
1893         default:
1894           return false;
1895       }
1896       break;
1897     default:
1898       return false;
1899   }
1900 }
1901 }  // namespace internal
1902 }  // namespace v8
1903 
1904 #endif  // V8_CODEGEN_MIPS_CONSTANTS_MIPS_H_
1905