blob: 57e947b138656b63df66ec75ffbc2e9bbd4a7273 [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001// 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_H_
6#define V8_MIPS_CONSTANTS_H_
7
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008#include "src/base/logging.h"
9#include "src/base/macros.h"
10#include "src/globals.h"
11
Ben Murdochb8a8cc12014-11-26 15:28:44 +000012// UNIMPLEMENTED_ macro for MIPS.
13#ifdef DEBUG
14#define UNIMPLEMENTED_MIPS() \
15 v8::internal::PrintF("%s, \tline %d: \tfunction %s not implemented. \n", \
16 __FILE__, __LINE__, __func__)
17#else
18#define UNIMPLEMENTED_MIPS()
19#endif
20
21#define UNSUPPORTED_MIPS() v8::internal::PrintF("Unsupported instruction.\n")
22
23enum ArchVariants {
24 kMips64r2,
25 kMips64r6
26};
27
28
29#ifdef _MIPS_ARCH_MIPS64R2
30 static const ArchVariants kArchVariant = kMips64r2;
31#elif _MIPS_ARCH_MIPS64R6
32 static const ArchVariants kArchVariant = kMips64r6;
33#else
34 static const ArchVariants kArchVariant = kMips64r2;
35#endif
36
37
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000038 enum Endianness { kLittle, kBig };
39
40#if defined(V8_TARGET_LITTLE_ENDIAN)
41 static const Endianness kArchEndian = kLittle;
42#elif defined(V8_TARGET_BIG_ENDIAN)
43 static const Endianness kArchEndian = kBig;
44#else
45#error Unknown endianness
46#endif
47
Ben Murdochb8a8cc12014-11-26 15:28:44 +000048
49// TODO(plind): consider renaming these ...
50#if(defined(__mips_hard_float) && __mips_hard_float != 0)
51// Use floating-point coprocessor instructions. This flag is raised when
52// -mhard-float is passed to the compiler.
53const bool IsMipsSoftFloatABI = false;
54#elif(defined(__mips_soft_float) && __mips_soft_float != 0)
55// This flag is raised when -msoft-float is passed to the compiler.
56// Although FPU is a base requirement for v8, soft-float ABI is used
57// on soft-float systems with FPU kernel emulation.
58const bool IsMipsSoftFloatABI = true;
59#else
60const bool IsMipsSoftFloatABI = true;
61#endif
62
63
64#ifndef __STDC_FORMAT_MACROS
65#define __STDC_FORMAT_MACROS
66#endif
67#include <inttypes.h>
68
69
70// Defines constants and accessor classes to assemble, disassemble and
71// simulate MIPS32 instructions.
72//
73// See: MIPS32 Architecture For Programmers
74// Volume II: The MIPS32 Instruction Set
75// Try www.cs.cornell.edu/courses/cs3410/2008fa/MIPS_Vol2.pdf.
76
77namespace v8 {
78namespace internal {
79
80// -----------------------------------------------------------------------------
81// Registers and FPURegisters.
82
83// Number of general purpose registers.
84const int kNumRegisters = 32;
85const int kInvalidRegister = -1;
86
87// Number of registers with HI, LO, and pc.
88const int kNumSimuRegisters = 35;
89
90// In the simulator, the PC register is simulated as the 34th register.
91const int kPCRegister = 34;
92
93// Number coprocessor registers.
94const int kNumFPURegisters = 32;
95const int kInvalidFPURegister = -1;
96
97// FPU (coprocessor 1) control registers. Currently only FCSR is implemented.
98const int kFCSRRegister = 31;
99const int kInvalidFPUControlRegister = -1;
100const uint32_t kFPUInvalidResult = static_cast<uint32_t>(1 << 31) - 1;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000101const int32_t kFPUInvalidResultNegative = static_cast<int32_t>(1 << 31);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000102const uint64_t kFPU64InvalidResult =
103 static_cast<uint64_t>(static_cast<uint64_t>(1) << 63) - 1;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000104const int64_t kFPU64InvalidResultNegative =
105 static_cast<int64_t>(static_cast<uint64_t>(1) << 63);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000106
107// FCSR constants.
108const uint32_t kFCSRInexactFlagBit = 2;
109const uint32_t kFCSRUnderflowFlagBit = 3;
110const uint32_t kFCSROverflowFlagBit = 4;
111const uint32_t kFCSRDivideByZeroFlagBit = 5;
112const uint32_t kFCSRInvalidOpFlagBit = 6;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000113const uint32_t kFCSRNaN2008FlagBit = 18;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000114
115const uint32_t kFCSRInexactFlagMask = 1 << kFCSRInexactFlagBit;
116const uint32_t kFCSRUnderflowFlagMask = 1 << kFCSRUnderflowFlagBit;
117const uint32_t kFCSROverflowFlagMask = 1 << kFCSROverflowFlagBit;
118const uint32_t kFCSRDivideByZeroFlagMask = 1 << kFCSRDivideByZeroFlagBit;
119const uint32_t kFCSRInvalidOpFlagMask = 1 << kFCSRInvalidOpFlagBit;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000120const uint32_t kFCSRNaN2008FlagMask = 1 << kFCSRNaN2008FlagBit;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000121
122const uint32_t kFCSRFlagMask =
123 kFCSRInexactFlagMask |
124 kFCSRUnderflowFlagMask |
125 kFCSROverflowFlagMask |
126 kFCSRDivideByZeroFlagMask |
127 kFCSRInvalidOpFlagMask;
128
129const uint32_t kFCSRExceptionFlagMask = kFCSRFlagMask ^ kFCSRInexactFlagMask;
130
131// 'pref' instruction hints
132const int32_t kPrefHintLoad = 0;
133const int32_t kPrefHintStore = 1;
134const int32_t kPrefHintLoadStreamed = 4;
135const int32_t kPrefHintStoreStreamed = 5;
136const int32_t kPrefHintLoadRetained = 6;
137const int32_t kPrefHintStoreRetained = 7;
138const int32_t kPrefHintWritebackInvalidate = 25;
139const int32_t kPrefHintPrepareForStore = 30;
140
141// Helper functions for converting between register numbers and names.
142class Registers {
143 public:
144 // Return the name of the register.
145 static const char* Name(int reg);
146
147 // Lookup the register number for the name provided.
148 static int Number(const char* name);
149
150 struct RegisterAlias {
151 int reg;
152 const char* name;
153 };
154
155 static const int64_t kMaxValue = 0x7fffffffffffffffl;
156 static const int64_t kMinValue = 0x8000000000000000l;
157
158 private:
159 static const char* names_[kNumSimuRegisters];
160 static const RegisterAlias aliases_[];
161};
162
163// Helper functions for converting between register numbers and names.
164class FPURegisters {
165 public:
166 // Return the name of the register.
167 static const char* Name(int reg);
168
169 // Lookup the register number for the name provided.
170 static int Number(const char* name);
171
172 struct RegisterAlias {
173 int creg;
174 const char* name;
175 };
176
177 private:
178 static const char* names_[kNumFPURegisters];
179 static const RegisterAlias aliases_[];
180};
181
182
183// -----------------------------------------------------------------------------
184// Instructions encoding constants.
185
186// On MIPS all instructions are 32 bits.
187typedef int32_t Instr;
188
189// Special Software Interrupt codes when used in the presence of the MIPS
190// simulator.
191enum SoftwareInterruptCodes {
192 // Transition to C code.
193 call_rt_redirected = 0xfffff
194};
195
196// On MIPS Simulator breakpoints can have different codes:
197// - Breaks between 0 and kMaxWatchpointCode are treated as simple watchpoints,
198// the simulator will run through them and print the registers.
199// - Breaks between kMaxWatchpointCode and kMaxStopCode are treated as stop()
200// instructions (see Assembler::stop()).
201// - Breaks larger than kMaxStopCode are simple breaks, dropping you into the
202// debugger.
203const uint32_t kMaxWatchpointCode = 31;
204const uint32_t kMaxStopCode = 127;
205STATIC_ASSERT(kMaxWatchpointCode < kMaxStopCode);
206
207
208// ----- Fields offset and length.
209const int kOpcodeShift = 26;
210const int kOpcodeBits = 6;
211const int kRsShift = 21;
212const int kRsBits = 5;
213const int kRtShift = 16;
214const int kRtBits = 5;
215const int kRdShift = 11;
216const int kRdBits = 5;
217const int kSaShift = 6;
218const int kSaBits = 5;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000219const int kLsaSaBits = 2;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000220const int kFunctionShift = 0;
221const int kFunctionBits = 6;
222const int kLuiShift = 16;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000223const int kBp2Shift = 6;
224const int kBp2Bits = 2;
225const int kBp3Shift = 6;
226const int kBp3Bits = 3;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000227
228const int kImm16Shift = 0;
229const int kImm16Bits = 16;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000230const int kImm18Shift = 0;
231const int kImm18Bits = 18;
232const int kImm19Shift = 0;
233const int kImm19Bits = 19;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000234const int kImm21Shift = 0;
235const int kImm21Bits = 21;
236const int kImm26Shift = 0;
237const int kImm26Bits = 26;
238const int kImm28Shift = 0;
239const int kImm28Bits = 28;
240const int kImm32Shift = 0;
241const int kImm32Bits = 32;
242
243// In branches and jumps immediate fields point to words, not bytes,
244// and are therefore shifted by 2.
245const int kImmFieldShift = 2;
246
247const int kFrBits = 5;
248const int kFrShift = 21;
249const int kFsShift = 11;
250const int kFsBits = 5;
251const int kFtShift = 16;
252const int kFtBits = 5;
253const int kFdShift = 6;
254const int kFdBits = 5;
255const int kFCccShift = 8;
256const int kFCccBits = 3;
257const int kFBccShift = 18;
258const int kFBccBits = 3;
259const int kFBtrueShift = 16;
260const int kFBtrueBits = 1;
261
262// ----- Miscellaneous useful masks.
263// Instruction bit masks.
264const int kOpcodeMask = ((1 << kOpcodeBits) - 1) << kOpcodeShift;
265const int kImm16Mask = ((1 << kImm16Bits) - 1) << kImm16Shift;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000266const int kImm18Mask = ((1 << kImm18Bits) - 1) << kImm18Shift;
267const int kImm19Mask = ((1 << kImm19Bits) - 1) << kImm19Shift;
268const int kImm21Mask = ((1 << kImm21Bits) - 1) << kImm21Shift;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000269const int kImm26Mask = ((1 << kImm26Bits) - 1) << kImm26Shift;
270const int kImm28Mask = ((1 << kImm28Bits) - 1) << kImm28Shift;
271const int kRsFieldMask = ((1 << kRsBits) - 1) << kRsShift;
272const int kRtFieldMask = ((1 << kRtBits) - 1) << kRtShift;
273const int kRdFieldMask = ((1 << kRdBits) - 1) << kRdShift;
274const int kSaFieldMask = ((1 << kSaBits) - 1) << kSaShift;
275const int kFunctionFieldMask = ((1 << kFunctionBits) - 1) << kFunctionShift;
276// Misc masks.
277const int kHiMask = 0xffff << 16;
278const int kLoMask = 0xffff;
279const int kSignMask = 0x80000000;
280const int kJumpAddrMask = (1 << (kImm26Bits + kImmFieldShift)) - 1;
281const int64_t kHi16MaskOf64 = (int64_t)0xffff << 48;
282const int64_t kSe16MaskOf64 = (int64_t)0xffff << 32;
283const int64_t kTh16MaskOf64 = (int64_t)0xffff << 16;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000284const int32_t kJalRawMark = 0x00000000;
285const int32_t kJRawMark = 0xf0000000;
286const int32_t kJumpRawMask = 0xf0000000;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000287
288// ----- MIPS Opcodes and Function Fields.
289// We use this presentation to stay close to the table representation in
290// MIPS32 Architecture For Programmers, Volume II: The MIPS32 Instruction Set.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000291enum Opcode : uint32_t {
292 SPECIAL = 0U << kOpcodeShift,
293 REGIMM = 1U << kOpcodeShift,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000294
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000295 J = ((0U << 3) + 2) << kOpcodeShift,
296 JAL = ((0U << 3) + 3) << kOpcodeShift,
297 BEQ = ((0U << 3) + 4) << kOpcodeShift,
298 BNE = ((0U << 3) + 5) << kOpcodeShift,
299 BLEZ = ((0U << 3) + 6) << kOpcodeShift,
300 BGTZ = ((0U << 3) + 7) << kOpcodeShift,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000301
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000302 ADDI = ((1U << 3) + 0) << kOpcodeShift,
303 ADDIU = ((1U << 3) + 1) << kOpcodeShift,
304 SLTI = ((1U << 3) + 2) << kOpcodeShift,
305 SLTIU = ((1U << 3) + 3) << kOpcodeShift,
306 ANDI = ((1U << 3) + 4) << kOpcodeShift,
307 ORI = ((1U << 3) + 5) << kOpcodeShift,
308 XORI = ((1U << 3) + 6) << kOpcodeShift,
309 LUI = ((1U << 3) + 7) << kOpcodeShift, // LUI/AUI family.
310 DAUI = ((3U << 3) + 5) << kOpcodeShift,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000311
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000312 BEQC = ((2U << 3) + 0) << kOpcodeShift,
313 COP1 = ((2U << 3) + 1) << kOpcodeShift, // Coprocessor 1 class.
314 BEQL = ((2U << 3) + 4) << kOpcodeShift,
315 BNEL = ((2U << 3) + 5) << kOpcodeShift,
316 BLEZL = ((2U << 3) + 6) << kOpcodeShift,
317 BGTZL = ((2U << 3) + 7) << kOpcodeShift,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000318
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000319 DADDI = ((3U << 3) + 0) << kOpcodeShift, // This is also BNEC.
320 DADDIU = ((3U << 3) + 1) << kOpcodeShift,
321 LDL = ((3U << 3) + 2) << kOpcodeShift,
322 LDR = ((3U << 3) + 3) << kOpcodeShift,
323 SPECIAL2 = ((3U << 3) + 4) << kOpcodeShift,
324 SPECIAL3 = ((3U << 3) + 7) << kOpcodeShift,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000325
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000326 LB = ((4U << 3) + 0) << kOpcodeShift,
327 LH = ((4U << 3) + 1) << kOpcodeShift,
328 LWL = ((4U << 3) + 2) << kOpcodeShift,
329 LW = ((4U << 3) + 3) << kOpcodeShift,
330 LBU = ((4U << 3) + 4) << kOpcodeShift,
331 LHU = ((4U << 3) + 5) << kOpcodeShift,
332 LWR = ((4U << 3) + 6) << kOpcodeShift,
333 LWU = ((4U << 3) + 7) << kOpcodeShift,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000334
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000335 SB = ((5U << 3) + 0) << kOpcodeShift,
336 SH = ((5U << 3) + 1) << kOpcodeShift,
337 SWL = ((5U << 3) + 2) << kOpcodeShift,
338 SW = ((5U << 3) + 3) << kOpcodeShift,
339 SDL = ((5U << 3) + 4) << kOpcodeShift,
340 SDR = ((5U << 3) + 5) << kOpcodeShift,
341 SWR = ((5U << 3) + 6) << kOpcodeShift,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000342
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000343 LWC1 = ((6U << 3) + 1) << kOpcodeShift,
344 BC = ((6U << 3) + 2) << kOpcodeShift,
345 LLD = ((6U << 3) + 4) << kOpcodeShift,
346 LDC1 = ((6U << 3) + 5) << kOpcodeShift,
347 POP66 = ((6U << 3) + 6) << kOpcodeShift,
348 LD = ((6U << 3) + 7) << kOpcodeShift,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000349
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000350 PREF = ((6U << 3) + 3) << kOpcodeShift,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000351
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000352 SWC1 = ((7U << 3) + 1) << kOpcodeShift,
353 BALC = ((7U << 3) + 2) << kOpcodeShift,
354 PCREL = ((7U << 3) + 3) << kOpcodeShift,
355 SCD = ((7U << 3) + 4) << kOpcodeShift,
356 SDC1 = ((7U << 3) + 5) << kOpcodeShift,
357 POP76 = ((7U << 3) + 6) << kOpcodeShift,
358 SD = ((7U << 3) + 7) << kOpcodeShift,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000359
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000360 COP1X = ((1U << 4) + 3) << kOpcodeShift,
361
362 // New r6 instruction.
363 POP06 = BLEZ, // bgeuc/bleuc, blezalc, bgezalc
364 POP07 = BGTZ, // bltuc/bgtuc, bgtzalc, bltzalc
365 POP10 = ADDI, // beqzalc, bovc, beqc
366 POP26 = BLEZL, // bgezc, blezc, bgec/blec
367 POP27 = BGTZL, // bgtzc, bltzc, bltc/bgtc
368 POP30 = DADDI, // bnezalc, bnvc, bnec
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000369};
370
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000371enum SecondaryField : uint32_t {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000372 // SPECIAL Encoding of Function Field.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000373 SLL = ((0U << 3) + 0),
374 MOVCI = ((0U << 3) + 1),
375 SRL = ((0U << 3) + 2),
376 SRA = ((0U << 3) + 3),
377 SLLV = ((0U << 3) + 4),
378 LSA = ((0U << 3) + 5),
379 SRLV = ((0U << 3) + 6),
380 SRAV = ((0U << 3) + 7),
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000381
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000382 JR = ((1U << 3) + 0),
383 JALR = ((1U << 3) + 1),
384 MOVZ = ((1U << 3) + 2),
385 MOVN = ((1U << 3) + 3),
386 BREAK = ((1U << 3) + 5),
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000387
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000388 MFHI = ((2U << 3) + 0),
389 CLZ_R6 = ((2U << 3) + 0),
390 CLO_R6 = ((2U << 3) + 1),
391 MFLO = ((2U << 3) + 2),
392 DCLZ_R6 = ((2U << 3) + 2),
393 DCLO_R6 = ((2U << 3) + 3),
394 DSLLV = ((2U << 3) + 4),
395 DLSA = ((2U << 3) + 5),
396 DSRLV = ((2U << 3) + 6),
397 DSRAV = ((2U << 3) + 7),
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000398
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000399 MULT = ((3U << 3) + 0),
400 MULTU = ((3U << 3) + 1),
401 DIV = ((3U << 3) + 2),
402 DIVU = ((3U << 3) + 3),
403 DMULT = ((3U << 3) + 4),
404 DMULTU = ((3U << 3) + 5),
405 DDIV = ((3U << 3) + 6),
406 DDIVU = ((3U << 3) + 7),
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000407
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000408 ADD = ((4U << 3) + 0),
409 ADDU = ((4U << 3) + 1),
410 SUB = ((4U << 3) + 2),
411 SUBU = ((4U << 3) + 3),
412 AND = ((4U << 3) + 4),
413 OR = ((4U << 3) + 5),
414 XOR = ((4U << 3) + 6),
415 NOR = ((4U << 3) + 7),
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000416
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000417 SLT = ((5U << 3) + 2),
418 SLTU = ((5U << 3) + 3),
419 DADD = ((5U << 3) + 4),
420 DADDU = ((5U << 3) + 5),
421 DSUB = ((5U << 3) + 6),
422 DSUBU = ((5U << 3) + 7),
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000423
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000424 TGE = ((6U << 3) + 0),
425 TGEU = ((6U << 3) + 1),
426 TLT = ((6U << 3) + 2),
427 TLTU = ((6U << 3) + 3),
428 TEQ = ((6U << 3) + 4),
429 SELEQZ_S = ((6U << 3) + 5),
430 TNE = ((6U << 3) + 6),
431 SELNEZ_S = ((6U << 3) + 7),
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000432
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000433 DSLL = ((7U << 3) + 0),
434 DSRL = ((7U << 3) + 2),
435 DSRA = ((7U << 3) + 3),
436 DSLL32 = ((7U << 3) + 4),
437 DSRL32 = ((7U << 3) + 6),
438 DSRA32 = ((7U << 3) + 7),
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000439
440 // Multiply integers in r6.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000441 MUL_MUH = ((3U << 3) + 0), // MUL, MUH.
442 MUL_MUH_U = ((3U << 3) + 1), // MUL_U, MUH_U.
443 D_MUL_MUH = ((7U << 2) + 0), // DMUL, DMUH.
444 D_MUL_MUH_U = ((7U << 2) + 1), // DMUL_U, DMUH_U.
445 RINT = ((3U << 3) + 2),
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000446
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000447 MUL_OP = ((0U << 3) + 2),
448 MUH_OP = ((0U << 3) + 3),
449 DIV_OP = ((0U << 3) + 2),
450 MOD_OP = ((0U << 3) + 3),
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000451
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000452 DIV_MOD = ((3U << 3) + 2),
453 DIV_MOD_U = ((3U << 3) + 3),
454 D_DIV_MOD = ((3U << 3) + 6),
455 D_DIV_MOD_U = ((3U << 3) + 7),
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000456
457 // drotr in special4?
458
459 // SPECIAL2 Encoding of Function Field.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000460 MUL = ((0U << 3) + 2),
461 CLZ = ((4U << 3) + 0),
462 CLO = ((4U << 3) + 1),
463 DCLZ = ((4U << 3) + 4),
464 DCLO = ((4U << 3) + 5),
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000465
466 // SPECIAL3 Encoding of Function Field.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000467 EXT = ((0U << 3) + 0),
468 DEXTM = ((0U << 3) + 1),
469 DEXTU = ((0U << 3) + 2),
470 DEXT = ((0U << 3) + 3),
471 INS = ((0U << 3) + 4),
472 DINSM = ((0U << 3) + 5),
473 DINSU = ((0U << 3) + 6),
474 DINS = ((0U << 3) + 7),
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000475
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000476 BSHFL = ((4U << 3) + 0),
477 DBSHFL = ((4U << 3) + 4),
478
479 // SPECIAL3 Encoding of sa Field.
480 BITSWAP = ((0U << 3) + 0),
481 ALIGN = ((0U << 3) + 2),
482 WSBH = ((0U << 3) + 2),
483 SEB = ((2U << 3) + 0),
484 SEH = ((3U << 3) + 0),
485
486 DBITSWAP = ((0U << 3) + 0),
487 DALIGN = ((0U << 3) + 1),
488 DBITSWAP_SA = ((0U << 3) + 0) << kSaShift,
489 DSBH = ((0U << 3) + 2),
490 DSHD = ((0U << 3) + 5),
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000491
492 // REGIMM encoding of rt Field.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000493 BLTZ = ((0U << 3) + 0) << 16,
494 BGEZ = ((0U << 3) + 1) << 16,
495 BLTZAL = ((2U << 3) + 0) << 16,
496 BGEZAL = ((2U << 3) + 1) << 16,
497 BGEZALL = ((2U << 3) + 3) << 16,
498 DAHI = ((0U << 3) + 6) << 16,
499 DATI = ((3U << 3) + 6) << 16,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000500
501 // COP1 Encoding of rs Field.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000502 MFC1 = ((0U << 3) + 0) << 21,
503 DMFC1 = ((0U << 3) + 1) << 21,
504 CFC1 = ((0U << 3) + 2) << 21,
505 MFHC1 = ((0U << 3) + 3) << 21,
506 MTC1 = ((0U << 3) + 4) << 21,
507 DMTC1 = ((0U << 3) + 5) << 21,
508 CTC1 = ((0U << 3) + 6) << 21,
509 MTHC1 = ((0U << 3) + 7) << 21,
510 BC1 = ((1U << 3) + 0) << 21,
511 S = ((2U << 3) + 0) << 21,
512 D = ((2U << 3) + 1) << 21,
513 W = ((2U << 3) + 4) << 21,
514 L = ((2U << 3) + 5) << 21,
515 PS = ((2U << 3) + 6) << 21,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000516 // COP1 Encoding of Function Field When rs=S.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000517
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000518 ADD_S = ((0U << 3) + 0),
519 SUB_S = ((0U << 3) + 1),
520 MUL_S = ((0U << 3) + 2),
521 DIV_S = ((0U << 3) + 3),
522 ABS_S = ((0U << 3) + 5),
523 SQRT_S = ((0U << 3) + 4),
524 MOV_S = ((0U << 3) + 6),
525 NEG_S = ((0U << 3) + 7),
526 ROUND_L_S = ((1U << 3) + 0),
527 TRUNC_L_S = ((1U << 3) + 1),
528 CEIL_L_S = ((1U << 3) + 2),
529 FLOOR_L_S = ((1U << 3) + 3),
530 ROUND_W_S = ((1U << 3) + 4),
531 TRUNC_W_S = ((1U << 3) + 5),
532 CEIL_W_S = ((1U << 3) + 6),
533 FLOOR_W_S = ((1U << 3) + 7),
534 RECIP_S = ((2U << 3) + 5),
535 RSQRT_S = ((2U << 3) + 6),
536 CLASS_S = ((3U << 3) + 3),
537 CVT_D_S = ((4U << 3) + 1),
538 CVT_W_S = ((4U << 3) + 4),
539 CVT_L_S = ((4U << 3) + 5),
540 CVT_PS_S = ((4U << 3) + 6),
541 // COP1 Encoding of Function Field When rs=D.
542 ADD_D = ((0U << 3) + 0),
543 SUB_D = ((0U << 3) + 1),
544 MUL_D = ((0U << 3) + 2),
545 DIV_D = ((0U << 3) + 3),
546 SQRT_D = ((0U << 3) + 4),
547 ABS_D = ((0U << 3) + 5),
548 MOV_D = ((0U << 3) + 6),
549 NEG_D = ((0U << 3) + 7),
550 ROUND_L_D = ((1U << 3) + 0),
551 TRUNC_L_D = ((1U << 3) + 1),
552 CEIL_L_D = ((1U << 3) + 2),
553 FLOOR_L_D = ((1U << 3) + 3),
554 ROUND_W_D = ((1U << 3) + 4),
555 TRUNC_W_D = ((1U << 3) + 5),
556 CEIL_W_D = ((1U << 3) + 6),
557 FLOOR_W_D = ((1U << 3) + 7),
558 RECIP_D = ((2U << 3) + 5),
559 RSQRT_D = ((2U << 3) + 6),
560 CLASS_D = ((3U << 3) + 3),
561 MIN = ((3U << 3) + 4),
562 MINA = ((3U << 3) + 5),
563 MAX = ((3U << 3) + 6),
564 MAXA = ((3U << 3) + 7),
565 CVT_S_D = ((4U << 3) + 0),
566 CVT_W_D = ((4U << 3) + 4),
567 CVT_L_D = ((4U << 3) + 5),
568 C_F_D = ((6U << 3) + 0),
569 C_UN_D = ((6U << 3) + 1),
570 C_EQ_D = ((6U << 3) + 2),
571 C_UEQ_D = ((6U << 3) + 3),
572 C_OLT_D = ((6U << 3) + 4),
573 C_ULT_D = ((6U << 3) + 5),
574 C_OLE_D = ((6U << 3) + 6),
575 C_ULE_D = ((6U << 3) + 7),
576
577 // COP1 Encoding of Function Field When rs=W or L.
578 CVT_S_W = ((4U << 3) + 0),
579 CVT_D_W = ((4U << 3) + 1),
580 CVT_S_L = ((4U << 3) + 0),
581 CVT_D_L = ((4U << 3) + 1),
582 BC1EQZ = ((2U << 2) + 1) << 21,
583 BC1NEZ = ((3U << 2) + 1) << 21,
584 // COP1 CMP positive predicates Bit 5..4 = 00.
585 CMP_AF = ((0U << 3) + 0),
586 CMP_UN = ((0U << 3) + 1),
587 CMP_EQ = ((0U << 3) + 2),
588 CMP_UEQ = ((0U << 3) + 3),
589 CMP_LT = ((0U << 3) + 4),
590 CMP_ULT = ((0U << 3) + 5),
591 CMP_LE = ((0U << 3) + 6),
592 CMP_ULE = ((0U << 3) + 7),
593 CMP_SAF = ((1U << 3) + 0),
594 CMP_SUN = ((1U << 3) + 1),
595 CMP_SEQ = ((1U << 3) + 2),
596 CMP_SUEQ = ((1U << 3) + 3),
597 CMP_SSLT = ((1U << 3) + 4),
598 CMP_SSULT = ((1U << 3) + 5),
599 CMP_SLE = ((1U << 3) + 6),
600 CMP_SULE = ((1U << 3) + 7),
601 // COP1 CMP negative predicates Bit 5..4 = 01.
602 CMP_AT = ((2U << 3) + 0), // Reserved, not implemented.
603 CMP_OR = ((2U << 3) + 1),
604 CMP_UNE = ((2U << 3) + 2),
605 CMP_NE = ((2U << 3) + 3),
606 CMP_UGE = ((2U << 3) + 4), // Reserved, not implemented.
607 CMP_OGE = ((2U << 3) + 5), // Reserved, not implemented.
608 CMP_UGT = ((2U << 3) + 6), // Reserved, not implemented.
609 CMP_OGT = ((2U << 3) + 7), // Reserved, not implemented.
610 CMP_SAT = ((3U << 3) + 0), // Reserved, not implemented.
611 CMP_SOR = ((3U << 3) + 1),
612 CMP_SUNE = ((3U << 3) + 2),
613 CMP_SNE = ((3U << 3) + 3),
614 CMP_SUGE = ((3U << 3) + 4), // Reserved, not implemented.
615 CMP_SOGE = ((3U << 3) + 5), // Reserved, not implemented.
616 CMP_SUGT = ((3U << 3) + 6), // Reserved, not implemented.
617 CMP_SOGT = ((3U << 3) + 7), // Reserved, not implemented.
618
619 SEL = ((2U << 3) + 0),
620 MOVF = ((2U << 3) + 1), // Function field for MOVT.fmt and MOVF.fmt
621 MOVZ_C = ((2U << 3) + 2), // COP1 on FPR registers.
622 MOVN_C = ((2U << 3) + 3), // COP1 on FPR registers.
623 SELEQZ_C = ((2U << 3) + 4), // COP1 on FPR registers.
624 SELNEZ_C = ((2U << 3) + 7), // COP1 on FPR registers.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000625
626 // COP1 Encoding of Function Field When rs=PS.
627 // COP1X Encoding of Function Field.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000628 MADD_D = ((4U << 3) + 1),
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000629
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000630 // PCREL Encoding of rt Field.
631 ADDIUPC = ((0U << 2) + 0),
632 LWPC = ((0U << 2) + 1),
633 LWUPC = ((0U << 2) + 2),
634 LDPC = ((0U << 3) + 6),
635 // reserved ((1U << 3) + 6),
636 AUIPC = ((3U << 3) + 6),
637 ALUIPC = ((3U << 3) + 7),
638
639 // POP66 Encoding of rs Field.
640 JIC = ((0U << 5) + 0),
641
642 // POP76 Encoding of rs Field.
643 JIALC = ((0U << 5) + 0),
644
645 NULLSF = 0U
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000646};
647
648
649// ----- Emulated conditions.
650// On MIPS we use this enum to abstract from conditional branch instructions.
651// The 'U' prefix is used to specify unsigned comparisons.
652// Opposite conditions must be paired as odd/even numbers
653// because 'NegateCondition' function flips LSB to negate condition.
654enum Condition {
655 // Any value < 0 is considered no_condition.
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400656 kNoCondition = -1,
657 overflow = 0,
658 no_overflow = 1,
659 Uless = 2,
660 Ugreater_equal = 3,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000661 Uless_equal = 4,
662 Ugreater = 5,
663 equal = 6,
664 not_equal = 7, // Unordered or Not Equal.
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400665 negative = 8,
666 positive = 9,
667 parity_even = 10,
668 parity_odd = 11,
669 less = 12,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000670 greater_equal = 13,
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400671 less_equal = 14,
672 greater = 15,
673 ueq = 16, // Unordered or Equal.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000674 ogl = 17, // Ordered and Not Equal.
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400675 cc_always = 18,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000676
677 // Aliases.
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400678 carry = Uless,
679 not_carry = Ugreater_equal,
680 zero = equal,
681 eq = equal,
682 not_zero = not_equal,
683 ne = not_equal,
684 nz = not_equal,
685 sign = negative,
686 not_sign = positive,
687 mi = negative,
688 pl = positive,
689 hi = Ugreater,
690 ls = Uless_equal,
691 ge = greater_equal,
692 lt = less,
693 gt = greater,
694 le = less_equal,
695 hs = Ugreater_equal,
696 lo = Uless,
697 al = cc_always,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000698 ult = Uless,
699 uge = Ugreater_equal,
700 ule = Uless_equal,
701 ugt = Ugreater,
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400702 cc_default = kNoCondition
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000703};
704
705
706// Returns the equivalent of !cc.
707// Negation of the default kNoCondition (-1) results in a non-default
708// no_condition value (-2). As long as tests for no_condition check
709// for condition < 0, this will work as expected.
710inline Condition NegateCondition(Condition cc) {
711 DCHECK(cc != cc_always);
712 return static_cast<Condition>(cc ^ 1);
713}
714
715
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000716inline Condition NegateFpuCondition(Condition cc) {
717 DCHECK(cc != cc_always);
718 switch (cc) {
719 case ult:
720 return ge;
721 case ugt:
722 return le;
723 case uge:
724 return lt;
725 case ule:
726 return gt;
727 case lt:
728 return uge;
729 case gt:
730 return ule;
731 case ge:
732 return ult;
733 case le:
734 return ugt;
735 case eq:
736 return ne;
737 case ne:
738 return eq;
739 case ueq:
740 return ogl;
741 case ogl:
742 return ueq;
743 default:
744 return cc;
745 }
746}
747
748
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000749// Commute a condition such that {a cond b == b cond' a}.
750inline Condition CommuteCondition(Condition cc) {
751 switch (cc) {
752 case Uless:
753 return Ugreater;
754 case Ugreater:
755 return Uless;
756 case Ugreater_equal:
757 return Uless_equal;
758 case Uless_equal:
759 return Ugreater_equal;
760 case less:
761 return greater;
762 case greater:
763 return less;
764 case greater_equal:
765 return less_equal;
766 case less_equal:
767 return greater_equal;
768 default:
769 return cc;
770 }
771}
772
773
774// ----- Coprocessor conditions.
775enum FPUCondition {
776 kNoFPUCondition = -1,
777
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000778 F = 0x00, // False.
779 UN = 0x01, // Unordered.
780 EQ = 0x02, // Equal.
781 UEQ = 0x03, // Unordered or Equal.
782 OLT = 0x04, // Ordered or Less Than, on Mips release < 6.
783 LT = 0x04, // Ordered or Less Than, on Mips release >= 6.
784 ULT = 0x05, // Unordered or Less Than.
785 OLE = 0x06, // Ordered or Less Than or Equal, on Mips release < 6.
786 LE = 0x06, // Ordered or Less Than or Equal, on Mips release >= 6.
787 ULE = 0x07, // Unordered or Less Than or Equal.
788
789 // Following constants are available on Mips release >= 6 only.
790 ORD = 0x11, // Ordered, on Mips release >= 6.
791 UNE = 0x12, // Not equal, on Mips release >= 6.
792 NE = 0x13, // Ordered Greater Than or Less Than. on Mips >= 6 only.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000793};
794
795
796// FPU rounding modes.
797enum FPURoundingMode {
798 RN = 0 << 0, // Round to Nearest.
799 RZ = 1 << 0, // Round towards zero.
800 RP = 2 << 0, // Round towards Plus Infinity.
801 RM = 3 << 0, // Round towards Minus Infinity.
802
803 // Aliases.
804 kRoundToNearest = RN,
805 kRoundToZero = RZ,
806 kRoundToPlusInf = RP,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000807 kRoundToMinusInf = RM,
808
809 mode_round = RN,
810 mode_ceil = RP,
811 mode_floor = RM,
812 mode_trunc = RZ
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000813};
814
815const uint32_t kFPURoundingModeMask = 3 << 0;
816
817enum CheckForInexactConversion {
818 kCheckForInexactConversion,
819 kDontCheckForInexactConversion
820};
821
Ben Murdoch097c5b22016-05-18 11:27:45 +0100822enum class MaxMinKind : int { kMin = 0, kMax = 1 };
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000823
824// -----------------------------------------------------------------------------
825// Hints.
826
827// Branch hints are not used on the MIPS. They are defined so that they can
828// appear in shared function signatures, but will be ignored in MIPS
829// implementations.
830enum Hint {
831 no_hint = 0
832};
833
834
835inline Hint NegateHint(Hint hint) {
836 return no_hint;
837}
838
839
840// -----------------------------------------------------------------------------
841// Specific instructions, constants, and masks.
842// These constants are declared in assembler-mips.cc, as they use named
843// registers and other constants.
844
845// addiu(sp, sp, 4) aka Pop() operation or part of Pop(r)
846// operations as post-increment of sp.
847extern const Instr kPopInstruction;
848// addiu(sp, sp, -4) part of Push(r) operation as pre-decrement of sp.
849extern const Instr kPushInstruction;
850// sw(r, MemOperand(sp, 0))
851extern const Instr kPushRegPattern;
852// lw(r, MemOperand(sp, 0))
853extern const Instr kPopRegPattern;
854extern const Instr kLwRegFpOffsetPattern;
855extern const Instr kSwRegFpOffsetPattern;
856extern const Instr kLwRegFpNegOffsetPattern;
857extern const Instr kSwRegFpNegOffsetPattern;
858// A mask for the Rt register for push, pop, lw, sw instructions.
859extern const Instr kRtMask;
860extern const Instr kLwSwInstrTypeMask;
861extern const Instr kLwSwInstrArgumentMask;
862extern const Instr kLwSwOffsetMask;
863
864// Break 0xfffff, reserved for redirected real time call.
865const Instr rtCallRedirInstr = SPECIAL | BREAK | call_rt_redirected << 6;
866// A nop instruction. (Encoding of sll 0 0 0).
867const Instr nopInstr = 0;
868
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000869static constexpr uint64_t OpcodeToBitNumber(Opcode opcode) {
870 return 1ULL << (static_cast<uint32_t>(opcode) >> kOpcodeShift);
871}
872
873
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000874class Instruction {
875 public:
876 enum {
877 kInstrSize = 4,
878 kInstrSizeLog2 = 2,
879 // On MIPS PC cannot actually be directly accessed. We behave as if PC was
880 // always the value of the current instruction being executed.
881 kPCReadOffset = 0
882 };
883
884 // Get the raw instruction bits.
885 inline Instr InstructionBits() const {
886 return *reinterpret_cast<const Instr*>(this);
887 }
888
889 // Set the raw instruction bits to value.
890 inline void SetInstructionBits(Instr value) {
891 *reinterpret_cast<Instr*>(this) = value;
892 }
893
894 // Read one particular bit out of the instruction bits.
895 inline int Bit(int nr) const {
896 return (InstructionBits() >> nr) & 1;
897 }
898
899 // Read a bit field out of the instruction bits.
900 inline int Bits(int hi, int lo) const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000901 return (InstructionBits() >> lo) & ((2U << (hi - lo)) - 1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000902 }
903
904 // Instruction type.
905 enum Type {
906 kRegisterType,
907 kImmediateType,
908 kJumpType,
909 kUnsupported = -1
910 };
911
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000912 enum TypeChecks { NORMAL, EXTRA };
913
914
915 static constexpr uint64_t kOpcodeImmediateTypeMask =
916 OpcodeToBitNumber(REGIMM) | OpcodeToBitNumber(BEQ) |
917 OpcodeToBitNumber(BNE) | OpcodeToBitNumber(BLEZ) |
918 OpcodeToBitNumber(BGTZ) | OpcodeToBitNumber(ADDI) |
919 OpcodeToBitNumber(DADDI) | OpcodeToBitNumber(ADDIU) |
920 OpcodeToBitNumber(DADDIU) | OpcodeToBitNumber(SLTI) |
921 OpcodeToBitNumber(SLTIU) | OpcodeToBitNumber(ANDI) |
922 OpcodeToBitNumber(ORI) | OpcodeToBitNumber(XORI) |
923 OpcodeToBitNumber(LUI) | OpcodeToBitNumber(BEQL) |
924 OpcodeToBitNumber(BNEL) | OpcodeToBitNumber(BLEZL) |
925 OpcodeToBitNumber(BGTZL) | OpcodeToBitNumber(POP66) |
926 OpcodeToBitNumber(POP76) | OpcodeToBitNumber(LB) | OpcodeToBitNumber(LH) |
927 OpcodeToBitNumber(LWL) | OpcodeToBitNumber(LW) | OpcodeToBitNumber(LWU) |
928 OpcodeToBitNumber(LD) | OpcodeToBitNumber(LBU) | OpcodeToBitNumber(LHU) |
929 OpcodeToBitNumber(LWR) | OpcodeToBitNumber(SB) | OpcodeToBitNumber(SH) |
930 OpcodeToBitNumber(SWL) | OpcodeToBitNumber(SW) | OpcodeToBitNumber(SD) |
931 OpcodeToBitNumber(SWR) | OpcodeToBitNumber(LWC1) |
932 OpcodeToBitNumber(LDC1) | OpcodeToBitNumber(SWC1) |
933 OpcodeToBitNumber(SDC1) | OpcodeToBitNumber(PCREL) |
934 OpcodeToBitNumber(DAUI) | OpcodeToBitNumber(BC) | OpcodeToBitNumber(BALC);
935
936#define FunctionFieldToBitNumber(function) (1ULL << function)
937
938 // On r6, DCLZ_R6 aliases to existing MFLO.
939 static const uint64_t kFunctionFieldRegisterTypeMask =
940 FunctionFieldToBitNumber(JR) | FunctionFieldToBitNumber(JALR) |
941 FunctionFieldToBitNumber(BREAK) | FunctionFieldToBitNumber(SLL) |
942 FunctionFieldToBitNumber(DSLL) | FunctionFieldToBitNumber(DSLL32) |
943 FunctionFieldToBitNumber(SRL) | FunctionFieldToBitNumber(DSRL) |
944 FunctionFieldToBitNumber(DSRL32) | FunctionFieldToBitNumber(SRA) |
945 FunctionFieldToBitNumber(DSRA) | FunctionFieldToBitNumber(DSRA32) |
946 FunctionFieldToBitNumber(SLLV) | FunctionFieldToBitNumber(DSLLV) |
947 FunctionFieldToBitNumber(SRLV) | FunctionFieldToBitNumber(DSRLV) |
948 FunctionFieldToBitNumber(SRAV) | FunctionFieldToBitNumber(DSRAV) |
949 FunctionFieldToBitNumber(LSA) | FunctionFieldToBitNumber(DLSA) |
950 FunctionFieldToBitNumber(MFHI) | FunctionFieldToBitNumber(MFLO) |
951 FunctionFieldToBitNumber(MULT) | FunctionFieldToBitNumber(DMULT) |
952 FunctionFieldToBitNumber(MULTU) | FunctionFieldToBitNumber(DMULTU) |
953 FunctionFieldToBitNumber(DIV) | FunctionFieldToBitNumber(DDIV) |
954 FunctionFieldToBitNumber(DIVU) | FunctionFieldToBitNumber(DDIVU) |
955 FunctionFieldToBitNumber(ADD) | FunctionFieldToBitNumber(DADD) |
956 FunctionFieldToBitNumber(ADDU) | FunctionFieldToBitNumber(DADDU) |
957 FunctionFieldToBitNumber(SUB) | FunctionFieldToBitNumber(DSUB) |
958 FunctionFieldToBitNumber(SUBU) | FunctionFieldToBitNumber(DSUBU) |
959 FunctionFieldToBitNumber(AND) | FunctionFieldToBitNumber(OR) |
960 FunctionFieldToBitNumber(XOR) | FunctionFieldToBitNumber(NOR) |
961 FunctionFieldToBitNumber(SLT) | FunctionFieldToBitNumber(SLTU) |
962 FunctionFieldToBitNumber(TGE) | FunctionFieldToBitNumber(TGEU) |
963 FunctionFieldToBitNumber(TLT) | FunctionFieldToBitNumber(TLTU) |
964 FunctionFieldToBitNumber(TEQ) | FunctionFieldToBitNumber(TNE) |
965 FunctionFieldToBitNumber(MOVZ) | FunctionFieldToBitNumber(MOVN) |
966 FunctionFieldToBitNumber(MOVCI) | FunctionFieldToBitNumber(SELEQZ_S) |
967 FunctionFieldToBitNumber(SELNEZ_S);
968
969
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000970 // Get the encoding type of the instruction.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000971 inline Type InstructionType(TypeChecks checks = NORMAL) const;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000972
973
974 // Accessors for the different named fields used in the MIPS encoding.
975 inline Opcode OpcodeValue() const {
976 return static_cast<Opcode>(
977 Bits(kOpcodeShift + kOpcodeBits - 1, kOpcodeShift));
978 }
979
980 inline int RsValue() const {
981 DCHECK(InstructionType() == kRegisterType ||
982 InstructionType() == kImmediateType);
983 return Bits(kRsShift + kRsBits - 1, kRsShift);
984 }
985
986 inline int RtValue() const {
987 DCHECK(InstructionType() == kRegisterType ||
988 InstructionType() == kImmediateType);
989 return Bits(kRtShift + kRtBits - 1, kRtShift);
990 }
991
992 inline int RdValue() const {
993 DCHECK(InstructionType() == kRegisterType);
994 return Bits(kRdShift + kRdBits - 1, kRdShift);
995 }
996
997 inline int SaValue() const {
998 DCHECK(InstructionType() == kRegisterType);
999 return Bits(kSaShift + kSaBits - 1, kSaShift);
1000 }
1001
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001002 inline int LsaSaValue() const {
1003 DCHECK(InstructionType() == kRegisterType);
1004 return Bits(kSaShift + kLsaSaBits - 1, kSaShift);
1005 }
1006
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001007 inline int FunctionValue() const {
1008 DCHECK(InstructionType() == kRegisterType ||
1009 InstructionType() == kImmediateType);
1010 return Bits(kFunctionShift + kFunctionBits - 1, kFunctionShift);
1011 }
1012
1013 inline int FdValue() const {
1014 return Bits(kFdShift + kFdBits - 1, kFdShift);
1015 }
1016
1017 inline int FsValue() const {
1018 return Bits(kFsShift + kFsBits - 1, kFsShift);
1019 }
1020
1021 inline int FtValue() const {
1022 return Bits(kFtShift + kFtBits - 1, kFtShift);
1023 }
1024
1025 inline int FrValue() const {
1026 return Bits(kFrShift + kFrBits -1, kFrShift);
1027 }
1028
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001029 inline int Bp2Value() const {
1030 DCHECK(InstructionType() == kRegisterType);
1031 return Bits(kBp2Shift + kBp2Bits - 1, kBp2Shift);
1032 }
1033
1034 inline int Bp3Value() const {
1035 DCHECK(InstructionType() == kRegisterType);
1036 return Bits(kBp3Shift + kBp3Bits - 1, kBp3Shift);
1037 }
1038
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001039 // Float Compare condition code instruction bits.
1040 inline int FCccValue() const {
1041 return Bits(kFCccShift + kFCccBits - 1, kFCccShift);
1042 }
1043
1044 // Float Branch condition code instruction bits.
1045 inline int FBccValue() const {
1046 return Bits(kFBccShift + kFBccBits - 1, kFBccShift);
1047 }
1048
1049 // Float Branch true/false instruction bit.
1050 inline int FBtrueValue() const {
1051 return Bits(kFBtrueShift + kFBtrueBits - 1, kFBtrueShift);
1052 }
1053
1054 // Return the fields at their original place in the instruction encoding.
1055 inline Opcode OpcodeFieldRaw() const {
1056 return static_cast<Opcode>(InstructionBits() & kOpcodeMask);
1057 }
1058
1059 inline int RsFieldRaw() const {
1060 DCHECK(InstructionType() == kRegisterType ||
1061 InstructionType() == kImmediateType);
1062 return InstructionBits() & kRsFieldMask;
1063 }
1064
1065 // Same as above function, but safe to call within InstructionType().
1066 inline int RsFieldRawNoAssert() const {
1067 return InstructionBits() & kRsFieldMask;
1068 }
1069
1070 inline int RtFieldRaw() const {
1071 DCHECK(InstructionType() == kRegisterType ||
1072 InstructionType() == kImmediateType);
1073 return InstructionBits() & kRtFieldMask;
1074 }
1075
1076 inline int RdFieldRaw() const {
1077 DCHECK(InstructionType() == kRegisterType);
1078 return InstructionBits() & kRdFieldMask;
1079 }
1080
1081 inline int SaFieldRaw() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001082 return InstructionBits() & kSaFieldMask;
1083 }
1084
1085 inline int FunctionFieldRaw() const {
1086 return InstructionBits() & kFunctionFieldMask;
1087 }
1088
1089 // Get the secondary field according to the opcode.
1090 inline int SecondaryValue() const {
1091 Opcode op = OpcodeFieldRaw();
1092 switch (op) {
1093 case SPECIAL:
1094 case SPECIAL2:
1095 return FunctionValue();
1096 case COP1:
1097 return RsValue();
1098 case REGIMM:
1099 return RtValue();
1100 default:
1101 return NULLSF;
1102 }
1103 }
1104
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001105 inline int32_t ImmValue(int bits) const {
1106 DCHECK(InstructionType() == kImmediateType);
1107 return Bits(bits - 1, 0);
1108 }
1109
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001110 inline int32_t Imm16Value() const {
1111 DCHECK(InstructionType() == kImmediateType);
1112 return Bits(kImm16Shift + kImm16Bits - 1, kImm16Shift);
1113 }
1114
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001115 inline int32_t Imm18Value() const {
1116 DCHECK(InstructionType() == kImmediateType);
1117 return Bits(kImm18Shift + kImm18Bits - 1, kImm18Shift);
1118 }
1119
1120 inline int32_t Imm19Value() const {
1121 DCHECK(InstructionType() == kImmediateType);
1122 return Bits(kImm19Shift + kImm19Bits - 1, kImm19Shift);
1123 }
1124
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001125 inline int32_t Imm21Value() const {
1126 DCHECK(InstructionType() == kImmediateType);
1127 return Bits(kImm21Shift + kImm21Bits - 1, kImm21Shift);
1128 }
1129
1130 inline int32_t Imm26Value() const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001131 DCHECK((InstructionType() == kJumpType) ||
1132 (InstructionType() == kImmediateType));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001133 return Bits(kImm26Shift + kImm26Bits - 1, kImm26Shift);
1134 }
1135
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001136 static bool IsForbiddenAfterBranchInstr(Instr instr);
1137
1138 // Say if the instruction should not be used in a branch delay slot or
1139 // immediately after a compact branch.
1140 inline bool IsForbiddenAfterBranch() const {
1141 return IsForbiddenAfterBranchInstr(InstructionBits());
1142 }
1143
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001144 // Say if the instruction 'links'. e.g. jal, bal.
1145 bool IsLinkingInstruction() const;
1146 // Say if the instruction is a break or a trap.
1147 bool IsTrap() const;
1148
1149 // Instructions are read of out a code stream. The only way to get a
1150 // reference to an instruction is to convert a pointer. There is no way
1151 // to allocate or create instances of class Instruction.
1152 // Use the At(pc) function to create references to Instruction.
1153 static Instruction* At(byte* pc) {
1154 return reinterpret_cast<Instruction*>(pc);
1155 }
1156
1157 private:
1158 // We need to prevent the creation of instances of class Instruction.
1159 DISALLOW_IMPLICIT_CONSTRUCTORS(Instruction);
1160};
1161
1162
1163// -----------------------------------------------------------------------------
1164// MIPS assembly various constants.
1165
1166// C/C++ argument slots size.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001167const int kCArgSlotCount = 0;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001168
1169// TODO(plind): below should be based on kPointerSize
1170// TODO(plind): find all usages and remove the needless instructions for n64.
1171const int kCArgsSlotsSize = kCArgSlotCount * Instruction::kInstrSize * 2;
1172
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001173const int kInvalidStackOffset = -1;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001174const int kBranchReturnOffset = 2 * Instruction::kInstrSize;
1175
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001176
1177Instruction::Type Instruction::InstructionType(TypeChecks checks) const {
1178 if (checks == EXTRA) {
1179 if (OpcodeToBitNumber(OpcodeFieldRaw()) & kOpcodeImmediateTypeMask) {
1180 return kImmediateType;
1181 }
1182 }
1183 switch (OpcodeFieldRaw()) {
1184 case SPECIAL:
1185 if (checks == EXTRA) {
1186 if (FunctionFieldToBitNumber(FunctionFieldRaw()) &
1187 kFunctionFieldRegisterTypeMask) {
1188 return kRegisterType;
1189 } else {
1190 return kUnsupported;
1191 }
1192 } else {
1193 return kRegisterType;
1194 }
1195 break;
1196 case SPECIAL2:
1197 switch (FunctionFieldRaw()) {
1198 case MUL:
1199 case CLZ:
1200 case DCLZ:
1201 return kRegisterType;
1202 default:
1203 return kUnsupported;
1204 }
1205 break;
1206 case SPECIAL3:
1207 switch (FunctionFieldRaw()) {
1208 case INS:
Ben Murdoch097c5b22016-05-18 11:27:45 +01001209 case DINS:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001210 case EXT:
1211 case DEXT:
1212 case DEXTM:
1213 case DEXTU:
1214 return kRegisterType;
1215 case BSHFL: {
1216 int sa = SaFieldRaw() >> kSaShift;
1217 switch (sa) {
1218 case BITSWAP:
1219 return kRegisterType;
1220 case WSBH:
1221 case SEB:
1222 case SEH:
1223 return kUnsupported;
1224 }
1225 sa >>= kBp2Bits;
1226 switch (sa) {
1227 case ALIGN:
1228 return kRegisterType;
1229 default:
1230 return kUnsupported;
1231 }
1232 }
1233 case DBSHFL: {
1234 int sa = SaFieldRaw() >> kSaShift;
1235 switch (sa) {
1236 case DBITSWAP:
1237 return kRegisterType;
1238 case DSBH:
1239 case DSHD:
1240 return kUnsupported;
1241 }
1242 sa = SaFieldRaw() >> kSaShift;
1243 sa >>= kBp3Bits;
1244 switch (sa) {
1245 case DALIGN:
1246 return kRegisterType;
1247 default:
1248 return kUnsupported;
1249 }
1250 }
1251 default:
1252 return kUnsupported;
1253 }
1254 break;
1255 case COP1: // Coprocessor instructions.
1256 switch (RsFieldRawNoAssert()) {
1257 case BC1: // Branch on coprocessor condition.
1258 case BC1EQZ:
1259 case BC1NEZ:
1260 return kImmediateType;
1261 default:
1262 return kRegisterType;
1263 }
1264 break;
1265 case COP1X:
1266 return kRegisterType;
1267
1268 // 26 bits immediate type instructions. e.g.: j imm26.
1269 case J:
1270 case JAL:
1271 return kJumpType;
1272
1273 default:
1274 if (checks == NORMAL) {
1275 return kImmediateType;
1276 } else {
1277 return kUnsupported;
1278 }
1279 }
1280 return kUnsupported;
1281}
1282
1283#undef OpcodeToBitNumber
1284#undef FunctionFieldToBitNumber
1285} // namespace internal
1286} // namespace v8
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001287
1288#endif // #ifndef V8_MIPS_CONSTANTS_H_