From 7b56502c52271c52ef0232ccd47e96badfe5dba6 Mon Sep 17 00:00:00 2001 From: Aart Bik Date: Thu, 28 Jan 2016 14:36:22 -0800 Subject: [PATCH] Implement compare() on ARM64. Change-Id: I6b5982aeb7401cd90fc37431a72bdd2b7f3e322b --- compiler/optimizing/intrinsics_arm64.cc | 50 +++++++++++++++++++++++++-------- 1 file changed, 39 insertions(+), 11 deletions(-) diff --git a/compiler/optimizing/intrinsics_arm64.cc b/compiler/optimizing/intrinsics_arm64.cc index d5ed58530..98d041a5f 100644 --- a/compiler/optimizing/intrinsics_arm64.cc +++ b/compiler/optimizing/intrinsics_arm64.cc @@ -275,6 +275,45 @@ void IntrinsicCodeGeneratorARM64::VisitShortReverseBytes(HInvoke* invoke) { GenReverseBytes(invoke->GetLocations(), Primitive::kPrimShort, GetVIXLAssembler()); } +static void CreateIntIntToIntLocations(ArenaAllocator* arena, HInvoke* invoke) { + LocationSummary* locations = new (arena) LocationSummary(invoke, + LocationSummary::kNoCall, + kIntrinsified); + locations->SetInAt(0, Location::RequiresRegister()); + locations->SetInAt(1, Location::RequiresRegister()); + locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap); +} + +static void GenCompare(LocationSummary* locations, bool is_long, vixl::MacroAssembler* masm) { + Location op1 = locations->InAt(0); + Location op2 = locations->InAt(1); + Location out = locations->Out(); + + Register op1_reg = is_long ? XRegisterFrom(op1) : WRegisterFrom(op1); + Register op2_reg = is_long ? XRegisterFrom(op2) : WRegisterFrom(op2); + Register out_reg = WRegisterFrom(out); + + __ Cmp(op1_reg, op2_reg); + __ Cset(out_reg, gt); // out == +1 if GT or 0 otherwise + __ Cinv(out_reg, out_reg, lt); // out == -1 if LT or unchanged otherwise +} + +void IntrinsicLocationsBuilderARM64::VisitIntegerCompare(HInvoke* invoke) { + CreateIntIntToIntLocations(arena_, invoke); +} + +void IntrinsicCodeGeneratorARM64::VisitIntegerCompare(HInvoke* invoke) { + GenCompare(invoke->GetLocations(), /* is_long */ false, GetVIXLAssembler()); +} + +void IntrinsicLocationsBuilderARM64::VisitLongCompare(HInvoke* invoke) { + CreateIntIntToIntLocations(arena_, invoke); +} + +void IntrinsicCodeGeneratorARM64::VisitLongCompare(HInvoke* invoke) { + GenCompare(invoke->GetLocations(), /* is_long */ true, GetVIXLAssembler()); +} + static void GenNumberOfLeadingZeros(LocationSummary* locations, Primitive::Type type, vixl::MacroAssembler* masm) { @@ -504,15 +543,6 @@ static void GenMinMax(LocationSummary* locations, __ Csel(out_reg, op1_reg, op2_reg, is_min ? lt : gt); } -static void CreateIntIntToIntLocations(ArenaAllocator* arena, HInvoke* invoke) { - LocationSummary* locations = new (arena) LocationSummary(invoke, - LocationSummary::kNoCall, - kIntrinsified); - locations->SetInAt(0, Location::RequiresRegister()); - locations->SetInAt(1, Location::RequiresRegister()); - locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap); -} - void IntrinsicLocationsBuilderARM64::VisitMathMinIntInt(HInvoke* invoke) { CreateIntIntToIntLocations(arena_, invoke); } @@ -1507,8 +1537,6 @@ UNIMPLEMENTED_INTRINSIC(DoubleIsInfinite) UNIMPLEMENTED_INTRINSIC(FloatIsNaN) UNIMPLEMENTED_INTRINSIC(DoubleIsNaN) -UNIMPLEMENTED_INTRINSIC(IntegerCompare) -UNIMPLEMENTED_INTRINSIC(LongCompare) UNIMPLEMENTED_INTRINSIC(IntegerHighestOneBit) UNIMPLEMENTED_INTRINSIC(LongHighestOneBit) UNIMPLEMENTED_INTRINSIC(IntegerLowestOneBit) -- 2.11.0