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