summaryrefslogtreecommitdiff
path: root/compiler/optimizing/intrinsics_riscv64.cc
diff options
context:
space:
mode:
author Olga Mikhaltsova <olga.mikhaltsova@syntacore.com> 2024-07-22 18:16:20 +0000
committer Treehugger Robot <android-test-infra-autosubmit@system.gserviceaccount.com> 2024-08-12 15:17:18 +0000
commitbda29056665961578f2b97cd6d40daca2058694d (patch)
treeff3df2723b2c19ac393dbbdb6137e296e94e2868 /compiler/optimizing/intrinsics_riscv64.cc
parent3244be57e9c170696b0a17369bcf3e77f82ee9ec (diff)
riscv64: implement signum{float|double} and copySign{float|double} intrinsics
Performance improvement: copySign(double) -29% copySign(float) -33% signum(double) -20% signum(float) -22% Test: testrunner.py --target --64 --ndebug --optimizing Change-Id: I3b69a4d35a0b37e5debed9f16c3a757a4204387e
Diffstat (limited to 'compiler/optimizing/intrinsics_riscv64.cc')
-rw-r--r--compiler/optimizing/intrinsics_riscv64.cc86
1 files changed, 86 insertions, 0 deletions
diff --git a/compiler/optimizing/intrinsics_riscv64.cc b/compiler/optimizing/intrinsics_riscv64.cc
index 9f1ac08a26..eec73ea052 100644
--- a/compiler/optimizing/intrinsics_riscv64.cc
+++ b/compiler/optimizing/intrinsics_riscv64.cc
@@ -5526,6 +5526,92 @@ void IntrinsicCodeGeneratorRISCV64::VisitStringGetCharsNoCheck(HInvoke* invoke)
__ Bind(&done);
}
+void GenMathSignum(CodeGeneratorRISCV64* codegen, HInvoke* invoke, DataType::Type type) {
+ LocationSummary* locations = invoke->GetLocations();
+ DCHECK(locations->InAt(0).Equals(locations->Out()));
+ FRegister in = locations->InAt(0).AsFpuRegister<FRegister>();
+ Riscv64Assembler* assembler = codegen->GetAssembler();
+ ScratchRegisterScope srs(assembler);
+ XRegister tmp = srs.AllocateXRegister();
+ FRegister ftmp = srs.AllocateFRegister();
+ Riscv64Label done;
+
+ if (type == DataType::Type::kFloat64) {
+ // 0x3FF0000000000000L = 1.0
+ __ Li(tmp, 0x3FF0000000000000L);
+ __ FMvDX(ftmp, tmp);
+ __ FClassD(tmp, in);
+ } else {
+ // 0x3f800000 = 1.0f
+ __ Li(tmp, 0x3F800000);
+ __ FMvWX(ftmp, tmp);
+ __ FClassS(tmp, in);
+ }
+
+ __ Andi(tmp, tmp, kPositiveZero | kNegativeZero | kSignalingNaN | kQuietNaN);
+ __ Bnez(tmp, &done);
+
+ if (type == DataType::Type::kFloat64) {
+ __ FSgnjD(in, ftmp, in);
+ } else {
+ __ FSgnjS(in, ftmp, in);
+ }
+
+ __ Bind(&done);
+}
+
+void IntrinsicLocationsBuilderRISCV64::VisitMathSignumDouble(HInvoke* invoke) {
+ LocationSummary* locations =
+ new (allocator_) LocationSummary(invoke, LocationSummary::kNoCall, kIntrinsified);
+ locations->SetInAt(0, Location::RequiresFpuRegister());
+ locations->SetOut(Location::SameAsFirstInput());
+}
+
+void IntrinsicCodeGeneratorRISCV64::VisitMathSignumDouble(HInvoke* invoke) {
+ GenMathSignum(codegen_, invoke, DataType::Type::kFloat64);
+}
+
+void IntrinsicLocationsBuilderRISCV64::VisitMathSignumFloat(HInvoke* invoke) {
+ LocationSummary* locations =
+ new (allocator_) LocationSummary(invoke, LocationSummary::kNoCall, kIntrinsified);
+ locations->SetInAt(0, Location::RequiresFpuRegister());
+ locations->SetOut(Location::SameAsFirstInput());
+}
+
+void IntrinsicCodeGeneratorRISCV64::VisitMathSignumFloat(HInvoke* invoke) {
+ GenMathSignum(codegen_, invoke, DataType::Type::kFloat32);
+}
+
+void GenMathCopySign(CodeGeneratorRISCV64* codegen, HInvoke* invoke, DataType::Type type) {
+ Riscv64Assembler* assembler = codegen->GetAssembler();
+ LocationSummary* locations = invoke->GetLocations();
+ FRegister in0 = locations->InAt(0).AsFpuRegister<FRegister>();
+ FRegister in1 = locations->InAt(1).AsFpuRegister<FRegister>();
+ FRegister out = locations->Out().AsFpuRegister<FRegister>();
+
+ if (type == DataType::Type::kFloat64) {
+ __ FSgnjD(out, in0, in1);
+ } else {
+ __ FSgnjS(out, in0, in1);
+ }
+}
+
+void IntrinsicLocationsBuilderRISCV64::VisitMathCopySignDouble(HInvoke* invoke) {
+ CreateFPFPToFPCallLocations(allocator_, invoke);
+}
+
+void IntrinsicCodeGeneratorRISCV64::VisitMathCopySignDouble(HInvoke* invoke) {
+ GenMathCopySign(codegen_, invoke, DataType::Type::kFloat64);
+}
+
+void IntrinsicLocationsBuilderRISCV64::VisitMathCopySignFloat(HInvoke* invoke) {
+ CreateFPFPToFPCallLocations(allocator_, invoke);
+}
+
+void IntrinsicCodeGeneratorRISCV64::VisitMathCopySignFloat(HInvoke* invoke) {
+ GenMathCopySign(codegen_, invoke, DataType::Type::kFloat32);
+}
+
#define MARK_UNIMPLEMENTED(Name) UNIMPLEMENTED_INTRINSIC(RISCV64, Name)
UNIMPLEMENTED_INTRINSIC_LIST_RISCV64(MARK_UNIMPLEMENTED);
#undef MARK_UNIMPLEMENTED