diff options
| author | 2017-06-06 13:28:42 +0200 | |
|---|---|---|
| committer | 2017-06-07 09:45:18 +0200 | |
| commit | 8fea1e18ecce190bbffbc0085f20ad49ca10a8c2 (patch) | |
| tree | e026d33cc0928a977118faff46fdbbb50ff0967e /compiler/optimizing | |
| parent | 11d72c608e0565fabcf6b2d6c13fbc85c560a608 (diff) | |
MIPS64: Min/max vectorization support
Test: mma test-art-host-gtest
Test: ./testrunner.py --optimizing --target --64 in QEMU
Change-Id: I60dc9c97c2b6470414fa64750e7c9824e70bfb4e
Diffstat (limited to 'compiler/optimizing')
| -rw-r--r-- | compiler/optimizing/code_generator_vector_mips64.cc | 110 | ||||
| -rw-r--r-- | compiler/optimizing/loop_optimization.cc | 12 |
2 files changed, 114 insertions, 8 deletions
diff --git a/compiler/optimizing/code_generator_vector_mips64.cc b/compiler/optimizing/code_generator_vector_mips64.cc index af9e89e791..0395db1df9 100644 --- a/compiler/optimizing/code_generator_vector_mips64.cc +++ b/compiler/optimizing/code_generator_vector_mips64.cc @@ -495,7 +495,60 @@ void LocationsBuilderMIPS64::VisitVecMin(HVecMin* instruction) { } void InstructionCodeGeneratorMIPS64::VisitVecMin(HVecMin* instruction) { - LOG(FATAL) << "No SIMD for " << instruction->GetId(); + 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 Primitive::kPrimByte: + DCHECK_EQ(16u, instruction->GetVectorLength()); + if (instruction->IsUnsigned()) { + __ Min_uB(dst, lhs, rhs); + } else { + __ Min_sB(dst, lhs, rhs); + } + break; + case Primitive::kPrimChar: + case Primitive::kPrimShort: + DCHECK_EQ(8u, instruction->GetVectorLength()); + if (instruction->IsUnsigned()) { + __ Min_uH(dst, lhs, rhs); + } else { + __ Min_sH(dst, lhs, rhs); + } + break; + case Primitive::kPrimInt: + DCHECK_EQ(4u, instruction->GetVectorLength()); + if (instruction->IsUnsigned()) { + __ Min_uW(dst, lhs, rhs); + } else { + __ Min_sW(dst, lhs, rhs); + } + break; + case Primitive::kPrimLong: + DCHECK_EQ(2u, instruction->GetVectorLength()); + if (instruction->IsUnsigned()) { + __ Min_uD(dst, lhs, rhs); + } else { + __ 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 Primitive::kPrimFloat: + DCHECK_EQ(4u, instruction->GetVectorLength()); + DCHECK(!instruction->IsUnsigned()); + __ FminW(dst, lhs, rhs); + break; + case Primitive::kPrimDouble: + DCHECK_EQ(2u, instruction->GetVectorLength()); + DCHECK(!instruction->IsUnsigned()); + __ FminD(dst, lhs, rhs); + break; + default: + LOG(FATAL) << "Unsupported SIMD type"; + UNREACHABLE(); + } } void LocationsBuilderMIPS64::VisitVecMax(HVecMax* instruction) { @@ -503,7 +556,60 @@ void LocationsBuilderMIPS64::VisitVecMax(HVecMax* instruction) { } void InstructionCodeGeneratorMIPS64::VisitVecMax(HVecMax* instruction) { - LOG(FATAL) << "No SIMD for " << instruction->GetId(); + 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 Primitive::kPrimByte: + DCHECK_EQ(16u, instruction->GetVectorLength()); + if (instruction->IsUnsigned()) { + __ Max_uB(dst, lhs, rhs); + } else { + __ Max_sB(dst, lhs, rhs); + } + break; + case Primitive::kPrimChar: + case Primitive::kPrimShort: + DCHECK_EQ(8u, instruction->GetVectorLength()); + if (instruction->IsUnsigned()) { + __ Max_uH(dst, lhs, rhs); + } else { + __ Max_sH(dst, lhs, rhs); + } + break; + case Primitive::kPrimInt: + DCHECK_EQ(4u, instruction->GetVectorLength()); + if (instruction->IsUnsigned()) { + __ Max_uW(dst, lhs, rhs); + } else { + __ Max_sW(dst, lhs, rhs); + } + break; + case Primitive::kPrimLong: + DCHECK_EQ(2u, instruction->GetVectorLength()); + if (instruction->IsUnsigned()) { + __ Max_uD(dst, lhs, rhs); + } else { + __ 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 Primitive::kPrimFloat: + DCHECK_EQ(4u, instruction->GetVectorLength()); + DCHECK(!instruction->IsUnsigned()); + __ FmaxW(dst, lhs, rhs); + break; + case Primitive::kPrimDouble: + DCHECK_EQ(2u, instruction->GetVectorLength()); + DCHECK(!instruction->IsUnsigned()); + __ FmaxD(dst, lhs, rhs); + break; + default: + LOG(FATAL) << "Unsupported SIMD type"; + UNREACHABLE(); + } } void LocationsBuilderMIPS64::VisitVecAnd(HVecAnd* instruction) { diff --git a/compiler/optimizing/loop_optimization.cc b/compiler/optimizing/loop_optimization.cc index c3aa976d49..cfcafa5c24 100644 --- a/compiler/optimizing/loop_optimization.cc +++ b/compiler/optimizing/loop_optimization.cc @@ -1084,23 +1084,23 @@ bool HLoopOptimization::TrySetVectorType(Primitive::Type type, uint64_t* restric switch (type) { case Primitive::kPrimBoolean: case Primitive::kPrimByte: - *restrictions |= kNoDiv | kNoMinMax; + *restrictions |= kNoDiv; return TrySetVectorLength(16); case Primitive::kPrimChar: case Primitive::kPrimShort: - *restrictions |= kNoDiv | kNoMinMax | kNoStringCharAt; + *restrictions |= kNoDiv | kNoStringCharAt; return TrySetVectorLength(8); case Primitive::kPrimInt: - *restrictions |= kNoDiv | kNoMinMax; + *restrictions |= kNoDiv; return TrySetVectorLength(4); case Primitive::kPrimLong: - *restrictions |= kNoDiv | kNoMinMax; + *restrictions |= kNoDiv; return TrySetVectorLength(2); case Primitive::kPrimFloat: - *restrictions |= kNoMinMax; + *restrictions |= kNoMinMax; // min/max(x, NaN) return TrySetVectorLength(4); case Primitive::kPrimDouble: - *restrictions |= kNoMinMax; + *restrictions |= kNoMinMax; // min/max(x, NaN) return TrySetVectorLength(2); default: break; |