summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Nicolas Geoffray <ngeoffray@google.com> 2016-03-04 10:11:09 +0000
committer Gerrit Code Review <noreply-gerritcodereview@google.com> 2016-03-04 10:11:09 +0000
commitdd11dde40a9002eaebb977fc754f64d94ec4e60c (patch)
tree0c2b6ba9baa995549f96ca04fb246e0d9b841a3f
parent9ec0676c8e17664926055e40a7283074dd9b3474 (diff)
parent49924c970536bc570b84e3bf0d525fa9f56debde (diff)
Merge "Integer.bitCount and Long.bitCount intrinsics for ARM64"
-rw-r--r--compiler/optimizing/intrinsics_arm64.cc37
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)