blob: dcf8b82db03dad803426eb474fbb37ad722aa812 [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)
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +000064// This flag is raised when -msoft-float is passed to the compiler.
65// Although FPU is a base requirement for v8, soft-float ABI is used
66// on soft-float systems with FPU kernel emulation.
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +000067const bool IsMipsSoftFloatABI = true;
danno@chromium.org40cb8782011-05-25 07:58:50 +000068#else
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +000069const bool IsMipsSoftFloatABI = true;
danno@chromium.org40cb8782011-05-25 07:58:50 +000070#endif
71
72
ager@chromium.org5c838252010-02-19 08:53:10 +000073// Defines constants and accessor classes to assemble, disassemble and
74// simulate MIPS32 instructions.
75//
76// See: MIPS32 Architecture For Programmers
77// Volume II: The MIPS32 Instruction Set
78// Try www.cs.cornell.edu/courses/cs3410/2008fa/MIPS_Vol2.pdf.
79
lrn@chromium.org7516f052011-03-30 08:52:27 +000080namespace v8 {
81namespace internal {
ager@chromium.org5c838252010-02-19 08:53:10 +000082
83// -----------------------------------------------------------------------------
karlklose@chromium.org83a47282011-05-11 11:54:09 +000084// Registers and FPURegisters.
ager@chromium.org5c838252010-02-19 08:53:10 +000085
86// Number of general purpose registers.
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +000087const int kNumRegisters = 32;
88const int kInvalidRegister = -1;
ager@chromium.org5c838252010-02-19 08:53:10 +000089
90// Number of registers with HI, LO, and pc.
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +000091const int kNumSimuRegisters = 35;
ager@chromium.org5c838252010-02-19 08:53:10 +000092
93// In the simulator, the PC register is simulated as the 34th register.
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +000094const int kPCRegister = 34;
ager@chromium.org5c838252010-02-19 08:53:10 +000095
96// Number coprocessor registers.
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +000097const int kNumFPURegisters = 32;
98const int kInvalidFPURegister = -1;
ager@chromium.org5c838252010-02-19 08:53:10 +000099
lrn@chromium.org7516f052011-03-30 08:52:27 +0000100// FPU (coprocessor 1) control registers. Currently only FCSR is implemented.
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000101const int kFCSRRegister = 31;
102const int kInvalidFPUControlRegister = -1;
jkummerow@chromium.org59297c72013-01-09 16:32:23 +0000103const uint32_t kFPUInvalidResult = static_cast<uint32_t>(1 << 31) - 1;
lrn@chromium.org7516f052011-03-30 08:52:27 +0000104
105// FCSR constants.
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000106const uint32_t kFCSRInexactFlagBit = 2;
107const uint32_t kFCSRUnderflowFlagBit = 3;
108const uint32_t kFCSROverflowFlagBit = 4;
109const uint32_t kFCSRDivideByZeroFlagBit = 5;
110const uint32_t kFCSRInvalidOpFlagBit = 6;
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +0000111
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000112const uint32_t kFCSRInexactFlagMask = 1 << kFCSRInexactFlagBit;
113const uint32_t kFCSRUnderflowFlagMask = 1 << kFCSRUnderflowFlagBit;
114const uint32_t kFCSROverflowFlagMask = 1 << kFCSROverflowFlagBit;
115const uint32_t kFCSRDivideByZeroFlagMask = 1 << kFCSRDivideByZeroFlagBit;
116const uint32_t kFCSRInvalidOpFlagMask = 1 << kFCSRInvalidOpFlagBit;
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +0000117
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000118const uint32_t kFCSRFlagMask =
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +0000119 kFCSRInexactFlagMask |
120 kFCSRUnderflowFlagMask |
121 kFCSROverflowFlagMask |
122 kFCSRDivideByZeroFlagMask |
123 kFCSRInvalidOpFlagMask;
124
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000125const uint32_t kFCSRExceptionFlagMask = kFCSRFlagMask ^ kFCSRInexactFlagMask;
lrn@chromium.org7516f052011-03-30 08:52:27 +0000126
machenbach@chromium.orgafbdadc2013-12-09 16:12:18 +0000127// 'pref' instruction hints
128const int32_t kPrefHintLoad = 0;
129const int32_t kPrefHintStore = 1;
130const int32_t kPrefHintLoadStreamed = 4;
131const int32_t kPrefHintStoreStreamed = 5;
132const int32_t kPrefHintLoadRetained = 6;
133const int32_t kPrefHintStoreRetained = 7;
134const int32_t kPrefHintWritebackInvalidate = 25;
135const int32_t kPrefHintPrepareForStore = 30;
136
ager@chromium.org5c838252010-02-19 08:53:10 +0000137// Helper functions for converting between register numbers and names.
138class Registers {
139 public:
140 // Return the name of the register.
141 static const char* Name(int reg);
142
143 // Lookup the register number for the name provided.
144 static int Number(const char* name);
145
146 struct RegisterAlias {
147 int reg;
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +0000148 const char* name;
ager@chromium.org5c838252010-02-19 08:53:10 +0000149 };
150
151 static const int32_t kMaxValue = 0x7fffffff;
152 static const int32_t kMinValue = 0x80000000;
153
154 private:
ager@chromium.org5c838252010-02-19 08:53:10 +0000155 static const char* names_[kNumSimuRegisters];
156 static const RegisterAlias aliases_[];
157};
158
159// Helper functions for converting between register numbers and names.
lrn@chromium.org7516f052011-03-30 08:52:27 +0000160class FPURegisters {
ager@chromium.org5c838252010-02-19 08:53:10 +0000161 public:
162 // Return the name of the register.
163 static const char* Name(int reg);
164
165 // Lookup the register number for the name provided.
166 static int Number(const char* name);
167
168 struct RegisterAlias {
169 int creg;
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +0000170 const char* name;
ager@chromium.org5c838252010-02-19 08:53:10 +0000171 };
172
173 private:
lrn@chromium.org7516f052011-03-30 08:52:27 +0000174 static const char* names_[kNumFPURegisters];
ager@chromium.org5c838252010-02-19 08:53:10 +0000175 static const RegisterAlias aliases_[];
176};
177
178
179// -----------------------------------------------------------------------------
180// Instructions encoding constants.
181
182// On MIPS all instructions are 32 bits.
183typedef int32_t Instr;
184
ager@chromium.org5c838252010-02-19 08:53:10 +0000185// Special Software Interrupt codes when used in the presence of the MIPS
186// simulator.
187enum SoftwareInterruptCodes {
188 // Transition to C code.
189 call_rt_redirected = 0xfffff
190};
191
ricow@chromium.orgc54d3652011-05-30 09:20:16 +0000192// On MIPS Simulator breakpoints can have different codes:
193// - Breaks between 0 and kMaxWatchpointCode are treated as simple watchpoints,
194// the simulator will run through them and print the registers.
195// - Breaks between kMaxWatchpointCode and kMaxStopCode are treated as stop()
196// instructions (see Assembler::stop()).
197// - Breaks larger than kMaxStopCode are simple breaks, dropping you into the
198// debugger.
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000199const uint32_t kMaxWatchpointCode = 31;
200const uint32_t kMaxStopCode = 127;
ricow@chromium.orgc54d3652011-05-30 09:20:16 +0000201STATIC_ASSERT(kMaxWatchpointCode < kMaxStopCode);
202
203
ager@chromium.org5c838252010-02-19 08:53:10 +0000204// ----- Fields offset and length.
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000205const int kOpcodeShift = 26;
206const int kOpcodeBits = 6;
207const int kRsShift = 21;
208const int kRsBits = 5;
209const int kRtShift = 16;
210const int kRtBits = 5;
211const int kRdShift = 11;
212const int kRdBits = 5;
213const int kSaShift = 6;
214const int kSaBits = 5;
215const int kFunctionShift = 0;
216const int kFunctionBits = 6;
217const int kLuiShift = 16;
ager@chromium.org5c838252010-02-19 08:53:10 +0000218
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000219const int kImm16Shift = 0;
220const int kImm16Bits = 16;
221const int kImm26Shift = 0;
222const int kImm26Bits = 26;
223const int kImm28Shift = 0;
224const int kImm28Bits = 28;
ager@chromium.org5c838252010-02-19 08:53:10 +0000225
lrn@chromium.org34e60782011-09-15 07:25:40 +0000226// In branches and jumps immediate fields point to words, not bytes,
227// and are therefore shifted by 2.
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000228const int kImmFieldShift = 2;
lrn@chromium.org34e60782011-09-15 07:25:40 +0000229
jkummerow@chromium.org59297c72013-01-09 16:32:23 +0000230const int kFrBits = 5;
231const int kFrShift = 21;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000232const int kFsShift = 11;
233const int kFsBits = 5;
234const int kFtShift = 16;
235const int kFtBits = 5;
236const int kFdShift = 6;
237const int kFdBits = 5;
238const int kFCccShift = 8;
239const int kFCccBits = 3;
240const int kFBccShift = 18;
241const int kFBccBits = 3;
242const int kFBtrueShift = 16;
243const int kFBtrueBits = 1;
ager@chromium.org5c838252010-02-19 08:53:10 +0000244
karlklose@chromium.org83a47282011-05-11 11:54:09 +0000245// ----- Miscellaneous useful masks.
ager@chromium.org5c838252010-02-19 08:53:10 +0000246// Instruction bit masks.
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000247const int kOpcodeMask = ((1 << kOpcodeBits) - 1) << kOpcodeShift;
248const int kImm16Mask = ((1 << kImm16Bits) - 1) << kImm16Shift;
249const int kImm26Mask = ((1 << kImm26Bits) - 1) << kImm26Shift;
250const int kImm28Mask = ((1 << kImm28Bits) - 1) << kImm28Shift;
251const int kRsFieldMask = ((1 << kRsBits) - 1) << kRsShift;
252const int kRtFieldMask = ((1 << kRtBits) - 1) << kRtShift;
253const int kRdFieldMask = ((1 << kRdBits) - 1) << kRdShift;
254const int kSaFieldMask = ((1 << kSaBits) - 1) << kSaShift;
255const int kFunctionFieldMask = ((1 << kFunctionBits) - 1) << kFunctionShift;
ager@chromium.org5c838252010-02-19 08:53:10 +0000256// Misc masks.
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000257const int kHiMask = 0xffff << 16;
258const int kLoMask = 0xffff;
259const int kSignMask = 0x80000000;
260const int kJumpAddrMask = (1 << (kImm26Bits + kImmFieldShift)) - 1;
ager@chromium.org5c838252010-02-19 08:53:10 +0000261
262// ----- MIPS Opcodes and Function Fields.
263// We use this presentation to stay close to the table representation in
264// MIPS32 Architecture For Programmers, Volume II: The MIPS32 Instruction Set.
265enum Opcode {
266 SPECIAL = 0 << kOpcodeShift,
267 REGIMM = 1 << kOpcodeShift,
268
269 J = ((0 << 3) + 2) << kOpcodeShift,
270 JAL = ((0 << 3) + 3) << kOpcodeShift,
271 BEQ = ((0 << 3) + 4) << kOpcodeShift,
272 BNE = ((0 << 3) + 5) << kOpcodeShift,
273 BLEZ = ((0 << 3) + 6) << kOpcodeShift,
274 BGTZ = ((0 << 3) + 7) << kOpcodeShift,
275
276 ADDI = ((1 << 3) + 0) << kOpcodeShift,
277 ADDIU = ((1 << 3) + 1) << kOpcodeShift,
278 SLTI = ((1 << 3) + 2) << kOpcodeShift,
279 SLTIU = ((1 << 3) + 3) << kOpcodeShift,
280 ANDI = ((1 << 3) + 4) << kOpcodeShift,
281 ORI = ((1 << 3) + 5) << kOpcodeShift,
282 XORI = ((1 << 3) + 6) << kOpcodeShift,
283 LUI = ((1 << 3) + 7) << kOpcodeShift,
284
karlklose@chromium.org83a47282011-05-11 11:54:09 +0000285 COP1 = ((2 << 3) + 1) << kOpcodeShift, // Coprocessor 1 class.
ager@chromium.org5c838252010-02-19 08:53:10 +0000286 BEQL = ((2 << 3) + 4) << kOpcodeShift,
287 BNEL = ((2 << 3) + 5) << kOpcodeShift,
288 BLEZL = ((2 << 3) + 6) << kOpcodeShift,
289 BGTZL = ((2 << 3) + 7) << kOpcodeShift,
290
291 SPECIAL2 = ((3 << 3) + 4) << kOpcodeShift,
lrn@chromium.org7516f052011-03-30 08:52:27 +0000292 SPECIAL3 = ((3 << 3) + 7) << kOpcodeShift,
ager@chromium.org5c838252010-02-19 08:53:10 +0000293
294 LB = ((4 << 3) + 0) << kOpcodeShift,
lrn@chromium.org7516f052011-03-30 08:52:27 +0000295 LH = ((4 << 3) + 1) << kOpcodeShift,
296 LWL = ((4 << 3) + 2) << kOpcodeShift,
ager@chromium.org5c838252010-02-19 08:53:10 +0000297 LW = ((4 << 3) + 3) << kOpcodeShift,
298 LBU = ((4 << 3) + 4) << kOpcodeShift,
lrn@chromium.org7516f052011-03-30 08:52:27 +0000299 LHU = ((4 << 3) + 5) << kOpcodeShift,
300 LWR = ((4 << 3) + 6) << kOpcodeShift,
ager@chromium.org5c838252010-02-19 08:53:10 +0000301 SB = ((5 << 3) + 0) << kOpcodeShift,
lrn@chromium.org7516f052011-03-30 08:52:27 +0000302 SH = ((5 << 3) + 1) << kOpcodeShift,
303 SWL = ((5 << 3) + 2) << kOpcodeShift,
ager@chromium.org5c838252010-02-19 08:53:10 +0000304 SW = ((5 << 3) + 3) << kOpcodeShift,
lrn@chromium.org7516f052011-03-30 08:52:27 +0000305 SWR = ((5 << 3) + 6) << kOpcodeShift,
ager@chromium.org5c838252010-02-19 08:53:10 +0000306
307 LWC1 = ((6 << 3) + 1) << kOpcodeShift,
308 LDC1 = ((6 << 3) + 5) << kOpcodeShift,
309
machenbach@chromium.orgafbdadc2013-12-09 16:12:18 +0000310 PREF = ((6 << 3) + 3) << kOpcodeShift,
311
ager@chromium.org5c838252010-02-19 08:53:10 +0000312 SWC1 = ((7 << 3) + 1) << kOpcodeShift,
jkummerow@chromium.org59297c72013-01-09 16:32:23 +0000313 SDC1 = ((7 << 3) + 5) << kOpcodeShift,
314
315 COP1X = ((1 << 4) + 3) << kOpcodeShift
ager@chromium.org5c838252010-02-19 08:53:10 +0000316};
317
318enum SecondaryField {
319 // SPECIAL Encoding of Function Field.
320 SLL = ((0 << 3) + 0),
lrn@chromium.org34e60782011-09-15 07:25:40 +0000321 MOVCI = ((0 << 3) + 1),
ager@chromium.org5c838252010-02-19 08:53:10 +0000322 SRL = ((0 << 3) + 2),
323 SRA = ((0 << 3) + 3),
324 SLLV = ((0 << 3) + 4),
325 SRLV = ((0 << 3) + 6),
326 SRAV = ((0 << 3) + 7),
327
328 JR = ((1 << 3) + 0),
329 JALR = ((1 << 3) + 1),
lrn@chromium.org7516f052011-03-30 08:52:27 +0000330 MOVZ = ((1 << 3) + 2),
331 MOVN = ((1 << 3) + 3),
ager@chromium.org5c838252010-02-19 08:53:10 +0000332 BREAK = ((1 << 3) + 5),
333
334 MFHI = ((2 << 3) + 0),
335 MFLO = ((2 << 3) + 2),
336
337 MULT = ((3 << 3) + 0),
338 MULTU = ((3 << 3) + 1),
339 DIV = ((3 << 3) + 2),
340 DIVU = ((3 << 3) + 3),
341
342 ADD = ((4 << 3) + 0),
343 ADDU = ((4 << 3) + 1),
344 SUB = ((4 << 3) + 2),
345 SUBU = ((4 << 3) + 3),
346 AND = ((4 << 3) + 4),
347 OR = ((4 << 3) + 5),
348 XOR = ((4 << 3) + 6),
349 NOR = ((4 << 3) + 7),
350
351 SLT = ((5 << 3) + 2),
352 SLTU = ((5 << 3) + 3),
353
354 TGE = ((6 << 3) + 0),
355 TGEU = ((6 << 3) + 1),
356 TLT = ((6 << 3) + 2),
357 TLTU = ((6 << 3) + 3),
358 TEQ = ((6 << 3) + 4),
359 TNE = ((6 << 3) + 6),
360
361 // SPECIAL2 Encoding of Function Field.
362 MUL = ((0 << 3) + 2),
lrn@chromium.org7516f052011-03-30 08:52:27 +0000363 CLZ = ((4 << 3) + 0),
364 CLO = ((4 << 3) + 1),
365
366 // SPECIAL3 Encoding of Function Field.
367 EXT = ((0 << 3) + 0),
368 INS = ((0 << 3) + 4),
ager@chromium.org5c838252010-02-19 08:53:10 +0000369
370 // REGIMM encoding of rt Field.
371 BLTZ = ((0 << 3) + 0) << 16,
372 BGEZ = ((0 << 3) + 1) << 16,
373 BLTZAL = ((2 << 3) + 0) << 16,
374 BGEZAL = ((2 << 3) + 1) << 16,
375
376 // COP1 Encoding of rs Field.
377 MFC1 = ((0 << 3) + 0) << 21,
lrn@chromium.org7516f052011-03-30 08:52:27 +0000378 CFC1 = ((0 << 3) + 2) << 21,
ager@chromium.org5c838252010-02-19 08:53:10 +0000379 MFHC1 = ((0 << 3) + 3) << 21,
380 MTC1 = ((0 << 3) + 4) << 21,
lrn@chromium.org7516f052011-03-30 08:52:27 +0000381 CTC1 = ((0 << 3) + 6) << 21,
ager@chromium.org5c838252010-02-19 08:53:10 +0000382 MTHC1 = ((0 << 3) + 7) << 21,
383 BC1 = ((1 << 3) + 0) << 21,
384 S = ((2 << 3) + 0) << 21,
385 D = ((2 << 3) + 1) << 21,
386 W = ((2 << 3) + 4) << 21,
387 L = ((2 << 3) + 5) << 21,
388 PS = ((2 << 3) + 6) << 21,
389 // COP1 Encoding of Function Field When rs=S.
lrn@chromium.org7516f052011-03-30 08:52:27 +0000390 ROUND_L_S = ((1 << 3) + 0),
391 TRUNC_L_S = ((1 << 3) + 1),
392 CEIL_L_S = ((1 << 3) + 2),
393 FLOOR_L_S = ((1 << 3) + 3),
394 ROUND_W_S = ((1 << 3) + 4),
395 TRUNC_W_S = ((1 << 3) + 5),
396 CEIL_W_S = ((1 << 3) + 6),
397 FLOOR_W_S = ((1 << 3) + 7),
ager@chromium.org5c838252010-02-19 08:53:10 +0000398 CVT_D_S = ((4 << 3) + 1),
399 CVT_W_S = ((4 << 3) + 4),
400 CVT_L_S = ((4 << 3) + 5),
401 CVT_PS_S = ((4 << 3) + 6),
402 // COP1 Encoding of Function Field When rs=D.
lrn@chromium.org7516f052011-03-30 08:52:27 +0000403 ADD_D = ((0 << 3) + 0),
404 SUB_D = ((0 << 3) + 1),
405 MUL_D = ((0 << 3) + 2),
406 DIV_D = ((0 << 3) + 3),
407 SQRT_D = ((0 << 3) + 4),
408 ABS_D = ((0 << 3) + 5),
409 MOV_D = ((0 << 3) + 6),
410 NEG_D = ((0 << 3) + 7),
411 ROUND_L_D = ((1 << 3) + 0),
412 TRUNC_L_D = ((1 << 3) + 1),
413 CEIL_L_D = ((1 << 3) + 2),
414 FLOOR_L_D = ((1 << 3) + 3),
415 ROUND_W_D = ((1 << 3) + 4),
416 TRUNC_W_D = ((1 << 3) + 5),
417 CEIL_W_D = ((1 << 3) + 6),
418 FLOOR_W_D = ((1 << 3) + 7),
ager@chromium.org5c838252010-02-19 08:53:10 +0000419 CVT_S_D = ((4 << 3) + 0),
420 CVT_W_D = ((4 << 3) + 4),
421 CVT_L_D = ((4 << 3) + 5),
lrn@chromium.org7516f052011-03-30 08:52:27 +0000422 C_F_D = ((6 << 3) + 0),
423 C_UN_D = ((6 << 3) + 1),
424 C_EQ_D = ((6 << 3) + 2),
425 C_UEQ_D = ((6 << 3) + 3),
426 C_OLT_D = ((6 << 3) + 4),
427 C_ULT_D = ((6 << 3) + 5),
428 C_OLE_D = ((6 << 3) + 6),
429 C_ULE_D = ((6 << 3) + 7),
ager@chromium.org5c838252010-02-19 08:53:10 +0000430 // COP1 Encoding of Function Field When rs=W or L.
431 CVT_S_W = ((4 << 3) + 0),
432 CVT_D_W = ((4 << 3) + 1),
433 CVT_S_L = ((4 << 3) + 0),
434 CVT_D_L = ((4 << 3) + 1),
435 // COP1 Encoding of Function Field When rs=PS.
jkummerow@chromium.org59297c72013-01-09 16:32:23 +0000436 // COP1X Encoding of Function Field.
437 MADD_D = ((4 << 3) + 1),
ager@chromium.org5c838252010-02-19 08:53:10 +0000438
439 NULLSF = 0
440};
441
442
443// ----- Emulated conditions.
444// On MIPS we use this enum to abstract from conditionnal branch instructions.
ulan@chromium.org750145a2013-03-07 15:14:13 +0000445// The 'U' prefix is used to specify unsigned comparisons.
446// Oppposite conditions must be paired as odd/even numbers
447// because 'NegateCondition' function flips LSB to negate condition.
ager@chromium.org5c838252010-02-19 08:53:10 +0000448enum Condition {
449 // Any value < 0 is considered no_condition.
lrn@chromium.org7516f052011-03-30 08:52:27 +0000450 kNoCondition = -1,
ager@chromium.org5c838252010-02-19 08:53:10 +0000451
452 overflow = 0,
453 no_overflow = 1,
454 Uless = 2,
455 Ugreater_equal= 3,
456 equal = 4,
457 not_equal = 5,
458 Uless_equal = 6,
459 Ugreater = 7,
460 negative = 8,
461 positive = 9,
462 parity_even = 10,
463 parity_odd = 11,
464 less = 12,
465 greater_equal = 13,
466 less_equal = 14,
467 greater = 15,
ulan@chromium.org750145a2013-03-07 15:14:13 +0000468 ueq = 16, // Unordered or Equal.
469 nue = 17, // Not (Unordered or Equal).
ager@chromium.org5c838252010-02-19 08:53:10 +0000470
ulan@chromium.org750145a2013-03-07 15:14:13 +0000471 cc_always = 18,
ager@chromium.org5c838252010-02-19 08:53:10 +0000472
karlklose@chromium.org83a47282011-05-11 11:54:09 +0000473 // Aliases.
ager@chromium.org5c838252010-02-19 08:53:10 +0000474 carry = Uless,
475 not_carry = Ugreater_equal,
476 zero = equal,
477 eq = equal,
478 not_zero = not_equal,
479 ne = not_equal,
lrn@chromium.org7516f052011-03-30 08:52:27 +0000480 nz = not_equal,
ager@chromium.org5c838252010-02-19 08:53:10 +0000481 sign = negative,
482 not_sign = positive,
lrn@chromium.org7516f052011-03-30 08:52:27 +0000483 mi = negative,
484 pl = positive,
485 hi = Ugreater,
486 ls = Uless_equal,
487 ge = greater_equal,
488 lt = less,
489 gt = greater,
490 le = less_equal,
491 hs = Ugreater_equal,
492 lo = Uless,
493 al = cc_always,
ager@chromium.org5c838252010-02-19 08:53:10 +0000494
lrn@chromium.org7516f052011-03-30 08:52:27 +0000495 cc_default = kNoCondition
ager@chromium.org5c838252010-02-19 08:53:10 +0000496};
497
lrn@chromium.org7516f052011-03-30 08:52:27 +0000498
499// Returns the equivalent of !cc.
500// Negation of the default kNoCondition (-1) results in a non-default
501// no_condition value (-2). As long as tests for no_condition check
502// for condition < 0, this will work as expected.
503inline Condition NegateCondition(Condition cc) {
504 ASSERT(cc != cc_always);
505 return static_cast<Condition>(cc ^ 1);
506}
507
508
509inline Condition ReverseCondition(Condition cc) {
510 switch (cc) {
511 case Uless:
512 return Ugreater;
513 case Ugreater:
514 return Uless;
515 case Ugreater_equal:
516 return Uless_equal;
517 case Uless_equal:
518 return Ugreater_equal;
519 case less:
520 return greater;
521 case greater:
522 return less;
523 case greater_equal:
524 return less_equal;
525 case less_equal:
526 return greater_equal;
527 default:
528 return cc;
529 };
530}
531
532
ager@chromium.org5c838252010-02-19 08:53:10 +0000533// ----- Coprocessor conditions.
534enum FPUCondition {
lrn@chromium.org34e60782011-09-15 07:25:40 +0000535 kNoFPUCondition = -1,
536
537 F = 0, // False.
538 UN = 1, // Unordered.
539 EQ = 2, // Equal.
540 UEQ = 3, // Unordered or Equal.
541 OLT = 4, // Ordered or Less Than.
542 ULT = 5, // Unordered or Less Than.
543 OLE = 6, // Ordered or Less Than or Equal.
544 ULE = 7 // Unordered or Less Than or Equal.
545};
546
547
548// FPU rounding modes.
549enum FPURoundingMode {
550 RN = 0 << 0, // Round to Nearest.
551 RZ = 1 << 0, // Round towards zero.
552 RP = 2 << 0, // Round towards Plus Infinity.
553 RM = 3 << 0, // Round towards Minus Infinity.
554
555 // Aliases.
556 kRoundToNearest = RN,
557 kRoundToZero = RZ,
558 kRoundToPlusInf = RP,
559 kRoundToMinusInf = RM
560};
561
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000562const uint32_t kFPURoundingModeMask = 3 << 0;
lrn@chromium.org34e60782011-09-15 07:25:40 +0000563
564enum CheckForInexactConversion {
565 kCheckForInexactConversion,
566 kDontCheckForInexactConversion
ager@chromium.org5c838252010-02-19 08:53:10 +0000567};
568
569
lrn@chromium.org7516f052011-03-30 08:52:27 +0000570// -----------------------------------------------------------------------------
571// Hints.
572
573// Branch hints are not used on the MIPS. They are defined so that they can
574// appear in shared function signatures, but will be ignored in MIPS
575// implementations.
576enum Hint {
577 no_hint = 0
578};
579
580
581inline Hint NegateHint(Hint hint) {
582 return no_hint;
583}
584
585
586// -----------------------------------------------------------------------------
587// Specific instructions, constants, and masks.
588// These constants are declared in assembler-mips.cc, as they use named
589// registers and other constants.
590
591// addiu(sp, sp, 4) aka Pop() operation or part of Pop(r)
592// operations as post-increment of sp.
593extern const Instr kPopInstruction;
594// addiu(sp, sp, -4) part of Push(r) operation as pre-decrement of sp.
595extern const Instr kPushInstruction;
596// sw(r, MemOperand(sp, 0))
597extern const Instr kPushRegPattern;
karlklose@chromium.org83a47282011-05-11 11:54:09 +0000598// lw(r, MemOperand(sp, 0))
lrn@chromium.org7516f052011-03-30 08:52:27 +0000599extern const Instr kPopRegPattern;
600extern const Instr kLwRegFpOffsetPattern;
601extern const Instr kSwRegFpOffsetPattern;
602extern const Instr kLwRegFpNegOffsetPattern;
603extern const Instr kSwRegFpNegOffsetPattern;
604// A mask for the Rt register for push, pop, lw, sw instructions.
605extern const Instr kRtMask;
606extern const Instr kLwSwInstrTypeMask;
607extern const Instr kLwSwInstrArgumentMask;
608extern const Instr kLwSwOffsetMask;
609
ager@chromium.org5c838252010-02-19 08:53:10 +0000610// Break 0xfffff, reserved for redirected real time call.
611const Instr rtCallRedirInstr = SPECIAL | BREAK | call_rt_redirected << 6;
612// A nop instruction. (Encoding of sll 0 0 0).
613const Instr nopInstr = 0;
614
615class Instruction {
616 public:
617 enum {
lrn@chromium.org7516f052011-03-30 08:52:27 +0000618 kInstrSize = 4,
619 kInstrSizeLog2 = 2,
ager@chromium.org5c838252010-02-19 08:53:10 +0000620 // On MIPS PC cannot actually be directly accessed. We behave as if PC was
lrn@chromium.org7516f052011-03-30 08:52:27 +0000621 // always the value of the current instruction being executed.
ager@chromium.org5c838252010-02-19 08:53:10 +0000622 kPCReadOffset = 0
623 };
624
625 // Get the raw instruction bits.
626 inline Instr InstructionBits() const {
627 return *reinterpret_cast<const Instr*>(this);
628 }
629
630 // Set the raw instruction bits to value.
631 inline void SetInstructionBits(Instr value) {
632 *reinterpret_cast<Instr*>(this) = value;
633 }
634
635 // Read one particular bit out of the instruction bits.
636 inline int Bit(int nr) const {
637 return (InstructionBits() >> nr) & 1;
638 }
639
640 // Read a bit field out of the instruction bits.
641 inline int Bits(int hi, int lo) const {
642 return (InstructionBits() >> lo) & ((2 << (hi - lo)) - 1);
643 }
644
645 // Instruction type.
646 enum Type {
647 kRegisterType,
648 kImmediateType,
649 kJumpType,
650 kUnsupported = -1
651 };
652
653 // Get the encoding type of the instruction.
654 Type InstructionType() const;
655
656
657 // Accessors for the different named fields used in the MIPS encoding.
lrn@chromium.org7516f052011-03-30 08:52:27 +0000658 inline Opcode OpcodeValue() const {
ager@chromium.org5c838252010-02-19 08:53:10 +0000659 return static_cast<Opcode>(
660 Bits(kOpcodeShift + kOpcodeBits - 1, kOpcodeShift));
661 }
662
lrn@chromium.org7516f052011-03-30 08:52:27 +0000663 inline int RsValue() const {
ager@chromium.org5c838252010-02-19 08:53:10 +0000664 ASSERT(InstructionType() == kRegisterType ||
665 InstructionType() == kImmediateType);
666 return Bits(kRsShift + kRsBits - 1, kRsShift);
667 }
668
lrn@chromium.org7516f052011-03-30 08:52:27 +0000669 inline int RtValue() const {
ager@chromium.org5c838252010-02-19 08:53:10 +0000670 ASSERT(InstructionType() == kRegisterType ||
671 InstructionType() == kImmediateType);
672 return Bits(kRtShift + kRtBits - 1, kRtShift);
673 }
674
lrn@chromium.org7516f052011-03-30 08:52:27 +0000675 inline int RdValue() const {
ager@chromium.org5c838252010-02-19 08:53:10 +0000676 ASSERT(InstructionType() == kRegisterType);
677 return Bits(kRdShift + kRdBits - 1, kRdShift);
678 }
679
lrn@chromium.org7516f052011-03-30 08:52:27 +0000680 inline int SaValue() const {
ager@chromium.org5c838252010-02-19 08:53:10 +0000681 ASSERT(InstructionType() == kRegisterType);
682 return Bits(kSaShift + kSaBits - 1, kSaShift);
683 }
684
lrn@chromium.org7516f052011-03-30 08:52:27 +0000685 inline int FunctionValue() const {
ager@chromium.org5c838252010-02-19 08:53:10 +0000686 ASSERT(InstructionType() == kRegisterType ||
687 InstructionType() == kImmediateType);
688 return Bits(kFunctionShift + kFunctionBits - 1, kFunctionShift);
689 }
690
lrn@chromium.org7516f052011-03-30 08:52:27 +0000691 inline int FdValue() const {
692 return Bits(kFdShift + kFdBits - 1, kFdShift);
ager@chromium.org5c838252010-02-19 08:53:10 +0000693 }
694
lrn@chromium.org7516f052011-03-30 08:52:27 +0000695 inline int FsValue() const {
696 return Bits(kFsShift + kFsBits - 1, kFsShift);
697 }
698
699 inline int FtValue() const {
700 return Bits(kFtShift + kFtBits - 1, kFtShift);
701 }
702
jkummerow@chromium.org59297c72013-01-09 16:32:23 +0000703 inline int FrValue() const {
704 return Bits(kFrShift + kFrBits -1, kFrShift);
705 }
706
lrn@chromium.org7516f052011-03-30 08:52:27 +0000707 // Float Compare condition code instruction bits.
708 inline int FCccValue() const {
709 return Bits(kFCccShift + kFCccBits - 1, kFCccShift);
710 }
711
712 // Float Branch condition code instruction bits.
713 inline int FBccValue() const {
714 return Bits(kFBccShift + kFBccBits - 1, kFBccShift);
715 }
716
717 // Float Branch true/false instruction bit.
718 inline int FBtrueValue() const {
719 return Bits(kFBtrueShift + kFBtrueBits - 1, kFBtrueShift);
ager@chromium.org5c838252010-02-19 08:53:10 +0000720 }
721
722 // Return the fields at their original place in the instruction encoding.
723 inline Opcode OpcodeFieldRaw() const {
724 return static_cast<Opcode>(InstructionBits() & kOpcodeMask);
725 }
726
727 inline int RsFieldRaw() const {
728 ASSERT(InstructionType() == kRegisterType ||
729 InstructionType() == kImmediateType);
730 return InstructionBits() & kRsFieldMask;
731 }
732
lrn@chromium.org7516f052011-03-30 08:52:27 +0000733 // Same as above function, but safe to call within InstructionType().
734 inline int RsFieldRawNoAssert() const {
735 return InstructionBits() & kRsFieldMask;
736 }
737
ager@chromium.org5c838252010-02-19 08:53:10 +0000738 inline int RtFieldRaw() const {
739 ASSERT(InstructionType() == kRegisterType ||
740 InstructionType() == kImmediateType);
741 return InstructionBits() & kRtFieldMask;
742 }
743
744 inline int RdFieldRaw() const {
745 ASSERT(InstructionType() == kRegisterType);
746 return InstructionBits() & kRdFieldMask;
747 }
748
749 inline int SaFieldRaw() const {
750 ASSERT(InstructionType() == kRegisterType);
751 return InstructionBits() & kSaFieldMask;
752 }
753
754 inline int FunctionFieldRaw() const {
755 return InstructionBits() & kFunctionFieldMask;
756 }
757
758 // Get the secondary field according to the opcode.
lrn@chromium.org7516f052011-03-30 08:52:27 +0000759 inline int SecondaryValue() const {
ager@chromium.org5c838252010-02-19 08:53:10 +0000760 Opcode op = OpcodeFieldRaw();
761 switch (op) {
762 case SPECIAL:
763 case SPECIAL2:
lrn@chromium.org7516f052011-03-30 08:52:27 +0000764 return FunctionValue();
ager@chromium.org5c838252010-02-19 08:53:10 +0000765 case COP1:
lrn@chromium.org7516f052011-03-30 08:52:27 +0000766 return RsValue();
ager@chromium.org5c838252010-02-19 08:53:10 +0000767 case REGIMM:
lrn@chromium.org7516f052011-03-30 08:52:27 +0000768 return RtValue();
ager@chromium.org5c838252010-02-19 08:53:10 +0000769 default:
770 return NULLSF;
771 }
772 }
773
lrn@chromium.org7516f052011-03-30 08:52:27 +0000774 inline int32_t Imm16Value() const {
ager@chromium.org5c838252010-02-19 08:53:10 +0000775 ASSERT(InstructionType() == kImmediateType);
776 return Bits(kImm16Shift + kImm16Bits - 1, kImm16Shift);
777 }
778
lrn@chromium.org7516f052011-03-30 08:52:27 +0000779 inline int32_t Imm26Value() const {
ager@chromium.org5c838252010-02-19 08:53:10 +0000780 ASSERT(InstructionType() == kJumpType);
lrn@chromium.org34e60782011-09-15 07:25:40 +0000781 return Bits(kImm26Shift + kImm26Bits - 1, kImm26Shift);
ager@chromium.org5c838252010-02-19 08:53:10 +0000782 }
783
784 // Say if the instruction should not be used in a branch delay slot.
lrn@chromium.org7516f052011-03-30 08:52:27 +0000785 bool IsForbiddenInBranchDelay() const;
ulan@chromium.org2efb9002012-01-19 15:36:35 +0000786 // Say if the instruction 'links'. e.g. jal, bal.
lrn@chromium.org7516f052011-03-30 08:52:27 +0000787 bool IsLinkingInstruction() const;
ager@chromium.org5c838252010-02-19 08:53:10 +0000788 // Say if the instruction is a break or a trap.
lrn@chromium.org7516f052011-03-30 08:52:27 +0000789 bool IsTrap() const;
ager@chromium.org5c838252010-02-19 08:53:10 +0000790
791 // Instructions are read of out a code stream. The only way to get a
792 // reference to an instruction is to convert a pointer. There is no way
793 // to allocate or create instances of class Instruction.
794 // Use the At(pc) function to create references to Instruction.
karlklose@chromium.org83a47282011-05-11 11:54:09 +0000795 static Instruction* At(byte* pc) {
ager@chromium.org5c838252010-02-19 08:53:10 +0000796 return reinterpret_cast<Instruction*>(pc);
797 }
798
799 private:
800 // We need to prevent the creation of instances of class Instruction.
801 DISALLOW_IMPLICIT_CONSTRUCTORS(Instruction);
802};
803
804
805// -----------------------------------------------------------------------------
806// MIPS assembly various constants.
807
lrn@chromium.org7516f052011-03-30 08:52:27 +0000808// C/C++ argument slots size.
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000809const int kCArgSlotCount = 4;
810const int kCArgsSlotsSize = kCArgSlotCount * Instruction::kInstrSize;
lrn@chromium.org7516f052011-03-30 08:52:27 +0000811// JS argument slots size.
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000812const int kJSArgsSlotsSize = 0 * Instruction::kInstrSize;
lrn@chromium.org7516f052011-03-30 08:52:27 +0000813// Assembly builtins argument slots size.
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000814const int kBArgsSlotsSize = 0 * Instruction::kInstrSize;
ager@chromium.org5c838252010-02-19 08:53:10 +0000815
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000816const int kBranchReturnOffset = 2 * Instruction::kInstrSize;
ager@chromium.org5c838252010-02-19 08:53:10 +0000817
lrn@chromium.org7516f052011-03-30 08:52:27 +0000818} } // namespace v8::internal
ager@chromium.org5c838252010-02-19 08:53:10 +0000819
820#endif // #ifndef V8_MIPS_CONSTANTS_H_