diff options
author | 2017-01-13 14:42:47 +0000 | |
---|---|---|
committer | 2017-02-17 14:59:27 +0000 | |
commit | 74234daabb28a4b9c804bf8bf908e7334bd4d400 (patch) | |
tree | 0b60cb00ab117c1a9a4b92983514962198b548bf /compiler/optimizing/nodes_shared.h | |
parent | a7e9bfafeb64b1142433a41b05ddc263cadc61e3 (diff) |
ARM: Merge data-processing instructions and shifts/(un)signed extensions
This commit mirrors the work that has already been done for ARM64.
Test: m test-art-target-run-test-551-checker-shifter-operand
Change-Id: Iec8c1563b035f40f0e18dcffde28d91dc21922f8
Diffstat (limited to 'compiler/optimizing/nodes_shared.h')
-rw-r--r-- | compiler/optimizing/nodes_shared.h | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/compiler/optimizing/nodes_shared.h b/compiler/optimizing/nodes_shared.h index 814202e97b..c6bfbcc7fb 100644 --- a/compiler/optimizing/nodes_shared.h +++ b/compiler/optimizing/nodes_shared.h @@ -150,6 +150,81 @@ class HIntermediateAddress FINAL : public HExpression<2> { DISALLOW_COPY_AND_ASSIGN(HIntermediateAddress); }; +class HDataProcWithShifterOp FINAL : public HExpression<2> { + public: + enum OpKind { + kLSL, // Logical shift left. + kLSR, // Logical shift right. + kASR, // Arithmetic shift right. + kUXTB, // Unsigned extend byte. + kUXTH, // Unsigned extend half-word. + kUXTW, // Unsigned extend word. + kSXTB, // Signed extend byte. + kSXTH, // Signed extend half-word. + kSXTW, // Signed extend word. + + // Aliases. + kFirstShiftOp = kLSL, + kLastShiftOp = kASR, + kFirstExtensionOp = kUXTB, + kLastExtensionOp = kSXTW + }; + HDataProcWithShifterOp(HInstruction* instr, + HInstruction* left, + HInstruction* right, + OpKind op, + // The shift argument is unused if the operation + // is an extension. + int shift = 0, + uint32_t dex_pc = kNoDexPc) + : HExpression(instr->GetType(), SideEffects::None(), dex_pc), + instr_kind_(instr->GetKind()), op_kind_(op), + shift_amount_(shift & (instr->GetType() == Primitive::kPrimInt + ? kMaxIntShiftDistance + : kMaxLongShiftDistance)) { + DCHECK(!instr->HasSideEffects()); + SetRawInputAt(0, left); + SetRawInputAt(1, right); + } + + bool CanBeMoved() const OVERRIDE { return true; } + bool InstructionDataEquals(const HInstruction* other_instr) const OVERRIDE { + const HDataProcWithShifterOp* other = other_instr->AsDataProcWithShifterOp(); + return instr_kind_ == other->instr_kind_ && + op_kind_ == other->op_kind_ && + shift_amount_ == other->shift_amount_; + } + + static bool IsShiftOp(OpKind op_kind) { + return kFirstShiftOp <= op_kind && op_kind <= kLastShiftOp; + } + + static bool IsExtensionOp(OpKind op_kind) { + return kFirstExtensionOp <= op_kind && op_kind <= kLastExtensionOp; + } + + // Find the operation kind and shift amount from a bitfield move instruction. + static void GetOpInfoFromInstruction(HInstruction* bitfield_op, + /*out*/OpKind* op_kind, + /*out*/int* shift_amount); + + InstructionKind GetInstrKind() const { return instr_kind_; } + OpKind GetOpKind() const { return op_kind_; } + int GetShiftAmount() const { return shift_amount_; } + + DECLARE_INSTRUCTION(DataProcWithShifterOp); + + private: + InstructionKind instr_kind_; + OpKind op_kind_; + int shift_amount_; + + friend std::ostream& operator<<(std::ostream& os, OpKind op); + + DISALLOW_COPY_AND_ASSIGN(HDataProcWithShifterOp); +}; + +std::ostream& operator<<(std::ostream& os, const HDataProcWithShifterOp::OpKind op); } // namespace art |