diff options
| -rw-r--r-- | compiler/optimizing/intrinsics_mips.cc | 65 | ||||
| -rw-r--r-- | test/082-inline-execute/src/Main.java | 104 |
2 files changed, 166 insertions, 3 deletions
diff --git a/compiler/optimizing/intrinsics_mips.cc b/compiler/optimizing/intrinsics_mips.cc index 5a35dd57a4..78b400dfef 100644 --- a/compiler/optimizing/intrinsics_mips.cc +++ b/compiler/optimizing/intrinsics_mips.cc @@ -1502,6 +1502,66 @@ void IntrinsicCodeGeneratorMIPS::VisitStringEquals(HInvoke* invoke) { __ 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, MathSinh) 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 @@ UNIMPLEMENTED_INTRINSIC(MIPS, LongLowestOneBit) UNREACHABLE_INTRINSICS(MIPS) +#undef UNIMPLEMENTED_INTRINSIC + #undef __ } // namespace mips diff --git a/test/082-inline-execute/src/Main.java b/test/082-inline-execute/src/Main.java index 93a9005fe0..9aaed9d589 100644 --- a/test/082-inline-execute/src/Main.java +++ b/test/082-inline-execute/src/Main.java @@ -40,6 +40,10 @@ public class Main { test_Math_rint(); test_Math_round_D(); test_Math_round_F(); + test_Math_isNaN_D(); + test_Math_isNaN_F(); + test_Math_isInfinite_D(); + test_Math_isInfinite_F(); test_Short_reverseBytes(); test_Integer_reverseBytes(); test_Long_reverseBytes(); @@ -836,6 +840,106 @@ public class Main { Assert.assertEquals(Math.round(Float.NEGATIVE_INFINITY), Integer.MIN_VALUE); } + public static void test_Math_isNaN_D() { + // Quiet NaN. + Assert.assertTrue(Double.isNaN(Double.longBitsToDouble(0x7FF4000000000000l))); + Assert.assertTrue(Double.isNaN(Double.longBitsToDouble(0xFFF4000000000000l))); + // Signaling NaN. + Assert.assertTrue(Double.isNaN(Double.longBitsToDouble(0x7FF8000000000000l))); + Assert.assertTrue(Double.isNaN(Double.longBitsToDouble(0xFFF8000000000000l))); + // Distinct from +/- infinity. + Assert.assertFalse(Double.isNaN(Double.longBitsToDouble(0x7FF0000000000000l))); + Assert.assertFalse(Double.isNaN(Double.longBitsToDouble(0xFFF0000000000000l))); + // Distinct from normal numbers. + Assert.assertFalse(Double.isNaN(Double.longBitsToDouble(0x7FE0000000000000l))); + Assert.assertFalse(Double.isNaN(Double.longBitsToDouble(0xFFE0000000000000l))); + Assert.assertFalse(Double.isNaN(Double.longBitsToDouble(0x0010000000000000l))); + Assert.assertFalse(Double.isNaN(Double.longBitsToDouble(0x8010000000000000l))); + // Distinct from +/- zero. + Assert.assertFalse(Double.isNaN(Double.longBitsToDouble(0x0000000000000000l))); + Assert.assertFalse(Double.isNaN(Double.longBitsToDouble(0x8000000000000000l))); + // Distinct from subnormal numbers. + Assert.assertFalse(Double.isNaN(Double.longBitsToDouble(0x0008000000000000l))); + Assert.assertFalse(Double.isNaN(Double.longBitsToDouble(0x8008000000000000l))); + Assert.assertFalse(Double.isNaN(Double.longBitsToDouble(0x0000000000000001l))); + Assert.assertFalse(Double.isNaN(Double.longBitsToDouble(0x8000000000000001l))); + } + + public static void test_Math_isNaN_F() { + // Quiet NaN. + Assert.assertTrue(Float.isNaN(Float.intBitsToFloat(0x7FA00000))); + Assert.assertTrue(Float.isNaN(Float.intBitsToFloat(0xFFA00000))); + // Signaling NaN. + Assert.assertTrue(Float.isNaN(Float.intBitsToFloat(0x7FC00000))); + Assert.assertTrue(Float.isNaN(Float.intBitsToFloat(0xFFC00000))); + // Distinct from +/- infinity. + Assert.assertFalse(Float.isNaN(Float.intBitsToFloat(0x7F800000))); + Assert.assertFalse(Float.isNaN(Float.intBitsToFloat(0xFF800000))); + // Distinct from normal numbers. + Assert.assertFalse(Float.isNaN(Float.intBitsToFloat(0x7F000000))); + Assert.assertFalse(Float.isNaN(Float.intBitsToFloat(0xFF000000))); + Assert.assertFalse(Float.isNaN(Float.intBitsToFloat(0x00800000))); + Assert.assertFalse(Float.isNaN(Float.intBitsToFloat(0x80800000))); + // Distinct from +/- zero. + Assert.assertFalse(Float.isNaN(Float.intBitsToFloat(0x00000000))); + Assert.assertFalse(Float.isNaN(Float.intBitsToFloat(0x80000000))); + // Distinct from subnormal numbers. + Assert.assertFalse(Float.isNaN(Float.intBitsToFloat(0x00400000))); + Assert.assertFalse(Float.isNaN(Float.intBitsToFloat(0x80400000))); + Assert.assertFalse(Float.isNaN(Float.intBitsToFloat(0x00000001))); + Assert.assertFalse(Float.isNaN(Float.intBitsToFloat(0x80000001))); + } + + public static void test_Math_isInfinite_D() { + // Distinct from Quiet NaN. + Assert.assertFalse(Double.isInfinite(Double.longBitsToDouble(0x7FF4000000000000l))); + Assert.assertFalse(Double.isInfinite(Double.longBitsToDouble(0xFFF4000000000000l))); + // Distinct from Signaling NaN. + Assert.assertFalse(Double.isInfinite(Double.longBitsToDouble(0x7FF8000000000000l))); + Assert.assertFalse(Double.isInfinite(Double.longBitsToDouble(0xFFF8000000000000l))); + // +/- infinity. + Assert.assertTrue(Double.isInfinite(Double.longBitsToDouble(0x7FF0000000000000l))); + Assert.assertTrue(Double.isInfinite(Double.longBitsToDouble(0xFFF0000000000000l))); + // Distinct from normal numbers. + Assert.assertFalse(Double.isInfinite(Double.longBitsToDouble(0x7FE0000000000000l))); + Assert.assertFalse(Double.isInfinite(Double.longBitsToDouble(0xFFE0000000000000l))); + Assert.assertFalse(Double.isInfinite(Double.longBitsToDouble(0x0010000000000000l))); + Assert.assertFalse(Double.isInfinite(Double.longBitsToDouble(0x8010000000000000l))); + // Distinct from +/- zero. + Assert.assertFalse(Double.isInfinite(Double.longBitsToDouble(0x0000000000000000l))); + Assert.assertFalse(Double.isInfinite(Double.longBitsToDouble(0x8000000000000000l))); + // Distinct from subnormal numbers. + Assert.assertFalse(Double.isInfinite(Double.longBitsToDouble(0x0008000000000000l))); + Assert.assertFalse(Double.isInfinite(Double.longBitsToDouble(0x8008000000000000l))); + Assert.assertFalse(Double.isInfinite(Double.longBitsToDouble(0x0000000000000001l))); + Assert.assertFalse(Double.isInfinite(Double.longBitsToDouble(0x8000000000000001l))); + } + + public static void test_Math_isInfinite_F() { + // Distinct from Quiet NaN. + Assert.assertFalse(Float.isInfinite(Float.intBitsToFloat(0x7FA00000))); + Assert.assertFalse(Float.isInfinite(Float.intBitsToFloat(0xFFA00000))); + // Distinct from Signaling NaN. + Assert.assertFalse(Float.isInfinite(Float.intBitsToFloat(0x7FC00000))); + Assert.assertFalse(Float.isInfinite(Float.intBitsToFloat(0xFFC00000))); + // +/- infinity. + Assert.assertTrue(Float.isInfinite(Float.intBitsToFloat(0x7F800000))); + Assert.assertTrue(Float.isInfinite(Float.intBitsToFloat(0xFF800000))); + // Distinct from normal numbers. + Assert.assertFalse(Float.isInfinite(Float.intBitsToFloat(0x7F000000))); + Assert.assertFalse(Float.isInfinite(Float.intBitsToFloat(0xFF000000))); + Assert.assertFalse(Float.isInfinite(Float.intBitsToFloat(0x00800000))); + Assert.assertFalse(Float.isInfinite(Float.intBitsToFloat(0x80800000))); + // Distinct from +/- zero. + Assert.assertFalse(Float.isInfinite(Float.intBitsToFloat(0x00000000))); + Assert.assertFalse(Float.isInfinite(Float.intBitsToFloat(0x80000000))); + // Distinct from subnormal numbers. + Assert.assertFalse(Float.isInfinite(Float.intBitsToFloat(0x00400000))); + Assert.assertFalse(Float.isInfinite(Float.intBitsToFloat(0x80400000))); + Assert.assertFalse(Float.isInfinite(Float.intBitsToFloat(0x00000001))); + Assert.assertFalse(Float.isInfinite(Float.intBitsToFloat(0x80000001))); + } + public static void test_StrictMath_abs_I() { StrictMath.abs(-1); Assert.assertEquals(StrictMath.abs(0), 0); |