constants-mips.h revision 18a7ebb96c51b556b3e71ebdefae0b5c7639102f
1// Copyright 2012 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef  V8_MIPS_CONSTANTS_H_
6#define  V8_MIPS_CONSTANTS_H_
7#include "src/globals.h"
8// UNIMPLEMENTED_ macro for MIPS.
9#ifdef DEBUG
10#define UNIMPLEMENTED_MIPS()                                                  \
11  v8::internal::PrintF("%s, \tline %d: \tfunction %s not implemented. \n",    \
12                       __FILE__, __LINE__, __func__)
13#else
14#define UNIMPLEMENTED_MIPS()
15#endif
16
17#define UNSUPPORTED_MIPS() v8::internal::PrintF("Unsupported instruction.\n")
18
19enum ArchVariants {
20  kMips32r1 = v8::internal::MIPSr1,
21  kMips32r2 = v8::internal::MIPSr2,
22  kMips32r6 = v8::internal::MIPSr6,
23  kLoongson
24};
25
26#ifdef _MIPS_ARCH_MIPS32R2
27  static const ArchVariants kArchVariant = kMips32r2;
28#elif _MIPS_ARCH_MIPS32R6
29  static const ArchVariants kArchVariant = kMips32r6;
30#elif _MIPS_ARCH_LOONGSON
31// The loongson flag refers to the LOONGSON architectures based on MIPS-III,
32// which predates (and is a subset of) the mips32r2 and r1 architectures.
33  static const ArchVariants kArchVariant = kLoongson;
34#elif _MIPS_ARCH_MIPS32RX
35// This flags referred to compatibility mode that creates universal code that
36// can run on any MIPS32 architecture revision. The dynamically generated code
37// by v8 is specialized for the MIPS host detected in runtime probing.
38  static const ArchVariants kArchVariant = kMips32r1;
39#else
40  static const ArchVariants kArchVariant = kMips32r1;
41#endif
42
43enum Endianness {
44  kLittle,
45  kBig
46};
47
48#if defined(V8_TARGET_LITTLE_ENDIAN)
49  static const Endianness kArchEndian = kLittle;
50#elif defined(V8_TARGET_BIG_ENDIAN)
51  static const Endianness kArchEndian = kBig;
52#else
53#error Unknown endianness
54#endif
55
56enum FpuMode {
57  kFP32,
58  kFP64,
59  kFPXX
60};
61
62#if defined(FPU_MODE_FP32)
63  static const FpuMode kFpuMode = kFP32;
64#elif defined(FPU_MODE_FP64)
65  static const FpuMode kFpuMode = kFP64;
66#elif defined(FPU_MODE_FPXX)
67  static const FpuMode kFpuMode = kFPXX;
68#else
69  static const FpuMode kFpuMode = kFP32;
70#endif
71
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.
75const 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.
80const bool IsMipsSoftFloatABI = true;
81#else
82const bool IsMipsSoftFloatABI = true;
83#endif
84
85#if defined(V8_TARGET_LITTLE_ENDIAN)
86const uint32_t kHoleNanUpper32Offset = 4;
87const uint32_t kHoleNanLower32Offset = 0;
88#elif defined(V8_TARGET_BIG_ENDIAN)
89const uint32_t kHoleNanUpper32Offset = 0;
90const uint32_t kHoleNanLower32Offset = 4;
91#else
92#error Unknown endianness
93#endif
94
95#ifndef FPU_MODE_FPXX
96#define IsFp64Mode() \
97  (kFpuMode == kFP64)
98#else
99#define IsFp64Mode() \
100  (CpuFeatures::IsSupported(FP64FPU))
101#endif
102
103#ifndef _MIPS_ARCH_MIPS32RX
104#define IsMipsArchVariant(check) \
105  (kArchVariant == check)
106#else
107#define IsMipsArchVariant(check) \
108  (CpuFeatures::IsSupported(static_cast<CpuFeature>(check)))
109#endif
110
111
112#define __STDC_FORMAT_MACROS
113#include <inttypes.h>
114
115// Defines constants and accessor classes to assemble, disassemble and
116// simulate MIPS32 instructions.
117//
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.
121
122namespace v8 {
123namespace internal {
124
125// -----------------------------------------------------------------------------
126// Registers and FPURegisters.
127
128// Number of general purpose registers.
129const int kNumRegisters = 32;
130const int kInvalidRegister = -1;
131
132// Number of registers with HI, LO, and pc.
133const int kNumSimuRegisters = 35;
134
135// In the simulator, the PC register is simulated as the 34th register.
136const int kPCRegister = 34;
137
138// Number coprocessor registers.
139const int kNumFPURegisters = 32;
140const int kInvalidFPURegister = -1;
141
142// FPU (coprocessor 1) control registers. Currently only FCSR is implemented.
143const int kFCSRRegister = 31;
144const int kInvalidFPUControlRegister = -1;
145const uint32_t kFPUInvalidResult = static_cast<uint32_t>(1 << 31) - 1;
146const uint64_t kFPU64InvalidResult =
147    static_cast<uint64_t>(static_cast<uint64_t>(1) << 63) - 1;
148
149// FCSR constants.
150const uint32_t kFCSRInexactFlagBit = 2;
151const uint32_t kFCSRUnderflowFlagBit = 3;
152const uint32_t kFCSROverflowFlagBit = 4;
153const uint32_t kFCSRDivideByZeroFlagBit = 5;
154const uint32_t kFCSRInvalidOpFlagBit = 6;
155
156const uint32_t kFCSRInexactFlagMask = 1 << kFCSRInexactFlagBit;
157const uint32_t kFCSRUnderflowFlagMask = 1 << kFCSRUnderflowFlagBit;
158const uint32_t kFCSROverflowFlagMask = 1 << kFCSROverflowFlagBit;
159const uint32_t kFCSRDivideByZeroFlagMask = 1 << kFCSRDivideByZeroFlagBit;
160const uint32_t kFCSRInvalidOpFlagMask = 1 << kFCSRInvalidOpFlagBit;
161
162const uint32_t kFCSRFlagMask =
163    kFCSRInexactFlagMask |
164    kFCSRUnderflowFlagMask |
165    kFCSROverflowFlagMask |
166    kFCSRDivideByZeroFlagMask |
167    kFCSRInvalidOpFlagMask;
168
169const uint32_t kFCSRExceptionFlagMask = kFCSRFlagMask ^ kFCSRInexactFlagMask;
170
171// 'pref' instruction hints
172const int32_t kPrefHintLoad = 0;
173const int32_t kPrefHintStore = 1;
174const int32_t kPrefHintLoadStreamed = 4;
175const int32_t kPrefHintStoreStreamed = 5;
176const int32_t kPrefHintLoadRetained = 6;
177const int32_t kPrefHintStoreRetained = 7;
178const int32_t kPrefHintWritebackInvalidate = 25;
179const int32_t kPrefHintPrepareForStore = 30;
180
181// Helper functions for converting between register numbers and names.
182class Registers {
183 public:
184  // Return the name of the register.
185  static const char* Name(int reg);
186
187  // Lookup the register number for the name provided.
188  static int Number(const char* name);
189
190  struct RegisterAlias {
191    int reg;
192    const char* name;
193  };
194
195  static const int32_t kMaxValue = 0x7fffffff;
196  static const int32_t kMinValue = 0x80000000;
197
198 private:
199  static const char* names_[kNumSimuRegisters];
200  static const RegisterAlias aliases_[];
201};
202
203// Helper functions for converting between register numbers and names.
204class FPURegisters {
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 creg;
214    const char* name;
215  };
216
217 private:
218  static const char* names_[kNumFPURegisters];
219  static const RegisterAlias aliases_[];
220};
221
222
223// -----------------------------------------------------------------------------
224// Instructions encoding constants.
225
226// On MIPS all instructions are 32 bits.
227typedef int32_t Instr;
228
229// Special Software Interrupt codes when used in the presence of the MIPS
230// simulator.
231enum SoftwareInterruptCodes {
232  // Transition to C code.
233  call_rt_redirected = 0xfffff
234};
235
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
242//   debugger.
243const uint32_t kMaxWatchpointCode = 31;
244const uint32_t kMaxStopCode = 127;
245STATIC_ASSERT(kMaxWatchpointCode < kMaxStopCode);
246
247
248// ----- Fields offset and length.
249const int kOpcodeShift   = 26;
250const int kOpcodeBits    = 6;
251const int kRsShift       = 21;
252const int kRsBits        = 5;
253const int kRtShift       = 16;
254const int kRtBits        = 5;
255const int kRdShift       = 11;
256const int kRdBits        = 5;
257const int kSaShift       = 6;
258const int kSaBits        = 5;
259const int kFunctionShift = 0;
260const int kFunctionBits  = 6;
261const int kLuiShift      = 16;
262
263const int kImm16Shift = 0;
264const int kImm16Bits  = 16;
265const int kImm21Shift = 0;
266const int kImm21Bits  = 21;
267const int kImm26Shift = 0;
268const int kImm26Bits  = 26;
269const int kImm28Shift = 0;
270const int kImm28Bits  = 28;
271const int kImm32Shift = 0;
272const int kImm32Bits  = 32;
273
274// In branches and jumps immediate fields point to words, not bytes,
275// and are therefore shifted by 2.
276const int kImmFieldShift = 2;
277
278const int kFrBits        = 5;
279const int kFrShift       = 21;
280const int kFsShift       = 11;
281const int kFsBits        = 5;
282const int kFtShift       = 16;
283const int kFtBits        = 5;
284const int kFdShift       = 6;
285const int kFdBits        = 5;
286const int kFCccShift     = 8;
287const int kFCccBits      = 3;
288const int kFBccShift     = 18;
289const int kFBccBits      = 3;
290const int kFBtrueShift   = 16;
291const int kFBtrueBits    = 1;
292
293// ----- Miscellaneous useful masks.
294// Instruction bit masks.
295const int  kOpcodeMask   = ((1 << kOpcodeBits) - 1) << kOpcodeShift;
296const int  kImm16Mask    = ((1 << kImm16Bits) - 1) << kImm16Shift;
297const int  kImm26Mask    = ((1 << kImm26Bits) - 1) << kImm26Shift;
298const int  kImm28Mask    = ((1 << kImm28Bits) - 1) << kImm28Shift;
299const int  kRsFieldMask  = ((1 << kRsBits) - 1) << kRsShift;
300const int  kRtFieldMask  = ((1 << kRtBits) - 1) << kRtShift;
301const int  kRdFieldMask  = ((1 << kRdBits) - 1) << kRdShift;
302const int  kSaFieldMask  = ((1 << kSaBits) - 1) << kSaShift;
303const int  kFunctionFieldMask = ((1 << kFunctionBits) - 1) << kFunctionShift;
304// Misc masks.
305const int  kHiMask       =   0xffff << 16;
306const int  kLoMask       =   0xffff;
307const int  kSignMask     =   0x80000000;
308const int  kJumpAddrMask = (1 << (kImm26Bits + kImmFieldShift)) - 1;
309
310// ----- MIPS Opcodes and Function Fields.
311// We use this presentation to stay close to the table representation in
312// MIPS32 Architecture For Programmers, Volume II: The MIPS32 Instruction Set.
313enum Opcode {
314  SPECIAL   =   0 << kOpcodeShift,
315  REGIMM    =   1 << kOpcodeShift,
316
317  J         =   ((0 << 3) + 2) << kOpcodeShift,
318  JAL       =   ((0 << 3) + 3) << kOpcodeShift,
319  BEQ       =   ((0 << 3) + 4) << kOpcodeShift,
320  BNE       =   ((0 << 3) + 5) << kOpcodeShift,
321  BLEZ      =   ((0 << 3) + 6) << kOpcodeShift,
322  BGTZ      =   ((0 << 3) + 7) << kOpcodeShift,
323
324  ADDI      =   ((1 << 3) + 0) << kOpcodeShift,
325  ADDIU     =   ((1 << 3) + 1) << kOpcodeShift,
326  SLTI      =   ((1 << 3) + 2) << kOpcodeShift,
327  SLTIU     =   ((1 << 3) + 3) << kOpcodeShift,
328  ANDI      =   ((1 << 3) + 4) << kOpcodeShift,
329  ORI       =   ((1 << 3) + 5) << kOpcodeShift,
330  XORI      =   ((1 << 3) + 6) << kOpcodeShift,
331  LUI       =   ((1 << 3) + 7) << kOpcodeShift,  // LUI/AUI family.
332
333  BEQC      =   ((2 << 3) + 0) << kOpcodeShift,
334  COP1      =   ((2 << 3) + 1) << kOpcodeShift,  // Coprocessor 1 class.
335  BEQL      =   ((2 << 3) + 4) << kOpcodeShift,
336  BNEL      =   ((2 << 3) + 5) << kOpcodeShift,
337  BLEZL     =   ((2 << 3) + 6) << kOpcodeShift,
338  BGTZL     =   ((2 << 3) + 7) << kOpcodeShift,
339
340  DADDI     =   ((3 << 3) + 0) << kOpcodeShift,  // This is also BNEC.
341  SPECIAL2  =   ((3 << 3) + 4) << kOpcodeShift,
342  SPECIAL3  =   ((3 << 3) + 7) << kOpcodeShift,
343
344  LB        =   ((4 << 3) + 0) << kOpcodeShift,
345  LH        =   ((4 << 3) + 1) << kOpcodeShift,
346  LWL       =   ((4 << 3) + 2) << kOpcodeShift,
347  LW        =   ((4 << 3) + 3) << kOpcodeShift,
348  LBU       =   ((4 << 3) + 4) << kOpcodeShift,
349  LHU       =   ((4 << 3) + 5) << kOpcodeShift,
350  LWR       =   ((4 << 3) + 6) << kOpcodeShift,
351  SB        =   ((5 << 3) + 0) << kOpcodeShift,
352  SH        =   ((5 << 3) + 1) << kOpcodeShift,
353  SWL       =   ((5 << 3) + 2) << kOpcodeShift,
354  SW        =   ((5 << 3) + 3) << kOpcodeShift,
355  SWR       =   ((5 << 3) + 6) << kOpcodeShift,
356
357  LWC1      =   ((6 << 3) + 1) << kOpcodeShift,
358  LDC1      =   ((6 << 3) + 5) << kOpcodeShift,
359  BEQZC     =   ((6 << 3) + 6) << kOpcodeShift,
360
361  PREF      =   ((6 << 3) + 3) << kOpcodeShift,
362
363  SWC1      =   ((7 << 3) + 1) << kOpcodeShift,
364  SDC1      =   ((7 << 3) + 5) << kOpcodeShift,
365  BNEZC     =   ((7 << 3) + 6) << kOpcodeShift,
366
367  COP1X     =   ((1 << 4) + 3) << kOpcodeShift
368};
369
370enum SecondaryField {
371  // SPECIAL Encoding of Function Field.
372  SLL       =   ((0 << 3) + 0),
373  MOVCI     =   ((0 << 3) + 1),
374  SRL       =   ((0 << 3) + 2),
375  SRA       =   ((0 << 3) + 3),
376  SLLV      =   ((0 << 3) + 4),
377  SRLV      =   ((0 << 3) + 6),
378  SRAV      =   ((0 << 3) + 7),
379
380  JR        =   ((1 << 3) + 0),
381  JALR      =   ((1 << 3) + 1),
382  MOVZ      =   ((1 << 3) + 2),
383  MOVN      =   ((1 << 3) + 3),
384  BREAK     =   ((1 << 3) + 5),
385
386  MFHI      =   ((2 << 3) + 0),
387  CLZ_R6    =   ((2 << 3) + 0),
388  CLO_R6    =   ((2 << 3) + 1),
389  MFLO      =   ((2 << 3) + 2),
390
391  MULT      =   ((3 << 3) + 0),
392  MULTU     =   ((3 << 3) + 1),
393  DIV       =   ((3 << 3) + 2),
394  DIVU      =   ((3 << 3) + 3),
395
396  ADD       =   ((4 << 3) + 0),
397  ADDU      =   ((4 << 3) + 1),
398  SUB       =   ((4 << 3) + 2),
399  SUBU      =   ((4 << 3) + 3),
400  AND       =   ((4 << 3) + 4),
401  OR        =   ((4 << 3) + 5),
402  XOR       =   ((4 << 3) + 6),
403  NOR       =   ((4 << 3) + 7),
404
405  SLT       =   ((5 << 3) + 2),
406  SLTU      =   ((5 << 3) + 3),
407
408  TGE       =   ((6 << 3) + 0),
409  TGEU      =   ((6 << 3) + 1),
410  TLT       =   ((6 << 3) + 2),
411  TLTU      =   ((6 << 3) + 3),
412  TEQ       =   ((6 << 3) + 4),
413  SELEQZ_S  =   ((6 << 3) + 5),
414  TNE       =   ((6 << 3) + 6),
415  SELNEZ_S  =   ((6 << 3) + 7),
416
417  // Multiply integers in r6.
418  MUL_MUH   =   ((3 << 3) + 0),  // MUL, MUH.
419  MUL_MUH_U =   ((3 << 3) + 1),  // MUL_U, MUH_U.
420
421  MUL_OP    =   ((0 << 3) + 2),
422  MUH_OP    =   ((0 << 3) + 3),
423  DIV_OP    =   ((0 << 3) + 2),
424  MOD_OP    =   ((0 << 3) + 3),
425
426  DIV_MOD   =   ((3 << 3) + 2),
427  DIV_MOD_U =   ((3 << 3) + 3),
428
429  // SPECIAL2 Encoding of Function Field.
430  MUL       =   ((0 << 3) + 2),
431  CLZ       =   ((4 << 3) + 0),
432  CLO       =   ((4 << 3) + 1),
433
434  // SPECIAL3 Encoding of Function Field.
435  EXT       =   ((0 << 3) + 0),
436  INS       =   ((0 << 3) + 4),
437
438  // REGIMM  encoding of rt Field.
439  BLTZ      =   ((0 << 3) + 0) << 16,
440  BGEZ      =   ((0 << 3) + 1) << 16,
441  BLTZAL    =   ((2 << 3) + 0) << 16,
442  BGEZAL    =   ((2 << 3) + 1) << 16,
443  BGEZALL   =   ((2 << 3) + 3) << 16,
444
445  // COP1 Encoding of rs Field.
446  MFC1      =   ((0 << 3) + 0) << 21,
447  CFC1      =   ((0 << 3) + 2) << 21,
448  MFHC1     =   ((0 << 3) + 3) << 21,
449  MTC1      =   ((0 << 3) + 4) << 21,
450  CTC1      =   ((0 << 3) + 6) << 21,
451  MTHC1     =   ((0 << 3) + 7) << 21,
452  BC1       =   ((1 << 3) + 0) << 21,
453  S         =   ((2 << 3) + 0) << 21,
454  D         =   ((2 << 3) + 1) << 21,
455  W         =   ((2 << 3) + 4) << 21,
456  L         =   ((2 << 3) + 5) << 21,
457  PS        =   ((2 << 3) + 6) << 21,
458  // COP1 Encoding of Function Field When rs=S.
459  ROUND_L_S =   ((1 << 3) + 0),
460  TRUNC_L_S =   ((1 << 3) + 1),
461  CEIL_L_S  =   ((1 << 3) + 2),
462  FLOOR_L_S =   ((1 << 3) + 3),
463  ROUND_W_S =   ((1 << 3) + 4),
464  TRUNC_W_S =   ((1 << 3) + 5),
465  CEIL_W_S  =   ((1 << 3) + 6),
466  FLOOR_W_S =   ((1 << 3) + 7),
467  CVT_D_S   =   ((4 << 3) + 1),
468  CVT_W_S   =   ((4 << 3) + 4),
469  CVT_L_S   =   ((4 << 3) + 5),
470  CVT_PS_S  =   ((4 << 3) + 6),
471  // COP1 Encoding of Function Field When rs=D.
472  ADD_D     =   ((0 << 3) + 0),
473  SUB_D     =   ((0 << 3) + 1),
474  MUL_D     =   ((0 << 3) + 2),
475  DIV_D     =   ((0 << 3) + 3),
476  SQRT_D    =   ((0 << 3) + 4),
477  ABS_D     =   ((0 << 3) + 5),
478  MOV_D     =   ((0 << 3) + 6),
479  NEG_D     =   ((0 << 3) + 7),
480  ROUND_L_D =   ((1 << 3) + 0),
481  TRUNC_L_D =   ((1 << 3) + 1),
482  CEIL_L_D  =   ((1 << 3) + 2),
483  FLOOR_L_D =   ((1 << 3) + 3),
484  ROUND_W_D =   ((1 << 3) + 4),
485  TRUNC_W_D =   ((1 << 3) + 5),
486  CEIL_W_D  =   ((1 << 3) + 6),
487  FLOOR_W_D =   ((1 << 3) + 7),
488  MIN       =   ((3 << 3) + 4),
489  MINA      =   ((3 << 3) + 5),
490  MAX       =   ((3 << 3) + 6),
491  MAXA      =   ((3 << 3) + 7),
492  CVT_S_D   =   ((4 << 3) + 0),
493  CVT_W_D   =   ((4 << 3) + 4),
494  CVT_L_D   =   ((4 << 3) + 5),
495  C_F_D     =   ((6 << 3) + 0),
496  C_UN_D    =   ((6 << 3) + 1),
497  C_EQ_D    =   ((6 << 3) + 2),
498  C_UEQ_D   =   ((6 << 3) + 3),
499  C_OLT_D   =   ((6 << 3) + 4),
500  C_ULT_D   =   ((6 << 3) + 5),
501  C_OLE_D   =   ((6 << 3) + 6),
502  C_ULE_D   =   ((6 << 3) + 7),
503  // COP1 Encoding of Function Field When rs=W or L.
504  CVT_S_W   =   ((4 << 3) + 0),
505  CVT_D_W   =   ((4 << 3) + 1),
506  CVT_S_L   =   ((4 << 3) + 0),
507  CVT_D_L   =   ((4 << 3) + 1),
508  BC1EQZ    =   ((2 << 2) + 1) << 21,
509  BC1NEZ    =   ((3 << 2) + 1) << 21,
510  // COP1 CMP positive predicates Bit 5..4 = 00.
511  CMP_AF    =   ((0 << 3) + 0),
512  CMP_UN    =   ((0 << 3) + 1),
513  CMP_EQ    =   ((0 << 3) + 2),
514  CMP_UEQ   =   ((0 << 3) + 3),
515  CMP_LT    =   ((0 << 3) + 4),
516  CMP_ULT   =   ((0 << 3) + 5),
517  CMP_LE    =   ((0 << 3) + 6),
518  CMP_ULE   =   ((0 << 3) + 7),
519  CMP_SAF   =   ((1 << 3) + 0),
520  CMP_SUN   =   ((1 << 3) + 1),
521  CMP_SEQ   =   ((1 << 3) + 2),
522  CMP_SUEQ  =   ((1 << 3) + 3),
523  CMP_SSLT  =   ((1 << 3) + 4),
524  CMP_SSULT =   ((1 << 3) + 5),
525  CMP_SLE   =   ((1 << 3) + 6),
526  CMP_SULE  =   ((1 << 3) + 7),
527  // COP1 CMP negative predicates Bit 5..4 = 01.
528  CMP_AT    =   ((2 << 3) + 0),  // Reserved, not implemented.
529  CMP_OR    =   ((2 << 3) + 1),
530  CMP_UNE   =   ((2 << 3) + 2),
531  CMP_NE    =   ((2 << 3) + 3),
532  CMP_UGE   =   ((2 << 3) + 4),  // Reserved, not implemented.
533  CMP_OGE   =   ((2 << 3) + 5),  // Reserved, not implemented.
534  CMP_UGT   =   ((2 << 3) + 6),  // Reserved, not implemented.
535  CMP_OGT   =   ((2 << 3) + 7),  // Reserved, not implemented.
536  CMP_SAT   =   ((3 << 3) + 0),  // Reserved, not implemented.
537  CMP_SOR   =   ((3 << 3) + 1),
538  CMP_SUNE  =   ((3 << 3) + 2),
539  CMP_SNE   =   ((3 << 3) + 3),
540  CMP_SUGE  =   ((3 << 3) + 4),  // Reserved, not implemented.
541  CMP_SOGE  =   ((3 << 3) + 5),  // Reserved, not implemented.
542  CMP_SUGT  =   ((3 << 3) + 6),  // Reserved, not implemented.
543  CMP_SOGT  =   ((3 << 3) + 7),  // Reserved, not implemented.
544
545  SEL       =   ((2 << 3) + 0),
546  SELEQZ_C  =   ((2 << 3) + 4),  // COP1 on FPR registers.
547  SELNEZ_C  =   ((2 << 3) + 7),  // COP1 on FPR registers.
548  // COP1 Encoding of Function Field When rs=PS.
549  // COP1X Encoding of Function Field.
550  MADD_D    =   ((4 << 3) + 1),
551
552  NULLSF    =   0
553};
554
555
556// ----- Emulated conditions.
557// On MIPS we use this enum to abstract from conditionnal branch instructions.
558// The 'U' prefix is used to specify unsigned comparisons.
559// Oppposite conditions must be paired as odd/even numbers
560// because 'NegateCondition' function flips LSB to negate condition.
561enum Condition {
562  // Any value < 0 is considered no_condition.
563  kNoCondition  = -1,
564
565  overflow      =  0,
566  no_overflow   =  1,
567  Uless         =  2,
568  Ugreater_equal=  3,
569  equal         =  4,
570  not_equal     =  5,
571  Uless_equal   =  6,
572  Ugreater      =  7,
573  negative      =  8,
574  positive      =  9,
575  parity_even   = 10,
576  parity_odd    = 11,
577  less          = 12,
578  greater_equal = 13,
579  less_equal    = 14,
580  greater       = 15,
581  ueq           = 16,  // Unordered or Equal.
582  nue           = 17,  // Not (Unordered or Equal).
583
584  cc_always     = 18,
585
586  // Aliases.
587  carry         = Uless,
588  not_carry     = Ugreater_equal,
589  zero          = equal,
590  eq            = equal,
591  not_zero      = not_equal,
592  ne            = not_equal,
593  nz            = not_equal,
594  sign          = negative,
595  not_sign      = positive,
596  mi            = negative,
597  pl            = positive,
598  hi            = Ugreater,
599  ls            = Uless_equal,
600  ge            = greater_equal,
601  lt            = less,
602  gt            = greater,
603  le            = less_equal,
604  hs            = Ugreater_equal,
605  lo            = Uless,
606  al            = cc_always,
607
608  cc_default    = kNoCondition
609};
610
611
612// Returns the equivalent of !cc.
613// Negation of the default kNoCondition (-1) results in a non-default
614// no_condition value (-2). As long as tests for no_condition check
615// for condition < 0, this will work as expected.
616inline Condition NegateCondition(Condition cc) {
617  DCHECK(cc != cc_always);
618  return static_cast<Condition>(cc ^ 1);
619}
620
621
622// Commute a condition such that {a cond b == b cond' a}.
623inline Condition CommuteCondition(Condition cc) {
624  switch (cc) {
625    case Uless:
626      return Ugreater;
627    case Ugreater:
628      return Uless;
629    case Ugreater_equal:
630      return Uless_equal;
631    case Uless_equal:
632      return Ugreater_equal;
633    case less:
634      return greater;
635    case greater:
636      return less;
637    case greater_equal:
638      return less_equal;
639    case less_equal:
640      return greater_equal;
641    default:
642      return cc;
643  }
644}
645
646
647// ----- Coprocessor conditions.
648enum FPUCondition {
649  kNoFPUCondition = -1,
650
651  F     = 0,  // False.
652  UN    = 1,  // Unordered.
653  EQ    = 2,  // Equal.
654  UEQ   = 3,  // Unordered or Equal.
655  OLT   = 4,  // Ordered or Less Than.
656  ULT   = 5,  // Unordered or Less Than.
657  OLE   = 6,  // Ordered or Less Than or Equal.
658  ULE   = 7   // Unordered or Less Than or Equal.
659};
660
661
662// FPU rounding modes.
663enum FPURoundingMode {
664  RN = 0 << 0,  // Round to Nearest.
665  RZ = 1 << 0,  // Round towards zero.
666  RP = 2 << 0,  // Round towards Plus Infinity.
667  RM = 3 << 0,  // Round towards Minus Infinity.
668
669  // Aliases.
670  kRoundToNearest = RN,
671  kRoundToZero = RZ,
672  kRoundToPlusInf = RP,
673  kRoundToMinusInf = RM
674};
675
676const uint32_t kFPURoundingModeMask = 3 << 0;
677
678enum CheckForInexactConversion {
679  kCheckForInexactConversion,
680  kDontCheckForInexactConversion
681};
682
683
684// -----------------------------------------------------------------------------
685// Hints.
686
687// Branch hints are not used on the MIPS.  They are defined so that they can
688// appear in shared function signatures, but will be ignored in MIPS
689// implementations.
690enum Hint {
691  no_hint = 0
692};
693
694
695inline Hint NegateHint(Hint hint) {
696  return no_hint;
697}
698
699
700// -----------------------------------------------------------------------------
701// Specific instructions, constants, and masks.
702// These constants are declared in assembler-mips.cc, as they use named
703// registers and other constants.
704
705// addiu(sp, sp, 4) aka Pop() operation or part of Pop(r)
706// operations as post-increment of sp.
707extern const Instr kPopInstruction;
708// addiu(sp, sp, -4) part of Push(r) operation as pre-decrement of sp.
709extern const Instr kPushInstruction;
710// sw(r, MemOperand(sp, 0))
711extern const Instr kPushRegPattern;
712// lw(r, MemOperand(sp, 0))
713extern const Instr kPopRegPattern;
714extern const Instr kLwRegFpOffsetPattern;
715extern const Instr kSwRegFpOffsetPattern;
716extern const Instr kLwRegFpNegOffsetPattern;
717extern const Instr kSwRegFpNegOffsetPattern;
718// A mask for the Rt register for push, pop, lw, sw instructions.
719extern const Instr kRtMask;
720extern const Instr kLwSwInstrTypeMask;
721extern const Instr kLwSwInstrArgumentMask;
722extern const Instr kLwSwOffsetMask;
723
724// Break 0xfffff, reserved for redirected real time call.
725const Instr rtCallRedirInstr = SPECIAL | BREAK | call_rt_redirected << 6;
726// A nop instruction. (Encoding of sll 0 0 0).
727const Instr nopInstr = 0;
728
729class Instruction {
730 public:
731  enum {
732    kInstrSize = 4,
733    kInstrSizeLog2 = 2,
734    // On MIPS PC cannot actually be directly accessed. We behave as if PC was
735    // always the value of the current instruction being executed.
736    kPCReadOffset = 0
737  };
738
739  // Get the raw instruction bits.
740  inline Instr InstructionBits() const {
741    return *reinterpret_cast<const Instr*>(this);
742  }
743
744  // Set the raw instruction bits to value.
745  inline void SetInstructionBits(Instr value) {
746    *reinterpret_cast<Instr*>(this) = value;
747  }
748
749  // Read one particular bit out of the instruction bits.
750  inline int Bit(int nr) const {
751    return (InstructionBits() >> nr) & 1;
752  }
753
754  // Read a bit field out of the instruction bits.
755  inline int Bits(int hi, int lo) const {
756    return (InstructionBits() >> lo) & ((2 << (hi - lo)) - 1);
757  }
758
759  // Instruction type.
760  enum Type {
761    kRegisterType,
762    kImmediateType,
763    kJumpType,
764    kUnsupported = -1
765  };
766
767  // Get the encoding type of the instruction.
768  Type InstructionType() const;
769
770
771  // Accessors for the different named fields used in the MIPS encoding.
772  inline Opcode OpcodeValue() const {
773    return static_cast<Opcode>(
774        Bits(kOpcodeShift + kOpcodeBits - 1, kOpcodeShift));
775  }
776
777  inline int RsValue() const {
778    DCHECK(InstructionType() == kRegisterType ||
779           InstructionType() == kImmediateType);
780    return Bits(kRsShift + kRsBits - 1, kRsShift);
781  }
782
783  inline int RtValue() const {
784    DCHECK(InstructionType() == kRegisterType ||
785           InstructionType() == kImmediateType);
786    return Bits(kRtShift + kRtBits - 1, kRtShift);
787  }
788
789  inline int RdValue() const {
790    DCHECK(InstructionType() == kRegisterType);
791    return Bits(kRdShift + kRdBits - 1, kRdShift);
792  }
793
794  inline int SaValue() const {
795    DCHECK(InstructionType() == kRegisterType);
796    return Bits(kSaShift + kSaBits - 1, kSaShift);
797  }
798
799  inline int FunctionValue() const {
800    DCHECK(InstructionType() == kRegisterType ||
801           InstructionType() == kImmediateType);
802    return Bits(kFunctionShift + kFunctionBits - 1, kFunctionShift);
803  }
804
805  inline int FdValue() const {
806    return Bits(kFdShift + kFdBits - 1, kFdShift);
807  }
808
809  inline int FsValue() const {
810    return Bits(kFsShift + kFsBits - 1, kFsShift);
811  }
812
813  inline int FtValue() const {
814    return Bits(kFtShift + kFtBits - 1, kFtShift);
815  }
816
817  inline int FrValue() const {
818    return Bits(kFrShift + kFrBits -1, kFrShift);
819  }
820
821  // Float Compare condition code instruction bits.
822  inline int FCccValue() const {
823    return Bits(kFCccShift + kFCccBits - 1, kFCccShift);
824  }
825
826  // Float Branch condition code instruction bits.
827  inline int FBccValue() const {
828    return Bits(kFBccShift + kFBccBits - 1, kFBccShift);
829  }
830
831  // Float Branch true/false instruction bit.
832  inline int FBtrueValue() const {
833    return Bits(kFBtrueShift + kFBtrueBits - 1, kFBtrueShift);
834  }
835
836  // Return the fields at their original place in the instruction encoding.
837  inline Opcode OpcodeFieldRaw() const {
838    return static_cast<Opcode>(InstructionBits() & kOpcodeMask);
839  }
840
841  inline int RsFieldRaw() const {
842    DCHECK(InstructionType() == kRegisterType ||
843           InstructionType() == kImmediateType);
844    return InstructionBits() & kRsFieldMask;
845  }
846
847  // Same as above function, but safe to call within InstructionType().
848  inline int RsFieldRawNoAssert() const {
849    return InstructionBits() & kRsFieldMask;
850  }
851
852  inline int RtFieldRaw() const {
853    DCHECK(InstructionType() == kRegisterType ||
854           InstructionType() == kImmediateType);
855    return InstructionBits() & kRtFieldMask;
856  }
857
858  inline int RdFieldRaw() const {
859    DCHECK(InstructionType() == kRegisterType);
860    return InstructionBits() & kRdFieldMask;
861  }
862
863  inline int SaFieldRaw() const {
864    DCHECK(InstructionType() == kRegisterType);
865    return InstructionBits() & kSaFieldMask;
866  }
867
868  inline int FunctionFieldRaw() const {
869    return InstructionBits() & kFunctionFieldMask;
870  }
871
872  // Get the secondary field according to the opcode.
873  inline int SecondaryValue() const {
874    Opcode op = OpcodeFieldRaw();
875    switch (op) {
876      case SPECIAL:
877      case SPECIAL2:
878        return FunctionValue();
879      case COP1:
880        return RsValue();
881      case REGIMM:
882        return RtValue();
883      default:
884        return NULLSF;
885    }
886  }
887
888  inline int32_t Imm16Value() const {
889    DCHECK(InstructionType() == kImmediateType);
890    return Bits(kImm16Shift + kImm16Bits - 1, kImm16Shift);
891  }
892
893  inline int32_t Imm21Value() const {
894    DCHECK(InstructionType() == kImmediateType);
895    return Bits(kImm21Shift + kImm21Bits - 1, kImm21Shift);
896  }
897
898  inline int32_t Imm26Value() const {
899    DCHECK(InstructionType() == kJumpType);
900    return Bits(kImm26Shift + kImm26Bits - 1, kImm26Shift);
901  }
902
903  // Say if the instruction should not be used in a branch delay slot.
904  bool IsForbiddenInBranchDelay() const;
905  // Say if the instruction 'links'. e.g. jal, bal.
906  bool IsLinkingInstruction() const;
907  // Say if the instruction is a break or a trap.
908  bool IsTrap() const;
909
910  // Instructions are read of out a code stream. The only way to get a
911  // reference to an instruction is to convert a pointer. There is no way
912  // to allocate or create instances of class Instruction.
913  // Use the At(pc) function to create references to Instruction.
914  static Instruction* At(byte* pc) {
915    return reinterpret_cast<Instruction*>(pc);
916  }
917
918 private:
919  // We need to prevent the creation of instances of class Instruction.
920  DISALLOW_IMPLICIT_CONSTRUCTORS(Instruction);
921};
922
923
924// -----------------------------------------------------------------------------
925// MIPS assembly various constants.
926
927// C/C++ argument slots size.
928const int kCArgSlotCount = 4;
929const int kCArgsSlotsSize = kCArgSlotCount * Instruction::kInstrSize;
930// JS argument slots size.
931const int kJSArgsSlotsSize = 0 * Instruction::kInstrSize;
932// Assembly builtins argument slots size.
933const int kBArgsSlotsSize = 0 * Instruction::kInstrSize;
934
935const int kBranchReturnOffset = 2 * Instruction::kInstrSize;
936
937} }   // namespace v8::internal
938
939#endif    // #ifndef V8_MIPS_CONSTANTS_H_
940