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

Unified Diff: runtime/vm/constants_arm64.h

Issue 231373003: Adds logical operations to arm64. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/assembler_arm64_test.cc ('k') | runtime/vm/disassembler_arm64.cc » ('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 34900)
+++ runtime/vm/constants_arm64.h (working copy)
@@ -299,6 +299,16 @@
SUBI = AddSubImmFixed | B30,
};
+// C3.4.4
+enum LogicalImmOp {
+ LogicalImmMask = 0x1f800000,
+ LogicalImmFixed = DPImmediateFixed | B25,
+ ANDI = LogicalImmFixed,
+ ORRI = LogicalImmFixed | B29,
+ EORI = LogicalImmFixed | B30,
+ ANDIS = LogicalImmFixed | B30 | B29,
+};
+
// C3.4.5
enum MoveWideOp {
MoveWideMask = 0x1f800000,
@@ -308,7 +318,6 @@
MOVK = MoveWideFixed | B30 | B29,
};
-
// C3.5.1
enum AddSubShiftExtOp {
AddSubShiftExtMask = 0x1f000000,
@@ -317,6 +326,19 @@
SUB = AddSubShiftExtFixed | B30,
};
+enum LogicalShiftOp {
+ LogicalShiftMask = 0x1f000000,
+ LogicalShiftFixed = DPRegisterFixed,
+ AND = LogicalShiftFixed,
+ BIC = LogicalShiftFixed | B21,
+ ORR = LogicalShiftFixed | B29,
+ ORN = LogicalShiftFixed | B29 | B21,
+ EOR = LogicalShiftFixed | B30,
+ EON = LogicalShiftFixed | B30 | B21,
+ ANDS = LogicalShiftFixed | B30 | B29,
+ BICS = LogicalShiftFixed | B30 | B29 | B21,
+};
+
#define APPLY_OP_LIST(_V) \
_V(DPImmediate) \
_V(CompareBranch) \
@@ -329,8 +351,10 @@
_V(LoadStoreReg) \
_V(UnconditionalBranchReg) \
_V(AddSubImm) \
+_V(LogicalImm) \
_V(MoveWide) \
_V(AddSubShiftExt) \
+_V(LogicalShift) \
enum Shift {
@@ -402,12 +426,20 @@
kImm16Shift = 5,
kImm16Bits = 16,
+ // Bitfield immediates.
+ kNShift = 22,
+ kNBits = 1,
+ kImmRShift = 16,
+ kImmRBits = 6,
+ kImmSShift = 10,
+ kImmSBits = 6,
+
kHWShift = 21,
kHWBits = 2,
// Shift and Extend.
- kShiftExtendShift = 21,
- kShiftExtendBits = 1,
+ kAddShiftExtendShift = 21,
+ kAddShiftExtendBits = 1,
kShiftTypeShift = 22,
kShiftTypeBits = 2,
kExtendTypeShift = 13,
@@ -426,6 +458,27 @@
const uint32_t kImmExceptionIsPrintf = 0xdeb1;
const uint32_t kImmExceptionIsDebug = 0xdeb0;
+// Helper functions for decoding logical immediates.
+static inline uint64_t RotateRight(
+ uint64_t value, uint8_t rotate, uint8_t width) {
+ ASSERT(width <= 64);
+ rotate &= 63;
+ return ((value & ((1UL << rotate) - 1UL)) << (width - rotate)) |
+ (value >> rotate);
+}
+
+static inline uint64_t RepeatBitsAcrossReg(
+ uint8_t reg_size, uint64_t value, uint8_t width) {
+ ASSERT((width == 2) || (width == 4) || (width == 8) || (width == 16) ||
+ (width == 32));
+ ASSERT((reg_size == kWRegSizeInBits) || (reg_size == kXRegSizeInBits));
+ uint64_t result = value & ((1UL << width) - 1UL);
+ for (unsigned i = width; i < reg_size; i *= 2) {
+ result |= (result << i);
+ }
+ return result;
+}
+
// The class Instr enables access to individual fields defined in the ARM
// architecture instruction set encoding as described in figure A3-1.
//
@@ -470,7 +523,7 @@
return (InstructionBits() >> shift) & ((1 << count) - 1);
}
-
+ inline int NField() const { return Bit(22); }
inline int SField() const { return Bit(kSShift); }
inline int SFField() const { return Bit(kSFShift); }
inline int SzField() const { return Bits(kSzShift, kSzBits); }
@@ -488,20 +541,29 @@
// Immediates
inline int Imm3Field() const { return Bits(kImm3Shift, kImm3Bits); }
inline int Imm6Field() const { return Bits(kImm6Shift, kImm6Bits); }
+
inline int Imm9Field() const { return Bits(kImm9Shift, kImm9Bits); }
// Sign-extended Imm9Field()
inline int64_t SImm9Field() const {
return (static_cast<int32_t>(Imm9Field()) << 23) >> 23; }
+
inline int Imm12Field() const { return Bits(kImm12Shift, kImm12Bits); }
- inline int Imm16Field() const { return Bits(kImm16Shift, kImm16Bits); }
-
inline int Imm12ShiftField() const {
return Bits(kImm12ShiftShift, kImm12ShiftBits); }
+
+ inline int Imm16Field() const { return Bits(kImm16Shift, kImm16Bits); }
inline int HWField() const { return Bits(kHWShift, kHWBits); }
+ inline int ImmRField() const { return Bits(kImmRShift, kImmRBits); }
+ inline int ImmSField() const { return Bits(kImmSShift, kImmSBits); }
+
// Shift and Extend.
- inline bool IsShift() const { return (Bit(kShiftExtendShift) == 0); }
- inline bool IsExtend() const { return (Bit(kShiftExtendShift) == 1); }
+ inline bool IsShift() const {
+ return IsLogicalShiftOp() || (Bit(kAddShiftExtendShift) == 0);
+ }
+ inline bool IsExtend() const {
+ return !IsLogicalShiftOp() && (Bit(kAddShiftExtendShift) == 1);
+ }
inline Shift ShiftTypeField() const {
return static_cast<Shift>(Bits(kShiftTypeShift, kShiftTypeBits)); }
inline Extend ExtendTypeField() const {
@@ -553,6 +615,59 @@
return R31IsZR;
}
+ // Logical immediates can't encode zero, so a return value of zero is used to
+ // indicate a failure case. Specifically, where the constraints on imm_s are
+ // not met.
+ uint64_t ImmLogical() {
+ const uint8_t reg_size =
+ SFField() == 1 ? kXRegSizeInBits : kWRegSizeInBits;
+ const int64_t n = NField();
+ const int64_t imm_s = ImmSField();
+ const int64_t imm_r = ImmRField();
+
+ // An integer is constructed from the n, imm_s and imm_r bits according to
+ // the following table:
+ //
+ // N imms immr size S R
+ // 1 ssssss rrrrrr 64 UInt(ssssss) UInt(rrrrrr)
+ // 0 0sssss xrrrrr 32 UInt(sssss) UInt(rrrrr)
+ // 0 10ssss xxrrrr 16 UInt(ssss) UInt(rrrr)
+ // 0 110sss xxxrrr 8 UInt(sss) UInt(rrr)
+ // 0 1110ss xxxxrr 4 UInt(ss) UInt(rr)
+ // 0 11110s xxxxxr 2 UInt(s) UInt(r)
+ // (s bits must not be all set)
+ //
+ // A pattern is constructed of size bits, where the least significant S+1
+ // bits are set. The pattern is rotated right by R, and repeated across a
+ // 32 or 64-bit value, depending on destination register width.
+
+ if (n == 1) {
+ if (imm_s == 0x3F) {
+ return 0;
+ }
+ uint64_t bits = (1UL << (imm_s + 1)) - 1;
+ return RotateRight(bits, imm_r, 64);
+ } else {
+ if ((imm_s >> 1) == 0x1F) {
+ return 0;
+ }
+ for (int width = 0x20; width >= 0x2; width >>= 1) {
+ if ((imm_s & width) == 0) {
+ int mask = width - 1;
+ if ((imm_s & mask) == mask) {
+ return 0;
+ }
+ uint64_t bits = (1UL << ((imm_s & mask) + 1)) - 1;
+ return RepeatBitsAcrossReg(reg_size,
+ RotateRight(bits, imm_r & mask, width),
+ width);
+ }
+ }
+ }
+ UNREACHABLE();
+ return 0;
+ }
+
// 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.
« no previous file with comments | « runtime/vm/assembler_arm64_test.cc ('k') | runtime/vm/disassembler_arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698