MIPS32: Implement isInfinite intrinsics.
- boolean java.lang.Float.isInfinite(float)
- boolean java.lang.Double.isInfinite(double)
Change-Id: I17dc2380ec864fd7612025ed400e29dd115ccab4
diff --git a/compiler/optimizing/intrinsics_mips.cc b/compiler/optimizing/intrinsics_mips.cc
index 5a35dd5..78b400d 100644
--- a/compiler/optimizing/intrinsics_mips.cc
+++ b/compiler/optimizing/intrinsics_mips.cc
@@ -1502,6 +1502,66 @@
__ Bind(&end);
}
+static void GenIsInfinite(LocationSummary* locations,
+ const Primitive::Type type,
+ const bool isR6,
+ MipsAssembler* assembler) {
+ FRegister in = locations->InAt(0).AsFpuRegister<FRegister>();
+ Register out = locations->Out().AsRegister<Register>();
+
+ DCHECK(type == Primitive::kPrimFloat || type == Primitive::kPrimDouble);
+
+ if (isR6) {
+ if (type == Primitive::kPrimDouble) {
+ __ ClassD(FTMP, in);
+ } else {
+ __ ClassS(FTMP, in);
+ }
+ __ Mfc1(out, FTMP);
+ __ Andi(out, out, kPositiveInfinity | kNegativeInfinity);
+ __ Sltu(out, ZERO, out);
+ } else {
+ // If one, or more, of the exponent bits is zero, then the number can't be infinite.
+ if (type == Primitive::kPrimDouble) {
+ __ MoveFromFpuHigh(TMP, in);
+ __ LoadConst32(AT, 0x7FF00000);
+ } else {
+ __ Mfc1(TMP, in);
+ __ LoadConst32(AT, 0x7F800000);
+ }
+ __ Xor(TMP, TMP, AT);
+
+ __ Sll(TMP, TMP, 1);
+
+ if (type == Primitive::kPrimDouble) {
+ __ Mfc1(AT, in);
+ __ Or(TMP, TMP, AT);
+ }
+ // If any of the significand bits are one, then the number is not infinite.
+ __ Sltiu(out, TMP, 1);
+ }
+}
+
+// boolean java.lang.Float.isInfinite(float)
+void IntrinsicLocationsBuilderMIPS::VisitFloatIsInfinite(HInvoke* invoke) {
+ CreateFPToIntLocations(arena_, invoke);
+}
+
+void IntrinsicCodeGeneratorMIPS::VisitFloatIsInfinite(HInvoke* invoke) {
+ GenIsInfinite(invoke->GetLocations(), Primitive::kPrimFloat, IsR6(), GetAssembler());
+}
+
+// boolean java.lang.Double.isInfinite(double)
+void IntrinsicLocationsBuilderMIPS::VisitDoubleIsInfinite(HInvoke* invoke) {
+ CreateFPToIntLocations(arena_, invoke);
+}
+
+void IntrinsicCodeGeneratorMIPS::VisitDoubleIsInfinite(HInvoke* invoke) {
+ GenIsInfinite(invoke->GetLocations(), Primitive::kPrimDouble, IsR6(), GetAssembler());
+}
+
+// Unimplemented intrinsics.
+
UNIMPLEMENTED_INTRINSIC(MIPS, IntegerBitCount)
UNIMPLEMENTED_INTRINSIC(MIPS, LongBitCount)
@@ -1559,9 +1619,6 @@
UNIMPLEMENTED_INTRINSIC(MIPS, MathTan)
UNIMPLEMENTED_INTRINSIC(MIPS, MathTanh)
-UNIMPLEMENTED_INTRINSIC(MIPS, FloatIsInfinite)
-UNIMPLEMENTED_INTRINSIC(MIPS, DoubleIsInfinite)
-
UNIMPLEMENTED_INTRINSIC(MIPS, IntegerHighestOneBit)
UNIMPLEMENTED_INTRINSIC(MIPS, LongHighestOneBit)
UNIMPLEMENTED_INTRINSIC(MIPS, IntegerLowestOneBit)
@@ -1569,6 +1626,8 @@
UNREACHABLE_INTRINSICS(MIPS)
+#undef UNIMPLEMENTED_INTRINSIC
+
#undef __
} // namespace mips