diff options
| author | 2015-10-19 15:45:55 +0000 | |
|---|---|---|
| committer | 2015-10-19 15:45:55 +0000 | |
| commit | aeae32f846a04c9472fd3bdbbee92c0e1ace9b6c (patch) | |
| tree | 78a49ebd0052617c3bd7d0bc17ec0b9d3fd206a0 | |
| parent | a5903e622c0c11c1513a62e128a26d3cefd16c6f (diff) | |
| parent | 9aebff2f19b605bff864308be51b604b7191163e (diff) | |
Merge "MIPS64: Add intrinsic support for bit rotation"
| -rw-r--r-- | compiler/optimizing/intrinsics_mips64.cc | 63 | ||||
| -rw-r--r-- | compiler/utils/mips64/assembler_mips64.cc | 16 | ||||
| -rw-r--r-- | compiler/utils/mips64/assembler_mips64.h | 4 |
3 files changed, 81 insertions, 2 deletions
diff --git a/compiler/optimizing/intrinsics_mips64.cc b/compiler/optimizing/intrinsics_mips64.cc index a3121a93dc..fe16d00b72 100644 --- a/compiler/optimizing/intrinsics_mips64.cc +++ b/compiler/optimizing/intrinsics_mips64.cc @@ -336,6 +336,67 @@ void IntrinsicCodeGeneratorMIPS64::VisitLongNumberOfTrailingZeros(HInvoke* invok GenNumberOfTrailingZeroes(invoke->GetLocations(), true, GetAssembler()); } +static void GenRotateRight(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()) { + uint32_t shift = static_cast<uint32_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) { + __ Rotrv(out, in, shamt); + } else { + __ Drotrv(out, in, shamt); + } + } +} + +// int java.lang.Integer.rotateRight(int i, int distance) +void IntrinsicLocationsBuilderMIPS64::VisitIntegerRotateRight(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::VisitIntegerRotateRight(HInvoke* invoke) { + GenRotateRight(invoke, Primitive::kPrimInt, GetAssembler()); +} + +// int java.lang.Long.rotateRight(long i, int distance) +void IntrinsicLocationsBuilderMIPS64::VisitLongRotateRight(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::VisitLongRotateRight(HInvoke* invoke) { + GenRotateRight(invoke, Primitive::kPrimLong, GetAssembler()); +} + static void GenReverse(LocationSummary* locations, Primitive::Type type, Mips64Assembler* assembler) { @@ -1402,9 +1463,7 @@ UNIMPLEMENTED_INTRINSIC(UnsafeCASLong) UNIMPLEMENTED_INTRINSIC(UnsafeCASObject) UNIMPLEMENTED_INTRINSIC(StringEquals) UNIMPLEMENTED_INTRINSIC(LongRotateLeft) -UNIMPLEMENTED_INTRINSIC(LongRotateRight) UNIMPLEMENTED_INTRINSIC(IntegerRotateLeft) -UNIMPLEMENTED_INTRINSIC(IntegerRotateRight) UNIMPLEMENTED_INTRINSIC(ReferenceGetReferent) UNIMPLEMENTED_INTRINSIC(StringGetCharsNoCheck) diff --git a/compiler/utils/mips64/assembler_mips64.cc b/compiler/utils/mips64/assembler_mips64.cc index 7b4e6a3044..00e8995bff 100644 --- a/compiler/utils/mips64/assembler_mips64.cc +++ b/compiler/utils/mips64/assembler_mips64.cc @@ -335,6 +335,10 @@ void Mips64Assembler::Sllv(GpuRegister rd, GpuRegister rt, GpuRegister rs) { EmitR(0, rs, rt, rd, 0, 0x04); } +void Mips64Assembler::Rotrv(GpuRegister rd, GpuRegister rt, GpuRegister rs) { + EmitR(0, rs, rt, rd, 1, 0x06); +} + void Mips64Assembler::Srlv(GpuRegister rd, GpuRegister rt, GpuRegister rs) { EmitR(0, rs, rt, rd, 0, 0x06); } @@ -351,6 +355,10 @@ void Mips64Assembler::Dsrl(GpuRegister rd, GpuRegister rt, int shamt) { EmitR(0, static_cast<GpuRegister>(0), rt, rd, shamt, 0x3a); } +void Mips64Assembler::Drotr(GpuRegister rd, GpuRegister rt, int shamt) { + EmitR(0, static_cast<GpuRegister>(1), rt, rd, shamt, 0x3a); +} + void Mips64Assembler::Dsra(GpuRegister rd, GpuRegister rt, int shamt) { EmitR(0, static_cast<GpuRegister>(0), rt, rd, shamt, 0x3b); } @@ -363,6 +371,10 @@ void Mips64Assembler::Dsrl32(GpuRegister rd, GpuRegister rt, int shamt) { EmitR(0, static_cast<GpuRegister>(0), rt, rd, shamt, 0x3e); } +void Mips64Assembler::Drotr32(GpuRegister rd, GpuRegister rt, int shamt) { + EmitR(0, static_cast<GpuRegister>(1), rt, rd, shamt, 0x3e); +} + void Mips64Assembler::Dsra32(GpuRegister rd, GpuRegister rt, int shamt) { EmitR(0, static_cast<GpuRegister>(0), rt, rd, shamt, 0x3f); } @@ -375,6 +387,10 @@ void Mips64Assembler::Dsrlv(GpuRegister rd, GpuRegister rt, GpuRegister rs) { EmitR(0, rs, rt, rd, 0, 0x16); } +void Mips64Assembler::Drotrv(GpuRegister rd, GpuRegister rt, GpuRegister rs) { + EmitR(0, rs, rt, rd, 1, 0x16); +} + void Mips64Assembler::Dsrav(GpuRegister rd, GpuRegister rt, GpuRegister rs) { EmitR(0, rs, rt, rd, 0, 0x17); } diff --git a/compiler/utils/mips64/assembler_mips64.h b/compiler/utils/mips64/assembler_mips64.h index ac06521ec0..33f22d2c2d 100644 --- a/compiler/utils/mips64/assembler_mips64.h +++ b/compiler/utils/mips64/assembler_mips64.h @@ -123,15 +123,19 @@ class Mips64Assembler FINAL : public Assembler { void Sra(GpuRegister rd, GpuRegister rt, int shamt); void Sllv(GpuRegister rd, GpuRegister rt, GpuRegister rs); void Srlv(GpuRegister rd, GpuRegister rt, GpuRegister rs); + void Rotrv(GpuRegister rd, GpuRegister rt, GpuRegister rs); void Srav(GpuRegister rd, GpuRegister rt, GpuRegister rs); void Dsll(GpuRegister rd, GpuRegister rt, int shamt); // MIPS64 void Dsrl(GpuRegister rd, GpuRegister rt, int shamt); // MIPS64 + void Drotr(GpuRegister rd, GpuRegister rt, int shamt); void Dsra(GpuRegister rd, GpuRegister rt, int shamt); // MIPS64 void Dsll32(GpuRegister rd, GpuRegister rt, int shamt); // MIPS64 void Dsrl32(GpuRegister rd, GpuRegister rt, int shamt); // MIPS64 + void Drotr32(GpuRegister rd, GpuRegister rt, int shamt); // MIPS64 void Dsra32(GpuRegister rd, GpuRegister rt, int shamt); // MIPS64 void Dsllv(GpuRegister rd, GpuRegister rt, GpuRegister rs); // MIPS64 void Dsrlv(GpuRegister rd, GpuRegister rt, GpuRegister rs); // MIPS64 + void Drotrv(GpuRegister rd, GpuRegister rt, GpuRegister rs); // MIPS64 void Dsrav(GpuRegister rd, GpuRegister rt, GpuRegister rs); // MIPS64 void Lb(GpuRegister rt, GpuRegister rs, uint16_t imm16); |