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