blob: b20e9a284dff7ff713f4ee60f150f518482ebccb [file] [log] [blame]
Andrei Popescu31002712010-02-23 13:46:05 +00001// Copyright 2010 the V8 project authors. All rights reserved.
2// 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
Andrei Popescu31002712010-02-23 13:46:05 +000031// UNIMPLEMENTED_ macro for MIPS.
Steve Block44f0eee2011-05-26 01:26:41 +010032#ifdef DEBUG
Andrei Popescu31002712010-02-23 13:46:05 +000033#define UNIMPLEMENTED_MIPS() \
34 v8::internal::PrintF("%s, \tline %d: \tfunction %s not implemented. \n", \
35 __FILE__, __LINE__, __func__)
Steve Block44f0eee2011-05-26 01:26:41 +010036#else
37#define UNIMPLEMENTED_MIPS()
38#endif
39
Andrei Popescu31002712010-02-23 13:46:05 +000040#define UNSUPPORTED_MIPS() v8::internal::PrintF("Unsupported instruction.\n")
41
42
Steve Block44f0eee2011-05-26 01:26:41 +010043#ifdef _MIPS_ARCH_MIPS32R2
44 #define mips32r2 1
45#else
46 #define mips32r2 0
47#endif
48
49
Andrei Popescu31002712010-02-23 13:46:05 +000050// Defines constants and accessor classes to assemble, disassemble and
51// simulate MIPS32 instructions.
52//
53// See: MIPS32 Architecture For Programmers
54// Volume II: The MIPS32 Instruction Set
55// Try www.cs.cornell.edu/courses/cs3410/2008fa/MIPS_Vol2.pdf.
56
Steve Block44f0eee2011-05-26 01:26:41 +010057namespace v8 {
58namespace internal {
Andrei Popescu31002712010-02-23 13:46:05 +000059
60// -----------------------------------------------------------------------------
61// Registers and FPURegister.
62
63// Number of general purpose registers.
64static const int kNumRegisters = 32;
65static const int kInvalidRegister = -1;
66
67// Number of registers with HI, LO, and pc.
68static const int kNumSimuRegisters = 35;
69
70// In the simulator, the PC register is simulated as the 34th register.
71static const int kPCRegister = 34;
72
73// Number coprocessor registers.
Steve Block44f0eee2011-05-26 01:26:41 +010074static const int kNumFPURegisters = 32;
Andrei Popescu31002712010-02-23 13:46:05 +000075static const int kInvalidFPURegister = -1;
76
Steve Block44f0eee2011-05-26 01:26:41 +010077// FPU (coprocessor 1) control registers. Currently only FCSR is implemented.
78static const int kFCSRRegister = 31;
79static const int kInvalidFPUControlRegister = -1;
80static const uint32_t kFPUInvalidResult = (uint32_t) (1 << 31) - 1;
81
82// FCSR constants.
83static const uint32_t kFCSRFlagMask = (1 << 6) - 1;
84static const uint32_t kFCSRFlagShift = 2;
85
Andrei Popescu31002712010-02-23 13:46:05 +000086// Helper functions for converting between register numbers and names.
87class Registers {
88 public:
89 // Return the name of the register.
90 static const char* Name(int reg);
91
92 // Lookup the register number for the name provided.
93 static int Number(const char* name);
94
95 struct RegisterAlias {
96 int reg;
97 const char *name;
98 };
99
100 static const int32_t kMaxValue = 0x7fffffff;
101 static const int32_t kMinValue = 0x80000000;
102
103 private:
104
105 static const char* names_[kNumSimuRegisters];
106 static const RegisterAlias aliases_[];
107};
108
109// Helper functions for converting between register numbers and names.
Steve Block44f0eee2011-05-26 01:26:41 +0100110class FPURegisters {
Andrei Popescu31002712010-02-23 13:46:05 +0000111 public:
112 // Return the name of the register.
113 static const char* Name(int reg);
114
115 // Lookup the register number for the name provided.
116 static int Number(const char* name);
117
118 struct RegisterAlias {
119 int creg;
120 const char *name;
121 };
122
123 private:
124
Steve Block44f0eee2011-05-26 01:26:41 +0100125 static const char* names_[kNumFPURegisters];
Andrei Popescu31002712010-02-23 13:46:05 +0000126 static const RegisterAlias aliases_[];
127};
128
129
130// -----------------------------------------------------------------------------
131// Instructions encoding constants.
132
133// On MIPS all instructions are 32 bits.
134typedef int32_t Instr;
135
136typedef unsigned char byte_;
137
138// Special Software Interrupt codes when used in the presence of the MIPS
139// simulator.
140enum SoftwareInterruptCodes {
141 // Transition to C code.
142 call_rt_redirected = 0xfffff
143};
144
145// ----- Fields offset and length.
146static const int kOpcodeShift = 26;
147static const int kOpcodeBits = 6;
148static const int kRsShift = 21;
149static const int kRsBits = 5;
150static const int kRtShift = 16;
151static const int kRtBits = 5;
152static const int kRdShift = 11;
153static const int kRdBits = 5;
154static const int kSaShift = 6;
155static const int kSaBits = 5;
156static const int kFunctionShift = 0;
157static const int kFunctionBits = 6;
Steve Block44f0eee2011-05-26 01:26:41 +0100158static const int kLuiShift = 16;
Andrei Popescu31002712010-02-23 13:46:05 +0000159
160static const int kImm16Shift = 0;
161static const int kImm16Bits = 16;
162static const int kImm26Shift = 0;
163static const int kImm26Bits = 26;
164
165static const int kFsShift = 11;
166static const int kFsBits = 5;
167static const int kFtShift = 16;
168static const int kFtBits = 5;
Steve Block44f0eee2011-05-26 01:26:41 +0100169static const int kFdShift = 6;
170static const int kFdBits = 5;
171static const int kFCccShift = 8;
172static const int kFCccBits = 3;
173static const int kFBccShift = 18;
174static const int kFBccBits = 3;
175static const int kFBtrueShift = 16;
176static const int kFBtrueBits = 1;
Andrei Popescu31002712010-02-23 13:46:05 +0000177
178// ----- Miscellianous useful masks.
179// Instruction bit masks.
180static const int kOpcodeMask = ((1 << kOpcodeBits) - 1) << kOpcodeShift;
181static const int kImm16Mask = ((1 << kImm16Bits) - 1) << kImm16Shift;
182static const int kImm26Mask = ((1 << kImm26Bits) - 1) << kImm26Shift;
183static const int kRsFieldMask = ((1 << kRsBits) - 1) << kRsShift;
184static const int kRtFieldMask = ((1 << kRtBits) - 1) << kRtShift;
185static const int kRdFieldMask = ((1 << kRdBits) - 1) << kRdShift;
186static const int kSaFieldMask = ((1 << kSaBits) - 1) << kSaShift;
187static const int kFunctionFieldMask =
188 ((1 << kFunctionBits) - 1) << kFunctionShift;
189// Misc masks.
Steve Block44f0eee2011-05-26 01:26:41 +0100190static const int kHiMask = 0xffff << 16;
191static const int kLoMask = 0xffff;
192static const int kSignMask = 0x80000000;
Andrei Popescu31002712010-02-23 13:46:05 +0000193
194
195// ----- MIPS Opcodes and Function Fields.
196// We use this presentation to stay close to the table representation in
197// MIPS32 Architecture For Programmers, Volume II: The MIPS32 Instruction Set.
198enum Opcode {
199 SPECIAL = 0 << kOpcodeShift,
200 REGIMM = 1 << kOpcodeShift,
201
202 J = ((0 << 3) + 2) << kOpcodeShift,
203 JAL = ((0 << 3) + 3) << kOpcodeShift,
204 BEQ = ((0 << 3) + 4) << kOpcodeShift,
205 BNE = ((0 << 3) + 5) << kOpcodeShift,
206 BLEZ = ((0 << 3) + 6) << kOpcodeShift,
207 BGTZ = ((0 << 3) + 7) << kOpcodeShift,
208
209 ADDI = ((1 << 3) + 0) << kOpcodeShift,
210 ADDIU = ((1 << 3) + 1) << kOpcodeShift,
211 SLTI = ((1 << 3) + 2) << kOpcodeShift,
212 SLTIU = ((1 << 3) + 3) << kOpcodeShift,
213 ANDI = ((1 << 3) + 4) << kOpcodeShift,
214 ORI = ((1 << 3) + 5) << kOpcodeShift,
215 XORI = ((1 << 3) + 6) << kOpcodeShift,
216 LUI = ((1 << 3) + 7) << kOpcodeShift,
217
218 COP1 = ((2 << 3) + 1) << kOpcodeShift, // Coprocessor 1 class
219 BEQL = ((2 << 3) + 4) << kOpcodeShift,
220 BNEL = ((2 << 3) + 5) << kOpcodeShift,
221 BLEZL = ((2 << 3) + 6) << kOpcodeShift,
222 BGTZL = ((2 << 3) + 7) << kOpcodeShift,
223
224 SPECIAL2 = ((3 << 3) + 4) << kOpcodeShift,
Steve Block44f0eee2011-05-26 01:26:41 +0100225 SPECIAL3 = ((3 << 3) + 7) << kOpcodeShift,
Andrei Popescu31002712010-02-23 13:46:05 +0000226
227 LB = ((4 << 3) + 0) << kOpcodeShift,
Steve Block44f0eee2011-05-26 01:26:41 +0100228 LH = ((4 << 3) + 1) << kOpcodeShift,
229 LWL = ((4 << 3) + 2) << kOpcodeShift,
Andrei Popescu31002712010-02-23 13:46:05 +0000230 LW = ((4 << 3) + 3) << kOpcodeShift,
231 LBU = ((4 << 3) + 4) << kOpcodeShift,
Steve Block44f0eee2011-05-26 01:26:41 +0100232 LHU = ((4 << 3) + 5) << kOpcodeShift,
233 LWR = ((4 << 3) + 6) << kOpcodeShift,
Andrei Popescu31002712010-02-23 13:46:05 +0000234 SB = ((5 << 3) + 0) << kOpcodeShift,
Steve Block44f0eee2011-05-26 01:26:41 +0100235 SH = ((5 << 3) + 1) << kOpcodeShift,
236 SWL = ((5 << 3) + 2) << kOpcodeShift,
Andrei Popescu31002712010-02-23 13:46:05 +0000237 SW = ((5 << 3) + 3) << kOpcodeShift,
Steve Block44f0eee2011-05-26 01:26:41 +0100238 SWR = ((5 << 3) + 6) << kOpcodeShift,
Andrei Popescu31002712010-02-23 13:46:05 +0000239
240 LWC1 = ((6 << 3) + 1) << kOpcodeShift,
241 LDC1 = ((6 << 3) + 5) << kOpcodeShift,
242
243 SWC1 = ((7 << 3) + 1) << kOpcodeShift,
244 SDC1 = ((7 << 3) + 5) << kOpcodeShift
245};
246
247enum SecondaryField {
248 // SPECIAL Encoding of Function Field.
249 SLL = ((0 << 3) + 0),
250 SRL = ((0 << 3) + 2),
251 SRA = ((0 << 3) + 3),
252 SLLV = ((0 << 3) + 4),
253 SRLV = ((0 << 3) + 6),
254 SRAV = ((0 << 3) + 7),
Steve Block44f0eee2011-05-26 01:26:41 +0100255 MOVCI = ((0 << 3) + 1),
Andrei Popescu31002712010-02-23 13:46:05 +0000256
257 JR = ((1 << 3) + 0),
258 JALR = ((1 << 3) + 1),
Steve Block44f0eee2011-05-26 01:26:41 +0100259 MOVZ = ((1 << 3) + 2),
260 MOVN = ((1 << 3) + 3),
Andrei Popescu31002712010-02-23 13:46:05 +0000261 BREAK = ((1 << 3) + 5),
262
263 MFHI = ((2 << 3) + 0),
264 MFLO = ((2 << 3) + 2),
265
266 MULT = ((3 << 3) + 0),
267 MULTU = ((3 << 3) + 1),
268 DIV = ((3 << 3) + 2),
269 DIVU = ((3 << 3) + 3),
270
271 ADD = ((4 << 3) + 0),
272 ADDU = ((4 << 3) + 1),
273 SUB = ((4 << 3) + 2),
274 SUBU = ((4 << 3) + 3),
275 AND = ((4 << 3) + 4),
276 OR = ((4 << 3) + 5),
277 XOR = ((4 << 3) + 6),
278 NOR = ((4 << 3) + 7),
279
280 SLT = ((5 << 3) + 2),
281 SLTU = ((5 << 3) + 3),
282
283 TGE = ((6 << 3) + 0),
284 TGEU = ((6 << 3) + 1),
285 TLT = ((6 << 3) + 2),
286 TLTU = ((6 << 3) + 3),
287 TEQ = ((6 << 3) + 4),
288 TNE = ((6 << 3) + 6),
289
290 // SPECIAL2 Encoding of Function Field.
291 MUL = ((0 << 3) + 2),
Steve Block44f0eee2011-05-26 01:26:41 +0100292 CLZ = ((4 << 3) + 0),
293 CLO = ((4 << 3) + 1),
294
295 // SPECIAL3 Encoding of Function Field.
296 EXT = ((0 << 3) + 0),
297 INS = ((0 << 3) + 4),
Andrei Popescu31002712010-02-23 13:46:05 +0000298
299 // REGIMM encoding of rt Field.
300 BLTZ = ((0 << 3) + 0) << 16,
301 BGEZ = ((0 << 3) + 1) << 16,
302 BLTZAL = ((2 << 3) + 0) << 16,
303 BGEZAL = ((2 << 3) + 1) << 16,
304
305 // COP1 Encoding of rs Field.
306 MFC1 = ((0 << 3) + 0) << 21,
Steve Block44f0eee2011-05-26 01:26:41 +0100307 CFC1 = ((0 << 3) + 2) << 21,
Andrei Popescu31002712010-02-23 13:46:05 +0000308 MFHC1 = ((0 << 3) + 3) << 21,
309 MTC1 = ((0 << 3) + 4) << 21,
Steve Block44f0eee2011-05-26 01:26:41 +0100310 CTC1 = ((0 << 3) + 6) << 21,
Andrei Popescu31002712010-02-23 13:46:05 +0000311 MTHC1 = ((0 << 3) + 7) << 21,
312 BC1 = ((1 << 3) + 0) << 21,
313 S = ((2 << 3) + 0) << 21,
314 D = ((2 << 3) + 1) << 21,
315 W = ((2 << 3) + 4) << 21,
316 L = ((2 << 3) + 5) << 21,
317 PS = ((2 << 3) + 6) << 21,
318 // COP1 Encoding of Function Field When rs=S.
Steve Block44f0eee2011-05-26 01:26:41 +0100319 ROUND_L_S = ((1 << 3) + 0),
320 TRUNC_L_S = ((1 << 3) + 1),
321 CEIL_L_S = ((1 << 3) + 2),
322 FLOOR_L_S = ((1 << 3) + 3),
323 ROUND_W_S = ((1 << 3) + 4),
324 TRUNC_W_S = ((1 << 3) + 5),
325 CEIL_W_S = ((1 << 3) + 6),
326 FLOOR_W_S = ((1 << 3) + 7),
Andrei Popescu31002712010-02-23 13:46:05 +0000327 CVT_D_S = ((4 << 3) + 1),
328 CVT_W_S = ((4 << 3) + 4),
329 CVT_L_S = ((4 << 3) + 5),
330 CVT_PS_S = ((4 << 3) + 6),
331 // COP1 Encoding of Function Field When rs=D.
Steve Block44f0eee2011-05-26 01:26:41 +0100332 ADD_D = ((0 << 3) + 0),
333 SUB_D = ((0 << 3) + 1),
334 MUL_D = ((0 << 3) + 2),
335 DIV_D = ((0 << 3) + 3),
336 SQRT_D = ((0 << 3) + 4),
337 ABS_D = ((0 << 3) + 5),
338 MOV_D = ((0 << 3) + 6),
339 NEG_D = ((0 << 3) + 7),
340 ROUND_L_D = ((1 << 3) + 0),
341 TRUNC_L_D = ((1 << 3) + 1),
342 CEIL_L_D = ((1 << 3) + 2),
343 FLOOR_L_D = ((1 << 3) + 3),
344 ROUND_W_D = ((1 << 3) + 4),
345 TRUNC_W_D = ((1 << 3) + 5),
346 CEIL_W_D = ((1 << 3) + 6),
347 FLOOR_W_D = ((1 << 3) + 7),
Andrei Popescu31002712010-02-23 13:46:05 +0000348 CVT_S_D = ((4 << 3) + 0),
349 CVT_W_D = ((4 << 3) + 4),
350 CVT_L_D = ((4 << 3) + 5),
Steve Block44f0eee2011-05-26 01:26:41 +0100351 C_F_D = ((6 << 3) + 0),
352 C_UN_D = ((6 << 3) + 1),
353 C_EQ_D = ((6 << 3) + 2),
354 C_UEQ_D = ((6 << 3) + 3),
355 C_OLT_D = ((6 << 3) + 4),
356 C_ULT_D = ((6 << 3) + 5),
357 C_OLE_D = ((6 << 3) + 6),
358 C_ULE_D = ((6 << 3) + 7),
Andrei Popescu31002712010-02-23 13:46:05 +0000359 // COP1 Encoding of Function Field When rs=W or L.
360 CVT_S_W = ((4 << 3) + 0),
361 CVT_D_W = ((4 << 3) + 1),
362 CVT_S_L = ((4 << 3) + 0),
363 CVT_D_L = ((4 << 3) + 1),
364 // COP1 Encoding of Function Field When rs=PS.
365
366 NULLSF = 0
367};
368
369
370// ----- Emulated conditions.
371// On MIPS we use this enum to abstract from conditionnal branch instructions.
372// the 'U' prefix is used to specify unsigned comparisons.
373enum Condition {
374 // Any value < 0 is considered no_condition.
Steve Block44f0eee2011-05-26 01:26:41 +0100375 kNoCondition = -1,
Andrei Popescu31002712010-02-23 13:46:05 +0000376
377 overflow = 0,
378 no_overflow = 1,
379 Uless = 2,
380 Ugreater_equal= 3,
381 equal = 4,
382 not_equal = 5,
383 Uless_equal = 6,
384 Ugreater = 7,
385 negative = 8,
386 positive = 9,
387 parity_even = 10,
388 parity_odd = 11,
389 less = 12,
390 greater_equal = 13,
391 less_equal = 14,
392 greater = 15,
393
394 cc_always = 16,
395
396 // aliases
397 carry = Uless,
398 not_carry = Ugreater_equal,
399 zero = equal,
400 eq = equal,
401 not_zero = not_equal,
402 ne = not_equal,
Steve Block44f0eee2011-05-26 01:26:41 +0100403 nz = not_equal,
Andrei Popescu31002712010-02-23 13:46:05 +0000404 sign = negative,
405 not_sign = positive,
Steve Block44f0eee2011-05-26 01:26:41 +0100406 mi = negative,
407 pl = positive,
408 hi = Ugreater,
409 ls = Uless_equal,
410 ge = greater_equal,
411 lt = less,
412 gt = greater,
413 le = less_equal,
414 hs = Ugreater_equal,
415 lo = Uless,
416 al = cc_always,
Andrei Popescu31002712010-02-23 13:46:05 +0000417
Steve Block44f0eee2011-05-26 01:26:41 +0100418 cc_default = kNoCondition
Andrei Popescu31002712010-02-23 13:46:05 +0000419};
420
Steve Block44f0eee2011-05-26 01:26:41 +0100421
422// Returns the equivalent of !cc.
423// Negation of the default kNoCondition (-1) results in a non-default
424// no_condition value (-2). As long as tests for no_condition check
425// for condition < 0, this will work as expected.
426inline Condition NegateCondition(Condition cc) {
427 ASSERT(cc != cc_always);
428 return static_cast<Condition>(cc ^ 1);
429}
430
431
432inline Condition ReverseCondition(Condition cc) {
433 switch (cc) {
434 case Uless:
435 return Ugreater;
436 case Ugreater:
437 return Uless;
438 case Ugreater_equal:
439 return Uless_equal;
440 case Uless_equal:
441 return Ugreater_equal;
442 case less:
443 return greater;
444 case greater:
445 return less;
446 case greater_equal:
447 return less_equal;
448 case less_equal:
449 return greater_equal;
450 default:
451 return cc;
452 };
453}
454
455
Andrei Popescu31002712010-02-23 13:46:05 +0000456// ----- Coprocessor conditions.
457enum FPUCondition {
458 F, // False
459 UN, // Unordered
460 EQ, // Equal
461 UEQ, // Unordered or Equal
462 OLT, // Ordered or Less Than
463 ULT, // Unordered or Less Than
464 OLE, // Ordered or Less Than or Equal
465 ULE // Unordered or Less Than or Equal
466};
467
468
Steve Block44f0eee2011-05-26 01:26:41 +0100469// -----------------------------------------------------------------------------
470// Hints.
471
472// Branch hints are not used on the MIPS. They are defined so that they can
473// appear in shared function signatures, but will be ignored in MIPS
474// implementations.
475enum Hint {
476 no_hint = 0
477};
478
479
480inline Hint NegateHint(Hint hint) {
481 return no_hint;
482}
483
484
485// -----------------------------------------------------------------------------
486// Specific instructions, constants, and masks.
487// These constants are declared in assembler-mips.cc, as they use named
488// registers and other constants.
489
490// addiu(sp, sp, 4) aka Pop() operation or part of Pop(r)
491// operations as post-increment of sp.
492extern const Instr kPopInstruction;
493// addiu(sp, sp, -4) part of Push(r) operation as pre-decrement of sp.
494extern const Instr kPushInstruction;
495// sw(r, MemOperand(sp, 0))
496extern const Instr kPushRegPattern;
497// lw(r, MemOperand(sp, 0))
498extern const Instr kPopRegPattern;
499extern const Instr kLwRegFpOffsetPattern;
500extern const Instr kSwRegFpOffsetPattern;
501extern const Instr kLwRegFpNegOffsetPattern;
502extern const Instr kSwRegFpNegOffsetPattern;
503// A mask for the Rt register for push, pop, lw, sw instructions.
504extern const Instr kRtMask;
505extern const Instr kLwSwInstrTypeMask;
506extern const Instr kLwSwInstrArgumentMask;
507extern const Instr kLwSwOffsetMask;
508
Andrei Popescu31002712010-02-23 13:46:05 +0000509// Break 0xfffff, reserved for redirected real time call.
510const Instr rtCallRedirInstr = SPECIAL | BREAK | call_rt_redirected << 6;
511// A nop instruction. (Encoding of sll 0 0 0).
512const Instr nopInstr = 0;
513
514class Instruction {
515 public:
516 enum {
Steve Block44f0eee2011-05-26 01:26:41 +0100517 kInstrSize = 4,
518 kInstrSizeLog2 = 2,
Andrei Popescu31002712010-02-23 13:46:05 +0000519 // On MIPS PC cannot actually be directly accessed. We behave as if PC was
Steve Block44f0eee2011-05-26 01:26:41 +0100520 // always the value of the current instruction being executed.
Andrei Popescu31002712010-02-23 13:46:05 +0000521 kPCReadOffset = 0
522 };
523
524 // Get the raw instruction bits.
525 inline Instr InstructionBits() const {
526 return *reinterpret_cast<const Instr*>(this);
527 }
528
529 // Set the raw instruction bits to value.
530 inline void SetInstructionBits(Instr value) {
531 *reinterpret_cast<Instr*>(this) = value;
532 }
533
534 // Read one particular bit out of the instruction bits.
535 inline int Bit(int nr) const {
536 return (InstructionBits() >> nr) & 1;
537 }
538
539 // Read a bit field out of the instruction bits.
540 inline int Bits(int hi, int lo) const {
541 return (InstructionBits() >> lo) & ((2 << (hi - lo)) - 1);
542 }
543
544 // Instruction type.
545 enum Type {
546 kRegisterType,
547 kImmediateType,
548 kJumpType,
549 kUnsupported = -1
550 };
551
552 // Get the encoding type of the instruction.
553 Type InstructionType() const;
554
555
556 // Accessors for the different named fields used in the MIPS encoding.
Steve Block44f0eee2011-05-26 01:26:41 +0100557 inline Opcode OpcodeValue() const {
Andrei Popescu31002712010-02-23 13:46:05 +0000558 return static_cast<Opcode>(
559 Bits(kOpcodeShift + kOpcodeBits - 1, kOpcodeShift));
560 }
561
Steve Block44f0eee2011-05-26 01:26:41 +0100562 inline int RsValue() const {
Andrei Popescu31002712010-02-23 13:46:05 +0000563 ASSERT(InstructionType() == kRegisterType ||
564 InstructionType() == kImmediateType);
565 return Bits(kRsShift + kRsBits - 1, kRsShift);
566 }
567
Steve Block44f0eee2011-05-26 01:26:41 +0100568 inline int RtValue() const {
Andrei Popescu31002712010-02-23 13:46:05 +0000569 ASSERT(InstructionType() == kRegisterType ||
570 InstructionType() == kImmediateType);
571 return Bits(kRtShift + kRtBits - 1, kRtShift);
572 }
573
Steve Block44f0eee2011-05-26 01:26:41 +0100574 inline int RdValue() const {
Andrei Popescu31002712010-02-23 13:46:05 +0000575 ASSERT(InstructionType() == kRegisterType);
576 return Bits(kRdShift + kRdBits - 1, kRdShift);
577 }
578
Steve Block44f0eee2011-05-26 01:26:41 +0100579 inline int SaValue() const {
Andrei Popescu31002712010-02-23 13:46:05 +0000580 ASSERT(InstructionType() == kRegisterType);
581 return Bits(kSaShift + kSaBits - 1, kSaShift);
582 }
583
Steve Block44f0eee2011-05-26 01:26:41 +0100584 inline int FunctionValue() const {
Andrei Popescu31002712010-02-23 13:46:05 +0000585 ASSERT(InstructionType() == kRegisterType ||
586 InstructionType() == kImmediateType);
587 return Bits(kFunctionShift + kFunctionBits - 1, kFunctionShift);
588 }
589
Steve Block44f0eee2011-05-26 01:26:41 +0100590 inline int FdValue() const {
591 return Bits(kFdShift + kFdBits - 1, kFdShift);
Andrei Popescu31002712010-02-23 13:46:05 +0000592 }
593
Steve Block44f0eee2011-05-26 01:26:41 +0100594 inline int FsValue() const {
595 return Bits(kFsShift + kFsBits - 1, kFsShift);
596 }
597
598 inline int FtValue() const {
599 return Bits(kFtShift + kFtBits - 1, kFtShift);
600 }
601
602 // Float Compare condition code instruction bits.
603 inline int FCccValue() const {
604 return Bits(kFCccShift + kFCccBits - 1, kFCccShift);
605 }
606
607 // Float Branch condition code instruction bits.
608 inline int FBccValue() const {
609 return Bits(kFBccShift + kFBccBits - 1, kFBccShift);
610 }
611
612 // Float Branch true/false instruction bit.
613 inline int FBtrueValue() const {
614 return Bits(kFBtrueShift + kFBtrueBits - 1, kFBtrueShift);
Andrei Popescu31002712010-02-23 13:46:05 +0000615 }
616
617 // Return the fields at their original place in the instruction encoding.
618 inline Opcode OpcodeFieldRaw() const {
619 return static_cast<Opcode>(InstructionBits() & kOpcodeMask);
620 }
621
622 inline int RsFieldRaw() const {
623 ASSERT(InstructionType() == kRegisterType ||
624 InstructionType() == kImmediateType);
625 return InstructionBits() & kRsFieldMask;
626 }
627
Steve Block44f0eee2011-05-26 01:26:41 +0100628 // Same as above function, but safe to call within InstructionType().
629 inline int RsFieldRawNoAssert() const {
630 return InstructionBits() & kRsFieldMask;
631 }
632
Andrei Popescu31002712010-02-23 13:46:05 +0000633 inline int RtFieldRaw() const {
634 ASSERT(InstructionType() == kRegisterType ||
635 InstructionType() == kImmediateType);
636 return InstructionBits() & kRtFieldMask;
637 }
638
639 inline int RdFieldRaw() const {
640 ASSERT(InstructionType() == kRegisterType);
641 return InstructionBits() & kRdFieldMask;
642 }
643
644 inline int SaFieldRaw() const {
645 ASSERT(InstructionType() == kRegisterType);
646 return InstructionBits() & kSaFieldMask;
647 }
648
649 inline int FunctionFieldRaw() const {
650 return InstructionBits() & kFunctionFieldMask;
651 }
652
653 // Get the secondary field according to the opcode.
Steve Block44f0eee2011-05-26 01:26:41 +0100654 inline int SecondaryValue() const {
Andrei Popescu31002712010-02-23 13:46:05 +0000655 Opcode op = OpcodeFieldRaw();
656 switch (op) {
657 case SPECIAL:
658 case SPECIAL2:
Steve Block44f0eee2011-05-26 01:26:41 +0100659 return FunctionValue();
Andrei Popescu31002712010-02-23 13:46:05 +0000660 case COP1:
Steve Block44f0eee2011-05-26 01:26:41 +0100661 return RsValue();
Andrei Popescu31002712010-02-23 13:46:05 +0000662 case REGIMM:
Steve Block44f0eee2011-05-26 01:26:41 +0100663 return RtValue();
Andrei Popescu31002712010-02-23 13:46:05 +0000664 default:
665 return NULLSF;
666 }
667 }
668
Steve Block44f0eee2011-05-26 01:26:41 +0100669 inline int32_t Imm16Value() const {
Andrei Popescu31002712010-02-23 13:46:05 +0000670 ASSERT(InstructionType() == kImmediateType);
671 return Bits(kImm16Shift + kImm16Bits - 1, kImm16Shift);
672 }
673
Steve Block44f0eee2011-05-26 01:26:41 +0100674 inline int32_t Imm26Value() const {
Andrei Popescu31002712010-02-23 13:46:05 +0000675 ASSERT(InstructionType() == kJumpType);
676 return Bits(kImm16Shift + kImm26Bits - 1, kImm26Shift);
677 }
678
679 // Say if the instruction should not be used in a branch delay slot.
Steve Block44f0eee2011-05-26 01:26:41 +0100680 bool IsForbiddenInBranchDelay() const;
Andrei Popescu31002712010-02-23 13:46:05 +0000681 // Say if the instruction 'links'. eg: jal, bal.
Steve Block44f0eee2011-05-26 01:26:41 +0100682 bool IsLinkingInstruction() const;
Andrei Popescu31002712010-02-23 13:46:05 +0000683 // Say if the instruction is a break or a trap.
Steve Block44f0eee2011-05-26 01:26:41 +0100684 bool IsTrap() const;
Andrei Popescu31002712010-02-23 13:46:05 +0000685
686 // Instructions are read of out a code stream. The only way to get a
687 // reference to an instruction is to convert a pointer. There is no way
688 // to allocate or create instances of class Instruction.
689 // Use the At(pc) function to create references to Instruction.
690 static Instruction* At(byte_* pc) {
691 return reinterpret_cast<Instruction*>(pc);
692 }
693
694 private:
695 // We need to prevent the creation of instances of class Instruction.
696 DISALLOW_IMPLICIT_CONSTRUCTORS(Instruction);
697};
698
699
700// -----------------------------------------------------------------------------
701// MIPS assembly various constants.
702
Steve Block44f0eee2011-05-26 01:26:41 +0100703
704static const int kArgsSlotsSize = 4 * Instruction::kInstrSize;
Andrei Popescu31002712010-02-23 13:46:05 +0000705static const int kArgsSlotsNum = 4;
Steve Block44f0eee2011-05-26 01:26:41 +0100706// C/C++ argument slots size.
707static const int kCArgsSlotsSize = 4 * Instruction::kInstrSize;
708// JS argument slots size.
709static const int kJSArgsSlotsSize = 0 * Instruction::kInstrSize;
710// Assembly builtins argument slots size.
711static const int kBArgsSlotsSize = 0 * Instruction::kInstrSize;
Andrei Popescu31002712010-02-23 13:46:05 +0000712
Steve Block44f0eee2011-05-26 01:26:41 +0100713static const int kBranchReturnOffset = 2 * Instruction::kInstrSize;
Andrei Popescu31002712010-02-23 13:46:05 +0000714
Steve Block44f0eee2011-05-26 01:26:41 +0100715static const int kDoubleAlignmentBits = 3;
716static const int kDoubleAlignment = (1 << kDoubleAlignmentBits);
717static const int kDoubleAlignmentMask = kDoubleAlignment - 1;
Andrei Popescu31002712010-02-23 13:46:05 +0000718
719
Steve Block44f0eee2011-05-26 01:26:41 +0100720} } // namespace v8::internal
Andrei Popescu31002712010-02-23 13:46:05 +0000721
722#endif // #ifndef V8_MIPS_CONSTANTS_H_
723