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

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

Powered by Google App Engine
This is Rietveld 408576698