diff options
-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) |