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.
5 #ifndef V8_MIPS_CONSTANTS_H_
6 #define V8_MIPS_CONSTANTS_H_
7 #include "src/globals.h"
8 // UNIMPLEMENTED_ macro for MIPS.
10 #define UNIMPLEMENTED_MIPS() \
11 v8::internal::PrintF("%s, \tline %d: \tfunction %s not implemented. \n", \
12 __FILE__, __LINE__, __func__)
14 #define UNIMPLEMENTED_MIPS()
17 #define UNSUPPORTED_MIPS() v8::internal::PrintF("Unsupported instruction.\n")
20 kMips32r1 = v8::internal::MIPSr1,
21 kMips32r2 = v8::internal::MIPSr2,
22 kMips32r6 = v8::internal::MIPSr6,
26 #ifdef _MIPS_ARCH_MIPS32R2
27 static const ArchVariants kArchVariant = kMips32r2;
28 #elif _MIPS_ARCH_MIPS32R6
29 static const ArchVariants kArchVariant = kMips32r6;
30 #elif _MIPS_ARCH_LOONGSON
31 // The loongson flag refers to the LOONGSON architectures based on MIPS-III,
32 // which predates (and is a subset of) the mips32r2 and r1 architectures.
33 static const ArchVariants kArchVariant = kLoongson;
34 #elif _MIPS_ARCH_MIPS32RX
35 // This flags referred to compatibility mode that creates universal code that
36 // can run on any MIPS32 architecture revision. The dynamically generated code
37 // by v8 is specialized for the MIPS host detected in runtime probing.
38 static const ArchVariants kArchVariant = kMips32r1;
40 static const ArchVariants kArchVariant = kMips32r1;
48 #if defined(V8_TARGET_LITTLE_ENDIAN)
49 static const Endianness kArchEndian = kLittle;
50 #elif defined(V8_TARGET_BIG_ENDIAN)
51 static const Endianness kArchEndian = kBig;
53 #error Unknown endianness
62 #if defined(FPU_MODE_FP32)
63 static const FpuMode kFpuMode = kFP32;
64 #elif defined(FPU_MODE_FP64)
65 static const FpuMode kFpuMode = kFP64;
66 #elif defined(FPU_MODE_FPXX)
67 static const FpuMode kFpuMode = kFPXX;
69 static const FpuMode kFpuMode = kFP32;
72 #if(defined(__mips_hard_float) && __mips_hard_float != 0)
73 // Use floating-point coprocessor instructions. This flag is raised when
74 // -mhard-float is passed to the compiler.
75 const bool IsMipsSoftFloatABI = false;
76 #elif(defined(__mips_soft_float) && __mips_soft_float != 0)
77 // This flag is raised when -msoft-float is passed to the compiler.
78 // Although FPU is a base requirement for v8, soft-float ABI is used
79 // on soft-float systems with FPU kernel emulation.
80 const bool IsMipsSoftFloatABI = true;
82 const bool IsMipsSoftFloatABI = true;
85 #if defined(V8_TARGET_LITTLE_ENDIAN)
86 const uint32_t kHoleNanUpper32Offset = 4;
87 const uint32_t kHoleNanLower32Offset = 0;
88 #elif defined(V8_TARGET_BIG_ENDIAN)
89 const uint32_t kHoleNanUpper32Offset = 0;
90 const uint32_t kHoleNanLower32Offset = 4;
92 #error Unknown endianness
96 #define IsFp64Mode() \
99 #define IsFp64Mode() \
100 (CpuFeatures::IsSupported(FP64FPU))
103 #ifndef _MIPS_ARCH_MIPS32RX
104 #define IsMipsArchVariant(check) \
105 (kArchVariant == check)
107 #define IsMipsArchVariant(check) \
108 (CpuFeatures::IsSupported(static_cast<CpuFeature>(check)))
112 #define __STDC_FORMAT_MACROS
113 #include <inttypes.h>
115 // Defines constants and accessor classes to assemble, disassemble and
116 // simulate MIPS32 instructions.
118 // See: MIPS32 Architecture For Programmers
119 // Volume II: The MIPS32 Instruction Set
120 // Try www.cs.cornell.edu/courses/cs3410/2008fa/MIPS_Vol2.pdf.
125 // -----------------------------------------------------------------------------
126 // Registers and FPURegisters.
128 // Number of general purpose registers.
129 const int kNumRegisters = 32;
130 const int kInvalidRegister = -1;
132 // Number of registers with HI, LO, and pc.
133 const int kNumSimuRegisters = 35;
135 // In the simulator, the PC register is simulated as the 34th register.
136 const int kPCRegister = 34;
138 // Number coprocessor registers.
139 const int kNumFPURegisters = 32;
140 const int kInvalidFPURegister = -1;
142 // FPU (coprocessor 1) control registers. Currently only FCSR is implemented.
143 const int kFCSRRegister = 31;
144 const int kInvalidFPUControlRegister = -1;
145 const uint32_t kFPUInvalidResult = static_cast<uint32_t>(1 << 31) - 1;
146 const uint64_t kFPU64InvalidResult =
147 static_cast<uint64_t>(static_cast<uint64_t>(1) << 63) - 1;
150 const uint32_t kFCSRInexactFlagBit = 2;
151 const uint32_t kFCSRUnderflowFlagBit = 3;
152 const uint32_t kFCSROverflowFlagBit = 4;
153 const uint32_t kFCSRDivideByZeroFlagBit = 5;
154 const uint32_t kFCSRInvalidOpFlagBit = 6;
156 const uint32_t kFCSRInexactFlagMask = 1 << kFCSRInexactFlagBit;
157 const uint32_t kFCSRUnderflowFlagMask = 1 << kFCSRUnderflowFlagBit;
158 const uint32_t kFCSROverflowFlagMask = 1 << kFCSROverflowFlagBit;
159 const uint32_t kFCSRDivideByZeroFlagMask = 1 << kFCSRDivideByZeroFlagBit;
160 const uint32_t kFCSRInvalidOpFlagMask = 1 << kFCSRInvalidOpFlagBit;
162 const uint32_t kFCSRFlagMask =
163 kFCSRInexactFlagMask |
164 kFCSRUnderflowFlagMask |
165 kFCSROverflowFlagMask |
166 kFCSRDivideByZeroFlagMask |
167 kFCSRInvalidOpFlagMask;
169 const uint32_t kFCSRExceptionFlagMask = kFCSRFlagMask ^ kFCSRInexactFlagMask;
171 // 'pref' instruction hints
172 const int32_t kPrefHintLoad = 0;
173 const int32_t kPrefHintStore = 1;
174 const int32_t kPrefHintLoadStreamed = 4;
175 const int32_t kPrefHintStoreStreamed = 5;
176 const int32_t kPrefHintLoadRetained = 6;
177 const int32_t kPrefHintStoreRetained = 7;
178 const int32_t kPrefHintWritebackInvalidate = 25;
179 const int32_t kPrefHintPrepareForStore = 30;
181 // Helper functions for converting between register numbers and names.
184 // Return the name of the register.
185 static const char* Name(int reg);
187 // Lookup the register number for the name provided.
188 static int Number(const char* name);
190 struct RegisterAlias {
195 static const int32_t kMaxValue = 0x7fffffff;
196 static const int32_t kMinValue = 0x80000000;
199 static const char* names_[kNumSimuRegisters];
200 static const RegisterAlias aliases_[];
203 // Helper functions for converting between register numbers and names.
206 // Return the name of the register.
207 static const char* Name(int reg);
209 // Lookup the register number for the name provided.
210 static int Number(const char* name);
212 struct RegisterAlias {
218 static const char* names_[kNumFPURegisters];
219 static const RegisterAlias aliases_[];
223 // -----------------------------------------------------------------------------
224 // Instructions encoding constants.
226 // On MIPS all instructions are 32 bits.
227 typedef int32_t Instr;
229 // Special Software Interrupt codes when used in the presence of the MIPS
231 enum SoftwareInterruptCodes {
232 // Transition to C code.
233 call_rt_redirected = 0xfffff
236 // On MIPS Simulator breakpoints can have different codes:
237 // - Breaks between 0 and kMaxWatchpointCode are treated as simple watchpoints,
238 // the simulator will run through them and print the registers.
239 // - Breaks between kMaxWatchpointCode and kMaxStopCode are treated as stop()
240 // instructions (see Assembler::stop()).
241 // - Breaks larger than kMaxStopCode are simple breaks, dropping you into the
243 const uint32_t kMaxWatchpointCode = 31;
244 const uint32_t kMaxStopCode = 127;
245 STATIC_ASSERT(kMaxWatchpointCode < kMaxStopCode);
248 // ----- Fields offset and length.
249 const int kOpcodeShift = 26;
250 const int kOpcodeBits = 6;
251 const int kRsShift = 21;
252 const int kRsBits = 5;
253 const int kRtShift = 16;
254 const int kRtBits = 5;
255 const int kRdShift = 11;
256 const int kRdBits = 5;
257 const int kSaShift = 6;
258 const int kSaBits = 5;
259 const int kFunctionShift = 0;
260 const int kFunctionBits = 6;
261 const int kLuiShift = 16;
262 const int kBp2Shift = 6;
263 const int kBp2Bits = 2;
265 const int kImm16Shift = 0;
266 const int kImm16Bits = 16;
267 const int kImm18Shift = 0;
268 const int kImm18Bits = 18;
269 const int kImm19Shift = 0;
270 const int kImm19Bits = 19;
271 const int kImm21Shift = 0;
272 const int kImm21Bits = 21;
273 const int kImm26Shift = 0;
274 const int kImm26Bits = 26;
275 const int kImm28Shift = 0;
276 const int kImm28Bits = 28;
277 const int kImm32Shift = 0;
278 const int kImm32Bits = 32;
280 // In branches and jumps immediate fields point to words, not bytes,
281 // and are therefore shifted by 2.
282 const int kImmFieldShift = 2;
284 const int kFrBits = 5;
285 const int kFrShift = 21;
286 const int kFsShift = 11;
287 const int kFsBits = 5;
288 const int kFtShift = 16;
289 const int kFtBits = 5;
290 const int kFdShift = 6;
291 const int kFdBits = 5;
292 const int kFCccShift = 8;
293 const int kFCccBits = 3;
294 const int kFBccShift = 18;
295 const int kFBccBits = 3;
296 const int kFBtrueShift = 16;
297 const int kFBtrueBits = 1;
299 // ----- Miscellaneous useful masks.
300 // Instruction bit masks.
301 const int kOpcodeMask = ((1 << kOpcodeBits) - 1) << kOpcodeShift;
302 const int kImm16Mask = ((1 << kImm16Bits) - 1) << kImm16Shift;
303 const int kImm18Mask = ((1 << kImm18Bits) - 1) << kImm18Shift;
304 const int kImm19Mask = ((1 << kImm19Bits) - 1) << kImm19Shift;
305 const int kImm21Mask = ((1 << kImm21Bits) - 1) << kImm21Shift;
306 const int kImm26Mask = ((1 << kImm26Bits) - 1) << kImm26Shift;
307 const int kImm28Mask = ((1 << kImm28Bits) - 1) << kImm28Shift;
308 const int kRsFieldMask = ((1 << kRsBits) - 1) << kRsShift;
309 const int kRtFieldMask = ((1 << kRtBits) - 1) << kRtShift;
310 const int kRdFieldMask = ((1 << kRdBits) - 1) << kRdShift;
311 const int kSaFieldMask = ((1 << kSaBits) - 1) << kSaShift;
312 const int kFunctionFieldMask = ((1 << kFunctionBits) - 1) << kFunctionShift;
314 const int kHiMask = 0xffff << 16;
315 const int kLoMask = 0xffff;
316 const int kSignMask = 0x80000000;
317 const int kJumpAddrMask = (1 << (kImm26Bits + kImmFieldShift)) - 1;
319 // ----- MIPS Opcodes and Function Fields.
320 // We use this presentation to stay close to the table representation in
321 // MIPS32 Architecture For Programmers, Volume II: The MIPS32 Instruction Set.
323 SPECIAL = 0 << kOpcodeShift,
324 REGIMM = 1 << kOpcodeShift,
326 J = ((0 << 3) + 2) << kOpcodeShift,
327 JAL = ((0 << 3) + 3) << kOpcodeShift,
328 BEQ = ((0 << 3) + 4) << kOpcodeShift,
329 BNE = ((0 << 3) + 5) << kOpcodeShift,
330 BLEZ = ((0 << 3) + 6) << kOpcodeShift,
331 BGTZ = ((0 << 3) + 7) << kOpcodeShift,
333 ADDI = ((1 << 3) + 0) << kOpcodeShift,
334 ADDIU = ((1 << 3) + 1) << kOpcodeShift,
335 SLTI = ((1 << 3) + 2) << kOpcodeShift,
336 SLTIU = ((1 << 3) + 3) << kOpcodeShift,
337 ANDI = ((1 << 3) + 4) << kOpcodeShift,
338 ORI = ((1 << 3) + 5) << kOpcodeShift,
339 XORI = ((1 << 3) + 6) << kOpcodeShift,
340 LUI = ((1 << 3) + 7) << kOpcodeShift, // LUI/AUI family.
342 BEQC = ((2 << 3) + 0) << kOpcodeShift,
343 COP1 = ((2 << 3) + 1) << kOpcodeShift, // Coprocessor 1 class.
344 BEQL = ((2 << 3) + 4) << kOpcodeShift,
345 BNEL = ((2 << 3) + 5) << kOpcodeShift,
346 BLEZL = ((2 << 3) + 6) << kOpcodeShift,
347 BGTZL = ((2 << 3) + 7) << kOpcodeShift,
349 DADDI = ((3 << 3) + 0) << kOpcodeShift, // This is also BNEC.
350 SPECIAL2 = ((3 << 3) + 4) << kOpcodeShift,
351 SPECIAL3 = ((3 << 3) + 7) << kOpcodeShift,
353 LB = ((4 << 3) + 0) << kOpcodeShift,
354 LH = ((4 << 3) + 1) << kOpcodeShift,
355 LWL = ((4 << 3) + 2) << kOpcodeShift,
356 LW = ((4 << 3) + 3) << kOpcodeShift,
357 LBU = ((4 << 3) + 4) << kOpcodeShift,
358 LHU = ((4 << 3) + 5) << kOpcodeShift,
359 LWR = ((4 << 3) + 6) << kOpcodeShift,
360 SB = ((5 << 3) + 0) << kOpcodeShift,
361 SH = ((5 << 3) + 1) << kOpcodeShift,
362 SWL = ((5 << 3) + 2) << kOpcodeShift,
363 SW = ((5 << 3) + 3) << kOpcodeShift,
364 SWR = ((5 << 3) + 6) << kOpcodeShift,
366 LWC1 = ((6 << 3) + 1) << kOpcodeShift,
367 BC = ((6 << 3) + 2) << kOpcodeShift,
368 LDC1 = ((6 << 3) + 5) << kOpcodeShift,
369 POP66 = ((6 << 3) + 6) << kOpcodeShift,
371 PREF = ((6 << 3) + 3) << kOpcodeShift,
373 SWC1 = ((7 << 3) + 1) << kOpcodeShift,
374 BALC = ((7 << 3) + 2) << kOpcodeShift,
375 PCREL = ((7 << 3) + 3) << kOpcodeShift,
376 SDC1 = ((7 << 3) + 5) << kOpcodeShift,
377 POP76 = ((7 << 3) + 6) << kOpcodeShift,
379 COP1X = ((1 << 4) + 3) << kOpcodeShift
382 enum SecondaryField {
383 // SPECIAL Encoding of Function Field.
384 SLL = ((0 << 3) + 0),
385 MOVCI = ((0 << 3) + 1),
386 SRL = ((0 << 3) + 2),
387 SRA = ((0 << 3) + 3),
388 SLLV = ((0 << 3) + 4),
389 SRLV = ((0 << 3) + 6),
390 SRAV = ((0 << 3) + 7),
393 JALR = ((1 << 3) + 1),
394 MOVZ = ((1 << 3) + 2),
395 MOVN = ((1 << 3) + 3),
396 BREAK = ((1 << 3) + 5),
398 MFHI = ((2 << 3) + 0),
399 CLZ_R6 = ((2 << 3) + 0),
400 CLO_R6 = ((2 << 3) + 1),
401 MFLO = ((2 << 3) + 2),
403 MULT = ((3 << 3) + 0),
404 MULTU = ((3 << 3) + 1),
405 DIV = ((3 << 3) + 2),
406 DIVU = ((3 << 3) + 3),
408 ADD = ((4 << 3) + 0),
409 ADDU = ((4 << 3) + 1),
410 SUB = ((4 << 3) + 2),
411 SUBU = ((4 << 3) + 3),
412 AND = ((4 << 3) + 4),
414 XOR = ((4 << 3) + 6),
415 NOR = ((4 << 3) + 7),
417 SLT = ((5 << 3) + 2),
418 SLTU = ((5 << 3) + 3),
420 TGE = ((6 << 3) + 0),
421 TGEU = ((6 << 3) + 1),
422 TLT = ((6 << 3) + 2),
423 TLTU = ((6 << 3) + 3),
424 TEQ = ((6 << 3) + 4),
425 SELEQZ_S = ((6 << 3) + 5),
426 TNE = ((6 << 3) + 6),
427 SELNEZ_S = ((6 << 3) + 7),
429 // Multiply integers in r6.
430 MUL_MUH = ((3 << 3) + 0), // MUL, MUH.
431 MUL_MUH_U = ((3 << 3) + 1), // MUL_U, MUH_U.
432 RINT = ((3 << 3) + 2),
434 MUL_OP = ((0 << 3) + 2),
435 MUH_OP = ((0 << 3) + 3),
436 DIV_OP = ((0 << 3) + 2),
437 MOD_OP = ((0 << 3) + 3),
439 DIV_MOD = ((3 << 3) + 2),
440 DIV_MOD_U = ((3 << 3) + 3),
442 // SPECIAL2 Encoding of Function Field.
443 MUL = ((0 << 3) + 2),
444 CLZ = ((4 << 3) + 0),
445 CLO = ((4 << 3) + 1),
447 // SPECIAL3 Encoding of Function Field.
448 EXT = ((0 << 3) + 0),
449 INS = ((0 << 3) + 4),
450 BSHFL = ((4 << 3) + 0),
452 // SPECIAL3 Encoding of sa Field.
453 BITSWAP = ((0 << 3) + 0),
454 ALIGN = ((0 << 3) + 2),
455 WSBH = ((0 << 3) + 2),
456 SEB = ((2 << 3) + 0),
457 SEH = ((3 << 3) + 0),
459 // REGIMM encoding of rt Field.
460 BLTZ = ((0 << 3) + 0) << 16,
461 BGEZ = ((0 << 3) + 1) << 16,
462 BLTZAL = ((2 << 3) + 0) << 16,
463 BGEZAL = ((2 << 3) + 1) << 16,
464 BGEZALL = ((2 << 3) + 3) << 16,
466 // COP1 Encoding of rs Field.
467 MFC1 = ((0 << 3) + 0) << 21,
468 CFC1 = ((0 << 3) + 2) << 21,
469 MFHC1 = ((0 << 3) + 3) << 21,
470 MTC1 = ((0 << 3) + 4) << 21,
471 CTC1 = ((0 << 3) + 6) << 21,
472 MTHC1 = ((0 << 3) + 7) << 21,
473 BC1 = ((1 << 3) + 0) << 21,
474 S = ((2 << 3) + 0) << 21,
475 D = ((2 << 3) + 1) << 21,
476 W = ((2 << 3) + 4) << 21,
477 L = ((2 << 3) + 5) << 21,
478 PS = ((2 << 3) + 6) << 21,
479 // COP1 Encoding of Function Field When rs=S.
481 ADD_S = ((0 << 3) + 0),
482 SUB_S = ((0 << 3) + 1),
483 MUL_S = ((0 << 3) + 2),
484 DIV_S = ((0 << 3) + 3),
485 ABS_S = ((0 << 3) + 5),
486 SQRT_S = ((0 << 3) + 4),
487 MOV_S = ((0 << 3) + 6),
488 NEG_S = ((0 << 3) + 7),
489 ROUND_L_S = ((1 << 3) + 0),
490 TRUNC_L_S = ((1 << 3) + 1),
491 CEIL_L_S = ((1 << 3) + 2),
492 FLOOR_L_S = ((1 << 3) + 3),
493 ROUND_W_S = ((1 << 3) + 4),
494 TRUNC_W_S = ((1 << 3) + 5),
495 CEIL_W_S = ((1 << 3) + 6),
496 FLOOR_W_S = ((1 << 3) + 7),
497 RECIP_S = ((2 << 3) + 5),
498 RSQRT_S = ((2 << 3) + 6),
499 CLASS_S = ((3 << 3) + 3),
500 CVT_D_S = ((4 << 3) + 1),
501 CVT_W_S = ((4 << 3) + 4),
502 CVT_L_S = ((4 << 3) + 5),
503 CVT_PS_S = ((4 << 3) + 6),
505 // COP1 Encoding of Function Field When rs=D.
506 ADD_D = ((0 << 3) + 0),
507 SUB_D = ((0 << 3) + 1),
508 MUL_D = ((0 << 3) + 2),
509 DIV_D = ((0 << 3) + 3),
510 SQRT_D = ((0 << 3) + 4),
511 ABS_D = ((0 << 3) + 5),
512 MOV_D = ((0 << 3) + 6),
513 NEG_D = ((0 << 3) + 7),
514 ROUND_L_D = ((1 << 3) + 0),
515 TRUNC_L_D = ((1 << 3) + 1),
516 CEIL_L_D = ((1 << 3) + 2),
517 FLOOR_L_D = ((1 << 3) + 3),
518 ROUND_W_D = ((1 << 3) + 4),
519 TRUNC_W_D = ((1 << 3) + 5),
520 CEIL_W_D = ((1 << 3) + 6),
521 FLOOR_W_D = ((1 << 3) + 7),
522 RECIP_D = ((2 << 3) + 5),
523 RSQRT_D = ((2 << 3) + 6),
524 CLASS_D = ((3 << 3) + 3),
525 MIN = ((3 << 3) + 4),
526 MINA = ((3 << 3) + 5),
527 MAX = ((3 << 3) + 6),
528 MAXA = ((3 << 3) + 7),
529 CVT_S_D = ((4 << 3) + 0),
530 CVT_W_D = ((4 << 3) + 4),
531 CVT_L_D = ((4 << 3) + 5),
532 C_F_D = ((6 << 3) + 0),
533 C_UN_D = ((6 << 3) + 1),
534 C_EQ_D = ((6 << 3) + 2),
535 C_UEQ_D = ((6 << 3) + 3),
536 C_OLT_D = ((6 << 3) + 4),
537 C_ULT_D = ((6 << 3) + 5),
538 C_OLE_D = ((6 << 3) + 6),
539 C_ULE_D = ((6 << 3) + 7),
541 // COP1 Encoding of Function Field When rs=W or L.
542 CVT_S_W = ((4 << 3) + 0),
543 CVT_D_W = ((4 << 3) + 1),
544 CVT_S_L = ((4 << 3) + 0),
545 CVT_D_L = ((4 << 3) + 1),
546 BC1EQZ = ((2 << 2) + 1) << 21,
547 BC1NEZ = ((3 << 2) + 1) << 21,
548 // COP1 CMP positive predicates Bit 5..4 = 00.
549 CMP_AF = ((0 << 3) + 0),
550 CMP_UN = ((0 << 3) + 1),
551 CMP_EQ = ((0 << 3) + 2),
552 CMP_UEQ = ((0 << 3) + 3),
553 CMP_LT = ((0 << 3) + 4),
554 CMP_ULT = ((0 << 3) + 5),
555 CMP_LE = ((0 << 3) + 6),
556 CMP_ULE = ((0 << 3) + 7),
557 CMP_SAF = ((1 << 3) + 0),
558 CMP_SUN = ((1 << 3) + 1),
559 CMP_SEQ = ((1 << 3) + 2),
560 CMP_SUEQ = ((1 << 3) + 3),
561 CMP_SSLT = ((1 << 3) + 4),
562 CMP_SSULT = ((1 << 3) + 5),
563 CMP_SLE = ((1 << 3) + 6),
564 CMP_SULE = ((1 << 3) + 7),
565 // COP1 CMP negative predicates Bit 5..4 = 01.
566 CMP_AT = ((2 << 3) + 0), // Reserved, not implemented.
567 CMP_OR = ((2 << 3) + 1),
568 CMP_UNE = ((2 << 3) + 2),
569 CMP_NE = ((2 << 3) + 3),
570 CMP_UGE = ((2 << 3) + 4), // Reserved, not implemented.
571 CMP_OGE = ((2 << 3) + 5), // Reserved, not implemented.
572 CMP_UGT = ((2 << 3) + 6), // Reserved, not implemented.
573 CMP_OGT = ((2 << 3) + 7), // Reserved, not implemented.
574 CMP_SAT = ((3 << 3) + 0), // Reserved, not implemented.
575 CMP_SOR = ((3 << 3) + 1),
576 CMP_SUNE = ((3 << 3) + 2),
577 CMP_SNE = ((3 << 3) + 3),
578 CMP_SUGE = ((3 << 3) + 4), // Reserved, not implemented.
579 CMP_SOGE = ((3 << 3) + 5), // Reserved, not implemented.
580 CMP_SUGT = ((3 << 3) + 6), // Reserved, not implemented.
581 CMP_SOGT = ((3 << 3) + 7), // Reserved, not implemented.
583 SEL = ((2 << 3) + 0),
584 MOVZ_C = ((2 << 3) + 2),
585 MOVN_C = ((2 << 3) + 3),
586 SELEQZ_C = ((2 << 3) + 4), // COP1 on FPR registers.
587 MOVF = ((2 << 3) + 1), // Function field for MOVT.fmt and MOVF.fmt
588 SELNEZ_C = ((2 << 3) + 7), // COP1 on FPR registers.
589 // COP1 Encoding of Function Field When rs=PS.
590 // COP1X Encoding of Function Field.
591 MADD_D = ((4 << 3) + 1),
593 // PCREL Encoding of rt Field.
594 ADDIUPC = ((0 << 2) + 0),
595 LWPC = ((0 << 2) + 1),
596 AUIPC = ((3 << 3) + 6),
597 ALUIPC = ((3 << 3) + 7),
599 // POP66 Encoding of rs Field.
600 JIC = ((0 << 5) + 0),
602 // POP76 Encoding of rs Field.
603 JIALC = ((0 << 5) + 0),
609 // ----- Emulated conditions.
610 // On MIPS we use this enum to abstract from conditional branch instructions.
611 // The 'U' prefix is used to specify unsigned comparisons.
612 // Opposite conditions must be paired as odd/even numbers
613 // because 'NegateCondition' function flips LSB to negate condition.
615 // Any value < 0 is considered no_condition.
624 not_equal = 7, // Unordered or Not Equal.
633 ueq = 16, // Unordered or Equal.
634 ogl = 17, // Ordered and Not Equal.
639 not_carry = Ugreater_equal,
642 not_zero = not_equal,
659 uge = Ugreater_equal,
662 cc_default = kNoCondition
666 // Returns the equivalent of !cc.
667 // Negation of the default kNoCondition (-1) results in a non-default
668 // no_condition value (-2). As long as tests for no_condition check
669 // for condition < 0, this will work as expected.
670 inline Condition NegateCondition(Condition cc) {
671 DCHECK(cc != cc_always);
672 return static_cast<Condition>(cc ^ 1);
676 inline Condition NegateFpuCondition(Condition cc) {
677 DCHECK(cc != cc_always);
709 // Commute a condition such that {a cond b == b cond' a}.
710 inline Condition CommuteCondition(Condition cc) {
719 return Ugreater_equal;
727 return greater_equal;
734 // ----- Coprocessor conditions.
736 kNoFPUCondition = -1,
739 UN = 0x01, // Unordered.
741 UEQ = 0x03, // Unordered or Equal.
742 OLT = 0x04, // Ordered or Less Than, on Mips release < 6.
743 LT = 0x04, // Ordered or Less Than, on Mips release >= 6.
744 ULT = 0x05, // Unordered or Less Than.
745 OLE = 0x06, // Ordered or Less Than or Equal, on Mips release < 6.
746 LE = 0x06, // Ordered or Less Than or Equal, on Mips release >= 6.
747 ULE = 0x07, // Unordered or Less Than or Equal.
749 // Following constants are available on Mips release >= 6 only.
750 ORD = 0x11, // Ordered, on Mips release >= 6.
751 UNE = 0x12, // Not equal, on Mips release >= 6.
752 NE = 0x13, // Ordered Greater Than or Less Than. on Mips >= 6 only.
756 // FPU rounding modes.
757 enum FPURoundingMode {
758 RN = 0 << 0, // Round to Nearest.
759 RZ = 1 << 0, // Round towards zero.
760 RP = 2 << 0, // Round towards Plus Infinity.
761 RM = 3 << 0, // Round towards Minus Infinity.
764 kRoundToNearest = RN,
766 kRoundToPlusInf = RP,
767 kRoundToMinusInf = RM
770 const uint32_t kFPURoundingModeMask = 3 << 0;
772 enum CheckForInexactConversion {
773 kCheckForInexactConversion,
774 kDontCheckForInexactConversion
778 // -----------------------------------------------------------------------------
781 // Branch hints are not used on the MIPS. They are defined so that they can
782 // appear in shared function signatures, but will be ignored in MIPS
789 inline Hint NegateHint(Hint hint) {
794 // -----------------------------------------------------------------------------
795 // Specific instructions, constants, and masks.
796 // These constants are declared in assembler-mips.cc, as they use named
797 // registers and other constants.
799 // addiu(sp, sp, 4) aka Pop() operation or part of Pop(r)
800 // operations as post-increment of sp.
801 extern const Instr kPopInstruction;
802 // addiu(sp, sp, -4) part of Push(r) operation as pre-decrement of sp.
803 extern const Instr kPushInstruction;
804 // sw(r, MemOperand(sp, 0))
805 extern const Instr kPushRegPattern;
806 // lw(r, MemOperand(sp, 0))
807 extern const Instr kPopRegPattern;
808 extern const Instr kLwRegFpOffsetPattern;
809 extern const Instr kSwRegFpOffsetPattern;
810 extern const Instr kLwRegFpNegOffsetPattern;
811 extern const Instr kSwRegFpNegOffsetPattern;
812 // A mask for the Rt register for push, pop, lw, sw instructions.
813 extern const Instr kRtMask;
814 extern const Instr kLwSwInstrTypeMask;
815 extern const Instr kLwSwInstrArgumentMask;
816 extern const Instr kLwSwOffsetMask;
818 // Break 0xfffff, reserved for redirected real time call.
819 const Instr rtCallRedirInstr = SPECIAL | BREAK | call_rt_redirected << 6;
820 // A nop instruction. (Encoding of sll 0 0 0).
821 const Instr nopInstr = 0;
829 // On MIPS PC cannot actually be directly accessed. We behave as if PC was
830 // always the value of the current instruction being executed.
834 // Get the raw instruction bits.
835 inline Instr InstructionBits() const {
836 return *reinterpret_cast<const Instr*>(this);
839 // Set the raw instruction bits to value.
840 inline void SetInstructionBits(Instr value) {
841 *reinterpret_cast<Instr*>(this) = value;
844 // Read one particular bit out of the instruction bits.
845 inline int Bit(int nr) const {
846 return (InstructionBits() >> nr) & 1;
849 // Read a bit field out of the instruction bits.
850 inline int Bits(int hi, int lo) const {
851 return (InstructionBits() >> lo) & ((2 << (hi - lo)) - 1);
862 enum TypeChecks { NORMAL, EXTRA };
865 #define OpcodeToBitNumber(opcode) \
866 (1ULL << (static_cast<uint32_t>(opcode) >> kOpcodeShift))
868 static const uint64_t kOpcodeImmediateTypeMask =
869 OpcodeToBitNumber(REGIMM) | OpcodeToBitNumber(BEQ) |
870 OpcodeToBitNumber(BNE) | OpcodeToBitNumber(BLEZ) |
871 OpcodeToBitNumber(BGTZ) | OpcodeToBitNumber(ADDI) |
872 OpcodeToBitNumber(DADDI) | OpcodeToBitNumber(ADDIU) |
873 OpcodeToBitNumber(SLTI) | OpcodeToBitNumber(SLTIU) |
874 OpcodeToBitNumber(ANDI) | OpcodeToBitNumber(ORI) |
875 OpcodeToBitNumber(XORI) | OpcodeToBitNumber(LUI) |
876 OpcodeToBitNumber(BEQL) | OpcodeToBitNumber(BNEL) |
877 OpcodeToBitNumber(BLEZL) | OpcodeToBitNumber(BGTZL) |
878 OpcodeToBitNumber(POP66) | OpcodeToBitNumber(POP76) |
879 OpcodeToBitNumber(LB) | OpcodeToBitNumber(LH) | OpcodeToBitNumber(LWL) |
880 OpcodeToBitNumber(LW) | OpcodeToBitNumber(LBU) | OpcodeToBitNumber(LHU) |
881 OpcodeToBitNumber(LWR) | OpcodeToBitNumber(SB) | OpcodeToBitNumber(SH) |
882 OpcodeToBitNumber(SWL) | OpcodeToBitNumber(SW) | OpcodeToBitNumber(SWR) |
883 OpcodeToBitNumber(LWC1) | OpcodeToBitNumber(LDC1) |
884 OpcodeToBitNumber(SWC1) | OpcodeToBitNumber(SDC1) |
885 OpcodeToBitNumber(PCREL) | OpcodeToBitNumber(BC) |
886 OpcodeToBitNumber(BALC);
888 #define FunctionFieldToBitNumber(function) (1ULL << function)
890 static const uint64_t kFunctionFieldRegisterTypeMask =
891 FunctionFieldToBitNumber(JR) | FunctionFieldToBitNumber(JALR) |
892 FunctionFieldToBitNumber(BREAK) | FunctionFieldToBitNumber(SLL) |
893 FunctionFieldToBitNumber(SRL) | FunctionFieldToBitNumber(SRA) |
894 FunctionFieldToBitNumber(SLLV) | FunctionFieldToBitNumber(SRLV) |
895 FunctionFieldToBitNumber(SRAV) | FunctionFieldToBitNumber(MFHI) |
896 FunctionFieldToBitNumber(MFLO) | FunctionFieldToBitNumber(MULT) |
897 FunctionFieldToBitNumber(MULTU) | FunctionFieldToBitNumber(DIV) |
898 FunctionFieldToBitNumber(DIVU) | FunctionFieldToBitNumber(ADD) |
899 FunctionFieldToBitNumber(ADDU) | FunctionFieldToBitNumber(SUB) |
900 FunctionFieldToBitNumber(SUBU) | FunctionFieldToBitNumber(AND) |
901 FunctionFieldToBitNumber(OR) | FunctionFieldToBitNumber(XOR) |
902 FunctionFieldToBitNumber(NOR) | FunctionFieldToBitNumber(SLT) |
903 FunctionFieldToBitNumber(SLTU) | FunctionFieldToBitNumber(TGE) |
904 FunctionFieldToBitNumber(TGEU) | FunctionFieldToBitNumber(TLT) |
905 FunctionFieldToBitNumber(TLTU) | FunctionFieldToBitNumber(TEQ) |
906 FunctionFieldToBitNumber(TNE) | FunctionFieldToBitNumber(MOVZ) |
907 FunctionFieldToBitNumber(MOVN) | FunctionFieldToBitNumber(MOVCI) |
908 FunctionFieldToBitNumber(SELEQZ_S) | FunctionFieldToBitNumber(SELNEZ_S);
911 // Get the encoding type of the instruction.
912 inline Type InstructionType(TypeChecks checks = NORMAL) const;
914 // Accessors for the different named fields used in the MIPS encoding.
915 inline Opcode OpcodeValue() const {
916 return static_cast<Opcode>(
917 Bits(kOpcodeShift + kOpcodeBits - 1, kOpcodeShift));
920 inline int RsValue() const {
921 DCHECK(InstructionType() == kRegisterType ||
922 InstructionType() == kImmediateType);
923 return Bits(kRsShift + kRsBits - 1, kRsShift);
926 inline int RtValue() const {
927 DCHECK(InstructionType() == kRegisterType ||
928 InstructionType() == kImmediateType);
929 return Bits(kRtShift + kRtBits - 1, kRtShift);
932 inline int RdValue() const {
933 DCHECK(InstructionType() == kRegisterType);
934 return Bits(kRdShift + kRdBits - 1, kRdShift);
937 inline int SaValue() const {
938 DCHECK(InstructionType() == kRegisterType);
939 return Bits(kSaShift + kSaBits - 1, kSaShift);
942 inline int FunctionValue() const {
943 DCHECK(InstructionType() == kRegisterType ||
944 InstructionType() == kImmediateType);
945 return Bits(kFunctionShift + kFunctionBits - 1, kFunctionShift);
948 inline int FdValue() const {
949 return Bits(kFdShift + kFdBits - 1, kFdShift);
952 inline int FsValue() const {
953 return Bits(kFsShift + kFsBits - 1, kFsShift);
956 inline int FtValue() const {
957 return Bits(kFtShift + kFtBits - 1, kFtShift);
960 inline int FrValue() const {
961 return Bits(kFrShift + kFrBits -1, kFrShift);
964 inline int Bp2Value() const {
965 DCHECK(InstructionType() == kRegisterType);
966 return Bits(kBp2Shift + kBp2Bits - 1, kBp2Shift);
969 // Float Compare condition code instruction bits.
970 inline int FCccValue() const {
971 return Bits(kFCccShift + kFCccBits - 1, kFCccShift);
974 // Float Branch condition code instruction bits.
975 inline int FBccValue() const {
976 return Bits(kFBccShift + kFBccBits - 1, kFBccShift);
979 // Float Branch true/false instruction bit.
980 inline int FBtrueValue() const {
981 return Bits(kFBtrueShift + kFBtrueBits - 1, kFBtrueShift);
984 // Return the fields at their original place in the instruction encoding.
985 inline Opcode OpcodeFieldRaw() const {
986 return static_cast<Opcode>(InstructionBits() & kOpcodeMask);
989 inline int RsFieldRaw() const {
990 DCHECK(InstructionType() == kRegisterType ||
991 InstructionType() == kImmediateType);
992 return InstructionBits() & kRsFieldMask;
995 // Same as above function, but safe to call within InstructionType().
996 inline int RsFieldRawNoAssert() const {
997 return InstructionBits() & kRsFieldMask;
1000 inline int RtFieldRaw() const {
1001 DCHECK(InstructionType() == kRegisterType ||
1002 InstructionType() == kImmediateType);
1003 return InstructionBits() & kRtFieldMask;
1006 inline int RdFieldRaw() const {
1007 DCHECK(InstructionType() == kRegisterType);
1008 return InstructionBits() & kRdFieldMask;
1011 inline int SaFieldRaw() const {
1012 return InstructionBits() & kSaFieldMask;
1015 inline int FunctionFieldRaw() const {
1016 return InstructionBits() & kFunctionFieldMask;
1019 // Get the secondary field according to the opcode.
1020 inline int SecondaryValue() const {
1021 Opcode op = OpcodeFieldRaw();
1025 return FunctionValue();
1035 inline int32_t Imm16Value() const {
1036 DCHECK(InstructionType() == kImmediateType);
1037 return Bits(kImm16Shift + kImm16Bits - 1, kImm16Shift);
1040 inline int32_t Imm18Value() const {
1041 DCHECK(InstructionType() == kImmediateType);
1042 return Bits(kImm18Shift + kImm18Bits - 1, kImm18Shift);
1045 inline int32_t Imm19Value() const {
1046 DCHECK(InstructionType() == kImmediateType);
1047 return Bits(kImm19Shift + kImm19Bits - 1, kImm19Shift);
1050 inline int32_t Imm21Value() const {
1051 DCHECK(InstructionType() == kImmediateType);
1052 return Bits(kImm21Shift + kImm21Bits - 1, kImm21Shift);
1055 inline int32_t Imm26Value() const {
1056 DCHECK((InstructionType() == kJumpType) ||
1057 (InstructionType() == kImmediateType));
1058 return Bits(kImm26Shift + kImm26Bits - 1, kImm26Shift);
1061 // Say if the instruction should not be used in a branch delay slot.
1062 bool IsForbiddenInBranchDelay() const;
1063 // Say if the instruction 'links'. e.g. jal, bal.
1064 bool IsLinkingInstruction() const;
1065 // Say if the instruction is a break or a trap.
1066 bool IsTrap() const;
1068 // Instructions are read of out a code stream. The only way to get a
1069 // reference to an instruction is to convert a pointer. There is no way
1070 // to allocate or create instances of class Instruction.
1071 // Use the At(pc) function to create references to Instruction.
1072 static Instruction* At(byte* pc) {
1073 return reinterpret_cast<Instruction*>(pc);
1077 // We need to prevent the creation of instances of class Instruction.
1078 DISALLOW_IMPLICIT_CONSTRUCTORS(Instruction);
1082 // -----------------------------------------------------------------------------
1083 // MIPS assembly various constants.
1085 // C/C++ argument slots size.
1086 const int kCArgSlotCount = 4;
1087 const int kCArgsSlotsSize = kCArgSlotCount * Instruction::kInstrSize;
1088 const int kInvalidStackOffset = -1;
1089 // JS argument slots size.
1090 const int kJSArgsSlotsSize = 0 * Instruction::kInstrSize;
1091 // Assembly builtins argument slots size.
1092 const int kBArgsSlotsSize = 0 * Instruction::kInstrSize;
1094 const int kBranchReturnOffset = 2 * Instruction::kInstrSize;
1097 Instruction::Type Instruction::InstructionType(TypeChecks checks) const {
1098 if (checks == EXTRA) {
1099 if (OpcodeToBitNumber(OpcodeFieldRaw()) & kOpcodeImmediateTypeMask) {
1100 return kImmediateType;
1103 switch (OpcodeFieldRaw()) {
1105 if (checks == EXTRA) {
1106 if (FunctionFieldToBitNumber(FunctionFieldRaw()) &
1107 kFunctionFieldRegisterTypeMask) {
1108 return kRegisterType;
1110 return kUnsupported;
1113 return kRegisterType;
1117 switch (FunctionFieldRaw()) {
1120 return kRegisterType;
1122 return kUnsupported;
1126 switch (FunctionFieldRaw()) {
1129 return kRegisterType;
1131 int sa = SaFieldRaw() >> kSaShift;
1134 return kRegisterType;
1138 return kUnsupported;
1143 return kRegisterType;
1145 return kUnsupported;
1149 return kUnsupported;
1152 case COP1: // Coprocessor instructions.
1153 switch (RsFieldRawNoAssert()) {
1154 case BC1: // Branch on coprocessor condition.
1157 return kImmediateType;
1159 return kRegisterType;
1163 return kRegisterType;
1165 // 26 bits immediate type instructions. e.g.: j imm26.
1171 if (checks == NORMAL) {
1172 return kImmediateType;
1174 return kUnsupported;
1179 #undef OpcodeToBitNumber
1180 #undef FunctionFieldToBitNumber
1181 } } // namespace v8::internal
1183 #endif // #ifndef V8_MIPS_CONSTANTS_H_