Add tests for rootn() to math_conformance.

BUG=6319010

Change-Id: I3fa7d688e6f3b66f51a1c25a2c2104b659691c8b
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java
index 22e1bff..7105f2d 100644
--- a/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java
@@ -79,6 +79,7 @@
         unitTests.add(new UT_atomic(this, mRes, mCtx));
         unitTests.add(new UT_struct(this, mRes, mCtx));
         unitTests.add(new UT_math(this, mRes, mCtx));
+        unitTests.add(new UT_math_conformance(this, mRes, mCtx));
         unitTests.add(new UT_mesh(this, mRes, mCtx));
         unitTests.add(new UT_element(this, mRes, mCtx));
         unitTests.add(new UT_sampler(this, mRes, mCtx));
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_math_conformance.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_math_conformance.java
new file mode 100644
index 0000000..f256a3a
--- /dev/null
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_math_conformance.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.rs.test;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.renderscript.*;
+
+public class UT_math_conformance extends UnitTest {
+    private Resources mRes;
+
+    protected UT_math_conformance(RSTestCore rstc, Resources res, Context ctx) {
+        super(rstc, "Math Conformance", ctx);
+        mRes = res;
+    }
+
+    public void run() {
+        RenderScript pRS = RenderScript.create(mCtx);
+        ScriptC_math_conformance s =
+                new ScriptC_math_conformance(pRS, mRes, R.raw.math_conformance);
+        pRS.setMessageHandler(mRsMessage);
+        s.invoke_math_conformance_test();
+        pRS.finish();
+        waitForMessage();
+        pRS.destroy();
+        passTest();
+    }
+}
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/math_conformance.rs b/tests/RenderScriptTests/tests/src/com/android/rs/test/math_conformance.rs
new file mode 100644
index 0000000..2d62f34
--- /dev/null
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/math_conformance.rs
@@ -0,0 +1,57 @@
+#include "shared.rsh"
+
+// Testing math conformance
+
+static bool test_rootn() {
+    bool failed = false;
+
+    // rootn(x, 0) -> NaN
+    _RS_ASSERT(isnan(rootn(1.0f, 0)));
+
+    // rootn(+/-0, n) -> +/-inf for odd n < 0
+    _RS_ASSERT(isposinf(rootn(0.f, -3)));
+    _RS_ASSERT(isneginf(rootn(-0.f, -3)));
+
+    // rootn(+/-0, n) -> +inf for even n < 0
+    _RS_ASSERT(isposinf(rootn(0.f, -8)));
+    _RS_ASSERT(isposinf(rootn(-0.f, -8)));
+
+    // rootn(+/-0, n) -> +/-0 for odd n > 0
+    _RS_ASSERT(isposzero(rootn(0.f, 3)));
+    _RS_ASSERT(isnegzero(rootn(-0.f, 3)));
+
+    // rootn(+/-0, n) -> +0 for even n > 0
+    _RS_ASSERT(isposzero(rootn(0.f, 8)));
+    _RS_ASSERT(isposzero(rootn(-0.f, 8)));
+
+    // rootn(x, n) -> NaN for x < 0 and even n
+    _RS_ASSERT(isnan(rootn(-10000.f, -4)));
+    _RS_ASSERT(isnan(rootn(-10000.f, 4)));
+
+    // rootn(x, n) -> value for x < 0 and odd n
+    _RS_ASSERT(!isnan(rootn(-10000.f, -3)));
+    _RS_ASSERT(!isnan(rootn(-10000.f, 3)));
+
+    if (failed) {
+        rsDebug("test_rootn FAILED", -1);
+    }
+    else {
+        rsDebug("test_rootn PASSED", 0);
+    }
+
+    return failed;
+}
+
+void math_conformance_test() {
+    bool failed = false;
+    failed |= test_rootn();
+
+    if (failed) {
+        rsDebug("math_conformance_test FAILED", -1);
+        rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+    }
+    else {
+        rsDebug("math_conformance_test PASSED", 0);
+        rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+    }
+}
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/shared.rsh b/tests/RenderScriptTests/tests/src/com/android/rs/test/shared.rsh
index 21be9af..8cdf0d8 100644
--- a/tests/RenderScriptTests/tests/src/com/android/rs/test/shared.rsh
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/shared.rsh
@@ -32,6 +32,48 @@
 \
 } while (0)
 
+static const int iposinf = 0x7f800000;
+static const int ineginf = 0xff800000;
+
+static const float posinf() {
+    float f = *((float*)&iposinf);
+    return f;
+}
+
+static const float neginf() {
+    float f = *((float*)&ineginf);
+    return f;
+}
+
+static bool isposinf(float f) {
+    int i = *((int*)(void*)&f);
+    return (i == iposinf);
+}
+
+static bool isneginf(float f) {
+    int i = *((int*)(void*)&f);
+    return (i == ineginf);
+}
+
+static bool isnan(float f) {
+    int i = *((int*)(void*)&f);
+    return (((i & 0x7f800000) == 0x7f800000) && (i & 0x007fffff));
+}
+
+static bool isposzero(float f) {
+    int i = *((int*)(void*)&f);
+    return (i == 0x00000000);
+}
+
+static bool isnegzero(float f) {
+    int i = *((int*)(void*)&f);
+    return (i == 0x80000000);
+}
+
+static bool iszero(float f) {
+    return isposzero(f) || isnegzero(f);
+}
+
 /* These constants must match those in UnitTest.java */
 static const int RS_MSG_TEST_PASSED = 100;
 static const int RS_MSG_TEST_FAILED = 101;