diff options
| -rw-r--r-- | compiler/optimizing/code_generator_riscv64.h | 2 | ||||
| -rw-r--r-- | compiler/optimizing/intrinsics_riscv64.cc | 54 |
2 files changed, 54 insertions, 2 deletions
diff --git a/compiler/optimizing/code_generator_riscv64.h b/compiler/optimizing/code_generator_riscv64.h index 6a37eb01cd..bf086b03f6 100644 --- a/compiler/optimizing/code_generator_riscv64.h +++ b/compiler/optimizing/code_generator_riscv64.h @@ -51,8 +51,6 @@ static constexpr size_t kRuntimeParameterFpuRegistersLength = #define UNIMPLEMENTED_INTRINSIC_LIST_RISCV64(V) \ V(IntegerReverse) \ V(LongReverse) \ - V(MathFmaDouble) \ - V(MathFmaFloat) \ V(MathCos) \ V(MathSin) \ V(MathAcos) \ diff --git a/compiler/optimizing/intrinsics_riscv64.cc b/compiler/optimizing/intrinsics_riscv64.cc index 1ed1bb65b4..09fb37f005 100644 --- a/compiler/optimizing/intrinsics_riscv64.cc +++ b/compiler/optimizing/intrinsics_riscv64.cc @@ -1371,6 +1371,60 @@ void IntrinsicCodeGeneratorRISCV64::VisitLongDivideUnsigned(HInvoke* invoke) { GenerateDivideUnsigned(invoke, codegen_); } +void IntrinsicLocationsBuilderRISCV64::VisitMathFmaDouble(HInvoke* invoke) { + DCHECK_EQ(invoke->GetNumberOfArguments(), 3U); + DCHECK(DataType::IsFloatingPointType(invoke->InputAt(0)->GetType())); + DCHECK(DataType::IsFloatingPointType(invoke->InputAt(1)->GetType())); + DCHECK(DataType::IsFloatingPointType(invoke->InputAt(2)->GetType())); + DCHECK(DataType::IsFloatingPointType(invoke->GetType())); + + LocationSummary* const locations = + new (allocator_) LocationSummary(invoke, LocationSummary::kNoCall, kIntrinsified); + + locations->SetInAt(0, Location::RequiresFpuRegister()); + locations->SetInAt(1, Location::RequiresFpuRegister()); + locations->SetInAt(2, Location::RequiresFpuRegister()); + locations->SetOut(Location::RequiresFpuRegister(), Location::kNoOutputOverlap); +} + +void IntrinsicCodeGeneratorRISCV64::VisitMathFmaDouble(HInvoke* invoke) { + LocationSummary* locations = invoke->GetLocations(); + Riscv64Assembler* assembler = GetAssembler(); + FRegister n = locations->InAt(0).AsFpuRegister<FRegister>(); + FRegister m = locations->InAt(1).AsFpuRegister<FRegister>(); + FRegister a = locations->InAt(2).AsFpuRegister<FRegister>(); + FRegister out = locations->Out().AsFpuRegister<FRegister>(); + + __ FMAddD(out, n, m, a); +} + +void IntrinsicLocationsBuilderRISCV64::VisitMathFmaFloat(HInvoke* invoke) { + DCHECK_EQ(invoke->GetNumberOfArguments(), 3U); + DCHECK(DataType::IsFloatingPointType(invoke->InputAt(0)->GetType())); + DCHECK(DataType::IsFloatingPointType(invoke->InputAt(1)->GetType())); + DCHECK(DataType::IsFloatingPointType(invoke->InputAt(2)->GetType())); + DCHECK(DataType::IsFloatingPointType(invoke->GetType())); + + LocationSummary* const locations = + new (allocator_) LocationSummary(invoke, LocationSummary::kNoCall, kIntrinsified); + + locations->SetInAt(0, Location::RequiresFpuRegister()); + locations->SetInAt(1, Location::RequiresFpuRegister()); + locations->SetInAt(2, Location::RequiresFpuRegister()); + locations->SetOut(Location::RequiresFpuRegister(), Location::kNoOutputOverlap); +} + +void IntrinsicCodeGeneratorRISCV64::VisitMathFmaFloat(HInvoke* invoke) { + LocationSummary* locations = invoke->GetLocations(); + Riscv64Assembler* assembler = GetAssembler(); + FRegister n = locations->InAt(0).AsFpuRegister<FRegister>(); + FRegister m = locations->InAt(1).AsFpuRegister<FRegister>(); + FRegister a = locations->InAt(2).AsFpuRegister<FRegister>(); + FRegister out = locations->Out().AsFpuRegister<FRegister>(); + + __ FMAddS(out, n, m, a); +} + #define MARK_UNIMPLEMENTED(Name) UNIMPLEMENTED_INTRINSIC(RISCV64, Name) UNIMPLEMENTED_INTRINSIC_LIST_RISCV64(MARK_UNIMPLEMENTED); #undef MARK_UNIMPLEMENTED |