blob: 139e7db033c555adf6426674ac477bc21f190c25 [file] [log] [blame]
mstarzinger@chromium.org3233d2f2012-03-14 11:16:03 +00001// Copyright 2012 the V8 project authors. All rights reserved.
ager@chromium.org5c838252010-02-19 08:53:10 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#ifndef V8_MIPS_CONSTANTS_H_
29#define V8_MIPS_CONSTANTS_H_
30
ager@chromium.org5c838252010-02-19 08:53:10 +000031// UNIMPLEMENTED_ macro for MIPS.
lrn@chromium.org7516f052011-03-30 08:52:27 +000032#ifdef DEBUG
ager@chromium.org5c838252010-02-19 08:53:10 +000033#define UNIMPLEMENTED_MIPS() \
34 v8::internal::PrintF("%s, \tline %d: \tfunction %s not implemented. \n", \
35 __FILE__, __LINE__, __func__)
lrn@chromium.org7516f052011-03-30 08:52:27 +000036#else
37#define UNIMPLEMENTED_MIPS()
38#endif
39
ager@chromium.org5c838252010-02-19 08:53:10 +000040#define UNSUPPORTED_MIPS() v8::internal::PrintF("Unsupported instruction.\n")
41
mstarzinger@chromium.org3233d2f2012-03-14 11:16:03 +000042enum ArchVariants {
43 kMips32r2,
44 kMips32r1,
45 kLoongson
46};
ager@chromium.org5c838252010-02-19 08:53:10 +000047
lrn@chromium.org7516f052011-03-30 08:52:27 +000048#ifdef _MIPS_ARCH_MIPS32R2
mstarzinger@chromium.org3233d2f2012-03-14 11:16:03 +000049 static const ArchVariants kArchVariant = kMips32r2;
50#elif _MIPS_ARCH_LOONGSON
51// The loongson flag refers to the LOONGSON architectures based on MIPS-III,
52// which predates (and is a subset of) the mips32r2 and r1 architectures.
53 static const ArchVariants kArchVariant = kLoongson;
lrn@chromium.org7516f052011-03-30 08:52:27 +000054#else
mstarzinger@chromium.org3233d2f2012-03-14 11:16:03 +000055 static const ArchVariants kArchVariant = kMips32r1;
lrn@chromium.org7516f052011-03-30 08:52:27 +000056#endif
57
58
danno@chromium.org40cb8782011-05-25 07:58:50 +000059#if(defined(__mips_hard_float) && __mips_hard_float != 0)
60// Use floating-point coprocessor instructions. This flag is raised when
61// -mhard-float is passed to the compiler.
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +000062const bool IsMipsSoftFloatABI = false;
danno@chromium.org40cb8782011-05-25 07:58:50 +000063#elif(defined(__mips_soft_float) && __mips_soft_float != 0)
64// Not using floating-point coprocessor instructions. This flag is raised when
65// -msoft-float is passed to the compiler.
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +000066const bool IsMipsSoftFloatABI = true;
danno@chromium.org40cb8782011-05-25 07:58:50 +000067#else
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +000068const bool IsMipsSoftFloatABI = true;
danno@chromium.org40cb8782011-05-25 07:58:50 +000069#endif
70
71
ager@chromium.org5c838252010-02-19 08:53:10 +000072// Defines constants and accessor classes to assemble, disassemble and
73// simulate MIPS32 instructions.
74//
75// See: MIPS32 Architecture For Programmers
76// Volume II: The MIPS32 Instruction Set
77// Try www.cs.cornell.edu/courses/cs3410/2008fa/MIPS_Vol2.pdf.
78
lrn@chromium.org7516f052011-03-30 08:52:27 +000079namespace v8 {
80namespace internal {
ager@chromium.org5c838252010-02-19 08:53:10 +000081
82// -----------------------------------------------------------------------------
karlklose@chromium.org83a47282011-05-11 11:54:09 +000083// Registers and FPURegisters.
ager@chromium.org5c838252010-02-19 08:53:10 +000084
85// Number of general purpose registers.
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +000086const int kNumRegisters = 32;
87const int kInvalidRegister = -1;
ager@chromium.org5c838252010-02-19 08:53:10 +000088
89// Number of registers with HI, LO, and pc.
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +000090const int kNumSimuRegisters = 35;
ager@chromium.org5c838252010-02-19 08:53:10 +000091
92// In the simulator, the PC register is simulated as the 34th register.
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +000093const int kPCRegister = 34;
ager@chromium.org5c838252010-02-19 08:53:10 +000094
95// Number coprocessor registers.
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +000096const int kNumFPURegisters = 32;
97const int kInvalidFPURegister = -1;
ager@chromium.org5c838252010-02-19 08:53:10 +000098
lrn@chromium.org7516f052011-03-30 08:52:27 +000099// FPU (coprocessor 1) control registers. Currently only FCSR is implemented.
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000100const int kFCSRRegister = 31;
101const int kInvalidFPUControlRegister = -1;
jkummerow@chromium.org59297c72013-01-09 16:32:23 +0000102const uint32_t kFPUInvalidResult = static_cast<uint32_t>(1 << 31) - 1;
lrn@chromium.org7516f052011-03-30 08:52:27 +0000103
104// FCSR constants.
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000105const uint32_t kFCSRInexactFlagBit = 2;
106const uint32_t kFCSRUnderflowFlagBit = 3;
107const uint32_t kFCSROverflowFlagBit = 4;
108const uint32_t kFCSRDivideByZeroFlagBit = 5;
109const uint32_t kFCSRInvalidOpFlagBit = 6;
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +0000110
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000111const uint32_t kFCSRInexactFlagMask = 1 << kFCSRInexactFlagBit;
112const uint32_t kFCSRUnderflowFlagMask = 1 << kFCSRUnderflowFlagBit;
113const uint32_t kFCSROverflowFlagMask = 1 << kFCSROverflowFlagBit;
114const uint32_t kFCSRDivideByZeroFlagMask = 1 << kFCSRDivideByZeroFlagBit;
115const uint32_t kFCSRInvalidOpFlagMask = 1 << kFCSRInvalidOpFlagBit;
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +0000116
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000117const uint32_t kFCSRFlagMask =
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +0000118 kFCSRInexactFlagMask |
119 kFCSRUnderflowFlagMask |
120 kFCSROverflowFlagMask |
121 kFCSRDivideByZeroFlagMask |
122 kFCSRInvalidOpFlagMask;
123
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000124const uint32_t kFCSRExceptionFlagMask = kFCSRFlagMask ^ kFCSRInexactFlagMask;
lrn@chromium.org7516f052011-03-30 08:52:27 +0000125
ager@chromium.org5c838252010-02-19 08:53:10 +0000126// Helper functions for converting between register numbers and names.
127class Registers {
128 public:
129 // Return the name of the register.
130 static const char* Name(int reg);
131
132 // Lookup the register number for the name provided.
133 static int Number(const char* name);
134
135 struct RegisterAlias {
136 int reg;
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +0000137 const char* name;
ager@chromium.org5c838252010-02-19 08:53:10 +0000138 };
139
140 static const int32_t kMaxValue = 0x7fffffff;
141 static const int32_t kMinValue = 0x80000000;
142
143 private:
ager@chromium.org5c838252010-02-19 08:53:10 +0000144 static const char* names_[kNumSimuRegisters];
145 static const RegisterAlias aliases_[];
146};
147
148// Helper functions for converting between register numbers and names.
lrn@chromium.org7516f052011-03-30 08:52:27 +0000149class FPURegisters {
ager@chromium.org5c838252010-02-19 08:53:10 +0000150 public:
151 // Return the name of the register.
152 static const char* Name(int reg);
153
154 // Lookup the register number for the name provided.
155 static int Number(const char* name);
156
157 struct RegisterAlias {
158 int creg;
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +0000159 const char* name;
ager@chromium.org5c838252010-02-19 08:53:10 +0000160 };
161
162 private:
lrn@chromium.org7516f052011-03-30 08:52:27 +0000163 static const char* names_[kNumFPURegisters];
ager@chromium.org5c838252010-02-19 08:53:10 +0000164 static const RegisterAlias aliases_[];
165};
166
167
168// -----------------------------------------------------------------------------
169// Instructions encoding constants.
170
171// On MIPS all instructions are 32 bits.
172typedef int32_t Instr;
173
ager@chromium.org5c838252010-02-19 08:53:10 +0000174// Special Software Interrupt codes when used in the presence of the MIPS
175// simulator.
176enum SoftwareInterruptCodes {
177 // Transition to C code.
178 call_rt_redirected = 0xfffff
179};
180
ricow@chromium.orgc54d3652011-05-30 09:20:16 +0000181// On MIPS Simulator breakpoints can have different codes:
182// - Breaks between 0 and kMaxWatchpointCode are treated as simple watchpoints,
183// the simulator will run through them and print the registers.
184// - Breaks between kMaxWatchpointCode and kMaxStopCode are treated as stop()
185// instructions (see Assembler::stop()).
186// - Breaks larger than kMaxStopCode are simple breaks, dropping you into the
187// debugger.
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000188const uint32_t kMaxWatchpointCode = 31;
189const uint32_t kMaxStopCode = 127;
ricow@chromium.orgc54d3652011-05-30 09:20:16 +0000190STATIC_ASSERT(kMaxWatchpointCode < kMaxStopCode);
191
192
ager@chromium.org5c838252010-02-19 08:53:10 +0000193// ----- Fields offset and length.
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000194const int kOpcodeShift = 26;
195const int kOpcodeBits = 6;
196const int kRsShift = 21;
197const int kRsBits = 5;
198const int kRtShift = 16;
199const int kRtBits = 5;
200const int kRdShift = 11;
201const int kRdBits = 5;
202const int kSaShift = 6;
203const int kSaBits = 5;
204const int kFunctionShift = 0;
205const int kFunctionBits = 6;
206const int kLuiShift = 16;
ager@chromium.org5c838252010-02-19 08:53:10 +0000207
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000208const int kImm16Shift = 0;
209const int kImm16Bits = 16;
210const int kImm26Shift = 0;
211const int kImm26Bits = 26;
212const int kImm28Shift = 0;
213const int kImm28Bits = 28;
ager@chromium.org5c838252010-02-19 08:53:10 +0000214
lrn@chromium.org34e60782011-09-15 07:25:40 +0000215// In branches and jumps immediate fields point to words, not bytes,
216// and are therefore shifted by 2.
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000217const int kImmFieldShift = 2;
lrn@chromium.org34e60782011-09-15 07:25:40 +0000218
jkummerow@chromium.org59297c72013-01-09 16:32:23 +0000219const int kFrBits = 5;
220const int kFrShift = 21;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000221const int kFsShift = 11;
222const int kFsBits = 5;
223const int kFtShift = 16;
224const int kFtBits = 5;
225const int kFdShift = 6;
226const int kFdBits = 5;
227const int kFCccShift = 8;
228const int kFCccBits = 3;
229const int kFBccShift = 18;
230const int kFBccBits = 3;
231const int kFBtrueShift = 16;
232const int kFBtrueBits = 1;
ager@chromium.org5c838252010-02-19 08:53:10 +0000233
karlklose@chromium.org83a47282011-05-11 11:54:09 +0000234// ----- Miscellaneous useful masks.
ager@chromium.org5c838252010-02-19 08:53:10 +0000235// Instruction bit masks.
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000236const int kOpcodeMask = ((1 << kOpcodeBits) - 1) << kOpcodeShift;
237const int kImm16Mask = ((1 << kImm16Bits) - 1) << kImm16Shift;
238const int kImm26Mask = ((1 << kImm26Bits) - 1) << kImm26Shift;
239const int kImm28Mask = ((1 << kImm28Bits) - 1) << kImm28Shift;
240const int kRsFieldMask = ((1 << kRsBits) - 1) << kRsShift;
241const int kRtFieldMask = ((1 << kRtBits) - 1) << kRtShift;
242const int kRdFieldMask = ((1 << kRdBits) - 1) << kRdShift;
243const int kSaFieldMask = ((1 << kSaBits) - 1) << kSaShift;
244const int kFunctionFieldMask = ((1 << kFunctionBits) - 1) << kFunctionShift;
ager@chromium.org5c838252010-02-19 08:53:10 +0000245// Misc masks.
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000246const int kHiMask = 0xffff << 16;
247const int kLoMask = 0xffff;
248const int kSignMask = 0x80000000;
249const int kJumpAddrMask = (1 << (kImm26Bits + kImmFieldShift)) - 1;
ager@chromium.org5c838252010-02-19 08:53:10 +0000250
251// ----- MIPS Opcodes and Function Fields.
252// We use this presentation to stay close to the table representation in
253// MIPS32 Architecture For Programmers, Volume II: The MIPS32 Instruction Set.
254enum Opcode {
255 SPECIAL = 0 << kOpcodeShift,
256 REGIMM = 1 << kOpcodeShift,
257
258 J = ((0 << 3) + 2) << kOpcodeShift,
259 JAL = ((0 << 3) + 3) << kOpcodeShift,
260 BEQ = ((0 << 3) + 4) << kOpcodeShift,
261 BNE = ((0 << 3) + 5) << kOpcodeShift,
262 BLEZ = ((0 << 3) + 6) << kOpcodeShift,
263 BGTZ = ((0 << 3) + 7) << kOpcodeShift,
264
265 ADDI = ((1 << 3) + 0) << kOpcodeShift,
266 ADDIU = ((1 << 3) + 1) << kOpcodeShift,
267 SLTI = ((1 << 3) + 2) << kOpcodeShift,
268 SLTIU = ((1 << 3) + 3) << kOpcodeShift,
269 ANDI = ((1 << 3) + 4) << kOpcodeShift,
270 ORI = ((1 << 3) + 5) << kOpcodeShift,
271 XORI = ((1 << 3) + 6) << kOpcodeShift,
272 LUI = ((1 << 3) + 7) << kOpcodeShift,
273
karlklose@chromium.org83a47282011-05-11 11:54:09 +0000274 COP1 = ((2 << 3) + 1) << kOpcodeShift, // Coprocessor 1 class.
ager@chromium.org5c838252010-02-19 08:53:10 +0000275 BEQL = ((2 << 3) + 4) << kOpcodeShift,
276 BNEL = ((2 << 3) + 5) << kOpcodeShift,
277 BLEZL = ((2 << 3) + 6) << kOpcodeShift,
278 BGTZL = ((2 << 3) + 7) << kOpcodeShift,
279
280 SPECIAL2 = ((3 << 3) + 4) << kOpcodeShift,
lrn@chromium.org7516f052011-03-30 08:52:27 +0000281 SPECIAL3 = ((3 << 3) + 7) << kOpcodeShift,
ager@chromium.org5c838252010-02-19 08:53:10 +0000282
283 LB = ((4 << 3) + 0) << kOpcodeShift,
lrn@chromium.org7516f052011-03-30 08:52:27 +0000284 LH = ((4 << 3) + 1) << kOpcodeShift,
285 LWL = ((4 << 3) + 2) << kOpcodeShift,
ager@chromium.org5c838252010-02-19 08:53:10 +0000286 LW = ((4 << 3) + 3) << kOpcodeShift,
287 LBU = ((4 << 3) + 4) << kOpcodeShift,
lrn@chromium.org7516f052011-03-30 08:52:27 +0000288 LHU = ((4 << 3) + 5) << kOpcodeShift,
289 LWR = ((4 << 3) + 6) << kOpcodeShift,
ager@chromium.org5c838252010-02-19 08:53:10 +0000290 SB = ((5 << 3) + 0) << kOpcodeShift,
lrn@chromium.org7516f052011-03-30 08:52:27 +0000291 SH = ((5 << 3) + 1) << kOpcodeShift,
292 SWL = ((5 << 3) + 2) << kOpcodeShift,
ager@chromium.org5c838252010-02-19 08:53:10 +0000293 SW = ((5 << 3) + 3) << kOpcodeShift,
lrn@chromium.org7516f052011-03-30 08:52:27 +0000294 SWR = ((5 << 3) + 6) << kOpcodeShift,
ager@chromium.org5c838252010-02-19 08:53:10 +0000295
296 LWC1 = ((6 << 3) + 1) << kOpcodeShift,
297 LDC1 = ((6 << 3) + 5) << kOpcodeShift,
298
299 SWC1 = ((7 << 3) + 1) << kOpcodeShift,
jkummerow@chromium.org59297c72013-01-09 16:32:23 +0000300 SDC1 = ((7 << 3) + 5) << kOpcodeShift,
301
302 COP1X = ((1 << 4) + 3) << kOpcodeShift
ager@chromium.org5c838252010-02-19 08:53:10 +0000303};
304
305enum SecondaryField {
306 // SPECIAL Encoding of Function Field.
307 SLL = ((0 << 3) + 0),
lrn@chromium.org34e60782011-09-15 07:25:40 +0000308 MOVCI = ((0 << 3) + 1),
ager@chromium.org5c838252010-02-19 08:53:10 +0000309 SRL = ((0 << 3) + 2),
310 SRA = ((0 << 3) + 3),
311 SLLV = ((0 << 3) + 4),
312 SRLV = ((0 << 3) + 6),
313 SRAV = ((0 << 3) + 7),
314
315 JR = ((1 << 3) + 0),
316 JALR = ((1 << 3) + 1),
lrn@chromium.org7516f052011-03-30 08:52:27 +0000317 MOVZ = ((1 << 3) + 2),
318 MOVN = ((1 << 3) + 3),
ager@chromium.org5c838252010-02-19 08:53:10 +0000319 BREAK = ((1 << 3) + 5),
320
321 MFHI = ((2 << 3) + 0),
322 MFLO = ((2 << 3) + 2),
323
324 MULT = ((3 << 3) + 0),
325 MULTU = ((3 << 3) + 1),
326 DIV = ((3 << 3) + 2),
327 DIVU = ((3 << 3) + 3),
328
329 ADD = ((4 << 3) + 0),
330 ADDU = ((4 << 3) + 1),
331 SUB = ((4 << 3) + 2),
332 SUBU = ((4 << 3) + 3),
333 AND = ((4 << 3) + 4),
334 OR = ((4 << 3) + 5),
335 XOR = ((4 << 3) + 6),
336 NOR = ((4 << 3) + 7),
337
338 SLT = ((5 << 3) + 2),
339 SLTU = ((5 << 3) + 3),
340
341 TGE = ((6 << 3) + 0),
342 TGEU = ((6 << 3) + 1),
343 TLT = ((6 << 3) + 2),
344 TLTU = ((6 << 3) + 3),
345 TEQ = ((6 << 3) + 4),
346 TNE = ((6 << 3) + 6),
347
348 // SPECIAL2 Encoding of Function Field.
349 MUL = ((0 << 3) + 2),
lrn@chromium.org7516f052011-03-30 08:52:27 +0000350 CLZ = ((4 << 3) + 0),
351 CLO = ((4 << 3) + 1),
352
353 // SPECIAL3 Encoding of Function Field.
354 EXT = ((0 << 3) + 0),
355 INS = ((0 << 3) + 4),
ager@chromium.org5c838252010-02-19 08:53:10 +0000356
357 // REGIMM encoding of rt Field.
358 BLTZ = ((0 << 3) + 0) << 16,
359 BGEZ = ((0 << 3) + 1) << 16,
360 BLTZAL = ((2 << 3) + 0) << 16,
361 BGEZAL = ((2 << 3) + 1) << 16,
362
363 // COP1 Encoding of rs Field.
364 MFC1 = ((0 << 3) + 0) << 21,
lrn@chromium.org7516f052011-03-30 08:52:27 +0000365 CFC1 = ((0 << 3) + 2) << 21,
ager@chromium.org5c838252010-02-19 08:53:10 +0000366 MFHC1 = ((0 << 3) + 3) << 21,
367 MTC1 = ((0 << 3) + 4) << 21,
lrn@chromium.org7516f052011-03-30 08:52:27 +0000368 CTC1 = ((0 << 3) + 6) << 21,
ager@chromium.org5c838252010-02-19 08:53:10 +0000369 MTHC1 = ((0 << 3) + 7) << 21,
370 BC1 = ((1 << 3) + 0) << 21,
371 S = ((2 << 3) + 0) << 21,
372 D = ((2 << 3) + 1) << 21,
373 W = ((2 << 3) + 4) << 21,
374 L = ((2 << 3) + 5) << 21,
375 PS = ((2 << 3) + 6) << 21,
376 // COP1 Encoding of Function Field When rs=S.
lrn@chromium.org7516f052011-03-30 08:52:27 +0000377 ROUND_L_S = ((1 << 3) + 0),
378 TRUNC_L_S = ((1 << 3) + 1),
379 CEIL_L_S = ((1 << 3) + 2),
380 FLOOR_L_S = ((1 << 3) + 3),
381 ROUND_W_S = ((1 << 3) + 4),
382 TRUNC_W_S = ((1 << 3) + 5),
383 CEIL_W_S = ((1 << 3) + 6),
384 FLOOR_W_S = ((1 << 3) + 7),
ager@chromium.org5c838252010-02-19 08:53:10 +0000385 CVT_D_S = ((4 << 3) + 1),
386 CVT_W_S = ((4 << 3) + 4),
387 CVT_L_S = ((4 << 3) + 5),
388 CVT_PS_S = ((4 << 3) + 6),
389 // COP1 Encoding of Function Field When rs=D.
lrn@chromium.org7516f052011-03-30 08:52:27 +0000390 ADD_D = ((0 << 3) + 0),
391 SUB_D = ((0 << 3) + 1),
392 MUL_D = ((0 << 3) + 2),
393 DIV_D = ((0 << 3) + 3),
394 SQRT_D = ((0 << 3) + 4),
395 ABS_D = ((0 << 3) + 5),
396 MOV_D = ((0 << 3) + 6),
397 NEG_D = ((0 << 3) + 7),
398 ROUND_L_D = ((1 << 3) + 0),
399 TRUNC_L_D = ((1 << 3) + 1),
400 CEIL_L_D = ((1 << 3) + 2),
401 FLOOR_L_D = ((1 << 3) + 3),
402 ROUND_W_D = ((1 << 3) + 4),
403 TRUNC_W_D = ((1 << 3) + 5),
404 CEIL_W_D = ((1 << 3) + 6),
405 FLOOR_W_D = ((1 << 3) + 7),
ager@chromium.org5c838252010-02-19 08:53:10 +0000406 CVT_S_D = ((4 << 3) + 0),
407 CVT_W_D = ((4 << 3) + 4),
408 CVT_L_D = ((4 << 3) + 5),
lrn@chromium.org7516f052011-03-30 08:52:27 +0000409 C_F_D = ((6 << 3) + 0),
410 C_UN_D = ((6 << 3) + 1),
411 C_EQ_D = ((6 << 3) + 2),
412 C_UEQ_D = ((6 << 3) + 3),
413 C_OLT_D = ((6 << 3) + 4),
414 C_ULT_D = ((6 << 3) + 5),
415 C_OLE_D = ((6 << 3) + 6),
416 C_ULE_D = ((6 << 3) + 7),
ager@chromium.org5c838252010-02-19 08:53:10 +0000417 // COP1 Encoding of Function Field When rs=W or L.
418 CVT_S_W = ((4 << 3) + 0),
419 CVT_D_W = ((4 << 3) + 1),
420 CVT_S_L = ((4 << 3) + 0),
421 CVT_D_L = ((4 << 3) + 1),
422 // COP1 Encoding of Function Field When rs=PS.
jkummerow@chromium.org59297c72013-01-09 16:32:23 +0000423 // COP1X Encoding of Function Field.
424 MADD_D = ((4 << 3) + 1),
ager@chromium.org5c838252010-02-19 08:53:10 +0000425
426 NULLSF = 0
427};
428
429
430// ----- Emulated conditions.
431// On MIPS we use this enum to abstract from conditionnal branch instructions.
ulan@chromium.org750145a2013-03-07 15:14:13 +0000432// The 'U' prefix is used to specify unsigned comparisons.
433// Oppposite conditions must be paired as odd/even numbers
434// because 'NegateCondition' function flips LSB to negate condition.
ager@chromium.org5c838252010-02-19 08:53:10 +0000435enum Condition {
436 // Any value < 0 is considered no_condition.
lrn@chromium.org7516f052011-03-30 08:52:27 +0000437 kNoCondition = -1,
ager@chromium.org5c838252010-02-19 08:53:10 +0000438
439 overflow = 0,
440 no_overflow = 1,
441 Uless = 2,
442 Ugreater_equal= 3,
443 equal = 4,
444 not_equal = 5,
445 Uless_equal = 6,
446 Ugreater = 7,
447 negative = 8,
448 positive = 9,
449 parity_even = 10,
450 parity_odd = 11,
451 less = 12,
452 greater_equal = 13,
453 less_equal = 14,
454 greater = 15,
ulan@chromium.org750145a2013-03-07 15:14:13 +0000455 ueq = 16, // Unordered or Equal.
456 nue = 17, // Not (Unordered or Equal).
ager@chromium.org5c838252010-02-19 08:53:10 +0000457
ulan@chromium.org750145a2013-03-07 15:14:13 +0000458 cc_always = 18,
ager@chromium.org5c838252010-02-19 08:53:10 +0000459
karlklose@chromium.org83a47282011-05-11 11:54:09 +0000460 // Aliases.
ager@chromium.org5c838252010-02-19 08:53:10 +0000461 carry = Uless,
462 not_carry = Ugreater_equal,
463 zero = equal,
464 eq = equal,
465 not_zero = not_equal,
466 ne = not_equal,
lrn@chromium.org7516f052011-03-30 08:52:27 +0000467 nz = not_equal,
ager@chromium.org5c838252010-02-19 08:53:10 +0000468 sign = negative,
469 not_sign = positive,
lrn@chromium.org7516f052011-03-30 08:52:27 +0000470 mi = negative,
471 pl = positive,
472 hi = Ugreater,
473 ls = Uless_equal,
474 ge = greater_equal,
475 lt = less,
476 gt = greater,
477 le = less_equal,
478 hs = Ugreater_equal,
479 lo = Uless,
480 al = cc_always,
ager@chromium.org5c838252010-02-19 08:53:10 +0000481
lrn@chromium.org7516f052011-03-30 08:52:27 +0000482 cc_default = kNoCondition
ager@chromium.org5c838252010-02-19 08:53:10 +0000483};
484
lrn@chromium.org7516f052011-03-30 08:52:27 +0000485
486// Returns the equivalent of !cc.
487// Negation of the default kNoCondition (-1) results in a non-default
488// no_condition value (-2). As long as tests for no_condition check
489// for condition < 0, this will work as expected.
490inline Condition NegateCondition(Condition cc) {
491 ASSERT(cc != cc_always);
492 return static_cast<Condition>(cc ^ 1);
493}
494
495
496inline Condition ReverseCondition(Condition cc) {
497 switch (cc) {
498 case Uless:
499 return Ugreater;
500 case Ugreater:
501 return Uless;
502 case Ugreater_equal:
503 return Uless_equal;
504 case Uless_equal:
505 return Ugreater_equal;
506 case less:
507 return greater;
508 case greater:
509 return less;
510 case greater_equal:
511 return less_equal;
512 case less_equal:
513 return greater_equal;
514 default:
515 return cc;
516 };
517}
518
519
ager@chromium.org5c838252010-02-19 08:53:10 +0000520// ----- Coprocessor conditions.
521enum FPUCondition {
lrn@chromium.org34e60782011-09-15 07:25:40 +0000522 kNoFPUCondition = -1,
523
524 F = 0, // False.
525 UN = 1, // Unordered.
526 EQ = 2, // Equal.
527 UEQ = 3, // Unordered or Equal.
528 OLT = 4, // Ordered or Less Than.
529 ULT = 5, // Unordered or Less Than.
530 OLE = 6, // Ordered or Less Than or Equal.
531 ULE = 7 // Unordered or Less Than or Equal.
532};
533
534
535// FPU rounding modes.
536enum FPURoundingMode {
537 RN = 0 << 0, // Round to Nearest.
538 RZ = 1 << 0, // Round towards zero.
539 RP = 2 << 0, // Round towards Plus Infinity.
540 RM = 3 << 0, // Round towards Minus Infinity.
541
542 // Aliases.
543 kRoundToNearest = RN,
544 kRoundToZero = RZ,
545 kRoundToPlusInf = RP,
546 kRoundToMinusInf = RM
547};
548
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000549const uint32_t kFPURoundingModeMask = 3 << 0;
lrn@chromium.org34e60782011-09-15 07:25:40 +0000550
551enum CheckForInexactConversion {
552 kCheckForInexactConversion,
553 kDontCheckForInexactConversion
ager@chromium.org5c838252010-02-19 08:53:10 +0000554};
555
556
lrn@chromium.org7516f052011-03-30 08:52:27 +0000557// -----------------------------------------------------------------------------
558// Hints.
559
560// Branch hints are not used on the MIPS. They are defined so that they can
561// appear in shared function signatures, but will be ignored in MIPS
562// implementations.
563enum Hint {
564 no_hint = 0
565};
566
567
568inline Hint NegateHint(Hint hint) {
569 return no_hint;
570}
571
572
573// -----------------------------------------------------------------------------
574// Specific instructions, constants, and masks.
575// These constants are declared in assembler-mips.cc, as they use named
576// registers and other constants.
577
578// addiu(sp, sp, 4) aka Pop() operation or part of Pop(r)
579// operations as post-increment of sp.
580extern const Instr kPopInstruction;
581// addiu(sp, sp, -4) part of Push(r) operation as pre-decrement of sp.
582extern const Instr kPushInstruction;
583// sw(r, MemOperand(sp, 0))
584extern const Instr kPushRegPattern;
karlklose@chromium.org83a47282011-05-11 11:54:09 +0000585// lw(r, MemOperand(sp, 0))
lrn@chromium.org7516f052011-03-30 08:52:27 +0000586extern const Instr kPopRegPattern;
587extern const Instr kLwRegFpOffsetPattern;
588extern const Instr kSwRegFpOffsetPattern;
589extern const Instr kLwRegFpNegOffsetPattern;
590extern const Instr kSwRegFpNegOffsetPattern;
591// A mask for the Rt register for push, pop, lw, sw instructions.
592extern const Instr kRtMask;
593extern const Instr kLwSwInstrTypeMask;
594extern const Instr kLwSwInstrArgumentMask;
595extern const Instr kLwSwOffsetMask;
596
ager@chromium.org5c838252010-02-19 08:53:10 +0000597// Break 0xfffff, reserved for redirected real time call.
598const Instr rtCallRedirInstr = SPECIAL | BREAK | call_rt_redirected << 6;
599// A nop instruction. (Encoding of sll 0 0 0).
600const Instr nopInstr = 0;
601
602class Instruction {
603 public:
604 enum {
lrn@chromium.org7516f052011-03-30 08:52:27 +0000605 kInstrSize = 4,
606 kInstrSizeLog2 = 2,
ager@chromium.org5c838252010-02-19 08:53:10 +0000607 // On MIPS PC cannot actually be directly accessed. We behave as if PC was
lrn@chromium.org7516f052011-03-30 08:52:27 +0000608 // always the value of the current instruction being executed.
ager@chromium.org5c838252010-02-19 08:53:10 +0000609 kPCReadOffset = 0
610 };
611
612 // Get the raw instruction bits.
613 inline Instr InstructionBits() const {
614 return *reinterpret_cast<const Instr*>(this);
615 }
616
617 // Set the raw instruction bits to value.
618 inline void SetInstructionBits(Instr value) {
619 *reinterpret_cast<Instr*>(this) = value;
620 }
621
622 // Read one particular bit out of the instruction bits.
623 inline int Bit(int nr) const {
624 return (InstructionBits() >> nr) & 1;
625 }
626
627 // Read a bit field out of the instruction bits.
628 inline int Bits(int hi, int lo) const {
629 return (InstructionBits() >> lo) & ((2 << (hi - lo)) - 1);
630 }
631
632 // Instruction type.
633 enum Type {
634 kRegisterType,
635 kImmediateType,
636 kJumpType,
637 kUnsupported = -1
638 };
639
640 // Get the encoding type of the instruction.
641 Type InstructionType() const;
642
643
644 // Accessors for the different named fields used in the MIPS encoding.
lrn@chromium.org7516f052011-03-30 08:52:27 +0000645 inline Opcode OpcodeValue() const {
ager@chromium.org5c838252010-02-19 08:53:10 +0000646 return static_cast<Opcode>(
647 Bits(kOpcodeShift + kOpcodeBits - 1, kOpcodeShift));
648 }
649
lrn@chromium.org7516f052011-03-30 08:52:27 +0000650 inline int RsValue() const {
ager@chromium.org5c838252010-02-19 08:53:10 +0000651 ASSERT(InstructionType() == kRegisterType ||
652 InstructionType() == kImmediateType);
653 return Bits(kRsShift + kRsBits - 1, kRsShift);
654 }
655
lrn@chromium.org7516f052011-03-30 08:52:27 +0000656 inline int RtValue() const {
ager@chromium.org5c838252010-02-19 08:53:10 +0000657 ASSERT(InstructionType() == kRegisterType ||
658 InstructionType() == kImmediateType);
659 return Bits(kRtShift + kRtBits - 1, kRtShift);
660 }
661
lrn@chromium.org7516f052011-03-30 08:52:27 +0000662 inline int RdValue() const {
ager@chromium.org5c838252010-02-19 08:53:10 +0000663 ASSERT(InstructionType() == kRegisterType);
664 return Bits(kRdShift + kRdBits - 1, kRdShift);
665 }
666
lrn@chromium.org7516f052011-03-30 08:52:27 +0000667 inline int SaValue() const {
ager@chromium.org5c838252010-02-19 08:53:10 +0000668 ASSERT(InstructionType() == kRegisterType);
669 return Bits(kSaShift + kSaBits - 1, kSaShift);
670 }
671
lrn@chromium.org7516f052011-03-30 08:52:27 +0000672 inline int FunctionValue() const {
ager@chromium.org5c838252010-02-19 08:53:10 +0000673 ASSERT(InstructionType() == kRegisterType ||
674 InstructionType() == kImmediateType);
675 return Bits(kFunctionShift + kFunctionBits - 1, kFunctionShift);
676 }
677
lrn@chromium.org7516f052011-03-30 08:52:27 +0000678 inline int FdValue() const {
679 return Bits(kFdShift + kFdBits - 1, kFdShift);
ager@chromium.org5c838252010-02-19 08:53:10 +0000680 }
681
lrn@chromium.org7516f052011-03-30 08:52:27 +0000682 inline int FsValue() const {
683 return Bits(kFsShift + kFsBits - 1, kFsShift);
684 }
685
686 inline int FtValue() const {
687 return Bits(kFtShift + kFtBits - 1, kFtShift);
688 }
689
jkummerow@chromium.org59297c72013-01-09 16:32:23 +0000690 inline int FrValue() const {
691 return Bits(kFrShift + kFrBits -1, kFrShift);
692 }
693
lrn@chromium.org7516f052011-03-30 08:52:27 +0000694 // Float Compare condition code instruction bits.
695 inline int FCccValue() const {
696 return Bits(kFCccShift + kFCccBits - 1, kFCccShift);
697 }
698
699 // Float Branch condition code instruction bits.
700 inline int FBccValue() const {
701 return Bits(kFBccShift + kFBccBits - 1, kFBccShift);
702 }
703
704 // Float Branch true/false instruction bit.
705 inline int FBtrueValue() const {
706 return Bits(kFBtrueShift + kFBtrueBits - 1, kFBtrueShift);
ager@chromium.org5c838252010-02-19 08:53:10 +0000707 }
708
709 // Return the fields at their original place in the instruction encoding.
710 inline Opcode OpcodeFieldRaw() const {
711 return static_cast<Opcode>(InstructionBits() & kOpcodeMask);
712 }
713
714 inline int RsFieldRaw() const {
715 ASSERT(InstructionType() == kRegisterType ||
716 InstructionType() == kImmediateType);
717 return InstructionBits() & kRsFieldMask;
718 }
719
lrn@chromium.org7516f052011-03-30 08:52:27 +0000720 // Same as above function, but safe to call within InstructionType().
721 inline int RsFieldRawNoAssert() const {
722 return InstructionBits() & kRsFieldMask;
723 }
724
ager@chromium.org5c838252010-02-19 08:53:10 +0000725 inline int RtFieldRaw() const {
726 ASSERT(InstructionType() == kRegisterType ||
727 InstructionType() == kImmediateType);
728 return InstructionBits() & kRtFieldMask;
729 }
730
731 inline int RdFieldRaw() const {
732 ASSERT(InstructionType() == kRegisterType);
733 return InstructionBits() & kRdFieldMask;
734 }
735
736 inline int SaFieldRaw() const {
737 ASSERT(InstructionType() == kRegisterType);
738 return InstructionBits() & kSaFieldMask;
739 }
740
741 inline int FunctionFieldRaw() const {
742 return InstructionBits() & kFunctionFieldMask;
743 }
744
745 // Get the secondary field according to the opcode.
lrn@chromium.org7516f052011-03-30 08:52:27 +0000746 inline int SecondaryValue() const {
ager@chromium.org5c838252010-02-19 08:53:10 +0000747 Opcode op = OpcodeFieldRaw();
748 switch (op) {
749 case SPECIAL:
750 case SPECIAL2:
lrn@chromium.org7516f052011-03-30 08:52:27 +0000751 return FunctionValue();
ager@chromium.org5c838252010-02-19 08:53:10 +0000752 case COP1:
lrn@chromium.org7516f052011-03-30 08:52:27 +0000753 return RsValue();
ager@chromium.org5c838252010-02-19 08:53:10 +0000754 case REGIMM:
lrn@chromium.org7516f052011-03-30 08:52:27 +0000755 return RtValue();
ager@chromium.org5c838252010-02-19 08:53:10 +0000756 default:
757 return NULLSF;
758 }
759 }
760
lrn@chromium.org7516f052011-03-30 08:52:27 +0000761 inline int32_t Imm16Value() const {
ager@chromium.org5c838252010-02-19 08:53:10 +0000762 ASSERT(InstructionType() == kImmediateType);
763 return Bits(kImm16Shift + kImm16Bits - 1, kImm16Shift);
764 }
765
lrn@chromium.org7516f052011-03-30 08:52:27 +0000766 inline int32_t Imm26Value() const {
ager@chromium.org5c838252010-02-19 08:53:10 +0000767 ASSERT(InstructionType() == kJumpType);
lrn@chromium.org34e60782011-09-15 07:25:40 +0000768 return Bits(kImm26Shift + kImm26Bits - 1, kImm26Shift);
ager@chromium.org5c838252010-02-19 08:53:10 +0000769 }
770
771 // Say if the instruction should not be used in a branch delay slot.
lrn@chromium.org7516f052011-03-30 08:52:27 +0000772 bool IsForbiddenInBranchDelay() const;
ulan@chromium.org2efb9002012-01-19 15:36:35 +0000773 // Say if the instruction 'links'. e.g. jal, bal.
lrn@chromium.org7516f052011-03-30 08:52:27 +0000774 bool IsLinkingInstruction() const;
ager@chromium.org5c838252010-02-19 08:53:10 +0000775 // Say if the instruction is a break or a trap.
lrn@chromium.org7516f052011-03-30 08:52:27 +0000776 bool IsTrap() const;
ager@chromium.org5c838252010-02-19 08:53:10 +0000777
778 // Instructions are read of out a code stream. The only way to get a
779 // reference to an instruction is to convert a pointer. There is no way
780 // to allocate or create instances of class Instruction.
781 // Use the At(pc) function to create references to Instruction.
karlklose@chromium.org83a47282011-05-11 11:54:09 +0000782 static Instruction* At(byte* pc) {
ager@chromium.org5c838252010-02-19 08:53:10 +0000783 return reinterpret_cast<Instruction*>(pc);
784 }
785
786 private:
787 // We need to prevent the creation of instances of class Instruction.
788 DISALLOW_IMPLICIT_CONSTRUCTORS(Instruction);
789};
790
791
792// -----------------------------------------------------------------------------
793// MIPS assembly various constants.
794
lrn@chromium.org7516f052011-03-30 08:52:27 +0000795// C/C++ argument slots size.
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000796const int kCArgSlotCount = 4;
797const int kCArgsSlotsSize = kCArgSlotCount * Instruction::kInstrSize;
lrn@chromium.org7516f052011-03-30 08:52:27 +0000798// JS argument slots size.
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000799const int kJSArgsSlotsSize = 0 * Instruction::kInstrSize;
lrn@chromium.org7516f052011-03-30 08:52:27 +0000800// Assembly builtins argument slots size.
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000801const int kBArgsSlotsSize = 0 * Instruction::kInstrSize;
ager@chromium.org5c838252010-02-19 08:53:10 +0000802
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000803const int kBranchReturnOffset = 2 * Instruction::kInstrSize;
ager@chromium.org5c838252010-02-19 08:53:10 +0000804
lrn@chromium.org7516f052011-03-30 08:52:27 +0000805} } // namespace v8::internal
ager@chromium.org5c838252010-02-19 08:53:10 +0000806
807#endif // #ifndef V8_MIPS_CONSTANTS_H_