diff options
author | 2015-10-19 22:06:00 +0000 | |
---|---|---|
committer | 2015-10-19 22:06:00 +0000 | |
commit | e033ea69bcd1f343c3cf944d78beec726faf348f (patch) | |
tree | d470f7cd69e86a9287da947970a8f519de8ec6b9 | |
parent | 25cf8c412f966563a3f1a6ab629be74faf61e915 (diff) | |
parent | 0f8f8643bc10160a9034b9e3ccfd81e9e6ed8e74 (diff) |
Merge "MIPS64: Add intrinsic support for bit rotation"
-rw-r--r-- | compiler/optimizing/intrinsics_mips64.cc | 65 |
1 files changed, 63 insertions, 2 deletions
diff --git a/compiler/optimizing/intrinsics_mips64.cc b/compiler/optimizing/intrinsics_mips64.cc index fe16d00b72..56c4177b29 100644 --- a/compiler/optimizing/intrinsics_mips64.cc +++ b/compiler/optimizing/intrinsics_mips64.cc @@ -397,6 +397,69 @@ void IntrinsicCodeGeneratorMIPS64::VisitLongRotateRight(HInvoke* invoke) { GenRotateRight(invoke, Primitive::kPrimLong, GetAssembler()); } +static void GenRotateLeft(HInvoke* invoke, + Primitive::Type type, + Mips64Assembler* assembler) { + DCHECK(type == Primitive::kPrimInt || type == Primitive::kPrimLong); + + LocationSummary* locations = invoke->GetLocations(); + GpuRegister in = locations->InAt(0).AsRegister<GpuRegister>(); + GpuRegister out = locations->Out().AsRegister<GpuRegister>(); + + if (invoke->InputAt(1)->IsIntConstant()) { + int32_t shift = -static_cast<int32_t>(invoke->InputAt(1)->AsIntConstant()->GetValue()); + if (type == Primitive::kPrimInt) { + shift &= 0x1f; + __ Rotr(out, in, shift); + } else { + shift &= 0x3f; + if (shift < 32) { + __ Drotr(out, in, shift); + } else { + shift &= 0x1f; + __ Drotr32(out, in, shift); + } + } + } else { + GpuRegister shamt = locations->InAt(1).AsRegister<GpuRegister>(); + if (type == Primitive::kPrimInt) { + __ Subu(TMP, ZERO, shamt); + __ Rotrv(out, in, TMP); + } else { + __ Dsubu(TMP, ZERO, shamt); + __ Drotrv(out, in, TMP); + } + } +} + +// int java.lang.Integer.rotateLeft(int i, int distance) +void IntrinsicLocationsBuilderMIPS64::VisitIntegerRotateLeft(HInvoke* invoke) { + LocationSummary* locations = new (arena_) LocationSummary(invoke, + LocationSummary::kNoCall, + kIntrinsified); + locations->SetInAt(0, Location::RequiresRegister()); + locations->SetInAt(1, Location::RegisterOrConstant(invoke->InputAt(1))); + locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap); +} + +void IntrinsicCodeGeneratorMIPS64::VisitIntegerRotateLeft(HInvoke* invoke) { + GenRotateLeft(invoke, Primitive::kPrimInt, GetAssembler()); +} + +// int java.lang.Long.rotateLeft(long i, int distance) +void IntrinsicLocationsBuilderMIPS64::VisitLongRotateLeft(HInvoke* invoke) { + LocationSummary* locations = new (arena_) LocationSummary(invoke, + LocationSummary::kNoCall, + kIntrinsified); + locations->SetInAt(0, Location::RequiresRegister()); + locations->SetInAt(1, Location::RegisterOrConstant(invoke->InputAt(1))); + locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap); +} + +void IntrinsicCodeGeneratorMIPS64::VisitLongRotateLeft(HInvoke* invoke) { + GenRotateLeft(invoke, Primitive::kPrimLong, GetAssembler()); +} + static void GenReverse(LocationSummary* locations, Primitive::Type type, Mips64Assembler* assembler) { @@ -1462,8 +1525,6 @@ UNIMPLEMENTED_INTRINSIC(UnsafeCASInt) UNIMPLEMENTED_INTRINSIC(UnsafeCASLong) UNIMPLEMENTED_INTRINSIC(UnsafeCASObject) UNIMPLEMENTED_INTRINSIC(StringEquals) -UNIMPLEMENTED_INTRINSIC(LongRotateLeft) -UNIMPLEMENTED_INTRINSIC(IntegerRotateLeft) UNIMPLEMENTED_INTRINSIC(ReferenceGetReferent) UNIMPLEMENTED_INTRINSIC(StringGetCharsNoCheck) |