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