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

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

Issue 221133002: Begins work on ARM64, first assembler test. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: adds files Created 6 years, 8 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 | Annotate | Revision Log
« no previous file with comments | « runtime/vm/compiler_test.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) 2014, 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 VM_CONSTANTS_ARM64_H_
6 #define VM_CONSTANTS_ARM64_H_
7
8 #include "platform/assert.h"
9
10 namespace dart {
11
12 enum Register {
13 kFirstFreeCpuRegister = 0,
14 R0 = 0,
15 R1 = 1,
16 R2 = 2,
17 R3 = 3,
18 R4 = 4,
19 R5 = 5,
20 R6 = 6,
21 R7 = 7,
22 R8 = 8,
23 R9 = 9,
24 R10 = 10,
25 R11 = 11,
26 R12 = 12,
27 R13 = 13,
28 R14 = 14,
29 R15 = 15,
30 R16 = 16,
31 R17 = 17,
32 R18 = 18,
33 R19 = 19,
34 R20 = 20,
35 R21 = 21,
36 R22 = 22,
37 R23 = 23,
38 R24 = 24,
39 kLastFreeCpuRegister = 24,
40 R25 = 25, // IP0
41 R26 = 26, // IP1
42 R27 = 27, // PP
43 R28 = 28, // CTX
44 R29 = 29, // FP
45 R30 = 30, // LR
46 R31 = 31, // ZR, SP
47 kNumberOfCpuRegisters = 32,
48 kNoRegister = -1,
49
50 // Aliases.
51 IP0 = R25,
52 IP1 = R26,
53 FP = R29,
54 LR = R30,
55
56 // Left abstract so we can avoid misuse.
57 SP,
58 ZR,
59 };
60
61 enum VRegister {
62 V0 = 0,
63 V1 = 1,
64 V2 = 2,
65 V3 = 3,
66 V4 = 4,
67 V5 = 5,
68 V6 = 6,
69 V7 = 7,
70 V8 = 8,
71 V9 = 9,
72 V10 = 10,
73 V11 = 11,
74 V12 = 12,
75 V13 = 13,
76 V14 = 14,
77 V15 = 15,
78 V16 = 16,
79 V17 = 17,
80 V18 = 18,
81 V19 = 19,
82 V20 = 20,
83 V21 = 21,
84 V22 = 22,
85 V23 = 24,
86 V24 = 24,
87 V25 = 25,
88 V26 = 26,
89 V27 = 27,
90 V28 = 28,
91 V29 = 29,
92 V30 = 30,
93 V31 = 31,
94 kNumberOfVRegisters = 32,
95 kNoVRegister = -1,
96 };
97
98 // Register alias for floating point scratch register.
99 const VRegister VTMP0 = V30;
100 const VRegister VTMP1 = V31;
101
102 // Architecture independent aliases.
103 typedef VRegister FpuRegister;
104 const FpuRegister FpuTMP = VTMP0;
105 const int kNumberOfFpuRegisters = kNumberOfVRegisters;
106 const FpuRegister kNoFpuRegister = kNoVRegister;
107
108 // Register aliases.
109 const Register TMP = R25; // Used as scratch register by assembler.
110 const Register TMP0 = R25;
111 const Register TMP1 = R26;
112 const Register CTX = R27; // Caches current context in generated code.
113 const Register PP = R26; // Caches object pool pointer in generated code.
114 const Register SPREG = R31; // Stack pointer register.
115 const Register FPREG = FP; // Frame pointer register.
116 const Register ICREG = R5; // IC data register.
117
118 // Exception object is passed in this register to the catch handlers when an
119 // exception is thrown.
120 const Register kExceptionObjectReg = R0;
121
122 // Stack trace object is passed in this register to the catch handlers when
123 // an exception is thrown.
124 const Register kStackTraceObjectReg = R1;
125
126 // Masks, sizes, etc.
127 const int kXRegSizeInBits = 64;
128 const int kWRegSizeInBits = 32;
129 const int64_t kXRegMask = 0xffffffffffffffffL;
130 const int64_t kWRegMask = 0x00000000ffffffffL;
131
132 // List of registers used in load/store multiple.
133 typedef uint32_t RegList;
134 const RegList kAllCpuRegistersList = 0xFFFF;
135
136
137 // C++ ABI call registers.
138 const RegList kAbiArgumentCpuRegs =
139 (1 << R0) | (1 << R1) | (1 << R2) | (1 << R3) |
140 (1 << R4) | (1 << R5) | (1 << R6) | (1 << R7);
141 const RegList kAbiPreservedCpuRegs =
142 (1 << R19) | (1 << R20) | (1 << R21) | (1 << R22) |
143 (1 << R23) | (1 << R24) | (1 << R25) | (1 << R26) |
144 (1 << R27) | (1 << R28) | (1 << R29);
145 const int kAbiPreservedCpuRegCount = 11;
146 const VRegister kAbiFirstPreservedFpuReg = V8;
147 const VRegister kAbiLastPreservedFpuReg = V15;
148 const int kAbiPreservedFpuRegCount = 8;
149
150 // CPU registers available to Dart allocator.
151 const RegList kDartAvailableCpuRegs =
152 (1 << R0) | (1 << R1) | (1 << R2) | (1 << R3) |
153 (1 << R4) | (1 << R5) | (1 << R6) | (1 << R7) |
154 (1 << R8) | (1 << R9) | (1 << R10) | (1 << R11) |
155 (1 << R12) | (1 << R13) | (1 << R14) | (1 << R15) |
156 (1 << R16) | (1 << R17) | (1 << R18) | (1 << R19) |
157 (1 << R20) | (1 << R21) | (1 << R22) | (1 << R23) |
158 (1 << R24);
159
160 // Registers available to Dart that are not preserved by runtime calls.
161 const RegList kDartVolatileCpuRegs =
162 kDartAvailableCpuRegs & ~kAbiPreservedCpuRegs;
163 const int kDartVolatileCpuRegCount = 19;
164 const VRegister kDartFirstVolatileFpuReg = V0;
165 const VRegister kDartLastVolatileFpuReg = V7;
166 const int kDartVolatileFpuRegCount = 8;
167
168 static inline Register ConcreteRegister(Register r) {
169 return ((r == ZR) || (r == SP)) ? R31 : r;
170 }
171
172 // Values for the condition field as defined in section A3.2.
173 enum Condition {
174 kNoCondition = -1,
175 EQ = 0, // equal
176 NE = 1, // not equal
177 CS = 2, // carry set/unsigned higher or same
178 CC = 3, // carry clear/unsigned lower
179 MI = 4, // minus/negative
180 PL = 5, // plus/positive or zero
181 VS = 6, // overflow
182 VC = 7, // no overflow
183 HI = 8, // unsigned higher
184 LS = 9, // unsigned lower or same
185 GE = 10, // signed greater than or equal
186 LT = 11, // signed less than
187 GT = 12, // signed greater than
188 LE = 13, // signed less than or equal
189 AL = 14, // always (unconditional)
190 NV = 15, // special condition (refer to section C1.2.3)
191 kMaxCondition = 16,
192 };
193
194 enum Bits {
195 B0 = (1 << 0), B1 = (1 << 1), B2 = (1 << 2), B3 = (1 << 3),
196 B4 = (1 << 4), B5 = (1 << 5), B6 = (1 << 6), B7 = (1 << 7),
197 B8 = (1 << 8), B9 = (1 << 9), B10 = (1 << 10), B11 = (1 << 11),
198 B12 = (1 << 12), B13 = (1 << 13), B14 = (1 << 14), B15 = (1 << 15),
199 B16 = (1 << 16), B17 = (1 << 17), B18 = (1 << 18), B19 = (1 << 19),
200 B20 = (1 << 20), B21 = (1 << 21), B22 = (1 << 22), B23 = (1 << 23),
201 B24 = (1 << 24), B25 = (1 << 25), B26 = (1 << 26), B27 = (1 << 27),
202 B28 = (1 << 28), B29 = (1 << 29), B30 = (1 << 30), B31 = (1 << 31),
203 };
204
205 enum OperandSize {
206 kByte,
207 kUnsignedByte,
208 kHalfword,
209 kUnsignedHalfword,
210 kWord,
211 kUnsignedWord,
212 kDoubleWord,
213 kSWord,
214 kDWord,
215 };
216
217 // Opcodes from C3
218 // C3.1.
219 enum MainOp {
220 DPImmediateMask = 0x1c000000,
221 DPImmediateFixed = B28,
222
223 CompareBranchMask = 0x1c000000,
224 CompareBranchFixed = B28 | B26,
225
226 LoadStoreMask = B27 | B25,
227 LoadStoreFixed = B27,
228
229 DPRegisterMask = 0x0e000000,
230 DPRegisterFixed = B27 | B25,
231
232 DPSimd1Mask = 0x1e000000,
233 DPSimd1Fixed = B27 | B26 | B25,
234
235 DPSimd2Mask = 0x1e000000,
236 DPSimd2Fixed = B28 | DPSimd1Fixed,
237 };
238
239 // C3.2.3
240 enum ExceptionGenOp {
241 ExceptionGenMask = 0xff000000,
242 ExceptionGenFixed = CompareBranchFixed | B31 | B30,
243 SVC = ExceptionGenFixed | B0,
244 BRK = ExceptionGenFixed | B21,
245 HLT = ExceptionGenFixed | B22,
246 };
247
248 // C3.2.4
249 enum SystemOp {
250 SystemMask = 0xffc00000,
251 SystemFixed = CompareBranchFixed | B31 | B30 | B24,
252 HINT = SystemFixed | B17 | B16 | B13 | B4 | B3 | B2 | B1 | B0,
253 };
254
255 // C3.2.7
256 enum UnconditionalBranchRegOp {
257 UnconditionalBranchRegMask = 0xfe000000,
258 UnconditionalBranchRegFixed = CompareBranchFixed | B31 | B30 | B25,
259 BR = UnconditionalBranchRegFixed | B20 | B19 | B18 | B17 | B16,
260 BLR = BR | B21,
261 RET = BR | B22,
262 };
263
264 // C3.4.1
265 enum AddSubImmOp {
266 AddSubImmMask = 0x1f000000,
267 AddSubImmFixed = DPImmediateFixed | B24,
268 ADDI = AddSubImmFixed,
269 SUBI = AddSubImmFixed | B30,
270 };
271
272 // C3.4.5
273 enum MoveWideOp {
274 MoveWideMask = 0x1f800000,
275 MoveWideFixed = DPImmediateFixed | B25 | B23,
276 MOVN = MoveWideFixed,
277 MOVZ = MoveWideFixed | B30,
278 MOVK = MoveWideFixed | B30 | B29,
279 };
280
281
282 // C3.5.1
283 enum AddSubShiftExtOp {
284 AddSubShiftExtMask = 0x1f200000,
285 AddSubShiftExtFixed = DPRegisterFixed | B24,
286 ADD = AddSubShiftExtFixed,
287 SUB = AddSubShiftExtFixed | B30,
288 };
289
290 #define APPLY_OP_LIST(_V) \
291 _V(DPImmediate) \
292 _V(CompareBranch) \
293 _V(LoadStore) \
294 _V(DPRegister) \
295 _V(DPSimd1) \
296 _V(DPSimd2) \
297 _V(ExceptionGen) \
298 _V(System) \
299 _V(UnconditionalBranchReg) \
300 _V(AddSubImm) \
301 _V(MoveWide) \
302 _V(AddSubShiftExt) \
303
304
305 enum Shift {
306 kNoShift = -1,
307 LSL = 0, // Logical shift left
308 LSR = 1, // Logical shift right
309 ASR = 2, // Arithmetic shift right
310 ROR = 3, // Rotate right
311 kMaxShift = 4,
312 };
313
314 enum Extend {
315 kNoExtend = -1,
316 UXTB = 0,
317 UXTH = 1,
318 UXTW = 2,
319 UXTX = 3,
320 SXTB = 4,
321 SXTH = 5,
322 SXTW = 6,
323 SXTX = 7,
324 kMaxExtend = 8,
325 };
326
327 enum R31Type {
328 R31IsSP,
329 R31IsZR,
330 R31IsUndef,
331 };
332
333 // Constants used for the decoding or encoding of the individual fields of
334 // instructions. Based on the "Figure 3-1 ARM instruction set summary".
335 enum InstructionFields {
336 // S-bit (modify condition register)
337 kSShift = 29,
338 kSBits = 1,
339
340 // sf field.
341 kSFShift = 31,
342 kSFBits = 1,
343
344 // Registers.
345 kRdShift = 0,
346 kRdBits = 5,
347 kRnShift = 5,
348 kRnBits = 5,
349 kRaShift = 10,
350 kRaBits = 5,
351 kRmShift = 16,
352 kRmBits = 5,
353
354 // Immediates.
355 kImm3Shift = 10,
356 kImm3Bits = 3,
357 kImm6Shift = 10,
358 kImm6Bits = 6,
359 kImm12Shift = 10,
360 kImm12Bits = 12,
361 kImm12ShiftShift = 22,
362 kImm12ShiftBits = 2,
363 kImm16Shift = 5,
364 kImm16Bits = 16,
365
366 // Shift and Extend.
367 kShiftExtendShift = 21,
368 kShiftExtendBits = 1,
369 kShiftTypeShift = 22,
370 kShiftTypeBits = 2,
371 kExtendTypeShift = 13,
372 kExtendTypeBits = 3,
373
374 // Hint Fields.
375 kHintCRmShift = 8,
376 kHintCRmBits = 4,
377 kHintOp2Shift = 5,
378 kHintOp2Bits = 3,
379 };
380
381
382 const uint32_t kImmExceptionIsRedirectedCall = 0xca11;
383 const uint32_t kImmExceptionIsUnreachable = 0xdebf;
384 const uint32_t kImmExceptionIsPrintf = 0xdeb1;
385 const uint32_t kImmExceptionIsDebug = 0xdeb0;
386
387 // The class Instr enables access to individual fields defined in the ARM
388 // architecture instruction set encoding as described in figure A3-1.
389 //
390 // Example: Test whether the instruction at ptr sets the condition code bits.
391 //
392 // bool InstructionSetsConditionCodes(byte* ptr) {
393 // Instr* instr = Instr::At(ptr);
394 // int type = instr->TypeField();
395 // return ((type == 0) || (type == 1)) && instr->HasS();
396 // }
397 //
398 class Instr {
399 public:
400 enum {
401 kInstrSize = 4,
402 kInstrSizeLog2 = 2,
403 kPCReadOffset = 8
404 };
405
406 static const int32_t kNopInstruction = HINT; // hint #0 === nop.
407 static const int32_t kBreakPointInstruction = // hlt #kImmExceptionIsDebug.
408 HLT | (kImmExceptionIsDebug << kImm16Shift);
409 static const int kBreakPointInstructionSize = kInstrSize;
410
411 // Get the raw instruction bits.
412 inline int32_t InstructionBits() const {
413 return *reinterpret_cast<const int32_t*>(this);
414 }
415
416 // Set the raw instruction bits to value.
417 inline void SetInstructionBits(int32_t value) {
418 *reinterpret_cast<int32_t*>(this) = value;
419 }
420
421 // Read one particular bit out of the instruction bits.
422 inline int Bit(int nr) const {
423 return (InstructionBits() >> nr) & 1;
424 }
425
426 // Read a bit field out of the instruction bits.
427 inline int Bits(int shift, int count) const {
428 return (InstructionBits() >> shift) & ((1 << count) - 1);
429 }
430
431
432 inline int SField() const { return Bit(kSShift); }
433 inline int SFField() const { return Bit(kSFShift); }
434 inline Register RdField() const { return static_cast<Register>(
435 Bits(kRdShift, kRdBits)); }
436 inline Register RnField() const { return static_cast<Register>(
437 Bits(kRnShift, kRnBits)); }
438 inline Register RaField() const { return static_cast<Register>(
439 Bits(kRaShift, kRaBits)); }
440 inline Register RmField() const { return static_cast<Register>(
441 Bits(kRmShift, kRmBits)); }
442
443 // Immediates
444 inline int Imm3Field() const { return Bits(kImm3Shift, kImm3Bits); }
445 inline int Imm6Field() const { return Bits(kImm6Shift, kImm6Bits); }
446 inline int Imm12Field() const { return Bits(kImm12Shift, kImm12Bits); }
447 inline int Imm16Field() const { return Bits(kImm16Shift, kImm16Bits); }
448
449 inline int Imm12ShiftField() const {
450 return Bits(kImm12ShiftShift, kImm12ShiftBits); }
451
452 // Shift and Extend.
453 inline bool IsShift() const { return (Bit(kShiftExtendShift) == 0); }
454 inline bool IsExtend() const { return (Bit(kShiftExtendShift) == 1); }
455 inline Shift ShiftTypeField() const {
456 return static_cast<Shift>(Bits(kShiftTypeShift, kShiftTypeBits)); }
457 inline Extend ExtendTypeField() const {
458 return static_cast<Extend>(Bits(kExtendTypeShift, kExtendTypeBits)); }
459 inline int ShiftAmountField() const { return Imm6Field(); }
460 inline int ExtShiftAmountField() const { return Imm3Field(); }
461
462 // Instruction identification.
463 #define IS_OP(op) \
464 inline bool Is##op##Op() const { \
465 return ((InstructionBits() & op##Mask) == (op##Fixed & op##Mask)); }
466 APPLY_OP_LIST(IS_OP)
467 #undef IS_OP
468
469 inline bool HasS() const { return (SField() == 1); }
470
471 // Indicate whether Rd can be the SP or ZR. This does not check that the
472 // instruction actually has an Rd field.
473 R31Type RdMode() const {
474 // The following instructions use SP as Rd:
475 // Add/sub (immediate) when not setting the flags.
476 // Add/sub (extended) when not setting the flags.
477 // Logical (immediate) when not setting the flags.
478 // Otherwise, R31 is the ZR.
479 if (IsAddSubImmOp() || (IsAddSubShiftExtOp() && IsExtend())) {
480 if (HasS()) {
481 return R31IsZR;
482 } else {
483 return R31IsSP;
484 }
485 }
486 // TODO(zra): Handle for logical immediate operations.
487 return R31IsZR;
488 }
489
490 // Indicate whether Rn can be SP or ZR. This does not check that the
491 // instruction actually has an Rn field.
492 R31Type RnMode() const {
493 // The following instructions use SP as Rn:
494 // All loads and stores.
495 // Add/sub (immediate).
496 // Add/sub (extended).
497 // Otherwise, r31 is ZR.
498 if (IsLoadStoreOp() ||
499 IsAddSubImmOp() ||
500 (IsAddSubShiftExtOp() && IsExtend())) {
501 return R31IsSP;
502 }
503 return R31IsZR;
504 }
505
506 // Instructions are read out of a code stream. The only way to get a
507 // reference to an instruction is to convert a pointer. There is no way
508 // to allocate or create instances of class Instr.
509 // Use the At(pc) function to create references to Instr.
510 static Instr* At(uword pc) { return reinterpret_cast<Instr*>(pc); }
511
512 private:
513 DISALLOW_ALLOCATION();
514 DISALLOW_IMPLICIT_CONSTRUCTORS(Instr);
515 };
516
517 } // namespace dart
518
519 #endif // VM_CONSTANTS_ARM64_H_
OLDNEW
« no previous file with comments | « runtime/vm/compiler_test.cc ('k') | runtime/vm/cpu.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698