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