diff options
author | Vladimir Marko <vmarko@google.com> | 2020-02-12 10:52:22 +0000 |
---|---|---|
committer | Vladimir Marko <vmarko@google.com> | 2020-02-13 09:14:02 +0000 |
commit | 54f4fbd1a6834f06dc9b644b865423fdc03afb15 (patch) | |
tree | 4f55b2a196453a8a197a1787a688cc299682e55d /compiler/optimizing/code_generator_vector_mips.cc | |
parent | 2d3de3a40015af07f7645a298f77b398af0c6c2c (diff) |
Remove MIPS support from Optimizing.
Test: aosp_taimen-userdebug boots.
Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Bug: 147346243
Change-Id: I97fdc15e568ae3fe390efb1da690343025f84944
Diffstat (limited to 'compiler/optimizing/code_generator_vector_mips.cc')
-rw-r--r-- | compiler/optimizing/code_generator_vector_mips.cc | 1430 |
1 files changed, 0 insertions, 1430 deletions
diff --git a/compiler/optimizing/code_generator_vector_mips.cc b/compiler/optimizing/code_generator_vector_mips.cc deleted file mode 100644 index 4e9ba0d3d2..0000000000 --- a/compiler/optimizing/code_generator_vector_mips.cc +++ /dev/null @@ -1,1430 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "code_generator_mips.h" -#include "mirror/array-inl.h" - -namespace art { -namespace mips { - -// NOLINT on __ macro to suppress wrong warning/fix (misc-macro-parentheses) from clang-tidy. -#define __ down_cast<MipsAssembler*>(GetAssembler())-> // NOLINT - -void LocationsBuilderMIPS::VisitVecReplicateScalar(HVecReplicateScalar* instruction) { - LocationSummary* locations = new (GetGraph()->GetAllocator()) LocationSummary(instruction); - switch (instruction->GetPackedType()) { - case DataType::Type::kBool: - case DataType::Type::kUint8: - case DataType::Type::kInt8: - case DataType::Type::kUint16: - case DataType::Type::kInt16: - case DataType::Type::kInt32: - case DataType::Type::kInt64: - locations->SetInAt(0, Location::RequiresRegister()); - locations->SetOut(Location::RequiresFpuRegister()); - break; - case DataType::Type::kFloat32: - case DataType::Type::kFloat64: - locations->SetInAt(0, Location::RequiresFpuRegister()); - locations->SetOut(Location::RequiresFpuRegister(), Location::kNoOutputOverlap); - break; - default: - LOG(FATAL) << "Unsupported SIMD type: " << instruction->GetPackedType(); - UNREACHABLE(); - } -} - -void InstructionCodeGeneratorMIPS::VisitVecReplicateScalar(HVecReplicateScalar* instruction) { - LocationSummary* locations = instruction->GetLocations(); - VectorRegister dst = VectorRegisterFrom(locations->Out()); - switch (instruction->GetPackedType()) { - case DataType::Type::kBool: - case DataType::Type::kUint8: - case DataType::Type::kInt8: - DCHECK_EQ(16u, instruction->GetVectorLength()); - __ FillB(dst, locations->InAt(0).AsRegister<Register>()); - break; - case DataType::Type::kUint16: - case DataType::Type::kInt16: - DCHECK_EQ(8u, instruction->GetVectorLength()); - __ FillH(dst, locations->InAt(0).AsRegister<Register>()); - break; - case DataType::Type::kInt32: - DCHECK_EQ(4u, instruction->GetVectorLength()); - __ FillW(dst, locations->InAt(0).AsRegister<Register>()); - break; - case DataType::Type::kInt64: - DCHECK_EQ(2u, instruction->GetVectorLength()); - __ InsertW(static_cast<VectorRegister>(FTMP), - locations->InAt(0).AsRegisterPairLow<Register>(), - 0); - __ InsertW(static_cast<VectorRegister>(FTMP), - locations->InAt(0).AsRegisterPairHigh<Register>(), - 1); - __ ReplicateFPToVectorRegister(dst, FTMP, /* is_double= */ true); - break; - case DataType::Type::kFloat32: - DCHECK_EQ(4u, instruction->GetVectorLength()); - __ ReplicateFPToVectorRegister(dst, - locations->InAt(0).AsFpuRegister<FRegister>(), - /* is_double= */ false); - break; - case DataType::Type::kFloat64: - DCHECK_EQ(2u, instruction->GetVectorLength()); - __ ReplicateFPToVectorRegister(dst, - locations->InAt(0).AsFpuRegister<FRegister>(), - /* is_double= */ true); - break; - default: - LOG(FATAL) << "Unsupported SIMD type: " << instruction->GetPackedType(); - UNREACHABLE(); - } -} - -void LocationsBuilderMIPS::VisitVecExtractScalar(HVecExtractScalar* instruction) { - LocationSummary* locations = new (GetGraph()->GetAllocator()) LocationSummary(instruction); - switch (instruction->GetPackedType()) { - case DataType::Type::kBool: - case DataType::Type::kUint8: - case DataType::Type::kInt8: - case DataType::Type::kUint16: - case DataType::Type::kInt16: - case DataType::Type::kInt32: - case DataType::Type::kInt64: - locations->SetInAt(0, Location::RequiresFpuRegister()); - locations->SetOut(Location::RequiresRegister()); - break; - case DataType::Type::kFloat32: - case DataType::Type::kFloat64: - locations->SetInAt(0, Location::RequiresFpuRegister()); - locations->SetOut(Location::SameAsFirstInput()); - break; - default: - LOG(FATAL) << "Unsupported SIMD type: " << instruction->GetPackedType(); - UNREACHABLE(); - } -} - -void InstructionCodeGeneratorMIPS::VisitVecExtractScalar(HVecExtractScalar* instruction) { - LocationSummary* locations = instruction->GetLocations(); - VectorRegister src = VectorRegisterFrom(locations->InAt(0)); - switch (instruction->GetPackedType()) { - case DataType::Type::kInt32: - DCHECK_EQ(4u, instruction->GetVectorLength()); - __ Copy_sW(locations->Out().AsRegister<Register>(), src, 0); - break; - case DataType::Type::kInt64: - DCHECK_EQ(2u, instruction->GetVectorLength()); - __ Copy_sW(locations->Out().AsRegisterPairLow<Register>(), src, 0); - __ Copy_sW(locations->Out().AsRegisterPairHigh<Register>(), src, 1); - break; - case DataType::Type::kFloat32: - case DataType::Type::kFloat64: - DCHECK_LE(2u, instruction->GetVectorLength()); - DCHECK_LE(instruction->GetVectorLength(), 4u); - DCHECK(locations->InAt(0).Equals(locations->Out())); // no code required - break; - default: - LOG(FATAL) << "Unsupported SIMD type: " << instruction->GetPackedType(); - UNREACHABLE(); - } -} - -// Helper to set up locations for vector unary operations. -static void CreateVecUnOpLocations(ArenaAllocator* allocator, HVecUnaryOperation* instruction) { - LocationSummary* locations = new (allocator) LocationSummary(instruction); - DataType::Type type = instruction->GetPackedType(); - switch (type) { - case DataType::Type::kBool: - locations->SetInAt(0, Location::RequiresFpuRegister()); - locations->SetOut(Location::RequiresFpuRegister(), - instruction->IsVecNot() ? Location::kOutputOverlap - : Location::kNoOutputOverlap); - break; - case DataType::Type::kUint8: - case DataType::Type::kInt8: - case DataType::Type::kUint16: - case DataType::Type::kInt16: - case DataType::Type::kInt32: - case DataType::Type::kInt64: - case DataType::Type::kFloat32: - case DataType::Type::kFloat64: - locations->SetInAt(0, Location::RequiresFpuRegister()); - locations->SetOut(Location::RequiresFpuRegister(), - (instruction->IsVecNeg() || instruction->IsVecAbs() || - (instruction->IsVecReduce() && type == DataType::Type::kInt64)) - ? Location::kOutputOverlap - : Location::kNoOutputOverlap); - break; - default: - LOG(FATAL) << "Unsupported SIMD type: " << instruction->GetPackedType(); - UNREACHABLE(); - } -} - -void LocationsBuilderMIPS::VisitVecReduce(HVecReduce* instruction) { - CreateVecUnOpLocations(GetGraph()->GetAllocator(), instruction); -} - -void InstructionCodeGeneratorMIPS::VisitVecReduce(HVecReduce* instruction) { - LocationSummary* locations = instruction->GetLocations(); - VectorRegister src = VectorRegisterFrom(locations->InAt(0)); - VectorRegister dst = VectorRegisterFrom(locations->Out()); - VectorRegister tmp = static_cast<VectorRegister>(FTMP); - switch (instruction->GetPackedType()) { - case DataType::Type::kInt32: - DCHECK_EQ(4u, instruction->GetVectorLength()); - switch (instruction->GetReductionKind()) { - case HVecReduce::kSum: - __ Hadd_sD(tmp, src, src); - __ IlvlD(dst, tmp, tmp); - __ AddvW(dst, dst, tmp); - break; - case HVecReduce::kMin: - __ IlvodW(tmp, src, src); - __ Min_sW(tmp, src, tmp); - __ IlvlW(dst, tmp, tmp); - __ Min_sW(dst, dst, tmp); - break; - case HVecReduce::kMax: - __ IlvodW(tmp, src, src); - __ Max_sW(tmp, src, tmp); - __ IlvlW(dst, tmp, tmp); - __ Max_sW(dst, dst, tmp); - break; - } - break; - case DataType::Type::kInt64: - DCHECK_EQ(2u, instruction->GetVectorLength()); - switch (instruction->GetReductionKind()) { - case HVecReduce::kSum: - __ IlvlD(dst, src, src); - __ AddvD(dst, dst, src); - break; - case HVecReduce::kMin: - __ IlvlD(dst, src, src); - __ Min_sD(dst, dst, src); - break; - case HVecReduce::kMax: - __ IlvlD(dst, src, src); - __ Max_sD(dst, dst, src); - break; - } - break; - default: - LOG(FATAL) << "Unsupported SIMD type: " << instruction->GetPackedType(); - UNREACHABLE(); - } -} - -void LocationsBuilderMIPS::VisitVecCnv(HVecCnv* instruction) { - CreateVecUnOpLocations(GetGraph()->GetAllocator(), instruction); -} - -void InstructionCodeGeneratorMIPS::VisitVecCnv(HVecCnv* instruction) { - LocationSummary* locations = instruction->GetLocations(); - VectorRegister src = VectorRegisterFrom(locations->InAt(0)); - VectorRegister dst = VectorRegisterFrom(locations->Out()); - DataType::Type from = instruction->GetInputType(); - DataType::Type to = instruction->GetResultType(); - if (from == DataType::Type::kInt32 && to == DataType::Type::kFloat32) { - DCHECK_EQ(4u, instruction->GetVectorLength()); - __ Ffint_sW(dst, src); - } else { - LOG(FATAL) << "Unsupported SIMD type: " << instruction->GetPackedType(); - } -} - -void LocationsBuilderMIPS::VisitVecNeg(HVecNeg* instruction) { - CreateVecUnOpLocations(GetGraph()->GetAllocator(), instruction); -} - -void InstructionCodeGeneratorMIPS::VisitVecNeg(HVecNeg* instruction) { - LocationSummary* locations = instruction->GetLocations(); - VectorRegister src = VectorRegisterFrom(locations->InAt(0)); - VectorRegister dst = VectorRegisterFrom(locations->Out()); - switch (instruction->GetPackedType()) { - case DataType::Type::kUint8: - case DataType::Type::kInt8: - DCHECK_EQ(16u, instruction->GetVectorLength()); - __ FillB(dst, ZERO); - __ SubvB(dst, dst, src); - break; - case DataType::Type::kUint16: - case DataType::Type::kInt16: - DCHECK_EQ(8u, instruction->GetVectorLength()); - __ FillH(dst, ZERO); - __ SubvH(dst, dst, src); - break; - case DataType::Type::kInt32: - DCHECK_EQ(4u, instruction->GetVectorLength()); - __ FillW(dst, ZERO); - __ SubvW(dst, dst, src); - break; - case DataType::Type::kInt64: - DCHECK_EQ(2u, instruction->GetVectorLength()); - __ FillW(dst, ZERO); - __ SubvD(dst, dst, src); - break; - case DataType::Type::kFloat32: - DCHECK_EQ(4u, instruction->GetVectorLength()); - __ FillW(dst, ZERO); - __ FsubW(dst, dst, src); - break; - case DataType::Type::kFloat64: - DCHECK_EQ(2u, instruction->GetVectorLength()); - __ FillW(dst, ZERO); - __ FsubD(dst, dst, src); - break; - default: - LOG(FATAL) << "Unsupported SIMD type: " << instruction->GetPackedType(); - UNREACHABLE(); - } -} - -void LocationsBuilderMIPS::VisitVecAbs(HVecAbs* instruction) { - CreateVecUnOpLocations(GetGraph()->GetAllocator(), instruction); -} - -void InstructionCodeGeneratorMIPS::VisitVecAbs(HVecAbs* instruction) { - LocationSummary* locations = instruction->GetLocations(); - VectorRegister src = VectorRegisterFrom(locations->InAt(0)); - VectorRegister dst = VectorRegisterFrom(locations->Out()); - switch (instruction->GetPackedType()) { - case DataType::Type::kInt8: - DCHECK_EQ(16u, instruction->GetVectorLength()); - __ FillB(dst, ZERO); // all zeroes - __ Add_aB(dst, dst, src); // dst = abs(0) + abs(src) - break; - case DataType::Type::kInt16: - DCHECK_EQ(8u, instruction->GetVectorLength()); - __ FillH(dst, ZERO); // all zeroes - __ Add_aH(dst, dst, src); // dst = abs(0) + abs(src) - break; - case DataType::Type::kInt32: - DCHECK_EQ(4u, instruction->GetVectorLength()); - __ FillW(dst, ZERO); // all zeroes - __ Add_aW(dst, dst, src); // dst = abs(0) + abs(src) - break; - case DataType::Type::kInt64: - DCHECK_EQ(2u, instruction->GetVectorLength()); - __ FillW(dst, ZERO); // all zeroes - __ Add_aD(dst, dst, src); // dst = abs(0) + abs(src) - break; - case DataType::Type::kFloat32: - DCHECK_EQ(4u, instruction->GetVectorLength()); - __ LdiW(dst, -1); // all ones - __ SrliW(dst, dst, 1); - __ AndV(dst, dst, src); - break; - case DataType::Type::kFloat64: - DCHECK_EQ(2u, instruction->GetVectorLength()); - __ LdiD(dst, -1); // all ones - __ SrliD(dst, dst, 1); - __ AndV(dst, dst, src); - break; - default: - LOG(FATAL) << "Unsupported SIMD type: " << instruction->GetPackedType(); - UNREACHABLE(); - } -} - -void LocationsBuilderMIPS::VisitVecNot(HVecNot* instruction) { - CreateVecUnOpLocations(GetGraph()->GetAllocator(), instruction); -} - -void InstructionCodeGeneratorMIPS::VisitVecNot(HVecNot* instruction) { - LocationSummary* locations = instruction->GetLocations(); - VectorRegister src = VectorRegisterFrom(locations->InAt(0)); - VectorRegister dst = VectorRegisterFrom(locations->Out()); - switch (instruction->GetPackedType()) { - case DataType::Type::kBool: // special case boolean-not - DCHECK_EQ(16u, instruction->GetVectorLength()); - __ LdiB(dst, 1); - __ XorV(dst, dst, src); - break; - case DataType::Type::kUint8: - case DataType::Type::kInt8: - case DataType::Type::kUint16: - case DataType::Type::kInt16: - case DataType::Type::kInt32: - case DataType::Type::kInt64: - case DataType::Type::kFloat32: - case DataType::Type::kFloat64: - DCHECK_LE(2u, instruction->GetVectorLength()); - DCHECK_LE(instruction->GetVectorLength(), 16u); - __ NorV(dst, src, src); // lanes do not matter - break; - default: - LOG(FATAL) << "Unsupported SIMD type: " << instruction->GetPackedType(); - UNREACHABLE(); - } -} - -// Helper to set up locations for vector binary operations. -static void CreateVecBinOpLocations(ArenaAllocator* allocator, HVecBinaryOperation* instruction) { - LocationSummary* locations = new (allocator) LocationSummary(instruction); - switch (instruction->GetPackedType()) { - case DataType::Type::kBool: - case DataType::Type::kUint8: - case DataType::Type::kInt8: - case DataType::Type::kUint16: - case DataType::Type::kInt16: - case DataType::Type::kInt32: - case DataType::Type::kInt64: - case DataType::Type::kFloat32: - case DataType::Type::kFloat64: - locations->SetInAt(0, Location::RequiresFpuRegister()); - locations->SetInAt(1, Location::RequiresFpuRegister()); - locations->SetOut(Location::RequiresFpuRegister(), Location::kNoOutputOverlap); - break; - default: - LOG(FATAL) << "Unsupported SIMD type: " << instruction->GetPackedType(); - UNREACHABLE(); - } -} - -void LocationsBuilderMIPS::VisitVecAdd(HVecAdd* instruction) { - CreateVecBinOpLocations(GetGraph()->GetAllocator(), instruction); -} - -void InstructionCodeGeneratorMIPS::VisitVecAdd(HVecAdd* instruction) { - LocationSummary* locations = instruction->GetLocations(); - VectorRegister lhs = VectorRegisterFrom(locations->InAt(0)); - VectorRegister rhs = VectorRegisterFrom(locations->InAt(1)); - VectorRegister dst = VectorRegisterFrom(locations->Out()); - switch (instruction->GetPackedType()) { - case DataType::Type::kUint8: - case DataType::Type::kInt8: - DCHECK_EQ(16u, instruction->GetVectorLength()); - __ AddvB(dst, lhs, rhs); - break; - case DataType::Type::kUint16: - case DataType::Type::kInt16: - DCHECK_EQ(8u, instruction->GetVectorLength()); - __ AddvH(dst, lhs, rhs); - break; - case DataType::Type::kInt32: - DCHECK_EQ(4u, instruction->GetVectorLength()); - __ AddvW(dst, lhs, rhs); - break; - case DataType::Type::kInt64: - DCHECK_EQ(2u, instruction->GetVectorLength()); - __ AddvD(dst, lhs, rhs); - break; - case DataType::Type::kFloat32: - DCHECK_EQ(4u, instruction->GetVectorLength()); - __ FaddW(dst, lhs, rhs); - break; - case DataType::Type::kFloat64: - DCHECK_EQ(2u, instruction->GetVectorLength()); - __ FaddD(dst, lhs, rhs); - break; - default: - LOG(FATAL) << "Unsupported SIMD type: " << instruction->GetPackedType(); - UNREACHABLE(); - } -} - -void LocationsBuilderMIPS::VisitVecSaturationAdd(HVecSaturationAdd* instruction) { - CreateVecBinOpLocations(GetGraph()->GetAllocator(), instruction); -} - -void InstructionCodeGeneratorMIPS::VisitVecSaturationAdd(HVecSaturationAdd* instruction) { - LOG(FATAL) << "Unsupported SIMD " << instruction->GetId(); -} - -void LocationsBuilderMIPS::VisitVecHalvingAdd(HVecHalvingAdd* instruction) { - CreateVecBinOpLocations(GetGraph()->GetAllocator(), instruction); -} - -void InstructionCodeGeneratorMIPS::VisitVecHalvingAdd(HVecHalvingAdd* instruction) { - LocationSummary* locations = instruction->GetLocations(); - VectorRegister lhs = VectorRegisterFrom(locations->InAt(0)); - VectorRegister rhs = VectorRegisterFrom(locations->InAt(1)); - VectorRegister dst = VectorRegisterFrom(locations->Out()); - switch (instruction->GetPackedType()) { - case DataType::Type::kUint8: - DCHECK_EQ(16u, instruction->GetVectorLength()); - instruction->IsRounded() - ? __ Aver_uB(dst, lhs, rhs) - : __ Ave_uB(dst, lhs, rhs); - break; - case DataType::Type::kInt8: - DCHECK_EQ(16u, instruction->GetVectorLength()); - instruction->IsRounded() - ? __ Aver_sB(dst, lhs, rhs) - : __ Ave_sB(dst, lhs, rhs); - break; - case DataType::Type::kUint16: - DCHECK_EQ(8u, instruction->GetVectorLength()); - instruction->IsRounded() - ? __ Aver_uH(dst, lhs, rhs) - : __ Ave_uH(dst, lhs, rhs); - break; - case DataType::Type::kInt16: - DCHECK_EQ(8u, instruction->GetVectorLength()); - instruction->IsRounded() - ? __ Aver_sH(dst, lhs, rhs) - : __ Ave_sH(dst, lhs, rhs); - break; - default: - LOG(FATAL) << "Unsupported SIMD type: " << instruction->GetPackedType(); - UNREACHABLE(); - } -} - -void LocationsBuilderMIPS::VisitVecSub(HVecSub* instruction) { - CreateVecBinOpLocations(GetGraph()->GetAllocator(), instruction); -} - -void InstructionCodeGeneratorMIPS::VisitVecSub(HVecSub* instruction) { - LocationSummary* locations = instruction->GetLocations(); - VectorRegister lhs = VectorRegisterFrom(locations->InAt(0)); - VectorRegister rhs = VectorRegisterFrom(locations->InAt(1)); - VectorRegister dst = VectorRegisterFrom(locations->Out()); - switch (instruction->GetPackedType()) { - case DataType::Type::kUint8: - case DataType::Type::kInt8: - DCHECK_EQ(16u, instruction->GetVectorLength()); - __ SubvB(dst, lhs, rhs); - break; - case DataType::Type::kUint16: - case DataType::Type::kInt16: - DCHECK_EQ(8u, instruction->GetVectorLength()); - __ SubvH(dst, lhs, rhs); - break; - case DataType::Type::kInt32: - DCHECK_EQ(4u, instruction->GetVectorLength()); - __ SubvW(dst, lhs, rhs); - break; - case DataType::Type::kInt64: - DCHECK_EQ(2u, instruction->GetVectorLength()); - __ SubvD(dst, lhs, rhs); - break; - case DataType::Type::kFloat32: - DCHECK_EQ(4u, instruction->GetVectorLength()); - __ FsubW(dst, lhs, rhs); - break; - case DataType::Type::kFloat64: - DCHECK_EQ(2u, instruction->GetVectorLength()); - __ FsubD(dst, lhs, rhs); - break; - default: - LOG(FATAL) << "Unsupported SIMD type: " << instruction->GetPackedType(); - UNREACHABLE(); - } -} - -void LocationsBuilderMIPS::VisitVecSaturationSub(HVecSaturationSub* instruction) { - CreateVecBinOpLocations(GetGraph()->GetAllocator(), instruction); -} - -void InstructionCodeGeneratorMIPS::VisitVecSaturationSub(HVecSaturationSub* instruction) { - LOG(FATAL) << "Unsupported SIMD " << instruction->GetId(); -} - -void LocationsBuilderMIPS::VisitVecMul(HVecMul* instruction) { - CreateVecBinOpLocations(GetGraph()->GetAllocator(), instruction); -} - -void InstructionCodeGeneratorMIPS::VisitVecMul(HVecMul* instruction) { - LocationSummary* locations = instruction->GetLocations(); - VectorRegister lhs = VectorRegisterFrom(locations->InAt(0)); - VectorRegister rhs = VectorRegisterFrom(locations->InAt(1)); - VectorRegister dst = VectorRegisterFrom(locations->Out()); - switch (instruction->GetPackedType()) { - case DataType::Type::kUint8: - case DataType::Type::kInt8: - DCHECK_EQ(16u, instruction->GetVectorLength()); - __ MulvB(dst, lhs, rhs); - break; - case DataType::Type::kUint16: - case DataType::Type::kInt16: - DCHECK_EQ(8u, instruction->GetVectorLength()); - __ MulvH(dst, lhs, rhs); - break; - case DataType::Type::kInt32: - DCHECK_EQ(4u, instruction->GetVectorLength()); - __ MulvW(dst, lhs, rhs); - break; - case DataType::Type::kInt64: - DCHECK_EQ(2u, instruction->GetVectorLength()); - __ MulvD(dst, lhs, rhs); - break; - case DataType::Type::kFloat32: - DCHECK_EQ(4u, instruction->GetVectorLength()); - __ FmulW(dst, lhs, rhs); - break; - case DataType::Type::kFloat64: - DCHECK_EQ(2u, instruction->GetVectorLength()); - __ FmulD(dst, lhs, rhs); - break; - default: - LOG(FATAL) << "Unsupported SIMD type: " << instruction->GetPackedType(); - UNREACHABLE(); - } -} - -void LocationsBuilderMIPS::VisitVecDiv(HVecDiv* instruction) { - CreateVecBinOpLocations(GetGraph()->GetAllocator(), instruction); -} - -void InstructionCodeGeneratorMIPS::VisitVecDiv(HVecDiv* instruction) { - LocationSummary* locations = instruction->GetLocations(); - VectorRegister lhs = VectorRegisterFrom(locations->InAt(0)); - VectorRegister rhs = VectorRegisterFrom(locations->InAt(1)); - VectorRegister dst = VectorRegisterFrom(locations->Out()); - switch (instruction->GetPackedType()) { - case DataType::Type::kFloat32: - DCHECK_EQ(4u, instruction->GetVectorLength()); - __ FdivW(dst, lhs, rhs); - break; - case DataType::Type::kFloat64: - DCHECK_EQ(2u, instruction->GetVectorLength()); - __ FdivD(dst, lhs, rhs); - break; - default: - LOG(FATAL) << "Unsupported SIMD type: " << instruction->GetPackedType(); - UNREACHABLE(); - } -} - -void LocationsBuilderMIPS::VisitVecMin(HVecMin* instruction) { - CreateVecBinOpLocations(GetGraph()->GetAllocator(), instruction); -} - -void InstructionCodeGeneratorMIPS::VisitVecMin(HVecMin* instruction) { - LocationSummary* locations = instruction->GetLocations(); - VectorRegister lhs = VectorRegisterFrom(locations->InAt(0)); - VectorRegister rhs = VectorRegisterFrom(locations->InAt(1)); - VectorRegister dst = VectorRegisterFrom(locations->Out()); - switch (instruction->GetPackedType()) { - case DataType::Type::kUint8: - DCHECK_EQ(16u, instruction->GetVectorLength()); - __ Min_uB(dst, lhs, rhs); - break; - case DataType::Type::kInt8: - DCHECK_EQ(16u, instruction->GetVectorLength()); - __ Min_sB(dst, lhs, rhs); - break; - case DataType::Type::kUint16: - DCHECK_EQ(8u, instruction->GetVectorLength()); - __ Min_uH(dst, lhs, rhs); - break; - case DataType::Type::kInt16: - DCHECK_EQ(8u, instruction->GetVectorLength()); - __ Min_sH(dst, lhs, rhs); - break; - case DataType::Type::kUint32: - DCHECK_EQ(4u, instruction->GetVectorLength()); - __ Min_uW(dst, lhs, rhs); - break; - case DataType::Type::kInt32: - DCHECK_EQ(4u, instruction->GetVectorLength()); - __ Min_sW(dst, lhs, rhs); - break; - case DataType::Type::kUint64: - DCHECK_EQ(2u, instruction->GetVectorLength()); - __ Min_uD(dst, lhs, rhs); - break; - case DataType::Type::kInt64: - DCHECK_EQ(2u, instruction->GetVectorLength()); - __ Min_sD(dst, lhs, rhs); - break; - // When one of arguments is NaN, fmin.df returns other argument, but Java expects a NaN value. - // TODO: Fix min(x, NaN) cases for float and double. - case DataType::Type::kFloat32: - DCHECK_EQ(4u, instruction->GetVectorLength()); - __ FminW(dst, lhs, rhs); - break; - case DataType::Type::kFloat64: - DCHECK_EQ(2u, instruction->GetVectorLength()); - __ FminD(dst, lhs, rhs); - break; - default: - LOG(FATAL) << "Unsupported SIMD type: " << instruction->GetPackedType(); - UNREACHABLE(); - } -} - -void LocationsBuilderMIPS::VisitVecMax(HVecMax* instruction) { - CreateVecBinOpLocations(GetGraph()->GetAllocator(), instruction); -} - -void InstructionCodeGeneratorMIPS::VisitVecMax(HVecMax* instruction) { - LocationSummary* locations = instruction->GetLocations(); - VectorRegister lhs = VectorRegisterFrom(locations->InAt(0)); - VectorRegister rhs = VectorRegisterFrom(locations->InAt(1)); - VectorRegister dst = VectorRegisterFrom(locations->Out()); - switch (instruction->GetPackedType()) { - case DataType::Type::kUint8: - DCHECK_EQ(16u, instruction->GetVectorLength()); - __ Max_uB(dst, lhs, rhs); - break; - case DataType::Type::kInt8: - DCHECK_EQ(16u, instruction->GetVectorLength()); - __ Max_sB(dst, lhs, rhs); - break; - case DataType::Type::kUint16: - DCHECK_EQ(8u, instruction->GetVectorLength()); - __ Max_uH(dst, lhs, rhs); - break; - case DataType::Type::kInt16: - DCHECK_EQ(8u, instruction->GetVectorLength()); - __ Max_sH(dst, lhs, rhs); - break; - case DataType::Type::kUint32: - DCHECK_EQ(4u, instruction->GetVectorLength()); - __ Max_uW(dst, lhs, rhs); - break; - case DataType::Type::kInt32: - DCHECK_EQ(4u, instruction->GetVectorLength()); - __ Max_sW(dst, lhs, rhs); - break; - case DataType::Type::kUint64: - DCHECK_EQ(2u, instruction->GetVectorLength()); - __ Max_uD(dst, lhs, rhs); - break; - case DataType::Type::kInt64: - DCHECK_EQ(2u, instruction->GetVectorLength()); - __ Max_sD(dst, lhs, rhs); - break; - // When one of arguments is NaN, fmax.df returns other argument, but Java expects a NaN value. - // TODO: Fix max(x, NaN) cases for float and double. - case DataType::Type::kFloat32: - DCHECK_EQ(4u, instruction->GetVectorLength()); - __ FmaxW(dst, lhs, rhs); - break; - case DataType::Type::kFloat64: - DCHECK_EQ(2u, instruction->GetVectorLength()); - __ FmaxD(dst, lhs, rhs); - break; - default: - LOG(FATAL) << "Unsupported SIMD type: " << instruction->GetPackedType(); - UNREACHABLE(); - } -} - -void LocationsBuilderMIPS::VisitVecAnd(HVecAnd* instruction) { - CreateVecBinOpLocations(GetGraph()->GetAllocator(), instruction); -} - -void InstructionCodeGeneratorMIPS::VisitVecAnd(HVecAnd* instruction) { - LocationSummary* locations = instruction->GetLocations(); - VectorRegister lhs = VectorRegisterFrom(locations->InAt(0)); - VectorRegister rhs = VectorRegisterFrom(locations->InAt(1)); - VectorRegister dst = VectorRegisterFrom(locations->Out()); - switch (instruction->GetPackedType()) { - case DataType::Type::kBool: - case DataType::Type::kUint8: - case DataType::Type::kInt8: - case DataType::Type::kUint16: - case DataType::Type::kInt16: - case DataType::Type::kInt32: - case DataType::Type::kInt64: - case DataType::Type::kFloat32: - case DataType::Type::kFloat64: - DCHECK_LE(2u, instruction->GetVectorLength()); - DCHECK_LE(instruction->GetVectorLength(), 16u); - __ AndV(dst, lhs, rhs); // lanes do not matter - break; - default: - LOG(FATAL) << "Unsupported SIMD type: " << instruction->GetPackedType(); - UNREACHABLE(); - } -} - -void LocationsBuilderMIPS::VisitVecAndNot(HVecAndNot* instruction) { - CreateVecBinOpLocations(GetGraph()->GetAllocator(), instruction); -} - -void InstructionCodeGeneratorMIPS::VisitVecAndNot(HVecAndNot* instruction) { - LOG(FATAL) << "No SIMD for " << instruction->GetId(); -} - -void LocationsBuilderMIPS::VisitVecOr(HVecOr* instruction) { - CreateVecBinOpLocations(GetGraph()->GetAllocator(), instruction); -} - -void InstructionCodeGeneratorMIPS::VisitVecOr(HVecOr* instruction) { - LocationSummary* locations = instruction->GetLocations(); - VectorRegister lhs = VectorRegisterFrom(locations->InAt(0)); - VectorRegister rhs = VectorRegisterFrom(locations->InAt(1)); - VectorRegister dst = VectorRegisterFrom(locations->Out()); - switch (instruction->GetPackedType()) { - case DataType::Type::kBool: - case DataType::Type::kUint8: - case DataType::Type::kInt8: - case DataType::Type::kUint16: - case DataType::Type::kInt16: - case DataType::Type::kInt32: - case DataType::Type::kInt64: - case DataType::Type::kFloat32: - case DataType::Type::kFloat64: - DCHECK_LE(2u, instruction->GetVectorLength()); - DCHECK_LE(instruction->GetVectorLength(), 16u); - __ OrV(dst, lhs, rhs); // lanes do not matter - break; - default: - LOG(FATAL) << "Unsupported SIMD type: " << instruction->GetPackedType(); - UNREACHABLE(); - } -} - -void LocationsBuilderMIPS::VisitVecXor(HVecXor* instruction) { - CreateVecBinOpLocations(GetGraph()->GetAllocator(), instruction); -} - -void InstructionCodeGeneratorMIPS::VisitVecXor(HVecXor* instruction) { - LocationSummary* locations = instruction->GetLocations(); - VectorRegister lhs = VectorRegisterFrom(locations->InAt(0)); - VectorRegister rhs = VectorRegisterFrom(locations->InAt(1)); - VectorRegister dst = VectorRegisterFrom(locations->Out()); - switch (instruction->GetPackedType()) { - case DataType::Type::kBool: - case DataType::Type::kUint8: - case DataType::Type::kInt8: - case DataType::Type::kUint16: - case DataType::Type::kInt16: - case DataType::Type::kInt32: - case DataType::Type::kInt64: - case DataType::Type::kFloat32: - case DataType::Type::kFloat64: - DCHECK_LE(2u, instruction->GetVectorLength()); - DCHECK_LE(instruction->GetVectorLength(), 16u); - __ XorV(dst, lhs, rhs); // lanes do not matter - break; - default: - LOG(FATAL) << "Unsupported SIMD type: " << instruction->GetPackedType(); - UNREACHABLE(); - } -} - -// Helper to set up locations for vector shift operations. -static void CreateVecShiftLocations(ArenaAllocator* allocator, HVecBinaryOperation* instruction) { - LocationSummary* locations = new (allocator) LocationSummary(instruction); - switch (instruction->GetPackedType()) { - case DataType::Type::kUint8: - case DataType::Type::kInt8: - case DataType::Type::kUint16: - case DataType::Type::kInt16: - case DataType::Type::kInt32: - case DataType::Type::kInt64: - locations->SetInAt(0, Location::RequiresFpuRegister()); - locations->SetInAt(1, Location::ConstantLocation(instruction->InputAt(1)->AsConstant())); - locations->SetOut(Location::RequiresFpuRegister(), Location::kNoOutputOverlap); - break; - default: - LOG(FATAL) << "Unsupported SIMD type: " << instruction->GetPackedType(); - UNREACHABLE(); - } -} - -void LocationsBuilderMIPS::VisitVecShl(HVecShl* instruction) { - CreateVecShiftLocations(GetGraph()->GetAllocator(), instruction); -} - -void InstructionCodeGeneratorMIPS::VisitVecShl(HVecShl* instruction) { - LocationSummary* locations = instruction->GetLocations(); - VectorRegister lhs = VectorRegisterFrom(locations->InAt(0)); - VectorRegister dst = VectorRegisterFrom(locations->Out()); - int32_t value = locations->InAt(1).GetConstant()->AsIntConstant()->GetValue(); - switch (instruction->GetPackedType()) { - case DataType::Type::kUint8: - case DataType::Type::kInt8: - DCHECK_EQ(16u, instruction->GetVectorLength()); - __ SlliB(dst, lhs, value); - break; - case DataType::Type::kUint16: - case DataType::Type::kInt16: - DCHECK_EQ(8u, instruction->GetVectorLength()); - __ SlliH(dst, lhs, value); - break; - case DataType::Type::kInt32: - DCHECK_EQ(4u, instruction->GetVectorLength()); - __ SlliW(dst, lhs, value); - break; - case DataType::Type::kInt64: - DCHECK_EQ(2u, instruction->GetVectorLength()); - __ SlliD(dst, lhs, value); - break; - default: - LOG(FATAL) << "Unsupported SIMD type: " << instruction->GetPackedType(); - UNREACHABLE(); - } -} - -void LocationsBuilderMIPS::VisitVecShr(HVecShr* instruction) { - CreateVecShiftLocations(GetGraph()->GetAllocator(), instruction); -} - -void InstructionCodeGeneratorMIPS::VisitVecShr(HVecShr* instruction) { - LocationSummary* locations = instruction->GetLocations(); - VectorRegister lhs = VectorRegisterFrom(locations->InAt(0)); - VectorRegister dst = VectorRegisterFrom(locations->Out()); - int32_t value = locations->InAt(1).GetConstant()->AsIntConstant()->GetValue(); - switch (instruction->GetPackedType()) { - case DataType::Type::kUint8: - case DataType::Type::kInt8: - DCHECK_EQ(16u, instruction->GetVectorLength()); - __ SraiB(dst, lhs, value); - break; - case DataType::Type::kUint16: - case DataType::Type::kInt16: - DCHECK_EQ(8u, instruction->GetVectorLength()); - __ SraiH(dst, lhs, value); - break; - case DataType::Type::kInt32: - DCHECK_EQ(4u, instruction->GetVectorLength()); - __ SraiW(dst, lhs, value); - break; - case DataType::Type::kInt64: - DCHECK_EQ(2u, instruction->GetVectorLength()); - __ SraiD(dst, lhs, value); - break; - default: - LOG(FATAL) << "Unsupported SIMD type: " << instruction->GetPackedType(); - UNREACHABLE(); - } -} - -void LocationsBuilderMIPS::VisitVecUShr(HVecUShr* instruction) { - CreateVecShiftLocations(GetGraph()->GetAllocator(), instruction); -} - -void InstructionCodeGeneratorMIPS::VisitVecUShr(HVecUShr* instruction) { - LocationSummary* locations = instruction->GetLocations(); - VectorRegister lhs = VectorRegisterFrom(locations->InAt(0)); - VectorRegister dst = VectorRegisterFrom(locations->Out()); - int32_t value = locations->InAt(1).GetConstant()->AsIntConstant()->GetValue(); - switch (instruction->GetPackedType()) { - case DataType::Type::kUint8: - case DataType::Type::kInt8: - DCHECK_EQ(16u, instruction->GetVectorLength()); - __ SrliB(dst, lhs, value); - break; - case DataType::Type::kUint16: - case DataType::Type::kInt16: - DCHECK_EQ(8u, instruction->GetVectorLength()); - __ SrliH(dst, lhs, value); - break; - case DataType::Type::kInt32: - DCHECK_EQ(4u, instruction->GetVectorLength()); - __ SrliW(dst, lhs, value); - break; - case DataType::Type::kInt64: - DCHECK_EQ(2u, instruction->GetVectorLength()); - __ SrliD(dst, lhs, value); - break; - default: - LOG(FATAL) << "Unsupported SIMD type: " << instruction->GetPackedType(); - UNREACHABLE(); - } -} - -void LocationsBuilderMIPS::VisitVecSetScalars(HVecSetScalars* instruction) { - LocationSummary* locations = new (GetGraph()->GetAllocator()) LocationSummary(instruction); - - DCHECK_EQ(1u, instruction->InputCount()); // only one input currently implemented - - HInstruction* input = instruction->InputAt(0); - bool is_zero = IsZeroBitPattern(input); - - switch (instruction->GetPackedType()) { - case DataType::Type::kBool: - case DataType::Type::kUint8: - case DataType::Type::kInt8: - case DataType::Type::kUint16: - case DataType::Type::kInt16: - case DataType::Type::kInt32: - case DataType::Type::kInt64: - locations->SetInAt(0, is_zero ? Location::ConstantLocation(input->AsConstant()) - : Location::RequiresRegister()); - locations->SetOut(Location::RequiresFpuRegister()); - break; - case DataType::Type::kFloat32: - case DataType::Type::kFloat64: - locations->SetInAt(0, is_zero ? Location::ConstantLocation(input->AsConstant()) - : Location::RequiresFpuRegister()); - locations->SetOut(Location::RequiresFpuRegister()); - break; - default: - LOG(FATAL) << "Unsupported SIMD type: " << instruction->GetPackedType(); - UNREACHABLE(); - } -} - -void InstructionCodeGeneratorMIPS::VisitVecSetScalars(HVecSetScalars* instruction) { - LocationSummary* locations = instruction->GetLocations(); - VectorRegister dst = VectorRegisterFrom(locations->Out()); - - DCHECK_EQ(1u, instruction->InputCount()); // only one input currently implemented - - // Zero out all other elements first. - __ FillW(dst, ZERO); - - // Shorthand for any type of zero. - if (IsZeroBitPattern(instruction->InputAt(0))) { - return; - } - - // Set required elements. - switch (instruction->GetPackedType()) { - case DataType::Type::kBool: - case DataType::Type::kUint8: - case DataType::Type::kInt8: - DCHECK_EQ(16u, instruction->GetVectorLength()); - __ InsertB(dst, locations->InAt(0).AsRegister<Register>(), 0); - break; - case DataType::Type::kUint16: - case DataType::Type::kInt16: - DCHECK_EQ(8u, instruction->GetVectorLength()); - __ InsertH(dst, locations->InAt(0).AsRegister<Register>(), 0); - break; - case DataType::Type::kInt32: - DCHECK_EQ(4u, instruction->GetVectorLength()); - __ InsertW(dst, locations->InAt(0).AsRegister<Register>(), 0); - break; - case DataType::Type::kInt64: - DCHECK_EQ(2u, instruction->GetVectorLength()); - __ InsertW(dst, locations->InAt(0).AsRegisterPairLow<Register>(), 0); - __ InsertW(dst, locations->InAt(0).AsRegisterPairHigh<Register>(), 1); - break; - default: - LOG(FATAL) << "Unsupported SIMD type: " << instruction->GetPackedType(); - UNREACHABLE(); - } -} - -// Helper to set up locations for vector accumulations. -static void CreateVecAccumLocations(ArenaAllocator* allocator, HVecOperation* instruction) { - LocationSummary* locations = new (allocator) LocationSummary(instruction); - switch (instruction->GetPackedType()) { - case DataType::Type::kUint8: - case DataType::Type::kInt8: - case DataType::Type::kUint16: - case DataType::Type::kInt16: - case DataType::Type::kInt32: - case DataType::Type::kInt64: - locations->SetInAt(0, Location::RequiresFpuRegister()); - locations->SetInAt(1, Location::RequiresFpuRegister()); - locations->SetInAt(2, Location::RequiresFpuRegister()); - locations->SetOut(Location::SameAsFirstInput()); - break; - default: - LOG(FATAL) << "Unsupported SIMD type: " << instruction->GetPackedType(); - UNREACHABLE(); - } -} - -void LocationsBuilderMIPS::VisitVecMultiplyAccumulate(HVecMultiplyAccumulate* instruction) { - CreateVecAccumLocations(GetGraph()->GetAllocator(), instruction); -} - -void InstructionCodeGeneratorMIPS::VisitVecMultiplyAccumulate(HVecMultiplyAccumulate* instruction) { - LocationSummary* locations = instruction->GetLocations(); - VectorRegister acc = VectorRegisterFrom(locations->InAt(0)); - VectorRegister left = VectorRegisterFrom(locations->InAt(1)); - VectorRegister right = VectorRegisterFrom(locations->InAt(2)); - switch (instruction->GetPackedType()) { - case DataType::Type::kUint8: - case DataType::Type::kInt8: - DCHECK_EQ(16u, instruction->GetVectorLength()); - if (instruction->GetOpKind() == HInstruction::kAdd) { - __ MaddvB(acc, left, right); - } else { - __ MsubvB(acc, left, right); - } - break; - case DataType::Type::kUint16: - case DataType::Type::kInt16: - DCHECK_EQ(8u, instruction->GetVectorLength()); - if (instruction->GetOpKind() == HInstruction::kAdd) { - __ MaddvH(acc, left, right); - } else { - __ MsubvH(acc, left, right); - } - break; - case DataType::Type::kInt32: - DCHECK_EQ(4u, instruction->GetVectorLength()); - if (instruction->GetOpKind() == HInstruction::kAdd) { - __ MaddvW(acc, left, right); - } else { - __ MsubvW(acc, left, right); - } - break; - case DataType::Type::kInt64: - DCHECK_EQ(2u, instruction->GetVectorLength()); - if (instruction->GetOpKind() == HInstruction::kAdd) { - __ MaddvD(acc, left, right); - } else { - __ MsubvD(acc, left, right); - } - break; - default: - LOG(FATAL) << "Unsupported SIMD type: " << instruction->GetPackedType(); - UNREACHABLE(); - } -} - -void LocationsBuilderMIPS::VisitVecSADAccumulate(HVecSADAccumulate* instruction) { - CreateVecAccumLocations(GetGraph()->GetAllocator(), instruction); - LocationSummary* locations = instruction->GetLocations(); - // All conversions require at least one temporary register. - locations->AddTemp(Location::RequiresFpuRegister()); - // Some conversions require a second temporary register. - HVecOperation* a = instruction->InputAt(1)->AsVecOperation(); - HVecOperation* b = instruction->InputAt(2)->AsVecOperation(); - DCHECK_EQ(HVecOperation::ToSignedType(a->GetPackedType()), - HVecOperation::ToSignedType(b->GetPackedType())); - switch (a->GetPackedType()) { - case DataType::Type::kInt32: - if (instruction->GetPackedType() == DataType::Type::kInt32) { - break; - } - FALLTHROUGH_INTENDED; - case DataType::Type::kUint8: - case DataType::Type::kInt8: - case DataType::Type::kUint16: - case DataType::Type::kInt16: - locations->AddTemp(Location::RequiresFpuRegister()); - break; - default: - break; - } -} - -void InstructionCodeGeneratorMIPS::VisitVecSADAccumulate(HVecSADAccumulate* instruction) { - LocationSummary* locations = instruction->GetLocations(); - VectorRegister acc = VectorRegisterFrom(locations->InAt(0)); - VectorRegister left = VectorRegisterFrom(locations->InAt(1)); - VectorRegister right = VectorRegisterFrom(locations->InAt(2)); - VectorRegister tmp = static_cast<VectorRegister>(FTMP); - VectorRegister tmp1 = VectorRegisterFrom(locations->GetTemp(0)); - - DCHECK(locations->InAt(0).Equals(locations->Out())); - - // Handle all feasible acc_T += sad(a_S, b_S) type combinations (T x S). - HVecOperation* a = instruction->InputAt(1)->AsVecOperation(); - HVecOperation* b = instruction->InputAt(2)->AsVecOperation(); - DCHECK_EQ(HVecOperation::ToSignedType(a->GetPackedType()), - HVecOperation::ToSignedType(b->GetPackedType())); - switch (a->GetPackedType()) { - case DataType::Type::kUint8: - case DataType::Type::kInt8: - DCHECK_EQ(16u, a->GetVectorLength()); - switch (instruction->GetPackedType()) { - case DataType::Type::kUint16: - case DataType::Type::kInt16: { - DCHECK_EQ(8u, instruction->GetVectorLength()); - VectorRegister tmp2 = VectorRegisterFrom(locations->GetTemp(1)); - __ FillB(tmp, ZERO); - __ Hadd_sH(tmp1, left, tmp); - __ Hadd_sH(tmp2, right, tmp); - __ Asub_sH(tmp1, tmp1, tmp2); - __ AddvH(acc, acc, tmp1); - __ Hadd_sH(tmp1, tmp, left); - __ Hadd_sH(tmp2, tmp, right); - __ Asub_sH(tmp1, tmp1, tmp2); - __ AddvH(acc, acc, tmp1); - break; - } - case DataType::Type::kInt32: { - DCHECK_EQ(4u, instruction->GetVectorLength()); - VectorRegister tmp2 = VectorRegisterFrom(locations->GetTemp(1)); - __ FillB(tmp, ZERO); - __ Hadd_sH(tmp1, left, tmp); - __ Hadd_sH(tmp2, right, tmp); - __ Asub_sH(tmp1, tmp1, tmp2); - __ Hadd_sW(tmp1, tmp1, tmp1); - __ AddvW(acc, acc, tmp1); - __ Hadd_sH(tmp1, tmp, left); - __ Hadd_sH(tmp2, tmp, right); - __ Asub_sH(tmp1, tmp1, tmp2); - __ Hadd_sW(tmp1, tmp1, tmp1); - __ AddvW(acc, acc, tmp1); - break; - } - case DataType::Type::kInt64: { - DCHECK_EQ(2u, instruction->GetVectorLength()); - VectorRegister tmp2 = VectorRegisterFrom(locations->GetTemp(1)); - __ FillB(tmp, ZERO); - __ Hadd_sH(tmp1, left, tmp); - __ Hadd_sH(tmp2, right, tmp); - __ Asub_sH(tmp1, tmp1, tmp2); - __ Hadd_sW(tmp1, tmp1, tmp1); - __ Hadd_sD(tmp1, tmp1, tmp1); - __ AddvD(acc, acc, tmp1); - __ Hadd_sH(tmp1, tmp, left); - __ Hadd_sH(tmp2, tmp, right); - __ Asub_sH(tmp1, tmp1, tmp2); - __ Hadd_sW(tmp1, tmp1, tmp1); - __ Hadd_sD(tmp1, tmp1, tmp1); - __ AddvD(acc, acc, tmp1); - break; - } - default: - LOG(FATAL) << "Unsupported SIMD type: " << instruction->GetPackedType(); - UNREACHABLE(); - } - break; - case DataType::Type::kUint16: - case DataType::Type::kInt16: - DCHECK_EQ(8u, a->GetVectorLength()); - switch (instruction->GetPackedType()) { - case DataType::Type::kInt32: { - DCHECK_EQ(4u, instruction->GetVectorLength()); - VectorRegister tmp2 = VectorRegisterFrom(locations->GetTemp(1)); - __ FillH(tmp, ZERO); - __ Hadd_sW(tmp1, left, tmp); - __ Hadd_sW(tmp2, right, tmp); - __ Asub_sW(tmp1, tmp1, tmp2); - __ AddvW(acc, acc, tmp1); - __ Hadd_sW(tmp1, tmp, left); - __ Hadd_sW(tmp2, tmp, right); - __ Asub_sW(tmp1, tmp1, tmp2); - __ AddvW(acc, acc, tmp1); - break; - } - case DataType::Type::kInt64: { - DCHECK_EQ(2u, instruction->GetVectorLength()); - VectorRegister tmp2 = VectorRegisterFrom(locations->GetTemp(1)); - __ FillH(tmp, ZERO); - __ Hadd_sW(tmp1, left, tmp); - __ Hadd_sW(tmp2, right, tmp); - __ Asub_sW(tmp1, tmp1, tmp2); - __ Hadd_sD(tmp1, tmp1, tmp1); - __ AddvD(acc, acc, tmp1); - __ Hadd_sW(tmp1, tmp, left); - __ Hadd_sW(tmp2, tmp, right); - __ Asub_sW(tmp1, tmp1, tmp2); - __ Hadd_sD(tmp1, tmp1, tmp1); - __ AddvD(acc, acc, tmp1); - break; - } - default: - LOG(FATAL) << "Unsupported SIMD type: " << instruction->GetPackedType(); - UNREACHABLE(); - } - break; - case DataType::Type::kInt32: - DCHECK_EQ(4u, a->GetVectorLength()); - switch (instruction->GetPackedType()) { - case DataType::Type::kInt32: { - DCHECK_EQ(4u, instruction->GetVectorLength()); - __ FillW(tmp, ZERO); - __ SubvW(tmp1, left, right); - __ Add_aW(tmp1, tmp1, tmp); - __ AddvW(acc, acc, tmp1); - break; - } - case DataType::Type::kInt64: { - DCHECK_EQ(2u, instruction->GetVectorLength()); - VectorRegister tmp2 = VectorRegisterFrom(locations->GetTemp(1)); - __ FillW(tmp, ZERO); - __ Hadd_sD(tmp1, left, tmp); - __ Hadd_sD(tmp2, right, tmp); - __ Asub_sD(tmp1, tmp1, tmp2); - __ AddvD(acc, acc, tmp1); - __ Hadd_sD(tmp1, tmp, left); - __ Hadd_sD(tmp2, tmp, right); - __ Asub_sD(tmp1, tmp1, tmp2); - __ AddvD(acc, acc, tmp1); - break; - } - default: - LOG(FATAL) << "Unsupported SIMD type: " << instruction->GetPackedType(); - UNREACHABLE(); - } - break; - case DataType::Type::kInt64: { - DCHECK_EQ(2u, a->GetVectorLength()); - switch (instruction->GetPackedType()) { - case DataType::Type::kInt64: { - DCHECK_EQ(2u, instruction->GetVectorLength()); - __ FillW(tmp, ZERO); - __ SubvD(tmp1, left, right); - __ Add_aD(tmp1, tmp1, tmp); - __ AddvD(acc, acc, tmp1); - break; - } - default: - LOG(FATAL) << "Unsupported SIMD type: " << instruction->GetPackedType(); - UNREACHABLE(); - } - break; - } - default: - LOG(FATAL) << "Unsupported SIMD type: " << instruction->GetPackedType(); - UNREACHABLE(); - } -} - -void LocationsBuilderMIPS::VisitVecDotProd(HVecDotProd* instruction) { - LOG(FATAL) << "No SIMD for " << instruction->GetId(); -} - -void InstructionCodeGeneratorMIPS::VisitVecDotProd(HVecDotProd* instruction) { - LOG(FATAL) << "No SIMD for " << instruction->GetId(); -} - -// Helper to set up locations for vector memory operations. -static void CreateVecMemLocations(ArenaAllocator* allocator, - HVecMemoryOperation* instruction, - bool is_load) { - LocationSummary* locations = new (allocator) LocationSummary(instruction); - switch (instruction->GetPackedType()) { - case DataType::Type::kBool: - case DataType::Type::kUint8: - case DataType::Type::kInt8: - case DataType::Type::kUint16: - case DataType::Type::kInt16: - case DataType::Type::kInt32: - case DataType::Type::kInt64: - case DataType::Type::kFloat32: - case DataType::Type::kFloat64: - locations->SetInAt(0, Location::RequiresRegister()); - locations->SetInAt(1, Location::RegisterOrConstant(instruction->InputAt(1))); - if (is_load) { - locations->SetOut(Location::RequiresFpuRegister()); - } else { - locations->SetInAt(2, Location::RequiresFpuRegister()); - } - break; - default: - LOG(FATAL) << "Unsupported SIMD type: " << instruction->GetPackedType(); - UNREACHABLE(); - } -} - -// Helper to prepare register and offset for vector memory operations. Returns the offset and sets -// the output parameter adjusted_base to the original base or to a reserved temporary register (AT). -int32_t InstructionCodeGeneratorMIPS::VecAddress(LocationSummary* locations, - size_t size, - /* out */ Register* adjusted_base) { - Register base = locations->InAt(0).AsRegister<Register>(); - Location index = locations->InAt(1); - int scale = TIMES_1; - switch (size) { - case 2: scale = TIMES_2; break; - case 4: scale = TIMES_4; break; - case 8: scale = TIMES_8; break; - default: break; - } - int32_t offset = mirror::Array::DataOffset(size).Int32Value(); - - if (index.IsConstant()) { - offset += index.GetConstant()->AsIntConstant()->GetValue() << scale; - __ AdjustBaseOffsetAndElementSizeShift(base, offset, scale); - *adjusted_base = base; - } else { - Register index_reg = index.AsRegister<Register>(); - if (scale != TIMES_1) { - __ Lsa(AT, index_reg, base, scale); - } else { - __ Addu(AT, base, index_reg); - } - *adjusted_base = AT; - } - return offset; -} - -void LocationsBuilderMIPS::VisitVecLoad(HVecLoad* instruction) { - CreateVecMemLocations(GetGraph()->GetAllocator(), instruction, /* is_load= */ true); -} - -void InstructionCodeGeneratorMIPS::VisitVecLoad(HVecLoad* instruction) { - LocationSummary* locations = instruction->GetLocations(); - size_t size = DataType::Size(instruction->GetPackedType()); - VectorRegister reg = VectorRegisterFrom(locations->Out()); - Register base; - int32_t offset = VecAddress(locations, size, &base); - switch (instruction->GetPackedType()) { - case DataType::Type::kBool: - case DataType::Type::kUint8: - case DataType::Type::kInt8: - DCHECK_EQ(16u, instruction->GetVectorLength()); - __ LdB(reg, base, offset); - break; - case DataType::Type::kUint16: - case DataType::Type::kInt16: - // Loading 8-bytes (needed if dealing with compressed strings in StringCharAt) from unaligned - // memory address may cause a trap to the kernel if the CPU doesn't directly support unaligned - // loads and stores. - // TODO: Implement support for StringCharAt. - DCHECK(!instruction->IsStringCharAt()); - DCHECK_EQ(8u, instruction->GetVectorLength()); - __ LdH(reg, base, offset); - break; - case DataType::Type::kInt32: - case DataType::Type::kFloat32: - DCHECK_EQ(4u, instruction->GetVectorLength()); - __ LdW(reg, base, offset); - break; - case DataType::Type::kInt64: - case DataType::Type::kFloat64: - DCHECK_EQ(2u, instruction->GetVectorLength()); - __ LdD(reg, base, offset); - break; - default: - LOG(FATAL) << "Unsupported SIMD type: " << instruction->GetPackedType(); - UNREACHABLE(); - } -} - -void LocationsBuilderMIPS::VisitVecStore(HVecStore* instruction) { - CreateVecMemLocations(GetGraph()->GetAllocator(), instruction, /* is_load= */ false); -} - -void InstructionCodeGeneratorMIPS::VisitVecStore(HVecStore* instruction) { - LocationSummary* locations = instruction->GetLocations(); - size_t size = DataType::Size(instruction->GetPackedType()); - VectorRegister reg = VectorRegisterFrom(locations->InAt(2)); - Register base; - int32_t offset = VecAddress(locations, size, &base); - switch (instruction->GetPackedType()) { - case DataType::Type::kBool: - case DataType::Type::kUint8: - case DataType::Type::kInt8: - DCHECK_EQ(16u, instruction->GetVectorLength()); - __ StB(reg, base, offset); - break; - case DataType::Type::kUint16: - case DataType::Type::kInt16: - DCHECK_EQ(8u, instruction->GetVectorLength()); - __ StH(reg, base, offset); - break; - case DataType::Type::kInt32: - case DataType::Type::kFloat32: - DCHECK_EQ(4u, instruction->GetVectorLength()); - __ StW(reg, base, offset); - break; - case DataType::Type::kInt64: - case DataType::Type::kFloat64: - DCHECK_EQ(2u, instruction->GetVectorLength()); - __ StD(reg, base, offset); - break; - default: - LOG(FATAL) << "Unsupported SIMD type: " << instruction->GetPackedType(); - UNREACHABLE(); - } -} - -#undef __ - -} // namespace mips -} // namespace art |