diff options
| author | 2016-03-04 10:11:09 +0000 | |
|---|---|---|
| committer | 2016-03-04 10:11:09 +0000 | |
| commit | dd11dde40a9002eaebb977fc754f64d94ec4e60c (patch) | |
| tree | 0c2b6ba9baa995549f96ca04fb246e0d9b841a3f /compiler/optimizing | |
| parent | 9ec0676c8e17664926055e40a7283074dd9b3474 (diff) | |
| parent | 49924c970536bc570b84e3bf0d525fa9f56debde (diff) | |
Merge "Integer.bitCount and Long.bitCount intrinsics for ARM64"
Diffstat (limited to 'compiler/optimizing')
| -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)  |