Merge "MIPS32: java.lang.*.reverse" am: eddbfb74ae am: 9754484c2b
am: e54062b2d2
* commit 'e54062b2d2a4e2038f55822bc443248e1170cb3b':
MIPS32: java.lang.*.reverse
diff --git a/compiler/optimizing/intrinsics_mips.cc b/compiler/optimizing/intrinsics_mips.cc
index 3268445..9f16462 100644
--- a/compiler/optimizing/intrinsics_mips.cc
+++ b/compiler/optimizing/intrinsics_mips.cc
@@ -230,13 +230,16 @@
locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap);
}
-static void GenReverseBytes(LocationSummary* locations,
- Primitive::Type type,
- MipsAssembler* assembler,
- bool isR2OrNewer) {
+static void GenReverse(LocationSummary* locations,
+ Primitive::Type type,
+ bool isR2OrNewer,
+ bool isR6,
+ bool reverseBits,
+ MipsAssembler* assembler) {
DCHECK(type == Primitive::kPrimShort ||
type == Primitive::kPrimInt ||
type == Primitive::kPrimLong);
+ DCHECK(type != Primitive::kPrimShort || !reverseBits);
if (type == Primitive::kPrimShort) {
Register in = locations->InAt(0).AsRegister<Register>();
@@ -273,6 +276,30 @@
__ And(out, out, AT);
__ Or(out, out, TMP);
}
+ if (reverseBits) {
+ if (isR6) {
+ __ Bitswap(out, out);
+ } else {
+ __ LoadConst32(AT, 0x0F0F0F0F);
+ __ And(TMP, out, AT);
+ __ Sll(TMP, TMP, 4);
+ __ Srl(out, out, 4);
+ __ And(out, out, AT);
+ __ Or(out, TMP, out);
+ __ LoadConst32(AT, 0x33333333);
+ __ And(TMP, out, AT);
+ __ Sll(TMP, TMP, 2);
+ __ Srl(out, out, 2);
+ __ And(out, out, AT);
+ __ Or(out, TMP, out);
+ __ LoadConst32(AT, 0x55555555);
+ __ And(TMP, out, AT);
+ __ Sll(TMP, TMP, 1);
+ __ Srl(out, out, 1);
+ __ And(out, out, AT);
+ __ Or(out, TMP, out);
+ }
+ }
} else if (type == Primitive::kPrimLong) {
Register in_lo = locations->InAt(0).AsRegisterPairLow<Register>();
Register in_hi = locations->InAt(0).AsRegisterPairHigh<Register>();
@@ -314,6 +341,46 @@
__ And(out_lo, out_lo, AT);
__ Or(out_lo, out_lo, TMP);
}
+ if (reverseBits) {
+ if (isR6) {
+ __ Bitswap(out_hi, out_hi);
+ __ Bitswap(out_lo, out_lo);
+ } else {
+ __ LoadConst32(AT, 0x0F0F0F0F);
+ __ And(TMP, out_hi, AT);
+ __ Sll(TMP, TMP, 4);
+ __ Srl(out_hi, out_hi, 4);
+ __ And(out_hi, out_hi, AT);
+ __ Or(out_hi, TMP, out_hi);
+ __ And(TMP, out_lo, AT);
+ __ Sll(TMP, TMP, 4);
+ __ Srl(out_lo, out_lo, 4);
+ __ And(out_lo, out_lo, AT);
+ __ Or(out_lo, TMP, out_lo);
+ __ LoadConst32(AT, 0x33333333);
+ __ And(TMP, out_hi, AT);
+ __ Sll(TMP, TMP, 2);
+ __ Srl(out_hi, out_hi, 2);
+ __ And(out_hi, out_hi, AT);
+ __ Or(out_hi, TMP, out_hi);
+ __ And(TMP, out_lo, AT);
+ __ Sll(TMP, TMP, 2);
+ __ Srl(out_lo, out_lo, 2);
+ __ And(out_lo, out_lo, AT);
+ __ Or(out_lo, TMP, out_lo);
+ __ LoadConst32(AT, 0x55555555);
+ __ And(TMP, out_hi, AT);
+ __ Sll(TMP, TMP, 1);
+ __ Srl(out_hi, out_hi, 1);
+ __ And(out_hi, out_hi, AT);
+ __ Or(out_hi, TMP, out_hi);
+ __ And(TMP, out_lo, AT);
+ __ Sll(TMP, TMP, 1);
+ __ Srl(out_lo, out_lo, 1);
+ __ And(out_lo, out_lo, AT);
+ __ Or(out_lo, TMP, out_lo);
+ }
+ }
}
}
@@ -323,10 +390,12 @@
}
void IntrinsicCodeGeneratorMIPS::VisitIntegerReverseBytes(HInvoke* invoke) {
- GenReverseBytes(invoke->GetLocations(),
- Primitive::kPrimInt,
- GetAssembler(),
- codegen_->GetInstructionSetFeatures().IsMipsIsaRevGreaterThanEqual2());
+ GenReverse(invoke->GetLocations(),
+ Primitive::kPrimInt,
+ codegen_->GetInstructionSetFeatures().IsMipsIsaRevGreaterThanEqual2(),
+ codegen_->GetInstructionSetFeatures().IsR6(),
+ false,
+ GetAssembler());
}
// long java.lang.Long.reverseBytes(long)
@@ -335,10 +404,12 @@
}
void IntrinsicCodeGeneratorMIPS::VisitLongReverseBytes(HInvoke* invoke) {
- GenReverseBytes(invoke->GetLocations(),
- Primitive::kPrimLong,
- GetAssembler(),
- codegen_->GetInstructionSetFeatures().IsMipsIsaRevGreaterThanEqual2());
+ GenReverse(invoke->GetLocations(),
+ Primitive::kPrimLong,
+ codegen_->GetInstructionSetFeatures().IsMipsIsaRevGreaterThanEqual2(),
+ codegen_->GetInstructionSetFeatures().IsR6(),
+ false,
+ GetAssembler());
}
// short java.lang.Short.reverseBytes(short)
@@ -347,10 +418,40 @@
}
void IntrinsicCodeGeneratorMIPS::VisitShortReverseBytes(HInvoke* invoke) {
- GenReverseBytes(invoke->GetLocations(),
- Primitive::kPrimShort,
- GetAssembler(),
- codegen_->GetInstructionSetFeatures().IsMipsIsaRevGreaterThanEqual2());
+ GenReverse(invoke->GetLocations(),
+ Primitive::kPrimShort,
+ codegen_->GetInstructionSetFeatures().IsMipsIsaRevGreaterThanEqual2(),
+ codegen_->GetInstructionSetFeatures().IsR6(),
+ false,
+ GetAssembler());
+}
+
+// int java.lang.Integer.reverse(int)
+void IntrinsicLocationsBuilderMIPS::VisitIntegerReverse(HInvoke* invoke) {
+ CreateIntToIntLocations(arena_, invoke);
+}
+
+void IntrinsicCodeGeneratorMIPS::VisitIntegerReverse(HInvoke* invoke) {
+ GenReverse(invoke->GetLocations(),
+ Primitive::kPrimInt,
+ codegen_->GetInstructionSetFeatures().IsMipsIsaRevGreaterThanEqual2(),
+ codegen_->GetInstructionSetFeatures().IsR6(),
+ true,
+ GetAssembler());
+}
+
+// long java.lang.Long.reverse(long)
+void IntrinsicLocationsBuilderMIPS::VisitLongReverse(HInvoke* invoke) {
+ CreateIntToIntLocations(arena_, invoke);
+}
+
+void IntrinsicCodeGeneratorMIPS::VisitLongReverse(HInvoke* invoke) {
+ GenReverse(invoke->GetLocations(),
+ Primitive::kPrimLong,
+ codegen_->GetInstructionSetFeatures().IsMipsIsaRevGreaterThanEqual2(),
+ codegen_->GetInstructionSetFeatures().IsR6(),
+ true,
+ GetAssembler());
}
// boolean java.lang.String.equals(Object anObject)
@@ -463,8 +564,6 @@
void IntrinsicCodeGeneratorMIPS::Visit ## Name(HInvoke* invoke ATTRIBUTE_UNUSED) { \
}
-UNIMPLEMENTED_INTRINSIC(IntegerReverse)
-UNIMPLEMENTED_INTRINSIC(LongReverse)
UNIMPLEMENTED_INTRINSIC(LongNumberOfLeadingZeros)
UNIMPLEMENTED_INTRINSIC(IntegerNumberOfLeadingZeros)
UNIMPLEMENTED_INTRINSIC(MathAbsDouble)
diff --git a/compiler/utils/mips/assembler_mips.cc b/compiler/utils/mips/assembler_mips.cc
index fc7ac70..86e5762 100644
--- a/compiler/utils/mips/assembler_mips.cc
+++ b/compiler/utils/mips/assembler_mips.cc
@@ -314,6 +314,11 @@
EmitR(0x1f, static_cast<Register>(0), rt, rd, 2, 0x20);
}
+void MipsAssembler::Bitswap(Register rd, Register rt) {
+ CHECK(IsR6());
+ EmitR(0x1f, static_cast<Register>(0), rt, rd, 0x0, 0x20);
+}
+
void MipsAssembler::Sll(Register rd, Register rt, int shamt) {
CHECK(IsUint<5>(shamt)) << shamt;
EmitR(0, static_cast<Register>(0), rt, rd, shamt, 0x00);
diff --git a/compiler/utils/mips/assembler_mips.h b/compiler/utils/mips/assembler_mips.h
index 1ef0992..6a37cc9 100644
--- a/compiler/utils/mips/assembler_mips.h
+++ b/compiler/utils/mips/assembler_mips.h
@@ -136,6 +136,7 @@
void Seb(Register rd, Register rt); // R2+
void Seh(Register rd, Register rt); // R2+
void Wsbh(Register rd, Register rt); // R2+
+ void Bitswap(Register rd, Register rt); // R6
void Sll(Register rd, Register rt, int shamt);
void Srl(Register rd, Register rt, int shamt);