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