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

Unified 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, 9 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/compiler_test.cc ('k') | runtime/vm/cpu.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/constants_arm64.h
===================================================================
--- runtime/vm/constants_arm64.h (revision 0)
+++ runtime/vm/constants_arm64.h (revision 0)
@@ -0,0 +1,519 @@
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#ifndef VM_CONSTANTS_ARM64_H_
+#define VM_CONSTANTS_ARM64_H_
+
+#include "platform/assert.h"
+
+namespace dart {
+
+enum Register {
+ kFirstFreeCpuRegister = 0,
+ R0 = 0,
+ R1 = 1,
+ R2 = 2,
+ R3 = 3,
+ R4 = 4,
+ R5 = 5,
+ R6 = 6,
+ R7 = 7,
+ R8 = 8,
+ R9 = 9,
+ R10 = 10,
+ R11 = 11,
+ R12 = 12,
+ R13 = 13,
+ R14 = 14,
+ R15 = 15,
+ R16 = 16,
+ R17 = 17,
+ R18 = 18,
+ R19 = 19,
+ R20 = 20,
+ R21 = 21,
+ R22 = 22,
+ R23 = 23,
+ R24 = 24,
+ kLastFreeCpuRegister = 24,
+ R25 = 25, // IP0
+ R26 = 26, // IP1
+ R27 = 27, // PP
+ R28 = 28, // CTX
+ R29 = 29, // FP
+ R30 = 30, // LR
+ R31 = 31, // ZR, SP
+ kNumberOfCpuRegisters = 32,
+ kNoRegister = -1,
+
+ // Aliases.
+ IP0 = R25,
+ IP1 = R26,
+ FP = R29,
+ LR = R30,
+
+ // Left abstract so we can avoid misuse.
+ SP,
+ ZR,
+};
+
+enum VRegister {
+ V0 = 0,
+ V1 = 1,
+ V2 = 2,
+ V3 = 3,
+ V4 = 4,
+ V5 = 5,
+ V6 = 6,
+ V7 = 7,
+ V8 = 8,
+ V9 = 9,
+ V10 = 10,
+ V11 = 11,
+ V12 = 12,
+ V13 = 13,
+ V14 = 14,
+ V15 = 15,
+ V16 = 16,
+ V17 = 17,
+ V18 = 18,
+ V19 = 19,
+ V20 = 20,
+ V21 = 21,
+ V22 = 22,
+ V23 = 24,
+ V24 = 24,
+ V25 = 25,
+ V26 = 26,
+ V27 = 27,
+ V28 = 28,
+ V29 = 29,
+ V30 = 30,
+ V31 = 31,
+ kNumberOfVRegisters = 32,
+ kNoVRegister = -1,
+};
+
+// Register alias for floating point scratch register.
+const VRegister VTMP0 = V30;
+const VRegister VTMP1 = V31;
+
+// Architecture independent aliases.
+typedef VRegister FpuRegister;
+const FpuRegister FpuTMP = VTMP0;
+const int kNumberOfFpuRegisters = kNumberOfVRegisters;
+const FpuRegister kNoFpuRegister = kNoVRegister;
+
+// Register aliases.
+const Register TMP = R25; // Used as scratch register by assembler.
+const Register TMP0 = R25;
+const Register TMP1 = R26;
+const Register CTX = R27; // Caches current context in generated code.
+const Register PP = R26; // Caches object pool pointer in generated code.
+const Register SPREG = R31; // Stack pointer register.
+const Register FPREG = FP; // Frame pointer register.
+const Register ICREG = R5; // IC data register.
+
+// Exception object is passed in this register to the catch handlers when an
+// exception is thrown.
+const Register kExceptionObjectReg = R0;
+
+// Stack trace object is passed in this register to the catch handlers when
+// an exception is thrown.
+const Register kStackTraceObjectReg = R1;
+
+// Masks, sizes, etc.
+const int kXRegSizeInBits = 64;
+const int kWRegSizeInBits = 32;
+const int64_t kXRegMask = 0xffffffffffffffffL;
+const int64_t kWRegMask = 0x00000000ffffffffL;
+
+// List of registers used in load/store multiple.
+typedef uint32_t RegList;
+const RegList kAllCpuRegistersList = 0xFFFF;
+
+
+// C++ ABI call registers.
+const RegList kAbiArgumentCpuRegs =
+ (1 << R0) | (1 << R1) | (1 << R2) | (1 << R3) |
+ (1 << R4) | (1 << R5) | (1 << R6) | (1 << R7);
+const RegList kAbiPreservedCpuRegs =
+ (1 << R19) | (1 << R20) | (1 << R21) | (1 << R22) |
+ (1 << R23) | (1 << R24) | (1 << R25) | (1 << R26) |
+ (1 << R27) | (1 << R28) | (1 << R29);
+const int kAbiPreservedCpuRegCount = 11;
+const VRegister kAbiFirstPreservedFpuReg = V8;
+const VRegister kAbiLastPreservedFpuReg = V15;
+const int kAbiPreservedFpuRegCount = 8;
+
+// CPU registers available to Dart allocator.
+const RegList kDartAvailableCpuRegs =
+ (1 << R0) | (1 << R1) | (1 << R2) | (1 << R3) |
+ (1 << R4) | (1 << R5) | (1 << R6) | (1 << R7) |
+ (1 << R8) | (1 << R9) | (1 << R10) | (1 << R11) |
+ (1 << R12) | (1 << R13) | (1 << R14) | (1 << R15) |
+ (1 << R16) | (1 << R17) | (1 << R18) | (1 << R19) |
+ (1 << R20) | (1 << R21) | (1 << R22) | (1 << R23) |
+ (1 << R24);
+
+// Registers available to Dart that are not preserved by runtime calls.
+const RegList kDartVolatileCpuRegs =
+ kDartAvailableCpuRegs & ~kAbiPreservedCpuRegs;
+const int kDartVolatileCpuRegCount = 19;
+const VRegister kDartFirstVolatileFpuReg = V0;
+const VRegister kDartLastVolatileFpuReg = V7;
+const int kDartVolatileFpuRegCount = 8;
+
+static inline Register ConcreteRegister(Register r) {
+ return ((r == ZR) || (r == SP)) ? R31 : r;
+}
+
+// Values for the condition field as defined in section A3.2.
+enum Condition {
+ kNoCondition = -1,
+ EQ = 0, // equal
+ NE = 1, // not equal
+ CS = 2, // carry set/unsigned higher or same
+ CC = 3, // carry clear/unsigned lower
+ MI = 4, // minus/negative
+ PL = 5, // plus/positive or zero
+ VS = 6, // overflow
+ VC = 7, // no overflow
+ HI = 8, // unsigned higher
+ LS = 9, // unsigned lower or same
+ GE = 10, // signed greater than or equal
+ LT = 11, // signed less than
+ GT = 12, // signed greater than
+ LE = 13, // signed less than or equal
+ AL = 14, // always (unconditional)
+ NV = 15, // special condition (refer to section C1.2.3)
+ kMaxCondition = 16,
+};
+
+enum Bits {
+ B0 = (1 << 0), B1 = (1 << 1), B2 = (1 << 2), B3 = (1 << 3),
+ B4 = (1 << 4), B5 = (1 << 5), B6 = (1 << 6), B7 = (1 << 7),
+ B8 = (1 << 8), B9 = (1 << 9), B10 = (1 << 10), B11 = (1 << 11),
+ B12 = (1 << 12), B13 = (1 << 13), B14 = (1 << 14), B15 = (1 << 15),
+ B16 = (1 << 16), B17 = (1 << 17), B18 = (1 << 18), B19 = (1 << 19),
+ B20 = (1 << 20), B21 = (1 << 21), B22 = (1 << 22), B23 = (1 << 23),
+ B24 = (1 << 24), B25 = (1 << 25), B26 = (1 << 26), B27 = (1 << 27),
+ B28 = (1 << 28), B29 = (1 << 29), B30 = (1 << 30), B31 = (1 << 31),
+};
+
+enum OperandSize {
+ kByte,
+ kUnsignedByte,
+ kHalfword,
+ kUnsignedHalfword,
+ kWord,
+ kUnsignedWord,
+ kDoubleWord,
+ kSWord,
+ kDWord,
+};
+
+// Opcodes from C3
+// C3.1.
+enum MainOp {
+ DPImmediateMask = 0x1c000000,
+ DPImmediateFixed = B28,
+
+ CompareBranchMask = 0x1c000000,
+ CompareBranchFixed = B28 | B26,
+
+ LoadStoreMask = B27 | B25,
+ LoadStoreFixed = B27,
+
+ DPRegisterMask = 0x0e000000,
+ DPRegisterFixed = B27 | B25,
+
+ DPSimd1Mask = 0x1e000000,
+ DPSimd1Fixed = B27 | B26 | B25,
+
+ DPSimd2Mask = 0x1e000000,
+ DPSimd2Fixed = B28 | DPSimd1Fixed,
+};
+
+// C3.2.3
+enum ExceptionGenOp {
+ ExceptionGenMask = 0xff000000,
+ ExceptionGenFixed = CompareBranchFixed | B31 | B30,
+ SVC = ExceptionGenFixed | B0,
+ BRK = ExceptionGenFixed | B21,
+ HLT = ExceptionGenFixed | B22,
+};
+
+// C3.2.4
+enum SystemOp {
+ SystemMask = 0xffc00000,
+ SystemFixed = CompareBranchFixed | B31 | B30 | B24,
+ HINT = SystemFixed | B17 | B16 | B13 | B4 | B3 | B2 | B1 | B0,
+};
+
+// C3.2.7
+enum UnconditionalBranchRegOp {
+ UnconditionalBranchRegMask = 0xfe000000,
+ UnconditionalBranchRegFixed = CompareBranchFixed | B31 | B30 | B25,
+ BR = UnconditionalBranchRegFixed | B20 | B19 | B18 | B17 | B16,
+ BLR = BR | B21,
+ RET = BR | B22,
+};
+
+// C3.4.1
+enum AddSubImmOp {
+ AddSubImmMask = 0x1f000000,
+ AddSubImmFixed = DPImmediateFixed | B24,
+ ADDI = AddSubImmFixed,
+ SUBI = AddSubImmFixed | B30,
+};
+
+// C3.4.5
+enum MoveWideOp {
+ MoveWideMask = 0x1f800000,
+ MoveWideFixed = DPImmediateFixed | B25 | B23,
+ MOVN = MoveWideFixed,
+ MOVZ = MoveWideFixed | B30,
+ MOVK = MoveWideFixed | B30 | B29,
+};
+
+
+// C3.5.1
+enum AddSubShiftExtOp {
+ AddSubShiftExtMask = 0x1f200000,
+ AddSubShiftExtFixed = DPRegisterFixed | B24,
+ ADD = AddSubShiftExtFixed,
+ SUB = AddSubShiftExtFixed | B30,
+};
+
+#define APPLY_OP_LIST(_V) \
+_V(DPImmediate) \
+_V(CompareBranch) \
+_V(LoadStore) \
+_V(DPRegister) \
+_V(DPSimd1) \
+_V(DPSimd2) \
+_V(ExceptionGen) \
+_V(System) \
+_V(UnconditionalBranchReg) \
+_V(AddSubImm) \
+_V(MoveWide) \
+_V(AddSubShiftExt) \
+
+
+enum Shift {
+ kNoShift = -1,
+ LSL = 0, // Logical shift left
+ LSR = 1, // Logical shift right
+ ASR = 2, // Arithmetic shift right
+ ROR = 3, // Rotate right
+ kMaxShift = 4,
+};
+
+enum Extend {
+ kNoExtend = -1,
+ UXTB = 0,
+ UXTH = 1,
+ UXTW = 2,
+ UXTX = 3,
+ SXTB = 4,
+ SXTH = 5,
+ SXTW = 6,
+ SXTX = 7,
+ kMaxExtend = 8,
+};
+
+enum R31Type {
+ R31IsSP,
+ R31IsZR,
+ R31IsUndef,
+};
+
+// Constants used for the decoding or encoding of the individual fields of
+// instructions. Based on the "Figure 3-1 ARM instruction set summary".
+enum InstructionFields {
+ // S-bit (modify condition register)
+ kSShift = 29,
+ kSBits = 1,
+
+ // sf field.
+ kSFShift = 31,
+ kSFBits = 1,
+
+ // Registers.
+ kRdShift = 0,
+ kRdBits = 5,
+ kRnShift = 5,
+ kRnBits = 5,
+ kRaShift = 10,
+ kRaBits = 5,
+ kRmShift = 16,
+ kRmBits = 5,
+
+ // Immediates.
+ kImm3Shift = 10,
+ kImm3Bits = 3,
+ kImm6Shift = 10,
+ kImm6Bits = 6,
+ kImm12Shift = 10,
+ kImm12Bits = 12,
+ kImm12ShiftShift = 22,
+ kImm12ShiftBits = 2,
+ kImm16Shift = 5,
+ kImm16Bits = 16,
+
+ // Shift and Extend.
+ kShiftExtendShift = 21,
+ kShiftExtendBits = 1,
+ kShiftTypeShift = 22,
+ kShiftTypeBits = 2,
+ kExtendTypeShift = 13,
+ kExtendTypeBits = 3,
+
+ // Hint Fields.
+ kHintCRmShift = 8,
+ kHintCRmBits = 4,
+ kHintOp2Shift = 5,
+ kHintOp2Bits = 3,
+};
+
+
+const uint32_t kImmExceptionIsRedirectedCall = 0xca11;
+const uint32_t kImmExceptionIsUnreachable = 0xdebf;
+const uint32_t kImmExceptionIsPrintf = 0xdeb1;
+const uint32_t kImmExceptionIsDebug = 0xdeb0;
+
+// The class Instr enables access to individual fields defined in the ARM
+// architecture instruction set encoding as described in figure A3-1.
+//
+// Example: Test whether the instruction at ptr sets the condition code bits.
+//
+// bool InstructionSetsConditionCodes(byte* ptr) {
+// Instr* instr = Instr::At(ptr);
+// int type = instr->TypeField();
+// return ((type == 0) || (type == 1)) && instr->HasS();
+// }
+//
+class Instr {
+ public:
+ enum {
+ kInstrSize = 4,
+ kInstrSizeLog2 = 2,
+ kPCReadOffset = 8
+ };
+
+ static const int32_t kNopInstruction = HINT; // hint #0 === nop.
+ static const int32_t kBreakPointInstruction = // hlt #kImmExceptionIsDebug.
+ HLT | (kImmExceptionIsDebug << kImm16Shift);
+ static const int kBreakPointInstructionSize = kInstrSize;
+
+ // Get the raw instruction bits.
+ inline int32_t InstructionBits() const {
+ return *reinterpret_cast<const int32_t*>(this);
+ }
+
+ // Set the raw instruction bits to value.
+ inline void SetInstructionBits(int32_t value) {
+ *reinterpret_cast<int32_t*>(this) = value;
+ }
+
+ // Read one particular bit out of the instruction bits.
+ inline int Bit(int nr) const {
+ return (InstructionBits() >> nr) & 1;
+ }
+
+ // Read a bit field out of the instruction bits.
+ inline int Bits(int shift, int count) const {
+ return (InstructionBits() >> shift) & ((1 << count) - 1);
+ }
+
+
+ inline int SField() const { return Bit(kSShift); }
+ inline int SFField() const { return Bit(kSFShift); }
+ inline Register RdField() const { return static_cast<Register>(
+ Bits(kRdShift, kRdBits)); }
+ inline Register RnField() const { return static_cast<Register>(
+ Bits(kRnShift, kRnBits)); }
+ inline Register RaField() const { return static_cast<Register>(
+ Bits(kRaShift, kRaBits)); }
+ inline Register RmField() const { return static_cast<Register>(
+ Bits(kRmShift, kRmBits)); }
+
+ // Immediates
+ inline int Imm3Field() const { return Bits(kImm3Shift, kImm3Bits); }
+ inline int Imm6Field() const { return Bits(kImm6Shift, kImm6Bits); }
+ inline int Imm12Field() const { return Bits(kImm12Shift, kImm12Bits); }
+ inline int Imm16Field() const { return Bits(kImm16Shift, kImm16Bits); }
+
+ inline int Imm12ShiftField() const {
+ return Bits(kImm12ShiftShift, kImm12ShiftBits); }
+
+ // Shift and Extend.
+ inline bool IsShift() const { return (Bit(kShiftExtendShift) == 0); }
+ inline bool IsExtend() const { return (Bit(kShiftExtendShift) == 1); }
+ inline Shift ShiftTypeField() const {
+ return static_cast<Shift>(Bits(kShiftTypeShift, kShiftTypeBits)); }
+ inline Extend ExtendTypeField() const {
+ return static_cast<Extend>(Bits(kExtendTypeShift, kExtendTypeBits)); }
+ inline int ShiftAmountField() const { return Imm6Field(); }
+ inline int ExtShiftAmountField() const { return Imm3Field(); }
+
+ // Instruction identification.
+ #define IS_OP(op) \
+ inline bool Is##op##Op() const { \
+ return ((InstructionBits() & op##Mask) == (op##Fixed & op##Mask)); }
+ APPLY_OP_LIST(IS_OP)
+ #undef IS_OP
+
+ inline bool HasS() const { return (SField() == 1); }
+
+ // Indicate whether Rd can be the SP or ZR. This does not check that the
+ // instruction actually has an Rd field.
+ R31Type RdMode() const {
+ // The following instructions use SP as Rd:
+ // Add/sub (immediate) when not setting the flags.
+ // Add/sub (extended) when not setting the flags.
+ // Logical (immediate) when not setting the flags.
+ // Otherwise, R31 is the ZR.
+ if (IsAddSubImmOp() || (IsAddSubShiftExtOp() && IsExtend())) {
+ if (HasS()) {
+ return R31IsZR;
+ } else {
+ return R31IsSP;
+ }
+ }
+ // TODO(zra): Handle for logical immediate operations.
+ return R31IsZR;
+ }
+
+ // Indicate whether Rn can be SP or ZR. This does not check that the
+ // instruction actually has an Rn field.
+ R31Type RnMode() const {
+ // The following instructions use SP as Rn:
+ // All loads and stores.
+ // Add/sub (immediate).
+ // Add/sub (extended).
+ // Otherwise, r31 is ZR.
+ if (IsLoadStoreOp() ||
+ IsAddSubImmOp() ||
+ (IsAddSubShiftExtOp() && IsExtend())) {
+ return R31IsSP;
+ }
+ return R31IsZR;
+ }
+
+ // Instructions are read out of a code stream. The only way to get a
+ // reference to an instruction is to convert a pointer. There is no way
+ // to allocate or create instances of class Instr.
+ // Use the At(pc) function to create references to Instr.
+ static Instr* At(uword pc) { return reinterpret_cast<Instr*>(pc); }
+
+ private:
+ DISALLOW_ALLOCATION();
+ DISALLOW_IMPLICIT_CONSTRUCTORS(Instr);
+};
+
+} // namespace dart
+
+#endif // VM_CONSTANTS_ARM64_H_
« 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