summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Vladimir Marko <vmarko@google.com> 2023-08-14 08:31:44 +0000
committer VladimĂ­r Marko <vmarko@google.com> 2023-08-16 06:50:30 +0000
commit4a05ac01506780dfe4435c40016501041c38b6b9 (patch)
tree91929092b57c338d0500f73656da2c2ca4f4959b
parentb6f3b439d4f12e89393ba8101eea8671c94ba237 (diff)
riscv64: Implement Memory peek/poke intrinsics.
Test: m test-art-host-gtest Bug: 283082089 Change-Id: I0b6c2d6d875ca1ca511310993fc8fda7f9df73e2
-rw-r--r--compiler/optimizing/code_generator_riscv64.cc8
-rw-r--r--compiler/optimizing/code_generator_riscv64.h8
-rw-r--r--compiler/optimizing/intrinsics_riscv64.cc105
-rw-r--r--compiler/optimizing/intrinsics_riscv64.h9
4 files changed, 111 insertions, 19 deletions
diff --git a/compiler/optimizing/code_generator_riscv64.cc b/compiler/optimizing/code_generator_riscv64.cc
index cdef15f785..31e8bafb43 100644
--- a/compiler/optimizing/code_generator_riscv64.cc
+++ b/compiler/optimizing/code_generator_riscv64.cc
@@ -2194,9 +2194,11 @@ void LocationsBuilderRISCV64::VisitInvokeStaticOrDirect(HInvokeStaticOrDirect* i
}
static bool TryGenerateIntrinsicCode(HInvoke* invoke, CodeGeneratorRISCV64* codegen) {
- // TODO(riscv64): Implement intrinsics later
- UNUSED(invoke);
- UNUSED(codegen);
+ if (invoke->GetLocations()->Intrinsified()) {
+ IntrinsicCodeGeneratorRISCV64 intrinsic(codegen);
+ intrinsic.Dispatch(invoke);
+ return true;
+ }
return false;
}
diff --git a/compiler/optimizing/code_generator_riscv64.h b/compiler/optimizing/code_generator_riscv64.h
index eea4338fe7..1e3c652a6c 100644
--- a/compiler/optimizing/code_generator_riscv64.h
+++ b/compiler/optimizing/code_generator_riscv64.h
@@ -104,14 +104,6 @@ static constexpr size_t kRuntimeParameterFpuRegistersLength =
V(SystemArrayCopyInt) \
V(SystemArrayCopy) \
V(ThreadCurrentThread) \
- V(MemoryPeekByte) \
- V(MemoryPeekIntNative) \
- V(MemoryPeekLongNative) \
- V(MemoryPeekShortNative) \
- V(MemoryPokeByte) \
- V(MemoryPokeIntNative) \
- V(MemoryPokeLongNative) \
- V(MemoryPokeShortNative) \
V(FP16Ceil) \
V(FP16Compare) \
V(FP16Floor) \
diff --git a/compiler/optimizing/intrinsics_riscv64.cc b/compiler/optimizing/intrinsics_riscv64.cc
index f4bcb4abb6..e8edab0692 100644
--- a/compiler/optimizing/intrinsics_riscv64.cc
+++ b/compiler/optimizing/intrinsics_riscv64.cc
@@ -21,6 +21,111 @@
namespace art HIDDEN {
namespace riscv64 {
+bool IntrinsicLocationsBuilderRISCV64::TryDispatch(HInvoke* invoke) {
+ Dispatch(invoke);
+ LocationSummary* res = invoke->GetLocations();
+ if (res == nullptr) {
+ return false;
+ }
+ return res->Intrinsified();
+}
+
+Riscv64Assembler* IntrinsicCodeGeneratorRISCV64::GetAssembler() {
+ return codegen_->GetAssembler();
+}
+
+#define __ GetAssembler()->
+
+static void CreateIntToIntLocations(ArenaAllocator* allocator, HInvoke* invoke) {
+ LocationSummary* locations =
+ new (allocator) LocationSummary(invoke, LocationSummary::kNoCall, kIntrinsified);
+ locations->SetInAt(0, Location::RequiresRegister());
+ locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap);
+}
+
+template <typename EmitOp>
+void EmitMemoryPeek(HInvoke* invoke, EmitOp&& emit_op) {
+ LocationSummary* locations = invoke->GetLocations();
+ emit_op(locations->Out().AsRegister<XRegister>(), locations->InAt(0).AsRegister<XRegister>());
+}
+
+void IntrinsicLocationsBuilderRISCV64::VisitMemoryPeekByte(HInvoke* invoke) {
+ CreateIntToIntLocations(allocator_, invoke);
+}
+
+void IntrinsicCodeGeneratorRISCV64::VisitMemoryPeekByte(HInvoke* invoke) {
+ EmitMemoryPeek(invoke, [&](XRegister rd, XRegister rs1) { __ Lb(rd, rs1, 0); });
+}
+
+void IntrinsicLocationsBuilderRISCV64::VisitMemoryPeekIntNative(HInvoke* invoke) {
+ CreateIntToIntLocations(allocator_, invoke);
+}
+
+void IntrinsicCodeGeneratorRISCV64::VisitMemoryPeekIntNative(HInvoke* invoke) {
+ EmitMemoryPeek(invoke, [&](XRegister rd, XRegister rs1) { __ Lw(rd, rs1, 0); });
+}
+
+void IntrinsicLocationsBuilderRISCV64::VisitMemoryPeekLongNative(HInvoke* invoke) {
+ CreateIntToIntLocations(allocator_, invoke);
+}
+
+void IntrinsicCodeGeneratorRISCV64::VisitMemoryPeekLongNative(HInvoke* invoke) {
+ EmitMemoryPeek(invoke, [&](XRegister rd, XRegister rs1) { __ Ld(rd, rs1, 0); });
+}
+
+void IntrinsicLocationsBuilderRISCV64::VisitMemoryPeekShortNative(HInvoke* invoke) {
+ CreateIntToIntLocations(allocator_, invoke);
+}
+
+void IntrinsicCodeGeneratorRISCV64::VisitMemoryPeekShortNative(HInvoke* invoke) {
+ EmitMemoryPeek(invoke, [&](XRegister rd, XRegister rs1) { __ Lh(rd, rs1, 0); });
+}
+
+static void CreateIntIntToVoidLocations(ArenaAllocator* allocator, HInvoke* invoke) {
+ LocationSummary* locations =
+ new (allocator) LocationSummary(invoke, LocationSummary::kNoCall, kIntrinsified);
+ locations->SetInAt(0, Location::RequiresRegister());
+ locations->SetInAt(1, Location::RequiresRegister());
+}
+
+template <typename EmitOp>
+void EmitMemoryPoke(HInvoke* invoke, EmitOp&& emit_op) {
+ LocationSummary* locations = invoke->GetLocations();
+ emit_op(locations->InAt(1).AsRegister<XRegister>(), locations->InAt(0).AsRegister<XRegister>());
+}
+
+void IntrinsicLocationsBuilderRISCV64::VisitMemoryPokeByte(HInvoke* invoke) {
+ CreateIntIntToVoidLocations(allocator_, invoke);
+}
+
+void IntrinsicCodeGeneratorRISCV64::VisitMemoryPokeByte(HInvoke* invoke) {
+ EmitMemoryPoke(invoke, [&](XRegister rs2, XRegister rs1) { __ Sb(rs2, rs1, 0); });
+}
+
+void IntrinsicLocationsBuilderRISCV64::VisitMemoryPokeIntNative(HInvoke* invoke) {
+ CreateIntIntToVoidLocations(allocator_, invoke);
+}
+
+void IntrinsicCodeGeneratorRISCV64::VisitMemoryPokeIntNative(HInvoke* invoke) {
+ EmitMemoryPoke(invoke, [&](XRegister rs2, XRegister rs1) { __ Sw(rs2, rs1, 0); });
+}
+
+void IntrinsicLocationsBuilderRISCV64::VisitMemoryPokeLongNative(HInvoke* invoke) {
+ CreateIntIntToVoidLocations(allocator_, invoke);
+}
+
+void IntrinsicCodeGeneratorRISCV64::VisitMemoryPokeLongNative(HInvoke* invoke) {
+ EmitMemoryPoke(invoke, [&](XRegister rs2, XRegister rs1) { __ Sd(rs2, rs1, 0); });
+}
+
+void IntrinsicLocationsBuilderRISCV64::VisitMemoryPokeShortNative(HInvoke* invoke) {
+ CreateIntIntToVoidLocations(allocator_, invoke);
+}
+
+void IntrinsicCodeGeneratorRISCV64::VisitMemoryPokeShortNative(HInvoke* invoke) {
+ EmitMemoryPoke(invoke, [&](XRegister rs2, XRegister rs1) { __ Sh(rs2, rs1, 0); });
+}
+
#define MARK_UNIMPLEMENTED(Name) UNIMPLEMENTED_INTRINSIC(RISCV64, Name)
UNIMPLEMENTED_INTRINSIC_LIST_RISCV64(MARK_UNIMPLEMENTED);
#undef MARK_UNIMPLEMENTED
diff --git a/compiler/optimizing/intrinsics_riscv64.h b/compiler/optimizing/intrinsics_riscv64.h
index 3557741797..49c057de2b 100644
--- a/compiler/optimizing/intrinsics_riscv64.h
+++ b/compiler/optimizing/intrinsics_riscv64.h
@@ -48,14 +48,7 @@ class IntrinsicLocationsBuilderRISCV64 final : public IntrinsicVisitor {
// Check whether an invoke is an intrinsic, and if so, create a location summary. Returns whether
// a corresponding LocationSummary with the intrinsified_ flag set was generated and attached to
// the invoke.
- bool TryDispatch(HInvoke* invoke) {
- // TODO(riscv64): Implement in `intrinsics_riscv64.cc`.
- UNUSED(invoke);
- // Avoid compiling failed with "not used"
- UNUSED(codegen_);
- UNUSED(allocator_);
- return false;
- }
+ bool TryDispatch(HInvoke* invoke);
private:
ArenaAllocator* const allocator_;