summaryrefslogtreecommitdiff
path: root/compiler/optimizing/code_generator_vector_mips.cc
diff options
context:
space:
mode:
authorLena Djokic <Lena.Djokic@imgtec.com>2017-07-20 16:07:36 +0200
committerGoran Jakovljevic <Goran.Jakovljevic@imgtec.com>2017-08-14 10:16:34 +0200
commitbc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8 (patch)
tree0db1314987cd0f24c7294c4ad540c7f28e2739d9 /compiler/optimizing/code_generator_vector_mips.cc
parentc1bb1cd339b2ebea9c4770fb4d61bacd7d77746f (diff)
MIPS: Support MultiplyAccumulate for SIMD.
Moved support for multiply accumulate from arm64-specific to general instruction simplification. Also extended 550-checker-multiply-accumulate test. Test: test-art-host, test-art-target Change-Id: If113f0f0d5cb48e8a76273c919cfa2f49fce667d
Diffstat (limited to 'compiler/optimizing/code_generator_vector_mips.cc')
-rw-r--r--compiler/optimizing/code_generator_vector_mips.cc67
1 files changed, 65 insertions, 2 deletions
diff --git a/compiler/optimizing/code_generator_vector_mips.cc b/compiler/optimizing/code_generator_vector_mips.cc
index ea36e90112..6bf28ab1a3 100644
--- a/compiler/optimizing/code_generator_vector_mips.cc
+++ b/compiler/optimizing/code_generator_vector_mips.cc
@@ -819,11 +819,74 @@ void InstructionCodeGeneratorMIPS::VisitVecUShr(HVecUShr* instruction) {
}
void LocationsBuilderMIPS::VisitVecMultiplyAccumulate(HVecMultiplyAccumulate* instr) {
- LOG(FATAL) << "No SIMD for " << instr->GetId();
+ LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(instr);
+ switch (instr->GetPackedType()) {
+ case Primitive::kPrimByte:
+ case Primitive::kPrimChar:
+ case Primitive::kPrimShort:
+ case Primitive::kPrimInt:
+ case Primitive::kPrimLong:
+ locations->SetInAt(
+ HVecMultiplyAccumulate::kInputAccumulatorIndex, Location::RequiresFpuRegister());
+ locations->SetInAt(
+ HVecMultiplyAccumulate::kInputMulLeftIndex, Location::RequiresFpuRegister());
+ locations->SetInAt(
+ HVecMultiplyAccumulate::kInputMulRightIndex, Location::RequiresFpuRegister());
+ DCHECK_EQ(HVecMultiplyAccumulate::kInputAccumulatorIndex, 0);
+ locations->SetOut(Location::SameAsFirstInput());
+ break;
+ default:
+ LOG(FATAL) << "Unsupported SIMD type";
+ UNREACHABLE();
+ }
}
void InstructionCodeGeneratorMIPS::VisitVecMultiplyAccumulate(HVecMultiplyAccumulate* instr) {
- LOG(FATAL) << "No SIMD for " << instr->GetId();
+ LocationSummary* locations = instr->GetLocations();
+ VectorRegister acc =
+ VectorRegisterFrom(locations->InAt(HVecMultiplyAccumulate::kInputAccumulatorIndex));
+ VectorRegister left =
+ VectorRegisterFrom(locations->InAt(HVecMultiplyAccumulate::kInputMulLeftIndex));
+ VectorRegister right =
+ VectorRegisterFrom(locations->InAt(HVecMultiplyAccumulate::kInputMulRightIndex));
+ switch (instr->GetPackedType()) {
+ case Primitive::kPrimByte:
+ DCHECK_EQ(16u, instr->GetVectorLength());
+ if (instr->GetOpKind() == HInstruction::kAdd) {
+ __ MaddvB(acc, left, right);
+ } else {
+ __ MsubvB(acc, left, right);
+ }
+ break;
+ case Primitive::kPrimChar:
+ case Primitive::kPrimShort:
+ DCHECK_EQ(8u, instr->GetVectorLength());
+ if (instr->GetOpKind() == HInstruction::kAdd) {
+ __ MaddvH(acc, left, right);
+ } else {
+ __ MsubvH(acc, left, right);
+ }
+ break;
+ case Primitive::kPrimInt:
+ DCHECK_EQ(4u, instr->GetVectorLength());
+ if (instr->GetOpKind() == HInstruction::kAdd) {
+ __ MaddvW(acc, left, right);
+ } else {
+ __ MsubvW(acc, left, right);
+ }
+ break;
+ case Primitive::kPrimLong:
+ DCHECK_EQ(2u, instr->GetVectorLength());
+ if (instr->GetOpKind() == HInstruction::kAdd) {
+ __ MaddvD(acc, left, right);
+ } else {
+ __ MsubvD(acc, left, right);
+ }
+ break;
+ default:
+ LOG(FATAL) << "Unsupported SIMD type";
+ UNREACHABLE();
+ }
}
// Helper to set up locations for vector memory operations.