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