summaryrefslogtreecommitdiff
path: root/compiler/optimizing/nodes_vector.h
diff options
context:
space:
mode:
author Artem Serov <artem.serov@linaro.org> 2017-04-10 17:41:46 +0100
committer Artem Serov <artem.serov@linaro.org> 2017-04-20 00:21:29 +0100
commitf34dd206d0073fb3949be872224420a8488f551f (patch)
treeb24b451af6efdd9f67c4cbd5c37ebb4ec6a4aaad /compiler/optimizing/nodes_vector.h
parent1f56cb5c594f5757085820b1042988d10f02bb0b (diff)
ARM64: Support MultiplyAccumulate for SIMD.
Test: test-art-host, test-art-target. Change-Id: I06af8415e15352d09d176cae828163cbe99ae7a7
Diffstat (limited to 'compiler/optimizing/nodes_vector.h')
-rw-r--r--compiler/optimizing/nodes_vector.h57
1 files changed, 57 insertions, 0 deletions
diff --git a/compiler/optimizing/nodes_vector.h b/compiler/optimizing/nodes_vector.h
index bff58d0910..450691c1ea 100644
--- a/compiler/optimizing/nodes_vector.h
+++ b/compiler/optimizing/nodes_vector.h
@@ -143,6 +143,10 @@ class HVecBinaryOperation : public HVecOperation {
/*number_of_inputs*/ 2,
vector_length,
dex_pc) { }
+
+ HInstruction* GetLeft() const { return InputAt(0); }
+ HInstruction* GetRight() const { return InputAt(1); }
+
DECLARE_ABSTRACT_INSTRUCTION(VecBinaryOperation);
private:
DISALLOW_COPY_AND_ASSIGN(HVecBinaryOperation);
@@ -627,6 +631,59 @@ class HVecUShr FINAL : public HVecBinaryOperation {
DISALLOW_COPY_AND_ASSIGN(HVecUShr);
};
+// Multiplies every component in the two vectors, adds the result vector to the accumulator vector.
+// viz. [ acc1, .., accn ] + [ x1, .. , xn ] * [ y1, .. , yn ] =
+// [ acc1 + x1 * y1, .. , accn + xn * yn ].
+class HVecMultiplyAccumulate FINAL : public HVecOperation {
+ public:
+ HVecMultiplyAccumulate(ArenaAllocator* arena,
+ InstructionKind op,
+ HInstruction* accumulator,
+ HInstruction* mul_left,
+ HInstruction* mul_right,
+ Primitive::Type packed_type,
+ size_t vector_length,
+ uint32_t dex_pc = kNoDexPc)
+ : HVecOperation(arena,
+ packed_type,
+ SideEffects::None(),
+ /*number_of_inputs*/ 3,
+ vector_length,
+ dex_pc),
+ op_kind_(op) {
+ DCHECK(op == InstructionKind::kAdd || op == InstructionKind::kSub);
+ DCHECK(accumulator->IsVecOperation());
+ DCHECK(mul_left->IsVecOperation() && mul_right->IsVecOperation());
+ DCHECK_EQ(accumulator->AsVecOperation()->GetPackedType(), packed_type);
+ DCHECK_EQ(mul_left->AsVecOperation()->GetPackedType(), packed_type);
+ DCHECK_EQ(mul_right->AsVecOperation()->GetPackedType(), packed_type);
+
+ SetRawInputAt(kInputAccumulatorIndex, accumulator);
+ SetRawInputAt(kInputMulLeftIndex, mul_left);
+ SetRawInputAt(kInputMulRightIndex, mul_right);
+ }
+
+ static constexpr int kInputAccumulatorIndex = 0;
+ static constexpr int kInputMulLeftIndex = 1;
+ static constexpr int kInputMulRightIndex = 2;
+
+ bool CanBeMoved() const OVERRIDE { return true; }
+
+ bool InstructionDataEquals(const HInstruction* other) const OVERRIDE {
+ return op_kind_ == other->AsVecMultiplyAccumulate()->op_kind_;
+ }
+
+ InstructionKind GetOpKind() const { return op_kind_; }
+
+ DECLARE_INSTRUCTION(VecMultiplyAccumulate);
+
+ private:
+ // Indicates if this is a MADD or MSUB.
+ const InstructionKind op_kind_;
+
+ DISALLOW_COPY_AND_ASSIGN(HVecMultiplyAccumulate);
+};
+
// Loads a vector from memory, viz. load(mem, 1)
// yield the vector [ mem(1), .. , mem(n) ].
class HVecLoad FINAL : public HVecMemoryOperation {