diff options
author | 2023-08-14 08:31:44 +0000 | |
---|---|---|
committer | 2023-08-16 06:50:30 +0000 | |
commit | 4a05ac01506780dfe4435c40016501041c38b6b9 (patch) | |
tree | 91929092b57c338d0500f73656da2c2ca4f4959b | |
parent | b6f3b439d4f12e89393ba8101eea8671c94ba237 (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.cc | 8 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_riscv64.h | 8 | ||||
-rw-r--r-- | compiler/optimizing/intrinsics_riscv64.cc | 105 | ||||
-rw-r--r-- | compiler/optimizing/intrinsics_riscv64.h | 9 |
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_; |