From bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8 Mon Sep 17 00:00:00 2001 From: Lena Djokic Date: Thu, 20 Jul 2017 16:07:36 +0200 Subject: 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 --- .../optimizing/code_generator_vector_mips64.cc | 67 +++++++++++++++++++++- 1 file changed, 65 insertions(+), 2 deletions(-) (limited to 'compiler/optimizing/code_generator_vector_mips64.cc') diff --git a/compiler/optimizing/code_generator_vector_mips64.cc b/compiler/optimizing/code_generator_vector_mips64.cc index 0395db1df9..75bf7a7cbb 100644 --- a/compiler/optimizing/code_generator_vector_mips64.cc +++ b/compiler/optimizing/code_generator_vector_mips64.cc @@ -823,11 +823,74 @@ void InstructionCodeGeneratorMIPS64::VisitVecUShr(HVecUShr* instruction) { } void LocationsBuilderMIPS64::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 InstructionCodeGeneratorMIPS64::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. -- cgit v1.2.3