Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(97)

Side by Side Diff: runtime/vm/constants_mips.h

Issue 2858623002: Remove MIPS support (Closed)
Patch Set: Merge and cleanup Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/compiler.cc ('k') | runtime/vm/cpu.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5 #ifndef RUNTIME_VM_CONSTANTS_MIPS_H_
6 #define RUNTIME_VM_CONSTANTS_MIPS_H_
7
8 #include "platform/assert.h"
9
10 namespace dart {
11
12 enum Register {
13 R0 = 0,
14 R1 = 1, // AT aka TMP
15 R2 = 2,
16 R3 = 3,
17 R4 = 4,
18 R5 = 5,
19 R6 = 6,
20 R7 = 7,
21 R8 = 8,
22 R9 = 9,
23 R10 = 10,
24 R11 = 11,
25 R12 = 12,
26 R13 = 13,
27 R14 = 14,
28 R15 = 15,
29 R16 = 16,
30 R17 = 17,
31 R18 = 18,
32 R19 = 19, // THR
33 R20 = 20,
34 R21 = 21,
35 R22 = 22, // CTX
36 R23 = 23, // PP
37 R24 = 24,
38 R25 = 25,
39 R26 = 26,
40 R27 = 27,
41 R28 = 28,
42 R29 = 29, // SP
43 R30 = 30, // FP
44 R31 = 31, // RA
45 kNumberOfCpuRegisters = 32,
46 IMM = 32, // Positive value is easier to encode than kNoRegister in bitfield.
47 kNoRegister = -1, // Signals an illegal register.
48
49
50 // Register aliases.
51 ZR = R0,
52 AT = R1,
53
54 V0 = R2,
55 V1 = R3,
56
57 A0 = R4,
58 A1 = R5,
59 A2 = R6,
60 A3 = R7,
61
62 T0 = R8,
63 T1 = R9,
64 T2 = R10,
65 T3 = R11,
66 T4 = R12,
67 T5 = R13,
68 T6 = R14,
69 T7 = R15,
70
71 S0 = R16,
72 S1 = R17,
73 S2 = R18,
74 S3 = R19,
75 S4 = R20,
76 S5 = R21,
77 S6 = R22,
78 S7 = R23,
79
80 T8 = R24,
81 T9 = R25,
82
83 K0 = R26,
84 K1 = R27,
85
86 GP = R28,
87 SP = R29,
88 FP = R30,
89 RA = R31,
90 };
91
92
93 // Values for floating point registers.
94 // Double-precision values use register pairs.
95 enum FRegister {
96 F0 = 0,
97 F1 = 1,
98 F2 = 2,
99 F3 = 3,
100 F4 = 4,
101 F5 = 5,
102 F6 = 6,
103 F7 = 7,
104 F8 = 8,
105 F9 = 9,
106 F10 = 10,
107 F11 = 11,
108 F12 = 12,
109 F13 = 13,
110 F14 = 14,
111 F15 = 15,
112 F16 = 16,
113 F17 = 17,
114 F18 = 18,
115 F19 = 19,
116 F20 = 20,
117 F21 = 21,
118 F22 = 22,
119 F23 = 23,
120 F24 = 24,
121 F25 = 25,
122 F26 = 26,
123 F27 = 27,
124 F28 = 28,
125 F29 = 29,
126 F30 = 30,
127 F31 = 31,
128 kNumberOfFRegisters = 32,
129 kNoFRegister = -1,
130 };
131
132 // The double precision floating point registers are concatenated pairs of the
133 // single precision registers, e.g. D0 is F1:F0, D1 is F3:F2, etc.. We only
134 // tell the architecture generic code about the double precision registers, then
135 // convert to the single precision registers when needed in the mips-specific
136 // code.
137 enum DRegister {
138 D0 = 0, // Function return value 1.
139 D1 = 1, // Function return value 2.
140 D2 = 2, // Not preserved.
141 D3 = 3, // Not preserved.
142 D4 = 4, // Not preserved.
143 D5 = 5, // Not preserved.
144 D6 = 6, // Argument 1.
145 D7 = 7, // Argument 2.
146 D8 = 8, // Not preserved.
147 D9 = 9, // Not preserved.
148 D10 = 10, // Preserved.
149 D11 = 11, // Preserved.
150 D12 = 12, // Preserved.
151 D13 = 13, // Preserved.
152 D14 = 14, // Preserved.
153 D15 = 15, // Preserved.
154 kNumberOfDRegisters = 16,
155 kNoDRegister = -1,
156 };
157
158 static inline FRegister EvenFRegisterOf(DRegister d) {
159 return static_cast<FRegister>(d * 2);
160 }
161
162 static inline FRegister OddFRegisterOf(DRegister d) {
163 return static_cast<FRegister>((d * 2) + 1);
164 }
165
166 const DRegister DTMP = D9;
167 const FRegister STMP1 = F18;
168 const FRegister STMP2 = F19;
169
170 // Architecture independent aliases.
171 typedef DRegister FpuRegister;
172 const FpuRegister FpuTMP = DTMP;
173 const int kNumberOfFpuRegisters = kNumberOfDRegisters;
174 const FpuRegister kNoFpuRegister = kNoDRegister;
175
176
177 // Register aliases.
178 const Register TMP = AT; // Used as scratch register by assembler.
179 const Register TMP2 = kNoRegister; // No second assembler scratch register.
180 const Register CTX = S6; // Location of current context at method entry.
181 const Register CODE_REG = S6;
182 const Register PP = S7; // Caches object pool pointer in generated code.
183 const Register SPREG = SP; // Stack pointer register.
184 const Register FPREG = FP; // Frame pointer register.
185 const Register LRREG = RA; // Link register.
186 const Register ICREG = S5; // IC data register.
187 const Register ARGS_DESC_REG = S4;
188 const Register THR = S3; // Caches current thread in generated code.
189 const Register CALLEE_SAVED_TEMP = S5;
190
191 // The code that generates a comparison can be far away from the code that
192 // generates the branch that uses the result of that comparison. In this case,
193 // CMPRES1 and CMPRES2 are used for the results of the comparison. We need two
194 // since TMP is clobbered by a far branch.
195 const Register CMPRES1 = T8;
196 const Register CMPRES2 = T9;
197
198 // Exception object is passed in this register to the catch handlers when an
199 // exception is thrown.
200 const Register kExceptionObjectReg = V0;
201
202 // Stack trace object is passed in this register to the catch handlers when
203 // an exception is thrown.
204 const Register kStackTraceObjectReg = V1;
205
206
207 typedef uint32_t RegList;
208 const RegList kAllCpuRegistersList = 0xFFFFFFFF;
209
210 const RegList kAbiArgumentCpuRegs =
211 (1 << A0) | (1 << A1) | (1 << A2) | (1 << A3);
212 const RegList kAbiPreservedCpuRegs = (1 << S0) | (1 << S1) | (1 << S2) |
213 (1 << S3) | (1 << S4) | (1 << S5) |
214 (1 << S6) | (1 << S7);
215 const int kAbiPreservedCpuRegCount = 8;
216
217 // FPU registers 20 - 31 are preserved across calls.
218 const FRegister kAbiFirstPreservedFpuReg = F20;
219 const FRegister kAbiLastPreservedFpuReg =
220 static_cast<FRegister>(kNumberOfFRegisters - 1);
221 const int kAbiPreservedFpuRegCount = 12;
222
223 const RegList kReservedCpuRegisters =
224 (1 << SPREG) | (1 << FPREG) | (1 << TMP) | (1 << PP) | (1 << THR) |
225 (1 << CTX) | (1 << ZR) | (1 << CMPRES1) | (1 << CMPRES2) | (1 << K0) |
226 (1 << K1) | (1 << GP) | (1 << RA);
227 // CPU registers available to Dart allocator.
228 const RegList kDartAvailableCpuRegs =
229 kAllCpuRegistersList & ~kReservedCpuRegisters;
230 // Registers available to Dart that are not preserved by runtime calls.
231 const RegList kDartVolatileCpuRegs =
232 kDartAvailableCpuRegs & ~kAbiPreservedCpuRegs;
233 const int kDartVolatileCpuRegCount = 14;
234 const Register kDartFirstVolatileCpuReg = R2;
235 const Register kDartLastVolatileCpuReg = R15;
236
237 // FPU registers 0 - 19 are not preserved across calls.
238 const FRegister kDartFirstVolatileFpuReg = F0;
239 const FRegister kDartLastVolatileFpuReg = F19;
240 const int kDartVolatileFpuRegCount = 20;
241
242
243 // There is no status register on MIPS. Instead of representing a condition
244 // code, type Condition (see assembler_mips.h) represents a pair of operands and
245 // a relation operator between them.
246 enum RelationOperator {
247 AL, // always
248 NV, // never
249 EQ, // equal
250 NE, // not equal
251 GT, // greater than
252 GE, // greater equal
253 LT, // less than
254 LE, // less equal
255 UGT, // unsigned greater than
256 UGE, // unsigned greater equal
257 ULT, // unsigned less than
258 ULE, // unsigned less equal
259 INVALID_RELATION
260 };
261
262
263 // Constants used for the decoding or encoding of the individual fields of
264 // instructions. Based on the "Table 4.25 CPU Instruction Format Fields".
265 enum InstructionFields {
266 kOpcodeShift = 26,
267 kOpcodeBits = 6,
268 kRsShift = 21,
269 kRsBits = 5,
270 kFmtShift = 21,
271 kFmtBits = 5,
272 kRtShift = 16,
273 kRtBits = 5,
274 kFtShift = 16,
275 kFtBits = 5,
276 kRdShift = 11,
277 kRdBits = 5,
278 kFsShift = 11,
279 kFsBits = 5,
280 kSaShift = 6,
281 kSaBits = 5,
282 kFdShift = 6,
283 kFdBits = 5,
284 kFunctionShift = 0,
285 kFunctionBits = 6,
286 kCop1FnShift = 0,
287 kCop1FnBits = 6,
288 kCop1SubShift = 21,
289 kCop1SubBits = 5,
290 kImmShift = 0,
291 kImmBits = 16,
292 kInstrShift = 0,
293 kInstrBits = 26,
294 kBreakCodeShift = 6,
295 kBreakCodeBits = 20,
296 kFpuCCShift = 8,
297 kFpuCCBits = 3,
298
299 kBranchOffsetMask = 0x0000ffff,
300 };
301
302
303 enum Opcode {
304 SPECIAL = 0,
305 REGIMM = 1,
306 J = 2,
307 JAL = 3,
308 BEQ = 4,
309 BNE = 5,
310 BLEZ = 6,
311 BGTZ = 7,
312 ADDI = 8,
313 ADDIU = 9,
314 SLTI = 10,
315 SLTIU = 11,
316 ANDI = 12,
317 ORI = 13,
318 XORI = 14,
319 LUI = 15,
320 CPO0 = 16,
321 COP1 = 17,
322 COP2 = 18,
323 COP1X = 19,
324 BEQL = 20,
325 BNEL = 21,
326 BLEZL = 22,
327 BGTZL = 23,
328 SPECIAL2 = 28,
329 JALX = 29,
330 SPECIAL3 = 31,
331 LB = 32,
332 LH = 33,
333 LWL = 34,
334 LW = 35,
335 LBU = 36,
336 LHU = 37,
337 LWR = 38,
338 SB = 40,
339 SH = 41,
340 SWL = 42,
341 SW = 43,
342 SWR = 46,
343 CACHE = 47,
344 LL = 48,
345 LWC1 = 49,
346 LWC2 = 50,
347 PREF = 51,
348 LDC1 = 53,
349 LDC2 = 54,
350 SC = 56,
351 SWC1 = 57,
352 SWC2 = 58,
353 SDC1 = 61,
354 SDC2 = 62,
355 };
356
357
358 enum SpecialFunction {
359 // SPECIAL opcodes.
360 SLL = 0,
361 MOVCI = 1,
362 SRL = 2,
363 SRA = 3,
364 SLLV = 4,
365 SRLV = 6,
366 SRAV = 7,
367 JR = 8,
368 JALR = 9,
369 MOVZ = 10,
370 MOVN = 11,
371 SYSCALL = 12,
372 BREAK = 13,
373 SYNC = 15,
374 MFHI = 16,
375 MTHI = 17,
376 MFLO = 18,
377 MTLO = 19,
378 MULT = 24,
379 MULTU = 25,
380 DIV = 26,
381 DIVU = 27,
382 ADD = 32,
383 ADDU = 33,
384 SUB = 34,
385 SUBU = 35,
386 AND = 36,
387 OR = 37,
388 XOR = 38,
389 NOR = 39,
390 SLT = 42,
391 SLTU = 43,
392 TGE = 48,
393 TGEU = 49,
394 TLT = 50,
395 TLTU = 51,
396 TEQ = 52,
397 TNE = 54,
398
399 // SPECIAL2 opcodes.
400 MADD = 0,
401 MADDU = 1,
402 CLZ = 32,
403 CLO = 33,
404 };
405
406
407 enum RtRegImm {
408 BLTZ = 0,
409 BGEZ = 1,
410 BLTZL = 2,
411 BGEZL = 3,
412 TGEI = 8,
413 TGEIU = 9,
414 TLTI = 10,
415 TLTIU = 11,
416 TEQI = 12,
417 TNEI = 14,
418 BLTZAL = 16,
419 BGEZAL = 17,
420 BLTZALL = 18,
421 BGEZALL = 19,
422 SYNCI = 31,
423 };
424
425
426 enum Cop1Function {
427 COP1_ADD = 0x00,
428 COP1_SUB = 0x01,
429 COP1_MUL = 0x02,
430 COP1_DIV = 0x03,
431 COP1_SQRT = 0x04,
432 COP1_MOV = 0x06,
433 COP1_NEG = 0x07,
434 COP1_TRUNC_W = 0x0d,
435 COP1_CVT_S = 0x20,
436 COP1_CVT_D = 0x21,
437 COP1_C_F = 0x30,
438 COP1_C_UN = 0x31,
439 COP1_C_EQ = 0x32,
440 COP1_C_UEQ = 0x33,
441 COP1_C_OLT = 0x34,
442 COP1_C_ULT = 0x35,
443 COP1_C_OLE = 0x36,
444 COP1_C_ULE = 0x37,
445 };
446
447
448 enum Cop1Sub {
449 COP1_MF = 0,
450 COP1_MT = 4,
451 COP1_BC = 8,
452 };
453
454
455 enum Format {
456 FMT_S = 16,
457 FMT_D = 17,
458 FMT_W = 20,
459 FMT_L = 21,
460 FMT_PS = 22,
461 };
462
463
464 class Instr {
465 public:
466 enum {
467 kInstrSize = 4,
468 };
469
470 static const int32_t kNopInstruction = 0;
471
472 // Reserved break instruction codes.
473 static const int32_t kBreakPointCode = 0xdeb0; // For breakpoint.
474 static const int32_t kStopMessageCode = 0xdeb1; // For Stop(message).
475 static const int32_t kSimulatorBreakCode = 0xdeb2; // For breakpoint in sim.
476 static const int32_t kSimulatorRedirectCode = 0xca11; // For redirection.
477
478 static const int32_t kBreakPointZeroInstruction =
479 (SPECIAL << kOpcodeShift) | (BREAK << kFunctionShift);
480
481 // Breakpoint instruction filling assembler code buffers in debug mode.
482 static const int32_t kBreakPointInstruction =
483 kBreakPointZeroInstruction | (kBreakPointCode << kBreakCodeShift);
484
485 // Breakpoint instruction used by the simulator.
486 // Should be distinct from kBreakPointInstruction and from a typical user
487 // breakpoint inserted in generated code for debugging, e.g. break_(0).
488 static const int32_t kSimulatorBreakpointInstruction =
489 kBreakPointZeroInstruction | (kSimulatorBreakCode << kBreakCodeShift);
490
491 // Runtime call redirection instruction used by the simulator.
492 static const int32_t kSimulatorRedirectInstruction =
493 kBreakPointZeroInstruction | (kSimulatorRedirectCode << kBreakCodeShift);
494
495 // Get the raw instruction bits.
496 inline int32_t InstructionBits() const {
497 return *reinterpret_cast<const int32_t*>(this);
498 }
499
500 // Set the raw instruction bits to value.
501 inline void SetInstructionBits(int32_t value) {
502 *reinterpret_cast<int32_t*>(this) = value;
503 }
504
505 inline void SetImmInstrBits(Opcode op,
506 Register rs,
507 Register rt,
508 uint16_t imm) {
509 SetInstructionBits(op << kOpcodeShift | rs << kRsShift | rt << kRtShift |
510 imm << kImmShift);
511 }
512
513 inline void SetSpecialInstrBits(SpecialFunction f,
514 Register rs,
515 Register rt,
516 Register rd) {
517 SetInstructionBits(SPECIAL << kOpcodeShift | f << kFunctionShift |
518 rs << kRsShift | rt << kRtShift | rd << kRdShift);
519 }
520
521 // Read one particular bit out of the instruction bits.
522 inline int32_t Bit(int nr) const { return (InstructionBits() >> nr) & 1; }
523
524 // Read a bit field out of the instruction bits.
525 inline int32_t Bits(int shift, int count) const {
526 return (InstructionBits() >> shift) & ((1 << count) - 1);
527 }
528
529 // Accessors to the different named fields used in the MIPS encoding.
530 inline Opcode OpcodeField() const {
531 return static_cast<Opcode>(Bits(kOpcodeShift, kOpcodeBits));
532 }
533
534 inline void SetOpcodeField(Opcode b) {
535 int32_t instr = InstructionBits();
536 int32_t mask = ((1 << kOpcodeBits) - 1) << kOpcodeShift;
537 SetInstructionBits((b << kOpcodeShift) | (instr & ~mask));
538 }
539
540 inline Register RsField() const {
541 return static_cast<Register>(Bits(kRsShift, kRsBits));
542 }
543
544 inline Register RtField() const {
545 return static_cast<Register>(Bits(kRtShift, kRtBits));
546 }
547
548 inline Register RdField() const {
549 return static_cast<Register>(Bits(kRdShift, kRdBits));
550 }
551
552 inline FRegister FsField() const {
553 return static_cast<FRegister>(Bits(kFsShift, kFsBits));
554 }
555
556 inline FRegister FtField() const {
557 return static_cast<FRegister>(Bits(kFtShift, kFtBits));
558 }
559
560 inline FRegister FdField() const {
561 return static_cast<FRegister>(Bits(kFdShift, kFdBits));
562 }
563
564 inline int SaField() const { return Bits(kSaShift, kSaBits); }
565
566 inline int32_t UImmField() const { return Bits(kImmShift, kImmBits); }
567
568 inline int32_t SImmField() const {
569 // Sign-extend the imm field.
570 return (Bits(kImmShift, kImmBits) << (32 - kImmBits)) >> (32 - kImmBits);
571 }
572
573 inline int32_t BreakCodeField() const {
574 return Bits(kBreakCodeShift, kBreakCodeBits);
575 }
576
577 inline SpecialFunction FunctionField() const {
578 return static_cast<SpecialFunction>(Bits(kFunctionShift, kFunctionBits));
579 }
580
581 inline RtRegImm RegImmFnField() const {
582 return static_cast<RtRegImm>(Bits(kRtShift, kRtBits));
583 }
584
585 inline void SetRegImmFnField(RtRegImm b) {
586 int32_t instr = InstructionBits();
587 int32_t mask = ((1 << kRtBits) - 1) << kRtShift;
588 SetInstructionBits((b << kRtShift) | (instr & ~mask));
589 }
590
591 inline bool IsBreakPoint() {
592 return (OpcodeField() == SPECIAL) && (FunctionField() == BREAK);
593 }
594
595 inline Cop1Function Cop1FunctionField() const {
596 return static_cast<Cop1Function>(Bits(kCop1FnShift, kCop1FnBits));
597 }
598
599 inline Cop1Sub Cop1SubField() const {
600 return static_cast<Cop1Sub>(Bits(kCop1SubShift, kCop1SubBits));
601 }
602
603 inline bool HasFormat() const {
604 return (OpcodeField() == COP1) && (Bit(25) == 1);
605 }
606
607 inline Format FormatField() const {
608 return static_cast<Format>(Bits(kFmtShift, kFmtBits));
609 }
610
611 inline int32_t FpuCCField() const { return Bits(kFpuCCShift, kFpuCCBits); }
612
613 // Instructions are read out of a code stream. The only way to get a
614 // reference to an instruction is to convert a pc. There is no way
615 // to allocate or create instances of class Instr.
616 // Use the At(pc) function to create references to Instr.
617 static Instr* At(uword pc) { return reinterpret_cast<Instr*>(pc); }
618
619 #if defined(DEBUG)
620 inline void AssertIsImmInstr(Opcode op,
621 Register rs,
622 Register rt,
623 int32_t imm) {
624 ASSERT((OpcodeField() == op) && (RsField() == rs) && (RtField() == rt) &&
625 (SImmField() == imm));
626 }
627
628 inline void AssertIsSpecialInstr(SpecialFunction f,
629 Register rs,
630 Register rt,
631 Register rd) {
632 ASSERT((OpcodeField() == SPECIAL) && (FunctionField() == f) &&
633 (RsField() == rs) && (RtField() == rt) && (RdField() == rd));
634 }
635 #endif // defined(DEBUG)
636
637 private:
638 DISALLOW_ALLOCATION();
639 DISALLOW_IMPLICIT_CONSTRUCTORS(Instr);
640 };
641
642 } // namespace dart
643
644 #endif // RUNTIME_VM_CONSTANTS_MIPS_H_
OLDNEW
« no previous file with comments | « runtime/vm/compiler.cc ('k') | runtime/vm/cpu.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698