diff options
| author | 2016-03-04 10:11:09 +0000 | |
|---|---|---|
| committer | 2016-03-04 10:11:09 +0000 | |
| commit | dd11dde40a9002eaebb977fc754f64d94ec4e60c (patch) | |
| tree | 0c2b6ba9baa995549f96ca04fb246e0d9b841a3f | |
| parent | 9ec0676c8e17664926055e40a7283074dd9b3474 (diff) | |
| parent | 49924c970536bc570b84e3bf0d525fa9f56debde (diff) | |
Merge "Integer.bitCount and Long.bitCount intrinsics for ARM64"
| -rw-r--r-- | compiler/optimizing/intrinsics_arm64.cc | 37 |
1 files changed, 35 insertions, 2 deletions
diff --git a/compiler/optimizing/intrinsics_arm64.cc b/compiler/optimizing/intrinsics_arm64.cc index 7a4a6ef266..2e1198c515 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) |