From 49924c970536bc570b84e3bf0d525fa9f56debde Mon Sep 17 00:00:00 2001 From: "xueliang.zhong" Date: Thu, 3 Mar 2016 10:52:51 +0000 Subject: [PATCH] Integer.bitCount and Long.bitCount intrinsics for ARM64 Change-Id: If6180acc90239e52e5d33901b65e194d1ca7e248 --- compiler/optimizing/intrinsics_arm64.cc | 37 +++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/compiler/optimizing/intrinsics_arm64.cc b/compiler/optimizing/intrinsics_arm64.cc index 7a4a6ef26..2e1198c51 100644 --- a/compiler/optimizing/intrinsics_arm64.cc +++ b/compiler/optimizing/intrinsics_arm64.cc @@ -46,6 +46,7 @@ using helpers::RegisterFrom; using helpers::SRegisterFrom; using helpers::WRegisterFrom; using helpers::XRegisterFrom; +using helpers::InputRegisterAt; namespace { @@ -367,6 +368,40 @@ void IntrinsicCodeGeneratorARM64::VisitLongReverse(HInvoke* invoke) { GenReverse(invoke->GetLocations(), Primitive::kPrimLong, GetVIXLAssembler()); } +static void GenBitCount(HInvoke* instr, bool is_long, vixl::MacroAssembler* masm) { + DCHECK(instr->GetType() == Primitive::kPrimInt); + DCHECK((is_long && instr->InputAt(0)->GetType() == Primitive::kPrimLong) || + (!is_long && instr->InputAt(0)->GetType() == Primitive::kPrimInt)); + + Location out = instr->GetLocations()->Out(); + UseScratchRegisterScope temps(masm); + + Register src = InputRegisterAt(instr, 0); + FPRegister fpr = is_long ? temps.AcquireD() : temps.AcquireS(); + Register dst = is_long ? XRegisterFrom(out) : WRegisterFrom(out); + + __ Fmov(fpr, src); + __ Cnt (fpr.V8B(), fpr.V8B()); + __ Addv(fpr.B(), fpr.V8B()); + __ Fmov(dst, fpr); +} + +void IntrinsicLocationsBuilderARM64::VisitLongBitCount(HInvoke* invoke) { + CreateIntToIntLocations(arena_, invoke); +} + +void IntrinsicCodeGeneratorARM64::VisitLongBitCount(HInvoke* invoke) { + GenBitCount(invoke, /* is_long */ true, GetVIXLAssembler()); +} + +void IntrinsicLocationsBuilderARM64::VisitIntegerBitCount(HInvoke* invoke) { + CreateIntToIntLocations(arena_, invoke); +} + +void IntrinsicCodeGeneratorARM64::VisitIntegerBitCount(HInvoke* invoke) { + GenBitCount(invoke, /* is_long */ false, GetVIXLAssembler()); +} + static void CreateFPToFPLocations(ArenaAllocator* arena, HInvoke* invoke) { LocationSummary* locations = new (arena) LocationSummary(invoke, LocationSummary::kNoCall, @@ -1672,8 +1707,6 @@ void IntrinsicCodeGeneratorARM64::VisitStringGetCharsNoCheck(HInvoke* invoke) { __ Bind(&done); } -UNIMPLEMENTED_INTRINSIC(ARM64, IntegerBitCount) -UNIMPLEMENTED_INTRINSIC(ARM64, LongBitCount) UNIMPLEMENTED_INTRINSIC(ARM64, SystemArrayCopyChar) UNIMPLEMENTED_INTRINSIC(ARM64, SystemArrayCopy) UNIMPLEMENTED_INTRINSIC(ARM64, ReferenceGetReferent) -- 2.11.0