diff --git a/CtsTestCaseList.mk b/CtsTestCaseList.mk
index 6de82f7..ce12fff 100644
--- a/CtsTestCaseList.mk
+++ b/CtsTestCaseList.mk
@@ -139,7 +139,10 @@
 cts_native_exes := \
 	NativeMediaTest_SL \
 	NativeMediaTest_XA \
-	bionic-unit-tests-cts \
+
+ifeq ($(HOST_OS)-$(HOST_ARCH),$(filter $(HOST_OS)-$(HOST_ARCH),linux-x86 linux-x86_64))
+cts_native_exes += bionic-unit-tests-cts
+endif
 
 cts_ui_tests := \
     CtsUiAutomatorTests
diff --git a/apps/CtsVerifier/Android.mk b/apps/CtsVerifier/Android.mk
index 397b39a..c227665 100644
--- a/apps/CtsVerifier/Android.mk
+++ b/apps/CtsVerifier/Android.mk
@@ -32,7 +32,15 @@
 
 LOCAL_PROGUARD_FLAG_FILES := proguard.flags
 
-LOCAL_SDK_VERSION := current
+# This can't be built against LOCAL_SDK_VERSION := current because
+# it depends on a static library that's built directly against the
+# platform.
+#
+# uncomment when b/13281332 is fixed
+# please also uncomment the equivalent code in
+# cts/tests/tests/hardware/Android.mk
+#
+# LOCAL_SDK_VERSION := current
 
 LOCAL_DEX_PREOPT := false
 
diff --git a/apps/CtsVerifier/res/layout/intent_driven_test.xml b/apps/CtsVerifier/res/layout/intent_driven_test.xml
index e23f441..00c1cf6 100644
--- a/apps/CtsVerifier/res/layout/intent_driven_test.xml
+++ b/apps/CtsVerifier/res/layout/intent_driven_test.xml
@@ -1,32 +1,30 @@
 <?xml version="1.0" encoding="utf-8"?>
 
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-                android:layout_width="match_parent"
-                android:layout_height="match_parent"
-                android:orientation="vertical"
-    >
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical">
 
   <ScrollView
       android:layout_width="match_parent"
       android:layout_height="0dp"
       android:layout_weight="1">
     <TextView android:id="@+id/info"
-              android:layout_width="match_parent"
-              android:layout_height="wrap_content"
-              android:textSize="18sp"
-              android:padding="5dp"
-              android:text="@string/dc_start_alarm_test_info"
-        />
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:textSize="18sp"
+        android:padding="5dp"
+        android:text="@string/dc_start_alarm_test_info"/>
   </ScrollView>
 
   <LinearLayout android:id="@+id/buttons"
-                android:orientation="horizontal"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"/>
+      android:orientation="horizontal"
+      android:layout_width="wrap_content"
+      android:layout_height="wrap_content"/>
 
     <LinearLayout
         android:layout_width="match_parent"
         android:layout_height="wrap_content">
-        <include layout="@layout/pass_fail_buttons"/>
-    </LinearLayout>
+      <include layout="@layout/pass_fail_buttons"/>
+  </LinearLayout>
 </LinearLayout>
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/formats/CameraFormatsActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/formats/CameraFormatsActivity.java
old mode 100644
new mode 100755
index d68d1da..3e52ed8
--- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/formats/CameraFormatsActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/formats/CameraFormatsActivity.java
@@ -34,13 +34,17 @@
 import android.os.Handler;
 import android.util.Log;
 import android.util.SparseArray;
+import android.view.Menu;
+import android.view.MenuItem;
 import android.view.View;
 import android.view.Surface;
 import android.view.TextureView;
 import android.widget.AdapterView;
 import android.widget.ArrayAdapter;
+import android.widget.Button;
 import android.widget.ImageView;
 import android.widget.Spinner;
+import android.widget.Toast;
 
 import java.io.IOException;
 import java.lang.InterruptedException;
@@ -100,11 +104,22 @@
     private TreeSet<String> mTestedCombinations = new TreeSet<String>();
     private TreeSet<String> mUntestedCombinations = new TreeSet<String>();
 
+    private int mAllCombinationsSize = 0;
+
+    // Menu to show the test progress
+    private static final int MENU_ID_PROGRESS = Menu.FIRST + 1;
+
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
         setContentView(R.layout.cf_main);
+
+        mAllCombinationsSize = calcAllCombinationsSize();
+
+        // disable "Pass" button until all combinations are tested
+        setPassButtonEnabled(false);
+
         setPassFailButtonClickListeners();
         setInfoResources(R.string.camera_format, R.string.cf_info, -1);
 
@@ -161,6 +176,36 @@
     }
 
     @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        menu.add(Menu.NONE, MENU_ID_PROGRESS, Menu.NONE, "Current Progress");
+        return super.onCreateOptionsMenu(menu);
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        boolean ret = true;
+        switch (item.getItemId()) {
+        case MENU_ID_PROGRESS:
+            showCombinationsDialog();
+            ret = true;
+            break;
+        default:
+            ret = super.onOptionsItemSelected(item);
+            break;
+        }
+        return ret;
+    }
+
+    private void showCombinationsDialog() {
+        AlertDialog.Builder builder =
+                new AlertDialog.Builder(CameraFormatsActivity.this);
+        builder.setMessage(getTestDetails())
+                .setTitle("Current Progress")
+                .setPositiveButton("OK", null);
+        builder.show();
+    }
+
+    @Override
     public void onResume() {
         super.onResume();
 
@@ -526,6 +571,12 @@
                             + "\n";
                     mUntestedCombinations.remove(combination);
                     mTestedCombinations.add(combination);
+
+                    displayToast(combination.replace("\n", ""));
+
+                    if (mTestedCombinations.size() == mAllCombinationsSize) {
+                        setPassButtonEnabled(true);
+                    }
                 }
             }
             mProcessInProgress = false;
@@ -533,6 +584,34 @@
 
     }
 
+    private void setPassButtonEnabled(boolean enabled) {
+        Button pass_button = (Button) findViewById(R.id.pass_button);
+        pass_button.setEnabled(enabled);
+    }
+
+    private int calcAllCombinationsSize() {
+        int allCombinationsSize = 0;
+        int numCameras = Camera.getNumberOfCameras();
+
+        for (int i = 0; i<numCameras; i++) {
+            // must release a Camera object before a new Camera object is created
+            shutdownCamera();
+
+            mCamera = Camera.open(i);
+            Camera.Parameters p = mCamera.getParameters();
+
+            allCombinationsSize +=
+                    p.getSupportedPreviewSizes().size() *   // resolutions
+                    p.getSupportedPreviewFormats().size();  // formats
+        }
+
+        return allCombinationsSize;
+    }
+
+    private void displayToast(String combination) {
+        Toast.makeText(this, "\"" + combination + "\"\n" + " has been tested.", Toast.LENGTH_LONG).show();
+    }
+
     public void onPreviewFrame(byte[] data, Camera camera) {
         if (mProcessInProgress || mState != STATE_PREVIEW) return;
 
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/AccelerometerMeasurementTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/AccelerometerMeasurementTestActivity.java
index bcd00ed..5a0af28 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/AccelerometerMeasurementTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/AccelerometerMeasurementTestActivity.java
@@ -18,7 +18,8 @@
 
 import android.hardware.Sensor;
 import android.hardware.SensorManager;
-import android.hardware.cts.helpers.sensorTestOperations.VerifyMeasurementsOperation;
+import android.hardware.cts.helpers.sensoroperations.TestSensorOperation;
+import android.hardware.cts.helpers.sensorverification.MeanVerification;
 
 import java.util.concurrent.TimeUnit;
 
@@ -72,22 +73,24 @@
      * - the values representing the expectation of the test
      * - the mean of values sampled from the sensor
      */
-    private void verifyMeasurements(double ... expectations) throws Throwable {
+    private void verifyMeasurements(float ... expectations) throws Throwable {
         Thread.sleep(500 /*ms*/);
-        VerifyMeasurementsOperation verifyMeasurements = new VerifyMeasurementsOperation(
+        TestSensorOperation verifyMeasurements = new TestSensorOperation(
                 getApplicationContext(),
                 Sensor.TYPE_ACCELEROMETER,
                 SensorManager.SENSOR_DELAY_FASTEST,
                 0 /*reportLatencyInUs*/,
+                100 /* event count */);
+        verifyMeasurements.addVerification(new MeanVerification(
                 expectations,
-                1.95f /* m / s^2 */);
+                new float[]{1.95f, 1.95f, 1.95f} /* m / s^2 */));
         verifyMeasurements.execute();
         logSuccess();
     }
 
     private void delayedVerifyMeasurements(
             String message,
-            double ... expectations) throws Throwable {
+            float ... expectations) throws Throwable {
         appendText(String.format("\n%s.", message));
         appendText("A sound will be played once the verification is complete...");
         waitForUser();
@@ -100,7 +103,7 @@
         }
     }
 
-    private void verifyMeasurements(String message, double ... expectations) throws Throwable {
+    private void verifyMeasurements(String message, float ... expectations) throws Throwable {
         appendText(String.format("\n%s.", message));
         appendText("Press 'Next' when ready and keep the device steady.");
         waitForUser();
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/GyroscopeMeasurementTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/GyroscopeMeasurementTestActivity.java
index 4bcdd56..066bda4 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/GyroscopeMeasurementTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/GyroscopeMeasurementTestActivity.java
@@ -18,7 +18,8 @@
 
 import android.hardware.Sensor;
 import android.hardware.SensorManager;
-import android.hardware.cts.helpers.sensorTestOperations.VerifySignumOperation;
+import android.hardware.cts.helpers.sensoroperations.TestSensorOperation;
+import android.hardware.cts.helpers.sensorverification.SigNumVerification;
 
 /**
  * Semi-automated test that focuses on characteristics associated with Accelerometer measurements.
@@ -96,12 +97,15 @@
         waitForUser();
 
         Thread.sleep(500 /*ms*/);
-        VerifySignumOperation verifySignum = new VerifySignumOperation(
+        TestSensorOperation verifySignum = new TestSensorOperation(
                 getApplicationContext(),
                 Sensor.TYPE_GYROSCOPE,
                 SensorManager.SENSOR_DELAY_FASTEST,
+                0 /*reportLatencyInUs*/,
+                100 /* event count */);
+        verifySignum.addVerification(new SigNumVerification(
                 expectations,
-                0.2 /*noiseThreshold*/);
+                new float[]{0.2f, 0.2f, 0.2f} /*noiseThreshold*/));
         verifySignum.execute();
         logSuccess();
     }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/MagneticFieldMeasurementTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/MagneticFieldMeasurementTestActivity.java
index ffed1ab..a131b2b 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/MagneticFieldMeasurementTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/MagneticFieldMeasurementTestActivity.java
@@ -19,10 +19,13 @@
 import android.graphics.Color;
 import android.hardware.Sensor;
 import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener2;
 import android.hardware.SensorManager;
-import android.hardware.cts.helpers.SensorManagerTestVerifier;
-import android.hardware.cts.helpers.sensorTestOperations.VerifyMagnitudeOperation;
-import android.hardware.cts.helpers.sensorTestOperations.VerifyStandardDeviationOperation;
+import android.hardware.cts.helpers.TestSensorEventListener;
+import android.hardware.cts.helpers.TestSensorManager;
+import android.hardware.cts.helpers.sensoroperations.TestSensorOperation;
+import android.hardware.cts.helpers.sensorverification.MagnitudeVerification;
+import android.hardware.cts.helpers.sensorverification.StandardDeviationVerification;
 
 /**
  * Semi-automated test that focuses characteristics associated with Accelerometer measurements.
@@ -43,27 +46,34 @@
     }
 
     private void calibrateMagnetometer() {
-        SensorManagerTestVerifier magnetometer = new SensorManagerTestVerifier(
-                this.getApplicationContext(),
-                Sensor.TYPE_MAGNETIC_FIELD,
-                SensorManager.SENSOR_DELAY_NORMAL,
-                0 /*reportLatencyInUs*/) {
+        SensorEventListener2 listener = new SensorEventListener2() {
             @Override
             public void onSensorChanged(SensorEvent event) {
                 float values[] = event.values;
                 clearText();
-                appendText(
-                        "Please calibrate the Magnetometer by moving it in 8 shapes in different " +
-                                "orientations.");
-                appendText(
-                        String.format("->  (%.2f, %.2f, %.2f) uT", values[0], values[1], values[2]),
-                        Color.GRAY);
+                appendText("Please calibrate the Magnetometer by moving it in 8 shapes in "
+                        + "different orientations.");
+                appendText(String.format("->  (%.2f, %.2f, %.2f) uT", values[0], values[1],
+                        values[2]), Color.GRAY);
                 appendText("Then leave the device in a flat surface and press Next...\n");
             }
+
+            @Override
+            public void onAccuracyChanged(Sensor sensor, int accuracy) {}
+
+            @Override
+            public void onFlushCompleted(Sensor sensor) {}
         };
-        magnetometer.registerListener();
-        waitForUser();
-        magnetometer.unregisterListener();
+
+        TestSensorManager magnetometer = new TestSensorManager(
+                this.getApplicationContext(), Sensor.TYPE_MAGNETIC_FIELD,
+                SensorManager.SENSOR_DELAY_NORMAL, 0);
+        try {
+            magnetometer.registerListener(new TestSensorEventListener(listener));
+            waitForUser();
+        } finally {
+            magnetometer.unregisterListener();
+        }
     }
 
     /**
@@ -91,12 +101,15 @@
                 (SensorManager.MAGNETIC_FIELD_EARTH_MAX + SensorManager.MAGNETIC_FIELD_EARTH_MIN) / 2;
         float magneticFieldEarthThreshold =
                 expectedMagneticFieldEarth - SensorManager.MAGNETIC_FIELD_EARTH_MIN;
-        VerifyMagnitudeOperation verifyNorm = new VerifyMagnitudeOperation(
+        TestSensorOperation verifyNorm = new TestSensorOperation(
                 this.getApplicationContext(),
                 Sensor.TYPE_MAGNETIC_FIELD,
                 SensorManager.SENSOR_DELAY_FASTEST,
+                0 /*reportLatencyInUs*/,
+                100 /* event count */);
+        verifyNorm.addVerification(new MagnitudeVerification(
                 expectedMagneticFieldEarth,
-                magneticFieldEarthThreshold);
+                magneticFieldEarthThreshold));
         verifyNorm.execute();
         logSuccess();
     }
@@ -125,12 +138,14 @@
      * the failure to help track down the issue.
      */
     private void verifyStandardDeviation() throws Throwable {
-        VerifyStandardDeviationOperation verifyStdDev = new VerifyStandardDeviationOperation(
+        TestSensorOperation verifyStdDev = new TestSensorOperation(
                 this.getApplicationContext(),
                 Sensor.TYPE_MAGNETIC_FIELD,
                 SensorManager.SENSOR_DELAY_FASTEST,
                 0 /*reportLatencyInUs*/,
-                2f /* uT */);
+                100 /* event count */);
+        verifyStdDev.addVerification(new StandardDeviationVerification(
+                new float[]{2f, 2f, 2f} /* uT */));
         verifyStdDev.execute();
         logSuccess();
     }
diff --git a/apps/cts-usb-accessory/Android.mk b/apps/cts-usb-accessory/Android.mk
index 76022a1..8d18da3 100644
--- a/apps/cts-usb-accessory/Android.mk
+++ b/apps/cts-usb-accessory/Android.mk
@@ -28,7 +28,7 @@
 
 LOCAL_C_INCLUDES += \
 	bionic/libc/kernel/uapi \
-	bionic/libc/kernel/uapi/asm-$(HOST_ARCH) \
+	bionic/libc/kernel/uapi/asm-x86 \
 
 LOCAL_STATIC_LIBRARIES := libusbhost libcutils
 LOCAL_LDLIBS += -lpthread
diff --git a/build/test_executable.mk b/build/test_executable.mk
index 0d42d02..fb41b73 100644
--- a/build/test_executable.mk
+++ b/build/test_executable.mk
@@ -29,11 +29,12 @@
 
 $(cts_executable_xml): PRIVATE_TEST_PACKAGE := $(LOCAL_CTS_TEST_PACKAGE)
 $(cts_executable_xml): PRIVATE_EXECUTABLE := $(LOCAL_MODULE)
-$(cts_executable_xml): PRIVATE_TEST_LIST := $(LOCAL_PATH)/$(LOCAL_MODULE)_list.txt
-$(cts_executable_xml): $(addprefix $(LOCAL_PATH)/,$(LOCAL_SRC_FILES)) $(CTS_EXPECTATIONS) $(CTS_NATIVE_TEST_SCANNER) $(CTS_XML_GENERATOR)
+$(cts_executable_xml): PRIVATE_LIST_EXECUTABLE := $(HOST_OUT_EXECUTABLES)/$(LOCAL_MODULE)_list
+$(cts_executable_xml): $(HOST_OUT_EXECUTABLES)/$(LOCAL_MODULE)_list
+$(cts_executable_xml): $(addprefix $(LOCAL_PATH)/,$(LOCAL_SRC_FILES)) $(CTS_EXPECTATIONS) $(CTS_NATIVE_TEST_SCANNER) $(CTS_XML_GENERATOR) $(cts_list_executable)
 	$(hide) echo Generating test description for native package $(PRIVATE_TEST_PACKAGE)
 	$(hide) mkdir -p $(CTS_TESTCASES_OUT)
-	$(hide) cat $(PRIVATE_TEST_LIST) | \
+	$(hide) $(PRIVATE_LIST_EXECUTABLE) --gtest_list_tests | \
 			$(CTS_NATIVE_TEST_SCANNER) -t $(PRIVATE_TEST_PACKAGE) | \
 			$(CTS_XML_GENERATOR) -t native \
 						-n $(PRIVATE_EXECUTABLE) \
diff --git a/hostsidetests/aadb/src/com/android/cts/aadb/TestDeviceStressTest.java b/hostsidetests/aadb/src/com/android/cts/aadb/TestDeviceStressTest.java
index c780fb9..2c6fcef 100644
--- a/hostsidetests/aadb/src/com/android/cts/aadb/TestDeviceStressTest.java
+++ b/hostsidetests/aadb/src/com/android/cts/aadb/TestDeviceStressTest.java
@@ -36,7 +36,7 @@
  */
 public class TestDeviceStressTest extends DeviceTestCase {
 
-    private int mIterations = 50;
+    private int mIterations = 25;
 
     private static final String LOG_TAG = "TestDeviceStressTest";
     private static final int TEST_FILE_COUNT= 200;
diff --git a/hostsidetests/appsecurity/test-apps/ExternalStorageApp/src/com/android/cts/externalstorageapp/CommonExternalStorageTest.java b/hostsidetests/appsecurity/test-apps/ExternalStorageApp/src/com/android/cts/externalstorageapp/CommonExternalStorageTest.java
index f38236b..5b4d9f7 100644
--- a/hostsidetests/appsecurity/test-apps/ExternalStorageApp/src/com/android/cts/externalstorageapp/CommonExternalStorageTest.java
+++ b/hostsidetests/appsecurity/test-apps/ExternalStorageApp/src/com/android/cts/externalstorageapp/CommonExternalStorageTest.java
@@ -274,8 +274,38 @@
         }
     }
 
+    private static boolean isWhiteList(File file) {
+        final String[] whiteLists = {
+                "autorun.inf", ".android_secure", "android_secure"
+        };
+        if (file.getParentFile().getAbsolutePath().equals(
+                Environment.getExternalStorageDirectory().getAbsolutePath())) {
+            for (String whiteList : whiteLists) {
+                if (file.getName().equalsIgnoreCase(whiteList)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    private static File[] removeWhiteList(File[] files) {
+        List<File> fileList = new ArrayList<File>();
+        if (files == null) {
+            return null;
+        }
+
+        for (File file : files) {
+            if (!isWhiteList(file)) {
+                fileList.add(file);
+            }
+        }
+        return fileList.toArray(new File[fileList.size()]);
+    }
+
     public static void deleteContents(File dir) throws IOException {
         File[] files = dir.listFiles();
+        files = removeWhiteList(files);
         if (files != null) {
             for (File file : files) {
                 if (file.isDirectory()) {
@@ -283,7 +313,9 @@
                 }
                 assertTrue(file.delete());
             }
-            assertEquals(0, dir.listFiles().length);
+
+            File[] dirs = removeWhiteList(dir.listFiles());
+            assertEquals(0, dirs.length);
         }
     }
 
diff --git a/libs/deviceutil/src/android/cts/util/DeviceReportLog.java b/libs/deviceutil/src/android/cts/util/DeviceReportLog.java
index b707fc8..a3ceecf 100644
--- a/libs/deviceutil/src/android/cts/util/DeviceReportLog.java
+++ b/libs/deviceutil/src/android/cts/util/DeviceReportLog.java
@@ -16,19 +16,24 @@
 
 package android.cts.util;
 
-import com.android.cts.util.ReportLog;
-
 import android.app.Instrumentation;
 import android.os.Bundle;
 import android.util.Log;
 
+import com.android.cts.util.ReportLog;
+
 public class DeviceReportLog extends ReportLog {
     private static final String TAG = "DeviceCtsReport";
     private static final String CTS_RESULT = "CTS_RESULT";
     private static final int INST_STATUS_IN_PROGRESS = 2;
+    private static final int BASE_DEPTH = 4;
 
-    DeviceReportLog() {
-        mDepth = 4;
+    public DeviceReportLog() {
+        mDepth = BASE_DEPTH;
+    }
+
+    public DeviceReportLog(int depth) {
+        mDepth = BASE_DEPTH + depth;
     }
 
     @Override
diff --git a/suite/audio_quality/executable/Android.mk b/suite/audio_quality/executable/Android.mk
index dfb67d0..a37b987 100644
--- a/suite/audio_quality/executable/Android.mk
+++ b/suite/audio_quality/executable/Android.mk
@@ -29,7 +29,7 @@
 LOCAL_STATIC_LIBRARIES += libutils liblog libcutils libtinyalsa libtinyxml
 LOCAL_WHOLE_STATIC_LIBRARIES := libcts_audio_quality
 LOCAL_CFLAGS:= -g -fno-exceptions
-LOCAL_LDFLAGS:= -g -lrt -ldl -lstdc++ -lm -fno-exceptions
+LOCAL_LDFLAGS:= -g -lrt -ldl -lstdc++ -lm -fno-exceptions -lpthread
 LOCAL_MODULE:= cts_audio_quality
 include $(BUILD_HOST_EXECUTABLE)
 
diff --git a/suite/audio_quality/lib/src/audio/AudioPlaybackLocal.cpp b/suite/audio_quality/lib/src/audio/AudioPlaybackLocal.cpp
index fe91cb3..06c92d6 100644
--- a/suite/audio_quality/lib/src/audio/AudioPlaybackLocal.cpp
+++ b/suite/audio_quality/lib/src/audio/AudioPlaybackLocal.cpp
@@ -42,12 +42,12 @@
     : mHwId(hwId),
       mPcmHandle(NULL)
 {
-    LOGV("AudioPlaybackLocal %x", (unsigned int)this);
+    LOGV("AudioPlaybackLocal %x", (unsigned long)this);
 }
 
 AudioPlaybackLocal::~AudioPlaybackLocal()
 {
-    LOGV("~AudioPlaybackLocal %x", (unsigned int)this);
+    LOGV("~AudioPlaybackLocal %x", (unsigned long)this);
     releaseHw();
 }
 
@@ -108,7 +108,7 @@
 void AudioPlaybackLocal::releaseHw()
 {
     if (mPcmHandle != NULL) {
-        LOGV("releaseHw %x", (unsigned int)this);
+        LOGV("releaseHw %x", (unsigned long)this);
         doStop();
         pcm_close(mPcmHandle);
         mPcmHandle = NULL;
diff --git a/suite/audio_quality/lib/src/audio/AudioRecordingLocal.cpp b/suite/audio_quality/lib/src/audio/AudioRecordingLocal.cpp
index 1325949..eda705d 100644
--- a/suite/audio_quality/lib/src/audio/AudioRecordingLocal.cpp
+++ b/suite/audio_quality/lib/src/audio/AudioRecordingLocal.cpp
@@ -29,12 +29,12 @@
     : mHwId(hwId),
       mPcmHandle(NULL)
 {
-    LOGV("AudioRecordingLocal %x", (unsigned int)this);
+    LOGV("AudioRecordingLocal %x", (unsigned long)this);
 }
 
 AudioRecordingLocal::~AudioRecordingLocal()
 {
-    LOGV("~AudioRecordingLocal %x", (unsigned int)this);
+    LOGV("~AudioRecordingLocal %x", (unsigned long)this);
     releaseHw();
 }
 
@@ -97,7 +97,7 @@
 void AudioRecordingLocal::releaseHw()
 {
     if (mPcmHandle != NULL) {
-        LOGV("releaseHw %x", (unsigned int)this);
+        LOGV("releaseHw %x", (unsigned long)this);
         doStop();
         pcm_close(mPcmHandle);
         mPcmHandle = NULL;
diff --git a/suite/audio_quality/lib/src/task/TaskProcess.cpp b/suite/audio_quality/lib/src/task/TaskProcess.cpp
index f1e47af..061dda5 100644
--- a/suite/audio_quality/lib/src/task/TaskProcess.cpp
+++ b/suite/audio_quality/lib/src/task/TaskProcess.cpp
@@ -271,7 +271,7 @@
             list.push_back(param);
             LOGD(" val %s", param.getParamString().string());
         } else if (isInput && (StringUtil::compare(item[0], "consti") == 0)) {
-            long long value = atoll(item[1].string());
+            int64_t value = atoll(item[1].string());
             TaskCase::Value v(value);
             Param param(v);
             list.push_back(param);
diff --git a/suite/audio_quality/test/Android.mk b/suite/audio_quality/test/Android.mk
index 9e32557..4582fe7 100644
--- a/suite/audio_quality/test/Android.mk
+++ b/suite/audio_quality/test/Android.mk
@@ -34,7 +34,7 @@
 # functions and linker error happens
 LOCAL_WHOLE_STATIC_LIBRARIES := libcts_audio_quality
 LOCAL_CFLAGS:= -g -fno-exceptions
-LOCAL_LDFLAGS:= -g -lrt -ldl -lstdc++ -lm -fno-exceptions
+LOCAL_LDFLAGS:= -g -lrt -ldl -lstdc++ -lm -fno-exceptions -lpthread
 LOCAL_MODULE:= cts_audio_quality_test
 include $(BUILD_HOST_EXECUTABLE)
 
diff --git a/suite/cts/deviceTests/dram/Android.mk b/suite/cts/deviceTests/dram/Android.mk
index 1935483..861a313 100644
--- a/suite/cts/deviceTests/dram/Android.mk
+++ b/suite/cts/deviceTests/dram/Android.mk
@@ -16,7 +16,7 @@
 include $(CLEAR_VARS)
 
 # don't include this package in any target
-LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TAGS := tests
 
 LOCAL_JAVA_LIBRARIES := android.test.runner
 
diff --git a/suite/cts/deviceTests/filesystemperf/src/com/android/cts/filesystemperf/FileUtil.java b/suite/cts/deviceTests/filesystemperf/src/com/android/cts/filesystemperf/FileUtil.java
old mode 100644
new mode 100755
index b342b61..6231774
--- a/suite/cts/deviceTests/filesystemperf/src/com/android/cts/filesystemperf/FileUtil.java
+++ b/suite/cts/deviceTests/filesystemperf/src/com/android/cts/filesystemperf/FileUtil.java
@@ -244,6 +244,7 @@
         long memSize = SystemUtil.getTotalMemory(context);
         long diskSizeTarget = (2 * memSize / bufferSize) * bufferSize;
         final long minimumDiskSize = (512L * 1024L * 1024L / bufferSize) * bufferSize;
+        final long reservedDiskSize = (50L * 1024L * 1024L / bufferSize) * bufferSize;
         if ( diskSizeTarget < minimumDiskSize ) {
             diskSizeTarget = minimumDiskSize;
         }
@@ -251,6 +252,9 @@
             Log.i(TAG, "Free disk size " + freeDisk + " too small");
             return 0;
         }
+        if ((freeDisk - diskSizeTarget) < reservedDiskSize) {
+            diskSizeTarget -= reservedDiskSize;
+        }
         return diskSizeTarget;
     }
 
diff --git a/suite/cts/deviceTests/opengl/Android.mk b/suite/cts/deviceTests/opengl/Android.mk
index 1b7d42b..8617436 100644
--- a/suite/cts/deviceTests/opengl/Android.mk
+++ b/suite/cts/deviceTests/opengl/Android.mk
@@ -16,7 +16,7 @@
 include $(CLEAR_VARS)
 
 # don't include this package in any target
-LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TAGS := tests
 
 LOCAL_JAVA_LIBRARIES := android.test.runner
 
@@ -32,4 +32,4 @@
 
 include $(BUILD_CTS_PACKAGE)
 
-include $(call all-makefiles-under,$(LOCAL_PATH))
\ No newline at end of file
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/suite/cts/deviceTests/opengl/jni/graphics/GLUtils.cpp b/suite/cts/deviceTests/opengl/jni/graphics/GLUtils.cpp
index 9076f39..ea166a1 100644
--- a/suite/cts/deviceTests/opengl/jni/graphics/GLUtils.cpp
+++ b/suite/cts/deviceTests/opengl/jni/graphics/GLUtils.cpp
@@ -77,7 +77,8 @@
 }
 
 static int readInt(char* b) {
-    return (((int) b[0]) << 24) | (((int) b[1]) << 16) | (((int) b[2]) << 8) | ((int) b[3]);
+    unsigned char* ub = (unsigned char*) b;
+    return (((int) ub[0]) << 24) | (((int) ub[1]) << 16) | (((int) ub[2]) << 8) | ((int) ub[3]);
 }
 
 static float readFloat(char* b) {
diff --git a/suite/cts/deviceTests/opengl/test/Android.mk b/suite/cts/deviceTests/opengl/test/Android.mk
index b571dbf..a4abe4f 100644
--- a/suite/cts/deviceTests/opengl/test/Android.mk
+++ b/suite/cts/deviceTests/opengl/test/Android.mk
@@ -27,7 +27,7 @@
 #$(info $(LOCAL_SRC_FILES))
 LOCAL_C_INCLUDES += external/gtest/include $(LOCAL_PATH)/../jni/graphics/
 LOCAL_STATIC_LIBRARIES := libutils libcutils libgtest_host libgtest_main_host liblog
-LOCAL_LDFLAGS:= -g -lrt -ldl -lstdc++ -lm -fno-exceptions
+LOCAL_LDFLAGS:= -g -lrt -ldl -lstdc++ -lm -fno-exceptions -lpthread
 LOCAL_MODULE:= cts_device_opengl_test
 include $(BUILD_HOST_EXECUTABLE)
 
diff --git a/suite/cts/deviceTests/simplecpu/Android.mk b/suite/cts/deviceTests/simplecpu/Android.mk
index 003b0f2..0cc73cc 100644
--- a/suite/cts/deviceTests/simplecpu/Android.mk
+++ b/suite/cts/deviceTests/simplecpu/Android.mk
@@ -16,7 +16,7 @@
 include $(CLEAR_VARS)
 
 # don't include this package in any target
-LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TAGS := tests
 
 LOCAL_JAVA_LIBRARIES := android.test.runner
 
diff --git a/tests/Android.mk b/tests/Android.mk
index a4cc38f..6621518 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -30,6 +30,7 @@
 # Resource unit tests use a private locale and some densities
 LOCAL_AAPT_FLAGS = -c xx_YY -c cs -c small -c normal -c large -c xlarge \
         -c 320dpi -c 240dpi -c 160dpi -c 32dpi \
+	-c kok,kok_IN,kok_419,kok_419_VARIANT,kok_Knda_419,kok_Knda_419_VARIANT,kok_VARIANT,kok_Knda,tgl,tgl_PH \
         --preferred-configurations 320dpi --preferred-configurations 240dpi \
         --preferred-configurations 160dpi --preferred-configurations 32dpi
 
diff --git a/tests/SignatureTest/Android.mk b/tests/SignatureTest/Android.mk
index 209e78a..696f99e 100644
--- a/tests/SignatureTest/Android.mk
+++ b/tests/SignatureTest/Android.mk
@@ -44,8 +44,6 @@
 
 include $(BUILD_CTS_PACKAGE)
 
-$(info $(call local-intermediates-dir))
-
 generated_res_stamp := $(intermediates.COMMON)/genres.stamp
 api_ver_file := $(intermediates.COMMON)/api_ver_is_$(CTS_API_VERSION)
 
diff --git a/tests/core/libcore/com/Android.mk b/tests/core/libcore/com/Android.mk
index 02dc3de..db08dbd 100644
--- a/tests/core/libcore/com/Android.mk
+++ b/tests/core/libcore/com/Android.mk
@@ -14,10 +14,6 @@
 
 LOCAL_PATH:= $(call my-dir)
 
-ifeq ($(BUILD_CTSCORE_PACKAGE),)
-    $(error BUILD_CTSCORE_PACKAGE must be defined)
-endif
-
 include $(CLEAR_VARS)
 LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.com
 LOCAL_STATIC_JAVA_LIBRARIES := core-tests
diff --git a/tests/core/libcore/dalvik/Android.mk b/tests/core/libcore/dalvik/Android.mk
index 7b77a75..42d14f3 100644
--- a/tests/core/libcore/dalvik/Android.mk
+++ b/tests/core/libcore/dalvik/Android.mk
@@ -14,10 +14,6 @@
 
 LOCAL_PATH:= $(call my-dir)
 
-ifeq ($(BUILD_CTSCORE_PACKAGE),)
-    $(error BUILD_CTSCORE_PACKAGE must be defined)
-endif
-
 include $(CLEAR_VARS)
 LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.dalvik
 LOCAL_STATIC_JAVA_LIBRARIES := core-tests
diff --git a/tests/core/libcore/harmony_annotation/Android.mk b/tests/core/libcore/harmony_annotation/Android.mk
new file mode 100644
index 0000000..e9f716e
--- /dev/null
+++ b/tests/core/libcore/harmony_annotation/Android.mk
@@ -0,0 +1,24 @@
+# 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+ifeq ($(BUILD_CTSCORE_PACKAGE),)
+    $(error BUILD_CTSCORE_PACKAGE must be defined)
+endif
+
+include $(CLEAR_VARS)
+LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.harmony_annotation
+LOCAL_STATIC_JAVA_LIBRARIES := core-tests
+include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/harmony_annotation/AndroidManifest.xml b/tests/core/libcore/harmony_annotation/AndroidManifest.xml
new file mode 100644
index 0000000..0c59b1b
--- /dev/null
+++ b/tests/core/libcore/harmony_annotation/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.core.tests.libcore.package.harmony_annotation">
+    <uses-permission android:name="android.permission.INTERNET" />
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="android.test.InstrumentationCtsTestRunner"
+                     android:targetPackage="android.core.tests.runner"
+                     android:label="cts framework tests"/>
+
+</manifest>
diff --git a/tests/core/libcore/harmony_beans/Android.mk b/tests/core/libcore/harmony_beans/Android.mk
new file mode 100644
index 0000000..2131ae0
--- /dev/null
+++ b/tests/core/libcore/harmony_beans/Android.mk
@@ -0,0 +1,24 @@
+# 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+ifeq ($(BUILD_CTSCORE_PACKAGE),)
+    $(error BUILD_CTSCORE_PACKAGE must be defined)
+endif
+
+include $(CLEAR_VARS)
+LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.harmony_beans
+LOCAL_STATIC_JAVA_LIBRARIES := apache-harmony-tests
+include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/harmony_beans/AndroidManifest.xml b/tests/core/libcore/harmony_beans/AndroidManifest.xml
new file mode 100644
index 0000000..b4932dd
--- /dev/null
+++ b/tests/core/libcore/harmony_beans/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.core.tests.libcore.package.harmony_beans">
+    <uses-permission android:name="android.permission.INTERNET" />
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="android.test.InstrumentationCtsTestRunner"
+                     android:targetPackage="android.core.tests.runner"
+                     android:label="cts framework tests"/>
+
+</manifest>
diff --git a/tests/core/libcore/harmony_java_io/Android.mk b/tests/core/libcore/harmony_java_io/Android.mk
new file mode 100644
index 0000000..a8d4fa0
--- /dev/null
+++ b/tests/core/libcore/harmony_java_io/Android.mk
@@ -0,0 +1,24 @@
+# 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+ifeq ($(BUILD_CTSCORE_PACKAGE),)
+    $(error BUILD_CTSCORE_PACKAGE must be defined)
+endif
+
+include $(CLEAR_VARS)
+LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.harmony_java_io
+LOCAL_STATIC_JAVA_LIBRARIES := core-tests
+include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/harmony_java_io/AndroidManifest.xml b/tests/core/libcore/harmony_java_io/AndroidManifest.xml
new file mode 100644
index 0000000..65d64ab
--- /dev/null
+++ b/tests/core/libcore/harmony_java_io/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.core.tests.libcore.package.harmony_java_io">
+    <uses-permission android:name="android.permission.INTERNET" />
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="android.test.InstrumentationCtsTestRunner"
+                     android:targetPackage="android.core.tests.runner"
+                     android:label="cts framework tests"/>
+
+</manifest>
diff --git a/tests/core/libcore/harmony_java_lang/Android.mk b/tests/core/libcore/harmony_java_lang/Android.mk
new file mode 100644
index 0000000..8b1bdff
--- /dev/null
+++ b/tests/core/libcore/harmony_java_lang/Android.mk
@@ -0,0 +1,24 @@
+# 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+ifeq ($(BUILD_CTSCORE_PACKAGE),)
+    $(error BUILD_CTSCORE_PACKAGE must be defined)
+endif
+
+include $(CLEAR_VARS)
+LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.harmony_java_lang
+LOCAL_STATIC_JAVA_LIBRARIES := core-tests
+include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/harmony_java_lang/AndroidManifest.xml b/tests/core/libcore/harmony_java_lang/AndroidManifest.xml
new file mode 100644
index 0000000..a5e499a
--- /dev/null
+++ b/tests/core/libcore/harmony_java_lang/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.core.tests.libcore.package.harmony_java_lang">
+    <uses-permission android:name="android.permission.INTERNET" />
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="android.test.InstrumentationCtsTestRunner"
+                     android:targetPackage="android.core.tests.runner"
+                     android:label="cts framework tests"/>
+
+</manifest>
diff --git a/tests/core/libcore/harmony_java_math/Android.mk b/tests/core/libcore/harmony_java_math/Android.mk
new file mode 100644
index 0000000..8310743
--- /dev/null
+++ b/tests/core/libcore/harmony_java_math/Android.mk
@@ -0,0 +1,24 @@
+# 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+ifeq ($(BUILD_CTSCORE_PACKAGE),)
+    $(error BUILD_CTSCORE_PACKAGE must be defined)
+endif
+
+include $(CLEAR_VARS)
+LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.harmony_java_math
+LOCAL_STATIC_JAVA_LIBRARIES := core-tests
+include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/harmony_java_math/AndroidManifest.xml b/tests/core/libcore/harmony_java_math/AndroidManifest.xml
new file mode 100644
index 0000000..f8cd224
--- /dev/null
+++ b/tests/core/libcore/harmony_java_math/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.core.tests.libcore.package.harmony_java_math">
+    <uses-permission android:name="android.permission.INTERNET" />
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="android.test.InstrumentationCtsTestRunner"
+                     android:targetPackage="android.core.tests.runner"
+                     android:label="cts framework tests"/>
+
+</manifest>
diff --git a/tests/core/libcore/harmony_java_net/Android.mk b/tests/core/libcore/harmony_java_net/Android.mk
new file mode 100644
index 0000000..7917bcc
--- /dev/null
+++ b/tests/core/libcore/harmony_java_net/Android.mk
@@ -0,0 +1,24 @@
+# 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+ifeq ($(BUILD_CTSCORE_PACKAGE),)
+    $(error BUILD_CTSCORE_PACKAGE must be defined)
+endif
+
+include $(CLEAR_VARS)
+LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.harmony_java_net
+LOCAL_STATIC_JAVA_LIBRARIES := core-tests
+include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/harmony_java_net/AndroidManifest.xml b/tests/core/libcore/harmony_java_net/AndroidManifest.xml
new file mode 100644
index 0000000..3c9fd63
--- /dev/null
+++ b/tests/core/libcore/harmony_java_net/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.core.tests.libcore.package.harmony_java_net">
+    <uses-permission android:name="android.permission.INTERNET" />
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="android.test.InstrumentationCtsTestRunner"
+                     android:targetPackage="android.core.tests.runner"
+                     android:label="cts framework tests"/>
+
+</manifest>
diff --git a/tests/core/libcore/harmony_java_nio/Android.mk b/tests/core/libcore/harmony_java_nio/Android.mk
new file mode 100644
index 0000000..2c6f673
--- /dev/null
+++ b/tests/core/libcore/harmony_java_nio/Android.mk
@@ -0,0 +1,24 @@
+# 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+ifeq ($(BUILD_CTSCORE_PACKAGE),)
+    $(error BUILD_CTSCORE_PACKAGE must be defined)
+endif
+
+include $(CLEAR_VARS)
+LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.harmony_java_nio
+LOCAL_STATIC_JAVA_LIBRARIES := core-tests
+include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/harmony_java_nio/AndroidManifest.xml b/tests/core/libcore/harmony_java_nio/AndroidManifest.xml
new file mode 100644
index 0000000..27166d4
--- /dev/null
+++ b/tests/core/libcore/harmony_java_nio/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.core.tests.libcore.package.harmony_java_nio">
+    <uses-permission android:name="android.permission.INTERNET" />
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="android.test.InstrumentationCtsTestRunner"
+                     android:targetPackage="android.core.tests.runner"
+                     android:label="cts framework tests"/>
+
+</manifest>
diff --git a/tests/core/libcore/harmony_java_text/Android.mk b/tests/core/libcore/harmony_java_text/Android.mk
new file mode 100644
index 0000000..ecd1574
--- /dev/null
+++ b/tests/core/libcore/harmony_java_text/Android.mk
@@ -0,0 +1,24 @@
+# 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+ifeq ($(BUILD_CTSCORE_PACKAGE),)
+    $(error BUILD_CTSCORE_PACKAGE must be defined)
+endif
+
+include $(CLEAR_VARS)
+LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.harmony_java_text
+LOCAL_STATIC_JAVA_LIBRARIES := core-tests
+include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/harmony_java_text/AndroidManifest.xml b/tests/core/libcore/harmony_java_text/AndroidManifest.xml
new file mode 100644
index 0000000..0b6beed
--- /dev/null
+++ b/tests/core/libcore/harmony_java_text/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.core.tests.libcore.package.harmony_java_text">
+    <uses-permission android:name="android.permission.INTERNET" />
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="android.test.InstrumentationCtsTestRunner"
+                     android:targetPackage="android.core.tests.runner"
+                     android:label="cts framework tests"/>
+
+</manifest>
diff --git a/tests/core/libcore/harmony_java_util/Android.mk b/tests/core/libcore/harmony_java_util/Android.mk
new file mode 100644
index 0000000..6d7bded
--- /dev/null
+++ b/tests/core/libcore/harmony_java_util/Android.mk
@@ -0,0 +1,24 @@
+# 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+ifeq ($(BUILD_CTSCORE_PACKAGE),)
+    $(error BUILD_CTSCORE_PACKAGE must be defined)
+endif
+
+include $(CLEAR_VARS)
+LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.harmony_java_util
+LOCAL_STATIC_JAVA_LIBRARIES := core-tests
+include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/harmony_java_util/AndroidManifest.xml b/tests/core/libcore/harmony_java_util/AndroidManifest.xml
new file mode 100644
index 0000000..72fa3ef
--- /dev/null
+++ b/tests/core/libcore/harmony_java_util/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.core.tests.libcore.package.harmony_java_util">
+    <uses-permission android:name="android.permission.INTERNET" />
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="android.test.InstrumentationCtsTestRunner"
+                     android:targetPackage="android.core.tests.runner"
+                     android:label="cts framework tests"/>
+
+</manifest>
diff --git a/tests/core/libcore/harmony_javax_security/Android.mk b/tests/core/libcore/harmony_javax_security/Android.mk
new file mode 100644
index 0000000..011940d
--- /dev/null
+++ b/tests/core/libcore/harmony_javax_security/Android.mk
@@ -0,0 +1,24 @@
+# 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+ifeq ($(BUILD_CTSCORE_PACKAGE),)
+    $(error BUILD_CTSCORE_PACKAGE must be defined)
+endif
+
+include $(CLEAR_VARS)
+LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.harmony_javax_security
+LOCAL_STATIC_JAVA_LIBRARIES := core-tests
+include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/harmony_javax_security/AndroidManifest.xml b/tests/core/libcore/harmony_javax_security/AndroidManifest.xml
new file mode 100644
index 0000000..b7b35f2
--- /dev/null
+++ b/tests/core/libcore/harmony_javax_security/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.core.tests.libcore.package.harmony_javax_security">
+    <uses-permission android:name="android.permission.INTERNET" />
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="android.test.InstrumentationCtsTestRunner"
+                     android:targetPackage="android.core.tests.runner"
+                     android:label="cts framework tests"/>
+
+</manifest>
diff --git a/tests/core/libcore/harmony_logging/Android.mk b/tests/core/libcore/harmony_logging/Android.mk
new file mode 100644
index 0000000..2ec10f1
--- /dev/null
+++ b/tests/core/libcore/harmony_logging/Android.mk
@@ -0,0 +1,24 @@
+# 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+ifeq ($(BUILD_CTSCORE_PACKAGE),)
+    $(error BUILD_CTSCORE_PACKAGE must be defined)
+endif
+
+include $(CLEAR_VARS)
+LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.harmony_logging
+LOCAL_STATIC_JAVA_LIBRARIES := apache-harmony-tests
+include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/harmony_logging/AndroidManifest.xml b/tests/core/libcore/harmony_logging/AndroidManifest.xml
new file mode 100644
index 0000000..94ee60e
--- /dev/null
+++ b/tests/core/libcore/harmony_logging/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.core.tests.libcore.package.harmony_logging">
+    <uses-permission android:name="android.permission.INTERNET" />
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="android.test.InstrumentationCtsTestRunner"
+                     android:targetPackage="android.core.tests.runner"
+                     android:label="cts framework tests"/>
+
+</manifest>
diff --git a/tests/core/libcore/harmony_prefs/Android.mk b/tests/core/libcore/harmony_prefs/Android.mk
new file mode 100644
index 0000000..92b0c7d
--- /dev/null
+++ b/tests/core/libcore/harmony_prefs/Android.mk
@@ -0,0 +1,24 @@
+# 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+ifeq ($(BUILD_CTSCORE_PACKAGE),)
+    $(error BUILD_CTSCORE_PACKAGE must be defined)
+endif
+
+include $(CLEAR_VARS)
+LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.harmony_prefs
+LOCAL_STATIC_JAVA_LIBRARIES := apache-harmony-tests
+include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/harmony_prefs/AndroidManifest.xml b/tests/core/libcore/harmony_prefs/AndroidManifest.xml
new file mode 100644
index 0000000..f8fdea2
--- /dev/null
+++ b/tests/core/libcore/harmony_prefs/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.core.tests.libcore.package.harmony_prefs">
+    <uses-permission android:name="android.permission.INTERNET" />
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="android.test.InstrumentationCtsTestRunner"
+                     android:targetPackage="android.core.tests.runner"
+                     android:label="cts framework tests"/>
+
+</manifest>
diff --git a/tests/core/libcore/harmony_sql/Android.mk b/tests/core/libcore/harmony_sql/Android.mk
new file mode 100644
index 0000000..b1df215
--- /dev/null
+++ b/tests/core/libcore/harmony_sql/Android.mk
@@ -0,0 +1,24 @@
+# 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+ifeq ($(BUILD_CTSCORE_PACKAGE),)
+    $(error BUILD_CTSCORE_PACKAGE must be defined)
+endif
+
+include $(CLEAR_VARS)
+LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.harmony_sql
+LOCAL_STATIC_JAVA_LIBRARIES := apache-harmony-tests
+include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/harmony_sql/AndroidManifest.xml b/tests/core/libcore/harmony_sql/AndroidManifest.xml
new file mode 100644
index 0000000..c6c31b2
--- /dev/null
+++ b/tests/core/libcore/harmony_sql/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.core.tests.libcore.package.harmony_sql">
+    <uses-permission android:name="android.permission.INTERNET" />
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="android.test.InstrumentationCtsTestRunner"
+                     android:targetPackage="android.core.tests.runner"
+                     android:label="cts framework tests"/>
+
+</manifest>
diff --git a/tests/core/libcore/jsr166/Android.mk b/tests/core/libcore/jsr166/Android.mk
new file mode 100644
index 0000000..3f9871e
--- /dev/null
+++ b/tests/core/libcore/jsr166/Android.mk
@@ -0,0 +1,20 @@
+# Copyright (C) 2013 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.jsr166
+LOCAL_STATIC_JAVA_LIBRARIES := jsr166-tests
+include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/jsr166/AndroidManifest.xml b/tests/core/libcore/jsr166/AndroidManifest.xml
new file mode 100644
index 0000000..3a0150e
--- /dev/null
+++ b/tests/core/libcore/jsr166/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2013 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.core.tests.libcore.package.jsr166">
+    <uses-permission android:name="android.permission.INTERNET" />
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="android.test.InstrumentationCtsTestRunner"
+                     android:targetPackage="android.core.tests.runner"
+                     android:label="cts framework tests"/>
+
+</manifest>
diff --git a/tests/core/libcore/libcore/Android.mk b/tests/core/libcore/libcore/Android.mk
index 382b386..a86d2c0 100644
--- a/tests/core/libcore/libcore/Android.mk
+++ b/tests/core/libcore/libcore/Android.mk
@@ -14,10 +14,6 @@
 
 LOCAL_PATH:= $(call my-dir)
 
-ifeq ($(BUILD_CTSCORE_PACKAGE),)
-    $(error BUILD_CTSCORE_PACKAGE must be defined)
-endif
-
 include $(CLEAR_VARS)
 LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.libcore
 LOCAL_STATIC_JAVA_LIBRARIES := core-tests
diff --git a/tests/core/libcore/org/Android.mk b/tests/core/libcore/org/Android.mk
index d7a96b3..0f3f0ca 100644
--- a/tests/core/libcore/org/Android.mk
+++ b/tests/core/libcore/org/Android.mk
@@ -14,10 +14,6 @@
 
 LOCAL_PATH:= $(call my-dir)
 
-ifeq ($(BUILD_CTSCORE_PACKAGE),)
-    $(error BUILD_CTSCORE_PACKAGE must be defined)
-endif
-
 include $(CLEAR_VARS)
 LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.org
 LOCAL_STATIC_JAVA_LIBRARIES := core-tests
diff --git a/tests/core/libcore/sun/Android.mk b/tests/core/libcore/sun/Android.mk
index 44d3d70..ed6d2c7 100644
--- a/tests/core/libcore/sun/Android.mk
+++ b/tests/core/libcore/sun/Android.mk
@@ -14,10 +14,6 @@
 
 LOCAL_PATH:= $(call my-dir)
 
-ifeq ($(BUILD_CTSCORE_PACKAGE),)
-    $(error BUILD_CTSCORE_PACKAGE must be defined)
-endif
-
 include $(CLEAR_VARS)
 LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.sun
 LOCAL_STATIC_JAVA_LIBRARIES := core-tests
diff --git a/tests/core/libcore/tests/Android.mk b/tests/core/libcore/tests/Android.mk
index bfd235f..54ffd31 100644
--- a/tests/core/libcore/tests/Android.mk
+++ b/tests/core/libcore/tests/Android.mk
@@ -14,10 +14,6 @@
 
 LOCAL_PATH:= $(call my-dir)
 
-ifeq ($(BUILD_CTSCORE_PACKAGE),)
-    $(error BUILD_CTSCORE_PACKAGE must be defined)
-endif
-
 include $(CLEAR_VARS)
 LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.tests
 LOCAL_STATIC_JAVA_LIBRARIES := core-tests
diff --git a/tests/core/runner/src/android/test/InstrumentationCtsTestRunner.java b/tests/core/runner/src/android/test/InstrumentationCtsTestRunner.java
index d992839..96aeb51 100644
--- a/tests/core/runner/src/android/test/InstrumentationCtsTestRunner.java
+++ b/tests/core/runner/src/android/test/InstrumentationCtsTestRunner.java
@@ -75,16 +75,7 @@
     public void onCreate(Bundle arguments) {
         // We might want to move this to /sdcard, if is is mounted/writable.
         File cacheDir = getTargetContext().getCacheDir();
-
-        // Set some properties that the core tests absolutely need.
-        System.setProperty("user.language", "en");
-        System.setProperty("user.region", "US");
-
-        System.setProperty("java.home", cacheDir.getAbsolutePath());
-        System.setProperty("user.home", cacheDir.getAbsolutePath());
         System.setProperty("java.io.tmpdir", cacheDir.getAbsolutePath());
-        System.setProperty("user.dir", cacheDir.getAbsolutePath());
-
 
         mEnvironment = new TestEnvironment();
 
@@ -201,24 +192,25 @@
 
     // http://code.google.com/p/vogar/source/browse/trunk/src/vogar/target/TestEnvironment.java
     static class TestEnvironment {
-        private Locale mDefaultLocale;
-        private String mUserHome;
-        private String mJavaIoTmpDir;
-        private HostnameVerifier mHostnameVerifier;
-        private SSLSocketFactory mSslSocketFactory;
+        private final Locale mDefaultLocale;
+        private final TimeZone mDefaultTimeZone;
+        private final String mJavaIoTmpDir;
+        private final HostnameVerifier mHostnameVerifier;
+        private final SSLSocketFactory mSslSocketFactory;
 
         TestEnvironment() {
             mDefaultLocale = Locale.getDefault();
-            mUserHome = System.getProperty("user.home");
+            mDefaultTimeZone = TimeZone.getDefault();
             mJavaIoTmpDir = System.getProperty("java.io.tmpdir");
             mHostnameVerifier = HttpsURLConnection.getDefaultHostnameVerifier();
             mSslSocketFactory = HttpsURLConnection.getDefaultSSLSocketFactory();
         }
 
         void reset() {
-            Locale.setDefault(mDefaultLocale);
-            System.setProperty("user.home", mUserHome);
+            System.setProperties(null);
             System.setProperty("java.io.tmpdir", mJavaIoTmpDir);
+            Locale.setDefault(mDefaultLocale);
+            TimeZone.setDefault(mDefaultTimeZone);
             Authenticator.setDefault(null);
             CookieHandler.setDefault(null);
             ResponseCache.setDefault(null);
diff --git a/tests/jni/Android.mk b/tests/jni/Android.mk
index 0f7511e..139118d 100644
--- a/tests/jni/Android.mk
+++ b/tests/jni/Android.mk
@@ -23,13 +23,14 @@
 
 LOCAL_SRC_FILES := \
 		CtsJniOnLoad.cpp \
+		android_os_cts_TaggedPointer.cpp \
 		android_os_cts_OSFeatures.cpp \
 		android_os_cts_FileUtils.cpp \
 		android_net_cts_NetlinkSocket.cpp
 
-LOCAL_C_INCLUDES := $(JNI_H_INCLUDE) 
+LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
 
-LOCAL_SHARED_LIBRARIES := libnativehelper liblog
+LOCAL_SHARED_LIBRARIES := libnativehelper liblog libdl
 
 LOCAL_SRC_FILES += android_os_cts_CpuFeatures.cpp
 LOCAL_C_INCLUDES += ndk/sources/cpufeatures
diff --git a/tests/jni/CtsJniOnLoad.cpp b/tests/jni/CtsJniOnLoad.cpp
index 99ea37e..e0bb813 100644
--- a/tests/jni/CtsJniOnLoad.cpp
+++ b/tests/jni/CtsJniOnLoad.cpp
@@ -20,6 +20,8 @@
 
 extern int register_android_os_cts_CpuFeatures(JNIEnv*);
 
+extern int register_android_os_cts_TaggedPointer(JNIEnv*);
+
 extern int register_android_os_cts_OSFeatures(JNIEnv*);
 
 extern int register_android_os_cts_FileUtils(JNIEnv*);
@@ -35,6 +37,10 @@
         return JNI_ERR;
     }
 
+    if (register_android_os_cts_TaggedPointer(env)) {
+        return JNI_ERR;
+    }
+
     if (register_android_os_cts_OSFeatures(env)) {
         return JNI_ERR;
     }
diff --git a/tests/jni/android_os_cts_CpuFeatures.cpp b/tests/jni/android_os_cts_CpuFeatures.cpp
index 053b44e..5276257 100644
--- a/tests/jni/android_os_cts_CpuFeatures.cpp
+++ b/tests/jni/android_os_cts_CpuFeatures.cpp
@@ -42,6 +42,24 @@
     return cpuFamily == ANDROID_CPU_FAMILY_X86;
 }
 
+jboolean android_os_cts_CpuFeatures_isArm64Cpu(JNIEnv* env, jobject thiz)
+{
+    AndroidCpuFamily cpuFamily = android_getCpuFamily();
+    return cpuFamily == ANDROID_CPU_FAMILY_ARM64;
+}
+
+jboolean android_os_cts_CpuFeatures_isMips64Cpu(JNIEnv* env, jobject thiz)
+{
+    AndroidCpuFamily cpuFamily = android_getCpuFamily();
+    return cpuFamily == ANDROID_CPU_FAMILY_MIPS64;
+}
+
+jboolean android_os_cts_CpuFeatures_isX86_64Cpu(JNIEnv* env, jobject thiz)
+{
+    AndroidCpuFamily cpuFamily = android_getCpuFamily();
+    return cpuFamily == ANDROID_CPU_FAMILY_X86_64;
+}
+
 static JNINativeMethod gMethods[] = {
     {  "isArmCpu", "()Z",
             (void *) android_os_cts_CpuFeatures_isArmCpu  },
@@ -51,6 +69,12 @@
             (void *) android_os_cts_CpuFeatures_isMipsCpu  },
     {  "isX86Cpu", "()Z",
             (void *) android_os_cts_CpuFeatures_isX86Cpu  },
+    {  "isArm64Cpu", "()Z",
+            (void *) android_os_cts_CpuFeatures_isArm64Cpu  },
+    {  "isMips64Cpu", "()Z",
+            (void *) android_os_cts_CpuFeatures_isMips64Cpu  },
+    {  "isX86_64Cpu", "()Z",
+            (void *) android_os_cts_CpuFeatures_isX86_64Cpu  },
 };
 
 int register_android_os_cts_CpuFeatures(JNIEnv* env)
diff --git a/tests/jni/android_os_cts_TaggedPointer.cpp b/tests/jni/android_os_cts_TaggedPointer.cpp
new file mode 100644
index 0000000..e8f83a3
--- /dev/null
+++ b/tests/jni/android_os_cts_TaggedPointer.cpp
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2014 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.
+ *
+ */
+#include <jni.h>
+#include <inttypes.h>
+#include <setjmp.h>
+#include <signal.h>
+#include <stdbool.h>
+#include <stdlib.h>
+
+//mask the top 8 bits
+#define TAG_MASK ((0xFFULL) << 56)
+
+#define PATTERN 0x600DC0DE
+
+static sigjmp_buf jmpenv;
+
+static void sigsegv_handler(int signum) {
+    siglongjmp(jmpenv, 1);
+}
+
+jboolean android_os_cts_TaggedPointer_hasTaggedPointer(JNIEnv* env, jobject thiz)
+{
+    uint32_t data;
+    uint32_t *tagged;
+    uintptr_t tmp;
+    int err;
+    jboolean ret = true;
+    struct sigaction sigsegv_act;
+    struct sigaction oldact;
+
+    tmp = TAG_MASK | (uintptr_t)(&data);
+    tagged = (uint32_t *)tmp;
+    data = PATTERN;
+
+    memset(&sigsegv_act, 0, sizeof(sigsegv_act));
+    sigsegv_act.sa_handler = sigsegv_handler;
+
+    err = sigaction(SIGSEGV, &sigsegv_act, &oldact);
+    if (err) {
+        ret = false;
+        goto err_sigaction;
+    }
+
+    if (sigsetjmp(jmpenv, 1)) {
+        ret = false;
+        goto err_segfault;
+    }
+
+    if (*tagged != PATTERN) {
+        ret = false;
+    }
+
+err_segfault:
+    sigaction(SIGSEGV, &oldact, NULL);
+err_sigaction:
+    return ret;
+}
+
+static JNINativeMethod gMethods[] = {
+    {  "hasTaggedPointer", "()Z",
+            (void *) android_os_cts_TaggedPointer_hasTaggedPointer },
+};
+
+int register_android_os_cts_TaggedPointer(JNIEnv* env)
+{
+    jclass clazz = env->FindClass("android/os/cts/TaggedPointer");
+
+    return env->RegisterNatives(clazz, gMethods,
+            sizeof(gMethods) / sizeof(JNINativeMethod));
+}
diff --git a/tests/res/raw/rs_loopfilter_param.bin b/tests/res/raw/rs_loopfilter_param.bin
new file mode 100644
index 0000000..cf52c44
--- /dev/null
+++ b/tests/res/raw/rs_loopfilter_param.bin
Binary files differ
diff --git a/tests/res/values-b+kok+419+VARIANT/configVarying.xml b/tests/res/values-b+kok+419+VARIANT/configVarying.xml
new file mode 100644
index 0000000..3560279
--- /dev/null
+++ b/tests/res/values-b+kok+419+VARIANT/configVarying.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+
+<resources>
+    <item type="configVarying" name="simple">simple kok 419 VARIANT</item>
+    <bag type="configVarying" name="bag">
+        <item name="testString">bag kok 419 VARIANT</item>
+    </bag>
+</resources>
diff --git a/tests/res/values-b+kok+419/configVarying.xml b/tests/res/values-b+kok+419/configVarying.xml
new file mode 100644
index 0000000..b6f37f9
--- /dev/null
+++ b/tests/res/values-b+kok+419/configVarying.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 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.
+-->
+
+<resources>
+    <item type="configVarying" name="simple">simple kok 419</item>
+    <bag type="configVarying" name="bag">
+        <item name="testString">bag kok 419</item>
+    </bag>
+</resources>
diff --git a/tests/res/values-b+kok+IN/configVarying.xml b/tests/res/values-b+kok+IN/configVarying.xml
new file mode 100644
index 0000000..967ea47
--- /dev/null
+++ b/tests/res/values-b+kok+IN/configVarying.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 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.
+-->
+
+<resources>
+    <item type="configVarying" name="simple">simple kok IN</item>
+    <bag type="configVarying" name="bag">
+        <item name="testString">bag kok IN</item>
+    </bag>
+</resources>
diff --git a/tests/res/values-b+kok+Knda+419+VARIANT/configVarying.xml b/tests/res/values-b+kok+Knda+419+VARIANT/configVarying.xml
new file mode 100644
index 0000000..2b2bcea
--- /dev/null
+++ b/tests/res/values-b+kok+Knda+419+VARIANT/configVarying.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+
+<resources>
+    <item type="configVarying" name="simple">simple kok Knda 419 VARIANT</item>
+    <bag type="configVarying" name="bag">
+        <item name="testString">bag kok Knda 419 VARIANT</item>
+    </bag>
+</resources>
diff --git a/tests/res/values-b+kok+Knda+419/configVarying.xml b/tests/res/values-b+kok+Knda+419/configVarying.xml
new file mode 100644
index 0000000..cbc53b9
--- /dev/null
+++ b/tests/res/values-b+kok+Knda+419/configVarying.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 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.
+-->
+
+<resources>
+    <item type="configVarying" name="simple">simple kok Knda 419</item>
+    <bag type="configVarying" name="bag">
+        <item name="testString">bag kok Knda 419</item>
+    </bag>
+</resources>
diff --git a/tests/res/values-b+kok+Knda/configVarying.xml b/tests/res/values-b+kok+Knda/configVarying.xml
new file mode 100644
index 0000000..f735749
--- /dev/null
+++ b/tests/res/values-b+kok+Knda/configVarying.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 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.
+-->
+
+<resources>
+    <item type="configVarying" name="simple">simple kok Knda</item>
+    <bag type="configVarying" name="bag">
+        <item name="testString">bag kok Knda</item>
+    </bag>
+</resources>
diff --git a/tests/res/values-b+kok+VARIANT/configVarying.xml b/tests/res/values-b+kok+VARIANT/configVarying.xml
new file mode 100644
index 0000000..6743b7f
--- /dev/null
+++ b/tests/res/values-b+kok+VARIANT/configVarying.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+
+<resources>
+    <item type="configVarying" name="simple">simple kok VARIANT</item>
+    <bag type="configVarying" name="bag">
+        <item name="testString">bag kok VARIANT</item>
+    </bag>
+</resources>
diff --git a/tests/res/values-b+kok/configVarying.xml b/tests/res/values-b+kok/configVarying.xml
new file mode 100644
index 0000000..e1bafa1
--- /dev/null
+++ b/tests/res/values-b+kok/configVarying.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 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.
+-->
+
+<resources>
+    <item type="configVarying" name="simple">simple kok</item>
+    <bag type="configVarying" name="bag">
+        <item name="testString">bag kok</item>
+    </bag>
+</resources>
diff --git a/tests/res/values-b+tgl+PH/configVarying.xml b/tests/res/values-b+tgl+PH/configVarying.xml
new file mode 100644
index 0000000..e6b9e25
--- /dev/null
+++ b/tests/res/values-b+tgl+PH/configVarying.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 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.
+-->
+
+<resources>
+    <item type="configVarying" name="simple">simple tgl PH</item>
+    <bag type="configVarying" name="bag">
+        <item name="testString">bag tgl PH</item>
+    </bag>
+</resources>
diff --git a/tests/res/values-b+tgl/configVarying.xml b/tests/res/values-b+tgl/configVarying.xml
new file mode 100644
index 0000000..ac7e051
--- /dev/null
+++ b/tests/res/values-b+tgl/configVarying.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 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.
+-->
+
+<resources>
+    <item type="configVarying" name="simple">simple tgl</item>
+    <bag type="configVarying" name="bag">
+        <item name="testString">bag tgl</item>
+    </bag>
+</resources>
diff --git a/tests/res/values-tl-rPH/configVarying.xml b/tests/res/values-tl-rPH/configVarying.xml
new file mode 100644
index 0000000..034d2ab
--- /dev/null
+++ b/tests/res/values-tl-rPH/configVarying.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 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.
+-->
+
+<resources>
+    <item type="configVarying" name="simple">simple tl PH</item>
+    <bag type="configVarying" name="bag">
+        <item name="testString">bag tl PH</item>
+    </bag>
+</resources>
diff --git a/tests/res/values-tl/configVarying.xml b/tests/res/values-tl/configVarying.xml
new file mode 100644
index 0000000..4fc5012
--- /dev/null
+++ b/tests/res/values-tl/configVarying.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 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.
+-->
+
+<resources>
+    <item type="configVarying" name="simple">simple tl</item>
+    <bag type="configVarying" name="bag">
+        <item name="testString">bag tl</item>
+    </bag>
+</resources>
diff --git a/tests/src/android/os/cts/CpuFeatures.java b/tests/src/android/os/cts/CpuFeatures.java
index 5009474..b767da2 100644
--- a/tests/src/android/os/cts/CpuFeatures.java
+++ b/tests/src/android/os/cts/CpuFeatures.java
@@ -37,4 +37,10 @@
     public static native boolean isMipsCpu();
 
     public static native boolean isX86Cpu();
+
+    public static native boolean isArm64Cpu();
+
+    public static native boolean isMips64Cpu();
+
+    public static native boolean isX86_64Cpu();
 }
diff --git a/tests/src/android/os/cts/TaggedPointer.java b/tests/src/android/os/cts/TaggedPointer.java
new file mode 100644
index 0000000..16e76c9
--- /dev/null
+++ b/tests/src/android/os/cts/TaggedPointer.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2014 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 android.os.cts;
+
+public class TaggedPointer {
+
+    static {
+        System.loadLibrary("cts_jni");
+    }
+
+    public static native boolean hasTaggedPointer();
+}
diff --git a/tests/src/android/renderscript/cts/TestAbs.rs b/tests/src/android/renderscript/cts/TestAbs.rs
new file mode 100644
index 0000000..8f1747e
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestAbs.rs
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+
+uchar __attribute__((kernel)) testAbsCharUchar(char inValue) {
+    return abs(inValue);
+}
+
+uchar2 __attribute__((kernel)) testAbsChar2Uchar2(char2 inValue) {
+    return abs(inValue);
+}
+
+uchar3 __attribute__((kernel)) testAbsChar3Uchar3(char3 inValue) {
+    return abs(inValue);
+}
+
+uchar4 __attribute__((kernel)) testAbsChar4Uchar4(char4 inValue) {
+    return abs(inValue);
+}
+
+ushort __attribute__((kernel)) testAbsShortUshort(short inValue) {
+    return abs(inValue);
+}
+
+ushort2 __attribute__((kernel)) testAbsShort2Ushort2(short2 inValue) {
+    return abs(inValue);
+}
+
+ushort3 __attribute__((kernel)) testAbsShort3Ushort3(short3 inValue) {
+    return abs(inValue);
+}
+
+ushort4 __attribute__((kernel)) testAbsShort4Ushort4(short4 inValue) {
+    return abs(inValue);
+}
+
+uint __attribute__((kernel)) testAbsIntUint(int inValue) {
+    return abs(inValue);
+}
+
+uint2 __attribute__((kernel)) testAbsInt2Uint2(int2 inValue) {
+    return abs(inValue);
+}
+
+uint3 __attribute__((kernel)) testAbsInt3Uint3(int3 inValue) {
+    return abs(inValue);
+}
+
+uint4 __attribute__((kernel)) testAbsInt4Uint4(int4 inValue) {
+    return abs(inValue);
+}
diff --git a/tests/src/android/renderscript/cts/TestAbsRelaxed.rs b/tests/src/android/renderscript/cts/TestAbsRelaxed.rs
new file mode 100644
index 0000000..437a467
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestAbsRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestAbs.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestAcos.rs b/tests/src/android/renderscript/cts/TestAcos.rs
new file mode 100644
index 0000000..ccf273e
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestAcos.rs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+
+float __attribute__((kernel)) testAcosFloatFloat(float inV) {
+    return acos(inV);
+}
+
+float2 __attribute__((kernel)) testAcosFloat2Float2(float2 inV) {
+    return acos(inV);
+}
+
+float3 __attribute__((kernel)) testAcosFloat3Float3(float3 inV) {
+    return acos(inV);
+}
+
+float4 __attribute__((kernel)) testAcosFloat4Float4(float4 inV) {
+    return acos(inV);
+}
diff --git a/tests/src/android/renderscript/cts/TestAcosRelaxed.rs b/tests/src/android/renderscript/cts/TestAcosRelaxed.rs
new file mode 100644
index 0000000..92fd9e8
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestAcosRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestAcos.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestAcosh.rs b/tests/src/android/renderscript/cts/TestAcosh.rs
new file mode 100644
index 0000000..9be2fa2
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestAcosh.rs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+
+float __attribute__((kernel)) testAcoshFloatFloat(float in) {
+    return acosh(in);
+}
+
+float2 __attribute__((kernel)) testAcoshFloat2Float2(float2 in) {
+    return acosh(in);
+}
+
+float3 __attribute__((kernel)) testAcoshFloat3Float3(float3 in) {
+    return acosh(in);
+}
+
+float4 __attribute__((kernel)) testAcoshFloat4Float4(float4 in) {
+    return acosh(in);
+}
diff --git a/tests/src/android/renderscript/cts/TestAcoshRelaxed.rs b/tests/src/android/renderscript/cts/TestAcoshRelaxed.rs
new file mode 100644
index 0000000..269cec5
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestAcoshRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestAcosh.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestAcospi.rs b/tests/src/android/renderscript/cts/TestAcospi.rs
new file mode 100644
index 0000000..b29cff7
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestAcospi.rs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+
+float __attribute__((kernel)) testAcospiFloatFloat(float inV) {
+    return acospi(inV);
+}
+
+float2 __attribute__((kernel)) testAcospiFloat2Float2(float2 inV) {
+    return acospi(inV);
+}
+
+float3 __attribute__((kernel)) testAcospiFloat3Float3(float3 inV) {
+    return acospi(inV);
+}
+
+float4 __attribute__((kernel)) testAcospiFloat4Float4(float4 inV) {
+    return acospi(inV);
+}
diff --git a/tests/src/android/renderscript/cts/TestAcospiRelaxed.rs b/tests/src/android/renderscript/cts/TestAcospiRelaxed.rs
new file mode 100644
index 0000000..203fe7e
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestAcospiRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestAcospi.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestAsin.rs b/tests/src/android/renderscript/cts/TestAsin.rs
new file mode 100644
index 0000000..43e6940
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestAsin.rs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+
+float __attribute__((kernel)) testAsinFloatFloat(float inV) {
+    return asin(inV);
+}
+
+float2 __attribute__((kernel)) testAsinFloat2Float2(float2 inV) {
+    return asin(inV);
+}
+
+float3 __attribute__((kernel)) testAsinFloat3Float3(float3 inV) {
+    return asin(inV);
+}
+
+float4 __attribute__((kernel)) testAsinFloat4Float4(float4 inV) {
+    return asin(inV);
+}
diff --git a/tests/src/android/renderscript/cts/TestAsinRelaxed.rs b/tests/src/android/renderscript/cts/TestAsinRelaxed.rs
new file mode 100644
index 0000000..f972148
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestAsinRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestAsin.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestAsinh.rs b/tests/src/android/renderscript/cts/TestAsinh.rs
new file mode 100644
index 0000000..a72a5f4
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestAsinh.rs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+
+float __attribute__((kernel)) testAsinhFloatFloat(float in) {
+    return asinh(in);
+}
+
+float2 __attribute__((kernel)) testAsinhFloat2Float2(float2 in) {
+    return asinh(in);
+}
+
+float3 __attribute__((kernel)) testAsinhFloat3Float3(float3 in) {
+    return asinh(in);
+}
+
+float4 __attribute__((kernel)) testAsinhFloat4Float4(float4 in) {
+    return asinh(in);
+}
diff --git a/tests/src/android/renderscript/cts/TestAsinhRelaxed.rs b/tests/src/android/renderscript/cts/TestAsinhRelaxed.rs
new file mode 100644
index 0000000..7540ea8
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestAsinhRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestAsinh.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestAsinpi.rs b/tests/src/android/renderscript/cts/TestAsinpi.rs
new file mode 100644
index 0000000..112f722
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestAsinpi.rs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+
+float __attribute__((kernel)) testAsinpiFloatFloat(float inV) {
+    return asinpi(inV);
+}
+
+float2 __attribute__((kernel)) testAsinpiFloat2Float2(float2 inV) {
+    return asinpi(inV);
+}
+
+float3 __attribute__((kernel)) testAsinpiFloat3Float3(float3 inV) {
+    return asinpi(inV);
+}
+
+float4 __attribute__((kernel)) testAsinpiFloat4Float4(float4 inV) {
+    return asinpi(inV);
+}
diff --git a/tests/src/android/renderscript/cts/TestAsinpiRelaxed.rs b/tests/src/android/renderscript/cts/TestAsinpiRelaxed.rs
new file mode 100644
index 0000000..aad672b
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestAsinpiRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestAsinpi.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestAtan.rs b/tests/src/android/renderscript/cts/TestAtan.rs
new file mode 100644
index 0000000..36d3814
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestAtan.rs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+
+float __attribute__((kernel)) testAtanFloatFloat(float inV) {
+    return atan(inV);
+}
+
+float2 __attribute__((kernel)) testAtanFloat2Float2(float2 inV) {
+    return atan(inV);
+}
+
+float3 __attribute__((kernel)) testAtanFloat3Float3(float3 inV) {
+    return atan(inV);
+}
+
+float4 __attribute__((kernel)) testAtanFloat4Float4(float4 inV) {
+    return atan(inV);
+}
diff --git a/tests/src/android/renderscript/cts/TestAtan2.rs b/tests/src/android/renderscript/cts/TestAtan2.rs
new file mode 100644
index 0000000..877402d
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestAtan2.rs
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+rs_allocation gAllocInX;
+
+float __attribute__((kernel)) testAtan2FloatFloatFloat(float inY, unsigned int x) {
+    float inX = rsGetElementAt_float(gAllocInX, x);
+    return atan2(inY, inX);
+}
+
+float2 __attribute__((kernel)) testAtan2Float2Float2Float2(float2 inY, unsigned int x) {
+    float2 inX = rsGetElementAt_float2(gAllocInX, x);
+    return atan2(inY, inX);
+}
+
+float3 __attribute__((kernel)) testAtan2Float3Float3Float3(float3 inY, unsigned int x) {
+    float3 inX = rsGetElementAt_float3(gAllocInX, x);
+    return atan2(inY, inX);
+}
+
+float4 __attribute__((kernel)) testAtan2Float4Float4Float4(float4 inY, unsigned int x) {
+    float4 inX = rsGetElementAt_float4(gAllocInX, x);
+    return atan2(inY, inX);
+}
diff --git a/tests/src/android/renderscript/cts/TestAtan2Relaxed.rs b/tests/src/android/renderscript/cts/TestAtan2Relaxed.rs
new file mode 100644
index 0000000..d5d90a1
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestAtan2Relaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestAtan2.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestAtan2pi.rs b/tests/src/android/renderscript/cts/TestAtan2pi.rs
new file mode 100644
index 0000000..f0520d7
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestAtan2pi.rs
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+rs_allocation gAllocInX;
+
+float __attribute__((kernel)) testAtan2piFloatFloatFloat(float inY, unsigned int x) {
+    float inX = rsGetElementAt_float(gAllocInX, x);
+    return atan2pi(inY, inX);
+}
+
+float2 __attribute__((kernel)) testAtan2piFloat2Float2Float2(float2 inY, unsigned int x) {
+    float2 inX = rsGetElementAt_float2(gAllocInX, x);
+    return atan2pi(inY, inX);
+}
+
+float3 __attribute__((kernel)) testAtan2piFloat3Float3Float3(float3 inY, unsigned int x) {
+    float3 inX = rsGetElementAt_float3(gAllocInX, x);
+    return atan2pi(inY, inX);
+}
+
+float4 __attribute__((kernel)) testAtan2piFloat4Float4Float4(float4 inY, unsigned int x) {
+    float4 inX = rsGetElementAt_float4(gAllocInX, x);
+    return atan2pi(inY, inX);
+}
diff --git a/tests/src/android/renderscript/cts/TestAtan2piRelaxed.rs b/tests/src/android/renderscript/cts/TestAtan2piRelaxed.rs
new file mode 100644
index 0000000..9f87fff
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestAtan2piRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestAtan2pi.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestAtanRelaxed.rs b/tests/src/android/renderscript/cts/TestAtanRelaxed.rs
new file mode 100644
index 0000000..cab9300
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestAtanRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestAtan.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestAtanh.rs b/tests/src/android/renderscript/cts/TestAtanh.rs
new file mode 100644
index 0000000..fc946b6
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestAtanh.rs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+
+float __attribute__((kernel)) testAtanhFloatFloat(float in) {
+    return atanh(in);
+}
+
+float2 __attribute__((kernel)) testAtanhFloat2Float2(float2 in) {
+    return atanh(in);
+}
+
+float3 __attribute__((kernel)) testAtanhFloat3Float3(float3 in) {
+    return atanh(in);
+}
+
+float4 __attribute__((kernel)) testAtanhFloat4Float4(float4 in) {
+    return atanh(in);
+}
diff --git a/tests/src/android/renderscript/cts/TestAtanhRelaxed.rs b/tests/src/android/renderscript/cts/TestAtanhRelaxed.rs
new file mode 100644
index 0000000..88dfc75
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestAtanhRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestAtanh.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestAtanpi.rs b/tests/src/android/renderscript/cts/TestAtanpi.rs
new file mode 100644
index 0000000..a1c6d2d
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestAtanpi.rs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+
+float __attribute__((kernel)) testAtanpiFloatFloat(float inV) {
+    return atanpi(inV);
+}
+
+float2 __attribute__((kernel)) testAtanpiFloat2Float2(float2 inV) {
+    return atanpi(inV);
+}
+
+float3 __attribute__((kernel)) testAtanpiFloat3Float3(float3 inV) {
+    return atanpi(inV);
+}
+
+float4 __attribute__((kernel)) testAtanpiFloat4Float4(float4 inV) {
+    return atanpi(inV);
+}
diff --git a/tests/src/android/renderscript/cts/TestAtanpiRelaxed.rs b/tests/src/android/renderscript/cts/TestAtanpiRelaxed.rs
new file mode 100644
index 0000000..6183636
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestAtanpiRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestAtanpi.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestCbrt.rs b/tests/src/android/renderscript/cts/TestCbrt.rs
new file mode 100644
index 0000000..d14f508
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestCbrt.rs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+
+float __attribute__((kernel)) testCbrtFloatFloat(float in) {
+    return cbrt(in);
+}
+
+float2 __attribute__((kernel)) testCbrtFloat2Float2(float2 in) {
+    return cbrt(in);
+}
+
+float3 __attribute__((kernel)) testCbrtFloat3Float3(float3 in) {
+    return cbrt(in);
+}
+
+float4 __attribute__((kernel)) testCbrtFloat4Float4(float4 in) {
+    return cbrt(in);
+}
diff --git a/tests/src/android/renderscript/cts/TestCbrtRelaxed.rs b/tests/src/android/renderscript/cts/TestCbrtRelaxed.rs
new file mode 100644
index 0000000..ad970fe
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestCbrtRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestCbrt.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestCeil.rs b/tests/src/android/renderscript/cts/TestCeil.rs
new file mode 100644
index 0000000..80c8708
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestCeil.rs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+
+float __attribute__((kernel)) testCeilFloatFloat(float in) {
+    return ceil(in);
+}
+
+float2 __attribute__((kernel)) testCeilFloat2Float2(float2 in) {
+    return ceil(in);
+}
+
+float3 __attribute__((kernel)) testCeilFloat3Float3(float3 in) {
+    return ceil(in);
+}
+
+float4 __attribute__((kernel)) testCeilFloat4Float4(float4 in) {
+    return ceil(in);
+}
diff --git a/tests/src/android/renderscript/cts/TestCeilRelaxed.rs b/tests/src/android/renderscript/cts/TestCeilRelaxed.rs
new file mode 100644
index 0000000..bbafb0d
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestCeilRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestCeil.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestClamp.rs b/tests/src/android/renderscript/cts/TestClamp.rs
new file mode 100644
index 0000000..bc0b379
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestClamp.rs
@@ -0,0 +1,317 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+rs_allocation gAllocInMinValue;
+rs_allocation gAllocInMaxValue;
+
+float __attribute__((kernel)) testClampFloatFloatFloatFloat(float inValue, unsigned int x) {
+    float inMinValue = rsGetElementAt_float(gAllocInMinValue, x);
+    float inMaxValue = rsGetElementAt_float(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+float2 __attribute__((kernel)) testClampFloat2Float2Float2Float2(float2 inValue, unsigned int x) {
+    float2 inMinValue = rsGetElementAt_float2(gAllocInMinValue, x);
+    float2 inMaxValue = rsGetElementAt_float2(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+float3 __attribute__((kernel)) testClampFloat3Float3Float3Float3(float3 inValue, unsigned int x) {
+    float3 inMinValue = rsGetElementAt_float3(gAllocInMinValue, x);
+    float3 inMaxValue = rsGetElementAt_float3(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+float4 __attribute__((kernel)) testClampFloat4Float4Float4Float4(float4 inValue, unsigned int x) {
+    float4 inMinValue = rsGetElementAt_float4(gAllocInMinValue, x);
+    float4 inMaxValue = rsGetElementAt_float4(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+float2 __attribute__((kernel)) testClampFloat2FloatFloatFloat2(float2 inValue, unsigned int x) {
+    float inMinValue = rsGetElementAt_float(gAllocInMinValue, x);
+    float inMaxValue = rsGetElementAt_float(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+float3 __attribute__((kernel)) testClampFloat3FloatFloatFloat3(float3 inValue, unsigned int x) {
+    float inMinValue = rsGetElementAt_float(gAllocInMinValue, x);
+    float inMaxValue = rsGetElementAt_float(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+float4 __attribute__((kernel)) testClampFloat4FloatFloatFloat4(float4 inValue, unsigned int x) {
+    float inMinValue = rsGetElementAt_float(gAllocInMinValue, x);
+    float inMaxValue = rsGetElementAt_float(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+char __attribute__((kernel)) testClampCharCharCharChar(char inValue, unsigned int x) {
+    char inMinValue = rsGetElementAt_char(gAllocInMinValue, x);
+    char inMaxValue = rsGetElementAt_char(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+char2 __attribute__((kernel)) testClampChar2Char2Char2Char2(char2 inValue, unsigned int x) {
+    char2 inMinValue = rsGetElementAt_char2(gAllocInMinValue, x);
+    char2 inMaxValue = rsGetElementAt_char2(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+char3 __attribute__((kernel)) testClampChar3Char3Char3Char3(char3 inValue, unsigned int x) {
+    char3 inMinValue = rsGetElementAt_char3(gAllocInMinValue, x);
+    char3 inMaxValue = rsGetElementAt_char3(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+char4 __attribute__((kernel)) testClampChar4Char4Char4Char4(char4 inValue, unsigned int x) {
+    char4 inMinValue = rsGetElementAt_char4(gAllocInMinValue, x);
+    char4 inMaxValue = rsGetElementAt_char4(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+uchar __attribute__((kernel)) testClampUcharUcharUcharUchar(uchar inValue, unsigned int x) {
+    uchar inMinValue = rsGetElementAt_uchar(gAllocInMinValue, x);
+    uchar inMaxValue = rsGetElementAt_uchar(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+uchar2 __attribute__((kernel)) testClampUchar2Uchar2Uchar2Uchar2(uchar2 inValue, unsigned int x) {
+    uchar2 inMinValue = rsGetElementAt_uchar2(gAllocInMinValue, x);
+    uchar2 inMaxValue = rsGetElementAt_uchar2(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+uchar3 __attribute__((kernel)) testClampUchar3Uchar3Uchar3Uchar3(uchar3 inValue, unsigned int x) {
+    uchar3 inMinValue = rsGetElementAt_uchar3(gAllocInMinValue, x);
+    uchar3 inMaxValue = rsGetElementAt_uchar3(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+uchar4 __attribute__((kernel)) testClampUchar4Uchar4Uchar4Uchar4(uchar4 inValue, unsigned int x) {
+    uchar4 inMinValue = rsGetElementAt_uchar4(gAllocInMinValue, x);
+    uchar4 inMaxValue = rsGetElementAt_uchar4(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+short __attribute__((kernel)) testClampShortShortShortShort(short inValue, unsigned int x) {
+    short inMinValue = rsGetElementAt_short(gAllocInMinValue, x);
+    short inMaxValue = rsGetElementAt_short(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+short2 __attribute__((kernel)) testClampShort2Short2Short2Short2(short2 inValue, unsigned int x) {
+    short2 inMinValue = rsGetElementAt_short2(gAllocInMinValue, x);
+    short2 inMaxValue = rsGetElementAt_short2(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+short3 __attribute__((kernel)) testClampShort3Short3Short3Short3(short3 inValue, unsigned int x) {
+    short3 inMinValue = rsGetElementAt_short3(gAllocInMinValue, x);
+    short3 inMaxValue = rsGetElementAt_short3(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+short4 __attribute__((kernel)) testClampShort4Short4Short4Short4(short4 inValue, unsigned int x) {
+    short4 inMinValue = rsGetElementAt_short4(gAllocInMinValue, x);
+    short4 inMaxValue = rsGetElementAt_short4(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+ushort __attribute__((kernel)) testClampUshortUshortUshortUshort(ushort inValue, unsigned int x) {
+    ushort inMinValue = rsGetElementAt_ushort(gAllocInMinValue, x);
+    ushort inMaxValue = rsGetElementAt_ushort(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+ushort2 __attribute__((kernel)) testClampUshort2Ushort2Ushort2Ushort2(ushort2 inValue, unsigned int x) {
+    ushort2 inMinValue = rsGetElementAt_ushort2(gAllocInMinValue, x);
+    ushort2 inMaxValue = rsGetElementAt_ushort2(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+ushort3 __attribute__((kernel)) testClampUshort3Ushort3Ushort3Ushort3(ushort3 inValue, unsigned int x) {
+    ushort3 inMinValue = rsGetElementAt_ushort3(gAllocInMinValue, x);
+    ushort3 inMaxValue = rsGetElementAt_ushort3(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+ushort4 __attribute__((kernel)) testClampUshort4Ushort4Ushort4Ushort4(ushort4 inValue, unsigned int x) {
+    ushort4 inMinValue = rsGetElementAt_ushort4(gAllocInMinValue, x);
+    ushort4 inMaxValue = rsGetElementAt_ushort4(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+int __attribute__((kernel)) testClampIntIntIntInt(int inValue, unsigned int x) {
+    int inMinValue = rsGetElementAt_int(gAllocInMinValue, x);
+    int inMaxValue = rsGetElementAt_int(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+int2 __attribute__((kernel)) testClampInt2Int2Int2Int2(int2 inValue, unsigned int x) {
+    int2 inMinValue = rsGetElementAt_int2(gAllocInMinValue, x);
+    int2 inMaxValue = rsGetElementAt_int2(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+int3 __attribute__((kernel)) testClampInt3Int3Int3Int3(int3 inValue, unsigned int x) {
+    int3 inMinValue = rsGetElementAt_int3(gAllocInMinValue, x);
+    int3 inMaxValue = rsGetElementAt_int3(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+int4 __attribute__((kernel)) testClampInt4Int4Int4Int4(int4 inValue, unsigned int x) {
+    int4 inMinValue = rsGetElementAt_int4(gAllocInMinValue, x);
+    int4 inMaxValue = rsGetElementAt_int4(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+uint __attribute__((kernel)) testClampUintUintUintUint(uint inValue, unsigned int x) {
+    uint inMinValue = rsGetElementAt_uint(gAllocInMinValue, x);
+    uint inMaxValue = rsGetElementAt_uint(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+uint2 __attribute__((kernel)) testClampUint2Uint2Uint2Uint2(uint2 inValue, unsigned int x) {
+    uint2 inMinValue = rsGetElementAt_uint2(gAllocInMinValue, x);
+    uint2 inMaxValue = rsGetElementAt_uint2(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+uint3 __attribute__((kernel)) testClampUint3Uint3Uint3Uint3(uint3 inValue, unsigned int x) {
+    uint3 inMinValue = rsGetElementAt_uint3(gAllocInMinValue, x);
+    uint3 inMaxValue = rsGetElementAt_uint3(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+uint4 __attribute__((kernel)) testClampUint4Uint4Uint4Uint4(uint4 inValue, unsigned int x) {
+    uint4 inMinValue = rsGetElementAt_uint4(gAllocInMinValue, x);
+    uint4 inMaxValue = rsGetElementAt_uint4(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+char2 __attribute__((kernel)) testClampChar2CharCharChar2(char2 inValue, unsigned int x) {
+    char inMinValue = rsGetElementAt_char(gAllocInMinValue, x);
+    char inMaxValue = rsGetElementAt_char(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+char3 __attribute__((kernel)) testClampChar3CharCharChar3(char3 inValue, unsigned int x) {
+    char inMinValue = rsGetElementAt_char(gAllocInMinValue, x);
+    char inMaxValue = rsGetElementAt_char(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+char4 __attribute__((kernel)) testClampChar4CharCharChar4(char4 inValue, unsigned int x) {
+    char inMinValue = rsGetElementAt_char(gAllocInMinValue, x);
+    char inMaxValue = rsGetElementAt_char(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+uchar2 __attribute__((kernel)) testClampUchar2UcharUcharUchar2(uchar2 inValue, unsigned int x) {
+    uchar inMinValue = rsGetElementAt_uchar(gAllocInMinValue, x);
+    uchar inMaxValue = rsGetElementAt_uchar(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+uchar3 __attribute__((kernel)) testClampUchar3UcharUcharUchar3(uchar3 inValue, unsigned int x) {
+    uchar inMinValue = rsGetElementAt_uchar(gAllocInMinValue, x);
+    uchar inMaxValue = rsGetElementAt_uchar(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+uchar4 __attribute__((kernel)) testClampUchar4UcharUcharUchar4(uchar4 inValue, unsigned int x) {
+    uchar inMinValue = rsGetElementAt_uchar(gAllocInMinValue, x);
+    uchar inMaxValue = rsGetElementAt_uchar(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+short2 __attribute__((kernel)) testClampShort2ShortShortShort2(short2 inValue, unsigned int x) {
+    short inMinValue = rsGetElementAt_short(gAllocInMinValue, x);
+    short inMaxValue = rsGetElementAt_short(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+short3 __attribute__((kernel)) testClampShort3ShortShortShort3(short3 inValue, unsigned int x) {
+    short inMinValue = rsGetElementAt_short(gAllocInMinValue, x);
+    short inMaxValue = rsGetElementAt_short(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+short4 __attribute__((kernel)) testClampShort4ShortShortShort4(short4 inValue, unsigned int x) {
+    short inMinValue = rsGetElementAt_short(gAllocInMinValue, x);
+    short inMaxValue = rsGetElementAt_short(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+ushort2 __attribute__((kernel)) testClampUshort2UshortUshortUshort2(ushort2 inValue, unsigned int x) {
+    ushort inMinValue = rsGetElementAt_ushort(gAllocInMinValue, x);
+    ushort inMaxValue = rsGetElementAt_ushort(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+ushort3 __attribute__((kernel)) testClampUshort3UshortUshortUshort3(ushort3 inValue, unsigned int x) {
+    ushort inMinValue = rsGetElementAt_ushort(gAllocInMinValue, x);
+    ushort inMaxValue = rsGetElementAt_ushort(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+ushort4 __attribute__((kernel)) testClampUshort4UshortUshortUshort4(ushort4 inValue, unsigned int x) {
+    ushort inMinValue = rsGetElementAt_ushort(gAllocInMinValue, x);
+    ushort inMaxValue = rsGetElementAt_ushort(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+int2 __attribute__((kernel)) testClampInt2IntIntInt2(int2 inValue, unsigned int x) {
+    int inMinValue = rsGetElementAt_int(gAllocInMinValue, x);
+    int inMaxValue = rsGetElementAt_int(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+int3 __attribute__((kernel)) testClampInt3IntIntInt3(int3 inValue, unsigned int x) {
+    int inMinValue = rsGetElementAt_int(gAllocInMinValue, x);
+    int inMaxValue = rsGetElementAt_int(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+int4 __attribute__((kernel)) testClampInt4IntIntInt4(int4 inValue, unsigned int x) {
+    int inMinValue = rsGetElementAt_int(gAllocInMinValue, x);
+    int inMaxValue = rsGetElementAt_int(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+uint2 __attribute__((kernel)) testClampUint2UintUintUint2(uint2 inValue, unsigned int x) {
+    uint inMinValue = rsGetElementAt_uint(gAllocInMinValue, x);
+    uint inMaxValue = rsGetElementAt_uint(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+uint3 __attribute__((kernel)) testClampUint3UintUintUint3(uint3 inValue, unsigned int x) {
+    uint inMinValue = rsGetElementAt_uint(gAllocInMinValue, x);
+    uint inMaxValue = rsGetElementAt_uint(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+uint4 __attribute__((kernel)) testClampUint4UintUintUint4(uint4 inValue, unsigned int x) {
+    uint inMinValue = rsGetElementAt_uint(gAllocInMinValue, x);
+    uint inMaxValue = rsGetElementAt_uint(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
diff --git a/tests/src/android/renderscript/cts/TestClampRelaxed.rs b/tests/src/android/renderscript/cts/TestClampRelaxed.rs
new file mode 100644
index 0000000..15fd58c
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestClampRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestClamp.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestClz.rs b/tests/src/android/renderscript/cts/TestClz.rs
new file mode 100644
index 0000000..3501e01
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestClz.rs
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+
+char __attribute__((kernel)) testClzCharChar(char inValue) {
+    return clz(inValue);
+}
+
+char2 __attribute__((kernel)) testClzChar2Char2(char2 inValue) {
+    return clz(inValue);
+}
+
+char3 __attribute__((kernel)) testClzChar3Char3(char3 inValue) {
+    return clz(inValue);
+}
+
+char4 __attribute__((kernel)) testClzChar4Char4(char4 inValue) {
+    return clz(inValue);
+}
+
+uchar __attribute__((kernel)) testClzUcharUchar(uchar inValue) {
+    return clz(inValue);
+}
+
+uchar2 __attribute__((kernel)) testClzUchar2Uchar2(uchar2 inValue) {
+    return clz(inValue);
+}
+
+uchar3 __attribute__((kernel)) testClzUchar3Uchar3(uchar3 inValue) {
+    return clz(inValue);
+}
+
+uchar4 __attribute__((kernel)) testClzUchar4Uchar4(uchar4 inValue) {
+    return clz(inValue);
+}
+
+short __attribute__((kernel)) testClzShortShort(short inValue) {
+    return clz(inValue);
+}
+
+short2 __attribute__((kernel)) testClzShort2Short2(short2 inValue) {
+    return clz(inValue);
+}
+
+short3 __attribute__((kernel)) testClzShort3Short3(short3 inValue) {
+    return clz(inValue);
+}
+
+short4 __attribute__((kernel)) testClzShort4Short4(short4 inValue) {
+    return clz(inValue);
+}
+
+ushort __attribute__((kernel)) testClzUshortUshort(ushort inValue) {
+    return clz(inValue);
+}
+
+ushort2 __attribute__((kernel)) testClzUshort2Ushort2(ushort2 inValue) {
+    return clz(inValue);
+}
+
+ushort3 __attribute__((kernel)) testClzUshort3Ushort3(ushort3 inValue) {
+    return clz(inValue);
+}
+
+ushort4 __attribute__((kernel)) testClzUshort4Ushort4(ushort4 inValue) {
+    return clz(inValue);
+}
+
+int __attribute__((kernel)) testClzIntInt(int inValue) {
+    return clz(inValue);
+}
+
+int2 __attribute__((kernel)) testClzInt2Int2(int2 inValue) {
+    return clz(inValue);
+}
+
+int3 __attribute__((kernel)) testClzInt3Int3(int3 inValue) {
+    return clz(inValue);
+}
+
+int4 __attribute__((kernel)) testClzInt4Int4(int4 inValue) {
+    return clz(inValue);
+}
+
+uint __attribute__((kernel)) testClzUintUint(uint inValue) {
+    return clz(inValue);
+}
+
+uint2 __attribute__((kernel)) testClzUint2Uint2(uint2 inValue) {
+    return clz(inValue);
+}
+
+uint3 __attribute__((kernel)) testClzUint3Uint3(uint3 inValue) {
+    return clz(inValue);
+}
+
+uint4 __attribute__((kernel)) testClzUint4Uint4(uint4 inValue) {
+    return clz(inValue);
+}
diff --git a/tests/src/android/renderscript/cts/TestClzRelaxed.rs b/tests/src/android/renderscript/cts/TestClzRelaxed.rs
new file mode 100644
index 0000000..c463c94
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestClzRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestClz.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestConvert.rs b/tests/src/android/renderscript/cts/TestConvert.rs
new file mode 100644
index 0000000..85f8c94
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestConvert.rs
@@ -0,0 +1,609 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+
+float2 __attribute__((kernel)) testConvertFloat2Float2Float2(float2 inV) {
+    return convert_float2(inV);
+}
+
+float3 __attribute__((kernel)) testConvertFloat3Float3Float3(float3 inV) {
+    return convert_float3(inV);
+}
+
+float4 __attribute__((kernel)) testConvertFloat4Float4Float4(float4 inV) {
+    return convert_float4(inV);
+}
+
+float2 __attribute__((kernel)) testConvertFloat2Char2Float2(char2 inV) {
+    return convert_float2(inV);
+}
+
+float3 __attribute__((kernel)) testConvertFloat3Char3Float3(char3 inV) {
+    return convert_float3(inV);
+}
+
+float4 __attribute__((kernel)) testConvertFloat4Char4Float4(char4 inV) {
+    return convert_float4(inV);
+}
+
+float2 __attribute__((kernel)) testConvertFloat2Uchar2Float2(uchar2 inV) {
+    return convert_float2(inV);
+}
+
+float3 __attribute__((kernel)) testConvertFloat3Uchar3Float3(uchar3 inV) {
+    return convert_float3(inV);
+}
+
+float4 __attribute__((kernel)) testConvertFloat4Uchar4Float4(uchar4 inV) {
+    return convert_float4(inV);
+}
+
+float2 __attribute__((kernel)) testConvertFloat2Short2Float2(short2 inV) {
+    return convert_float2(inV);
+}
+
+float3 __attribute__((kernel)) testConvertFloat3Short3Float3(short3 inV) {
+    return convert_float3(inV);
+}
+
+float4 __attribute__((kernel)) testConvertFloat4Short4Float4(short4 inV) {
+    return convert_float4(inV);
+}
+
+float2 __attribute__((kernel)) testConvertFloat2Ushort2Float2(ushort2 inV) {
+    return convert_float2(inV);
+}
+
+float3 __attribute__((kernel)) testConvertFloat3Ushort3Float3(ushort3 inV) {
+    return convert_float3(inV);
+}
+
+float4 __attribute__((kernel)) testConvertFloat4Ushort4Float4(ushort4 inV) {
+    return convert_float4(inV);
+}
+
+float2 __attribute__((kernel)) testConvertFloat2Int2Float2(int2 inV) {
+    return convert_float2(inV);
+}
+
+float3 __attribute__((kernel)) testConvertFloat3Int3Float3(int3 inV) {
+    return convert_float3(inV);
+}
+
+float4 __attribute__((kernel)) testConvertFloat4Int4Float4(int4 inV) {
+    return convert_float4(inV);
+}
+
+float2 __attribute__((kernel)) testConvertFloat2Uint2Float2(uint2 inV) {
+    return convert_float2(inV);
+}
+
+float3 __attribute__((kernel)) testConvertFloat3Uint3Float3(uint3 inV) {
+    return convert_float3(inV);
+}
+
+float4 __attribute__((kernel)) testConvertFloat4Uint4Float4(uint4 inV) {
+    return convert_float4(inV);
+}
+
+char2 __attribute__((kernel)) testConvertChar2Float2Char2(float2 inV) {
+    return convert_char2(inV);
+}
+
+char3 __attribute__((kernel)) testConvertChar3Float3Char3(float3 inV) {
+    return convert_char3(inV);
+}
+
+char4 __attribute__((kernel)) testConvertChar4Float4Char4(float4 inV) {
+    return convert_char4(inV);
+}
+
+char2 __attribute__((kernel)) testConvertChar2Char2Char2(char2 inV) {
+    return convert_char2(inV);
+}
+
+char3 __attribute__((kernel)) testConvertChar3Char3Char3(char3 inV) {
+    return convert_char3(inV);
+}
+
+char4 __attribute__((kernel)) testConvertChar4Char4Char4(char4 inV) {
+    return convert_char4(inV);
+}
+
+char2 __attribute__((kernel)) testConvertChar2Uchar2Char2(uchar2 inV) {
+    return convert_char2(inV);
+}
+
+char3 __attribute__((kernel)) testConvertChar3Uchar3Char3(uchar3 inV) {
+    return convert_char3(inV);
+}
+
+char4 __attribute__((kernel)) testConvertChar4Uchar4Char4(uchar4 inV) {
+    return convert_char4(inV);
+}
+
+char2 __attribute__((kernel)) testConvertChar2Short2Char2(short2 inV) {
+    return convert_char2(inV);
+}
+
+char3 __attribute__((kernel)) testConvertChar3Short3Char3(short3 inV) {
+    return convert_char3(inV);
+}
+
+char4 __attribute__((kernel)) testConvertChar4Short4Char4(short4 inV) {
+    return convert_char4(inV);
+}
+
+char2 __attribute__((kernel)) testConvertChar2Ushort2Char2(ushort2 inV) {
+    return convert_char2(inV);
+}
+
+char3 __attribute__((kernel)) testConvertChar3Ushort3Char3(ushort3 inV) {
+    return convert_char3(inV);
+}
+
+char4 __attribute__((kernel)) testConvertChar4Ushort4Char4(ushort4 inV) {
+    return convert_char4(inV);
+}
+
+char2 __attribute__((kernel)) testConvertChar2Int2Char2(int2 inV) {
+    return convert_char2(inV);
+}
+
+char3 __attribute__((kernel)) testConvertChar3Int3Char3(int3 inV) {
+    return convert_char3(inV);
+}
+
+char4 __attribute__((kernel)) testConvertChar4Int4Char4(int4 inV) {
+    return convert_char4(inV);
+}
+
+char2 __attribute__((kernel)) testConvertChar2Uint2Char2(uint2 inV) {
+    return convert_char2(inV);
+}
+
+char3 __attribute__((kernel)) testConvertChar3Uint3Char3(uint3 inV) {
+    return convert_char3(inV);
+}
+
+char4 __attribute__((kernel)) testConvertChar4Uint4Char4(uint4 inV) {
+    return convert_char4(inV);
+}
+
+uchar2 __attribute__((kernel)) testConvertUchar2Float2Uchar2(float2 inV) {
+    return convert_uchar2(inV);
+}
+
+uchar3 __attribute__((kernel)) testConvertUchar3Float3Uchar3(float3 inV) {
+    return convert_uchar3(inV);
+}
+
+uchar4 __attribute__((kernel)) testConvertUchar4Float4Uchar4(float4 inV) {
+    return convert_uchar4(inV);
+}
+
+uchar2 __attribute__((kernel)) testConvertUchar2Char2Uchar2(char2 inV) {
+    return convert_uchar2(inV);
+}
+
+uchar3 __attribute__((kernel)) testConvertUchar3Char3Uchar3(char3 inV) {
+    return convert_uchar3(inV);
+}
+
+uchar4 __attribute__((kernel)) testConvertUchar4Char4Uchar4(char4 inV) {
+    return convert_uchar4(inV);
+}
+
+uchar2 __attribute__((kernel)) testConvertUchar2Uchar2Uchar2(uchar2 inV) {
+    return convert_uchar2(inV);
+}
+
+uchar3 __attribute__((kernel)) testConvertUchar3Uchar3Uchar3(uchar3 inV) {
+    return convert_uchar3(inV);
+}
+
+uchar4 __attribute__((kernel)) testConvertUchar4Uchar4Uchar4(uchar4 inV) {
+    return convert_uchar4(inV);
+}
+
+uchar2 __attribute__((kernel)) testConvertUchar2Short2Uchar2(short2 inV) {
+    return convert_uchar2(inV);
+}
+
+uchar3 __attribute__((kernel)) testConvertUchar3Short3Uchar3(short3 inV) {
+    return convert_uchar3(inV);
+}
+
+uchar4 __attribute__((kernel)) testConvertUchar4Short4Uchar4(short4 inV) {
+    return convert_uchar4(inV);
+}
+
+uchar2 __attribute__((kernel)) testConvertUchar2Ushort2Uchar2(ushort2 inV) {
+    return convert_uchar2(inV);
+}
+
+uchar3 __attribute__((kernel)) testConvertUchar3Ushort3Uchar3(ushort3 inV) {
+    return convert_uchar3(inV);
+}
+
+uchar4 __attribute__((kernel)) testConvertUchar4Ushort4Uchar4(ushort4 inV) {
+    return convert_uchar4(inV);
+}
+
+uchar2 __attribute__((kernel)) testConvertUchar2Int2Uchar2(int2 inV) {
+    return convert_uchar2(inV);
+}
+
+uchar3 __attribute__((kernel)) testConvertUchar3Int3Uchar3(int3 inV) {
+    return convert_uchar3(inV);
+}
+
+uchar4 __attribute__((kernel)) testConvertUchar4Int4Uchar4(int4 inV) {
+    return convert_uchar4(inV);
+}
+
+uchar2 __attribute__((kernel)) testConvertUchar2Uint2Uchar2(uint2 inV) {
+    return convert_uchar2(inV);
+}
+
+uchar3 __attribute__((kernel)) testConvertUchar3Uint3Uchar3(uint3 inV) {
+    return convert_uchar3(inV);
+}
+
+uchar4 __attribute__((kernel)) testConvertUchar4Uint4Uchar4(uint4 inV) {
+    return convert_uchar4(inV);
+}
+
+short2 __attribute__((kernel)) testConvertShort2Float2Short2(float2 inV) {
+    return convert_short2(inV);
+}
+
+short3 __attribute__((kernel)) testConvertShort3Float3Short3(float3 inV) {
+    return convert_short3(inV);
+}
+
+short4 __attribute__((kernel)) testConvertShort4Float4Short4(float4 inV) {
+    return convert_short4(inV);
+}
+
+short2 __attribute__((kernel)) testConvertShort2Char2Short2(char2 inV) {
+    return convert_short2(inV);
+}
+
+short3 __attribute__((kernel)) testConvertShort3Char3Short3(char3 inV) {
+    return convert_short3(inV);
+}
+
+short4 __attribute__((kernel)) testConvertShort4Char4Short4(char4 inV) {
+    return convert_short4(inV);
+}
+
+short2 __attribute__((kernel)) testConvertShort2Uchar2Short2(uchar2 inV) {
+    return convert_short2(inV);
+}
+
+short3 __attribute__((kernel)) testConvertShort3Uchar3Short3(uchar3 inV) {
+    return convert_short3(inV);
+}
+
+short4 __attribute__((kernel)) testConvertShort4Uchar4Short4(uchar4 inV) {
+    return convert_short4(inV);
+}
+
+short2 __attribute__((kernel)) testConvertShort2Short2Short2(short2 inV) {
+    return convert_short2(inV);
+}
+
+short3 __attribute__((kernel)) testConvertShort3Short3Short3(short3 inV) {
+    return convert_short3(inV);
+}
+
+short4 __attribute__((kernel)) testConvertShort4Short4Short4(short4 inV) {
+    return convert_short4(inV);
+}
+
+short2 __attribute__((kernel)) testConvertShort2Ushort2Short2(ushort2 inV) {
+    return convert_short2(inV);
+}
+
+short3 __attribute__((kernel)) testConvertShort3Ushort3Short3(ushort3 inV) {
+    return convert_short3(inV);
+}
+
+short4 __attribute__((kernel)) testConvertShort4Ushort4Short4(ushort4 inV) {
+    return convert_short4(inV);
+}
+
+short2 __attribute__((kernel)) testConvertShort2Int2Short2(int2 inV) {
+    return convert_short2(inV);
+}
+
+short3 __attribute__((kernel)) testConvertShort3Int3Short3(int3 inV) {
+    return convert_short3(inV);
+}
+
+short4 __attribute__((kernel)) testConvertShort4Int4Short4(int4 inV) {
+    return convert_short4(inV);
+}
+
+short2 __attribute__((kernel)) testConvertShort2Uint2Short2(uint2 inV) {
+    return convert_short2(inV);
+}
+
+short3 __attribute__((kernel)) testConvertShort3Uint3Short3(uint3 inV) {
+    return convert_short3(inV);
+}
+
+short4 __attribute__((kernel)) testConvertShort4Uint4Short4(uint4 inV) {
+    return convert_short4(inV);
+}
+
+ushort2 __attribute__((kernel)) testConvertUshort2Float2Ushort2(float2 inV) {
+    return convert_ushort2(inV);
+}
+
+ushort3 __attribute__((kernel)) testConvertUshort3Float3Ushort3(float3 inV) {
+    return convert_ushort3(inV);
+}
+
+ushort4 __attribute__((kernel)) testConvertUshort4Float4Ushort4(float4 inV) {
+    return convert_ushort4(inV);
+}
+
+ushort2 __attribute__((kernel)) testConvertUshort2Char2Ushort2(char2 inV) {
+    return convert_ushort2(inV);
+}
+
+ushort3 __attribute__((kernel)) testConvertUshort3Char3Ushort3(char3 inV) {
+    return convert_ushort3(inV);
+}
+
+ushort4 __attribute__((kernel)) testConvertUshort4Char4Ushort4(char4 inV) {
+    return convert_ushort4(inV);
+}
+
+ushort2 __attribute__((kernel)) testConvertUshort2Uchar2Ushort2(uchar2 inV) {
+    return convert_ushort2(inV);
+}
+
+ushort3 __attribute__((kernel)) testConvertUshort3Uchar3Ushort3(uchar3 inV) {
+    return convert_ushort3(inV);
+}
+
+ushort4 __attribute__((kernel)) testConvertUshort4Uchar4Ushort4(uchar4 inV) {
+    return convert_ushort4(inV);
+}
+
+ushort2 __attribute__((kernel)) testConvertUshort2Short2Ushort2(short2 inV) {
+    return convert_ushort2(inV);
+}
+
+ushort3 __attribute__((kernel)) testConvertUshort3Short3Ushort3(short3 inV) {
+    return convert_ushort3(inV);
+}
+
+ushort4 __attribute__((kernel)) testConvertUshort4Short4Ushort4(short4 inV) {
+    return convert_ushort4(inV);
+}
+
+ushort2 __attribute__((kernel)) testConvertUshort2Ushort2Ushort2(ushort2 inV) {
+    return convert_ushort2(inV);
+}
+
+ushort3 __attribute__((kernel)) testConvertUshort3Ushort3Ushort3(ushort3 inV) {
+    return convert_ushort3(inV);
+}
+
+ushort4 __attribute__((kernel)) testConvertUshort4Ushort4Ushort4(ushort4 inV) {
+    return convert_ushort4(inV);
+}
+
+ushort2 __attribute__((kernel)) testConvertUshort2Int2Ushort2(int2 inV) {
+    return convert_ushort2(inV);
+}
+
+ushort3 __attribute__((kernel)) testConvertUshort3Int3Ushort3(int3 inV) {
+    return convert_ushort3(inV);
+}
+
+ushort4 __attribute__((kernel)) testConvertUshort4Int4Ushort4(int4 inV) {
+    return convert_ushort4(inV);
+}
+
+ushort2 __attribute__((kernel)) testConvertUshort2Uint2Ushort2(uint2 inV) {
+    return convert_ushort2(inV);
+}
+
+ushort3 __attribute__((kernel)) testConvertUshort3Uint3Ushort3(uint3 inV) {
+    return convert_ushort3(inV);
+}
+
+ushort4 __attribute__((kernel)) testConvertUshort4Uint4Ushort4(uint4 inV) {
+    return convert_ushort4(inV);
+}
+
+int2 __attribute__((kernel)) testConvertInt2Float2Int2(float2 inV) {
+    return convert_int2(inV);
+}
+
+int3 __attribute__((kernel)) testConvertInt3Float3Int3(float3 inV) {
+    return convert_int3(inV);
+}
+
+int4 __attribute__((kernel)) testConvertInt4Float4Int4(float4 inV) {
+    return convert_int4(inV);
+}
+
+int2 __attribute__((kernel)) testConvertInt2Char2Int2(char2 inV) {
+    return convert_int2(inV);
+}
+
+int3 __attribute__((kernel)) testConvertInt3Char3Int3(char3 inV) {
+    return convert_int3(inV);
+}
+
+int4 __attribute__((kernel)) testConvertInt4Char4Int4(char4 inV) {
+    return convert_int4(inV);
+}
+
+int2 __attribute__((kernel)) testConvertInt2Uchar2Int2(uchar2 inV) {
+    return convert_int2(inV);
+}
+
+int3 __attribute__((kernel)) testConvertInt3Uchar3Int3(uchar3 inV) {
+    return convert_int3(inV);
+}
+
+int4 __attribute__((kernel)) testConvertInt4Uchar4Int4(uchar4 inV) {
+    return convert_int4(inV);
+}
+
+int2 __attribute__((kernel)) testConvertInt2Short2Int2(short2 inV) {
+    return convert_int2(inV);
+}
+
+int3 __attribute__((kernel)) testConvertInt3Short3Int3(short3 inV) {
+    return convert_int3(inV);
+}
+
+int4 __attribute__((kernel)) testConvertInt4Short4Int4(short4 inV) {
+    return convert_int4(inV);
+}
+
+int2 __attribute__((kernel)) testConvertInt2Ushort2Int2(ushort2 inV) {
+    return convert_int2(inV);
+}
+
+int3 __attribute__((kernel)) testConvertInt3Ushort3Int3(ushort3 inV) {
+    return convert_int3(inV);
+}
+
+int4 __attribute__((kernel)) testConvertInt4Ushort4Int4(ushort4 inV) {
+    return convert_int4(inV);
+}
+
+int2 __attribute__((kernel)) testConvertInt2Int2Int2(int2 inV) {
+    return convert_int2(inV);
+}
+
+int3 __attribute__((kernel)) testConvertInt3Int3Int3(int3 inV) {
+    return convert_int3(inV);
+}
+
+int4 __attribute__((kernel)) testConvertInt4Int4Int4(int4 inV) {
+    return convert_int4(inV);
+}
+
+int2 __attribute__((kernel)) testConvertInt2Uint2Int2(uint2 inV) {
+    return convert_int2(inV);
+}
+
+int3 __attribute__((kernel)) testConvertInt3Uint3Int3(uint3 inV) {
+    return convert_int3(inV);
+}
+
+int4 __attribute__((kernel)) testConvertInt4Uint4Int4(uint4 inV) {
+    return convert_int4(inV);
+}
+
+uint2 __attribute__((kernel)) testConvertUint2Float2Uint2(float2 inV) {
+    return convert_uint2(inV);
+}
+
+uint3 __attribute__((kernel)) testConvertUint3Float3Uint3(float3 inV) {
+    return convert_uint3(inV);
+}
+
+uint4 __attribute__((kernel)) testConvertUint4Float4Uint4(float4 inV) {
+    return convert_uint4(inV);
+}
+
+uint2 __attribute__((kernel)) testConvertUint2Char2Uint2(char2 inV) {
+    return convert_uint2(inV);
+}
+
+uint3 __attribute__((kernel)) testConvertUint3Char3Uint3(char3 inV) {
+    return convert_uint3(inV);
+}
+
+uint4 __attribute__((kernel)) testConvertUint4Char4Uint4(char4 inV) {
+    return convert_uint4(inV);
+}
+
+uint2 __attribute__((kernel)) testConvertUint2Uchar2Uint2(uchar2 inV) {
+    return convert_uint2(inV);
+}
+
+uint3 __attribute__((kernel)) testConvertUint3Uchar3Uint3(uchar3 inV) {
+    return convert_uint3(inV);
+}
+
+uint4 __attribute__((kernel)) testConvertUint4Uchar4Uint4(uchar4 inV) {
+    return convert_uint4(inV);
+}
+
+uint2 __attribute__((kernel)) testConvertUint2Short2Uint2(short2 inV) {
+    return convert_uint2(inV);
+}
+
+uint3 __attribute__((kernel)) testConvertUint3Short3Uint3(short3 inV) {
+    return convert_uint3(inV);
+}
+
+uint4 __attribute__((kernel)) testConvertUint4Short4Uint4(short4 inV) {
+    return convert_uint4(inV);
+}
+
+uint2 __attribute__((kernel)) testConvertUint2Ushort2Uint2(ushort2 inV) {
+    return convert_uint2(inV);
+}
+
+uint3 __attribute__((kernel)) testConvertUint3Ushort3Uint3(ushort3 inV) {
+    return convert_uint3(inV);
+}
+
+uint4 __attribute__((kernel)) testConvertUint4Ushort4Uint4(ushort4 inV) {
+    return convert_uint4(inV);
+}
+
+uint2 __attribute__((kernel)) testConvertUint2Int2Uint2(int2 inV) {
+    return convert_uint2(inV);
+}
+
+uint3 __attribute__((kernel)) testConvertUint3Int3Uint3(int3 inV) {
+    return convert_uint3(inV);
+}
+
+uint4 __attribute__((kernel)) testConvertUint4Int4Uint4(int4 inV) {
+    return convert_uint4(inV);
+}
+
+uint2 __attribute__((kernel)) testConvertUint2Uint2Uint2(uint2 inV) {
+    return convert_uint2(inV);
+}
+
+uint3 __attribute__((kernel)) testConvertUint3Uint3Uint3(uint3 inV) {
+    return convert_uint3(inV);
+}
+
+uint4 __attribute__((kernel)) testConvertUint4Uint4Uint4(uint4 inV) {
+    return convert_uint4(inV);
+}
diff --git a/tests/src/android/renderscript/cts/TestConvertRelaxed.rs b/tests/src/android/renderscript/cts/TestConvertRelaxed.rs
new file mode 100644
index 0000000..d13c634
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestConvertRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestConvert.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestCopysign.rs b/tests/src/android/renderscript/cts/TestCopysign.rs
new file mode 100644
index 0000000..d7bc4d0
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestCopysign.rs
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+rs_allocation gAllocInY;
+
+float __attribute__((kernel)) testCopysignFloatFloatFloat(float inX, unsigned int x) {
+    float inY = rsGetElementAt_float(gAllocInY, x);
+    return copysign(inX, inY);
+}
+
+float2 __attribute__((kernel)) testCopysignFloat2Float2Float2(float2 inX, unsigned int x) {
+    float2 inY = rsGetElementAt_float2(gAllocInY, x);
+    return copysign(inX, inY);
+}
+
+float3 __attribute__((kernel)) testCopysignFloat3Float3Float3(float3 inX, unsigned int x) {
+    float3 inY = rsGetElementAt_float3(gAllocInY, x);
+    return copysign(inX, inY);
+}
+
+float4 __attribute__((kernel)) testCopysignFloat4Float4Float4(float4 inX, unsigned int x) {
+    float4 inY = rsGetElementAt_float4(gAllocInY, x);
+    return copysign(inX, inY);
+}
diff --git a/tests/src/android/renderscript/cts/TestCopysignRelaxed.rs b/tests/src/android/renderscript/cts/TestCopysignRelaxed.rs
new file mode 100644
index 0000000..01002d7
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestCopysignRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestCopysign.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestCos.rs b/tests/src/android/renderscript/cts/TestCos.rs
new file mode 100644
index 0000000..5605139
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestCos.rs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+
+float __attribute__((kernel)) testCosFloatFloat(float in) {
+    return cos(in);
+}
+
+float2 __attribute__((kernel)) testCosFloat2Float2(float2 in) {
+    return cos(in);
+}
+
+float3 __attribute__((kernel)) testCosFloat3Float3(float3 in) {
+    return cos(in);
+}
+
+float4 __attribute__((kernel)) testCosFloat4Float4(float4 in) {
+    return cos(in);
+}
diff --git a/tests/src/android/renderscript/cts/TestCosRelaxed.rs b/tests/src/android/renderscript/cts/TestCosRelaxed.rs
new file mode 100644
index 0000000..1871a69
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestCosRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestCos.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestCosh.rs b/tests/src/android/renderscript/cts/TestCosh.rs
new file mode 100644
index 0000000..b2d89b9
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestCosh.rs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+
+float __attribute__((kernel)) testCoshFloatFloat(float in) {
+    return cosh(in);
+}
+
+float2 __attribute__((kernel)) testCoshFloat2Float2(float2 in) {
+    return cosh(in);
+}
+
+float3 __attribute__((kernel)) testCoshFloat3Float3(float3 in) {
+    return cosh(in);
+}
+
+float4 __attribute__((kernel)) testCoshFloat4Float4(float4 in) {
+    return cosh(in);
+}
diff --git a/tests/src/android/renderscript/cts/TestCoshRelaxed.rs b/tests/src/android/renderscript/cts/TestCoshRelaxed.rs
new file mode 100644
index 0000000..cf28629
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestCoshRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestCosh.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestCospi.rs b/tests/src/android/renderscript/cts/TestCospi.rs
new file mode 100644
index 0000000..a0cc778
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestCospi.rs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+
+float __attribute__((kernel)) testCospiFloatFloat(float in) {
+    return cospi(in);
+}
+
+float2 __attribute__((kernel)) testCospiFloat2Float2(float2 in) {
+    return cospi(in);
+}
+
+float3 __attribute__((kernel)) testCospiFloat3Float3(float3 in) {
+    return cospi(in);
+}
+
+float4 __attribute__((kernel)) testCospiFloat4Float4(float4 in) {
+    return cospi(in);
+}
diff --git a/tests/src/android/renderscript/cts/TestCospiRelaxed.rs b/tests/src/android/renderscript/cts/TestCospiRelaxed.rs
new file mode 100644
index 0000000..aac7b90
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestCospiRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestCospi.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestCross.rs b/tests/src/android/renderscript/cts/TestCross.rs
new file mode 100644
index 0000000..16d5d35
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestCross.rs
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+rs_allocation gAllocInRhs;
+
+float3 __attribute__((kernel)) testCrossFloat3Float3Float3(float3 inLhs, unsigned int x) {
+    float3 inRhs = rsGetElementAt_float3(gAllocInRhs, x);
+    return cross(inLhs, inRhs);
+}
+
+float4 __attribute__((kernel)) testCrossFloat4Float4Float4(float4 inLhs, unsigned int x) {
+    float4 inRhs = rsGetElementAt_float4(gAllocInRhs, x);
+    return cross(inLhs, inRhs);
+}
diff --git a/tests/src/android/renderscript/cts/TestCrossRelaxed.rs b/tests/src/android/renderscript/cts/TestCrossRelaxed.rs
new file mode 100644
index 0000000..59fa62d
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestCrossRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestCross.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestDegrees.rs b/tests/src/android/renderscript/cts/TestDegrees.rs
new file mode 100644
index 0000000..78741a8
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestDegrees.rs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+
+float __attribute__((kernel)) testDegreesFloatFloat(float inValue) {
+    return degrees(inValue);
+}
+
+float2 __attribute__((kernel)) testDegreesFloat2Float2(float2 inValue) {
+    return degrees(inValue);
+}
+
+float3 __attribute__((kernel)) testDegreesFloat3Float3(float3 inValue) {
+    return degrees(inValue);
+}
+
+float4 __attribute__((kernel)) testDegreesFloat4Float4(float4 inValue) {
+    return degrees(inValue);
+}
diff --git a/tests/src/android/renderscript/cts/TestDegreesRelaxed.rs b/tests/src/android/renderscript/cts/TestDegreesRelaxed.rs
new file mode 100644
index 0000000..7a443bf
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestDegreesRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestDegrees.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestDistance.rs b/tests/src/android/renderscript/cts/TestDistance.rs
new file mode 100644
index 0000000..fdc1783
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestDistance.rs
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+rs_allocation gAllocInRhs;
+
+float __attribute__((kernel)) testDistanceFloatFloatFloat(float inLhs, unsigned int x) {
+    float inRhs = rsGetElementAt_float(gAllocInRhs, x);
+    return distance(inLhs, inRhs);
+}
+
+float __attribute__((kernel)) testDistanceFloat2Float2Float(float2 inLhs, unsigned int x) {
+    float2 inRhs = rsGetElementAt_float2(gAllocInRhs, x);
+    return distance(inLhs, inRhs);
+}
+
+float __attribute__((kernel)) testDistanceFloat3Float3Float(float3 inLhs, unsigned int x) {
+    float3 inRhs = rsGetElementAt_float3(gAllocInRhs, x);
+    return distance(inLhs, inRhs);
+}
+
+float __attribute__((kernel)) testDistanceFloat4Float4Float(float4 inLhs, unsigned int x) {
+    float4 inRhs = rsGetElementAt_float4(gAllocInRhs, x);
+    return distance(inLhs, inRhs);
+}
diff --git a/tests/src/android/renderscript/cts/TestDistanceRelaxed.rs b/tests/src/android/renderscript/cts/TestDistanceRelaxed.rs
new file mode 100644
index 0000000..ba4c096
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestDistanceRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestDistance.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestDot.rs b/tests/src/android/renderscript/cts/TestDot.rs
new file mode 100644
index 0000000..27aa8aa
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestDot.rs
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+rs_allocation gAllocInRhs;
+
+float __attribute__((kernel)) testDotFloatFloatFloat(float inLhs, unsigned int x) {
+    float inRhs = rsGetElementAt_float(gAllocInRhs, x);
+    return dot(inLhs, inRhs);
+}
+
+float __attribute__((kernel)) testDotFloat2Float2Float(float2 inLhs, unsigned int x) {
+    float2 inRhs = rsGetElementAt_float2(gAllocInRhs, x);
+    return dot(inLhs, inRhs);
+}
+
+float __attribute__((kernel)) testDotFloat3Float3Float(float3 inLhs, unsigned int x) {
+    float3 inRhs = rsGetElementAt_float3(gAllocInRhs, x);
+    return dot(inLhs, inRhs);
+}
+
+float __attribute__((kernel)) testDotFloat4Float4Float(float4 inLhs, unsigned int x) {
+    float4 inRhs = rsGetElementAt_float4(gAllocInRhs, x);
+    return dot(inLhs, inRhs);
+}
diff --git a/tests/src/android/renderscript/cts/TestDotRelaxed.rs b/tests/src/android/renderscript/cts/TestDotRelaxed.rs
new file mode 100644
index 0000000..53e7080
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestDotRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestDot.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestErf.rs b/tests/src/android/renderscript/cts/TestErf.rs
new file mode 100644
index 0000000..5d26ed6
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestErf.rs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+
+float __attribute__((kernel)) testErfFloatFloat(float in) {
+    return erf(in);
+}
+
+float2 __attribute__((kernel)) testErfFloat2Float2(float2 in) {
+    return erf(in);
+}
+
+float3 __attribute__((kernel)) testErfFloat3Float3(float3 in) {
+    return erf(in);
+}
+
+float4 __attribute__((kernel)) testErfFloat4Float4(float4 in) {
+    return erf(in);
+}
diff --git a/tests/src/android/renderscript/cts/TestErfRelaxed.rs b/tests/src/android/renderscript/cts/TestErfRelaxed.rs
new file mode 100644
index 0000000..1551db8
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestErfRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestErf.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestErfc.rs b/tests/src/android/renderscript/cts/TestErfc.rs
new file mode 100644
index 0000000..d12ea25
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestErfc.rs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+
+float __attribute__((kernel)) testErfcFloatFloat(float in) {
+    return erfc(in);
+}
+
+float2 __attribute__((kernel)) testErfcFloat2Float2(float2 in) {
+    return erfc(in);
+}
+
+float3 __attribute__((kernel)) testErfcFloat3Float3(float3 in) {
+    return erfc(in);
+}
+
+float4 __attribute__((kernel)) testErfcFloat4Float4(float4 in) {
+    return erfc(in);
+}
diff --git a/tests/src/android/renderscript/cts/TestErfcRelaxed.rs b/tests/src/android/renderscript/cts/TestErfcRelaxed.rs
new file mode 100644
index 0000000..f6117c8
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestErfcRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestErfc.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestExp.rs b/tests/src/android/renderscript/cts/TestExp.rs
new file mode 100644
index 0000000..90879d9
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestExp.rs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+
+float __attribute__((kernel)) testExpFloatFloat(float in) {
+    return exp(in);
+}
+
+float2 __attribute__((kernel)) testExpFloat2Float2(float2 in) {
+    return exp(in);
+}
+
+float3 __attribute__((kernel)) testExpFloat3Float3(float3 in) {
+    return exp(in);
+}
+
+float4 __attribute__((kernel)) testExpFloat4Float4(float4 in) {
+    return exp(in);
+}
diff --git a/tests/src/android/renderscript/cts/TestExp10.rs b/tests/src/android/renderscript/cts/TestExp10.rs
new file mode 100644
index 0000000..117fe26
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestExp10.rs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+
+float __attribute__((kernel)) testExp10FloatFloat(float in) {
+    return exp10(in);
+}
+
+float2 __attribute__((kernel)) testExp10Float2Float2(float2 in) {
+    return exp10(in);
+}
+
+float3 __attribute__((kernel)) testExp10Float3Float3(float3 in) {
+    return exp10(in);
+}
+
+float4 __attribute__((kernel)) testExp10Float4Float4(float4 in) {
+    return exp10(in);
+}
diff --git a/tests/src/android/renderscript/cts/TestExp10Relaxed.rs b/tests/src/android/renderscript/cts/TestExp10Relaxed.rs
new file mode 100644
index 0000000..9b07598
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestExp10Relaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestExp10.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestExp2.rs b/tests/src/android/renderscript/cts/TestExp2.rs
new file mode 100644
index 0000000..61ff900
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestExp2.rs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+
+float __attribute__((kernel)) testExp2FloatFloat(float in) {
+    return exp2(in);
+}
+
+float2 __attribute__((kernel)) testExp2Float2Float2(float2 in) {
+    return exp2(in);
+}
+
+float3 __attribute__((kernel)) testExp2Float3Float3(float3 in) {
+    return exp2(in);
+}
+
+float4 __attribute__((kernel)) testExp2Float4Float4(float4 in) {
+    return exp2(in);
+}
diff --git a/tests/src/android/renderscript/cts/TestExp2Relaxed.rs b/tests/src/android/renderscript/cts/TestExp2Relaxed.rs
new file mode 100644
index 0000000..06810b3
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestExp2Relaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestExp2.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestExpRelaxed.rs b/tests/src/android/renderscript/cts/TestExpRelaxed.rs
new file mode 100644
index 0000000..f98bf80
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestExpRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestExp.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestExpm1.rs b/tests/src/android/renderscript/cts/TestExpm1.rs
new file mode 100644
index 0000000..9399576
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestExpm1.rs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+
+float __attribute__((kernel)) testExpm1FloatFloat(float in) {
+    return expm1(in);
+}
+
+float2 __attribute__((kernel)) testExpm1Float2Float2(float2 in) {
+    return expm1(in);
+}
+
+float3 __attribute__((kernel)) testExpm1Float3Float3(float3 in) {
+    return expm1(in);
+}
+
+float4 __attribute__((kernel)) testExpm1Float4Float4(float4 in) {
+    return expm1(in);
+}
diff --git a/tests/src/android/renderscript/cts/TestExpm1Relaxed.rs b/tests/src/android/renderscript/cts/TestExpm1Relaxed.rs
new file mode 100644
index 0000000..bd73f9d
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestExpm1Relaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestExpm1.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestFabs.rs b/tests/src/android/renderscript/cts/TestFabs.rs
new file mode 100644
index 0000000..aed0318
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestFabs.rs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+
+float __attribute__((kernel)) testFabsFloatFloat(float in) {
+    return fabs(in);
+}
+
+float2 __attribute__((kernel)) testFabsFloat2Float2(float2 in) {
+    return fabs(in);
+}
+
+float3 __attribute__((kernel)) testFabsFloat3Float3(float3 in) {
+    return fabs(in);
+}
+
+float4 __attribute__((kernel)) testFabsFloat4Float4(float4 in) {
+    return fabs(in);
+}
diff --git a/tests/src/android/renderscript/cts/TestFabsRelaxed.rs b/tests/src/android/renderscript/cts/TestFabsRelaxed.rs
new file mode 100644
index 0000000..4d2214a
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestFabsRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestFabs.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestFastDistance.rs b/tests/src/android/renderscript/cts/TestFastDistance.rs
new file mode 100644
index 0000000..62c0931
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestFastDistance.rs
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+rs_allocation gAllocInRhs;
+
+float __attribute__((kernel)) testFastDistanceFloatFloatFloat(float inLhs, unsigned int x) {
+    float inRhs = rsGetElementAt_float(gAllocInRhs, x);
+    return fast_distance(inLhs, inRhs);
+}
+
+float __attribute__((kernel)) testFastDistanceFloat2Float2Float(float2 inLhs, unsigned int x) {
+    float2 inRhs = rsGetElementAt_float2(gAllocInRhs, x);
+    return fast_distance(inLhs, inRhs);
+}
+
+float __attribute__((kernel)) testFastDistanceFloat3Float3Float(float3 inLhs, unsigned int x) {
+    float3 inRhs = rsGetElementAt_float3(gAllocInRhs, x);
+    return fast_distance(inLhs, inRhs);
+}
+
+float __attribute__((kernel)) testFastDistanceFloat4Float4Float(float4 inLhs, unsigned int x) {
+    float4 inRhs = rsGetElementAt_float4(gAllocInRhs, x);
+    return fast_distance(inLhs, inRhs);
+}
diff --git a/tests/src/android/renderscript/cts/TestFastDistanceRelaxed.rs b/tests/src/android/renderscript/cts/TestFastDistanceRelaxed.rs
new file mode 100644
index 0000000..245bc65
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestFastDistanceRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestFastDistance.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestFastLength.rs b/tests/src/android/renderscript/cts/TestFastLength.rs
new file mode 100644
index 0000000..f4fc853
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestFastLength.rs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+
+float __attribute__((kernel)) testFastLengthFloatFloat(float inV) {
+    return fast_length(inV);
+}
+
+float __attribute__((kernel)) testFastLengthFloat2Float(float2 inV) {
+    return fast_length(inV);
+}
+
+float __attribute__((kernel)) testFastLengthFloat3Float(float3 inV) {
+    return fast_length(inV);
+}
+
+float __attribute__((kernel)) testFastLengthFloat4Float(float4 inV) {
+    return fast_length(inV);
+}
diff --git a/tests/src/android/renderscript/cts/TestFastLengthRelaxed.rs b/tests/src/android/renderscript/cts/TestFastLengthRelaxed.rs
new file mode 100644
index 0000000..680c3e1
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestFastLengthRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestFastLength.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestFastNormalize.rs b/tests/src/android/renderscript/cts/TestFastNormalize.rs
new file mode 100644
index 0000000..449c49c
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestFastNormalize.rs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+
+float __attribute__((kernel)) testFastNormalizeFloatFloat(float inV) {
+    return fast_normalize(inV);
+}
+
+float2 __attribute__((kernel)) testFastNormalizeFloat2Float2(float2 inV) {
+    return fast_normalize(inV);
+}
+
+float3 __attribute__((kernel)) testFastNormalizeFloat3Float3(float3 inV) {
+    return fast_normalize(inV);
+}
+
+float4 __attribute__((kernel)) testFastNormalizeFloat4Float4(float4 inV) {
+    return fast_normalize(inV);
+}
diff --git a/tests/src/android/renderscript/cts/TestFastNormalizeRelaxed.rs b/tests/src/android/renderscript/cts/TestFastNormalizeRelaxed.rs
new file mode 100644
index 0000000..e195f60
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestFastNormalizeRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestFastNormalize.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestFdim.rs b/tests/src/android/renderscript/cts/TestFdim.rs
new file mode 100644
index 0000000..8f68c14
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestFdim.rs
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+rs_allocation gAllocInB;
+
+float __attribute__((kernel)) testFdimFloatFloatFloat(float inA, unsigned int x) {
+    float inB = rsGetElementAt_float(gAllocInB, x);
+    return fdim(inA, inB);
+}
+
+float2 __attribute__((kernel)) testFdimFloat2Float2Float2(float2 inA, unsigned int x) {
+    float2 inB = rsGetElementAt_float2(gAllocInB, x);
+    return fdim(inA, inB);
+}
+
+float3 __attribute__((kernel)) testFdimFloat3Float3Float3(float3 inA, unsigned int x) {
+    float3 inB = rsGetElementAt_float3(gAllocInB, x);
+    return fdim(inA, inB);
+}
+
+float4 __attribute__((kernel)) testFdimFloat4Float4Float4(float4 inA, unsigned int x) {
+    float4 inB = rsGetElementAt_float4(gAllocInB, x);
+    return fdim(inA, inB);
+}
diff --git a/tests/src/android/renderscript/cts/TestFdimRelaxed.rs b/tests/src/android/renderscript/cts/TestFdimRelaxed.rs
new file mode 100644
index 0000000..473a588
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestFdimRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestFdim.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestFloor.rs b/tests/src/android/renderscript/cts/TestFloor.rs
new file mode 100644
index 0000000..f74fc2b
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestFloor.rs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+
+float __attribute__((kernel)) testFloorFloatFloat(float in) {
+    return floor(in);
+}
+
+float2 __attribute__((kernel)) testFloorFloat2Float2(float2 in) {
+    return floor(in);
+}
+
+float3 __attribute__((kernel)) testFloorFloat3Float3(float3 in) {
+    return floor(in);
+}
+
+float4 __attribute__((kernel)) testFloorFloat4Float4(float4 in) {
+    return floor(in);
+}
diff --git a/tests/src/android/renderscript/cts/TestFloorRelaxed.rs b/tests/src/android/renderscript/cts/TestFloorRelaxed.rs
new file mode 100644
index 0000000..4caf0de
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestFloorRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestFloor.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestFma.rs b/tests/src/android/renderscript/cts/TestFma.rs
new file mode 100644
index 0000000..b0cb2dd
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestFma.rs
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+rs_allocation gAllocInB;
+rs_allocation gAllocInC;
+
+float __attribute__((kernel)) testFmaFloatFloatFloatFloat(float inA, unsigned int x) {
+    float inB = rsGetElementAt_float(gAllocInB, x);
+    float inC = rsGetElementAt_float(gAllocInC, x);
+    return fma(inA, inB, inC);
+}
+
+float2 __attribute__((kernel)) testFmaFloat2Float2Float2Float2(float2 inA, unsigned int x) {
+    float2 inB = rsGetElementAt_float2(gAllocInB, x);
+    float2 inC = rsGetElementAt_float2(gAllocInC, x);
+    return fma(inA, inB, inC);
+}
+
+float3 __attribute__((kernel)) testFmaFloat3Float3Float3Float3(float3 inA, unsigned int x) {
+    float3 inB = rsGetElementAt_float3(gAllocInB, x);
+    float3 inC = rsGetElementAt_float3(gAllocInC, x);
+    return fma(inA, inB, inC);
+}
+
+float4 __attribute__((kernel)) testFmaFloat4Float4Float4Float4(float4 inA, unsigned int x) {
+    float4 inB = rsGetElementAt_float4(gAllocInB, x);
+    float4 inC = rsGetElementAt_float4(gAllocInC, x);
+    return fma(inA, inB, inC);
+}
diff --git a/tests/src/android/renderscript/cts/TestFmaRelaxed.rs b/tests/src/android/renderscript/cts/TestFmaRelaxed.rs
new file mode 100644
index 0000000..cc80e06
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestFmaRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestFma.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestFmax.rs b/tests/src/android/renderscript/cts/TestFmax.rs
new file mode 100644
index 0000000..50e5e3f
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestFmax.rs
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+rs_allocation gAllocInY;
+
+float __attribute__((kernel)) testFmaxFloatFloatFloat(float inX, unsigned int x) {
+    float inY = rsGetElementAt_float(gAllocInY, x);
+    return fmax(inX, inY);
+}
+
+float2 __attribute__((kernel)) testFmaxFloat2Float2Float2(float2 inX, unsigned int x) {
+    float2 inY = rsGetElementAt_float2(gAllocInY, x);
+    return fmax(inX, inY);
+}
+
+float3 __attribute__((kernel)) testFmaxFloat3Float3Float3(float3 inX, unsigned int x) {
+    float3 inY = rsGetElementAt_float3(gAllocInY, x);
+    return fmax(inX, inY);
+}
+
+float4 __attribute__((kernel)) testFmaxFloat4Float4Float4(float4 inX, unsigned int x) {
+    float4 inY = rsGetElementAt_float4(gAllocInY, x);
+    return fmax(inX, inY);
+}
+
+float2 __attribute__((kernel)) testFmaxFloat2FloatFloat2(float2 inX, unsigned int x) {
+    float inY = rsGetElementAt_float(gAllocInY, x);
+    return fmax(inX, inY);
+}
+
+float3 __attribute__((kernel)) testFmaxFloat3FloatFloat3(float3 inX, unsigned int x) {
+    float inY = rsGetElementAt_float(gAllocInY, x);
+    return fmax(inX, inY);
+}
+
+float4 __attribute__((kernel)) testFmaxFloat4FloatFloat4(float4 inX, unsigned int x) {
+    float inY = rsGetElementAt_float(gAllocInY, x);
+    return fmax(inX, inY);
+}
diff --git a/tests/src/android/renderscript/cts/TestFmaxRelaxed.rs b/tests/src/android/renderscript/cts/TestFmaxRelaxed.rs
new file mode 100644
index 0000000..74c8b3d
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestFmaxRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestFmax.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestFmin.rs b/tests/src/android/renderscript/cts/TestFmin.rs
new file mode 100644
index 0000000..28db18f
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestFmin.rs
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+rs_allocation gAllocInY;
+
+float __attribute__((kernel)) testFminFloatFloatFloat(float inX, unsigned int x) {
+    float inY = rsGetElementAt_float(gAllocInY, x);
+    return fmin(inX, inY);
+}
+
+float2 __attribute__((kernel)) testFminFloat2Float2Float2(float2 inX, unsigned int x) {
+    float2 inY = rsGetElementAt_float2(gAllocInY, x);
+    return fmin(inX, inY);
+}
+
+float3 __attribute__((kernel)) testFminFloat3Float3Float3(float3 inX, unsigned int x) {
+    float3 inY = rsGetElementAt_float3(gAllocInY, x);
+    return fmin(inX, inY);
+}
+
+float4 __attribute__((kernel)) testFminFloat4Float4Float4(float4 inX, unsigned int x) {
+    float4 inY = rsGetElementAt_float4(gAllocInY, x);
+    return fmin(inX, inY);
+}
+
+float2 __attribute__((kernel)) testFminFloat2FloatFloat2(float2 inX, unsigned int x) {
+    float inY = rsGetElementAt_float(gAllocInY, x);
+    return fmin(inX, inY);
+}
+
+float3 __attribute__((kernel)) testFminFloat3FloatFloat3(float3 inX, unsigned int x) {
+    float inY = rsGetElementAt_float(gAllocInY, x);
+    return fmin(inX, inY);
+}
+
+float4 __attribute__((kernel)) testFminFloat4FloatFloat4(float4 inX, unsigned int x) {
+    float inY = rsGetElementAt_float(gAllocInY, x);
+    return fmin(inX, inY);
+}
diff --git a/tests/src/android/renderscript/cts/TestFminRelaxed.rs b/tests/src/android/renderscript/cts/TestFminRelaxed.rs
new file mode 100644
index 0000000..571f64a
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestFminRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestFmin.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestFmod.rs b/tests/src/android/renderscript/cts/TestFmod.rs
new file mode 100644
index 0000000..c1c2bff
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestFmod.rs
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+rs_allocation gAllocInY;
+
+float __attribute__((kernel)) testFmodFloatFloatFloat(float inX, unsigned int x) {
+    float inY = rsGetElementAt_float(gAllocInY, x);
+    return fmod(inX, inY);
+}
+
+float2 __attribute__((kernel)) testFmodFloat2Float2Float2(float2 inX, unsigned int x) {
+    float2 inY = rsGetElementAt_float2(gAllocInY, x);
+    return fmod(inX, inY);
+}
+
+float3 __attribute__((kernel)) testFmodFloat3Float3Float3(float3 inX, unsigned int x) {
+    float3 inY = rsGetElementAt_float3(gAllocInY, x);
+    return fmod(inX, inY);
+}
+
+float4 __attribute__((kernel)) testFmodFloat4Float4Float4(float4 inX, unsigned int x) {
+    float4 inY = rsGetElementAt_float4(gAllocInY, x);
+    return fmod(inX, inY);
+}
diff --git a/tests/src/android/renderscript/cts/TestFmodRelaxed.rs b/tests/src/android/renderscript/cts/TestFmodRelaxed.rs
new file mode 100644
index 0000000..02888a1
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestFmodRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestFmod.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestFract.rs b/tests/src/android/renderscript/cts/TestFract.rs
new file mode 100644
index 0000000..38351ab
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestFract.rs
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+rs_allocation gAllocOutFloor;
+
+float __attribute__((kernel)) testFractFloatFloatFloat(float inV, unsigned int x) {
+    float outFloor = 0;
+    float out = fract(inV, &outFloor);
+    rsSetElementAt_float(gAllocOutFloor, outFloor, x);
+    return out;
+}
+
+float2 __attribute__((kernel)) testFractFloat2Float2Float2(float2 inV, unsigned int x) {
+    float2 outFloor = 0;
+    float2 out = fract(inV, &outFloor);
+    rsSetElementAt_float2(gAllocOutFloor, outFloor, x);
+    return out;
+}
+
+float3 __attribute__((kernel)) testFractFloat3Float3Float3(float3 inV, unsigned int x) {
+    float3 outFloor = 0;
+    float3 out = fract(inV, &outFloor);
+    rsSetElementAt_float3(gAllocOutFloor, outFloor, x);
+    return out;
+}
+
+float4 __attribute__((kernel)) testFractFloat4Float4Float4(float4 inV, unsigned int x) {
+    float4 outFloor = 0;
+    float4 out = fract(inV, &outFloor);
+    rsSetElementAt_float4(gAllocOutFloor, outFloor, x);
+    return out;
+}
+
+float __attribute__((kernel)) testFractFloatFloat(float inV) {
+    return fract(inV);
+}
+
+float2 __attribute__((kernel)) testFractFloat2Float2(float2 inV) {
+    return fract(inV);
+}
+
+float3 __attribute__((kernel)) testFractFloat3Float3(float3 inV) {
+    return fract(inV);
+}
+
+float4 __attribute__((kernel)) testFractFloat4Float4(float4 inV) {
+    return fract(inV);
+}
diff --git a/tests/src/android/renderscript/cts/TestFractRelaxed.rs b/tests/src/android/renderscript/cts/TestFractRelaxed.rs
new file mode 100644
index 0000000..c9a98df
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestFractRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestFract.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestFrexp.rs b/tests/src/android/renderscript/cts/TestFrexp.rs
new file mode 100644
index 0000000..70c6c13
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestFrexp.rs
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+rs_allocation gAllocOutIptr;
+
+float __attribute__((kernel)) testFrexpFloatIntFloat(float inV, unsigned int x) {
+    int outIptr = 0;
+    float out = frexp(inV, &outIptr);
+    rsSetElementAt_int(gAllocOutIptr, outIptr, x);
+    return out;
+}
+
+float2 __attribute__((kernel)) testFrexpFloat2Int2Float2(float2 inV, unsigned int x) {
+    int2 outIptr = 0;
+    float2 out = frexp(inV, &outIptr);
+    rsSetElementAt_int2(gAllocOutIptr, outIptr, x);
+    return out;
+}
+
+float3 __attribute__((kernel)) testFrexpFloat3Int3Float3(float3 inV, unsigned int x) {
+    int3 outIptr = 0;
+    float3 out = frexp(inV, &outIptr);
+    rsSetElementAt_int3(gAllocOutIptr, outIptr, x);
+    return out;
+}
+
+float4 __attribute__((kernel)) testFrexpFloat4Int4Float4(float4 inV, unsigned int x) {
+    int4 outIptr = 0;
+    float4 out = frexp(inV, &outIptr);
+    rsSetElementAt_int4(gAllocOutIptr, outIptr, x);
+    return out;
+}
diff --git a/tests/src/android/renderscript/cts/TestFrexpRelaxed.rs b/tests/src/android/renderscript/cts/TestFrexpRelaxed.rs
new file mode 100644
index 0000000..8dc4c4d
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestFrexpRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestFrexp.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestHalfRecip.rs b/tests/src/android/renderscript/cts/TestHalfRecip.rs
new file mode 100644
index 0000000..03c5802
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestHalfRecip.rs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+
+float __attribute__((kernel)) testHalfRecipFloatFloat(float inV) {
+    return half_recip(inV);
+}
+
+float2 __attribute__((kernel)) testHalfRecipFloat2Float2(float2 inV) {
+    return half_recip(inV);
+}
+
+float3 __attribute__((kernel)) testHalfRecipFloat3Float3(float3 inV) {
+    return half_recip(inV);
+}
+
+float4 __attribute__((kernel)) testHalfRecipFloat4Float4(float4 inV) {
+    return half_recip(inV);
+}
diff --git a/tests/src/android/renderscript/cts/TestHalfRecipRelaxed.rs b/tests/src/android/renderscript/cts/TestHalfRecipRelaxed.rs
new file mode 100644
index 0000000..da453fa
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestHalfRecipRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestHalfRecip.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestHalfRsqrt.rs b/tests/src/android/renderscript/cts/TestHalfRsqrt.rs
new file mode 100644
index 0000000..27840d1
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestHalfRsqrt.rs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+
+float __attribute__((kernel)) testHalfRsqrtFloatFloat(float inV) {
+    return half_rsqrt(inV);
+}
+
+float2 __attribute__((kernel)) testHalfRsqrtFloat2Float2(float2 inV) {
+    return half_rsqrt(inV);
+}
+
+float3 __attribute__((kernel)) testHalfRsqrtFloat3Float3(float3 inV) {
+    return half_rsqrt(inV);
+}
+
+float4 __attribute__((kernel)) testHalfRsqrtFloat4Float4(float4 inV) {
+    return half_rsqrt(inV);
+}
diff --git a/tests/src/android/renderscript/cts/TestHalfRsqrtRelaxed.rs b/tests/src/android/renderscript/cts/TestHalfRsqrtRelaxed.rs
new file mode 100644
index 0000000..4f94200
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestHalfRsqrtRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestHalfRsqrt.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestHalfSqrt.rs b/tests/src/android/renderscript/cts/TestHalfSqrt.rs
new file mode 100644
index 0000000..d785e44
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestHalfSqrt.rs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+
+float __attribute__((kernel)) testHalfSqrtFloatFloat(float inV) {
+    return half_sqrt(inV);
+}
+
+float2 __attribute__((kernel)) testHalfSqrtFloat2Float2(float2 inV) {
+    return half_sqrt(inV);
+}
+
+float3 __attribute__((kernel)) testHalfSqrtFloat3Float3(float3 inV) {
+    return half_sqrt(inV);
+}
+
+float4 __attribute__((kernel)) testHalfSqrtFloat4Float4(float4 inV) {
+    return half_sqrt(inV);
+}
diff --git a/tests/src/android/renderscript/cts/TestHalfSqrtRelaxed.rs b/tests/src/android/renderscript/cts/TestHalfSqrtRelaxed.rs
new file mode 100644
index 0000000..46b979d
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestHalfSqrtRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestHalfSqrt.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestHypot.rs b/tests/src/android/renderscript/cts/TestHypot.rs
new file mode 100644
index 0000000..9425121
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestHypot.rs
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+rs_allocation gAllocInY;
+
+float __attribute__((kernel)) testHypotFloatFloatFloat(float inX, unsigned int x) {
+    float inY = rsGetElementAt_float(gAllocInY, x);
+    return hypot(inX, inY);
+}
+
+float2 __attribute__((kernel)) testHypotFloat2Float2Float2(float2 inX, unsigned int x) {
+    float2 inY = rsGetElementAt_float2(gAllocInY, x);
+    return hypot(inX, inY);
+}
+
+float3 __attribute__((kernel)) testHypotFloat3Float3Float3(float3 inX, unsigned int x) {
+    float3 inY = rsGetElementAt_float3(gAllocInY, x);
+    return hypot(inX, inY);
+}
+
+float4 __attribute__((kernel)) testHypotFloat4Float4Float4(float4 inX, unsigned int x) {
+    float4 inY = rsGetElementAt_float4(gAllocInY, x);
+    return hypot(inX, inY);
+}
diff --git a/tests/src/android/renderscript/cts/TestHypotRelaxed.rs b/tests/src/android/renderscript/cts/TestHypotRelaxed.rs
new file mode 100644
index 0000000..15d02f3
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestHypotRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestHypot.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestIlogb.rs b/tests/src/android/renderscript/cts/TestIlogb.rs
new file mode 100644
index 0000000..d9d62ed
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestIlogb.rs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+
+int __attribute__((kernel)) testIlogbFloatInt(float in) {
+    return ilogb(in);
+}
+
+int2 __attribute__((kernel)) testIlogbFloat2Int2(float2 in) {
+    return ilogb(in);
+}
+
+int3 __attribute__((kernel)) testIlogbFloat3Int3(float3 in) {
+    return ilogb(in);
+}
+
+int4 __attribute__((kernel)) testIlogbFloat4Int4(float4 in) {
+    return ilogb(in);
+}
diff --git a/tests/src/android/renderscript/cts/TestIlogbRelaxed.rs b/tests/src/android/renderscript/cts/TestIlogbRelaxed.rs
new file mode 100644
index 0000000..6a60e53
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestIlogbRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestIlogb.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestLdexp.rs b/tests/src/android/renderscript/cts/TestLdexp.rs
new file mode 100644
index 0000000..e8b05f2
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestLdexp.rs
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+rs_allocation gAllocInY;
+
+float __attribute__((kernel)) testLdexpFloatIntFloat(float inX, unsigned int x) {
+    int inY = rsGetElementAt_int(gAllocInY, x);
+    return ldexp(inX, inY);
+}
+
+float2 __attribute__((kernel)) testLdexpFloat2Int2Float2(float2 inX, unsigned int x) {
+    int2 inY = rsGetElementAt_int2(gAllocInY, x);
+    return ldexp(inX, inY);
+}
+
+float3 __attribute__((kernel)) testLdexpFloat3Int3Float3(float3 inX, unsigned int x) {
+    int3 inY = rsGetElementAt_int3(gAllocInY, x);
+    return ldexp(inX, inY);
+}
+
+float4 __attribute__((kernel)) testLdexpFloat4Int4Float4(float4 inX, unsigned int x) {
+    int4 inY = rsGetElementAt_int4(gAllocInY, x);
+    return ldexp(inX, inY);
+}
+
+float2 __attribute__((kernel)) testLdexpFloat2IntFloat2(float2 inX, unsigned int x) {
+    int inY = rsGetElementAt_int(gAllocInY, x);
+    return ldexp(inX, inY);
+}
+
+float3 __attribute__((kernel)) testLdexpFloat3IntFloat3(float3 inX, unsigned int x) {
+    int inY = rsGetElementAt_int(gAllocInY, x);
+    return ldexp(inX, inY);
+}
+
+float4 __attribute__((kernel)) testLdexpFloat4IntFloat4(float4 inX, unsigned int x) {
+    int inY = rsGetElementAt_int(gAllocInY, x);
+    return ldexp(inX, inY);
+}
diff --git a/tests/src/android/renderscript/cts/TestLdexpRelaxed.rs b/tests/src/android/renderscript/cts/TestLdexpRelaxed.rs
new file mode 100644
index 0000000..ee9f5cf
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestLdexpRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestLdexp.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestLength.rs b/tests/src/android/renderscript/cts/TestLength.rs
new file mode 100644
index 0000000..3239dbd
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestLength.rs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+
+float __attribute__((kernel)) testLengthFloatFloat(float inV) {
+    return length(inV);
+}
+
+float __attribute__((kernel)) testLengthFloat2Float(float2 inV) {
+    return length(inV);
+}
+
+float __attribute__((kernel)) testLengthFloat3Float(float3 inV) {
+    return length(inV);
+}
+
+float __attribute__((kernel)) testLengthFloat4Float(float4 inV) {
+    return length(inV);
+}
diff --git a/tests/src/android/renderscript/cts/TestLengthRelaxed.rs b/tests/src/android/renderscript/cts/TestLengthRelaxed.rs
new file mode 100644
index 0000000..12eba8b
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestLengthRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestLength.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestLgamma.rs b/tests/src/android/renderscript/cts/TestLgamma.rs
new file mode 100644
index 0000000..b39e592
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestLgamma.rs
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+
+float __attribute__((kernel)) testLgammaFloatFloat(float in) {
+    return lgamma(in);
+}
+
+float2 __attribute__((kernel)) testLgammaFloat2Float2(float2 in) {
+    return lgamma(in);
+}
+
+float3 __attribute__((kernel)) testLgammaFloat3Float3(float3 in) {
+    return lgamma(in);
+}
+
+float4 __attribute__((kernel)) testLgammaFloat4Float4(float4 in) {
+    return lgamma(in);
+}
+rs_allocation gAllocOutY;
+
+float __attribute__((kernel)) testLgammaFloatIntFloat(float inX, unsigned int x) {
+    int outY = 0;
+    float out = lgamma(inX, &outY);
+    rsSetElementAt_int(gAllocOutY, outY, x);
+    return out;
+}
+
+float2 __attribute__((kernel)) testLgammaFloat2Int2Float2(float2 inX, unsigned int x) {
+    int2 outY = 0;
+    float2 out = lgamma(inX, &outY);
+    rsSetElementAt_int2(gAllocOutY, outY, x);
+    return out;
+}
+
+float3 __attribute__((kernel)) testLgammaFloat3Int3Float3(float3 inX, unsigned int x) {
+    int3 outY = 0;
+    float3 out = lgamma(inX, &outY);
+    rsSetElementAt_int3(gAllocOutY, outY, x);
+    return out;
+}
+
+float4 __attribute__((kernel)) testLgammaFloat4Int4Float4(float4 inX, unsigned int x) {
+    int4 outY = 0;
+    float4 out = lgamma(inX, &outY);
+    rsSetElementAt_int4(gAllocOutY, outY, x);
+    return out;
+}
diff --git a/tests/src/android/renderscript/cts/TestLgammaRelaxed.rs b/tests/src/android/renderscript/cts/TestLgammaRelaxed.rs
new file mode 100644
index 0000000..a259576
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestLgammaRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestLgamma.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestLog.rs b/tests/src/android/renderscript/cts/TestLog.rs
new file mode 100644
index 0000000..4261b61
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestLog.rs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+
+float __attribute__((kernel)) testLogFloatFloat(float in) {
+    return log(in);
+}
+
+float2 __attribute__((kernel)) testLogFloat2Float2(float2 in) {
+    return log(in);
+}
+
+float3 __attribute__((kernel)) testLogFloat3Float3(float3 in) {
+    return log(in);
+}
+
+float4 __attribute__((kernel)) testLogFloat4Float4(float4 in) {
+    return log(in);
+}
diff --git a/tests/src/android/renderscript/cts/TestLog10.rs b/tests/src/android/renderscript/cts/TestLog10.rs
new file mode 100644
index 0000000..18fb3c3
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestLog10.rs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+
+float __attribute__((kernel)) testLog10FloatFloat(float in) {
+    return log10(in);
+}
+
+float2 __attribute__((kernel)) testLog10Float2Float2(float2 in) {
+    return log10(in);
+}
+
+float3 __attribute__((kernel)) testLog10Float3Float3(float3 in) {
+    return log10(in);
+}
+
+float4 __attribute__((kernel)) testLog10Float4Float4(float4 in) {
+    return log10(in);
+}
diff --git a/tests/src/android/renderscript/cts/TestLog10Relaxed.rs b/tests/src/android/renderscript/cts/TestLog10Relaxed.rs
new file mode 100644
index 0000000..c0c47f3
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestLog10Relaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestLog10.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestLog1p.rs b/tests/src/android/renderscript/cts/TestLog1p.rs
new file mode 100644
index 0000000..bc5577e
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestLog1p.rs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+
+float __attribute__((kernel)) testLog1pFloatFloat(float in) {
+    return log1p(in);
+}
+
+float2 __attribute__((kernel)) testLog1pFloat2Float2(float2 in) {
+    return log1p(in);
+}
+
+float3 __attribute__((kernel)) testLog1pFloat3Float3(float3 in) {
+    return log1p(in);
+}
+
+float4 __attribute__((kernel)) testLog1pFloat4Float4(float4 in) {
+    return log1p(in);
+}
diff --git a/tests/src/android/renderscript/cts/TestLog1pRelaxed.rs b/tests/src/android/renderscript/cts/TestLog1pRelaxed.rs
new file mode 100644
index 0000000..3136d9e
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestLog1pRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestLog1p.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestLog2.rs b/tests/src/android/renderscript/cts/TestLog2.rs
new file mode 100644
index 0000000..4cf8ef2
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestLog2.rs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+
+float __attribute__((kernel)) testLog2FloatFloat(float in) {
+    return log2(in);
+}
+
+float2 __attribute__((kernel)) testLog2Float2Float2(float2 in) {
+    return log2(in);
+}
+
+float3 __attribute__((kernel)) testLog2Float3Float3(float3 in) {
+    return log2(in);
+}
+
+float4 __attribute__((kernel)) testLog2Float4Float4(float4 in) {
+    return log2(in);
+}
diff --git a/tests/src/android/renderscript/cts/TestLog2Relaxed.rs b/tests/src/android/renderscript/cts/TestLog2Relaxed.rs
new file mode 100644
index 0000000..e79f105
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestLog2Relaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestLog2.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestLogRelaxed.rs b/tests/src/android/renderscript/cts/TestLogRelaxed.rs
new file mode 100644
index 0000000..3fed787
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestLogRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestLog.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestLogb.rs b/tests/src/android/renderscript/cts/TestLogb.rs
new file mode 100644
index 0000000..8317a22
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestLogb.rs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+
+float __attribute__((kernel)) testLogbFloatFloat(float in) {
+    return logb(in);
+}
+
+float2 __attribute__((kernel)) testLogbFloat2Float2(float2 in) {
+    return logb(in);
+}
+
+float3 __attribute__((kernel)) testLogbFloat3Float3(float3 in) {
+    return logb(in);
+}
+
+float4 __attribute__((kernel)) testLogbFloat4Float4(float4 in) {
+    return logb(in);
+}
diff --git a/tests/src/android/renderscript/cts/TestLogbRelaxed.rs b/tests/src/android/renderscript/cts/TestLogbRelaxed.rs
new file mode 100644
index 0000000..bcf84b7
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestLogbRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestLogb.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestMad.rs b/tests/src/android/renderscript/cts/TestMad.rs
new file mode 100644
index 0000000..bcf908b
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestMad.rs
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+rs_allocation gAllocInB;
+rs_allocation gAllocInC;
+
+float __attribute__((kernel)) testMadFloatFloatFloatFloat(float inA, unsigned int x) {
+    float inB = rsGetElementAt_float(gAllocInB, x);
+    float inC = rsGetElementAt_float(gAllocInC, x);
+    return mad(inA, inB, inC);
+}
+
+float2 __attribute__((kernel)) testMadFloat2Float2Float2Float2(float2 inA, unsigned int x) {
+    float2 inB = rsGetElementAt_float2(gAllocInB, x);
+    float2 inC = rsGetElementAt_float2(gAllocInC, x);
+    return mad(inA, inB, inC);
+}
+
+float3 __attribute__((kernel)) testMadFloat3Float3Float3Float3(float3 inA, unsigned int x) {
+    float3 inB = rsGetElementAt_float3(gAllocInB, x);
+    float3 inC = rsGetElementAt_float3(gAllocInC, x);
+    return mad(inA, inB, inC);
+}
+
+float4 __attribute__((kernel)) testMadFloat4Float4Float4Float4(float4 inA, unsigned int x) {
+    float4 inB = rsGetElementAt_float4(gAllocInB, x);
+    float4 inC = rsGetElementAt_float4(gAllocInC, x);
+    return mad(inA, inB, inC);
+}
diff --git a/tests/src/android/renderscript/cts/TestMadRelaxed.rs b/tests/src/android/renderscript/cts/TestMadRelaxed.rs
new file mode 100644
index 0000000..acec458
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestMadRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestMad.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestMax.rs b/tests/src/android/renderscript/cts/TestMax.rs
new file mode 100644
index 0000000..87d8040
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestMax.rs
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+rs_allocation gAllocIn1;
+
+float __attribute__((kernel)) testMaxFloatFloatFloat(float in, unsigned int x) {
+    float in1 = rsGetElementAt_float(gAllocIn1, x);
+    return max(in, in1);
+}
+
+float2 __attribute__((kernel)) testMaxFloat2Float2Float2(float2 in, unsigned int x) {
+    float2 in1 = rsGetElementAt_float2(gAllocIn1, x);
+    return max(in, in1);
+}
+
+float3 __attribute__((kernel)) testMaxFloat3Float3Float3(float3 in, unsigned int x) {
+    float3 in1 = rsGetElementAt_float3(gAllocIn1, x);
+    return max(in, in1);
+}
+
+float4 __attribute__((kernel)) testMaxFloat4Float4Float4(float4 in, unsigned int x) {
+    float4 in1 = rsGetElementAt_float4(gAllocIn1, x);
+    return max(in, in1);
+}
+rs_allocation gAllocInV2;
+
+char __attribute__((kernel)) testMaxCharCharChar(char inV1, unsigned int x) {
+    char inV2 = rsGetElementAt_char(gAllocInV2, x);
+    return max(inV1, inV2);
+}
+
+uchar __attribute__((kernel)) testMaxUcharUcharUchar(uchar inV1, unsigned int x) {
+    uchar inV2 = rsGetElementAt_uchar(gAllocInV2, x);
+    return max(inV1, inV2);
+}
+
+short __attribute__((kernel)) testMaxShortShortShort(short inV1, unsigned int x) {
+    short inV2 = rsGetElementAt_short(gAllocInV2, x);
+    return max(inV1, inV2);
+}
+
+ushort __attribute__((kernel)) testMaxUshortUshortUshort(ushort inV1, unsigned int x) {
+    ushort inV2 = rsGetElementAt_ushort(gAllocInV2, x);
+    return max(inV1, inV2);
+}
+
+int __attribute__((kernel)) testMaxIntIntInt(int inV1, unsigned int x) {
+    int inV2 = rsGetElementAt_int(gAllocInV2, x);
+    return max(inV1, inV2);
+}
+
+uint __attribute__((kernel)) testMaxUintUintUint(uint inV1, unsigned int x) {
+    uint inV2 = rsGetElementAt_uint(gAllocInV2, x);
+    return max(inV1, inV2);
+}
+
+char2 __attribute__((kernel)) testMaxChar2Char2Char2(char2 inV1, unsigned int x) {
+    char2 inV2 = rsGetElementAt_char2(gAllocInV2, x);
+    return max(inV1, inV2);
+}
+
+uchar2 __attribute__((kernel)) testMaxUchar2Uchar2Uchar2(uchar2 inV1, unsigned int x) {
+    uchar2 inV2 = rsGetElementAt_uchar2(gAllocInV2, x);
+    return max(inV1, inV2);
+}
+
+short2 __attribute__((kernel)) testMaxShort2Short2Short2(short2 inV1, unsigned int x) {
+    short2 inV2 = rsGetElementAt_short2(gAllocInV2, x);
+    return max(inV1, inV2);
+}
+
+ushort2 __attribute__((kernel)) testMaxUshort2Ushort2Ushort2(ushort2 inV1, unsigned int x) {
+    ushort2 inV2 = rsGetElementAt_ushort2(gAllocInV2, x);
+    return max(inV1, inV2);
+}
+
+int2 __attribute__((kernel)) testMaxInt2Int2Int2(int2 inV1, unsigned int x) {
+    int2 inV2 = rsGetElementAt_int2(gAllocInV2, x);
+    return max(inV1, inV2);
+}
+
+uint2 __attribute__((kernel)) testMaxUint2Uint2Uint2(uint2 inV1, unsigned int x) {
+    uint2 inV2 = rsGetElementAt_uint2(gAllocInV2, x);
+    return max(inV1, inV2);
+}
+
+char3 __attribute__((kernel)) testMaxChar3Char3Char3(char3 inV1, unsigned int x) {
+    char3 inV2 = rsGetElementAt_char3(gAllocInV2, x);
+    return max(inV1, inV2);
+}
+
+uchar3 __attribute__((kernel)) testMaxUchar3Uchar3Uchar3(uchar3 inV1, unsigned int x) {
+    uchar3 inV2 = rsGetElementAt_uchar3(gAllocInV2, x);
+    return max(inV1, inV2);
+}
+
+short3 __attribute__((kernel)) testMaxShort3Short3Short3(short3 inV1, unsigned int x) {
+    short3 inV2 = rsGetElementAt_short3(gAllocInV2, x);
+    return max(inV1, inV2);
+}
+
+ushort3 __attribute__((kernel)) testMaxUshort3Ushort3Ushort3(ushort3 inV1, unsigned int x) {
+    ushort3 inV2 = rsGetElementAt_ushort3(gAllocInV2, x);
+    return max(inV1, inV2);
+}
+
+int3 __attribute__((kernel)) testMaxInt3Int3Int3(int3 inV1, unsigned int x) {
+    int3 inV2 = rsGetElementAt_int3(gAllocInV2, x);
+    return max(inV1, inV2);
+}
+
+uint3 __attribute__((kernel)) testMaxUint3Uint3Uint3(uint3 inV1, unsigned int x) {
+    uint3 inV2 = rsGetElementAt_uint3(gAllocInV2, x);
+    return max(inV1, inV2);
+}
+
+char4 __attribute__((kernel)) testMaxChar4Char4Char4(char4 inV1, unsigned int x) {
+    char4 inV2 = rsGetElementAt_char4(gAllocInV2, x);
+    return max(inV1, inV2);
+}
+
+uchar4 __attribute__((kernel)) testMaxUchar4Uchar4Uchar4(uchar4 inV1, unsigned int x) {
+    uchar4 inV2 = rsGetElementAt_uchar4(gAllocInV2, x);
+    return max(inV1, inV2);
+}
+
+short4 __attribute__((kernel)) testMaxShort4Short4Short4(short4 inV1, unsigned int x) {
+    short4 inV2 = rsGetElementAt_short4(gAllocInV2, x);
+    return max(inV1, inV2);
+}
+
+ushort4 __attribute__((kernel)) testMaxUshort4Ushort4Ushort4(ushort4 inV1, unsigned int x) {
+    ushort4 inV2 = rsGetElementAt_ushort4(gAllocInV2, x);
+    return max(inV1, inV2);
+}
+
+int4 __attribute__((kernel)) testMaxInt4Int4Int4(int4 inV1, unsigned int x) {
+    int4 inV2 = rsGetElementAt_int4(gAllocInV2, x);
+    return max(inV1, inV2);
+}
+
+uint4 __attribute__((kernel)) testMaxUint4Uint4Uint4(uint4 inV1, unsigned int x) {
+    uint4 inV2 = rsGetElementAt_uint4(gAllocInV2, x);
+    return max(inV1, inV2);
+}
diff --git a/tests/src/android/renderscript/cts/TestMaxRelaxed.rs b/tests/src/android/renderscript/cts/TestMaxRelaxed.rs
new file mode 100644
index 0000000..fb0319b
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestMaxRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestMax.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestMin.rs b/tests/src/android/renderscript/cts/TestMin.rs
new file mode 100644
index 0000000..26301ff
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestMin.rs
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+rs_allocation gAllocIn1;
+
+float __attribute__((kernel)) testMinFloatFloatFloat(float in, unsigned int x) {
+    float in1 = rsGetElementAt_float(gAllocIn1, x);
+    return min(in, in1);
+}
+
+float2 __attribute__((kernel)) testMinFloat2Float2Float2(float2 in, unsigned int x) {
+    float2 in1 = rsGetElementAt_float2(gAllocIn1, x);
+    return min(in, in1);
+}
+
+float3 __attribute__((kernel)) testMinFloat3Float3Float3(float3 in, unsigned int x) {
+    float3 in1 = rsGetElementAt_float3(gAllocIn1, x);
+    return min(in, in1);
+}
+
+float4 __attribute__((kernel)) testMinFloat4Float4Float4(float4 in, unsigned int x) {
+    float4 in1 = rsGetElementAt_float4(gAllocIn1, x);
+    return min(in, in1);
+}
+rs_allocation gAllocInV2;
+
+char __attribute__((kernel)) testMinCharCharChar(char inV1, unsigned int x) {
+    char inV2 = rsGetElementAt_char(gAllocInV2, x);
+    return min(inV1, inV2);
+}
+
+uchar __attribute__((kernel)) testMinUcharUcharUchar(uchar inV1, unsigned int x) {
+    uchar inV2 = rsGetElementAt_uchar(gAllocInV2, x);
+    return min(inV1, inV2);
+}
+
+short __attribute__((kernel)) testMinShortShortShort(short inV1, unsigned int x) {
+    short inV2 = rsGetElementAt_short(gAllocInV2, x);
+    return min(inV1, inV2);
+}
+
+ushort __attribute__((kernel)) testMinUshortUshortUshort(ushort inV1, unsigned int x) {
+    ushort inV2 = rsGetElementAt_ushort(gAllocInV2, x);
+    return min(inV1, inV2);
+}
+
+int __attribute__((kernel)) testMinIntIntInt(int inV1, unsigned int x) {
+    int inV2 = rsGetElementAt_int(gAllocInV2, x);
+    return min(inV1, inV2);
+}
+
+uint __attribute__((kernel)) testMinUintUintUint(uint inV1, unsigned int x) {
+    uint inV2 = rsGetElementAt_uint(gAllocInV2, x);
+    return min(inV1, inV2);
+}
+
+char2 __attribute__((kernel)) testMinChar2Char2Char2(char2 inV1, unsigned int x) {
+    char2 inV2 = rsGetElementAt_char2(gAllocInV2, x);
+    return min(inV1, inV2);
+}
+
+uchar2 __attribute__((kernel)) testMinUchar2Uchar2Uchar2(uchar2 inV1, unsigned int x) {
+    uchar2 inV2 = rsGetElementAt_uchar2(gAllocInV2, x);
+    return min(inV1, inV2);
+}
+
+short2 __attribute__((kernel)) testMinShort2Short2Short2(short2 inV1, unsigned int x) {
+    short2 inV2 = rsGetElementAt_short2(gAllocInV2, x);
+    return min(inV1, inV2);
+}
+
+ushort2 __attribute__((kernel)) testMinUshort2Ushort2Ushort2(ushort2 inV1, unsigned int x) {
+    ushort2 inV2 = rsGetElementAt_ushort2(gAllocInV2, x);
+    return min(inV1, inV2);
+}
+
+int2 __attribute__((kernel)) testMinInt2Int2Int2(int2 inV1, unsigned int x) {
+    int2 inV2 = rsGetElementAt_int2(gAllocInV2, x);
+    return min(inV1, inV2);
+}
+
+uint2 __attribute__((kernel)) testMinUint2Uint2Uint2(uint2 inV1, unsigned int x) {
+    uint2 inV2 = rsGetElementAt_uint2(gAllocInV2, x);
+    return min(inV1, inV2);
+}
+
+char3 __attribute__((kernel)) testMinChar3Char3Char3(char3 inV1, unsigned int x) {
+    char3 inV2 = rsGetElementAt_char3(gAllocInV2, x);
+    return min(inV1, inV2);
+}
+
+uchar3 __attribute__((kernel)) testMinUchar3Uchar3Uchar3(uchar3 inV1, unsigned int x) {
+    uchar3 inV2 = rsGetElementAt_uchar3(gAllocInV2, x);
+    return min(inV1, inV2);
+}
+
+short3 __attribute__((kernel)) testMinShort3Short3Short3(short3 inV1, unsigned int x) {
+    short3 inV2 = rsGetElementAt_short3(gAllocInV2, x);
+    return min(inV1, inV2);
+}
+
+ushort3 __attribute__((kernel)) testMinUshort3Ushort3Ushort3(ushort3 inV1, unsigned int x) {
+    ushort3 inV2 = rsGetElementAt_ushort3(gAllocInV2, x);
+    return min(inV1, inV2);
+}
+
+int3 __attribute__((kernel)) testMinInt3Int3Int3(int3 inV1, unsigned int x) {
+    int3 inV2 = rsGetElementAt_int3(gAllocInV2, x);
+    return min(inV1, inV2);
+}
+
+uint3 __attribute__((kernel)) testMinUint3Uint3Uint3(uint3 inV1, unsigned int x) {
+    uint3 inV2 = rsGetElementAt_uint3(gAllocInV2, x);
+    return min(inV1, inV2);
+}
+
+char4 __attribute__((kernel)) testMinChar4Char4Char4(char4 inV1, unsigned int x) {
+    char4 inV2 = rsGetElementAt_char4(gAllocInV2, x);
+    return min(inV1, inV2);
+}
+
+uchar4 __attribute__((kernel)) testMinUchar4Uchar4Uchar4(uchar4 inV1, unsigned int x) {
+    uchar4 inV2 = rsGetElementAt_uchar4(gAllocInV2, x);
+    return min(inV1, inV2);
+}
+
+short4 __attribute__((kernel)) testMinShort4Short4Short4(short4 inV1, unsigned int x) {
+    short4 inV2 = rsGetElementAt_short4(gAllocInV2, x);
+    return min(inV1, inV2);
+}
+
+ushort4 __attribute__((kernel)) testMinUshort4Ushort4Ushort4(ushort4 inV1, unsigned int x) {
+    ushort4 inV2 = rsGetElementAt_ushort4(gAllocInV2, x);
+    return min(inV1, inV2);
+}
+
+int4 __attribute__((kernel)) testMinInt4Int4Int4(int4 inV1, unsigned int x) {
+    int4 inV2 = rsGetElementAt_int4(gAllocInV2, x);
+    return min(inV1, inV2);
+}
+
+uint4 __attribute__((kernel)) testMinUint4Uint4Uint4(uint4 inV1, unsigned int x) {
+    uint4 inV2 = rsGetElementAt_uint4(gAllocInV2, x);
+    return min(inV1, inV2);
+}
diff --git a/tests/src/android/renderscript/cts/TestMinRelaxed.rs b/tests/src/android/renderscript/cts/TestMinRelaxed.rs
new file mode 100644
index 0000000..29a4d89
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestMinRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestMin.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestMix.rs b/tests/src/android/renderscript/cts/TestMix.rs
new file mode 100644
index 0000000..c2ebcb3
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestMix.rs
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+rs_allocation gAllocInStop;
+rs_allocation gAllocInAmount;
+
+float __attribute__((kernel)) testMixFloatFloatFloatFloat(float inStart, unsigned int x) {
+    float inStop = rsGetElementAt_float(gAllocInStop, x);
+    float inAmount = rsGetElementAt_float(gAllocInAmount, x);
+    return mix(inStart, inStop, inAmount);
+}
+
+float2 __attribute__((kernel)) testMixFloat2Float2Float2Float2(float2 inStart, unsigned int x) {
+    float2 inStop = rsGetElementAt_float2(gAllocInStop, x);
+    float2 inAmount = rsGetElementAt_float2(gAllocInAmount, x);
+    return mix(inStart, inStop, inAmount);
+}
+
+float3 __attribute__((kernel)) testMixFloat3Float3Float3Float3(float3 inStart, unsigned int x) {
+    float3 inStop = rsGetElementAt_float3(gAllocInStop, x);
+    float3 inAmount = rsGetElementAt_float3(gAllocInAmount, x);
+    return mix(inStart, inStop, inAmount);
+}
+
+float4 __attribute__((kernel)) testMixFloat4Float4Float4Float4(float4 inStart, unsigned int x) {
+    float4 inStop = rsGetElementAt_float4(gAllocInStop, x);
+    float4 inAmount = rsGetElementAt_float4(gAllocInAmount, x);
+    return mix(inStart, inStop, inAmount);
+}
+
+float2 __attribute__((kernel)) testMixFloat2Float2FloatFloat2(float2 inStart, unsigned int x) {
+    float2 inStop = rsGetElementAt_float2(gAllocInStop, x);
+    float inAmount = rsGetElementAt_float(gAllocInAmount, x);
+    return mix(inStart, inStop, inAmount);
+}
+
+float3 __attribute__((kernel)) testMixFloat3Float3FloatFloat3(float3 inStart, unsigned int x) {
+    float3 inStop = rsGetElementAt_float3(gAllocInStop, x);
+    float inAmount = rsGetElementAt_float(gAllocInAmount, x);
+    return mix(inStart, inStop, inAmount);
+}
+
+float4 __attribute__((kernel)) testMixFloat4Float4FloatFloat4(float4 inStart, unsigned int x) {
+    float4 inStop = rsGetElementAt_float4(gAllocInStop, x);
+    float inAmount = rsGetElementAt_float(gAllocInAmount, x);
+    return mix(inStart, inStop, inAmount);
+}
diff --git a/tests/src/android/renderscript/cts/TestMixRelaxed.rs b/tests/src/android/renderscript/cts/TestMixRelaxed.rs
new file mode 100644
index 0000000..6b59e70
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestMixRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestMix.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestModf.rs b/tests/src/android/renderscript/cts/TestModf.rs
new file mode 100644
index 0000000..be10983
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestModf.rs
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+rs_allocation gAllocOutIret;
+
+float __attribute__((kernel)) testModfFloatFloatFloat(float inX, unsigned int x) {
+    float outIret = 0;
+    float out = modf(inX, &outIret);
+    rsSetElementAt_float(gAllocOutIret, outIret, x);
+    return out;
+}
+
+float2 __attribute__((kernel)) testModfFloat2Float2Float2(float2 inX, unsigned int x) {
+    float2 outIret = 0;
+    float2 out = modf(inX, &outIret);
+    rsSetElementAt_float2(gAllocOutIret, outIret, x);
+    return out;
+}
+
+float3 __attribute__((kernel)) testModfFloat3Float3Float3(float3 inX, unsigned int x) {
+    float3 outIret = 0;
+    float3 out = modf(inX, &outIret);
+    rsSetElementAt_float3(gAllocOutIret, outIret, x);
+    return out;
+}
+
+float4 __attribute__((kernel)) testModfFloat4Float4Float4(float4 inX, unsigned int x) {
+    float4 outIret = 0;
+    float4 out = modf(inX, &outIret);
+    rsSetElementAt_float4(gAllocOutIret, outIret, x);
+    return out;
+}
diff --git a/tests/src/android/renderscript/cts/TestModfRelaxed.rs b/tests/src/android/renderscript/cts/TestModfRelaxed.rs
new file mode 100644
index 0000000..4c9cd9a
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestModfRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestModf.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestNan.rs b/tests/src/android/renderscript/cts/TestNan.rs
new file mode 100644
index 0000000..bb434d6
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestNan.rs
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+
+float __attribute__((kernel)) testNanUintFloat(uint in) {
+    return nan(in);
+}
diff --git a/tests/src/android/renderscript/cts/TestNanRelaxed.rs b/tests/src/android/renderscript/cts/TestNanRelaxed.rs
new file mode 100644
index 0000000..fc7b9eb
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestNanRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestNan.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestNativeExp.rs b/tests/src/android/renderscript/cts/TestNativeExp.rs
new file mode 100644
index 0000000..6143d9f
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestNativeExp.rs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+
+float __attribute__((kernel)) testNativeExpFloatFloat(float inV) {
+    return native_exp(inV);
+}
+
+float2 __attribute__((kernel)) testNativeExpFloat2Float2(float2 inV) {
+    return native_exp(inV);
+}
+
+float3 __attribute__((kernel)) testNativeExpFloat3Float3(float3 inV) {
+    return native_exp(inV);
+}
+
+float4 __attribute__((kernel)) testNativeExpFloat4Float4(float4 inV) {
+    return native_exp(inV);
+}
diff --git a/tests/src/android/renderscript/cts/TestNativeExp10.rs b/tests/src/android/renderscript/cts/TestNativeExp10.rs
new file mode 100644
index 0000000..1d03607
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestNativeExp10.rs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+
+float __attribute__((kernel)) testNativeExp10FloatFloat(float inV) {
+    return native_exp10(inV);
+}
+
+float2 __attribute__((kernel)) testNativeExp10Float2Float2(float2 inV) {
+    return native_exp10(inV);
+}
+
+float3 __attribute__((kernel)) testNativeExp10Float3Float3(float3 inV) {
+    return native_exp10(inV);
+}
+
+float4 __attribute__((kernel)) testNativeExp10Float4Float4(float4 inV) {
+    return native_exp10(inV);
+}
diff --git a/tests/src/android/renderscript/cts/TestNativeExp10Relaxed.rs b/tests/src/android/renderscript/cts/TestNativeExp10Relaxed.rs
new file mode 100644
index 0000000..4f12665
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestNativeExp10Relaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestNativeExp10.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestNativeExp2.rs b/tests/src/android/renderscript/cts/TestNativeExp2.rs
new file mode 100644
index 0000000..1112900
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestNativeExp2.rs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+
+float __attribute__((kernel)) testNativeExp2FloatFloat(float inV) {
+    return native_exp2(inV);
+}
+
+float2 __attribute__((kernel)) testNativeExp2Float2Float2(float2 inV) {
+    return native_exp2(inV);
+}
+
+float3 __attribute__((kernel)) testNativeExp2Float3Float3(float3 inV) {
+    return native_exp2(inV);
+}
+
+float4 __attribute__((kernel)) testNativeExp2Float4Float4(float4 inV) {
+    return native_exp2(inV);
+}
diff --git a/tests/src/android/renderscript/cts/TestNativeExp2Relaxed.rs b/tests/src/android/renderscript/cts/TestNativeExp2Relaxed.rs
new file mode 100644
index 0000000..8b99710
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestNativeExp2Relaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestNativeExp2.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestNativeExpRelaxed.rs b/tests/src/android/renderscript/cts/TestNativeExpRelaxed.rs
new file mode 100644
index 0000000..dd3a73c
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestNativeExpRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestNativeExp.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestNativeLog.rs b/tests/src/android/renderscript/cts/TestNativeLog.rs
new file mode 100644
index 0000000..05a4688
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestNativeLog.rs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+
+float __attribute__((kernel)) testNativeLogFloatFloat(float inV) {
+    return native_log(inV);
+}
+
+float2 __attribute__((kernel)) testNativeLogFloat2Float2(float2 inV) {
+    return native_log(inV);
+}
+
+float3 __attribute__((kernel)) testNativeLogFloat3Float3(float3 inV) {
+    return native_log(inV);
+}
+
+float4 __attribute__((kernel)) testNativeLogFloat4Float4(float4 inV) {
+    return native_log(inV);
+}
diff --git a/tests/src/android/renderscript/cts/TestNativeLog10.rs b/tests/src/android/renderscript/cts/TestNativeLog10.rs
new file mode 100644
index 0000000..3e86a13
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestNativeLog10.rs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+
+float __attribute__((kernel)) testNativeLog10FloatFloat(float inV) {
+    return native_log10(inV);
+}
+
+float2 __attribute__((kernel)) testNativeLog10Float2Float2(float2 inV) {
+    return native_log10(inV);
+}
+
+float3 __attribute__((kernel)) testNativeLog10Float3Float3(float3 inV) {
+    return native_log10(inV);
+}
+
+float4 __attribute__((kernel)) testNativeLog10Float4Float4(float4 inV) {
+    return native_log10(inV);
+}
diff --git a/tests/src/android/renderscript/cts/TestNativeLog10Relaxed.rs b/tests/src/android/renderscript/cts/TestNativeLog10Relaxed.rs
new file mode 100644
index 0000000..a00ed08
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestNativeLog10Relaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestNativeLog10.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestNativeLog2.rs b/tests/src/android/renderscript/cts/TestNativeLog2.rs
new file mode 100644
index 0000000..748a2a0
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestNativeLog2.rs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+
+float __attribute__((kernel)) testNativeLog2FloatFloat(float inV) {
+    return native_log2(inV);
+}
+
+float2 __attribute__((kernel)) testNativeLog2Float2Float2(float2 inV) {
+    return native_log2(inV);
+}
+
+float3 __attribute__((kernel)) testNativeLog2Float3Float3(float3 inV) {
+    return native_log2(inV);
+}
+
+float4 __attribute__((kernel)) testNativeLog2Float4Float4(float4 inV) {
+    return native_log2(inV);
+}
diff --git a/tests/src/android/renderscript/cts/TestNativeLog2Relaxed.rs b/tests/src/android/renderscript/cts/TestNativeLog2Relaxed.rs
new file mode 100644
index 0000000..71c2580
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestNativeLog2Relaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestNativeLog2.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestNativeLogRelaxed.rs b/tests/src/android/renderscript/cts/TestNativeLogRelaxed.rs
new file mode 100644
index 0000000..70d5e2f
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestNativeLogRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestNativeLog.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestNativePowr.rs b/tests/src/android/renderscript/cts/TestNativePowr.rs
new file mode 100644
index 0000000..06de2f9
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestNativePowr.rs
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+rs_allocation gAllocInY;
+
+float __attribute__((kernel)) testNativePowrFloatFloatFloat(float inV, unsigned int x) {
+    float inY = rsGetElementAt_float(gAllocInY, x);
+    return native_powr(inV, inY);
+}
+
+float2 __attribute__((kernel)) testNativePowrFloat2Float2Float2(float2 inV, unsigned int x) {
+    float2 inY = rsGetElementAt_float2(gAllocInY, x);
+    return native_powr(inV, inY);
+}
+
+float3 __attribute__((kernel)) testNativePowrFloat3Float3Float3(float3 inV, unsigned int x) {
+    float3 inY = rsGetElementAt_float3(gAllocInY, x);
+    return native_powr(inV, inY);
+}
+
+float4 __attribute__((kernel)) testNativePowrFloat4Float4Float4(float4 inV, unsigned int x) {
+    float4 inY = rsGetElementAt_float4(gAllocInY, x);
+    return native_powr(inV, inY);
+}
diff --git a/tests/src/android/renderscript/cts/TestNativePowrRelaxed.rs b/tests/src/android/renderscript/cts/TestNativePowrRelaxed.rs
new file mode 100644
index 0000000..069e40e
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestNativePowrRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestNativePowr.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestNextafter.rs b/tests/src/android/renderscript/cts/TestNextafter.rs
new file mode 100644
index 0000000..a7ae02d
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestNextafter.rs
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+rs_allocation gAllocInY;
+
+float __attribute__((kernel)) testNextafterFloatFloatFloat(float inX, unsigned int x) {
+    float inY = rsGetElementAt_float(gAllocInY, x);
+    return nextafter(inX, inY);
+}
+
+float2 __attribute__((kernel)) testNextafterFloat2Float2Float2(float2 inX, unsigned int x) {
+    float2 inY = rsGetElementAt_float2(gAllocInY, x);
+    return nextafter(inX, inY);
+}
+
+float3 __attribute__((kernel)) testNextafterFloat3Float3Float3(float3 inX, unsigned int x) {
+    float3 inY = rsGetElementAt_float3(gAllocInY, x);
+    return nextafter(inX, inY);
+}
+
+float4 __attribute__((kernel)) testNextafterFloat4Float4Float4(float4 inX, unsigned int x) {
+    float4 inY = rsGetElementAt_float4(gAllocInY, x);
+    return nextafter(inX, inY);
+}
diff --git a/tests/src/android/renderscript/cts/TestNextafterRelaxed.rs b/tests/src/android/renderscript/cts/TestNextafterRelaxed.rs
new file mode 100644
index 0000000..2111f17
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestNextafterRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestNextafter.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestNormalize.rs b/tests/src/android/renderscript/cts/TestNormalize.rs
new file mode 100644
index 0000000..fbb5281
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestNormalize.rs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+
+float __attribute__((kernel)) testNormalizeFloatFloat(float inV) {
+    return normalize(inV);
+}
+
+float2 __attribute__((kernel)) testNormalizeFloat2Float2(float2 inV) {
+    return normalize(inV);
+}
+
+float3 __attribute__((kernel)) testNormalizeFloat3Float3(float3 inV) {
+    return normalize(inV);
+}
+
+float4 __attribute__((kernel)) testNormalizeFloat4Float4(float4 inV) {
+    return normalize(inV);
+}
diff --git a/tests/src/android/renderscript/cts/TestNormalizeRelaxed.rs b/tests/src/android/renderscript/cts/TestNormalizeRelaxed.rs
new file mode 100644
index 0000000..148bec3
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestNormalizeRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestNormalize.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestPow.rs b/tests/src/android/renderscript/cts/TestPow.rs
new file mode 100644
index 0000000..855419a
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestPow.rs
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+rs_allocation gAllocInY;
+
+float __attribute__((kernel)) testPowFloatFloatFloat(float inX, unsigned int x) {
+    float inY = rsGetElementAt_float(gAllocInY, x);
+    return pow(inX, inY);
+}
+
+float2 __attribute__((kernel)) testPowFloat2Float2Float2(float2 inX, unsigned int x) {
+    float2 inY = rsGetElementAt_float2(gAllocInY, x);
+    return pow(inX, inY);
+}
+
+float3 __attribute__((kernel)) testPowFloat3Float3Float3(float3 inX, unsigned int x) {
+    float3 inY = rsGetElementAt_float3(gAllocInY, x);
+    return pow(inX, inY);
+}
+
+float4 __attribute__((kernel)) testPowFloat4Float4Float4(float4 inX, unsigned int x) {
+    float4 inY = rsGetElementAt_float4(gAllocInY, x);
+    return pow(inX, inY);
+}
diff --git a/tests/src/android/renderscript/cts/TestPowRelaxed.rs b/tests/src/android/renderscript/cts/TestPowRelaxed.rs
new file mode 100644
index 0000000..eae1207
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestPowRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestPow.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestPown.rs b/tests/src/android/renderscript/cts/TestPown.rs
new file mode 100644
index 0000000..3ee4fc0
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestPown.rs
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+rs_allocation gAllocInY;
+
+float __attribute__((kernel)) testPownFloatIntFloat(float inX, unsigned int x) {
+    int inY = rsGetElementAt_int(gAllocInY, x);
+    return pown(inX, inY);
+}
+
+float2 __attribute__((kernel)) testPownFloat2Int2Float2(float2 inX, unsigned int x) {
+    int2 inY = rsGetElementAt_int2(gAllocInY, x);
+    return pown(inX, inY);
+}
+
+float3 __attribute__((kernel)) testPownFloat3Int3Float3(float3 inX, unsigned int x) {
+    int3 inY = rsGetElementAt_int3(gAllocInY, x);
+    return pown(inX, inY);
+}
+
+float4 __attribute__((kernel)) testPownFloat4Int4Float4(float4 inX, unsigned int x) {
+    int4 inY = rsGetElementAt_int4(gAllocInY, x);
+    return pown(inX, inY);
+}
diff --git a/tests/src/android/renderscript/cts/TestPownRelaxed.rs b/tests/src/android/renderscript/cts/TestPownRelaxed.rs
new file mode 100644
index 0000000..d35cd0b
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestPownRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestPown.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestPowr.rs b/tests/src/android/renderscript/cts/TestPowr.rs
new file mode 100644
index 0000000..0fd603e
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestPowr.rs
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+rs_allocation gAllocInY;
+
+float __attribute__((kernel)) testPowrFloatFloatFloat(float inX, unsigned int x) {
+    float inY = rsGetElementAt_float(gAllocInY, x);
+    return powr(inX, inY);
+}
+
+float2 __attribute__((kernel)) testPowrFloat2Float2Float2(float2 inX, unsigned int x) {
+    float2 inY = rsGetElementAt_float2(gAllocInY, x);
+    return powr(inX, inY);
+}
+
+float3 __attribute__((kernel)) testPowrFloat3Float3Float3(float3 inX, unsigned int x) {
+    float3 inY = rsGetElementAt_float3(gAllocInY, x);
+    return powr(inX, inY);
+}
+
+float4 __attribute__((kernel)) testPowrFloat4Float4Float4(float4 inX, unsigned int x) {
+    float4 inY = rsGetElementAt_float4(gAllocInY, x);
+    return powr(inX, inY);
+}
diff --git a/tests/src/android/renderscript/cts/TestPowrRelaxed.rs b/tests/src/android/renderscript/cts/TestPowrRelaxed.rs
new file mode 100644
index 0000000..95e6f84
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestPowrRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestPowr.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestRadians.rs b/tests/src/android/renderscript/cts/TestRadians.rs
new file mode 100644
index 0000000..09aa9a0
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestRadians.rs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+
+float __attribute__((kernel)) testRadiansFloatFloat(float inValue) {
+    return radians(inValue);
+}
+
+float2 __attribute__((kernel)) testRadiansFloat2Float2(float2 inValue) {
+    return radians(inValue);
+}
+
+float3 __attribute__((kernel)) testRadiansFloat3Float3(float3 inValue) {
+    return radians(inValue);
+}
+
+float4 __attribute__((kernel)) testRadiansFloat4Float4(float4 inValue) {
+    return radians(inValue);
+}
diff --git a/tests/src/android/renderscript/cts/TestRadiansRelaxed.rs b/tests/src/android/renderscript/cts/TestRadiansRelaxed.rs
new file mode 100644
index 0000000..fa9209f
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestRadiansRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestRadians.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestRemainder.rs b/tests/src/android/renderscript/cts/TestRemainder.rs
new file mode 100644
index 0000000..86f2030
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestRemainder.rs
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+rs_allocation gAllocInY;
+
+float __attribute__((kernel)) testRemainderFloatFloatFloat(float inX, unsigned int x) {
+    float inY = rsGetElementAt_float(gAllocInY, x);
+    return remainder(inX, inY);
+}
+
+float2 __attribute__((kernel)) testRemainderFloat2Float2Float2(float2 inX, unsigned int x) {
+    float2 inY = rsGetElementAt_float2(gAllocInY, x);
+    return remainder(inX, inY);
+}
+
+float3 __attribute__((kernel)) testRemainderFloat3Float3Float3(float3 inX, unsigned int x) {
+    float3 inY = rsGetElementAt_float3(gAllocInY, x);
+    return remainder(inX, inY);
+}
+
+float4 __attribute__((kernel)) testRemainderFloat4Float4Float4(float4 inX, unsigned int x) {
+    float4 inY = rsGetElementAt_float4(gAllocInY, x);
+    return remainder(inX, inY);
+}
diff --git a/tests/src/android/renderscript/cts/TestRemainderRelaxed.rs b/tests/src/android/renderscript/cts/TestRemainderRelaxed.rs
new file mode 100644
index 0000000..7c45964
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestRemainderRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestRemainder.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestRemquo.rs b/tests/src/android/renderscript/cts/TestRemquo.rs
new file mode 100644
index 0000000..032e6c0
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestRemquo.rs
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+rs_allocation gAllocInC;
+rs_allocation gAllocOutD;
+
+float __attribute__((kernel)) testRemquoFloatFloatIntFloat(float inB, unsigned int x) {
+    float inC = rsGetElementAt_float(gAllocInC, x);
+    int outD = 0;
+    float out = remquo(inB, inC, &outD);
+    rsSetElementAt_int(gAllocOutD, outD, x);
+    return out;
+}
+
+float2 __attribute__((kernel)) testRemquoFloat2Float2Int2Float2(float2 inB, unsigned int x) {
+    float2 inC = rsGetElementAt_float2(gAllocInC, x);
+    int2 outD = 0;
+    float2 out = remquo(inB, inC, &outD);
+    rsSetElementAt_int2(gAllocOutD, outD, x);
+    return out;
+}
+
+float3 __attribute__((kernel)) testRemquoFloat3Float3Int3Float3(float3 inB, unsigned int x) {
+    float3 inC = rsGetElementAt_float3(gAllocInC, x);
+    int3 outD = 0;
+    float3 out = remquo(inB, inC, &outD);
+    rsSetElementAt_int3(gAllocOutD, outD, x);
+    return out;
+}
+
+float4 __attribute__((kernel)) testRemquoFloat4Float4Int4Float4(float4 inB, unsigned int x) {
+    float4 inC = rsGetElementAt_float4(gAllocInC, x);
+    int4 outD = 0;
+    float4 out = remquo(inB, inC, &outD);
+    rsSetElementAt_int4(gAllocOutD, outD, x);
+    return out;
+}
diff --git a/tests/src/android/renderscript/cts/TestRemquoRelaxed.rs b/tests/src/android/renderscript/cts/TestRemquoRelaxed.rs
new file mode 100644
index 0000000..3962532
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestRemquoRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestRemquo.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestRint.rs b/tests/src/android/renderscript/cts/TestRint.rs
new file mode 100644
index 0000000..a551d68
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestRint.rs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+
+float __attribute__((kernel)) testRintFloatFloat(float in) {
+    return rint(in);
+}
+
+float2 __attribute__((kernel)) testRintFloat2Float2(float2 in) {
+    return rint(in);
+}
+
+float3 __attribute__((kernel)) testRintFloat3Float3(float3 in) {
+    return rint(in);
+}
+
+float4 __attribute__((kernel)) testRintFloat4Float4(float4 in) {
+    return rint(in);
+}
diff --git a/tests/src/android/renderscript/cts/TestRintRelaxed.rs b/tests/src/android/renderscript/cts/TestRintRelaxed.rs
new file mode 100644
index 0000000..9fb4636
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestRintRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestRint.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestRootn.rs b/tests/src/android/renderscript/cts/TestRootn.rs
new file mode 100644
index 0000000..e4ee02b
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestRootn.rs
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+rs_allocation gAllocInN;
+
+float __attribute__((kernel)) testRootnFloatIntFloat(float inV, unsigned int x) {
+    int inN = rsGetElementAt_int(gAllocInN, x);
+    return rootn(inV, inN);
+}
+
+float2 __attribute__((kernel)) testRootnFloat2Int2Float2(float2 inV, unsigned int x) {
+    int2 inN = rsGetElementAt_int2(gAllocInN, x);
+    return rootn(inV, inN);
+}
+
+float3 __attribute__((kernel)) testRootnFloat3Int3Float3(float3 inV, unsigned int x) {
+    int3 inN = rsGetElementAt_int3(gAllocInN, x);
+    return rootn(inV, inN);
+}
+
+float4 __attribute__((kernel)) testRootnFloat4Int4Float4(float4 inV, unsigned int x) {
+    int4 inN = rsGetElementAt_int4(gAllocInN, x);
+    return rootn(inV, inN);
+}
diff --git a/tests/src/android/renderscript/cts/TestRootnRelaxed.rs b/tests/src/android/renderscript/cts/TestRootnRelaxed.rs
new file mode 100644
index 0000000..e42d664
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestRootnRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestRootn.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestRound.rs b/tests/src/android/renderscript/cts/TestRound.rs
new file mode 100644
index 0000000..0442849
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestRound.rs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+
+float __attribute__((kernel)) testRoundFloatFloat(float in) {
+    return round(in);
+}
+
+float2 __attribute__((kernel)) testRoundFloat2Float2(float2 in) {
+    return round(in);
+}
+
+float3 __attribute__((kernel)) testRoundFloat3Float3(float3 in) {
+    return round(in);
+}
+
+float4 __attribute__((kernel)) testRoundFloat4Float4(float4 in) {
+    return round(in);
+}
diff --git a/tests/src/android/renderscript/cts/TestRoundRelaxed.rs b/tests/src/android/renderscript/cts/TestRoundRelaxed.rs
new file mode 100644
index 0000000..ebbdccf
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestRoundRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestRound.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestRsqrt.rs b/tests/src/android/renderscript/cts/TestRsqrt.rs
new file mode 100644
index 0000000..5978899
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestRsqrt.rs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+
+float __attribute__((kernel)) testRsqrtFloatFloat(float in) {
+    return rsqrt(in);
+}
+
+float2 __attribute__((kernel)) testRsqrtFloat2Float2(float2 in) {
+    return rsqrt(in);
+}
+
+float3 __attribute__((kernel)) testRsqrtFloat3Float3(float3 in) {
+    return rsqrt(in);
+}
+
+float4 __attribute__((kernel)) testRsqrtFloat4Float4(float4 in) {
+    return rsqrt(in);
+}
diff --git a/tests/src/android/renderscript/cts/TestRsqrtRelaxed.rs b/tests/src/android/renderscript/cts/TestRsqrtRelaxed.rs
new file mode 100644
index 0000000..262761e
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestRsqrtRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestRsqrt.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestSign.rs b/tests/src/android/renderscript/cts/TestSign.rs
new file mode 100644
index 0000000..8f35b36
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestSign.rs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+
+float __attribute__((kernel)) testSignFloatFloat(float inV) {
+    return sign(inV);
+}
+
+float2 __attribute__((kernel)) testSignFloat2Float2(float2 inV) {
+    return sign(inV);
+}
+
+float3 __attribute__((kernel)) testSignFloat3Float3(float3 inV) {
+    return sign(inV);
+}
+
+float4 __attribute__((kernel)) testSignFloat4Float4(float4 inV) {
+    return sign(inV);
+}
diff --git a/tests/src/android/renderscript/cts/TestSignRelaxed.rs b/tests/src/android/renderscript/cts/TestSignRelaxed.rs
new file mode 100644
index 0000000..1bc69fb
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestSignRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestSign.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestSin.rs b/tests/src/android/renderscript/cts/TestSin.rs
new file mode 100644
index 0000000..15e78ba
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestSin.rs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+
+float __attribute__((kernel)) testSinFloatFloat(float in) {
+    return sin(in);
+}
+
+float2 __attribute__((kernel)) testSinFloat2Float2(float2 in) {
+    return sin(in);
+}
+
+float3 __attribute__((kernel)) testSinFloat3Float3(float3 in) {
+    return sin(in);
+}
+
+float4 __attribute__((kernel)) testSinFloat4Float4(float4 in) {
+    return sin(in);
+}
diff --git a/tests/src/android/renderscript/cts/TestSinRelaxed.rs b/tests/src/android/renderscript/cts/TestSinRelaxed.rs
new file mode 100644
index 0000000..e9e4912
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestSinRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestSin.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestSincos.rs b/tests/src/android/renderscript/cts/TestSincos.rs
new file mode 100644
index 0000000..82ff9cd
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestSincos.rs
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+rs_allocation gAllocOutCosptr;
+
+float __attribute__((kernel)) testSincosFloatFloatFloat(float inV, unsigned int x) {
+    float outCosptr = 0;
+    float out = sincos(inV, &outCosptr);
+    rsSetElementAt_float(gAllocOutCosptr, outCosptr, x);
+    return out;
+}
+
+float2 __attribute__((kernel)) testSincosFloat2Float2Float2(float2 inV, unsigned int x) {
+    float2 outCosptr = 0;
+    float2 out = sincos(inV, &outCosptr);
+    rsSetElementAt_float2(gAllocOutCosptr, outCosptr, x);
+    return out;
+}
+
+float3 __attribute__((kernel)) testSincosFloat3Float3Float3(float3 inV, unsigned int x) {
+    float3 outCosptr = 0;
+    float3 out = sincos(inV, &outCosptr);
+    rsSetElementAt_float3(gAllocOutCosptr, outCosptr, x);
+    return out;
+}
+
+float4 __attribute__((kernel)) testSincosFloat4Float4Float4(float4 inV, unsigned int x) {
+    float4 outCosptr = 0;
+    float4 out = sincos(inV, &outCosptr);
+    rsSetElementAt_float4(gAllocOutCosptr, outCosptr, x);
+    return out;
+}
diff --git a/tests/src/android/renderscript/cts/TestSincosRelaxed.rs b/tests/src/android/renderscript/cts/TestSincosRelaxed.rs
new file mode 100644
index 0000000..56cb9fc
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestSincosRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestSincos.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestSinh.rs b/tests/src/android/renderscript/cts/TestSinh.rs
new file mode 100644
index 0000000..bd94f0d
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestSinh.rs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+
+float __attribute__((kernel)) testSinhFloatFloat(float in) {
+    return sinh(in);
+}
+
+float2 __attribute__((kernel)) testSinhFloat2Float2(float2 in) {
+    return sinh(in);
+}
+
+float3 __attribute__((kernel)) testSinhFloat3Float3(float3 in) {
+    return sinh(in);
+}
+
+float4 __attribute__((kernel)) testSinhFloat4Float4(float4 in) {
+    return sinh(in);
+}
diff --git a/tests/src/android/renderscript/cts/TestSinhRelaxed.rs b/tests/src/android/renderscript/cts/TestSinhRelaxed.rs
new file mode 100644
index 0000000..8ca3390
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestSinhRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestSinh.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestSinpi.rs b/tests/src/android/renderscript/cts/TestSinpi.rs
new file mode 100644
index 0000000..367040e
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestSinpi.rs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+
+float __attribute__((kernel)) testSinpiFloatFloat(float in) {
+    return sinpi(in);
+}
+
+float2 __attribute__((kernel)) testSinpiFloat2Float2(float2 in) {
+    return sinpi(in);
+}
+
+float3 __attribute__((kernel)) testSinpiFloat3Float3(float3 in) {
+    return sinpi(in);
+}
+
+float4 __attribute__((kernel)) testSinpiFloat4Float4(float4 in) {
+    return sinpi(in);
+}
diff --git a/tests/src/android/renderscript/cts/TestSinpiRelaxed.rs b/tests/src/android/renderscript/cts/TestSinpiRelaxed.rs
new file mode 100644
index 0000000..dd611a7
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestSinpiRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestSinpi.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestSqrt.rs b/tests/src/android/renderscript/cts/TestSqrt.rs
new file mode 100644
index 0000000..f1c163b
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestSqrt.rs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+
+float __attribute__((kernel)) testSqrtFloatFloat(float in) {
+    return sqrt(in);
+}
+
+float2 __attribute__((kernel)) testSqrtFloat2Float2(float2 in) {
+    return sqrt(in);
+}
+
+float3 __attribute__((kernel)) testSqrtFloat3Float3(float3 in) {
+    return sqrt(in);
+}
+
+float4 __attribute__((kernel)) testSqrtFloat4Float4(float4 in) {
+    return sqrt(in);
+}
diff --git a/tests/src/android/renderscript/cts/TestSqrtRelaxed.rs b/tests/src/android/renderscript/cts/TestSqrtRelaxed.rs
new file mode 100644
index 0000000..ee5b6a8
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestSqrtRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestSqrt.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestStep.rs b/tests/src/android/renderscript/cts/TestStep.rs
new file mode 100644
index 0000000..41f8462
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestStep.rs
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+rs_allocation gAllocInV;
+
+float __attribute__((kernel)) testStepFloatFloatFloat(float inEdge, unsigned int x) {
+    float inV = rsGetElementAt_float(gAllocInV, x);
+    return step(inEdge, inV);
+}
+
+float2 __attribute__((kernel)) testStepFloat2Float2Float2(float2 inEdge, unsigned int x) {
+    float2 inV = rsGetElementAt_float2(gAllocInV, x);
+    return step(inEdge, inV);
+}
+
+float3 __attribute__((kernel)) testStepFloat3Float3Float3(float3 inEdge, unsigned int x) {
+    float3 inV = rsGetElementAt_float3(gAllocInV, x);
+    return step(inEdge, inV);
+}
+
+float4 __attribute__((kernel)) testStepFloat4Float4Float4(float4 inEdge, unsigned int x) {
+    float4 inV = rsGetElementAt_float4(gAllocInV, x);
+    return step(inEdge, inV);
+}
+
+float2 __attribute__((kernel)) testStepFloat2FloatFloat2(float2 inEdge, unsigned int x) {
+    float inV = rsGetElementAt_float(gAllocInV, x);
+    return step(inEdge, inV);
+}
+
+float3 __attribute__((kernel)) testStepFloat3FloatFloat3(float3 inEdge, unsigned int x) {
+    float inV = rsGetElementAt_float(gAllocInV, x);
+    return step(inEdge, inV);
+}
+
+float4 __attribute__((kernel)) testStepFloat4FloatFloat4(float4 inEdge, unsigned int x) {
+    float inV = rsGetElementAt_float(gAllocInV, x);
+    return step(inEdge, inV);
+}
diff --git a/tests/src/android/renderscript/cts/TestStepRelaxed.rs b/tests/src/android/renderscript/cts/TestStepRelaxed.rs
new file mode 100644
index 0000000..b2bad68
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestStepRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestStep.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestTan.rs b/tests/src/android/renderscript/cts/TestTan.rs
new file mode 100644
index 0000000..1024943
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestTan.rs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+
+float __attribute__((kernel)) testTanFloatFloat(float in) {
+    return tan(in);
+}
+
+float2 __attribute__((kernel)) testTanFloat2Float2(float2 in) {
+    return tan(in);
+}
+
+float3 __attribute__((kernel)) testTanFloat3Float3(float3 in) {
+    return tan(in);
+}
+
+float4 __attribute__((kernel)) testTanFloat4Float4(float4 in) {
+    return tan(in);
+}
diff --git a/tests/src/android/renderscript/cts/TestTanRelaxed.rs b/tests/src/android/renderscript/cts/TestTanRelaxed.rs
new file mode 100644
index 0000000..9297033
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestTanRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestTan.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestTanh.rs b/tests/src/android/renderscript/cts/TestTanh.rs
new file mode 100644
index 0000000..a017c2b
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestTanh.rs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+
+float __attribute__((kernel)) testTanhFloatFloat(float in) {
+    return tanh(in);
+}
+
+float2 __attribute__((kernel)) testTanhFloat2Float2(float2 in) {
+    return tanh(in);
+}
+
+float3 __attribute__((kernel)) testTanhFloat3Float3(float3 in) {
+    return tanh(in);
+}
+
+float4 __attribute__((kernel)) testTanhFloat4Float4(float4 in) {
+    return tanh(in);
+}
diff --git a/tests/src/android/renderscript/cts/TestTanhRelaxed.rs b/tests/src/android/renderscript/cts/TestTanhRelaxed.rs
new file mode 100644
index 0000000..f99420a
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestTanhRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestTanh.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestTanpi.rs b/tests/src/android/renderscript/cts/TestTanpi.rs
new file mode 100644
index 0000000..883a571
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestTanpi.rs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+
+float __attribute__((kernel)) testTanpiFloatFloat(float in) {
+    return tanpi(in);
+}
+
+float2 __attribute__((kernel)) testTanpiFloat2Float2(float2 in) {
+    return tanpi(in);
+}
+
+float3 __attribute__((kernel)) testTanpiFloat3Float3(float3 in) {
+    return tanpi(in);
+}
+
+float4 __attribute__((kernel)) testTanpiFloat4Float4(float4 in) {
+    return tanpi(in);
+}
diff --git a/tests/src/android/renderscript/cts/TestTanpiRelaxed.rs b/tests/src/android/renderscript/cts/TestTanpiRelaxed.rs
new file mode 100644
index 0000000..3fc9d28
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestTanpiRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestTanpi.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestTgamma.rs b/tests/src/android/renderscript/cts/TestTgamma.rs
new file mode 100644
index 0000000..7dae4cf
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestTgamma.rs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+
+float __attribute__((kernel)) testTgammaFloatFloat(float in) {
+    return tgamma(in);
+}
+
+float2 __attribute__((kernel)) testTgammaFloat2Float2(float2 in) {
+    return tgamma(in);
+}
+
+float3 __attribute__((kernel)) testTgammaFloat3Float3(float3 in) {
+    return tgamma(in);
+}
+
+float4 __attribute__((kernel)) testTgammaFloat4Float4(float4 in) {
+    return tgamma(in);
+}
diff --git a/tests/src/android/renderscript/cts/TestTgammaRelaxed.rs b/tests/src/android/renderscript/cts/TestTgammaRelaxed.rs
new file mode 100644
index 0000000..7d57ba0
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestTgammaRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestTgamma.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/TestTrunc.rs b/tests/src/android/renderscript/cts/TestTrunc.rs
new file mode 100644
index 0000000..2422ae4
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestTrunc.rs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+
+float __attribute__((kernel)) testTruncFloatFloat(float in) {
+    return trunc(in);
+}
+
+float2 __attribute__((kernel)) testTruncFloat2Float2(float2 in) {
+    return trunc(in);
+}
+
+float3 __attribute__((kernel)) testTruncFloat3Float3(float3 in) {
+    return trunc(in);
+}
+
+float4 __attribute__((kernel)) testTruncFloat4Float4(float4 in) {
+    return trunc(in);
+}
diff --git a/tests/src/android/renderscript/cts/TestTruncRelaxed.rs b/tests/src/android/renderscript/cts/TestTruncRelaxed.rs
new file mode 100644
index 0000000..b365243
--- /dev/null
+++ b/tests/src/android/renderscript/cts/TestTruncRelaxed.rs
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "TestTrunc.rs"
+#pragma rs_fp_relaxed
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
diff --git a/tests/src/android/renderscript/cts/acos_f32.rs b/tests/src/android/renderscript/cts/acos_f32.rs
deleted file mode 100644
index 4bc948b..0000000
--- a/tests/src/android/renderscript/cts/acos_f32.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-void acos_f32_1 (const float* in, float* out) {
-    *out = acos(*in);
-}
-
-void acos_f32_2 (const float2* in, float2* out) {
-    *out = acos(*in);
-}
-
-void acos_f32_3 (const float3* in, float3* out) {
-    *out = acos(*in);
-}
-
-void acos_f32_4 (const float4* in , float4* out) {
-    *out = acos(*in);
-}
diff --git a/tests/src/android/renderscript/cts/acos_f32_relaxed.rs b/tests/src/android/renderscript/cts/acos_f32_relaxed.rs
deleted file mode 100644
index b553719..0000000
--- a/tests/src/android/renderscript/cts/acos_f32_relaxed.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "acos_f32.rs"
-#pragma rs_fp_relaxed
diff --git a/tests/src/android/renderscript/cts/acosh_f32.rs b/tests/src/android/renderscript/cts/acosh_f32.rs
deleted file mode 100644
index 8784b02..0000000
--- a/tests/src/android/renderscript/cts/acosh_f32.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-void acosh_f32_1 (const float* in, float* out) {
-    *out = acosh(*in);
-}
-
-void acosh_f32_2 (const float2* in, float2* out) {
-    *out = acosh(*in);
-}
-
-void acosh_f32_3 (const float3* in, float3* out) {
-    *out = acosh(*in);
-}
-
-void acosh_f32_4 (const float4* in , float4* out) {
-    *out = acosh(*in);
-}
diff --git a/tests/src/android/renderscript/cts/acosh_f32_relaxed.rs b/tests/src/android/renderscript/cts/acosh_f32_relaxed.rs
deleted file mode 100644
index b7995c1..0000000
--- a/tests/src/android/renderscript/cts/acosh_f32_relaxed.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "acosh_f32.rs"
-#pragma rs_fp_relaxed
diff --git a/tests/src/android/renderscript/cts/acospi_f32.rs b/tests/src/android/renderscript/cts/acospi_f32.rs
deleted file mode 100644
index 66d89eb..0000000
--- a/tests/src/android/renderscript/cts/acospi_f32.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-void acospi_f32_1 (const float* in, float* out) {
-    *out = acospi(*in);
-}
-
-void acospi_f32_2 (const float2* in, float2* out) {
-    *out = acospi(*in);
-}
-
-void acospi_f32_3 (const float3* in, float3* out) {
-    *out = acospi(*in);
-}
-
-void acospi_f32_4 (const float4* in, float4* out) {
-    *out = acospi(*in);
-}
diff --git a/tests/src/android/renderscript/cts/acospi_f32_relaxed.rs b/tests/src/android/renderscript/cts/acospi_f32_relaxed.rs
deleted file mode 100644
index 0d76365..0000000
--- a/tests/src/android/renderscript/cts/acospi_f32_relaxed.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "acospi_f32.rs"
-#pragma rs_fp_relaxed
diff --git a/tests/src/android/renderscript/cts/asin_f32.rs b/tests/src/android/renderscript/cts/asin_f32.rs
deleted file mode 100644
index 5f062f9..0000000
--- a/tests/src/android/renderscript/cts/asin_f32.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-void asin_f32_1 (const float* in, float* out) {
-    *out = asin(*in);
-}
-
-void asin_f32_2 (const float2* in, float2* out) {
-    *out = asin(*in);
-}
-
-void asin_f32_3 (const float3* in, float3* out) {
-    *out = asin(*in);
-}
-
-void asin_f32_4 (const float4* in , float4* out) {
-    *out = asin (*in) ;
-}
diff --git a/tests/src/android/renderscript/cts/asin_f32_relaxed.rs b/tests/src/android/renderscript/cts/asin_f32_relaxed.rs
deleted file mode 100644
index b5b3926..0000000
--- a/tests/src/android/renderscript/cts/asin_f32_relaxed.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "asin_f32.rs"
-#pragma rs_fp_relaxed
diff --git a/tests/src/android/renderscript/cts/asinh_f32.rs b/tests/src/android/renderscript/cts/asinh_f32.rs
deleted file mode 100644
index 8252507..0000000
--- a/tests/src/android/renderscript/cts/asinh_f32.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-void asinh_f32_1 (const float* in, float* out) {
-    *out = asinh(*in);
-}
-
-void asinh_f32_2 (const float2* in, float2* out) {
-    *out = asinh(*in);
-}
-
-void asinh_f32_3 (const float3* in, float3* out) {
-    *out = asinh(*in);
-}
-
-void asinh_f32_4 (const float4* in, float4* out) {
-    *out = asinh(*in);
-}
diff --git a/tests/src/android/renderscript/cts/asinh_f32_relaxed.rs b/tests/src/android/renderscript/cts/asinh_f32_relaxed.rs
deleted file mode 100644
index 02a7082..0000000
--- a/tests/src/android/renderscript/cts/asinh_f32_relaxed.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "asinh_f32.rs"
-#pragma rs_fp_relaxed
diff --git a/tests/src/android/renderscript/cts/asinpi_f32.rs b/tests/src/android/renderscript/cts/asinpi_f32.rs
deleted file mode 100644
index 66bf1d7..0000000
--- a/tests/src/android/renderscript/cts/asinpi_f32.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-void asinpi_f32_1 (const float* in, float* out) {
-    *out = asinpi(*in);
-}
-
-void asinpi_f32_2 (const float2* in, float2* out) {
-    *out = asinpi(*in);
-}
-
-void asinpi_f32_3 (const float3* in, float3* out) {
-    *out = asinpi(*in);
-}
-
-void asinpi_f32_4 (const float4* in, float4* out) {
-    *out = asinpi(*in);
-}
diff --git a/tests/src/android/renderscript/cts/asinpi_f32_relaxed.rs b/tests/src/android/renderscript/cts/asinpi_f32_relaxed.rs
deleted file mode 100644
index 924a534..0000000
--- a/tests/src/android/renderscript/cts/asinpi_f32_relaxed.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "asinpi_f32.rs"
-#pragma rs_fp_relaxed
diff --git a/tests/src/android/renderscript/cts/atan2_f32.rs b/tests/src/android/renderscript/cts/atan2_f32.rs
deleted file mode 100644
index e1bab48..0000000
--- a/tests/src/android/renderscript/cts/atan2_f32.rs
+++ /dev/null
@@ -1,38 +0,0 @@
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-typedef struct atan2_f32_in {
-    float first;
-    float second;
-} input;
-
-void atan2_f32_1(const input* in, float* out){
-    *out = atan2(in->first, in->second);
-}
-
-typedef struct atan2_f32_2_in {
-    float2 first;
-    float2 second;
-} input2;
-
-void atan2_f32_2(const input2* in, float2* out){
-    *out = atan2(in->first, in->second);
-}
-
-typedef struct atan2_f32_3_in {
-    float3 first;
-    float3 second;
-} input3;
-
-void atan2_f32_3(const input3* in, float3* out){
-    *out = atan2(in->first, in->second);
-}
-
-typedef struct atan2_f32_4_in {
-    float4 first;
-    float4 second;
-} input4;
-
-void atan2_f32_4(const input4* in, float4* out){
-    *out = atan2(in->first, in->second);
-}
diff --git a/tests/src/android/renderscript/cts/atan2_f32_relaxed.rs b/tests/src/android/renderscript/cts/atan2_f32_relaxed.rs
deleted file mode 100644
index dd749fa..0000000
--- a/tests/src/android/renderscript/cts/atan2_f32_relaxed.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "atan2_f32.rs"
-#pragma rs_fp_relaxed
diff --git a/tests/src/android/renderscript/cts/atan2pi_f32.rs b/tests/src/android/renderscript/cts/atan2pi_f32.rs
deleted file mode 100644
index 2fe52d8..0000000
--- a/tests/src/android/renderscript/cts/atan2pi_f32.rs
+++ /dev/null
@@ -1,38 +0,0 @@
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-struct atan2pi_float_input {
-    float x;
-    float y;
-};
-
-void atan2pi_f32_1 (const struct atan2pi_float_input* in, float* out) {
-    *out = atan2pi(in->x, in->y);
-}
-
-struct atan2pi_float2_input {
-    float2 x;
-    float2 y;
-};
-
-void atan2pi_f32_2 (const struct atan2pi_float2_input* in, float2* out) {
-    *out = atan2pi(in->x, in->y);
-}
-
-struct atan2pi_float3_input {
-    float3 x;
-    float3 y;
-};
-
-void atan2pi_f32_3 (const struct atan2pi_float3_input* in, float3* out) {
-    *out = atan2pi(in->x, in->y);
-}
-
-struct atan2pi_float4_input {
-    float4 x;
-    float4 y;
-};
-
-void atan2pi_f32_4 (const struct atan2pi_float4_input* in, float4* out) {
-    *out = atan2pi(in->x, in->y);
-}
diff --git a/tests/src/android/renderscript/cts/atan2pi_f32_relaxed.rs b/tests/src/android/renderscript/cts/atan2pi_f32_relaxed.rs
deleted file mode 100644
index 0d4e8fb..0000000
--- a/tests/src/android/renderscript/cts/atan2pi_f32_relaxed.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "atan2pi_f32.rs"
-#pragma rs_fp_relaxed
diff --git a/tests/src/android/renderscript/cts/atan_f32.rs b/tests/src/android/renderscript/cts/atan_f32.rs
deleted file mode 100644
index 65a5ab5..0000000
--- a/tests/src/android/renderscript/cts/atan_f32.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-void atan_f32_1 (const float* in, float* out) {
-    *out = atan(*in);
-}
-
-void atan_f32_2 (const float2* in, float2* out) {
-    *out = atan(*in);
-}
-
-void atan_f32_3 (const float3* in, float3* out) {
-    *out = atan(*in);
-}
-
-void atan_f32_4 (const float4* in, float4* out) {
-    *out =atan(*in);
-}
diff --git a/tests/src/android/renderscript/cts/atan_f32_relaxed.rs b/tests/src/android/renderscript/cts/atan_f32_relaxed.rs
deleted file mode 100644
index e015aa8..0000000
--- a/tests/src/android/renderscript/cts/atan_f32_relaxed.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "atan_f32.rs"
-#pragma rs_fp_relaxed
diff --git a/tests/src/android/renderscript/cts/atanh_f32.rs b/tests/src/android/renderscript/cts/atanh_f32.rs
deleted file mode 100644
index 1f61e5e..0000000
--- a/tests/src/android/renderscript/cts/atanh_f32.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-void atanh_f32_1 (const float* in, float* out) {
-    *out = atanh(*in);
-}
-
-void atanh_f32_2 (const float2* in, float2* out) {
-    *out = atanh(*in);
-}
-
-void atanh_f32_3 (const float3* in, float3* out) {
-    *out = atanh(*in);
-}
-
-void atanh_f32_4 (const float4* in, float4* out) {
-    *out = atanh(*in);
-}
diff --git a/tests/src/android/renderscript/cts/atanh_f32_relaxed.rs b/tests/src/android/renderscript/cts/atanh_f32_relaxed.rs
deleted file mode 100644
index 2083e4d..0000000
--- a/tests/src/android/renderscript/cts/atanh_f32_relaxed.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "atanh_f32.rs"
-#pragma rs_fp_relaxed
diff --git a/tests/src/android/renderscript/cts/atanpi_f32.rs b/tests/src/android/renderscript/cts/atanpi_f32.rs
deleted file mode 100644
index 182a43c..0000000
--- a/tests/src/android/renderscript/cts/atanpi_f32.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-void atanpi_f32_1 (const float* in, float* out) {
-    *out = atanpi(*in);
-}
-
-void atanpi_f32_2 (const float2* in, float2* out) {
-    *out = atanpi(*in);
-}
-
-void atanpi_f32_3 (const float3* in, float3* out) {
-    *out = atanpi(*in);
-}
-
-void atanpi_f32_4 (const float4* in, float4* out) {
-    *out = atanpi(*in);
-}
diff --git a/tests/src/android/renderscript/cts/atanpi_f32_relaxed.rs b/tests/src/android/renderscript/cts/atanpi_f32_relaxed.rs
deleted file mode 100644
index fefe784..0000000
--- a/tests/src/android/renderscript/cts/atanpi_f32_relaxed.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "atanpi_f32.rs"
-#pragma rs_fp_relaxed
diff --git a/tests/src/android/renderscript/cts/cbrt_f32.rs b/tests/src/android/renderscript/cts/cbrt_f32.rs
deleted file mode 100644
index 273e8a4..0000000
--- a/tests/src/android/renderscript/cts/cbrt_f32.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-void cbrt_f32_1(const float *in, float *out) {
-    *out = cbrt(*in);
-}
-
-void cbrt_f32_2(const float2 *in, float2 *out) {
-    *out = cbrt(*in);
-}
-
-void cbrt_f32_3(const float3 *in, float3 *out) {
-    *out = cbrt(*in);
-}
-
-void cbrt_f32_4(const float4 *in, float4 *out) {
-    *out = cbrt(*in);
-}
diff --git a/tests/src/android/renderscript/cts/cbrt_f32_relaxed.rs b/tests/src/android/renderscript/cts/cbrt_f32_relaxed.rs
deleted file mode 100644
index 9b9e5a5..0000000
--- a/tests/src/android/renderscript/cts/cbrt_f32_relaxed.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "cbrt_f32.rs"
-#pragma rs_fp_relaxed
diff --git a/tests/src/android/renderscript/cts/ceil_f32.rs b/tests/src/android/renderscript/cts/ceil_f32.rs
deleted file mode 100644
index c0817e2..0000000
--- a/tests/src/android/renderscript/cts/ceil_f32.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-void ceil_f32_1(const float *in, float *out) {
-    *out = ceil(*in);
-}
-
-void ceil_f32_2(const float2 *in, float2 *out) {
-    *out = ceil(*in);
-}
-
-void ceil_f32_3(const float3 *in, float3 *out) {
-    *out = ceil(*in);
-}
-
-void ceil_f32_4(const float4 *in, float4 *out) {
-    *out = ceil(*in);
-}
diff --git a/tests/src/android/renderscript/cts/ceil_f32_relaxed.rs b/tests/src/android/renderscript/cts/ceil_f32_relaxed.rs
deleted file mode 100644
index 332ca6c..0000000
--- a/tests/src/android/renderscript/cts/ceil_f32_relaxed.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "ceil_f32.rs"
-#pragma rs_fp_relaxed
diff --git a/tests/src/android/renderscript/cts/clamp.rs b/tests/src/android/renderscript/cts/clamp.rs
deleted file mode 100644
index 28b00bd..0000000
--- a/tests/src/android/renderscript/cts/clamp.rs
+++ /dev/null
@@ -1,56 +0,0 @@
-#include "shared.rsh"
-
-static bool test_clamp_vector() {
-    bool failed = false;
-
-    float2 src2 = { 2.0f, 2.0f};
-    float2 min2 = { 0.5f, -3.0f};
-    float2 max2 = { 1.0f, 9.0f};
-
-    float2 res2 = clamp(src2, min2, max2);
-    _RS_ASSERT(res2.x == 1.0f);
-    _RS_ASSERT(res2.y == 2.0f);
-
-
-    float3 src3 = { 2.0f, 2.0f, 1.0f};
-    float3 min3 = { 0.5f, -3.0f, 3.0f};
-    float3 max3 = { 1.0f, 9.0f, 4.0f};
-
-    float3 res3 = clamp(src3, min3, max3);
-    _RS_ASSERT(res3.x == 1.0f);
-    _RS_ASSERT(res3.y == 2.0f);
-    _RS_ASSERT(res3.z == 3.0f);
-
-
-    float4 src4 = { 2.0f, 2.0f, 1.0f, 4.0f };
-    float4 min4 = { 0.5f, -3.0f, 3.0f, 4.0f };
-    float4 max4 = { 1.0f, 9.0f, 4.0f, 4.0f };
-
-    float4 res4 = clamp(src4, min4, max4);
-    _RS_ASSERT(res4.x == 1.0f);
-    _RS_ASSERT(res4.y == 2.0f);
-    _RS_ASSERT(res4.z == 3.0f);
-    _RS_ASSERT(res4.w == 4.0f);
-
-    if (failed) {
-        rsDebug("test_clamp_vector FAILED", 0);
-    }
-    else {
-        rsDebug("test_clamp_vector PASSED", 0);
-    }
-
-    return failed;
-}
-
-void clamp_test() {
-    bool failed = false;
-    failed |= test_clamp_vector();
-
-    if (failed) {
-        rsSendToClientBlocking(RS_MSG_TEST_FAILED);
-    }
-    else {
-        rsSendToClientBlocking(RS_MSG_TEST_PASSED);
-    }
-}
-
diff --git a/tests/src/android/renderscript/cts/clamp_relaxed.rs b/tests/src/android/renderscript/cts/clamp_relaxed.rs
deleted file mode 100644
index 71c65ae..0000000
--- a/tests/src/android/renderscript/cts/clamp_relaxed.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "clamp.rs"
-#pragma rs_fp_relaxed
diff --git a/tests/src/android/renderscript/cts/copysign_f32.rs b/tests/src/android/renderscript/cts/copysign_f32.rs
deleted file mode 100644
index b0b300d..0000000
--- a/tests/src/android/renderscript/cts/copysign_f32.rs
+++ /dev/null
@@ -1,38 +0,0 @@
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-struct copysign_f32_input {
-    float x;
-    float y;
-};
-
-void copysign_f32_1(const struct copysign_f32_input *in, float *out) {
-    *out = copysign(in->x, in->y);
-}
-
-struct copysign_f32_2_input {
-    float2 x;
-    float2 y;
-};
-
-void copysign_f32_2(const struct copysign_f32_2_input *in, float2 *out) {
-    *out = copysign(in->x, in->y);
-}
-
-struct copysign_f32_3_input {
-    float3 x;
-    float3 y;
-};
-
-void copysign_f32_3(const struct copysign_f32_3_input *in, float3 *out) {
-    *out = copysign(in->x, in->y);
-}
-
-struct copysign_f32_4_input {
-    float4 x;
-    float4 y;
-};
-
-void copysign_f32_4(const struct copysign_f32_4_input *in, float4 *out) {
-    *out = copysign(in->x, in->y);
-}
diff --git a/tests/src/android/renderscript/cts/copysign_f32_relaxed.rs b/tests/src/android/renderscript/cts/copysign_f32_relaxed.rs
deleted file mode 100644
index e7fe701..0000000
--- a/tests/src/android/renderscript/cts/copysign_f32_relaxed.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "copysign_f32.rs"
-#pragma rs_fp_relaxed
diff --git a/tests/src/android/renderscript/cts/cos_f32.rs b/tests/src/android/renderscript/cts/cos_f32.rs
deleted file mode 100644
index fd061dc..0000000
--- a/tests/src/android/renderscript/cts/cos_f32.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-void cos_f32_1(const float *in, float *out) {
-    *out = cos(*in);
-}
-
-void cos_f32_2(const float2 *in, float2 *out) {
-    *out = cos(*in);
-}
-
-void cos_f32_3(const float3 *in, float3 *out) {
-    *out = cos(*in);
-}
-
-void cos_f32_4(const float4 *in, float4 *out) {
-    *out = cos(*in);
-}
diff --git a/tests/src/android/renderscript/cts/cos_f32_relaxed.rs b/tests/src/android/renderscript/cts/cos_f32_relaxed.rs
deleted file mode 100644
index ceb51d2..0000000
--- a/tests/src/android/renderscript/cts/cos_f32_relaxed.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "cos_f32.rs"
-#pragma rs_fp_relaxed
diff --git a/tests/src/android/renderscript/cts/cosh_f32.rs b/tests/src/android/renderscript/cts/cosh_f32.rs
deleted file mode 100644
index 0f2ab0f..0000000
--- a/tests/src/android/renderscript/cts/cosh_f32.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-void cosh_f32_1(const float *in, float *out) {
-    *out = cosh(*in);
-}
-
-void cosh_f32_2(const float2 *in, float2 *out) {
-    *out = cosh(*in);
-}
-
-void cosh_f32_3(const float3 *in, float3 *out) {
-    *out = cosh(*in);
-}
-
-void cosh_f32_4(const float4 *in, float4 *out) {
-    *out = cosh(*in);
-}
diff --git a/tests/src/android/renderscript/cts/cosh_f32_relaxed.rs b/tests/src/android/renderscript/cts/cosh_f32_relaxed.rs
deleted file mode 100644
index 7f6a79b..0000000
--- a/tests/src/android/renderscript/cts/cosh_f32_relaxed.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "cosh_f32.rs"
-#pragma rs_fp_relaxed
diff --git a/tests/src/android/renderscript/cts/cross_f32.rs b/tests/src/android/renderscript/cts/cross_f32.rs
deleted file mode 100644
index e996e5f..0000000
--- a/tests/src/android/renderscript/cts/cross_f32.rs
+++ /dev/null
@@ -1,19 +0,0 @@
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-typedef struct _cross_f32_3_struct {
-    float3 low;
-    float3 high;
-} cross_f32_3_struct;
-
-void cross_f32_3(const cross_f32_3_struct *in, float3 *out) {
-    *out = cross(in->low, in->high);
-}
-
-typedef struct _cross_f32_4_struct {
-    float4 low;
-    float4 high;
-} cross_f32_4_struct;
-
-void cross_f32_4(const cross_f32_4_struct *in, float4 *out) {
-    *out = cross(in->low, in->high);
-}
diff --git a/tests/src/android/renderscript/cts/cross_f32_relaxed.rs b/tests/src/android/renderscript/cts/cross_f32_relaxed.rs
deleted file mode 100644
index d9fbfed..0000000
--- a/tests/src/android/renderscript/cts/cross_f32_relaxed.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "cross_f32.rs"
-#pragma rs_fp_relaxed
diff --git a/tests/src/android/renderscript/cts/degrees_f32.rs b/tests/src/android/renderscript/cts/degrees_f32.rs
deleted file mode 100644
index e571246..0000000
--- a/tests/src/android/renderscript/cts/degrees_f32.rs
+++ /dev/null
@@ -1,21 +0,0 @@
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-void degrees_f32_1(const float* in, float* out) {
-    *out = degrees(*in);
-}
-
-void degrees_f32_2(const float2* in, float2* out) {
-    *out = degrees (*in);
-
-}
-
-void degrees_f32_3(const float3* in, float3* out) {
-    *out = degrees(*in);
-
-}
-
-void degrees_f32_4(const float4* in, float4* out) {
-    *out = degrees(*in);
-
-}
diff --git a/tests/src/android/renderscript/cts/degrees_f32_relaxed.rs b/tests/src/android/renderscript/cts/degrees_f32_relaxed.rs
deleted file mode 100644
index bc603a5..0000000
--- a/tests/src/android/renderscript/cts/degrees_f32_relaxed.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "degrees_f32.rs"
-#pragma rs_fp_relaxed
diff --git a/tests/src/android/renderscript/cts/exp10_f32.rs b/tests/src/android/renderscript/cts/exp10_f32.rs
deleted file mode 100644
index 67f5c26..0000000
--- a/tests/src/android/renderscript/cts/exp10_f32.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-void exp10_f32_1(const float *in, float *out) {
-    *out = exp10(*in);
-}
-
-void exp10_f32_2(const float2 *in, float2 *out) {
-    *out = exp10(*in);
-}
-
-void exp10_f32_3(const float3 *in, float3 *out) {
-    *out = exp10(*in);
-}
-
-void exp10_f32_4(const float4 *in, float4 *out) {
-    *out = exp10(*in);
-}
diff --git a/tests/src/android/renderscript/cts/exp10_f32_relaxed.rs b/tests/src/android/renderscript/cts/exp10_f32_relaxed.rs
deleted file mode 100644
index 6e4e007..0000000
--- a/tests/src/android/renderscript/cts/exp10_f32_relaxed.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "exp10_f32.rs"
-#pragma rs_fp_relaxed
diff --git a/tests/src/android/renderscript/cts/exp2_f32.rs b/tests/src/android/renderscript/cts/exp2_f32.rs
deleted file mode 100644
index 9095bf3..0000000
--- a/tests/src/android/renderscript/cts/exp2_f32.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-void exp2_f32_1(const float *in, float *out) {
-    *out = exp2(*in);
-}
-
-void exp2_f32_2(const float2 *in, float2 *out) {
-    *out = exp2(*in);
-}
-
-void exp2_f32_3(const float3 *in, float3 *out) {
-    *out = exp2(*in);
-}
-
-void exp2_f32_4(const float4 *in, float4 *out) {
-    *out = exp2(*in);
-}
diff --git a/tests/src/android/renderscript/cts/exp2_f32_relaxed.rs b/tests/src/android/renderscript/cts/exp2_f32_relaxed.rs
deleted file mode 100644
index 676b30a..0000000
--- a/tests/src/android/renderscript/cts/exp2_f32_relaxed.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "exp2_f32.rs"
-#pragma rs_fp_relaxed
diff --git a/tests/src/android/renderscript/cts/exp_f32.rs b/tests/src/android/renderscript/cts/exp_f32.rs
deleted file mode 100644
index 036c490..0000000
--- a/tests/src/android/renderscript/cts/exp_f32.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-void exp_f32_1(const float *in, float *out) {
-    *out = exp(*in);
-}
-
-void exp_f32_2(const float2 *in, float2 *out) {
-    *out = exp(*in);
-}
-
-void exp_f32_3(const float3 *in, float3 *out) {
-    *out = exp(*in);
-}
-
-void exp_f32_4(const float4 *in, float4 *out) {
-    *out = exp(*in);
-}
diff --git a/tests/src/android/renderscript/cts/exp_f32_relaxed.rs b/tests/src/android/renderscript/cts/exp_f32_relaxed.rs
deleted file mode 100644
index dc4b3d0..0000000
--- a/tests/src/android/renderscript/cts/exp_f32_relaxed.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "exp_f32.rs"
-#pragma rs_fp_relaxed
diff --git a/tests/src/android/renderscript/cts/expm1_f32.rs b/tests/src/android/renderscript/cts/expm1_f32.rs
deleted file mode 100644
index 1950131..0000000
--- a/tests/src/android/renderscript/cts/expm1_f32.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-void expm1_f32_1(const float *in, float *out) {
-    *out = expm1(*in);
-}
-
-void expm1_f32_2(const float2 *in, float2 *out) {
-    *out = expm1(*in);
-}
-
-void expm1_f32_3(const float3 *in, float3 *out) {
-    *out = expm1(*in);
-}
-
-void expm1_f32_4(const float4 *in, float4 *out) {
-    *out = expm1(*in);
-}
diff --git a/tests/src/android/renderscript/cts/expm1_f32_relaxed.rs b/tests/src/android/renderscript/cts/expm1_f32_relaxed.rs
deleted file mode 100644
index 5a3c40e..0000000
--- a/tests/src/android/renderscript/cts/expm1_f32_relaxed.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "expm1_f32.rs"
-#pragma rs_fp_relaxed
diff --git a/tests/src/android/renderscript/cts/fabs_f32.rs b/tests/src/android/renderscript/cts/fabs_f32.rs
deleted file mode 100644
index 1567e4d..0000000
--- a/tests/src/android/renderscript/cts/fabs_f32.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-void fabs_f32_1(const float *in, float *out) {
-    *out = fabs(*in);
-}
-
-void fabs_f32_2(const float2 *in, float2 *out) {
-    *out = fabs(*in);
-}
-
-void fabs_f32_3(const float3 *in, float3 *out) {
-    *out = fabs(*in);
-}
-
-void fabs_f32_4(const float4 *in, float4 *out) {
-    *out = fabs(*in);
-}
diff --git a/tests/src/android/renderscript/cts/fabs_f32_relaxed.rs b/tests/src/android/renderscript/cts/fabs_f32_relaxed.rs
deleted file mode 100644
index e0add35..0000000
--- a/tests/src/android/renderscript/cts/fabs_f32_relaxed.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "fabs_f32.rs"
-#pragma rs_fp_relaxed
diff --git a/tests/src/android/renderscript/cts/fdim_f32.rs b/tests/src/android/renderscript/cts/fdim_f32.rs
deleted file mode 100644
index e2c5fb1..0000000
--- a/tests/src/android/renderscript/cts/fdim_f32.rs
+++ /dev/null
@@ -1,38 +0,0 @@
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-struct fdim_f32_input {
-    float x;
-    float y;
-};
-
-void fdim_f32_1(const struct fdim_f32_input *in, float *out) {
-    *out = fdim(in->x, in->y);
-}
-
-struct fdim_f32_2_input {
-    float2 x;
-    float2 y;
-};
-
-void fdim_f32_2(const struct fdim_f32_2_input *in, float2 *out) {
-    *out = fdim(in->x, in->y);
-}
-
-struct fdim_f32_3_input {
-    float3 x;
-    float3 y;
-};
-
-void fdim_f32_3(const struct fdim_f32_3_input *in, float3 *out) {
-    *out = fdim(in->x, in->y);
-}
-
-struct fdim_f32_4_input {
-    float4 x;
-    float4 y;
-};
-
-void fdim_f32_4(const struct fdim_f32_4_input *in, float4 *out) {
-    *out = fdim(in->x, in->y);
-}
diff --git a/tests/src/android/renderscript/cts/fdim_f32_relaxed.rs b/tests/src/android/renderscript/cts/fdim_f32_relaxed.rs
deleted file mode 100644
index 18c8cf0..0000000
--- a/tests/src/android/renderscript/cts/fdim_f32_relaxed.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "fdim_f32.rs"
-#pragma rs_fp_relaxed
diff --git a/tests/src/android/renderscript/cts/floor_f32.rs b/tests/src/android/renderscript/cts/floor_f32.rs
deleted file mode 100644
index 2300dab..0000000
--- a/tests/src/android/renderscript/cts/floor_f32.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-void floor_f32_1(const float *in, float *out) {
-    *out = floor(*in);
-}
-
-void floor_f32_2(const float2 *in, float2 *out) {
-    *out = floor(*in);
-}
-
-void floor_f32_3(const float3 *in, float3 *out) {
-    *out = floor(*in);
-}
-
-void floor_f32_4(const float4 *in, float4 *out) {
-    *out = floor(*in);
-}
diff --git a/tests/src/android/renderscript/cts/floor_f32_relaxed.rs b/tests/src/android/renderscript/cts/floor_f32_relaxed.rs
deleted file mode 100644
index d6bef83..0000000
--- a/tests/src/android/renderscript/cts/floor_f32_relaxed.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "floor_f32.rs"
-#pragma rs_fp_relaxed
diff --git a/tests/src/android/renderscript/cts/fma_f32.rs b/tests/src/android/renderscript/cts/fma_f32.rs
deleted file mode 100644
index 36257a5..0000000
--- a/tests/src/android/renderscript/cts/fma_f32.rs
+++ /dev/null
@@ -1,42 +0,0 @@
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-typedef struct Floats {
-    float fa;
-    float fb;
-    float fc;
-} Floats;
-
-void fma_f32_1(const Floats *in, float *out) {
-    *out = fma(in->fa, in->fb, in->fc);
-}
-
-typedef struct Floats2 {
-    float2 fa;
-    float2 fb;
-    float2 fc;
-} Floats2;
-
-void fma_f32_2(const Floats2 *in, float2 *out) {
-    *out = fma(in->fa, in->fb, in->fc);
-}
-
-typedef struct Floats3 {
-    float3 fa;
-    float3 fb;
-    float3 fc;
-} Floats3;
-
-void fma_f32_3(const Floats3 *in, float3 *out) {
-    *out = fma(in->fa, in->fb, in->fc);
-}
-
-typedef struct Floats4 {
-    float4 fa;
-    float4 fb;
-    float4 fc;
-} Floats4;
-
-void fma_f32_4(const Floats4 *in, float4 *out) {
-    *out = fma(in->fa, in->fb, in->fc);
-}
diff --git a/tests/src/android/renderscript/cts/fma_f32_relaxed.rs b/tests/src/android/renderscript/cts/fma_f32_relaxed.rs
deleted file mode 100644
index 77f92df..0000000
--- a/tests/src/android/renderscript/cts/fma_f32_relaxed.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "fma_f32.rs"
-#pragma rs_fp_relaxed
diff --git a/tests/src/android/renderscript/cts/fmax_f32.rs b/tests/src/android/renderscript/cts/fmax_f32.rs
deleted file mode 100644
index e03f258..0000000
--- a/tests/src/android/renderscript/cts/fmax_f32.rs
+++ /dev/null
@@ -1,38 +0,0 @@
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-typedef struct fmax_f32_in {
-    float first;
-    float second;
-} input1;
-
-void fmax_f32_1(const input1* in, float* out){
-    *out = fmax(in->first, in->second);
-}
-
-typedef struct fmax_f32_2_in {
-    float2 first;
-    float2 second;
-} input2;
-
-void fmax_f32_2(const input2* in, float2* out){
-    *out = fmax(in->first, in->second);
-}
-
-typedef struct fmax_f32_3_in {
-    float3 first;
-    float3 second;
-} input3;
-
-void fmax_f32_3(const input3* in, float3* out){
-    *out = fmax(in->first, in->second);
-}
-
-typedef struct fmax_f32_4_in {
-    float4 first;
-    float4 second;
-} input4;
-
-void fmax_f32_4(const input4* in, float4* out){
-    *out = fmax(in->first, in->second);
-}
diff --git a/tests/src/android/renderscript/cts/fmax_f32_relaxed.rs b/tests/src/android/renderscript/cts/fmax_f32_relaxed.rs
deleted file mode 100644
index 23beccf..0000000
--- a/tests/src/android/renderscript/cts/fmax_f32_relaxed.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "fmax_f32.rs"
-#pragma rs_fp_relaxed
diff --git a/tests/src/android/renderscript/cts/fmin_f32.rs b/tests/src/android/renderscript/cts/fmin_f32.rs
deleted file mode 100644
index 49033f0..0000000
--- a/tests/src/android/renderscript/cts/fmin_f32.rs
+++ /dev/null
@@ -1,38 +0,0 @@
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-typedef struct fmin_f32_in {
-    float first;
-    float second;
-} input1;
-
-void fmin_f32_1(const input1* in, float* out){
-    *out = fmin(in->first, in->second);
-}
-
-typedef struct fmin_f32_2_in {
-    float2 first;
-    float2 second;
-} input2;
-
-void fmin_f32_2(const input2* in, float2* out){
-    *out = fmin(in->first, in->second);
-}
-
-typedef struct fmin_f32_3_in {
-    float3 first;
-    float3 second;
-} input3;
-
-void fmin_f32_3(const input3* in, float3* out){
-    *out = fmin(in->first, in->second);
-}
-
-typedef struct fmin_f32_4_in {
-    float4 first;
-    float4 second;
-} input4;
-
-void fmin_f32_4(const input4* in, float4* out){
-    *out = fmin(in->first, in->second);
-}
diff --git a/tests/src/android/renderscript/cts/fmin_f32_relaxed.rs b/tests/src/android/renderscript/cts/fmin_f32_relaxed.rs
deleted file mode 100644
index 8be4f13..0000000
--- a/tests/src/android/renderscript/cts/fmin_f32_relaxed.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "fmin_f32.rs"
-#pragma rs_fp_relaxed
diff --git a/tests/src/android/renderscript/cts/fmod_f32.rs b/tests/src/android/renderscript/cts/fmod_f32.rs
deleted file mode 100644
index ca8b282..0000000
--- a/tests/src/android/renderscript/cts/fmod_f32.rs
+++ /dev/null
@@ -1,38 +0,0 @@
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-struct fmod_input_f32 {
-    float param1;
-    float param2;
-};
-
-void fmod_f32_1(const struct fmod_input_f32 *in, float *out) {
-    *out = fmod(in->param1, in->param2);
-}
-
-struct fmod_input_f32_2 {
-    float2 param1;
-    float2 param2;
-};
-
-void fmod_f32_2(const struct fmod_input_f32_2 *in, float2 *out) {
-    *out = fmod(in->param1, in->param2);
-}
-
-struct fmod_input_f32_3 {
-    float3 param1;
-    float3 param2;
-};
-
-void fmod_f32_3(const struct fmod_input_f32_3 *in, float3 *out) {
-    *out = fmod(in->param1, in->param2);
-}
-
-struct fmod_input_f32_4 {
-    float4 param1;
-    float4 param2;
-};
-
-void fmod_f32_4(const struct fmod_input_f32_4 *in, float4 *out) {
-    *out = fmod(in->param1, in->param2);
-}
diff --git a/tests/src/android/renderscript/cts/fmod_f32_relaxed.rs b/tests/src/android/renderscript/cts/fmod_f32_relaxed.rs
deleted file mode 100644
index 7a02136..0000000
--- a/tests/src/android/renderscript/cts/fmod_f32_relaxed.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "fmod_f32.rs"
-#pragma rs_fp_relaxed
diff --git a/tests/src/android/renderscript/cts/foreach.rs b/tests/src/android/renderscript/cts/foreach.rs
index 8747961..08e6bed 100644
--- a/tests/src/android/renderscript/cts/foreach.rs
+++ b/tests/src/android/renderscript/cts/foreach.rs
@@ -1,6 +1,5 @@
 #include "shared.rsh"
 
-int *a;
 rs_allocation aRaw;
 int dimX;
 int dimY;
diff --git a/tests/src/android/renderscript/cts/hypot_f32.rs b/tests/src/android/renderscript/cts/hypot_f32.rs
deleted file mode 100644
index 4f9159c..0000000
--- a/tests/src/android/renderscript/cts/hypot_f32.rs
+++ /dev/null
@@ -1,38 +0,0 @@
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-typedef struct hypot_f32_in {
-    float x;
-    float y;
-} hypot_input_f32;
-
-void hypot_f32_1(const hypot_input_f32 *in, float *out) {
-    *out = hypot(in->x, in->y);
-}
-
-typedef struct hypot_f32_2_in {
-    float2 x;
-    float2 y;
-} hypot_input_f32_2;
-
-void hypot_f32_2(const hypot_input_f32_2 *in, float2 *out) {
-    *out = hypot(in->x, in->y);
-}
-
-typedef struct hypot_f32_3_in {
-    float3 x;
-    float3 y;
-} hypot_input_f32_3;
-
-void hypot_f32_3(const hypot_input_f32_3 *in, float3 *out) {
-    *out = hypot(in->x, in->y);
-}
-
-typedef struct hypot_f32_4_in {
-    float4 x;
-    float4 y;
-} hypot_input_f32_4;
-
-void hypot_f32_4(const hypot_input_f32_4 *in, float4 *out) {
-    *out = hypot(in->x, in->y);
-}
diff --git a/tests/src/android/renderscript/cts/hypot_f32_relaxed.rs b/tests/src/android/renderscript/cts/hypot_f32_relaxed.rs
deleted file mode 100644
index 7414788..0000000
--- a/tests/src/android/renderscript/cts/hypot_f32_relaxed.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "hypot_f32.rs"
-#pragma rs_fp_relaxed
diff --git a/tests/src/android/renderscript/cts/intrinsic_3dlut.rs b/tests/src/android/renderscript/cts/intrinsic_3dlut.rs
new file mode 100644
index 0000000..d577b63
--- /dev/null
+++ b/tests/src/android/renderscript/cts/intrinsic_3dlut.rs
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "shared.rsh"
+
+static rs_allocation gCube;
+static int4 gDims;
+static float4 gCoordMul;
+
+void setCube(rs_allocation c) {
+    gCube = c;
+    gDims.x = rsAllocationGetDimX(gCube);
+    gDims.y = rsAllocationGetDimY(gCube);
+    gDims.z = rsAllocationGetDimZ(gCube);
+    gDims.w = 0;
+    gCoordMul = (float4)(1.f / 255.f) * convert_float4(gDims - 1);
+}
+
+uchar4 __attribute__((kernel)) root(uchar4 in) {
+    float4 baseCoord = convert_float4(in) * gCoordMul;
+    int4 coord1 = convert_int4(floor(baseCoord));
+    int4 coord2 = min(coord1 + 1, gDims - 1);
+    float4 f = baseCoord - convert_float4(coord1);
+
+    float4 v000 = convert_float4(rsGetElementAt_uchar4(gCube, coord1.x, coord1.y, coord1.z));
+    float4 v100 = convert_float4(rsGetElementAt_uchar4(gCube, coord2.x, coord1.y, coord1.z));
+    float4 v010 = convert_float4(rsGetElementAt_uchar4(gCube, coord1.x, coord2.y, coord1.z));
+    float4 v110 = convert_float4(rsGetElementAt_uchar4(gCube, coord2.x, coord2.y, coord1.z));
+    float4 v001 = convert_float4(rsGetElementAt_uchar4(gCube, coord1.x, coord1.y, coord2.z));
+    float4 v101 = convert_float4(rsGetElementAt_uchar4(gCube, coord2.x, coord1.y, coord2.z));
+    float4 v011 = convert_float4(rsGetElementAt_uchar4(gCube, coord1.x, coord2.y, coord2.z));
+    float4 v111 = convert_float4(rsGetElementAt_uchar4(gCube, coord2.x, coord2.y, coord2.z));
+
+    float4 yz00 = mix(v000, v100, f.x);
+    float4 yz10 = mix(v010, v110, f.x);
+    float4 yz01 = mix(v001, v101, f.x);
+    float4 yz11 = mix(v011, v111, f.x);
+
+    float4 z0 = mix(yz00, yz10, f.y);
+    float4 z1 = mix(yz01, yz11, f.y);
+
+    float4 v = mix(z0, z1, f.z);
+
+    v = clamp(v, 0.f, 255.f);
+    uchar4 o = convert_uchar4(v + 0.5f);
+    o.w = in.w;
+    return o;
+}
+
diff --git a/tests/src/android/renderscript/cts/intrinsic_blur.rs b/tests/src/android/renderscript/cts/intrinsic_blur.rs
new file mode 100644
index 0000000..88f9ca5
--- /dev/null
+++ b/tests/src/android/renderscript/cts/intrinsic_blur.rs
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "shared.rsh"
+
+int height;
+int width;
+static int radius;
+rs_allocation ScratchPixel1;
+rs_allocation ScratchPixel2;
+
+const int MAX_RADIUS = 25;
+
+// Store our coefficients here
+static float gaussian[MAX_RADIUS * 2 + 1];
+
+float4 __attribute__((kernel)) convert1_uToF(uchar v) {
+    float4 r = rsUnpackColor8888(v);
+    return r.r;
+}
+
+float4 __attribute__((kernel)) convert4_uToF(uchar4 v) {
+    return rsUnpackColor8888(v);
+}
+
+uchar __attribute__((kernel)) convert1_fToU(float4 v) {
+    uchar4 r = rsPackColorTo8888(v);
+    return r.r;
+}
+
+uchar4 __attribute__((kernel)) convert4_fToU(float4 v) {
+    return rsPackColorTo8888(v);
+}
+
+void setRadius(int rad) {
+    // This function is a duplicate of:
+    // RsdCpuScriptIntrinsicBlur::ComputeGaussianWeights()
+    // Which is the reference C implementation
+    radius = rad;
+    const float e = M_E;
+    const float pi = M_PI;
+    float sigma = 0.4f * (float)radius + 0.6f;
+    float coeff1 = 1.0f / (sqrt( 2.0f * pi ) * sigma);
+    float coeff2 = - 1.0f / (2.0f * sigma * sigma);
+    float normalizeFactor = 0.0f;
+    float floatR = 0.0f;
+    for (int r = -radius; r <= radius; r ++) {
+        floatR = (float)r;
+        gaussian[r + radius] = coeff1 * pow(e, floatR * floatR * coeff2);
+        normalizeFactor += gaussian[r + radius];
+    }
+
+    normalizeFactor = 1.0f / normalizeFactor;
+    for (int r = -radius; r <= radius; r ++) {
+        floatR = (float)r;
+        gaussian[r + radius] *= normalizeFactor;
+    }
+}
+
+float4 __attribute__((kernel)) vert(uint32_t x, uint32_t y) {
+    float4 blurredPixel = 0;
+    int gi = 0;
+    for (int r = -radius; r <= radius; r ++) {
+        int validH = rsClamp((int)y + r, (int)0, (int)(height - 1));
+        float4 i = rsGetElementAt_float4(ScratchPixel2, x, validH);
+        blurredPixel += i * gaussian[gi++];
+    }
+    return blurredPixel;
+}
+
+float4 __attribute__((kernel)) horz(uint32_t x, uint32_t y) {
+    float4 blurredPixel = 0;
+    int gi = 0;
+    for (int r = -radius; r <= radius; r ++) {
+        // Stepping left and right away from the pixel
+        int validX = rsClamp((int)x + r, (int)0, (int)(width - 1));
+        float4 i = rsGetElementAt_float4(ScratchPixel1, validX, y);
+        blurredPixel += i * gaussian[gi++];
+    }
+    return blurredPixel;
+}
+
+
diff --git a/tests/src/android/renderscript/cts/log10_f32.rs b/tests/src/android/renderscript/cts/log10_f32.rs
deleted file mode 100644
index dbb5150..0000000
--- a/tests/src/android/renderscript/cts/log10_f32.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-void log10_f32_1 (const float* in, float* out) {
-    *out = log10(*in);
-}
-
-void log10_f32_2 (const float2* in, float2* out) {
-    *out = log10(*in);
-}
-
-void log10_f32_3 (const float3* in, float3* out) {
-    *out = log10(*in);
-}
-
-void log10_f32_4 (const float4* in, float4* out) {
-    *out = log10(*in);
-}
diff --git a/tests/src/android/renderscript/cts/log10_f32_relaxed.rs b/tests/src/android/renderscript/cts/log10_f32_relaxed.rs
deleted file mode 100644
index bedfa6d..0000000
--- a/tests/src/android/renderscript/cts/log10_f32_relaxed.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "log10_f32.rs"
-#pragma rs_fp_relaxed
diff --git a/tests/src/android/renderscript/cts/log1p_f32.rs b/tests/src/android/renderscript/cts/log1p_f32.rs
deleted file mode 100644
index 3c725fe..0000000
--- a/tests/src/android/renderscript/cts/log1p_f32.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-void log1p_f32_1 (const float* in, float* out) {
-    *out = log1p(*in);
-}
-
-void log1p_f32_2 (const float2* in, float2* out) {
-    *out = log1p(*in);
-}
-
-void log1p_f32_3 (const float3* in, float3* out) {
-    *out = log1p(*in);
-}
-
-void log1p_f32_4 (const float4* in, float4* out) {
-    *out = log1p(*in);
-}
diff --git a/tests/src/android/renderscript/cts/log1p_f32_relaxed.rs b/tests/src/android/renderscript/cts/log1p_f32_relaxed.rs
deleted file mode 100644
index c3aed11..0000000
--- a/tests/src/android/renderscript/cts/log1p_f32_relaxed.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "log1p_f32.rs"
-#pragma rs_fp_relaxed
diff --git a/tests/src/android/renderscript/cts/log2_f32.rs b/tests/src/android/renderscript/cts/log2_f32.rs
deleted file mode 100644
index 2ed2b98..0000000
--- a/tests/src/android/renderscript/cts/log2_f32.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-void log2_f32_1 (const float* in, float* out) {
-    *out = log2(*in);
-}
-
-void log2_f32_2 (const float2* in, float2* out) {
-    *out = log2(*in);
-}
-
-void log2_f32_3 (const float3* in, float3* out) {
-    *out = log2(*in);
-}
-
-void log2_f32_4 (const float4* in, float4* out) {
-    *out = log2(*in);
-}
diff --git a/tests/src/android/renderscript/cts/log2_f32_relaxed.rs b/tests/src/android/renderscript/cts/log2_f32_relaxed.rs
deleted file mode 100644
index 7e0883a..0000000
--- a/tests/src/android/renderscript/cts/log2_f32_relaxed.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "log2_f32.rs"
-#pragma rs_fp_relaxed
diff --git a/tests/src/android/renderscript/cts/log_f32.rs b/tests/src/android/renderscript/cts/log_f32.rs
deleted file mode 100644
index 14052a2..0000000
--- a/tests/src/android/renderscript/cts/log_f32.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-void log_f32_1 (const float* in, float* out) {
-    *out = log(*in);
-}
-
-void log_f32_2 (const float2* in, float2* out) {
-    *out = log(*in);
-}
-
-void log_f32_3 (const float3* in, float3* out) {
-    *out = log(*in);
-}
-
-void log_f32_4 (const float4* in, float4* out) {
-    *out = log(*in);
-}
diff --git a/tests/src/android/renderscript/cts/log_f32_relaxed.rs b/tests/src/android/renderscript/cts/log_f32_relaxed.rs
deleted file mode 100644
index d66d3c9..0000000
--- a/tests/src/android/renderscript/cts/log_f32_relaxed.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "log_f32.rs"
-#pragma rs_fp_relaxed
diff --git a/tests/src/android/renderscript/cts/logb_f32.rs b/tests/src/android/renderscript/cts/logb_f32.rs
deleted file mode 100644
index 1b3acfa..0000000
--- a/tests/src/android/renderscript/cts/logb_f32.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-void logb_f32_1 (const float* in, float* out) {
-    *out = logb(*in);
-}
-
-void logb_f32_2 (const float2* in, float2* out) {
-    *out = logb(*in);
-}
-
-void logb_f32_3 (const float3* in, float3* out) {
-    *out = logb(*in);
-}
-
-void logb_f32_4 (const float4* in, float4* out) {
-    *out = logb(*in);
-}
diff --git a/tests/src/android/renderscript/cts/logb_f32_relaxed.rs b/tests/src/android/renderscript/cts/logb_f32_relaxed.rs
deleted file mode 100644
index 9b906dc..0000000
--- a/tests/src/android/renderscript/cts/logb_f32_relaxed.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "logb_f32.rs"
-#pragma rs_fp_relaxed
diff --git a/tests/src/android/renderscript/cts/mad_f32.rs b/tests/src/android/renderscript/cts/mad_f32.rs
deleted file mode 100644
index fc5081b..0000000
--- a/tests/src/android/renderscript/cts/mad_f32.rs
+++ /dev/null
@@ -1,42 +0,0 @@
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-struct mad_input_f32 {
-    float x;
-    float y;
-    float z;
-};
-
-void mad_f32_1(const struct mad_input_f32 *param, float *out) {
-    *out = mad(param->x, param->y, param->z);
-}
-
-struct mad_input_f32_2 {
-    float2 x;
-    float2 y;
-    float2 z;
-};
-
-void mad_f32_2(const struct mad_input_f32_2 *param, float2 *out) {
-    *out = mad(param->x, param->y, param->z);
-}
-
-struct mad_input_f32_3 {
-    float3 x;
-    float3 y;
-    float3 z;
-};
-
-void mad_f32_3(const struct mad_input_f32_3 *param, float3 *out) {
-    *out = mad(param->x, param->y, param->z);
-}
-
-struct mad_input_f32_4 {
-    float4 x;
-    float4 y;
-    float4 z;
-};
-
-void mad_f32_4(const struct mad_input_f32_4 *param, float4 *out) {
-    *out = mad(param->x, param->y, param->z);
-}
diff --git a/tests/src/android/renderscript/cts/mad_f32_relaxed.rs b/tests/src/android/renderscript/cts/mad_f32_relaxed.rs
deleted file mode 100644
index 36d8306..0000000
--- a/tests/src/android/renderscript/cts/mad_f32_relaxed.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "mad_f32.rs"
-#pragma rs_fp_relaxed
diff --git a/tests/src/android/renderscript/cts/nextafter_f32.rs b/tests/src/android/renderscript/cts/nextafter_f32.rs
deleted file mode 100644
index 04ce73a4..0000000
--- a/tests/src/android/renderscript/cts/nextafter_f32.rs
+++ /dev/null
@@ -1,38 +0,0 @@
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-typedef struct InputData {
-    float a;
-    float b;
-} InputData;
-
-void nextafter_f32_1(const InputData *in, float *out) {
-    *out = nextafter (in->a, in->b);
-}
-
-typedef struct InputData_2 {
-    float2 a;
-    float2 b;
-} InputData_2;
-
-void nextafter_f32_2(const InputData_2 *in, float2 *out) {
-    *out = nextafter (in->a, in->b);
-}
-
-typedef struct InputData_3 {
-    float3 a;
-    float3 b;
-} InputData_3;
-
-void nextafter_f32_3(const InputData_3 *in, float3 *out) {
-    *out = nextafter (in->a, in->b);
-}
-
-typedef struct InputData_4 {
-    float4 a;
-    float4 b;
-} InputData_4;
-
-void nextafter_f32_4(const InputData_4 *in, float4 *out) {
-    *out = nextafter (in->a, in->b);
-}
diff --git a/tests/src/android/renderscript/cts/nextafter_f32_relaxed.rs b/tests/src/android/renderscript/cts/nextafter_f32_relaxed.rs
deleted file mode 100644
index 5c6edd5..0000000
--- a/tests/src/android/renderscript/cts/nextafter_f32_relaxed.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "nextafter_f32.rs"
-#pragma rs_fp_relaxed
diff --git a/tests/src/android/renderscript/cts/pow_f32.rs b/tests/src/android/renderscript/cts/pow_f32.rs
deleted file mode 100644
index 426d4b1..0000000
--- a/tests/src/android/renderscript/cts/pow_f32.rs
+++ /dev/null
@@ -1,38 +0,0 @@
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-typedef struct PowInputData {
-    float base;
-    float expo;
-} PowInputData;
-
-void pow_f32_1(const PowInputData *in, float *out) {
-    *out = pow(in->base, in->expo);
-}
-
-typedef struct PowInputData_2 {
-    float2 base;
-    float2 expo;
-} PowInputData_2;
-
-void pow_f32_2(const PowInputData_2 *in, float2 *out) {
-    *out = pow(in->base, in->expo);
-}
-
-typedef struct PowInputData_3 {
-    float3 base;
-    float3 expo;
-} PowInputData_3;
-
-void pow_f32_3(const PowInputData_3 *in, float3 *out) {
-    *out = pow(in->base, in->expo);
-}
-
-typedef struct PowInputData_4 {
-    float4 base;
-    float4 expo;
-} PowInputData_4;
-
-void pow_f32_4(const PowInputData_4 *in, float4 *out) {
-    *out = pow(in->base, in->expo);
-}
diff --git a/tests/src/android/renderscript/cts/pow_f32_relaxed.rs b/tests/src/android/renderscript/cts/pow_f32_relaxed.rs
deleted file mode 100644
index 5da7048..0000000
--- a/tests/src/android/renderscript/cts/pow_f32_relaxed.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "pow_f32.rs"
-#pragma rs_fp_relaxed
diff --git a/tests/src/android/renderscript/cts/pown_f32.rs b/tests/src/android/renderscript/cts/pown_f32.rs
deleted file mode 100644
index fa066d0..0000000
--- a/tests/src/android/renderscript/cts/pown_f32.rs
+++ /dev/null
@@ -1,26 +0,0 @@
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-rs_allocation n1;
-
-void pown_f32_1(const float *in, float *out, uint32_t x) {
-    *out = pown(*in, *(int *)rsGetElementAt(n1,x));
-}
-
-rs_allocation n2;
-
-void pown_f32_2(const float2 *in, float2 *out, uint32_t x) {
-    *out = pown(*in, *(int2 *)rsGetElementAt(n2,x));
-}
-
-rs_allocation n3;
-
-void pown_f32_3(const float3 *in, float3 *out, uint32_t x) {
-    *out = pown(*in, *(int3 *)rsGetElementAt(n3,x));
-}
-
-rs_allocation n4;
-
-void pown_f32_4(const float4 *in, float4 *out, uint32_t x) {
-    *out = pown(*in, *(int4 *)rsGetElementAt(n4,x));
-}
diff --git a/tests/src/android/renderscript/cts/pown_f32_relaxed.rs b/tests/src/android/renderscript/cts/pown_f32_relaxed.rs
deleted file mode 100644
index bdc4b47..0000000
--- a/tests/src/android/renderscript/cts/pown_f32_relaxed.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "pown_f32.rs"
-#pragma rs_fp_relaxed
diff --git a/tests/src/android/renderscript/cts/powr_f32.rs b/tests/src/android/renderscript/cts/powr_f32.rs
deleted file mode 100644
index 6eb36b0..0000000
--- a/tests/src/android/renderscript/cts/powr_f32.rs
+++ /dev/null
@@ -1,38 +0,0 @@
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-typedef struct PowInputData {
-    float base;
-    float expo;
-} PowInputData;
-
-void powr_f32_1(const PowInputData *in, float *out) {
-    *out = powr(in->base, in->expo);
-}
-
-typedef struct PowInputData_2 {
-    float2 base;
-    float2 expo;
-} PowInputData_2;
-
-void powr_f32_2(const PowInputData_2 *in, float2 *out) {
-    *out = powr(in->base, in->expo);
-}
-
-typedef struct PowInputData_3 {
-    float3 base;
-    float3 expo;
-} PowInputData_3;
-
-void powr_f32_3(const PowInputData_3 *in, float3 *out) {
-    *out = powr(in->base, in->expo);
-}
-
-typedef struct PowInputData_4 {
-    float4 base;
-    float4 expo;
-} PowInputData_4;
-
-void powr_f32_4(const PowInputData_4 *in, float4 *out) {
-    *out = powr(in->base, in->expo);
-}
diff --git a/tests/src/android/renderscript/cts/powr_f32_relaxed.rs b/tests/src/android/renderscript/cts/powr_f32_relaxed.rs
deleted file mode 100644
index b8690af..0000000
--- a/tests/src/android/renderscript/cts/powr_f32_relaxed.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "powr_f32.rs"
-#pragma rs_fp_relaxed
diff --git a/tests/src/android/renderscript/cts/radians_f32.rs b/tests/src/android/renderscript/cts/radians_f32.rs
deleted file mode 100644
index 1aa743e..0000000
--- a/tests/src/android/renderscript/cts/radians_f32.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-void radians_f32_1(const float* in, float* out) {
-    *out = radians (*in);
-}
-
-void radians_f32_2(const float2* in, float2* out) {
-    *out = radians(*in);
-}
-
-void radians_f32_3(const float3* in, float3* out) {
-    *out = radians(*in);
-}
-
-void radians_f32_4(const float4* in, float4* out) {
-    *out = radians(*in);
-}
diff --git a/tests/src/android/renderscript/cts/radians_f32_relaxed.rs b/tests/src/android/renderscript/cts/radians_f32_relaxed.rs
deleted file mode 100644
index 4ab3070..0000000
--- a/tests/src/android/renderscript/cts/radians_f32_relaxed.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "radians_f32.rs"
-#pragma rs_fp_relaxed
diff --git a/tests/src/android/renderscript/cts/remainder_f32.rs b/tests/src/android/renderscript/cts/remainder_f32.rs
deleted file mode 100644
index d08a034..0000000
--- a/tests/src/android/renderscript/cts/remainder_f32.rs
+++ /dev/null
@@ -1,38 +0,0 @@
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-struct remainder_f32 {
-    float num;
-    float den;
-};
-
-void remainder_f32_1 (const struct remainder_f32* in, float* out) {
-    *out = remainder(in->num, in->den);
-}
-
-struct remainder_f32_2 {
-    float2 num;
-    float2 den;
-};
-
-void remainder_f32_2 (const struct remainder_f32_2* in, float2* out) {
-    *out = remainder(in->num, in->den);
-}
-
-struct remainder_f32_3 {
-    float3 num;
-    float3 den;
-};
-
-void remainder_f32_3 (const struct remainder_f32_3* in, float3* out) {
-    *out = remainder(in->num, in->den);
-}
-
-struct remainder_f32_4 {
-    float4 num;
-    float4 den;
-};
-
-void remainder_f32_4 (const struct remainder_f32_4* in, float4* out) {
-    *out = remainder(in->num, in->den);
-}
diff --git a/tests/src/android/renderscript/cts/remainder_f32_relaxed.rs b/tests/src/android/renderscript/cts/remainder_f32_relaxed.rs
deleted file mode 100644
index d546e50..0000000
--- a/tests/src/android/renderscript/cts/remainder_f32_relaxed.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "remainder_f32.rs"
-#pragma rs_fp_relaxed
diff --git a/tests/src/android/renderscript/cts/rint_f32.rs b/tests/src/android/renderscript/cts/rint_f32.rs
deleted file mode 100644
index 46ef8b1..0000000
--- a/tests/src/android/renderscript/cts/rint_f32.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-void rint_f32_1 (const float* in, float* out) {
-    *out = rint(*in);
-}
-
-void rint_f32_2 (const float2* in, float2* out) {
-    *out = rint(*in);
-}
-
-void rint_f32_3 (const float3* in, float3* out) {
-    *out = rint(*in);
-}
-
-void rint_f32_4 (const float4* in, float4* out) {
-    *out = rint(*in);
-}
diff --git a/tests/src/android/renderscript/cts/rint_f32_relaxed.rs b/tests/src/android/renderscript/cts/rint_f32_relaxed.rs
deleted file mode 100644
index e9b4950..0000000
--- a/tests/src/android/renderscript/cts/rint_f32_relaxed.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "rint_f32.rs"
-#pragma rs_fp_relaxed
diff --git a/tests/src/android/renderscript/cts/rootn_f32.rs b/tests/src/android/renderscript/cts/rootn_f32.rs
deleted file mode 100644
index 1c60ea9..0000000
--- a/tests/src/android/renderscript/cts/rootn_f32.rs
+++ /dev/null
@@ -1,26 +0,0 @@
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-rs_allocation n1;
-
-void rootn_f32_1(const float *in, float *out, uint32_t x) {
-    *out = rootn(*in, *(int *)rsGetElementAt(n1,x));
-}
-
-rs_allocation n2;
-
-void rootn_f32_2(const float2 *in, float2 *out, uint32_t x) {
-    *out = rootn(*in, *(int2 *)rsGetElementAt(n2,x));
-}
-
-rs_allocation n3;
-
-void rootn_f32_3(const float3 *in, float3 *out, uint32_t x) {
-    *out = rootn(*in, *(int3 *)rsGetElementAt(n3,x));
-}
-
-rs_allocation n4;
-
-void rootn_f32_4(const float4 *in, float4 *out, uint32_t x) {
-    *out = rootn(*in, *(int4 *)rsGetElementAt(n4,x));
-}
diff --git a/tests/src/android/renderscript/cts/rootn_f32_relaxed.rs b/tests/src/android/renderscript/cts/rootn_f32_relaxed.rs
deleted file mode 100644
index f6509ae..0000000
--- a/tests/src/android/renderscript/cts/rootn_f32_relaxed.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "rootn_f32.rs"
-#pragma rs_fp_relaxed
diff --git a/tests/src/android/renderscript/cts/round_f32.rs b/tests/src/android/renderscript/cts/round_f32.rs
deleted file mode 100644
index 60b5e8d..0000000
--- a/tests/src/android/renderscript/cts/round_f32.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-void round_f32_1 (const float* in, float* out) {
-    *out = round(*in);
-}
-
-void round_f32_2 (const float2* in , float2* out) {
-    *out = round(*in);
-}
-
-void round_f32_3 (const float3* in, float3* out) {
-    *out = round(*in);
-}
-
-void round_f32_4 (const float4* in , float4* out) {
-    *out = round(*in);
-}
diff --git a/tests/src/android/renderscript/cts/round_f32_relaxed.rs b/tests/src/android/renderscript/cts/round_f32_relaxed.rs
deleted file mode 100644
index 026515e..0000000
--- a/tests/src/android/renderscript/cts/round_f32_relaxed.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "round_f32.rs"
-#pragma rs_fp_relaxed
diff --git a/tests/src/android/renderscript/cts/rsqrt_f32.rs b/tests/src/android/renderscript/cts/rsqrt_f32.rs
deleted file mode 100644
index 1e8f5a2..0000000
--- a/tests/src/android/renderscript/cts/rsqrt_f32.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-void Rsqrt_f32_1 (const float* in, float* out) {
-    *out = rsqrt(*in);
-}
-
-void Rsqrt_f32_2 (const float2* in, float2* out) {
-    *out = rsqrt(*in);
-}
-
-void Rsqrt_f32_3 (const float3* in, float3* out) {
-    *out = rsqrt(*in);
-}
-
-void Rsqrt_f32_4 (const float4* in, float4* out) {
-    *out = rsqrt(*in);
-}
diff --git a/tests/src/android/renderscript/cts/rsqrt_f32_relaxed.rs b/tests/src/android/renderscript/cts/rsqrt_f32_relaxed.rs
deleted file mode 100644
index 1d7c08b..0000000
--- a/tests/src/android/renderscript/cts/rsqrt_f32_relaxed.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "rsqrt_f32.rs"
-#pragma rs_fp_relaxed
diff --git a/tests/src/android/renderscript/cts/sample.rs b/tests/src/android/renderscript/cts/sample.rs
index 7a8d5bb..64fb262 100644
--- a/tests/src/android/renderscript/cts/sample.rs
+++ b/tests/src/android/renderscript/cts/sample.rs
@@ -8,46 +8,11 @@
 rs_sampler gMipNearest;
 rs_sampler gMipLinear;
 
-uint8_t *gAllocPtr;
-
 static uchar4 lod0Color = {255, 255, 0, 0};
 static uchar4 lod1Color = {255, 0, 255, 0};
 static uchar4 lod2Color = {0, 255, 255, 0};
 static uchar4 lod3Color = {255, 255, 255, 0};
 
-// Allocation has been bound to gAllocPtr
-void init_RGBA(rs_allocation a) {
-    // Fill base level with one color, mips with something else
-    uchar4 *allocPtr = (uchar4*)gAllocPtr;
-    uint32_t dimX = rsAllocationGetDimX(a);
-    uint32_t dimY = rsAllocationGetDimY(a);
-    uint32_t minSize = 1;
-    dimX = max(dimX, minSize);
-    dimY = max(dimY, minSize);
-
-    uint32_t numPixels = dimX * dimY;
-    for (uint32_t i = 0; i < numPixels; i ++) {
-        (*allocPtr++) = lod0Color;
-    }
-    dimX = max(dimX >> 1, minSize);
-    dimY = max(dimY >> 1, minSize);
-    numPixels = dimX * dimY;
-    for (uint32_t i = 0; i < numPixels; i ++) {
-        (*allocPtr++) = lod1Color;
-    }
-    dimX = max(dimX >> 1, minSize);
-    dimY = max(dimY >> 1, minSize);
-    numPixels = dimX * dimY;
-    for (uint32_t i = 0; i < numPixels; i ++) {
-        (*allocPtr++) = lod2Color;
-    }
-    dimX = max(dimX >> 1, minSize);
-    dimY = max(dimY >> 1, minSize);
-    numPixels = dimX * dimY;
-    for (uint32_t i = 0; i < numPixels; i ++) {
-        (*allocPtr++) = lod3Color;
-    }
-}
 
 static bool compare(float4 expected, float4 value) {
     float allowedDelta = 10.0f;
diff --git a/tests/src/android/renderscript/cts/sign_f32.rs b/tests/src/android/renderscript/cts/sign_f32.rs
deleted file mode 100644
index f9edb90..0000000
--- a/tests/src/android/renderscript/cts/sign_f32.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-void sign_f32_1(const float *in, float *out) {
-    *out = sign (*in);
-}
-
-void sign_f32_2(const float2 *in, float2 *out) {
-    *out = sign (*in);
-}
-
-void sign_f32_3(const float3 *in, float3 *out) {
-    *out = sign (*in);
-}
-
-void sign_f32_4(const float4 *in, float4 *out) {
-    *out = sign (*in);
-}
diff --git a/tests/src/android/renderscript/cts/sign_f32_relaxed.rs b/tests/src/android/renderscript/cts/sign_f32_relaxed.rs
deleted file mode 100644
index 2ea41e2..0000000
--- a/tests/src/android/renderscript/cts/sign_f32_relaxed.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "sign_f32.rs"
-#pragma rs_fp_relaxed
diff --git a/tests/src/android/renderscript/cts/sin_f32.rs b/tests/src/android/renderscript/cts/sin_f32.rs
deleted file mode 100644
index 91652bb..0000000
--- a/tests/src/android/renderscript/cts/sin_f32.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-void sin_f32_1(const float *in, float *out) {
-    *out = sin(*in);
-}
-
-void sin_f32_2(const float2 *in, float2 *out) {
-    *out = sin(*in);
-}
-
-void sin_f32_3(const float3 *in, float3 *out) {
-    *out = sin(*in);
-}
-
-void sin_f32_4(const float4 *in, float4 *out) {
-    *out = sin(*in);
-}
diff --git a/tests/src/android/renderscript/cts/sin_f32_relaxed.rs b/tests/src/android/renderscript/cts/sin_f32_relaxed.rs
deleted file mode 100644
index 1ebf69e..0000000
--- a/tests/src/android/renderscript/cts/sin_f32_relaxed.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "sin_f32.rs"
-#pragma rs_fp_relaxed
diff --git a/tests/src/android/renderscript/cts/sinh_f32.rs b/tests/src/android/renderscript/cts/sinh_f32.rs
deleted file mode 100644
index b785399..0000000
--- a/tests/src/android/renderscript/cts/sinh_f32.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-void sinh_f32_1(const float *in, float *out) {
-    *out = sinh(*in);
-}
-
-void sinh_f32_2(const float2 *in, float2 *out) {
-    *out = sinh(*in);
-}
-
-void sinh_f32_3(const float3 *in, float3 *out) {
-    *out = sinh(*in);
-}
-
-void sinh_f32_4(const float4 *in, float4 *out) {
-    *out = sinh(*in);
-}
diff --git a/tests/src/android/renderscript/cts/sinh_f32_relaxed.rs b/tests/src/android/renderscript/cts/sinh_f32_relaxed.rs
deleted file mode 100644
index ba1d5c7..0000000
--- a/tests/src/android/renderscript/cts/sinh_f32_relaxed.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "sinh_f32.rs"
-#pragma rs_fp_relaxed
diff --git a/tests/src/android/renderscript/cts/sqrt_f32.rs b/tests/src/android/renderscript/cts/sqrt_f32.rs
deleted file mode 100644
index 253f1c0..0000000
--- a/tests/src/android/renderscript/cts/sqrt_f32.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-void sqrt_f32_1 (const float* in, float* out) {
-    *out = sqrt(*in);
-}
-
-void sqrt_f32_2 (const float2* in, float2* out) {
-    *out = sqrt(*in);
-}
-
-void sqrt_f32_3 (const float3* in, float3* out) {
-    *out = sqrt(*in);
-}
-
-void sqrt_f32_4 (const float4* in, float4* out) {
-    *out = sqrt(*in);
-}
diff --git a/tests/src/android/renderscript/cts/sqrt_f32_relaxed.rs b/tests/src/android/renderscript/cts/sqrt_f32_relaxed.rs
deleted file mode 100644
index 460ea63..0000000
--- a/tests/src/android/renderscript/cts/sqrt_f32_relaxed.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "sqrt_f32.rs"
-#pragma rs_fp_relaxed
diff --git a/tests/src/android/renderscript/cts/step_f32.rs b/tests/src/android/renderscript/cts/step_f32.rs
deleted file mode 100644
index d2261b3..0000000
--- a/tests/src/android/renderscript/cts/step_f32.rs
+++ /dev/null
@@ -1,38 +0,0 @@
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-struct step_input {
-    float x;
-    float y;
-};
-
-void step_f32_1(const struct step_input *in, float *out) {
-    *out = step(in->x, in->y);
-}
-
-struct step_2_input {
-    float2 x;
-    float2 y;
-};
-
-void step_f32_2(const struct step_2_input *in, float2 *out) {
-    *out = step(in->x, in->y);
-}
-
-struct step_3_input {
-    float3 x;
-    float3 y;
-};
-
-void step_f32_3(const struct step_3_input *in, float3 *out) {
-    *out = step(in->x, in->y);
-}
-
-struct step_4_input {
-    float4 x;
-    float4 y;
-};
-
-void step_f32_4(const struct step_4_input *in, float4 *out) {
-    *out = step(in->x, in->y);
-}
diff --git a/tests/src/android/renderscript/cts/step_f32_relaxed.rs b/tests/src/android/renderscript/cts/step_f32_relaxed.rs
deleted file mode 100644
index c59b548..0000000
--- a/tests/src/android/renderscript/cts/step_f32_relaxed.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "step_f32.rs"
-#pragma rs_fp_relaxed
diff --git a/tests/src/android/renderscript/cts/tan_f32.rs b/tests/src/android/renderscript/cts/tan_f32.rs
deleted file mode 100644
index 35ee971..0000000
--- a/tests/src/android/renderscript/cts/tan_f32.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-void tan_f32_1(const float *in, float *out) {
-    *out = tan(*in);
-}
-
-void tan_f32_2(const float2 *in, float2 *out) {
-    *out = tan(*in);
-}
-
-void tan_f32_3(const float3 *in, float3 *out) {
-    *out = tan(*in);
-}
-
-void tan_f32_4(const float4 *in, float4 *out) {
-    *out = tan(*in);
-}
diff --git a/tests/src/android/renderscript/cts/tan_f32_relaxed.rs b/tests/src/android/renderscript/cts/tan_f32_relaxed.rs
deleted file mode 100644
index adf98f0..0000000
--- a/tests/src/android/renderscript/cts/tan_f32_relaxed.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "tan_f32.rs"
-#pragma rs_fp_relaxed
diff --git a/tests/src/android/renderscript/cts/tanh_f32.rs b/tests/src/android/renderscript/cts/tanh_f32.rs
deleted file mode 100644
index 2b0782e..0000000
--- a/tests/src/android/renderscript/cts/tanh_f32.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-void tanh_f32_1(const float *in, float *out) {
-    *out = tanh(*in);
-}
-
-void tanh_f32_2(const float2 *in, float2 *out) {
-    *out = tanh(*in);
-}
-
-void tanh_f32_3(const float3 *in, float3 *out) {
-    *out = tanh(*in);
-}
-
-void tanh_f32_4(const float4 *in, float4 *out) {
-    *out = tanh(*in);
-}
diff --git a/tests/src/android/renderscript/cts/tanh_f32_relaxed.rs b/tests/src/android/renderscript/cts/tanh_f32_relaxed.rs
deleted file mode 100644
index 2d7463b..0000000
--- a/tests/src/android/renderscript/cts/tanh_f32_relaxed.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "tanh_f32.rs"
-#pragma rs_fp_relaxed
diff --git a/tests/src/android/renderscript/cts/trunc_f32.rs b/tests/src/android/renderscript/cts/trunc_f32.rs
deleted file mode 100644
index a464086..0000000
--- a/tests/src/android/renderscript/cts/trunc_f32.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-void trunc_f32_1 (const float* in, float* out) {
-    *out = trunc(*in);
-}
-
-void trunc_f32_2 (const float2* in, float2* out) {
-    *out = trunc(*in);
-}
-
-void trunc_f32_3 (const float3* in, float3* out) {
-    *out = trunc(*in);
-}
-
-void trunc_f32_4 (const float4* in, float4* out) {
-    *out = trunc(*in);
-}
diff --git a/tests/src/android/renderscript/cts/trunc_f32_relaxed.rs b/tests/src/android/renderscript/cts/trunc_f32_relaxed.rs
deleted file mode 100644
index f55c8b3..0000000
--- a/tests/src/android/renderscript/cts/trunc_f32_relaxed.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "trunc_f32.rs"
-#pragma rs_fp_relaxed
diff --git a/tests/tests/app/src/android/app/cts/DialogTest.java b/tests/tests/app/src/android/app/cts/DialogTest.java
index 4f2e197..f0d00ba 100644
--- a/tests/tests/app/src/android/app/cts/DialogTest.java
+++ b/tests/tests/app/src/android/app/cts/DialogTest.java
@@ -812,11 +812,9 @@
         assertTrue(d.isShowing());
         assertFalse(mCalledCallback);
         dialogDismiss(d);
-        Thread.sleep(SLEEP_TIME);
+        ht.join(100);
         assertTrue(mCalledCallback);
         assertFalse(d.isShowing());
-
-        ht.join(100);
     }
 
     private void dialogDismiss(final Dialog d) throws Throwable {
diff --git a/tests/tests/bionic/Android.mk b/tests/tests/bionic/Android.mk
index 326fd56..1a048c6 100644
--- a/tests/tests/bionic/Android.mk
+++ b/tests/tests/bionic/Android.mk
@@ -1,6 +1,7 @@
 LOCAL_PATH := $(call my-dir)
 
 test_executable := bionic-unit-tests-cts
+list_executable := $(test_executable)_list
 
 include $(CLEAR_VARS)
 
@@ -24,3 +25,25 @@
 
 LOCAL_CTS_TEST_PACKAGE := android.bionic
 include $(BUILD_CTS_EXECUTABLE)
+
+ifeq ($(HOST_OS)-$(HOST_ARCH),$(filter $(HOST_OS)-$(HOST_ARCH),linux-x86 linux-x86_64))
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE := $(list_executable)
+
+LOCAL_ADDITION_DEPENDENCIES := \
+    $(LOCAL_PATH)/Android.mk \
+
+# A main without the extra output from the gtest main.
+LOCAL_SRC_FILES := \
+    main.cpp \
+
+LOCAL_LDLIBS += \
+    -lrt \
+
+LOCAL_WHOLE_STATIC_LIBRARIES += \
+    libBionicTests \
+
+include $(BUILD_HOST_NATIVE_TEST)
+endif  # ifeq ($(HOST_OS)-$(HOST_ARCH),$(filter $(HOST_OS)-$(HOST_ARCH),linux-x86 linux-x86_64))
diff --git a/tests/tests/bionic/bionic-unit-tests-cts_list.txt b/tests/tests/bionic/bionic-unit-tests-cts_list.txt
deleted file mode 100644
index 370bb9e..0000000
--- a/tests/tests/bionic/bionic-unit-tests-cts_list.txt
+++ /dev/null
@@ -1,576 +0,0 @@
-Fortify1_Gcc_DeathTest.
-  strcpy_fortified
-  strcpy2_fortified
-  strcpy3_fortified
-  strcpy4_fortified
-  strlen_fortified
-  strchr_fortified
-  strrchr_fortified
-  strlcpy_fortified
-  strlcat_fortified
-  sprintf_fortified
-  sprintf2_fortified
-  vsprintf_fortified
-  vsprintf2_fortified
-  vsnprintf_fortified
-  vsnprintf2_fortified
-  strncat_fortified
-  strncat2_fortified
-  strcat_fortified
-  memmove_fortified
-  memcpy_fortified
-  strncpy_fortified
-  snprintf_fortified
-  bzero_fortified
-  umask_fortified
-Fortify2_Gcc_DeathTest.
-  strncpy_fortified2
-  sprintf_fortified2
-  sprintf2_fortified2
-  vsprintf_fortified2
-  vsprintf2_fortified2
-  vsnprintf_fortified2
-  vsnprintf2_fortified2
-  strcpy_fortified2
-  strcpy2_fortified2
-  strcpy3_fortified2
-  strchr_fortified2
-  strrchr_fortified2
-  strlcpy_fortified2
-  strlcat_fortified2
-  strncat_fortified2
-  strncat2_fortified2
-  strncat3_fortified2
-  strcat_fortified2
-  strcat2_fortified2
-  snprintf_fortified2
-  bzero_fortified2
-  strcpy_fortified
-  strcpy2_fortified
-  strcpy3_fortified
-  strcpy4_fortified
-  strlen_fortified
-  strchr_fortified
-  strrchr_fortified
-  strlcpy_fortified
-  strlcat_fortified
-  sprintf_fortified
-  sprintf2_fortified
-  vsprintf_fortified
-  vsprintf2_fortified
-  vsnprintf_fortified
-  vsnprintf2_fortified
-  strncat_fortified
-  strncat2_fortified
-  strcat_fortified
-  memmove_fortified
-  memcpy_fortified
-  strncpy_fortified
-  snprintf_fortified
-  bzero_fortified
-  umask_fortified
-Fortify1_Clang_DeathTest.
-  strcpy_fortified
-  strcpy2_fortified
-  strcpy3_fortified
-  strcpy4_fortified
-  strlen_fortified
-  strchr_fortified
-  strrchr_fortified
-  strlcpy_fortified
-  strlcat_fortified
-  sprintf_fortified
-  sprintf2_fortified
-  vsprintf_fortified
-  vsprintf2_fortified
-  vsnprintf_fortified
-  vsnprintf2_fortified
-  strncat_fortified
-  strncat2_fortified
-  strcat_fortified
-  memmove_fortified
-  memcpy_fortified
-  strncpy_fortified
-  snprintf_fortified
-  bzero_fortified
-  umask_fortified
-Fortify2_Clang_DeathTest.
-  strncat3_fortified2
-  strcat2_fortified2
-  snprintf_fortified2
-  bzero_fortified2
-  strcpy_fortified
-  strcpy2_fortified
-  strcpy3_fortified
-  strcpy4_fortified
-  strlen_fortified
-  strchr_fortified
-  strrchr_fortified
-  strlcpy_fortified
-  strlcat_fortified
-  sprintf_fortified
-  sprintf2_fortified
-  vsprintf_fortified
-  vsprintf2_fortified
-  vsnprintf_fortified
-  vsnprintf2_fortified
-  strncat_fortified
-  strncat2_fortified
-  strcat_fortified
-  memmove_fortified
-  memcpy_fortified
-  strncpy_fortified
-  snprintf_fortified
-  bzero_fortified
-  umask_fortified
-pthread_DeathTest.
-  pthread_bug_37410
-stack_protector_DeathTest.
-  modify_stack_protector
-properties_DeathTest.
-  read_only
-Fortify1_Gcc.
-  strncat
-  strncat2
-  strncat3
-  strncat4
-  strncat5
-  strncat6
-  strcat
-  strcat2
-  strcat_chk_max_int_size
-  strcpy_chk_max_int_size
-  memcpy_chk_max_int_size
-Fortify2_Gcc.
-  strncat
-  strncat2
-  strncat3
-  strncat4
-  strncat5
-  strncat6
-  strcat
-  strcat2
-  strcat_chk_max_int_size
-  strcpy_chk_max_int_size
-  memcpy_chk_max_int_size
-Fortify1_Clang.
-  strncat
-  strncat2
-  strncat3
-  strncat4
-  strncat5
-  strncat6
-  strcat
-  strcat2
-  strcat_chk_max_int_size
-  strcpy_chk_max_int_size
-  memcpy_chk_max_int_size
-Fortify2_Clang.
-  strncat
-  strncat2
-  strncat3
-  strncat4
-  strncat5
-  strncat6
-  strcat
-  strcat2
-  strcat_chk_max_int_size
-  strcpy_chk_max_int_size
-  memcpy_chk_max_int_size
-dirent.
-  scandir
-  fdopendir_invalid
-  fdopendir
-  opendir_invalid
-  opendir
-  closedir_invalid
-  closedir
-  readdir
-  readdir_r
-  rewinddir
-eventfd.
-  smoke
-fenv.
-  fesetround_fegetround_FE_TONEAREST
-  fesetround_fegetround_FE_TOWARDZERO
-  fesetround_fegetround_FE_UPWARD
-  fesetround_fegetround_FE_DOWNWARD
-  feclearexcept_fetestexcept
-  FE_DFL_ENV_macro
-getauxval.
-  expected_values
-  unexpected_values
-getcwd.
-  auto_full
-  auto_reasonable
-  auto_too_small
-  auto_too_large
-  manual_too_small
-  manual_zero
-  manual_path_max
-inttypes.
-  misc
-libc_logging.
-  smoke
-  d_INT_MAX
-  d_INT_MIN
-  ld_LONG_MAX
-  ld_LONG_MIN
-  lld_LLONG_MAX
-  lld_LLONG_MIN
-libgen.
-  basename
-  dirname
-  basename_r
-  dirname_r
-malloc.
-  malloc_std
-  calloc_std
-  memalign_multiple
-  memalign_realloc
-  malloc_realloc_larger
-  malloc_realloc_smaller
-  malloc_multiple_realloc
-  calloc_realloc_larger
-  calloc_realloc_smaller
-  calloc_multiple_realloc
-math.
-  fpclassify
-  isinf
-  isnan
-  isnormal
-  __fpclassifyd
-  __fpclassifyf
-  __fpclassifyl
-  finitef
-  __isfinite
-  __isfinitef
-  __isfinitel
-  finite
-  __isinff
-  __isinfl
-  __isnanf
-  __isnanl
-  isnanf
-  __isnormal
-  __isnormalf
-  __isnormall
-  __signbit
-  __signbitf
-  __signbitl
-  acos
-  acosf
-  acosl
-  asin
-  asinf
-  asinl
-  atan
-  atanf
-  atanl
-  atan2
-  atan2f
-  atan2l
-  cos
-  cosf
-  cosl
-  sin
-  sinf
-  sinl
-  tan
-  tanf
-  tanl
-  acosh
-  acoshf
-  acoshl
-  asinh
-  asinhf
-  asinhl
-  atanh
-  atanhf
-  atanhl
-  cosh
-  coshf
-  coshl
-  sinh
-  sinhf
-  sinhl
-  tanh
-  tanhf
-  tanhl
-  log
-  logf
-  logl
-  log2
-  log2f
-  log2l
-  log10
-  log10f
-  log10l
-  cbrt
-  cbrtf
-  cbrtl
-  sqrt
-  sqrtf
-  sqrtl
-  exp
-  expf
-  expl
-  exp2
-  exp2f
-  exp2l
-  expm1
-  expm1f
-  expm1l
-  pow
-  powf
-  powl
-  ceil
-  ceilf
-  ceill
-  floor
-  floorf
-  floorl
-  fabs
-  fabsf
-  fabsl
-  ldexp
-  ldexpf
-  ldexpl
-  fmod
-  fmodf
-  fmodl
-  remainder
-  remainderf
-  remainderl
-  drem
-  dremf
-  fmax
-  fmaxf
-  fmaxl
-  fmin
-  fminf
-  fminl
-  fma
-  fmaf
-  fmal
-  hypot
-  hypotf
-  hypotl
-  erf
-  erff
-  erfl
-  erfc
-  erfcf
-  erfcl
-  lrint
-  rint
-  nearbyint
-  lround
-  llround
-  ilogb
-  ilogbf
-  ilogbl
-  logb
-  logbf
-  logbl
-  log1p
-  log1pf
-  log1pl
-  fdim
-  fdimf
-  fdiml
-  round
-  roundf
-  roundl
-  trunc
-  truncf
-  truncl
-  nextafter
-  nextafterf
-  nextafterl
-  copysign
-  copysignf
-  copysignl
-  significand
-  significandf
-  significandl
-  scalb
-  scalbf
-  scalbln
-  scalblnf
-  scalblnl
-  scalbn
-  scalbnf
-  scalbnl
-  gamma
-  gammaf
-  gamma_r
-  gammaf_r
-  lgamma
-  lgammaf
-  lgammal
-  lgamma_r
-  lgammaf_r
-  tgamma
-  tgammaf
-  tgammal
-  j0
-  j0f
-  j1
-  j1f
-  jn
-  jnf
-  y0
-  y0f
-  y1
-  y1f
-  yn
-  ynf
-  frexp
-  frexpf
-  frexpl
-  modf
-  modff
-  modfl
-  remquo
-  remquof
-  remquol
-  frexpf_public_bug_6697
-netdb.
-  getaddrinfo_NULL_hints
-  getnameinfo_salen
-pthread.
-  pthread_key_create
-  pthread_key_create_lots
-  pthread_create
-  pthread_create_EAGAIN
-  pthread_no_join_after_detach
-  pthread_no_op_detach_after_join
-  pthread_join_self
-  pthread_sigmask
-  __bionic_clone
-  pthread_setname_np__too_long
-  pthread_setname_np__self
-  pthread_setname_np__other
-  pthread_setname_np__no_such_thread
-  pthread_kill__0
-  pthread_kill__invalid_signal
-  pthread_kill__in_signal_handler
-  pthread_detach__no_such_thread
-  pthread_getcpuclockid__clock_gettime
-  pthread_getcpuclockid__no_such_thread
-  pthread_getschedparam__no_such_thread
-  pthread_setschedparam__no_such_thread
-  pthread_join__no_such_thread
-  pthread_kill__no_such_thread
-  pthread_join__multijoin
-  pthread_attr_setguardsize
-  pthread_attr_setstacksize
-regex.
-  smoke
-signal.
-  sigismember_invalid
-  sigaddset_invalid
-  sigdelset_invalid
-  sigemptyset_invalid
-  sigfillset_invalid
-  raise_invalid
-  raise_in_signal_handler
-  sigwait
-stack_protector.
-  global_guard
-statvfs.
-  statvfs
-  fstatvfs
-stdio.
-  tmpfile_fileno_fprintf_rewind_fgets
-  getdelim
-  getdelim_invalid
-  getline
-  getline_invalid
-  printf_ssize_t
-  popen
-  getc
-  putc
-stdlib.
-  drand48
-  lrand48_random_rand
-  mrand48
-  posix_memalign
-  realpath__NULL_filename
-  realpath__empty_filename
-  realpath__ENOENT
-  realpath
-  qsort
-string.
-  strerror
-  strerror_concurrent
-  strerror_r
-  strsignal
-  strsignal_concurrent
-  strcat
-  strcpy2
-  strcpy3
-  strcpy4
-  strcat2
-  strcat3
-  strncat2
-  strncat3
-  strncat4
-  strncat5
-  strchr_with_0
-  strchr
-  strcmp
-  strcpy
-  strlcat
-  strlcpy
-  strncat
-  strncmp
-  strncpy
-  strrchr
-  memchr
-  memrchr
-  memcmp
-  __memcmp16
-  wmemcmp
-  memcpy
-  memset
-  memmove
-  bcopy
-  bzero
-strings.
-  ffs
-getpwnam.
-  system_id_root
-  system_id_system
-  app_id_radio
-  app_id_nobody
-  app_id_all_a0
-  app_id_u1_a40000
-  app_id_u0_a0
-  app_id_u0_a1234
-  app_id_u0_a9999
-  app_id_u1_root
-  app_id_u1_radio
-  app_id_u1_a0
-  app_id_u1_i0
-sys_stat.
-  futimens
-  futimens_EBADF
-properties.
-  add
-  update
-  fill
-  foreach
-  find_nth
-  fill_hierarchical
-  errors
-  serial
-  wait
-time.
-  mktime_tz
-  gmtime
-  mktime_10310929
-unistd.
-  sysconf_SC_MONOTONIC_CLOCK
-  sbrk
diff --git a/tests/tests/bionic/main.cpp b/tests/tests/bionic/main.cpp
new file mode 100644
index 0000000..b661af4
--- /dev/null
+++ b/tests/tests/bionic/main.cpp
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include <gtest/gtest.h>
+
+int main(int argc, char **argv) {
+  // Do not use gtest_main to avoid the Running main() ... output.
+  testing::InitGoogleTest(&argc, argv);
+
+  return RUN_ALL_TESTS();
+}
diff --git a/tests/tests/content/src/android/content/res/cts/AssetManager_AssetInputStreamTest.java b/tests/tests/content/src/android/content/res/cts/AssetManager_AssetInputStreamTest.java
index 0100a7a..32c1a3a 100644
--- a/tests/tests/content/src/android/content/res/cts/AssetManager_AssetInputStreamTest.java
+++ b/tests/tests/content/src/android/content/res/cts/AssetManager_AssetInputStreamTest.java
@@ -42,8 +42,12 @@
     }
 
     public void testGetAssetInt() {
-        // the return value of getAssetInt is a random number
-        mAssetInputStream.getAssetInt();
+        try {
+            // getAssetInt is no longer supported.
+            mAssetInputStream.getAssetInt();
+            fail();
+        } catch (UnsupportedOperationException expected) {
+        }
     }
 
     public void testMarkReset() throws IOException {
diff --git a/tests/tests/content/src/android/content/res/cts/ConfigTest.java b/tests/tests/content/src/android/content/res/cts/ConfigTest.java
index bcfabe1..bfc7887 100644
--- a/tests/tests/content/src/android/content/res/cts/ConfigTest.java
+++ b/tests/tests/content/src/android/content/res/cts/ConfigTest.java
@@ -16,6 +16,8 @@
 
 package android.content.res.cts;
 
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Locale;
 
 import android.content.res.AssetManager;
@@ -35,6 +37,8 @@
     enum Properties {
         LANGUAGE,
         COUNTRY,
+        SCRIPT,
+        VARIANT,
         MCC,
         MNC,
         TOUCHSCREEN,
@@ -88,7 +92,7 @@
         public TotalConfig() {
             mConfig = new Configuration();
             mMetrics = new DisplayMetrics();
-            mConfig.locale = new Locale("++", "++");
+            mConfig.locale = Locale.ROOT;
         }
 
         public void setProperty(final Properties p, final int value) {
@@ -149,12 +153,28 @@
         public void setProperty(final Properties p, final String value) {
             switch(p) {
                 case LANGUAGE:
-                    final String oldCountry = mConfig.locale.getCountry();
-                    mConfig.locale = new Locale(value, oldCountry);
+                    mConfig.locale = new Locale.Builder()
+                            .setLocale(mConfig.locale)
+                            .setLanguage(value)
+                            .build();
                     break;
                 case COUNTRY:
-                    final String oldLanguage = mConfig.locale.getLanguage();
-                    mConfig.locale = new Locale(oldLanguage, value);
+                    mConfig.locale = new Locale.Builder()
+                            .setLocale(mConfig.locale)
+                            .setRegion(value)
+                            .build();
+                    break;
+                case SCRIPT:
+                    mConfig.locale = new Locale.Builder()
+                            .setLocale(mConfig.locale)
+                            .setScript(value)
+                            .build();
+                    break;
+                case VARIANT:
+                    mConfig.locale = new Locale.Builder()
+                            .setLocale(mConfig.locale)
+                            .setVariant(value)
+                            .build();
                     break;
                 default:
                     assert(false);
@@ -1131,4 +1151,133 @@
         assertEquals("base",  mContext.getResources().getString(R.string.version_old));
         assertEquals("v3",  mContext.getResources().getString(R.string.version_v3));
     }
+
+    @MediumTest
+    public void testExtendedLocales() {
+        TotalConfig config = makeClassicConfig();
+        // BCP 47 Locale kok
+        config.setProperty(Properties.LANGUAGE, "kok");
+        Resources res = config.getResources();
+        checkValue(res, R.configVarying.simple, "simple kok");
+        checkValue(res, R.configVarying.bag,
+                R.styleable.TestConfig, new String[]{"bag kok"});
+
+        // BCP 47 Locale kok-IN
+        config.setProperty(Properties.COUNTRY, "IN");
+        res = config.getResources();
+        checkValue(res, R.configVarying.simple, "simple kok IN");
+        checkValue(res, R.configVarying.bag,
+                R.styleable.TestConfig, new String[]{"bag kok IN"});
+
+        // BCP 47 Locale kok-419
+        config.setProperty(Properties.COUNTRY, "419");
+        res = config.getResources();
+        checkValue(res, R.configVarying.simple, "simple kok 419");
+        checkValue(res, R.configVarying.bag,
+                R.styleable.TestConfig, new String[]{"bag kok 419"});
+
+
+        // BCP 47 Locale kok-419-VARIANT
+        config.setProperty(Properties.VARIANT, "VARIANT");
+        res = config.getResources();
+        checkValue(res, R.configVarying.simple, "simple kok 419 VARIANT");
+        checkValue(res, R.configVarying.bag,
+                R.styleable.TestConfig, new String[]{"bag kok 419 VARIANT"});
+
+        // BCP 47 Locale kok-Knda
+        config = makeClassicConfig();
+        config.setProperty(Properties.LANGUAGE, "kok");
+        config.setProperty(Properties.SCRIPT, "Knda");
+        res = config.getResources();
+        checkValue(res, R.configVarying.simple, "simple kok Knda");
+        checkValue(res, R.configVarying.bag,
+                R.styleable.TestConfig, new String[]{"bag kok Knda"});
+
+        // BCP 47 Locale kok-Knda-419
+        config.setProperty(Properties.COUNTRY, "419");
+        res = config.getResources();
+        checkValue(res, R.configVarying.simple, "simple kok Knda 419");
+        checkValue(res, R.configVarying.bag,
+                R.styleable.TestConfig, new String[]{"bag kok Knda 419"});
+
+        // BCP 47 Locale kok-Knda-419-VARIANT
+        config.setProperty(Properties.VARIANT, "VARIANT");
+        res = config.getResources();
+        checkValue(res, R.configVarying.simple, "simple kok Knda 419 VARIANT");
+        checkValue(res, R.configVarying.bag,
+                R.styleable.TestConfig, new String[]{"bag kok Knda 419 VARIANT"});
+
+        // BCP 47 Locale kok-VARIANT
+        config = makeClassicConfig();
+        config.setProperty(Properties.LANGUAGE, "kok");
+        config.setProperty(Properties.VARIANT, "VARIANT");
+        res = config.getResources();
+        checkValue(res, R.configVarying.simple, "simple kok VARIANT");
+        checkValue(res, R.configVarying.bag,
+                R.styleable.TestConfig, new String[]{"bag kok VARIANT"});
+    }
+
+    @MediumTest
+    public void testTlAndFilConversion() {
+        TotalConfig config = makeClassicConfig();
+
+        // Ensure that "fil" is mapped to "tl" correctly.
+        config.setProperty(Properties.LANGUAGE, "fil");
+        config.setProperty(Properties.COUNTRY, "US");
+        Resources res = config.getResources();
+        checkValue(res, R.configVarying.simple, "simple tl");
+        checkValue(res, R.configVarying.bag,
+                R.styleable.TestConfig, new String[] { "bag tl" });
+
+        // Ensure that "fil-PH" is mapped to "tl-PH" correctly.
+        config = makeClassicConfig();
+        config.setProperty(Properties.LANGUAGE, "fil");
+        config.setProperty(Properties.COUNTRY, "PH");
+        res = config.getResources();
+        checkValue(res, R.configVarying.simple, "simple tl PH");
+        checkValue(res, R.configVarying.bag,
+                R.styleable.TestConfig, new String[] { "bag tl PH" });
+
+        config = makeClassicConfig();
+        config.setProperty(Properties.LANGUAGE, "tgl");
+        res = config.getResources();
+        checkValue(res, R.configVarying.simple, "simple tgl");
+        checkValue(res, R.configVarying.bag,
+                R.styleable.TestConfig, new String[] { "bag tgl" });
+
+        config = makeClassicConfig();
+        config.setProperty(Properties.LANGUAGE, "tgl");
+        config.setProperty(Properties.COUNTRY, "PH");
+        res = config.getResources();
+        checkValue(res, R.configVarying.simple, "simple tgl PH");
+        checkValue(res, R.configVarying.bag,
+                R.styleable.TestConfig, new String[] { "bag tgl PH" });
+    }
+
+    @MediumTest
+    public void testGetLocalesConvertsTlToFil() {
+        TotalConfig config = makeClassicConfig();
+
+        // Check that the list of locales doesn't contain any of the
+        // "tl" variants. They should've been converted to "fil"
+        // locales.
+        AssetManager am = config.getResources().getAssets();
+        String[] locales = am.getLocales();
+        final List<String> tlLocales = new ArrayList<String>(4);
+        final List<String> filLocales = new ArrayList<String>(4);
+        for (String locale : locales) {
+            if (locale.startsWith("tl-") || locale.equals("tl")) {
+                tlLocales.add(locale);
+            }
+
+            if (locale.startsWith("fil-") || locale.equals("fil")) {
+                filLocales.add(locale);
+            }
+        }
+
+        assertEquals(0, tlLocales.size());
+        assertEquals(2, filLocales.size());
+        assertTrue(filLocales.contains("fil"));
+        assertTrue(filLocales.contains("fil-PH"));
+    }
 }
diff --git a/tests/tests/hardware/Android.mk b/tests/tests/hardware/Android.mk
index e0ad6e5..68684b5 100644
--- a/tests/tests/hardware/Android.mk
+++ b/tests/tests/hardware/Android.mk
@@ -21,6 +21,12 @@
 LOCAL_MODULE := cts-sensors-tests
 LOCAL_MODULE_TAGS := tests
 
+# uncomment when b/13281332 is fixed
+# please also uncomment the equivalent code in
+# cts/apps/CtsVerifiers/Android.mk
+#
+# LOCAL_SDK_VERSION := current
+
 LOCAL_SRC_FILES := $(call all-java-files-under, src/android/hardware/cts/helpers)
 
 include $(BUILD_STATIC_JAVA_LIBRARY)
@@ -34,7 +40,7 @@
 
 LOCAL_JAVA_LIBRARIES := android.test.runner
 
-LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner mockito-target android-ex-camera2
+LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil ctstestrunner mockito-target android-ex-camera2
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
@@ -42,7 +48,11 @@
 
 LOCAL_INSTRUMENTATION_FOR := CtsTestStubs
 
-# uncomment when dalvik.annotation.Test* are removed or part of SDK
-#LOCAL_SDK_VERSION := current
+# uncomment when b/13281332 is fixed
+# please also uncomment the equivalent code in
+# cts/apps/CtsVerifiers/Android.mk
+#
+# LOCAL_SDK_VERSION := current
+LOCAL_JAVA_LIBRARIES := android.test.runner
 
 include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/hardware/src/android/hardware/cts/CameraGLTest.java b/tests/tests/hardware/src/android/hardware/cts/CameraGLTest.java
old mode 100644
new mode 100755
index c1809b8..c7e998c
--- a/tests/tests/hardware/src/android/hardware/cts/CameraGLTest.java
+++ b/tests/tests/hardware/src/android/hardware/cts/CameraGLTest.java
@@ -84,6 +84,7 @@
 
     Camera mCamera;
     SurfaceTexture mSurfaceTexture;
+    private final Object mSurfaceTextureSyncLock = new Object();
     Renderer mRenderer;
     GLSurfaceView mGLView;
 
@@ -165,7 +166,9 @@
         // the method. So we need to join the looper thread here.
         mLooper.getThread().join();
         mCamera = null;
-        mSurfaceTexture = null;
+        synchronized(mSurfaceTextureSyncLock) {
+            mSurfaceTexture = null;
+        }
         if (LOGV) Log.v(TAG, "Shutdown of camera complete.");
     }
 
@@ -662,10 +665,12 @@
 
         public void onDrawFrame(GL10 glUnused) {
             if (LOGVV) Log.v(TAG, "onDrawFrame()");
-            if (CameraGLTest.this.mSurfaceTexture != null) {
-                CameraGLTest.this.mSurfaceTexture.updateTexImage();
-                CameraGLTest.this.mSurfaceTexture.getTransformMatrix(mSTMatrix);
-                mDrawDone.open();
+            synchronized(mSurfaceTextureSyncLock) {
+                if (CameraGLTest.this.mSurfaceTexture != null) {
+                    CameraGLTest.this.mSurfaceTexture.updateTexImage();
+                    CameraGLTest.this.mSurfaceTexture.getTransformMatrix(mSTMatrix);
+                    mDrawDone.open();
+                }
             }
 
             // Ignore the passed-in GL10 interface, and use the GLES20
diff --git a/tests/tests/hardware/src/android/hardware/cts/SensorEventOrderingTests.java b/tests/tests/hardware/src/android/hardware/cts/SensorEventOrderingTests.java
deleted file mode 100644
index 116ac80..0000000
--- a/tests/tests/hardware/src/android/hardware/cts/SensorEventOrderingTests.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2013 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 android.hardware.cts;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-import android.hardware.Sensor;
-import android.hardware.SensorManager;
-
-import android.hardware.cts.helpers.SensorTestCase;
-
-import android.hardware.cts.helpers.sensorTestOperations.VerifyEventOrderingOperation;
-
-/**
- * Verifies the proper ordering in time of sensor events.
- */
-public class SensorEventOrderingTests extends SensorTestCase {
-    /**
-     * Builder for the test suite.
-     * This is the method that will build dynamically the set of test cases to execute.
-     * Each 'base' test case is composed by three parts:
-     * - the matrix definition
-     * - the test method that will execute the test case
-     * - a static method that will combine both and add test case instances to the test suite
-     */
-    public static Test suite() {
-        TestSuite testSuite = new TestSuite();
-
-        // add test generation routines
-        createEventOrderingTestCases(testSuite);
-
-        return testSuite;
-    }
-
-    /**
-     * Event ordering test cases.
-     */
-    private int mSensorType;
-    private int mSamplingRateInUs;
-    private int mReportLatencyInUs;
-
-    private static void createEventOrderingTestCases(TestSuite testSuite) {
-        int testDefinitionMatrix[][] = {
-                // { SensorType, SamplingRateInUs, ReportLatencyInUs },
-                { Sensor.TYPE_ACCELEROMETER, SensorManager.SENSOR_DELAY_FASTEST, 0 },
-                { Sensor.TYPE_GYROSCOPE, SensorManager.SENSOR_DELAY_FASTEST, 0 },
-                { Sensor.TYPE_MAGNETIC_FIELD, SensorManager.SENSOR_DELAY_FASTEST, 0 },
-                { Sensor.TYPE_PRESSURE, SensorManager.SENSOR_DELAY_FASTEST, 0 },
-                { Sensor.TYPE_GRAVITY, SensorManager.SENSOR_DELAY_FASTEST, 0 },
-                { Sensor.TYPE_LINEAR_ACCELERATION, SensorManager.SENSOR_DELAY_FASTEST, 0 },
-                { Sensor.TYPE_ROTATION_VECTOR, SensorManager.SENSOR_DELAY_FASTEST, 0 },
-                { Sensor.TYPE_RELATIVE_HUMIDITY, SensorManager.SENSOR_DELAY_FASTEST, 0 },
-                { Sensor.TYPE_AMBIENT_TEMPERATURE, SensorManager.SENSOR_DELAY_FASTEST, 0 },
-                { Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED, SensorManager.SENSOR_DELAY_FASTEST, 0 },
-                { Sensor.TYPE_GAME_ROTATION_VECTOR, SensorManager.SENSOR_DELAY_FASTEST, 0 },
-                { Sensor.TYPE_GYROSCOPE_UNCALIBRATED, SensorManager.SENSOR_DELAY_FASTEST, 0 },
-                { Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR, SensorManager.SENSOR_DELAY_FASTEST,0 },
-        };
-
-        for(int definition[] : testDefinitionMatrix) {
-            SensorEventOrderingTests test = new SensorEventOrderingTests();
-            test.mSensorType = definition[0];
-            test.mSamplingRateInUs = definition[1];
-            test.mReportLatencyInUs = definition[2];
-            test.setName("testEventOrdering");
-            testSuite.addTest(test);
-        }
-    }
-
-    /**
-     * This test verifies the ordering of the sampled data reported by the Sensor under test.
-     * This test is used to guarantee that sensor data is reported in the order it occurs, and that
-     * events are always reported in order.
-     *
-     * The test takes a set of samples from the Sensor under test, and then it verifies that each
-     * event's timestamp is in the future compared with the previous event. At the end of the
-     * validation, the full set of events is verified to be ordered by timestamp as they are
-     * generated.
-     *
-     * The test can be susceptible to errors if the sensor sampled data is not timestamped at the
-     * Hardware level. Or events sampled at high rates are added to the FIFO without controlling the
-     * appropriate ordering of the events.
-     *
-     * The assertion associated with the test provides the information of the two consecutive events
-     * that cause the test to fail.
-     */
-    public void testEventOrdering() throws Throwable {
-        VerifyEventOrderingOperation operation = new VerifyEventOrderingOperation(
-                this.getContext(),
-                mSensorType,
-                mSamplingRateInUs,
-                mReportLatencyInUs);
-        operation.execute();
-    }
-}
diff --git a/tests/tests/hardware/src/android/hardware/cts/SensorFrequencyTests.java b/tests/tests/hardware/src/android/hardware/cts/SensorFrequencyTests.java
deleted file mode 100644
index b35f515..0000000
--- a/tests/tests/hardware/src/android/hardware/cts/SensorFrequencyTests.java
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Copyright (C) 2013 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 android.hardware.cts;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-import android.hardware.Sensor;
-
-import android.hardware.cts.helpers.SensorCtsHelper;
-import android.hardware.cts.helpers.SensorTestCase;
-
-import android.hardware.cts.helpers.sensorTestOperations.VerifyJitteringOperation;
-import android.hardware.cts.helpers.sensorTestOperations.VerifyMaximumFrequencyOperation;
-
-/**
- * Verifies several properties of the sampling rate of the different sensors in the platform.
- */
-public class SensorFrequencyTests extends SensorTestCase {
-    private int mSensorType;
-    private int mReportLatencyInUs;
-    private int mThresholdPercentageOfNs;
-
-    /**
-     * Builder for the test suite.
-     * This is the method that will build dynamically the set of test cases to execute.
-     * Each 'base' test case is composed by three parts:
-     * - the matrix definition
-     * - the test method that will execute the test case
-     * - a static method that will combine both and add test case instances to the test suite
-     */
-    public static Test suite() {
-        TestSuite testSuite = new TestSuite();
-
-        // add test generation routines
-        createMaxFrequencyExpectedTestCases(testSuite);
-        // TODO: tests are a unreliable in the lab
-        //createMaxFrequencyTestCases(testSuite);
-        //createJitteringTestCases(testSuite);
-
-        return testSuite;
-    }
-
-    /**
-     * Max frequency test cases.
-     */
-    private static void createMaxFrequencyTestCases(TestSuite testSuite) {
-        int testDefinitionMatrix[][] = {
-                // { SensorType, ReportLatencyInUs, ThresholdPercentageOfNs },
-                { Sensor.TYPE_ACCELEROMETER, 0, 10 },
-                { Sensor.TYPE_GYROSCOPE, 0, 10 },
-                { Sensor.TYPE_MAGNETIC_FIELD, 0, 10 },
-        };
-
-        for(int definition[] : testDefinitionMatrix) {
-            SensorFrequencyTests test = new SensorFrequencyTests();
-            test.mSensorType = definition[0];
-            test.mReportLatencyInUs = definition[1];
-            test.mThresholdPercentageOfNs = definition[2];
-            test.setName("testMaxFrequency");
-            testSuite.addTest(test);
-        }
-    }
-
-    /**
-     * This test verifies that the Sensor under test can sample and report data at the Maximum
-     * frequency (sampling rate) it advertises.
-     *
-     * The test takes a set of samples from the sensor under test, and calculates the mean of the
-     * frequency at which the events are reported. The frequency between events is calculated by
-     * looking at the delta between the timestamps associated with each event.
-     *
-     * The test is susceptible to errors if the Sensor is not capable to sample data at the maximum
-     * rate it supports, or the sensor events are not timestamped at the Hardware level.
-     *
-     * The assertion associated with the test provides the required data to identify:
-     * - the thread id on which the failure occurred
-     * - the sensor type and sensor handle that caused the failure
-     * - the expected frequency
-     * - the observed frequency
-     * In addition to that, the device's debug output (adb logcat) dumps the set of timestamp deltas
-     * associated with the set of data gathered from the Sensor under test.
-     */
-    public void testMaxFrequency() throws Throwable {
-        VerifyMaximumFrequencyOperation operation = new VerifyMaximumFrequencyOperation(
-                this.getContext(),
-                mSensorType,
-                mReportLatencyInUs,
-                mThresholdPercentageOfNs);
-        operation.execute();
-    }
-
-    /**
-     * Jittering test cases.
-     */
-    private static void createJitteringTestCases(TestSuite testSuite) {
-        int testDefinitionMatrix[][] = {
-                // { SensorType, ReportLatencyInUs, ThresholdPercentageOfNs },
-                { Sensor.TYPE_ACCELEROMETER, 0, 10 },
-                { Sensor.TYPE_GYROSCOPE, 0, 10 },
-                { Sensor.TYPE_MAGNETIC_FIELD, 0, 10 },
-        };
-
-        for(int definition[] : testDefinitionMatrix) {
-            SensorFrequencyTests test = new SensorFrequencyTests();
-            test.mSensorType = definition[0];
-            test.mReportLatencyInUs = definition[1];
-            test.mThresholdPercentageOfNs = definition[2];
-            test.setName("testJittering");
-            testSuite.addTest(test);
-        }
-    }
-
-    /**
-     * This test verifies that the event jittering associated with the sampled data reported by the
-     * Sensor under test, aligns with the requirements imposed in the CDD.
-     * This test characterizes how the sensor behaves while sampling data at a specific rate.
-     *
-     * The test takes a set of samples from the sensor under test, using the maximum sampling rate
-     * advertised by the Sensor under test. It then compares the 95%ile associated with the
-     * jittering of the timestamps, with an expected value.
-     *
-     * The test is susceptible to errors if the sensor events are not timestamped at the Hardware
-     * level.
-     *
-     * The assertion associated with the failure provides the following information:
-     * - the thread id on which the failure occurred
-     * - the sensor type and sensor handle that caused the failure
-     * - the expectation of the test with respect of the 95%ile
-     * - the calculated 95%ile jittering
-     * Additionally, the device's debug output (adb logcat) dumps the set of jitter values
-     * calculated.
-     */
-    public void testJittering() throws Throwable {
-        VerifyJitteringOperation operation = new VerifyJitteringOperation(
-                this.getContext(),
-                mSensorType,
-                mReportLatencyInUs,
-                mThresholdPercentageOfNs);
-        operation.execute();
-    }
-
-    /**
-     * Max Frequency expected Test Cases.
-     */
-    private int mExpectedSamplingRateInUs;
-
-    private static void createMaxFrequencyExpectedTestCases(TestSuite testSuite) {
-        int testDefinitionMatrix[][] = {
-                // { SensorType, ExpectedSamplingRateInUs },
-                { Sensor.TYPE_ACCELEROMETER, 10000 /* 100 Hz */ },
-                { Sensor.TYPE_GYROSCOPE, 10000 /* 100 Hz */ },
-                { Sensor.TYPE_MAGNETIC_FIELD, 100000 /* 10 Hz */ },
-        };
-
-        for(int definition[] : testDefinitionMatrix) {
-            SensorFrequencyTests test = new SensorFrequencyTests();
-            test.mSensorType = definition[0];
-            test.mExpectedSamplingRateInUs = definition[1];
-            test.setName("testMaxFrequencyExpected");
-            testSuite.addTest(test);
-        }
-    }
-
-    /**
-     * This test verifies that the sensor's maximum advertised frequency (sampling rate) complies
-     * with the required frequency set in the CDD.
-     * This characterizes that the sensor is able to provide data at the rate the platform requires
-     * it.
-     *
-     * The test simply compares the sampling rate specified in the CDD with the maximum sampling
-     * rate advertised by the Sensor under test.
-     *
-     * The test can fail if the Sensor Hardware does not support the sampling rate required by the
-     * platform.
-     *
-     * The assertion associated with the test failure contains:
-     * - the thread id on which the failure occurred
-     * - the sensor type and sensor handle that caused the failure
-     * - the expected maximum sampling rate
-     * - the observed maximum sampling rate
-     */
-    public void testMaxFrequencyExpected() {
-        Sensor sensor = SensorCtsHelper.getSensor(this.getContext(), mSensorType);
-        int samplingRateInUs = sensor.getMinDelay();
-        String message = String.format(
-                "samplingRateInUs| expected:%d, actual:%d",
-                mExpectedSamplingRateInUs,
-                samplingRateInUs);
-        assertTrue(message, mExpectedSamplingRateInUs >= samplingRateInUs);
-    }
-}
diff --git a/tests/tests/hardware/src/android/hardware/cts/SensorIntegrationTests.java b/tests/tests/hardware/src/android/hardware/cts/SensorIntegrationTests.java
index a1aa760..d5d7972 100644
--- a/tests/tests/hardware/src/android/hardware/cts/SensorIntegrationTests.java
+++ b/tests/tests/hardware/src/android/hardware/cts/SensorIntegrationTests.java
@@ -15,23 +15,19 @@
  */
 package android.hardware.cts;
 
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
 import android.content.Context;
-
 import android.hardware.Sensor;
 import android.hardware.SensorManager;
-
 import android.hardware.cts.helpers.SensorCtsHelper;
-import android.hardware.cts.helpers.SensorTestCase;
-import android.hardware.cts.helpers.SensorTestInformation;
-import android.hardware.cts.helpers.SensorTestOperation;
+import android.hardware.cts.helpers.SensorStats;
+import android.hardware.cts.helpers.sensoroperations.ParallelSensorOperation;
+import android.hardware.cts.helpers.sensoroperations.RepeatingSensorOperation;
+import android.hardware.cts.helpers.sensoroperations.SequentialSensorOperation;
+import android.hardware.cts.helpers.sensoroperations.TestSensorOperation;
+import android.hardware.cts.helpers.sensorverification.EventOrderingVerification;
 
-import android.hardware.cts.helpers.sensorTestOperations.ParallelCompositeSensorTestOperation;
-import android.hardware.cts.helpers.sensorTestOperations.RepeatingSensorTestOperation;
-import android.hardware.cts.helpers.sensorTestOperations.SequentialCompositeSensorTestOperation;
-import android.hardware.cts.helpers.sensorTestOperations.VerifyEventOrderingOperation;
+import junit.framework.Test;
+import junit.framework.TestSuite;
 
 import java.util.Random;
 
@@ -43,6 +39,8 @@
  *          -w com.android.cts.hardware/android.test.InstrumentationCtsTestRunner
  */
 public class SensorIntegrationTests extends SensorTestCase {
+    private static final String TAG = "SensorIntegrationTests";
+
     /**
      * Builder for the test suite.
      * This is the method that will build dynamically the set of test cases to execute.
@@ -87,7 +85,7 @@
      */
     public void testSensorsWithSeveralClients() throws Throwable {
         final int ITERATIONS = 50;
-        final int BATCHING_RATE_IN_SECONDS = 5;
+        final int MAX_REPORTING_LATENCY_IN_SECONDS = 5;
         final Context context = this.getContext();
 
         int sensorTypes[] = {
@@ -95,23 +93,28 @@
                 Sensor.TYPE_MAGNETIC_FIELD,
                 Sensor.TYPE_GYROSCOPE };
 
-        ParallelCompositeSensorTestOperation operation = new ParallelCompositeSensorTestOperation();
+        ParallelSensorOperation operation = new ParallelSensorOperation();
         for(int sensorType : sensorTypes) {
-            SensorTestOperation continuousOperation = new VerifyEventOrderingOperation(
+            TestSensorOperation continuousOperation = new TestSensorOperation(
                     context,
                     sensorType,
                     SensorManager.SENSOR_DELAY_NORMAL,
-                    0 /* reportLatencyInUs */);
-            operation.add(new RepeatingSensorTestOperation(continuousOperation, ITERATIONS));
+                    0 /* reportLatencyInUs */,
+                    100 /* event count */);
+            continuousOperation.addVerification(new EventOrderingVerification());
+            operation.add(new RepeatingSensorOperation(continuousOperation, ITERATIONS));
 
-            SensorTestOperation batchingOperation = new VerifyEventOrderingOperation(
+            TestSensorOperation batchingOperation = new TestSensorOperation(
                     context,
                     sensorType,
-                    SensorTestInformation.getMaxSamplingRateInUs(context, sensorType),
-                    SensorCtsHelper.getSecondsAsMicroSeconds(BATCHING_RATE_IN_SECONDS));
-            operation.add(new RepeatingSensorTestOperation(batchingOperation, ITERATIONS));
+                    SensorCtsHelper.getSensor(getContext(), sensorType).getMinDelay(),
+                    SensorCtsHelper.getSecondsAsMicroSeconds(MAX_REPORTING_LATENCY_IN_SECONDS),
+                    100);
+            batchingOperation.addVerification(new EventOrderingVerification());
+            operation.add(new RepeatingSensorOperation(batchingOperation, ITERATIONS));
         }
         operation.execute();
+        SensorStats.logStats(TAG, operation.getStats());
     }
 
     /**
@@ -140,7 +143,7 @@
         final int INSTANCES_TO_USE = 5;
         final int ITERATIONS_TO_EXECUTE = 100;
 
-        ParallelCompositeSensorTestOperation operation = new ParallelCompositeSensorTestOperation();
+        ParallelSensorOperation operation = new ParallelSensorOperation();
         int sensorTypes[] = {
                 Sensor.TYPE_ACCELEROMETER,
                 Sensor.TYPE_MAGNETIC_FIELD,
@@ -148,14 +151,15 @@
 
         for(int sensorType : sensorTypes) {
             for(int instance = 0; instance < INSTANCES_TO_USE; ++instance) {
-                SequentialCompositeSensorTestOperation sequentialOperation =
-                        new SequentialCompositeSensorTestOperation();
+                SequentialSensorOperation sequentialOperation = new SequentialSensorOperation();
                 for(int iteration = 0; iteration < ITERATIONS_TO_EXECUTE; ++iteration) {
-                    VerifyEventOrderingOperation sensorOperation = new VerifyEventOrderingOperation(
+                    TestSensorOperation sensorOperation = new TestSensorOperation(
                             this.getContext(),
                             sensorType,
                             this.generateSamplingRateInUs(sensorType),
-                            this.generateReportLatencyInUs());
+                            this.generateReportLatencyInUs(),
+                            100);
+                    sensorOperation.addVerification(new EventOrderingVerification());
                     sequentialOperation.add(sensorOperation);
                 }
                 operation.add(sequentialOperation);
@@ -163,6 +167,7 @@
         }
 
         operation.execute();
+        SensorStats.logStats(TAG, operation.getStats());
     }
 
     /**
@@ -212,24 +217,30 @@
     public void testSensorStoppingInteraction() throws Throwable {
         Context context = this.getContext();
 
-        SensorTestOperation tester = new VerifyEventOrderingOperation(
+        TestSensorOperation tester = new TestSensorOperation(
                 context,
                 mSensorTypeTester,
                 SensorManager.SENSOR_DELAY_NORMAL,
-                0 /*reportLatencyInUs*/);
-        tester.start();
+                0 /*reportLatencyInUs*/,
+                100 /* event count */);
+        tester.addVerification(new EventOrderingVerification());
 
-        SensorTestOperation testee = new VerifyEventOrderingOperation(
+        TestSensorOperation testee = new TestSensorOperation(
                 context,
                 mSensorTypeTestee,
                 SensorManager.SENSOR_DELAY_UI,
-                0 /*reportLatencyInUs*/);
-        testee.start();
+                0 /*reportLatencyInUs*/,
+                100 /* event count */);
+        testee.addVerification(new EventOrderingVerification());
 
-        testee.waitForCompletion();
-        tester.waitForCompletion();
+        ParallelSensorOperation operation = new ParallelSensorOperation();
+        operation.add(tester, testee);
+        operation.execute();
+        SensorStats.logStats(TAG, operation.getStats());
 
+        testee = testee.clone();
         testee.execute();
+        SensorStats.logStats(TAG, testee.getStats());
     }
 
     /**
@@ -254,9 +265,8 @@
                 break;
             case 4:
             default:
-                int maxSamplingRate = SensorTestInformation.getMaxSamplingRateInUs(
-                        this.getContext(),
-                        sensorType);
+                int maxSamplingRate = SensorCtsHelper.getSensor(getContext(), sensorType)
+                        .getMinDelay();
                 rate = maxSamplingRate * mGenerator.nextInt(10);
         }
         return rate;
diff --git a/tests/tests/hardware/src/android/hardware/cts/SensorMeasurementTests.java b/tests/tests/hardware/src/android/hardware/cts/SensorMeasurementTests.java
deleted file mode 100644
index 859b26d..0000000
--- a/tests/tests/hardware/src/android/hardware/cts/SensorMeasurementTests.java
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * Copyright (C) 2013 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 android.hardware.cts;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-import android.hardware.Sensor;
-import android.hardware.SensorManager;
-
-import android.hardware.cts.helpers.SensorTestCase;
-
-import android.hardware.cts.helpers.sensorTestOperations.VerifyMagnitudeOperation;
-import android.hardware.cts.helpers.sensorTestOperations.VerifyStandardDeviationOperation;
-
-/**
- * Verifies several properties of the sensor measurements.
- */
-public class SensorMeasurementTests extends SensorTestCase {
-    private int mSensorType;
-    private int mSamplingRateInUs;
-
-    /**
-     * Builder for the test suite.
-     * This is the method that will build dynamically the set of test cases to execute.
-     * Each 'base' test case is composed by three parts:
-     * - the matrix definition
-     * - the test method that will execute the test case
-     * - a static method that will combine both and add test case instances to the test suite
-     */
-    public static Test suite() {
-        TestSuite testSuite = new TestSuite();
-
-        // add test generation routines
-        createEventNormTestCases(testSuite);
-        createStandardDeviationTestCases(testSuite);
-
-        return testSuite;
-    }
-
-    /**
-     * SensorEvent Norm test cases.
-     *
-     * Regress:
-     * - b/9503957
-     * - b/9611609
-     */
-    private float mReferenceValue;
-    private float mThreshold;
-
-    private static void createEventNormTestCases(TestSuite testSuite) {
-        Object testDefinitionMatrix[][] = {
-                // { SensorType, SamplingRateInUs, ReferenceValue, Threshold },
-                { Sensor.TYPE_ACCELEROMETER,
-                        SensorManager.SENSOR_DELAY_FASTEST,
-                        SensorManager.STANDARD_GRAVITY,
-                        1.5f /* m / s^2 */},
-                { Sensor.TYPE_GYROSCOPE, SensorManager.SENSOR_DELAY_FASTEST, 0.0f, 2.5f /* dps */ },
-        };
-
-        for(Object definition[] : testDefinitionMatrix)  {
-            SensorMeasurementTests test = new SensorMeasurementTests();
-            test.mSensorType = (Integer)definition[0];
-            test.mSamplingRateInUs = (Integer)definition[1];
-            test.mReferenceValue = (Float)definition[2];
-            test.mThreshold = (Float)definition[3];
-            test.setName("testEventNorm");
-            testSuite.addTest(test);
-        }
-    }
-
-    /**
-     * This test verifies that the Norm of the sensor data is close to the expected reference value.
-     * The units of the reference value are dependent on the type of sensor.
-     * This test is used to verify that the data reported by the sensor is close to the expected
-     * range and scale.
-     *
-     * The test takes a sample from the sensor under test and calculates the Euclidean Norm of the
-     * vector represented by the sampled data. It then compares it against the test expectations
-     * that are represented by a reference value and a threshold.
-     *
-     * The test is susceptible to errors when the Sensor under test is uncalibrated, or the units in
-     * which the data are reported and the expectations are set are different.
-     *
-     * The assertion associated with the test provides the required data needed to identify any
-     * possible issue. It provides:
-     * - the thread id on which the failure occurred
-     * - the sensor type and sensor handle that caused the failure
-     * - the values representing the expectation of the test
-     * - the values sampled from the sensor
-     */
-    public void testEventNorm() throws Throwable {
-        VerifyMagnitudeOperation operation = new VerifyMagnitudeOperation(
-                this.getContext(),
-                mSensorType,
-                mSamplingRateInUs,
-                mReferenceValue,
-                mThreshold);
-        operation.execute();
-    }
-
-    /**
-     * SensorEvent Standard Deviation test cases.
-     */
-    private int mReportLatencyInUs;
-    private float mExpectedStandardDeviation;
-
-    private static void createStandardDeviationTestCases(TestSuite testSuite) {
-        Object testDefinitionMatrix[][] = {
-                // { SensorType, SamplingRateInUs, ReportLatencyInUs, ExpectedStandardDeviation },
-                { Sensor.TYPE_ACCELEROMETER, SensorManager.SENSOR_DELAY_FASTEST, 0, 1f /* m/s^2 */ },
-                { Sensor.TYPE_GYROSCOPE, SensorManager.SENSOR_DELAY_FASTEST, 0, 0.5f /* dps */ },
-        };
-
-        for(Object definition[] : testDefinitionMatrix) {
-            SensorMeasurementTests test = new SensorMeasurementTests();
-            test.mSensorType = (Integer)definition[0];
-            test.mSamplingRateInUs = (Integer)definition[1];
-            test.mReportLatencyInUs = (Integer)definition[2];
-            test.mExpectedStandardDeviation = (Float)definition[3];
-            test.setName("testStandardDeviation");
-            testSuite.addTest(test);
-        }
-    }
-
-    /**
-     * This test verifies that the standard deviation of a set of sampled data from a particular
-     * sensor falls into the expectations defined in the CDD. The verification applies to each axis
-     * of the sampled data reported by the Sensor under test.
-     * This test is used to validate the requirement imposed by the CDD to Sensors in Android. And
-     * characterizes how the Sensor behaves while static.
-     *
-     * The test takes a set of samples from the sensor under test, and calculates the Standard
-     * Deviation for each of the axes the Sensor reports data for. The StdDev is compared against
-     * the expected value documented in the CDD.
-     *
-     * The test is susceptible to errors if the device is moving while the test is running, or if
-     * the Sensor's sampled data indeed falls into a large StdDev.
-     *
-     * The assertion associated with the test provides the required data to identify any possible
-     * issue. It provides:
-     * - the thread id on which the failure occurred
-     * - the sensor type and sensor handle that caused the failure
-     * - the expectation of the test
-     * - the std dev calculated and the axis it applies to
-     * Additionally, the device's debug output (adb logcat) dumps the set of values associated with
-     * the failure to help track down the issue.
-     */
-    public void testStandardDeviation() throws Throwable {
-        VerifyStandardDeviationOperation operation = new VerifyStandardDeviationOperation(
-                this.getContext(),
-                mSensorType,
-                mSamplingRateInUs,
-                mReportLatencyInUs,
-                mExpectedStandardDeviation);
-        operation.execute();
-    }
-}
diff --git a/tests/tests/hardware/src/android/hardware/cts/SensorTestCase.java b/tests/tests/hardware/src/android/hardware/cts/SensorTestCase.java
new file mode 100644
index 0000000..222da56
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/SensorTestCase.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2013 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 android.hardware.cts;
+
+import android.app.Instrumentation;
+import android.cts.util.CtsAndroidTestCase;
+import android.cts.util.DeviceReportLog;
+import android.hardware.cts.helpers.SensorNotSupportedException;
+import android.hardware.cts.helpers.SensorStats;
+import android.util.Log;
+
+import com.android.cts.util.ReportLog;
+import com.android.cts.util.ResultType;
+import com.android.cts.util.ResultUnit;
+
+/**
+ * Test Case class that handles gracefully sensors that are not available in the device.
+ */
+public abstract class SensorTestCase extends CtsAndroidTestCase {
+    protected final String LOG_TAG = "TestRunner";
+
+    protected SensorTestCase() {}
+
+    @Override
+    public void runTest() throws Throwable {
+        try {
+            super.runTest();
+        } catch (SensorNotSupportedException e) {
+            // the sensor is not supported/available in the device, log a warning and skip the test
+            Log.w(LOG_TAG, e.getMessage());
+        }
+    }
+
+    /**
+     * Utility method to log selected stats to a {@link ReportLog} object.  The stats must be
+     * a number or an array of numbers.
+     */
+    public static void logSelectedStatsToReportLog(Instrumentation instrumentation, int depth,
+            String[] keys, SensorStats stats) {
+        DeviceReportLog reportLog = new DeviceReportLog(depth);
+
+        for (String key : keys) {
+            Object value = stats.getValue(key);
+            if (value instanceof Integer) {
+                reportLog.printValue(key, (Integer) value, ResultType.NEUTRAL, ResultUnit.NONE);
+            } else if (value instanceof Double) {
+                reportLog.printValue(key, (Double) value, ResultType.NEUTRAL, ResultUnit.NONE);
+            } else if (value instanceof Float) {
+                reportLog.printValue(key, (Float) value, ResultType.NEUTRAL, ResultUnit.NONE);
+            } else if (value instanceof double[]) {
+                reportLog.printArray(key, (double[]) value, ResultType.NEUTRAL, ResultUnit.NONE);
+            } else if (value instanceof float[]) {
+                float[] tmpFloat = (float[]) value;
+                double[] tmpDouble = new double[tmpFloat.length];
+                for (int i = 0; i < tmpDouble.length; i++) tmpDouble[i] = tmpFloat[i];
+                reportLog.printArray(key, tmpDouble, ResultType.NEUTRAL, ResultUnit.NONE);
+            }
+        }
+
+        reportLog.printSummary("summary", 0, ResultType.NEUTRAL, ResultUnit.NONE);
+        reportLog.deliverReportToHost(instrumentation);
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/SingleSensorTests.java b/tests/tests/hardware/src/android/hardware/cts/SingleSensorTests.java
new file mode 100644
index 0000000..cd6adb1
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/SingleSensorTests.java
@@ -0,0 +1,628 @@
+/*
+ * Copyright (C) 2014 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 android.hardware.cts;
+
+import android.hardware.Sensor;
+import android.hardware.SensorManager;
+import android.hardware.cts.helpers.SensorCtsHelper;
+import android.hardware.cts.helpers.SensorStats;
+import android.hardware.cts.helpers.SensorTestInformation;
+import android.hardware.cts.helpers.sensoroperations.TestSensorOperation;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Set of tests to verify that sensors operate correctly when operating alone.
+ * <p>
+ * To execute these test cases, the following command can be used:
+ * </p><pre>
+ * adb shell am instrument -e class android.hardware.cts.SingleSensorTests \
+ *     -w com.android.cts.hardware/android.test.InstrumentationCtsTestRunner
+ * </pre><p>
+ * For each sensor that reports continuously, it takes a set of samples. The test suite verifies
+ * that the event ordering, frequency, and jitter pass for the collected sensor events. It
+ * additionally tests that the mean, standard deviation, and magnitude are correct for the sensor
+ * event values, where applicable for a device in a static environment.
+ * </p><p>
+ * The event ordering test verifies the ordering of the sampled data reported by the Sensor under
+ * test. This test is used to guarantee that sensor data is reported in the order it occurs, and
+ * that events are always reported in order. It verifies that each event's timestamp is in the
+ * future compared with the previous event. At the end of the validation, the full set of events is
+ * verified to be ordered by timestamp as they are generated. The test can be susceptible to errors
+ * if the sensor sampled data is not timestamped at the hardware level. Or events sampled at high
+ * rates are added to the FIFO without controlling the appropriate ordering of the events.
+ * </p><p>
+ * The frequency test verifies that the sensor under test can sample and report data at the maximum
+ * frequency (sampling rate) it advertises. The frequency between events is calculated by looking at
+ * the delta between the timestamps associated with each event to get the period. The test is
+ * susceptible to errors if the sensor is not capable to sample data at the maximum rate it
+ * supports, or the sensor events are not timestamped at the hardware level.
+ * </p><p>
+ * The jitter test verifies that the event jittering associated with the sampled data reported by
+ * the sensor under test aligns with the requirements imposed in the CDD. This test characterizes
+ * how the sensor behaves while sampling data at a specific rate. It compares the 95th percentile of
+ * the jittering with a certain percentage of the minimum period. The test is susceptible to errors
+ * if the sensor events are not timestamped at the hardware level.
+ * </p><p>
+ * The mean test verifies that the mean of a set of sampled data from a particular sensor falls into
+ * the expectations defined in the CDD. The verification applies to each axis of the sampled data
+ * reported by the sensor under test. This test is used to validate the requirement imposed by the
+ * CDD to Sensors in Android and characterizes how the Sensor behaves while static. The test is
+ * susceptible to errors if the device is moving while the test is running, or if the sensor's
+ * sampled data indeed varies from the expected mean.
+ * </p><p>
+ * The magnitude test verifies that the magnitude of the sensor data is close to the expected
+ * reference value. The units of the reference value are dependent on the type of sensor.
+ * This test is used to verify that the data reported by the sensor is close to the expected
+ * range and scale. The test calculates the Euclidean norm of the vector represented by the sampled
+ * data and compares it against the test expectations. The test is susceptible to errors when the
+ * sensor under test is uncalibrated, or the units between the data and expectations are different.
+ * </p><p>
+ * The standard deviation test verifies that the standard deviation of a set of sampled data from a
+ * particular sensor falls into the expectations defined in the CDD. The verification applies to
+ * each axis of the sampled data reported by the sensor under test. This test is used to validate
+ * the requirement imposed by the CDD to Sensors in Android and characterizes how the Sensor behaves
+ * while static. The test is susceptible to errors if the device is moving while the test is
+ * running, or if the sensor's sampled data indeed falls into a large standard deviation.
+ * </p>
+ */
+public class SingleSensorTests extends SensorTestCase {
+    private static final String TAG = "SingleSensorTests";
+
+    private static final int BATCHING_OFF = 0;
+    private static final int BATCHING_5S = 5000000;
+
+    private static final int RATE_100HZ = 10000;
+    private static final int RATE_50HZ = 20000;
+    private static final int RATE_25HZ = 40000;
+    private static final int RATE_15HZ = 66667;
+    private static final int RATE_10HZ = 100000;
+    private static final int RATE_5HZ = 200000;
+    private static final int RATE_1HZ = 1000000;
+
+    private static final String[] STAT_KEYS = {
+        SensorStats.FREQUENCY_KEY,
+        SensorStats.JITTER_95_PERCENTILE_KEY,
+        SensorStats.EVENT_OUT_OF_ORDER_COUNT_KEY,
+        SensorStats.MAGNITUDE_KEY,
+        SensorStats.MEAN_KEY,
+        SensorStats.STANDARD_DEVIATION_KEY,
+    };
+
+    /**
+     * This test verifies that the sensor's properties complies with the required properites set in
+     * the CDD.
+     * <p>
+     * It checks that the sampling rate advertised by the sensor under test matches that which is
+     * required by the CDD.
+     * </p>
+     */
+    public void testSensorProperties() {
+        // sensor type: [getMinDelay()]
+        Map<Integer, Object[]> expectedProperties = new HashMap<Integer, Object[]>(3);
+        expectedProperties.put(Sensor.TYPE_ACCELEROMETER, new Object[]{10000});
+        expectedProperties.put(Sensor.TYPE_GYROSCOPE, new Object[]{10000});
+        expectedProperties.put(Sensor.TYPE_MAGNETIC_FIELD, new Object[]{100000});
+
+        for (Entry<Integer, Object[]> entry : expectedProperties.entrySet()) {
+            Sensor sensor = SensorCtsHelper.getSensor(getContext(), entry.getKey());
+            String sensorName = SensorTestInformation.getSensorName(entry.getKey());
+            if (entry.getValue()[0] != null) {
+                int expected = (Integer) entry.getValue()[0];
+                String msg = String.format(
+                        "%s: min delay %dus expected to be less than or equal to %dus",
+                        sensorName, sensor.getMinDelay(), expected);
+                assertTrue(msg, sensor.getMinDelay() <= expected);
+            }
+        }
+    }
+
+    // TODO: Figure out if a better way to enumerate test cases programmatically exists that works
+    // with CTS framework.
+    public void testAccelerometer_fastest() throws Throwable {
+        runSensorTest(Sensor.TYPE_ACCELEROMETER, SensorManager.SENSOR_DELAY_FASTEST, BATCHING_OFF);
+    }
+
+    public void testAccelerometer_100hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_ACCELEROMETER, RATE_100HZ, BATCHING_OFF);
+    }
+
+    public void testAccelerometer_50hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_ACCELEROMETER, RATE_50HZ, BATCHING_OFF);
+    }
+
+    public void testAccelerometer_25hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_ACCELEROMETER, RATE_25HZ, BATCHING_OFF);
+    }
+
+    public void testAccelerometer_15hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_ACCELEROMETER, RATE_15HZ, BATCHING_OFF);
+    }
+
+    public void testAccelerometer_10hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_ACCELEROMETER, RATE_10HZ, BATCHING_OFF);
+    }
+
+    public void testAccelerometer_5hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_ACCELEROMETER, RATE_5HZ, BATCHING_OFF);
+    }
+
+    public void testAccelerometer_1hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_ACCELEROMETER, RATE_1HZ, BATCHING_OFF);
+    }
+
+    public void testAccelerometer_fastest_batching() throws Throwable {
+        runSensorTest(Sensor.TYPE_ACCELEROMETER, SensorManager.SENSOR_DELAY_FASTEST, BATCHING_5S);
+    }
+
+    public void testAccelerometer_50hz_batching() throws Throwable {
+        runSensorTest(Sensor.TYPE_ACCELEROMETER, RATE_50HZ, BATCHING_5S);
+    }
+
+    public void testMagneticField_fastest() throws Throwable {
+        runSensorTest(Sensor.TYPE_MAGNETIC_FIELD, SensorManager.SENSOR_DELAY_FASTEST, BATCHING_OFF);
+    }
+
+    public void testMagneticField_100hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_MAGNETIC_FIELD, RATE_100HZ, BATCHING_OFF);
+    }
+
+    public void testMagneticField_50hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_MAGNETIC_FIELD, RATE_50HZ, BATCHING_OFF);
+    }
+
+    public void testMagneticField_25hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_MAGNETIC_FIELD, RATE_25HZ, BATCHING_OFF);
+    }
+
+    public void testMagneticField_15hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_MAGNETIC_FIELD, RATE_15HZ, BATCHING_OFF);
+    }
+
+    public void testMagneticField_10hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_MAGNETIC_FIELD, RATE_10HZ, BATCHING_OFF);
+    }
+
+    public void testMagneticField_5hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_MAGNETIC_FIELD, RATE_5HZ, BATCHING_OFF);
+    }
+
+    public void testMagneticField_1hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_MAGNETIC_FIELD, RATE_1HZ, BATCHING_OFF);
+    }
+
+    public void testMagneticField_fastest_batching() throws Throwable {
+        runSensorTest(Sensor.TYPE_MAGNETIC_FIELD, SensorManager.SENSOR_DELAY_FASTEST, BATCHING_5S);
+    }
+
+    public void testMagneticField_50hz_batching() throws Throwable {
+        runSensorTest(Sensor.TYPE_MAGNETIC_FIELD, RATE_50HZ, BATCHING_5S);
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testOrientation_fastest() throws Throwable {
+        runSensorTest(Sensor.TYPE_ORIENTATION, SensorManager.SENSOR_DELAY_FASTEST, BATCHING_OFF);
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testOrientation_100hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_ORIENTATION, RATE_100HZ, BATCHING_OFF);
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testOrientation_50hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_ORIENTATION, RATE_50HZ, BATCHING_OFF);
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testOrientation_25hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_ORIENTATION, RATE_25HZ, BATCHING_OFF);
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testOrientation_15hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_ORIENTATION, RATE_15HZ, BATCHING_OFF);
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testOrientation_10hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_ORIENTATION, RATE_10HZ, BATCHING_OFF);
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testOrientation_5hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_ORIENTATION, RATE_5HZ, BATCHING_OFF);
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testOrientation_1hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_ORIENTATION, RATE_1HZ, BATCHING_OFF);
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testOrientation_fastest_batching() throws Throwable {
+        runSensorTest(Sensor.TYPE_ORIENTATION, SensorManager.SENSOR_DELAY_FASTEST, BATCHING_5S);
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testOrientation_50hz_batching() throws Throwable {
+        runSensorTest(Sensor.TYPE_ORIENTATION, RATE_50HZ, BATCHING_5S);
+    }
+
+    public void testGyroscope_fastest() throws Throwable {
+        runSensorTest(Sensor.TYPE_GYROSCOPE, SensorManager.SENSOR_DELAY_FASTEST, BATCHING_OFF);
+    }
+
+    public void testGyroscope_100hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_GYROSCOPE, RATE_100HZ, BATCHING_OFF);
+    }
+
+    public void testGyroscope_50hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_GYROSCOPE, RATE_50HZ, BATCHING_OFF);
+    }
+
+    public void testGyroscope_25hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_GYROSCOPE, RATE_25HZ, BATCHING_OFF);
+    }
+
+    public void testGyroscope_15hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_GYROSCOPE, RATE_15HZ, BATCHING_OFF);
+    }
+
+    public void testGyroscope_10hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_GYROSCOPE, RATE_10HZ, BATCHING_OFF);
+    }
+
+    public void testGyroscope_5hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_GYROSCOPE, RATE_5HZ, BATCHING_OFF);
+    }
+
+    public void testGyroscope_1hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_GYROSCOPE, RATE_1HZ, BATCHING_OFF);
+    }
+
+    public void testGyroscope_fastest_batching() throws Throwable {
+        runSensorTest(Sensor.TYPE_GYROSCOPE, SensorManager.SENSOR_DELAY_FASTEST, BATCHING_5S);
+    }
+
+    public void testGyroscope_50hz_batching() throws Throwable {
+        runSensorTest(Sensor.TYPE_GYROSCOPE, RATE_50HZ, BATCHING_5S);
+    }
+
+    public void testPressure_fastest() throws Throwable {
+        runSensorTest(Sensor.TYPE_PRESSURE, SensorManager.SENSOR_DELAY_FASTEST, BATCHING_OFF);
+    }
+
+    public void testPressure_100hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_PRESSURE, RATE_100HZ, BATCHING_OFF);
+    }
+
+    public void testPressure_50hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_PRESSURE, RATE_50HZ, BATCHING_OFF);
+    }
+
+    public void testPressure_25hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_PRESSURE, RATE_25HZ, BATCHING_OFF);
+    }
+
+    public void testPressure_15hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_PRESSURE, RATE_15HZ, BATCHING_OFF);
+    }
+
+    public void testPressure_10hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_PRESSURE, RATE_10HZ, BATCHING_OFF);
+    }
+
+    public void testPressure_5hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_PRESSURE, RATE_5HZ, BATCHING_OFF);
+    }
+
+    public void testPressure_1hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_PRESSURE, RATE_1HZ, BATCHING_OFF);
+    }
+
+    public void testPressure_fastest_batching() throws Throwable {
+        runSensorTest(Sensor.TYPE_PRESSURE, SensorManager.SENSOR_DELAY_FASTEST, BATCHING_5S);
+    }
+
+    public void testPressure_50hz_batching() throws Throwable {
+        runSensorTest(Sensor.TYPE_PRESSURE, RATE_50HZ, BATCHING_5S);
+    }
+
+    public void testGravity_fastest() throws Throwable {
+        runSensorTest(Sensor.TYPE_GRAVITY, SensorManager.SENSOR_DELAY_FASTEST, BATCHING_OFF);
+    }
+
+    public void testGravity_100hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_GRAVITY, RATE_100HZ, BATCHING_OFF);
+    }
+
+    public void testGravity_50hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_GRAVITY, RATE_50HZ, BATCHING_OFF);
+    }
+
+    public void testGravity_25hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_GRAVITY, RATE_25HZ, BATCHING_OFF);
+    }
+
+    public void testGravity_15hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_GRAVITY, RATE_15HZ, BATCHING_OFF);
+    }
+
+    public void testGravity_10hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_GRAVITY, RATE_10HZ, BATCHING_OFF);
+    }
+
+    public void testGravity_5hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_GRAVITY, RATE_5HZ, BATCHING_OFF);
+    }
+
+    public void testGravity_1hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_GRAVITY, RATE_1HZ, BATCHING_OFF);
+    }
+
+    public void testGravity_fastest_batching() throws Throwable {
+        runSensorTest(Sensor.TYPE_GRAVITY, SensorManager.SENSOR_DELAY_FASTEST, BATCHING_5S);
+    }
+
+    public void testGravity_50hz_batching() throws Throwable {
+        runSensorTest(Sensor.TYPE_GRAVITY, RATE_50HZ, BATCHING_5S);
+    }
+
+    public void testRotationVector_fastest() throws Throwable {
+        runSensorTest(Sensor.TYPE_ROTATION_VECTOR, SensorManager.SENSOR_DELAY_FASTEST,
+                BATCHING_OFF);
+    }
+    public void testRotationVector_100hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_ROTATION_VECTOR, RATE_100HZ, BATCHING_OFF);
+    }
+
+    public void testRotationVector_50hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_ROTATION_VECTOR, RATE_50HZ, BATCHING_OFF);
+    }
+
+    public void testRotationVector_25hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_ROTATION_VECTOR, RATE_25HZ, BATCHING_OFF);
+    }
+
+    public void testRotationVector_15hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_ROTATION_VECTOR, RATE_15HZ, BATCHING_OFF);
+    }
+
+    public void testRotationVector_10hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_ROTATION_VECTOR, RATE_10HZ, BATCHING_OFF);
+    }
+
+    public void testRotationVector_5hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_ROTATION_VECTOR, RATE_5HZ, BATCHING_OFF);
+    }
+
+    public void testRotationVector_1hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_ROTATION_VECTOR, RATE_1HZ, BATCHING_OFF);
+    }
+
+    public void testRotationVector_fastest_batching() throws Throwable {
+        runSensorTest(Sensor.TYPE_ROTATION_VECTOR, SensorManager.SENSOR_DELAY_FASTEST, BATCHING_5S);
+    }
+
+    public void testRotationVector_50hz_batching() throws Throwable {
+        runSensorTest(Sensor.TYPE_ROTATION_VECTOR, RATE_50HZ, BATCHING_5S);
+    }
+
+    public void testMagneticFieldUncalibrated_fastest() throws Throwable {
+        runSensorTest(Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED, SensorManager.SENSOR_DELAY_FASTEST,
+                BATCHING_OFF);
+    }
+
+    public void testMagneticFieldUncalibrated_100hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED, RATE_100HZ, BATCHING_OFF);
+    }
+
+    public void testMagneticFieldUncalibrated_50hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED, RATE_50HZ, BATCHING_OFF);
+    }
+
+    public void testMagneticFieldUncalibrated_25hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED, RATE_25HZ, BATCHING_OFF);
+    }
+
+    public void testMagneticFieldUncalibrated_15hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED, RATE_15HZ, BATCHING_OFF);
+    }
+
+    public void testMagneticFieldUncalibrated_10hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED, RATE_10HZ, BATCHING_OFF);
+    }
+
+    public void testMagneticFieldUncalibrated_5hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED, RATE_5HZ, BATCHING_OFF);
+    }
+
+    public void testMagneticFieldUncalibrated_1hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED, RATE_1HZ, BATCHING_OFF);
+    }
+
+    public void testMagneticFieldUncalibrated_fastest_batching() throws Throwable {
+        runSensorTest(Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED, SensorManager.SENSOR_DELAY_FASTEST,
+                BATCHING_5S);
+    }
+
+    public void testMagneticFieldUncalibrated_50hz_batching() throws Throwable {
+        runSensorTest(Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED, RATE_50HZ, BATCHING_5S);
+    }
+
+    public void testGameRotationVector_fastest() throws Throwable {
+        runSensorTest(Sensor.TYPE_GAME_ROTATION_VECTOR, SensorManager.SENSOR_DELAY_FASTEST,
+                BATCHING_OFF);
+    }
+
+    public void testGameRotationVector_100hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_GAME_ROTATION_VECTOR, RATE_100HZ, BATCHING_OFF);
+    }
+
+    public void testGameRotationVector_50hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_GAME_ROTATION_VECTOR, RATE_50HZ, BATCHING_OFF);
+    }
+
+    public void testGameRotationVector_25hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_GAME_ROTATION_VECTOR, RATE_25HZ, BATCHING_OFF);
+    }
+
+    public void testGameRotationVector_15hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_GAME_ROTATION_VECTOR, RATE_15HZ, BATCHING_OFF);
+    }
+
+    public void testGameRotationVector_10hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_GAME_ROTATION_VECTOR, RATE_10HZ, BATCHING_OFF);
+    }
+
+    public void testGameRotationVector_5hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_GAME_ROTATION_VECTOR, RATE_5HZ, BATCHING_OFF);
+    }
+
+    public void testGameRotationVector_1hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_GAME_ROTATION_VECTOR, RATE_1HZ, BATCHING_OFF);
+    }
+
+    public void testGameRotationVector_fastest_batching() throws Throwable {
+        runSensorTest(Sensor.TYPE_GAME_ROTATION_VECTOR, SensorManager.SENSOR_DELAY_FASTEST,
+                BATCHING_5S);
+    }
+
+    public void testGameRotationVector_50hz_batching() throws Throwable {
+        runSensorTest(Sensor.TYPE_GAME_ROTATION_VECTOR, RATE_50HZ, BATCHING_5S);
+    }
+
+    public void testGyroscopeUncalibrated_fastest() throws Throwable {
+        runSensorTest(Sensor.TYPE_GYROSCOPE_UNCALIBRATED, SensorManager.SENSOR_DELAY_FASTEST,
+                BATCHING_OFF);
+    }
+
+    public void testGyroscopeUncalibrated_100hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_GYROSCOPE_UNCALIBRATED, RATE_100HZ, BATCHING_OFF);
+    }
+
+    public void testGyroscopeUncalibrated_50hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_GYROSCOPE_UNCALIBRATED, RATE_50HZ, BATCHING_OFF);
+    }
+
+    public void testGyroscopeUncalibrated_25hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_GYROSCOPE_UNCALIBRATED, RATE_25HZ, BATCHING_OFF);
+    }
+
+    public void testGyroscopeUncalibrated_15hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_GYROSCOPE_UNCALIBRATED, RATE_15HZ, BATCHING_OFF);
+    }
+
+    public void testGyroscopeUncalibrated_10hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_GYROSCOPE_UNCALIBRATED, RATE_10HZ, BATCHING_OFF);
+    }
+
+    public void testGyroscopeUncalibrated_5hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_GYROSCOPE_UNCALIBRATED, RATE_5HZ, BATCHING_OFF);
+    }
+
+    public void testGyroscopeUncalibrated_1hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_GYROSCOPE_UNCALIBRATED, RATE_1HZ, BATCHING_OFF);
+    }
+
+    public void testGyroscopeUncalibrated_fastest_batching() throws Throwable {
+        runSensorTest(Sensor.TYPE_GYROSCOPE_UNCALIBRATED, SensorManager.SENSOR_DELAY_FASTEST,
+                BATCHING_5S);
+    }
+
+    public void testGyroscopeUncalibrated_50hz_batching() throws Throwable {
+        runSensorTest(Sensor.TYPE_GYROSCOPE_UNCALIBRATED, RATE_50HZ, BATCHING_5S);
+    }
+
+    public void  testGeomagneticRotationVector_fastest() throws Throwable {
+        runSensorTest(Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR, SensorManager.SENSOR_DELAY_FASTEST,
+                BATCHING_OFF);
+    }
+
+    public void  testGeomagneticRotationVector_100hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR, RATE_100HZ, BATCHING_OFF);
+    }
+
+    public void testGeomagneticRotationVector_50hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR, RATE_50HZ, BATCHING_OFF);
+    }
+
+    public void testGeomagneticRotationVector_25hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR, RATE_25HZ, BATCHING_OFF);
+    }
+
+    public void testGeomagneticRotationVector_15hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR, RATE_15HZ, BATCHING_OFF);
+    }
+
+    public void testGeomagneticRotationVector_10hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR, RATE_10HZ, BATCHING_OFF);
+    }
+
+    public void testGeomagneticRotationVector_5hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR, RATE_5HZ, BATCHING_OFF);
+    }
+
+    public void testGeomagneticRotationVector_1hz() throws Throwable {
+        runSensorTest(Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR, RATE_1HZ, BATCHING_OFF);
+    }
+
+    public void testGeomagneticRotationVector_fastest_batching() throws Throwable {
+        runSensorTest(Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR, SensorManager.SENSOR_DELAY_FASTEST,
+                BATCHING_5S);
+    }
+
+    public void testGeomagneticRotationVector_50hz_batching() throws Throwable {
+        runSensorTest(Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR, RATE_50HZ, BATCHING_5S);
+    }
+
+    private void runSensorTest(int sensorType, int rateUs, int maxBatchReportLatencyUs)
+            throws Throwable {
+        TestSensorOperation op = new TestSensorOperation(this.getContext(), sensorType,
+                rateUs, maxBatchReportLatencyUs, 5, TimeUnit.SECONDS);
+        op.setDefaultVerifications();
+        op.setLogEvents(true);
+        try {
+            op.execute();
+
+            // Only report stats if it passes.
+            logSelectedStatsToReportLog(getInstrumentation(), 2, STAT_KEYS,
+                    op.getStats());
+        } finally {
+            SensorStats.logStats(TAG, op.getStats());
+
+            String sensorName = SensorTestInformation.getSanitizedSensorName(sensorType);
+            String sensorRate;
+            if (rateUs == SensorManager.SENSOR_DELAY_FASTEST) {
+                sensorRate = "fastest";
+            } else {
+                sensorRate = String.format("%.0fhz",
+                        SensorCtsHelper.getFrequency(rateUs, TimeUnit.MICROSECONDS));
+            }
+            String batching = maxBatchReportLatencyUs > 0 ? "_batching" : "";
+            String fileName = String.format("single_sensor_%s_%s%s.txt",
+                    sensorName, sensorRate, batching);
+            SensorStats.logStatsToFile(fileName, op.getStats());
+
+
+        }
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/CollectingSensorEventListener.java b/tests/tests/hardware/src/android/hardware/cts/helpers/CollectingSensorEventListener.java
new file mode 100644
index 0000000..981d74c
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/CollectingSensorEventListener.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2014 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 android.hardware.cts.helpers;
+
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener2;
+import android.os.SystemClock;
+
+import java.util.concurrent.ConcurrentLinkedDeque;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * A {@link TestSensorEventListener} which collects events to be processed after the test is run.
+ * This should only be used for short tests.
+ */
+public class CollectingSensorEventListener extends TestSensorEventListener {
+    private final ConcurrentLinkedDeque<TestSensorEvent> mSensorEventsList =
+            new ConcurrentLinkedDeque<TestSensorEvent>();
+
+    /**
+     * Constructs a {@link CollectingSensorEventListener} with an additional
+     * {@link SensorEventListener2}.
+     */
+    public CollectingSensorEventListener(SensorEventListener2 listener) {
+        super(listener);
+    }
+
+    /**
+     * Constructs a {@link CollectingSensorEventListener}.
+     */
+    public CollectingSensorEventListener() {
+        this(null);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void onSensorChanged(SensorEvent event) {
+        super.onSensorChanged(event);
+        mSensorEventsList.addLast(new TestSensorEvent(event, SystemClock.elapsedRealtimeNanos()));
+    }
+
+    /**
+     * {@inheritDoc}
+     * <p>
+     * Clears the event queue before starting.
+     * </p>
+     */
+    @Override
+    public void waitForEvents(int eventCount) {
+        clearEvents();
+        super.waitForEvents(eventCount);
+    }
+
+    /**
+     * {@inheritDoc}
+     * <p>
+     * Clears the event queue before starting.
+     * </p>
+     */
+    @Override
+    public void waitForEvents(long duration, TimeUnit timeUnit) {
+        clearEvents();
+        super.waitForEvents(duration, timeUnit);
+    }
+
+    /**
+     * Get the {@link TestSensorEvent} array from the event queue.
+     */
+    public TestSensorEvent[] getEvents() {
+        return mSensorEventsList.toArray(new TestSensorEvent[0]);
+    }
+
+    /**
+     * Clear the event queue.
+     */
+    public void clearEvents() {
+        mSensorEventsList.clear();
+    }
+}
\ No newline at end of file
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/FrameworkUnitTests.java b/tests/tests/hardware/src/android/hardware/cts/helpers/FrameworkUnitTests.java
new file mode 100644
index 0000000..6075add
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/FrameworkUnitTests.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2014 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 android.hardware.cts.helpers;
+
+import android.hardware.cts.helpers.sensoroperations.SensorOperationTest;
+import android.hardware.cts.helpers.sensorverification.EventOrderingVerificationTest;
+import android.hardware.cts.helpers.sensorverification.FrequencyVerificationTest;
+import android.hardware.cts.helpers.sensorverification.JitterVerificationTest;
+import android.hardware.cts.helpers.sensorverification.MagnitudeVerificationTest;
+import android.hardware.cts.helpers.sensorverification.MeanVerificationTest;
+import android.hardware.cts.helpers.sensorverification.EventGapVerificationTest;
+import android.hardware.cts.helpers.sensorverification.SigNumVerificationTest;
+import android.hardware.cts.helpers.sensorverification.StandardDeviationVerificationTest;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * Unit test suite for the CTS sensor framework.
+ */
+public class FrameworkUnitTests extends TestSuite {
+
+    public FrameworkUnitTests() {
+        super();
+
+        // helpers
+        addTestSuite(SensorCtsHelperTest.class);
+        addTestSuite(SensorStatsTest.class);
+
+        // sensorverification
+        addTestSuite(EventOrderingVerificationTest.class);
+        addTestSuite(FrequencyVerificationTest.class);
+        addTestSuite(JitterVerificationTest.class);
+        addTestSuite(MagnitudeVerificationTest.class);
+        addTestSuite(MeanVerificationTest.class);
+        addTestSuite(EventGapVerificationTest.class);
+        addTestSuite(SigNumVerificationTest.class);
+        addTestSuite(StandardDeviationVerificationTest.class);
+
+        // sensorOperations
+        addTestSuite(SensorOperationTest.class);
+    }
+
+    public static Test suite() {
+        return new FrameworkUnitTests();
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/SensorCtsHelper.java b/tests/tests/hardware/src/android/hardware/cts/helpers/SensorCtsHelper.java
index 9d860cd..ed55b01 100644
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/SensorCtsHelper.java
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/SensorCtsHelper.java
@@ -18,24 +18,21 @@
 import android.content.Context;
 import android.hardware.Sensor;
 import android.hardware.SensorManager;
-import android.os.Environment;
-import android.util.Log;
 
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.Date;
 import java.util.List;
 import java.util.concurrent.TimeUnit;
 
 /**
  * Set of static helper methods for CTS tests.
  */
+//TODO: Refactor this class and SensorTestInformation into several more well defined helper classes
 public class SensorCtsHelper {
 
+    private static long NANOS_PER_MILLI = 1000000;
+
     /**
      * Private constructor for static class.
      */
@@ -60,61 +57,6 @@
     }
 
     /**
-     * Calculates the mean for each of the values in the set of TestSensorEvents.
-     *
-     * @throws IllegalArgumentException if there are no events
-     */
-    public static double[] getMeans(TestSensorEvent[] events) {
-        if (events.length == 0) {
-            throw new IllegalArgumentException("Events cannot be empty");
-        }
-
-        double[] means = new double[events[0].values.length];
-        for (TestSensorEvent event : events) {
-            for (int i = 0; i < means.length; i++) {
-                means[i] += event.values[i];
-            }
-        }
-        for (int i = 0; i < means.length; i++) {
-            means[i] /= events.length;
-        }
-        return means;
-    }
-
-    /**
-     * Calculates the variance for each of the values in the set of TestSensorEvents.
-     *
-     * @throws IllegalArgumentException if there are no events
-     */
-    public static double[] getVariances(TestSensorEvent[] events) {
-        double[] means = getMeans(events);
-        double[] variances = new double[means.length];
-        for (int i = 0; i < means.length; i++) {
-            Collection<Double> squaredDiffs = new ArrayList<Double>(events.length);
-            for (TestSensorEvent event : events) {
-                double diff = event.values[i] - means[i];
-                squaredDiffs.add(diff * diff);
-            }
-            variances[i] = getMean(squaredDiffs);
-        }
-        return variances;
-    }
-
-    /**
-     * Calculates the standard deviation for each of the values in the set of TestSensorEvents.
-     *
-     * @throws IllegalArgumentException if there are no events
-     */
-    public static double[] getStandardDeviations(TestSensorEvent[] events) {
-        double[] variances = getVariances(events);
-        double[] stdDevs = new double[variances.length];
-        for (int i = 0; i < variances.length; i++) {
-            stdDevs[i] = Math.sqrt(variances[i]);
-        }
-        return stdDevs;
-    }
-
-    /**
      * Calculate the mean of a collection.
      *
      * @throws IllegalArgumentException if the collection is null or empty
@@ -130,7 +72,7 @@
     }
 
     /**
-     * Calculate the variance of a collection.
+     * Calculate the bias-corrected sample variance of a collection.
      *
      * @throws IllegalArgumentException if the collection is null or empty
      */
@@ -138,17 +80,21 @@
         validateCollection(collection);
 
         double mean = getMean(collection);
-        ArrayList<Double> squaredDifferences = new ArrayList<Double>();
+        ArrayList<Double> squaredDiffs = new ArrayList<Double>();
         for(TValue value : collection) {
             double difference = mean - value.doubleValue();
-            squaredDifferences.add(Math.pow(difference, 2));
+            squaredDiffs.add(Math.pow(difference, 2));
         }
 
-        return getMean(squaredDifferences);
+        double sum = 0.0;
+        for (Double value : squaredDiffs) {
+            sum += value;
+        }
+        return sum / (squaredDiffs.size() - 1);
     }
 
     /**
-     * Calculate the standard deviation of a collection.
+     * Calculate the bias-corrected standard deviation of a collection.
      *
      * @throws IllegalArgumentException if the collection is null or empty
      */
@@ -158,89 +104,6 @@
     }
 
     /**
-     * Get a list containing the delay between sensor events.
-     *
-     * @param events The array of {@link TestSensorEvent}.
-     * @return A list containing the delay between sensor events in nanoseconds.
-     */
-    public static List<Long> getTimestampDelayValues(TestSensorEvent[] events) {
-        if (events.length < 2) {
-            return new ArrayList<Long>();
-        }
-        List<Long> timestampDelayValues = new ArrayList<Long>(events.length - 1);
-        for (int i = 1; i < events.length; i++) {
-            timestampDelayValues.add(events[i].timestamp - events[i - 1].timestamp);
-        }
-        return timestampDelayValues;
-    }
-
-    /**
-     * Get a list containing the jitter values for a collection of sensor events.
-     *
-     * @param events The array of {@link TestSensorEvent}.
-     * @return A list containing the jitter values between each event.
-     * @throws IllegalArgumentException if the number of events is less that 2.
-     */
-    public static List<Double> getJitterValues(TestSensorEvent[] events) {
-        List<Long> timestampDelayValues = getTimestampDelayValues(events);
-        double averageTimestampDelay = getMean(timestampDelayValues);
-
-        List<Double> jitterValues = new ArrayList<Double>(timestampDelayValues.size());
-        for (long timestampDelay : timestampDelayValues) {
-            jitterValues.add(Math.abs(timestampDelay - averageTimestampDelay));
-        }
-        return jitterValues;
-    }
-
-    /**
-     * NOTE:
-     * - The bug report is usually written to /sdcard/Downloads
-     * - In order for the test Instrumentation to gather useful data the following permissions are
-     *   required:
-     *      . android.permission.READ_LOGS
-     *      . android.permission.DUMP
-     */
-    public static String collectBugreport(String collectorId)
-            throws IOException, InterruptedException {
-        String commands[] = new String[] {
-                "dumpstate",
-                "dumpsys",
-                "logcat -d -v threadtime",
-                "exit"
-        };
-
-        SimpleDateFormat dateFormat = new SimpleDateFormat("M-d-y_H:m:s.S");
-        String outputFile = String.format(
-                "%s/%s_%s",
-                Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS),
-                collectorId,
-                dateFormat.format(new Date()));
-
-        DataOutputStream processOutput = null;
-        try {
-            Process process = Runtime.getRuntime().exec("/system/bin/sh -");
-            processOutput = new DataOutputStream(process.getOutputStream());
-
-            for(String command : commands) {
-                processOutput.writeBytes(String.format("%s >> %s\n", command, outputFile));
-            }
-
-            processOutput.flush();
-            process.waitFor();
-
-            Log.d(collectorId, String.format("Bug-Report collected at: %s", outputFile));
-        } finally {
-            if(processOutput != null) {
-                try {
-                    processOutput.close();
-                } catch(IOException e) {}
-            }
-        }
-
-        return outputFile;
-    }
-
-    /**
      * Get the default sensor for a given type.
      */
     public static Sensor getSensor(Context context, int sensorType) {
@@ -286,57 +149,79 @@
     }
 
     /**
-     * Format an assertion message.
-     *
-     * @param verificationName The verification name
-     * @param sensor The sensor under test
-     * @param format The additional format string, use "" if blank
-     * @param params The additional format params
-     * @return The formatted string.
+     * Convert the sensor delay or rate in microseconds into delay in microseconds.
+     * <p>
+     * The flags SensorManager.SENSOR_DELAY_[GAME|UI|NORMAL] are not supported since the CDD does
+     * not specify values for these flags. The rate is set to the max of
+     * {@link Sensor#getMinDelay()} and the rate given.
+     * </p>
      */
-    public static String formatAssertionMessage(
-            String verificationName,
-            Sensor sensor,
-            String format,
-            Object ... params) {
-        return formatAssertionMessage(verificationName, null, sensor, format, params);
+    public static int getDelay(Sensor sensor, int rateUs) {
+        if (!isDelayRateTestable(rateUs)) {
+            throw new IllegalArgumentException("rateUs cannot be SENSOR_DELAY_[GAME|UI|NORMAL]");
+        }
+        int delay;
+        if (rateUs == SensorManager.SENSOR_DELAY_FASTEST) {
+            delay = 0;
+        } else {
+            delay = rateUs;
+        }
+        return Math.max(delay, sensor.getMinDelay());
+    }
+
+    /**
+     * Return true if the operation rate is not one of {@link SensorManager#SENSOR_DELAY_GAME},
+     * {@link SensorManager#SENSOR_DELAY_UI}, or {@link SensorManager#SENSOR_DELAY_NORMAL}.
+     */
+    public static boolean isDelayRateTestable(int rateUs) {
+        return (rateUs != SensorManager.SENSOR_DELAY_GAME
+                && rateUs != SensorManager.SENSOR_DELAY_UI
+                && rateUs != SensorManager.SENSOR_DELAY_NORMAL);
+    }
+
+    /**
+     * Helper method to sleep for a given duration.
+     */
+    public static void sleep(long duration, TimeUnit timeUnit) {
+        long durationNs = TimeUnit.NANOSECONDS.convert(duration, timeUnit);
+        try {
+            Thread.sleep(durationNs / NANOS_PER_MILLI, (int) (durationNs % NANOS_PER_MILLI));
+        } catch (InterruptedException e) {
+            // Ignore
+        }
     }
 
     /**
      * Format an assertion message.
      *
-     * @param verificationName The verification name
-     * @param test The test, optional
-     * @param sensor The sensor under test
-     * @param format The additional format string, use "" if blank
-     * @param params The additional format params
-     * @return The formatted string.
+     * @param sensor the {@link Sensor}
+     * @param label the verification name
+     * @param rateUs the rate of the sensor
+     * @param maxBatchReportLatencyUs the max batch report latency of the sensor
+     * @return The formatted string
      */
-    public static String formatAssertionMessage(
-            String verificationName,
-            SensorTestOperation test,
-            Sensor sensor,
-            String format,
-            Object ... params) {
-        StringBuilder builder = new StringBuilder();
+    public static String formatAssertionMessage(Sensor sensor, String label, int rateUs,
+            int maxBatchReportLatencyUs) {
+        return String.format("%s | %s, handle: %d", label,
+                SensorTestInformation.getSensorName(sensor.getType()), sensor.getHandle());
+    }
 
-        // identify the verification
-        builder.append(verificationName);
-        builder.append("| ");
-        // add test context information
-        if(test != null) {
-            builder.append(test.toString());
-            builder.append("| ");
-        }
-        // add context information
-        builder.append(SensorTestInformation.getSensorName(sensor.getType()));
-        builder.append(", handle:");
-        builder.append(sensor.getHandle());
-        builder.append("| ");
-        // add the custom formatting
-        builder.append(String.format(format, params));
-
-        return builder.toString();
+    /**
+     * Format an assertion message with a custom message.
+     *
+     * @param sensor the {@link Sensor}
+     * @param label the verification name
+     * @param rateUs the rate of the sensor
+     * @param maxBatchReportLatencyUs the max batch report latency of the sensor
+     * @param format the additional format string
+     * @param params the additional format params
+     * @return The formatted string
+     */
+    public static String formatAssertionMessage(Sensor sensor, String label, int rateUs,
+            int maxBatchReportLatencyUs, String format, Object ... params) {
+        return String.format("%s | %s, handle: %d, rateUs: %d, maxBatchReportLatencyUs: %d | %s",
+                label, SensorTestInformation.getSensorName(sensor.getType()), sensor.getHandle(),
+                rateUs, maxBatchReportLatencyUs, String.format(format, params));
     }
 
     /**
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/SensorCtsHelperTest.java b/tests/tests/hardware/src/android/hardware/cts/helpers/SensorCtsHelperTest.java
index ccfaf2a..6f99692 100644
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/SensorCtsHelperTest.java
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/SensorCtsHelperTest.java
@@ -53,73 +53,6 @@
     }
 
     /**
-     * Test {@link SensorCtsHelper#getMeans(TestSensorEvent[])}.
-     */
-    public void testGetMeans() {
-        long[] timestamps = {0, 1, 2, 3, 4};
-
-        float[] values = {0, 1, 2, 3, 4};  // 2.0
-        double[] means = SensorCtsHelper.getMeans(getSensorEvents(timestamps, values));
-        assertEquals(1, means.length);
-        assertEquals(2.0, means[0], 0.00001);
-
-        float[] values1 = {0, 1, 2, 3, 4};  // 2.0
-        float[] values2 = {1, 2, 3, 4, 5};  // 3.0
-        float[] values3 = {0, 1, 4, 9, 16};  // 6.0
-        means = SensorCtsHelper.getMeans(
-                getSensorEvents(timestamps, values1, values2, values3));
-        assertEquals(3, means.length);
-        assertEquals(2.0, means[0], 0.00001);
-        assertEquals(3.0, means[1], 0.00001);
-        assertEquals(6.0, means[2], 0.00001);
-    }
-
-    /**
-     * Test {@link SensorCtsHelper#getVariances(TestSensorEvent[])}.
-     */
-    public void testGetVariences() {
-        long[] timestamps = {0, 1, 2, 3, 4};
-
-        float[] values = {0, 1, 2, 3, 4};  // 2.0
-        double[] variances = SensorCtsHelper.getVariances(getSensorEvents(timestamps, values));
-        assertEquals(1, variances.length);
-        assertEquals(2.0, variances[0], 0.00001);
-
-        float[] values1 = {0, 1, 2, 3, 4};  // 2.0
-        float[] values2 = {1, 2, 3, 4, 5};  // 2.0
-        float[] values3 = {0, 2, 4, 6, 8};  // 8.0
-        variances = SensorCtsHelper.getVariances(
-                getSensorEvents(timestamps, values1, values2, values3));
-        assertEquals(3, variances.length);
-        assertEquals(2.0, variances[0], 0.00001);
-        assertEquals(2.0, variances[1], 0.00001);
-        assertEquals(8.0, variances[2], 0.00001);
-    }
-
-    /**
-     * Test {@link SensorCtsHelper#getStandardDeviations(TestSensorEvent[])}.
-     */
-    public void testGetStandardDeviations() {
-        long[] timestamps = {0, 1, 2, 3, 4};
-
-        float[] values = {0, 1, 2, 3, 4};  // sqrt(2.0)
-        double[] stddev = SensorCtsHelper.getStandardDeviations(
-                getSensorEvents(timestamps, values));
-        assertEquals(1, stddev.length);
-        assertEquals(Math.sqrt(2.0), stddev[0], 0.00001);
-
-        float[] values1 = {0, 1, 2, 3, 4};  // sqrt(2.0)
-        float[] values2 = {1, 2, 3, 4, 5};  // sqrt(2.0)
-        float[] values3 = {0, 2, 4, 6, 8};  // sqrt(8.0)
-        stddev = SensorCtsHelper.getStandardDeviations(
-                getSensorEvents(timestamps, values1, values2, values3));
-        assertEquals(3, stddev.length);
-        assertEquals(Math.sqrt(2.0), stddev[0], 0.00001);
-        assertEquals(Math.sqrt(2.0), stddev[1], 0.00001);
-        assertEquals(Math.sqrt(8.0), stddev[2], 0.00001);
-    }
-
-    /**
      * Test {@link SensorCtsHelper#getMean(Collection)}.
      */
     public void testGetMean() {
@@ -142,15 +75,15 @@
     public void testGetVariance() {
         List<Integer> values = Arrays.asList(0, 1, 2, 3, 4);
         double variance = SensorCtsHelper.getVariance(values);
-        assertEquals(2.0, variance, 0.00001);
+        assertEquals(2.5, variance, 0.00001);
 
         values = Arrays.asList(1, 2, 3, 4, 5);
         variance = SensorCtsHelper.getVariance(values);
-        assertEquals(2.0, variance, 0.00001);
+        assertEquals(2.5, variance, 0.00001);
 
         values = Arrays.asList(0, 2, 4, 6, 8);
         variance = SensorCtsHelper.getVariance(values);
-        assertEquals(8.0, variance, 0.00001);
+        assertEquals(10.0, variance, 0.00001);
     }
 
     /**
@@ -159,31 +92,15 @@
     public void testGetStandardDeviation() {
         List<Integer> values = Arrays.asList(0, 1, 2, 3, 4);
         double stddev = SensorCtsHelper.getStandardDeviation(values);
-        assertEquals(Math.sqrt(2.0), stddev, 0.00001);
+        assertEquals(Math.sqrt(2.5), stddev, 0.00001);
 
         values = Arrays.asList(1, 2, 3, 4, 5);
         stddev = SensorCtsHelper.getStandardDeviation(values);
-        assertEquals(Math.sqrt(2.0), stddev, 0.00001);
+        assertEquals(Math.sqrt(2.5), stddev, 0.00001);
 
         values = Arrays.asList(0, 2, 4, 6, 8);
         stddev = SensorCtsHelper.getStandardDeviation(values);
-        assertEquals(Math.sqrt(8.0), stddev, 0.00001);
-    }
-
-    /**
-     * Test {@link SensorCtsHelper#getTimestampDelayValues(TestSensorEvent[])}.
-     */
-    public void testGetTimestampDelayValues() {
-        float[] values = {0, 1, 2, 3, 4};
-
-        long[] timestamps = {0, 0, 1, 3, 100};
-        List<Long> timestampDelayValues = SensorCtsHelper.getTimestampDelayValues(
-                getSensorEvents(timestamps, values));
-        assertEquals(4, timestampDelayValues.size());
-        assertEquals(0, (long) timestampDelayValues.get(0));
-        assertEquals(1, (long) timestampDelayValues.get(1));
-        assertEquals(2, (long) timestampDelayValues.get(2));
-        assertEquals(97, (long) timestampDelayValues.get(3));
+        assertEquals(Math.sqrt(10.0), stddev, 0.00001);
     }
 
     /**
@@ -217,50 +134,4 @@
         assertEquals(100, SensorCtsHelper.getPeriod(10000000, TimeUnit.NANOSECONDS), 0.001);
         assertEquals(1, SensorCtsHelper.getPeriod(1000000000, TimeUnit.NANOSECONDS), 0.001);
     }
-
-    /**
-     * Test {@link SensorCtsHelper#getJitterValues(TestSensorEvent[])}.
-     */
-    public void testGetJitterValues() {
-        float[] values = {0, 1, 2, 3, 4};
-
-        long[] timestamps1 = {0, 1, 2, 3, 4};
-        List<Double> jitterValues = SensorCtsHelper.getJitterValues(
-                getSensorEvents(timestamps1, values));
-        assertEquals(4, jitterValues.size());
-        assertEquals(0.0, (double) jitterValues.get(0));
-        assertEquals(0.0, (double) jitterValues.get(1));
-        assertEquals(0.0, (double) jitterValues.get(2));
-        assertEquals(0.0, (double) jitterValues.get(3));
-
-        long[] timestamps2 = {0, 0, 2, 4, 4};
-        jitterValues = SensorCtsHelper.getJitterValues(
-                getSensorEvents(timestamps2, values));
-        assertEquals(4, jitterValues.size());
-        assertEquals(1.0, (double) jitterValues.get(0));
-        assertEquals(1.0, (double) jitterValues.get(1));
-        assertEquals(1.0, (double) jitterValues.get(2));
-        assertEquals(1.0, (double) jitterValues.get(3));
-
-        long[] timestamps3 = {0, 1, 4, 9, 16};
-        jitterValues = SensorCtsHelper.getJitterValues(
-                getSensorEvents(timestamps3, values));
-        assertEquals(4, jitterValues.size());
-        assertEquals(3.0, (double) jitterValues.get(0));
-        assertEquals(1.0, (double) jitterValues.get(1));
-        assertEquals(1.0, (double) jitterValues.get(2));
-        assertEquals(3.0, (double) jitterValues.get(3));
-    }
-
-    private TestSensorEvent[] getSensorEvents(long[] timestamps, float[] ... values) {
-        TestSensorEvent[] events = new TestSensorEvent[timestamps.length];
-        for (int i = 0; i < timestamps.length; i++) {
-            float[] eventValues = new float[values.length];
-            for (int j = 0; j < values.length; j++) {
-                eventValues[j] = values[j][i];
-            }
-            events[i] = new TestSensorEvent(null, timestamps[i], 0, eventValues);
-        }
-        return events;
-    }
 }
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/SensorManagerTestVerifier.java b/tests/tests/hardware/src/android/hardware/cts/helpers/SensorManagerTestVerifier.java
deleted file mode 100644
index 85f4f0e..0000000
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/SensorManagerTestVerifier.java
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * Copyright (C) 2013 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 android.hardware.cts.helpers;
-
-import android.content.Context;
-import android.hardware.Sensor;
-import android.hardware.SensorEvent;
-import android.hardware.SensorEventListener2;
-import android.hardware.SensorManager;
-
-import junit.framework.Assert;
-
-import java.io.Closeable;
-import java.security.InvalidParameterException;
-import java.util.concurrent.ConcurrentLinkedDeque;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Test class to wrap SensorManager with verifications and test checks.
- * This class allows to perform operations in the Sensor Manager and performs all the expected test
- * verification on behalf of the owner.
- * An object can be used to quickly writing tests that focus on the scenario that needs to be
- * verified, and not in the implicit verifications that need to take place at any step.
- */
-public class SensorManagerTestVerifier implements Closeable, SensorEventListener2 {
-    private final int WAIT_TIMEOUT_IN_SECONDS = 30;
-
-    private final SensorManager mSensorManager;
-    private final Sensor mSensorUnderTest;
-    private final int mSamplingRateInUs;
-    private final int mReportLatencyInUs;
-
-    private TestSensorListener mEventListener;
-
-    /**
-     * Construction methods.
-     */
-    public SensorManagerTestVerifier(
-            Context context,
-            int sensorType,
-            int samplingRateInUs,
-            int reportLatencyInUs) {
-        mSensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
-        mSensorUnderTest = SensorCtsHelper.getSensor(context, sensorType);
-        mSamplingRateInUs = samplingRateInUs;
-        mReportLatencyInUs = reportLatencyInUs;
-
-        mEventListener = new TestSensorListener(mSensorUnderTest, this);
-    }
-
-    /**
-     * {@inheritDoc}
-     * <p>
-     * Available for subclasses to implement if they need access to the raw eventing model.
-     * </p>
-     */
-    @Override
-    public void onAccuracyChanged(Sensor sensor, int accuracy) {}
-
-    /**
-     * {@inheritDoc}
-     * <p>
-     * Available for subclasses to implement if they need access to the raw eventing model.
-     * </p>
-     */
-    @Override
-    public void onSensorChanged(SensorEvent event) {}
-
-    /**
-     * {@inheritDoc}
-     * <p>
-     * Available for subclasses to implement if they need access to the raw eventing model.
-     * </p>
-     */
-    @Override
-    public void onFlushCompleted(Sensor sensor) {}
-
-    /**
-     * Closes the {@link SensorManagerTestVerifier} and unregister the listener.
-     */
-    @Override
-    public void close() {
-        this.unregisterListener();
-        mEventListener = null;
-    }
-
-    /**
-     * Get the sensor under test.
-     */
-    public Sensor getUnderlyingSensor() {
-        return mSensorUnderTest;
-    }
-
-    /**
-     * Register the
-     * @param debugInfo
-     */
-    public void registerListener(String debugInfo) {
-        boolean result = mSensorManager.registerListener(
-                mEventListener,
-                mSensorUnderTest,
-                mSamplingRateInUs,
-                mReportLatencyInUs);
-        String message = SensorCtsHelper.formatAssertionMessage(
-                "registerListener",
-                mSensorUnderTest,
-                debugInfo);
-        Assert.assertTrue(message, result);
-    }
-
-    public void registerListener() {
-        this.registerListener("");
-    }
-
-    public void unregisterListener() {
-        mSensorManager.unregisterListener(mEventListener, mSensorUnderTest);
-    }
-
-    public TestSensorEvent[] getEvents(int count, String debugInfo) {
-        mEventListener.waitForEvents(count, debugInfo);
-        TestSensorEvent[] events = mEventListener.getAllEvents();
-        mEventListener.clearEvents();
-
-        return events;
-    }
-
-    public TestSensorEvent[] getEvents(int count) {
-        return this.getEvents(count, "");
-    }
-
-    public TestSensorEvent[] getQueuedEvents() {
-        return mEventListener.getAllEvents();
-    }
-
-    public TestSensorEvent[] collectEvents(int eventCount, String debugInfo) {
-        this.registerListener(debugInfo);
-        TestSensorEvent[] events = this.getEvents(eventCount, debugInfo);
-        this.unregisterListener();
-
-        return events;
-    }
-
-    public TestSensorEvent[] collectEvents(int eventCount) {
-        return this.collectEvents(eventCount, "");
-    }
-
-    public void startFlush() {
-        String message = SensorCtsHelper.formatAssertionMessage(
-                "Flush",
-                mSensorUnderTest,
-                "" /* format */);
-        Assert.assertTrue(message, mSensorManager.flush(mEventListener));
-    }
-
-    public void waitForFlush() throws InterruptedException {
-        mEventListener.waitForFlushComplete();
-    }
-
-    public void flush() throws InterruptedException {
-        this.startFlush();
-        this.waitForFlush();
-    }
-
-    /**
-     * Definition of support test classes.
-     */
-    private class TestSensorListener implements SensorEventListener2 {
-        private final Sensor mSensorUnderTest;
-        private final SensorEventListener2 mListener;
-
-        private final ConcurrentLinkedDeque<TestSensorEvent> mSensorEventsList =
-                new ConcurrentLinkedDeque<TestSensorEvent>();
-
-        private volatile CountDownLatch mEventLatch;
-        private volatile CountDownLatch mFlushLatch = new CountDownLatch(1);
-
-        public TestSensorListener(Sensor sensor, SensorEventListener2 listener) {
-            if(sensor == null) {
-                throw new InvalidParameterException("sensor cannot be null");
-            }
-            if(listener == null) {
-                throw new InvalidParameterException("listener cannot be null");
-            }
-            mSensorUnderTest = sensor;
-            mListener = listener;
-        }
-
-        @Override
-        public void onSensorChanged(SensorEvent event) {
-            // copy the event because there is no better way to do this in the platform
-            mSensorEventsList.addLast(new TestSensorEvent(event));
-            if(mEventLatch != null) {
-                mEventLatch.countDown();
-            }
-            mListener.onSensorChanged(event);
-        }
-
-        @Override
-        public void onAccuracyChanged(Sensor sensor, int accuracy) {
-            mListener.onAccuracyChanged(sensor, accuracy);
-        }
-
-        @Override
-        public void onFlushCompleted(Sensor sensor) {
-            CountDownLatch latch = mFlushLatch;
-            mFlushLatch = new CountDownLatch(1);
-            if(latch != null) {
-                latch.countDown();
-            }
-            mListener.onFlushCompleted(sensor);
-        }
-
-        public void waitForFlushComplete() throws InterruptedException {
-            CountDownLatch latch = mFlushLatch;
-            if(latch != null) {
-                String message = SensorCtsHelper.formatAssertionMessage(
-                        "WaitForFlush",
-                        mSensorUnderTest,
-                        "" /* format */);
-                Assert.assertTrue(message, latch.await(WAIT_TIMEOUT_IN_SECONDS, TimeUnit.SECONDS));
-            }
-        }
-
-        public void waitForEvents(int eventCount, String timeoutInfo) {
-            mEventLatch = new CountDownLatch(eventCount);
-            this.clearEvents();
-            try {
-                boolean awaitCompleted = mEventLatch.await(WAIT_TIMEOUT_IN_SECONDS, TimeUnit.SECONDS);
-                // TODO: can we collect bug reports on error based only if needed? env var?
-
-                String message = SensorCtsHelper.formatAssertionMessage(
-                        "WaitForEvents",
-                        mSensorUnderTest,
-                        "count:%d, available:%d, %s",
-                        eventCount,
-                        mSensorEventsList.size(),
-                        timeoutInfo);
-                Assert.assertTrue(message, awaitCompleted);
-            } catch(InterruptedException e) {
-            } finally {
-                mEventLatch = null;
-            }
-        }
-
-        public TestSensorEvent[] getAllEvents() {
-            return mSensorEventsList.toArray(new TestSensorEvent[0]);
-        }
-
-        public void clearEvents() {
-            mSensorEventsList.clear();
-        }
-    }
-}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/SensorStats.java b/tests/tests/hardware/src/android/hardware/cts/helpers/SensorStats.java
new file mode 100644
index 0000000..1a500d4
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/SensorStats.java
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2014 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 android.hardware.cts.helpers;
+
+import android.hardware.cts.helpers.sensoroperations.ISensorOperation;
+import android.os.Environment;
+import android.util.Log;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+/**
+ * Class used to store stats related to {@link ISensorOperation}s.  Sensor stats may be linked
+ * together so that they form a tree.
+ */
+public class SensorStats {
+    public static final String DELIMITER = "__";
+
+    public static final String FIRST_TIMESTAMP_KEY = "first_timestamp";
+    public static final String LAST_TIMESTAMP_KEY = "last_timestamp";
+    public static final String ERROR = "error";
+    public static final String EVENT_COUNT_KEY = "event_count";
+    public static final String EVENT_GAP_COUNT_KEY = "event_gap_count";
+    public static final String EVENT_GAP_POSITIONS_KEY = "event_gap_positions";
+    public static final String EVENT_OUT_OF_ORDER_COUNT_KEY = "event_out_of_order_count";
+    public static final String EVENT_OUT_OF_ORDER_POSITIONS_KEY = "event_out_of_order_positions";
+    public static final String FREQUENCY_KEY = "frequency";
+    public static final String JITTER_95_PERCENTILE_KEY = "jitter_95_percentile";
+    public static final String MEAN_KEY = "mean";
+    public static final String STANDARD_DEVIATION_KEY = "standard_deviation";
+    public static final String MAGNITUDE_KEY = "magnitude";
+
+    private final Map<String, Object> mValues = new HashMap<String, Object>();
+    private final Map<String, SensorStats> mSensorStats = new HashMap<String, SensorStats>();
+
+    /**
+     * Add a value.
+     *
+     * @param key the key.
+     * @param value the value as an {@link Object}.
+     */
+    public synchronized void addValue(String key, Object value) {
+        if (value == null) {
+            return;
+        }
+        mValues.put(key, value);
+    }
+
+    /**
+     * Add a nested {@link SensorStats}. This is useful for keeping track of stats in a
+     * {@link ISensorOperation} tree.
+     *
+     * @param key the key
+     * @param stats the sub {@link SensorStats} object.
+     */
+    public synchronized void addSensorStats(String key, SensorStats stats) {
+        if (stats == null) {
+            return;
+        }
+        mSensorStats.put(key, stats);
+    }
+
+    /**
+     * Get the keys from the values table. Will not get the keys from the nested
+     * {@link SensorStats}.
+     */
+    public synchronized Set<String> getKeys() {
+        return mValues.keySet();
+    }
+
+    /**
+     * Get a value from the values table. Will not attempt to get values from nested
+     * {@link SensorStats}.
+     */
+    public synchronized Object getValue(String key) {
+        return mValues.get(key);
+    }
+
+    /**
+     * Flattens the map and all sub {@link SensorStats} objects. Keys will be flattened using
+     * {@value #DELIMITER}. For example, if a sub {@link SensorStats} is added with key
+     * {@code "key1"} containing the key value pair {@code ("key2", "value")}, the flattened map
+     * will contain the entry {@code ("key1__key2", "value")}.
+     *
+     * @return a {@link Map} containing all stats from the value and sub {@link SensorStats}.
+     */
+    public synchronized Map<String, Object> flatten() {
+        final Map<String, Object> flattenedMap = new HashMap<String, Object>(mValues);
+        for (Entry<String, SensorStats> statsEntry : mSensorStats.entrySet()) {
+            for (Entry<String, Object> valueEntry : statsEntry.getValue().flatten().entrySet()) {
+                String key = statsEntry.getKey() + DELIMITER + valueEntry.getKey();
+                flattenedMap.put(key, valueEntry.getValue());
+            }
+        }
+        return flattenedMap;
+    }
+
+    /**
+     * Utility method to log the stats to the logcat.
+     */
+    public static void logStats(String tag, SensorStats stats) {
+        final Map<String, Object> flattened = stats.flatten();
+        for (String key : getSortedKeys(flattened)) {
+            Object value = flattened.get(key);
+            Log.v(tag, String.format("%s: %s", key, getValueString(value)));
+        }
+    }
+
+    /**
+     * Utility method to log the stats to a file. Will overwrite the file if it already exists.
+     */
+    public static void logStatsToFile(String fileName, SensorStats stats) throws IOException {
+        final BufferedWriter writer = new BufferedWriter(new FileWriter(
+                new File(Environment.getExternalStorageDirectory(), fileName), false));
+        final Map<String, Object> flattened = stats.flatten();
+        try {
+            for (String key : getSortedKeys(flattened)) {
+                Object value = flattened.get(key);
+                writer.write(String.format("%s: %s\n", key, getValueString(value)));
+            }
+        } finally {
+            writer.flush();
+            writer.close();
+        }
+    }
+
+    private static List<String> getSortedKeys(Map<String, Object> flattenedStats) {
+        List<String> keys = new ArrayList<String>(flattenedStats.keySet());
+        Collections.sort(keys);
+        return keys;
+    }
+
+    private static String getValueString(Object value) {
+        if (value == null) {
+            return "";
+        } else if (value instanceof boolean[]) {
+            return Arrays.toString((boolean[]) value);
+        } else if (value instanceof byte[]) {
+            return Arrays.toString((byte[]) value);
+        } else if (value instanceof char[]) {
+            return Arrays.toString((char[]) value);
+        } else if (value instanceof double[]) {
+            return Arrays.toString((double[]) value);
+        } else if (value instanceof float[]) {
+            return Arrays.toString((float[]) value);
+        } else if (value instanceof int[]) {
+            return Arrays.toString((int[]) value);
+        } else if (value instanceof long[]) {
+            return Arrays.toString((long[]) value);
+        } else if (value instanceof short[]) {
+            return Arrays.toString((short[]) value);
+        } else if (value instanceof Object[]) {
+            return Arrays.toString((Object[]) value);
+        } else {
+            return value.toString();
+        }
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/SensorStatsTest.java b/tests/tests/hardware/src/android/hardware/cts/helpers/SensorStatsTest.java
new file mode 100644
index 0000000..8ba0f41
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/SensorStatsTest.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2014 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 android.hardware.cts.helpers;
+
+import junit.framework.TestCase;
+
+import java.util.Map;
+
+/**
+ * Unit tests for the {@link SensorStats} class.
+ */
+public class SensorStatsTest extends TestCase {
+
+    /**
+     * Test that {@link SensorStats#flatten()} works correctly.
+     */
+    public void testFlatten() {
+        SensorStats stats = new SensorStats();
+        stats.addValue("value0", 0);
+        stats.addValue("value1", 1);
+
+        SensorStats subStats = new SensorStats();
+        subStats.addValue("value2", 2);
+        subStats.addValue("value3", 3);
+
+        SensorStats subSubStats = new SensorStats();
+        subSubStats.addValue("value4", 4);
+        subSubStats.addValue("value5", 5);
+
+        subStats.addSensorStats("stats1", subSubStats);
+        stats.addSensorStats("stats0", subStats);
+
+        // Add empty stats, expect no value in flattened map
+        stats.addSensorStats("stats2", new SensorStats());
+
+        // Add null values, expect no value in flattened map
+        stats.addSensorStats("stats3", null);
+        stats.addValue("value6", null);
+
+        Map<String, Object> flattened = stats.flatten();
+
+        assertEquals(6, flattened.size());
+        assertEquals(0, (int) (Integer) flattened.get("value0"));
+        assertEquals(1, (int) (Integer) flattened.get("value1"));
+        assertEquals(2, (int) (Integer) flattened.get("stats0__value2"));
+        assertEquals(3, (int) (Integer) flattened.get("stats0__value3"));
+        assertEquals(4, (int) (Integer) flattened.get("stats0__stats1__value4"));
+        assertEquals(5, (int) (Integer) flattened.get("stats0__stats1__value5"));
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/SensorTestCase.java b/tests/tests/hardware/src/android/hardware/cts/helpers/SensorTestCase.java
deleted file mode 100644
index 4bd0eed..0000000
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/SensorTestCase.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2013 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 android.hardware.cts.helpers;
-
-import android.test.AndroidTestCase;
-
-import android.util.Log;
-
-/**
- * Test Case class that handles gracefully sensors that are not available in the device.
- */
-public abstract class SensorTestCase extends AndroidTestCase {
-    protected final String LOG_TAG = "TestRunner";
-
-    protected SensorTestCase() {}
-
-    @Override
-    public void runTest() throws Throwable {
-        try {
-            super.runTest();
-        } catch (SensorNotSupportedException e) {
-            // the sensor is not supported/available in the device, log a warning and skip the test
-            Log.w(LOG_TAG, e.getMessage());
-        }
-    }
-}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/SensorTestInformation.java b/tests/tests/hardware/src/android/hardware/cts/helpers/SensorTestInformation.java
index 90e0706..b220b00 100644
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/SensorTestInformation.java
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/SensorTestInformation.java
@@ -16,137 +16,149 @@
 
 package android.hardware.cts.helpers;
 
-import android.content.Context;
-
 import android.hardware.Sensor;
 
-import java.security.InvalidParameterException;
-
 /**
  * A 'property' bag of sensor information used for testing purposes.
  */
+// TODO: Refactor this class and SensorCtsHelper into several more well defined helper classes
 public class SensorTestInformation {
     private SensorTestInformation() {}
 
-    public static int getAxisCount(int sensorType) {
+    public enum SensorReportingMode {
+        CONTINUOUS,
+        ON_CHANGE,
+        ONE_SHOT,
+    }
+
+    @SuppressWarnings("deprecation")
+    public static SensorReportingMode getReportingMode(int sensorType) {
         switch(sensorType) {
             case Sensor.TYPE_ACCELEROMETER:
-                return 3;
             case Sensor.TYPE_MAGNETIC_FIELD:
-                return 3;
-//            case Sensor.TYPE_ORIENTATION:
-//                return "Orientation";
+            case Sensor.TYPE_ORIENTATION:
             case Sensor.TYPE_GYROSCOPE:
-                return 3;
-//            case Sensor.TYPE_LIGHT:
-//                return "Light";
-//            case Sensor.TYPE_PRESSURE:
-//                return "Pressure";
-//            case Sensor.TYPE_TEMPERATURE:
-//                return "Temperature";
-//            case Sensor.TYPE_PROXIMITY:
-//                return "Proximity";
+            case Sensor.TYPE_PRESSURE:
             case Sensor.TYPE_GRAVITY:
-                return 3;
             case Sensor.TYPE_LINEAR_ACCELERATION:
-                return 3;
-//            case Sensor.TYPE_ROTATION_VECTOR:
-//                return "Rotation Vector";
-//            case Sensor.TYPE_RELATIVE_HUMIDITY:
-//                return "Relative Humidity";
-//            case Sensor.TYPE_AMBIENT_TEMPERATURE:
-//                return "Ambient Temperature";
-//            case Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED:
-//                return "Magnetic Field Uncalibrated";
-//            case Sensor.TYPE_GAME_ROTATION_VECTOR:
-//                return "Game Rotation Vector";
-//            case Sensor.TYPE_GYROSCOPE_UNCALIBRATED:
-//                return "Gyroscope Uncalibrated";
-//            case Sensor.TYPE_SIGNIFICANT_MOTION:
-//                return "Significant Motion";
-//            case Sensor.TYPE_STEP_DETECTOR:
-//                return "Step Detector";
-//            case Sensor.TYPE_STEP_COUNTER:
-//                return "Step Counter";
-//            case Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR:
-//                return "Geomagnetic Rotation Vector";
+            case Sensor.TYPE_ROTATION_VECTOR:
+            case Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED:
+            case Sensor.TYPE_GAME_ROTATION_VECTOR:
+            case Sensor.TYPE_GYROSCOPE_UNCALIBRATED:
+            case Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR:
+                return SensorReportingMode.CONTINUOUS;
+            case Sensor.TYPE_LIGHT:
+            case Sensor.TYPE_TEMPERATURE:
+            case Sensor.TYPE_PROXIMITY:
+            case Sensor.TYPE_RELATIVE_HUMIDITY:
+            case Sensor.TYPE_AMBIENT_TEMPERATURE:
+            case Sensor.TYPE_STEP_DETECTOR:
+            case Sensor.TYPE_STEP_COUNTER:
+                return SensorReportingMode.ON_CHANGE;
+            case Sensor.TYPE_SIGNIFICANT_MOTION:
+                return SensorReportingMode.ONE_SHOT;
             default:
-                throw new InvalidParameterException(
-                        String.format("Invalid sensorType:%d. Unable to find axis count.", sensorType));
+                return null;
         }
     }
 
     public static String getSensorName(int sensorType) {
-        String name;
-        switch(sensorType) {
-            case Sensor.TYPE_ACCELEROMETER:
-                name = "Accelerometer";
-                break;
-            case Sensor.TYPE_MAGNETIC_FIELD:
-                name = "Magnetic Field";
-                break;
-            case Sensor.TYPE_ORIENTATION:
-                name = "Orientation";
-                break;
-            case Sensor.TYPE_GYROSCOPE:
-                name = "Gyroscope";
-                break;
-            case Sensor.TYPE_LIGHT:
-                name = "Light";
-                break;
-            case Sensor.TYPE_PRESSURE:
-                name = "Pressure";
-                break;
-            case Sensor.TYPE_TEMPERATURE:
-                name = "Temperature";
-                break;
-            case Sensor.TYPE_PROXIMITY:
-                name = "Proximity";
-                break;
-            case Sensor.TYPE_GRAVITY:
-                name = "Gravity";
-                break;
-            case Sensor.TYPE_LINEAR_ACCELERATION:
-                name = "Linear Acceleration";
-                break;
-            case Sensor.TYPE_ROTATION_VECTOR:
-                name = "Rotation Vector";
-                break;
-            case Sensor.TYPE_RELATIVE_HUMIDITY:
-                name = "Relative Humidity";
-                break;
-            case Sensor.TYPE_AMBIENT_TEMPERATURE:
-                name = "Ambient Temperature";
-                break;
-            case Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED:
-                name = "Magnetic Field Uncalibrated";
-                break;
-            case Sensor.TYPE_GAME_ROTATION_VECTOR:
-                name = "Game Rotation Vector";
-                break;
-            case Sensor.TYPE_GYROSCOPE_UNCALIBRATED:
-                name = "Gyroscope Uncalibrated";
-                break;
-            case Sensor.TYPE_SIGNIFICANT_MOTION:
-                name = "Significant Motion";
-                break;
-            case Sensor.TYPE_STEP_DETECTOR:
-                name = "Step Detector";
-                break;
-            case Sensor.TYPE_STEP_COUNTER:
-                name = "Step Counter";
-                break;
-            case Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR:
-                name = "Geomagnetic Rotation Vector";
-                break;
-            default:
-                name = "<Unknown>";
-        }
-        return String.format("%s (%d)", name, sensorType);
+        return String.format("%s (%d)", getSimpleSensorName(sensorType), sensorType);
     }
 
-    public static int getMaxSamplingRateInUs(Context context, int sensorType) {
-        Sensor sensor = SensorCtsHelper.getSensor(context, sensorType);
-        return sensor.getMinDelay();
+    @SuppressWarnings("deprecation")
+    public static String getSimpleSensorName(int sensorType) {
+        switch(sensorType) {
+            case Sensor.TYPE_ACCELEROMETER:
+                return "Accelerometer";
+            case Sensor.TYPE_MAGNETIC_FIELD:
+                return "Magnetic Field";
+            case Sensor.TYPE_ORIENTATION:
+                return "Orientation";
+            case Sensor.TYPE_GYROSCOPE:
+                return "Gyroscope";
+            case Sensor.TYPE_LIGHT:
+                return "Light";
+            case Sensor.TYPE_PRESSURE:
+                return "Pressure";
+            case Sensor.TYPE_TEMPERATURE:
+                return "Temperature";
+            case Sensor.TYPE_PROXIMITY:
+                return "Proximity";
+            case Sensor.TYPE_GRAVITY:
+                return "Gravity";
+            case Sensor.TYPE_LINEAR_ACCELERATION:
+                return "Linear Acceleration";
+            case Sensor.TYPE_ROTATION_VECTOR:
+                return "Rotation Vector";
+            case Sensor.TYPE_RELATIVE_HUMIDITY:
+                return "Relative Humidity";
+            case Sensor.TYPE_AMBIENT_TEMPERATURE:
+                return "Ambient Temperature";
+            case Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED:
+                return "Magnetic Field Uncalibrated";
+            case Sensor.TYPE_GAME_ROTATION_VECTOR:
+                return "Game Rotation Vector";
+            case Sensor.TYPE_GYROSCOPE_UNCALIBRATED:
+                return "Gyroscope Uncalibrated";
+            case Sensor.TYPE_SIGNIFICANT_MOTION:
+                return "Significant Motion";
+            case Sensor.TYPE_STEP_DETECTOR:
+                return "Step Detector";
+            case Sensor.TYPE_STEP_COUNTER:
+                return "Step Counter";
+            case Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR:
+                return "Geomagnetic Rotation Vector";
+            default:
+                return "<Unknown>";
+        }
+    }
+
+    @SuppressWarnings("deprecation")
+    public static String getSanitizedSensorName(int sensorType) {
+        switch(sensorType) {
+            case Sensor.TYPE_ACCELEROMETER:
+                return "Accelerometer";
+            case Sensor.TYPE_MAGNETIC_FIELD:
+                return "MagneticField";
+            case Sensor.TYPE_ORIENTATION:
+                return "Orientation";
+            case Sensor.TYPE_GYROSCOPE:
+                return "Gyroscope";
+            case Sensor.TYPE_LIGHT:
+                return "Light";
+            case Sensor.TYPE_PRESSURE:
+                return "Pressure";
+            case Sensor.TYPE_TEMPERATURE:
+                return "Temperature";
+            case Sensor.TYPE_PROXIMITY:
+                return "Proximity";
+            case Sensor.TYPE_GRAVITY:
+                return "Gravity";
+            case Sensor.TYPE_LINEAR_ACCELERATION:
+                return "LinearAcceleration";
+            case Sensor.TYPE_ROTATION_VECTOR:
+                return "RotationVector";
+            case Sensor.TYPE_RELATIVE_HUMIDITY:
+                return "RelativeHumidity";
+            case Sensor.TYPE_AMBIENT_TEMPERATURE:
+                return "AmbientTemperature";
+            case Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED:
+                return "MagneticFieldUncalibrated";
+            case Sensor.TYPE_GAME_ROTATION_VECTOR:
+                return "GameRotationVector";
+            case Sensor.TYPE_GYROSCOPE_UNCALIBRATED:
+                return "GyroscopeUncalibrated";
+            case Sensor.TYPE_SIGNIFICANT_MOTION:
+                return "SignificantMotion";
+            case Sensor.TYPE_STEP_DETECTOR:
+                return "StepDetector";
+            case Sensor.TYPE_STEP_COUNTER:
+                return "StepCounter";
+            case Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR:
+                return "GeomagneticRotationVector";
+            default:
+                return String.format("UnknownSensorType%d", sensorType);
+        }
     }
 }
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/SensorTestOperation.java b/tests/tests/hardware/src/android/hardware/cts/helpers/SensorTestOperation.java
deleted file mode 100644
index 902c802..0000000
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/SensorTestOperation.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright (C) 2013 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 android.hardware.cts.helpers;
-
-import junit.framework.Assert;
-
-import java.util.concurrent.TimeUnit;
-
-/**
- * Base test class that supports a basic test operation performed in a sensor.
- * The class follows a command patter as a base for its work.
- *
- * Remarks:
- * - The class wraps verifications and test checks that are needed to verify the operation.
- * - The operation runs in a background thread where it performs the bulk of its work.
- */
-public abstract class SensorTestOperation {
-    private final SensorTestExceptionHandler mExceptionHandler = new SensorTestExceptionHandler();
-
-    protected final String LOG_TAG = "TestRunner";
-    protected final long WAIT_TIMEOUT_IN_MILLISECONDS =
-            TimeUnit.MILLISECONDS.convert(5, TimeUnit.MINUTES);
-
-    private Thread mThread;
-
-    protected int mIterationCount;
-
-    /**
-     * Public API definition.
-     */
-    public synchronized void start() throws Throwable {
-        if(mThread != null) {
-            throw new IllegalStateException("The operation has already been started.");
-        }
-
-        mThread = new Thread() {
-            @Override
-            public void run() {
-                try {
-                    doWork();
-                } catch (Throwable e) {
-                    // log the exception so it can be sent back to the appropriate test thread
-                    this.getUncaughtExceptionHandler().uncaughtException(this, e);
-                }
-            }
-        };
-
-        ++mIterationCount;
-        mThread.setUncaughtExceptionHandler(mExceptionHandler);
-        mThread.start();
-    }
-
-    public synchronized void waitForCompletion() throws Throwable {
-        if(mThread == null) {
-            // let a wait on a stopped operation to be no-op
-            return;
-        }
-        mThread.join(WAIT_TIMEOUT_IN_MILLISECONDS);
-        if(mThread.isAlive()) {
-            // the test is hung so collect the state of the system and fail
-            String operationName = this.getClass().getSimpleName();
-            String message = String.format(
-                    "%s hung. %s. BugReport collected at: %s",
-                    operationName,
-                    this.toString(),
-                    SensorCtsHelper.collectBugreport(operationName));
-            Assert.fail(message);
-        }
-        mThread = null;
-        mExceptionHandler.rethrow();
-    }
-
-    public void execute() throws Throwable {
-        this.start();
-        this.waitForCompletion();
-    }
-
-    @Override
-    public String toString() {
-        return String.format("ThreadId:%d, Iteration:%d", mThread.getId(), mIterationCount);
-    }
-
-    /**
-     * Subclasses implement this method to perform the work associated with the operation they
-     * represent.
-     */
-    protected abstract void doWork() throws Throwable;
-
-    /**
-     * Private helpers.
-     */
-    private class SensorTestExceptionHandler implements Thread.UncaughtExceptionHandler {
-        private final Object mLock = new Object();
-
-        private Throwable mThrowable;
-
-        @Override
-        public void uncaughtException(Thread thread, Throwable throwable) {
-            synchronized(mLock) {
-                // the fist exception is in general the one that is more interesting
-                if(mThrowable != null) {
-                    return;
-                }
-                mThrowable = throwable;
-            }
-        }
-
-        public void rethrow() throws Throwable {
-            Throwable throwable;
-            synchronized(mLock) {
-                throwable = mThrowable;
-                mThrowable = null;
-            }
-            if(throwable != null) {
-                throw throwable;
-            }
-        }
-    }
-}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/SensorVerificationHelper.java b/tests/tests/hardware/src/android/hardware/cts/helpers/SensorVerificationHelper.java
deleted file mode 100644
index d1013e0..0000000
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/SensorVerificationHelper.java
+++ /dev/null
@@ -1,352 +0,0 @@
-/*
- * Copyright (C) 2013 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 android.hardware.cts.helpers;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Set of static helper methods to verify sensor CTS tests.
- */
-public class SensorVerificationHelper {
-
-    private static final int MESSAGE_LENGTH = 3;
-
-    /**
-     * Class which holds results from the verification.
-     */
-    public static class VerificationResult {
-        private boolean mFailed = false;
-        private String mMessage = null;
-        private Map<String, Object> mValueMap = new HashMap<String, Object>();
-
-        public void fail(String messageFormat, Object ... args) {
-            mFailed = true;
-            mMessage = String.format(messageFormat, args);
-        }
-
-        public boolean isFailed() {
-            return mFailed;
-        }
-
-        public String getFailureMessage() {
-            return mMessage;
-        }
-
-        public void putValue(String key, Object value) {
-            mValueMap.put(key, value);
-        }
-
-        public Object getValue(String key) {
-            return mValueMap.get(key);
-        }
-    }
-
-    /**
-     * Private constructor for static class.
-     */
-    private SensorVerificationHelper() {}
-
-    /**
-     * Verify that the events are in the correct order.
-     *
-     * @param events The array of {@link TestSensorEvent}
-     * @return a {@link VerificationResult} containing the verification info including the keys
-     *     "count" which is the number of events out of order and "positions" which contains an
-     *     array of indexes that were out of order.
-     * @throws IllegalStateException if number of events less than 1.
-     */
-    public static VerificationResult verifyEventOrdering(TestSensorEvent[] events) {
-        VerificationResult result = new VerificationResult();
-        List<Integer> indices = new ArrayList<Integer>();
-        long maxTimestamp = events[0].timestamp;
-        for (int i = 1; i < events.length; i++) {
-            long currentTimestamp = events[i].timestamp;
-            if (currentTimestamp < maxTimestamp) {
-                indices.add(i);
-            } else if (currentTimestamp > maxTimestamp) {
-                maxTimestamp = currentTimestamp;
-            }
-        }
-
-        result.putValue("count", indices.size());
-        result.putValue("positions", indices);
-
-        if (indices.size() > 0) {
-            StringBuilder sb = new StringBuilder();
-            sb.append(indices.size()).append(" events out of order: ");
-            for (int i = 0; i < Math.min(indices.size(), MESSAGE_LENGTH); i++) {
-                int index = indices.get(i);
-                sb.append(String.format("position=%d, previous=%d, timestamp=%d; ", index,
-                        events[index - 1].timestamp, events[index].timestamp));
-            }
-            if (indices.size() > MESSAGE_LENGTH) {
-                sb.append(indices.size() - MESSAGE_LENGTH).append(" more");
-            } else {
-                // Delete the "; "
-                sb.delete(sb.length() - 2, sb.length());
-            }
-
-            result.fail(sb.toString());
-        }
-
-        return result;
-    }
-
-    /**
-     * Verify that the sensor frequency matches the expected frequency.
-     *
-     * @param events The array of {@link TestSensorEvent}
-     * @param expected The expected frequency in Hz
-     * @param threshold The acceptable margin of error in Hz
-     * @return a {@link VerificationResult} containing the verification info including the key
-     *     "frequency" which is the computed frequency of the events in Hz.
-     * @throws IllegalStateException if number of events less than 1.
-     */
-    public static VerificationResult verifyFrequency(TestSensorEvent[] events, double expected,
-            double threshold) {
-        VerificationResult result = new VerificationResult();
-        List<Long> timestampDelayValues = SensorCtsHelper.getTimestampDelayValues(events);
-        double frequency = SensorCtsHelper.getFrequency(
-                SensorCtsHelper.getMean(timestampDelayValues), TimeUnit.NANOSECONDS);
-        result.putValue("frequency", frequency);
-
-        if (Math.abs(frequency - expected) > threshold) {
-            result.fail("Frequency out of range: frequency=%.2fHz, expected=%.2f+/-%.2fHz",
-                    frequency, expected, threshold);
-        }
-        return result;
-    }
-
-    /**
-     * Verify that the jitter is in an acceptable range
-     *
-     * @param events The array of {@link TestSensorEvent}
-     * @param threshold The acceptable margin of error in nanoseconds
-     * @return a {@link VerificationResult} containing the verification info including the keys
-     *     "jitter" which is the list of computed jitter values and "jitter95Percentile" which is
-     *     95th percentile of the jitter values.
-     * @throws IllegalStateException if number of events less than 2.
-     */
-    public static VerificationResult verifyJitter(TestSensorEvent[] events, double threshold) {
-        VerificationResult result = new VerificationResult();
-        List<Double> jitterValues = SensorCtsHelper.getJitterValues(events);
-        double jitter95Percentile = SensorCtsHelper.get95PercentileValue(jitterValues);
-        result.putValue("jitter", jitterValues);
-        result.putValue("jitter95Percentile", jitter95Percentile);
-
-        if (jitter95Percentile > threshold) {
-            result.fail("Jitter out of range: jitter at 95th percentile=%.0fns, expected=<%.0fns",
-                    jitter95Percentile, threshold);
-        }
-        return result;
-    }
-
-    /**
-     * Verify that the means matches the expected measurement.
-     *
-     * @param events The array of {@link TestSensorEvent}
-     * @param expected The array of expected values
-     * @param threshold The array of thresholds
-     * @return a {@link VerificationResult} containing the verification info including the key
-     *     "mean" which is the computed means for each value of the sensor.
-     * @throws IllegalStateException if number of events less than 1.
-     */
-    public static VerificationResult verifyMean(TestSensorEvent[] events, double[] expected,
-            double[] threshold) {
-        VerificationResult result = new VerificationResult();
-        double[] means = SensorCtsHelper.getMeans(events);
-        result.putValue("means", means);
-
-        boolean failed = false;
-        StringBuilder meanSb = new StringBuilder();
-        StringBuilder expectedSb = new StringBuilder();
-
-        if (means.length > 1) {
-            meanSb.append("(");
-            expectedSb.append("(");
-        }
-        for (int i = 0; i < means.length && !failed; i++) {
-            if (Math.abs(means[i] - expected[i]) > threshold[i]) {
-                failed = true;
-            }
-            meanSb.append(String.format("%.2f", means[i]));
-            if (i != means.length - 1) meanSb.append(", ");
-            expectedSb.append(String.format("%.2f+/-%.2f", expected[i], threshold[i]));
-            if (i != means.length - 1) expectedSb.append(", ");
-        }
-        if (means.length > 1) {
-            meanSb.append(")");
-            expectedSb.append(")");
-        }
-
-        if (failed) {
-            result.fail("Mean out of range: mean=%s, expected=%s",
-                    meanSb.toString(), expectedSb.toString());
-        }
-        return result;
-    }
-
-    /**
-     * Verify that the mean of the magnitude of the sensors vector is within the expected range.
-     *
-     * @param events The array of {@link TestSensorEvent}
-     * @param expected The expected value
-     * @param threshold The threshold
-     * @return a {@link VerificationResult} containing the verification info including the key
-     *     "magnitude" which is the mean of the computed magnitude of the sensor values.
-     * @throws IllegalStateException if number of events less than 1.
-     */
-    public static VerificationResult verifyMagnitude(TestSensorEvent[] events, double expected,
-            double threshold) {
-        VerificationResult result = new VerificationResult();
-        Collection<Double> magnitudes = new ArrayList<Double>(events.length);
-
-        for (TestSensorEvent event : events) {
-            double norm = 0;
-            for (int i = 0; i < event.values.length; i++) {
-                norm += event.values[i] * event.values[i];
-            }
-            magnitudes.add(Math.sqrt(norm));
-        }
-
-        double mean = SensorCtsHelper.getMean(magnitudes);
-        result.putValue("magnitude", mean);
-
-        if (Math.abs(mean - expected) > threshold) {
-            result.fail(String.format("Magnitude mean out of range: mean=%s, expected=%s+/-%s",
-                    mean, expected, threshold));
-        }
-        return result;
-    }
-
-    /**
-     * Verify that the sign of each of the sensor values is correct.
-     * <p>
-     * If the value of the measurement is in [-threshold, threshold], the sign is considered 0. If
-     * it is less than -threshold, it is considered -1. If it is greater than threshold, it is
-     * considered 1.
-     * </p>
-     *
-     * @param events
-     * @param threshold The threshold that needs to be crossed to consider a measurement nonzero
-     * @return a {@link VerificationResult} containing the verification info including the key
-     *     "mean" which is the computed means for each value of the sensor.
-     * @throws IllegalStateException if number of events less than 1.
-     */
-    public static VerificationResult verifySignum(TestSensorEvent[] events, int[] expected,
-            double[] threshold) {
-        VerificationResult result = new VerificationResult();
-        for (int i = 0; i < expected.length; i++) {
-            if (!(expected[i] == -1 || expected[i] == 0 || expected[i] == 1)) {
-                throw new IllegalArgumentException("Expected value must be -1, 0, or 1");
-            }
-        }
-        double[] means = SensorCtsHelper.getMeans(events);
-        result.putValue("means", means);
-
-        boolean failed = false;
-        StringBuilder meanSb = new StringBuilder();
-        StringBuilder expectedSb = new StringBuilder();
-
-        if (means.length > 1) {
-            meanSb.append("(");
-            expectedSb.append("(");
-        }
-        for (int i = 0; i < means.length; i++) {
-            meanSb.append(String.format("%.2f", means[i]));
-            if (i != means.length - 1) meanSb.append(", ");
-
-            if (expected[i] == 0) {
-                if (Math.abs(means[i]) > threshold[i]) {
-                    failed = true;
-                }
-                expectedSb.append(String.format("[%.2f, %.2f]", -threshold[i], threshold[i]));
-            } else {
-                if (expected[i] > 0) {
-                    if (means[i] <= threshold[i]) {
-                        failed = true;
-                    }
-                    expectedSb.append(String.format("(%.2f, inf)", threshold[i]));
-                } else {
-                    if (means[i] >= -1 * threshold[i]) {
-                        failed = true;
-                    }
-                    expectedSb.append(String.format("(-inf, %.2f)", -1 * threshold[i]));
-                }
-            }
-            if (i != means.length - 1) expectedSb.append(", ");
-        }
-        if (means.length > 1) {
-            meanSb.append(")");
-            expectedSb.append(")");
-        }
-
-        if (failed) {
-            result.fail("Signum out of range: mean=%s, expected=%s",
-                    meanSb.toString(), expectedSb.toString());
-        }
-        return result;
-    }
-
-    /**
-     * Verify that the standard deviations is within the expected range.
-     *
-     * @param events The array of {@link TestSensorEvent}
-     * @param threshold The array of thresholds
-     * @return a {@link VerificationResult} containing the verification info including the key
-     *     "stddevs" which is the computed standard deviations for each value of the sensor.
-     * @throws IllegalStateException if number of events less than 1.
-     */
-    public static VerificationResult verifyStandardDeviation(TestSensorEvent[] events,
-            double[] threshold) {
-        VerificationResult result = new VerificationResult();
-        double[] standardDeviations = SensorCtsHelper.getStandardDeviations(events);
-        result.putValue("stddevs", standardDeviations);
-
-        boolean failed = false;
-        StringBuilder meanSb = new StringBuilder();
-        StringBuilder expectedSb = new StringBuilder();
-
-        if (standardDeviations.length > 1) {
-            meanSb.append("(");
-            expectedSb.append("(");
-        }
-        for (int i = 0; i < standardDeviations.length && !failed; i++) {
-            if (standardDeviations[i] > threshold[i]) {
-                failed = true;
-            }
-            meanSb.append(String.format("%.2f", standardDeviations[i]));
-            if (i != standardDeviations.length - 1) meanSb.append(", ");
-            expectedSb.append(String.format("0+/-%.2f", threshold[i]));
-            if (i != standardDeviations.length - 1) expectedSb.append(", ");
-        }
-        if (standardDeviations.length > 1) {
-            meanSb.append(")");
-            expectedSb.append(")");
-        }
-
-        if (failed) {
-            result.fail("Standard deviation out of range: mean=%s, expected=%s",
-                    meanSb.toString(), expectedSb.toString());
-        }
-        return result;
-    }
-}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/SensorVerificationHelperTest.java b/tests/tests/hardware/src/android/hardware/cts/helpers/SensorVerificationHelperTest.java
deleted file mode 100644
index 875fa7f..0000000
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/SensorVerificationHelperTest.java
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
- * Copyright (C) 2014 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 android.hardware.cts.helpers;
-
-import android.hardware.cts.helpers.SensorVerificationHelper.VerificationResult;
-
-import junit.framework.TestCase;
-
-import java.util.List;
-
-/**
- * Unit tests for the {@link SensorVerificationHelper} class.
- */
-public class SensorVerificationHelperTest extends TestCase {
-
-    /**
-     * Test {@link SensorVerificationHelper#verifyEventOrdering(TestSensorEvent[])}.
-     */
-    @SuppressWarnings("unchecked")
-    public void testVerifyEventOrdering() {
-        float[] values = {0, 1, 2, 3, 4};
-
-        long[] timestamps1 = {0, 0, 0, 0, 0};
-        TestSensorEvent[] events1 = getSensorEvents(timestamps1, values);
-        VerificationResult result = SensorVerificationHelper.verifyEventOrdering(events1);
-        assertFalse(result.isFailed());
-        assertEquals(0, result.getValue("count"));
-
-        long[] timestamps2 = {0, 1, 2, 3, 4};
-        TestSensorEvent[] events2 = getSensorEvents(timestamps2, values);
-        result = SensorVerificationHelper.verifyEventOrdering(events2);
-        assertFalse(result.isFailed());
-        assertEquals(0, result.getValue("count"));
-
-        long[] timestamps3 = {0, 2, 1, 3, 4};
-        TestSensorEvent[] events3 = getSensorEvents(timestamps3, values);
-        result = SensorVerificationHelper.verifyEventOrdering(events3);
-        assertTrue(result.isFailed());
-        assertEquals(1, result.getValue("count"));
-        List<Integer> indices = (List<Integer>) result.getValue("positions");
-        assertTrue(indices.contains(2));
-
-        long[] timestamps4 = {4, 0, 1, 2, 3};
-        TestSensorEvent[] events4 = getSensorEvents(timestamps4, values);
-        result = SensorVerificationHelper.verifyEventOrdering(events4);
-        assertTrue(result.isFailed());
-        assertEquals(4, result.getValue("count"));
-        indices = (List<Integer>) result.getValue("positions");
-        assertTrue(indices.contains(1));
-        assertTrue(indices.contains(2));
-        assertTrue(indices.contains(3));
-        assertTrue(indices.contains(4));
-    }
-
-    /**
-     * Test {@link SensorVerificationHelper#verifyFrequency(TestSensorEvent[], double, double)}.
-     */
-    public void testVerifyFrequency() {
-        float[] values = {0, 1, 2, 3, 4};
-        long[] timestamps = {0, 1000000, 2000000, 3000000, 4000000};  // 1000Hz
-        TestSensorEvent[] events = getSensorEvents(timestamps, values);
-
-        VerificationResult result = SensorVerificationHelper.verifyFrequency(events, 1000.0, 1.0);
-        assertFalse(result.isFailed());
-        assertEquals(1000.0, (Double) result.getValue("frequency"), 0.01);
-
-        result = SensorVerificationHelper.verifyFrequency(events, 950.0, 100.0);
-        assertFalse(result.isFailed());
-        assertEquals(1000.0, (Double) result.getValue("frequency"), 0.01);
-
-        result = SensorVerificationHelper.verifyFrequency(events, 1050.0, 100.0);
-        assertFalse(result.isFailed());
-        assertEquals(1000.0, (Double) result.getValue("frequency"), 0.01);
-
-        result = SensorVerificationHelper.verifyFrequency(events, 950.0, 25.0);
-        assertTrue(result.isFailed());
-        assertEquals(1000.0, (Double) result.getValue("frequency"), 0.01);
-    }
-
-    /**
-     * Test {@link SensorVerificationHelper#verifyJitter(TestSensorEvent[], double)}.
-     */
-    public void testVerifyJitter() {
-        final int SAMPLE_SIZE = 100;
-        float[] values = new float[SAMPLE_SIZE];
-        for (int i = 0; i < SAMPLE_SIZE; i++) {
-            values[i] = i;
-        }
-
-        long[] timestamps1 = new long[SAMPLE_SIZE];  // 100 samples at 1000Hz
-        for (int i = 0; i < SAMPLE_SIZE; i++) {
-            timestamps1[i] = i * 100000;
-        }
-        TestSensorEvent[] events1 = getSensorEvents(timestamps1, values);
-        VerificationResult result = SensorVerificationHelper.verifyJitter(events1, 100000);
-        assertFalse(result.isFailed());
-        assertEquals(0.0, (Double) result.getValue("jitter95Percentile"), 0.01);
-
-        long[] timestamps2 = new long[SAMPLE_SIZE];  // 90 samples at 1000Hz, 10 samples at 2000Hz
-        long timestamp = 0;
-        for (int i = 0; i < SAMPLE_SIZE; i++) {
-            timestamps2[i] = timestamp;
-            timestamp += (i % 10 == 0) ? 500000 : 1000000;
-        }
-        TestSensorEvent[] events2 = getSensorEvents(timestamps2, values);
-        result = SensorVerificationHelper.verifyJitter(events2, 100000);
-        assertTrue(result.isFailed());
-        assertNotNull(result.getValue("jitter"));
-        assertNotNull(result.getValue("jitter95Percentile"));
-    }
-
-    /**
-     * Test {@link SensorVerificationHelper#verifyMean(TestSensorEvent[], double[], double[])}.
-     */
-    public void testVerifyMean() {
-        long[] timestamps = {0, 1, 2, 3, 4};
-        float[] values1 = {0, 1, 2, 3, 4};
-        float[] values2 = {1, 2, 3, 4, 5};
-        float[] values3 = {0, 1, 4, 9, 16};
-        TestSensorEvent[] events = getSensorEvents(timestamps, values1, values2, values3);
-
-        double[] expected1 = {2.0, 3.0, 6.0};
-        double[] threshold1 = {0.1, 0.1, 0.1};
-        VerificationResult result = SensorVerificationHelper.verifyMean(events, expected1,
-                threshold1);
-        assertFalse(result.isFailed());
-        double[] means = (double[]) result.getValue("means");
-        assertEquals(2.0, means[0], 0.01);
-        assertEquals(3.0, means[1], 0.01);
-        assertEquals(6.0, means[2], 0.01);
-
-        double[] expected2 = {2.5, 2.5, 5.5};
-        double[] threshold2 = {0.6, 0.6, 0.6};
-        result = SensorVerificationHelper.verifyMean(events, expected2, threshold2);
-        assertFalse(result.isFailed());
-
-        double[] expected3 = {2.5, 2.5, 5.5};
-        double[] threshold3 = {0.1, 0.6, 0.6};
-        result = SensorVerificationHelper.verifyMean(events, expected3, threshold3);
-        assertTrue(result.isFailed());
-
-        double[] expected4 = {2.5, 2.5, 5.5};
-        double[] threshold4 = {0.6, 0.1, 0.6};
-        result = SensorVerificationHelper.verifyMean(events, expected4, threshold4);
-        assertTrue(result.isFailed());
-
-        double[] expected5 = {2.5, 2.5, 5.5};
-        double[] threshold5 = {0.6, 0.6, 0.1};
-        result = SensorVerificationHelper.verifyMean(events, expected5, threshold5);
-        assertTrue(result.isFailed());
-    }
-
-    /**
-     * Test {@link SensorVerificationHelper#verifyMagnitude(TestSensorEvent[], double, double)}.
-     */
-    public void testVerifyMagnitude() {
-        long[] timestamps = {0, 1, 2, 3, 4};
-        float[] values1 = {0, 4, 3, 0, 6};
-        float[] values2 = {3, 0, 4, 0, 0};
-        float[] values3 = {4, 3, 0, 4, 0};
-        TestSensorEvent[] events = getSensorEvents(timestamps, values1, values2, values3);
-
-        double expected = 5.0;
-        double threshold = 0.1;
-        VerificationResult result = SensorVerificationHelper.verifyMagnitude(events, expected,
-                threshold);
-        assertFalse(result.isFailed());
-        assertEquals(5.0, (Double) result.getValue("magnitude"), 0.01);
-
-        expected = 4.5;
-        threshold = 0.6;
-        result = SensorVerificationHelper.verifyMagnitude(events, expected, threshold);
-        assertFalse(result.isFailed());
-
-        expected = 5.5;
-        threshold = 0.6;
-        result = SensorVerificationHelper.verifyMagnitude(events, expected, threshold);
-        assertFalse(result.isFailed());
-
-        expected = 4.5;
-        threshold = 0.1;
-        result = SensorVerificationHelper.verifyMagnitude(events, expected, threshold);
-        assertTrue(result.isFailed());
-
-        expected = 5.5;
-        threshold = 0.1;
-        result = SensorVerificationHelper.verifyMagnitude(events, expected, threshold);
-        assertTrue(result.isFailed());
-    }
-
-    /**
-     * Test {@link SensorVerificationHelper#verifySignum(TestSensorEvent[], int[], double[])}.
-     */
-    public void testVerifySignum() {
-        long[] timestamps = {0};
-        float[][] values = {{1}, {0.2f}, {0}, {-0.2f}, {-1}};
-        TestSensorEvent[] events = getSensorEvents(timestamps, values);
-
-        int[] expected1 = {1, 1, 0, -1, -1};
-        double[] threshold1 = {0.1, 0.1, 0.1, 0.1, 0.1};
-        VerificationResult result = SensorVerificationHelper.verifySignum(events, expected1,
-                threshold1);
-        assertFalse(result.isFailed());
-        assertNotNull(result.getValue("means"));
-
-        int[] expected2 = {1, 0, 0, 0, -1};
-        double[] threshold2 = {0.5, 0.5, 0.5, 0.5, 0.5};
-        result = SensorVerificationHelper.verifySignum(events, expected2, threshold2);
-        assertFalse(result.isFailed());
-
-        int[] expected3 = {0, 1, 0, -1, 0};
-        double[] threshold3 = {1.5, 0.1, 0.1, 0.1, 1.5};
-        result = SensorVerificationHelper.verifySignum(events, expected3, threshold3);
-        assertFalse(result.isFailed());
-
-        int[] expected4 = {1, 0, 0, 0, 1};
-        double[] threshold4 = {0.5, 0.5, 0.5, 0.5, 0.5};
-        result = SensorVerificationHelper.verifySignum(events, expected4, threshold4);
-        assertTrue(result.isFailed());
-
-        int[] expected5 = {-1, 0, 0, 0, -1};
-        double[] threshold5 = {0.5, 0.5, 0.5, 0.5, 0.5};
-        result = SensorVerificationHelper.verifySignum(events, expected5, threshold5);
-        assertTrue(result.isFailed());
-    }
-
-    /**
-     * Test {@link SensorVerificationHelper#verifyStandardDeviation(TestSensorEvent[], double[])}.
-     */
-    public void testVerifyStandardDeviation() {
-        long[] timestamps = {0, 1, 2, 3, 4};
-        float[] values1 = {0, 1, 2, 3, 4};  // sqrt(2.0)
-        float[] values2 = {1, 2, 3, 4, 5};  // sqrt(2.0)
-        float[] values3 = {0, 2, 4, 6, 8};  // sqrt(8.0)
-        TestSensorEvent[] events = getSensorEvents(timestamps, values1, values2, values3);
-
-        double[] threshold1 = {2, 2, 3};
-        VerificationResult result = SensorVerificationHelper.verifyStandardDeviation(events,
-                threshold1);
-        assertFalse(result.isFailed());
-        double[] means = (double[]) result.getValue("stddevs");
-        assertEquals(Math.sqrt(2.0), means[0], 0.01);
-        assertEquals(Math.sqrt(2.0), means[1], 0.01);
-        assertEquals(Math.sqrt(8.0), means[2], 0.01);
-
-        double[] threshold2 = {1, 2, 3};
-        result = SensorVerificationHelper.verifyStandardDeviation(events, threshold2);
-        assertTrue(result.isFailed());
-
-        double[] threshold3 = {2, 1, 3};
-        result = SensorVerificationHelper.verifyStandardDeviation(events, threshold3);
-        assertTrue(result.isFailed());
-
-        double[] threshold4 = {2, 2, 2};
-        result = SensorVerificationHelper.verifyStandardDeviation(events, threshold4);
-        assertTrue(result.isFailed());
-    }
-
-    private TestSensorEvent[] getSensorEvents(long[] timestamps, float[] ... values) {
-        TestSensorEvent[] events = new TestSensorEvent[timestamps.length];
-        for (int i = 0; i < timestamps.length; i++) {
-            float[] eventValues = new float[values.length];
-            for (int j = 0; j < values.length; j++) {
-                eventValues[j] = values[j][i];
-            }
-            events[i] = new TestSensorEvent(null, timestamps[i], 0, eventValues);
-        }
-        return events;
-    }
-}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/TestSensorEvent.java b/tests/tests/hardware/src/android/hardware/cts/helpers/TestSensorEvent.java
index 48bc1d3..b349e1b 100644
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/TestSensorEvent.java
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/TestSensorEvent.java
@@ -18,33 +18,51 @@
 
 import android.hardware.Sensor;
 import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener2;
 
 /**
- * Test class to wrap SensorEvent.
- * It currently only provides a way to clone SensorEvent data, but in the future it can contain
- * verifications and test checks.
+ * Class for holding information about individual {@link SensorEvent}s.
  */
 public class TestSensorEvent {
     public final Sensor sensor;
     public final long timestamp;
+    public final long receivedTimestamp;
     public final int accuracy;
     public final float values[];
 
-    public TestSensorEvent(SensorEvent event) {
+    /**
+     * Construct a TestSensorEvent from {@link SensorEvent} data and a received timestamp.
+     *
+     * @param event the {@link SensorEvent} to be cloned
+     * @param receivedTimestamp the timestamp when
+     * {@link SensorEventListener2#onSensorChanged(SensorEvent)} was called, in nanoseconds.
+     */
+    public TestSensorEvent(SensorEvent event, long receivedTimestamp) {
         values = new float[event.values.length];
-        System.arraycopy(event.values, 0, values, 0, event.values.length);
+        System.arraycopy(event.values, 0, values, 0, values.length);
 
         sensor = event.sensor;
         timestamp = event.timestamp;
         accuracy = event.accuracy;
+
+        this.receivedTimestamp = receivedTimestamp;
     }
 
     /**
      * Constructor for TestSensorEvent. Exposed for unit testing.
      */
-    protected TestSensorEvent(Sensor sensor, long timestamp, int accuracy, float[] values) {
+    public TestSensorEvent(Sensor sensor, long timestamp, int accuracy, float[] values) {
+        this(sensor, timestamp, timestamp, accuracy, values);
+    }
+
+    /**
+     * Constructor for TestSensorEvent. Exposed for unit testing.
+     */
+    public TestSensorEvent(Sensor sensor, long timestamp, long receivedTimestamp, int accuracy,
+            float[] values) {
         this.sensor = sensor;
         this.timestamp = timestamp;
+        this.receivedTimestamp = receivedTimestamp;
         this.accuracy = accuracy;
         this.values = values;
     }
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/TestSensorEventListener.java b/tests/tests/hardware/src/android/hardware/cts/helpers/TestSensorEventListener.java
new file mode 100644
index 0000000..ddbc8c2
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/TestSensorEventListener.java
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2014 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 android.hardware.cts.helpers;
+
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener2;
+import android.util.Log;
+
+import junit.framework.Assert;
+
+import java.util.Arrays;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * A {@link SensorEventListener2} which performs operations such as waiting for a specific number of
+ * events or for a specific time, or waiting for a flush to complete. This class performs
+ * verifications and will throw {@link AssertionError}s if there are any errors. It may also wrap
+ * another {@link SensorEventListener2}.
+ */
+public class TestSensorEventListener implements SensorEventListener2 {
+    public static final String LOG_TAG = "TestSensorEventListener";
+    private static final long EVENT_TIMEOUT_US = TimeUnit.MICROSECONDS.convert(5, TimeUnit.SECONDS);
+    private static final long FLUSH_TIMEOUT_US = TimeUnit.MICROSECONDS.convert(5, TimeUnit.SECONDS);
+
+    private final SensorEventListener2 mListener;
+
+    private volatile CountDownLatch mEventLatch = null;
+    private volatile CountDownLatch mFlushLatch = new CountDownLatch(1);
+
+    private Sensor mSensor = null;
+    private int mRateUs = 0;
+    private int mMaxBatchReportLatencyUs = 0;
+    private boolean mLogEvents = false;
+
+    /**
+     * Construct a {@link TestSensorEventListener}.
+     */
+    public TestSensorEventListener() {
+        this(null);
+    }
+
+    /**
+     * Construct a {@link TestSensorEventListener} that wraps a {@link SensorEventListener2}.
+     */
+    public TestSensorEventListener(SensorEventListener2 listener) {
+        mListener = listener;
+    }
+
+    /**
+     * Set the sensor, rate, and batch report latency used for the assertions.
+     */
+    public void setSensorInfo(Sensor sensor, int rateUs, int maxBatchReportLatencyUs) {
+        mSensor = sensor;
+        mRateUs = rateUs;
+        mMaxBatchReportLatencyUs = maxBatchReportLatencyUs;
+    }
+
+    /**
+     * Set whether or not to log events
+     */
+    public void setLogEvents(boolean log) {
+        mLogEvents = log;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void onSensorChanged(SensorEvent event) {
+        if(mEventLatch != null) {
+            mEventLatch.countDown();
+        }
+        if (mListener != null) {
+            mListener.onSensorChanged(event);
+        }
+        if (mLogEvents) {
+            StringBuilder valuesSb = new StringBuilder();
+            if (event.values.length == 1) {
+                valuesSb.append(String.format("%.2f", event.values[0]));
+            } else {
+                valuesSb.append("[").append(String.format("%.2f", event.values[0]));
+                for (int i = 1; i < event.values.length; i++) {
+                    valuesSb.append(String.format(", %.2f", event.values[i]));
+                }
+                valuesSb.append("]");
+            }
+
+            Log.v(LOG_TAG, String.format(
+                    "Sensor %d: sensor_timestamp=%d, received_timestamp=%d, values=%s",
+                    mSensor.getType(), event.timestamp, System.nanoTime(),
+                    Arrays.toString(event.values)));
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void onAccuracyChanged(Sensor sensor, int accuracy) {
+        if (mListener != null) {
+            mListener.onAccuracyChanged(sensor, accuracy);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void onFlushCompleted(Sensor sensor) {
+        CountDownLatch latch = mFlushLatch;
+        mFlushLatch = new CountDownLatch(1);
+        if(latch != null) {
+            latch.countDown();
+        }
+        if (mListener != null) {
+            mListener.onFlushCompleted(sensor);
+        }
+    }
+
+    /**
+     * Wait for {@link #onFlushCompleted(Sensor)} to be called.
+     *
+     * @throws AssertionError if there was a timeout after {@value #FLUSH_TIMEOUT_US} &micro;s
+     */
+    public void waitForFlushComplete() {
+        CountDownLatch latch = mFlushLatch;
+        try {
+            if(latch != null) {
+                String message = SensorCtsHelper.formatAssertionMessage(mSensor, "WaitForFlush",
+                        mRateUs, mMaxBatchReportLatencyUs);
+                Assert.assertTrue(message, latch.await(FLUSH_TIMEOUT_US, TimeUnit.MICROSECONDS));
+            }
+        } catch(InterruptedException e) {
+            // Ignore
+        }
+    }
+
+    /**
+     * Collect a specific number of {@link TestSensorEvent}s.
+     *
+     * @throws AssertionError if there was a timeout after {@value #FLUSH_TIMEOUT_US} &micro;s
+     */
+    public void waitForEvents(int eventCount) {
+        mEventLatch = new CountDownLatch(eventCount);
+        try {
+            int rateUs = SensorCtsHelper.getDelay(mSensor, mRateUs);
+            // Timeout is 2 * event count * expected period + batch timeout + default wait
+            long timeoutUs = ((2 * eventCount * rateUs)
+                    + mMaxBatchReportLatencyUs + EVENT_TIMEOUT_US);
+
+            String message = SensorCtsHelper.formatAssertionMessage(mSensor, "WaitForEvents",
+                    mRateUs, mMaxBatchReportLatencyUs, "count:%d, available:%d", eventCount,
+                    mEventLatch.getCount());
+            Assert.assertTrue(message, mEventLatch.await(timeoutUs, TimeUnit.MICROSECONDS));
+        } catch(InterruptedException e) {
+            // Ignore
+        } finally {
+            mEventLatch = null;
+        }
+    }
+
+    /**
+     * Collect {@link TestSensorEvent} for a specific duration.
+     */
+    public void waitForEvents(long duration, TimeUnit timeUnit) {
+        SensorCtsHelper.sleep(duration, timeUnit);
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/TestSensorManager.java b/tests/tests/hardware/src/android/hardware/cts/helpers/TestSensorManager.java
new file mode 100644
index 0000000..a45ad70
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/TestSensorManager.java
@@ -0,0 +1,221 @@
+/*
+ * Copyright (C) 2014 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 android.hardware.cts.helpers;
+
+import android.content.Context;
+import android.hardware.Sensor;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorEventListener2;
+import android.hardware.SensorManager;
+import android.util.Log;
+
+import junit.framework.Assert;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * A test class that performs the actions of {@link SensorManager} on a single sensor. This
+ * class allows for a single sensor to be registered and unregistered as well as performing
+ * operations such as flushing the sensor events and gathering events. This class also manages
+ * performing the test verifications for the sensor manager.
+ * <p>
+ * This class requires that operations are performed in the following order:
+ * <p><ul>
+ * <li>{@link #registerListener(TestSensorEventListener)}</li>
+ * <li>{@link #startFlush()}, {@link #waitForFlushCompleted()}, or {@link #flush()}.
+ * <li>{@link #unregisterListener()}</li>
+ * </ul><p>Or:</p><ul>
+ * <li>{@link #runSensor(TestSensorEventListener, int)}</li>
+ * </ul><p>Or:</p><ul>
+ * <li>{@link #runSensor(TestSensorEventListener, long, TimeUnit)}</li>
+ * </ul><p>
+ * If methods are called outside of this order, they will print a warning to the log and then
+ * return. Both {@link #runSensor(TestSensorEventListener, int)}} and
+ * {@link #runSensor(TestSensorEventListener, long, TimeUnit)} will perform the appropriate
+ * set up and tear down.
+ * <p>
+ */
+public class TestSensorManager {
+    private static final String LOG_TAG = "TestSensorManager";
+
+    private final SensorManager mSensorManager;
+    private final Sensor mSensor;
+    private final int mRateUs;
+    private final int mMaxBatchReportLatencyUs;
+
+    private TestSensorEventListener mTestSensorEventListener = null;
+
+    /**
+     * Construct a {@link TestSensorManager}.
+     */
+    public TestSensorManager(Context context, int sensorType, int rateUs,
+            int maxBatchReportLatencyUs) {
+        mSensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
+        mSensor = SensorCtsHelper.getSensor(context, sensorType);
+        mRateUs = rateUs;
+        mMaxBatchReportLatencyUs = maxBatchReportLatencyUs;
+    }
+
+    /**
+     * Register the listener. This method will perform a no-op if the sensor is already registered.
+     *
+     * @throws AssertionError if there was an error registering the listener with the
+     * {@link SensorManager}
+     */
+    public void registerListener(TestSensorEventListener listener) {
+        if (mTestSensorEventListener != null) {
+            Log.w(LOG_TAG, "Listener already registered, returning.");
+            return;
+        }
+
+        mTestSensorEventListener = listener != null ? listener : new TestSensorEventListener();
+        mTestSensorEventListener.setSensorInfo(mSensor, mRateUs, mMaxBatchReportLatencyUs);
+
+        String message = SensorCtsHelper.formatAssertionMessage(mSensor, "registerListener",
+                mRateUs, mMaxBatchReportLatencyUs);
+        boolean result = mSensorManager.registerListener(mTestSensorEventListener, mSensor, mRateUs,
+                mMaxBatchReportLatencyUs);
+        Assert.assertTrue(message, result);
+    }
+
+    /**
+     * Unregister the listener. This method will perform a no-op if the sensor is not registered.
+     */
+    public void unregisterListener() {
+        if (mTestSensorEventListener == null) {
+            Log.w(LOG_TAG, "No listener registered, returning.");
+            return;
+        }
+
+        mSensorManager.unregisterListener(mTestSensorEventListener, mSensor);
+        mTestSensorEventListener = null;
+    }
+
+    /**
+     * Wait for a specific number of events.
+     */
+    public void waitForEvents(int eventCount) {
+        if (mTestSensorEventListener == null) {
+            Log.w(LOG_TAG, "No listener registered, returning.");
+            return;
+        }
+
+        mTestSensorEventListener.waitForEvents(eventCount);
+    }
+
+    /**
+     * Wait for a specific duration.
+     */
+    public void waitForEvents(long duration, TimeUnit timeUnit) {
+        if (mTestSensorEventListener == null) {
+            Log.w(LOG_TAG, "No listener registered, returning.");
+            return;
+        }
+
+        mTestSensorEventListener.waitForEvents(duration, timeUnit);
+    }
+
+    /**
+     * Call {@link SensorManager#flush(SensorEventListener)}. This method will perform a no-op if
+     * the sensor is not registered.
+     *
+     * @throws AssertionError if {@link SensorManager#flush(SensorEventListener)} returns false
+     */
+    public void startFlush() {
+        if (mTestSensorEventListener == null) {
+            return;
+        }
+
+        String message = SensorCtsHelper.formatAssertionMessage(mSensor, "Flush", mRateUs,
+                mMaxBatchReportLatencyUs);
+        Assert.assertTrue(message, mSensorManager.flush(mTestSensorEventListener));
+    }
+
+    /**
+     * Wait for {@link SensorEventListener2#onFlushCompleted(Sensor)} to be called. This method will
+     * perform a no-op if the sensor is not registered.
+     *
+     * @throws AssertionError if there is a time out
+     * @throws InterruptedException if the thread was interrupted
+     */
+    public void waitForFlushCompleted() throws InterruptedException {
+        if (mTestSensorEventListener == null) {
+            return;
+        }
+
+        mTestSensorEventListener.waitForFlushComplete();
+    }
+
+    /**
+     * Call {@link SensorManager#flush(SensorEventListener)} and wait for
+     * {@link SensorEventListener2#onFlushCompleted(Sensor)} to be called. This method will perform
+     * a no-op if the sensor is not registered.
+     *
+     * @throws AssertionError if {@link SensorManager#flush(SensorEventListener)} returns false or
+     * if there is a time out
+     * @throws InterruptedException if the thread was interrupted
+     */
+    public void flush() throws InterruptedException {
+        if (mTestSensorEventListener == null) {
+            return;
+        }
+
+        startFlush();
+        waitForFlushCompleted();
+    }
+
+    /**
+     * Register a listener, wait for a specific number of events, and then unregister the listener.
+     */
+    public void runSensor(TestSensorEventListener listener, int eventCount) {
+        if (mTestSensorEventListener != null) {
+            Log.w(LOG_TAG, "Listener already registered, returning.");
+            return;
+        }
+
+        try {
+            registerListener(listener);
+            waitForEvents(eventCount);
+        } finally {
+            unregisterListener();
+        }
+    }
+
+    /**
+     * Register a listener, wait for a specific duration, and then unregister the listener.
+     */
+    public void runSensor(TestSensorEventListener listener, long duration, TimeUnit timeUnit) {
+        if (mTestSensorEventListener != null) {
+            Log.w(LOG_TAG, "Listener already registered, returning.");
+            return;
+        }
+
+        try {
+            registerListener(listener);
+            waitForEvents(duration, timeUnit);
+        } finally {
+            unregisterListener();
+        }
+    }
+
+    /**
+     * Get the sensor under test.
+     */
+    public Sensor getSensor() {
+        return mSensor;
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/ValidatingSensorEventListener.java b/tests/tests/hardware/src/android/hardware/cts/helpers/ValidatingSensorEventListener.java
new file mode 100644
index 0000000..ae7ea04
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/ValidatingSensorEventListener.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2014 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 android.hardware.cts.helpers;
+
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener2;
+import android.hardware.cts.helpers.sensorverification.ISensorVerification;
+import android.os.SystemClock;
+
+import java.util.Collection;
+import java.util.LinkedList;
+
+/**
+ * A {@link TestSensorEventListener} which performs validations on the received events on the fly.
+ * This class is useful for long running tests where it is not practical to store all the events to
+ * be processed after.
+ */
+public class ValidatingSensorEventListener extends TestSensorEventListener {
+
+    private final Collection<ISensorVerification> mVerifications =
+            new LinkedList<ISensorVerification>();
+
+    /**
+     * Construct a {@link ValidatingSensorEventListener} with an additional
+     * {@link SensorEventListener2}.
+     */
+    public ValidatingSensorEventListener(SensorEventListener2 listener,
+            ISensorVerification ... verifications) {
+        super(listener);
+        for (ISensorVerification verification : verifications) {
+            mVerifications.add(verification);
+        }
+    }
+
+    /**
+     * Construct a {@link ValidatingSensorEventListener} with an additional
+     * {@link SensorEventListener2}.
+     */
+    public ValidatingSensorEventListener(SensorEventListener2 listener,
+            Collection<ISensorVerification> verifications) {
+        this(listener, verifications.toArray(new ISensorVerification[0]));
+    }
+
+    /**
+     * Construct a {@link ValidatingSensorEventListener}.
+     */
+    public ValidatingSensorEventListener(ISensorVerification ... verifications) {
+        this(null, verifications);
+    }
+
+    /**
+     * Construct a {@link ValidatingSensorEventListener}.
+     */
+    public ValidatingSensorEventListener(Collection<ISensorVerification> verifications) {
+        this(null, verifications);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void onSensorChanged(SensorEvent event) {
+        TestSensorEvent testEvent = new TestSensorEvent(event, SystemClock.elapsedRealtimeNanos());
+        for (ISensorVerification verification : mVerifications) {
+            verification.addSensorEvent(testEvent);
+        }
+        super.onSensorChanged(event);
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorTestOperations/ParallelCompositeSensorTestOperation.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorTestOperations/ParallelCompositeSensorTestOperation.java
deleted file mode 100644
index 3730f4b..0000000
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorTestOperations/ParallelCompositeSensorTestOperation.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2013 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 android.hardware.cts.helpers.sensorTestOperations;
-
-import android.hardware.cts.helpers.SensorTestOperation;
-
-import java.util.ArrayList;
-
-/**
- * A test operation that groups a set of SensorTestOperations and allows to execute them all in
- * parallel.
- * This class can be combined to compose other primitive SensorTestOperations.
- */
-public class ParallelCompositeSensorTestOperation extends SensorTestOperation {
-    private final ArrayList<SensorTestOperation> mOperations = new ArrayList<SensorTestOperation>();
-
-    /**
-     * There is no synchronization
-     * @param operations
-     */
-    public void add(SensorTestOperation ... operations) {
-        synchronized (mOperations) {
-            for(SensorTestOperation operation : operations) {
-                mOperations.add(operation);
-            }
-        }
-    }
-
-    @Override
-    protected void doWork() throws Throwable {
-        synchronized (mOperations) {
-            for(SensorTestOperation operation : mOperations) {
-                operation.start();
-            }
-            for(SensorTestOperation operation : mOperations) {
-                operation.waitForCompletion();
-            }
-        }
-    }
-}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorTestOperations/RepeatingSensorTestOperation.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorTestOperations/RepeatingSensorTestOperation.java
deleted file mode 100644
index 7a3c450..0000000
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorTestOperations/RepeatingSensorTestOperation.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2013 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 android.hardware.cts.helpers.sensorTestOperations;
-
-import android.hardware.cts.helpers.SensorTestOperation;
-
-/**
- * High level SensorTestOperation that executes the inner operation in a loop.
- */
-public class RepeatingSensorTestOperation extends SensorTestOperation {
-    private final SensorTestOperation mSensorTestOperation;
-    private final int mRepetitionCount;
-
-    public RepeatingSensorTestOperation(SensorTestOperation operation, int repetitionCount) {
-        mSensorTestOperation = operation;
-        mRepetitionCount = repetitionCount;
-    }
-
-    @Override
-    protected void doWork() throws Throwable {
-        for(int i = 0; i < mRepetitionCount; ++i) {
-            mSensorTestOperation.execute();
-        }
-    }
-}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorTestOperations/SequentialCompositeSensorTestOperation.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorTestOperations/SequentialCompositeSensorTestOperation.java
deleted file mode 100644
index 4b92168..0000000
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorTestOperations/SequentialCompositeSensorTestOperation.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2013 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 android.hardware.cts.helpers.sensorTestOperations;
-
-import android.hardware.cts.helpers.SensorTestOperation;
-
-import java.util.ArrayList;
-
-/**
- * A test operation that groups a set of SensorTestOperations and allows to execute them in a
- * sequence, each operation executes in the order they are added to the composite container.
- * This class can be combined to compose other primitive SensorTestOperations.
- */
-public class SequentialCompositeSensorTestOperation extends SensorTestOperation {
-    private final ArrayList<SensorTestOperation> mOperations = new ArrayList<SensorTestOperation>();
-
-    /**
-     * There is no synchronization
-     * @param operations
-     */
-    public void add(SensorTestOperation ... operations) {
-        synchronized (mOperations) {
-            for(SensorTestOperation operation : operations) {
-                mOperations.add(operation);
-            }
-        }
-    }
-
-    @Override
-    protected void doWork() throws Throwable {
-        synchronized (mOperations) {
-            for(SensorTestOperation operation : mOperations) {
-                operation.execute();
-            }
-        }
-    }
-}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorTestOperations/VerifyEventOrderingOperation.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorTestOperations/VerifyEventOrderingOperation.java
deleted file mode 100644
index 03d0f9a..0000000
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorTestOperations/VerifyEventOrderingOperation.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2013 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 android.hardware.cts.helpers.sensorTestOperations;
-
-import android.content.Context;
-import android.hardware.cts.helpers.SensorCtsHelper;
-import android.hardware.cts.helpers.SensorManagerTestVerifier;
-import android.hardware.cts.helpers.SensorTestOperation;
-import android.hardware.cts.helpers.SensorVerificationHelper;
-import android.hardware.cts.helpers.SensorVerificationHelper.VerificationResult;
-import android.hardware.cts.helpers.TestSensorEvent;
-
-import junit.framework.Assert;
-
-/**
- * Test Operation class that validates the ordering of sensor events.
- */
-public class VerifyEventOrderingOperation extends SensorTestOperation {
-    private SensorManagerTestVerifier mSensor;
-
-    public VerifyEventOrderingOperation(
-            Context context,
-            int sensorType,
-            int samplingRateInUs,
-            int reportLatencyInUs) {
-        mSensor = new SensorManagerTestVerifier(
-                context,
-                sensorType,
-                samplingRateInUs,
-                reportLatencyInUs);
-    }
-
-    @Override
-    public void doWork() {
-        TestSensorEvent[] events = mSensor.collectEvents(100);
-        VerificationResult result = SensorVerificationHelper.verifyEventOrdering(events);
-        if (result.isFailed()) {
-            Assert.fail(SensorCtsHelper.formatAssertionMessage(
-                    "Ordering",
-                    this,
-                    mSensor.getUnderlyingSensor(),
-                    result.getFailureMessage()));
-        }
-    }
-}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorTestOperations/VerifyJitteringOperation.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorTestOperations/VerifyJitteringOperation.java
deleted file mode 100644
index 303dc9b..0000000
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorTestOperations/VerifyJitteringOperation.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2013 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 android.hardware.cts.helpers.sensorTestOperations;
-
-import android.content.Context;
-import android.hardware.cts.helpers.SensorCtsHelper;
-import android.hardware.cts.helpers.SensorManagerTestVerifier;
-import android.hardware.cts.helpers.SensorTestInformation;
-import android.hardware.cts.helpers.SensorTestOperation;
-import android.hardware.cts.helpers.SensorVerificationHelper;
-import android.hardware.cts.helpers.SensorVerificationHelper.VerificationResult;
-import android.hardware.cts.helpers.TestSensorEvent;
-
-import junit.framework.Assert;
-
-import java.security.InvalidParameterException;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Test Operation class that validates the sampling rate jittering of a given sensor.
- *
- * Remarks:
- * - In order to guarantee proper results in any environment, the maximum sampling rate supported by
- *   the Sensor is used, this guarantees the frequency reference for the test.
- */
-public class VerifyJitteringOperation extends SensorTestOperation {
-    protected SensorManagerTestVerifier mSensor;
-    protected long mExpectedtimestampInNs;
-    protected long mThresholdPercentage;
-    protected long mThresholdInNs;
-
-    public VerifyJitteringOperation(
-            Context context,
-            int sensorType,
-            int reportLatencyInUs,
-            int thresholdPercentageOfNs) throws InvalidParameterException {
-        if(thresholdPercentageOfNs < 0) {
-            throw new InvalidParameterException("thresholdPercentageOfNs needs to be >= 0");
-        }
-        // use the max sampling frequency the sensor reports to guarantee the results
-        int maxSamplingRateInUs = SensorTestInformation.getMaxSamplingRateInUs(context, sensorType);
-        mSensor = new SensorManagerTestVerifier(
-                context,
-                sensorType,
-                maxSamplingRateInUs,
-                reportLatencyInUs);
-        // set expectations
-        mExpectedtimestampInNs = TimeUnit.NANOSECONDS.convert(
-                maxSamplingRateInUs,
-                TimeUnit.MICROSECONDS);
-        mThresholdPercentage = thresholdPercentageOfNs;
-        mThresholdInNs = mExpectedtimestampInNs / mThresholdPercentage;
-    }
-
-    @Override
-    public void doWork() {
-        TestSensorEvent[] events = mSensor.collectEvents(100);
-        VerificationResult result = SensorVerificationHelper.verifyJitter(events, mThresholdInNs);
-        if (result.isFailed()) {
-            Assert.fail(SensorCtsHelper.formatAssertionMessage(
-                    "Jitter(95%ile)",
-                    this,
-                    mSensor.getUnderlyingSensor(),
-                    result.getFailureMessage()));
-        }
-    }
-}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorTestOperations/VerifyMagnitudeOperation.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorTestOperations/VerifyMagnitudeOperation.java
deleted file mode 100644
index cbcff6a..0000000
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorTestOperations/VerifyMagnitudeOperation.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2013 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 android.hardware.cts.helpers.sensorTestOperations;
-
-import android.content.Context;
-import android.hardware.cts.helpers.SensorCtsHelper;
-import android.hardware.cts.helpers.SensorManagerTestVerifier;
-import android.hardware.cts.helpers.SensorTestInformation;
-import android.hardware.cts.helpers.SensorTestOperation;
-import android.hardware.cts.helpers.SensorVerificationHelper;
-import android.hardware.cts.helpers.SensorVerificationHelper.VerificationResult;
-import android.hardware.cts.helpers.TestSensorEvent;
-
-import junit.framework.Assert;
-
-/**
- * Test Operation class that validates the norm of a given sensor.
- * The operation relies in the number of axes each sensor type reports.
- */
-public class VerifyMagnitudeOperation extends SensorTestOperation {
-    private SensorManagerTestVerifier mSensor;
-    private int mAxisCount;
-    private double mReferenceValue;
-    private double mThreshold;
-
-    public VerifyMagnitudeOperation(
-            Context context,
-            int sensorType,
-            int samplingRateInUs,
-            float referenceValue,
-            float threshold) {
-        mSensor = new SensorManagerTestVerifier(
-                context,
-                sensorType,
-                samplingRateInUs,
-                0 /*reportLatencyInUs*/);
-        // set expectations
-        mAxisCount = SensorTestInformation.getAxisCount(mSensor.getUnderlyingSensor().getType());
-        mReferenceValue = referenceValue;
-        mThreshold = threshold;
-    }
-
-    @Override
-    public void doWork() {
-        TestSensorEvent[] events = mSensor.collectEvents(1);
-        VerificationResult result = SensorVerificationHelper.verifyMagnitude(events, mReferenceValue,
-                mThreshold);
-        if (result.isFailed()) {
-            Assert.fail(SensorCtsHelper.formatAssertionMessage(
-                    "Norm",
-                    this,
-                    mSensor.getUnderlyingSensor(),
-                    result.getFailureMessage()));
-        }
-    }
-}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorTestOperations/VerifyMaximumFrequencyOperation.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorTestOperations/VerifyMaximumFrequencyOperation.java
deleted file mode 100644
index 0af15a2..0000000
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorTestOperations/VerifyMaximumFrequencyOperation.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2013 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 android.hardware.cts.helpers.sensorTestOperations;
-
-import android.content.Context;
-import android.hardware.cts.helpers.SensorCtsHelper;
-import android.hardware.cts.helpers.SensorManagerTestVerifier;
-import android.hardware.cts.helpers.SensorTestInformation;
-import android.hardware.cts.helpers.SensorTestOperation;
-import android.hardware.cts.helpers.SensorVerificationHelper;
-import android.hardware.cts.helpers.SensorVerificationHelper.VerificationResult;
-import android.hardware.cts.helpers.TestSensorEvent;
-
-import junit.framework.Assert;
-
-import java.security.InvalidParameterException;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Test Operation class that validates the max sampling rate of a given sensor.
- *
- * Remarks:
- * - In order to guarantee proper results in any environment, the maximum sampling rate supported by
- *   the Sensor is used, this guarantees the frequency reference for the test.
- */
-public class VerifyMaximumFrequencyOperation extends SensorTestOperation {
-    protected SensorManagerTestVerifier mSensor;
-    protected long mExpectedTimestampInNs;
-    protected long mThresholdPercentage;
-    protected long mThresholdInNs;
-
-    public VerifyMaximumFrequencyOperation(
-            Context context,
-            int sensorType,
-            int reportLatencyInUs,
-            int thresholdPercentageOfNs) throws InvalidParameterException {
-        if(thresholdPercentageOfNs < 0) {
-            throw new InvalidParameterException("thresholdPercentageOfNs needs to be >= 0");
-        }
-        // use the max sampling frequency the sensor reports to guarantee the results
-        int maxSamplingRateInUs = SensorTestInformation.getMaxSamplingRateInUs(context, sensorType);
-        mSensor = new SensorManagerTestVerifier(
-                context,
-                sensorType,
-                maxSamplingRateInUs,
-                reportLatencyInUs);
-        // set expectations
-        mExpectedTimestampInNs = TimeUnit.NANOSECONDS.convert(
-                maxSamplingRateInUs,
-                TimeUnit.MICROSECONDS);
-        mThresholdPercentage = thresholdPercentageOfNs;
-        mThresholdInNs = mExpectedTimestampInNs / mThresholdPercentage;
-    }
-
-    @Override
-    public void doWork() {
-        TestSensorEvent[] events = mSensor.collectEvents(100);
-        VerificationResult result = SensorVerificationHelper.verifyFrequency(events,
-                mExpectedTimestampInNs, mThresholdInNs);
-        if (result.isFailed()) {
-            Assert.fail(SensorCtsHelper.formatAssertionMessage(
-                    "Frequency",
-                    this,
-                    mSensor.getUnderlyingSensor(),
-                    result.getFailureMessage()));
-        }
-    }
-}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorTestOperations/VerifyMeasurementsOperation.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorTestOperations/VerifyMeasurementsOperation.java
deleted file mode 100644
index 2368eb4..0000000
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorTestOperations/VerifyMeasurementsOperation.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright 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 android.hardware.cts.helpers.sensorTestOperations;
-
-import android.content.Context;
-import android.hardware.cts.helpers.SensorCtsHelper;
-import android.hardware.cts.helpers.SensorManagerTestVerifier;
-import android.hardware.cts.helpers.SensorTestInformation;
-import android.hardware.cts.helpers.SensorTestOperation;
-import android.hardware.cts.helpers.SensorVerificationHelper;
-import android.hardware.cts.helpers.SensorVerificationHelper.VerificationResult;
-import android.hardware.cts.helpers.TestSensorEvent;
-
-import junit.framework.Assert;
-
-import java.security.InvalidParameterException;
-
-/**
- * Test Operation class that validates the measurements of a a given sensor.
- * The operation relies on the number of axes each sensor type reports.
- * The verification calculates the mean for each axis on the measurements, and verifies that they
- * fall into the expected intervals.
- */
-public class VerifyMeasurementsOperation extends SensorTestOperation {
-    private final SensorManagerTestVerifier mSensor;
-    private final int mAxisCount;
-    private final double[] mReferenceValues;
-    private final double[] mThreshold;
-
-    public VerifyMeasurementsOperation(
-            Context context,
-            int sensorType,
-            int samplingRateInUs,
-            int reportLatencyInUs,
-            double referenceValues[],
-            float threshold) {
-        mAxisCount = SensorTestInformation.getAxisCount(sensorType);
-        if(mAxisCount != referenceValues.length) {
-            throw new InvalidParameterException(
-                    String.format("%d reference values are expected.", mAxisCount));
-        }
-        mSensor = new SensorManagerTestVerifier(
-                context,
-                sensorType,
-                samplingRateInUs,
-                reportLatencyInUs);
-        // set expectations
-        mReferenceValues = referenceValues;
-        mThreshold = new double[mAxisCount];
-        for (int i = 0; i < mThreshold.length; i++) {
-            mThreshold[i] = threshold;
-        }
-    }
-
-    @Override
-    public void doWork() {
-        TestSensorEvent[] events = mSensor.collectEvents(100);
-        VerificationResult result = SensorVerificationHelper.verifyMean(events, mReferenceValues,
-                mThreshold);
-        if (result.isFailed()) {
-            Assert.fail(SensorCtsHelper.formatAssertionMessage(
-                    "Measurement",
-                    this,
-                    mSensor.getUnderlyingSensor(),
-                    result.getFailureMessage()));
-        }
-    }
-}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorTestOperations/VerifySignumOperation.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorTestOperations/VerifySignumOperation.java
deleted file mode 100644
index f58baa1..0000000
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorTestOperations/VerifySignumOperation.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright 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 android.hardware.cts.helpers.sensorTestOperations;
-
-import android.content.Context;
-import android.hardware.cts.helpers.SensorCtsHelper;
-import android.hardware.cts.helpers.SensorManagerTestVerifier;
-import android.hardware.cts.helpers.SensorTestInformation;
-import android.hardware.cts.helpers.SensorTestOperation;
-import android.hardware.cts.helpers.SensorVerificationHelper;
-import android.hardware.cts.helpers.SensorVerificationHelper.VerificationResult;
-import android.hardware.cts.helpers.TestSensorEvent;
-
-import junit.framework.Assert;
-
-import java.security.InvalidParameterException;
-
-/**
- * Test Operation class that validates the sign of measurements of a a given sensor.
- * The operation relies in the number of axes each sensor type reports.
- */
-public class VerifySignumOperation extends SensorTestOperation {
-    private final SensorManagerTestVerifier mSensor;
-    private final int mAxisCount;
-    private final int mReferenceValues[];
-    private final double mNoiseThresholds[];
-
-    /**
-     * @param noiseThreshold Defines the threshold that needs to be crossed to consider a
-     *                       measurement different from zero
-     */
-    public VerifySignumOperation(
-            Context context,
-            int sensorType,
-            int samplingRateInUs,
-            int referenceValues[],
-            double noiseThreshold) {
-        mAxisCount = SensorTestInformation.getAxisCount(sensorType);
-        if(mAxisCount != referenceValues.length) {
-            throw new InvalidParameterException(
-                    String.format("%d reference values are expected.", mAxisCount));
-        }
-        for(int i = 0; i < referenceValues.length; ++i) {
-            int value = referenceValues[i];
-            if(value != 0 && value != -1 && value != +1) {
-                throw new InvalidParameterException(
-                        "A ReferenceValue can only be one of the following: -1, 0, +1");
-            }
-        }
-        mSensor = new SensorManagerTestVerifier(
-                context,
-                sensorType,
-                samplingRateInUs,
-                0 /*reportLatencyInUs*/);
-        // set expectations
-        mReferenceValues = referenceValues;
-        mNoiseThresholds = new double[mReferenceValues.length];
-        for (int i = 0; i < mNoiseThresholds.length; i++) {
-            mNoiseThresholds[i] = noiseThreshold;
-        }
-    }
-
-    @Override
-    public void doWork() {
-        TestSensorEvent[] events = mSensor.collectEvents(100);
-        VerificationResult result = SensorVerificationHelper.verifySignum(events, mReferenceValues,
-                mNoiseThresholds);
-        if (result.isFailed()) {
-            Assert.fail(SensorCtsHelper.formatAssertionMessage(
-                    "Measurement",
-                    this,
-                    mSensor.getUnderlyingSensor(),
-                    result.getFailureMessage()));
-        }
-    }
-}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorTestOperations/VerifyStandardDeviationOperation.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorTestOperations/VerifyStandardDeviationOperation.java
deleted file mode 100644
index 05b92e0..0000000
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorTestOperations/VerifyStandardDeviationOperation.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2013 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 android.hardware.cts.helpers.sensorTestOperations;
-
-import android.content.Context;
-import android.hardware.cts.helpers.SensorCtsHelper;
-import android.hardware.cts.helpers.SensorManagerTestVerifier;
-import android.hardware.cts.helpers.SensorTestInformation;
-import android.hardware.cts.helpers.SensorTestOperation;
-import android.hardware.cts.helpers.SensorVerificationHelper;
-import android.hardware.cts.helpers.SensorVerificationHelper.VerificationResult;
-import android.hardware.cts.helpers.TestSensorEvent;
-
-import junit.framework.Assert;
-
-/**
- * Test Operation class that validates the standard deviation of a given sensor.
- */
-public class VerifyStandardDeviationOperation extends SensorTestOperation {
-    private SensorManagerTestVerifier mSensor;
-    private int mAxisCount;
-    private double[] mExpectedStandardDeviation;
-
-    public VerifyStandardDeviationOperation(
-            Context context,
-            int sensorType,
-            int samplingRateInUs,
-            int reportLatencyInUs,
-            float expectedStandardDeviation) {
-        mSensor = new SensorManagerTestVerifier(
-                context,
-                sensorType,
-                samplingRateInUs,
-                reportLatencyInUs);
-        // set expectations
-        mAxisCount = SensorTestInformation.getAxisCount(mSensor.getUnderlyingSensor().getType());
-        mExpectedStandardDeviation = new double[mAxisCount];
-        for (int i = 0; i < mExpectedStandardDeviation.length; i++) {
-            mExpectedStandardDeviation[i] = expectedStandardDeviation;
-        }
-    }
-
-    @Override
-    public void doWork() {
-        TestSensorEvent[] events = mSensor.collectEvents(100);
-        VerificationResult result = SensorVerificationHelper.verifyStandardDeviation(events,
-                mExpectedStandardDeviation);
-        if (result.isFailed()) {
-            Assert.fail(SensorCtsHelper.formatAssertionMessage(
-                    "StandardDeviation",
-                    this,
-                    mSensor.getUnderlyingSensor(),
-                    result.getFailureMessage()));
-        }
-    }
-}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/AbstractSensorOperation.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/AbstractSensorOperation.java
new file mode 100644
index 0000000..5b969f2
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/AbstractSensorOperation.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2014 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 android.hardware.cts.helpers.sensoroperations;
+
+import android.hardware.cts.helpers.SensorStats;
+
+/**
+ * A {@link ISensorOperation} which contains a common implementation for gathering
+ * {@link SensorStats}.
+ */
+public abstract class AbstractSensorOperation implements ISensorOperation {
+
+    private final SensorStats mStats = new SensorStats();
+
+    /**
+     * Wrapper around {@link SensorStats#addSensorStats(String, SensorStats)}
+     */
+    protected void addSensorStats(String key, SensorStats stats) {
+        mStats.addSensorStats(key, stats);
+    }
+
+    /**
+     * Wrapper around {@link SensorStats#addSensorStats(String, SensorStats)} that allows an index
+     * to be added. This is useful for {@link ISensorOperation}s that have many iterations or child
+     * operations. The key added is in the form {@code key + "_" + index} where index may be zero
+     * padded.
+     */
+    protected void addSensorStats(String key, int index, SensorStats stats) {
+        addSensorStats(String.format("%s_%03d", key, index), stats);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public SensorStats getStats() {
+        return mStats;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public abstract ISensorOperation clone();
+
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/AlarmOperation.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/AlarmOperation.java
new file mode 100644
index 0000000..95f1248
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/AlarmOperation.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2014 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 android.hardware.cts.helpers.sensoroperations;
+
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.hardware.cts.helpers.SensorStats;
+import android.os.PowerManager;
+import android.os.PowerManager.WakeLock;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * An {@link ISensorOperation} which performs another {@link ISensorOperation} and then wakes up
+ * after a specified period of time and waits for the child operation to complete.
+ * <p>
+ * This operation can be used to allow the device to go to sleep and wake it up after a specified
+ * period of time. After the device wakes up, this operation will hold a wake lock until the child
+ * operation finishes. This operation will not force the device into suspend, so if another
+ * operation is holding a wake lock, the device will stay awake.  Also, if the child operation
+ * finishes before the specified period, this operation return when the child operation finishes
+ * but wake the device one time at the specified period.
+ * </p>
+ */
+public class AlarmOperation extends AbstractSensorOperation {
+    private static final String ACTION = "AlarmOperationAction";
+    private static final String WAKE_LOCK_TAG = "AlarmOperationWakeLock";
+
+    private final ISensorOperation mOperation;
+    private final Context mContext;
+    private final long mSleepDuration;
+    private final TimeUnit mTimeUnit;
+
+    private boolean mCompleted = false;
+    private WakeLock mWakeLock = null;
+
+    /**
+     * Constructor for {@link DelaySensorOperation}
+     *
+     * @param operation the child {@link ISensorOperation} to perform after the delay
+     * @param context the context used to access the alarm manager
+     * @param sleepDuration the amount of time to sleep
+     * @param timeUnit the unit of the duration
+     */
+    public AlarmOperation(ISensorOperation operation, Context context, long sleepDuration,
+            TimeUnit timeUnit) {
+        mOperation = operation;
+        mContext = context;
+        mSleepDuration = sleepDuration;
+        mTimeUnit = timeUnit;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void execute() {
+        // Start alarm
+        IntentFilter intentFilter = new IntentFilter(ACTION);
+        BroadcastReceiver receiver = new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                acquireWakeLock();
+            }
+        };
+        mContext.registerReceiver(receiver, intentFilter);
+
+        AlarmManager am = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
+        long wakeupTimeMs = (System.currentTimeMillis()
+                + TimeUnit.MILLISECONDS.convert(mSleepDuration, mTimeUnit));
+        Intent intent = new Intent(ACTION);
+        PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0);
+        am.setExact(AlarmManager.RTC_WAKEUP, wakeupTimeMs, pendingIntent);
+
+        // Execute operation
+        try {
+            mOperation.execute();
+        } finally {
+            releaseWakeLock();
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public SensorStats getStats() {
+        return mOperation.getStats();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public AlarmOperation clone() {
+        return new AlarmOperation(mOperation, mContext, mSleepDuration, mTimeUnit);
+    }
+
+    /**
+     * Method that acquires a wake lock if a wake lock has not already been acquired and if the
+     * operation has not yet completed.
+     */
+    private synchronized void acquireWakeLock() {
+        // Don't acquire wake lock if the operation has already completed.
+        if (mCompleted == true || mWakeLock != null) {
+            return;
+        }
+        PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
+        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKE_LOCK_TAG);
+    }
+
+    /**
+     * Method that releases the wake lock if it has been acquired.
+     */
+    private synchronized void releaseWakeLock() {
+        mCompleted = true;
+        if (mWakeLock != null) {
+            mWakeLock.release();
+        }
+        mWakeLock = null;
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/DelaySensorOperation.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/DelaySensorOperation.java
new file mode 100644
index 0000000..bf43189
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/DelaySensorOperation.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2014 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 android.hardware.cts.helpers.sensoroperations;
+
+import android.hardware.cts.helpers.SensorCtsHelper;
+import android.hardware.cts.helpers.SensorStats;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * An {@link ISensorOperation} which delays for a specified period of time before performing another
+ * {@link ISensorOperation}.
+ */
+public class DelaySensorOperation implements ISensorOperation {
+    private final ISensorOperation mOperation;
+    private final long mDelay;
+    private final TimeUnit mTimeUnit;
+
+    /**
+     * Constructor for {@link DelaySensorOperation}
+     *
+     * @param operation the child {@link ISensorOperation} to perform after the delay
+     * @param delay the amount of time to delay
+     * @param timeUnit the unit of the delay
+     */
+    public DelaySensorOperation(ISensorOperation operation, long delay, TimeUnit timeUnit) {
+        if (operation == null || timeUnit == null) {
+            throw new IllegalArgumentException("Arguments cannot be null");
+        }
+        mOperation = operation;
+        mDelay = delay;
+        mTimeUnit = timeUnit;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void execute() {
+        sleep(mDelay, mTimeUnit);
+        mOperation.execute();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public SensorStats getStats() {
+        return mOperation.getStats();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public DelaySensorOperation clone() {
+        return new DelaySensorOperation(mOperation.clone(), mDelay, mTimeUnit);
+    }
+
+    /**
+     * Helper method to sleep for a given number of ns. Exposed for unit testing.
+     */
+    void sleep(long delay, TimeUnit timeUnit) {
+        SensorCtsHelper.sleep(delay, timeUnit);
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/FakeSensorOperation.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/FakeSensorOperation.java
new file mode 100644
index 0000000..bb64dfa
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/FakeSensorOperation.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2014 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 android.hardware.cts.helpers.sensoroperations;
+
+import android.hardware.cts.helpers.SensorStats;
+
+import junit.framework.Assert;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * A fake {@ISensorOperation} that will run for a specified time and then pass or fail. Useful when
+ * debugging the framework.
+ */
+public class FakeSensorOperation extends AbstractSensorOperation {
+    private static final int NANOS_PER_MILLI = 1000000;
+
+    private final boolean mFail;
+    private final long mDelay;
+    private final TimeUnit mTimeUnit;
+
+    /**
+     * Constructor for {@link FakeSensorOperation} that passes
+     */
+    public FakeSensorOperation(long delay, TimeUnit timeUnit) {
+        this(false, delay, timeUnit);
+    }
+
+    /**
+     * Constructor for {@link FakeSensorOperation}
+     */
+    public FakeSensorOperation(boolean fail, long delay, TimeUnit timeUnit) {
+        if (timeUnit == null) {
+            throw new IllegalArgumentException("Arguments cannot be null");
+        }
+        mFail = fail;
+        mDelay = delay;
+        mTimeUnit = timeUnit;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void execute() {
+        long delayNs = TimeUnit.NANOSECONDS.convert(mDelay, mTimeUnit);
+        try {
+            Thread.sleep(delayNs / NANOS_PER_MILLI, (int) (delayNs % NANOS_PER_MILLI));
+            getStats().addValue("executed", true);
+            if (mFail) {
+                doFail();
+            }
+        }catch (InterruptedException e) {
+            // Ignore
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public FakeSensorOperation clone() {
+        return new FakeSensorOperation(mFail, mDelay, mTimeUnit);
+    }
+
+    /**
+     * Fails the operation.
+     */
+    protected void doFail() {
+        String msg = "FakeSensorOperation failed";
+        getStats().addValue(SensorStats.ERROR, msg);
+        Assert.fail(msg);
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/ISensorOperation.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/ISensorOperation.java
new file mode 100644
index 0000000..4ae56ea
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/ISensorOperation.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2014 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 android.hardware.cts.helpers.sensoroperations;
+
+import android.hardware.cts.helpers.SensorStats;
+
+/**
+ * Interface used by all sensor operations. This allows for complex operations such as chaining
+ * operations together or running operations in parallel.
+ * <p>
+ * Certain restrictions exist for {@link ISensorOperation}s:
+ * <p><ul>
+ * <li>{@link #execute()} should only be called once and behavior is undefined for subsequent calls.
+ * Once {@link #execute()} is called, the class should not be modified. Generally, there is no
+ * synchronization for operations.</li>
+ * <li>{@link #getStats()} should only be called after {@link #execute()}. If it is called before,
+ * the returned value is undefined.</li>
+ * <li>{@link #clone()} may be called any time and should return an operation with the same
+ * parameters as the original.</li>
+ * </ul>
+ */
+public interface ISensorOperation {
+
+    /**
+     * Executes the sensor operation.  This may throw {@link RuntimeException}s such as
+     * {@link AssertionError}s.
+     */
+    public void execute();
+
+    /**
+     * Get the stats for the operation.
+     *
+     * @return The {@link SensorStats} for the operation.
+     */
+    public SensorStats getStats();
+
+    /**
+     * Clones the {@link ISensorOperation}. The implementation should also clone all child
+     * operations, so that a cloned operation will run with the exact same parameters as the
+     * original. The stats should not be cloned.
+     *
+     * @return The cloned {@link ISensorOperation}
+     */
+    public ISensorOperation clone();
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/ParallelSensorOperation.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/ParallelSensorOperation.java
new file mode 100644
index 0000000..4cca428
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/ParallelSensorOperation.java
@@ -0,0 +1,257 @@
+/*
+ * Copyright (C) 2013 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 android.hardware.cts.helpers.sensoroperations;
+
+import android.hardware.cts.helpers.SensorStats;
+import android.util.Log;
+
+import junit.framework.Assert;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * A {@link ISensorOperation} that executes a set of children {@link ISensorOperation}s in parallel.
+ * The children are run in parallel but are given an index label in the order they are added. This
+ * class can be combined to compose complex {@link ISensorOperation}s.
+ */
+public class ParallelSensorOperation extends AbstractSensorOperation {
+    public static final String STATS_TAG = "parallel";
+
+    private static final String TAG = "ParallelSensorOperation";
+    private static final int NANOS_PER_MILLI = 1000000;
+
+    private final List<ISensorOperation> mOperations = new LinkedList<ISensorOperation>();
+    private final Long mTimeout;
+    private final TimeUnit mTimeUnit;
+
+    /**
+     * Constructor for the {@link ParallelSensorOperation} without a timeout.
+     */
+    public ParallelSensorOperation() {
+        mTimeout = null;
+        mTimeUnit = null;
+    }
+
+    /**
+     * Constructor for the {@link ParallelSensorOperation} with a timeout.
+     */
+    public ParallelSensorOperation(long timeout, TimeUnit timeUnit) {
+        if (timeUnit == null) {
+            throw new IllegalArgumentException("Arguments cannot be null");
+        }
+        mTimeout = timeout;
+        mTimeUnit = timeUnit;
+    }
+
+    /**
+     * Add a set of {@link ISensorOperation}s.
+     */
+    public void add(ISensorOperation ... operations) {
+        for (ISensorOperation operation : operations) {
+            if (operation == null) {
+                throw new IllegalArgumentException("Arguments cannot be null");
+            }
+            mOperations.add(operation);
+        }
+    }
+
+    /**
+     * Executes the {@link ISensorOperation}s in parallel. If an exception occurs one or more
+     * operations, the first exception will be thrown once all operations are completed.
+     */
+    @Override
+    public void execute() {
+        Long timeoutTimeNs = null;
+        if (mTimeout != null && mTimeUnit != null) {
+            timeoutTimeNs = System.nanoTime() + TimeUnit.NANOSECONDS.convert(mTimeout, mTimeUnit);
+        }
+
+        List<OperationThread> threadPool = new ArrayList<OperationThread>(mOperations.size());
+        for (final ISensorOperation operation : mOperations) {
+            OperationThread thread = new OperationThread(operation);
+            thread.start();
+            threadPool.add(thread);
+        }
+
+        List<Integer> timeoutIndices = new ArrayList<Integer>();
+        List<OperationExceptionInfo> exceptions = new ArrayList<OperationExceptionInfo>();
+        Throwable earliestException = null;
+        Long earliestExceptionTime = null;
+
+        for (int i = 0; i < threadPool.size(); i++) {
+            OperationThread thread = threadPool.get(i);
+            join(thread, timeoutTimeNs);
+            if (thread.isAlive()) {
+                timeoutIndices.add(i);
+                thread.interrupt();
+            }
+
+            Throwable exception = thread.getException();
+            Long exceptionTime = thread.getExceptionTime();
+            if (exception != null && exceptionTime != null) {
+                if (exception instanceof AssertionError) {
+                    exceptions.add(new OperationExceptionInfo(i, (AssertionError) exception));
+                }
+                if (earliestExceptionTime == null || exceptionTime < earliestExceptionTime) {
+                    earliestException = exception;
+                    earliestExceptionTime = exceptionTime;
+                }
+            }
+
+            addSensorStats(STATS_TAG, i, thread.getSensorOperation().getStats());
+        }
+
+        if (earliestException == null) {
+            if (timeoutIndices.size() > 0) {
+                Assert.fail(getTimeoutMessage(timeoutIndices));
+            }
+        } else if (earliestException instanceof AssertionError) {
+            String msg = getExceptionMessage(exceptions, timeoutIndices);
+            getStats().addValue(SensorStats.ERROR, msg);
+            throw new AssertionError(msg, earliestException);
+        } else if (earliestException instanceof RuntimeException) {
+            throw (RuntimeException) earliestException;
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public ParallelSensorOperation clone() {
+        ParallelSensorOperation operation = new ParallelSensorOperation();
+        for (ISensorOperation subOperation : mOperations) {
+            operation.add(subOperation.clone());
+        }
+        return operation;
+    }
+
+    /**
+     * Helper method that joins a thread at a given time in the future.
+     */
+    private void join(Thread thread, Long timeoutTimeNs) {
+        try {
+            if (timeoutTimeNs == null) {
+                thread.join();
+            } else {
+                // Cap wait time to 1ns so that join doesn't block indefinitely.
+                long waitTimeNs = Math.max(timeoutTimeNs - System.nanoTime(), 1);
+                thread.join(waitTimeNs / NANOS_PER_MILLI, (int) waitTimeNs % NANOS_PER_MILLI);
+            }
+        } catch (InterruptedException e) {
+            // Log and ignore
+            Log.w(TAG, "Thread interrupted during join, operations may timeout before expected"
+                    + " time");
+        }
+    }
+
+    /**
+     * Helper method for joining the exception messages used in assertions.
+     */
+    private String getExceptionMessage(List<OperationExceptionInfo> exceptions,
+            List<Integer> timeoutIndices) {
+        StringBuilder sb = new StringBuilder();
+        sb.append(exceptions.get(0).toString());
+        for (int i = 1; i < exceptions.size(); i++) {
+            sb.append(", ").append(exceptions.get(i).toString());
+        }
+        if (timeoutIndices.size() > 0) {
+            sb.append(", ").append(getTimeoutMessage(timeoutIndices));
+        }
+        return sb.toString();
+    }
+
+    /**
+     * Helper method for formatting the operation timed out message used in assertions
+     */
+    private String getTimeoutMessage(List<Integer> indices) {
+        StringBuilder sb = new StringBuilder();
+        sb.append("Operation");
+        if (indices.size() != 1) {
+            sb.append("s");
+        }
+        sb.append(" ").append(indices.get(0));
+        for (int i = 1; i < indices.size(); i++) {
+            sb.append(", ").append(indices.get(i));
+        }
+        sb.append(" timed out");
+        return sb.toString();
+    }
+
+    /**
+     * Helper class for holding operation index and exception
+     */
+    private class OperationExceptionInfo {
+        private final int mIndex;
+        private final AssertionError mException;
+
+        public OperationExceptionInfo(int index, AssertionError exception) {
+            mIndex = index;
+            mException = exception;
+        }
+
+        @Override
+        public String toString() {
+            return String.format("Operation %d failed: \"%s\"", mIndex, mException.getMessage());
+        }
+    }
+
+    /**
+     * Helper class to run the {@link ISensorOperation} in its own thread.
+     */
+    private class OperationThread extends Thread {
+        final private ISensorOperation mOperation;
+        private Throwable mException = null;
+        private Long mExceptionTime = null;
+
+        public OperationThread(ISensorOperation operation) {
+            mOperation = operation;
+        }
+
+        /**
+         * Run the thread catching {@link RuntimeException}s and {@link AssertionError}s and
+         * the time it happened.
+         */
+        @Override
+        public void run() {
+            try {
+                mOperation.execute();
+            } catch (AssertionError e) {
+                mExceptionTime = System.nanoTime();
+                mException = e;
+            } catch (RuntimeException e) {
+                mExceptionTime = System.nanoTime();
+                mException = e;
+            }
+        }
+
+        public ISensorOperation getSensorOperation() {
+            return mOperation;
+        }
+
+        public Throwable getException() {
+            return mException;
+        }
+
+        public Long getExceptionTime() {
+            return mExceptionTime;
+        }
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/RepeatingSensorOperation.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/RepeatingSensorOperation.java
new file mode 100644
index 0000000..5e023e5
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/RepeatingSensorOperation.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2013 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 android.hardware.cts.helpers.sensoroperations;
+
+import android.hardware.cts.helpers.SensorStats;
+
+/**
+ * A {@link ISensorOperation} that executes a single {@link ISensorOperation} a given number of
+ * times. This class can be combined to compose complex {@link ISensorOperation}s.
+ */
+public class RepeatingSensorOperation extends AbstractSensorOperation {
+    public static final String STATS_TAG = "repeating";
+
+    private final ISensorOperation mOperation;
+    private final int mIterations;
+
+    /**
+     * Constructor for {@link RepeatingSensorOperation}.
+     *
+     * @param operation the {@link ISensorOperation} to run.
+     * @param iterations the number of iterations to run the operation for.
+     */
+    public RepeatingSensorOperation(ISensorOperation operation, int iterations) {
+        if (operation == null) {
+            throw new IllegalArgumentException("Arguments cannot be null");
+        }
+        mOperation = operation;
+        mIterations = iterations;
+
+    }
+
+    /**
+     * Executes the {@link ISensorOperation}s the given number of times. If an exception occurs
+     * in one iterations, it is thrown and all subsequent iterations will not run.
+     */
+    @Override
+    public void execute() {
+        for(int i = 0; i < mIterations; ++i) {
+            ISensorOperation operation = mOperation.clone();
+            try {
+                operation.execute();
+            } catch (AssertionError e) {
+                String msg = String.format("Iteration %d failed: \"%s\"", i, e.getMessage());
+                getStats().addValue(SensorStats.ERROR, msg);
+                throw new AssertionError(msg, e);
+            } finally {
+                addSensorStats(STATS_TAG, i, operation.getStats());
+            }
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public RepeatingSensorOperation clone() {
+        return new RepeatingSensorOperation(mOperation.clone(), mIterations);
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/SensorOperationTest.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/SensorOperationTest.java
new file mode 100644
index 0000000..7148454
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/SensorOperationTest.java
@@ -0,0 +1,336 @@
+/*
+ * Copyright (C) 2014 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 android.hardware.cts.helpers.sensoroperations;
+
+import android.hardware.cts.helpers.SensorStats;
+
+import junit.framework.TestCase;
+
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Tests for the primitive {@link ISensorOperation}s including {@link DelaySensorOperation},
+ * {@link ParallelSensorOperation}, {@link RepeatingSensorOperation} and
+ * {@link SequentialSensorOperation}.
+ */
+public class SensorOperationTest extends TestCase {
+    private static final int THRESHOLD_MS = 50;
+
+    /**
+     * Test that the {@link FakeSensorOperation} functions correctly. Other tests in this class
+     * rely on this operation.
+     */
+    public void testFakeSensorOperation() {
+        final int opDurationMs = 100;
+
+        ISensorOperation op = new FakeSensorOperation(opDurationMs, TimeUnit.MILLISECONDS);
+
+        assertFalse(op.getStats().flatten().containsKey("executed"));
+        long start = System.currentTimeMillis();
+        op.execute();
+        long duration = System.currentTimeMillis() - start;
+        assertTrue(Math.abs(opDurationMs - duration) < THRESHOLD_MS);
+        assertTrue(op.getStats().flatten().containsKey("executed"));
+
+        op = new FakeSensorOperation(true, 0, TimeUnit.MILLISECONDS);
+        try {
+            op.execute();
+            fail("AssertionError expected");
+        } catch (AssertionError e) {
+            // Expected
+        }
+        assertTrue(op.getStats().flatten().keySet().contains(SensorStats.ERROR));
+    }
+
+    /**
+     * Test that the {@link DelaySensorOperation} functions correctly.
+     */
+    public void testDelaySensorOperation() {
+        final int opDurationMs = 500;
+        final int subOpDurationMs = 100;
+
+        FakeSensorOperation subOp = new FakeSensorOperation(subOpDurationMs, TimeUnit.MILLISECONDS);
+        ISensorOperation op = new DelaySensorOperation(subOp, opDurationMs, TimeUnit.MILLISECONDS);
+
+        long start = System.currentTimeMillis();
+        op.execute();
+        long duration = System.currentTimeMillis() - start;
+        assertTrue(Math.abs(opDurationMs + subOpDurationMs - duration) < THRESHOLD_MS);
+    }
+
+    /**
+     * Test that the {@link ParallelSensorOperation} functions correctly.
+     */
+    public void testParallelSensorOperation() {
+        final int subOpCount = 100;
+        final int subOpDurationMs = 500;
+
+        ParallelSensorOperation op = new ParallelSensorOperation();
+        for (int i = 0; i < subOpCount; i++) {
+            ISensorOperation subOp = new FakeSensorOperation(subOpDurationMs,
+                    TimeUnit.MILLISECONDS);
+            op.add(subOp);
+        }
+
+        Set<String> statsKeys = op.getStats().flatten().keySet();
+        assertEquals(0, statsKeys.size());
+
+        long start = System.currentTimeMillis();
+        op.execute();
+        long duration = System.currentTimeMillis() - start;
+        assertTrue(Math.abs(subOpDurationMs - duration) < THRESHOLD_MS);
+
+        statsKeys = op.getStats().flatten().keySet();
+        assertEquals(subOpCount, statsKeys.size());
+        for (int i = 0; i < subOpCount; i++) {
+            assertTrue(statsKeys.contains(String.format("%s_%03d%sexecuted",
+                    ParallelSensorOperation.STATS_TAG, i, SensorStats.DELIMITER)));
+        }
+    }
+
+    /**
+     * Test that the {@link ParallelSensorOperation} functions correctly if there is a failure in
+     * a child operation.
+     */
+    public void testParallelSensorOperation_fail() {
+        final int subOpCount = 100;
+
+        ParallelSensorOperation op = new ParallelSensorOperation();
+        for (int i = 0; i < subOpCount; i++) {
+            // Trigger failures in the 5th, 55th operations at t=5ms, t=55ms
+            ISensorOperation subOp = new FakeSensorOperation(i % 50 == 5, i, TimeUnit.MILLISECONDS);
+            op.add(subOp);
+        }
+
+        Set<String> statsKeys = op.getStats().flatten().keySet();
+        assertEquals(0, statsKeys.size());
+
+        try {
+            op.execute();
+            fail("AssertionError expected");
+        } catch (AssertionError e) {
+            // Expected
+            System.out.println(e.getMessage());
+            // TODO: Verify that the exception rethrown was at t=5ms.
+        }
+
+        statsKeys = op.getStats().flatten().keySet();
+        assertEquals(subOpCount + 3, statsKeys.size());
+        for (int i = 0; i < subOpCount; i++) {
+            assertTrue(statsKeys.contains(String.format("%s_%03d%sexecuted",
+                    ParallelSensorOperation.STATS_TAG, i, SensorStats.DELIMITER)));
+            if (i % 50 == 5) {
+                assertTrue(statsKeys.contains(String.format("%s_%03d%s%s",
+                        ParallelSensorOperation.STATS_TAG, i, SensorStats.DELIMITER,
+                        SensorStats.ERROR)));
+            }
+
+        }
+        assertTrue(statsKeys.contains(SensorStats.ERROR));
+    }
+
+    /**
+     * Test that the {@link ParallelSensorOperation} functions correctly if a child exceeds the
+     * timeout.
+     */
+    public void testParallelSensorOperation_timeout() {
+        final int subOpCount = 100;
+
+        ParallelSensorOperation op = new ParallelSensorOperation(100, TimeUnit.MILLISECONDS);
+        for (int i = 0; i < subOpCount; i++) {
+            // Trigger timeouts in the 5th, 55th operations (5 seconds vs 0 seconds)
+            ISensorOperation subOp = new FakeSensorOperation(i % 50 == 5 ? 5 : 0, TimeUnit.SECONDS);
+            op.add(subOp);
+        }
+
+        Set<String> statsKeys = op.getStats().flatten().keySet();
+        assertEquals(0, statsKeys.size());
+
+        try {
+            op.execute();
+            fail("AssertionError expected");
+        } catch (AssertionError e) {
+            // Expected
+            System.out.println(e.getMessage());
+            // TODO: Verify that the exception rethrown was at t=5ms.
+        }
+
+        statsKeys = op.getStats().flatten().keySet();
+        assertEquals(subOpCount - 2, statsKeys.size());
+        for (int i = 0; i < subOpCount; i++) {
+            if (i % 50 != 5) {
+                assertTrue(statsKeys.contains(String.format("%s_%03d%sexecuted",
+                        ParallelSensorOperation.STATS_TAG, i, SensorStats.DELIMITER)));
+            }
+        }
+    }
+
+    /**
+     * Test that the {@link RepeatingSensorOperation} functions correctly.
+     */
+    public void testRepeatingSensorOperation() {
+        final int iterations = 10;
+        final int subOpDurationMs = 100;
+
+        ISensorOperation subOp = new FakeSensorOperation(subOpDurationMs, TimeUnit.MILLISECONDS);
+        ISensorOperation op = new RepeatingSensorOperation(subOp, iterations);
+
+        Set<String> statsKeys = op.getStats().flatten().keySet();
+        assertEquals(0, statsKeys.size());
+
+        long start = System.currentTimeMillis();
+        op.execute();
+        long duration = System.currentTimeMillis() - start;
+        assertTrue(Math.abs(subOpDurationMs * iterations - duration) < THRESHOLD_MS);
+
+        statsKeys = op.getStats().flatten().keySet();
+        assertEquals(iterations, statsKeys.size());
+        for (int i = 0; i < iterations; i++) {
+            assertTrue(statsKeys.contains(String.format("%s_%03d%sexecuted",
+                    RepeatingSensorOperation.STATS_TAG, i, SensorStats.DELIMITER)));
+        }
+    }
+
+    /**
+     * Test that the {@link RepeatingSensorOperation} functions correctly if there is a failure in
+     * a child operation.
+     */
+    public void testRepeatingSensorOperation_fail() {
+        final int iterations = 100;
+        final int failCount = 75;
+
+        ISensorOperation subOp = new FakeSensorOperation(0, TimeUnit.MILLISECONDS) {
+            private int mExecutedCount = 0;
+            private SensorStats mFakeStats = new SensorStats();
+
+            @Override
+            public void execute() {
+                super.execute();
+                mExecutedCount++;
+
+                if (failCount == mExecutedCount) {
+                    doFail();
+                }
+            }
+
+            @Override
+            public FakeSensorOperation clone() {
+                // Don't clone
+                mFakeStats = new SensorStats();
+                return this;
+            }
+
+            @Override
+            public SensorStats getStats() {
+                return mFakeStats;
+            }
+        };
+        ISensorOperation op = new RepeatingSensorOperation(subOp, iterations);
+
+        Set<String> statsKeys = op.getStats().flatten().keySet();
+        assertEquals(0, statsKeys.size());
+
+        try {
+            op.execute();
+            fail("AssertionError expected");
+        } catch (AssertionError e) {
+            // Expected
+            System.out.println(e.getMessage());
+        }
+
+        statsKeys = op.getStats().flatten().keySet();
+        assertEquals(failCount + 2, statsKeys.size());
+        for (int i = 0; i < failCount; i++) {
+            assertTrue(statsKeys.contains(String.format("%s_%03d%sexecuted",
+                    RepeatingSensorOperation.STATS_TAG, i, SensorStats.DELIMITER)));
+        }
+        assertTrue(statsKeys.contains(String.format("%s_%03d%s%s",
+                RepeatingSensorOperation.STATS_TAG, failCount - 1, SensorStats.DELIMITER,
+                SensorStats.ERROR)));
+        assertTrue(statsKeys.contains(SensorStats.ERROR));
+    }
+
+    /**
+     * Test that the {@link SequentialSensorOperation} functions correctly.
+     */
+    public void testSequentialSensorOperation() {
+        final int subOpCount = 10;
+        final int subOpDurationMs = 100;
+
+        SequentialSensorOperation op = new SequentialSensorOperation();
+        for (int i = 0; i < subOpCount; i++) {
+            ISensorOperation subOp = new FakeSensorOperation(subOpDurationMs,
+                    TimeUnit.MILLISECONDS);
+            op.add(subOp);
+        }
+
+        Set<String> statsKeys = op.getStats().flatten().keySet();
+        assertEquals(0, statsKeys.size());
+
+        long start = System.currentTimeMillis();
+        op.execute();
+        long duration = System.currentTimeMillis() - start;
+        assertTrue(Math.abs(subOpDurationMs * subOpCount - duration) < THRESHOLD_MS);
+
+        statsKeys = op.getStats().flatten().keySet();
+        assertEquals(subOpCount, statsKeys.size());
+        for (int i = 0; i < subOpCount; i++) {
+            assertTrue(statsKeys.contains(String.format("%s_%03d%sexecuted",
+                    SequentialSensorOperation.STATS_TAG, i, SensorStats.DELIMITER)));
+        }
+    }
+
+    /**
+     * Test that the {@link SequentialSensorOperation} functions correctly if there is a failure in
+     * a child operation.
+     */
+    public void testSequentialSensorOperation_fail() {
+        final int subOpCount = 100;
+        final int failCount = 75;
+
+        SequentialSensorOperation op = new SequentialSensorOperation();
+        for (int i = 0; i < subOpCount; i++) {
+            // Trigger a failure in the 75th operation only
+            ISensorOperation subOp = new FakeSensorOperation(i + 1 == failCount, 0,
+                    TimeUnit.MILLISECONDS);
+            op.add(subOp);
+        }
+
+        Set<String> statsKeys = op.getStats().flatten().keySet();
+        assertEquals(0, statsKeys.size());
+
+        try {
+            op.execute();
+            fail("AssertionError expected");
+        } catch (AssertionError e) {
+            // Expected
+            System.out.println(e.getMessage());
+        }
+
+        statsKeys = op.getStats().flatten().keySet();
+        assertEquals(failCount + 2, statsKeys.size());
+        for (int i = 0; i < failCount; i++) {
+            assertTrue(statsKeys.contains(String.format("%s_%03d%sexecuted",
+                    SequentialSensorOperation.STATS_TAG, i, SensorStats.DELIMITER)));
+        }
+        assertTrue(statsKeys.contains(String.format("%s_%03d%s%s",
+                SequentialSensorOperation.STATS_TAG, failCount - 1, SensorStats.DELIMITER,
+                SensorStats.ERROR)));
+        assertTrue(statsKeys.contains(SensorStats.ERROR));
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/SequentialSensorOperation.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/SequentialSensorOperation.java
new file mode 100644
index 0000000..050a8f6
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/SequentialSensorOperation.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2013 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 android.hardware.cts.helpers.sensoroperations;
+
+import android.hardware.cts.helpers.SensorStats;
+
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * A {@link ISensorOperation} that executes a set of children {@link ISensorOperation}s in a
+ * sequence. The children are executed in the order they are added. This class can be combined to
+ * compose complex {@link ISensorOperation}s.
+ */
+public class SequentialSensorOperation extends AbstractSensorOperation {
+    public static final String STATS_TAG = "sequential";
+
+    private final List<ISensorOperation> mOperations = new LinkedList<ISensorOperation>();
+
+    /**
+     * Add a set of {@link ISensorOperation}s.
+     */
+    public void add(ISensorOperation ... operations) {
+        for (ISensorOperation operation : operations) {
+            if (operation == null) {
+                throw new IllegalArgumentException("Arguments cannot be null");
+            }
+            mOperations.add(operation);
+        }
+    }
+
+    /**
+     * Executes the {@link ISensorOperation}s in the order they were added. If an exception occurs
+     * in one operation, it is thrown and all subsequent operations will not run.
+     */
+    @Override
+    public void execute() {
+        for (int i = 0; i < mOperations.size(); i++) {
+            ISensorOperation operation = mOperations.get(i);
+            try {
+                operation.execute();
+            } catch (AssertionError e) {
+                String msg = String.format("Operation %d failed: \"%s\"", i, e.getMessage());
+                getStats().addValue(SensorStats.ERROR, msg);
+                throw new AssertionError(msg, e);
+            } finally {
+                addSensorStats(STATS_TAG, i, operation.getStats());
+            }
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public SequentialSensorOperation clone() {
+        SequentialSensorOperation operation = new SequentialSensorOperation();
+        for (ISensorOperation subOperation : mOperations) {
+            operation.add(subOperation.clone());
+        }
+        return operation;
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/TestSensorOperation.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/TestSensorOperation.java
new file mode 100644
index 0000000..1be0ba2
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/TestSensorOperation.java
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2014 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 android.hardware.cts.helpers.sensoroperations;
+
+import android.content.Context;
+import android.hardware.Sensor;
+import android.hardware.cts.helpers.SensorCtsHelper;
+import android.hardware.cts.helpers.SensorStats;
+import android.hardware.cts.helpers.SensorTestInformation;
+import android.hardware.cts.helpers.TestSensorManager;
+import android.hardware.cts.helpers.ValidatingSensorEventListener;
+import android.hardware.cts.helpers.sensorverification.EventGapVerification;
+import android.hardware.cts.helpers.sensorverification.EventOrderingVerification;
+import android.hardware.cts.helpers.sensorverification.FrequencyVerification;
+import android.hardware.cts.helpers.sensorverification.ISensorVerification;
+import android.hardware.cts.helpers.sensorverification.JitterVerification;
+import android.hardware.cts.helpers.sensorverification.MagnitudeVerification;
+import android.hardware.cts.helpers.sensorverification.MeanVerification;
+import android.hardware.cts.helpers.sensorverification.StandardDeviationVerification;
+
+import junit.framework.Assert;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * A {@link ISensorOperation} used to verify that sensor events and sensor values are correct.
+ * <p>
+ * Provides methods to set test expectations as well as providing a set of default expectations
+ * depending on sensor type.  When {{@link #execute()} is called, the sensor will collect the
+ * events and then run all the tests.
+ * </p>
+ */
+public class TestSensorOperation extends AbstractSensorOperation {
+    private final TestSensorManager mSensorManager;
+    private final Context mContext;
+    private final int mSensorType;
+    private final int mRateUs;
+    private final int mMaxBatchReportLatencyUs;
+    private final Integer mEventCount;
+    private final Long mDuration;
+    private final TimeUnit mTimeUnit;
+
+    private final Collection<ISensorVerification> mVerifications =
+            new HashSet<ISensorVerification>();
+
+    private boolean mLogEvents = false;
+
+    /**
+     * Create a {@link TestSensorOperation}.
+     *
+     * @param context the {@link Context}.
+     * @param sensorType the sensor type
+     * @param rateUs the rate that
+     * @param maxBatchReportLatencyUs the max batch report latency
+     * @param eventCount the number of events to gather
+     */
+    public TestSensorOperation(Context context, int sensorType, int rateUs,
+            int maxBatchReportLatencyUs, int eventCount) {
+        this(context, sensorType, rateUs, maxBatchReportLatencyUs, eventCount, null, null);
+    }
+
+    /**
+     * Create a {@link TestSensorOperation}.
+     *
+     * @param context the {@link Context}.
+     * @param sensorType the sensor type
+     * @param rateUs the rate that
+     * @param maxBatchReportLatencyUs the max batch report latency
+     * @param duration the duration to gather events for
+     * @param timeUnit the time unit of the duration
+     */
+    public TestSensorOperation(Context context, int sensorType, int rateUs,
+            int maxBatchReportLatencyUs, long duration, TimeUnit timeUnit) {
+        this(context, sensorType, rateUs, maxBatchReportLatencyUs, null, duration, timeUnit);
+    }
+
+    /**
+     * Private helper constructor.
+     */
+    private TestSensorOperation(Context context, int sensorType, int rateUs,
+            int maxBatchReportLatencyUs, Integer eventCount, Long duration, TimeUnit timeUnit) {
+        mContext = context;
+        mSensorType = sensorType;
+        mRateUs = rateUs;
+        mMaxBatchReportLatencyUs = maxBatchReportLatencyUs;
+        mEventCount = eventCount;
+        mDuration = duration;
+        mTimeUnit = timeUnit;
+        mSensorManager = new TestSensorManager(mContext, mSensorType, mRateUs,
+                mMaxBatchReportLatencyUs);
+    }
+
+    /**
+     * Set whether to log events.
+     */
+    public void setLogEvents(boolean logEvents) {
+        mLogEvents = logEvents;
+    }
+
+    /**
+     * Set all of the default test expectations.
+     */
+    public void setDefaultVerifications() {
+        Sensor sensor = mSensorManager.getSensor();
+        addVerification(EventGapVerification.getDefault(sensor, mRateUs));
+        addVerification(EventOrderingVerification.getDefault(sensor));
+        addVerification(FrequencyVerification.getDefault(sensor, mRateUs));
+        addVerification(JitterVerification.getDefault(sensor, mRateUs));
+        addVerification(MagnitudeVerification.getDefault(sensor));
+        addVerification(MeanVerification.getDefault(sensor));
+        // Skip SigNumVerification since it has no default
+        addVerification(StandardDeviationVerification.getDefault(sensor));
+    }
+
+    public void addVerification(ISensorVerification verification) {
+        if (verification != null) {
+            mVerifications.add(verification);
+        }
+    }
+
+    /**
+     * Collect the specified number of events from the sensor and run all enabled verifications.
+     */
+    @Override
+    public void execute() {
+        getStats().addValue("sensor_name", SensorTestInformation.getSensorName(mSensorType));
+        getStats().addValue("sensor_handle", mSensorManager.getSensor().getHandle());
+
+        ValidatingSensorEventListener listener = new ValidatingSensorEventListener(mVerifications);
+        listener.setLogEvents(mLogEvents);
+
+        if (mEventCount != null) {
+            mSensorManager.runSensor(listener, mEventCount);
+        } else {
+            mSensorManager.runSensor(listener, mDuration, mTimeUnit);
+        }
+
+        boolean failed = false;
+        StringBuilder sb = new StringBuilder();
+
+        for (ISensorVerification verification : mVerifications) {
+            failed |= evaluateResults(verification, sb);
+        }
+
+        if (failed) {
+            String msg = SensorCtsHelper.formatAssertionMessage(mSensorManager.getSensor(),
+                    "VerifySensorOperation", mRateUs, mMaxBatchReportLatencyUs, sb.toString());
+            getStats().addValue(SensorStats.ERROR, msg);
+            Assert.fail(msg);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public TestSensorOperation clone() {
+        TestSensorOperation operation;
+        if (mEventCount != null) {
+            operation = new TestSensorOperation(mContext, mSensorType, mRateUs,
+                    mMaxBatchReportLatencyUs, mEventCount);
+        } else {
+            operation = new TestSensorOperation(mContext, mSensorType, mRateUs,
+                    mMaxBatchReportLatencyUs, mDuration, mTimeUnit);
+        }
+
+        for (ISensorVerification verification : mVerifications) {
+            operation.addVerification(verification.clone());
+        }
+        return operation;
+    }
+
+    /**
+     * Evaluate the results of a test, aggregate the stats, and build the error message.
+     */
+    private boolean evaluateResults(ISensorVerification verification, StringBuilder sb) {
+        try {
+            verification.verify(getStats());
+        } catch (AssertionError e) {
+            if (sb.length() > 0) {
+                sb.append(", ");
+            }
+            sb.append(e.getMessage());
+            return true;
+        }
+        return false;
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/WakeLockOperation.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/WakeLockOperation.java
new file mode 100644
index 0000000..73da9c9
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/WakeLockOperation.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2014 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 android.hardware.cts.helpers.sensoroperations;
+
+import android.content.Context;
+import android.hardware.cts.helpers.SensorStats;
+import android.os.PowerManager;
+import android.os.PowerManager.WakeLock;
+
+/**
+ * An {@link ISensorOperation} which holds a wakelock while performing another
+ * {@link ISensorOperation}.
+ */
+public class WakeLockOperation extends AbstractSensorOperation {
+    private static final String TAG = "WakeLockOperation";
+
+    private final ISensorOperation mOperation;
+    private final Context mContext;
+    private final int mWakelockFlags;
+
+    /**
+     * Constructor for {@link WakeLockOperation}.
+     *
+     * @param operation the child {@link ISensorOperation} to perform after the delay
+     * @param context the context used to access the power manager
+     * @param wakelockFlags the flags used when acquiring the wakelock
+     */
+    public WakeLockOperation(ISensorOperation operation, Context context, int wakelockFlags) {
+        mOperation = operation;
+        mContext = context;
+        mWakelockFlags = wakelockFlags;
+    }
+
+    /**
+     * Constructor for {@link WakeLockOperation}.
+     *
+     * @param operation the child {@link ISensorOperation} to perform after the delay
+     * @param context the context used to access the power manager
+     */
+    public WakeLockOperation(ISensorOperation operation, Context context) {
+        this(operation, context, PowerManager.PARTIAL_WAKE_LOCK);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void execute() {
+        PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
+        WakeLock wakeLock = pm.newWakeLock(mWakelockFlags, TAG);
+
+        wakeLock.acquire();
+        try {
+            mOperation.execute();
+        } finally {
+            wakeLock.release();
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public SensorStats getStats() {
+        return mOperation.getStats();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public ISensorOperation clone() {
+        return new WakeLockOperation(mOperation, mContext, mWakelockFlags);
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/AbstractMeanVerification.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/AbstractMeanVerification.java
new file mode 100644
index 0000000..8d132a3
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/AbstractMeanVerification.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2014 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 android.hardware.cts.helpers.sensorverification;
+
+import android.hardware.cts.helpers.TestSensorEvent;
+
+import junit.framework.Assert;
+
+/**
+ * Abstract class that calculates of the mean event values.
+ */
+public abstract class AbstractMeanVerification extends AbstractSensorVerification {
+    private float[] mSums = null;
+    private int mCount = 0;
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected void addSensorEventInternal(TestSensorEvent event) {
+        if (mSums == null) {
+            mSums = new float[event.values.length];
+        }
+        Assert.assertEquals(mSums.length, event.values.length);
+        for (int i = 0; i < mSums.length; i++) {
+            mSums[i] += event.values[i];
+        }
+        mCount++;
+    }
+
+    /**
+     * Return the number of events.
+     */
+    protected int getCount() {
+        return mCount;
+    }
+
+    /**
+     * Return the means of the event values.
+     */
+    protected float[] getMeans() {
+        if (mCount < 0) {
+            return null;
+        }
+
+        float[] means = new float[mSums.length];
+        for (int i = 0; i < mSums.length; i++) {
+            means[i] = mSums[i] / mCount;
+        }
+        return means;
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/AbstractSensorVerification.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/AbstractSensorVerification.java
new file mode 100644
index 0000000..911ae3a
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/AbstractSensorVerification.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2014 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 android.hardware.cts.helpers.sensorverification;
+
+import android.hardware.cts.helpers.TestSensorEvent;
+
+/**
+ * Abstract class that deals with the synchronization of the sensor verifications.
+ */
+public abstract class AbstractSensorVerification implements ISensorVerification {
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized void addSensorEvents(TestSensorEvent ... events) {
+        for (TestSensorEvent event : events) {
+            addSensorEventInternal(event);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized void addSensorEvent(TestSensorEvent event) {
+        addSensorEventInternal(event);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public abstract ISensorVerification clone();
+
+    /**
+     * Used by implementing classes to add a sensor event.
+     */
+    protected abstract void addSensorEventInternal(TestSensorEvent event);
+
+    /**
+     * Helper class to store the index, previous event, and current event.
+     */
+    protected class IndexedEventPair {
+        public final int index;
+        public final TestSensorEvent event;
+        public final TestSensorEvent previousEvent;
+
+        public IndexedEventPair(int index, TestSensorEvent event,
+                TestSensorEvent previousEvent) {
+            this.index = index;
+            this.event = event;
+            this.previousEvent = previousEvent;
+        }
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventGapVerification.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventGapVerification.java
new file mode 100644
index 0000000..251ef3c
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventGapVerification.java
@@ -0,0 +1,117 @@
+package android.hardware.cts.helpers.sensorverification;
+
+import android.hardware.Sensor;
+import android.hardware.cts.helpers.SensorCtsHelper;
+import android.hardware.cts.helpers.SensorStats;
+import android.hardware.cts.helpers.SensorTestInformation;
+import android.hardware.cts.helpers.SensorTestInformation.SensorReportingMode;
+import android.hardware.cts.helpers.TestSensorEvent;
+
+import junit.framework.Assert;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * A {@link ISensorVerification} which verifies that there are no missing events. This is done by
+ * checking the last received sensor timestamp and checking that it is within 1.8 * the expected
+ * period.
+ */
+public class EventGapVerification extends AbstractSensorVerification {
+    public static final String PASSED_KEY = "missing_event_passed";
+
+    // Fail if no events are delivered within 1.8 times the expected interval
+    private static final double THRESHOLD = 1.8;
+
+    // Number of indices to print in assert message before truncating
+    private static final int TRUNCATE_MESSAGE_LENGTH = 3;
+
+    private final int mExpectedDelayUs;
+
+    private final List<IndexedEventPair> mEventGaps = new LinkedList<IndexedEventPair>();
+    private TestSensorEvent mPreviousEvent = null;
+    private int mIndex = 0;
+
+    /**
+     * Construct a {@link EventGapVerification}
+     *
+     * @param expectedDelayUs the expected period in us.
+     */
+    public EventGapVerification(int expectedDelayUs) {
+        mExpectedDelayUs = expectedDelayUs;
+    }
+
+    /**
+     * Get the default {@link EventGapVerification}.
+     *
+     * @param sensor the {@link Sensor}
+     * @param rateUs the requested rate in us
+     * @return the verification or null if the verification is not a continuous mode sensor.
+     */
+    public static EventGapVerification getDefault(Sensor sensor, int rateUs) {
+        if (!SensorReportingMode.CONTINUOUS.equals(SensorTestInformation.getReportingMode(
+                sensor.getType()))) {
+            return null;
+        }
+        return new EventGapVerification(SensorCtsHelper.getDelay(sensor, rateUs));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void verify(SensorStats stats) {
+        final int count = mEventGaps.size();
+        stats.addValue(PASSED_KEY, count == 0);
+        stats.addValue(SensorStats.EVENT_GAP_COUNT_KEY, count);
+
+        final int[] indices = new int[count];
+        for (int i = 0; i < indices.length; i++) {
+            indices[i] = mEventGaps.get(i).index;
+        }
+        stats.addValue(SensorStats.EVENT_GAP_POSITIONS_KEY, indices);
+
+        if (count > 0) {
+            StringBuilder sb = new StringBuilder();
+            sb.append(count).append(" events gaps: ");
+            for (int i = 0; i < Math.min(count, TRUNCATE_MESSAGE_LENGTH); i++) {
+                IndexedEventPair info = mEventGaps.get(i);
+                sb.append(String.format("position=%d, delta_time=%dns; ", info.index,
+                        info.event.timestamp - info.previousEvent.timestamp));
+            }
+            if (count > TRUNCATE_MESSAGE_LENGTH) {
+                sb.append(count - TRUNCATE_MESSAGE_LENGTH).append(" more; ");
+            }
+            sb.append(String.format("(expected <%dns)",
+                    TimeUnit.NANOSECONDS.convert((int) (THRESHOLD * mExpectedDelayUs),
+                            TimeUnit.MICROSECONDS)));
+            Assert.fail(sb.toString());
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public EventGapVerification clone() {
+        return new EventGapVerification(mExpectedDelayUs);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected void addSensorEventInternal(TestSensorEvent event) {
+        if (mPreviousEvent != null) {
+            long deltaNs = event.timestamp - mPreviousEvent.timestamp;
+            long deltaUs = TimeUnit.MICROSECONDS.convert(deltaNs, TimeUnit.NANOSECONDS);
+            if (deltaUs > mExpectedDelayUs * THRESHOLD) {
+                mEventGaps.add(new IndexedEventPair(mIndex, event, mPreviousEvent));
+            }
+        }
+
+        mPreviousEvent = event;
+        mIndex++;
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventGapVerificationTest.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventGapVerificationTest.java
new file mode 100644
index 0000000..b7861b2
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventGapVerificationTest.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2014 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 android.hardware.cts.helpers.sensorverification;
+
+import android.hardware.cts.helpers.SensorStats;
+import android.hardware.cts.helpers.TestSensorEvent;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests for {@link EventGapVerification}.
+ */
+public class EventGapVerificationTest extends TestCase {
+
+    /**
+     * Test that the verification passes when there are no results.
+     */
+    public void testVerify_no_events() {
+        // Timestamps in ns, expected in us
+        runVerification(1000, new long[]{}, true, new int[]{});
+    }
+
+    /**
+     * Test that the verification passes when there are not missing events.
+     */
+    public void testVerify_correct() {
+        // Timestamps in ns, expected in us
+        long[] timestamps = {1000000, 2000000, 3000000, 4000000, 5000000};
+        runVerification(1000, timestamps, true, new int[]{});
+    }
+
+    /**
+     * Test that the verification passes when there are not missing events but some jitter.
+     */
+    public void testVerify_jitter() {
+        // Timestamps in ns, expected in us
+        long[] timestamps = {1100000, 2050000, 2990000, 4000000, 4950000};
+        runVerification(1000, timestamps, true, new int[]{});
+    }
+
+    /**
+     * Test that the verification fails when there are missing events.
+     */
+    public void testVerify_missing_events() {
+        // Timestamps in ns, expected in us
+        long[] timestamps = {1000000, 2000000, 3000000, 5000000, 6000000};
+        runVerification(1000, timestamps, false, new int[]{3});
+    }
+
+    private void runVerification(int expected, long[] timestamps, boolean pass,
+            int[] indices) {
+        SensorStats stats = new SensorStats();
+        ISensorVerification verification = getVerification(expected, timestamps);
+        if (pass) {
+            verification.verify(stats);
+        } else {
+            boolean failed = false;
+            try {
+                verification.verify(stats);
+            } catch (AssertionError e) {
+                // Expected;
+                failed = true;
+            }
+            assertTrue("Expected an AssertionError", failed);
+        }
+        assertEquals(pass, stats.getValue(EventGapVerification.PASSED_KEY));
+        assertEquals(indices.length, stats.getValue(SensorStats.EVENT_GAP_COUNT_KEY));
+        assertNotNull(stats.getValue(SensorStats.EVENT_GAP_POSITIONS_KEY));
+        int[] actualIndices = (int[]) stats.getValue(SensorStats.EVENT_GAP_POSITIONS_KEY);
+        assertEquals(indices.length, actualIndices.length);
+
+        for (int i = 0; i < indices.length; i++) {
+            assertEquals(indices[i], actualIndices[i]);
+        }
+    }
+
+    private ISensorVerification getVerification(int expected, long ... timestamps) {
+        ISensorVerification verification = new EventGapVerification(expected);
+        for (long timestamp : timestamps) {
+            verification.addSensorEvent(new TestSensorEvent(null, timestamp, 0, null));
+        }
+        return verification;
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventOrderingVerification.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventOrderingVerification.java
new file mode 100644
index 0000000..c74c826
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventOrderingVerification.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2014 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 android.hardware.cts.helpers.sensorverification;
+
+import android.hardware.Sensor;
+import android.hardware.cts.helpers.SensorStats;
+import android.hardware.cts.helpers.SensorTestInformation;
+import android.hardware.cts.helpers.SensorTestInformation.SensorReportingMode;
+import android.hardware.cts.helpers.TestSensorEvent;
+
+import junit.framework.Assert;
+
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * A {@link ISensorVerification} which verifies that all events are received in the correct order.
+ */
+public class EventOrderingVerification extends AbstractSensorVerification {
+    public static final String PASSED_KEY = "event_out_of_order_passed";
+
+    // Number of indices to print in assert message before truncating
+    private static final int TRUNCATE_MESSAGE_LENGTH = 3;
+
+    private Long mMaxTimestamp = null;
+    private final List<IndexedEventPair> mOutOfOrderEvents = new LinkedList<IndexedEventPair>();
+    private TestSensorEvent mPreviousEvent = null;
+    private int mIndex = 0;
+
+    /**
+     * Get the default {@link EventOrderingVerification} for a sensor.
+     *
+     * @param sensor a {@link Sensor}
+     * @return the verification or null if the verification does not apply to the sensor.
+     */
+    @SuppressWarnings("deprecation")
+    public static EventOrderingVerification getDefault(Sensor sensor) {
+        SensorReportingMode mode = SensorTestInformation.getReportingMode(sensor.getType());
+        if (!SensorReportingMode.CONTINUOUS.equals(mode)
+                && !SensorReportingMode.ON_CHANGE.equals(mode)) {
+            return null;
+        }
+        return new EventOrderingVerification();
+    }
+
+    /**
+     * Verify that the events are in the correct order.  Add {@value #PASSED_KEY},
+     * {@value SensorStats#EVENT_OUT_OF_ORDER_COUNT_KEY}, and
+     * {@value SensorStats#EVENT_OUT_OF_ORDER_POSITIONS_KEY} keys to {@link SensorStats}.
+     *
+     * @throws AssertionError if the verification failed.
+     */
+    @Override
+    public void verify(SensorStats stats) {
+        final int count = mOutOfOrderEvents.size();
+        stats.addValue(PASSED_KEY, count == 0);
+        stats.addValue(SensorStats.EVENT_OUT_OF_ORDER_COUNT_KEY, count);
+
+        final int[] indices = new int[count];
+        for (int i = 0; i < indices.length; i++) {
+            indices[i] = mOutOfOrderEvents.get(i).index;
+        }
+        stats.addValue(SensorStats.EVENT_OUT_OF_ORDER_POSITIONS_KEY, indices);
+
+        if (count > 0) {
+            StringBuilder sb = new StringBuilder();
+            sb.append(count).append(" events out of order: ");
+            for (int i = 0; i < Math.min(count, TRUNCATE_MESSAGE_LENGTH); i++) {
+                IndexedEventPair info = mOutOfOrderEvents.get(i);
+                sb.append(String.format("position=%d, previous=%d, timestamp=%d; ", info.index,
+                        info.previousEvent.timestamp, info.event.timestamp));
+            }
+            if (count > TRUNCATE_MESSAGE_LENGTH) {
+                sb.append(count - TRUNCATE_MESSAGE_LENGTH).append(" more");
+            } else {
+                // Delete the trailing "; "
+                sb.delete(sb.length() - 2, sb.length());
+            }
+
+            Assert.fail(sb.toString());
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public EventOrderingVerification clone() {
+        return new EventOrderingVerification();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected void addSensorEventInternal(TestSensorEvent event) {
+        if (mPreviousEvent == null) {
+            mMaxTimestamp = event.timestamp;
+        } else {
+            if (event.timestamp < mMaxTimestamp) {
+                mOutOfOrderEvents.add(new IndexedEventPair(mIndex, event, mPreviousEvent));
+            } else if (event.timestamp > mMaxTimestamp) {
+                mMaxTimestamp = event.timestamp;
+            }
+        }
+
+        mPreviousEvent = event;
+        mIndex++;
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventOrderingVerificationTest.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventOrderingVerificationTest.java
new file mode 100644
index 0000000..28cbd01
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventOrderingVerificationTest.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2014 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 android.hardware.cts.helpers.sensorverification;
+
+import android.hardware.cts.helpers.SensorStats;
+import android.hardware.cts.helpers.TestSensorEvent;
+
+import junit.framework.TestCase;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Tests for {@link EventOrderingVerification}.
+ */
+public class EventOrderingVerificationTest extends TestCase {
+
+    /**
+     * Test that the verification passes when there are no results.
+     */
+    public void testNoEvents() {
+        SensorStats stats = new SensorStats();
+        ISensorVerification verification = getVerification();
+        verification.verify(stats);
+        verifyStats(stats, true, 0);
+    }
+
+    /**
+     * Test that the verification passes when the timestamps are the same.
+     */
+    public void testSameTimestamp() {
+        SensorStats stats = new SensorStats();
+        ISensorVerification verification = getVerification(0, 0, 0, 0, 0);
+        verification.verify(stats);
+        verifyStats(stats, true, 0);
+    }
+
+    /**
+     * Test that the verification passes when the timestamps are increasing.
+     */
+    public void testSequentialTimestamp() {
+        SensorStats stats = new SensorStats();
+        ISensorVerification verification = getVerification(0, 1, 2, 3, 4);
+        verification.verify(stats);
+        verifyStats(stats, true, 0);
+    }
+
+    /**
+     * Test that the verification fails when there is one event out of order.
+     */
+    public void testSingleOutofOrder() {
+        SensorStats stats = new SensorStats();
+        ISensorVerification verification = getVerification(0, 2, 1, 3, 4);
+        try {
+            verification.verify(stats);
+            fail("Expected an AssertionError");
+        } catch (AssertionError e) {
+            // Expected;
+        }
+        verifyStats(stats, false, 1);
+        List<Integer> indices = getIndices(stats);
+        assertTrue(indices.contains(2));
+    }
+
+    /**
+     * Test that the verification fails when there are multiple events out of order.
+     */
+    public void testMultipleOutOfOrder() {
+        SensorStats stats = new SensorStats();
+        ISensorVerification verification = getVerification(4, 0, 1, 2, 3);
+        try {
+            verification.verify(stats);
+            fail("Expected an AssertionError");
+        } catch (AssertionError e) {
+            // Expected;
+        }
+        verifyStats(stats, false, 4);
+        List<Integer> indices = getIndices(stats);
+        assertTrue(indices.contains(1));
+        assertTrue(indices.contains(2));
+        assertTrue(indices.contains(3));
+        assertTrue(indices.contains(4));
+    }
+
+    private ISensorVerification getVerification(long ... timestamps) {
+        ISensorVerification verification = new EventOrderingVerification();
+        for (long timestamp : timestamps) {
+            verification.addSensorEvent(new TestSensorEvent(null, timestamp, 0, null));
+        }
+        return verification;
+    }
+
+    private void verifyStats(SensorStats stats, boolean passed, int count) {
+        assertEquals(passed, stats.getValue(EventOrderingVerification.PASSED_KEY));
+        assertEquals(count, stats.getValue(SensorStats.EVENT_OUT_OF_ORDER_COUNT_KEY));
+        assertNotNull(stats.getValue(SensorStats.EVENT_OUT_OF_ORDER_POSITIONS_KEY));
+    }
+
+    private List<Integer> getIndices(SensorStats stats) {
+        int[] primitiveIndices = (int[]) stats.getValue(
+                SensorStats.EVENT_OUT_OF_ORDER_POSITIONS_KEY);
+        List<Integer> indices = new ArrayList<Integer>(primitiveIndices.length);
+        for (int index : primitiveIndices) {
+            indices.add(index);
+        }
+        return indices;
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/FrequencyVerification.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/FrequencyVerification.java
new file mode 100644
index 0000000..4815688
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/FrequencyVerification.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2014 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 android.hardware.cts.helpers.sensorverification;
+
+import android.hardware.Sensor;
+import android.hardware.cts.helpers.SensorCtsHelper;
+import android.hardware.cts.helpers.SensorStats;
+import android.hardware.cts.helpers.SensorTestInformation;
+import android.hardware.cts.helpers.SensorTestInformation.SensorReportingMode;
+import android.hardware.cts.helpers.TestSensorEvent;
+
+import junit.framework.Assert;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * A {@link ISensorVerification} which verifies that the sensor frequency are within the expected
+ * range.
+ */
+public class FrequencyVerification extends AbstractSensorVerification {
+    public static final String PASSED_KEY = "frequency_passed";
+
+    // lower threshold is (100 - 10)% expected
+    private static final int DEFAULT_LOWER_THRESHOLD = 10;
+    // upper threshold is (100 + 110)% expected
+    private static final int DEFAULT_UPPER_THRESHOLD = 110;
+
+    private final double mExpected;
+    private final double mLowerThreshold;
+    private final double mUpperThreshold;
+
+    private long mMinTimestamp = 0;
+    private long mMaxTimestamp = 0;
+    private int mCount = 0;
+
+    /**
+     * Construct a {@link FrequencyVerification}.
+     *
+     * @param expected the expected frequency in Hz.
+     * @param lowerTheshold the lower threshold in Hz. {@code expected - lower} should be the
+     * slowest acceptable frequency of the sensor.
+     * @param upperThreshold the upper threshold in Hz. {@code expected + upper} should be the
+     * fastest acceptable frequency of the sensor.
+     */
+    public FrequencyVerification(double expected, double lowerTheshold, double upperThreshold) {
+        mExpected = expected;
+        mLowerThreshold = lowerTheshold;
+        mUpperThreshold = upperThreshold;
+    }
+
+    /**
+     * Get the default {@link FrequencyVerification} for a sensor.
+     *
+     * @param sensor a {@link Sensor}
+     * @param rateUs the desired rate of the sensor
+     * @return the verification or null if the verification does not apply to the sensor.
+     */
+    public static FrequencyVerification getDefault(Sensor sensor, int rateUs) {
+        if (!SensorReportingMode.CONTINUOUS.equals(
+                SensorTestInformation.getReportingMode(sensor.getType()))) {
+            return null;
+        }
+
+        // Expected frequency in Hz
+        double expected = SensorCtsHelper.getFrequency(SensorCtsHelper.getDelay(sensor, rateUs),
+                TimeUnit.MICROSECONDS);
+        // Expected frequency * threshold percentage
+        double lowerThreshold = expected * DEFAULT_LOWER_THRESHOLD / 100;
+        double upperThreshold = expected * DEFAULT_UPPER_THRESHOLD / 100;
+        return new FrequencyVerification(expected, lowerThreshold, upperThreshold);
+    }
+
+    /**
+     * Verify that the frequency is correct. Add {@value #PASSED_KEY} and
+     * {@value SensorStats#FREQUENCY_KEY} keys to {@link SensorStats}.
+     *
+     * @throws AssertionError if the verification failed.
+     */
+    @Override
+    public void verify(SensorStats stats) {
+        if (mCount < 2) {
+            stats.addValue(PASSED_KEY, true);
+            return;
+        }
+
+        double frequency = SensorCtsHelper.getFrequency(
+                ((double) (mMaxTimestamp - mMinTimestamp)) / (mCount - 1), TimeUnit.NANOSECONDS);
+        boolean failed = (frequency <= mExpected - mLowerThreshold
+                || frequency >= mExpected + mUpperThreshold);
+
+        stats.addValue(SensorStats.FREQUENCY_KEY, frequency);
+        stats.addValue(PASSED_KEY, !failed);
+
+        if (failed) {
+            Assert.fail(String.format("Frequency out of range: frequency=%.2fHz "
+                    + "(expected (%.2f-%.2fHz, %.2f+%.2fHz))", frequency, mExpected,
+                    mLowerThreshold, mExpected, mUpperThreshold));
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public FrequencyVerification clone() {
+        return new FrequencyVerification(mExpected, mLowerThreshold, mUpperThreshold);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected void addSensorEventInternal(TestSensorEvent event) {
+        if (mCount == 0) {
+            mMinTimestamp = event.timestamp;
+            mMaxTimestamp = event.timestamp;
+        } else {
+            if (mMinTimestamp > event.timestamp) {
+                mMinTimestamp = event.timestamp;
+            }
+            if (mMaxTimestamp < event.timestamp) {
+                mMaxTimestamp = event.timestamp;
+            }
+        }
+        mCount++;
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/FrequencyVerificationTest.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/FrequencyVerificationTest.java
new file mode 100644
index 0000000..cec09a5
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/FrequencyVerificationTest.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2014 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 android.hardware.cts.helpers.sensorverification;
+
+import android.hardware.cts.helpers.SensorStats;
+import android.hardware.cts.helpers.TestSensorEvent;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests for {@link EventOrderingVerification}.
+ */
+public class FrequencyVerificationTest extends TestCase {
+
+    /**
+     * Test that the verifications passes/fails based on threshold given.
+     */
+    public void testVerifification() {
+        long[] timestamps = {0, 1000000, 2000000, 3000000, 4000000};  // 1000Hz
+
+        SensorStats stats = new SensorStats();
+        ISensorVerification verification = getVerification(1000.0, 1.0, 1.0, timestamps);
+        verification.verify(stats);
+        verifyStats(stats, true, 1000.0);
+
+        stats = new SensorStats();
+        verification = getVerification(950.0, 100.0, 100.0, timestamps);
+        verification.verify(stats);
+        verifyStats(stats, true, 1000.0);
+
+        stats = new SensorStats();
+        verification = getVerification(1050.0, 100.0, 100.0, timestamps);
+        verification.verify(stats);
+        verifyStats(stats, true, 1000.0);
+
+        stats = new SensorStats();
+        verification = getVerification(950.0, 100.0, 25.0, timestamps);
+        try {
+            verification.verify(stats);
+            fail("Expected an AssertionError");
+        } catch (AssertionError e) {
+            // Expected;
+        }
+        verifyStats(stats, false, 1000.0);
+
+        stats = new SensorStats();
+        verification = getVerification(1050.0, 25.0, 100.0, timestamps);
+        try {
+            verification.verify(stats);
+            fail("Expected an AssertionError");
+        } catch (AssertionError e) {
+            // Expected;
+        }
+        verifyStats(stats, false, 1000.0);
+    }
+
+    private ISensorVerification getVerification(double expected, double lowerThreshold,
+            double upperThreshold, long ... timestamps) {
+        ISensorVerification verification = new FrequencyVerification(expected, lowerThreshold,
+                upperThreshold);
+        for (long timestamp : timestamps) {
+            verification.addSensorEvent(new TestSensorEvent(null, timestamp, 0, null));
+        }
+        return verification;
+    }
+
+    private void verifyStats(SensorStats stats, boolean passed, double frequency) {
+        assertEquals(passed, stats.getValue(FrequencyVerification.PASSED_KEY));
+        assertEquals(frequency, stats.getValue(SensorStats.FREQUENCY_KEY));
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/ISensorVerification.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/ISensorVerification.java
new file mode 100644
index 0000000..07af392
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/ISensorVerification.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2014 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 android.hardware.cts.helpers.sensorverification;
+
+import android.hardware.cts.helpers.SensorStats;
+import android.hardware.cts.helpers.TestSensorEvent;
+
+/**
+ * Interface describing the sensor verification. This class was designed for to handle streaming
+ * events. The methods {@link #addSensorEvent(TestSensorEvent)} and
+ * {@link #addSensorEvents(TestSensorEvent...)} should be called in the order that the events are
+ * received. The method {@link #verify(SensorStats)} should be called after all events are added.
+ */
+public interface ISensorVerification {
+
+    /**
+     * Add a single {@link TestSensorEvent} to be evaluated.
+     */
+    public void addSensorEvent(TestSensorEvent event);
+
+    /**
+     * Add multiple {@link TestSensorEvent}s to be evaluated.
+     */
+    public void addSensorEvents(TestSensorEvent ... events);
+
+    /**
+     * Evaluate all added {@link TestSensorEvent}s and update stats.
+     *
+     * @param stats a {@link SensorStats} object used to keep track of the stats.
+     * @throws AssertionError if the verification fails.
+     */
+    public void verify(SensorStats stats);
+
+    /**
+     * Clones the {@link ISensorVerification}
+     */
+    public ISensorVerification clone();
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/JitterVerification.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/JitterVerification.java
new file mode 100644
index 0000000..6feceb8
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/JitterVerification.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2014 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 android.hardware.cts.helpers.sensorverification;
+
+import android.hardware.Sensor;
+import android.hardware.cts.helpers.SensorCtsHelper;
+import android.hardware.cts.helpers.SensorStats;
+import android.hardware.cts.helpers.TestSensorEvent;
+
+import junit.framework.Assert;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * A {@link ISensorVerification} which verifies that the sensor jitter is in an acceptable range.
+ */
+public class JitterVerification extends AbstractSensorVerification {
+    public static final String PASSED_KEY = "jitter_passed";
+
+    // sensorType: threshold (% of expected period)
+    private static final Map<Integer, Integer> DEFAULTS = new HashMap<Integer, Integer>(12);
+    static {
+        // Use a method so that the @deprecation warning can be set for that method only
+        setDefaults();
+    }
+
+    private final int mExpected;
+    private final int mThreshold;
+
+    private List<Long> mTimestamps = new LinkedList<Long>();
+
+    /**
+     * Construct a {@link JitterVerification}
+     *
+     * @param expected the expected period in ns
+     * @param threshold the acceptable margin of error as a percentage
+     */
+    public JitterVerification(int expected, int threshold) {
+        mExpected = expected;
+        mThreshold = threshold;
+    }
+
+    /**
+     * Get the default {@link JitterVerification} for a sensor.
+     *
+     * @param sensor a {@link Sensor}
+     * @param rateUs the desired rate of the sensor
+     * @return the verification or null if the verification does not apply to the sensor.
+     */
+    public static JitterVerification getDefault(Sensor sensor, int rateUs) {
+        if (!DEFAULTS.containsKey(sensor.getType())) {
+            return null;
+        }
+
+        int expected = (int) TimeUnit.NANOSECONDS.convert(SensorCtsHelper.getDelay(sensor, rateUs),
+                TimeUnit.MICROSECONDS);
+        return new JitterVerification(expected, DEFAULTS.get(sensor.getType()));
+    }
+
+    /**
+     * Verify that the 95th percentile of the jitter is in the acceptable range. Add
+     * {@value #PASSED_KEY} and {@value SensorStats#JITTER_95_PERCENTILE_KEY} keys to
+     * {@link SensorStats}.
+     *
+     * @throws AssertionError if the verification failed.
+     */
+    @Override
+    public void verify(SensorStats stats) {
+        if (mTimestamps.size() < 2) {
+            stats.addValue(PASSED_KEY, true);
+            return;
+        }
+
+        List<Double> jitters = getJitterValues();
+        double jitter95Percentile = SensorCtsHelper.get95PercentileValue(jitters);
+        boolean failed = (jitter95Percentile > mExpected * (mThreshold / 100.0));
+
+        stats.addValue(PASSED_KEY, !failed);
+        stats.addValue(SensorStats.JITTER_95_PERCENTILE_KEY, jitter95Percentile);
+
+        if (failed) {
+            Assert.fail(String.format("Jitter out of range: jitter at 95th percentile=%.0fns "
+                    + "(expected <%.0fns)", jitter95Percentile, mExpected * (mThreshold / 100.0)));
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public JitterVerification clone() {
+        return new JitterVerification(mExpected, mThreshold);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected void addSensorEventInternal(TestSensorEvent event) {
+        mTimestamps.add(event.timestamp);
+    }
+
+    /**
+     * Get the list of all jitter values. Exposed for unit testing.
+     */
+    List<Double> getJitterValues() {
+        List<Long> deltas = new ArrayList<Long>(mTimestamps.size() - 1);
+        for (int i = 1; i < mTimestamps.size(); i++) {
+            deltas.add(mTimestamps.get(i) - mTimestamps.get(i -1));
+        }
+        double deltaMean = SensorCtsHelper.getMean(deltas);
+        List<Double> jitters = new ArrayList<Double>(deltas.size());
+        for (long delta : deltas) {
+            jitters.add(Math.abs(delta - deltaMean));
+        }
+        return jitters;
+    }
+
+    @SuppressWarnings("deprecation")
+    private static void setDefaults() {
+        // Sensors that we don't want to test at this time but still want to record the values.
+        DEFAULTS.put(Sensor.TYPE_ACCELEROMETER, Integer.MAX_VALUE);
+        DEFAULTS.put(Sensor.TYPE_MAGNETIC_FIELD, Integer.MAX_VALUE);
+        DEFAULTS.put(Sensor.TYPE_GYROSCOPE, Integer.MAX_VALUE);
+        DEFAULTS.put(Sensor.TYPE_ORIENTATION, Integer.MAX_VALUE);
+        DEFAULTS.put(Sensor.TYPE_PRESSURE, Integer.MAX_VALUE);
+        DEFAULTS.put(Sensor.TYPE_GRAVITY, Integer.MAX_VALUE);
+        DEFAULTS.put(Sensor.TYPE_LINEAR_ACCELERATION, Integer.MAX_VALUE);
+        DEFAULTS.put(Sensor.TYPE_ROTATION_VECTOR, Integer.MAX_VALUE);
+        DEFAULTS.put(Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED, Integer.MAX_VALUE);
+        DEFAULTS.put(Sensor.TYPE_GAME_ROTATION_VECTOR, Integer.MAX_VALUE);
+        DEFAULTS.put(Sensor.TYPE_GYROSCOPE_UNCALIBRATED, Integer.MAX_VALUE);
+        DEFAULTS.put(Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR, Integer.MAX_VALUE);
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/JitterVerificationTest.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/JitterVerificationTest.java
new file mode 100644
index 0000000..a9e872a
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/JitterVerificationTest.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2014 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 android.hardware.cts.helpers.sensorverification;
+
+import android.hardware.cts.helpers.SensorStats;
+import android.hardware.cts.helpers.TestSensorEvent;
+
+import junit.framework.TestCase;
+
+import java.util.List;
+
+/**
+ * Tests for {@link EventOrderingVerification}.
+ */
+public class JitterVerificationTest extends TestCase {
+
+
+    public void testVerify() {
+        final int SAMPLE_SIZE = 100;
+
+        // 100 samples at 1000Hz
+        long[] timestamps = new long[SAMPLE_SIZE];
+        for (int i = 0; i < SAMPLE_SIZE; i++) {
+            timestamps[i] = i * 100000;
+        }
+        SensorStats stats = new SensorStats();
+        ISensorVerification verification = getVerification(1000, 1, timestamps);
+        verification.verify(stats);
+        verifyStats(stats, true, 0.0);
+
+        // 90 samples at 1000Hz, 10 samples at 2000Hz
+        long timestamp = 0;
+        for (int i = 0; i < SAMPLE_SIZE; i++) {
+            timestamps[i] = timestamp;
+            timestamp += (i % 10 == 0) ? 500000 : 1000000;
+        }
+        stats = new SensorStats();
+        verification = getVerification(1000, 1, timestamps);
+        try {
+            verification.verify(stats);
+            fail("Expected an AssertionError");
+        } catch (AssertionError e) {
+            // Expected;
+        }
+        verifyStats(stats, false, 449494.9494);
+    }
+
+    public void testCalculateJitter() {
+        long[] timestamps = new long[]{0, 1, 2, 3, 4};
+        JitterVerification verification = getVerification(1000, 1, timestamps);
+        List<Double> jitterValues = verification.getJitterValues();
+        assertEquals(4, jitterValues.size());
+        assertEquals(0.0, (double) jitterValues.get(0));
+        assertEquals(0.0, (double) jitterValues.get(1));
+        assertEquals(0.0, (double) jitterValues.get(2));
+        assertEquals(0.0, (double) jitterValues.get(3));
+
+        timestamps = new long[]{0, 0, 2, 4, 4};
+        verification = getVerification(1000, 1, timestamps);
+        jitterValues = verification.getJitterValues();
+        assertEquals(4, jitterValues.size());
+        assertEquals(1.0, (double) jitterValues.get(0));
+        assertEquals(1.0, (double) jitterValues.get(1));
+        assertEquals(1.0, (double) jitterValues.get(2));
+        assertEquals(1.0, (double) jitterValues.get(3));
+
+        timestamps = new long[]{0, 1, 4, 9, 16};
+        verification = getVerification(1000, 1, timestamps);
+        jitterValues = verification.getJitterValues();
+        assertEquals(4, jitterValues.size());
+        assertEquals(4, jitterValues.size());
+        assertEquals(3.0, (double) jitterValues.get(0));
+        assertEquals(1.0, (double) jitterValues.get(1));
+        assertEquals(1.0, (double) jitterValues.get(2));
+        assertEquals(3.0, (double) jitterValues.get(3));
+    }
+
+    private JitterVerification getVerification(int expected, int threshold, long ... timestamps) {
+        JitterVerification verification = new JitterVerification(expected, threshold);
+        for (long timestamp : timestamps) {
+            verification.addSensorEvent(new TestSensorEvent(null, timestamp, 0, null));
+        }
+        return verification;
+    }
+
+    private void verifyStats(SensorStats stats, boolean passed, double jitter95) {
+        assertEquals(passed, stats.getValue(JitterVerification.PASSED_KEY));
+        assertEquals(jitter95, (Double) stats.getValue(SensorStats.JITTER_95_PERCENTILE_KEY), 0.1);
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/MagnitudeVerification.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/MagnitudeVerification.java
new file mode 100644
index 0000000..5e44273
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/MagnitudeVerification.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2014 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 android.hardware.cts.helpers.sensorverification;
+
+import android.hardware.Sensor;
+import android.hardware.SensorManager;
+import android.hardware.cts.helpers.SensorStats;
+import android.hardware.cts.helpers.TestSensorEvent;
+
+import junit.framework.Assert;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * A {@link ISensorVerification} which verifies that the mean of the magnitude of the sensors vector
+ * is within the expected range.
+ */
+public class MagnitudeVerification extends AbstractSensorVerification {
+    public static final String PASSED_KEY = "magnitude_passed";
+
+    // sensorType: {expected, threshold}
+    private static Map<Integer, Float[]> DEFAULTS = new HashMap<Integer, Float[]>(3);
+    static {
+        // Use a method so that the @deprecation warning can be set for that method only
+        setDefaults();
+    }
+
+    private final float mExpected;
+    private final float mThreshold;
+
+    private float mSum = 0.0f;
+    private int mCount = 0;
+
+    /**
+     * Construct a {@link MagnitudeVerification}
+     *
+     * @param expected the expected value
+     * @param threshold the threshold
+     */
+    public MagnitudeVerification(float expected, float threshold) {
+        mExpected = expected;
+        mThreshold = threshold;
+    }
+
+    /**
+     * Get the default {@link MagnitudeVerification} for a sensor.
+     *
+     * @param sensor a {@link Sensor}
+     * @return the verification or null if the verification does not apply to the sensor.
+     */
+    public static MagnitudeVerification getDefault(Sensor sensor) {
+        if (!DEFAULTS.containsKey(sensor.getType())) {
+            return null;
+        }
+        Float expected = DEFAULTS.get(sensor.getType())[0];
+        Float threshold = DEFAULTS.get(sensor.getType())[1];
+        return new MagnitudeVerification(expected, threshold);
+    }
+
+    /**
+     * Verify that the magnitude is in the acceptable range. Add {@value #PASSED_KEY} and
+     * {@value SensorStats#MAGNITUDE_KEY} keys to {@link SensorStats}.
+     *
+     * @throws AssertionError if the verification failed.
+     */
+    @Override
+    public void verify(SensorStats stats) {
+        if (mCount < 1) {
+            stats.addValue(PASSED_KEY, true);
+            return;
+        }
+
+        float mean = mSum / mCount;
+        boolean failed = Math.abs(mean - mExpected) > mThreshold;
+
+        stats.addValue(PASSED_KEY, !failed);
+        stats.addValue(SensorStats.MAGNITUDE_KEY, mean);
+
+        if (failed) {
+            Assert.fail(String.format("Magnitude mean out of range: mean=%s (expected %s+/-%s)",
+                    mean, mExpected, mThreshold));
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public MagnitudeVerification clone() {
+        return new MagnitudeVerification(mExpected, mThreshold);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected void addSensorEventInternal(TestSensorEvent event) {
+        float sumOfSquares = 0.0f;
+        for (float value : event.values) {
+            sumOfSquares += value * value;
+        }
+        mSum += (float) Math.sqrt(sumOfSquares);
+        mCount++;
+    }
+
+    @SuppressWarnings("deprecation")
+    private static void setDefaults() {
+        DEFAULTS.put(Sensor.TYPE_ACCELEROMETER, new Float[]{SensorManager.STANDARD_GRAVITY, 1.5f});
+        DEFAULTS.put(Sensor.TYPE_GYROSCOPE, new Float[]{0.0f, 1.5f});
+        // Sensors that we don't want to test at this time but still want to record the values.
+        DEFAULTS.put(Sensor.TYPE_GRAVITY,
+                new Float[]{SensorManager.STANDARD_GRAVITY, Float.MAX_VALUE});
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/MagnitudeVerificationTest.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/MagnitudeVerificationTest.java
new file mode 100644
index 0000000..9a50753
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/MagnitudeVerificationTest.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2014 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 android.hardware.cts.helpers.sensorverification;
+
+import android.hardware.cts.helpers.SensorStats;
+import android.hardware.cts.helpers.TestSensorEvent;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests for {@link MagnitudeVerification}.
+ */
+public class MagnitudeVerificationTest extends TestCase {
+
+    /**
+     * Test {@link MagnitudeVerification#verify(SensorStats)}.
+     */
+    public void testVerify() {
+        float[][] values = {
+                {0, 3, 4},
+                {4, 0, 3},
+                {3, 4, 0},
+                {0, 0, 4},
+                {6, 0, 0},
+        };
+
+        runStats(5.0f, 0.1f, values, true, 5.0f);
+        runStats(4.5f, 0.6f, values, true, 5.0f);
+        runStats(5.5f, 0.6f, values, true, 5.0f);
+        runStats(4.5f, 0.1f, values, false, 5.0f);
+        runStats(5.5f, 0.1f, values, false, 5.0f);
+    }
+
+    private void runStats(float expected, float threshold, float[][] values, boolean pass, float magnitude) {
+        SensorStats stats = new SensorStats();
+        ISensorVerification verification = getVerification(expected, threshold, values);
+        if (pass) {
+            verification.verify(stats);
+        } else {
+            try {
+                verification.verify(stats);
+                fail("Expected an AssertionError");
+            } catch (AssertionError e) {
+                // Expected;
+            }
+        }
+        assertEquals(pass, stats.getValue(MagnitudeVerification.PASSED_KEY));
+        assertEquals(magnitude, (Float) stats.getValue(SensorStats.MAGNITUDE_KEY), 0.01);
+    }
+
+    private ISensorVerification getVerification(float expected, float threshold,
+            float[] ... values) {
+        ISensorVerification verification = new MagnitudeVerification(expected, threshold);
+        for (float[] value : values) {
+            verification.addSensorEvent(new TestSensorEvent(null, 0, 0, value));
+        }
+        return verification;
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/MeanVerification.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/MeanVerification.java
new file mode 100644
index 0000000..d6769d0
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/MeanVerification.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2014 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 android.hardware.cts.helpers.sensorverification;
+
+import android.hardware.Sensor;
+import android.hardware.SensorManager;
+import android.hardware.cts.helpers.SensorStats;
+
+import junit.framework.Assert;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * A {@link ISensorVerification} which verifies that the means matches the expected measurement.
+ */
+public class MeanVerification extends AbstractMeanVerification {
+    public static final String PASSED_KEY = "mean_passed";
+
+    // sensorType: {expected, threshold}
+    private static final Map<Integer, Object[]> DEFAULTS = new HashMap<Integer, Object[]>(5);
+    static {
+        // Use a method so that the @deprecation warning can be set for that method only
+        setDefaults();
+    }
+
+    private final float[] mExpected;
+    private final float[] mThreshold;
+
+    /**
+     * Construct a {@link MeanVerification}
+     *
+     * @param expected the expected values
+     * @param threshold the thresholds
+     */
+    public MeanVerification(float[] expected, float[] threshold) {
+        mExpected = expected;
+        mThreshold = threshold;
+    }
+
+    /**
+     * Get the default {@link MeanVerification} for a sensor.
+     *
+     * @param sensor a {@link Sensor}
+     * @return the verification or null if the verification does not apply to the sensor.
+     */
+    public static MeanVerification getDefault(Sensor sensor) {
+        if (!DEFAULTS.containsKey(sensor.getType())) {
+            return null;
+        }
+        float[] expected = (float[]) DEFAULTS.get(sensor.getType())[0];
+        float[] threshold = (float[]) DEFAULTS.get(sensor.getType())[1];
+        return new MeanVerification(expected, threshold);
+    }
+
+    /**
+     * Verify that the mean is in the acceptable range. Add {@value #PASSED_KEY} and
+     * {@value SensorStats#MEAN_KEY} keys to {@link SensorStats}.
+     *
+     * @throws AssertionError if the verification failed.
+     */
+    @Override
+    public void verify(SensorStats stats) {
+        if (getCount() < 1) {
+            stats.addValue(PASSED_KEY, true);
+            return;
+        }
+
+        float[] means = getMeans();
+
+        boolean failed = false;
+        StringBuilder meanSb = new StringBuilder();
+        StringBuilder expectedSb = new StringBuilder();
+
+        if (means.length > 1) {
+            meanSb.append("(");
+            expectedSb.append("(");
+        }
+        for (int i = 0; i < means.length; i++) {
+            if (Math.abs(means[i] - mExpected[i]) > mThreshold[i]) {
+                failed = true;
+            }
+            meanSb.append(String.format("%.2f", means[i]));
+            if (i != means.length - 1) meanSb.append(", ");
+            expectedSb.append(String.format("%.2f+/-%.2f", mExpected[i], mThreshold[i]));
+            if (i != means.length - 1) expectedSb.append(", ");
+        }
+        if (means.length > 1) {
+            meanSb.append(")");
+            expectedSb.append(")");
+        }
+
+        stats.addValue(PASSED_KEY, !failed);
+        stats.addValue(SensorStats.MEAN_KEY, means);
+
+        if (failed) {
+            Assert.fail(String.format("Mean out of range: mean=%s (expected %s)", meanSb.toString(),
+                    expectedSb.toString()));
+        }
+    }
+
+    @Override
+    public MeanVerification clone() {
+        return new MeanVerification(mExpected, mThreshold);
+    }
+
+    @SuppressWarnings("deprecation")
+    private static void setDefaults() {
+        // Sensors that we don't want to test at this time but still want to record the values.
+        // Gyroscope should be 0 for a static device
+        DEFAULTS.put(Sensor.TYPE_GYROSCOPE, new Object[]{
+                new float[]{0.0f, 0.0f, 0.0f},
+                new float[]{Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE}});
+        // Pressure will not be exact in a controlled environment but should be relatively close to
+        // sea level. Second values should always be 0.
+        DEFAULTS.put(Sensor.TYPE_PRESSURE, new Object[]{
+                new float[]{SensorManager.PRESSURE_STANDARD_ATMOSPHERE, 0.0f, 0.0f},
+                new float[]{Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE}});
+        // Linear acceleration should be 0 in all directions for a static device
+        DEFAULTS.put(Sensor.TYPE_LINEAR_ACCELERATION, new Object[]{
+                new float[]{0.0f, 0.0f, 0.0f},
+                new float[]{Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE}});
+        // Game rotation vector should be (0, 0, 0, 1, 0) for a static device
+        DEFAULTS.put(Sensor.TYPE_GAME_ROTATION_VECTOR, new Object[]{
+                new float[]{0.0f, 0.0f, 0.0f, 1.0f, 0.0f},
+                new float[]{Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE,
+                        Float.MAX_VALUE}});
+        // Uncalibrated gyroscope should be 0 for a static device but allow a bigger threshold
+        DEFAULTS.put(Sensor.TYPE_GYROSCOPE_UNCALIBRATED, new Object[]{
+                new float[]{0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f},
+                new float[]{Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE,
+                        Float.MAX_VALUE, Float.MAX_VALUE}});
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/MeanVerificationTest.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/MeanVerificationTest.java
new file mode 100644
index 0000000..94b6362
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/MeanVerificationTest.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2014 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 android.hardware.cts.helpers.sensorverification;
+
+import android.hardware.cts.helpers.SensorStats;
+import android.hardware.cts.helpers.TestSensorEvent;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests for {@link MeanVerification}.
+ */
+public class MeanVerificationTest extends TestCase {
+
+    /**
+     * Test {@link MeanVerification#verify(SensorStats)}.
+     */
+    public void testVerify() {
+        float[][] values = {
+                {0, 1, 0},
+                {1, 2, 1},
+                {2, 3, 4},
+                {3, 4, 9},
+                {4, 5, 16},
+        };
+
+        float[] expected = {2.0f, 3.0f, 6.0f};
+        float[] threshold = {0.1f, 0.1f, 0.1f};
+        SensorStats stats = new SensorStats();
+        ISensorVerification verification = getVerification(expected, threshold, values);
+        verification.verify(stats);
+        verifyStats(stats, true, new float[]{2.0f, 3.0f, 6.0f});
+
+        expected = new float[]{2.5f, 2.5f, 5.5f};
+        threshold = new float[]{0.6f, 0.6f, 0.6f};
+        stats = new SensorStats();
+        verification = getVerification(expected, threshold, values);
+        verification.verify(stats);
+        verifyStats(stats, true, new float[]{2.0f, 3.0f, 6.0f});
+
+        expected = new float[]{2.5f, 2.5f, 5.5f};
+        threshold = new float[]{0.1f, 0.6f, 0.6f};
+        stats = new SensorStats();
+        verification = getVerification(expected, threshold, values);
+        try {
+            verification.verify(stats);
+            fail("Expected an AssertionError");
+        } catch (AssertionError e) {
+            // Expected;
+        }
+        verifyStats(stats, false, new float[]{2.0f, 3.0f, 6.0f});
+
+        expected = new float[]{2.5f, 2.5f, 5.5f};
+        threshold = new float[]{0.6f, 0.1f, 0.6f};
+        stats = new SensorStats();
+        verification = getVerification(expected, threshold, values);
+        try {
+            verification.verify(stats);
+            fail("Expected an AssertionError");
+        } catch (AssertionError e) {
+            // Expected;
+        }
+        verifyStats(stats, false, new float[]{2.0f, 3.0f, 6.0f});
+
+        threshold = new float[]{2.5f, 2.5f, 5.5f};
+        threshold = new float[]{0.6f, 0.6f, 0.1f};
+        stats = new SensorStats();
+        verification = getVerification(expected, threshold, values);
+        try {
+            verification.verify(stats);
+            fail("Expected an AssertionError");
+        } catch (AssertionError e) {
+            // Expected;
+        }
+        verifyStats(stats, false, new float[]{2.0f, 3.0f, 6.0f});
+    }
+
+    private ISensorVerification getVerification(float[] expected, float[] threshold,
+            float[] ... values) {
+        ISensorVerification verification = new MeanVerification(expected, threshold);
+        for (float[] value : values) {
+            verification.addSensorEvent(new TestSensorEvent(null, 0, 0, value));
+        }
+        return verification;
+    }
+
+    private void verifyStats(SensorStats stats, boolean passed, float[] means) {
+        assertEquals(passed, stats.getValue(MeanVerification.PASSED_KEY));
+        float[] actual = (float[]) stats.getValue(SensorStats.MEAN_KEY);
+        for (int i = 0; i < means.length; i++) {
+            assertEquals(means[i], actual[i], 0.1);
+        }
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/SigNumVerification.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/SigNumVerification.java
new file mode 100644
index 0000000..9428d1d
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/SigNumVerification.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2014 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 android.hardware.cts.helpers.sensorverification;
+
+import android.hardware.cts.helpers.SensorStats;
+
+import junit.framework.Assert;
+
+/**
+ * A {@link ISensorVerification} which verifies that the sign of each of the sensor values is
+ * correct.
+ * <p>
+ * If the value of the measurement is in [-threshold, threshold], the sign is considered 0. If
+ * it is less than -threshold, it is considered -1. If it is greater than threshold, it is
+ * considered 1.
+ * </p>
+ */
+public class SigNumVerification extends AbstractMeanVerification {
+    public static final String PASSED_KEY = "sig_num_passed";
+
+    private final int[] mExpected;
+    private final float[] mThreshold;
+
+    /**
+     * Construct a {@link SigNumVerification}
+     *
+     * @param expected the expected values
+     * @param threshold the threshold that needs to be crossed to consider a measurement nonzero
+     * @throws IllegalStateException if the expected values are not 0, -1, or 1.
+     */
+    public SigNumVerification(int[] expected, float[] threshold) {
+        for (int i = 0; i < expected.length; i++) {
+            if (!(expected[i] == -1 || expected[i] == 0 || expected[i] == 1)) {
+                throw new IllegalArgumentException("Expected value must be -1, 0, or 1");
+            }
+        }
+
+        mExpected = expected;
+        mThreshold = threshold;
+    }
+
+    /**
+     * Verify that the sign of each of the sensor values is correct. Add {@value #PASSED_KEY} and
+     * {@value SensorStats#MEAN_KEY} keys to {@link SensorStats}.
+     *
+     * @throws AssertionError if the verification failed.
+     */
+    @Override
+    public void verify(SensorStats stats) {
+        if (getCount() < 1) {
+            stats.addValue(PASSED_KEY, true);
+            return;
+        }
+
+        float[] means = getMeans();
+
+        boolean failed = false;
+        StringBuilder meanSb = new StringBuilder();
+        StringBuilder expectedSb = new StringBuilder();
+
+        if (means.length > 1) {
+            meanSb.append("(");
+            expectedSb.append("(");
+        }
+        for (int i = 0; i < means.length; i++) {
+            meanSb.append(String.format("%.2f", means[i]));
+            if (i != means.length - 1) meanSb.append(", ");
+
+            if (mExpected[i] == 0) {
+                if (Math.abs(means[i]) > mThreshold[i]) {
+                    failed = true;
+                }
+                expectedSb.append(String.format("[%.2f, %.2f]", -mThreshold[i], mThreshold[i]));
+            } else {
+                if (mExpected[i] > 0) {
+                    if (means[i] <= mThreshold[i]) {
+                        failed = true;
+                    }
+                    expectedSb.append(String.format("(%.2f, inf)", mThreshold[i]));
+                } else {
+                    if (means[i] >= -1 * mThreshold[i]) {
+                        failed = true;
+                    }
+                    expectedSb.append(String.format("(-inf, %.2f)", -1 * mThreshold[i]));
+                }
+            }
+            if (i != means.length - 1) expectedSb.append(", ");
+        }
+        if (means.length > 1) {
+            meanSb.append(")");
+            expectedSb.append(")");
+        }
+
+        stats.addValue(PASSED_KEY, !failed);
+        stats.addValue(SensorStats.MEAN_KEY, means);
+
+        if (failed) {
+            Assert.fail(String.format("Signum out of range: mean=%s (expected %s)",
+                    meanSb.toString(), expectedSb.toString()));
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public SigNumVerification clone() {
+        return new SigNumVerification(mExpected, mThreshold);
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/SigNumVerificationTest.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/SigNumVerificationTest.java
new file mode 100644
index 0000000..009ab65
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/SigNumVerificationTest.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2014 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 android.hardware.cts.helpers.sensorverification;
+
+import android.hardware.cts.helpers.SensorStats;
+import android.hardware.cts.helpers.TestSensorEvent;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests for {@link SigNumVerification}.
+ */
+public class SigNumVerificationTest extends TestCase {
+
+    /**
+     * Test {@link SigNumVerification#verify(SensorStats)}.
+     */
+    public void testVerify() {
+        float[][] values = {{1.0f, 0.2f, 0.0f, -0.2f, -1.0f}};
+
+        int[] expected = {1, 1, 0, -1, -1};
+        float[] threshold = {0.1f, 0.1f, 0.1f, 0.1f, 0.1f};
+        runVerification(true, expected, threshold, values);
+
+        expected = new int[]{1, 0, 0, 0, -1};
+        threshold = new float[]{0.5f, 0.5f, 0.5f, 0.5f, 0.5f};
+        runVerification(true, expected, threshold, values);
+
+        expected = new int[]{0, 1, 0, -1, 0};
+        threshold = new float[]{1.5f, 0.1f, 0.1f, 0.1f, 1.5f};
+        runVerification(true, expected, threshold, values);
+
+        expected = new int[]{1, 0, 0, 0, 1};
+        threshold = new float[]{0.5f, 0.5f, 0.5f, 0.5f, 0.5f};
+        runVerification(false, expected, threshold, values);
+
+        expected = new int[]{-1, 0, 0, 0, -1};
+        threshold = new float[]{0.5f, 0.5f, 0.5f, 0.5f, 0.5f};
+        runVerification(false, expected, threshold, values);
+    }
+
+    private SigNumVerification getVerification(int[] expected, float[] threshold,
+            float[] ... values) {
+        SigNumVerification verification = new SigNumVerification(expected, threshold);
+        for (float[] value : values) {
+            verification.addSensorEvent(new TestSensorEvent(null, 0, 0, value));
+        }
+        return verification;
+    }
+
+    private void runVerification(boolean passed, int[] expected, float[] threshold,
+            float[][] values) {
+        SensorStats stats = new SensorStats();
+        ISensorVerification verification = getVerification(expected, threshold, values);
+        if (passed) {
+            verification.verify(stats);
+        } else {
+            try {
+                verification.verify(stats);
+                fail("Expected an AssertionError");
+            } catch (AssertionError e) {
+                // Expected;
+            }
+        }
+        assertEquals(passed, stats.getValue(SigNumVerification.PASSED_KEY));
+        assertNotNull(stats.getValue(SensorStats.MEAN_KEY));
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/StandardDeviationVerification.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/StandardDeviationVerification.java
new file mode 100644
index 0000000..57b34b0
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/StandardDeviationVerification.java
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2014 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 android.hardware.cts.helpers.sensorverification;
+
+import android.hardware.Sensor;
+import android.hardware.cts.helpers.SensorStats;
+import android.hardware.cts.helpers.TestSensorEvent;
+
+import junit.framework.Assert;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * A {@link ISensorVerification} which verifies that the standard deviations is within the expected
+ * range.
+ */
+public class StandardDeviationVerification extends AbstractSensorVerification {
+    public static final String PASSED_KEY = "standard_deviation_passed";
+
+    // sensorType: threshold
+    private static final Map<Integer, float[]> DEFAULTS = new HashMap<Integer, float[]>(12);
+    static {
+        // Use a method so that the @deprecation warning can be set for that method only
+        setDefaults();
+    }
+
+    private final float[] mThreshold;
+
+    private float[] mMeans = null;
+    private float[] mM2s = null;
+    private int mCount = 0;
+
+    /**
+     * Construct a {@link StandardDeviationVerification}
+     *
+     * @param threshold the thresholds
+     */
+    public StandardDeviationVerification(float[] threshold) {
+        mThreshold = threshold;
+    }
+
+    /**
+     * Get the default {@link StandardDeviationVerification} for a sensor.
+     *
+     * @param sensor a {@link Sensor}
+     * @return the verification or null if the verification does not apply to the sensor.
+     */
+    public static StandardDeviationVerification getDefault(Sensor sensor) {
+        if (!DEFAULTS.containsKey(sensor.getType())) {
+            return null;
+        }
+
+        return new StandardDeviationVerification(DEFAULTS.get(sensor.getType()));
+    }
+
+    /**
+     * Verify that the standard deviation is in the acceptable range. Add {@value #PASSED_KEY} and
+     * {@value SensorStats#STANDARD_DEVIATION_KEY} keys to {@link SensorStats}.
+     *
+     * @throws AssertionError if the verification failed.
+     */
+    @Override
+    public void verify(SensorStats stats) {
+        if (mCount < 2) {
+            stats.addValue(PASSED_KEY, true);
+            return;
+        }
+
+        float[] stdDevs = new float[mM2s.length];
+        for (int i = 0; i < mM2s.length; i++) {
+            stdDevs[i] = (float) Math.sqrt(mM2s[i] / (mCount - 1));
+        }
+
+        boolean failed = false;
+        StringBuilder stddevSb = new StringBuilder();
+        StringBuilder expectedSb = new StringBuilder();
+
+        if (stdDevs.length > 1) {
+            stddevSb.append("(");
+            expectedSb.append("(");
+        }
+        for (int i = 0; i < stdDevs.length; i++) {
+            if (stdDevs[i] > mThreshold[i]) {
+                failed = true;
+            }
+            stddevSb.append(String.format("%.2f", stdDevs[i]));
+            if (i != stdDevs.length - 1) stddevSb.append(", ");
+            expectedSb.append(String.format("<%.2f", mThreshold[i]));
+            if (i != stdDevs.length - 1) expectedSb.append(", ");
+        }
+        if (stdDevs.length > 1) {
+            stddevSb.append(")");
+            expectedSb.append(")");
+        }
+
+        stats.addValue(PASSED_KEY, !failed);
+        stats.addValue(SensorStats.STANDARD_DEVIATION_KEY, stdDevs);
+
+        if (failed) {
+            Assert.fail(String.format("Standard deviation out of range: stddev=%s (expected %s)",
+                    stddevSb.toString(), expectedSb.toString()));
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public StandardDeviationVerification clone() {
+        return new StandardDeviationVerification(mThreshold);
+    }
+
+    /**
+     * {@inheritDoc}
+     * <p>
+     * Computes the standard deviation using
+     * <a href="http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#On-line_algorithm">
+     * Welford's algorith</a>.
+     * </p>
+     */
+    @Override
+    protected void addSensorEventInternal(TestSensorEvent event) {
+        if (mMeans == null || mM2s == null) {
+            mMeans = new float[event.values.length];
+            mM2s = new float[event.values.length];
+        }
+
+        Assert.assertEquals(mMeans.length, event.values.length);
+        Assert.assertEquals(mM2s.length, event.values.length);
+
+        mCount++;
+
+        for (int i = 0; i < event.values.length; i++) {
+            float delta = event.values[i] - mMeans[i];
+            mMeans[i] += delta / mCount;
+            mM2s[i] += delta * (event.values[i] - mMeans[i]);
+        }
+    }
+
+    @SuppressWarnings("deprecation")
+    private static void setDefaults() {
+        DEFAULTS.put(Sensor.TYPE_ACCELEROMETER, new float[]{1.0f, 1.0f, 1.0f});
+        DEFAULTS.put(Sensor.TYPE_GYROSCOPE, new float[]{0.5f, 0.5f, 0.5f});
+        // Sensors that we don't want to test at this time but still want to record the values.
+        DEFAULTS.put(Sensor.TYPE_MAGNETIC_FIELD,
+                new float[]{Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE});
+        DEFAULTS.put(Sensor.TYPE_ORIENTATION,
+                new float[]{Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE});
+        DEFAULTS.put(Sensor.TYPE_PRESSURE,
+                new float[]{Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE});
+        DEFAULTS.put(Sensor.TYPE_GRAVITY,
+                new float[]{Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE});
+        DEFAULTS.put(Sensor.TYPE_LINEAR_ACCELERATION,
+                new float[]{Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE});
+        DEFAULTS.put(Sensor.TYPE_ROTATION_VECTOR,
+                new float[]{Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE,
+                Float.MAX_VALUE});
+        DEFAULTS.put(Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED,
+                new float[]{Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE,
+                Float.MAX_VALUE, Float.MAX_VALUE});
+        DEFAULTS.put(Sensor.TYPE_GAME_ROTATION_VECTOR,
+                new float[]{Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE,
+                Float.MAX_VALUE});
+        DEFAULTS.put(Sensor.TYPE_GYROSCOPE_UNCALIBRATED,
+                new float[]{Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE,
+                Float.MAX_VALUE, Float.MAX_VALUE});
+        DEFAULTS.put(Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR,
+                new float[]{Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE,
+                Float.MAX_VALUE});
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/StandardDeviationVerificationTest.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/StandardDeviationVerificationTest.java
new file mode 100644
index 0000000..308f114
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/StandardDeviationVerificationTest.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2014 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 android.hardware.cts.helpers.sensorverification;
+
+import android.hardware.cts.helpers.SensorStats;
+import android.hardware.cts.helpers.TestSensorEvent;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests for {@link StandardDeviationVerification}.
+ */
+public class StandardDeviationVerificationTest extends TestCase {
+
+    /**
+     * Test {@link StandardDeviationVerification#verify(SensorStats)}.
+     */
+    public void testVerify() {
+        // Stddev should be {sqrt(2.5), sqrt(2.5), sqrt(2.5)}
+        float[][] values = {
+                {0, 1, 0},
+                {1, 2, 2},
+                {2, 3, 4},
+                {3, 4, 6},
+                {4, 5, 8},
+        };
+        float[] standardDeviations = {
+                (float) Math.sqrt(2.5), (float) Math.sqrt(2.5), (float) Math.sqrt(10.0)
+        };
+
+        float[] threshold = {2, 2, 4};
+        runVerification(threshold, values, true, standardDeviations);
+
+        threshold = new float[]{1, 2, 4};
+        runVerification(threshold, values, false, standardDeviations);
+
+        threshold = new float[]{2, 1, 4};
+        runVerification(threshold, values, false, standardDeviations);
+
+        threshold = new float[]{2, 2, 3};
+        runVerification(threshold, values, false, standardDeviations);
+    }
+
+    private void runVerification(float[] threshold, float[][] values, boolean pass,
+            float[] standardDeviations) {
+        SensorStats stats = new SensorStats();
+        ISensorVerification verification = getVerification(threshold, values);
+        if (pass) {
+            verification.verify(stats);
+        } else {
+            boolean failed = false;
+            try {
+                verification.verify(stats);
+            } catch (AssertionError e) {
+                // Expected;
+                failed = true;
+            }
+            assertTrue("Expected an AssertionError", failed);
+        }
+        assertEquals(pass, stats.getValue(StandardDeviationVerification.PASSED_KEY));
+        float[] actual = (float[]) stats.getValue(SensorStats.STANDARD_DEVIATION_KEY);
+        for (int i = 0; i < standardDeviations.length; i++) {
+            assertEquals(standardDeviations[i], actual[i], 0.1);
+        }
+    }
+
+    private ISensorVerification getVerification(float[] threshold, float[] ... values) {
+        ISensorVerification verification = new StandardDeviationVerification(threshold);
+        for (float[] value : values) {
+            verification.addSensorEvent(new TestSensorEvent(null, 0, 0, value));
+        }
+        return verification;
+    }
+}
diff --git a/tests/tests/media/src/android/media/cts/AudioManagerTest.java b/tests/tests/media/src/android/media/cts/AudioManagerTest.java
index 4a74b47..13e5fd9 100644
--- a/tests/tests/media/src/android/media/cts/AudioManagerTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioManagerTest.java
@@ -40,6 +40,7 @@
 
 
 import android.content.Context;
+import android.content.res.Resources;
 import android.media.AudioManager;
 import android.media.MediaPlayer;
 import android.os.Vibrator;
@@ -63,7 +64,7 @@
         Vibrator vibrator = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE);
         mHasVibrator = (vibrator != null) && vibrator.hasVibrator();
         mUseFixedVolume = mContext.getResources().getBoolean(
-                                            com.android.internal.R.bool.config_useFixedVolume);
+                Resources.getSystem().getIdentifier("config_useFixedVolume", "bool", "android"));
     }
 
     public void testMicrophoneMute() throws Exception {
diff --git a/tests/tests/media/src/android/media/cts/EncodeDecodeTest.java b/tests/tests/media/src/android/media/cts/EncodeDecodeTest.java
index 6f1faf6..f2fb322 100644
--- a/tests/tests/media/src/android/media/cts/EncodeDecodeTest.java
+++ b/tests/tests/media/src/android/media/cts/EncodeDecodeTest.java
@@ -51,7 +51,8 @@
     private static final String DEBUG_FILE_NAME_BASE = "/sdcard/test.";
 
     // parameters for the encoder
-    private static final String MIME_TYPE = "video/avc";    // H.264 Advanced Video Coding
+    private static final String MIME_TYPE_AVC = "video/avc";    // H.264 Advanced Video Coding
+    private static final String MIME_TYPE_VP8 = "video/x-vnd.on2.vp8";
     private static final int FRAME_RATE = 15;               // 15fps
     private static final int IFRAME_INTERVAL = 10;          // 10 seconds between I-frames
 
@@ -61,22 +62,32 @@
     private static final int TEST_Y = 120;                  // YUV values for colored rect
     private static final int TEST_U = 160;
     private static final int TEST_V = 200;
-    private static final int TEST_R0 = 0;                   // RGB equivalent of {0,0,0}
+    private static final int TEST_R0 = 0;                   // RGB equivalent of {0,0,0} (BT.601)
     private static final int TEST_G0 = 136;
     private static final int TEST_B0 = 0;
-    private static final int TEST_R1 = 236;                 // RGB equivalent of {120,160,200}
+    private static final int TEST_R1 = 236;                 // RGB equivalent of {120,160,200} (BT.601)
     private static final int TEST_G1 = 50;
     private static final int TEST_B1 = 186;
+    private static final int TEST_R0_BT709 = 0;             // RGB equivalent of {0,0,0} (BT.709)
+    private static final int TEST_G0_BT709 = 77;
+    private static final int TEST_B0_BT709 = 0;
+    private static final int TEST_R1_BT709 = 250;           // RGB equivalent of {120,160,200} (BT.709)
+    private static final int TEST_G1_BT709 = 76;
+    private static final int TEST_B1_BT709 = 189;
 
     // size of a frame, in pixels
     private int mWidth = -1;
     private int mHeight = -1;
     // bit rate, in bits per second
     private int mBitRate = -1;
+    private String mMimeType = MIME_TYPE_AVC;
 
     // largest color component delta seen (i.e. actual vs. expected)
     private int mLargestColorDelta;
 
+    // validate YUV->RGB decoded frames against BT.601 and/or BT.709
+    private boolean mAllowBT601 = true;
+    private boolean mAllowBT709 = false;
 
     /**
      * Tests streaming of AVC video through the encoder and decoder.  Data is encoded from
@@ -84,15 +95,33 @@
      * validity.
      */
     public void testEncodeDecodeVideoFromBufferToBufferQCIF() throws Exception {
-        setParameters(176, 144, 1000000);
+        setParameters(176, 144, 1000000, MIME_TYPE_AVC, true, false);
         encodeDecodeVideoFromBuffer(false);
     }
     public void testEncodeDecodeVideoFromBufferToBufferQVGA() throws Exception {
-        setParameters(320, 240, 2000000);
+        setParameters(320, 240, 2000000, MIME_TYPE_AVC, true, false);
         encodeDecodeVideoFromBuffer(false);
     }
     public void testEncodeDecodeVideoFromBufferToBuffer720p() throws Exception {
-        setParameters(1280, 720, 6000000);
+        setParameters(1280, 720, 6000000, MIME_TYPE_AVC, true, false);
+        encodeDecodeVideoFromBuffer(false);
+    }
+
+    /**
+     * Tests streaming of VP8 video through the encoder and decoder.  Data is encoded from
+     * a series of byte[] buffers and decoded into ByteBuffers.  The output is checked for
+     * validity.
+     */
+    public void testVP8EncodeDecodeVideoFromBufferToBufferQCIF() throws Exception {
+        setParameters(176, 144, 1000000, MIME_TYPE_VP8, true, false);
+        encodeDecodeVideoFromBuffer(false);
+    }
+    public void testVP8EncodeDecodeVideoFromBufferToBufferQVGA() throws Exception {
+        setParameters(320, 240, 2000000, MIME_TYPE_VP8, true, false);
+        encodeDecodeVideoFromBuffer(false);
+    }
+    public void testVP8EncodeDecodeVideoFromBufferToBuffer720p() throws Exception {
+        setParameters(1280, 720, 6000000, MIME_TYPE_VP8, true, false);
         encodeDecodeVideoFromBuffer(false);
     }
 
@@ -109,15 +138,33 @@
      * the test.
      */
     public void testEncodeDecodeVideoFromBufferToSurfaceQCIF() throws Throwable {
-        setParameters(176, 144, 1000000);
+        setParameters(176, 144, 1000000, MIME_TYPE_AVC, true, false);
         BufferToSurfaceWrapper.runTest(this);
     }
     public void testEncodeDecodeVideoFromBufferToSurfaceQVGA() throws Throwable {
-        setParameters(320, 240, 2000000);
+        setParameters(320, 240, 2000000, MIME_TYPE_AVC, true, false);
         BufferToSurfaceWrapper.runTest(this);
     }
     public void testEncodeDecodeVideoFromBufferToSurface720p() throws Throwable {
-        setParameters(1280, 720, 6000000);
+        setParameters(1280, 720, 6000000, MIME_TYPE_AVC, true, true);
+        BufferToSurfaceWrapper.runTest(this);
+    }
+
+    /**
+     * Tests streaming of VP8 video through the encoder and decoder.  Data is encoded from
+     * a series of byte[] buffers and decoded into Surfaces.  The output is checked for
+     * validity.
+     */
+    public void testVP8EncodeDecodeVideoFromBufferToSurfaceQCIF() throws Throwable {
+        setParameters(176, 144, 1000000, MIME_TYPE_VP8, true, false);
+        BufferToSurfaceWrapper.runTest(this);
+    }
+    public void testVP8EncodeDecodeVideoFromBufferToSurfaceQVGA() throws Throwable {
+        setParameters(320, 240, 2000000, MIME_TYPE_VP8, true, false);
+        BufferToSurfaceWrapper.runTest(this);
+    }
+    public void testVP8EncodeDecodeVideoFromBufferToSurface720p() throws Throwable {
+        setParameters(1280, 720, 6000000, MIME_TYPE_VP8, true, true);
         BufferToSurfaceWrapper.runTest(this);
     }
 
@@ -158,15 +205,32 @@
      * a Surface and decoded onto a Surface.  The output is checked for validity.
      */
     public void testEncodeDecodeVideoFromSurfaceToSurfaceQCIF() throws Throwable {
-        setParameters(176, 144, 1000000);
+        setParameters(176, 144, 1000000, MIME_TYPE_AVC, true, false);
         SurfaceToSurfaceWrapper.runTest(this);
     }
     public void testEncodeDecodeVideoFromSurfaceToSurfaceQVGA() throws Throwable {
-        setParameters(320, 240, 2000000);
+        setParameters(320, 240, 2000000, MIME_TYPE_AVC, true, false);
         SurfaceToSurfaceWrapper.runTest(this);
     }
     public void testEncodeDecodeVideoFromSurfaceToSurface720p() throws Throwable {
-        setParameters(1280, 720, 6000000);
+        setParameters(1280, 720, 6000000, MIME_TYPE_AVC, true, false);
+        SurfaceToSurfaceWrapper.runTest(this);
+    }
+
+    /**
+     * Tests streaming of VP8 video through the encoder and decoder.  Data is provided through
+     * a Surface and decoded onto a Surface.  The output is checked for validity.
+     */
+    public void testVP8EncodeDecodeVideoFromSurfaceToSurfaceQCIF() throws Throwable {
+        setParameters(176, 144, 1000000, MIME_TYPE_VP8, true, false);
+        SurfaceToSurfaceWrapper.runTest(this);
+    }
+    public void testVP8EncodeDecodeVideoFromSurfaceToSurfaceQVGA() throws Throwable {
+        setParameters(320, 240, 2000000, MIME_TYPE_VP8, true, false);
+        SurfaceToSurfaceWrapper.runTest(this);
+    }
+    public void testVP8EncodeDecodeVideoFromSurfaceToSurface720p() throws Throwable {
+        setParameters(1280, 720, 6000000, MIME_TYPE_VP8, true, false);
         SurfaceToSurfaceWrapper.runTest(this);
     }
 
@@ -205,13 +269,17 @@
     /**
      * Sets the desired frame size and bit rate.
      */
-    private void setParameters(int width, int height, int bitRate) {
+    private void setParameters(int width, int height, int bitRate, String mimeType,
+	        boolean allowBT601, boolean allowBT709) {
         if ((width % 16) != 0 || (height % 16) != 0) {
             Log.w(TAG, "WARNING: width or height not multiple of 16");
         }
         mWidth = width;
         mHeight = height;
         mBitRate = bitRate;
+        mMimeType = mimeType;
+        mAllowBT601 = allowBT601;
+        mAllowBT709 = allowBT709;
     }
 
     /**
@@ -229,20 +297,20 @@
         mLargestColorDelta = -1;
 
         try {
-            MediaCodecInfo codecInfo = selectCodec(MIME_TYPE);
+            MediaCodecInfo codecInfo = selectCodec(mMimeType);
             if (codecInfo == null) {
                 // Don't fail CTS if they don't have an AVC codec (not here, anyway).
-                Log.e(TAG, "Unable to find an appropriate codec for " + MIME_TYPE);
+                Log.e(TAG, "Unable to find an appropriate codec for " + mMimeType);
                 return;
             }
             if (VERBOSE) Log.d(TAG, "found codec: " + codecInfo.getName());
 
-            int colorFormat = selectColorFormat(codecInfo, MIME_TYPE);
+            int colorFormat = selectColorFormat(codecInfo, mMimeType);
             if (VERBOSE) Log.d(TAG, "found colorFormat: " + colorFormat);
 
             // We avoid the device-specific limitations on width and height by using values that
             // are multiples of 16, which all tested devices seem to be able to handle.
-            MediaFormat format = MediaFormat.createVideoFormat(MIME_TYPE, mWidth, mHeight);
+            MediaFormat format = MediaFormat.createVideoFormat(mMimeType, mWidth, mHeight);
 
             // Set some properties.  Failing to specify some of these can cause the MediaCodec
             // configure() call to throw an unhelpful exception.
@@ -260,7 +328,7 @@
 
             // Create a MediaCodec for the decoder, just based on the MIME type.  The various
             // format details will be passed through the csd-0 meta-data later on.
-            decoder = MediaCodec.createDecoderByType(MIME_TYPE);
+            decoder = MediaCodec.createDecoderByType(mMimeType);
             if (VERBOSE) Log.d(TAG, "got decoder: " + decoder.getName());
 
             doEncodeDecodeVideoFromBuffer(encoder, colorFormat, decoder, toSurface);
@@ -294,10 +362,10 @@
         mLargestColorDelta = -1;
 
         try {
-            MediaCodecInfo codecInfo = selectCodec(MIME_TYPE);
+            MediaCodecInfo codecInfo = selectCodec(mMimeType);
             if (codecInfo == null) {
                 // Don't fail CTS if they don't have an AVC codec (not here, anyway).
-                Log.e(TAG, "Unable to find an appropriate codec for " + MIME_TYPE);
+                Log.e(TAG, "Unable to find an appropriate codec for " + mMimeType);
                 return;
             }
             if (VERBOSE) Log.d(TAG, "found codec: " + codecInfo.getName());
@@ -306,7 +374,7 @@
 
             // We avoid the device-specific limitations on width and height by using values that
             // are multiples of 16, which all tested devices seem to be able to handle.
-            MediaFormat format = MediaFormat.createVideoFormat(MIME_TYPE, mWidth, mHeight);
+            MediaFormat format = MediaFormat.createVideoFormat(mMimeType, mWidth, mHeight);
 
             // Set some properties.  Failing to specify some of these can cause the MediaCodec
             // configure() call to throw an unhelpful exception.
@@ -321,7 +389,7 @@
 
             // Create a MediaCodec for the decoder, just based on the MIME type.  The various
             // format details will be passed through the csd-0 meta-data later on.
-            decoder = MediaCodec.createDecoderByType(MIME_TYPE);
+            decoder = MediaCodec.createDecoderByType(mMimeType);
             if (VERBOSE) Log.d(TAG, "got decoder: " + decoder.getName());
             decoder.configure(format, outputSurface.getSurface(), null, 0);
             decoder.start();
@@ -564,14 +632,18 @@
                             throw new RuntimeException(ioe);
                         }
                     }
-                    if ((info.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0) {
+                    if (!decoderConfigured) {
                         // Codec config info.  Only expected on first packet.  One way to
                         // handle this is to manually stuff the data into the MediaFormat
                         // and pass that to configure().  We do that here to exercise the API.
-                        assertFalse(decoderConfigured);
+                        // For codecs that don't have codec config data (such as VP8),
+                        // initialize the decoder before trying to decode the first packet.
+                        assertTrue((info.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0 ||
+                                   mMimeType.equals(MIME_TYPE_VP8));
                         MediaFormat format =
-                                MediaFormat.createVideoFormat(MIME_TYPE, mWidth, mHeight);
-                        format.setByteBuffer("csd-0", encodedData);
+                                MediaFormat.createVideoFormat(mMimeType, mWidth, mHeight);
+                        if ((info.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0)
+                            format.setByteBuffer("csd-0", encodedData);
                         decoder.configure(format, toSurface ? outputSurface.getSurface() : null,
                                 null, 0);
                         decoder.start();
@@ -579,7 +651,8 @@
                         decoderOutputBuffers = decoder.getOutputBuffers();
                         decoderConfigured = true;
                         if (VERBOSE) Log.d(TAG, "decoder configured (" + info.size + " bytes)");
-                    } else {
+                    }
+                    if ((info.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) == 0) {
                         // Get a decoder input buffer, blocking until it's available.
                         assertTrue(decoderConfigured);
                         int inputBufIndex = decoder.dequeueInputBuffer(-1);
@@ -1088,22 +1161,41 @@
             int b = pixelBuf.get(2) & 0xff;
             //Log.d(TAG, "GOT(" + frameIndex + "/" + i + "): r=" + r + " g=" + g + " b=" + b);
 
-            int expR, expG, expB;
+            int expR, expG, expB, expR_bt709, expG_bt709, expB_bt709;
             if (i == frameIndex % 8) {
                 // colored rect
                 expR = TEST_R1;
                 expG = TEST_G1;
                 expB = TEST_B1;
+                expR_bt709 = TEST_R1_BT709;
+                expG_bt709 = TEST_G1_BT709;
+                expB_bt709 = TEST_B1_BT709;
             } else {
                 // zero background color
                 expR = TEST_R0;
                 expG = TEST_G0;
                 expB = TEST_B0;
+                expR_bt709 = TEST_R0_BT709;
+                expG_bt709 = TEST_G0_BT709;
+                expB_bt709 = TEST_B0_BT709;
             }
-            if (!isColorClose(r, expR) ||
-                    !isColorClose(g, expG) ||
-                    !isColorClose(b, expB)) {
-                Log.w(TAG, "Bad frame " + frameIndex + " (rect=" + i + ": rgb=" + r +
+
+            // Some decoders use BT.709 when converting HD (i.e. >= 720p)
+            // frames from YUV to RGB, so check against both BT.601 and BT.709
+            if (mAllowBT601 &&
+                    isColorClose(r, expR) &&
+                    isColorClose(g, expG) &&
+                    isColorClose(b, expB)) {
+                // frame OK on BT.601
+                mAllowBT709 = false;
+            } else if (mAllowBT709 &&
+                           isColorClose(r, expR_bt709) &&
+                           isColorClose(g, expG_bt709) &&
+                           isColorClose(b, expB_bt709)) {
+                // frame OK on BT.709
+                mAllowBT601 = false;
+            } else {
+                Log.w(TAG, "Bad frame " + frameIndex + " (rect=" + i + " @ " + x + " " + y + ": rgb=" + r +
                         "," + g + "," + b + " vs. expected " + expR + "," + expG +
                         "," + expB + ")");
                 frameFailed = true;
diff --git a/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayTest.java b/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayTest.java
old mode 100644
new mode 100755
index 39c7b77..7b33b75
--- a/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayTest.java
+++ b/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayTest.java
@@ -65,20 +65,29 @@
     private static final boolean DEBUG_SAVE_FILE = false;   // save copy of encoded movie
     private static final String DEBUG_FILE_NAME_BASE = "/sdcard/test.";
 
+    // Encoder parameters table, sort by encoder level from high to low.
+    private static final int[][] ENCODER_PARAM_TABLE = {
+        // encoder level,                             width,   height,  bitrate,    framerate
+        {MediaCodecInfo.CodecProfileLevel.AVCLevel31, 1280,     720,    14000000,   30},
+        {MediaCodecInfo.CodecProfileLevel.AVCLevel3,   720,     480,    10000000,   30},
+        {MediaCodecInfo.CodecProfileLevel.AVCLevel22,  720,     480,    4000000,    15},
+        {MediaCodecInfo.CodecProfileLevel.AVCLevel21,  352,     576,    4000000,    25},
+    };
+
     // Virtual display characteristics.  Scaled down from full display size because not all
     // devices can encode at the resolution of their own display.
     private static final String NAME = TAG;
-    private static final int WIDTH = 1280;
-    private static final int HEIGHT = 720;
+    private static int sWidth = ENCODER_PARAM_TABLE[ENCODER_PARAM_TABLE.length-1][1];
+    private static int sHeight = ENCODER_PARAM_TABLE[ENCODER_PARAM_TABLE.length-1][2];
     private static final int DENSITY = DisplayMetrics.DENSITY_HIGH;
     private static final int UI_TIMEOUT_MS = 2000;
     private static final int UI_RENDER_PAUSE_MS = 400;
 
     // Encoder parameters.  We use the same width/height as the virtual display.
     private static final String MIME_TYPE = "video/avc";
-    private static final int FRAME_RATE = 15;               // 15fps
-    private static final int IFRAME_INTERVAL = 10;          // 10 seconds between I-frames
-    private static final int BIT_RATE = 6000000;            // 6Mbps
+    private static int sFrameRate = 15;               // 15fps
+    private static final int IFRAME_INTERVAL = 10;    // 10 seconds between I-frames
+    private static int sBitRate = 6000000;            // 6Mbps
 
     // Colors to test (RGB).  These must convert cleanly to and from BT.601 YUV.
     private static final int TEST_COLORS[] = {
@@ -106,6 +115,7 @@
 
         mUiHandler = new Handler(Looper.getMainLooper());
         mDisplayManager = (DisplayManager)mContext.getSystemService(Context.DISPLAY_SERVICE);
+        setupEncoderParameters();
     }
 
     /**
@@ -171,6 +181,62 @@
     }
 
     /**
+     * Returns true if the encoder level, specified in the ENCODER_PARAM_TABLE, can be supported.
+     */
+    private static boolean verifySupportForEncoderLevel(int index) {
+        int numCodecs = MediaCodecList.getCodecCount();
+        for (int i = 0; i < numCodecs; i++) {
+            MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(i);
+
+            if (!codecInfo.isEncoder()) {
+                continue;
+            }
+
+            String[] types = codecInfo.getSupportedTypes();
+            for (int j = 0; j < types.length; j++) {
+
+                if (false == types[j].equalsIgnoreCase(MIME_TYPE)) {
+                    continue;
+                }
+
+                MediaCodecInfo.CodecCapabilities caps = codecInfo.getCapabilitiesForType(types[j]);
+                for (int k = 0; k < caps.profileLevels.length; k++) {
+                    int profile = caps.profileLevels[k].profile;
+                    int level = caps.profileLevels[k].level;
+                    //Log.d(TAG, "[" + k + "] supported profile = " + profile + ", level = " + level);
+                    if (caps.profileLevels[k].level >= ENCODER_PARAM_TABLE[index][0]) {
+                        return true;
+                    }
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Initialize the encoder parameters according to the device capability.
+     */
+    private static void setupEncoderParameters() {
+
+        // Loop over each tabel entry until a proper encoder setting is found.
+        for (int i = 0; i < ENCODER_PARAM_TABLE.length; i++) {
+
+            // Check if we can support it?
+            if (verifySupportForEncoderLevel(i)) {
+
+                sWidth = ENCODER_PARAM_TABLE[i][1];
+                sHeight = ENCODER_PARAM_TABLE[i][2];
+                sBitRate = ENCODER_PARAM_TABLE[i][3];
+                sFrameRate = ENCODER_PARAM_TABLE[i][4];
+
+                Log.d(TAG, "encoder parameters changed: width = " + sWidth + ", height = " + sHeight
+                    + ", bitrate = " + sBitRate + ", framerate = " + sFrameRate);
+                break;
+            }
+        }
+    }
+
+    /**
      * Prepares the encoder, decoder, and virtual display.
      */
     private void encodeVirtualDisplayTest() {
@@ -186,11 +252,11 @@
 
         try {
             // Encoded video resolution matches virtual display.
-            MediaFormat encoderFormat = MediaFormat.createVideoFormat(MIME_TYPE, WIDTH, HEIGHT);
+            MediaFormat encoderFormat = MediaFormat.createVideoFormat(MIME_TYPE, sWidth, sHeight);
             encoderFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT,
                     MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);
-            encoderFormat.setInteger(MediaFormat.KEY_BIT_RATE, BIT_RATE);
-            encoderFormat.setInteger(MediaFormat.KEY_FRAME_RATE, FRAME_RATE);
+            encoderFormat.setInteger(MediaFormat.KEY_BIT_RATE, sBitRate);
+            encoderFormat.setInteger(MediaFormat.KEY_FRAME_RATE, sFrameRate);
             encoderFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, IFRAME_INTERVAL);
 
             encoder = MediaCodec.createEncoderByType(MIME_TYPE);
@@ -200,12 +266,12 @@
 
             // Create a virtual display that will output to our encoder.
             virtualDisplay = mDisplayManager.createVirtualDisplay(NAME,
-                    WIDTH, HEIGHT, DENSITY, inputSurface, 0);
+                    sWidth, sHeight, DENSITY, inputSurface, 0);
 
             // We also need a decoder to check the output of the encoder.
             decoder = MediaCodec.createDecoderByType(MIME_TYPE);
-            MediaFormat decoderFormat = MediaFormat.createVideoFormat(MIME_TYPE, WIDTH, HEIGHT);
-            outputSurface = new OutputSurface(WIDTH, HEIGHT);
+            MediaFormat decoderFormat = MediaFormat.createVideoFormat(MIME_TYPE, sWidth, sHeight);
+            outputSurface = new OutputSurface(sWidth, sHeight);
             decoder.configure(decoderFormat, outputSurface.getSurface(), null, 0);
             decoder.start();
 
@@ -253,7 +319,7 @@
         // stream, not a .mp4 file, so not all players will know what to do with it.
         FileOutputStream outputStream = null;
         if (DEBUG_SAVE_FILE) {
-            String fileName = DEBUG_FILE_NAME_BASE + WIDTH + "x" + HEIGHT + ".mp4";
+            String fileName = DEBUG_FILE_NAME_BASE + sWidth + "x" + sHeight + ".mp4";
             try {
                 outputStream = new FileOutputStream(fileName);
                 Log.d(TAG, "encoded output will be saved as " + fileName);
@@ -447,8 +513,8 @@
 
         // Read a pixel from the center of the surface.  Might want to read from multiple points
         // and average them together.
-        int x = WIDTH / 2;
-        int y = HEIGHT / 2;
+        int x = sWidth / 2;
+        int y = sHeight / 2;
         GLES20.glReadPixels(x, y, 1, 1, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, mPixelBuf);
         int r = mPixelBuf.get(0) & 0xff;
         int g = mPixelBuf.get(1) & 0xff;
diff --git a/tests/tests/media/src/android/media/cts/MediaMuxerTest.java b/tests/tests/media/src/android/media/cts/MediaMuxerTest.java
index 9cad011..6591555 100644
--- a/tests/tests/media/src/android/media/cts/MediaMuxerTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaMuxerTest.java
@@ -56,7 +56,8 @@
      */
     public void testVideoAudio() throws Exception {
         int source = R.raw.video_176x144_3gp_h263_300kbps_25fps_aac_stereo_128kbps_11025hz;
-        String outputFile = "/sdcard/videoAudio.mp4";
+        String outputFile = File.createTempFile("MediaMuxerTest_testAudioVideo", ".mp4")
+                .getAbsolutePath();
         cloneAndVerify(source, outputFile, 2, 90);
     }
 
@@ -65,7 +66,8 @@
      */
     public void testAudioOnly() throws Exception {
         int source = R.raw.sinesweepm4a;
-        String outputFile = "/sdcard/audioOnly.mp4";
+        String outputFile = File.createTempFile("MediaMuxerTest_testAudioOnly", ".mp4")
+                .getAbsolutePath();
         cloneAndVerify(source, outputFile, 1, -1);
     }
 
@@ -74,7 +76,8 @@
      */
     public void testVideoOnly() throws Exception {
         int source = R.raw.video_only_176x144_3gp_h263_25fps;
-        String outputFile = "/sdcard/videoOnly.mp4";
+        String outputFile = File.createTempFile("MediaMuxerTest_videoOnly", ".mp4")
+                .getAbsolutePath();
         cloneAndVerify(source, outputFile, 1, 180);
     }
 
@@ -88,7 +91,8 @@
      * <br> Throws exception b/c a wrong format.
      */
     public void testIllegalStateExceptions() throws IOException {
-        String outputFile = "/sdcard/muxerExceptions.mp4";
+        String outputFile = File.createTempFile("MediaMuxerTest_testISEs", ".mp4")
+                .getAbsolutePath();
         MediaMuxer muxer;
 
         // Throws exception b/c start() is not called.
@@ -369,25 +373,26 @@
         String location = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_LOCATION);
         assertNotNull("No location information found in file " + fileName, location);
 
-        // parsing String location and recover the location inforamtion in floats
+
+        // parsing String location and recover the location information in floats
         // Make sure the tolerance is very small - due to rounding errors.
 
         // Get the position of the -/+ sign in location String, which indicates
-        // the beginning of the longtitude.
-        int index = location.lastIndexOf('-');
-        if (index == -1) {
-            index = location.lastIndexOf('+');
-        }
-        assertTrue("+ or - is not found", index != -1);
-        assertTrue("+ or - is only found at the beginning", index != 0);
+        // the beginning of the longitude.
+        int minusIndex = location.lastIndexOf('-');
+        int plusIndex = location.lastIndexOf('+');
+
+        assertTrue("+ or - is not found or found only at the beginning [" + location + "]",
+                (minusIndex > 0 || plusIndex > 0));
+        int index = Math.max(minusIndex, plusIndex);
+
         float latitude = Float.parseFloat(location.substring(0, index - 1));
         float longitude = Float.parseFloat(location.substring(index));
-        assertTrue("Incorrect latitude: " + latitude,
+        assertTrue("Incorrect latitude: " + latitude + " [" + location + "]",
                 Math.abs(latitude - LATITUDE) <= TOLERANCE);
-        assertTrue("Incorrect longitude: " + longitude,
+        assertTrue("Incorrect longitude: " + longitude + " [" + location + "]",
                 Math.abs(longitude - LONGITUDE) <= TOLERANCE);
         retriever.release();
     }
-
 }
 
diff --git a/tests/tests/media/src/android/media/cts/StreamingMediaPlayerTest.java b/tests/tests/media/src/android/media/cts/StreamingMediaPlayerTest.java
index 8368a23..8bac442 100644
--- a/tests/tests/media/src/android/media/cts/StreamingMediaPlayerTest.java
+++ b/tests/tests/media/src/android/media/cts/StreamingMediaPlayerTest.java
@@ -199,7 +199,6 @@
             mServer.shutdown();
         }
     }
-
     private void localHttpsAudioStreamTest(final String name, boolean redirect, boolean nolength)
             throws Throwable {
         mServer = new CtsTestServer(mContext, true);
diff --git a/tests/tests/nativemedia/sl/Android.mk b/tests/tests/nativemedia/sl/Android.mk
index 49ccb10..5b34b3d 100644
--- a/tests/tests/nativemedia/sl/Android.mk
+++ b/tests/tests/nativemedia/sl/Android.mk
@@ -3,6 +3,7 @@
 LOCAL_PATH:= $(call my-dir)
 
 test_executable := NativeMediaTest_SL
+list_executable := $(test_executable)_list
 
 include $(CLEAR_VARS)
 
@@ -33,3 +34,19 @@
 
 LOCAL_CTS_TEST_PACKAGE := android.nativemedia.sl
 include $(BUILD_CTS_EXECUTABLE)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := $(list_executable)
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := \
+    src/SLObjectCreationTest.cpp
+
+LOCAL_CFLAGS := \
+    -DBUILD_ONLY \
+
+LOCAL_SHARED_LIBRARIES := \
+    liblog \
+
+include $(BUILD_HOST_NATIVE_TEST)
diff --git a/tests/tests/nativemedia/sl/NativeMediaTest_SL_list.txt b/tests/tests/nativemedia/sl/NativeMediaTest_SL_list.txt
deleted file mode 100644
index c5d17a3..0000000
--- a/tests/tests/nativemedia/sl/NativeMediaTest_SL_list.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-SLObjectCreationTest.
-  testEngineCreation
-  testOutputMixCreation
-  testAudioPlayerFromUriCreation
-  testAudioPlayerFromFdCreation
-  testAudioPlayerFromPcmBqCreation
-  testAudioPlayerFromTsAbqCreation
-  testAudioPlayerFromUriToPcmBqCreation
-  testAudioPlayerFromFdToPcmBqCreation
-  testAudioPlayerFromAdtsAbqToPcmBqCreation
-  testAudioRecorderCreation
diff --git a/tests/tests/nativemedia/xa/Android.mk b/tests/tests/nativemedia/xa/Android.mk
index f2c0ca0..6995bc0 100644
--- a/tests/tests/nativemedia/xa/Android.mk
+++ b/tests/tests/nativemedia/xa/Android.mk
@@ -3,6 +3,7 @@
 LOCAL_PATH:= $(call my-dir)
 
 test_executable := NativeMediaTest_XA
+list_executable := $(test_executable)_list
 
 include $(CLEAR_VARS)
 
@@ -32,3 +33,19 @@
 
 LOCAL_CTS_TEST_PACKAGE := android.nativemedia.xa
 include $(BUILD_CTS_EXECUTABLE)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := $(list_executable)
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := \
+    src/XAObjectCreationTest.cpp
+
+LOCAL_CFLAGS := \
+    -DBUILD_ONLY \
+
+LOCAL_SHARED_LIBRARIES := \
+    liblog \
+
+include $(BUILD_HOST_NATIVE_TEST)
diff --git a/tests/tests/nativemedia/xa/NativeMediaTest_XA_list.txt b/tests/tests/nativemedia/xa/NativeMediaTest_XA_list.txt
deleted file mode 100644
index af8bfad..0000000
--- a/tests/tests/nativemedia/xa/NativeMediaTest_XA_list.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-XAObjectCreationTest.
-  testEngineCreation
-  testOutputMixCreation
diff --git a/tests/tests/net/src/android/net/cts/TrafficStatsTest.java b/tests/tests/net/src/android/net/cts/TrafficStatsTest.java
old mode 100644
new mode 100755
index 9483bdc..5b93bee
--- a/tests/tests/net/src/android/net/cts/TrafficStatsTest.java
+++ b/tests/tests/net/src/android/net/cts/TrafficStatsTest.java
@@ -207,27 +207,37 @@
         final int maxExpectedExtraPackets = 7;
         final int minExpectedExtraPackets = 5;
 
+        // Some other tests don't cleanup connections correctly.
+        // They have the same UID, so we discount their lingering traffic
+        // which happens only on non-localhost, such as TCP FIN retranmission packets
+        long deltaTxOtherPackets = (totalTxPacketsAfter - totalTxPacketsBefore) - uidTxDeltaPackets;
+        long deltaRxOtherPackets = (totalRxPacketsAfter - totalRxPacketsBefore) - uidRxDeltaPackets;
+        if (deltaTxOtherPackets > 0 || deltaRxOtherPackets > 0) {
+            Log.i(LOG_TAG, "lingering traffic data: " + deltaTxOtherPackets + "/" + deltaRxOtherPackets);
+            // Make sure that not too many non-localhost packets are accounted for
+            assertTrue("too many non-localhost packets on the sam UID", deltaTxOtherPackets + deltaTxOtherPackets < 20);
+        }
 
         assertTrue("uidtxp: " + uidTxPacketsBefore + " -> " + uidTxPacketsAfter + " delta=" + uidTxDeltaPackets +
             " Wanted: " + uidTxDeltaPackets + ">=" + packetCount + "+" + minExpectedExtraPackets + " && " +
-            uidTxDeltaPackets + "<=" + packetCount + "+" + packetCount + "+" + maxExpectedExtraPackets,
+            uidTxDeltaPackets + "<=" + packetCount + "+" + packetCount + "+" + maxExpectedExtraPackets + "+" + deltaTxOtherPackets,
             uidTxDeltaPackets >= packetCount + minExpectedExtraPackets &&
-            uidTxDeltaPackets <= packetCount + packetCount + maxExpectedExtraPackets);
+            uidTxDeltaPackets <= packetCount + packetCount + maxExpectedExtraPackets + deltaTxOtherPackets);
         assertTrue("uidrxp: " + uidRxPacketsBefore + " -> " + uidRxPacketsAfter + " delta=" + uidRxDeltaPackets +
             " Wanted: " + uidRxDeltaPackets + ">=" + packetCount + "+" + minExpectedExtraPackets + " && " +
             uidRxDeltaPackets + "<=" + packetCount + "+" + packetCount + "+" + maxExpectedExtraPackets,
             uidRxDeltaPackets >= packetCount + minExpectedExtraPackets &&
-            uidRxDeltaPackets <= packetCount + packetCount + maxExpectedExtraPackets);
+            uidRxDeltaPackets <= packetCount + packetCount + maxExpectedExtraPackets + deltaRxOtherPackets);
         assertTrue("uidtxb: " + uidTxBytesBefore + " -> " + uidTxBytesAfter + " delta=" + uidTxDeltaBytes +
             " Wanted: " + uidTxDeltaBytes + ">=" + tcpPacketToIpBytes(packetCount, byteCount) + "+" + tcpPacketToIpBytes(minExpectedExtraPackets, 0) + " && " +
             uidTxDeltaBytes + "<=" + tcpPacketToIpBytes(packetCount, byteCount) + "+" + tcpPacketToIpBytes(packetCount + maxExpectedExtraPackets, 0),
             uidTxDeltaBytes >= tcpPacketToIpBytes(packetCount, byteCount) + tcpPacketToIpBytes(minExpectedExtraPackets, 0) &&
-            uidTxDeltaBytes <= tcpPacketToIpBytes(packetCount, byteCount) + tcpPacketToIpBytes(packetCount + maxExpectedExtraPackets, 0));
+            uidTxDeltaBytes <= tcpPacketToIpBytes(packetCount, byteCount) + tcpPacketToIpBytes(packetCount + maxExpectedExtraPackets + deltaTxOtherPackets, 0));
         assertTrue("uidrxb: " + uidRxBytesBefore + " -> " + uidRxBytesAfter + " delta=" + uidRxDeltaBytes +
             " Wanted: " + uidRxDeltaBytes + ">=" + tcpPacketToIpBytes(packetCount, byteCount) + "+" + tcpPacketToIpBytes(minExpectedExtraPackets, 0) + " && " +
             uidRxDeltaBytes + "<=" + tcpPacketToIpBytes(packetCount, byteCount) + "+" + tcpPacketToIpBytes(packetCount + maxExpectedExtraPackets, 0),
             uidRxDeltaBytes >= tcpPacketToIpBytes(packetCount, byteCount) + tcpPacketToIpBytes(minExpectedExtraPackets, 0) &&
-            uidRxDeltaBytes <= tcpPacketToIpBytes(packetCount, byteCount) + tcpPacketToIpBytes(packetCount + maxExpectedExtraPackets, 0));
+            uidRxDeltaBytes <= tcpPacketToIpBytes(packetCount, byteCount) + tcpPacketToIpBytes(packetCount + maxExpectedExtraPackets + deltaRxOtherPackets, 0));
 
         // Localhost traffic *does* count against total stats.
         // Fudge by 132 packets of 1500 bytes not related to the test.
diff --git a/tests/tests/net/src/android/net/ipv6/cts/PingTest.java b/tests/tests/net/src/android/net/ipv6/cts/PingTest.java
index 41eb03d..49fc59c 100644
--- a/tests/tests/net/src/android/net/ipv6/cts/PingTest.java
+++ b/tests/tests/net/src/android/net/ipv6/cts/PingTest.java
@@ -19,10 +19,10 @@
 import android.test.AndroidTestCase;
 import android.util.Log;
 
-import libcore.io.ErrnoException;
-import libcore.io.Libcore;
-import libcore.io.StructTimeval;
-import static libcore.io.OsConstants.*;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.system.StructTimeval;
+import static android.system.OsConstants.*;
 
 import java.io.FileDescriptor;
 import java.io.IOException;
@@ -34,6 +34,21 @@
 import java.util.Arrays;
 import java.util.Random;
 
+/**
+ * Checks that the device has kernel support for the IPv6 ping socket. This allows ping6 to work
+ * without root privileges. The necessary kernel code is in Linux 3.11 or above, or the
+ * <code>common/android-3.x</code> kernel trees. If you are not running one of these kernels, the
+ * functionality can be obtained by cherry-picking the following patches from David Miller's
+ * <code>net-next</code> tree:
+ * <ul>
+ * <li>6d0bfe2 net: ipv6: Add IPv6 support to the ping socket.
+ * <li>c26d6b4 ping: always initialize ->sin6_scope_id and ->sin6_flowinfo
+ * <li>fbfe80c net: ipv6: fix wrong ping_v6_sendmsg return value
+ * <li>a1bdc45 net: ipv6: add missing lock in ping_v6_sendmsg
+ * <li>cf970c0 ping: prevent NULL pointer dereference on write to msg_name
+ * </ul>
+ * or the equivalent backports to the <code>common/android-3.x</code> trees.
+ */
 public class PingTest extends AndroidTestCase {
     /** Maximum size of the packets we're using to test. */
     private static final int MAX_SIZE = 4096;
@@ -69,8 +84,8 @@
      * Creates an IPv6 ping socket and sets a receive timeout of 100ms.
      */
     private FileDescriptor createPingSocket() throws ErrnoException {
-        FileDescriptor s = Libcore.os.socket(AF_INET6, SOCK_DGRAM, IPPROTO_ICMPV6);
-        Libcore.os.setsockoptTimeval(s, SOL_SOCKET, SO_RCVTIMEO, StructTimeval.fromMillis(100));
+        FileDescriptor s = Os.socket(AF_INET6, SOCK_DGRAM, IPPROTO_ICMPV6);
+        Os.setsockoptTimeval(s, SOL_SOCKET, SO_RCVTIMEO, StructTimeval.fromMillis(100));
         return s;
     }
 
@@ -83,26 +98,32 @@
         int port = (int) (Math.random() * 2048);
 
         // Send the packet.
-        int ret = Libcore.os.sendto(s, ByteBuffer.wrap(packet), 0, address, port);
+        int ret = Os.sendto(s, ByteBuffer.wrap(packet), 0, address, port);
         assertEquals(packet.length, ret);
     }
 
     /**
      * Checks that a socket has received a response appropriate to the specified packet.
      */
-    private void checkResponse(FileDescriptor s,
-            InetAddress dest, byte[] sent) throws ErrnoException, IOException {
-        // Receive the response.
-        InetSocketAddress from = new InetSocketAddress();
+    private void checkResponse(FileDescriptor s, InetAddress dest,
+            byte[] sent, boolean useRecvfrom) throws ErrnoException, IOException {
         ByteBuffer responseBuffer = ByteBuffer.allocate(MAX_SIZE);
-        int bytesRead = Libcore.os.recvfrom(s, responseBuffer, 0, from);
+        int bytesRead;
 
-        // Check the source address and scope ID.
-        assertTrue(from.getAddress() instanceof Inet6Address);
-        Inet6Address fromAddress = (Inet6Address) from.getAddress();
-        assertEquals(0, fromAddress.getScopeId());
-        assertNull(fromAddress.getScopedInterface());
-        assertEquals(dest.getHostAddress(), fromAddress.getHostAddress());
+        // Receive the response.
+        if (useRecvfrom) {
+            InetSocketAddress from = new InetSocketAddress();
+            bytesRead = Os.recvfrom(s, responseBuffer, 0, from);
+
+            // Check the source address and scope ID.
+            assertTrue(from.getAddress() instanceof Inet6Address);
+            Inet6Address fromAddress = (Inet6Address) from.getAddress();
+            assertEquals(0, fromAddress.getScopeId());
+            assertNull(fromAddress.getScopedInterface());
+            assertEquals(dest.getHostAddress(), fromAddress.getHostAddress());
+        } else {
+            bytesRead = Os.read(s, responseBuffer);
+        }
 
         // Check the packet length.
         assertEquals(sent.length, bytesRead);
@@ -113,7 +134,7 @@
         assertEquals((byte) 0x81, response[0]);
 
         // Find out what ICMP ID was used in the packet that was sent.
-        int id = ((InetSocketAddress) Libcore.os.getsockname(s)).getPort();
+        int id = ((InetSocketAddress) Os.getsockname(s)).getPort();
         sent[4] = (byte) (id / 256);
         sent[5] = (byte) (id % 256);
 
@@ -135,10 +156,13 @@
         for (int i = 0; i < NUM_PACKETS; i++) {
             byte[] packet = pingPacket((int) (Math.random() * MAX_SIZE));
             FileDescriptor s = createPingSocket();
+            // Use both recvfrom and read().
             sendPing(s, ipv6Loopback, packet);
-            checkResponse(s, ipv6Loopback, packet);
+            checkResponse(s, ipv6Loopback, packet, true);
+            sendPing(s, ipv6Loopback, packet);
+            checkResponse(s, ipv6Loopback, packet, false);
             // Check closing the socket doesn't raise an exception.
-            Libcore.os.close(s);
+            Os.close(s);
         }
     }
 }
diff --git a/tests/tests/openglperf/src/android/openglperf/cts/PlanetsSurfaceView.java b/tests/tests/openglperf/src/android/openglperf/cts/PlanetsSurfaceView.java
old mode 100644
new mode 100755
index 072988d..afe664f
--- a/tests/tests/openglperf/src/android/openglperf/cts/PlanetsSurfaceView.java
+++ b/tests/tests/openglperf/src/android/openglperf/cts/PlanetsSurfaceView.java
@@ -33,9 +33,9 @@
 
     @Override
     public void onPause() {
-        mWatchDog.stop();
         super.onPause();
         setRenderMode(RENDERMODE_WHEN_DIRTY);
+        mWatchDog.stop();
     }
 
     @Override
diff --git a/tests/tests/os/src/android/os/cts/BundleTest.java b/tests/tests/os/src/android/os/cts/BundleTest.java
index 7674b6b..0db5fd0 100644
--- a/tests/tests/os/src/android/os/cts/BundleTest.java
+++ b/tests/tests/os/src/android/os/cts/BundleTest.java
@@ -31,9 +31,11 @@
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Set;
 
 public class BundleTest extends AndroidTestCase {
+
     private static final boolean BOOLEANKEYVALUE = false;
 
     private static final int INTKEYVALUE = 20;
@@ -513,12 +515,37 @@
         assertBundleEquals(bundle2, (Bundle) ret.get(1));
     }
 
-    public void testGetSerializable() {
+    public void testGetSerializableWithString() {
         assertNull(mBundle.getSerializable(KEY));
-        mBundle.putSerializable(KEY, "android");
-        assertEquals("android", mBundle.getSerializable(KEY));
+        String s = "android";
+        mBundle.putSerializable(KEY, s);
+        assertEquals(s, mBundle.getSerializable(KEY));
         roundtrip();
-        assertEquals("android", mBundle.getSerializable(KEY));
+        assertEquals(s, mBundle.getSerializable(KEY));
+    }
+
+    public void testGetSerializableWithStringArray() {
+        assertNull(mBundle.getSerializable(KEY));
+        String[] strings = new String[]{"first", "last"};
+        mBundle.putSerializable(KEY, strings);
+        assertEquals(Arrays.asList(strings),
+                Arrays.asList((String[]) mBundle.getSerializable(KEY)));
+        roundtrip();
+        assertEquals(Arrays.asList(strings),
+                Arrays.asList((String[]) mBundle.getSerializable(KEY)));
+    }
+
+    public void testGetSerializableWithMultiDimensionalObjectArray() {
+        assertNull(mBundle.getSerializable(KEY));
+        Object[][] objects = new Object[][] {
+                {"string", 1L}
+        };
+        mBundle.putSerializable(KEY, objects);
+        assertEquals(Arrays.asList(objects[0]),
+                Arrays.asList(((Object[][]) mBundle.getSerializable(KEY))[0]));
+        roundtrip();
+        assertEquals(Arrays.asList(objects[0]),
+                Arrays.asList(((Object[][]) mBundle.getSerializable(KEY))[0]));
     }
 
     public void testGetShort1() {
@@ -812,9 +839,5 @@
         MockClassLoader() {
             super();
         }
-
-        MockClassLoader(ClassLoader parent) {
-            super(parent);
-        }
     }
 }
diff --git a/tests/tests/os/src/android/os/cts/MemoryFileTest.java b/tests/tests/os/src/android/os/cts/MemoryFileTest.java
index 137f3c3..def73b2 100644
--- a/tests/tests/os/src/android/os/cts/MemoryFileTest.java
+++ b/tests/tests/os/src/android/os/cts/MemoryFileTest.java
@@ -33,13 +33,11 @@
     }
 
     public void testConstructor() throws IOException {
-        // new the MemoryFile instance
         new MemoryFile("Test File", 1024);
     }
 
     public void testWriteBytes() throws IOException {
         byte[] data = new byte[512];
-        // new the MemoryFile instance
         mMemoryFile = new MemoryFile("Test File", 1024);
 
         mMemoryFile.writeBytes(data, 0, 0, 512);
@@ -103,11 +101,14 @@
         mMemoryFile = new MemoryFile("Test File", 512);
         assertEquals(512, mMemoryFile.length());
 
-        mMemoryFile = new MemoryFile("Test File", Integer.MAX_VALUE);
-        assertEquals(Integer.MAX_VALUE, mMemoryFile.length());
+        mMemoryFile = new MemoryFile("Test File", 0);
+        assertEquals(0, mMemoryFile.length());
 
-        mMemoryFile = new MemoryFile("Test File", Integer.MIN_VALUE);
-        assertEquals(Integer.MIN_VALUE, mMemoryFile.length());
+        try {
+            mMemoryFile = new MemoryFile("Test File", -512);
+            fail();
+        } catch (IOException expected) {
+        }
     }
 
     public void testReadBytes() throws IOException {
diff --git a/tests/tests/os/src/android/os/cts/TaggedPointerTest.java b/tests/tests/os/src/android/os/cts/TaggedPointerTest.java
new file mode 100644
index 0000000..4c619de
--- /dev/null
+++ b/tests/tests/os/src/android/os/cts/TaggedPointerTest.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2014 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 android.os.cts;
+
+
+import android.test.AndroidTestCase;
+
+import android.os.cts.CpuFeatures;
+import android.os.cts.TaggedPointer;
+
+public class TaggedPointerTest extends AndroidTestCase {
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+    }
+
+    public void testHasTaggedPointer() {
+        if (!CpuFeatures.isArm64Cpu()) {
+            return;
+        }
+        assertTrue("Machine does not support tagged pointers", TaggedPointer.hasTaggedPointer());
+    }
+}
diff --git a/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java b/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
old mode 100644
new mode 100755
index d455727..85af555
--- a/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
+++ b/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
@@ -734,6 +734,8 @@
                 new File("/dev/alarm"),      // b/9035217
                 new File("/dev/ashmem"),
                 new File("/dev/binder"),
+                new File("/dev/card0"),       // b/13159510
+                new File("/dev/dri/card0"),   // b/13159510
                 new File("/dev/felica"),     // b/11142586
                 new File("/dev/felica_ant"), // b/11142586
                 new File("/dev/felica_cen"), // b/11142586
@@ -742,7 +744,9 @@
                 new File("/dev/felica_rws"), // b/11142586
                 new File("/dev/felica_uicc"), // b/11142586
                 new File("/dev/full"),
+                new File("/dev/galcore"),
                 new File("/dev/genlock"),    // b/9035217
+                new File("/dev/graphics/galcore"),
                 new File("/dev/ion"),
                 new File("/dev/kgsl-2d0"),   // b/11271533
                 new File("/dev/kgsl-2d1"),   // b/11271533
@@ -753,6 +757,9 @@
                 new File("/dev/log/system"), // b/9035217
                 new File("/dev/mali0"),       // b/9106968
                 new File("/dev/mali"),        // b/11142586
+                new File("/dev/mm_interlock"), // b/12955573
+                new File("/dev/mm_isp"),      // b/12955573
+                new File("/dev/mm_v3d"),      // b/12955573
                 new File("/dev/msm_rotator"), // b/9035217
                 new File("/dev/null"),
                 new File("/dev/nvhost-as-gpu"),
diff --git a/tests/tests/provider/src/android/provider/cts/ContactsProvider2_AccountRemovalTest.java b/tests/tests/provider/src/android/provider/cts/ContactsProvider2_AccountRemovalTest.java
old mode 100644
new mode 100755
index f700220..cdb3546
--- a/tests/tests/provider/src/android/provider/cts/ContactsProvider2_AccountRemovalTest.java
+++ b/tests/tests/provider/src/android/provider/cts/ContactsProvider2_AccountRemovalTest.java
@@ -113,6 +113,7 @@
      */
     public void testAccountRemovalWithMergedContact_doesNotDeleteContactAndTimestampUpdated() {
         mAccountManager.addAccountExplicitly(ACCT_1, null, null);
+        mAccountManager.addAccountExplicitly(ACCT_2, null, null);
         ArrayList<ContactIdPair> idList = createAndAssertMergedContact(ACCT_1, ACCT_2);
         long contactId = idList.get(0).mContactId;
 
@@ -125,6 +126,7 @@
                     "Contact " + contactId + " last updated timestamp has not been updated.");
             SystemClock.sleep(SLEEP_BETWEEN_POLL_MS);
         }
+        mAccountManager.removeAccount(ACCT_2, null, null);
     }
 
     public void testAccountRemovalWithMergedContact_hasDeleteLogsForContacts() {
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_Images_ThumbnailsTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_Images_ThumbnailsTest.java
index 03adad7..3819cff 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_Images_ThumbnailsTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_Images_ThumbnailsTest.java
@@ -30,6 +30,7 @@
 import android.provider.MediaStore;
 import android.provider.MediaStore.Images.Media;
 import android.provider.MediaStore.Images.Thumbnails;
+import android.provider.MediaStore.MediaColumns;
 import android.test.InstrumentationTestCase;
 
 import java.io.File;
@@ -284,4 +285,74 @@
             // expected
         }
     }
+
+    public void testThumbnailOrderedQuery() throws Exception {
+        Bitmap src = BitmapFactory.decodeResource(mContext.getResources(), R.raw.scenery);
+        Uri url[] = new Uri[3];
+        try{
+            for (int i = 0; i < url.length; i++) {
+                url[i] = Uri.parse(Media.insertImage(mContentResolver, src, null, null));
+                long origId = Long.parseLong(url[i].getLastPathSegment());
+                Bitmap foo = MediaStore.Images.Thumbnails.getThumbnail(mContentResolver,
+                        origId, Thumbnails.MICRO_KIND, null);
+                assertNotNull(foo);
+            }
+
+            // remove one of the images, its thumbnail, and the thumbnail cache
+            Cursor c = mContentResolver.query(url[1], null, null, null, null);
+            assertEquals(1, c.getCount());
+            c.moveToFirst();
+            String path = c.getString(c.getColumnIndex(MediaColumns.DATA));
+            long id = c.getLong(c.getColumnIndex(MediaColumns._ID));
+            c.close();
+            assertTrue(new File(path).delete());
+
+            long removedId = Long.parseLong(url[1].getLastPathSegment());
+            long remainingId1 = Long.parseLong(url[0].getLastPathSegment());
+            long remainingId2 = Long.parseLong(url[2].getLastPathSegment());
+            c = mContentResolver.query(
+                    MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI, null,
+                    Thumbnails.IMAGE_ID + "=?", new String[] { Long.toString(removedId) }, null);
+            assertTrue(c.getCount() > 0);  // one or more thumbnail kinds
+            while (c.moveToNext()) {
+                path = c.getString(c.getColumnIndex(MediaColumns.DATA));
+                assertTrue(new File(path).delete());
+            }
+            c.close();
+
+            File thumbdir = new File(path).getParentFile();
+            File[] list = thumbdir.listFiles();
+            for (int i = 0; i < list.length; i++) {
+                if (list[i].getName().startsWith(".thumbdata")) {
+                    assertTrue(list[i].delete());
+                }
+            }
+
+            // check if a thumbnail is still being returned for the image that was removed
+            Bitmap foo = MediaStore.Images.Thumbnails.getThumbnail(mContentResolver,
+                    removedId, Thumbnails.MICRO_KIND, null);
+            assertNull(foo);
+
+            for (String order: new String[] { " ASC", " DESC" }) {
+                c = mContentResolver.query(
+                        MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null, null, null,
+                        MediaColumns._ID + order);
+                while (c.moveToNext()) {
+                    id = c.getLong(c.getColumnIndex(MediaColumns._ID));
+                    foo = MediaStore.Images.Thumbnails.getThumbnail(
+                            mContentResolver, id,
+                            MediaStore.Images.Thumbnails.MICRO_KIND, null);
+                    if (id == removedId) {
+                        assertNull("unexpected bitmap with" + order + " ordering", foo);
+                    } else if (id == remainingId1 || id == remainingId2) {
+                        assertNotNull("missing bitmap with" + order + " ordering", foo);
+                    }
+                }
+                c.close();
+            }
+        } catch (UnsupportedOperationException e) {
+            // the tests will be aborted because the image will be put in sdcard
+            fail("There is no sdcard attached! " + e.getMessage());
+        }
+    }
 }
diff --git a/tests/tests/provider/src/android/provider/cts/contacts/DeletedContactUtil.java b/tests/tests/provider/src/android/provider/cts/contacts/DeletedContactUtil.java
index 692570a..3b05cf9 100644
--- a/tests/tests/provider/src/android/provider/cts/contacts/DeletedContactUtil.java
+++ b/tests/tests/provider/src/android/provider/cts/contacts/DeletedContactUtil.java
@@ -38,8 +38,13 @@
         };
         Uri uri = ContentUris.withAppendedId(URI, contactId);
         Cursor cursor = resolver.query(uri, projection, null, null, null);
-        if (cursor.moveToNext()) {
-            return cursor.getLong(0);
+        if (null != cursor) {
+           long deletedTime = -1;
+           if (cursor.moveToNext()) {
+               deletedTime = cursor.getLong(0);
+               cursor.close();
+               return deletedTime;
+           }
         }
         return CommonDatabaseUtils.NOT_FOUND;
     }
diff --git a/tests/tests/renderscript/Android.mk b/tests/tests/renderscript/Android.mk
index 77bef50..e5ef654 100644
--- a/tests/tests/renderscript/Android.mk
+++ b/tests/tests/renderscript/Android.mk
@@ -29,6 +29,7 @@
 LOCAL_JAVA_LIBRARIES := android.test.runner
 
 LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
+LOCAL_JNI_SHARED_LIBRARIES := libcoremathtestcpp_jni
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
@@ -37,3 +38,4 @@
 LOCAL_SDK_VERSION := current
 
 include $(BUILD_CTS_PACKAGE)
+include $(LOCAL_PATH)/libcoremathtestcpp/Android.mk
diff --git a/tests/tests/renderscript/libcoremathtestcpp/Android.mk b/tests/tests/renderscript/libcoremathtestcpp/Android.mk
new file mode 100644
index 0000000..7ec8671
--- /dev/null
+++ b/tests/tests/renderscript/libcoremathtestcpp/Android.mk
@@ -0,0 +1,31 @@
+# Copyright (C) 2013 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.
+
+#
+# This is the shared library included by the JNI test app.
+#
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+LOCAL_MODULE := libcoremathtestcpp_jni
+LOCAL_MODULE_TAGS := optional
+LOCAL_SRC_FILES := CoreMathTestJni.cpp
+
+LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
+LOCAL_C_INCLUDES += frameworks/rs/cpp
+LOCAL_C_INCLUDES += frameworks/rs
+LOCAL_C_INCLUDES += external/stlport/stlport bionic/ bionic/libstdc++/include
+
+LOCAL_SHARED_LIBRARIES := libdl liblog libRScpp libstlport
+LOCAL_STATIC_LIBRARIES := libcutils
+include $(BUILD_SHARED_LIBRARY)
diff --git a/tests/tests/renderscript/libcoremathtestcpp/CoreMathTestJni.cpp b/tests/tests/renderscript/libcoremathtestcpp/CoreMathTestJni.cpp
new file mode 100644
index 0000000..90c8100
--- /dev/null
+++ b/tests/tests/renderscript/libcoremathtestcpp/CoreMathTestJni.cpp
@@ -0,0 +1,818 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include <jni.h>
+#include <android/log.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <algorithm>
+#include <math.h>
+#include <string>
+
+#include <RenderScript.h>
+
+#define LOG_TAG "rscpptest"
+#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
+#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
+
+using namespace android::RSC;
+
+/* This class helps return multiple values to Java.  To use:
+ * - define a class in Java,
+ * - have the jni method return a jobject,
+ * - create an instance of this class,
+ * - use Set* to fill the fields,
+ * - return getObject() on exit of the JNI method.
+ */
+class JavaStruct {
+private:
+    JNIEnv* mEnv;
+    jclass mClass;
+    jobject mObject;
+
+    /* Returns the id of the named field.  Type is one of "F" (float) or "I" (int).
+     * If there's an error, logs a message and returns 0.
+     */
+    jfieldID GetFieldId(const char* name, const char* type);
+
+public:
+    // Creates an instance of the named Java class.
+    JavaStruct(JNIEnv* env, const std::string& name);
+    // Sets the field of the instance.
+    void SetFloat(const char* name, float value);
+    void SetInt(const char* name, int value);
+    // Returns the instance.
+    jobject getObject() { return mObject; }
+};
+
+JavaStruct::JavaStruct(JNIEnv* env, const std::string& name) : mEnv(env), mClass(0), mObject(0) {
+    /* This creates an instance of the specified static inner class of CoreMathVerifier.
+     * To convert this to return a non-static inner class instead, pass
+     * "(Landroid/renderscript/cts/CoreMathVerifier;)V" instead of "()V" go getMethodID
+     * and pass the parent class as a third argument to NewObject.
+     */
+    std::string fullName = "android/renderscript/cts/CoreMathVerifier$" + name;
+    mClass = env->FindClass(fullName.c_str());
+    if (!mClass) {
+        LOGE("Can't find the Java class %s", name.c_str());
+        return;
+    }
+    jmethodID constructor = env->GetMethodID(mClass, "<init>", "()V");
+    if (!constructor) {
+        LOGE("Can't find the constructor of %s", name.c_str());
+        return;
+    }
+    mObject = env->NewObject(mClass, constructor);
+    if (!mObject) {
+        LOGE("Can't construct a %s", name.c_str());
+    }
+}
+
+void JavaStruct::SetInt(const char* name, int value) {
+    jfieldID fieldId = GetFieldId(name, "I");
+    if (fieldId) {
+        mEnv->SetIntField(mObject, fieldId, value);
+    }
+}
+
+void JavaStruct::SetFloat(const char* name, float value) {
+    jfieldID fieldId = GetFieldId(name, "F");
+    if (fieldId) {
+        mEnv->SetFloatField(mObject, fieldId, value);
+    }
+}
+
+jfieldID JavaStruct::GetFieldId(const char* name, const char* type) {
+    if (!mClass) {
+        return 0;  // We already have logged the error in the constructor.
+    }
+    jfieldID fieldId = mEnv->GetFieldID(mClass, name, type);
+    if (!fieldId) {
+        LOGE("Can't find the field %s", name);
+        return 0;
+    }
+    return fieldId;
+}
+
+/* We provide access to many primitive math functions because:
+ * - not all functions are available in Java, notably gamma and erf,
+ * - Java lacks float version of these functions, so we can compare implementations with
+ *   similar constraints, and
+ * - handling unsigned integers, especially longs, is painful and error prone in Java.
+ */
+
+extern "C" JNIEXPORT jfloat JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_acos(JNIEnv*, jclass, jfloat x) {
+    return acosf(x);
+}
+
+extern "C" JNIEXPORT jfloat JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_acosh(JNIEnv*, jclass, jfloat x) {
+    return acoshf(x);
+}
+
+extern "C" JNIEXPORT jfloat JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_asin(JNIEnv*, jclass, jfloat x) {
+    return asinf(x);
+}
+
+extern "C" JNIEXPORT jfloat JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_asinh(JNIEnv*, jclass, jfloat x) {
+    return asinhf(x);
+}
+
+extern "C" JNIEXPORT jfloat JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_atan(JNIEnv*, jclass, jfloat x) {
+    return atanf(x);
+}
+
+extern "C" JNIEXPORT jfloat JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_atan2(JNIEnv*, jclass, jfloat x, jfloat y) {
+    return atan2f(x, y);
+}
+
+extern "C" JNIEXPORT jfloat JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_atanh(JNIEnv*, jclass, jfloat x) {
+    return atanhf(x);
+}
+
+extern "C" JNIEXPORT jfloat JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_cbrt(JNIEnv*, jclass, jfloat x) {
+    return cbrtf(x);
+}
+
+extern "C" JNIEXPORT jfloat JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_ceil(JNIEnv*, jclass, jfloat x) {
+    return ceilf(x);
+}
+
+extern "C" JNIEXPORT jfloat JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_cos(JNIEnv*, jclass, jfloat x) {
+    return cosf(x);
+}
+
+extern "C" JNIEXPORT jfloat JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_cosh(JNIEnv*, jclass, jfloat x) {
+    return coshf(x);
+}
+
+extern "C" JNIEXPORT jfloat JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_erf(JNIEnv*, jclass, jfloat x) {
+    return erff(x);
+}
+
+extern "C" JNIEXPORT jfloat JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_erfc(JNIEnv*, jclass, jfloat x) {
+    return erfcf(x);
+}
+
+extern "C" JNIEXPORT jfloat JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_exp(JNIEnv*, jclass, jfloat x) {
+    return expf(x);
+}
+
+extern "C" JNIEXPORT jfloat JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_exp10(JNIEnv*, jclass, jfloat x) {
+    return powf(10.0f, x);
+}
+
+extern "C" JNIEXPORT jfloat JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_exp2(JNIEnv*, jclass, jfloat x) {
+    return powf(2.0f, x);
+}
+
+extern "C" JNIEXPORT jfloat JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_expm1(JNIEnv*, jclass, jfloat x) {
+    return expm1f(x);
+}
+
+extern "C" JNIEXPORT jfloat JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_floor(JNIEnv*, jclass, jfloat x) {
+    return floorf(x);
+}
+
+extern "C" JNIEXPORT jobject JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_frexp(JNIEnv* env, jclass, jfloat x) {
+    JavaStruct result(env, "FrexpResult");
+    int exp = 0;
+    result.SetFloat("significand", frexpf(x, &exp));
+    result.SetInt("exponent", exp);
+    return result.getObject();
+}
+
+extern "C" JNIEXPORT jfloat JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_hypot(JNIEnv*, jclass, jfloat x, jfloat y) {
+    return hypotf(x, y);
+}
+
+extern "C" JNIEXPORT jint JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_ilogb(JNIEnv*, jclass, jfloat x) {
+    return ilogbf(x);
+}
+
+extern "C" JNIEXPORT jfloat JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_ldexp(JNIEnv*, jclass, jfloat x, jint exp) {
+    return ldexpf(x, exp);
+}
+
+extern "C" JNIEXPORT jfloat JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_lgamma(JNIEnv*, jclass, jfloat x) {
+    return lgammaf(x);
+}
+
+extern "C" JNIEXPORT jobject JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_lgamma2(JNIEnv* env, jclass, jfloat x) {
+    JavaStruct result(env, "LgammaResult");
+    result.SetFloat("lgamma", lgammaf(x));
+    result.SetInt("gammaSign", signgam);
+    return result.getObject();
+}
+
+extern "C" JNIEXPORT jfloat JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_log(JNIEnv*, jclass, jfloat x) {
+    return logf(x);
+}
+
+extern "C" JNIEXPORT jfloat JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_logb(JNIEnv*, jclass, jfloat x) {
+    return logbf(x);
+}
+
+extern "C" JNIEXPORT jfloat JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_log10(JNIEnv*, jclass, jfloat x) {
+    return log10f(x);
+}
+
+extern "C" JNIEXPORT jfloat JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_log1p(JNIEnv*, jclass, jfloat x) {
+    return log1pf(x);
+}
+
+extern "C" JNIEXPORT jfloat JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_log2(JNIEnv*, jclass, jfloat x) {
+    return log2f(x);
+}
+
+extern "C" JNIEXPORT jbyte JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_maxI8(JNIEnv*, jclass, jbyte x, jbyte y) {
+    return std::max(x, y);
+}
+
+extern "C" JNIEXPORT jbyte JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_maxU8(JNIEnv*, jclass, jbyte x, jbyte y) {
+    return std::max((uint8_t)x, (uint8_t)y);
+}
+
+extern "C" JNIEXPORT jshort JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_maxI16(JNIEnv*, jclass, jshort x, jshort y) {
+    return std::max(x, y);
+}
+
+extern "C" JNIEXPORT jshort JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_maxU16(JNIEnv*, jclass, jshort x, jshort y) {
+    return std::max((uint16_t)x, (uint16_t)y);
+}
+
+extern "C" JNIEXPORT jint JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_maxI32(JNIEnv*, jclass, jint x, jint y) {
+    return std::max(x, y);
+}
+
+extern "C" JNIEXPORT jint JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_maxU32(JNIEnv*, jclass, jint x, jint y) {
+    return std::max((uint32_t)x, (uint32_t)y);
+}
+
+extern "C" JNIEXPORT jlong JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_maxI64(JNIEnv*, jclass, jlong x, jlong y) {
+    return std::max(x, y);
+}
+
+extern "C" JNIEXPORT jlong JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_maxU64(JNIEnv*, jclass, jlong x, jlong y) {
+    return std::max((uint64_t)x, (uint64_t)y);
+}
+
+extern "C" JNIEXPORT jbyte JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_minI8(JNIEnv*, jclass, jbyte x, jbyte y) {
+    return std::min(x, y);
+}
+
+extern "C" JNIEXPORT jbyte JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_minU8(JNIEnv*, jclass, jbyte x, jbyte y) {
+    return std::min((uint8_t)x, (uint8_t)y);
+}
+
+extern "C" JNIEXPORT jshort JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_minI16(JNIEnv*, jclass, jshort x, jshort y) {
+    return std::min(x, y);
+}
+
+extern "C" JNIEXPORT jshort JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_minU16(JNIEnv*, jclass, jshort x, jshort y) {
+    return std::min((uint16_t)x, (uint16_t)y);
+}
+
+extern "C" JNIEXPORT jint JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_minI32(JNIEnv*, jclass, jint x, jint y) {
+    return std::min(x, y);
+}
+
+extern "C" JNIEXPORT jint JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_minU32(JNIEnv*, jclass, jint x, jint y) {
+    return std::min((uint32_t)x, (uint32_t)y);
+}
+
+extern "C" JNIEXPORT jlong JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_minI64(JNIEnv*, jclass, jlong x, jlong y) {
+    return std::min(x, y);
+}
+
+extern "C" JNIEXPORT jlong JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_minU64(JNIEnv*, jclass, jlong x, jlong y) {
+    return std::min((uint64_t)x, (uint64_t)y);
+}
+
+extern "C" JNIEXPORT jfloat JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_pow(JNIEnv*, jclass, jfloat x, jfloat y) {
+    return powf(x, y);
+}
+
+extern "C" JNIEXPORT jobject JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_remquo(JNIEnv* env, jclass, jfloat numerator,
+                                                      jfloat denominator) {
+    JavaStruct result(env, "RemquoResult");
+    int quotient = 0.0;
+    result.SetFloat("remainder", remquof(numerator, denominator, &quotient));
+    result.SetInt("quotient", quotient);
+    return result.getObject();
+}
+
+extern "C" JNIEXPORT jfloat JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_rint(JNIEnv*, jclass, jfloat x) {
+    return rintf(x);
+}
+
+extern "C" JNIEXPORT jfloat JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_round(JNIEnv*, jclass, jfloat x) {
+    return roundf(x);
+}
+
+extern "C" JNIEXPORT jfloat JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_sin(JNIEnv*, jclass, jfloat x) {
+    return sinf(x);
+}
+
+extern "C" JNIEXPORT jfloat JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_sinh(JNIEnv*, jclass, jfloat x) {
+    return sinhf(x);
+}
+
+extern "C" JNIEXPORT jfloat JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_sqrt(JNIEnv*, jclass, jfloat x) {
+    return sqrtf(x);
+}
+
+extern "C" JNIEXPORT jfloat JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_tan(JNIEnv*, jclass, jfloat x) {
+    return tanf(x);
+}
+
+extern "C" JNIEXPORT jfloat JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_tanh(JNIEnv*, jclass, jfloat x) {
+    return tanhf(x);
+}
+
+extern "C" JNIEXPORT jfloat JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_tgamma(JNIEnv*, jclass, jfloat x) {
+    return tgammaf(x);
+}
+
+extern "C" JNIEXPORT jfloat JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_trunc(JNIEnv*, jclass, jfloat x) {
+    return truncf(x);
+}
+
+extern "C" JNIEXPORT jbyte JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertCharToChar(JNIEnv*, jclass, jbyte x) {
+    return (jbyte)(int8_t)(int8_t)x;
+}
+extern "C" JNIEXPORT jbyte JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertCharToUchar(JNIEnv*, jclass, jbyte x) {
+    return (jbyte)(uint8_t)(int8_t)x;
+}
+extern "C" JNIEXPORT jshort JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertCharToShort(JNIEnv*, jclass, jbyte x) {
+    return (jshort)(int16_t)(int8_t)x;
+}
+extern "C" JNIEXPORT jshort JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertCharToUshort(JNIEnv*, jclass, jbyte x) {
+    return (jshort)(uint16_t)(int8_t)x;
+}
+extern "C" JNIEXPORT jint JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertCharToInt(JNIEnv*, jclass, jbyte x) {
+    return (jint)(int32_t)(int8_t)x;
+}
+extern "C" JNIEXPORT jint JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertCharToUint(JNIEnv*, jclass, jbyte x) {
+    return (jint)(uint32_t)(int8_t)x;
+}
+extern "C" JNIEXPORT jlong JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertCharToLong(JNIEnv*, jclass, jbyte x) {
+    return (jlong)(int64_t)(int8_t)x;
+}
+extern "C" JNIEXPORT jlong JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertCharToUlong(JNIEnv*, jclass, jbyte x) {
+    return (jlong)(uint64_t)(int8_t)x;
+}
+extern "C" JNIEXPORT jfloat JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertCharToFloat(JNIEnv*, jclass, jbyte x) {
+    return (jfloat)(float)(int8_t)x;
+}
+extern "C" JNIEXPORT jdouble JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertCharToDouble(JNIEnv*, jclass, jbyte x) {
+    return (jdouble)(double)(int8_t)x;
+}
+
+extern "C" JNIEXPORT jbyte JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertUcharToChar(JNIEnv*, jclass, jbyte x) {
+    return (jbyte)(int8_t)(uint8_t)x;
+}
+extern "C" JNIEXPORT jbyte JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertUcharToUchar(JNIEnv*, jclass, jbyte x) {
+    return (jbyte)(uint8_t)(uint8_t)x;
+}
+extern "C" JNIEXPORT jshort JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertUcharToShort(JNIEnv*, jclass, jbyte x) {
+    return (jshort)(int16_t)(uint8_t)x;
+}
+extern "C" JNIEXPORT jshort JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertUcharToUshort(JNIEnv*, jclass, jbyte x) {
+    return (jshort)(uint16_t)(uint8_t)x;
+}
+extern "C" JNIEXPORT jint JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertUcharToInt(JNIEnv*, jclass, jbyte x) {
+    return (jint)(int32_t)(uint8_t)x;
+}
+extern "C" JNIEXPORT jint JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertUcharToUint(JNIEnv*, jclass, jbyte x) {
+    return (jint)(uint32_t)(uint8_t)x;
+}
+extern "C" JNIEXPORT jlong JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertUcharToLong(JNIEnv*, jclass, jbyte x) {
+    return (jlong)(int64_t)(uint8_t)x;
+}
+extern "C" JNIEXPORT jlong JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertUcharToUlong(JNIEnv*, jclass, jbyte x) {
+    return (jlong)(uint64_t)(uint8_t)x;
+}
+extern "C" JNIEXPORT jfloat JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertUcharToFloat(JNIEnv*, jclass, jbyte x) {
+    return (jfloat)(float)(uint8_t)x;
+}
+extern "C" JNIEXPORT jdouble JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertUcharToDouble(JNIEnv*, jclass, jbyte x) {
+    return (jdouble)(double)(uint8_t)x;
+}
+
+extern "C" JNIEXPORT jbyte JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertShortToChar(JNIEnv*, jclass, jshort x) {
+    return (jbyte)(int8_t)(int16_t)x;
+}
+extern "C" JNIEXPORT jbyte JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertShortToUchar(JNIEnv*, jclass, jshort x) {
+    return (jbyte)(uint8_t)(int16_t)x;
+}
+extern "C" JNIEXPORT jshort JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertShortToShort(JNIEnv*, jclass, jshort x) {
+    return (jshort)(int16_t)(int16_t)x;
+}
+extern "C" JNIEXPORT jshort JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertShortToUshort(JNIEnv*, jclass, jshort x) {
+    return (jshort)(uint16_t)(int16_t)x;
+}
+extern "C" JNIEXPORT jint JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertShortToInt(JNIEnv*, jclass, jshort x) {
+    return (jint)(int32_t)(int16_t)x;
+}
+extern "C" JNIEXPORT jint JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertShortToUint(JNIEnv*, jclass, jshort x) {
+    return (jint)(uint32_t)(int16_t)x;
+}
+extern "C" JNIEXPORT jlong JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertShortToLong(JNIEnv*, jclass, jshort x) {
+    return (jlong)(int64_t)(int16_t)x;
+}
+extern "C" JNIEXPORT jlong JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertShortToUlong(JNIEnv*, jclass, jshort x) {
+    return (jlong)(uint64_t)(int16_t)x;
+}
+extern "C" JNIEXPORT jfloat JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertShortToFloat(JNIEnv*, jclass, jshort x) {
+    return (jfloat)(float)(int16_t)x;
+}
+extern "C" JNIEXPORT jdouble JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertShortToDouble(JNIEnv*, jclass, jshort x) {
+    return (jdouble)(double)(int16_t)x;
+}
+
+extern "C" JNIEXPORT jbyte JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertUshortToChar(JNIEnv*, jclass, jshort x) {
+    return (jbyte)(int8_t)(uint16_t)x;
+}
+extern "C" JNIEXPORT jbyte JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertUshortToUchar(JNIEnv*, jclass, jshort x) {
+    return (jbyte)(uint8_t)(uint16_t)x;
+}
+extern "C" JNIEXPORT jshort JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertUshortToShort(JNIEnv*, jclass, jshort x) {
+    return (jshort)(int16_t)(uint16_t)x;
+}
+extern "C" JNIEXPORT jshort JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertUshortToUshort(JNIEnv*, jclass, jshort x) {
+    return (jshort)(uint16_t)(uint16_t)x;
+}
+extern "C" JNIEXPORT jint JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertUshortToInt(JNIEnv*, jclass, jshort x) {
+    return (jint)(int32_t)(uint16_t)x;
+}
+extern "C" JNIEXPORT jint JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertUshortToUint(JNIEnv*, jclass, jshort x) {
+    return (jint)(uint32_t)(uint16_t)x;
+}
+extern "C" JNIEXPORT jlong JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertUshortToLong(JNIEnv*, jclass, jshort x) {
+    return (jlong)(int64_t)(uint16_t)x;
+}
+extern "C" JNIEXPORT jlong JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertUshortToUlong(JNIEnv*, jclass, jshort x) {
+    return (jlong)(uint64_t)(uint16_t)x;
+}
+extern "C" JNIEXPORT jfloat JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertUshortToFloat(JNIEnv*, jclass, jshort x) {
+    return (jfloat)(float)(uint16_t)x;
+}
+extern "C" JNIEXPORT jdouble JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertUshortToDouble(JNIEnv*, jclass, jshort x) {
+    return (jdouble)(double)(uint16_t)x;
+}
+
+extern "C" JNIEXPORT jbyte JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertIntToChar(JNIEnv*, jclass, jint x) {
+    return (jbyte)(int8_t)(int32_t)x;
+}
+extern "C" JNIEXPORT jbyte JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertIntToUchar(JNIEnv*, jclass, jint x) {
+    return (jbyte)(uint8_t)(int32_t)x;
+}
+extern "C" JNIEXPORT jshort JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertIntToShort(JNIEnv*, jclass, jint x) {
+    return (jshort)(int16_t)(int32_t)x;
+}
+extern "C" JNIEXPORT jshort JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertIntToUshort(JNIEnv*, jclass, jint x) {
+    return (jshort)(uint16_t)(int32_t)x;
+}
+extern "C" JNIEXPORT jint JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertIntToInt(JNIEnv*, jclass, jint x) {
+    return (jint)(int32_t)(int32_t)x;
+}
+extern "C" JNIEXPORT jint JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertIntToUint(JNIEnv*, jclass, jint x) {
+    return (jint)(uint32_t)(int32_t)x;
+}
+extern "C" JNIEXPORT jlong JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertIntToLong(JNIEnv*, jclass, jint x) {
+    return (jlong)(int64_t)(int32_t)x;
+}
+extern "C" JNIEXPORT jlong JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertIntToUlong(JNIEnv*, jclass, jint x) {
+    return (jlong)(uint64_t)(int32_t)x;
+}
+extern "C" JNIEXPORT jfloat JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertIntToFloat(JNIEnv*, jclass, jint x) {
+    return (jfloat)(float)(int32_t)x;
+}
+extern "C" JNIEXPORT jdouble JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertIntToDouble(JNIEnv*, jclass, jint x) {
+    return (jdouble)(double)(int32_t)x;
+}
+
+extern "C" JNIEXPORT jbyte JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertUintToChar(JNIEnv*, jclass, jint x) {
+    return (jbyte)(int8_t)(uint32_t)x;
+}
+extern "C" JNIEXPORT jbyte JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertUintToUchar(JNIEnv*, jclass, jint x) {
+    return (jbyte)(uint8_t)(uint32_t)x;
+}
+extern "C" JNIEXPORT jshort JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertUintToShort(JNIEnv*, jclass, jint x) {
+    return (jshort)(int16_t)(uint32_t)x;
+}
+extern "C" JNIEXPORT jshort JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertUintToUshort(JNIEnv*, jclass, jint x) {
+    return (jshort)(uint16_t)(uint32_t)x;
+}
+extern "C" JNIEXPORT jint JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertUintToInt(JNIEnv*, jclass, jint x) {
+    return (jint)(int32_t)(uint32_t)x;
+}
+extern "C" JNIEXPORT jint JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertUintToUint(JNIEnv*, jclass, jint x) {
+    return (jint)(uint32_t)(uint32_t)x;
+}
+extern "C" JNIEXPORT jlong JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertUintToLong(JNIEnv*, jclass, jint x) {
+    return (jlong)(int64_t)(uint32_t)x;
+}
+extern "C" JNIEXPORT jlong JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertUintToUlong(JNIEnv*, jclass, jint x) {
+    return (jlong)(uint64_t)(uint32_t)x;
+}
+extern "C" JNIEXPORT jfloat JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertUintToFloat(JNIEnv*, jclass, jint x) {
+    return (jfloat)(float)(uint32_t)x;
+}
+extern "C" JNIEXPORT jdouble JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertUintToDouble(JNIEnv*, jclass, jint x) {
+    return (jdouble)(double)(uint32_t)x;
+}
+
+extern "C" JNIEXPORT jbyte JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertLongToChar(JNIEnv*, jclass, jlong x) {
+    return (jbyte)(int8_t)(int64_t)x;
+}
+extern "C" JNIEXPORT jbyte JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertLongToUchar(JNIEnv*, jclass, jlong x) {
+    return (jbyte)(uint8_t)(int64_t)x;
+}
+extern "C" JNIEXPORT jshort JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertLongToShort(JNIEnv*, jclass, jlong x) {
+    return (jshort)(int16_t)(int64_t)x;
+}
+extern "C" JNIEXPORT jshort JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertLongToUshort(JNIEnv*, jclass, jlong x) {
+    return (jshort)(uint16_t)(int64_t)x;
+}
+extern "C" JNIEXPORT jint JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertLongToInt(JNIEnv*, jclass, jlong x) {
+    return (jint)(int32_t)(int64_t)x;
+}
+extern "C" JNIEXPORT jint JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertLongToUint(JNIEnv*, jclass, jlong x) {
+    return (jint)(uint32_t)(int64_t)x;
+}
+extern "C" JNIEXPORT jlong JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertLongToLong(JNIEnv*, jclass, jlong x) {
+    return (jlong)(int64_t)(int64_t)x;
+}
+extern "C" JNIEXPORT jlong JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertLongToUlong(JNIEnv*, jclass, jlong x) {
+    return (jlong)(uint64_t)(int64_t)x;
+}
+extern "C" JNIEXPORT jfloat JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertLongToFloat(JNIEnv*, jclass, jlong x) {
+    return (jfloat)(float)(int64_t)x;
+}
+extern "C" JNIEXPORT jdouble JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertLongToDouble(JNIEnv*, jclass, jlong x) {
+    return (jdouble)(double)(int64_t)x;
+}
+
+extern "C" JNIEXPORT jbyte JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertUlongToChar(JNIEnv*, jclass, jlong x) {
+    return (jbyte)(int8_t)(uint64_t)x;
+}
+extern "C" JNIEXPORT jbyte JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertUlongToUchar(JNIEnv*, jclass, jlong x) {
+    return (jbyte)(uint8_t)(uint64_t)x;
+}
+extern "C" JNIEXPORT jshort JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertUlongToShort(JNIEnv*, jclass, jlong x) {
+    return (jshort)(int16_t)(uint64_t)x;
+}
+extern "C" JNIEXPORT jshort JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertUlongToUshort(JNIEnv*, jclass, jlong x) {
+    return (jshort)(uint16_t)(uint64_t)x;
+}
+extern "C" JNIEXPORT jint JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertUlongToInt(JNIEnv*, jclass, jlong x) {
+    return (jint)(int32_t)(uint64_t)x;
+}
+extern "C" JNIEXPORT jint JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertUlongToUint(JNIEnv*, jclass, jlong x) {
+    return (jint)(uint32_t)(uint64_t)x;
+}
+extern "C" JNIEXPORT jlong JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertUlongToLong(JNIEnv*, jclass, jlong x) {
+    return (jlong)(int64_t)(uint64_t)x;
+}
+extern "C" JNIEXPORT jlong JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertUlongToUlong(JNIEnv*, jclass, jlong x) {
+    return (jlong)(uint64_t)(uint64_t)x;
+}
+extern "C" JNIEXPORT jfloat JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertUlongToFloat(JNIEnv*, jclass, jlong x) {
+    return (jfloat)(float)(uint64_t)x;
+}
+extern "C" JNIEXPORT jdouble JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertUlongToDouble(JNIEnv*, jclass, jlong x) {
+    return (jdouble)(double)(uint64_t)x;
+}
+
+extern "C" JNIEXPORT jbyte JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertFloatToChar(JNIEnv*, jclass, jfloat x) {
+    return (jbyte)(int8_t)(float)x;
+}
+extern "C" JNIEXPORT jbyte JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertFloatToUchar(JNIEnv*, jclass, jfloat x) {
+    return (jbyte)(uint8_t)(float)x;
+}
+extern "C" JNIEXPORT jshort JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertFloatToShort(JNIEnv*, jclass, jfloat x) {
+    return (jshort)(int16_t)(float)x;
+}
+extern "C" JNIEXPORT jshort JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertFloatToUshort(JNIEnv*, jclass, jfloat x) {
+    return (jshort)(uint16_t)(float)x;
+}
+extern "C" JNIEXPORT jint JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertFloatToInt(JNIEnv*, jclass, jfloat x) {
+    return (jint)(int32_t)(float)x;
+}
+extern "C" JNIEXPORT jint JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertFloatToUint(JNIEnv*, jclass, jfloat x) {
+    return (jint)(uint32_t)(float)x;
+}
+extern "C" JNIEXPORT jlong JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertFloatToLong(JNIEnv*, jclass, jfloat x) {
+    return (jlong)(int64_t)(float)x;
+}
+extern "C" JNIEXPORT jlong JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertFloatToUlong(JNIEnv*, jclass, jfloat x) {
+    return (jlong)(uint64_t)(float)x;
+}
+extern "C" JNIEXPORT jfloat JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertFloatToFloat(JNIEnv*, jclass, jfloat x) {
+    return (jfloat)(float)(float)x;
+}
+extern "C" JNIEXPORT jdouble JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertFloatToDouble(JNIEnv*, jclass, jfloat x) {
+    return (jdouble)(double)(float)x;
+}
+
+extern "C" JNIEXPORT jbyte JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertDoubleToChar(JNIEnv*, jclass, jdouble x) {
+    return (jbyte)(int8_t)(double)x;
+}
+extern "C" JNIEXPORT jbyte JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertDoubleToUchar(JNIEnv*, jclass, jdouble x) {
+    return (jbyte)(uint8_t)(double)x;
+}
+extern "C" JNIEXPORT jshort JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertDoubleToShort(JNIEnv*, jclass, jdouble x) {
+    return (jshort)(int16_t)(double)x;
+}
+extern "C" JNIEXPORT jshort JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertDoubleToUshort(JNIEnv*, jclass, jdouble x) {
+    return (jshort)(uint16_t)(double)x;
+}
+extern "C" JNIEXPORT jint JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertDoubleToInt(JNIEnv*, jclass, jdouble x) {
+    return (jint)(int32_t)(double)x;
+}
+extern "C" JNIEXPORT jint JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertDoubleToUint(JNIEnv*, jclass, jdouble x) {
+    return (jint)(uint32_t)(double)x;
+}
+extern "C" JNIEXPORT jlong JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertDoubleToLong(JNIEnv*, jclass, jdouble x) {
+    return (jlong)(int64_t)(double)x;
+}
+extern "C" JNIEXPORT jlong JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertDoubleToUlong(JNIEnv*, jclass, jdouble x) {
+    return (jlong)(uint64_t)(double)x;
+}
+extern "C" JNIEXPORT jfloat JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertDoubleToFloat(JNIEnv*, jclass, jdouble x) {
+    return (jfloat)(float)(double)x;
+}
+extern "C" JNIEXPORT jdouble JNICALL
+Java_android_renderscript_cts_CoreMathVerifier_convertDoubleToDouble(JNIEnv*, jclass, jdouble x) {
+    return (jdouble)(double)(double)x;
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/AcosPiTest.java b/tests/tests/renderscript/src/android/renderscript/cts/AcosPiTest.java
deleted file mode 100644
index 9d0bc7d..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/AcosPiTest.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * 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 android.renderscript.cts;
-
-import com.android.cts.stub.R;
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-
-public class AcosPiTest extends RSBaseCompute {
-    private ScriptC_acospi_f32 script_f32;
-    private ScriptC_acospi_f32_relaxed script_f32_relaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script_f32 = new ScriptC_acospi_f32(mRS);
-        script_f32_relaxed = new ScriptC_acospi_f32_relaxed(mRS);
-    }
-
-    @Override
-    public void forEach(int testId, Allocation mIn, Allocation mOut) throws RSRuntimeException {
-        switch (testId) {
-        case TEST_F32:
-            script_f32.forEach_acospi_f32_1(mIn, mOut);
-            break;
-        case TEST_F32_2:
-            script_f32.forEach_acospi_f32_2(mIn, mOut);
-            break;
-        case TEST_F32_3:
-            script_f32.forEach_acospi_f32_3(mIn, mOut);
-            break;
-        case TEST_F32_4:
-            script_f32.forEach_acospi_f32_4(mIn, mOut);
-            break;
-
-        case TEST_RELAXED_F32:
-            script_f32_relaxed.forEach_acospi_f32_1(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_2:
-            script_f32_relaxed.forEach_acospi_f32_2(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_3:
-            script_f32_relaxed.forEach_acospi_f32_3(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_4:
-            script_f32_relaxed.forEach_acospi_f32_4(mIn, mOut);
-            break;
-        }
-    }
-
-    @Override
-    protected float[] getRefArray(float[] in, int input_size, int stride, int skip) {
-        float[] ref = new float[input_size * stride];
-        for (int i = 0; i < input_size; i++) {
-            for (int j = 0; j < stride - skip; j++) {
-                int idx= i * stride + j;
-                int idxRef = i * (stride - skip) + j;
-                ref[idxRef] = (float)(Math.acos((double)in[idx])/Math.PI);
-            }
-        }
-        return ref;
-    }
-
-    public void testAcosPiF32() {
-        doF32(0xe1, 5);
-    }
-
-    public void testAcosPiF32_relaxed() {
-        doF32_relaxed(0xe1, 128);
-    }
-
-    public void testAcosPiF32_2() {
-        doF32_2(0xa123, 5);
-    }
-
-    public void testAcosPiF32_2_relaxed() {
-        doF32_2_relaxed(0xa123, 128);
-    }
-
-    public void testAcosPiF32_3() {
-        doF32_3(0x123, 5);
-    }
-
-    public void testAcosPiF32_3_relaxed() {
-        doF32_3_relaxed(0x123, 128);
-    }
-
-    public void testAcosPiF32_4() {
-        doF32_4(0x123ef, 5);
-
-    }
-    public void testAcosPiF32_4_relaxed() {
-        doF32_4_relaxed(0x123ef, 128);
-    }
-
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/AcosTest.java b/tests/tests/renderscript/src/android/renderscript/cts/AcosTest.java
deleted file mode 100644
index d540c60..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/AcosTest.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * 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 android.renderscript.cts;
-
-import com.android.cts.stub.R;
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-
-public class AcosTest extends RSBaseCompute {
-    private ScriptC_acos_f32 script_f32;
-    private ScriptC_acos_f32_relaxed script_f32_relaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script_f32 = new ScriptC_acos_f32(mRS);
-        script_f32_relaxed = new ScriptC_acos_f32_relaxed(mRS);
-    }
-
-    @Override
-    public void forEach(int testId, Allocation mIn, Allocation mOut) throws RSRuntimeException {
-        switch (testId) {
-        case TEST_F32:
-            script_f32.forEach_acos_f32_1(mIn, mOut);
-            break;
-        case TEST_F32_2:
-            script_f32.forEach_acos_f32_2(mIn, mOut);
-            break;
-        case TEST_F32_3:
-            script_f32.forEach_acos_f32_3(mIn, mOut);
-            break;
-        case TEST_F32_4:
-            script_f32.forEach_acos_f32_4(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32:
-            script_f32.forEach_acos_f32_1(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_2:
-            script_f32.forEach_acos_f32_2(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_3:
-            script_f32.forEach_acos_f32_3(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_4:
-            script_f32.forEach_acos_f32_4(mIn, mOut);
-            break;
-
-        }
-    }
-
-    @Override
-    protected float[] getRefArray(float[] in, int input_size, int stride, int skip) {
-        float[] ref = new float[input_size * stride];
-        for (int i = 0; i < input_size; i++) {
-            for (int j = 0; j < stride - skip; j++) {
-                int idx= i * stride + j;
-                int idxRef = i * (stride - skip) + j;
-                ref[idxRef] = (float)(Math.acos((double)in[idx]));
-            }
-        }
-        return ref;
-    }
-
-    public void testAcosF32() {
-        doF32(0x123e, 4);
-    }
-
-    public void testAcosF32_2() {
-        doF32_2(0x1e, 4);
-    }
-
-    public void testAcosF32_3() {
-        doF32_3(0xeaf, 4);
-    }
-
-    public void testAcosF32_4() {
-        doF32_4(0x123, 4);
-    }
-
-    public void testAcosF32_relaxed() {
-        doF32_relaxed(0x123e, 128);
-    }
-
-    public void testAcosF32_2_relaxed() {
-        doF32_2_relaxed(0x1e, 128);
-    }
-
-    public void testAcosF32_3_relaxed() {
-        doF32_3_relaxed(0xeaf, 128);
-    }
-
-    public void testAcosF32_4_relaxed() {
-        doF32_4_relaxed(0x123, 128);
-    }
-
-
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/AcoshTest.java b/tests/tests/renderscript/src/android/renderscript/cts/AcoshTest.java
deleted file mode 100644
index 5947066..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/AcoshTest.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * 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 android.renderscript.cts;
-
-import com.android.cts.stub.R;
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-
-public class AcoshTest extends RSBaseCompute {
-    private ScriptC_acosh_f32 script_f32;
-    private ScriptC_acosh_f32_relaxed script_f32_relaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script_f32 = new ScriptC_acosh_f32(mRS);
-        script_f32_relaxed = new ScriptC_acosh_f32_relaxed(mRS);
-    }
-
-    @Override
-    public void forEach(int testId, Allocation mIn, Allocation mOut) throws RSRuntimeException {
-        switch (testId) {
-        case TEST_F32:
-            script_f32.forEach_acosh_f32_1(mIn, mOut);
-            break;
-        case TEST_F32_2:
-            script_f32.forEach_acosh_f32_2(mIn, mOut);
-            break;
-        case TEST_F32_3:
-            script_f32.forEach_acosh_f32_3(mIn, mOut);
-            break;
-        case TEST_F32_4:
-            script_f32.forEach_acosh_f32_4(mIn, mOut);
-            break;
-
-        case TEST_RELAXED_F32:
-            script_f32_relaxed.forEach_acosh_f32_1(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_2:
-            script_f32_relaxed.forEach_acosh_f32_2(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_3:
-            script_f32_relaxed.forEach_acosh_f32_3(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_4:
-            script_f32_relaxed.forEach_acosh_f32_4(mIn, mOut);
-            break;
-        }
-    }
-
-    @Override
-    protected float[] getRefArray(float[] in, int input_size, int stride, int skip) {
-        float[] ref = new float[input_size * stride];
-        for (int i = 0; i < input_size; i++) {
-            for (int j = 0; j < stride - skip; j++) {
-                int idx= i * stride + j;
-                int idxRef = i * (stride - skip) + j;
-                double x = (double)in[idx];
-                ref[idxRef] = (float)(2*Math.log(Math.sqrt((x+1)/2) + Math.sqrt((x-1)/2)));
-            }
-        }
-        return ref;
-    }
-
-    public void testAcoshF32() {
-        doF32(0x12345678, 4);
-    }
-
-    public void testAcoshF32_relaxed() {
-        doF32_relaxed(0x12345678, 4);
-    }
-
-    public void testAcoshF32_2() {
-        doF32_2(0x1234ac, 4);
-    }
-
-    public void testAcoshF32_2_relaxed() {
-        doF32_2_relaxed(0x1234ac, 4);
-    }
-
-    public void testAcoshF32_3() {
-        doF32_3(0x123fc78, 4);
-    }
-
-    public void testAcoshF32_3_relaxed() {
-        doF32_3_relaxed(0x123fc78, 4);
-    }
-
-    public void testAcoshF32_4() {
-        doF32_4(0x12def8, 4);
-
-    }
-    public void testAcoshF32_4_relaxed() {
-        doF32_4_relaxed(0x12def8, 4);
-    }
-
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/AsinPiTest.java b/tests/tests/renderscript/src/android/renderscript/cts/AsinPiTest.java
deleted file mode 100644
index 64a001e..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/AsinPiTest.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * 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 android.renderscript.cts;
-
-import com.android.cts.stub.R;
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-
-public class AsinPiTest extends RSBaseCompute {
-    private ScriptC_asinpi_f32 script_f32;
-    private ScriptC_asinpi_f32_relaxed script_f32_relaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script_f32 = new ScriptC_asinpi_f32(mRS);
-        script_f32_relaxed = new ScriptC_asinpi_f32_relaxed(mRS);
-    }
-
-    @Override
-    public void forEach(int testId, Allocation mIn, Allocation mOut) throws RSRuntimeException {
-        switch (testId) {
-        case TEST_F32:
-            script_f32.forEach_asinpi_f32_1(mIn, mOut);
-            break;
-        case TEST_F32_2:
-            script_f32.forEach_asinpi_f32_2(mIn, mOut);
-            break;
-        case TEST_F32_3:
-            script_f32.forEach_asinpi_f32_3(mIn, mOut);
-            break;
-        case TEST_F32_4:
-            script_f32.forEach_asinpi_f32_4(mIn, mOut);
-            break;
-
-        case TEST_RELAXED_F32:
-            script_f32_relaxed.forEach_asinpi_f32_1(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_2:
-            script_f32_relaxed.forEach_asinpi_f32_2(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_3:
-            script_f32_relaxed.forEach_asinpi_f32_3(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_4:
-            script_f32_relaxed.forEach_asinpi_f32_4(mIn, mOut);
-            break;
-        }
-    }
-
-    @Override
-    protected float[] getRefArray(float[] in, int input_size, int stride, int skip) {
-        float[] ref = new float[input_size * stride];
-        for (int i = 0; i < input_size; i++) {
-            for (int j = 0; j < stride - skip; j++) {
-                int idx= i * stride + j;
-                int idxRef = i * (stride - skip) + j;
-                ref[idxRef] = (float)(Math.asin((double)in[idx])/Math.PI);
-            }
-        }
-        return ref;
-    }
-
-    public void testAsinPiF32() {
-        doF32(0xa, 5);
-    }
-
-    public void testAsinPiF32_relaxed() {
-        doF32_relaxed(0xa, 5);
-    }
-
-    public void testAsinPiF32_2() {
-        doF32_2(0xe, 5);
-    }
-
-    public void testAsinPiF32_2_relaxed() {
-        doF32_2_relaxed(0xe, 5);
-    }
-
-    public void testAsinPiF32_3() {
-        doF32_3(0x1234, 5);
-    }
-
-    public void testAsinPiF32_3_relaxed() {
-        doF32_3_relaxed(0x1234, 5);
-    }
-
-    public void testAsinPiF32_4() {
-        doF32_4(0xaf, 5);
-
-    }
-    public void testAsinPiF32_4_relaxed() {
-        doF32_4_relaxed(0xaf, 5);
-    }
-
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/AsinTest.java b/tests/tests/renderscript/src/android/renderscript/cts/AsinTest.java
deleted file mode 100644
index 7f3c367..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/AsinTest.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * 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 android.renderscript.cts;
-
-import com.android.cts.stub.R;
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-
-public class AsinTest extends RSBaseCompute {
-    private ScriptC_asin_f32 script_f32;
-    private ScriptC_asin_f32_relaxed script_f32_relaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script_f32 = new ScriptC_asin_f32(mRS);
-        script_f32_relaxed = new ScriptC_asin_f32_relaxed(mRS);
-    }
-
-    @Override
-    public void forEach(int testId, Allocation mIn, Allocation mOut) throws RSRuntimeException {
-        switch (testId) {
-        case TEST_F32:
-            script_f32.forEach_asin_f32_1(mIn, mOut);
-            break;
-        case TEST_F32_2:
-            script_f32.forEach_asin_f32_2(mIn, mOut);
-            break;
-        case TEST_F32_3:
-            script_f32.forEach_asin_f32_3(mIn, mOut);
-            break;
-        case TEST_F32_4:
-            script_f32.forEach_asin_f32_4(mIn, mOut);
-            break;
-
-        case TEST_RELAXED_F32:
-            script_f32_relaxed.forEach_asin_f32_1(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_2:
-            script_f32_relaxed.forEach_asin_f32_2(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_3:
-            script_f32_relaxed.forEach_asin_f32_3(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_4:
-            script_f32_relaxed.forEach_asin_f32_4(mIn, mOut);
-            break;
-        }
-    }
-
-    @Override
-    protected float[] getRefArray(float[] in, int input_size, int stride, int skip) {
-        float[] ref = new float[input_size * stride];
-        for (int i = 0; i < input_size; i++) {
-            for (int j = 0; j < stride - skip; j++) {
-                int idx= i * stride + j;
-                int idxRef = i * (stride - skip) + j;
-                ref[idxRef] = (float)(Math.asin((double)in[idx]));
-            }
-        }
-        return ref;
-    }
-
-    public void testAsinF32() {
-        doF32(0x12efa, 4);
-    }
-
-    public void testAsinF32_relaxed() {
-        doF32_relaxed(0x12efa, 128);
-    }
-
-    public void testAsinF32_2() {
-        doF32_2(0x34ef, 4);
-    }
-
-    public void testAsinF32_2_relaxed() {
-        doF32_2_relaxed(0x34ef, 128);
-    }
-
-    public void testAsinF32_3() {
-        doF32_3(0xae31, 4);
-    }
-
-    public void testAsinF32_3_relaxed() {
-        doF32_3_relaxed(0xae31, 128);
-    }
-
-    public void testAsinF32_4() {
-        doF32_4(0x341, 4);
-
-    }
-    public void testAsinF32_4_relaxed() {
-        doF32_4_relaxed(0x341, 128);
-    }
-
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/AsinhTest.java b/tests/tests/renderscript/src/android/renderscript/cts/AsinhTest.java
deleted file mode 100644
index e0204d2..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/AsinhTest.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * 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 android.renderscript.cts;
-
-import com.android.cts.stub.R;
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-
-public class AsinhTest extends RSBaseCompute {
-    private ScriptC_asinh_f32 script_f32;
-    private ScriptC_asinh_f32_relaxed script_f32_relaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script_f32 = new ScriptC_asinh_f32(mRS);
-        script_f32_relaxed = new ScriptC_asinh_f32_relaxed(mRS);
-    }
-
-    @Override
-    public void forEach(int testId, Allocation mIn, Allocation mOut) throws RSRuntimeException {
-        switch (testId) {
-        case TEST_F32:
-            script_f32.forEach_asinh_f32_1(mIn, mOut);
-            break;
-        case TEST_F32_2:
-            script_f32.forEach_asinh_f32_2(mIn, mOut);
-            break;
-        case TEST_F32_3:
-            script_f32.forEach_asinh_f32_3(mIn, mOut);
-            break;
-        case TEST_F32_4:
-            script_f32.forEach_asinh_f32_4(mIn, mOut);
-            break;
-
-        case TEST_RELAXED_F32:
-            script_f32_relaxed.forEach_asinh_f32_1(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_2:
-            script_f32_relaxed.forEach_asinh_f32_2(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_3:
-            script_f32_relaxed.forEach_asinh_f32_3(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_4:
-            script_f32_relaxed.forEach_asinh_f32_4(mIn, mOut);
-            break;
-        }
-    }
-
-    @Override
-    protected float[] getRefArray(float[] in, int input_size, int stride, int skip) {
-        float[] ref = new float[input_size * stride];
-        for (int i = 0; i < input_size; i++) {
-            for (int j = 0; j < stride - skip; j++) {
-                int idx= i * stride + j;
-                int idxRef = i * (stride - skip) + j;
-                double x = (double)in[idx];
-                ref[idxRef] = (float)(Math.log(x+Math.sqrt(1+Math.pow(x, 2))));
-            }
-        }
-        return ref;
-    }
-
-    public void testAsinhF32() {
-        doF32(0x12, 4);
-    }
-
-    public void testAsinhF32_relaxed() {
-        doF32_relaxed(0x12, 128);
-    }
-
-    public void testAsinhF32_2() {
-        doF32_2(0xead, 4);
-    }
-
-    public void testAsinhF32_2_relaxed() {
-        doF32_2_relaxed(0xead, 128);
-    }
-
-    public void testAsinhF32_3() {
-        doF32_3(0xabc, 4);
-    }
-
-    public void testAsinhF32_3_relaxed() {
-        doF32_3_relaxed(0xabc, 128);
-    }
-
-    public void testAsinhF32_4() {
-        doF32_4(0xfea, 4);
-
-    }
-    public void testAsinhF32_4_relaxed() {
-        doF32_4_relaxed(0xfea, 128);
-    }
-
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/Atan2PiTest.java b/tests/tests/renderscript/src/android/renderscript/cts/Atan2PiTest.java
deleted file mode 100644
index f96e7d6..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/Atan2PiTest.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * 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 android.renderscript.cts;
-
-import com.android.cts.stub.R;
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class Atan2PiTest extends RSBaseCompute {
-    private ScriptC_atan2pi_f32 script_f32;
-    private ScriptC_atan2pi_f32_relaxed script_f32_relaxed;
-    private Allocation mIn;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script_f32 = new ScriptC_atan2pi_f32(mRS);
-        script_f32_relaxed = new ScriptC_atan2pi_f32_relaxed(mRS);
-    }
-
-    @Override
-    public void forEach(int testId, Allocation mIn, Allocation mOut) throws RSRuntimeException {
-        switch (testId) {
-        case TEST_F32:
-            script_f32.forEach_atan2pi_f32_1(mIn, mOut);
-            break;
-        case TEST_F32_2:
-            script_f32.forEach_atan2pi_f32_2(mIn, mOut);
-            break;
-        case TEST_F32_3:
-            script_f32.forEach_atan2pi_f32_3(mIn, mOut);
-            break;
-        case TEST_F32_4:
-            script_f32.forEach_atan2pi_f32_4(mIn, mOut);
-            break;
-
-        case TEST_RELAXED_F32:
-            script_f32_relaxed.forEach_atan2pi_f32_1(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_2:
-            script_f32_relaxed.forEach_atan2pi_f32_2(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_3:
-            script_f32_relaxed.forEach_atan2pi_f32_3(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_4:
-            script_f32_relaxed.forEach_atan2pi_f32_4(mIn, mOut);
-            break;
-        }
-    }
-
-    @Override
-    protected float[] getRefArray(float[] in, int input_size, int stride, int skip) {
-        float[] ref = new float[input_size * stride];
-        for (int i = 0; i < input_size; i++) {
-            for (int j = 0; j < stride - skip; j++) {
-                int idx = i * stride * 2 + j;
-                ref[i * (stride - skip) + j] = (float)(Math.atan2((double)in[idx],(double)in[idx+stride]) / Math.PI);
-            }
-        }
-        return ref;
-    }
-
-    @Override
-    protected Allocation setInAlloc(Element e) {
-        return mIn;
-    }
-
-    @Override
-    protected float[] makeInArray(int size) {
-        return new float[size*2];
-    }
-
-    public void testAtan2PiF32() {
-        ScriptField_atan2pi_float_input in = new ScriptField_atan2pi_float_input(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32(0x12678, 6);
-    }
-
-    public void testAtan2PiF32_relaxed() {
-        ScriptField_atan2pi_float_input in = new ScriptField_atan2pi_float_input(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_relaxed(0x12678, 128);
-    }
-
-    public void testAtan2PiF32_2() {
-        ScriptField_atan2pi_float2_input in = new ScriptField_atan2pi_float2_input(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_2(0x1af45, 6);
-    }
-
-    public void testAtan2PiF32_2_relaxed() {
-        ScriptField_atan2pi_float2_input in = new ScriptField_atan2pi_float2_input(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_2_relaxed(0x1af45, 128);
-    }
-
-    public void testAtan2PiF32_3() {
-        ScriptField_atan2pi_float3_input in = new ScriptField_atan2pi_float3_input(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_3(0x1cd345, 6);
-    }
-
-    public void testAtan2PiF32_3_relaxed() {
-        ScriptField_atan2pi_float3_input in = new ScriptField_atan2pi_float3_input(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_3_relaxed(0x1cd345, 128);
-    }
-
-    public void testAtan2PiF32_4() {
-        ScriptField_atan2pi_float4_input in = new ScriptField_atan2pi_float4_input(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_4(0x1ca45, 6);
-    }
-
-    public void testAtan2PiF32_4_relaxed() {
-        ScriptField_atan2pi_float4_input in = new ScriptField_atan2pi_float4_input(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_4_relaxed(0x1ca45, 128);
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/Atan2Test.java b/tests/tests/renderscript/src/android/renderscript/cts/Atan2Test.java
deleted file mode 100644
index c3eabb7..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/Atan2Test.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * 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 android.renderscript.cts;
-
-import com.android.cts.stub.R;
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class Atan2Test extends RSBaseCompute {
-    private ScriptC_atan2_f32 script_f32;
-    private ScriptC_atan2_f32_relaxed script_f32_relaxed;
-    private Allocation mIn;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script_f32 = new ScriptC_atan2_f32(mRS);
-        script_f32_relaxed = new ScriptC_atan2_f32_relaxed(mRS);
-    }
-
-    @Override
-    public void forEach(int testId, Allocation mIn, Allocation mOut) throws RSRuntimeException {
-        switch (testId) {
-        case TEST_F32:
-            script_f32.forEach_atan2_f32_1(mIn, mOut);
-            break;
-        case TEST_F32_2:
-            script_f32.forEach_atan2_f32_2(mIn, mOut);
-            break;
-        case TEST_F32_3:
-            script_f32.forEach_atan2_f32_3(mIn, mOut);
-            break;
-        case TEST_F32_4:
-            script_f32.forEach_atan2_f32_4(mIn, mOut);
-            break;
-
-        case TEST_RELAXED_F32:
-            script_f32_relaxed.forEach_atan2_f32_1(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_2:
-            script_f32_relaxed.forEach_atan2_f32_2(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_3:
-            script_f32_relaxed.forEach_atan2_f32_3(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_4:
-            script_f32_relaxed.forEach_atan2_f32_4(mIn, mOut);
-            break;
-        }
-    }
-
-    @Override
-    protected float[] getRefArray(float[] in, int input_size, int stride, int skip) {
-        float[] ref = new float[input_size * stride];
-        for (int i = 0; i < input_size; i++) {
-            for (int j = 0; j < stride - skip; j++) {
-                int idx = i * stride * 2 + j;
-                ref[i * (stride - skip) + j] = (float)Math.atan2((double)in[idx],(double)in[idx+stride]);
-            }
-        }
-        return ref;
-    }
-
-    @Override
-    protected Allocation setInAlloc(Element e) {
-        return mIn;
-    }
-
-    @Override
-    protected float[] makeInArray(int size) {
-        return new float[size*2];
-    }
-
-    public void testAtan2F32() {
-        ScriptField_atan2_f32_in in = new ScriptField_atan2_f32_in(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32(0x12678, 6);
-    }
-
-    public void testAtan2F32_relaxed() {
-        ScriptField_atan2_f32_in in = new ScriptField_atan2_f32_in(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_relaxed(0x12678, 128);
-    }
-
-    public void testAtan2F32_2() {
-        ScriptField_atan2_f32_2_in in = new ScriptField_atan2_f32_2_in(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_2(0x1af45, 6);
-    }
-
-    public void testAtan2F32_2_relaxed() {
-        ScriptField_atan2_f32_2_in in = new ScriptField_atan2_f32_2_in(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_2_relaxed(0x1af45, 128);
-    }
-
-    public void testAtan2F32_3() {
-        ScriptField_atan2_f32_3_in in = new ScriptField_atan2_f32_3_in(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_3(0x1cd345, 6);
-    }
-
-    public void testAtan2F32_3_relaxed() {
-        ScriptField_atan2_f32_3_in in = new ScriptField_atan2_f32_3_in(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_3_relaxed(0x1cd345, 128);
-    }
-
-    public void testAtan2F32_4() {
-        ScriptField_atan2_f32_4_in in = new ScriptField_atan2_f32_4_in(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_4(0x1ca45, 6);
-    }
-
-    public void testAtan2F32_4_relaxed() {
-        ScriptField_atan2_f32_4_in in = new ScriptField_atan2_f32_4_in(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_4_relaxed(0x1ca45, 128);
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/AtanPiTest.java b/tests/tests/renderscript/src/android/renderscript/cts/AtanPiTest.java
deleted file mode 100644
index 17fe5ad..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/AtanPiTest.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * 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 android.renderscript.cts;
-
-import com.android.cts.stub.R;
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-
-public class AtanPiTest extends RSBaseCompute {
-    private ScriptC_atanpi_f32 script_f32;
-    private ScriptC_atanpi_f32_relaxed script_f32_relaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script_f32 = new ScriptC_atanpi_f32(mRS);
-        script_f32_relaxed = new ScriptC_atanpi_f32_relaxed(mRS);
-    }
-
-    @Override
-    public void forEach(int testId, Allocation mIn, Allocation mOut) throws RSRuntimeException {
-        switch (testId) {
-        case TEST_F32:
-            script_f32.forEach_atanpi_f32_1(mIn, mOut);
-            break;
-        case TEST_F32_2:
-            script_f32.forEach_atanpi_f32_2(mIn, mOut);
-            break;
-        case TEST_F32_3:
-            script_f32.forEach_atanpi_f32_3(mIn, mOut);
-            break;
-        case TEST_F32_4:
-            script_f32.forEach_atanpi_f32_4(mIn, mOut);
-            break;
-
-        case TEST_RELAXED_F32:
-            script_f32_relaxed.forEach_atanpi_f32_1(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_2:
-            script_f32_relaxed.forEach_atanpi_f32_2(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_3:
-            script_f32_relaxed.forEach_atanpi_f32_3(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_4:
-            script_f32_relaxed.forEach_atanpi_f32_4(mIn, mOut);
-            break;
-        }
-    }
-
-    @Override
-    protected float[] getRefArray(float[] in, int input_size, int stride, int skip) {
-        float[] ref = new float[input_size * stride];
-        for (int i = 0; i < input_size; i++) {
-            for (int j = 0; j < stride - skip; j++) {
-                int idx= i * stride + j;
-                int idxRef = i * (stride - skip) + j;
-                ref[idxRef] = (float)(Math.atan((double)in[idx])/Math.PI);
-            }
-        }
-        return ref;
-    }
-
-    public void testAtanPiF32() {
-        doF32(0x123, 5);
-    }
-
-    public void testAtanPiF32_relaxed() {
-        doF32_relaxed(0x123, 128);
-    }
-
-    public void testAtanPiF32_2() {
-        doF32_2(0x12, 5);
-    }
-
-    public void testAtanPiF32_2_relaxed() {
-        doF32_2_relaxed(0x12, 128);
-    }
-
-    public void testAtanPiF32_3() {
-        doF32_3(0x847, 5);
-    }
-
-    public void testAtanPiF32_3_relaxed() {
-        doF32_3_relaxed(0x847, 128);
-    }
-
-    public void testAtanPiF32_4() {
-        doF32_4(0xfa2, 5);
-
-    }
-    public void testAtanPiF32_4_relaxed() {
-        doF32_4_relaxed(0xfa2, 128);
-    }
-
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/AtanTest.java b/tests/tests/renderscript/src/android/renderscript/cts/AtanTest.java
deleted file mode 100644
index c41be40..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/AtanTest.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * 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 android.renderscript.cts;
-
-import com.android.cts.stub.R;
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-
-public class AtanTest extends RSBaseCompute {
-    private ScriptC_atan_f32 script_f32;
-    private ScriptC_atan_f32_relaxed script_f32_relaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script_f32 = new ScriptC_atan_f32(mRS);
-        script_f32_relaxed = new ScriptC_atan_f32_relaxed(mRS);
-    }
-
-    @Override
-    public void forEach(int testId, Allocation mIn, Allocation mOut) throws RSRuntimeException {
-        switch (testId) {
-        case TEST_F32:
-            script_f32.forEach_atan_f32_1(mIn, mOut);
-            break;
-        case TEST_F32_2:
-            script_f32.forEach_atan_f32_2(mIn, mOut);
-            break;
-        case TEST_F32_3:
-            script_f32.forEach_atan_f32_3(mIn, mOut);
-            break;
-        case TEST_F32_4:
-            script_f32.forEach_atan_f32_4(mIn, mOut);
-            break;
-
-        case TEST_RELAXED_F32:
-            script_f32_relaxed.forEach_atan_f32_1(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_2:
-            script_f32_relaxed.forEach_atan_f32_2(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_3:
-            script_f32_relaxed.forEach_atan_f32_3(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_4:
-            script_f32_relaxed.forEach_atan_f32_4(mIn, mOut);
-            break;
-        }
-    }
-
-    @Override
-    protected float[] getRefArray(float[] in, int input_size, int stride, int skip) {
-        float[] ref = new float[input_size * stride];
-        for (int i = 0; i < input_size; i++) {
-            for (int j = 0; j < stride - skip; j++) {
-                int idx= i * stride + j;
-                int idxRef = i * (stride - skip) + j;
-                ref[idxRef] = (float)(Math.atan((double)in[idx]));
-            }
-        }
-        return ref;
-    }
-
-    public void testAtanF32() {
-        doF32(0x12a, 5);
-    }
-
-    public void testAtanF32_relaxed() {
-        doF32_relaxed(0x12a, 128);
-    }
-
-    public void testAtanF32_2() {
-        doF32_2(0xad, 5);
-    }
-
-    public void testAtanF32_2_relaxed() {
-        doF32_2_relaxed(0xad, 128);
-    }
-
-    public void testAtanF32_3() {
-        doF32_3(0xafe, 5);
-    }
-
-    public void testAtanF32_3_relaxed() {
-        doF32_3_relaxed(0xafe, 128);
-    }
-
-    public void testAtanF32_4() {
-        doF32_4(0x1238, 5);
-
-    }
-    public void testAtanF32_4_relaxed() {
-        doF32_4_relaxed(0x1238, 128);
-    }
-
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/AtanhTest.java b/tests/tests/renderscript/src/android/renderscript/cts/AtanhTest.java
deleted file mode 100644
index 7182251..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/AtanhTest.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * 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 android.renderscript.cts;
-
-import com.android.cts.stub.R;
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-
-public class AtanhTest extends RSBaseCompute {
-    private ScriptC_atanh_f32 script_f32;
-    private ScriptC_atanh_f32_relaxed script_f32_relaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script_f32 = new ScriptC_atanh_f32(mRS);
-        script_f32_relaxed = new ScriptC_atanh_f32_relaxed(mRS);
-    }
-
-    @Override
-    public void forEach(int testId, Allocation mIn, Allocation mOut) throws RSRuntimeException {
-        switch (testId) {
-        case TEST_F32:
-            script_f32.forEach_atanh_f32_1(mIn, mOut);
-            break;
-        case TEST_F32_2:
-            script_f32.forEach_atanh_f32_2(mIn, mOut);
-            break;
-        case TEST_F32_3:
-            script_f32.forEach_atanh_f32_3(mIn, mOut);
-            break;
-        case TEST_F32_4:
-            script_f32.forEach_atanh_f32_4(mIn, mOut);
-            break;
-
-        case TEST_RELAXED_F32:
-            script_f32_relaxed.forEach_atanh_f32_1(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_2:
-            script_f32_relaxed.forEach_atanh_f32_2(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_3:
-            script_f32_relaxed.forEach_atanh_f32_3(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_4:
-            script_f32_relaxed.forEach_atanh_f32_4(mIn, mOut);
-            break;
-        }
-    }
-
-    @Override
-    protected float[] getRefArray(float[] in, int input_size, int stride, int skip) {
-        float[] ref = new float[input_size * stride];
-        for (int i = 0; i < input_size; i++) {
-            for (int j = 0; j < stride - skip; j++) {
-                int idx= i * stride + j;
-                int idxRef = i * (stride - skip) + j;
-                double x = (double)in[idx];
-                ref[idxRef] = (float)((Math.log(1+x) - Math.log(1-x))/2);
-            }
-        }
-        return ref;
-    }
-
-    public void testAtanhF32() {
-        doF32(0xace, 5);
-    }
-
-    public void testAtanhF32_relaxed() {
-        doF32_relaxed(0xace, 128);
-    }
-
-    public void testAtanhF32_2() {
-        doF32_2(0xdae, 5);
-    }
-
-    public void testAtanhF32_2_relaxed() {
-        doF32_2_relaxed(0xdae, 128);
-    }
-
-    public void testAtanhF32_3() {
-        doF32_3(0x123, 5);
-    }
-
-    public void testAtanhF32_3_relaxed() {
-        doF32_3_relaxed(0x123, 128);
-    }
-
-    public void testAtanhF32_4() {
-        doF32_4(0x6480, 5);
-
-    }
-    public void testAtanhF32_4_relaxed() {
-        doF32_4_relaxed(0x6480, 128);
-    }
-
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/CbrtTest.java b/tests/tests/renderscript/src/android/renderscript/cts/CbrtTest.java
deleted file mode 100644
index 603794a..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/CbrtTest.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * 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 android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import com.android.cts.stub.R;
-
-public class CbrtTest extends RSBaseCompute {
-    private ScriptC_cbrt_f32 script_f32;
-    private ScriptC_cbrt_f32_relaxed script_f32_relaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script_f32 = new ScriptC_cbrt_f32(mRS);
-        script_f32_relaxed = new ScriptC_cbrt_f32_relaxed(mRS);
-    }
-
-    @Override
-    public void forEach(int testId, Allocation mIn, Allocation mOut) throws RSRuntimeException {
-        switch (testId) {
-        case TEST_F32:
-            script_f32.forEach_cbrt_f32_1(mIn, mOut);
-            break;
-        case TEST_F32_2:
-            script_f32.forEach_cbrt_f32_2(mIn, mOut);
-            break;
-        case TEST_F32_3:
-            script_f32.forEach_cbrt_f32_3(mIn, mOut);
-            break;
-        case TEST_F32_4:
-            script_f32.forEach_cbrt_f32_4(mIn, mOut);
-            break;
-
-        case TEST_RELAXED_F32:
-            script_f32_relaxed.forEach_cbrt_f32_1(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_2:
-            script_f32_relaxed.forEach_cbrt_f32_2(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_3:
-            script_f32_relaxed.forEach_cbrt_f32_3(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_4:
-            script_f32_relaxed.forEach_cbrt_f32_4(mIn, mOut);
-            break;
-        }
-    }
-
-    @Override
-    protected float[] getRefArray(float[] in, int input_size, int stride, int skip) {
-        float[] ref = new float[input_size * stride];
-        for (int i = 0; i < input_size; i++) {
-            for (int j = 0; j < stride - skip; j++) {
-                int idx= i * stride + j;
-                int idxRef = i * (stride - skip) + j;
-                ref[idxRef] = (float)(Math.cbrt((double)in[idx]));
-            }
-        }
-        return ref;
-    }
-
-    public void testCbrtF32() {
-        doF32(0xabe, 2);
-    }
-
-    public void testCbrtF32_relaxed() {
-        doF32_relaxed(0xabe, 128);
-    }
-
-    public void testCbrtF32_2() {
-        doF32_2(0x78, 2);
-    }
-
-    public void testCbrtF32_2_relaxed() {
-        doF32_2_relaxed(0x78, 128);
-    }
-
-    public void testCbrtF32_3() {
-        doF32_3(0x1e, 2);
-    }
-
-    public void testCbrtF32_3_relaxed() {
-        doF32_3_relaxed(0x1e, 128);
-    }
-
-    public void testCbrtF32_4() {
-        doF32_4(0xfe2, 2);
-
-    }
-    public void testCbrtF32_4_relaxed() {
-        doF32_4_relaxed(0xfe2, 128);
-    }
-
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/CeilTest.java b/tests/tests/renderscript/src/android/renderscript/cts/CeilTest.java
deleted file mode 100644
index 5d64b95..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/CeilTest.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * 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 android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import com.android.cts.stub.R;
-
-public class CeilTest extends RSBaseCompute {
-    private ScriptC_ceil_f32 script_f32;
-    private ScriptC_ceil_f32_relaxed script_f32_relaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script_f32 = new ScriptC_ceil_f32(mRS);
-        script_f32_relaxed = new ScriptC_ceil_f32_relaxed(mRS);
-    }
-
-    @Override
-    public void forEach(int testId, Allocation mIn, Allocation mOut) throws RSRuntimeException {
-        switch (testId) {
-        case TEST_F32:
-            script_f32.forEach_ceil_f32_1(mIn, mOut);
-            break;
-        case TEST_F32_2:
-            script_f32.forEach_ceil_f32_2(mIn, mOut);
-            break;
-        case TEST_F32_3:
-            script_f32.forEach_ceil_f32_3(mIn, mOut);
-            break;
-        case TEST_F32_4:
-            script_f32.forEach_ceil_f32_4(mIn, mOut);
-            break;
-
-        case TEST_RELAXED_F32:
-            script_f32_relaxed.forEach_ceil_f32_1(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_2:
-            script_f32_relaxed.forEach_ceil_f32_2(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_3:
-            script_f32_relaxed.forEach_ceil_f32_3(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_4:
-            script_f32_relaxed.forEach_ceil_f32_4(mIn, mOut);
-            break;
-        }
-    }
-
-    @Override
-    protected float[] getRefArray(float[] in, int input_size, int stride, int skip) {
-        float[] ref = new float[input_size * stride];
-        for (int i = 0; i < input_size; i++) {
-            for (int j = 0; j < stride - skip; j++) {
-                int idx= i * stride + j;
-                int idxRef = i * (stride - skip) + j;
-                ref[idxRef] = (float)(Math.ceil((double)in[idx]));
-            }
-        }
-        return ref;
-    }
-
-    public void testCeilF32() {
-        doF32(0x12345ace, 0);
-    }
-
-    public void testCeilF32_relaxed() {
-        doF32_relaxed(0x12345ace, 1);
-    }
-
-    public void testCeilF32_2() {
-        doF32_2(0x1ac478, 0);
-    }
-
-    public void testCeilF32_2_relaxed() {
-        doF32_2_relaxed(0x1ac478, 1);
-    }
-
-    public void testCeilF32_3() {
-        doF32_3(0xacef, 0);
-    }
-
-    public void testCeilF32_3_relaxed() {
-        doF32_3_relaxed(0xacef, 1);
-    }
-
-    public void testCeilF32_4() {
-        doF32_4(0xef12, 0);
-
-    }
-    public void testCeilF32_4_relaxed() {
-        doF32_4_relaxed(0xef12, 1);
-    }
-
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/ComputeTest.java b/tests/tests/renderscript/src/android/renderscript/cts/ComputeTest.java
index 40611fd..d320448 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/ComputeTest.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/ComputeTest.java
@@ -704,6 +704,7 @@
         checkForErrors();
     }
 
+    /*
     public void testClamp() {
         ScriptC_clamp s = new ScriptC_clamp(mRS, mRes, R.raw.clamp);
         s.invoke_clamp_test();
@@ -720,6 +721,7 @@
         waitForMessage();
         checkForErrors();
     }
+    */
 
     /**
      * Test utility functions.
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/CopysignTest.java b/tests/tests/renderscript/src/android/renderscript/cts/CopysignTest.java
deleted file mode 100644
index a28caef..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/CopysignTest.java
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * 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 android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.Element;
-import android.renderscript.RSRuntimeException;
-import com.android.cts.stub.R;
-
-public class CopysignTest extends RSBaseCompute {
-    private ScriptC_copysign_f32 script_f32;
-    private ScriptC_copysign_f32_relaxed script_f32_relaxed;
-    private Allocation mIn;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script_f32 = new ScriptC_copysign_f32(mRS);
-        script_f32_relaxed = new ScriptC_copysign_f32_relaxed(mRS);
-    }
-
-    @Override
-    public void forEach(int testId, Allocation mIn, Allocation mOut) throws RSRuntimeException {
-        switch (testId) {
-        case TEST_F32:
-            script_f32.forEach_copysign_f32_1(mIn, mOut);
-            break;
-        case TEST_F32_2:
-            script_f32.forEach_copysign_f32_2(mIn, mOut);
-            break;
-        case TEST_F32_3:
-            script_f32.forEach_copysign_f32_3(mIn, mOut);
-            break;
-        case TEST_F32_4:
-            script_f32.forEach_copysign_f32_4(mIn, mOut);
-            break;
-
-        case TEST_RELAXED_F32:
-            script_f32_relaxed.forEach_copysign_f32_1(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_2:
-            script_f32_relaxed.forEach_copysign_f32_2(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_3:
-            script_f32_relaxed.forEach_copysign_f32_3(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_4:
-            script_f32_relaxed.forEach_copysign_f32_4(mIn, mOut);
-            break;
-        }
-    }
-
-    @Override
-    protected float[] getRefArray(float[] in, int input_size, int stride, int skip) {
-        int vec_size = stride - skip;
-        float[] ref = new float[vec_size * input_size];
-        for (int i = 0; i < input_size; i++) {
-            for (int j = 0; j < vec_size; j++) {
-                int idx = i * stride * 2 + j;
-                ref[i*vec_size + j] = Math.copySign(in[idx], in[idx + stride]);
-            }
-        }
-        return ref;
-    }
-
-    @Override
-    protected Allocation setInAlloc(Element e) {
-        return mIn;
-    }
-
-    @Override
-    protected float[] makeInArray(int size) {
-        return new float[size*2];
-    }
-
-    /**
-     * Tests copysign(float, float).
-     */
-    public void testCopysignF32() {
-        ScriptField_copysign_f32_input in = new ScriptField_copysign_f32_input(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32(0x12ac5678, 0);
-    }
-
-    public void testCopysignF32_relaxed() {
-        ScriptField_copysign_f32_input in = new ScriptField_copysign_f32_input(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_relaxed(0x12ac5678, 0);
-    }
-
-    /**
-     * Tests copysign(float2, float2).
-     */
-    public void testCopysignF32_2() {
-        ScriptField_copysign_f32_2_input in = new ScriptField_copysign_f32_2_input(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_2(0x12fe5678, 0);
-    }
-
-    public void testCopysignF32_2_relaxed() {
-        ScriptField_copysign_f32_2_input in = new ScriptField_copysign_f32_2_input(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_2_relaxed(0x12fe5678, 0);
-    }
-
-    /**
-     * Tests copysign(float3, float3).
-     */
-    public void testCopysignF32_3() {
-        ScriptField_copysign_f32_3_input in = new ScriptField_copysign_f32_3_input(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_3(0x1c345678, 0);
-    }
-
-    public void testCopysignF32_3_relaxed() {
-        ScriptField_copysign_f32_3_input in = new ScriptField_copysign_f32_3_input(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_3_relaxed(0x1c345678, 0);
-    }
-
-    /**
-     * Tests copysign(float4, float4).
-     */
-    public void testCopysignF32_4() {
-        ScriptField_copysign_f32_4_input in = new ScriptField_copysign_f32_4_input(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_4(0x123a5f7d, 0);
-    }
-
-    public void testCopysignF32_4_relaxed() {
-        ScriptField_copysign_f32_4_input in = new ScriptField_copysign_f32_4_input(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_4_relaxed(0x123a5f7d, 0);
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/CoreMathVerifier.java b/tests/tests/renderscript/src/android/renderscript/cts/CoreMathVerifier.java
new file mode 100644
index 0000000..90f47da
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/CoreMathVerifier.java
@@ -0,0 +1,1216 @@
+/*
+ * Copyright (C) 2014 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 android.renderscript.cts;
+
+import android.util.Log;
+
+public class CoreMathVerifier {
+    static {
+        System.loadLibrary("coremathtestcpp_jni");
+    }
+
+    /* The level of precision we expect out of the half_* functions.  floats (f32) have 23 bits of
+     * mantissa and halfs (f16) have 10 bits.  8192 = 2 ^ (23 - 10).
+     */
+    private static final int HALF_PRECISION = 8192;
+    // The level of precision we expect out of the fast_* functions.
+    private static final int FAST_PRECISION = 8192;
+    // The level of precision we expect out of the native_* functions.
+    private static final int NATIVE_PRECISION = 8192;
+
+    // Static classes used to return multiple values from a few JNI functions.
+    static public class FrexpResult {
+        public float significand;
+        public int exponent;
+    }
+
+    static public class LgammaResult {
+        public float lgamma;
+        public int gammaSign;
+    }
+
+    static public class RemquoResult {
+        public float remainder;
+        public int quotient;
+    }
+
+    /* We're calling into native:
+     * - not all functions are available in Java, notably gamma and erf,
+     * - Java lacks float version of these functions, so we can compare implementations with
+     *   similar constraints, and
+     * - handling unsigned integers, especially longs, is painful and error prone in Java.
+     */
+    static native float acos(float x);
+    static native float acosh(float x);
+    static native float asin(float x);
+    static native float asinh(float x);
+    static native float atan(float x);
+    static native float atan2(float x, float y);
+    static native float atanh(float x);
+    static native float cbrt(float x);
+    static native float ceil(float x);
+    static native float cos(float x);
+    static native float cosh(float x);
+    static native float erf(float x);
+    static native float erfc(float x);
+    static native float exp(float x);
+    static native float exp10(float x);
+    static native float exp2(float x);
+    static native float expm1(float x);
+    static native float floor(float x);
+    static native FrexpResult frexp(float x);
+    static native float hypot(float x, float y);
+    static native int ilogb(float x);
+    static native float ldexp(float x, int exp);
+    static native float lgamma(float x);
+    static native LgammaResult lgamma2(float x);
+    static native float log(float x);
+    static native float logb(float x);
+    static native float log10(float x);
+    static native float log1p(float x);
+    static native float log2(float x);
+    static native byte maxI8(byte x, byte y);
+    static native byte maxU8(byte x, byte y);
+    static native short maxI16(short x, short y);
+    static native short maxU16(short x, short y);
+    static native int maxI32(int x, int y);
+    static native int maxU32(int x, int y);
+    static native long maxI64(long x, long y);
+    static native long maxU64(long x, long y);
+    static native byte minI8(byte x, byte y);
+    static native byte minU8(byte x, byte y);
+    static native short minI16(short x, short y);
+    static native short minU16(short x, short y);
+    static native int minI32(int x, int y);
+    static native int minU32(int x, int y);
+    static native long minI64(long x, long y);
+    static native long minU64(long x, long y);
+    static native float pow(float x, float y);
+    static native RemquoResult remquo(float numerator, float denominator);
+    static native float rint(float x);
+    static native float round(float x);
+    static native float sin(float x);
+    static native float sinh(float x);
+    static native float sqrt(float x);
+    static native float tan(float x);
+    static native float tanh(float x);
+    static native float tgamma(float x);
+    static native float trunc(float x);
+
+    static native byte   convertCharToChar(byte x);
+    static native byte   convertCharToUchar(byte x);
+    static native short  convertCharToShort(byte x);
+    static native short  convertCharToUshort(byte x);
+    static native int    convertCharToInt(byte x);
+    static native int    convertCharToUint(byte x);
+    static native long   convertCharToLong(byte x);
+    static native long   convertCharToUlong(byte x);
+    static native float  convertCharToFloat(byte x);
+    static native double convertCharToDouble(byte x);
+
+    static native byte   convertUcharToChar(byte x);
+    static native byte   convertUcharToUchar(byte x);
+    static native short  convertUcharToShort(byte x);
+    static native short  convertUcharToUshort(byte x);
+    static native int    convertUcharToInt(byte x);
+    static native int    convertUcharToUint(byte x);
+    static native long   convertUcharToLong(byte x);
+    static native long   convertUcharToUlong(byte x);
+    static native float  convertUcharToFloat(byte x);
+    static native double convertUcharToDouble(byte x);
+
+    static native byte   convertShortToChar(short x);
+    static native byte   convertShortToUchar(short x);
+    static native short  convertShortToShort(short x);
+    static native short  convertShortToUshort(short x);
+    static native int    convertShortToInt(short x);
+    static native int    convertShortToUint(short x);
+    static native long   convertShortToLong(short x);
+    static native long   convertShortToUlong(short x);
+    static native float  convertShortToFloat(short x);
+    static native double convertShortToDouble(short x);
+
+    static native byte   convertUshortToChar(short x);
+    static native byte   convertUshortToUchar(short x);
+    static native short  convertUshortToShort(short x);
+    static native short  convertUshortToUshort(short x);
+    static native int    convertUshortToInt(short x);
+    static native int    convertUshortToUint(short x);
+    static native long   convertUshortToLong(short x);
+    static native long   convertUshortToUlong(short x);
+    static native float  convertUshortToFloat(short x);
+    static native double convertUshortToDouble(short x);
+
+    static native byte   convertIntToChar(int x);
+    static native byte   convertIntToUchar(int x);
+    static native short  convertIntToShort(int x);
+    static native short  convertIntToUshort(int x);
+    static native int    convertIntToInt(int x);
+    static native int    convertIntToUint(int x);
+    static native long   convertIntToLong(int x);
+    static native long   convertIntToUlong(int x);
+    static native float  convertIntToFloat(int x);
+    static native double convertIntToDouble(int x);
+
+    static native byte   convertUintToChar(int x);
+    static native byte   convertUintToUchar(int x);
+    static native short  convertUintToShort(int x);
+    static native short  convertUintToUshort(int x);
+    static native int    convertUintToInt(int x);
+    static native int    convertUintToUint(int x);
+    static native long   convertUintToLong(int x);
+    static native long   convertUintToUlong(int x);
+    static native float  convertUintToFloat(int x);
+    static native double convertUintToDouble(int x);
+
+    static native byte   convertLongToChar(long x);
+    static native byte   convertLongToUchar(long x);
+    static native short  convertLongToShort(long x);
+    static native short  convertLongToUshort(long x);
+    static native int    convertLongToInt(long x);
+    static native int    convertLongToUint(long x);
+    static native long   convertLongToLong(long x);
+    static native long   convertLongToUlong(long x);
+    static native float  convertLongToFloat(long x);
+    static native double convertLongToDouble(long x);
+
+    static native byte   convertUlongToChar(long x);
+    static native byte   convertUlongToUchar(long x);
+    static native short  convertUlongToShort(long x);
+    static native short  convertUlongToUshort(long x);
+    static native int    convertUlongToInt(long x);
+    static native int    convertUlongToUint(long x);
+    static native long   convertUlongToLong(long x);
+    static native long   convertUlongToUlong(long x);
+    static native float  convertUlongToFloat(long x);
+    static native double convertUlongToDouble(long x);
+
+    static native byte   convertFloatToChar(float x);
+    static native byte   convertFloatToUchar(float x);
+    static native short  convertFloatToShort(float x);
+    static native short  convertFloatToUshort(float x);
+    static native int    convertFloatToInt(float x);
+    static native int    convertFloatToUint(float x);
+    static native long   convertFloatToLong(float x);
+    static native long   convertFloatToUlong(float x);
+    static native float  convertFloatToFloat(float x);
+    static native double convertFloatToDouble(float x);
+
+    static native byte   convertDoubleToChar(double x);
+    static native byte   convertDoubleToUchar(double x);
+    static native short  convertDoubleToShort(double x);
+    static native short  convertDoubleToUshort(double x);
+    static native int    convertDoubleToInt(double x);
+    static native int    convertDoubleToUint(double x);
+    static native long   convertDoubleToLong(double x);
+    static native long   convertDoubleToUlong(double x);
+    static native float  convertDoubleToFloat(double x);
+    static native double convertDoubleToDouble(double x);
+
+    // Returns the distance between two points in n-dimensional space.
+    static private Floaty distance(float[] point1, float[] point2, int ulpFactor, int ulpRelaxedFactor) {
+        Floaty sum = new Floaty(0f, ulpFactor, ulpRelaxedFactor);
+        for (int i = 0; i < point1.length; i++) {
+            Floaty diff = Floaty.subtract(new Floaty(point1[i], ulpFactor, ulpRelaxedFactor),
+                                          new Floaty(point2[i], ulpFactor, ulpRelaxedFactor));
+            sum.add(Floaty.multiply(diff, diff));
+        }
+        return Floaty.sqrt(sum);
+    }
+
+    // Returns the length of the n-dimensional vector.
+    static private Floaty length(float[] array, int ulpFactor, int ulpRelaxedFactor) {
+        Floaty sum = new Floaty(0f, ulpFactor, ulpRelaxedFactor);
+        for (int i = 0; i < array.length; i++) {
+            Floaty f = new Floaty(array[i], ulpFactor, ulpRelaxedFactor);
+            sum.add(Floaty.multiply(f, f));
+        }
+        return Floaty.sqrt(sum);
+    }
+
+    // Normalizes the n-dimensional vector, i.e. makes it length 1.
+    static private void normalize(float[] in, Floaty[] out, int ulpFactor, int ulpRelaxedFactor) {
+        Floaty l = length(in, ulpFactor, ulpRelaxedFactor);
+        boolean isZero = l.getFloatValue() == 0f;
+        for (int i = 0; i < in.length; i++) {
+            out[i] = new Floaty(in[i], ulpFactor, ulpRelaxedFactor);
+            if (!isZero) {
+                out[i].divide(l);
+            }
+        }
+    }
+
+    // Computes the cross product of two 3D vectors.
+    static private void cross(float[] v1, float[] v2, Floaty[] out) {
+        Floaty a12 = Floaty.multiply(new Floaty(v1[1]), new Floaty(v2[2]));
+        Floaty a21 = Floaty.multiply(new Floaty(v1[2]), new Floaty(v2[1]));
+        out[0] = Floaty.subtract(a12, a21);
+        Floaty a02 = Floaty.multiply(new Floaty(v1[0]), new Floaty(v2[2]));
+        Floaty a20 = Floaty.multiply(new Floaty(v1[2]), new Floaty(v2[0]));
+        out[1] = Floaty.subtract(a20, a02);
+        Floaty a01 = Floaty.multiply(new Floaty(v1[0]), new Floaty(v2[1]));
+        Floaty a10 = Floaty.multiply(new Floaty(v1[1]), new Floaty(v2[0]));
+        out[2] = Floaty.subtract(a01, a10);
+        if (out.length == 4) {
+            out[3] = new Floaty(0f);
+        }
+    }
+
+    static public void computeAbs(TestAbs.ArgumentsCharUchar args) {
+        args.out = (byte) Math.abs(args.inValue);
+    }
+
+    static public void computeAbs(TestAbs.ArgumentsShortUshort args) {
+        args.out = (short) Math.abs(args.inValue);
+    }
+
+    static public void computeAbs(TestAbs.ArgumentsIntUint args) {
+        args.out = Math.abs(args.inValue);
+    }
+
+    static public void computeAcos(TestAcos.ArgumentsFloatFloat args) {
+        args.out = new Floaty(acos(args.inV), 4, 128);
+    }
+
+    static public void computeAcosh(TestAcosh.ArgumentsFloatFloat args) {
+        args.out = new Floaty(acosh(args.in), 4, 128);
+    }
+
+    static public void computeAcospi(TestAcospi.ArgumentsFloatFloat args) {
+        args.out = new Floaty(acos(args.inV) / (float) Math.PI, 5, 128);
+    }
+
+    static public void computeAsin(TestAsin.ArgumentsFloatFloat args) {
+        args.out = new Floaty(asin(args.inV), 4, 128);
+    }
+
+    static public void computeAsinh(TestAsinh.ArgumentsFloatFloat args) {
+        args.out = new Floaty(asinh(args.in), 4, 128);
+    }
+
+    static public void computeAsinpi(TestAsinpi.ArgumentsFloatFloat args) {
+        args.out = new Floaty(asin(args.inV) / (float) Math.PI, 5, 128);
+    }
+
+    static public void computeAtan(TestAtan.ArgumentsFloatFloat args) {
+        args.out = new Floaty(atan(args.inV), 5, 128);
+    }
+
+    static public void computeAtanh(TestAtanh.ArgumentsFloatFloat args) {
+        args.out = new Floaty(atanh(args.in), 5, 128);
+    }
+
+    static public void computeAtanpi(TestAtanpi.ArgumentsFloatFloat args) {
+        args.out = new Floaty(atan(args.inV) / (float) Math.PI, 5, 128);
+    }
+
+    static public void computeAtan2(TestAtan2.ArgumentsFloatFloatFloat args) {
+        args.out = new Floaty(atan2(args.inY, args.inX), 6, 128);
+    }
+
+    static public void computeAtan2pi(TestAtan2pi.ArgumentsFloatFloatFloat args) {
+        args.out = new Floaty(atan2(args.inY, args.inX) / (float) Math.PI, 6, 128);
+    }
+
+    static public void computeCbrt(TestCbrt.ArgumentsFloatFloat args) {
+        args.out = new Floaty(cbrt(args.in), 2, 128);
+    }
+
+    static public void computeCeil(TestCeil.ArgumentsFloatFloat args) {
+        args.out = new Floaty(ceil(args.in), 0, 1);
+    }
+
+    // TODO all clamp
+    static public void computeClamp(TestClamp.ArgumentsCharCharCharChar args) {
+        args.out = minI8(args.inMaxValue, maxI8(args.inValue, args.inMinValue));
+    }
+
+    static public void computeClamp(TestClamp.ArgumentsUcharUcharUcharUchar args) {
+        args.out = minU8(args.inMaxValue, maxU8(args.inValue, args.inMinValue));
+    }
+
+    static public void computeClamp(TestClamp.ArgumentsShortShortShortShort args) {
+        args.out = minI16(args.inMaxValue, maxI16(args.inValue, args.inMinValue));
+    }
+
+    static public void computeClamp(TestClamp.ArgumentsUshortUshortUshortUshort args) {
+        args.out = minU16(args.inMaxValue, maxU16(args.inValue, args.inMinValue));
+    }
+
+    static public void computeClamp(TestClamp.ArgumentsIntIntIntInt args) {
+        args.out = minI32(args.inMaxValue, maxI32(args.inValue, args.inMinValue));
+    }
+
+    static public void computeClamp(TestClamp.ArgumentsUintUintUintUint args) {
+        args.out = minU32(args.inMaxValue, maxU32(args.inValue, args.inMinValue));
+    }
+
+    static public void computeClamp(TestClamp.ArgumentsFloatFloatFloatFloat args) {
+        args.out = new Floaty(Math.min(args.inMaxValue,
+                        Math.max(args.inValue, args.inMinValue)), 0, 0);
+    }
+
+    /* TODO Not supporting long arguments currently
+    static public void computeClamp(TestClamp.ArgumentsLongLongLongLong args) {
+        args.out = minI64(args.inMaxValue, maxI64(args.inValue, args.inMinValue));
+    }
+
+    static public void computeClamp(TestClamp.ArgumentsUlongUlongUlongUlong args) {
+        args.out = minU64(args.inMaxValue, maxU64(args.inValue, args.inMinValue));
+    }
+    */
+
+    static public void computeClz(TestClz.ArgumentsCharChar args) {
+        int x = args.inValue;
+        args.out = (byte) (Integer.numberOfLeadingZeros(x & 0xff) - 24);
+    }
+
+    static public void computeClz(TestClz.ArgumentsUcharUchar args) {
+        int x = args.inValue;
+        args.out = (byte) (Integer.numberOfLeadingZeros(x & 0xff) - 24);
+    }
+
+    static public void computeClz(TestClz.ArgumentsShortShort args) {
+        args.out = (short) (Integer.numberOfLeadingZeros(args.inValue & 0xffff) - 16);
+    }
+
+    static public void computeClz(TestClz.ArgumentsUshortUshort args) {
+        args.out = (short) (Integer.numberOfLeadingZeros(args.inValue & 0xffff) - 16);
+    }
+
+    static public void computeClz(TestClz.ArgumentsIntInt args) {
+        args.out = (int) Integer.numberOfLeadingZeros(args.inValue);
+    }
+
+    static public void computeClz(TestClz.ArgumentsUintUint args) {
+        args.out = (int) Integer.numberOfLeadingZeros(args.inValue);
+    }
+
+
+    static public void computeConvert(TestConvert.ArgumentsCharChar args) {
+        args.out = convertCharToChar(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsCharUchar args) {
+        args.out = convertCharToUchar(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsCharShort args) {
+        args.out = convertCharToShort(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsCharUshort args) {
+        args.out = convertCharToUshort(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsCharInt args) {
+        args.out = convertCharToInt(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsCharUint args) {
+        args.out = convertCharToUint(args.inV);
+    }
+    /* TODO Not supporting long arguments currently
+    static public void computeConvert(TestConvert.ArgumentsCharLong args) {
+        args.out = convertCharToLong(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsCharUlong args) {
+        args.out = convertCharToUlong(args.inV);
+    }
+    */
+    static public void computeConvert(TestConvert.ArgumentsCharFloat args) {
+        args.out = new Floaty(convertCharToFloat(args.inV), 0, 0);
+    }
+    /* TODO Not supporting double arguments currently
+    static public void computeConvert(TestConvert.ArgumentsCharDouble args) {
+        args.out = new Floaty(convertCharToDouble(args.inV), 0, 0);
+    }
+    */
+
+    static public void computeConvert(TestConvert.ArgumentsUcharChar args) {
+        args.out = convertUcharToChar(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsUcharUchar args) {
+        args.out = convertUcharToUchar(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsUcharShort args) {
+        args.out = convertUcharToShort(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsUcharUshort args) {
+        args.out = convertUcharToUshort(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsUcharInt args) {
+        args.out = convertUcharToInt(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsUcharUint args) {
+        args.out = convertUcharToUint(args.inV);
+    }
+    /* TODO Not supporting long arguments currently
+    static public void computeConvert(TestConvert.ArgumentsUcharLong args) {
+        args.out = convertUcharToLong(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsUcharUlong args) {
+        args.out = convertUcharToUlong(args.inV);
+    }
+    */
+    static public void computeConvert(TestConvert.ArgumentsUcharFloat args) {
+        args.out = new Floaty(convertUcharToFloat(args.inV), 0, 0);
+    }
+    /* TODO Not supporting double arguments currently
+    static public void computeConvert(TestConvert.ArgumentsUcharDouble args) {
+        args.out = new Floaty(convertUcharToDouble(args.inV), 0, 0);
+    }
+    */
+
+    static public void computeConvert(TestConvert.ArgumentsShortChar args) {
+        args.out = convertShortToChar(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsShortUchar args) {
+        args.out = convertShortToUchar(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsShortShort args) {
+        args.out = convertShortToShort(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsShortUshort args) {
+        args.out = convertShortToUshort(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsShortInt args) {
+        args.out = convertShortToInt(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsShortUint args) {
+        args.out = convertShortToUint(args.inV);
+    }
+    /* TODO Not supporting long arguments currently
+    static public void computeConvert(TestConvert.ArgumentsShortLong args) {
+        args.out = convertShortToLong(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsShortUlong args) {
+        args.out = convertShortToUlong(args.inV);
+    }
+    */
+    static public void computeConvert(TestConvert.ArgumentsShortFloat args) {
+        args.out = new Floaty(convertShortToFloat(args.inV), 0, 0);
+    }
+    /* TODO Not supporting double arguments currently
+    static public void computeConvert(TestConvert.ArgumentsShortDouble args) {
+        args.out = new Floaty(convertShortToDouble(args.inV), 0, 0);
+    }
+    */
+
+    static public void computeConvert(TestConvert.ArgumentsUshortChar args) {
+        args.out = convertUshortToChar(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsUshortUchar args) {
+        args.out = convertUshortToUchar(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsUshortShort args) {
+        args.out = convertUshortToShort(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsUshortUshort args) {
+        args.out = convertUshortToUshort(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsUshortInt args) {
+        args.out = convertUshortToInt(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsUshortUint args) {
+        args.out = convertUshortToUint(args.inV);
+    }
+    /* TODO Not supporting long arguments currently
+    static public void computeConvert(TestConvert.ArgumentsUshortLong args) {
+        args.out = convertUshortToLong(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsUshortUlong args) {
+        args.out = convertUshortToUlong(args.inV);
+    }
+    */
+    static public void computeConvert(TestConvert.ArgumentsUshortFloat args) {
+        args.out = new Floaty(convertUshortToFloat(args.inV), 0, 0);
+    }
+    /* TODO Not supporting double arguments currently
+    static public void computeConvert(TestConvert.ArgumentsUshortDouble args) {
+        args.out = new Floaty(convertUshortToDouble(args.inV), 0, 0);
+    }
+    */
+
+    static public void computeConvert(TestConvert.ArgumentsIntChar args) {
+        args.out = convertIntToChar(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsIntUchar args) {
+        args.out = convertIntToUchar(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsIntShort args) {
+        args.out = convertIntToShort(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsIntUshort args) {
+        args.out = convertIntToUshort(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsIntInt args) {
+        args.out = convertIntToInt(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsIntUint args) {
+        args.out = convertIntToUint(args.inV);
+    }
+    /* TODO Not supporting long arguments currently
+    static public void computeConvert(TestConvert.ArgumentsIntLong args) {
+        args.out = convertIntToLong(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsIntUlong args) {
+        args.out = convertIntToUlong(args.inV);
+    }
+    */
+    static public void computeConvert(TestConvert.ArgumentsIntFloat args) {
+        args.out = new Floaty(convertIntToFloat(args.inV), 1, 1);
+    }
+    /* TODO Not supporting double arguments currently
+    static public void computeConvert(TestConvert.ArgumentsIntDouble args) {
+        args.out = new Floaty(convertIntToDouble(args.inV), 0, 0);
+    }
+    */
+
+    static public void computeConvert(TestConvert.ArgumentsUintChar args) {
+        args.out = convertUintToChar(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsUintUchar args) {
+        args.out = convertUintToUchar(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsUintShort args) {
+        args.out = convertUintToShort(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsUintUshort args) {
+        args.out = convertUintToUshort(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsUintInt args) {
+        args.out = convertUintToInt(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsUintUint args) {
+        args.out = convertUintToUint(args.inV);
+    }
+    /* TODO Not supporting long arguments currently
+    static public void computeConvert(TestConvert.ArgumentsUintLong args) {
+        args.out = convertUintToLong(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsUintUlong args) {
+        args.out = convertUintToUlong(args.inV);
+    }
+    */
+    static public void computeConvert(TestConvert.ArgumentsUintFloat args) {
+        args.out = new Floaty(convertUintToFloat(args.inV), 1, 1);
+    }
+    /* TODO Not supporting double arguments currently
+    static public void computeConvert(TestConvert.ArgumentsUintDouble args) {
+        args.out = new Floaty(convertUintToDouble(args.inV), 0, 0);
+    }
+    */
+
+    /* TODO Not supporting long arguments currently
+    static public void computeConvert(TestConvert.ArgumentsLongChar args) {
+        args.out = convertLongToChar(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsLongUchar args) {
+        args.out = convertLongToUchar(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsLongShort args) {
+        args.out = convertLongToShort(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsLongUshort args) {
+        args.out = convertLongToUshort(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsLongInt args) {
+        args.out = convertLongToInt(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsLongUint args) {
+        args.out = convertLongToUint(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsLongLong args) {
+        args.out = convertLongToLong(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsLongUlong args) {
+        args.out = convertLongToUlong(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsLongFloat args) {
+        args.out = new Floaty(convertLongToFloat(args.inV), 1, 1);
+    }
+    static public void computeConvert(TestConvert.ArgumentsLongDouble args) {
+        args.out = new Floaty(convertLongToDouble(args.inV), 1, 1);
+    }
+
+    static public void computeConvert(TestConvert.ArgumentsUlongChar args) {
+        args.out = convertUlongToChar(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsUlongUchar args) {
+        args.out = convertUlongToUchar(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsUlongShort args) {
+        args.out = convertUlongToShort(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsUlongUshort args) {
+        args.out = convertUlongToUshort(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsUlongInt args) {
+        args.out = convertUlongToInt(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsUlongUint args) {
+        args.out = convertUlongToUint(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsUlongLong args) {
+        args.out = convertUlongToLong(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsUlongUlong args) {
+        args.out = convertUlongToUlong(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsUlongFloat args) {
+        args.out = new Floaty(convertUlongToFloat(args.inV), 1, 1);
+    }
+    static public void computeConvert(TestConvert.ArgumentsUlongDouble args) {
+        args.out = new Floaty(convertUlongToDouble(args.inV), 1, 1);
+    }
+    */
+
+    static public void computeConvert(TestConvert.ArgumentsFloatChar args) {
+        args.out = convertFloatToChar(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsFloatUchar args) {
+        args.out = convertFloatToUchar(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsFloatShort args) {
+        args.out = convertFloatToShort(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsFloatUshort args) {
+        args.out = convertFloatToUshort(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsFloatInt args) {
+        args.out = convertFloatToInt(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsFloatUint args) {
+        args.out = convertFloatToUint(args.inV);
+    }
+    /* TODO Not supporting long arguments currently
+    static public void computeConvert(TestConvert.ArgumentsFloatLong args) {
+        args.out = convertFloatToLong(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsFloatUlong args) {
+        args.out = convertFloatToUlong(args.inV);
+    }
+    */
+    static public void computeConvert(TestConvert.ArgumentsFloatFloat args) {
+        args.out = new Floaty(convertFloatToFloat(args.inV), 0, 0);
+    }
+    /* TODO Not supporting double arguments currently
+    static public void computeConvert(TestConvert.ArgumentsFloatDouble args) {
+        args.out = new Floaty(convertFloatToDouble(args.inV), 0, 0);
+    }
+    */
+
+    /* TODO Not supporting double arguments currently
+    static public void computeConvert(TestConvert.ArgumentsDoubleChar args) {
+        args.out = convertDoubleToChar(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsDoubleUchar args) {
+        args.out = convertDoubleToUchar(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsDoubleShort args) {
+        args.out = convertDoubleToShort(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsDoubleUshort args) {
+        args.out = convertDoubleToUshort(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsDoubleInt args) {
+        args.out = convertDoubleToInt(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsDoubleUint args) {
+        args.out = convertDoubleToUint(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsDoubleLong args) {
+        args.out = convertDoubleToLong(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsDoubleUlong args) {
+        args.out = convertDoubleToUlong(args.inV);
+    }
+    static public void computeConvert(TestConvert.ArgumentsDoubleFloat args) {
+        args.out = new Floaty(convertDoubleToFloat(args.inV), 1, 1);
+    }
+    static public void computeConvert(TestConvert.ArgumentsDoubleDouble args) {
+        args.out = new Floaty(convertDoubleToDouble(args.inV), 0, 0);
+    }
+    */
+
+    static public void computeCopysign(TestCopysign.ArgumentsFloatFloatFloat args) {
+        args.out = new Floaty(Math.copySign(args.inX, args.inY), 0, 0);
+    }
+
+    static public void computeCos(TestCos.ArgumentsFloatFloat args) {
+        args.out = new Floaty(cos(args.in), 4, 128);
+    }
+
+    static public void computeCosh(TestCosh.ArgumentsFloatFloat args) {
+        args.out = new Floaty(cosh(args.in), 4, 128);
+    }
+
+    static public void computeCospi(TestCospi.ArgumentsFloatFloat args) {
+        args.out = new Floaty(cos(args.in * (float) Math.PI), 4, 128);
+    }
+
+    static public void computeCross(TestCross.ArgumentsFloatNFloatNFloatN args) {
+        cross(args.inLhs, args.inRhs, args.out);
+    }
+
+    static public void computeDegrees(TestDegrees.ArgumentsFloatFloat args) {
+        args.out = new Floaty(args.inValue * (float)(180.0 / Math.PI), 3, 3);
+    }
+
+    static public void computeDistance(TestDistance.ArgumentsFloatFloatFloat args) {
+        args.out = distance(new float[] {args.inLhs}, new float[] {args.inRhs}, 1, 1);
+    }
+
+    static public void computeDistance(TestDistance.ArgumentsFloatNFloatNFloat args) {
+        args.out = distance(args.inLhs, args.inRhs, 1, 1);
+    }
+
+    static public void computeDot(TestDot.ArgumentsFloatFloatFloat args) {
+        args.out = new Floaty(args.inLhs * args.inRhs);
+    }
+
+    static public void computeDot(TestDot.ArgumentsFloatNFloatNFloat args) {
+        Floaty sum = new Floaty(0.0f);
+        for (int i = 0; i < args.inLhs.length; i++) {
+            Floaty a = new Floaty(args.inLhs[i]);
+            Floaty b = new Floaty(args.inRhs[i]);
+            sum.add(Floaty.multiply(a, b));
+        }
+        args.out = sum;
+    }
+
+    static public void computeErf(TestErf.ArgumentsFloatFloat args) {
+        args.out = new Floaty(erf(args.in), 16, 128);
+    }
+
+    static public void computeErfc(TestErfc.ArgumentsFloatFloat args) {
+        args.out = new Floaty(erfc(args.in), 16, 128);
+    }
+
+    static public void computeExp(TestExp.ArgumentsFloatFloat args) {
+        // TODO Should the relaxed ulp be 128?
+        args.out = new Floaty(exp(args.in), 3, 16);
+    }
+
+    static public void computeExp10(TestExp10.ArgumentsFloatFloat args) {
+        // TODO OpenCL says 3, we needed 32 in both to pass.
+        args.out = new Floaty(exp10(args.in), 32, 32);
+    }
+
+    static public void computeExp2(TestExp2.ArgumentsFloatFloat args) {
+        args.out = new Floaty(exp2(args.in), 3, 16);
+    }
+
+    static public void computeExpm1(TestExpm1.ArgumentsFloatFloat args) {
+        args.out = new Floaty(expm1(args.in), 3, 16);
+    }
+
+    static public void computeFabs(TestFabs.ArgumentsFloatFloat args) {
+        args.out = new Floaty(Math.abs(args.in), 0, 0);
+    }
+
+    static public void computeFastDistance(TestFastDistance.ArgumentsFloatFloatFloat args) {
+        args.out = distance(new float[] {args.inLhs}, new float[] {args.inRhs},
+                FAST_PRECISION, FAST_PRECISION);
+    }
+
+    static public void computeFastDistance(TestFastDistance.ArgumentsFloatNFloatNFloat args) {
+        args.out = distance(args.inLhs, args.inRhs, FAST_PRECISION, FAST_PRECISION);
+    }
+
+    static public void computeFastLength(TestFastLength.ArgumentsFloatFloat args) {
+        args.out = length(new float[] {args.inV}, FAST_PRECISION, FAST_PRECISION);
+    }
+
+    static public void computeFastLength(TestFastLength.ArgumentsFloatNFloat args) {
+        args.out = length(args.inV, FAST_PRECISION, FAST_PRECISION);
+    }
+
+    static public void computeFastNormalize(TestFastNormalize.ArgumentsFloatFloat args) {
+        Floaty[] out = new Floaty[1];
+        normalize(new float[] {args.inV}, out, FAST_PRECISION, FAST_PRECISION);
+        args.out = out[0];
+    }
+
+    static public void computeFastNormalize(TestFastNormalize.ArgumentsFloatNFloatN args) {
+        normalize(args.inV, args.out, FAST_PRECISION, FAST_PRECISION);
+    }
+
+    static public void computeFdim(TestFdim.ArgumentsFloatFloatFloat args) {
+        args.out = new Floaty(Math.max(0f, args.inA - args.inB), 0, 0);
+    }
+
+    static public void computeFloor(TestFloor.ArgumentsFloatFloat args) {
+        args.out = new Floaty(floor(args.in), 0, 0);
+    }
+
+    static public void computeFma(TestFma.ArgumentsFloatFloatFloatFloat args) {
+        Floaty ab = Floaty.multiply(new Floaty(args.inA), new Floaty(args.inB));
+        ab.add(new Floaty(args.inC));
+        args.out = ab;
+    }
+
+    static public void computeFmax(TestFmax.ArgumentsFloatFloatFloat args) {
+        args.out = new Floaty(Math.max(args.inX, args.inY), 0, 0);
+    }
+
+    static public void computeFmin(TestFmin.ArgumentsFloatFloatFloat args) {
+        args.out = new Floaty(Math.min(args.inX, args.inY), 0, 0);
+    }
+
+    static public void computeFmod(TestFmod.ArgumentsFloatFloatFloat args) {
+        args.out = new Floaty(args.inX % args.inY, 0, 0);
+    }
+
+    static public void computeFract(TestFract.ArgumentsFloatFloatFloat args) {
+        float floor = floor(args.inV);
+        args.outFloor = new Floaty(floor);
+        // 0x1.fffffep-1f is 0.999999...
+        args.out = new Floaty(Math.min(args.inV - floor, 0x1.fffffep-1f), 0, 1);
+    }
+
+    static public void computeFract(TestFract.ArgumentsFloatFloat args) {
+        float floor = floor(args.inV);
+        // 0x1.fffffep-1f is 0.999999...
+        args.out = new Floaty(Math.min(args.inV - floor, 0x1.fffffep-1f), 0, 1);
+    }
+
+    static public void computeFrexp(TestFrexp.ArgumentsFloatIntFloat args) {
+        FrexpResult result = frexp(args.inV);
+        args.out = new Floaty(result.significand, 0, 0);
+        args.outIptr = result.exponent;
+    }
+
+    static public void computeHalfRecip(TestHalfRecip.ArgumentsFloatFloat args) {
+        // TODO we would like to use HALF_PRECISION, HALF_PRECISION
+        args.out = new Floaty(1.0f / args.inV, 64000, 64000);
+    }
+
+    static public void computeHalfRsqrt(TestHalfRsqrt.ArgumentsFloatFloat args) {
+        // TODO we would like to use HALF_PRECISION, HALF_PRECISION
+        args.out = new Floaty(1.0f / sqrt(args.inV), HALF_PRECISION, 45000);
+    }
+
+    static public void computeHalfSqrt(TestHalfSqrt.ArgumentsFloatFloat args) {
+        // TODO we would like to use HALF_PRECISION, HALF_PRECISION
+        args.out = new Floaty(sqrt(args.inV), HALF_PRECISION, 80000);
+    }
+
+    static public void computeHypot(TestHypot.ArgumentsFloatFloatFloat args) {
+        args.out = new Floaty(hypot(args.inX, args.inY), 4, 4);
+    }
+
+    static public void computeIlogb(TestIlogb.ArgumentsFloatInt args) {
+        args.out = ilogb(args.in);
+    }
+
+    static public void computeLdexp(TestLdexp.ArgumentsFloatIntFloat args) {
+        args.out = new Floaty(ldexp(args.inX, args.inY), 0, 1);
+    }
+
+    static public void computeLength(TestLength.ArgumentsFloatFloat args) {
+        args.out = length(new float[] {args.inV}, 1, 1);
+    }
+
+    static public void computeLength(TestLength.ArgumentsFloatNFloat args) {
+        args.out = length(args.inV, 1, 1);
+    }
+
+    static public void computeLgamma(TestLgamma.ArgumentsFloatFloat args) {
+        args.out = new Floaty(lgamma(args.in), 16, 128);
+    }
+
+    static public void computeLgamma(TestLgamma.ArgumentsFloatIntFloat args) {
+        LgammaResult result = lgamma2(args.inX);
+        args.out = new Floaty(result.lgamma, 16, 128);
+        args.outY = result.gammaSign;
+    }
+
+    // TODO The relaxed ulf for the various log are taken from the old tests.
+    // They are not consistent.
+    static public void computeLog(TestLog.ArgumentsFloatFloat args) {
+        args.out = new Floaty(log(args.in), 3, 16);
+    }
+
+    static public void computeLog10(TestLog10.ArgumentsFloatFloat args) {
+        args.out = new Floaty(log10(args.in), 3, 16);
+    }
+
+    static public void computeLog1p(TestLog1p.ArgumentsFloatFloat args) {
+        args.out = new Floaty(log1p(args.in), 2, 16);
+    }
+
+    static public void computeLog2(TestLog2.ArgumentsFloatFloat args) {
+        args.out = new Floaty(log2(args.in), 3, 128);
+    }
+
+    static public void computeLogb(TestLogb.ArgumentsFloatFloat args) {
+        args.out = new Floaty(logb(args.in), 0, 0);
+    }
+
+    static public void computeMad(TestMad.ArgumentsFloatFloatFloatFloat args) {
+        args.out = Floaty.add(new Floaty(args.inA * args.inB), new Floaty(args.inC));
+    }
+
+    static public void computeMax(TestMax.ArgumentsCharCharChar args) {
+        args.out = maxI8(args.inV1, args.inV2);
+    }
+
+    static public void computeMax(TestMax.ArgumentsUcharUcharUchar args) {
+        args.out = maxU8(args.inV1, args.inV2);
+    }
+
+    static public void computeMax(TestMax.ArgumentsShortShortShort args) {
+        args.out = maxI16(args.inV1, args.inV2);
+    }
+
+    static public void computeMax(TestMax.ArgumentsUshortUshortUshort args) {
+        args.out = maxU16(args.inV1, args.inV2);
+    }
+
+    static public void computeMax(TestMax.ArgumentsIntIntInt args) {
+        args.out = maxI32(args.inV1, args.inV2);
+    }
+
+    static public void computeMax(TestMax.ArgumentsUintUintUint args) {
+        args.out = maxU32(args.inV1, args.inV2);
+    }
+
+    /* TODO enable once precision has been improved.
+    static public void computeMax(TestMax.ArgumentsLongLongLong args) {
+        args.out = maxI64(args.inV1, args.inV2);
+    }
+
+    static public void computeMax(TestMax.ArgumentsUlongUlongUlong args) {
+        args.out = maxU64(args.inV1, args.inV2);
+    }
+    */
+
+    static public void computeMax(TestMax.ArgumentsFloatFloatFloat args) {
+        args.out = new Floaty(Math.max(args.in, args.in1), 0, 0);
+    }
+
+    static public void computeMin(TestMin.ArgumentsCharCharChar args) {
+        args.out = minI8(args.inV1, args.inV2);
+    }
+
+    static public void computeMin(TestMin.ArgumentsUcharUcharUchar args) {
+        args.out = minU8(args.inV1, args.inV2);
+    }
+
+    static public void computeMin(TestMin.ArgumentsShortShortShort args) {
+        args.out = minI16(args.inV1, args.inV2);
+    }
+
+    static public void computeMin(TestMin.ArgumentsUshortUshortUshort args) {
+        args.out = minU16(args.inV1, args.inV2);
+    }
+
+    static public void computeMin(TestMin.ArgumentsIntIntInt args) {
+        args.out = minI32(args.inV1, args.inV2);
+    }
+
+    static public void computeMin(TestMin.ArgumentsUintUintUint args) {
+        args.out = minU32(args.inV1, args.inV2);
+    }
+
+    /* TODO enable once precision has been improved.
+    static public void computeMin(TestMin.ArgumentsLongLongLong args) {
+        args.out = minI64(args.inV1, args.inV2);
+    }
+
+    static public void computeMin(TestMin.ArgumentsUlongUlongUlong args) {
+        args.out = minU64(args.inV1, args.inV2);
+    }
+    */
+
+    static public void computeMin(TestMin.ArgumentsFloatFloatFloat args) {
+        args.out = new Floaty(Math.min(args.in, args.in1), 0, 0);
+    }
+
+    static public void computeMix(TestMix.ArgumentsFloatFloatFloatFloat args) {
+        Floaty start = new Floaty(args.inStart);
+        Floaty stop = new Floaty(args.inStop);
+        Floaty diff = Floaty.subtract(stop, start);
+        args.out = Floaty.add(start, Floaty.multiply(diff, new Floaty(args.inAmount)));
+    }
+
+    static public void computeModf(TestModf.ArgumentsFloatFloatFloat args) {
+        float ret = (float)(int)args.inX;
+        args.outIret = new Floaty(ret);
+        args.out = new Floaty(args.inX - ret, 0, 0);
+    }
+
+    static public void computeNan(TestNan.ArgumentsUintFloat args) {
+        // TODO Should we use the input arg?
+        args.out = new Floaty(Float.NaN, 0, 0);
+    }
+
+    static public void computeNativeExp(TestNativeExp.ArgumentsFloatFloat args) {
+        // TODO we would like to use NATIVE_PRECISION, NATIVE_PRECISION
+        args.out = new Floaty(exp(args.inV), 9500, 9500);
+    }
+
+    static public void computeNativeExp10(TestNativeExp10.ArgumentsFloatFloat args) {
+        // TODO we would like to use NATIVE_PRECISION, NATIVE_PRECISION
+        args.out = new Floaty(exp10(args.inV), 13000, 13000);
+    }
+
+    static public void computeNativeExp2(TestNativeExp2.ArgumentsFloatFloat args) {
+        // TODO we would like to use NATIVE_PRECISION, NATIVE_PRECISION
+        args.out = new Floaty(exp2(args.inV), 13000, 13000);
+    }
+
+    static public void computeNativeLog(TestNativeLog.ArgumentsFloatFloat args) {
+        args.out = new Floaty(log(args.inV), NATIVE_PRECISION, NATIVE_PRECISION);
+    }
+
+    static public void computeNativeLog10(TestNativeLog10.ArgumentsFloatFloat args) {
+        args.out = new Floaty(log10(args.inV), NATIVE_PRECISION, NATIVE_PRECISION);
+    }
+
+    static public void computeNativeLog2(TestNativeLog2.ArgumentsFloatFloat args) {
+        args.out = new Floaty(log2(args.inV), NATIVE_PRECISION, NATIVE_PRECISION);
+    }
+
+    /* TODO enable once fixed handling of v = 0
+    static public void computeNativePowr(TestNativePowr.ArgumentsFloatFloatFloat args) {
+        // TODO we would like to use NATIVE_PRECISION, NATIVE_PRECISION
+        args.out = new Floaty(pow(args.inV, args.inY), 32000, 32000);
+    }
+    */
+
+    static public void computeNextafter(TestNextafter.ArgumentsFloatFloatFloat args) {
+        args.out = new Floaty(Math.nextAfter(args.inX, args.inY), 0, 0);
+    }
+
+    static public void computeNormalize(TestNormalize.ArgumentsFloatFloat args) {
+        Floaty[] out = new Floaty[1];
+        normalize(new float[] {args.inV}, out, 1, 1);
+        args.out = new Floaty(out[0]);
+    }
+
+    static public void computeNormalize(TestNormalize.ArgumentsFloatNFloatN args) {
+        normalize(args.inV, args.out, 1, 1);
+    }
+
+    static public void computePow(TestPow.ArgumentsFloatFloatFloat args) {
+        args.out = new Floaty(pow(args.inX, args.inY), 16, 128);
+    }
+
+    static public void computePown(TestPown.ArgumentsFloatIntFloat args) {
+        args.out = new Floaty((float) Math.pow(args.inX, (double) args.inY), 16, 128);
+    }
+
+    static public void computePowr(TestPowr.ArgumentsFloatFloatFloat args) {
+        args.out = new Floaty(pow(args.inX, args.inY), 16, 128);
+    }
+
+    static public void computeRadians(TestRadians.ArgumentsFloatFloat args) {
+        args.out = new Floaty(args.inValue * (float)(Math.PI / 180.0));
+    }
+
+    static public void computeRemainder(TestRemainder.ArgumentsFloatFloatFloat args) {
+        RemquoResult result = remquo(args.inX, args.inY);
+        args.out = new Floaty(result.remainder, 0, 0);
+    }
+
+    static public void computeRemquo(TestRemquo.ArgumentsFloatFloatIntFloat args) {
+        RemquoResult result = remquo(args.inB, args.inC);
+        args.out = new Floaty(result.remainder, 0, 0);
+        args.outD = result.quotient;
+    }
+
+    static public void computeRint(TestRint.ArgumentsFloatFloat args) {
+        args.out = new Floaty(rint(args.in), 0, 0);
+    }
+
+    /* TODO re-enable once zero issues resolved
+    static public void computeRootn(TestRootn.ArgumentsFloatIntFloat args) {
+        (* Rootn of a negative number should be possible only if the number
+         * is odd.  In cases where the int is very large, our approach will
+         * lose whether the int is odd, and we'll get a NaN for weird cases
+         * like rootn(-3.95, 818181881), which should return 1.  We handle the
+         * case by handling the sign ourselves.  We use copysign to handle the
+         * negative zero case.
+         *)
+        float value;
+        if ((args.inN & 0x1) == 0x1) {
+            value = Math.copySign(pow(Math.abs(args.inV), 1.0f / args.inN),
+                    args.inV);
+        } else {
+            value = pow(args.inV, 1.0f / args.inN);
+        }
+        args.out = new Floaty(value, 16, 16);
+        // args.out = new Floaty(Math.pow(args.inV, 1.0 / (double)args.inN), 16, 16);
+    }
+    */
+
+
+    static public void computeRound(TestRound.ArgumentsFloatFloat args) {
+        args.out = new Floaty(round(args.in), 0, 0);
+    }
+
+    static public void computeRsqrt(TestRsqrt.ArgumentsFloatFloat args) {
+        args.out = new Floaty(1f / sqrt(args.in), 2, 2);
+    }
+
+    static public void computeSign(TestSign.ArgumentsFloatFloat args) {
+        args.out = new Floaty(Math.signum(args.inV), 0, 0);
+    }
+
+    static public void computeSin(TestSin.ArgumentsFloatFloat args) {
+        args.out = new Floaty(sin(args.in), 4, 128);
+    }
+
+    static public void computeSincos(TestSincos.ArgumentsFloatFloatFloat args) {
+        args.outCosptr = new Floaty(cos(args.inV), 4, 128);
+        args.out = new Floaty(sin(args.inV), 4, 128);
+    }
+
+    static public void computeSinh(TestSinh.ArgumentsFloatFloat args) {
+        args.out = new Floaty(sinh(args.in), 4, 128);
+    }
+
+    static public void computeSinpi(TestSinpi.ArgumentsFloatFloat args) {
+        args.out = new Floaty(sin(args.in * (float) Math.PI), 4, 128);
+    }
+
+    static public void computeSqrt(TestSqrt.ArgumentsFloatFloat args) {
+        args.out = new Floaty(sqrt(args.in), 3, 3);
+    }
+
+    static public void computeStep(TestStep.ArgumentsFloatFloatFloat args) {
+        args.out = new Floaty(args.inV < args.inEdge ? 0f : 1f, 0, 0);
+    }
+
+    static public void computeTan(TestTan.ArgumentsFloatFloat args) {
+        args.out = new Floaty(tan(args.in), 5, 128);
+    }
+
+    static public void computeTanh(TestTanh.ArgumentsFloatFloat args) {
+        args.out = new Floaty(tanh(args.in), 5, 128);
+    }
+
+    static public void computeTanpi(TestTanpi.ArgumentsFloatFloat args) {
+        args.out = new Floaty(tan(args.in * (float) Math.PI), 6, 128);
+    }
+
+    static public void computeTgamma(TestTgamma.ArgumentsFloatFloat args) {
+        args.out = new Floaty(tgamma(args.in), 16, 128);
+    }
+
+    static public void computeTrunc(TestTrunc.ArgumentsFloatFloat args) {
+        args.out = new Floaty(trunc(args.in), 0, 0);
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/CosTest.java b/tests/tests/renderscript/src/android/renderscript/cts/CosTest.java
deleted file mode 100644
index dd5db8a..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/CosTest.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * 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 android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import com.android.cts.stub.R;
-
-public class CosTest extends RSBaseCompute {
-    private ScriptC_cos_f32 script_f32;
-    private ScriptC_cos_f32_relaxed script_f32_relaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script_f32 = new ScriptC_cos_f32(mRS);
-        script_f32_relaxed = new ScriptC_cos_f32_relaxed(mRS);
-    }
-
-    @Override
-    public void forEach(int testId, Allocation mIn, Allocation mOut) throws RSRuntimeException {
-        switch (testId) {
-        case TEST_F32:
-            script_f32.forEach_cos_f32_1(mIn, mOut);
-            break;
-        case TEST_F32_2:
-            script_f32.forEach_cos_f32_2(mIn, mOut);
-            break;
-        case TEST_F32_3:
-            script_f32.forEach_cos_f32_3(mIn, mOut);
-            break;
-        case TEST_F32_4:
-            script_f32.forEach_cos_f32_4(mIn, mOut);
-            break;
-
-        case TEST_RELAXED_F32:
-            script_f32_relaxed.forEach_cos_f32_1(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_2:
-            script_f32_relaxed.forEach_cos_f32_2(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_3:
-            script_f32_relaxed.forEach_cos_f32_3(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_4:
-            script_f32_relaxed.forEach_cos_f32_4(mIn, mOut);
-            break;
-        }
-    }
-
-    @Override
-    protected float[] getRefArray(float[] in, int input_size, int stride, int skip) {
-        float[] ref = new float[input_size * stride];
-        for (int i = 0; i < input_size; i++) {
-            for (int j = 0; j < stride - skip; j++) {
-                int idx= i * stride + j;
-                int idxRef = i * (stride - skip) + j;
-                ref[idxRef] = (float)(Math.cos((double)in[idx]));
-            }
-        }
-        return ref;
-    }
-
-    public void testCosF32() {
-        doF32(0xe, 4);
-    }
-
-    public void testCosF32_relaxed() {
-        doF32_relaxed(0xe, 4);
-    }
-
-    public void testCosF32_2() {
-        doF32_2(0xb, 4);
-    }
-
-    public void testCosF32_2_relaxed() {
-        doF32_2_relaxed(0xb, 4);
-    }
-
-    public void testCosF32_3() {
-        doF32_3(0x12a, 4);
-    }
-
-    public void testCosF32_3_relaxed() {
-        doF32_3_relaxed(0x12a, 4);
-    }
-
-    public void testCosF32_4() {
-        doF32_4(0x98a, 4);
-
-    }
-    public void testCosF32_4_relaxed() {
-        doF32_4_relaxed(0x98a, 4);
-    }
-
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/CoshTest.java b/tests/tests/renderscript/src/android/renderscript/cts/CoshTest.java
deleted file mode 100644
index 9fa3603..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/CoshTest.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * 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 android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import com.android.cts.stub.R;
-import android.renderscript.RSRuntimeException;
-
-public class CoshTest extends RSBaseCompute {
-
-    private ScriptC_cosh_f32 script_f32;
-    private ScriptC_cosh_f32_relaxed script_f32_relaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script_f32 = new ScriptC_cosh_f32(mRS);
-        script_f32_relaxed = new ScriptC_cosh_f32_relaxed(mRS);
-    }
-
-    @Override
-    public void forEach(int testId, Allocation mIn, Allocation mOut) throws RSRuntimeException {
-        switch (testId) {
-        case TEST_F32:
-            script_f32.forEach_cosh_f32_1(mIn, mOut);
-            break;
-        case TEST_F32_2:
-            script_f32.forEach_cosh_f32_2(mIn, mOut);
-            break;
-        case TEST_F32_3:
-            script_f32.forEach_cosh_f32_3(mIn, mOut);
-            break;
-        case TEST_F32_4:
-            script_f32.forEach_cosh_f32_4(mIn, mOut);
-            break;
-
-        case TEST_RELAXED_F32:
-            script_f32_relaxed.forEach_cosh_f32_1(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_2:
-            script_f32_relaxed.forEach_cosh_f32_2(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_3:
-            script_f32_relaxed.forEach_cosh_f32_3(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_4:
-            script_f32_relaxed.forEach_cosh_f32_4(mIn, mOut);
-            break;
-        }
-    }
-
-    @Override
-    protected float[] getRefArray(float[] in, int input_size, int stride, int skip) {
-        float[] ref = new float[input_size * stride];
-        for (int i = 0; i < input_size; i++) {
-            for (int j = 0; j < stride - skip; j++) {
-                int idx= i * stride + j;
-                int idxRef = i * (stride - skip) + j;
-                ref[idxRef] = (float)(Math.cosh((double)in[idx]));
-            }
-        }
-        return ref;
-    }
-
-    public void testCoshF32() {
-        doF32(0xfe, 4);
-    }
-
-    public void testCoshF32_relaxed() {
-        doF32_relaxed(0xfe, 128);
-    }
-
-    public void testCoshF32_2() {
-        doF32_2(0x71, 4);
-    }
-
-    public void testCoshF32_2_relaxed() {
-        doF32_2_relaxed(0x71, 128);
-    }
-
-    public void testCoshF32_3() {
-        doF32_3(0xa, 4);
-    }
-
-    public void testCoshF32_3_relaxed() {
-        doF32_3_relaxed(0xa, 128);
-    }
-
-    public void testCoshF32_4() {
-        doF32_4(0xabe, 4);
-
-    }
-    public void testCoshF32_4_relaxed() {
-        doF32_4_relaxed(0xabe, 128);
-    }
-
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/CrossTest.java b/tests/tests/renderscript/src/android/renderscript/cts/CrossTest.java
deleted file mode 100644
index 308f5f4..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/CrossTest.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * 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 android.renderscript.cts;
-
-import com.android.cts.stub.R;
-import android.renderscript.Allocation;
-import android.renderscript.Element;
-import android.renderscript.RSRuntimeException;
-
-public class CrossTest extends RSBaseCompute {
-    private ScriptC_cross_f32 script_f32;
-    private ScriptC_cross_f32_relaxed script_f32_relaxed;
-    private Allocation mIn;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script_f32 = new ScriptC_cross_f32(mRS);
-        script_f32_relaxed = new ScriptC_cross_f32_relaxed(mRS);
-    }
-
-    @Override
-    public void forEach(int testId, Allocation mIn, Allocation mOut) throws RSRuntimeException {
-        switch (testId) {
-        case TEST_F32_3:
-            script_f32.forEach_cross_f32_3(mIn, mOut);
-            break;
-        case TEST_F32_4:
-            script_f32.forEach_cross_f32_4(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_3:
-            script_f32_relaxed.forEach_cross_f32_3(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_4:
-            script_f32_relaxed.forEach_cross_f32_4(mIn, mOut);
-            break;
-        }
-
-    }
-
-    @Override
-    protected float[] getRefArray(float[] in, int input_size, int stride, int skip) {
-        float[] ref = new float[input_size * stride];
-        for (int i = 0; i < input_size; i++) {
-            int idx= i * stride * 2;
-            int idxRef = i * (stride - skip);
-            ref[idxRef + 0] = in[idx+1] * in[idx+2+stride] - in[idx+2] * in[idx+1+stride];
-            ref[idxRef + 1] = in[idx+2] * in[idx+0+stride] - in[idx+0] * in[idx+2+stride];
-            ref[idxRef + 2] = in[idx+0] * in[idx+1+stride] - in[idx+1] * in[idx+0+stride];
-            if (skip == 1)
-                ref[idxRef + 3] = 0.f;
-        }
-        return ref;
-    }
-
-    @Override
-    protected Allocation setInAlloc(Element e) {
-        return mIn;
-    }
-
-    @Override
-    protected float[] makeInArray(int size) {
-        return new float[size*2];
-    }
-
-    /**
-     * cross test for float3
-     */
-    public void testCrossF32_3() {
-        ScriptField__cross_f32_3_struct in = new ScriptField__cross_f32_3_struct(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_3(0x12345678, 0);
-    }
-
-    /*
-    Disable until we can add an absolute error metric
-    public void testCrossF32_3_relaxed() {
-        ScriptField__cross_f32_3_struct in = new ScriptField__cross_f32_3_struct(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_3_relaxed(0x12345678, 2);
-    }
-    */
-
-
-    /**
-     * cross test for float4
-     */
-    public void testCrossF32_4() {
-        ScriptField__cross_f32_4_struct in = new ScriptField__cross_f32_4_struct(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_4(0x12ac5678, 0);
-    }
-
-    /*
-    Disable until we can add an absolute error metric
-    public void testCrossF32_4_relaxed() {
-        ScriptField__cross_f32_4_struct in = new ScriptField__cross_f32_4_struct(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_4_relaxed(0x12ac5678, 2);
-    }
-    */
-
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/DegreesTest.java b/tests/tests/renderscript/src/android/renderscript/cts/DegreesTest.java
deleted file mode 100644
index 38c4824..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/DegreesTest.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * 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 android.renderscript.cts;
-
-import com.android.cts.stub.R;
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-
-public class DegreesTest extends RSBaseCompute {
-    private ScriptC_degrees_f32 script_f32;
-    private ScriptC_degrees_f32_relaxed script_f32_relaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script_f32 = new ScriptC_degrees_f32(mRS);
-        script_f32_relaxed = new ScriptC_degrees_f32_relaxed(mRS);
-    }
-
-    @Override
-    public void forEach(int testId, Allocation mIn, Allocation mOut) throws RSRuntimeException {
-        switch (testId) {
-        case TEST_F32:
-            script_f32.forEach_degrees_f32_1(mIn, mOut);
-            break;
-        case TEST_F32_2:
-            script_f32.forEach_degrees_f32_2(mIn, mOut);
-            break;
-        case TEST_F32_3:
-            script_f32.forEach_degrees_f32_3(mIn, mOut);
-            break;
-        case TEST_F32_4:
-            script_f32.forEach_degrees_f32_4(mIn, mOut);
-            break;
-
-        case TEST_RELAXED_F32:
-            script_f32_relaxed.forEach_degrees_f32_1(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_2:
-            script_f32_relaxed.forEach_degrees_f32_2(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_3:
-            script_f32_relaxed.forEach_degrees_f32_3(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_4:
-            script_f32_relaxed.forEach_degrees_f32_4(mIn, mOut);
-            break;
-        }
-    }
-
-    @Override
-    protected float[] getRefArray(float[] in, int input_size, int stride, int skip) {
-        float[] ref = new float[input_size * stride];
-        for (int i = 0; i < input_size; i++) {
-            for (int j = 0; j < stride - skip; j++) {
-                int idx= i * stride + j;
-                int idxRef = i * (stride - skip) + j;
-                double val = (double)in[idx] * (180.0 / Math.PI);
-                ref[idxRef] = (float)val;
-            }
-        }
-        return ref;
-    }
-
-    /**
-     * degrees test for float
-     */
-    public void testDegreesF32() {
-        doF32(0x12345678, 3);
-    }
-
-    public void testDegreesF32_relaxed() {
-        doF32_relaxed(0x12345678, 3);
-    }
-
-    /**
-     * degrees test for float2
-     */
-    public void testDegreesF32_2() {
-        doF32_2(0x12353678, 3);
-    }
-
-    public void testDegreesF32_2_relaxed() {
-        doF32_2_relaxed(0x12353678, 3);
-    }
-
-    /**
-     * degrees test for float3
-     */
-    public void testDegreesF32_3() {
-        doF32_3(0x12312678, 3);
-    }
-
-    public void testDegreesF32_3_relaxed() {
-        doF32_3_relaxed(0x12312678, 3);
-    }
-
-    /**
-     * degrees test for float4
-     */
-    public void testDegreesF32_4() {
-        doF32_4(0x12675678, 3);
-
-    }
-    public void testDegreesF32_4_relaxed() {
-        doF32_4_relaxed(0x12675678, 3);
-    }
-
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/Exp10Test.java b/tests/tests/renderscript/src/android/renderscript/cts/Exp10Test.java
deleted file mode 100644
index 875af18..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/Exp10Test.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * 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 android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import com.android.cts.stub.R;
-
-public class Exp10Test extends RSBaseCompute {
-    private ScriptC_exp10_f32 script_f32;
-    private ScriptC_exp10_f32_relaxed script_f32_relaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script_f32 = new ScriptC_exp10_f32(mRS);
-        script_f32_relaxed = new ScriptC_exp10_f32_relaxed(mRS);
-    }
-
-    @Override
-    public void forEach(int testId, Allocation mIn, Allocation mOut) throws RSRuntimeException {
-        switch (testId) {
-        case TEST_F32:
-            script_f32.forEach_exp10_f32_1(mIn, mOut);
-            break;
-        case TEST_F32_2:
-            script_f32.forEach_exp10_f32_2(mIn, mOut);
-            break;
-        case TEST_F32_3:
-            script_f32.forEach_exp10_f32_3(mIn, mOut);
-            break;
-        case TEST_F32_4:
-            script_f32.forEach_exp10_f32_4(mIn, mOut);
-            break;
-
-        case TEST_RELAXED_F32:
-            script_f32_relaxed.forEach_exp10_f32_1(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_2:
-            script_f32_relaxed.forEach_exp10_f32_2(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_3:
-            script_f32_relaxed.forEach_exp10_f32_3(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_4:
-            script_f32_relaxed.forEach_exp10_f32_4(mIn, mOut);
-            break;
-        }
-    }
-
-    @Override
-    protected float[] getRefArray(float[] in, int input_size, int stride, int skip) {
-        float[] ref = new float[input_size * stride];
-        for (int i = 0; i < input_size; i++) {
-            for (int j = 0; j < stride - skip; j++) {
-                int idx= i * stride + j;
-                int idxRef = i * (stride - skip) + j;
-                ref[idxRef] = (float)(Math.pow(10, (double)in[idx]));
-            }
-        }
-        return ref;
-    }
-
-    public void testExp10F32() {
-        doF32(0x81, 3);
-    }
-
-    public void testExp10F32_relaxed() {
-        doF32_relaxed(0x81, 16);
-    }
-
-    public void testExp10F32_2() {
-        doF32_2(0xa42, 3);
-    }
-
-    public void testExp10F32_2_relaxed() {
-        doF32_2_relaxed(0xa42, 16);
-    }
-
-    public void testExp10F32_3() {
-        doF32_3(0xace2, 3);
-    }
-
-    public void testExp10F32_3_relaxed() {
-        doF32_3_relaxed(0xace2, 16);
-    }
-
-    public void testExp10F32_4() {
-        doF32_4(0x918, 3);
-
-    }
-    public void testExp10F32_4_relaxed() {
-        doF32_4_relaxed(0x918, 16);
-    }
-
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/Exp2Test.java b/tests/tests/renderscript/src/android/renderscript/cts/Exp2Test.java
deleted file mode 100644
index ac99b92..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/Exp2Test.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * 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 android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import com.android.cts.stub.R;
-
-public class Exp2Test extends RSBaseCompute {
-    private ScriptC_exp2_f32 script_f32;
-    private ScriptC_exp2_f32_relaxed script_f32_relaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script_f32 = new ScriptC_exp2_f32(mRS);
-        script_f32_relaxed = new ScriptC_exp2_f32_relaxed(mRS);
-    }
-
-    @Override
-    public void forEach(int testId, Allocation mIn, Allocation mOut) throws RSRuntimeException {
-        switch (testId) {
-        case TEST_F32:
-            script_f32.forEach_exp2_f32_1(mIn, mOut);
-            break;
-        case TEST_F32_2:
-            script_f32.forEach_exp2_f32_2(mIn, mOut);
-            break;
-        case TEST_F32_3:
-            script_f32.forEach_exp2_f32_3(mIn, mOut);
-            break;
-        case TEST_F32_4:
-            script_f32.forEach_exp2_f32_4(mIn, mOut);
-            break;
-
-        case TEST_RELAXED_F32:
-            script_f32_relaxed.forEach_exp2_f32_1(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_2:
-            script_f32_relaxed.forEach_exp2_f32_2(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_3:
-            script_f32_relaxed.forEach_exp2_f32_3(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_4:
-            script_f32_relaxed.forEach_exp2_f32_4(mIn, mOut);
-            break;
-        }
-    }
-
-    @Override
-    protected float[] getRefArray(float[] in, int input_size, int stride, int skip) {
-        float[] ref = new float[input_size * stride];
-        for (int i = 0; i < input_size; i++) {
-            for (int j = 0; j < stride - skip; j++) {
-                int idx= i * stride + j;
-                int idxRef = i * (stride - skip) + j;
-                ref[idxRef] = (float)(Math.pow(2, (double)in[idx]));
-            }
-        }
-        return ref;
-    }
-
-    public void testExp2F32() {
-        doF32(0xa6, 3);
-    }
-
-    public void testExp2F32_relaxed() {
-        doF32_relaxed(0xa6, 16);
-    }
-
-    public void testExp2F32_2() {
-        doF32_2(0xab2, 3);
-    }
-
-    public void testExp2F32_2_relaxed() {
-        doF32_2_relaxed(0xab2, 16);
-    }
-
-    public void testExp2F32_3() {
-        doF32_3(0x617a, 3);
-    }
-
-    public void testExp2F32_3_relaxed() {
-        doF32_3_relaxed(0x617a, 16);
-    }
-
-    public void testExp2F32_4() {
-        doF32_4(0xabc3, 3);
-
-    }
-    public void testExp2F32_4_relaxed() {
-        doF32_4_relaxed(0xabc3, 16);
-    }
-
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/ExpTest.java b/tests/tests/renderscript/src/android/renderscript/cts/ExpTest.java
deleted file mode 100644
index e2f86ca..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/ExpTest.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * 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 android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import com.android.cts.stub.R;
-
-public class ExpTest extends RSBaseCompute {
-    private ScriptC_exp_f32 script_f32;
-    private ScriptC_exp_f32_relaxed script_f32_relaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script_f32 = new ScriptC_exp_f32(mRS);
-        script_f32_relaxed = new ScriptC_exp_f32_relaxed(mRS);
-    }
-
-    @Override
-    public void forEach(int testId, Allocation mIn, Allocation mOut) throws RSRuntimeException {
-        switch (testId) {
-        case TEST_F32:
-            script_f32.forEach_exp_f32_1(mIn, mOut);
-            break;
-        case TEST_F32_2:
-            script_f32.forEach_exp_f32_2(mIn, mOut);
-            break;
-        case TEST_F32_3:
-            script_f32.forEach_exp_f32_3(mIn, mOut);
-            break;
-        case TEST_F32_4:
-            script_f32.forEach_exp_f32_4(mIn, mOut);
-            break;
-
-        case TEST_RELAXED_F32:
-            script_f32_relaxed.forEach_exp_f32_1(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_2:
-            script_f32_relaxed.forEach_exp_f32_2(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_3:
-            script_f32_relaxed.forEach_exp_f32_3(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_4:
-            script_f32_relaxed.forEach_exp_f32_4(mIn, mOut);
-            break;
-        }
-    }
-
-    @Override
-    protected float[] getRefArray(float[] in, int input_size, int stride, int skip) {
-        float[] ref = new float[input_size * stride];
-        for (int i = 0; i < input_size; i++) {
-            for (int j = 0; j < stride - skip; j++) {
-                int idx= i * stride + j;
-                int idxRef = i * (stride - skip) + j;
-                ref[idxRef] = (float)(Math.exp((double)in[idx]));
-            }
-        }
-        return ref;
-    }
-
-    public void testExpF32() {
-        doF32(0xa28, 3);
-    }
-
-    public void testExpF32_relaxed() {
-        doF32_relaxed(0xa28, 16);
-    }
-
-    public void testExpF32_2() {
-        doF32_2(0xfeb4, 3);
-    }
-
-    public void testExpF32_2_relaxed() {
-        doF32_2_relaxed(0xfeb4, 16);
-    }
-
-    public void testExpF32_3() {
-        doF32_3(0xab2, 3);
-    }
-
-    public void testExpF32_3_relaxed() {
-        doF32_3_relaxed(0xab2, 16);
-    }
-
-    public void testExpF32_4() {
-        doF32_4(0x7a6, 3);
-
-    }
-    public void testExpF32_4_relaxed() {
-        doF32_4_relaxed(0x7a6, 16);
-    }
-
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/Expm1Test.java b/tests/tests/renderscript/src/android/renderscript/cts/Expm1Test.java
deleted file mode 100644
index 36b65ff..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/Expm1Test.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * 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 android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import com.android.cts.stub.R;
-
-public class Expm1Test extends RSBaseCompute {
-    private ScriptC_expm1_f32 script_f32;
-    private ScriptC_expm1_f32_relaxed script_f32_relaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script_f32 = new ScriptC_expm1_f32(mRS);
-        script_f32_relaxed = new ScriptC_expm1_f32_relaxed(mRS);
-    }
-
-    @Override
-    public void forEach(int testId, Allocation mIn, Allocation mOut) throws RSRuntimeException {
-        switch (testId) {
-        case TEST_F32:
-            script_f32.forEach_expm1_f32_1(mIn, mOut);
-            break;
-        case TEST_F32_2:
-            script_f32.forEach_expm1_f32_2(mIn, mOut);
-            break;
-        case TEST_F32_3:
-            script_f32.forEach_expm1_f32_3(mIn, mOut);
-            break;
-        case TEST_F32_4:
-            script_f32.forEach_expm1_f32_4(mIn, mOut);
-            break;
-
-        case TEST_RELAXED_F32:
-            script_f32_relaxed.forEach_expm1_f32_1(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_2:
-            script_f32_relaxed.forEach_expm1_f32_2(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_3:
-            script_f32_relaxed.forEach_expm1_f32_3(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_4:
-            script_f32_relaxed.forEach_expm1_f32_4(mIn, mOut);
-            break;
-        }
-    }
-
-    @Override
-    protected float[] getRefArray(float[] in, int input_size, int stride, int skip) {
-        float[] ref = new float[input_size * stride];
-        for (int i = 0; i < input_size; i++) {
-            for (int j = 0; j < stride - skip; j++) {
-                int idx= i * stride + j;
-                int idxRef = i * (stride - skip) + j;
-                ref[idxRef] = (float)(Math.expm1((double)in[idx]));
-            }
-        }
-        return ref;
-    }
-
-    public void testExpm1F32() {
-        doF32(0xa29, 3);
-    }
-
-    public void testExpm1F32_relaxed() {
-        doF32_relaxed(0xa29, 16);
-    }
-
-    public void testExpm1F32_2() {
-        doF32_2(0x8a2, 3);
-    }
-
-    public void testExpm1F32_2_relaxed() {
-        doF32_2_relaxed(0x8a2, 16);
-    }
-
-    public void testExpm1F32_3() {
-        doF32_3(0xa7c, 3);
-    }
-
-    public void testExpm1F32_3_relaxed() {
-        doF32_3_relaxed(0xa7c, 16);
-    }
-
-    public void testExpm1F32_4() {
-        doF32_4(0x81a, 3);
-
-    }
-    public void testExpm1F32_4_relaxed() {
-        doF32_4_relaxed(0x81a, 16);
-    }
-
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/FabsTest.java b/tests/tests/renderscript/src/android/renderscript/cts/FabsTest.java
deleted file mode 100644
index e8739d4..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/FabsTest.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * 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 android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import com.android.cts.stub.R;
-
-public class FabsTest extends RSBaseCompute {
-    private ScriptC_fabs_f32 script_f32;
-    private ScriptC_fabs_f32_relaxed script_f32_relaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script_f32 = new ScriptC_fabs_f32(mRS);
-        script_f32_relaxed = new ScriptC_fabs_f32_relaxed(mRS);
-    }
-
-    @Override
-    public void forEach(int testId, Allocation mIn, Allocation mOut) throws RSRuntimeException {
-        switch (testId) {
-        case TEST_F32:
-            script_f32.forEach_fabs_f32_1(mIn, mOut);
-            break;
-        case TEST_F32_2:
-            script_f32.forEach_fabs_f32_2(mIn, mOut);
-            break;
-        case TEST_F32_3:
-            script_f32.forEach_fabs_f32_3(mIn, mOut);
-            break;
-        case TEST_F32_4:
-            script_f32.forEach_fabs_f32_4(mIn, mOut);
-            break;
-
-        case TEST_RELAXED_F32:
-            script_f32_relaxed.forEach_fabs_f32_1(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_2:
-            script_f32_relaxed.forEach_fabs_f32_2(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_3:
-            script_f32_relaxed.forEach_fabs_f32_3(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_4:
-            script_f32_relaxed.forEach_fabs_f32_4(mIn, mOut);
-            break;
-        }
-    }
-
-    @Override
-    protected float[] getRefArray(float[] in, int input_size, int stride, int skip) {
-        float[] ref = new float[input_size * stride];
-        for (int i = 0; i < input_size; i++) {
-            for (int j = 0; j < stride - skip; j++) {
-                int idx= i * stride + j;
-                int idxRef = i * (stride - skip) + j;
-                ref[idxRef] = Math.abs(in[idx]);
-            }
-        }
-        return ref;
-    }
-
-    public void testfabsF32() {
-        doF32(0xa, 0);
-    }
-
-    public void testfabsF32_relaxed() {
-        doF32_relaxed(0xa, 0);
-    }
-
-    public void testfabsF32_2() {
-        doF32_2(0xb, 0);
-    }
-
-    public void testfabsF32_2_relaxed() {
-        doF32_2_relaxed(0xb, 0);
-    }
-
-    public void testfabsF32_3() {
-        doF32_3(0xc, 0);
-    }
-
-    public void testfabsF32_3_relaxed() {
-        doF32_3_relaxed(0xc, 0);
-    }
-
-    public void testfabsF32_4() {
-        doF32_4(0xd, 0);
-
-    }
-    public void testfabsF32_4_relaxed() {
-        doF32_4_relaxed(0xd, 0);
-    }
-
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/FdimTest.java b/tests/tests/renderscript/src/android/renderscript/cts/FdimTest.java
deleted file mode 100644
index 144c258..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/FdimTest.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * 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 android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.Element;
-import android.renderscript.RSRuntimeException;
-import com.android.cts.stub.R;
-
-public class FdimTest extends RSBaseCompute {
-    private ScriptC_fdim_f32 script_f32;
-    private ScriptC_fdim_f32_relaxed script_f32_relaxed;
-    private Allocation mIn;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script_f32 = new ScriptC_fdim_f32(mRS);
-        script_f32_relaxed = new ScriptC_fdim_f32_relaxed(mRS);
-    }
-
-    @Override
-    public void forEach(int testId, Allocation mIn, Allocation mOut) throws RSRuntimeException {
-        switch (testId) {
-        case TEST_F32:
-            script_f32.forEach_fdim_f32_1(mIn, mOut);
-            break;
-        case TEST_F32_2:
-            script_f32.forEach_fdim_f32_2(mIn, mOut);
-            break;
-        case TEST_F32_3:
-            script_f32.forEach_fdim_f32_3(mIn, mOut);
-            break;
-        case TEST_F32_4:
-            script_f32.forEach_fdim_f32_4(mIn, mOut);
-            break;
-
-        case TEST_RELAXED_F32:
-            script_f32_relaxed.forEach_fdim_f32_1(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_2:
-            script_f32_relaxed.forEach_fdim_f32_2(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_3:
-            script_f32_relaxed.forEach_fdim_f32_3(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_4:
-            script_f32_relaxed.forEach_fdim_f32_4(mIn, mOut);
-            break;
-        }
-    }
-
-    @Override
-    protected float[] getRefArray(float[] in, int input_size, int stride, int skip) {
-        float[] ref = new float[input_size * stride];
-        for (int i = 0; i < input_size; i++) {
-            for (int j = 0; j < stride - skip; j++) {
-                int idx = i * stride * 2 + j;
-                ref[i * (stride - skip) + j] = (float)(Math.max(0.0, (double)in[idx] - (double)in[idx+stride]));
-            }
-        }
-        return ref;
-    }
-
-    @Override
-    protected Allocation setInAlloc(Element e) {
-        return mIn;
-    }
-
-    @Override
-    protected float[] makeInArray(int size) {
-        return new float[size*2];
-    }
-
-    public void testfdimF32() {
-        ScriptField_fdim_f32_input floatArray = new ScriptField_fdim_f32_input(mRS, INPUTSIZE);
-        mIn = floatArray.getAllocation();
-        doF32(0x12678, 0);
-    }
-
-    public void testfdimF32_relaxed() {
-        ScriptField_fdim_f32_input floatArray = new ScriptField_fdim_f32_input(mRS, INPUTSIZE);
-        mIn = floatArray.getAllocation();
-        doF32_relaxed(0x12678, 0);
-    }
-
-    public void testfdimF32_2() {
-        ScriptField_fdim_f32_2_input floatArray = new ScriptField_fdim_f32_2_input(mRS, INPUTSIZE);
-        mIn = floatArray.getAllocation();
-        doF32_2(0x1af45, 0);
-    }
-
-    public void testfdimF32_2_relaxed() {
-        ScriptField_fdim_f32_2_input floatArray = new ScriptField_fdim_f32_2_input(mRS, INPUTSIZE);
-        mIn = floatArray.getAllocation();
-        doF32_2_relaxed(0x1af45, 0);
-    }
-
-    public void testfdimF32_3() {
-        ScriptField_fdim_f32_3_input floatArray = new ScriptField_fdim_f32_3_input(mRS, INPUTSIZE);
-        mIn = floatArray.getAllocation();
-        doF32_3(0x1cd345, 0);
-    }
-
-    public void testfdimF32_3_relaxed() {
-        ScriptField_fdim_f32_3_input floatArray = new ScriptField_fdim_f32_3_input(mRS, INPUTSIZE);
-        mIn = floatArray.getAllocation();
-        doF32_3_relaxed(0x1cd345, 0);
-    }
-
-    public void testfdimF32_4() {
-        ScriptField_fdim_f32_4_input floatArray = new ScriptField_fdim_f32_4_input(mRS, INPUTSIZE);
-        mIn = floatArray.getAllocation();
-        doF32_4(0x1ca45, 0);
-    }
-
-    public void testfdimF32_4_relaxed() {
-        ScriptField_fdim_f32_4_input floatArray = new ScriptField_fdim_f32_4_input(mRS, INPUTSIZE);
-        mIn = floatArray.getAllocation();
-        doF32_4_relaxed(0x1ca45, 0);
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/FieldPackerTest.java b/tests/tests/renderscript/src/android/renderscript/cts/FieldPackerTest.java
index 8625b9f..fb2ba50 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/FieldPackerTest.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/FieldPackerTest.java
@@ -146,7 +146,7 @@
             }
         }
 
-        int[] badResetArgs = {-1000, -2, -1, 256, 257, 1000};
+        int[] badResetArgs = {-1000, -2, -1, 257, 1000};
         for (int arg: badResetArgs) {
             try {
                 fp.reset(arg);
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/Floaty.java b/tests/tests/renderscript/src/android/renderscript/cts/Floaty.java
new file mode 100644
index 0000000..608e172
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/Floaty.java
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 2014 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 android.renderscript.cts;
+
+import android.util.Log;
+
+/**
+ * This class keeps track of a floating point value and the computation error that has accumulated
+ * in creating this number.  We also provide the four basic arithmetic operators and sqrt that
+ * compute the correct error of the result.
+ */
+public class Floaty {
+    private double mValue;  // The value this instance represent.
+    private double mError;  // The real value should be between mValue - mError and mValue + mError.
+    /* The number of bits the value should have, either 32 or 64.  It would have been nice to
+     * use generics, e.g. Floaty<float> and Floaty<double> but Java does not support generics
+     * of float and double.  Also, Java does not have a f16 type.  This can simulate it, although
+     * more work will be needed.
+     */
+    private int mNumberOfBits;
+
+    static private boolean relaxed;  // Whether we are doing relaxed precision computations.
+
+    static public void setRelaxed(boolean value) {
+        relaxed = value;
+    }
+
+    public Floaty(Floaty a) {
+        mValue = a.mValue;
+        mError = a.mError;
+        mNumberOfBits = a.mNumberOfBits;
+    }
+
+    public Floaty(float a) {
+        mValue = a;
+        mNumberOfBits = 32;
+        setErrorFromValue(1, 1);
+    }
+
+    public Floaty(double a) {
+        mValue = a;
+        mNumberOfBits = 64;
+        setErrorFromValue(1, 1);
+    }
+
+    /** Sets the value and the error based on whether we're doing relaxed computations or not. */
+    public Floaty(float v, int ulpFactor, int ulpRelaxedFactor) {
+        mValue = v;
+        mNumberOfBits = 32;
+        setErrorFromValue(ulpFactor, ulpRelaxedFactor);
+    }
+
+    public Floaty(double v, int ulpFactor, int ulpRelaxedFactor) {
+        mValue = v;
+        mNumberOfBits = 64;
+        setErrorFromValue(ulpFactor, ulpRelaxedFactor);
+    }
+
+    public float getFloatValue() { return (float) mValue; }
+    public double getDoubleValue() { return mValue; }
+
+    public float getFloatError() { return (float) mError; }
+    public double getDoubleError() { return mError; }
+
+    /** Returns the number we would need to multiply the ulp to get the current error. */
+    public int getUlf() {
+        return (int) Math.abs(mError / getUlp());
+    }
+
+    /** Returns the unit of least precision for the number we handle. */
+    private double getUlp() {
+        if (mNumberOfBits == 64) {
+            return Math.ulp(mValue);
+        } else {
+            return Math.ulp((float) mValue);
+        }
+    }
+
+    /**
+     * Set mError to be the appropriate factor multiplied by the Unit of Least Precision (ulp)
+     * of the current value.
+     */
+    private void setErrorFromValue(int ulpFactor, int ulpRelaxedFactor) {
+        int factor = relaxed ? ulpRelaxedFactor : ulpFactor;
+        mError = getUlp() * factor;
+    }
+
+    /**
+     * Creates a new Floaty as the result of a computation.  The precision factor are those
+     * associated with the operation just completed.
+     */
+    private Floaty(double actual, double valueMinusError, double valuePlusError, int ulpFactor,
+            int ulpRelaxedFactor, int numberOfBits) {
+        mValue = actual;
+        mError = 0f;
+        expandError(valueMinusError);
+        expandError(valuePlusError);
+        mError *= relaxed ? ulpRelaxedFactor : ulpFactor;
+        mNumberOfBits = numberOfBits;
+    }
+    
+    /** If needed, increases the error so that the provided value is covered by the error range. */
+    private void expandError(double valueWithError) {
+        // We disregard NaN values that can be produced when testing close to a cliff.
+        if (valueWithError != valueWithError) {
+            return;
+        }
+        double delta = Math.abs(valueWithError - mValue);
+        if (delta > mError) {
+            mError = delta;
+        }
+    }
+
+    /** Returns true if the number passed is within mError of our value. */
+    public boolean couldBe(double a) {
+        return couldBe(a, 0.0);
+    }
+
+    /**
+     * Returns true if the number passed is within mError of our value, or if it's whithin
+     * minimumError of the value.
+     */ 
+    public boolean couldBe(double a, double minimumError) {
+        if (a != a && mValue != mValue) {
+            return true;  // Both are NaN
+        }
+        /* Handle the simple case.  This may not be covered by the next test if mError is NaN.
+         */
+        if (a == mValue) {
+            return true;
+        }
+        double error = Math.max(mError, minimumError);
+        boolean inRange = mValue - error <= a && a <= mValue + error;
+
+        /* This is useful for debugging:
+        if (!inRange) {
+            int ulfNeeded = (int) Math.abs(Math.round((a - mValue) / Math.ulp(mValue)));
+            Log.e("Floaty.couldBe", "Comparing " + Float.toString(a) +
+                    " against " + Float.toString(mValue) + " +- " + Float.toString(error) +
+                    " relaxed " + Boolean.toString(relaxed) +
+                    " ulfNeeded " + Integer.toString(ulfNeeded) +
+                    ", off by " + Integer.toString(ulfNeeded - getUlf()));
+        }
+        */
+        return inRange;
+    }
+
+    public String toString() {
+        return String.format("%24.9g (%16x) +- %24.9g ulf %d (%d bits)", mValue,
+                Double.doubleToRawLongBits(mValue), mError, getUlf(), mNumberOfBits);
+    }
+
+    public boolean isNaN() {
+        return mValue == Float.NaN;
+    }
+
+    public Floaty add(Floaty a) {
+        mValue += a.mValue;
+        mError += a.mError;
+        return this;
+    }
+
+    public Floaty subtract(Floaty a) {
+        mValue -= a.mValue;
+        mError += a.mError;
+        return this;
+    }
+
+    public Floaty multiply(Floaty a) {
+        /* Theoretically, it should be also + a.mError * mError but that should be too small
+         * to matter.
+         */
+        mError = Math.abs(mValue) * a.mError + Math.abs(a.mValue) * mError;
+        mValue *= a.mValue;
+        return this;
+    }
+
+    public Floaty divide(Floaty a) {
+        double num = Math.abs(mValue);
+        double den = Math.abs(a.mValue);
+        mError = (num * a.mError + den * mError) / (den * (den - a.mError));
+        mValue /= a.mValue;
+        return this;
+    }
+
+    static public Floaty add(Floaty a, Floaty b) {
+        return new Floaty(a).add(b);
+    }
+
+    static public Floaty subtract(Floaty a, Floaty b) {
+        return new Floaty(a).subtract(b);
+    }
+
+    static public Floaty multiply(Floaty a, Floaty b) {
+        return new Floaty(a).multiply(b);
+    }
+
+    static public Floaty divide(Floaty a, Floaty b) {
+        return new Floaty(a).divide(b);
+    }
+
+    static public Floaty abs(Floaty a) {
+        Floaty c = new Floaty(Math.abs(a.mValue));
+        c.mError = a.mError;
+        return c;
+    }
+
+    static public Floaty sqrt(Floaty a) {
+        Floaty f = new Floaty(
+            Math.sqrt(a.mValue),
+            Math.sqrt(a.mValue - a.mError),
+            Math.sqrt(a.mValue + a.mError),
+            3, 10, a.mNumberOfBits);
+        return f;
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/FloorTest.java b/tests/tests/renderscript/src/android/renderscript/cts/FloorTest.java
deleted file mode 100644
index e7494e6..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/FloorTest.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * 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 android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import com.android.cts.stub.R;
-
-public class FloorTest extends RSBaseCompute {
-    private ScriptC_floor_f32 script_f32;
-    private ScriptC_floor_f32_relaxed script_f32_relaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script_f32 = new ScriptC_floor_f32(mRS);
-        script_f32_relaxed = new ScriptC_floor_f32_relaxed(mRS);
-    }
-
-    @Override
-    public void forEach(int testId, Allocation mIn, Allocation mOut) throws RSRuntimeException {
-        switch (testId) {
-        case TEST_F32:
-            script_f32.forEach_floor_f32_1(mIn, mOut);
-            break;
-        case TEST_F32_2:
-            script_f32.forEach_floor_f32_2(mIn, mOut);
-            break;
-        case TEST_F32_3:
-            script_f32.forEach_floor_f32_3(mIn, mOut);
-            break;
-        case TEST_F32_4:
-            script_f32.forEach_floor_f32_4(mIn, mOut);
-            break;
-
-        case TEST_RELAXED_F32:
-            script_f32_relaxed.forEach_floor_f32_1(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_2:
-            script_f32_relaxed.forEach_floor_f32_2(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_3:
-            script_f32_relaxed.forEach_floor_f32_3(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_4:
-            script_f32_relaxed.forEach_floor_f32_4(mIn, mOut);
-            break;
-        }
-    }
-
-    @Override
-    protected float[] getRefArray(float[] in, int input_size, int stride, int skip) {
-        float[] ref = new float[input_size * stride];
-        for (int i = 0; i < input_size; i++) {
-            for (int j = 0; j < stride - skip; j++) {
-                int idx= i * stride + j;
-                int idxRef = i * (stride - skip) + j;
-                ref[idxRef] = (float)(Math.floor((double)in[idx]));
-            }
-        }
-        return ref;
-    }
-
-    public void testfloorF32() {
-        doF32(0xa, 0);
-    }
-
-    public void testfloorF32_relaxed() {
-        doF32_relaxed(0xa, 1);
-    }
-
-    public void testfloorF32_2() {
-        doF32_2(0xb, 0);
-    }
-
-    public void testfloorF32_2_relaxed() {
-        doF32_2_relaxed(0xb, 1);
-    }
-
-    public void testfloorF32_3() {
-        doF32_3(0xef1, 0);
-    }
-
-    public void testfloorF32_3_relaxed() {
-        doF32_3_relaxed(0xef1, 1);
-    }
-
-    public void testfloorF32_4() {
-        doF32_4(0xefa12, 0);
-
-    }
-    public void testfloorF32_4_relaxed() {
-        doF32_4_relaxed(0xefa12, 1);
-    }
-
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/FmaTest.java b/tests/tests/renderscript/src/android/renderscript/cts/FmaTest.java
deleted file mode 100644
index 40fac7e..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/FmaTest.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * 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 android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.Element;
-import android.renderscript.RSRuntimeException;
-import com.android.cts.stub.R;
-
-public class FmaTest extends RSBaseCompute {
-    private ScriptC_fma_f32 script_f32;
-    private ScriptC_fma_f32_relaxed script_f32_relaxed;
-    private Allocation mIn;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script_f32 = new ScriptC_fma_f32(mRS);
-        script_f32_relaxed = new ScriptC_fma_f32_relaxed(mRS);
-    }
-
-    @Override
-    public void forEach(int testId, Allocation mIn, Allocation mOut) throws RSRuntimeException {
-        switch (testId) {
-        case TEST_F32:
-            script_f32.forEach_fma_f32_1(mIn, mOut);
-            break;
-        case TEST_F32_2:
-            script_f32.forEach_fma_f32_2(mIn, mOut);
-            break;
-        case TEST_F32_3:
-            script_f32.forEach_fma_f32_3(mIn, mOut);
-            break;
-        case TEST_F32_4:
-            script_f32.forEach_fma_f32_4(mIn, mOut);
-            break;
-
-        case TEST_RELAXED_F32:
-            script_f32_relaxed.forEach_fma_f32_1(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_2:
-            script_f32_relaxed.forEach_fma_f32_2(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_3:
-            script_f32_relaxed.forEach_fma_f32_3(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_4:
-            script_f32_relaxed.forEach_fma_f32_4(mIn, mOut);
-            break;
-        }
-    }
-
-    @Override
-    protected float[] getRefArray(float[] in, int input_size, int stride, int skip) {
-        float[] ref = new float[input_size * stride];
-        for (int i = 0; i < input_size; i++) {
-            for (int j = 0; j < stride - skip; j++) {
-                int idx = i * stride * 3 + j;
-                ref[i * (stride - skip) + j] = (float)((double)in[idx] * (double)in[idx+stride] + (double)in[idx+stride*2]);
-            }
-        }
-        return ref;
-    }
-
-    @Override
-    protected Allocation setInAlloc(Element e) {
-        return mIn;
-    }
-
-    @Override
-    protected float[] makeInArray(int size) {
-        return new float[size*3];
-    }
-
-    public void testFmaF32() {
-        ScriptField_Floats floatArray = new ScriptField_Floats(mRS, INPUTSIZE);
-        mIn = floatArray.getAllocation();
-        doF32(0xea1, 0);
-    }
-
-    public void testFmaF32_relaxed() {
-        ScriptField_Floats floatArray = new ScriptField_Floats(mRS, INPUTSIZE);
-        mIn = floatArray.getAllocation();
-        doF32_relaxed(0xea1, 0);
-    }
-
-    public void testFmaF32_2() {
-        ScriptField_Floats2 floatArray = new ScriptField_Floats2(mRS, INPUTSIZE);
-        mIn = floatArray.getAllocation();
-        doF32_2(0x12a, 0);
-    }
-
-    public void testFmaF32_2_relaxed() {
-        ScriptField_Floats2 floatArray = new ScriptField_Floats2(mRS, INPUTSIZE);
-        mIn = floatArray.getAllocation();
-        doF32_2_relaxed(0x12a, 0);
-    }
-
-    public void testFmaF32_3() {
-        ScriptField_Floats3 floatArray = new ScriptField_Floats3(mRS, INPUTSIZE);
-        mIn = floatArray.getAllocation();
-        doF32_3(0xfae, 0);
-    }
-
-    public void testFmaF32_3_relaxed() {
-        ScriptField_Floats3 floatArray = new ScriptField_Floats3(mRS, INPUTSIZE);
-        mIn = floatArray.getAllocation();
-        doF32_3_relaxed(0xfae, 0);
-    }
-
-    public void testFmaF32_4() {
-        ScriptField_Floats4 floatArray = new ScriptField_Floats4(mRS, INPUTSIZE);
-        mIn = floatArray.getAllocation();
-        doF32_4(0x87a, 0);
-    }
-
-    public void testFmaF32_4_relaxed() {
-        ScriptField_Floats4 floatArray = new ScriptField_Floats4(mRS, INPUTSIZE);
-        mIn = floatArray.getAllocation();
-        doF32_4_relaxed(0x87a, 0);
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/FmaxTest.java b/tests/tests/renderscript/src/android/renderscript/cts/FmaxTest.java
deleted file mode 100644
index 99f2b42..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/FmaxTest.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * 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 android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.Element;
-import android.renderscript.RSRuntimeException;
-import com.android.cts.stub.R;
-
-public class FmaxTest extends RSBaseCompute {
-    private ScriptC_fmax_f32 script_f32;
-    private ScriptC_fmax_f32_relaxed script_f32_relaxed;
-    private Allocation mIn;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script_f32 = new ScriptC_fmax_f32(mRS);
-        script_f32_relaxed = new ScriptC_fmax_f32_relaxed(mRS);
-    }
-
-    @Override
-    public void forEach(int testId, Allocation max, Allocation mOut) throws RSRuntimeException {
-        switch (testId) {
-        case TEST_F32:
-            script_f32.forEach_fmax_f32_1(mIn, mOut);
-            break;
-        case TEST_F32_2:
-            script_f32.forEach_fmax_f32_2(mIn, mOut);
-            break;
-        case TEST_F32_3:
-            script_f32.forEach_fmax_f32_3(mIn, mOut);
-            break;
-        case TEST_F32_4:
-            script_f32.forEach_fmax_f32_4(mIn, mOut);
-            break;
-
-        case TEST_RELAXED_F32:
-            script_f32_relaxed.forEach_fmax_f32_1(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_2:
-            script_f32_relaxed.forEach_fmax_f32_2(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_3:
-            script_f32_relaxed.forEach_fmax_f32_3(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_4:
-            script_f32_relaxed.forEach_fmax_f32_4(mIn, mOut);
-            break;
-        }
-    }
-
-    @Override
-    protected float[] getRefArray(float[] in, int input_size, int stride, int skip) {
-        float[] ref = new float[input_size * stride];
-        for (int i = 0; i < input_size; i++) {
-            for (int j = 0; j < stride - skip; j++) {
-                int idx = i * stride * 2 + j;
-                ref[i * (stride - skip) + j] = Math.max(in[idx], in[idx+stride]);
-            }
-        }
-        return ref;
-    }
-
-    @Override
-    protected Allocation setInAlloc(Element e) {
-        return mIn;
-    }
-
-    @Override
-    protected float[] makeInArray(int size) {
-        return new float[size*2];
-    }
-
-    public void testfmaxF32() {
-        ScriptField_fmax_f32_in in = new ScriptField_fmax_f32_in(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32(0x12678, 0);
-    }
-
-    public void testfmaxF32_relaxed() {
-        ScriptField_fmax_f32_in in = new ScriptField_fmax_f32_in(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_relaxed(0x12678, 0);
-    }
-
-    public void testfmaxF32_2() {
-        ScriptField_fmax_f32_2_in in = new ScriptField_fmax_f32_2_in(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_2(0x12ace, 0);
-    }
-
-    public void testfmaxF32_2_relaxed() {
-        ScriptField_fmax_f32_2_in in = new ScriptField_fmax_f32_2_in(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_2_relaxed(0x12ace, 0);
-    }
-
-    public void testfmaxF32_3() {
-        ScriptField_fmax_f32_3_in in = new ScriptField_fmax_f32_3_in(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_3(0x12e8, 0);
-    }
-
-    public void testfmaxF32_3_relaxed() {
-        ScriptField_fmax_f32_3_in in = new ScriptField_fmax_f32_3_in(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_3_relaxed(0x12e8, 0);
-    }
-
-    public void testfmaxF32_4() {
-        ScriptField_fmax_f32_4_in in = new ScriptField_fmax_f32_4_in(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_4(0xeac, 0);
-    }
-
-    public void testfmaxF32_4_relaxed() {
-        ScriptField_fmax_f32_4_in in = new ScriptField_fmax_f32_4_in(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_4_relaxed(0xeac, 0);
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/FminTest.java b/tests/tests/renderscript/src/android/renderscript/cts/FminTest.java
deleted file mode 100644
index b43b828..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/FminTest.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * 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 android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.Element;
-import android.renderscript.RSRuntimeException;
-import com.android.cts.stub.R;
-
-public class FminTest extends RSBaseCompute {
-    private ScriptC_fmin_f32 script_f32;
-    private ScriptC_fmin_f32_relaxed script_f32_relaxed;
-    private Allocation mIn;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script_f32 = new ScriptC_fmin_f32(mRS);
-        script_f32_relaxed = new ScriptC_fmin_f32_relaxed(mRS);
-    }
-
-    @Override
-    public void forEach(int testId, Allocation mIn, Allocation mOut) throws RSRuntimeException {
-        switch (testId) {
-        case TEST_F32:
-            script_f32.forEach_fmin_f32_1(mIn, mOut);
-            break;
-        case TEST_F32_2:
-            script_f32.forEach_fmin_f32_2(mIn, mOut);
-            break;
-        case TEST_F32_3:
-            script_f32.forEach_fmin_f32_3(mIn, mOut);
-            break;
-        case TEST_F32_4:
-            script_f32.forEach_fmin_f32_4(mIn, mOut);
-            break;
-
-        case TEST_RELAXED_F32:
-            script_f32_relaxed.forEach_fmin_f32_1(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_2:
-            script_f32_relaxed.forEach_fmin_f32_2(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_3:
-            script_f32_relaxed.forEach_fmin_f32_3(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_4:
-            script_f32_relaxed.forEach_fmin_f32_4(mIn, mOut);
-            break;
-        }
-    }
-
-    @Override
-    protected float[] getRefArray(float[] in, int input_size, int stride, int skip) {
-        float[] ref = new float[input_size * stride];
-        for (int i = 0; i < input_size; i++) {
-            for (int j = 0; j < stride - skip; j++) {
-                int idx = i * stride * 2 + j;
-                ref[i * (stride - skip) + j] = Math.min(in[idx], in[idx+stride]);
-            }
-        }
-        return ref;
-    }
-
-    @Override
-    protected Allocation setInAlloc(Element e) {
-        return mIn;
-    }
-
-    @Override
-    protected float[] makeInArray(int size) {
-        return new float[size*2];
-    }
-
-    public void testfminF32() {
-        ScriptField_fmin_f32_in in = new ScriptField_fmin_f32_in(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32(0x12678, 0);
-    }
-
-    public void testfminF32_relaxed() {
-        ScriptField_fmin_f32_in in = new ScriptField_fmin_f32_in(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_relaxed(0x12678, 0);
-    }
-
-    public void testfminF32_2() {
-        ScriptField_fmin_f32_2_in in = new ScriptField_fmin_f32_2_in(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_2(0x12ace, 0);
-    }
-
-    public void testfminF32_2_relaxed() {
-        ScriptField_fmin_f32_2_in in = new ScriptField_fmin_f32_2_in(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_2_relaxed(0x12ace, 0);
-    }
-
-    public void testfminF32_3() {
-        ScriptField_fmin_f32_3_in in = new ScriptField_fmin_f32_3_in(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_3(0x12e8, 0);
-    }
-
-    public void testfminF32_3_relaxed() {
-        ScriptField_fmin_f32_3_in in = new ScriptField_fmin_f32_3_in(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_3_relaxed(0x12e8, 0);
-    }
-
-    public void testfminF32_4() {
-        ScriptField_fmin_f32_4_in in = new ScriptField_fmin_f32_4_in(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_4(0xeac, 0);
-    }
-
-    public void testfminF32_4_relaxed() {
-        ScriptField_fmin_f32_4_in in = new ScriptField_fmin_f32_4_in(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_4_relaxed(0xeac, 0);
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/FmodTest.java b/tests/tests/renderscript/src/android/renderscript/cts/FmodTest.java
deleted file mode 100644
index d0d911d..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/FmodTest.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * 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 android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.Element;
-import android.renderscript.RSRuntimeException;
-import com.android.cts.stub.R;
-
-public class FmodTest extends RSBaseCompute {
-    private ScriptC_fmod_f32 script_f32;
-    private ScriptC_fmod_f32_relaxed script_f32_relaxed;
-    private Allocation mIn;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script_f32 = new ScriptC_fmod_f32(mRS);
-        script_f32_relaxed = new ScriptC_fmod_f32_relaxed(mRS);
-    }
-
-    @Override
-    public void forEach(int testId, Allocation mIn, Allocation mOut) throws RSRuntimeException {
-        switch (testId) {
-        case TEST_F32:
-            script_f32.forEach_fmod_f32_1(mIn, mOut);
-            break;
-        case TEST_F32_2:
-            script_f32.forEach_fmod_f32_2(mIn, mOut);
-            break;
-        case TEST_F32_3:
-            script_f32.forEach_fmod_f32_3(mIn, mOut);
-            break;
-        case TEST_F32_4:
-            script_f32.forEach_fmod_f32_4(mIn, mOut);
-            break;
-
-        case TEST_RELAXED_F32:
-            script_f32_relaxed.forEach_fmod_f32_1(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_2:
-            script_f32_relaxed.forEach_fmod_f32_2(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_3:
-            script_f32_relaxed.forEach_fmod_f32_3(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_4:
-            script_f32_relaxed.forEach_fmod_f32_4(mIn, mOut);
-            break;
-        }
-    }
-
-    @Override
-    protected float[] getRefArray(float[] in, int input_size, int stride, int skip) {
-        float[] ref = new float[input_size * stride];
-        for (int i = 0; i < input_size; i++) {
-            for (int j = 0; j < stride - skip; j++) {
-                int idx = i * stride * 2 + j;
-                ref[i * (stride - skip) + j] = (float)((double)in[idx] % (double)in[idx+stride]);
-            }
-        }
-        return ref;
-    }
-
-    @Override
-    protected Allocation setInAlloc(Element e) {
-        return mIn;
-    }
-
-    @Override
-    protected float[] makeInArray(int size) {
-        return new float[size*2];
-    }
-
-    /**
-     * This method is used for testing the fmod() function with F32
-     */
-    public void testfmodF32() {
-        ScriptField_fmod_input_f32 floatArray = new ScriptField_fmod_input_f32(mRS, INPUTSIZE);
-        mIn = floatArray.getAllocation();
-        doF32(0x12345678, 0);
-    }
-
-    public void testfmodF32_relaxed() {
-        ScriptField_fmod_input_f32 floatArray = new ScriptField_fmod_input_f32(mRS, INPUTSIZE);
-        mIn = floatArray.getAllocation();
-        doF32_relaxed(0x12345678, 0);
-    }
-
-    /**
-     * This method is used for testing the fmod() function with F32_2
-     */
-    public void testfmodF32_2() {
-        ScriptField_fmod_input_f32_2 floatArray = new ScriptField_fmod_input_f32_2(mRS, INPUTSIZE);
-        mIn = floatArray.getAllocation();
-        doF32_2(0x12345, 0);
-    }
-
-    public void testfmodF32_2_relaxed() {
-        ScriptField_fmod_input_f32_2 floatArray = new ScriptField_fmod_input_f32_2(mRS, INPUTSIZE);
-        mIn = floatArray.getAllocation();
-        doF32_2_relaxed(0x12345, 0);
-    }
-
-    /**
-     * This method is used for testing the fmod() function with F32_3
-     */
-    public void testfmodF32_3() {
-        ScriptField_fmod_input_f32_3 floatArray = new ScriptField_fmod_input_f32_3(mRS, INPUTSIZE);
-        mIn = floatArray.getAllocation();
-        doF32_3(0x12345, 0);
-    }
-
-    public void testfmodF32_3_relaxed() {
-        ScriptField_fmod_input_f32_3 floatArray = new ScriptField_fmod_input_f32_3(mRS, INPUTSIZE);
-        mIn = floatArray.getAllocation();
-        doF32_3_relaxed(0x12345, 0);
-    }
-
-    /**
-     * This method is used for testing the fmod() function with F32_4
-     */
-    public void testfmodF32_4() {
-        ScriptField_fmod_input_f32_4 floatArray = new ScriptField_fmod_input_f32_4(mRS, INPUTSIZE);
-        mIn = floatArray.getAllocation();
-        doF32_4(0x12345, 0);
-    }
-
-    public void testfmodF32_4_relaxed() {
-        ScriptField_fmod_input_f32_4 floatArray = new ScriptField_fmod_input_f32_4(mRS, INPUTSIZE);
-        mIn = floatArray.getAllocation();
-        doF32_4_relaxed(0x12345, 0);
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/ForEachTest.java b/tests/tests/renderscript/src/android/renderscript/cts/ForEachTest.java
index 433b7e6..8e82f1f 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/ForEachTest.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/ForEachTest.java
@@ -470,7 +470,6 @@
         s.set_dimY(Y);
         typeBuilder.setX(X).setY(Y);
         Allocation A = Allocation.createTyped(mRS, typeBuilder.create());
-        s.bind_a(A);
         s.set_aRaw(A);
         s.forEach_root(A);
         s.invoke_verify_root();
@@ -478,6 +477,7 @@
         s.invoke_verify_foo();
         s.invoke_foreach_test();
         mRS.finish();
+        checkForErrors();
         waitForMessage();
     }
 
@@ -491,7 +491,6 @@
         s.set_dimY(Y);
         typeBuilder.setX(X).setY(Y);
         Allocation A = Allocation.createTyped(mRS, typeBuilder.create());
-        s.bind_a(A);
         s.set_aRaw(A);
         s.forEach_foo(A, A);
         s.invoke_verify_foo();
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/HypotTest.java b/tests/tests/renderscript/src/android/renderscript/cts/HypotTest.java
deleted file mode 100644
index c5ce887..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/HypotTest.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * 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 android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.Element;
-import android.renderscript.RSRuntimeException;
-import com.android.cts.stub.R;
-
-public class HypotTest extends RSBaseCompute {
-    private ScriptC_hypot_f32 script_f32;
-    private ScriptC_hypot_f32_relaxed script_f32_relaxed;
-    private Allocation mIn;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script_f32 = new ScriptC_hypot_f32(mRS);
-        script_f32_relaxed = new ScriptC_hypot_f32_relaxed(mRS);
-    }
-
-    @Override
-    public void forEach(int testId, Allocation mIn, Allocation mOut) throws RSRuntimeException {
-        switch (testId) {
-        case TEST_F32:
-            script_f32.forEach_hypot_f32_1(mIn, mOut);
-            break;
-        case TEST_F32_2:
-            script_f32.forEach_hypot_f32_2(mIn, mOut);
-            break;
-        case TEST_F32_3:
-            script_f32.forEach_hypot_f32_3(mIn, mOut);
-            break;
-        case TEST_F32_4:
-            script_f32.forEach_hypot_f32_4(mIn, mOut);
-            break;
-
-        case TEST_RELAXED_F32:
-            script_f32_relaxed.forEach_hypot_f32_1(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_2:
-            script_f32_relaxed.forEach_hypot_f32_2(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_3:
-            script_f32_relaxed.forEach_hypot_f32_3(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_4:
-            script_f32_relaxed.forEach_hypot_f32_4(mIn, mOut);
-            break;
-        }
-    }
-
-    @Override
-    protected float[] getRefArray(float[] in, int input_size, int stride, int skip) {
-        float[] ref = new float[input_size * stride];
-        for (int i = 0; i < input_size; i++) {
-            for (int j = 0; j < stride - skip; j++) {
-                int idx = i * stride * 2 + j;
-                ref[i * (stride - skip) + j] = (float)Math.hypot((double)in[idx], (double)in[idx+stride]);
-            }
-        }
-        return ref;
-    }
-
-    @Override
-    protected Allocation setInAlloc(Element e) {
-        return mIn;
-    }
-
-    @Override
-    protected float[] makeInArray(int size) {
-        return new float[size*2];
-    }
-
-    public void testHypotF32() {
-        ScriptField_hypot_f32_in in = new ScriptField_hypot_f32_in(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32(0x123678, 4);
-    }
-
-    public void testHypotF32_relaxed() {
-        ScriptField_hypot_f32_in in = new ScriptField_hypot_f32_in(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_relaxed(0x123678, 4);
-    }
-
-    public void testHypotF32_2() {
-        ScriptField_hypot_f32_2_in in = new ScriptField_hypot_f32_2_in(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_2(0x1234a5, 4);
-    }
-
-    public void testHypotF32_2_relaxed() {
-        ScriptField_hypot_f32_2_in in = new ScriptField_hypot_f32_2_in(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_2_relaxed(0x1234a5, 4);
-    }
-
-    public void testHypotF32_3() {
-        ScriptField_hypot_f32_3_in in = new ScriptField_hypot_f32_3_in(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_3(0x1af345, 4);
-    }
-
-    public void testHypotF32_3_relaxed() {
-        ScriptField_hypot_f32_3_in in = new ScriptField_hypot_f32_3_in(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_3_relaxed(0x1af345, 4);
-    }
-
-    public void testHypotF32_4() {
-        ScriptField_hypot_f32_4_in in = new ScriptField_hypot_f32_4_in(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_4(0x12ce45, 4);
-    }
-
-    public void testHypotF32_4_relaxed() {
-        ScriptField_hypot_f32_4_in in = new ScriptField_hypot_f32_4_in(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_4_relaxed(0x12ce45, 4);
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/Intrinsic3DLut.java b/tests/tests/renderscript/src/android/renderscript/cts/Intrinsic3DLut.java
new file mode 100644
index 0000000..830982f
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/Intrinsic3DLut.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2014 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 android.renderscript.cts;
+
+import android.renderscript.*;
+import android.util.Log;
+
+public class Intrinsic3DLut extends IntrinsicBase {
+    private Allocation mCube;
+    private ScriptC_intrinsic_3dlut mScript;
+    private ScriptIntrinsic3DLUT mIntrinsic;
+    final int sx = 32;
+    final int sy = 32;
+    final int sz = 16;
+
+    private void genCubeIdent() {
+        int dat[] = new int[sx * sy * sz];
+        for (int z = 0; z < sz; z++) {
+            for (int y = 0; y < sy; y++) {
+                for (int x = 0; x < sx; x++ ) {
+                    int v = 0xff000000;
+                    v |= (0xff * x / (sx - 1));
+                    v |= (0xff * y / (sy - 1)) << 8;
+                    v |= (0xff * z / (sz - 1)) << 16;
+                    dat[z*sy*sx + y*sx + x] = v;
+                }
+            }
+        }
+
+        mCube.copyFromUnchecked(dat);
+    }
+
+    private void genCubeRand() {
+        java.util.Random r = new java.util.Random(100);
+        int dat[] = new int[sx * sy * sz];
+        for (int z = 0; z < sz; z++) {
+            for (int y = 0; y < sy; y++) {
+                for (int x = 0; x < sx; x++ ) {
+                    int v = 0xff000000;
+                    v |= r.nextInt(0x100);
+                    v |= r.nextInt(0x100) << 8;
+                    v |= r.nextInt(0x100) << 16;
+                    dat[z*sy*sx + y*sx + x] = v;
+                }
+            }
+        }
+
+        mCube.copyFromUnchecked(dat);
+    }
+
+    private void initCube() {
+        Type.Builder tb = new Type.Builder(mRS, Element.U8_4(mRS));
+        tb.setX(sx);
+        tb.setY(sy);
+        tb.setZ(sz);
+        Type t = tb.create();
+        mCube = Allocation.createTyped(mRS, t);
+        genCubeIdent();
+
+        mScript = new ScriptC_intrinsic_3dlut(mRS);
+        mScript.invoke_setCube(mCube);
+
+        mIntrinsic = ScriptIntrinsic3DLUT.create(mRS, Element.U8_4(mRS));
+        mIntrinsic.setLUT(mCube);
+    }
+
+    public void test1() {
+        initCube();
+        makeBuffers(97, 97, Element.U8_4(mRS));
+
+        mIntrinsic.forEach(mAllocSrc, mAllocDst);
+        mScript.forEach_root(mAllocSrc, mAllocRef);
+
+        mVerify.set_gAllowedIntError(1);
+        mVerify.invoke_verify(mAllocRef, mAllocDst, mAllocSrc);
+        mRS.finish();
+        checkError();
+    }
+
+    public void test2() {
+        initCube();
+        makeBuffers(97, 97, Element.U8_4(mRS));
+        genCubeRand();
+
+        mIntrinsic.forEach(mAllocSrc, mAllocDst);
+        mScript.forEach_root(mAllocSrc, mAllocRef);
+
+        mVerify.set_gAllowedIntError(2);
+        mVerify.invoke_verify(mAllocRef, mAllocDst, mAllocSrc);
+        mRS.finish();
+        checkError();
+    }
+
+
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/IntrinsicBlur.java b/tests/tests/renderscript/src/android/renderscript/cts/IntrinsicBlur.java
new file mode 100644
index 0000000..aa67012
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/IntrinsicBlur.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2013 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 android.renderscript.cts;
+
+import android.renderscript.*;
+import android.util.Log;
+
+public class IntrinsicBlur extends IntrinsicBase {
+    private ScriptIntrinsicBlur mIntrinsic;
+    private int MAX_RADIUS = 25;
+    private ScriptC_intrinsic_blur mScript;
+    private float mRadius = MAX_RADIUS;
+    private float mSaturation = 1.0f;
+    private Allocation mScratchPixelsAllocation1;
+    private Allocation mScratchPixelsAllocation2;
+
+
+
+    private void initTest(int w, int h, Element e) {
+        makeBuffers(w, h, e);
+
+        Type.Builder tb = new Type.Builder(mRS, Element.F32_4(mRS));
+        tb.setX(w);
+        tb.setY(h);
+        mScratchPixelsAllocation1 = Allocation.createTyped(mRS, tb.create());
+        mScratchPixelsAllocation2 = Allocation.createTyped(mRS, tb.create());
+
+        mIntrinsic = ScriptIntrinsicBlur.create(mRS, e);
+        mIntrinsic.setRadius(MAX_RADIUS);
+        mIntrinsic.setInput(mAllocSrc);
+
+        mScript = new ScriptC_intrinsic_blur(mRS);
+        mScript.set_width(w);
+        mScript.set_height(h);
+        mScript.invoke_setRadius(MAX_RADIUS);
+
+        mScript.set_ScratchPixel1(mScratchPixelsAllocation1);
+        mScript.set_ScratchPixel2(mScratchPixelsAllocation2);
+
+        // Make reference
+        copyInput();
+        mScript.forEach_horz(mScratchPixelsAllocation2);
+        mScript.forEach_vert(mScratchPixelsAllocation1);
+        copyOutput();
+    }
+
+    private void copyInput() {
+        if (mAllocSrc.getType().getElement().isCompatible(Element.U8(mRS))) {
+            mScript.forEach_convert1_uToF(mAllocSrc, mScratchPixelsAllocation1);
+            return;
+        }
+        if (mAllocSrc.getType().getElement().isCompatible(Element.U8_4(mRS))) {
+            mScript.forEach_convert4_uToF(mAllocSrc, mScratchPixelsAllocation1);
+            return;
+        }
+        throw new IllegalArgumentException("bad type");
+    }
+
+    private void copyOutput() {
+        if (mAllocSrc.getType().getElement().isCompatible(Element.U8(mRS))) {
+            mScript.forEach_convert1_fToU(mScratchPixelsAllocation1, mAllocRef);
+            return;
+        }
+        if (mAllocSrc.getType().getElement().isCompatible(Element.U8_4(mRS))) {
+            mScript.forEach_convert4_fToU(mScratchPixelsAllocation1, mAllocRef);
+            return;
+        }
+        throw new IllegalArgumentException("bad type");
+    }
+
+    public void testU8_1() {
+        final int w = 97;
+        final int h = 97;
+        Element e = Element.U8(mRS);
+        initTest(w, h, e);
+
+        mIntrinsic.forEach(mAllocDst);
+
+        mVerify.set_gAllowedIntError(1);
+        mVerify.invoke_verify(mAllocRef, mAllocDst, mAllocSrc);
+        mRS.finish();
+        checkError();
+    }
+
+    public void testU8_4() {
+        final int w = 97;
+        final int h = 97;
+        Element e = Element.U8_4(mRS);
+        initTest(w, h, e);
+
+        mIntrinsic.forEach(mAllocDst);
+
+        mVerify.set_gAllowedIntError(1);
+        mVerify.invoke_verify(mAllocRef, mAllocDst, mAllocSrc);
+        mRS.finish();
+        checkError();
+    }
+
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/KernelTest.java b/tests/tests/renderscript/src/android/renderscript/cts/KernelTest.java
index 56b5e89..dcfc0ba 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/KernelTest.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/KernelTest.java
@@ -470,7 +470,6 @@
         s.set_dimY(Y);
         typeBuilder.setX(X).setY(Y);
         Allocation A = Allocation.createTyped(mRS, typeBuilder.create());
-        s.bind_a(A);
         s.set_aRaw(A);
         s.forEach_root(A);
         s.invoke_verify_root();
@@ -478,6 +477,7 @@
         s.invoke_verify_foo();
         s.invoke_foreach_test();
         mRS.finish();
+        checkForErrors();
         waitForMessage();
     }
 
@@ -491,7 +491,6 @@
         s.set_dimY(Y);
         typeBuilder.setX(X).setY(Y);
         Allocation A = Allocation.createTyped(mRS, typeBuilder.create());
-        s.bind_a(A);
         s.set_aRaw(A);
         s.forEach_foo(A, A);
         s.invoke_verify_foo();
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/Log10Test.java b/tests/tests/renderscript/src/android/renderscript/cts/Log10Test.java
deleted file mode 100644
index bc571a3..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/Log10Test.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * 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 android.renderscript.cts;
-
-import com.android.cts.stub.R;
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-
-public class Log10Test extends RSBaseCompute {
-    private ScriptC_log10_f32 script_f32;
-    private ScriptC_log10_f32_relaxed script_f32_relaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script_f32 = new ScriptC_log10_f32(mRS);
-        script_f32_relaxed = new ScriptC_log10_f32_relaxed(mRS);
-    }
-
-    @Override
-    public void forEach(int testId, Allocation mIn, Allocation mOut) throws RSRuntimeException {
-        switch (testId) {
-        case TEST_F32:
-            script_f32.forEach_log10_f32_1(mIn, mOut);
-            break;
-        case TEST_F32_2:
-            script_f32.forEach_log10_f32_2(mIn, mOut);
-            break;
-        case TEST_F32_3:
-            script_f32.forEach_log10_f32_3(mIn, mOut);
-            break;
-        case TEST_F32_4:
-            script_f32.forEach_log10_f32_4(mIn, mOut);
-            break;
-
-        case TEST_RELAXED_F32:
-            script_f32_relaxed.forEach_log10_f32_1(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_2:
-            script_f32_relaxed.forEach_log10_f32_2(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_3:
-            script_f32_relaxed.forEach_log10_f32_3(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_4:
-            script_f32_relaxed.forEach_log10_f32_4(mIn, mOut);
-            break;
-        }
-    }
-
-    @Override
-    protected float[] getRefArray(float[] in, int input_size, int stride, int skip) {
-        float[] ref = new float[input_size * stride];
-        for (int i = 0; i < input_size; i++) {
-            for (int j = 0; j < stride - skip; j++) {
-                int idx= i * stride + j;
-                int idxRef = i * (stride - skip) + j;
-                ref[idxRef] = (float)(Math.log10((double)in[idx]));
-            }
-        }
-        return ref;
-    }
-
-    public void testLog10F32() {
-        doF32(0x13, 3);
-    }
-
-    public void testLog10F32_relaxed() {
-        doF32_relaxed(0x13, 16);
-    }
-
-    public void testLog10F32_2() {
-        doF32_2(0xf, 3);
-    }
-
-    public void testLog10F32_2_relaxed() {
-        doF32_2_relaxed(0xf, 16);
-    }
-
-    public void testLog10F32_3() {
-        doF32_3(0xa, 3);
-    }
-
-    public void testLog10F32_3_relaxed() {
-        doF32_3_relaxed(0xa, 16);
-    }
-
-    public void testLog10F32_4() {
-        doF32_4(0xf3, 3);
-
-    }
-    public void testLog10F32_4_relaxed() {
-        doF32_4_relaxed(0xf3, 16);
-    }
-
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/Log1PTest.java b/tests/tests/renderscript/src/android/renderscript/cts/Log1PTest.java
deleted file mode 100644
index a4daf61..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/Log1PTest.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * 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 android.renderscript.cts;
-
-import com.android.cts.stub.R;
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-
-public class Log1PTest extends RSBaseCompute {
-    private ScriptC_log1p_f32 script_f32;
-    private ScriptC_log1p_f32_relaxed script_f32_relaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script_f32 = new ScriptC_log1p_f32(mRS);
-        script_f32_relaxed = new ScriptC_log1p_f32_relaxed(mRS);
-    }
-
-    @Override
-    public void forEach(int testId, Allocation mIn, Allocation mOut) throws RSRuntimeException {
-        switch (testId) {
-        case TEST_F32:
-            script_f32.forEach_log1p_f32_1(mIn, mOut);
-            break;
-        case TEST_F32_2:
-            script_f32.forEach_log1p_f32_2(mIn, mOut);
-            break;
-        case TEST_F32_3:
-            script_f32.forEach_log1p_f32_3(mIn, mOut);
-            break;
-        case TEST_F32_4:
-            script_f32.forEach_log1p_f32_4(mIn, mOut);
-            break;
-
-        case TEST_RELAXED_F32:
-            script_f32_relaxed.forEach_log1p_f32_1(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_2:
-            script_f32_relaxed.forEach_log1p_f32_2(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_3:
-            script_f32_relaxed.forEach_log1p_f32_3(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_4:
-            script_f32_relaxed.forEach_log1p_f32_4(mIn, mOut);
-            break;
-        }
-    }
-
-    @Override
-    protected float[] getRefArray(float[] in, int input_size, int stride, int skip) {
-        float[] ref = new float[input_size * stride];
-        for (int i = 0; i < input_size; i++) {
-            for (int j = 0; j < stride - skip; j++) {
-                int idx= i * stride + j;
-                int idxRef = i * (stride - skip) + j;
-                ref[idxRef] = (float)(Math.log1p((double)in[idx]));
-            }
-        }
-        return ref;
-    }
-
-    public void testLog1PF32() {
-        doF32(0xab, 2);
-    }
-
-    public void testLog1PF32_relaxed() {
-        doF32_relaxed(0xab, 16);
-    }
-
-    public void testLog1PF32_2() {
-        doF32_2(0x12, 2);
-    }
-
-    public void testLog1PF32_2_relaxed() {
-        doF32_2_relaxed(0x12, 16);
-    }
-
-    public void testLog1PF32_3() {
-        doF32_3(0xa1, 2);
-    }
-
-    public void testLog1PF32_3_relaxed() {
-        doF32_3_relaxed(0xa1, 16);
-    }
-
-    public void testLog1PF32_4() {
-        doF32_4(0xbae, 2);
-
-    }
-    public void testLog1PF32_4_relaxed() {
-        doF32_4_relaxed(0xbae, 16);
-    }
-
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/Log2Test.java b/tests/tests/renderscript/src/android/renderscript/cts/Log2Test.java
deleted file mode 100644
index dd13d8d..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/Log2Test.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * 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 android.renderscript.cts;
-
-import com.android.cts.stub.R;
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-
-public class Log2Test extends RSBaseCompute {
-    private ScriptC_log2_f32 script_f32;
-    private ScriptC_log2_f32_relaxed script_f32_relaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script_f32 = new ScriptC_log2_f32(mRS);
-        script_f32_relaxed = new ScriptC_log2_f32_relaxed(mRS);
-    }
-
-    @Override
-    public void forEach(int testId, Allocation mIn, Allocation mOut) throws RSRuntimeException {
-        switch (testId) {
-        case TEST_F32:
-            script_f32.forEach_log2_f32_1(mIn, mOut);
-            break;
-        case TEST_F32_2:
-            script_f32.forEach_log2_f32_2(mIn, mOut);
-            break;
-        case TEST_F32_3:
-            script_f32.forEach_log2_f32_3(mIn, mOut);
-            break;
-        case TEST_F32_4:
-            script_f32.forEach_log2_f32_4(mIn, mOut);
-            break;
-
-        case TEST_RELAXED_F32:
-            script_f32_relaxed.forEach_log2_f32_1(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_2:
-            script_f32_relaxed.forEach_log2_f32_2(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_3:
-            script_f32_relaxed.forEach_log2_f32_3(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_4:
-            script_f32_relaxed.forEach_log2_f32_4(mIn, mOut);
-            break;
-        }
-    }
-
-    @Override
-    protected float[] getRefArray(float[] in, int input_size, int stride, int skip) {
-        float[] ref = new float[input_size * stride];
-        for (int i = 0; i < input_size; i++) {
-            for (int j = 0; j < stride - skip; j++) {
-                int idx= i * stride + j;
-                int idxRef = i * (stride - skip) + j;
-                ref[idxRef] = (float)(Math.log10((double)in[idx])/Math.log10(2.0));
-            }
-        }
-        return ref;
-    }
-
-    public void testLog2F32() {
-        doF32(0x18a, 3);
-    }
-
-    public void testLog2F32_relaxed() {
-        doF32_relaxed(0x18a, 128);
-    }
-
-    public void testLog2F32_2() {
-        doF32_2(0xfa, 3);
-    }
-
-    public void testLog2F32_2_relaxed() {
-        doF32_2_relaxed(0xfa, 128);
-    }
-
-    public void testLog2F32_3() {
-        doF32_3(0xaef, 3);
-    }
-
-    public void testLog2F32_3_relaxed() {
-        doF32_3_relaxed(0xaef, 128);
-    }
-
-    public void testLog2F32_4() {
-        doF32_4(0xae62, 3);
-
-    }
-    public void testLog2F32_4_relaxed() {
-        doF32_4_relaxed(0xae62, 128);
-    }
-
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/LogTest.java b/tests/tests/renderscript/src/android/renderscript/cts/LogTest.java
deleted file mode 100644
index ee03b4e..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/LogTest.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * 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 android.renderscript.cts;
-
-import com.android.cts.stub.R;
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-
-public class LogTest extends RSBaseCompute {
-    private ScriptC_log_f32 script_f32;
-    private ScriptC_log_f32_relaxed script_f32_relaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script_f32 = new ScriptC_log_f32(mRS);
-        script_f32_relaxed = new ScriptC_log_f32_relaxed(mRS);
-    }
-
-    @Override
-    public void forEach(int testId, Allocation mIn, Allocation mOut) throws RSRuntimeException {
-        switch (testId) {
-        case TEST_F32:
-            script_f32.forEach_log_f32_1(mIn, mOut);
-            break;
-        case TEST_F32_2:
-            script_f32.forEach_log_f32_2(mIn, mOut);
-            break;
-        case TEST_F32_3:
-            script_f32.forEach_log_f32_3(mIn, mOut);
-            break;
-        case TEST_F32_4:
-            script_f32.forEach_log_f32_4(mIn, mOut);
-            break;
-
-        case TEST_RELAXED_F32:
-            script_f32_relaxed.forEach_log_f32_1(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_2:
-            script_f32_relaxed.forEach_log_f32_2(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_3:
-            script_f32_relaxed.forEach_log_f32_3(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_4:
-            script_f32_relaxed.forEach_log_f32_4(mIn, mOut);
-            break;
-        }
-    }
-
-    @Override
-    protected float[] getRefArray(float[] in, int input_size, int stride, int skip) {
-        float[] ref = new float[input_size * stride];
-        for (int i = 0; i < input_size; i++) {
-            for (int j = 0; j < stride - skip; j++) {
-                int idx= i * stride + j;
-                int idxRef = i * (stride - skip) + j;
-                ref[idxRef] = (float)(Math.log((double)in[idx]));
-            }
-        }
-        return ref;
-    }
-
-    public void testLogF32() {
-        doF32(0xfae, 3);
-    }
-
-    public void testLogF32_relaxed() {
-        doF32_relaxed(0xfae, 16);
-    }
-
-    public void testLogF32_2() {
-        doF32_2(0x123, 3);
-    }
-
-    public void testLogF32_2_relaxed() {
-        doF32_2_relaxed(0x123, 16);
-    }
-
-    public void testLogF32_3() {
-        doF32_3(0xab4, 3);
-    }
-
-    public void testLogF32_3_relaxed() {
-        doF32_3_relaxed(0xab4, 16);
-    }
-
-    public void testLogF32_4() {
-        doF32_4(0xfa3, 3);
-
-    }
-    public void testLogF32_4_relaxed() {
-        doF32_4_relaxed(0xfa3, 16);
-    }
-
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/LogbTest.java b/tests/tests/renderscript/src/android/renderscript/cts/LogbTest.java
deleted file mode 100644
index b42d680..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/LogbTest.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * 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 android.renderscript.cts;
-
-import com.android.cts.stub.R;
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-
-public class LogbTest extends RSBaseCompute {
-    private ScriptC_logb_f32 script_f32;
-    private ScriptC_logb_f32_relaxed script_f32_relaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script_f32 = new ScriptC_logb_f32(mRS);
-        script_f32_relaxed = new ScriptC_logb_f32_relaxed(mRS);
-    }
-
-    @Override
-    public void forEach(int testId, Allocation mIn, Allocation mOut) throws RSRuntimeException {
-        switch (testId) {
-        case TEST_F32:
-            script_f32.forEach_logb_f32_1(mIn, mOut);
-            break;
-        case TEST_F32_2:
-            script_f32.forEach_logb_f32_2(mIn, mOut);
-            break;
-        case TEST_F32_3:
-            script_f32.forEach_logb_f32_3(mIn, mOut);
-            break;
-        case TEST_F32_4:
-            script_f32.forEach_logb_f32_4(mIn, mOut);
-            break;
-
-        case TEST_RELAXED_F32:
-            script_f32_relaxed.forEach_logb_f32_1(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_2:
-            script_f32_relaxed.forEach_logb_f32_2(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_3:
-            script_f32_relaxed.forEach_logb_f32_3(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_4:
-            script_f32_relaxed.forEach_logb_f32_4(mIn, mOut);
-            break;
-        }
-    }
-
-    @Override
-    protected float[] getRefArray(float[] in, int input_size, int stride, int skip) {
-        float[] ref = new float[input_size * stride];
-        for (int i = 0; i < input_size; i++) {
-            for (int j = 0; j < stride - skip; j++) {
-                int idx= i * stride + j;
-                int idxRef = i * (stride - skip) + j;
-                ref[idxRef] = ((Float.floatToIntBits(in[idx]) >> 23) & 0xFF) - 127.0f;
-            }
-        }
-        return ref;
-    }
-
-    public void testLogbF32() {
-        doF32(0xe, 0);
-    }
-
-    public void testLogbF32_relaxed() {
-        doF32_relaxed(0xe, 0);
-    }
-
-    public void testLogbF32_2() {
-        doF32_2(0xa1, 0);
-    }
-
-    public void testLogbF32_2_relaxed() {
-        doF32_2_relaxed(0xa1, 0);
-    }
-
-    public void testLogbF32_3() {
-        doF32_3(0xab2, 0);
-    }
-
-    public void testLogbF32_3_relaxed() {
-        doF32_3_relaxed(0xab2, 0);
-    }
-
-    public void testLogbF32_4() {
-        doF32_4(0xaa2, 0);
-
-    }
-    public void testLogbF32_4_relaxed() {
-        doF32_4_relaxed(0xaa2, 0);
-    }
-
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/MadTest.java b/tests/tests/renderscript/src/android/renderscript/cts/MadTest.java
deleted file mode 100644
index 3662035..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/MadTest.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * 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 android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.Element;
-import android.renderscript.RSRuntimeException;
-import com.android.cts.stub.R;
-
-public class MadTest extends RSBaseCompute {
-    private ScriptC_mad_f32 script_f32;
-    private ScriptC_mad_f32_relaxed script_f32_relaxed;
-    private Allocation mIn;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script_f32 = new ScriptC_mad_f32(mRS);
-        script_f32_relaxed = new ScriptC_mad_f32_relaxed(mRS);
-    }
-
-    @Override
-    public void forEach(int testId, Allocation mIn, Allocation mOut) throws RSRuntimeException {
-        switch (testId) {
-        case TEST_F32:
-            script_f32.forEach_mad_f32_1(mIn, mOut);
-            break;
-        case TEST_F32_2:
-            script_f32.forEach_mad_f32_2(mIn, mOut);
-            break;
-        case TEST_F32_3:
-            script_f32.forEach_mad_f32_3(mIn, mOut);
-            break;
-        case TEST_F32_4:
-            script_f32.forEach_mad_f32_4(mIn, mOut);
-            break;
-
-        case TEST_RELAXED_F32:
-            script_f32_relaxed.forEach_mad_f32_1(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_2:
-            script_f32_relaxed.forEach_mad_f32_2(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_3:
-            script_f32_relaxed.forEach_mad_f32_3(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_4:
-            script_f32_relaxed.forEach_mad_f32_4(mIn, mOut);
-            break;
-        }
-    }
-
-    @Override
-    protected float[] getRefArray(float[] in, int input_size, int stride, int skip) {
-        float[] ref = new float[input_size * stride];
-        for (int i = 0; i < input_size; i++) {
-            for (int j = 0; j < stride - skip; j++) {
-                int idx = i * stride * 3 + j;
-                ref[i * (stride - skip) + j] = (float)((double)in[idx] * (double)in[idx+stride] + (double)in[idx+stride*2]);
-            }
-        }
-        return ref;
-    }
-
-    @Override
-    protected Allocation setInAlloc(Element e) {
-        return mIn;
-    }
-
-    @Override
-    protected float[] makeInArray(int size) {
-        return new float[size*3];
-    }
-
-    public void testMadF32() {
-        ScriptField_mad_input_f32 in = new ScriptField_mad_input_f32(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32(0x123678, 4);
-    }
-
-    public void testMadF32_relaxed() {
-        ScriptField_mad_input_f32 in = new ScriptField_mad_input_f32(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_relaxed(0x123678, 4);
-    }
-
-    public void testMadF32_2() {
-        ScriptField_mad_input_f32_2 in = new ScriptField_mad_input_f32_2(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_2(0x1234a5, 4);
-    }
-
-    public void testMadF32_2_relaxed() {
-        ScriptField_mad_input_f32_2 in = new ScriptField_mad_input_f32_2(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_2_relaxed(0x1234a5, 4);
-    }
-
-    public void testMadF32_3() {
-        ScriptField_mad_input_f32_3 in = new ScriptField_mad_input_f32_3(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_3(0x1af345, 4);
-    }
-
-    public void testMadF32_3_relaxed() {
-        ScriptField_mad_input_f32_3 in = new ScriptField_mad_input_f32_3(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_3_relaxed(0x1af345, 4);
-    }
-
-    public void testMadF32_4() {
-        ScriptField_mad_input_f32_4 in = new ScriptField_mad_input_f32_4(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_4(0x12ce45, 4);
-    }
-
-    public void testMadF32_4_relaxed() {
-        ScriptField_mad_input_f32_4 in = new ScriptField_mad_input_f32_4(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_4_relaxed(0x12ce45, 4);
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/NextafterTest.java b/tests/tests/renderscript/src/android/renderscript/cts/NextafterTest.java
deleted file mode 100644
index 468b341..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/NextafterTest.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * 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 android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.Element;
-import android.renderscript.RSRuntimeException;
-import com.android.cts.stub.R;
-
-public class NextafterTest extends RSBaseCompute {
-    private ScriptC_nextafter_f32 script_f32;
-    private ScriptC_nextafter_f32_relaxed script_f32_relaxed;
-    private Allocation mIn;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script_f32 = new ScriptC_nextafter_f32(mRS);
-        script_f32_relaxed = new ScriptC_nextafter_f32_relaxed(mRS);
-    }
-
-    @Override
-    public void forEach(int testId, Allocation mIn, Allocation mOut) throws RSRuntimeException {
-        switch (testId) {
-        case TEST_F32:
-            script_f32.forEach_nextafter_f32_1(mIn, mOut);
-            break;
-        case TEST_F32_2:
-            script_f32.forEach_nextafter_f32_2(mIn, mOut);
-            break;
-        case TEST_F32_3:
-            script_f32.forEach_nextafter_f32_3(mIn, mOut);
-            break;
-        case TEST_F32_4:
-            script_f32.forEach_nextafter_f32_4(mIn, mOut);
-            break;
-
-        case TEST_RELAXED_F32:
-            script_f32_relaxed.forEach_nextafter_f32_1(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_2:
-            script_f32_relaxed.forEach_nextafter_f32_2(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_3:
-            script_f32_relaxed.forEach_nextafter_f32_3(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_4:
-            script_f32_relaxed.forEach_nextafter_f32_4(mIn, mOut);
-            break;
-        }
-    }
-
-    @Override
-    protected float[] getRefArray(float[] in, int input_size, int stride, int skip) {
-        float[] ref = new float[input_size * stride];
-        for (int i = 0; i < input_size; i++) {
-            for (int j = 0; j < stride - skip; j++) {
-                int idx = i * stride * 2 + j;
-                ref[i * (stride - skip) + j] = Math.nextAfter(in[idx],(double)in[idx+stride]);
-            }
-        }
-        return ref;
-    }
-
-    @Override
-    protected Allocation setInAlloc(Element e) {
-        return mIn;
-    }
-
-    @Override
-    protected float[] makeInArray(int size) {
-        return new float[size*2];
-    }
-
-    public void testNextafterF32() {
-        ScriptField_InputData inputDataArray = new ScriptField_InputData(mRS, INPUTSIZE);
-        mIn = inputDataArray.getAllocation();
-        doF32(0x12678, 0);
-    }
-
-    public void testNextafterF32_relaxed() {
-        ScriptField_InputData inputDataArray = new ScriptField_InputData(mRS, INPUTSIZE);
-        mIn = inputDataArray.getAllocation();
-        doF32_relaxed(0x12678, 0);
-    }
-
-    public void testNextafterF32_2() {
-        ScriptField_InputData_2 inputDataArray = new ScriptField_InputData_2(mRS, INPUTSIZE);
-        mIn = inputDataArray.getAllocation();
-        doF32_2(0x1af45, 0);
-    }
-
-    public void testNextafterF32_2_relaxed() {
-        ScriptField_InputData_2 inputDataArray = new ScriptField_InputData_2(mRS, INPUTSIZE);
-        mIn = inputDataArray.getAllocation();
-        doF32_2_relaxed(0x1af45, 0);
-    }
-
-    public void testNextafterF32_3() {
-        ScriptField_InputData_3 inputDataArray = new ScriptField_InputData_3(mRS, INPUTSIZE);
-        mIn = inputDataArray.getAllocation();
-        doF32_3(0x1cd345, 0);
-    }
-
-    public void testNextafterF32_3_relaxed() {
-        ScriptField_InputData_3 inputDataArray = new ScriptField_InputData_3(mRS, INPUTSIZE);
-        mIn = inputDataArray.getAllocation();
-        doF32_3_relaxed(0x1cd345, 0);
-    }
-
-    public void testNextafterF32_4() {
-        ScriptField_InputData_4 inputDataArray = new ScriptField_InputData_4(mRS, INPUTSIZE);
-        mIn = inputDataArray.getAllocation();
-        doF32_4(0x1ca45, 0);
-    }
-
-    public void testNextafterF32_4_relaxed() {
-        ScriptField_InputData_4 inputDataArray = new ScriptField_InputData_4(mRS, INPUTSIZE);
-        mIn = inputDataArray.getAllocation();
-        doF32_4_relaxed(0x1ca45, 0);
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/PowTest.java b/tests/tests/renderscript/src/android/renderscript/cts/PowTest.java
deleted file mode 100644
index ad3d078..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/PowTest.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * 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 android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.Element;
-import android.renderscript.RSRuntimeException;
-import com.android.cts.stub.R;
-
-public class PowTest extends RSBaseCompute {
-    private ScriptC_pow_f32 script_f32;
-    private ScriptC_pow_f32_relaxed script_f32_relaxed;
-    private Allocation mIn;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script_f32 = new ScriptC_pow_f32(mRS);
-        script_f32_relaxed = new ScriptC_pow_f32_relaxed(mRS);
-    }
-
-    @Override
-    public void forEach(int testId, Allocation mIn, Allocation mOut) throws RSRuntimeException {
-        switch (testId) {
-        case TEST_F32:
-            script_f32.forEach_pow_f32_1(mIn, mOut);
-            break;
-        case TEST_F32_2:
-            script_f32.forEach_pow_f32_2(mIn, mOut);
-            break;
-        case TEST_F32_3:
-            script_f32.forEach_pow_f32_3(mIn, mOut);
-            break;
-        case TEST_F32_4:
-            script_f32.forEach_pow_f32_4(mIn, mOut);
-            break;
-
-        case TEST_RELAXED_F32:
-            script_f32_relaxed.forEach_pow_f32_1(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_2:
-            script_f32_relaxed.forEach_pow_f32_2(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_3:
-            script_f32_relaxed.forEach_pow_f32_3(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_4:
-            script_f32_relaxed.forEach_pow_f32_4(mIn, mOut);
-            break;
-        }
-    }
-
-    @Override
-    protected float[] getRefArray(float[] in, int input_size, int stride, int skip) {
-        float[] ref = new float[input_size * stride];
-        for (int i = 0; i < input_size; i++) {
-            for (int j = 0; j < stride - skip; j++) {
-                int idx= i * stride * 2 + j;
-                int idxRef = i * (stride - skip) + j;
-                ref[idxRef] = (float)Math.pow((double)in[idx], (double)in[idx+stride]);
-            }
-        }
-        return ref;
-    }
-
-    @Override
-    protected Allocation setInAlloc(Element e) {
-        return mIn;
-    }
-
-    @Override
-    protected float[] makeInArray(int size) {
-        return new float[size*2];
-    }
-
-    @Override
-    protected void fillRandomFloats(long seed, int fact, int offset, float[] inArray) {
-        RSUtils.genRandomFloats(seed, 32, -16, inArray);
-    }
-
-    public void testPowF32() {
-        ScriptField_PowInputData in = new ScriptField_PowInputData(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32(0x12345678, 16);
-    }
-
-    public void testPowF32_relaxed() {
-        ScriptField_PowInputData in = new ScriptField_PowInputData(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_relaxed(0x12345678, 128);
-    }
-
-    public void testPowF32_2() {
-        ScriptField_PowInputData_2 in = new ScriptField_PowInputData_2(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_2(0x12ab78, 16);
-    }
-
-    public void testPowF32_2_relaxed() {
-        ScriptField_PowInputData_2 in = new ScriptField_PowInputData_2(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_2_relaxed(0x12ab78, 128);
-    }
-
-    public void testPowF32_3() {
-        ScriptField_PowInputData_3 in = new ScriptField_PowInputData_3(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_3(0x1f5678, 16);
-    }
-
-    public void testPowF32_3_relaxed() {
-        ScriptField_PowInputData_3 in = new ScriptField_PowInputData_3(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_3_relaxed(0x1f5678, 128);
-    }
-
-    public void testPowF32_4() {
-        ScriptField_PowInputData_4 in = new ScriptField_PowInputData_4(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_4(0xc678, 16);
-    }
-
-    public void testPowF32_4_relaxed() {
-        ScriptField_PowInputData_4 in = new ScriptField_PowInputData_4(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_4_relaxed(0xc678, 128);
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/PownTest.java b/tests/tests/renderscript/src/android/renderscript/cts/PownTest.java
deleted file mode 100644
index 32308ce..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/PownTest.java
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * 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 android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.Element;
-import android.renderscript.RSRuntimeException;
-import com.android.cts.stub.R;
-
-public class PownTest extends RSBaseCompute {
-    private ScriptC_pown_f32 script_f32;
-    private ScriptC_pown_f32_relaxed script_f32_relaxed;
-    private int[] n;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script_f32 = new ScriptC_pown_f32(mRS);
-        script_f32_relaxed = new ScriptC_pown_f32_relaxed(mRS);
-    }
-
-    @Override
-    public void forEach(int testId, Allocation mIn, Allocation mOut) throws RSRuntimeException {
-        switch (testId) {
-        case TEST_F32:
-            script_f32.forEach_pown_f32_1(mIn, mOut);
-            break;
-        case TEST_F32_2:
-            script_f32.forEach_pown_f32_2(mIn, mOut);
-            break;
-        case TEST_F32_3:
-            script_f32.forEach_pown_f32_3(mIn, mOut);
-            break;
-        case TEST_F32_4:
-            script_f32.forEach_pown_f32_4(mIn, mOut);
-            break;
-
-        case TEST_RELAXED_F32:
-            script_f32_relaxed.forEach_pown_f32_1(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_2:
-            script_f32_relaxed.forEach_pown_f32_2(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_3:
-            script_f32_relaxed.forEach_pown_f32_3(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_4:
-            script_f32_relaxed.forEach_pown_f32_4(mIn, mOut);
-            break;
-
-        }
-    }
-
-    @Override
-    protected float[] getRefArray(float[] in, int input_size, int stride, int skip) {
-        float[] ref = new float[input_size * stride];
-        for (int i = 0; i < input_size; i++) {
-            for (int j = 0; j < stride - skip; j++) {
-                int idx= i * stride + j;
-                int idxRef = i * (stride - skip) + j;
-                ref[idxRef] = (float)Math.pow((double)in[idx], (double)n[idx]);
-            }
-        }
-        return ref;
-    }
-
-    public void testPownF32() {
-        Allocation nAlloc = Allocation.createSized(mRS, Element.I32(mRS), INPUTSIZE);
-
-        n = new int[INPUTSIZE];
-        RSUtils.genRandomInts(0x12345678, 32, -16, n);
-        nAlloc.copyFrom(n);
-        script_f32.set_n1(nAlloc);
-
-        doF32(0x716acd, 16);
-    }
-
-    public void testPownF32_relaxed() {
-        Allocation nAlloc = Allocation.createSized(mRS, Element.I32(mRS), INPUTSIZE);
-
-        n = new int[INPUTSIZE];
-        RSUtils.genRandomInts(0x12345678, 32, -16, n);
-        nAlloc.copyFrom(n);
-        script_f32_relaxed.set_n1(nAlloc);
-
-        doF32_relaxed(0x716acd, 128);
-    }
-
-    public void testPownF32_2() {
-        Allocation nAlloc = Allocation.createSized(mRS, Element.I32_2(mRS), INPUTSIZE);
-
-        n = new int[INPUTSIZE*2];
-        RSUtils.genRandomInts(0xacdef1, 32, -16, n);
-        nAlloc.copyFrom(n);
-        script_f32.set_n2(nAlloc);
-
-        doF32_2(0xacdef1, 16);
-    }
-
-    public void testPownF32_2_relaxed() {
-        Allocation nAlloc = Allocation.createSized(mRS, Element.I32_2(mRS), INPUTSIZE);
-
-        n = new int[INPUTSIZE*2];
-        RSUtils.genRandomInts(0xacdef1, 32, -16, n);
-        nAlloc.copyFrom(n);
-        script_f32_relaxed.set_n2(nAlloc);
-
-        doF32_2_relaxed(0xacdef1, 128);
-    }
-
-    public void testPownF32_3() {
-        Allocation nAlloc = Allocation.createSized(mRS, Element.I32_3(mRS), INPUTSIZE);
-
-        n = new int[INPUTSIZE*4];
-        RSUtils.genRandomInts(0xa123f1, 32, -16, n);
-        nAlloc.copyFrom(n);
-        script_f32.set_n3(nAlloc);
-
-        doF32_3(0xaac3f1, 16);
-    }
-
-    public void testPownF32_3_relaxed() {
-        Allocation nAlloc = Allocation.createSized(mRS, Element.I32_3(mRS), INPUTSIZE);
-
-        n = new int[INPUTSIZE*4];
-        RSUtils.genRandomInts(0xa123f1, 32, -16, n);
-        nAlloc.copyFrom(n);
-        script_f32_relaxed.set_n3(nAlloc);
-
-        doF32_3_relaxed(0xaac3f1, 128);
-    }
-
-    public void testPownF32_4() {
-        Allocation nAlloc = Allocation.createSized(mRS, Element.I32_4(mRS), INPUTSIZE);
-
-        n = new int[INPUTSIZE*4];
-        RSUtils.genRandomInts(0x4323ca, 32, -16, n);
-        nAlloc.copyFrom(n);
-        script_f32.set_n4(nAlloc);
-
-        doF32_4(0xaa12f1, 16);
-    }
-
-    public void testPownF32_4_relaxed() {
-        Allocation nAlloc = Allocation.createSized(mRS, Element.I32_4(mRS), INPUTSIZE);
-
-        n = new int[INPUTSIZE*4];
-        RSUtils.genRandomInts(0x4323ca, 32, -16, n);
-        nAlloc.copyFrom(n);
-        script_f32_relaxed.set_n4(nAlloc);
-
-        doF32_4_relaxed(0xaa12f1, 128);
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/PowrTest.java b/tests/tests/renderscript/src/android/renderscript/cts/PowrTest.java
deleted file mode 100644
index cebbe24..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/PowrTest.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * 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 android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.Element;
-import android.renderscript.RSRuntimeException;
-import com.android.cts.stub.R;
-
-public class PowrTest extends RSBaseCompute {
-    private ScriptC_powr_f32 script_f32;
-    private ScriptC_powr_f32_relaxed script_f32_relaxed;
-    private Allocation mIn;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script_f32 = new ScriptC_powr_f32(mRS);
-        script_f32_relaxed = new ScriptC_powr_f32_relaxed(mRS);
-    }
-
-    @Override
-    public void forEach(int testId, Allocation mIn, Allocation mOut) throws RSRuntimeException {
-        switch (testId) {
-        case TEST_F32:
-            script_f32.forEach_powr_f32_1(mIn, mOut);
-            break;
-        case TEST_F32_2:
-            script_f32.forEach_powr_f32_2(mIn, mOut);
-            break;
-        case TEST_F32_3:
-            script_f32.forEach_powr_f32_3(mIn, mOut);
-            break;
-        case TEST_F32_4:
-            script_f32.forEach_powr_f32_4(mIn, mOut);
-            break;
-
-        case TEST_RELAXED_F32:
-            script_f32_relaxed.forEach_powr_f32_1(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_2:
-            script_f32_relaxed.forEach_powr_f32_2(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_3:
-            script_f32_relaxed.forEach_powr_f32_3(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_4:
-            script_f32_relaxed.forEach_powr_f32_4(mIn, mOut);
-            break;
-        }
-    }
-
-    @Override
-    protected float[] getRefArray(float[] in, int input_size, int stride, int skip) {
-        float[] ref = new float[input_size * stride];
-        for (int i = 0; i < input_size; i++) {
-            for (int j = 0; j < stride - skip; j++) {
-                int idx= i * stride * 2 + j;
-                int idxRef = i * (stride - skip) + j;
-                ref[idxRef] = (float)Math.pow((double)in[idx], (double)in[idx+stride]);
-            }
-        }
-        return ref;
-    }
-
-    @Override
-    protected Allocation setInAlloc(Element e) {
-        return mIn;
-    }
-
-    @Override
-    protected float[] makeInArray(int size) {
-        return new float[size*2];
-    }
-
-    @Override
-    protected void fillRandomFloats(long seed, int fact, int offset, float[] inArray) {
-        RSUtils.genRandomFloats(seed, 64, 0, inArray);
-    }
-
-    public void testPowrF32() {
-        ScriptField_PowInputData in = new ScriptField_PowInputData(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32(0x12345678, 16);
-    }
-
-    public void testPowrF32_relaxed() {
-        ScriptField_PowInputData in = new ScriptField_PowInputData(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_relaxed(0x12345678, 128);
-    }
-
-    public void testPowrF32_2() {
-        ScriptField_PowInputData_2 in = new ScriptField_PowInputData_2(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_2(0x12ab78, 16);
-    }
-
-    public void testPowrF32_2_relaxed() {
-        ScriptField_PowInputData_2 in = new ScriptField_PowInputData_2(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_2(0x12ab78, 128);
-    }
-
-    public void testPowrF32_3() {
-        ScriptField_PowInputData_3 in = new ScriptField_PowInputData_3(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_3(0x1f5678, 16);
-    }
-
-    public void testPowrF32_3_relaxed() {
-        ScriptField_PowInputData_3 in = new ScriptField_PowInputData_3(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_3_relaxed(0x1f5678, 128);
-    }
-
-    public void testPowrF32_4() {
-        ScriptField_PowInputData_4 in = new ScriptField_PowInputData_4(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_4(0xc678, 16);
-    }
-
-    public void testPowrF32_4_relaxed() {
-        ScriptField_PowInputData_4 in = new ScriptField_PowInputData_4(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_4_relaxed(0xc678, 128);
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/RSBase.java b/tests/tests/renderscript/src/android/renderscript/cts/RSBase.java
index 29183f0..ebf15dc 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/RSBase.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/RSBase.java
@@ -28,7 +28,7 @@
  * Base RenderScript test class. This class provides a message handler and a
  * convenient way to wait for compute scripts to complete their execution.
  */
-class RSBase extends AndroidTestCase {
+public class RSBase extends AndroidTestCase {
 
     Context mCtx;
     Resources mRes;
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/RSBaseCompute.java b/tests/tests/renderscript/src/android/renderscript/cts/RSBaseCompute.java
index d7759f1..f217bc3 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/RSBaseCompute.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/RSBaseCompute.java
@@ -26,17 +26,8 @@
  * Base RenderScript test class. This class provides a message handler and a
  * convenient way to wait for compute scripts to complete their execution.
  */
-class RSBaseCompute extends RSBase {
+public class RSBaseCompute extends RSBase {
     RenderScript mRS;
-
-    static final int TEST_F32 = 0;
-    static final int TEST_F32_2 = 1;
-    static final int TEST_F32_3 = 2;
-    static final int TEST_F32_4 = 3;
-    static final int TEST_RELAXED_F32 = 4;
-    static final int TEST_RELAXED_F32_2 = 5;
-    static final int TEST_RELAXED_F32_3 = 6;
-    static final int TEST_RELAXED_F32_4 = 7;
     protected int INPUTSIZE = 512;
 
     @Override
@@ -85,65 +76,322 @@
         }
     }
 
-    private void baseTestHelper(int testid, Element inElement, Element outElement, long seed, int fact,
-                                int offset, int rStride, int rSkip, int refStride, int outStride,
-                                int inStride, int skip, int ulp) {
-        float[] inArray = makeInArray(INPUTSIZE * inStride);
-        fillRandomFloats(seed, fact, offset, inArray);
-        float[] refArray = getRefArray(inArray, INPUTSIZE, inStride, skip);
-
-        Allocation mAllocationIn = setInAlloc(inElement);
-        fillInAlloc(mAllocationIn, inArray);
-
-        Allocation mAllocationOut = setOutAlloc(outElement);
-        try {
-            forEach(testid, mAllocationIn, mAllocationOut);
-        } catch (RSRuntimeException e) {
-            Log.e("RenderscriptCTS", "Caught RSRuntimeException: " +
-                  e.getMessage());
+    // TODO Is there a better way to do this
+    protected Element getElement(RenderScript rs, Element.DataType dataType, int size) {
+        Element element = null;
+        if (size == 1) {
+            if (dataType == Element.DataType.FLOAT_64) {
+                element = Element.F64(rs);
+            } else if (dataType == Element.DataType.FLOAT_32) {
+                element = Element.F32(rs);
+            } else if (dataType == Element.DataType.SIGNED_64) {
+                element = Element.I64(rs);
+            } else if (dataType == Element.DataType.UNSIGNED_64) {
+                element = Element.U64(rs);
+            } else if (dataType == Element.DataType.SIGNED_32) {
+                element = Element.I32(rs);
+            } else if (dataType == Element.DataType.UNSIGNED_32) {
+                element = Element.U32(rs);
+            } else if (dataType == Element.DataType.SIGNED_16) {
+                element = Element.I16(rs);
+            } else if (dataType == Element.DataType.UNSIGNED_16) {
+                element = Element.U16(rs);
+            } else if (dataType == Element.DataType.SIGNED_8) {
+                element = Element.I8(rs);
+            } else if (dataType == Element.DataType.UNSIGNED_8) {
+                element = Element.U8(rs);
+            } else {
+                android.util.Log.e("RenderscriptCTS", "Don't know how to create allocation of type" +
+                        dataType.toString());
+            }
+        } else {
+            element = Element.createVector(rs, dataType, size);
         }
-        float[] outArray = makeOutArray(INPUTSIZE * outStride);
-        mAllocationOut.copyTo(outArray);
-        checkArray(refArray, outArray, INPUTSIZE, refStride, outStride, ulp);
+        return element;
     }
 
-    public void baseTest(int testid, long seed, int refStride, int outStride, int inStride, int skip, int ulp) {
-        baseTestHelper(testid, null, null, seed, 1, 0, 1, 0, refStride, outStride, inStride, skip, ulp);
+    protected Allocation createRandomAllocation(RenderScript rs, Element.DataType dataType,
+            int size, long seed, boolean includeExtremes) {
+        Element element = getElement(rs, dataType, size);
+        Allocation alloc = Allocation.createSized(rs, element, INPUTSIZE);
+        int width = (size == 3) ? 4 : size;
+        /* TODO copy1DRangeFrom does not work for double
+        if (dataType == Element.DataType.FLOAT_64) {
+            double[] inArray = new double[INPUTSIZE * width];
+            // TODO The ranges for float is too small.  We need to accept a wider range of values.
+            double min = -4.0 * Math.PI;
+            double max = 4.0 * Math.PI;
+            RSUtils.genRandomDoubles(seed, min, max, inArray, includeExtremes);
+            alloc.copy1DRangeFrom(0, INPUTSIZE, inArray);
+        } else
+        */
+        if (dataType == Element.DataType.FLOAT_32) {
+            float[] inArray = new float[INPUTSIZE * width];
+            // TODO The ranges for float is too small.  We need to accept a wider range of values.
+            float min = -4.0f * (float) Math.PI;
+            float max = 4.0f * (float) Math.PI;
+            RSUtils.genRandomFloats(seed, min, max, inArray, includeExtremes);
+            alloc.copy1DRangeFrom(0, INPUTSIZE, inArray);
+        /* TODO copy1DRangFrom does not work for long
+        } else if (dataType == Element.DataType.SIGNED_64) {
+            long[] inArray = new long[INPUTSIZE * width];
+            RSUtils.genRandomLongs(seed, inArray, true, 63);
+            alloc.copy1DRangeFrom(0, INPUTSIZE, inArray);
+        } else if (dataType == Element.DataType.UNSIGNED_64) {
+            long[] inArray = new long[INPUTSIZE * width];
+            RSUtils.genRandomLongs(seed, inArray, false, 64);
+            alloc.copy1DRangeFrom(0, INPUTSIZE, inArray);
+        */
+        } else if (dataType == Element.DataType.SIGNED_32) {
+            int[] inArray = new int[INPUTSIZE * width];
+            RSUtils.genRandomInts(seed, inArray, true, 31);
+            alloc.copy1DRangeFrom(0, INPUTSIZE, inArray);
+        } else if (dataType == Element.DataType.UNSIGNED_32) {
+            int[] inArray = new int[INPUTSIZE * width];
+            RSUtils.genRandomInts(seed, inArray, false, 32);
+            alloc.copy1DRangeFrom(0, INPUTSIZE, inArray);
+        } else if (dataType == Element.DataType.SIGNED_16) {
+            short[] inArray = new short[INPUTSIZE * width];
+            RSUtils.genRandomShorts(seed, inArray, true, 15);
+            alloc.copy1DRangeFrom(0, INPUTSIZE, inArray);
+        } else if (dataType == Element.DataType.UNSIGNED_16) {
+            short[] inArray = new short[INPUTSIZE * width];
+            RSUtils.genRandomShorts(seed, inArray, false, 16);
+            alloc.copy1DRangeFrom(0, INPUTSIZE, inArray);
+        } else if (dataType == Element.DataType.SIGNED_8) {
+            byte[] inArray = new byte[INPUTSIZE * width];
+            RSUtils.genRandomBytes(seed, inArray, true, 7);
+            alloc.copy1DRangeFrom(0, INPUTSIZE, inArray);
+        } else if (dataType == Element.DataType.UNSIGNED_8) {
+            byte[] inArray = new byte[INPUTSIZE * width];
+            RSUtils.genRandomBytes(seed, inArray, true, 8);
+            alloc.copy1DRangeFrom(0, INPUTSIZE, inArray);
+        } else {
+            android.util.Log.e("RenderscriptCTS", "Don't know how to create allocation of type" +
+                    dataType.toString());
+        }
+        return alloc;
     }
 
-    public void doF32(long seed, int ulp) {
-        baseTestHelper(TEST_F32, Element.F32(mRS), Element.F32(mRS), seed, 1, 0, 1, 0, 1, 1, 1, 0, ulp);
+    protected Allocation createRandomFloatAllocation(RenderScript rs, Element.DataType dataType,
+            int size, long seed, double minValue, double maxValue) {
+        Element element = getElement(rs, dataType, size);
+        Allocation alloc = Allocation.createSized(rs, element, INPUTSIZE);
+        int width = (size == 3) ? 4 : size;
+        /* TODO copy1DRangeFrom does not work for double
+        if (dataType == Element.DataType.FLOAT_64) {
+            double[] inArray = new double[INPUTSIZE * width];
+            RSUtils.genRandomDoubles(seed, minValue, maxValue, inArray, false);
+            alloc.copy1DRangeFrom(0, INPUTSIZE, inArray);
+        } else */
+        if (dataType == Element.DataType.FLOAT_32) {
+            float[] inArray = new float[INPUTSIZE * width];
+            RSUtils.genRandomFloats(seed, (float) minValue, (float) maxValue, inArray, false);
+            alloc.copy1DRangeFrom(0, INPUTSIZE, inArray);
+        } else {
+            android.util.Log.e("RenderscriptCTS",
+                               "Don't know how to create a random float allocation for " +
+                                           dataType.toString());
+        }
+        return alloc;
     }
 
-    public void doF32_2(long seed, int ulp) {
-        baseTestHelper(TEST_F32_2, Element.F32_2(mRS), Element.F32_2(mRS), seed, 1, 0, 1, 0, 2, 2, 2, 0, ulp);
+    protected Allocation createRandomIntegerAllocation(RenderScript rs, Element.DataType dataType,
+            int size, long seed, boolean signed, int numberOfBits) {
+        Element element = getElement(rs, dataType, size);
+        Allocation alloc = Allocation.createSized(rs, element, INPUTSIZE);
+        int width = (size == 3) ? 4 : size;
+        /* TODO copy1DRangFrom does not work for long
+        if (dataType == Element.DataType.SIGNED_64 ||
+                dataType == Element.DataType.UNSIGNED_64) {
+            long[] inArray = new long[INPUTSIZE * width];
+            RSUtils.genRandomLongs(seed, inArray, signed, numberOfBits);
+            alloc.copy1DRangeFrom(0, INPUTSIZE, inArray);
+        } else */
+        if (dataType == Element.DataType.SIGNED_32 ||
+                dataType == Element.DataType.UNSIGNED_32) {
+            int[] inArray = new int[INPUTSIZE * width];
+            RSUtils.genRandomInts(seed, inArray, signed, numberOfBits);
+            alloc.copy1DRangeFrom(0, INPUTSIZE, inArray);
+        } else if (dataType == Element.DataType.SIGNED_16 ||
+                dataType == Element.DataType.UNSIGNED_16) {
+            short[] inArray = new short[INPUTSIZE * width];
+            RSUtils.genRandomShorts(seed, inArray, signed, numberOfBits);
+            alloc.copy1DRangeFrom(0, INPUTSIZE, inArray);
+        } else if (dataType == Element.DataType.SIGNED_8 ||
+                dataType == Element.DataType.UNSIGNED_8) {
+            byte[] inArray = new byte[INPUTSIZE * width];
+            RSUtils.genRandomBytes(seed, inArray, signed, numberOfBits);
+            alloc.copy1DRangeFrom(0, INPUTSIZE, inArray);
+        } else {
+            android.util.Log.e("RenderscriptCTS",
+                               "Don't know how to create an integer allocation of type" +
+                                           dataType.toString());
+        }
+        return alloc;
     }
 
-    public void doF32_3(long seed, int ulp) {
-        baseTestHelper(TEST_F32_3, Element.F32_3(mRS), Element.F32_3(mRS), seed, 1, 0, 4, 1, 3, 4, 4, 1, ulp);
+    protected <T> void enforceOrdering(/*RenderScript rs,*/ Allocation minAlloc, Allocation maxAlloc) {
+        Element element = minAlloc.getElement();
+        int stride = element.getVectorSize();
+        if (stride == 3) {
+            stride = 4;
+        }
+        int size = INPUTSIZE * stride;
+        Element.DataType dataType = element.getDataType();
+        /* TODO copy1DRangeFrom does not work for double
+        if (dataType == Element.DataType.FLOAT_64) {
+            double[] minArray = new double[size];
+            double[] maxArray = new double[size];
+            minAlloc.copyTo(minArray);
+            maxAlloc.copyTo(maxArray);
+            for (int i = 0; i < size; i++) {
+                if (minArray[i] > maxArray[i]) {
+                    double temp = minArray[i];
+                    minArray[i] = maxArray[i];
+                    maxArray[i] = temp;
+                }
+            }
+            minAlloc.copyFrom(minArray);
+            maxAlloc.copyFrom(maxArray);
+        } else */
+        if (dataType == Element.DataType.FLOAT_32) {
+            float[] minArray = new float[size];
+            float[] maxArray = new float[size];
+            minAlloc.copyTo(minArray);
+            maxAlloc.copyTo(maxArray);
+            for (int i = 0; i < size; i++) {
+                if (minArray[i] > maxArray[i]) {
+                    float temp = minArray[i];
+                    minArray[i] = maxArray[i];
+                    maxArray[i] = temp;
+                }
+            }
+            minAlloc.copyFrom(minArray);
+            maxAlloc.copyFrom(maxArray);
+        /* TODO copy1DRangFrom does not work for long
+        } else if (dataType == Element.DataType.SIGNED_64) {
+            long[] minArray = new long[size];
+            long[] maxArray = new long[size];
+            minAlloc.copyTo(minArray);
+            maxAlloc.copyTo(maxArray);
+            for (int i = 0; i < size; i++) {
+                if (minArray[i] > maxArray[i]) {
+                    long temp = minArray[i];
+                    minArray[i] = maxArray[i];
+                    maxArray[i] = temp;
+                }
+            }
+            minAlloc.copyFrom(minArray);
+            maxAlloc.copyFrom(maxArray);
+        } else if (dataType == Element.DataType.UNSIGNED_64) {
+            long[] minArray = new long[size];
+            long[] maxArray = new long[size];
+            minAlloc.copyTo(minArray);
+            maxAlloc.copyTo(maxArray);
+            for (int i = 0; i < size; i++) {
+                if (RSUtils.compareUnsignedLong(minArray[i], maxArray[i]) > 0) {
+                    long temp = minArray[i];
+                    minArray[i] = maxArray[i];
+                    maxArray[i] = temp;
+                }
+            }
+            minAlloc.copyFrom(minArray);
+            maxAlloc.copyFrom(maxArray);
+        */
+        } else if (dataType == Element.DataType.SIGNED_32) {
+            int[] minArray = new int[size];
+            int[] maxArray = new int[size];
+            minAlloc.copyTo(minArray);
+            maxAlloc.copyTo(maxArray);
+            for (int i = 0; i < size; i++) {
+                if (minArray[i] > maxArray[i]) {
+                    int temp = minArray[i];
+                    minArray[i] = maxArray[i];
+                    maxArray[i] = temp;
+                }
+            }
+            minAlloc.copyFrom(minArray);
+            maxAlloc.copyFrom(maxArray);
+        } else if (dataType == Element.DataType.UNSIGNED_32) {
+            int[] minArray = new int[size];
+            int[] maxArray = new int[size];
+            minAlloc.copyTo(minArray);
+            maxAlloc.copyTo(maxArray);
+            for (int i = 0; i < size; i++) {
+                long min = minArray[i] &0xffffffffl;
+                long max = maxArray[i] &0xffffffffl;
+                if (min > max) {
+                    minArray[i] = (int) max;
+                    maxArray[i] = (int) min;
+                }
+            }
+            minAlloc.copyFrom(minArray);
+            maxAlloc.copyFrom(maxArray);
+        } else if (dataType == Element.DataType.SIGNED_16) {
+            short[] minArray = new short[size];
+            short[] maxArray = new short[size];
+            minAlloc.copyTo(minArray);
+            maxAlloc.copyTo(maxArray);
+            for (int i = 0; i < size; i++) {
+                if (minArray[i] > maxArray[i]) {
+                    short temp = minArray[i];
+                    minArray[i] = maxArray[i];
+                    maxArray[i] = temp;
+                }
+            }
+            minAlloc.copyFrom(minArray);
+            maxAlloc.copyFrom(maxArray);
+        } else if (dataType == Element.DataType.UNSIGNED_16) {
+            short[] minArray = new short[size];
+            short[] maxArray = new short[size];
+            minAlloc.copyTo(minArray);
+            maxAlloc.copyTo(maxArray);
+            for (int i = 0; i < size; i++) {
+                int min = minArray[i] &0xffff;
+                int max = maxArray[i] &0xffff;
+                if (min > max) {
+                    minArray[i] = (short) max;
+                    maxArray[i] = (short) min;
+                }
+            }
+            minAlloc.copyFrom(minArray);
+            maxAlloc.copyFrom(maxArray);
+        } else if (dataType == Element.DataType.SIGNED_8) {
+            byte[] minArray = new byte[size];
+            byte[] maxArray = new byte[size];
+            minAlloc.copyTo(minArray);
+            maxAlloc.copyTo(maxArray);
+            for (int i = 0; i < size; i++) {
+                if (minArray[i] > maxArray[i]) {
+                    byte temp = minArray[i];
+                    minArray[i] = maxArray[i];
+                    maxArray[i] = temp;
+                }
+            }
+            minAlloc.copyFrom(minArray);
+            maxAlloc.copyFrom(maxArray);
+        } else if (dataType == Element.DataType.UNSIGNED_8) {
+            byte[] minArray = new byte[size];
+            byte[] maxArray = new byte[size];
+            minAlloc.copyTo(minArray);
+            maxAlloc.copyTo(maxArray);
+            for (int i = 0; i < size; i++) {
+                int min = minArray[i] &0xff;
+                int max = maxArray[i] &0xff;
+                if (min > max) {
+                    minArray[i] = (byte) max;
+                    maxArray[i] = (byte) min;
+                }
+            }
+            minAlloc.copyFrom(minArray);
+            maxAlloc.copyFrom(maxArray);
+        } else {
+            android.util.Log.e("RenderscriptCTS", "Ordering not supported for " +
+                    dataType.toString());
+        }
     }
 
-    public void doF32_4(long seed, int ulp) {
-        baseTestHelper(TEST_F32_4, Element.F32_4(mRS), Element.F32_4(mRS), seed, 1, 0, 1, 0, 4, 4, 4, 0, ulp);
-    }
-
-    public void doF32_relaxed(long seed, int ulp) {
-        baseTestHelper(TEST_RELAXED_F32, Element.F32(mRS), Element.F32(mRS), seed, 1, 0, 1, 0, 1, 1, 1, 0, ulp);
-    }
-
-    public void doF32_2_relaxed(long seed, int ulp) {
-        baseTestHelper(TEST_RELAXED_F32_2, Element.F32_2(mRS), Element.F32_2(mRS), seed, 1, 0, 1, 0, 2, 2, 2, 0, ulp);
-    }
-
-    public void doF32_3_relaxed(long seed, int ulp) {
-        baseTestHelper(TEST_RELAXED_F32_3, Element.F32_3(mRS), Element.F32_3(mRS), seed, 1, 0, 4, 1, 3, 4, 4, 1, ulp);
-    }
-
-    public void doF32_4_relaxed(long seed, int ulp) {
-        baseTestHelper(TEST_RELAXED_F32_4, Element.F32_4(mRS), Element.F32_4(mRS), seed, 1, 0, 1, 0, 4, 4, 4, 0, ulp);
-    }
-
-
     public void forEach(int testId, Allocation mIn, Allocation mOut) throws RSRuntimeException {
         // Intentionally empty... subclass will likely define only one, but not both
     }
@@ -151,33 +399,4 @@
     public void forEach(int testId, Allocation mIn) throws RSRuntimeException {
         // Intentionally empty... subclass will likely define only one, but not both
     }
-
-    //These are default actions for these functions, specific tests overload them
-    protected float[] getRefArray(float[] inArray, int size, int stride, int skip) {
-        return null;
-    }
-
-    protected Allocation setInAlloc(Element e) {
-        return Allocation.createSized(mRS, e, INPUTSIZE);
-    }
-
-    protected Allocation setOutAlloc(Element e) {
-        return Allocation.createSized(mRS, e, INPUTSIZE);
-    }
-
-    protected float[] makeInArray(int size) {
-        return new float[size];
-    }
-
-    protected float[] makeOutArray(int size) {
-        return new float[size];
-    }
-
-    protected void fillRandomFloats(long seed, int fact, int offset, float[] inArray) {
-        RSUtils.genRandomFloats(seed, fact, offset, inArray);
-    }
-
-    protected void fillInAlloc(Allocation mIn, float[] inArray) {
-        mIn.copy1DRangeFromUnchecked(0, INPUTSIZE, inArray);
-    }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/RSUtils.java b/tests/tests/renderscript/src/android/renderscript/cts/RSUtils.java
index d3fb5d0..acb8b1d 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/RSUtils.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/RSUtils.java
@@ -26,24 +26,154 @@
  * This class supplies some utils for renderscript tests
  */
 public class RSUtils {
+    private static final double[] sInterestingDoubles = {
+        0.0,
+        1.0,
+        Math.E,
+        Math.PI,
+        Math.PI / 2f,
+        Math.PI * 2f,
+        -0.0,
+        -1.0,
+        -Math.E,
+        -Math.PI,
+        -Math.PI / 2.0,
+        -Math.PI * 2.0,
+    };
 
     /**
-     * Fills the array with random floats.  Values will be: offset + number between 0 and max.
+     * Fills the array with random doubles.  Values will be between min (inclusive) and
+     * max (inclusive).
      */
-    public static void genRandomFloats(long seed, int max, int offset, float array[]) {
+    public static void genRandomDoubles(long seed, double min, double max, double array[],
+            boolean includeExtremes) {
         Random r = new Random(seed);
         for (int i = 0; i < array.length; i++) {
-            array[i] = r.nextFloat() * max + offset;
+            array[i] = min + r.nextDouble() * (max - min);
+        }
+        // Seed a few special numbers we want to be sure to test.
+        for (int i = 0; i < sInterestingDoubles.length; i++) {
+            double d = sInterestingDoubles[i];
+            if (min <= d && d <= max) {
+                array[r.nextInt(array.length)] = d;
+            }
+        }
+        array[r.nextInt(array.length)] = min;
+        array[r.nextInt(array.length)] = max;
+        if (includeExtremes) {
+            array[r.nextInt(array.length)] = Double.NaN;
+            array[r.nextInt(array.length)] = Double.POSITIVE_INFINITY;
+            array[r.nextInt(array.length)] = Double.NEGATIVE_INFINITY;
+            array[r.nextInt(array.length)] = Double.MIN_VALUE;
+            array[r.nextInt(array.length)] = Double.MIN_NORMAL;
+            array[r.nextInt(array.length)] = Double.MAX_VALUE;
         }
     }
 
     /**
-     * Fills the array with random ints.  Values will be: offset + number between 0 and max (exclusive).
+     * Fills the array with random floats.  Values will be between min (inclusive) and
+     * max (inclusive).
      */
-    public static void genRandomInts(long seed, int max, int offset, int array[]) {
+    public static void genRandomFloats(long seed, float min, float max, float array[],
+            boolean includeExtremes) {
         Random r = new Random(seed);
         for (int i = 0; i < array.length; i++) {
-            array[i] = (r.nextInt(max) + offset);
+            array[i] = min + r.nextFloat() * (max - min);
         }
+        // Seed a few special numbers we want to be sure to test.
+        for (int i = 0; i < sInterestingDoubles.length; i++) {
+            float f = (float) sInterestingDoubles[i];
+            if (min <= f && f <= max) {
+                array[r.nextInt(array.length)] = f;
+            }
+        }
+        array[r.nextInt(array.length)] = min;
+        array[r.nextInt(array.length)] = max;
+        if (includeExtremes) {
+            array[r.nextInt(array.length)] = Float.NaN;
+            array[r.nextInt(array.length)] = Float.POSITIVE_INFINITY;
+            array[r.nextInt(array.length)] = Float.NEGATIVE_INFINITY;
+            array[r.nextInt(array.length)] = Float.MIN_VALUE;
+            array[r.nextInt(array.length)] = Float.MIN_NORMAL;
+            array[r.nextInt(array.length)] = Float.MAX_VALUE;
+        }
+    }
+
+    /**
+     * Fills the array with random ints.  Values will be between min (inclusive) and
+     * max (inclusive).
+     */
+    public static void genRandomInts(long seed, int min, int max, int array[]) {
+        Random r = new Random(seed);
+        for (int i = 0; i < array.length; i++) {
+            long range = max - min + 1;
+            array[i] = (int) (min + r.nextLong() % range);
+        }
+        array[r.nextInt(array.length)] = min;
+        array[r.nextInt(array.length)] = max;
+    }
+
+    /**
+     * Fills the array with random longs.  If signed is true, negative values can be generated.
+     * The values will fit within 'numberOfBits'.  This is useful for conversion tests.
+     */
+    public static void genRandomLongs(long seed, long array[], boolean signed, int numberOfBits) {
+      long positiveMask = numberOfBits == 64 ? -1 : ((1l << numberOfBits) - 1);
+      long negativeMask = ~positiveMask;
+      Random r = new Random(seed);
+      for (int i = 0; i < array.length; i++) {
+          long l = r.nextLong();
+          if (signed && l < 0) {
+              l = l | negativeMask;
+          } else {
+              l = l & positiveMask;
+          }
+          array[i] = l;
+      }
+      // Seed a few special numbers we want to be sure to test.
+      array[r.nextInt(array.length)] = 0l;
+      array[r.nextInt(array.length)] = 1l;
+      array[r.nextInt(array.length)] = positiveMask;
+      if (signed) {
+          array[r.nextInt(array.length)] = negativeMask;
+          array[r.nextInt(array.length)] = -1;
+      }
+    }
+
+    public static void genRandomInts(long seed, int array[], boolean signed, int numberOfBits) {
+        long[] longs = new long[array.length];
+        genRandomLongs(seed, longs, signed, numberOfBits);
+        for (int i = 0; i < array.length; i++) {
+            array[i] = (int) longs[i];
+        }
+    }
+
+    public static void genRandomShorts(long seed, short array[], boolean signed, int numberOfBits) {
+        long[] longs = new long[array.length];
+        genRandomLongs(seed, longs, signed, numberOfBits);
+        for (int i = 0; i < array.length; i++) {
+            array[i] = (short) longs[i];
+        }
+    }
+
+    public static void genRandomBytes(long seed, byte array[], boolean signed, int numberOfBits) {
+        long[] longs = new long[array.length];
+        genRandomLongs(seed, longs, signed, numberOfBits);
+        for (int i = 0; i < array.length; i++) {
+            array[i] = (byte) longs[i];
+        }
+    }
+
+    // Compares two unsigned long.  Returns < 0 if a < b, 0 if a == b, > 0 if a > b.
+    public static long compareUnsignedLong(long a, long b) {
+        long aFirstFourBits = a >>> 60;
+        long bFirstFourBits = b >>> 60;
+        long firstFourBitsDiff = aFirstFourBits - bFirstFourBits;
+        if (firstFourBitsDiff != 0) {
+            return firstFourBitsDiff;
+        }
+        long aRest = a & 0x0fffffffffffffffl;
+        long bRest = b & 0x0fffffffffffffffl;
+        return aRest - bRest;
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/RadiansTest.java b/tests/tests/renderscript/src/android/renderscript/cts/RadiansTest.java
deleted file mode 100644
index a0c7834..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/RadiansTest.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * 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 android.renderscript.cts;
-
-import com.android.cts.stub.R;
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-
-public class RadiansTest extends RSBaseCompute {
-    private ScriptC_radians_f32 script_f32;
-    private ScriptC_radians_f32_relaxed script_f32_relaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script_f32 = new ScriptC_radians_f32(mRS);
-        script_f32_relaxed = new ScriptC_radians_f32_relaxed(mRS);
-    }
-
-    @Override
-    public void forEach(int testId, Allocation mIn, Allocation mOut) throws RSRuntimeException {
-        switch (testId) {
-        case TEST_F32:
-            script_f32.forEach_radians_f32_1(mIn, mOut);
-            break;
-        case TEST_F32_2:
-            script_f32.forEach_radians_f32_2(mIn, mOut);
-            break;
-        case TEST_F32_3:
-            script_f32.forEach_radians_f32_3(mIn, mOut);
-            break;
-        case TEST_F32_4:
-            script_f32.forEach_radians_f32_4(mIn, mOut);
-            break;
-
-        case TEST_RELAXED_F32:
-            script_f32_relaxed.forEach_radians_f32_1(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_2:
-            script_f32_relaxed.forEach_radians_f32_2(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_3:
-            script_f32_relaxed.forEach_radians_f32_3(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_4:
-            script_f32_relaxed.forEach_radians_f32_4(mIn, mOut);
-            break;
-        }
-    }
-
-    @Override
-    protected float[] getRefArray(float[] in, int input_size, int stride, int skip) {
-        float[] ref = new float[input_size * stride];
-        for (int i = 0; i < input_size; i++) {
-            for (int j = 0; j < stride - skip; j++) {
-                int idx= i * stride + j;
-                int idxRef = i * (stride - skip) + j;
-                double val = (double)in[idx] * (Math.PI / 180.0);
-                ref[idxRef] = (float)val;
-            }
-        }
-        return ref;
-    }
-
-    /**
-     * radians test for float
-     */
-    public void testRadiansF32() {
-        doF32(0x1234f678, 3);
-    }
-
-    public void testRadiansF32_relaxed() {
-        doF32_relaxed(0x1234f678, 3);
-    }
-
-    /**
-     * radians test for float2
-     */
-    public void testRadiansF32_2() {
-        doF32_2(0x12345678, 3);
-    }
-
-    public void testRadiansF32_2_relaxed() {
-        doF32_2_relaxed(0x12345678, 3);
-    }
-
-    /**
-     * radians test for float3
-     */
-    public void testRadiansF32_3() {
-        doF32_3(0x123d5678, 3);
-    }
-
-    public void testRadiansF32_3_relaxed() {
-        doF32_3_relaxed(0x123d5678, 3);
-    }
-
-    /**
-     * radians test for float4
-     */
-    public void testRadiansF32_4() {
-        doF32_4(0x123a5678, 3);
-
-    }
-    public void testRadiansF32_4_relaxed() {
-        doF32_4_relaxed(0x123a5678, 3);
-    }
-
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/RemainderTest.java b/tests/tests/renderscript/src/android/renderscript/cts/RemainderTest.java
deleted file mode 100644
index edd3320..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/RemainderTest.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * 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 android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.Element;
-import android.renderscript.RSRuntimeException;
-import com.android.cts.stub.R;
-
-public class RemainderTest extends RSBaseCompute {
-    private ScriptC_remainder_f32 script_f32;
-    private ScriptC_remainder_f32_relaxed script_f32_relaxed;
-    private Allocation mIn;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script_f32 = new ScriptC_remainder_f32(mRS);
-        script_f32_relaxed = new ScriptC_remainder_f32_relaxed(mRS);
-    }
-
-    @Override
-    public void forEach(int testId, Allocation mIn, Allocation mOut) throws RSRuntimeException {
-        switch (testId) {
-        case TEST_F32:
-            script_f32.forEach_remainder_f32_1(mIn, mOut);
-            break;
-        case TEST_F32_2:
-            script_f32.forEach_remainder_f32_2(mIn, mOut);
-            break;
-        case TEST_F32_3:
-            script_f32.forEach_remainder_f32_3(mIn, mOut);
-            break;
-        case TEST_F32_4:
-            script_f32.forEach_remainder_f32_4(mIn, mOut);
-            break;
-
-        case TEST_RELAXED_F32:
-            script_f32_relaxed.forEach_remainder_f32_1(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_2:
-            script_f32_relaxed.forEach_remainder_f32_2(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_3:
-            script_f32_relaxed.forEach_remainder_f32_3(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_4:
-            script_f32_relaxed.forEach_remainder_f32_4(mIn, mOut);
-            break;
-        }
-    }
-
-    @Override
-    protected float[] getRefArray(float[] in, int input_size, int stride, int skip) {
-        float[] ref = new float[input_size * stride];
-        for (int i = 0; i < input_size; i++) {
-            for (int j = 0; j < stride - skip; j++) {
-                int idx = i * stride * 2 + j;
-                double num = (double)in[idx];
-                double den = (double)in[idx+stride];
-                ref[i * (stride - skip) + j] = (float)(num - Math.round(num / den) * den);
-            }
-        }
-        return ref;
-    }
-
-    @Override
-    protected Allocation setInAlloc(Element e) {
-        return mIn;
-    }
-
-    @Override
-    protected float[] makeInArray(int size) {
-        return new float[size*2];
-    }
-
-    public void testRemainderF32() {
-        ScriptField_remainder_f32 in = new ScriptField_remainder_f32(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32(0x123678, 0);
-    }
-
-    public void testRemainderF32_relaxed() {
-        ScriptField_remainder_f32 in = new ScriptField_remainder_f32(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_relaxed(0x123678, 0);
-    }
-
-    public void testRemainderF32_2() {
-        ScriptField_remainder_f32_2 in = new ScriptField_remainder_f32_2(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_2(0x1234a5, 0);
-    }
-
-    public void testRemainderF32_2_relaxed() {
-        ScriptField_remainder_f32_2 in = new ScriptField_remainder_f32_2(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_2_relaxed(0x1234a5, 0);
-    }
-
-    public void testRemainderF32_3() {
-        ScriptField_remainder_f32_3 in = new ScriptField_remainder_f32_3(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_3(0x1af345, 0);
-    }
-
-    public void testRemainderF32_3_relaxed() {
-        ScriptField_remainder_f32_3 in = new ScriptField_remainder_f32_3(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_3_relaxed(0x1af345, 0);
-    }
-
-    public void testRemainderF32_4() {
-        ScriptField_remainder_f32_4 in = new ScriptField_remainder_f32_4(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_4(0x12ce45, 0);
-    }
-
-    public void testRemainderF32_4_relaxed() {
-        ScriptField_remainder_f32_4 in = new ScriptField_remainder_f32_4(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_4_relaxed(0x12ce45, 0);
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/RintTest.java b/tests/tests/renderscript/src/android/renderscript/cts/RintTest.java
deleted file mode 100644
index 56c0acf..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/RintTest.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * 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 android.renderscript.cts;
-
-import com.android.cts.stub.R;
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-
-public class RintTest extends RSBaseCompute {
-    private ScriptC_rint_f32 script_f32;
-    private ScriptC_rint_f32_relaxed script_f32_relaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script_f32 = new ScriptC_rint_f32(mRS);
-        script_f32_relaxed = new ScriptC_rint_f32_relaxed(mRS);
-    }
-
-    @Override
-    public void forEach(int testId, Allocation mIn, Allocation mOut)
-            throws RSRuntimeException {
-        switch (testId) {
-        case TEST_F32:
-            script_f32.forEach_rint_f32_1(mIn, mOut);
-            break;
-        case TEST_F32_2:
-            script_f32.forEach_rint_f32_2(mIn, mOut);
-            break;
-        case TEST_F32_3:
-            script_f32.forEach_rint_f32_3(mIn, mOut);
-            break;
-        case TEST_F32_4:
-            script_f32.forEach_rint_f32_4(mIn, mOut);
-            break;
-
-        case TEST_RELAXED_F32:
-            script_f32_relaxed.forEach_rint_f32_1(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_2:
-            script_f32_relaxed.forEach_rint_f32_2(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_3:
-            script_f32_relaxed.forEach_rint_f32_3(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_4:
-            script_f32_relaxed.forEach_rint_f32_4(mIn, mOut);
-            break;
-        }
-    }
-
-    @Override
-    protected float[] getRefArray(float[] inArray, int input_size, int stride, int skip) {
-        float[] ref = new float[input_size * (stride - skip)];
-        for (int i = 0; i < input_size; i++) {
-            for (int j = 0; j < stride - skip; j++) {
-                int idxIn = i * stride + j;
-                int idxRef = i * (stride - skip) + j;
-                ref[idxRef] = (float) Math.rint(inArray[idxIn]);
-            }
-        }
-        return ref;
-    }
-
-    /**
-     * rint test for float
-     */
-    public void testRintF32() {
-        doF32(0x12345678, 0);
-    }
-
-    public void testRintF32_relaxed() {
-        doF32_relaxed(0x12345678, 0);
-    }
-
-    /**
-     * rint test for float2
-     */
-    public void testRintF32_2() {
-        doF32_2(0x12ab5678, 0);
-    }
-
-    public void testRintF32_2_relaxed() {
-        doF32_2_relaxed(0x12ab5678, 0);
-    }
-
-    /**
-     * rint test for float3
-     */
-    public void testRintF32_3() {
-        doF32_3(0x123ac678, 0);
-    }
-
-    public void testRintF32_3_relaxed() {
-        doF32_3_relaxed(0x123ac678, 0);
-    }
-
-    /**
-     * rint test for float4
-     */
-    public void testRintF32_4() {
-        doF32_4(0x1f345678, 0);
-
-    }
-    public void testRintF32_4_relaxed() {
-        doF32_4_relaxed(0x1f345678, 0);
-    }
-
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/RootnTest.java b/tests/tests/renderscript/src/android/renderscript/cts/RootnTest.java
deleted file mode 100644
index 2c447bb..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/RootnTest.java
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * 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 android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.Element;
-import android.renderscript.RSRuntimeException;
-import com.android.cts.stub.R;
-
-public class RootnTest extends RSBaseCompute {
-    private ScriptC_rootn_f32 script_f32;
-    private ScriptC_rootn_f32_relaxed script_f32_relaxed;
-    private int[] n;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script_f32 = new ScriptC_rootn_f32(mRS);
-        script_f32_relaxed = new ScriptC_rootn_f32_relaxed(mRS);
-    }
-
-    @Override
-    public void forEach(int testId, Allocation mIn, Allocation mOut) throws RSRuntimeException {
-        switch (testId) {
-        case TEST_F32:
-            script_f32.forEach_rootn_f32_1(mIn, mOut);
-            break;
-        case TEST_F32_2:
-            script_f32.forEach_rootn_f32_2(mIn, mOut);
-            break;
-        case TEST_F32_3:
-            script_f32.forEach_rootn_f32_3(mIn, mOut);
-            break;
-        case TEST_F32_4:
-            script_f32.forEach_rootn_f32_4(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32:
-            script_f32_relaxed.forEach_rootn_f32_1(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_2:
-            script_f32_relaxed.forEach_rootn_f32_2(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_3:
-            script_f32_relaxed.forEach_rootn_f32_3(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_4:
-            script_f32_relaxed.forEach_rootn_f32_4(mIn, mOut);
-            break;
-        }
-    }
-
-    @Override
-    protected float[] getRefArray(float[] in, int input_size, int stride, int skip) {
-        float[] ref = new float[input_size * stride];
-        for (int i = 0; i < input_size; i++) {
-            for (int j = 0; j < stride - skip; j++) {
-                int idx= i * stride + j;
-                int idxRef = i * (stride - skip) + j;
-                ref[idxRef] = (float)Math.pow((double)in[idx], 1.0/(double)n[idx]);
-            }
-        }
-        return ref;
-    }
-
-    public void testRootnF32() {
-        Allocation nAlloc = Allocation.createSized(mRS, Element.I32(mRS), INPUTSIZE);
-
-        n = new int[INPUTSIZE];
-        RSUtils.genRandomInts(0x12345678, 32, 1, n);
-        nAlloc.copyFrom(n);
-        script_f32.set_n1(nAlloc);
-
-        doF32(0x716acd, 16);
-    }
-
-    public void testRootnF32_relaxed() {
-        Allocation nAlloc = Allocation.createSized(mRS, Element.I32(mRS), INPUTSIZE);
-
-        n = new int[INPUTSIZE];
-        RSUtils.genRandomInts(0x12345678, 32, 1, n);
-        nAlloc.copyFrom(n);
-        script_f32_relaxed.set_n1(nAlloc);
-
-        doF32_relaxed(0x716acd, 16);
-    }
-
-
-    public void testRootnF32_2() {
-        Allocation nAlloc = Allocation.createSized(mRS, Element.I32_2(mRS), INPUTSIZE);
-
-        n = new int[INPUTSIZE*2];
-        RSUtils.genRandomInts(0xacdef1, 32, 1, n);
-        nAlloc.copyFrom(n);
-        script_f32.set_n2(nAlloc);
-
-        doF32_2(0xacdef1, 16);
-    }
-
-    public void testRootnF32_2_relaxed() {
-        Allocation nAlloc = Allocation.createSized(mRS, Element.I32_2(mRS), INPUTSIZE);
-
-        n = new int[INPUTSIZE*2];
-        RSUtils.genRandomInts(0xacdef1, 32, 1, n);
-        nAlloc.copyFrom(n);
-        script_f32_relaxed.set_n2(nAlloc);
-
-        doF32_2_relaxed(0xacdef1, 16);
-    }
-
-
-    public void testRootnF32_3() {
-        Allocation nAlloc = Allocation.createSized(mRS, Element.I32_3(mRS), INPUTSIZE);
-
-        n = new int[INPUTSIZE*4];
-        RSUtils.genRandomInts(0xa123f1, 32, 1, n);
-        nAlloc.copyFrom(n);
-        script_f32.set_n3(nAlloc);
-
-        doF32_3(0xaac3f1, 16);
-    }
-
-    public void testRootnF32_3_relaxed() {
-        Allocation nAlloc = Allocation.createSized(mRS, Element.I32_3(mRS), INPUTSIZE);
-
-        n = new int[INPUTSIZE*4];
-        RSUtils.genRandomInts(0xa123f1, 32, 1, n);
-        nAlloc.copyFrom(n);
-        script_f32_relaxed.set_n3(nAlloc);
-
-        doF32_3_relaxed(0xaac3f1, 16);
-    }
-
-    public void testRootnF32_4() {
-        Allocation nAlloc = Allocation.createSized(mRS, Element.I32_4(mRS), INPUTSIZE);
-
-        n = new int[INPUTSIZE*4];
-        RSUtils.genRandomInts(0x4323ca, 32, 1, n);
-        nAlloc.copyFrom(n);
-        script_f32.set_n4(nAlloc);
-
-        doF32_4(0xaa12f1, 16);
-    }
-
-    public void testRootnF32_4_relaxed() {
-        Allocation nAlloc = Allocation.createSized(mRS, Element.I32_4(mRS), INPUTSIZE);
-
-        n = new int[INPUTSIZE*4];
-        RSUtils.genRandomInts(0x4323ca, 32, 1, n);
-        nAlloc.copyFrom(n);
-        script_f32_relaxed.set_n4(nAlloc);
-
-        doF32_4_relaxed(0xaa12f1, 16);
-    }
-
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/RoundTest.java b/tests/tests/renderscript/src/android/renderscript/cts/RoundTest.java
deleted file mode 100644
index ab85bc1..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/RoundTest.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * 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 android.renderscript.cts;
-
-import com.android.cts.stub.R;
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-
-public class RoundTest extends RSBaseCompute {
-    private ScriptC_round_f32 script_f32;
-    private ScriptC_round_f32_relaxed script_f32_relaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script_f32 = new ScriptC_round_f32(mRS);
-        script_f32_relaxed = new ScriptC_round_f32_relaxed(mRS);
-    }
-
-    @Override
-    public void forEach(int testId, Allocation mIn, Allocation mOut)
-            throws RSRuntimeException {
-        switch (testId) {
-        case TEST_F32:
-            script_f32.forEach_round_f32_1(mIn, mOut);
-            break;
-        case TEST_F32_2:
-            script_f32.forEach_round_f32_2(mIn, mOut);
-            break;
-        case TEST_F32_3:
-            script_f32.forEach_round_f32_3(mIn, mOut);
-            break;
-        case TEST_F32_4:
-            script_f32.forEach_round_f32_4(mIn, mOut);
-            break;
-
-        case TEST_RELAXED_F32:
-            script_f32_relaxed.forEach_round_f32_1(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_2:
-            script_f32_relaxed.forEach_round_f32_2(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_3:
-            script_f32_relaxed.forEach_round_f32_3(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_4:
-            script_f32_relaxed.forEach_round_f32_4(mIn, mOut);
-            break;
-        }
-    }
-
-    @Override
-    protected float[] getRefArray(float[] inArray, int input_size, int stride, int skip) {
-        float[] ref = new float[input_size * (stride - skip)];
-        for (int i = 0; i < input_size; i++) {
-            for (int j = 0; j < stride - skip; j++) {
-                int idxIn = i * stride + j;
-                int idxRef = i * (stride - skip) + j;
-                int res = ((Float.floatToIntBits(inArray[idxIn]) >> 31) & 0x01);
-                float roundValue = (float) Math.round(inArray[idxIn]);
-                float expective = roundValue;
-                if ((roundValue - inArray[idxIn]) == 0.5f && res == 1)
-                    expective -= 1;
-                if (res == 1 && expective == +0.0f) {
-                    expective = -0.0f;
-                }
-                ref[idxRef] = expective;
-            }
-        }
-        return ref;
-    }
-
-    /**
-     * round test for float
-     */
-    public void testRoundF32() {
-        doF32(0x12345678, 0);
-    }
-
-    public void testRoundF32_relaxed() {
-        doF32_relaxed(0x12345678, 0);
-    }
-
-    /**
-     * round test for float2
-     */
-    public void testRoundF32_2() {
-        doF32_2(0x123a5678, 0);
-    }
-
-    public void testRoundF32_2_relaxed() {
-        doF32_2_relaxed(0x123a5678, 0);
-    }
-
-    /**
-     * round test for float3
-     */
-    public void testRoundF32_3() {
-        doF32_3(0x1af45678, 0);
-    }
-
-    public void testRoundF32_3_relaxed() {
-        doF32_3_relaxed(0x1af45678, 0);
-    }
-
-    /**
-     * round test for float4
-     */
-    public void testRoundF32_4() {
-        doF32_4(0x1f345678, 0);
-
-    }
-    public void testRoundF32_4_relaxed() {
-        doF32_4_relaxed(0x1f345678, 0);
-    }
-
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/RsFracTest.java b/tests/tests/renderscript/src/android/renderscript/cts/RsFracTest.java
deleted file mode 100644
index 2185ae2..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/RsFracTest.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/**
- * 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 android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import com.android.cts.stub.R;
-
-public class RsFracTest extends RSBaseCompute {
-    private ScriptC_rs_frac_f32 mScript;
-    private ScriptC_rs_frac_f32_relaxed mScript_relaxed;
-
-    @Override
-    public void forEach(int testId, Allocation mIn, Allocation mOut)
-            throws RSRuntimeException {
-        if (testId == TEST_F32) {
-            mScript.forEach_root(mIn, mOut);
-        } else if (testId == TEST_RELAXED_F32) {
-            mScript_relaxed.forEach_root(mIn, mOut);
-        }
-    }
-
-    @Override
-    protected float[] getRefArray(float[] in, int input_size, int stride, int skip) {
-        float[] ref = new float[input_size * stride];
-        for (int i = 0; i < input_size; i++) {
-            for (int j = 0; j < stride - skip; j++) {
-                int idx= i * stride + j;
-                int idxRef = i * (stride - skip) + j;
-                ref[idxRef] = Math.min(in[idx] - (float)Math.floor((double)in[idx]), 0x1.fffffep-1f);
-            }
-        }
-        return ref;
-    }
-
-    public void testRsFrac() {
-        mScript = new ScriptC_rs_frac_f32(mRS, mRes, R.raw.rs_frac_f32);
-        doF32(0x12, 0);
-    }
-    public void testRsFrac_relaxed() {
-        mScript_relaxed = new ScriptC_rs_frac_f32_relaxed(mRS, mRes, R.raw.rs_frac_f32);
-        doF32_relaxed(0x12, 1);
-    }
-
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/RsPackColorTo8888Test.java b/tests/tests/renderscript/src/android/renderscript/cts/RsPackColorTo8888Test.java
index edff5b9..bb8b275 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/RsPackColorTo8888Test.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/RsPackColorTo8888Test.java
@@ -72,7 +72,7 @@
         float[] inArray = new float[INPUTSIZE * 4];
         byte[] outArray = new byte[INPUTSIZE * 4];
         byte[] refArray = new byte[INPUTSIZE * 4];
-        RSUtils.genRandomFloats(seed, 1, 0, inArray);
+        RSUtils.genRandomFloats(seed, 0.0f, 1.0f, inArray, false);
         mAllocationIn.copy1DRangeFrom(0, INPUTSIZE, inArray);
         try {
             forEach(testId, mAllocationIn, mAllocationOut);
@@ -99,7 +99,7 @@
         float[] inArray = new float[INPUTSIZE * 4];
         byte[] outArray = new byte[INPUTSIZE * 4];
         byte[] refArray = new byte[INPUTSIZE * 4];
-        RSUtils.genRandomFloats(seed, 1, 0, inArray);
+        RSUtils.genRandomFloats(seed, 0.0f, 1.0f, inArray, false);
         mAllocationIn.copy1DRangeFrom(0, INPUTSIZE, inArray);
         try {
             forEach(testId, mAllocationIn, mAllocationOut);
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/RsqrtTest.java b/tests/tests/renderscript/src/android/renderscript/cts/RsqrtTest.java
deleted file mode 100644
index 1183886..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/RsqrtTest.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * 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 android.renderscript.cts;
-
-import com.android.cts.stub.R;
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-
-public class RsqrtTest extends RSBaseCompute {
-    private ScriptC_rsqrt_f32 script_f32;
-    private ScriptC_rsqrt_f32_relaxed script_f32_relaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script_f32 = new ScriptC_rsqrt_f32(mRS);
-        script_f32_relaxed = new ScriptC_rsqrt_f32_relaxed(mRS);
-    }
-
-    @Override
-    public void forEach(int testId, Allocation mIn, Allocation mOut) throws RSRuntimeException {
-        switch (testId) {
-        case TEST_F32:
-            script_f32.forEach_Rsqrt_f32_1(mIn, mOut);
-            break;
-        case TEST_F32_2:
-            script_f32.forEach_Rsqrt_f32_2(mIn, mOut);
-            break;
-        case TEST_F32_3:
-            script_f32.forEach_Rsqrt_f32_3(mIn, mOut);
-            break;
-        case TEST_F32_4:
-            script_f32.forEach_Rsqrt_f32_4(mIn, mOut);
-            break;
-
-        case TEST_RELAXED_F32:
-            script_f32_relaxed.forEach_Rsqrt_f32_1(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_2:
-            script_f32_relaxed.forEach_Rsqrt_f32_2(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_3:
-            script_f32_relaxed.forEach_Rsqrt_f32_3(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_4:
-            script_f32_relaxed.forEach_Rsqrt_f32_4(mIn, mOut);
-            break;
-        }
-    }
-
-    @Override
-    protected float[] getRefArray(float[] in, int input_size, int stride, int skip) {
-        float[] ref = new float[input_size * stride];
-        for (int i = 0; i < input_size; i++) {
-            for (int j = 0; j < stride - skip; j++) {
-                int idx= i * stride + j;
-                int idxRef = i * (stride - skip) + j;
-                ref[idxRef] = (float)Math.pow((double)in[idx], -0.5);
-            }
-        }
-        return ref;
-    }
-
-    public void testRsqrtF32() {
-        doF32(0x12345678, 2);
-    }
-
-    public void testRsqrtF32_relaxed() {
-        doF32_relaxed(0x12345678, 2);
-    }
-
-    public void testRsqrtF32_2() {
-        doF32_2(0x12ae4567, 2);
-    }
-
-    public void testRsqrtF32_2_relaxed() {
-        doF32_2_relaxed(0x12ae4567, 2);
-    }
-
-    public void testRsqrtF32_3() {
-        doF32_3(0x12cf8, 2);
-    }
-
-    public void testRsqrtF32_3_relaxed() {
-        doF32_3_relaxed(0x12cf8, 2);
-    }
-
-    public void testRsqrtF32_4() {
-        doF32_4(0x12abc8, 2);
-
-    }
-    public void testRsqrtF32_4_relaxed() {
-        doF32_4_relaxed(0x12abc8, 2);
-    }
-
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/SampleTest.java b/tests/tests/renderscript/src/android/renderscript/cts/SampleTest.java
index 3c8650d..1729aeb 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/SampleTest.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/SampleTest.java
@@ -34,6 +34,36 @@
     Allocation mAlloc_RGBA_1D;
     Allocation mAlloc_RGBA_2D;
 
+    Allocation createAlloc(Type t) {
+        Allocation a = Allocation.createTyped(mRS, t, Allocation.MipmapControl.MIPMAP_FULL,
+                                              Allocation.USAGE_SCRIPT);
+
+        int[] tmp = new int[t.getCount()];
+        int idx = 0;
+        int w = t.getY();
+        if (w < 1) {
+            w = 1;
+        }
+
+        for (int ct = 0; ct < (8 * w); ct++) {
+            tmp[idx++] = 0x0000ffff;
+        }
+        w = (w + 1) >> 1;
+        for (int ct = 0; ct < (4 * w); ct++) {
+            tmp[idx++] = 0x00ff00ff;
+        }
+        w = (w + 1) >> 1;
+        for (int ct = 0; ct < (2 * w); ct++) {
+            tmp[idx++] = 0x00ffff00;
+        }
+        w = (w + 1) >> 1;
+        for (int ct = 0; ct < (1 * 1); ct++) {
+            tmp[idx++] = 0xffffff00;
+        }
+        a.copyFromUnchecked(tmp);
+        return a;
+    }
+
     @Override
     protected void setUp() throws Exception {
         super.setUp();
@@ -41,18 +71,10 @@
         Element format = Element.RGBA_8888(mRS);
         Type.Builder b = new Type.Builder(mRS, format);
         b.setMipmaps(true);
-        mAlloc_RGBA_1D = Allocation.createTyped(mRS, b.setX(8).create(),
-                                                Allocation.MipmapControl.MIPMAP_FULL,
-                                                Allocation.USAGE_SCRIPT);
-        mAlloc_RGBA_2D = Allocation.createTyped(mRS, b.setX(8).setY(8).create(),
-                                                Allocation.MipmapControl.MIPMAP_FULL,
-                                                Allocation.USAGE_SCRIPT);
+        mAlloc_RGBA_1D = createAlloc(b.setX(8).create());
+        mAlloc_RGBA_2D = createAlloc(b.setX(8).setY(8).create());
 
         mScript = new ScriptC_sample(mRS, mRes, R.raw.sample);
-        mScript.bind_gAllocPtr(mAlloc_RGBA_1D);
-        mScript.invoke_init_RGBA(mAlloc_RGBA_1D);
-        mScript.bind_gAllocPtr(mAlloc_RGBA_2D);
-        mScript.invoke_init_RGBA(mAlloc_RGBA_2D);
 
         mScript.set_gNearest(Sampler.CLAMP_NEAREST(mRS));
         mScript.set_gLinear(Sampler.CLAMP_LINEAR(mRS));
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/SignTest.java b/tests/tests/renderscript/src/android/renderscript/cts/SignTest.java
deleted file mode 100644
index 69e2636..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/SignTest.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * 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 android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import com.android.cts.stub.R;
-
-public class SignTest extends RSBaseCompute {
-    private ScriptC_sign_f32 script_f32;
-    private ScriptC_sign_f32_relaxed script_f32_relaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script_f32 = new ScriptC_sign_f32(mRS);
-        script_f32_relaxed = new ScriptC_sign_f32_relaxed(mRS);
-    }
-
-    @Override
-    public void forEach(int testId, Allocation mIn, Allocation mOut) throws RSRuntimeException {
-        switch (testId) {
-        case TEST_F32:
-            script_f32.forEach_sign_f32_1(mIn, mOut);
-            break;
-        case TEST_F32_2:
-            script_f32.forEach_sign_f32_2(mIn, mOut);
-            break;
-        case TEST_F32_3:
-            script_f32.forEach_sign_f32_3(mIn, mOut);
-            break;
-        case TEST_F32_4:
-            script_f32.forEach_sign_f32_4(mIn, mOut);
-            break;
-
-        case TEST_RELAXED_F32:
-            script_f32_relaxed.forEach_sign_f32_1(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_2:
-            script_f32_relaxed.forEach_sign_f32_2(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_3:
-            script_f32_relaxed.forEach_sign_f32_3(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_4:
-            script_f32_relaxed.forEach_sign_f32_4(mIn, mOut);
-            break;
-        }
-    }
-
-    @Override
-    protected float[] getRefArray(float[] in, int input_size, int stride, int skip) {
-        float[] ref = new float[input_size * stride];
-        for (int i = 0; i < input_size; i++) {
-            for (int j = 0; j < stride - skip; j++) {
-                int idxIn = i * stride + j;
-                int idxRef = i * (stride - skip) + j;
-                ref[idxRef] = in[idxIn] > 0.f ? 1.f : -1.f;
-            }
-        }
-        return ref;
-    }
-
-    /**
-     * This method is used for sign() function with f32
-     */
-    public void testSignF32() {
-        doF32(0x12345678, 0);
-    }
-
-    public void testSignF32_relaxed() {
-        doF32_relaxed(0x12345678, 0);
-    }
-
-    public void testSignF32_2() {
-        doF32_2(0x12a45678, 0);
-    }
-
-    public void testSignF32_2_relaxed() {
-        doF32_2_relaxed(0x12a45678, 0);
-    }
-
-    /**
-     * This method is used for sign() function with f32_3
-     */
-    public void testSignF32_3() {
-        doF32_3(0x123c5678, 0);
-    }
-
-    public void testSignF32_3_relaxed() {
-        doF32_3_relaxed(0x123c5678, 0);
-    }
-
-    /**
-     * This method is used for sign() function with f32_4
-     */
-    public void testSignF32_4() {
-        doF32_4(0x123d678, 0);
-
-    }
-    public void testSignF32_4_relaxed() {
-        doF32_4_relaxed(0x123d678, 0);
-    }
-
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/SinTest.java b/tests/tests/renderscript/src/android/renderscript/cts/SinTest.java
deleted file mode 100644
index 5911632..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/SinTest.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * 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 android.renderscript.cts;
-
-import com.android.cts.stub.R;
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-
-public class SinTest extends RSBaseCompute {
-    private ScriptC_sin_f32 script_f32;
-    private ScriptC_sin_f32_relaxed script_f32_relaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script_f32 = new ScriptC_sin_f32(mRS);
-        script_f32_relaxed = new ScriptC_sin_f32_relaxed(mRS);
-    }
-
-    @Override
-    public void forEach(int testId, Allocation mIn, Allocation mOut) throws RSRuntimeException {
-        switch (testId) {
-        case TEST_F32:
-            script_f32.forEach_sin_f32_1(mIn, mOut);
-            break;
-        case TEST_F32_2:
-            script_f32.forEach_sin_f32_2(mIn, mOut);
-            break;
-        case TEST_F32_3:
-            script_f32.forEach_sin_f32_3(mIn, mOut);
-            break;
-        case TEST_F32_4:
-            script_f32.forEach_sin_f32_4(mIn, mOut);
-            break;
-
-        case TEST_RELAXED_F32:
-            script_f32_relaxed.forEach_sin_f32_1(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_2:
-            script_f32_relaxed.forEach_sin_f32_2(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_3:
-            script_f32_relaxed.forEach_sin_f32_3(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_4:
-            script_f32_relaxed.forEach_sin_f32_4(mIn, mOut);
-            break;
-        }
-    }
-
-    @Override
-    protected float[] getRefArray(float[] in, int input_size, int stride, int skip) {
-        float[] ref = new float[input_size * stride];
-        for (int i = 0; i < input_size; i++) {
-            for (int j = 0; j < stride - skip; j++) {
-                int idx= i * stride + j;
-                int idxRef = i * (stride - skip) + j;
-                ref[idxRef] = (float)(Math.sin((double)in[idx]));
-            }
-        }
-        return ref;
-    }
-
-    public void testSinF32() {
-        doF32(0xba, 4);
-    }
-
-    public void testSinF32_relaxed() {
-        doF32_relaxed(0xba, 128);
-    }
-
-    public void testSinF32_2() {
-        doF32_2(0xbaa, 4);
-    }
-
-    public void testSinF32_2_relaxed() {
-        doF32_2_relaxed(0xbaa, 128);
-    }
-
-    public void testSinF32_3() {
-        doF32_3(0xca, 4);
-    }
-
-    public void testSinF32_3_relaxed() {
-        doF32_3_relaxed(0xca, 128);
-    }
-
-    public void testSinF32_4() {
-        doF32_4(0xda, 4);
-
-    }
-    public void testSinF32_4_relaxed() {
-        doF32_4_relaxed(0xda, 128);
-    }
-
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/SinhTest.java b/tests/tests/renderscript/src/android/renderscript/cts/SinhTest.java
deleted file mode 100644
index a95c574..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/SinhTest.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * 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 android.renderscript.cts;
-
-import com.android.cts.stub.R;
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-
-public class SinhTest extends RSBaseCompute {
-    private ScriptC_sinh_f32 script_f32;
-    private ScriptC_sinh_f32_relaxed script_f32_relaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script_f32 = new ScriptC_sinh_f32(mRS);
-        script_f32_relaxed = new ScriptC_sinh_f32_relaxed(mRS);
-    }
-
-    @Override
-    public void forEach(int testId, Allocation mIn, Allocation mOut) throws RSRuntimeException {
-        switch (testId) {
-        case TEST_F32:
-            script_f32.forEach_sinh_f32_1(mIn, mOut);
-            break;
-        case TEST_F32_2:
-            script_f32.forEach_sinh_f32_2(mIn, mOut);
-            break;
-        case TEST_F32_3:
-            script_f32.forEach_sinh_f32_3(mIn, mOut);
-            break;
-        case TEST_F32_4:
-            script_f32.forEach_sinh_f32_4(mIn, mOut);
-            break;
-
-        case TEST_RELAXED_F32:
-            script_f32_relaxed.forEach_sinh_f32_1(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_2:
-            script_f32_relaxed.forEach_sinh_f32_2(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_3:
-            script_f32_relaxed.forEach_sinh_f32_3(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_4:
-            script_f32_relaxed.forEach_sinh_f32_4(mIn, mOut);
-            break;
-        }
-    }
-
-    @Override
-    protected float[] getRefArray(float[] in, int input_size, int stride, int skip) {
-        float[] ref = new float[input_size * stride];
-        for (int i = 0; i < input_size; i++) {
-            for (int j = 0; j < stride - skip; j++) {
-                int idx= i * stride + j;
-                int idxRef = i * (stride - skip) + j;
-                ref[idxRef] = (float)(Math.sinh((double)in[idx]));
-            }
-        }
-        return ref;
-    }
-
-    public void testSinhF32() {
-        doF32(0x32a, 4);
-    }
-
-    public void testSinhF32_relaxed() {
-        doF32_relaxed(0x32a, 128);
-    }
-
-    public void testSinhF32_2() {
-        doF32_2(0xba35, 4);
-    }
-
-    public void testSinhF32_2_relaxed() {
-        doF32_2_relaxed(0xba35, 128);
-    }
-
-    public void testSinhF32_3() {
-        doF32_3(0xacc3, 4);
-    }
-
-    public void testSinhF32_3_relaxed() {
-        doF32_3_relaxed(0xacc3, 128);
-    }
-
-    public void testSinhF32_4() {
-        doF32_4(0xaa, 4);
-
-    }
-    public void testSinhF32_4_relaxed() {
-        doF32_4_relaxed(0xaa, 128);
-    }
-
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/SqrtTest.java b/tests/tests/renderscript/src/android/renderscript/cts/SqrtTest.java
deleted file mode 100644
index 02290ca..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/SqrtTest.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * 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 android.renderscript.cts;
-
-import com.android.cts.stub.R;
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-
-public class SqrtTest extends RSBaseCompute {
-    private ScriptC_sqrt_f32 script_f32;
-    private ScriptC_sqrt_f32_relaxed script_f32_relaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script_f32 = new ScriptC_sqrt_f32(mRS);
-        script_f32_relaxed = new ScriptC_sqrt_f32_relaxed(mRS);
-    }
-
-    @Override
-    public void forEach(int testId, Allocation mIn, Allocation mOut) throws RSRuntimeException {
-        switch (testId) {
-        case TEST_F32:
-            script_f32.forEach_sqrt_f32_1(mIn, mOut);
-            break;
-        case TEST_F32_2:
-            script_f32.forEach_sqrt_f32_2(mIn, mOut);
-            break;
-        case TEST_F32_3:
-            script_f32.forEach_sqrt_f32_3(mIn, mOut);
-            break;
-        case TEST_F32_4:
-            script_f32.forEach_sqrt_f32_4(mIn, mOut);
-            break;
-
-        case TEST_RELAXED_F32:
-            script_f32_relaxed.forEach_sqrt_f32_1(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_2:
-            script_f32_relaxed.forEach_sqrt_f32_2(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_3:
-            script_f32_relaxed.forEach_sqrt_f32_3(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_4:
-            script_f32_relaxed.forEach_sqrt_f32_4(mIn, mOut);
-            break;
-        }
-    }
-
-    @Override
-    protected float[] getRefArray(float[] in, int input_size, int stride, int skip) {
-        float[] ref = new float[input_size * stride];
-        for (int i = 0; i < input_size; i++) {
-            for (int j = 0; j < stride - skip; j++) {
-                int idx= i * stride + j;
-                int idxRef = i * (stride - skip) + j;
-                ref[idxRef] = (float)(Math.sqrt((double)in[idx]));
-            }
-        }
-        return ref;
-    }
-
-    public void testSqrtF32() {
-        doF32(0xab3, 3);
-    }
-
-    public void testSqrtF32_relaxed() {
-        doF32_relaxed(0xab3, 3);
-    }
-
-    public void testSqrtF32_2() {
-        doF32_2(0xa1, 3);
-    }
-
-    public void testSqrtF32_2_relaxed() {
-        doF32_2_relaxed(0xa1, 3);
-    }
-
-    public void testSqrtF32_3() {
-        doF32_3(0xbae7, 3);
-    }
-
-    public void testSqrtF32_3_relaxed() {
-        doF32_3_relaxed(0xbae7, 3);
-    }
-
-    public void testSqrtF32_4() {
-        doF32_4(0xbac361, 3);
-
-    }
-    public void testSqrtF32_4_relaxed() {
-        doF32_4_relaxed(0xbac361, 3);
-    }
-
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/StepTest.java b/tests/tests/renderscript/src/android/renderscript/cts/StepTest.java
deleted file mode 100644
index 39fb443..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/StepTest.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * 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 android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.Element;
-import android.renderscript.RSRuntimeException;
-import com.android.cts.stub.R;
-
-public class StepTest extends RSBaseCompute {
-    private ScriptC_step_f32 script_f32;
-    private ScriptC_step_f32_relaxed script_f32_relaxed;
-    private Allocation mIn;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script_f32 = new ScriptC_step_f32(mRS);
-        script_f32_relaxed = new ScriptC_step_f32_relaxed(mRS);
-    }
-
-    @Override
-    public void forEach(int testId, Allocation mIn, Allocation mOut) throws RSRuntimeException {
-        switch (testId) {
-        case TEST_F32:
-            script_f32.forEach_step_f32_1(mIn, mOut);
-            break;
-        case TEST_F32_2:
-            script_f32.forEach_step_f32_2(mIn, mOut);
-            break;
-        case TEST_F32_3:
-            script_f32.forEach_step_f32_3(mIn, mOut);
-            break;
-        case TEST_F32_4:
-            script_f32.forEach_step_f32_4(mIn, mOut);
-            break;
-
-        case TEST_RELAXED_F32:
-            script_f32_relaxed.forEach_step_f32_1(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_2:
-            script_f32_relaxed.forEach_step_f32_2(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_3:
-            script_f32_relaxed.forEach_step_f32_3(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_4:
-            script_f32_relaxed.forEach_step_f32_4(mIn, mOut);
-            break;
-        }
-    }
-
-    @Override
-    protected float[] getRefArray(float[] in, int input_size, int stride, int skip) {
-        float[] ref = new float[input_size * stride];
-        for (int i = 0; i < input_size; i++) {
-            for (int j = 0; j < stride - skip; j++) {
-                int idx = i * stride * 2 + j;
-                ref[i * (stride - skip) + j] = in[idx+stride] < in[idx] ? 0.0f : 1.0f;
-            }
-        }
-        return ref;
-    }
-
-    @Override
-    protected Allocation setInAlloc(Element e) {
-        return mIn;
-    }
-
-    @Override
-    protected float[] makeInArray(int size) {
-        return new float[size*2];
-    }
-
-    public void testStepF32() {
-        ScriptField_step_input in = new ScriptField_step_input(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32(0x12678, 0);
-    }
-
-    public void testStepF32_relaxed() {
-        ScriptField_step_input in = new ScriptField_step_input(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_relaxed(0x12678, 0);
-    }
-
-    public void testStepF32_2() {
-        ScriptField_step_2_input in = new ScriptField_step_2_input(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_2(0x1ace8, 0);
-    }
-
-    public void testStepF32_2_relaxed() {
-        ScriptField_step_2_input in = new ScriptField_step_2_input(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_2_relaxed(0x1ace8, 0);
-    }
-
-    public void testStepF32_3() {
-        ScriptField_step_3_input in = new ScriptField_step_3_input(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_3(0xa2ce8, 0);
-    }
-
-    public void testStepF32_3_relaxed() {
-        ScriptField_step_3_input in = new ScriptField_step_3_input(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_3_relaxed(0xa2ce8, 0);
-    }
-
-    public void testStepF32_4() {
-        ScriptField_step_4_input in = new ScriptField_step_4_input(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_4(0x1ee8, 0);
-    }
-
-    public void testStepF32_4_relaxed() {
-        ScriptField_step_4_input in = new ScriptField_step_4_input(mRS, INPUTSIZE);
-        mIn = in.getAllocation();
-        doF32_4_relaxed(0x1ee8, 0);
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TanTest.java b/tests/tests/renderscript/src/android/renderscript/cts/TanTest.java
deleted file mode 100644
index a4e62e9..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TanTest.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * 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 android.renderscript.cts;
-
-import com.android.cts.stub.R;
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-
-public class TanTest extends RSBaseCompute {
-    private ScriptC_tan_f32 script_f32;
-    private ScriptC_tan_f32_relaxed script_f32_relaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script_f32 = new ScriptC_tan_f32(mRS);
-        script_f32_relaxed = new ScriptC_tan_f32_relaxed(mRS);
-    }
-
-    @Override
-    public void forEach(int testId, Allocation mIn, Allocation mOut) throws RSRuntimeException {
-        switch (testId) {
-        case TEST_F32:
-            script_f32.forEach_tan_f32_1(mIn, mOut);
-            break;
-        case TEST_F32_2:
-            script_f32.forEach_tan_f32_2(mIn, mOut);
-            break;
-        case TEST_F32_3:
-            script_f32.forEach_tan_f32_3(mIn, mOut);
-            break;
-        case TEST_F32_4:
-            script_f32.forEach_tan_f32_4(mIn, mOut);
-            break;
-
-        case TEST_RELAXED_F32:
-            script_f32_relaxed.forEach_tan_f32_1(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_2:
-            script_f32_relaxed.forEach_tan_f32_2(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_3:
-            script_f32_relaxed.forEach_tan_f32_3(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_4:
-            script_f32_relaxed.forEach_tan_f32_4(mIn, mOut);
-            break;
-        }
-    }
-
-    @Override
-    protected float[] getRefArray(float[] in, int input_size, int stride, int skip) {
-        float[] ref = new float[input_size * stride];
-        for (int i = 0; i < input_size; i++) {
-            for (int j = 0; j < stride - skip; j++) {
-                int idx= i * stride + j;
-                int idxRef = i * (stride - skip) + j;
-                ref[idxRef] = (float)(Math.tan((double)in[idx]));
-            }
-        }
-        return ref;
-    }
-
-    public void testTanF32() {
-        doF32(0xabe, 5);
-    }
-
-    public void testTanF32_relaxed() {
-        doF32_relaxed(0xabe, 128);
-    }
-
-    public void testTanF32_2() {
-        doF32_2(0x29, 5);
-    }
-
-    public void testTanF32_2_relaxed() {
-        doF32_2_relaxed(0x29, 128);
-    }
-
-    public void testTanF32_3() {
-        doF32_3(0x9a, 5);
-    }
-
-    public void testTanF32_3_relaxed() {
-        doF32_3_relaxed(0x9a, 128);
-    }
-
-    public void testTanF32_4() {
-        doF32_4(0xac3, 5);
-
-    }
-    public void testTanF32_4_relaxed() {
-        doF32_4_relaxed(0xac3, 128);
-    }
-
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TanhTest.java b/tests/tests/renderscript/src/android/renderscript/cts/TanhTest.java
deleted file mode 100644
index 4dc7d15..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TanhTest.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * 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 android.renderscript.cts;
-
-import com.android.cts.stub.R;
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-
-public class TanhTest extends RSBaseCompute {
-    private ScriptC_tanh_f32 script_f32;
-    private ScriptC_tanh_f32_relaxed script_f32_relaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script_f32 = new ScriptC_tanh_f32(mRS);
-        script_f32_relaxed = new ScriptC_tanh_f32_relaxed(mRS);
-    }
-
-    @Override
-    public void forEach(int testId, Allocation mIn, Allocation mOut) throws RSRuntimeException {
-        switch (testId) {
-        case TEST_F32:
-            script_f32.forEach_tanh_f32_1(mIn, mOut);
-            break;
-        case TEST_F32_2:
-            script_f32.forEach_tanh_f32_2(mIn, mOut);
-            break;
-        case TEST_F32_3:
-            script_f32.forEach_tanh_f32_3(mIn, mOut);
-            break;
-        case TEST_F32_4:
-            script_f32.forEach_tanh_f32_4(mIn, mOut);
-            break;
-
-        case TEST_RELAXED_F32:
-            script_f32_relaxed.forEach_tanh_f32_1(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_2:
-            script_f32_relaxed.forEach_tanh_f32_2(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_3:
-            script_f32_relaxed.forEach_tanh_f32_3(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_4:
-            script_f32_relaxed.forEach_tanh_f32_4(mIn, mOut);
-            break;
-        }
-    }
-
-    @Override
-    protected float[] getRefArray(float[] in, int input_size, int stride, int skip) {
-        float[] ref = new float[input_size * stride];
-        for (int i = 0; i < input_size; i++) {
-            for (int j = 0; j < stride - skip; j++) {
-                int idx= i * stride + j;
-                int idxRef = i * (stride - skip) + j;
-                ref[idxRef] = (float)(Math.tanh((double)in[idx]));
-            }
-        }
-        return ref;
-    }
-
-    public void testTanhF32() {
-        doF32(0xab61, 5);
-    }
-
-    public void testTanhF32_relaxed() {
-        doF32_relaxed(0xab61, 128);
-    }
-
-    public void testTanhF32_2() {
-        doF32_2(0xa301, 5);
-    }
-
-    public void testTanhF32_2_relaxed() {
-        doF32_2_relaxed(0xa301, 128);
-    }
-
-    public void testTanhF32_3() {
-        doF32_3(0x918, 5);
-    }
-
-    public void testTanhF32_3_relaxed() {
-        doF32_3_relaxed(0x918, 128);
-    }
-
-    public void testTanhF32_4() {
-        doF32_4(0x81, 5);
-
-    }
-    public void testTanhF32_4_relaxed() {
-        doF32_4_relaxed(0x81, 128);
-    }
-
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestAbs.java b/tests/tests/renderscript/src/android/renderscript/cts/TestAbs.java
new file mode 100644
index 0000000..7799a8a
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestAbs.java
@@ -0,0 +1,750 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestAbs extends RSBaseCompute {
+
+    private ScriptC_TestAbs script;
+    private ScriptC_TestAbsRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestAbs(mRS);
+        scriptRelaxed = new ScriptC_TestAbsRelaxed(mRS);
+    }
+
+    public class ArgumentsCharUchar {
+        public byte inValue;
+        public byte out;
+    }
+
+    private void checkAbsCharUchar() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 1, 0x4c0d03eb0d0c5a91l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 1), INPUTSIZE);
+            script.forEach_testAbsCharUchar(inValue, out);
+            verifyResultsAbsCharUchar(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsCharUchar: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testAbsCharUchar(inValue, out);
+            verifyResultsAbsCharUchar(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsCharUchar: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAbsCharUchar(Allocation inValue, Allocation out, boolean relaxed) {
+        byte[] arrayInValue = new byte[INPUTSIZE * 1];
+        inValue.copyTo(arrayInValue);
+        byte[] arrayOut = new byte[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsCharUchar args = new ArgumentsCharUchar();
+                args.inValue = arrayInValue[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeAbs(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 1 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("%d", args.inValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 1 + j]));
+                    if (args.out != arrayOut[i * 1 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkAbsCharUchar" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkAbsChar2Uchar2() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 2, 0x901d551e7f67bb87l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
+            script.forEach_testAbsChar2Uchar2(inValue, out);
+            verifyResultsAbsChar2Uchar2(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsChar2Uchar2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testAbsChar2Uchar2(inValue, out);
+            verifyResultsAbsChar2Uchar2(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsChar2Uchar2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAbsChar2Uchar2(Allocation inValue, Allocation out, boolean relaxed) {
+        byte[] arrayInValue = new byte[INPUTSIZE * 2];
+        inValue.copyTo(arrayInValue);
+        byte[] arrayOut = new byte[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsCharUchar args = new ArgumentsCharUchar();
+                args.inValue = arrayInValue[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeAbs(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("%d", args.inValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkAbsChar2Uchar2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkAbsChar3Uchar3() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 3, 0xb5d1caa5c8a5e105l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
+            script.forEach_testAbsChar3Uchar3(inValue, out);
+            verifyResultsAbsChar3Uchar3(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsChar3Uchar3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testAbsChar3Uchar3(inValue, out);
+            verifyResultsAbsChar3Uchar3(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsChar3Uchar3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAbsChar3Uchar3(Allocation inValue, Allocation out, boolean relaxed) {
+        byte[] arrayInValue = new byte[INPUTSIZE * 4];
+        inValue.copyTo(arrayInValue);
+        byte[] arrayOut = new byte[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsCharUchar args = new ArgumentsCharUchar();
+                args.inValue = arrayInValue[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeAbs(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("%d", args.inValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkAbsChar3Uchar3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkAbsChar4Uchar4() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 4, 0xdb86402d11e40683l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
+            script.forEach_testAbsChar4Uchar4(inValue, out);
+            verifyResultsAbsChar4Uchar4(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsChar4Uchar4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testAbsChar4Uchar4(inValue, out);
+            verifyResultsAbsChar4Uchar4(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsChar4Uchar4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAbsChar4Uchar4(Allocation inValue, Allocation out, boolean relaxed) {
+        byte[] arrayInValue = new byte[INPUTSIZE * 4];
+        inValue.copyTo(arrayInValue);
+        byte[] arrayOut = new byte[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsCharUchar args = new ArgumentsCharUchar();
+                args.inValue = arrayInValue[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeAbs(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("%d", args.inValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkAbsChar4Uchar4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsShortUshort {
+        public short inValue;
+        public short out;
+    }
+
+    private void checkAbsShortUshort() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 1, 0xaead1a96b6ea02a7l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 1), INPUTSIZE);
+            script.forEach_testAbsShortUshort(inValue, out);
+            verifyResultsAbsShortUshort(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsShortUshort: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testAbsShortUshort(inValue, out);
+            verifyResultsAbsShortUshort(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsShortUshort: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAbsShortUshort(Allocation inValue, Allocation out, boolean relaxed) {
+        short[] arrayInValue = new short[INPUTSIZE * 1];
+        inValue.copyTo(arrayInValue);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsShortUshort args = new ArgumentsShortUshort();
+                args.inValue = arrayInValue[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeAbs(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 1 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("%d", args.inValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 1 + j]));
+                    if (args.out != arrayOut[i * 1 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkAbsShortUshort" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkAbsShort2Ushort2() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 2, 0x41a1894ff6b0da9l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
+            script.forEach_testAbsShort2Ushort2(inValue, out);
+            verifyResultsAbsShort2Ushort2(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsShort2Ushort2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testAbsShort2Ushort2(inValue, out);
+            verifyResultsAbsShort2Ushort2(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsShort2Ushort2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAbsShort2Ushort2(Allocation inValue, Allocation out, boolean relaxed) {
+        short[] arrayInValue = new short[INPUTSIZE * 2];
+        inValue.copyTo(arrayInValue);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsShortUshort args = new ArgumentsShortUshort();
+                args.inValue = arrayInValue[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeAbs(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("%d", args.inValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkAbsShort2Ushort2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkAbsShort3Ushort3() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 3, 0x5969cbec377ba515l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
+            script.forEach_testAbsShort3Ushort3(inValue, out);
+            verifyResultsAbsShort3Ushort3(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsShort3Ushort3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testAbsShort3Ushort3(inValue, out);
+            verifyResultsAbsShort3Ushort3(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsShort3Ushort3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAbsShort3Ushort3(Allocation inValue, Allocation out, boolean relaxed) {
+        short[] arrayInValue = new short[INPUTSIZE * 4];
+        inValue.copyTo(arrayInValue);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsShortUshort args = new ArgumentsShortUshort();
+                args.inValue = arrayInValue[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeAbs(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("%d", args.inValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkAbsShort3Ushort3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkAbsShort4Ushort4() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 4, 0xaeb97f436f8c3c81l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
+            script.forEach_testAbsShort4Ushort4(inValue, out);
+            verifyResultsAbsShort4Ushort4(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsShort4Ushort4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testAbsShort4Ushort4(inValue, out);
+            verifyResultsAbsShort4Ushort4(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsShort4Ushort4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAbsShort4Ushort4(Allocation inValue, Allocation out, boolean relaxed) {
+        short[] arrayInValue = new short[INPUTSIZE * 4];
+        inValue.copyTo(arrayInValue);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsShortUshort args = new ArgumentsShortUshort();
+                args.inValue = arrayInValue[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeAbs(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("%d", args.inValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkAbsShort4Ushort4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsIntUint {
+        public int inValue;
+        public int out;
+    }
+
+    private void checkAbsIntUint() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0xcda40fd4fa1abbd1l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 1), INPUTSIZE);
+            script.forEach_testAbsIntUint(inValue, out);
+            verifyResultsAbsIntUint(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsIntUint: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testAbsIntUint(inValue, out);
+            verifyResultsAbsIntUint(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsIntUint: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAbsIntUint(Allocation inValue, Allocation out, boolean relaxed) {
+        int[] arrayInValue = new int[INPUTSIZE * 1];
+        inValue.copyTo(arrayInValue);
+        int[] arrayOut = new int[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsIntUint args = new ArgumentsIntUint();
+                args.inValue = arrayInValue[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeAbs(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 1 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("%d", args.inValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 1 + j]));
+                    if (args.out != arrayOut[i * 1 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkAbsIntUint" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkAbsInt2Uint2() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 2, 0x71326739aabbb4a5l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
+            script.forEach_testAbsInt2Uint2(inValue, out);
+            verifyResultsAbsInt2Uint2(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsInt2Uint2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testAbsInt2Uint2(inValue, out);
+            verifyResultsAbsInt2Uint2(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsInt2Uint2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAbsInt2Uint2(Allocation inValue, Allocation out, boolean relaxed) {
+        int[] arrayInValue = new int[INPUTSIZE * 2];
+        inValue.copyTo(arrayInValue);
+        int[] arrayOut = new int[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsIntUint args = new ArgumentsIntUint();
+                args.inValue = arrayInValue[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeAbs(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("%d", args.inValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkAbsInt2Uint2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkAbsInt3Uint3() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 3, 0x9bbf87f7a6fae959l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
+            script.forEach_testAbsInt3Uint3(inValue, out);
+            verifyResultsAbsInt3Uint3(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsInt3Uint3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testAbsInt3Uint3(inValue, out);
+            verifyResultsAbsInt3Uint3(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsInt3Uint3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAbsInt3Uint3(Allocation inValue, Allocation out, boolean relaxed) {
+        int[] arrayInValue = new int[INPUTSIZE * 4];
+        inValue.copyTo(arrayInValue);
+        int[] arrayOut = new int[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsIntUint args = new ArgumentsIntUint();
+                args.inValue = arrayInValue[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeAbs(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("%d", args.inValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkAbsInt3Uint3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkAbsInt4Uint4() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 4, 0xc64ca8b5a33a1e0dl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
+            script.forEach_testAbsInt4Uint4(inValue, out);
+            verifyResultsAbsInt4Uint4(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsInt4Uint4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testAbsInt4Uint4(inValue, out);
+            verifyResultsAbsInt4Uint4(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsInt4Uint4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAbsInt4Uint4(Allocation inValue, Allocation out, boolean relaxed) {
+        int[] arrayInValue = new int[INPUTSIZE * 4];
+        inValue.copyTo(arrayInValue);
+        int[] arrayOut = new int[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsIntUint args = new ArgumentsIntUint();
+                args.inValue = arrayInValue[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeAbs(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("%d", args.inValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkAbsInt4Uint4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testAbs() {
+        checkAbsCharUchar();
+        checkAbsChar2Uchar2();
+        checkAbsChar3Uchar3();
+        checkAbsChar4Uchar4();
+        checkAbsShortUshort();
+        checkAbsShort2Ushort2();
+        checkAbsShort3Ushort3();
+        checkAbsShort4Ushort4();
+        checkAbsIntUint();
+        checkAbsInt2Uint2();
+        checkAbsInt3Uint3();
+        checkAbsInt4Uint4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestAcos.java b/tests/tests/renderscript/src/android/renderscript/cts/TestAcos.java
new file mode 100644
index 0000000..95f7a51
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestAcos.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestAcos extends RSBaseCompute {
+
+    private ScriptC_TestAcos script;
+    private ScriptC_TestAcosRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestAcos(mRS);
+        scriptRelaxed = new ScriptC_TestAcosRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Floaty out;
+    }
+
+    private void checkAcosFloatFloat() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xf6e893f6d1cc3bdfl, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testAcosFloatFloat(inV, out);
+            verifyResultsAcosFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcosFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testAcosFloatFloat(inV, out);
+            verifyResultsAcosFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcosFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAcosFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeAcos(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkAcosFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkAcosFloat2Float2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x55af66f81096ae8bl, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testAcosFloat2Float2(inV, out);
+            verifyResultsAcosFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcosFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testAcosFloat2Float2(inV, out);
+            verifyResultsAcosFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcosFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAcosFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeAcos(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkAcosFloat2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkAcosFloat3Float3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x55b1301306b1cf69l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testAcosFloat3Float3(inV, out);
+            verifyResultsAcosFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcosFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testAcosFloat3Float3(inV, out);
+            verifyResultsAcosFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcosFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAcosFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeAcos(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkAcosFloat3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkAcosFloat4Float4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x55b2f92dfcccf047l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testAcosFloat4Float4(inV, out);
+            verifyResultsAcosFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcosFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testAcosFloat4Float4(inV, out);
+            verifyResultsAcosFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcosFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAcosFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeAcos(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkAcosFloat4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testAcos() {
+        checkAcosFloatFloat();
+        checkAcosFloat2Float2();
+        checkAcosFloat3Float3();
+        checkAcosFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestAcosh.java b/tests/tests/renderscript/src/android/renderscript/cts/TestAcosh.java
new file mode 100644
index 0000000..90993cf
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestAcosh.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestAcosh extends RSBaseCompute {
+
+    private ScriptC_TestAcosh script;
+    private ScriptC_TestAcoshRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestAcosh(mRS);
+        scriptRelaxed = new ScriptC_TestAcoshRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float in;
+        public Floaty out;
+    }
+
+    private void checkAcoshFloatFloat() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xb2c74105f8e94ea7l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testAcoshFloatFloat(in, out);
+            verifyResultsAcoshFloatFloat(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcoshFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testAcoshFloatFloat(in, out);
+            verifyResultsAcoshFloatFloat(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcoshFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAcoshFloatFloat(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 1];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeAcosh(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkAcoshFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkAcoshFloat2Float2() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x4123c61e7e518f4bl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testAcoshFloat2Float2(in, out);
+            verifyResultsAcoshFloat2Float2(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcoshFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testAcoshFloat2Float2(in, out);
+            verifyResultsAcoshFloat2Float2(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcoshFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAcoshFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 2];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeAcosh(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkAcoshFloat2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkAcoshFloat3Float3() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x4123d0bfdd5824e5l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testAcoshFloat3Float3(in, out);
+            verifyResultsAcoshFloat3Float3(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcoshFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testAcoshFloat3Float3(in, out);
+            verifyResultsAcoshFloat3Float3(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcoshFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAcoshFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeAcosh(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkAcoshFloat3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkAcoshFloat4Float4() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x4123db613c5eba7fl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testAcoshFloat4Float4(in, out);
+            verifyResultsAcoshFloat4Float4(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcoshFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testAcoshFloat4Float4(in, out);
+            verifyResultsAcoshFloat4Float4(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcoshFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAcoshFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeAcosh(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkAcoshFloat4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testAcosh() {
+        checkAcoshFloatFloat();
+        checkAcoshFloat2Float2();
+        checkAcoshFloat3Float3();
+        checkAcoshFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestAcospi.java b/tests/tests/renderscript/src/android/renderscript/cts/TestAcospi.java
new file mode 100644
index 0000000..d11148d
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestAcospi.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestAcospi extends RSBaseCompute {
+
+    private ScriptC_TestAcospi script;
+    private ScriptC_TestAcospiRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestAcospi(mRS);
+        scriptRelaxed = new ScriptC_TestAcospiRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Floaty out;
+    }
+
+    private void checkAcospiFloatFloat() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x9fbdc3b5d1e084b2l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testAcospiFloatFloat(inV, out);
+            verifyResultsAcospiFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcospiFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testAcospiFloatFloat(inV, out);
+            verifyResultsAcospiFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcospiFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAcospiFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeAcospi(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkAcospiFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkAcospiFloat2Float2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xc175417fa318aa86l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testAcospiFloat2Float2(inV, out);
+            verifyResultsAcospiFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcospiFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testAcospiFloat2Float2(inV, out);
+            verifyResultsAcospiFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcospiFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAcospiFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeAcospi(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkAcospiFloat2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkAcospiFloat3Float3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xc1770a9a9933cb64l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testAcospiFloat3Float3(inV, out);
+            verifyResultsAcospiFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcospiFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testAcospiFloat3Float3(inV, out);
+            verifyResultsAcospiFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcospiFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAcospiFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeAcospi(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkAcospiFloat3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkAcospiFloat4Float4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xc178d3b58f4eec42l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testAcospiFloat4Float4(inV, out);
+            verifyResultsAcospiFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcospiFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testAcospiFloat4Float4(inV, out);
+            verifyResultsAcospiFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcospiFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAcospiFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeAcospi(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkAcospiFloat4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testAcospi() {
+        checkAcospiFloatFloat();
+        checkAcospiFloat2Float2();
+        checkAcospiFloat3Float3();
+        checkAcospiFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestAsin.java b/tests/tests/renderscript/src/android/renderscript/cts/TestAsin.java
new file mode 100644
index 0000000..71253f6
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestAsin.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestAsin extends RSBaseCompute {
+
+    private ScriptC_TestAsin script;
+    private ScriptC_TestAsinRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestAsin(mRS);
+        scriptRelaxed = new ScriptC_TestAsinRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Floaty out;
+    }
+
+    private void checkAsinFloatFloat() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x80b5674ff98b5a12l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testAsinFloatFloat(inV, out);
+            verifyResultsAsinFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testAsinFloatFloat(inV, out);
+            verifyResultsAsinFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAsinFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeAsin(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkAsinFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkAsinFloat2Float2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x9e11e5e823f7cce6l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testAsinFloat2Float2(inV, out);
+            verifyResultsAsinFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testAsinFloat2Float2(inV, out);
+            verifyResultsAsinFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAsinFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeAsin(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkAsinFloat2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkAsinFloat3Float3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x9e13af031a12edc4l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testAsinFloat3Float3(inV, out);
+            verifyResultsAsinFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testAsinFloat3Float3(inV, out);
+            verifyResultsAsinFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAsinFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeAsin(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkAsinFloat3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkAsinFloat4Float4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x9e15781e102e0ea2l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testAsinFloat4Float4(inV, out);
+            verifyResultsAsinFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testAsinFloat4Float4(inV, out);
+            verifyResultsAsinFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAsinFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeAsin(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkAsinFloat4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testAsin() {
+        checkAsinFloatFloat();
+        checkAsinFloat2Float2();
+        checkAsinFloat3Float3();
+        checkAsinFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestAsinh.java b/tests/tests/renderscript/src/android/renderscript/cts/TestAsinh.java
new file mode 100644
index 0000000..1ec9c0a
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestAsinh.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestAsinh extends RSBaseCompute {
+
+    private ScriptC_TestAsinh script;
+    private ScriptC_TestAsinhRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestAsinh(mRS);
+        scriptRelaxed = new ScriptC_TestAsinhRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float in;
+        public Floaty out;
+    }
+
+    private void checkAsinhFloatFloat() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x3c94145f20a86cdal, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testAsinhFloatFloat(in, out);
+            verifyResultsAsinhFloatFloat(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinhFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testAsinhFloatFloat(in, out);
+            verifyResultsAsinhFloatFloat(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinhFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAsinhFloatFloat(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 1];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeAsinh(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkAsinhFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkAsinhFloat2Float2() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x8986450e91b2ada6l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testAsinhFloat2Float2(in, out);
+            verifyResultsAsinhFloat2Float2(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinhFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testAsinhFloat2Float2(in, out);
+            verifyResultsAsinhFloat2Float2(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinhFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAsinhFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 2];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeAsinh(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkAsinhFloat2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkAsinhFloat3Float3() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x89864faff0b94340l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testAsinhFloat3Float3(in, out);
+            verifyResultsAsinhFloat3Float3(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinhFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testAsinhFloat3Float3(in, out);
+            verifyResultsAsinhFloat3Float3(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinhFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAsinhFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeAsinh(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkAsinhFloat3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkAsinhFloat4Float4() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x89865a514fbfd8dal, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testAsinhFloat4Float4(in, out);
+            verifyResultsAsinhFloat4Float4(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinhFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testAsinhFloat4Float4(in, out);
+            verifyResultsAsinhFloat4Float4(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinhFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAsinhFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeAsinh(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkAsinhFloat4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testAsinh() {
+        checkAsinhFloatFloat();
+        checkAsinhFloat2Float2();
+        checkAsinhFloat3Float3();
+        checkAsinhFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestAsinpi.java b/tests/tests/renderscript/src/android/renderscript/cts/TestAsinpi.java
new file mode 100644
index 0000000..f6bb172
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestAsinpi.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestAsinpi extends RSBaseCompute {
+
+    private ScriptC_TestAsinpi script;
+    private ScriptC_TestAsinpiRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestAsinpi(mRS);
+        scriptRelaxed = new ScriptC_TestAsinpiRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Floaty out;
+    }
+
+    private void checkAsinpiFloatFloat() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xe82042a5e541a30dl, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testAsinpiFloatFloat(inV, out);
+            verifyResultsAsinpiFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinpiFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testAsinpiFloatFloat(inV, out);
+            verifyResultsAsinpiFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinpiFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAsinpiFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeAsinpi(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkAsinpiFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkAsinpiFloat2Float2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x90dc157b9b8ce9c9l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testAsinpiFloat2Float2(inV, out);
+            verifyResultsAsinpiFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinpiFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testAsinpiFloat2Float2(inV, out);
+            verifyResultsAsinpiFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinpiFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAsinpiFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeAsinpi(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkAsinpiFloat2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkAsinpiFloat3Float3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x90ddde9691a80aa7l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testAsinpiFloat3Float3(inV, out);
+            verifyResultsAsinpiFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinpiFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testAsinpiFloat3Float3(inV, out);
+            verifyResultsAsinpiFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinpiFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAsinpiFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeAsinpi(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkAsinpiFloat3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkAsinpiFloat4Float4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x90dfa7b187c32b85l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testAsinpiFloat4Float4(inV, out);
+            verifyResultsAsinpiFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinpiFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testAsinpiFloat4Float4(inV, out);
+            verifyResultsAsinpiFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinpiFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAsinpiFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeAsinpi(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkAsinpiFloat4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testAsinpi() {
+        checkAsinpiFloatFloat();
+        checkAsinpiFloat2Float2();
+        checkAsinpiFloat3Float3();
+        checkAsinpiFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestAtan.java b/tests/tests/renderscript/src/android/renderscript/cts/TestAtan.java
new file mode 100644
index 0000000..cfdcba9
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestAtan.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestAtan extends RSBaseCompute {
+
+    private ScriptC_TestAtan script;
+    private ScriptC_TestAtanRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestAtan(mRS);
+        scriptRelaxed = new ScriptC_TestAtanRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Floaty out;
+    }
+
+    private void checkAtanFloatFloat() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x2a9ae39592004c8dl, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testAtanFloatFloat(inV, out);
+            verifyResultsAtanFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testAtanFloatFloat(inV, out);
+            verifyResultsAtanFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAtanFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeAtan(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkAtanFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkAtanFloat2Float2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xb890789248a32749l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testAtanFloat2Float2(inV, out);
+            verifyResultsAtanFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testAtanFloat2Float2(inV, out);
+            verifyResultsAtanFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAtanFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeAtan(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkAtanFloat2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkAtanFloat3Float3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xb89241ad3ebe4827l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testAtanFloat3Float3(inV, out);
+            verifyResultsAtanFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testAtanFloat3Float3(inV, out);
+            verifyResultsAtanFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAtanFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeAtan(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkAtanFloat3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkAtanFloat4Float4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xb8940ac834d96905l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testAtanFloat4Float4(inV, out);
+            verifyResultsAtanFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testAtanFloat4Float4(inV, out);
+            verifyResultsAtanFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAtanFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeAtan(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkAtanFloat4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testAtan() {
+        checkAtanFloatFloat();
+        checkAtanFloat2Float2();
+        checkAtanFloat3Float3();
+        checkAtanFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestAtan2.java b/tests/tests/renderscript/src/android/renderscript/cts/TestAtan2.java
new file mode 100644
index 0000000..6981149
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestAtan2.java
@@ -0,0 +1,325 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestAtan2 extends RSBaseCompute {
+
+    private ScriptC_TestAtan2 script;
+    private ScriptC_TestAtan2Relaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestAtan2(mRS);
+        scriptRelaxed = new ScriptC_TestAtan2Relaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloatFloat {
+        public float inY;
+        public float inX;
+        public Floaty out;
+    }
+
+    private void checkAtan2FloatFloatFloat() {
+        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x8f58f1f953c03c32l, false);
+        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x8f58f1f953c03c31l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInX(inX);
+            script.forEach_testAtan2FloatFloatFloat(inY, out);
+            verifyResultsAtan2FloatFloatFloat(inY, inX, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtan2FloatFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInX(inX);
+            scriptRelaxed.forEach_testAtan2FloatFloatFloat(inY, out);
+            verifyResultsAtan2FloatFloatFloat(inY, inX, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtan2FloatFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAtan2FloatFloatFloat(Allocation inY, Allocation inX, Allocation out, boolean relaxed) {
+        float[] arrayInY = new float[INPUTSIZE * 1];
+        inY.copyTo(arrayInY);
+        float[] arrayInX = new float[INPUTSIZE * 1];
+        inX.copyTo(arrayInX);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inY = arrayInY[i];
+                args.inX = arrayInX[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeAtan2(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inY: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
+                    message.append("\n");
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkAtan2FloatFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkAtan2Float2Float2Float2() {
+        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xbe78dcdcd414b6c0l, false);
+        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xbe78dcdcd414b6bfl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInX(inX);
+            script.forEach_testAtan2Float2Float2Float2(inY, out);
+            verifyResultsAtan2Float2Float2Float2(inY, inX, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtan2Float2Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInX(inX);
+            scriptRelaxed.forEach_testAtan2Float2Float2Float2(inY, out);
+            verifyResultsAtan2Float2Float2Float2(inY, inX, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtan2Float2Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAtan2Float2Float2Float2(Allocation inY, Allocation inX, Allocation out, boolean relaxed) {
+        float[] arrayInY = new float[INPUTSIZE * 2];
+        inY.copyTo(arrayInY);
+        float[] arrayInX = new float[INPUTSIZE * 2];
+        inX.copyTo(arrayInX);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inY = arrayInY[i * 2 + j];
+                args.inX = arrayInX[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeAtan2(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inY: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
+                    message.append("\n");
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkAtan2Float2Float2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkAtan2Float3Float3Float3() {
+        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x12ddbafcd5f2b861l, false);
+        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x12ddbafcd5f2b860l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInX(inX);
+            script.forEach_testAtan2Float3Float3Float3(inY, out);
+            verifyResultsAtan2Float3Float3Float3(inY, inX, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtan2Float3Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInX(inX);
+            scriptRelaxed.forEach_testAtan2Float3Float3Float3(inY, out);
+            verifyResultsAtan2Float3Float3Float3(inY, inX, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtan2Float3Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAtan2Float3Float3Float3(Allocation inY, Allocation inX, Allocation out, boolean relaxed) {
+        float[] arrayInY = new float[INPUTSIZE * 4];
+        inY.copyTo(arrayInY);
+        float[] arrayInX = new float[INPUTSIZE * 4];
+        inX.copyTo(arrayInX);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inY = arrayInY[i * 4 + j];
+                args.inX = arrayInX[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeAtan2(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inY: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
+                    message.append("\n");
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkAtan2Float3Float3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkAtan2Float4Float4Float4() {
+        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x6742991cd7d0ba02l, false);
+        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x6742991cd7d0ba01l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInX(inX);
+            script.forEach_testAtan2Float4Float4Float4(inY, out);
+            verifyResultsAtan2Float4Float4Float4(inY, inX, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtan2Float4Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInX(inX);
+            scriptRelaxed.forEach_testAtan2Float4Float4Float4(inY, out);
+            verifyResultsAtan2Float4Float4Float4(inY, inX, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtan2Float4Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAtan2Float4Float4Float4(Allocation inY, Allocation inX, Allocation out, boolean relaxed) {
+        float[] arrayInY = new float[INPUTSIZE * 4];
+        inY.copyTo(arrayInY);
+        float[] arrayInX = new float[INPUTSIZE * 4];
+        inX.copyTo(arrayInX);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inY = arrayInY[i * 4 + j];
+                args.inX = arrayInX[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeAtan2(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inY: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
+                    message.append("\n");
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkAtan2Float4Float4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testAtan2() {
+        checkAtan2FloatFloatFloat();
+        checkAtan2Float2Float2Float2();
+        checkAtan2Float3Float3Float3();
+        checkAtan2Float4Float4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestAtan2pi.java b/tests/tests/renderscript/src/android/renderscript/cts/TestAtan2pi.java
new file mode 100644
index 0000000..3f6960f
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestAtan2pi.java
@@ -0,0 +1,325 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestAtan2pi extends RSBaseCompute {
+
+    private ScriptC_TestAtan2pi script;
+    private ScriptC_TestAtan2piRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestAtan2pi(mRS);
+        scriptRelaxed = new ScriptC_TestAtan2piRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloatFloat {
+        public float inY;
+        public float inX;
+        public Floaty out;
+    }
+
+    private void checkAtan2piFloatFloatFloat() {
+        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x5a912731bef85233l, false);
+        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x5a912731bef85232l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInX(inX);
+            script.forEach_testAtan2piFloatFloatFloat(inY, out);
+            verifyResultsAtan2piFloatFloatFloat(inY, inX, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtan2piFloatFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInX(inX);
+            scriptRelaxed.forEach_testAtan2piFloatFloatFloat(inY, out);
+            verifyResultsAtan2piFloatFloatFloat(inY, inX, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtan2piFloatFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAtan2piFloatFloatFloat(Allocation inY, Allocation inX, Allocation out, boolean relaxed) {
+        float[] arrayInY = new float[INPUTSIZE * 1];
+        inY.copyTo(arrayInY);
+        float[] arrayInX = new float[INPUTSIZE * 1];
+        inX.copyTo(arrayInX);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inY = arrayInY[i];
+                args.inX = arrayInX[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeAtan2pi(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inY: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
+                    message.append("\n");
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkAtan2piFloatFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkAtan2piFloat2Float2Float2() {
+        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x8031be184fee8f53l, false);
+        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x8031be184fee8f52l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInX(inX);
+            script.forEach_testAtan2piFloat2Float2Float2(inY, out);
+            verifyResultsAtan2piFloat2Float2Float2(inY, inX, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtan2piFloat2Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInX(inX);
+            scriptRelaxed.forEach_testAtan2piFloat2Float2Float2(inY, out);
+            verifyResultsAtan2piFloat2Float2Float2(inY, inX, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtan2piFloat2Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAtan2piFloat2Float2Float2(Allocation inY, Allocation inX, Allocation out, boolean relaxed) {
+        float[] arrayInY = new float[INPUTSIZE * 2];
+        inY.copyTo(arrayInY);
+        float[] arrayInX = new float[INPUTSIZE * 2];
+        inX.copyTo(arrayInX);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inY = arrayInY[i * 2 + j];
+                args.inX = arrayInX[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeAtan2pi(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inY: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
+                    message.append("\n");
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkAtan2piFloat2Float2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkAtan2piFloat3Float3Float3() {
+        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xd4969c3851cc90f4l, false);
+        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xd4969c3851cc90f3l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInX(inX);
+            script.forEach_testAtan2piFloat3Float3Float3(inY, out);
+            verifyResultsAtan2piFloat3Float3Float3(inY, inX, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtan2piFloat3Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInX(inX);
+            scriptRelaxed.forEach_testAtan2piFloat3Float3Float3(inY, out);
+            verifyResultsAtan2piFloat3Float3Float3(inY, inX, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtan2piFloat3Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAtan2piFloat3Float3Float3(Allocation inY, Allocation inX, Allocation out, boolean relaxed) {
+        float[] arrayInY = new float[INPUTSIZE * 4];
+        inY.copyTo(arrayInY);
+        float[] arrayInX = new float[INPUTSIZE * 4];
+        inX.copyTo(arrayInX);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inY = arrayInY[i * 4 + j];
+                args.inX = arrayInX[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeAtan2pi(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inY: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
+                    message.append("\n");
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkAtan2piFloat3Float3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkAtan2piFloat4Float4Float4() {
+        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x28fb7a5853aa9295l, false);
+        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x28fb7a5853aa9294l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInX(inX);
+            script.forEach_testAtan2piFloat4Float4Float4(inY, out);
+            verifyResultsAtan2piFloat4Float4Float4(inY, inX, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtan2piFloat4Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInX(inX);
+            scriptRelaxed.forEach_testAtan2piFloat4Float4Float4(inY, out);
+            verifyResultsAtan2piFloat4Float4Float4(inY, inX, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtan2piFloat4Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAtan2piFloat4Float4Float4(Allocation inY, Allocation inX, Allocation out, boolean relaxed) {
+        float[] arrayInY = new float[INPUTSIZE * 4];
+        inY.copyTo(arrayInY);
+        float[] arrayInX = new float[INPUTSIZE * 4];
+        inX.copyTo(arrayInX);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inY = arrayInY[i * 4 + j];
+                args.inX = arrayInX[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeAtan2pi(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inY: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
+                    message.append("\n");
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkAtan2piFloat4Float4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testAtan2pi() {
+        checkAtan2piFloatFloatFloat();
+        checkAtan2piFloat2Float2Float2();
+        checkAtan2piFloat3Float3Float3();
+        checkAtan2piFloat4Float4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestAtanh.java b/tests/tests/renderscript/src/android/renderscript/cts/TestAtanh.java
new file mode 100644
index 0000000..d153efa
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestAtanh.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestAtanh extends RSBaseCompute {
+
+    private ScriptC_TestAtanh script;
+    private ScriptC_TestAtanhRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestAtanh(mRS);
+        scriptRelaxed = new ScriptC_TestAtanhRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float in;
+        public Floaty out;
+    }
+
+    private void checkAtanhFloatFloat() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xe67990a4b91d5f55l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testAtanhFloatFloat(in, out);
+            verifyResultsAtanhFloatFloat(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanhFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testAtanhFloatFloat(in, out);
+            verifyResultsAtanhFloatFloat(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanhFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAtanhFloatFloat(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 1];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeAtanh(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkAtanhFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkAtanhFloat2Float2() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xa404d7b8b65e0809l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testAtanhFloat2Float2(in, out);
+            verifyResultsAtanhFloat2Float2(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanhFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testAtanhFloat2Float2(in, out);
+            verifyResultsAtanhFloat2Float2(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanhFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAtanhFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 2];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeAtanh(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkAtanhFloat2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkAtanhFloat3Float3() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xa404e25a15649da3l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testAtanhFloat3Float3(in, out);
+            verifyResultsAtanhFloat3Float3(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanhFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testAtanhFloat3Float3(in, out);
+            verifyResultsAtanhFloat3Float3(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanhFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAtanhFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeAtanh(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkAtanhFloat3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkAtanhFloat4Float4() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xa404ecfb746b333dl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testAtanhFloat4Float4(in, out);
+            verifyResultsAtanhFloat4Float4(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanhFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testAtanhFloat4Float4(in, out);
+            verifyResultsAtanhFloat4Float4(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanhFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAtanhFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeAtanh(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkAtanhFloat4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testAtanh() {
+        checkAtanhFloatFloat();
+        checkAtanhFloat2Float2();
+        checkAtanhFloat3Float3();
+        checkAtanhFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestAtanpi.java b/tests/tests/renderscript/src/android/renderscript/cts/TestAtanpi.java
new file mode 100644
index 0000000..c9cd821
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestAtanpi.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestAtanpi extends RSBaseCompute {
+
+    private ScriptC_TestAtanpi script;
+    private ScriptC_TestAtanpiRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestAtanpi(mRS);
+        scriptRelaxed = new ScriptC_TestAtanpiRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Floaty out;
+    }
+
+    private void checkAtanpiFloatFloat() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x29ed55009ecfd70l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testAtanpiFloatFloat(inV, out);
+            verifyResultsAtanpiFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanpiFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testAtanpiFloatFloat(inV, out);
+            verifyResultsAtanpiFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanpiFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAtanpiFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeAtanpi(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkAtanpiFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkAtanpiFloat2Float2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xed0d645e752cbed4l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testAtanpiFloat2Float2(inV, out);
+            verifyResultsAtanpiFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanpiFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testAtanpiFloat2Float2(inV, out);
+            verifyResultsAtanpiFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanpiFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAtanpiFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeAtanpi(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkAtanpiFloat2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkAtanpiFloat3Float3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xed0f2d796b47dfb2l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testAtanpiFloat3Float3(inV, out);
+            verifyResultsAtanpiFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanpiFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testAtanpiFloat3Float3(inV, out);
+            verifyResultsAtanpiFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanpiFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAtanpiFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeAtanpi(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkAtanpiFloat3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkAtanpiFloat4Float4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xed10f69461630090l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testAtanpiFloat4Float4(inV, out);
+            verifyResultsAtanpiFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanpiFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testAtanpiFloat4Float4(inV, out);
+            verifyResultsAtanpiFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanpiFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAtanpiFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeAtanpi(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkAtanpiFloat4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testAtanpi() {
+        checkAtanpiFloatFloat();
+        checkAtanpiFloat2Float2();
+        checkAtanpiFloat3Float3();
+        checkAtanpiFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestCbrt.java b/tests/tests/renderscript/src/android/renderscript/cts/TestCbrt.java
new file mode 100644
index 0000000..5c364d5
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestCbrt.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestCbrt extends RSBaseCompute {
+
+    private ScriptC_TestCbrt script;
+    private ScriptC_TestCbrtRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestCbrt(mRS);
+        scriptRelaxed = new ScriptC_TestCbrtRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float in;
+        public Floaty out;
+    }
+
+    private void checkCbrtFloatFloat() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x4e2c540726cc677al, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testCbrtFloatFloat(in, out);
+            verifyResultsCbrtFloatFloat(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCbrtFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testCbrtFloatFloat(in, out);
+            verifyResultsCbrtFloatFloat(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCbrtFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCbrtFloatFloat(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 1];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeCbrt(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkCbrtFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkCbrtFloat2Float2() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x9e2a09a2eb8fdb46l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testCbrtFloat2Float2(in, out);
+            verifyResultsCbrtFloat2Float2(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCbrtFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testCbrtFloat2Float2(in, out);
+            verifyResultsCbrtFloat2Float2(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCbrtFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCbrtFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 2];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeCbrt(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkCbrtFloat2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkCbrtFloat3Float3() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x9e2a14444a9670e0l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testCbrtFloat3Float3(in, out);
+            verifyResultsCbrtFloat3Float3(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCbrtFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testCbrtFloat3Float3(in, out);
+            verifyResultsCbrtFloat3Float3(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCbrtFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCbrtFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeCbrt(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkCbrtFloat3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkCbrtFloat4Float4() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x9e2a1ee5a99d067al, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testCbrtFloat4Float4(in, out);
+            verifyResultsCbrtFloat4Float4(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCbrtFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testCbrtFloat4Float4(in, out);
+            verifyResultsCbrtFloat4Float4(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCbrtFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCbrtFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeCbrt(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkCbrtFloat4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testCbrt() {
+        checkCbrtFloatFloat();
+        checkCbrtFloat2Float2();
+        checkCbrtFloat3Float3();
+        checkCbrtFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestCeil.java b/tests/tests/renderscript/src/android/renderscript/cts/TestCeil.java
new file mode 100644
index 0000000..d14de2b
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestCeil.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestCeil extends RSBaseCompute {
+
+    private ScriptC_TestCeil script;
+    private ScriptC_TestCeilRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestCeil(mRS);
+        scriptRelaxed = new ScriptC_TestCeilRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float in;
+        public Floaty out;
+    }
+
+    private void checkCeilFloatFloat() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xa65a49d160f51d9al, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testCeilFloatFloat(in, out);
+            verifyResultsCeilFloatFloat(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCeilFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testCeilFloatFloat(in, out);
+            verifyResultsCeilFloatFloat(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCeilFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCeilFloatFloat(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 1];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeCeil(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkCeilFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkCeilFloat2Float2() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x821e4b40fb9b4866l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testCeilFloat2Float2(in, out);
+            verifyResultsCeilFloat2Float2(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCeilFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testCeilFloat2Float2(in, out);
+            verifyResultsCeilFloat2Float2(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCeilFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCeilFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 2];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeCeil(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkCeilFloat2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkCeilFloat3Float3() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x821e55e25aa1de00l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testCeilFloat3Float3(in, out);
+            verifyResultsCeilFloat3Float3(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCeilFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testCeilFloat3Float3(in, out);
+            verifyResultsCeilFloat3Float3(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCeilFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCeilFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeCeil(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkCeilFloat3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkCeilFloat4Float4() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x821e6083b9a8739al, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testCeilFloat4Float4(in, out);
+            verifyResultsCeilFloat4Float4(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCeilFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testCeilFloat4Float4(in, out);
+            verifyResultsCeilFloat4Float4(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCeilFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCeilFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeCeil(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkCeilFloat4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testCeil() {
+        checkCeilFloatFloat();
+        checkCeilFloat2Float2();
+        checkCeilFloat3Float3();
+        checkCeilFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestClamp.java b/tests/tests/renderscript/src/android/renderscript/cts/TestClamp.java
new file mode 100644
index 0000000..8e11182
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestClamp.java
@@ -0,0 +1,3889 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestClamp extends RSBaseCompute {
+
+    private ScriptC_TestClamp script;
+    private ScriptC_TestClampRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestClamp(mRS);
+        scriptRelaxed = new ScriptC_TestClampRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloatFloatFloat {
+        public float inValue;
+        public float inMinValue;
+        public float inMaxValue;
+        public Floaty out;
+    }
+
+    private void checkClampFloatFloatFloatFloat() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x7e886d7cc83c447dl, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xdcebf6f230234027l, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xdcebf6e6c180322dl, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampFloatFloatFloatFloat(inValue, out);
+            verifyResultsClampFloatFloatFloatFloat(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampFloatFloatFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampFloatFloatFloatFloat(inValue, out);
+            verifyResultsClampFloatFloatFloatFloat(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampFloatFloatFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampFloatFloatFloatFloat(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        float[] arrayInValue = new float[INPUTSIZE * 1];
+        inValue.copyTo(arrayInValue);
+        float[] arrayInMinValue = new float[INPUTSIZE * 1];
+        inMinValue.copyTo(arrayInMinValue);
+        float[] arrayInMaxValue = new float[INPUTSIZE * 1];
+        inMaxValue.copyTo(arrayInMaxValue);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
+                args.inValue = arrayInValue[i];
+                args.inMinValue = arrayInMinValue[i];
+                args.inMaxValue = arrayInMaxValue[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClamp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inValue, Float.floatToRawIntBits(args.inValue), args.inValue));
+                    message.append("\n");
+                    message.append("Input inMinValue: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inMinValue, Float.floatToRawIntBits(args.inMinValue), args.inMinValue));
+                    message.append("\n");
+                    message.append("Input inMaxValue: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inMaxValue, Float.floatToRawIntBits(args.inMaxValue), args.inMaxValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClampFloatFloatFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkClampFloat2Float2Float2Float2() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xa0d28bf142b07a5l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xb4e5c5f6ea8fc01fl, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xb4e5c5eb7becb225l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampFloat2Float2Float2Float2(inValue, out);
+            verifyResultsClampFloat2Float2Float2Float2(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampFloat2Float2Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampFloat2Float2Float2Float2(inValue, out);
+            verifyResultsClampFloat2Float2Float2Float2(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampFloat2Float2Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampFloat2Float2Float2Float2(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        float[] arrayInValue = new float[INPUTSIZE * 2];
+        inValue.copyTo(arrayInValue);
+        float[] arrayInMinValue = new float[INPUTSIZE * 2];
+        inMinValue.copyTo(arrayInMinValue);
+        float[] arrayInMaxValue = new float[INPUTSIZE * 2];
+        inMaxValue.copyTo(arrayInMaxValue);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
+                args.inValue = arrayInValue[i * 2 + j];
+                args.inMinValue = arrayInMinValue[i * 2 + j];
+                args.inMaxValue = arrayInMaxValue[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClamp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inValue, Float.floatToRawIntBits(args.inValue), args.inValue));
+                    message.append("\n");
+                    message.append("Input inMinValue: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inMinValue, Float.floatToRawIntBits(args.inMinValue), args.inMinValue));
+                    message.append("\n");
+                    message.append("Input inMaxValue: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inMaxValue, Float.floatToRawIntBits(args.inMaxValue), args.inMaxValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClampFloat2Float2Float2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkClampFloat3Float3Float3Float3() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xd3716a4730ad7481l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xc0d239a53946aa73l, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xc0d23999caa39c79l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampFloat3Float3Float3Float3(inValue, out);
+            verifyResultsClampFloat3Float3Float3Float3(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampFloat3Float3Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampFloat3Float3Float3Float3(inValue, out);
+            verifyResultsClampFloat3Float3Float3Float3(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampFloat3Float3Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampFloat3Float3Float3Float3(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        float[] arrayInValue = new float[INPUTSIZE * 4];
+        inValue.copyTo(arrayInValue);
+        float[] arrayInMinValue = new float[INPUTSIZE * 4];
+        inMinValue.copyTo(arrayInMinValue);
+        float[] arrayInMaxValue = new float[INPUTSIZE * 4];
+        inMaxValue.copyTo(arrayInMaxValue);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inMinValue = arrayInMinValue[i * 4 + j];
+                args.inMaxValue = arrayInMaxValue[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClamp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inValue, Float.floatToRawIntBits(args.inValue), args.inValue));
+                    message.append("\n");
+                    message.append("Input inMinValue: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inMinValue, Float.floatToRawIntBits(args.inMinValue), args.inMinValue));
+                    message.append("\n");
+                    message.append("Input inMaxValue: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inMaxValue, Float.floatToRawIntBits(args.inMaxValue), args.inMaxValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClampFloat3Float3Float3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkClampFloat4Float4Float4Float4() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x9cd5abcf4d2fe15dl, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xccbead5387fd94c7l, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xccbead48195a86cdl, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampFloat4Float4Float4Float4(inValue, out);
+            verifyResultsClampFloat4Float4Float4Float4(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampFloat4Float4Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampFloat4Float4Float4Float4(inValue, out);
+            verifyResultsClampFloat4Float4Float4Float4(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampFloat4Float4Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampFloat4Float4Float4Float4(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        float[] arrayInValue = new float[INPUTSIZE * 4];
+        inValue.copyTo(arrayInValue);
+        float[] arrayInMinValue = new float[INPUTSIZE * 4];
+        inMinValue.copyTo(arrayInMinValue);
+        float[] arrayInMaxValue = new float[INPUTSIZE * 4];
+        inMaxValue.copyTo(arrayInMaxValue);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inMinValue = arrayInMinValue[i * 4 + j];
+                args.inMaxValue = arrayInMaxValue[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClamp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inValue, Float.floatToRawIntBits(args.inValue), args.inValue));
+                    message.append("\n");
+                    message.append("Input inMinValue: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inMinValue, Float.floatToRawIntBits(args.inMinValue), args.inMinValue));
+                    message.append("\n");
+                    message.append("Input inMaxValue: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inMaxValue, Float.floatToRawIntBits(args.inMaxValue), args.inMaxValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClampFloat4Float4Float4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkClampFloat2FloatFloatFloat2() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x71623fb3f1fca1a1l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x148e792e1a6253d3l, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x148e7922abbf45d9l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampFloat2FloatFloatFloat2(inValue, out);
+            verifyResultsClampFloat2FloatFloatFloat2(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampFloat2FloatFloatFloat2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampFloat2FloatFloatFloat2(inValue, out);
+            verifyResultsClampFloat2FloatFloatFloat2(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampFloat2FloatFloatFloat2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampFloat2FloatFloatFloat2(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        float[] arrayInValue = new float[INPUTSIZE * 2];
+        inValue.copyTo(arrayInValue);
+        float[] arrayInMinValue = new float[INPUTSIZE * 1];
+        inMinValue.copyTo(arrayInMinValue);
+        float[] arrayInMaxValue = new float[INPUTSIZE * 1];
+        inMaxValue.copyTo(arrayInMaxValue);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
+                args.inValue = arrayInValue[i * 2 + j];
+                args.inMinValue = arrayInMinValue[i];
+                args.inMaxValue = arrayInMaxValue[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClamp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inValue, Float.floatToRawIntBits(args.inValue), args.inValue));
+                    message.append("\n");
+                    message.append("Input inMinValue: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inMinValue, Float.floatToRawIntBits(args.inMinValue), args.inMinValue));
+                    message.append("\n");
+                    message.append("Input inMaxValue: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inMaxValue, Float.floatToRawIntBits(args.inMaxValue), args.inMaxValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClampFloat2FloatFloatFloat2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkClampFloat3FloatFloatFloat3() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xc06893ff6ab8cf27l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x1f4444b84d90bbc5l, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x1f4444acdeedadcbl, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampFloat3FloatFloatFloat3(inValue, out);
+            verifyResultsClampFloat3FloatFloatFloat3(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampFloat3FloatFloatFloat3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampFloat3FloatFloatFloat3(inValue, out);
+            verifyResultsClampFloat3FloatFloatFloat3(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampFloat3FloatFloatFloat3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampFloat3FloatFloatFloat3(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        float[] arrayInValue = new float[INPUTSIZE * 4];
+        inValue.copyTo(arrayInValue);
+        float[] arrayInMinValue = new float[INPUTSIZE * 1];
+        inMinValue.copyTo(arrayInMinValue);
+        float[] arrayInMaxValue = new float[INPUTSIZE * 1];
+        inMaxValue.copyTo(arrayInMaxValue);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inMinValue = arrayInMinValue[i];
+                args.inMaxValue = arrayInMaxValue[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClamp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inValue, Float.floatToRawIntBits(args.inValue), args.inValue));
+                    message.append("\n");
+                    message.append("Input inMinValue: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inMinValue, Float.floatToRawIntBits(args.inMinValue), args.inMinValue));
+                    message.append("\n");
+                    message.append("Input inMaxValue: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inMaxValue, Float.floatToRawIntBits(args.inMaxValue), args.inMaxValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClampFloat3FloatFloatFloat3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkClampFloat4FloatFloatFloat4() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xf6ee84ae374fcadl, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x29fa104280bf23b7l, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x29fa1037121c15bdl, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampFloat4FloatFloatFloat4(inValue, out);
+            verifyResultsClampFloat4FloatFloatFloat4(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampFloat4FloatFloatFloat4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampFloat4FloatFloatFloat4(inValue, out);
+            verifyResultsClampFloat4FloatFloatFloat4(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampFloat4FloatFloatFloat4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampFloat4FloatFloatFloat4(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        float[] arrayInValue = new float[INPUTSIZE * 4];
+        inValue.copyTo(arrayInValue);
+        float[] arrayInMinValue = new float[INPUTSIZE * 1];
+        inMinValue.copyTo(arrayInMinValue);
+        float[] arrayInMaxValue = new float[INPUTSIZE * 1];
+        inMaxValue.copyTo(arrayInMaxValue);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inMinValue = arrayInMinValue[i];
+                args.inMaxValue = arrayInMaxValue[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClamp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inValue, Float.floatToRawIntBits(args.inValue), args.inValue));
+                    message.append("\n");
+                    message.append("Input inMinValue: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inMinValue, Float.floatToRawIntBits(args.inMinValue), args.inMinValue));
+                    message.append("\n");
+                    message.append("Input inMaxValue: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inMaxValue, Float.floatToRawIntBits(args.inMaxValue), args.inMaxValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClampFloat4FloatFloatFloat4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsCharCharCharChar {
+        public byte inValue;
+        public byte inMinValue;
+        public byte inMaxValue;
+        public byte out;
+    }
+
+    private void checkClampCharCharCharChar() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 1, 0xaec8640bb673cf75l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 1, 0x6379f7c3c505c8fl, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 1, 0x6379f70cdad4e95l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 1), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampCharCharCharChar(inValue, out);
+            verifyResultsClampCharCharCharChar(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampCharCharCharChar: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampCharCharCharChar(inValue, out);
+            verifyResultsClampCharCharCharChar(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampCharCharCharChar: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampCharCharCharChar(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        byte[] arrayInValue = new byte[INPUTSIZE * 1];
+        inValue.copyTo(arrayInValue);
+        byte[] arrayInMinValue = new byte[INPUTSIZE * 1];
+        inMinValue.copyTo(arrayInMinValue);
+        byte[] arrayInMaxValue = new byte[INPUTSIZE * 1];
+        inMaxValue.copyTo(arrayInMaxValue);
+        byte[] arrayOut = new byte[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsCharCharCharChar args = new ArgumentsCharCharCharChar();
+                args.inValue = arrayInValue[i];
+                args.inMinValue = arrayInMinValue[i];
+                args.inMaxValue = arrayInMaxValue[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClamp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 1 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("%d", args.inValue));
+                    message.append("\n");
+                    message.append("Input inMinValue: ");
+                    message.append(String.format("%d", args.inMinValue));
+                    message.append("\n");
+                    message.append("Input inMaxValue: ");
+                    message.append(String.format("%d", args.inMaxValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 1 + j]));
+                    if (args.out != arrayOut[i * 1 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClampCharCharCharChar" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkClampChar2Char2Char2Char2() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 2, 0xa209cfe6c3feb45dl, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 2, 0xed63d0ab3442bdc7l, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 2, 0xed63d09fc59fafcdl, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampChar2Char2Char2Char2(inValue, out);
+            verifyResultsClampChar2Char2Char2Char2(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampChar2Char2Char2Char2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampChar2Char2Char2Char2(inValue, out);
+            verifyResultsClampChar2Char2Char2Char2(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampChar2Char2Char2Char2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampChar2Char2Char2Char2(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        byte[] arrayInValue = new byte[INPUTSIZE * 2];
+        inValue.copyTo(arrayInValue);
+        byte[] arrayInMinValue = new byte[INPUTSIZE * 2];
+        inMinValue.copyTo(arrayInMinValue);
+        byte[] arrayInMaxValue = new byte[INPUTSIZE * 2];
+        inMaxValue.copyTo(arrayInMaxValue);
+        byte[] arrayOut = new byte[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsCharCharCharChar args = new ArgumentsCharCharCharChar();
+                args.inValue = arrayInValue[i * 2 + j];
+                args.inMinValue = arrayInMinValue[i * 2 + j];
+                args.inMaxValue = arrayInMaxValue[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClamp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("%d", args.inValue));
+                    message.append("\n");
+                    message.append("Input inMinValue: ");
+                    message.append(String.format("%d", args.inMinValue));
+                    message.append("\n");
+                    message.append("Input inMaxValue: ");
+                    message.append(String.format("%d", args.inMaxValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClampChar2Char2Char2Char2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkClampChar3Char3Char3Char3() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 3, 0xfab6edb7b9d3b0a5l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 3, 0x7ae6f958470ecb1fl, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 3, 0x7ae6f94cd86bbd25l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampChar3Char3Char3Char3(inValue, out);
+            verifyResultsClampChar3Char3Char3Char3(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampChar3Char3Char3Char3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampChar3Char3Char3Char3(inValue, out);
+            verifyResultsClampChar3Char3Char3Char3(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampChar3Char3Char3Char3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampChar3Char3Char3Char3(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        byte[] arrayInValue = new byte[INPUTSIZE * 4];
+        inValue.copyTo(arrayInValue);
+        byte[] arrayInMinValue = new byte[INPUTSIZE * 4];
+        inMinValue.copyTo(arrayInMinValue);
+        byte[] arrayInMaxValue = new byte[INPUTSIZE * 4];
+        inMaxValue.copyTo(arrayInMaxValue);
+        byte[] arrayOut = new byte[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsCharCharCharChar args = new ArgumentsCharCharCharChar();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inMinValue = arrayInMinValue[i * 4 + j];
+                args.inMaxValue = arrayInMaxValue[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClamp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("%d", args.inValue));
+                    message.append("\n");
+                    message.append("Input inMinValue: ");
+                    message.append(String.format("%d", args.inMinValue));
+                    message.append("\n");
+                    message.append("Input inMaxValue: ");
+                    message.append(String.format("%d", args.inMaxValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClampChar3Char3Char3Char3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkClampChar4Char4Char4Char4() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 4, 0x53640b88afa8acedl, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 4, 0x86a220559dad877l, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 4, 0x86a21f9eb37ca7dl, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampChar4Char4Char4Char4(inValue, out);
+            verifyResultsClampChar4Char4Char4Char4(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampChar4Char4Char4Char4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampChar4Char4Char4Char4(inValue, out);
+            verifyResultsClampChar4Char4Char4Char4(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampChar4Char4Char4Char4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampChar4Char4Char4Char4(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        byte[] arrayInValue = new byte[INPUTSIZE * 4];
+        inValue.copyTo(arrayInValue);
+        byte[] arrayInMinValue = new byte[INPUTSIZE * 4];
+        inMinValue.copyTo(arrayInMinValue);
+        byte[] arrayInMaxValue = new byte[INPUTSIZE * 4];
+        inMaxValue.copyTo(arrayInMaxValue);
+        byte[] arrayOut = new byte[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsCharCharCharChar args = new ArgumentsCharCharCharChar();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inMinValue = arrayInMinValue[i * 4 + j];
+                args.inMaxValue = arrayInMaxValue[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClamp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("%d", args.inValue));
+                    message.append("\n");
+                    message.append("Input inMinValue: ");
+                    message.append(String.format("%d", args.inMinValue));
+                    message.append("\n");
+                    message.append("Input inMaxValue: ");
+                    message.append(String.format("%d", args.inMaxValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClampChar4Char4Char4Char4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsUcharUcharUcharUchar {
+        public byte inValue;
+        public byte inMinValue;
+        public byte inMaxValue;
+        public byte out;
+    }
+
+    private void checkClampUcharUcharUcharUchar() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 1, 0x680c818a4447655l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 1, 0xae40bae375336f2fl, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 1, 0xae40bad806906135l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 1), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampUcharUcharUcharUchar(inValue, out);
+            verifyResultsClampUcharUcharUcharUchar(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUcharUcharUcharUchar: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampUcharUcharUcharUchar(inValue, out);
+            verifyResultsClampUcharUcharUcharUchar(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUcharUcharUcharUchar: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampUcharUcharUcharUchar(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        byte[] arrayInValue = new byte[INPUTSIZE * 1];
+        inValue.copyTo(arrayInValue);
+        byte[] arrayInMinValue = new byte[INPUTSIZE * 1];
+        inMinValue.copyTo(arrayInMinValue);
+        byte[] arrayInMaxValue = new byte[INPUTSIZE * 1];
+        inMaxValue.copyTo(arrayInMaxValue);
+        byte[] arrayOut = new byte[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsUcharUcharUcharUchar args = new ArgumentsUcharUcharUcharUchar();
+                args.inValue = arrayInValue[i];
+                args.inMinValue = arrayInMinValue[i];
+                args.inMaxValue = arrayInMaxValue[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClamp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 1 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("0x%x", args.inValue));
+                    message.append("\n");
+                    message.append("Input inMinValue: ");
+                    message.append(String.format("0x%x", args.inMinValue));
+                    message.append("\n");
+                    message.append("Input inMaxValue: ");
+                    message.append(String.format("0x%x", args.inMaxValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 1 + j]));
+                    if (args.out != arrayOut[i * 1 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClampUcharUcharUcharUchar" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkClampUchar2Uchar2Uchar2Uchar2() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 2, 0xd69df43245dae301l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 2, 0x82681747662c1df3l, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 2, 0x8268173bf7890ff9l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampUchar2Uchar2Uchar2Uchar2(inValue, out);
+            verifyResultsClampUchar2Uchar2Uchar2Uchar2(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUchar2Uchar2Uchar2Uchar2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampUchar2Uchar2Uchar2Uchar2(inValue, out);
+            verifyResultsClampUchar2Uchar2Uchar2Uchar2(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUchar2Uchar2Uchar2Uchar2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampUchar2Uchar2Uchar2Uchar2(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        byte[] arrayInValue = new byte[INPUTSIZE * 2];
+        inValue.copyTo(arrayInValue);
+        byte[] arrayInMinValue = new byte[INPUTSIZE * 2];
+        inMinValue.copyTo(arrayInMinValue);
+        byte[] arrayInMaxValue = new byte[INPUTSIZE * 2];
+        inMaxValue.copyTo(arrayInMaxValue);
+        byte[] arrayOut = new byte[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsUcharUcharUcharUchar args = new ArgumentsUcharUcharUcharUchar();
+                args.inValue = arrayInValue[i * 2 + j];
+                args.inMinValue = arrayInMinValue[i * 2 + j];
+                args.inMaxValue = arrayInMaxValue[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClamp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("0x%x", args.inValue));
+                    message.append("\n");
+                    message.append("Input inMinValue: ");
+                    message.append(String.format("0x%x", args.inMinValue));
+                    message.append("\n");
+                    message.append("Input inMaxValue: ");
+                    message.append(String.format("0x%x", args.inMaxValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClampUchar2Uchar2Uchar2Uchar2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkClampUchar3Uchar3Uchar3Uchar3() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 3, 0xa00235ba625d4fddl, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 3, 0x8e548af5b4e30847l, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 3, 0x8e548aea463ffa4dl, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampUchar3Uchar3Uchar3Uchar3(inValue, out);
+            verifyResultsClampUchar3Uchar3Uchar3Uchar3(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUchar3Uchar3Uchar3Uchar3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampUchar3Uchar3Uchar3Uchar3(inValue, out);
+            verifyResultsClampUchar3Uchar3Uchar3Uchar3(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUchar3Uchar3Uchar3Uchar3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampUchar3Uchar3Uchar3Uchar3(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        byte[] arrayInValue = new byte[INPUTSIZE * 4];
+        inValue.copyTo(arrayInValue);
+        byte[] arrayInMinValue = new byte[INPUTSIZE * 4];
+        inMinValue.copyTo(arrayInMinValue);
+        byte[] arrayInMaxValue = new byte[INPUTSIZE * 4];
+        inMaxValue.copyTo(arrayInMaxValue);
+        byte[] arrayOut = new byte[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsUcharUcharUcharUchar args = new ArgumentsUcharUcharUcharUchar();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inMinValue = arrayInMinValue[i * 4 + j];
+                args.inMaxValue = arrayInMaxValue[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClamp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("0x%x", args.inValue));
+                    message.append("\n");
+                    message.append("Input inMinValue: ");
+                    message.append(String.format("0x%x", args.inMinValue));
+                    message.append("\n");
+                    message.append("Input inMaxValue: ");
+                    message.append(String.format("0x%x", args.inMaxValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClampUchar3Uchar3Uchar3Uchar3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkClampUchar4Uchar4Uchar4Uchar4() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 4, 0x696677427edfbcb9l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 4, 0x9a40fea40399f29bl, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 4, 0x9a40fe9894f6e4a1l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampUchar4Uchar4Uchar4Uchar4(inValue, out);
+            verifyResultsClampUchar4Uchar4Uchar4Uchar4(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUchar4Uchar4Uchar4Uchar4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampUchar4Uchar4Uchar4Uchar4(inValue, out);
+            verifyResultsClampUchar4Uchar4Uchar4Uchar4(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUchar4Uchar4Uchar4Uchar4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampUchar4Uchar4Uchar4Uchar4(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        byte[] arrayInValue = new byte[INPUTSIZE * 4];
+        inValue.copyTo(arrayInValue);
+        byte[] arrayInMinValue = new byte[INPUTSIZE * 4];
+        inMinValue.copyTo(arrayInMinValue);
+        byte[] arrayInMaxValue = new byte[INPUTSIZE * 4];
+        inMaxValue.copyTo(arrayInMaxValue);
+        byte[] arrayOut = new byte[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsUcharUcharUcharUchar args = new ArgumentsUcharUcharUcharUchar();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inMinValue = arrayInMinValue[i * 4 + j];
+                args.inMaxValue = arrayInMaxValue[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClamp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("0x%x", args.inValue));
+                    message.append("\n");
+                    message.append("Input inMinValue: ");
+                    message.append(String.format("0x%x", args.inMinValue));
+                    message.append("\n");
+                    message.append("Input inMaxValue: ");
+                    message.append(String.format("0x%x", args.inMaxValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClampUchar4Uchar4Uchar4Uchar4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsShortShortShortShort {
+        public short inValue;
+        public short inMinValue;
+        public short inMaxValue;
+        public short out;
+    }
+
+    private void checkClampShortShortShortShort() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 1, 0x8035c0627fc993ddl, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 1, 0xb5d4bd1fb4661447l, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 1, 0xb5d4bd1445c3064dl, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 1), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampShortShortShortShort(inValue, out);
+            verifyResultsClampShortShortShortShort(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampShortShortShortShort: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampShortShortShortShort(inValue, out);
+            verifyResultsClampShortShortShortShort(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampShortShortShortShort: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampShortShortShortShort(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        short[] arrayInValue = new short[INPUTSIZE * 1];
+        inValue.copyTo(arrayInValue);
+        short[] arrayInMinValue = new short[INPUTSIZE * 1];
+        inMinValue.copyTo(arrayInMinValue);
+        short[] arrayInMaxValue = new short[INPUTSIZE * 1];
+        inMaxValue.copyTo(arrayInMaxValue);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsShortShortShortShort args = new ArgumentsShortShortShortShort();
+                args.inValue = arrayInValue[i];
+                args.inMinValue = arrayInMinValue[i];
+                args.inMaxValue = arrayInMaxValue[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClamp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 1 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("%d", args.inValue));
+                    message.append("\n");
+                    message.append("Input inMinValue: ");
+                    message.append(String.format("%d", args.inMinValue));
+                    message.append("\n");
+                    message.append("Input inMaxValue: ");
+                    message.append(String.format("%d", args.inMaxValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 1 + j]));
+                    if (args.out != arrayOut[i * 1 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClampShortShortShortShort" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkClampShort2Short2Short2Short2() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 2, 0x7eab8e9b984e0915l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 2, 0x7b334b992e67336fl, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 2, 0x7b334b8dbfc42575l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampShort2Short2Short2Short2(inValue, out);
+            verifyResultsClampShort2Short2Short2Short2(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampShort2Short2Short2Short2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampShort2Short2Short2Short2(inValue, out);
+            verifyResultsClampShort2Short2Short2Short2(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampShort2Short2Short2Short2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampShort2Short2Short2Short2(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        short[] arrayInValue = new short[INPUTSIZE * 2];
+        inValue.copyTo(arrayInValue);
+        short[] arrayInMinValue = new short[INPUTSIZE * 2];
+        inMinValue.copyTo(arrayInMinValue);
+        short[] arrayInMaxValue = new short[INPUTSIZE * 2];
+        inMaxValue.copyTo(arrayInMaxValue);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsShortShortShortShort args = new ArgumentsShortShortShortShort();
+                args.inValue = arrayInValue[i * 2 + j];
+                args.inMinValue = arrayInMinValue[i * 2 + j];
+                args.inMaxValue = arrayInMaxValue[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClamp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("%d", args.inValue));
+                    message.append("\n");
+                    message.append("Input inMinValue: ");
+                    message.append(String.format("%d", args.inMinValue));
+                    message.append("\n");
+                    message.append("Input inMaxValue: ");
+                    message.append(String.format("%d", args.inMaxValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClampShort2Short2Short2Short2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkClampShort3Short3Short3Short3() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 3, 0x480fd023b4d075f1l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 3, 0x871fbf477d1e1dc3l, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 3, 0x871fbf3c0e7b0fc9l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampShort3Short3Short3Short3(inValue, out);
+            verifyResultsClampShort3Short3Short3Short3(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampShort3Short3Short3Short3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampShort3Short3Short3Short3(inValue, out);
+            verifyResultsClampShort3Short3Short3Short3(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampShort3Short3Short3Short3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampShort3Short3Short3Short3(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        short[] arrayInValue = new short[INPUTSIZE * 4];
+        inValue.copyTo(arrayInValue);
+        short[] arrayInMinValue = new short[INPUTSIZE * 4];
+        inMinValue.copyTo(arrayInMinValue);
+        short[] arrayInMaxValue = new short[INPUTSIZE * 4];
+        inMaxValue.copyTo(arrayInMaxValue);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsShortShortShortShort args = new ArgumentsShortShortShortShort();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inMinValue = arrayInMinValue[i * 4 + j];
+                args.inMaxValue = arrayInMaxValue[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClamp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("%d", args.inValue));
+                    message.append("\n");
+                    message.append("Input inMinValue: ");
+                    message.append(String.format("%d", args.inMinValue));
+                    message.append("\n");
+                    message.append("Input inMaxValue: ");
+                    message.append(String.format("%d", args.inMaxValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClampShort3Short3Short3Short3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkClampShort4Short4Short4Short4() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 4, 0x117411abd152e2cdl, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 4, 0x930c32f5cbd50817l, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 4, 0x930c32ea5d31fa1dl, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampShort4Short4Short4Short4(inValue, out);
+            verifyResultsClampShort4Short4Short4Short4(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampShort4Short4Short4Short4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampShort4Short4Short4Short4(inValue, out);
+            verifyResultsClampShort4Short4Short4Short4(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampShort4Short4Short4Short4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampShort4Short4Short4Short4(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        short[] arrayInValue = new short[INPUTSIZE * 4];
+        inValue.copyTo(arrayInValue);
+        short[] arrayInMinValue = new short[INPUTSIZE * 4];
+        inMinValue.copyTo(arrayInMinValue);
+        short[] arrayInMaxValue = new short[INPUTSIZE * 4];
+        inMaxValue.copyTo(arrayInMaxValue);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsShortShortShortShort args = new ArgumentsShortShortShortShort();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inMinValue = arrayInMinValue[i * 4 + j];
+                args.inMaxValue = arrayInMaxValue[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClamp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("%d", args.inValue));
+                    message.append("\n");
+                    message.append("Input inMinValue: ");
+                    message.append(String.format("%d", args.inMinValue));
+                    message.append("\n");
+                    message.append("Input inMaxValue: ");
+                    message.append(String.format("%d", args.inMaxValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClampShort4Short4Short4Short4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsUshortUshortUshortUshort {
+        public short inValue;
+        public short inMinValue;
+        public short inMaxValue;
+        public short out;
+    }
+
+    private void checkClampUshortUshortUshortUshort() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 1, 0xf5881eeff74c4341l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 1, 0xd2a0571394d3e2b3l, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 1, 0xd2a057082630d4b9l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 1), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampUshortUshortUshortUshort(inValue, out);
+            verifyResultsClampUshortUshortUshortUshort(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUshortUshortUshortUshort: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampUshortUshortUshortUshort(inValue, out);
+            verifyResultsClampUshortUshortUshortUshort(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUshortUshortUshortUshort: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampUshortUshortUshortUshort(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        short[] arrayInValue = new short[INPUTSIZE * 1];
+        inValue.copyTo(arrayInValue);
+        short[] arrayInMinValue = new short[INPUTSIZE * 1];
+        inMinValue.copyTo(arrayInMinValue);
+        short[] arrayInMaxValue = new short[INPUTSIZE * 1];
+        inMaxValue.copyTo(arrayInMaxValue);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsUshortUshortUshortUshort args = new ArgumentsUshortUshortUshortUshort();
+                args.inValue = arrayInValue[i];
+                args.inMinValue = arrayInMinValue[i];
+                args.inMaxValue = arrayInMaxValue[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClamp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 1 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("0x%x", args.inValue));
+                    message.append("\n");
+                    message.append("Input inMinValue: ");
+                    message.append(String.format("0x%x", args.inMinValue));
+                    message.append("\n");
+                    message.append("Input inMaxValue: ");
+                    message.append(String.format("0x%x", args.inMaxValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 1 + j]));
+                    if (args.out != arrayOut[i * 1 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClampUshortUshortUshortUshort" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkClampUshort2Ushort2Ushort2Ushort2() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 2, 0x6441dbe2fc36b705l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 2, 0x52161e934fa3b43fl, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 2, 0x52161e87e100a645l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampUshort2Ushort2Ushort2Ushort2(inValue, out);
+            verifyResultsClampUshort2Ushort2Ushort2Ushort2(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUshort2Ushort2Ushort2Ushort2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampUshort2Ushort2Ushort2Ushort2(inValue, out);
+            verifyResultsClampUshort2Ushort2Ushort2Ushort2(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUshort2Ushort2Ushort2Ushort2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampUshort2Ushort2Ushort2Ushort2(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        short[] arrayInValue = new short[INPUTSIZE * 2];
+        inValue.copyTo(arrayInValue);
+        short[] arrayInMinValue = new short[INPUTSIZE * 2];
+        inMinValue.copyTo(arrayInMinValue);
+        short[] arrayInMaxValue = new short[INPUTSIZE * 2];
+        inMaxValue.copyTo(arrayInMaxValue);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsUshortUshortUshortUshort args = new ArgumentsUshortUshortUshortUshort();
+                args.inValue = arrayInValue[i * 2 + j];
+                args.inMinValue = arrayInMinValue[i * 2 + j];
+                args.inMaxValue = arrayInMaxValue[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClamp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("0x%x", args.inValue));
+                    message.append("\n");
+                    message.append("Input inMinValue: ");
+                    message.append(String.format("0x%x", args.inMinValue));
+                    message.append("\n");
+                    message.append("Input inMaxValue: ");
+                    message.append(String.format("0x%x", args.inMaxValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClampUshort2Ushort2Ushort2Ushort2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkClampUshort3Ushort3Ushort3Ushort3() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 3, 0x6b244d61fc64ee3dl, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 3, 0x7b8d14b8610b3967l, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 3, 0x7b8d14acf2682b6dl, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampUshort3Ushort3Ushort3Ushort3(inValue, out);
+            verifyResultsClampUshort3Ushort3Ushort3Ushort3(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUshort3Ushort3Ushort3Ushort3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampUshort3Ushort3Ushort3Ushort3(inValue, out);
+            verifyResultsClampUshort3Ushort3Ushort3Ushort3(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUshort3Ushort3Ushort3Ushort3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampUshort3Ushort3Ushort3Ushort3(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        short[] arrayInValue = new short[INPUTSIZE * 4];
+        inValue.copyTo(arrayInValue);
+        short[] arrayInMinValue = new short[INPUTSIZE * 4];
+        inMinValue.copyTo(arrayInMinValue);
+        short[] arrayInMaxValue = new short[INPUTSIZE * 4];
+        inMaxValue.copyTo(arrayInMaxValue);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsUshortUshortUshortUshort args = new ArgumentsUshortUshortUshortUshort();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inMinValue = arrayInMinValue[i * 4 + j];
+                args.inMaxValue = arrayInMaxValue[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClamp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("0x%x", args.inValue));
+                    message.append("\n");
+                    message.append("Input inMinValue: ");
+                    message.append(String.format("0x%x", args.inMinValue));
+                    message.append("\n");
+                    message.append("Input inMaxValue: ");
+                    message.append(String.format("0x%x", args.inMaxValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClampUshort3Ushort3Ushort3Ushort3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkClampUshort4Ushort4Ushort4Ushort4() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 4, 0x7206bee0fc932575l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 4, 0xa5040add7272be8fl, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 4, 0xa5040ad203cfb095l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampUshort4Ushort4Ushort4Ushort4(inValue, out);
+            verifyResultsClampUshort4Ushort4Ushort4Ushort4(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUshort4Ushort4Ushort4Ushort4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampUshort4Ushort4Ushort4Ushort4(inValue, out);
+            verifyResultsClampUshort4Ushort4Ushort4Ushort4(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUshort4Ushort4Ushort4Ushort4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampUshort4Ushort4Ushort4Ushort4(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        short[] arrayInValue = new short[INPUTSIZE * 4];
+        inValue.copyTo(arrayInValue);
+        short[] arrayInMinValue = new short[INPUTSIZE * 4];
+        inMinValue.copyTo(arrayInMinValue);
+        short[] arrayInMaxValue = new short[INPUTSIZE * 4];
+        inMaxValue.copyTo(arrayInMaxValue);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsUshortUshortUshortUshort args = new ArgumentsUshortUshortUshortUshort();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inMinValue = arrayInMinValue[i * 4 + j];
+                args.inMaxValue = arrayInMaxValue[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClamp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("0x%x", args.inValue));
+                    message.append("\n");
+                    message.append("Input inMinValue: ");
+                    message.append(String.format("0x%x", args.inMinValue));
+                    message.append("\n");
+                    message.append("Input inMaxValue: ");
+                    message.append(String.format("0x%x", args.inMaxValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClampUshort4Ushort4Ushort4Ushort4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsIntIntIntInt {
+        public int inValue;
+        public int inMinValue;
+        public int inMaxValue;
+        public int out;
+    }
+
+    private void checkClampIntIntIntInt() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0xfeb3aa11be6164c5l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0xd11c228c7c8bf97fl, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0xd11c22810de8eb85l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 1), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampIntIntIntInt(inValue, out);
+            verifyResultsClampIntIntIntInt(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampIntIntIntInt: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampIntIntIntInt(inValue, out);
+            verifyResultsClampIntIntIntInt(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampIntIntIntInt: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampIntIntIntInt(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        int[] arrayInValue = new int[INPUTSIZE * 1];
+        inValue.copyTo(arrayInValue);
+        int[] arrayInMinValue = new int[INPUTSIZE * 1];
+        inMinValue.copyTo(arrayInMinValue);
+        int[] arrayInMaxValue = new int[INPUTSIZE * 1];
+        inMaxValue.copyTo(arrayInMaxValue);
+        int[] arrayOut = new int[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsIntIntIntInt args = new ArgumentsIntIntIntInt();
+                args.inValue = arrayInValue[i];
+                args.inMinValue = arrayInMinValue[i];
+                args.inMaxValue = arrayInMaxValue[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClamp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 1 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("%d", args.inValue));
+                    message.append("\n");
+                    message.append("Input inMinValue: ");
+                    message.append(String.format("%d", args.inMinValue));
+                    message.append("\n");
+                    message.append("Input inMaxValue: ");
+                    message.append(String.format("%d", args.inMaxValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 1 + j]));
+                    if (args.out != arrayOut[i * 1 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClampIntIntIntInt" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkClampInt2Int2Int2Int2() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 2, 0x56252903bd307c01l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 2, 0x770112109398f8f3l, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 2, 0x7701120524f5eaf9l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampInt2Int2Int2Int2(inValue, out);
+            verifyResultsClampInt2Int2Int2Int2(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampInt2Int2Int2Int2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampInt2Int2Int2Int2(inValue, out);
+            verifyResultsClampInt2Int2Int2Int2(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampInt2Int2Int2Int2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampInt2Int2Int2Int2(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        int[] arrayInValue = new int[INPUTSIZE * 2];
+        inValue.copyTo(arrayInValue);
+        int[] arrayInMinValue = new int[INPUTSIZE * 2];
+        inMinValue.copyTo(arrayInMinValue);
+        int[] arrayInMaxValue = new int[INPUTSIZE * 2];
+        inMaxValue.copyTo(arrayInMaxValue);
+        int[] arrayOut = new int[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsIntIntIntInt args = new ArgumentsIntIntIntInt();
+                args.inValue = arrayInValue[i * 2 + j];
+                args.inMinValue = arrayInMinValue[i * 2 + j];
+                args.inMaxValue = arrayInMaxValue[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClamp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("%d", args.inValue));
+                    message.append("\n");
+                    message.append("Input inMinValue: ");
+                    message.append(String.format("%d", args.inMinValue));
+                    message.append("\n");
+                    message.append("Input inMaxValue: ");
+                    message.append(String.format("%d", args.inMaxValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClampInt2Int2Int2Int2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkClampInt3Int3Int3Int3() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 3, 0x966882045600d2edl, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 3, 0xeb73e6749c7caa77l, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 3, 0xeb73e6692dd99c7dl, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampInt3Int3Int3Int3(inValue, out);
+            verifyResultsClampInt3Int3Int3Int3(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampInt3Int3Int3Int3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampInt3Int3Int3Int3(inValue, out);
+            verifyResultsClampInt3Int3Int3Int3(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampInt3Int3Int3Int3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampInt3Int3Int3Int3(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        int[] arrayInValue = new int[INPUTSIZE * 4];
+        inValue.copyTo(arrayInValue);
+        int[] arrayInMinValue = new int[INPUTSIZE * 4];
+        inMinValue.copyTo(arrayInMinValue);
+        int[] arrayInMaxValue = new int[INPUTSIZE * 4];
+        inMaxValue.copyTo(arrayInMaxValue);
+        int[] arrayOut = new int[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsIntIntIntInt args = new ArgumentsIntIntIntInt();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inMinValue = arrayInMinValue[i * 4 + j];
+                args.inMaxValue = arrayInMaxValue[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClamp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("%d", args.inValue));
+                    message.append("\n");
+                    message.append("Input inMinValue: ");
+                    message.append(String.format("%d", args.inMinValue));
+                    message.append("\n");
+                    message.append("Input inMaxValue: ");
+                    message.append(String.format("%d", args.inMaxValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClampInt3Int3Int3Int3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkClampInt4Int4Int4Int4() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 4, 0xd6abdb04eed129d9l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 4, 0x5fe6bad8a5605bfbl, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 4, 0x5fe6bacd36bd4e01l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampInt4Int4Int4Int4(inValue, out);
+            verifyResultsClampInt4Int4Int4Int4(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampInt4Int4Int4Int4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampInt4Int4Int4Int4(inValue, out);
+            verifyResultsClampInt4Int4Int4Int4(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampInt4Int4Int4Int4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampInt4Int4Int4Int4(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        int[] arrayInValue = new int[INPUTSIZE * 4];
+        inValue.copyTo(arrayInValue);
+        int[] arrayInMinValue = new int[INPUTSIZE * 4];
+        inMinValue.copyTo(arrayInMinValue);
+        int[] arrayInMaxValue = new int[INPUTSIZE * 4];
+        inMaxValue.copyTo(arrayInMaxValue);
+        int[] arrayOut = new int[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsIntIntIntInt args = new ArgumentsIntIntIntInt();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inMinValue = arrayInMinValue[i * 4 + j];
+                args.inMaxValue = arrayInMaxValue[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClamp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("%d", args.inValue));
+                    message.append("\n");
+                    message.append("Input inMinValue: ");
+                    message.append(String.format("%d", args.inMinValue));
+                    message.append("\n");
+                    message.append("Input inMaxValue: ");
+                    message.append(String.format("%d", args.inMaxValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClampInt4Int4Int4Int4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsUintUintUintUint {
+        public int inValue;
+        public int inMinValue;
+        public int inMaxValue;
+        public int out;
+    }
+
+    private void checkClampUintUintUintUint() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 1, 0xd8df32b2efc89475l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 1, 0xcf8ec8eece8b7b8fl, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 1, 0xcf8ec8e35fe86d95l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 1), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampUintUintUintUint(inValue, out);
+            verifyResultsClampUintUintUintUint(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUintUintUintUint: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampUintUintUintUint(inValue, out);
+            verifyResultsClampUintUintUintUint(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUintUintUintUint: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampUintUintUintUint(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        int[] arrayInValue = new int[INPUTSIZE * 1];
+        inValue.copyTo(arrayInValue);
+        int[] arrayInMinValue = new int[INPUTSIZE * 1];
+        inMinValue.copyTo(arrayInMinValue);
+        int[] arrayInMaxValue = new int[INPUTSIZE * 1];
+        inMaxValue.copyTo(arrayInMaxValue);
+        int[] arrayOut = new int[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsUintUintUintUint args = new ArgumentsUintUintUintUint();
+                args.inValue = arrayInValue[i];
+                args.inMinValue = arrayInMinValue[i];
+                args.inMaxValue = arrayInMaxValue[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClamp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 1 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("0x%x", args.inValue));
+                    message.append("\n");
+                    message.append("Input inMinValue: ");
+                    message.append(String.format("0x%x", args.inMinValue));
+                    message.append("\n");
+                    message.append("Input inMaxValue: ");
+                    message.append(String.format("0x%x", args.inMaxValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 1 + j]));
+                    if (args.out != arrayOut[i * 1 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClampUintUintUintUint" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkClampUint2Uint2Uint2Uint2() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 2, 0xaf28d478873ae5dl, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 2, 0x5bbd21aa2a4bc7l, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 2, 0x5bbd163b873dcdl, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampUint2Uint2Uint2Uint2(inValue, out);
+            verifyResultsClampUint2Uint2Uint2Uint2(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUint2Uint2Uint2Uint2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampUint2Uint2Uint2Uint2(inValue, out);
+            verifyResultsClampUint2Uint2Uint2Uint2(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUint2Uint2Uint2Uint2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampUint2Uint2Uint2Uint2(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        int[] arrayInValue = new int[INPUTSIZE * 2];
+        inValue.copyTo(arrayInValue);
+        int[] arrayInMinValue = new int[INPUTSIZE * 2];
+        inMinValue.copyTo(arrayInMinValue);
+        int[] arrayInMaxValue = new int[INPUTSIZE * 2];
+        inMaxValue.copyTo(arrayInMaxValue);
+        int[] arrayOut = new int[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsUintUintUintUint args = new ArgumentsUintUintUintUint();
+                args.inValue = arrayInValue[i * 2 + j];
+                args.inMinValue = arrayInMinValue[i * 2 + j];
+                args.inMaxValue = arrayInMaxValue[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClamp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("0x%x", args.inValue));
+                    message.append("\n");
+                    message.append("Input inMinValue: ");
+                    message.append(String.format("0x%x", args.inMinValue));
+                    message.append("\n");
+                    message.append("Input inMaxValue: ");
+                    message.append(String.format("0x%x", args.inMaxValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClampUint2Uint2Uint2Uint2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkClampUint3Uint3Uint3Uint3() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 3, 0x639fab187e48aaa5l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 3, 0x8ddee5cebcf6591fl, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 3, 0x8ddee5c34e534b25l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampUint3Uint3Uint3Uint3(inValue, out);
+            verifyResultsClampUint3Uint3Uint3Uint3(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUint3Uint3Uint3Uint3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampUint3Uint3Uint3Uint3(inValue, out);
+            verifyResultsClampUint3Uint3Uint3Uint3(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUint3Uint3Uint3Uint3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampUint3Uint3Uint3Uint3(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        int[] arrayInValue = new int[INPUTSIZE * 4];
+        inValue.copyTo(arrayInValue);
+        int[] arrayInMinValue = new int[INPUTSIZE * 4];
+        inMinValue.copyTo(arrayInMinValue);
+        int[] arrayInMaxValue = new int[INPUTSIZE * 4];
+        inMaxValue.copyTo(arrayInMaxValue);
+        int[] arrayOut = new int[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsUintUintUintUint args = new ArgumentsUintUintUintUint();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inMinValue = arrayInMinValue[i * 4 + j];
+                args.inMaxValue = arrayInMaxValue[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClamp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("0x%x", args.inValue));
+                    message.append("\n");
+                    message.append("Input inMinValue: ");
+                    message.append(String.format("0x%x", args.inMinValue));
+                    message.append("\n");
+                    message.append("Input inMaxValue: ");
+                    message.append(String.format("0x%x", args.inMaxValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClampUint3Uint3Uint3Uint3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkClampUint4Uint4Uint4Uint4() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 4, 0xbc4cc8e9741da6edl, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 4, 0x1b620e7bcfc26677l, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 4, 0x1b620e70611f587dl, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampUint4Uint4Uint4Uint4(inValue, out);
+            verifyResultsClampUint4Uint4Uint4Uint4(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUint4Uint4Uint4Uint4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampUint4Uint4Uint4Uint4(inValue, out);
+            verifyResultsClampUint4Uint4Uint4Uint4(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUint4Uint4Uint4Uint4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampUint4Uint4Uint4Uint4(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        int[] arrayInValue = new int[INPUTSIZE * 4];
+        inValue.copyTo(arrayInValue);
+        int[] arrayInMinValue = new int[INPUTSIZE * 4];
+        inMinValue.copyTo(arrayInMinValue);
+        int[] arrayInMaxValue = new int[INPUTSIZE * 4];
+        inMaxValue.copyTo(arrayInMaxValue);
+        int[] arrayOut = new int[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsUintUintUintUint args = new ArgumentsUintUintUintUint();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inMinValue = arrayInMinValue[i * 4 + j];
+                args.inMaxValue = arrayInMaxValue[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClamp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("0x%x", args.inValue));
+                    message.append("\n");
+                    message.append("Input inMinValue: ");
+                    message.append(String.format("0x%x", args.inMinValue));
+                    message.append("\n");
+                    message.append("Input inMaxValue: ");
+                    message.append(String.format("0x%x", args.inMaxValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClampUint4Uint4Uint4Uint4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkClampChar2CharCharChar2() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 2, 0xd6884bbb7c57a5d1l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 1, 0x3bf8830cc3b7db63l, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 1, 0x3bf883015514cd69l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampChar2CharCharChar2(inValue, out);
+            verifyResultsClampChar2CharCharChar2(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampChar2CharCharChar2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampChar2CharCharChar2(inValue, out);
+            verifyResultsClampChar2CharCharChar2(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampChar2CharCharChar2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampChar2CharCharChar2(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        byte[] arrayInValue = new byte[INPUTSIZE * 2];
+        inValue.copyTo(arrayInValue);
+        byte[] arrayInMinValue = new byte[INPUTSIZE * 1];
+        inMinValue.copyTo(arrayInMinValue);
+        byte[] arrayInMaxValue = new byte[INPUTSIZE * 1];
+        inMaxValue.copyTo(arrayInMaxValue);
+        byte[] arrayOut = new byte[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsCharCharCharChar args = new ArgumentsCharCharCharChar();
+                args.inValue = arrayInValue[i * 2 + j];
+                args.inMinValue = arrayInMinValue[i];
+                args.inMaxValue = arrayInMaxValue[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClamp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("%d", args.inValue));
+                    message.append("\n");
+                    message.append("Input inMinValue: ");
+                    message.append(String.format("%d", args.inMinValue));
+                    message.append("\n");
+                    message.append("Input inMaxValue: ");
+                    message.append(String.format("%d", args.inMaxValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClampChar2CharCharChar2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkClampChar3CharCharChar3() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 3, 0x4aa68c1b65a26ee5l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 1, 0x8b4b9ea0492789dfl, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 1, 0x8b4b9e94da847be5l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampChar3CharCharChar3(inValue, out);
+            verifyResultsClampChar3CharCharChar3(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampChar3CharCharChar3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampChar3CharCharChar3(inValue, out);
+            verifyResultsClampChar3CharCharChar3(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampChar3CharCharChar3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampChar3CharCharChar3(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        byte[] arrayInValue = new byte[INPUTSIZE * 4];
+        inValue.copyTo(arrayInValue);
+        byte[] arrayInMinValue = new byte[INPUTSIZE * 1];
+        inMinValue.copyTo(arrayInMinValue);
+        byte[] arrayInMaxValue = new byte[INPUTSIZE * 1];
+        inMaxValue.copyTo(arrayInMaxValue);
+        byte[] arrayOut = new byte[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsCharCharCharChar args = new ArgumentsCharCharCharChar();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inMinValue = arrayInMinValue[i];
+                args.inMaxValue = arrayInMaxValue[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClamp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("%d", args.inValue));
+                    message.append("\n");
+                    message.append("Input inMinValue: ");
+                    message.append(String.format("%d", args.inMinValue));
+                    message.append("\n");
+                    message.append("Input inMaxValue: ");
+                    message.append(String.format("%d", args.inMaxValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClampChar3CharCharChar3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkClampChar4CharCharChar4() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 4, 0xbec4cc7b4eed37f9l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 1, 0xda9eba33ce97385bl, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 1, 0xda9eba285ff42a61l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampChar4CharCharChar4(inValue, out);
+            verifyResultsClampChar4CharCharChar4(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampChar4CharCharChar4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampChar4CharCharChar4(inValue, out);
+            verifyResultsClampChar4CharCharChar4(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampChar4CharCharChar4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampChar4CharCharChar4(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        byte[] arrayInValue = new byte[INPUTSIZE * 4];
+        inValue.copyTo(arrayInValue);
+        byte[] arrayInMinValue = new byte[INPUTSIZE * 1];
+        inMinValue.copyTo(arrayInMinValue);
+        byte[] arrayInMaxValue = new byte[INPUTSIZE * 1];
+        inMaxValue.copyTo(arrayInMaxValue);
+        byte[] arrayOut = new byte[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsCharCharCharChar args = new ArgumentsCharCharCharChar();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inMinValue = arrayInMinValue[i];
+                args.inMaxValue = arrayInMaxValue[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClamp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("%d", args.inValue));
+                    message.append("\n");
+                    message.append("Input inMinValue: ");
+                    message.append(String.format("%d", args.inMinValue));
+                    message.append("\n");
+                    message.append("Input inMaxValue: ");
+                    message.append(String.format("%d", args.inMaxValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClampChar4CharCharChar4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkClampUchar2UcharUcharUchar2() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 2, 0xafd4a680f02e0d63l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 1, 0x78bbbcb3e9402039l, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 1, 0x78bbbca87a9d123fl, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampUchar2UcharUcharUchar2(inValue, out);
+            verifyResultsClampUchar2UcharUcharUchar2(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUchar2UcharUcharUchar2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampUchar2UcharUcharUchar2(inValue, out);
+            verifyResultsClampUchar2UcharUcharUchar2(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUchar2UcharUcharUchar2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampUchar2UcharUcharUchar2(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        byte[] arrayInValue = new byte[INPUTSIZE * 2];
+        inValue.copyTo(arrayInValue);
+        byte[] arrayInMinValue = new byte[INPUTSIZE * 1];
+        inMinValue.copyTo(arrayInMinValue);
+        byte[] arrayInMaxValue = new byte[INPUTSIZE * 1];
+        inMaxValue.copyTo(arrayInMaxValue);
+        byte[] arrayOut = new byte[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsUcharUcharUcharUchar args = new ArgumentsUcharUcharUcharUchar();
+                args.inValue = arrayInValue[i * 2 + j];
+                args.inMinValue = arrayInMinValue[i];
+                args.inMaxValue = arrayInMaxValue[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClamp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("0x%x", args.inValue));
+                    message.append("\n");
+                    message.append("Input inMinValue: ");
+                    message.append(String.format("0x%x", args.inMinValue));
+                    message.append("\n");
+                    message.append("Input inMaxValue: ");
+                    message.append(String.format("0x%x", args.inMaxValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClampUchar2UcharUcharUchar2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkClampUchar3UcharUcharUchar3() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 3, 0xfedafacc68ea3ae9l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 1, 0x8371883e1c6e882bl, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 1, 0x83718832adcb7a31l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampUchar3UcharUcharUchar3(inValue, out);
+            verifyResultsClampUchar3UcharUcharUchar3(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUchar3UcharUcharUchar3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampUchar3UcharUcharUchar3(inValue, out);
+            verifyResultsClampUchar3UcharUcharUchar3(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUchar3UcharUcharUchar3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampUchar3UcharUcharUchar3(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        byte[] arrayInValue = new byte[INPUTSIZE * 4];
+        inValue.copyTo(arrayInValue);
+        byte[] arrayInMinValue = new byte[INPUTSIZE * 1];
+        inMinValue.copyTo(arrayInMinValue);
+        byte[] arrayInMaxValue = new byte[INPUTSIZE * 1];
+        inMaxValue.copyTo(arrayInMaxValue);
+        byte[] arrayOut = new byte[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsUcharUcharUcharUchar args = new ArgumentsUcharUcharUcharUchar();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inMinValue = arrayInMinValue[i];
+                args.inMaxValue = arrayInMaxValue[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClamp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("0x%x", args.inValue));
+                    message.append("\n");
+                    message.append("Input inMinValue: ");
+                    message.append(String.format("0x%x", args.inMinValue));
+                    message.append("\n");
+                    message.append("Input inMaxValue: ");
+                    message.append(String.format("0x%x", args.inMaxValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClampUchar3UcharUcharUchar3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkClampUchar4UcharUcharUchar4() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 4, 0x4de14f17e1a6686fl, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 1, 0x8e2753c84f9cf01dl, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 1, 0x8e2753bce0f9e223l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampUchar4UcharUcharUchar4(inValue, out);
+            verifyResultsClampUchar4UcharUcharUchar4(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUchar4UcharUcharUchar4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampUchar4UcharUcharUchar4(inValue, out);
+            verifyResultsClampUchar4UcharUcharUchar4(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUchar4UcharUcharUchar4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampUchar4UcharUcharUchar4(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        byte[] arrayInValue = new byte[INPUTSIZE * 4];
+        inValue.copyTo(arrayInValue);
+        byte[] arrayInMinValue = new byte[INPUTSIZE * 1];
+        inMinValue.copyTo(arrayInMinValue);
+        byte[] arrayInMaxValue = new byte[INPUTSIZE * 1];
+        inMaxValue.copyTo(arrayInMaxValue);
+        byte[] arrayOut = new byte[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsUcharUcharUcharUchar args = new ArgumentsUcharUcharUcharUchar();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inMinValue = arrayInMinValue[i];
+                args.inMaxValue = arrayInMaxValue[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClamp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("0x%x", args.inValue));
+                    message.append("\n");
+                    message.append("Input inMinValue: ");
+                    message.append(String.format("0x%x", args.inMinValue));
+                    message.append("\n");
+                    message.append("Input inMaxValue: ");
+                    message.append(String.format("0x%x", args.inMaxValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClampUchar4UcharUcharUchar4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkClampShort2ShortShortShort2() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 2, 0x89e3627eae2d6a9l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 1, 0x886d6d2ccaca776bl, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 1, 0x886d6d215c276971l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampShort2ShortShortShort2(inValue, out);
+            verifyResultsClampShort2ShortShortShort2(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampShort2ShortShortShort2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampShort2ShortShortShort2(inValue, out);
+            verifyResultsClampShort2ShortShortShort2(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampShort2ShortShortShort2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampShort2ShortShortShort2(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        short[] arrayInValue = new short[INPUTSIZE * 2];
+        inValue.copyTo(arrayInValue);
+        short[] arrayInMinValue = new short[INPUTSIZE * 1];
+        inMinValue.copyTo(arrayInMinValue);
+        short[] arrayInMaxValue = new short[INPUTSIZE * 1];
+        inMaxValue.copyTo(arrayInMaxValue);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsShortShortShortShort args = new ArgumentsShortShortShortShort();
+                args.inValue = arrayInValue[i * 2 + j];
+                args.inMinValue = arrayInMinValue[i];
+                args.inMaxValue = arrayInMaxValue[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClamp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("%d", args.inValue));
+                    message.append("\n");
+                    message.append("Input inMinValue: ");
+                    message.append(String.format("%d", args.inMinValue));
+                    message.append("\n");
+                    message.append("Input inMaxValue: ");
+                    message.append(String.format("%d", args.inMaxValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClampShort2ShortShortShort2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkClampShort3ShortShortShort3() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 3, 0x57a48a73639f042fl, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 1, 0x932338b6fdf8df5dl, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 1, 0x932338ab8f55d163l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampShort3ShortShortShort3(inValue, out);
+            verifyResultsClampShort3ShortShortShort3(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampShort3ShortShortShort3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampShort3ShortShortShort3(inValue, out);
+            verifyResultsClampShort3ShortShortShort3(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampShort3ShortShortShort3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampShort3ShortShortShort3(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        short[] arrayInValue = new short[INPUTSIZE * 4];
+        inValue.copyTo(arrayInValue);
+        short[] arrayInMinValue = new short[INPUTSIZE * 1];
+        inMinValue.copyTo(arrayInMinValue);
+        short[] arrayInMaxValue = new short[INPUTSIZE * 1];
+        inMaxValue.copyTo(arrayInMaxValue);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsShortShortShortShort args = new ArgumentsShortShortShortShort();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inMinValue = arrayInMinValue[i];
+                args.inMaxValue = arrayInMaxValue[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClamp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("%d", args.inValue));
+                    message.append("\n");
+                    message.append("Input inMinValue: ");
+                    message.append(String.format("%d", args.inMinValue));
+                    message.append("\n");
+                    message.append("Input inMaxValue: ");
+                    message.append(String.format("%d", args.inMaxValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClampShort3ShortShortShort3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkClampShort4ShortShortShort4() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 4, 0xa6aadebedc5b31b5l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 1, 0x9dd904413127474fl, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 1, 0x9dd90435c2843955l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampShort4ShortShortShort4(inValue, out);
+            verifyResultsClampShort4ShortShortShort4(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampShort4ShortShortShort4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampShort4ShortShortShort4(inValue, out);
+            verifyResultsClampShort4ShortShortShort4(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampShort4ShortShortShort4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampShort4ShortShortShort4(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        short[] arrayInValue = new short[INPUTSIZE * 4];
+        inValue.copyTo(arrayInValue);
+        short[] arrayInMinValue = new short[INPUTSIZE * 1];
+        inMinValue.copyTo(arrayInMinValue);
+        short[] arrayInMaxValue = new short[INPUTSIZE * 1];
+        inMaxValue.copyTo(arrayInMaxValue);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsShortShortShortShort args = new ArgumentsShortShortShortShort();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inMinValue = arrayInMinValue[i];
+                args.inMaxValue = arrayInMaxValue[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClamp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("%d", args.inValue));
+                    message.append("\n");
+                    message.append("Input inMinValue: ");
+                    message.append(String.format("%d", args.inMinValue));
+                    message.append("\n");
+                    message.append("Input inMaxValue: ");
+                    message.append(String.format("%d", args.inMaxValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClampShort4ShortShortShort4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkClampUshort2UshortUshortUshort2() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 2, 0x2ece6d045621ef07l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 1, 0xd88bd79cc7874965l, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 1, 0xd88bd79158e43b6bl, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampUshort2UshortUshortUshort2(inValue, out);
+            verifyResultsClampUshort2UshortUshortUshort2(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUshort2UshortUshortUshort2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampUshort2UshortUshortUshort2(inValue, out);
+            verifyResultsClampUshort2UshortUshortUshort2(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUshort2UshortUshortUshort2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampUshort2UshortUshortUshort2(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        short[] arrayInValue = new short[INPUTSIZE * 2];
+        inValue.copyTo(arrayInValue);
+        short[] arrayInMinValue = new short[INPUTSIZE * 1];
+        inMinValue.copyTo(arrayInMinValue);
+        short[] arrayInMaxValue = new short[INPUTSIZE * 1];
+        inMaxValue.copyTo(arrayInMaxValue);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsUshortUshortUshortUshort args = new ArgumentsUshortUshortUshortUshort();
+                args.inValue = arrayInValue[i * 2 + j];
+                args.inMinValue = arrayInMinValue[i];
+                args.inMaxValue = arrayInMaxValue[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClamp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("0x%x", args.inValue));
+                    message.append("\n");
+                    message.append("Input inMinValue: ");
+                    message.append(String.format("0x%x", args.inMinValue));
+                    message.append("\n");
+                    message.append("Input inMaxValue: ");
+                    message.append(String.format("0x%x", args.inMaxValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClampUshort2UshortUshortUshort2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkClampUshort3UshortUshortUshort3() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 3, 0x393771467c9cd603l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 1, 0xfe016431b3cf1419l, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 1, 0xfe016426452c061fl, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampUshort3UshortUshortUshort3(inValue, out);
+            verifyResultsClampUshort3UshortUshortUshort3(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUshort3UshortUshortUshort3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampUshort3UshortUshortUshort3(inValue, out);
+            verifyResultsClampUshort3UshortUshortUshort3(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUshort3UshortUshortUshort3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampUshort3UshortUshortUshort3(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        short[] arrayInValue = new short[INPUTSIZE * 4];
+        inValue.copyTo(arrayInValue);
+        short[] arrayInMinValue = new short[INPUTSIZE * 1];
+        inMinValue.copyTo(arrayInMinValue);
+        short[] arrayInMaxValue = new short[INPUTSIZE * 1];
+        inMaxValue.copyTo(arrayInMaxValue);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsUshortUshortUshortUshort args = new ArgumentsUshortUshortUshortUshort();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inMinValue = arrayInMinValue[i];
+                args.inMaxValue = arrayInMaxValue[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClamp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("0x%x", args.inValue));
+                    message.append("\n");
+                    message.append("Input inMinValue: ");
+                    message.append(String.format("0x%x", args.inMinValue));
+                    message.append("\n");
+                    message.append("Input inMaxValue: ");
+                    message.append(String.format("0x%x", args.inMaxValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClampUshort3UshortUshortUshort3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkClampUshort4UshortUshortUshort4() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 4, 0x43a07588a317bcffl, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 1, 0x2376f0c6a016decdl, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 1, 0x2376f0bb3173d0d3l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampUshort4UshortUshortUshort4(inValue, out);
+            verifyResultsClampUshort4UshortUshortUshort4(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUshort4UshortUshortUshort4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampUshort4UshortUshortUshort4(inValue, out);
+            verifyResultsClampUshort4UshortUshortUshort4(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUshort4UshortUshortUshort4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampUshort4UshortUshortUshort4(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        short[] arrayInValue = new short[INPUTSIZE * 4];
+        inValue.copyTo(arrayInValue);
+        short[] arrayInMinValue = new short[INPUTSIZE * 1];
+        inMinValue.copyTo(arrayInMinValue);
+        short[] arrayInMaxValue = new short[INPUTSIZE * 1];
+        inMaxValue.copyTo(arrayInMaxValue);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsUshortUshortUshortUshort args = new ArgumentsUshortUshortUshortUshort();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inMinValue = arrayInMinValue[i];
+                args.inMaxValue = arrayInMaxValue[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClamp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("0x%x", args.inValue));
+                    message.append("\n");
+                    message.append("Input inMinValue: ");
+                    message.append(String.format("0x%x", args.inMinValue));
+                    message.append("\n");
+                    message.append("Input inMaxValue: ");
+                    message.append(String.format("0x%x", args.inMaxValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClampUshort4UshortUshortUshort4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkClampInt2IntIntInt2() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 2, 0xbb55c0997906d1dbl, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0x69776e80fba24121l, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0x69776e758cff3327l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampInt2IntIntInt2(inValue, out);
+            verifyResultsClampInt2IntIntInt2(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampInt2IntIntInt2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampInt2IntIntInt2(inValue, out);
+            verifyResultsClampInt2IntIntInt2(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampInt2IntIntInt2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampInt2IntIntInt2(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        int[] arrayInValue = new int[INPUTSIZE * 2];
+        inValue.copyTo(arrayInValue);
+        int[] arrayInMinValue = new int[INPUTSIZE * 1];
+        inMinValue.copyTo(arrayInMinValue);
+        int[] arrayInMaxValue = new int[INPUTSIZE * 1];
+        inMaxValue.copyTo(arrayInMaxValue);
+        int[] arrayOut = new int[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsIntIntIntInt args = new ArgumentsIntIntIntInt();
+                args.inValue = arrayInValue[i * 2 + j];
+                args.inMinValue = arrayInMinValue[i];
+                args.inMaxValue = arrayInMaxValue[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClamp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("%d", args.inValue));
+                    message.append("\n");
+                    message.append("Input inMinValue: ");
+                    message.append(String.format("%d", args.inMinValue));
+                    message.append("\n");
+                    message.append("Input inMaxValue: ");
+                    message.append(String.format("%d", args.inMaxValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClampInt2IntIntInt2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkClampInt3IntIntInt3() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 3, 0x3af8924ab5370be9l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0xdde27628f1a08b2bl, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0xdde2761d82fd7d31l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampInt3IntIntInt3(inValue, out);
+            verifyResultsClampInt3IntIntInt3(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampInt3IntIntInt3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampInt3IntIntInt3(inValue, out);
+            verifyResultsClampInt3IntIntInt3(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampInt3IntIntInt3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampInt3IntIntInt3(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        int[] arrayInValue = new int[INPUTSIZE * 4];
+        inValue.copyTo(arrayInValue);
+        int[] arrayInMinValue = new int[INPUTSIZE * 1];
+        inMinValue.copyTo(arrayInMinValue);
+        int[] arrayInMaxValue = new int[INPUTSIZE * 1];
+        inMaxValue.copyTo(arrayInMaxValue);
+        int[] arrayOut = new int[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsIntIntIntInt args = new ArgumentsIntIntIntInt();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inMinValue = arrayInMinValue[i];
+                args.inMaxValue = arrayInMaxValue[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClamp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("%d", args.inValue));
+                    message.append("\n");
+                    message.append("Input inMinValue: ");
+                    message.append(String.format("%d", args.inMinValue));
+                    message.append("\n");
+                    message.append("Input inMaxValue: ");
+                    message.append(String.format("%d", args.inMaxValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClampInt3IntIntInt3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkClampInt4IntIntInt4() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 4, 0xba9b63fbf16745f7l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0x524d7dd0e79ed535l, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0x524d7dc578fbc73bl, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampInt4IntIntInt4(inValue, out);
+            verifyResultsClampInt4IntIntInt4(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampInt4IntIntInt4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampInt4IntIntInt4(inValue, out);
+            verifyResultsClampInt4IntIntInt4(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampInt4IntIntInt4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampInt4IntIntInt4(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        int[] arrayInValue = new int[INPUTSIZE * 4];
+        inValue.copyTo(arrayInValue);
+        int[] arrayInMinValue = new int[INPUTSIZE * 1];
+        inMinValue.copyTo(arrayInMinValue);
+        int[] arrayInMaxValue = new int[INPUTSIZE * 1];
+        inMaxValue.copyTo(arrayInMaxValue);
+        int[] arrayOut = new int[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsIntIntIntInt args = new ArgumentsIntIntIntInt();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inMinValue = arrayInMinValue[i];
+                args.inMaxValue = arrayInMaxValue[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClamp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("%d", args.inValue));
+                    message.append("\n");
+                    message.append("Input inMinValue: ");
+                    message.append(String.format("%d", args.inMinValue));
+                    message.append("\n");
+                    message.append("Input inMaxValue: ");
+                    message.append(String.format("%d", args.inMaxValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClampInt4IntIntInt4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkClampUint2UintUintUint2() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 2, 0x4fd098dd770d5a51l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 1, 0x6de3f327c2a180e3l, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 1, 0x6de3f31c53fe72e9l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampUint2UintUintUint2(inValue, out);
+            verifyResultsClampUint2UintUintUint2(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUint2UintUintUint2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampUint2UintUintUint2(inValue, out);
+            verifyResultsClampUint2UintUintUint2(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUint2UintUintUint2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampUint2UintUintUint2(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        int[] arrayInValue = new int[INPUTSIZE * 2];
+        inValue.copyTo(arrayInValue);
+        int[] arrayInMinValue = new int[INPUTSIZE * 1];
+        inMinValue.copyTo(arrayInMinValue);
+        int[] arrayInMaxValue = new int[INPUTSIZE * 1];
+        inMaxValue.copyTo(arrayInMaxValue);
+        int[] arrayOut = new int[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsUintUintUintUint args = new ArgumentsUintUintUintUint();
+                args.inValue = arrayInValue[i * 2 + j];
+                args.inMinValue = arrayInMinValue[i];
+                args.inMaxValue = arrayInMaxValue[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClamp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("0x%x", args.inValue));
+                    message.append("\n");
+                    message.append("Input inMinValue: ");
+                    message.append(String.format("0x%x", args.inMinValue));
+                    message.append("\n");
+                    message.append("Input inMaxValue: ");
+                    message.append(String.format("0x%x", args.inMaxValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClampUint2UintUintUint2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkClampUint3UintUintUint3() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 3, 0xc3eed93d60582365l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 1, 0xbd370ebb48112f5fl, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 1, 0xbd370eafd96e2165l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampUint3UintUintUint3(inValue, out);
+            verifyResultsClampUint3UintUintUint3(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUint3UintUintUint3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampUint3UintUintUint3(inValue, out);
+            verifyResultsClampUint3UintUintUint3(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUint3UintUintUint3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampUint3UintUintUint3(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        int[] arrayInValue = new int[INPUTSIZE * 4];
+        inValue.copyTo(arrayInValue);
+        int[] arrayInMinValue = new int[INPUTSIZE * 1];
+        inMinValue.copyTo(arrayInMinValue);
+        int[] arrayInMaxValue = new int[INPUTSIZE * 1];
+        inMaxValue.copyTo(arrayInMaxValue);
+        int[] arrayOut = new int[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsUintUintUintUint args = new ArgumentsUintUintUintUint();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inMinValue = arrayInMinValue[i];
+                args.inMaxValue = arrayInMaxValue[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClamp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("0x%x", args.inValue));
+                    message.append("\n");
+                    message.append("Input inMinValue: ");
+                    message.append(String.format("0x%x", args.inMinValue));
+                    message.append("\n");
+                    message.append("Input inMaxValue: ");
+                    message.append(String.format("0x%x", args.inMaxValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClampUint3UintUintUint3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkClampUint4UintUintUint4() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 4, 0x380d199d49a2ec79l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 1, 0xc8a2a4ecd80dddbl, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 1, 0xc8a2a435eddcfe1l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampUint4UintUintUint4(inValue, out);
+            verifyResultsClampUint4UintUintUint4(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUint4UintUintUint4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampUint4UintUintUint4(inValue, out);
+            verifyResultsClampUint4UintUintUint4(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUint4UintUintUint4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampUint4UintUintUint4(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        int[] arrayInValue = new int[INPUTSIZE * 4];
+        inValue.copyTo(arrayInValue);
+        int[] arrayInMinValue = new int[INPUTSIZE * 1];
+        inMinValue.copyTo(arrayInMinValue);
+        int[] arrayInMaxValue = new int[INPUTSIZE * 1];
+        inMaxValue.copyTo(arrayInMaxValue);
+        int[] arrayOut = new int[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsUintUintUintUint args = new ArgumentsUintUintUintUint();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inMinValue = arrayInMinValue[i];
+                args.inMaxValue = arrayInMaxValue[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClamp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("0x%x", args.inValue));
+                    message.append("\n");
+                    message.append("Input inMinValue: ");
+                    message.append(String.format("0x%x", args.inMinValue));
+                    message.append("\n");
+                    message.append("Input inMaxValue: ");
+                    message.append(String.format("0x%x", args.inMaxValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClampUint4UintUintUint4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testClamp() {
+        checkClampFloatFloatFloatFloat();
+        checkClampFloat2Float2Float2Float2();
+        checkClampFloat3Float3Float3Float3();
+        checkClampFloat4Float4Float4Float4();
+        checkClampFloat2FloatFloatFloat2();
+        checkClampFloat3FloatFloatFloat3();
+        checkClampFloat4FloatFloatFloat4();
+        checkClampCharCharCharChar();
+        checkClampChar2Char2Char2Char2();
+        checkClampChar3Char3Char3Char3();
+        checkClampChar4Char4Char4Char4();
+        checkClampUcharUcharUcharUchar();
+        checkClampUchar2Uchar2Uchar2Uchar2();
+        checkClampUchar3Uchar3Uchar3Uchar3();
+        checkClampUchar4Uchar4Uchar4Uchar4();
+        checkClampShortShortShortShort();
+        checkClampShort2Short2Short2Short2();
+        checkClampShort3Short3Short3Short3();
+        checkClampShort4Short4Short4Short4();
+        checkClampUshortUshortUshortUshort();
+        checkClampUshort2Ushort2Ushort2Ushort2();
+        checkClampUshort3Ushort3Ushort3Ushort3();
+        checkClampUshort4Ushort4Ushort4Ushort4();
+        checkClampIntIntIntInt();
+        checkClampInt2Int2Int2Int2();
+        checkClampInt3Int3Int3Int3();
+        checkClampInt4Int4Int4Int4();
+        checkClampUintUintUintUint();
+        checkClampUint2Uint2Uint2Uint2();
+        checkClampUint3Uint3Uint3Uint3();
+        checkClampUint4Uint4Uint4Uint4();
+        checkClampChar2CharCharChar2();
+        checkClampChar3CharCharChar3();
+        checkClampChar4CharCharChar4();
+        checkClampUchar2UcharUcharUchar2();
+        checkClampUchar3UcharUcharUchar3();
+        checkClampUchar4UcharUcharUchar4();
+        checkClampShort2ShortShortShort2();
+        checkClampShort3ShortShortShort3();
+        checkClampShort4ShortShortShort4();
+        checkClampUshort2UshortUshortUshort2();
+        checkClampUshort3UshortUshortUshort3();
+        checkClampUshort4UshortUshortUshort4();
+        checkClampInt2IntIntInt2();
+        checkClampInt3IntIntInt3();
+        checkClampInt4IntIntInt4();
+        checkClampUint2UintUintUint2();
+        checkClampUint3UintUintUint3();
+        checkClampUint4UintUintUint4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestClz.java b/tests/tests/renderscript/src/android/renderscript/cts/TestClz.java
new file mode 100644
index 0000000..8e9be9a
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestClz.java
@@ -0,0 +1,1461 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestClz extends RSBaseCompute {
+
+    private ScriptC_TestClz script;
+    private ScriptC_TestClzRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestClz(mRS);
+        scriptRelaxed = new ScriptC_TestClzRelaxed(mRS);
+    }
+
+    public class ArgumentsCharChar {
+        public byte inValue;
+        public byte out;
+    }
+
+    private void checkClzCharChar() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 1, 0xf6f3a15e2f7765afl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 1), INPUTSIZE);
+            script.forEach_testClzCharChar(inValue, out);
+            verifyResultsClzCharChar(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzCharChar: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testClzCharChar(inValue, out);
+            verifyResultsClzCharChar(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzCharChar: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClzCharChar(Allocation inValue, Allocation out, boolean relaxed) {
+        byte[] arrayInValue = new byte[INPUTSIZE * 1];
+        inValue.copyTo(arrayInValue);
+        byte[] arrayOut = new byte[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsCharChar args = new ArgumentsCharChar();
+                args.inValue = arrayInValue[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClz(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 1 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("%d", args.inValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 1 + j]));
+                    if (args.out != arrayOut[i * 1 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClzCharChar" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkClzChar2Char2() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 2, 0xf718b99dcaca5e93l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
+            script.forEach_testClzChar2Char2(inValue, out);
+            verifyResultsClzChar2Char2(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzChar2Char2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testClzChar2Char2(inValue, out);
+            verifyResultsClzChar2Char2(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzChar2Char2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClzChar2Char2(Allocation inValue, Allocation out, boolean relaxed) {
+        byte[] arrayInValue = new byte[INPUTSIZE * 2];
+        inValue.copyTo(arrayInValue);
+        byte[] arrayOut = new byte[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsCharChar args = new ArgumentsCharChar();
+                args.inValue = arrayInValue[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClz(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("%d", args.inValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClzChar2Char2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkClzChar3Char3() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 3, 0x21a5da5bc7099347l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
+            script.forEach_testClzChar3Char3(inValue, out);
+            verifyResultsClzChar3Char3(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzChar3Char3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testClzChar3Char3(inValue, out);
+            verifyResultsClzChar3Char3(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzChar3Char3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClzChar3Char3(Allocation inValue, Allocation out, boolean relaxed) {
+        byte[] arrayInValue = new byte[INPUTSIZE * 4];
+        inValue.copyTo(arrayInValue);
+        byte[] arrayOut = new byte[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsCharChar args = new ArgumentsCharChar();
+                args.inValue = arrayInValue[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClz(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("%d", args.inValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClzChar3Char3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkClzChar4Char4() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 4, 0x4c32fb19c348c7fbl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
+            script.forEach_testClzChar4Char4(inValue, out);
+            verifyResultsClzChar4Char4(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzChar4Char4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testClzChar4Char4(inValue, out);
+            verifyResultsClzChar4Char4(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzChar4Char4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClzChar4Char4(Allocation inValue, Allocation out, boolean relaxed) {
+        byte[] arrayInValue = new byte[INPUTSIZE * 4];
+        inValue.copyTo(arrayInValue);
+        byte[] arrayOut = new byte[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsCharChar args = new ArgumentsCharChar();
+                args.inValue = arrayInValue[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClz(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("%d", args.inValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClzChar4Char4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsUcharUchar {
+        public byte inValue;
+        public byte out;
+    }
+
+    private void checkClzUcharUchar() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 1, 0xd2e451b48b84f57fl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 1), INPUTSIZE);
+            script.forEach_testClzUcharUchar(inValue, out);
+            verifyResultsClzUcharUchar(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUcharUchar: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testClzUcharUchar(inValue, out);
+            verifyResultsClzUcharUchar(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUcharUchar: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClzUcharUchar(Allocation inValue, Allocation out, boolean relaxed) {
+        byte[] arrayInValue = new byte[INPUTSIZE * 1];
+        inValue.copyTo(arrayInValue);
+        byte[] arrayOut = new byte[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsUcharUchar args = new ArgumentsUcharUchar();
+                args.inValue = arrayInValue[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClz(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 1 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("0x%x", args.inValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 1 + j]));
+                    if (args.out != arrayOut[i * 1 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClzUcharUchar" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkClzUchar2Uchar2() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 2, 0x792e2970f47ebc85l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
+            script.forEach_testClzUchar2Uchar2(inValue, out);
+            verifyResultsClzUchar2Uchar2(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUchar2Uchar2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testClzUchar2Uchar2(inValue, out);
+            verifyResultsClzUchar2Uchar2(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUchar2Uchar2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClzUchar2Uchar2(Allocation inValue, Allocation out, boolean relaxed) {
+        byte[] arrayInValue = new byte[INPUTSIZE * 2];
+        inValue.copyTo(arrayInValue);
+        byte[] arrayOut = new byte[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsUcharUchar args = new ArgumentsUcharUchar();
+                args.inValue = arrayInValue[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClz(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("0x%x", args.inValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClzUchar2Uchar2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkClzUchar3Uchar3() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 3, 0x9ee29ef83dbce203l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
+            script.forEach_testClzUchar3Uchar3(inValue, out);
+            verifyResultsClzUchar3Uchar3(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUchar3Uchar3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testClzUchar3Uchar3(inValue, out);
+            verifyResultsClzUchar3Uchar3(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUchar3Uchar3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClzUchar3Uchar3(Allocation inValue, Allocation out, boolean relaxed) {
+        byte[] arrayInValue = new byte[INPUTSIZE * 4];
+        inValue.copyTo(arrayInValue);
+        byte[] arrayOut = new byte[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsUcharUchar args = new ArgumentsUcharUchar();
+                args.inValue = arrayInValue[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClz(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("0x%x", args.inValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClzUchar3Uchar3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkClzUchar4Uchar4() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 4, 0xc497147f86fb0781l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
+            script.forEach_testClzUchar4Uchar4(inValue, out);
+            verifyResultsClzUchar4Uchar4(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUchar4Uchar4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testClzUchar4Uchar4(inValue, out);
+            verifyResultsClzUchar4Uchar4(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUchar4Uchar4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClzUchar4Uchar4(Allocation inValue, Allocation out, boolean relaxed) {
+        byte[] arrayInValue = new byte[INPUTSIZE * 4];
+        inValue.copyTo(arrayInValue);
+        byte[] arrayOut = new byte[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsUcharUchar args = new ArgumentsUcharUchar();
+                args.inValue = arrayInValue[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClz(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("0x%x", args.inValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClzUchar4Uchar4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsShortShort {
+        public short inValue;
+        public short out;
+    }
+
+    private void checkClzShortShort() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 1, 0x3290aea900d8ad53l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 1), INPUTSIZE);
+            script.forEach_testClzShortShort(inValue, out);
+            verifyResultsClzShortShort(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzShortShort: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testClzShortShort(inValue, out);
+            verifyResultsClzShortShort(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzShortShort: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClzShortShort(Allocation inValue, Allocation out, boolean relaxed) {
+        short[] arrayInValue = new short[INPUTSIZE * 1];
+        inValue.copyTo(arrayInValue);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsShortShort args = new ArgumentsShortShort();
+                args.inValue = arrayInValue[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClz(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 1 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("%d", args.inValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 1 + j]));
+                    if (args.out != arrayOut[i * 1 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClzShortShort" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkClzShort2Short2() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 2, 0x81f69d4442dd6ebfl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
+            script.forEach_testClzShort2Short2(inValue, out);
+            verifyResultsClzShort2Short2(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzShort2Short2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testClzShort2Short2(inValue, out);
+            verifyResultsClzShort2Short2(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzShort2Short2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClzShort2Short2(Allocation inValue, Allocation out, boolean relaxed) {
+        short[] arrayInValue = new short[INPUTSIZE * 2];
+        inValue.copyTo(arrayInValue);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsShortShort args = new ArgumentsShortShort();
+                args.inValue = arrayInValue[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClz(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("%d", args.inValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClzShort2Short2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkClzShort3Short3() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 3, 0xa7ab12cb8c1b943dl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
+            script.forEach_testClzShort3Short3(inValue, out);
+            verifyResultsClzShort3Short3(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzShort3Short3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testClzShort3Short3(inValue, out);
+            verifyResultsClzShort3Short3(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzShort3Short3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClzShort3Short3(Allocation inValue, Allocation out, boolean relaxed) {
+        short[] arrayInValue = new short[INPUTSIZE * 4];
+        inValue.copyTo(arrayInValue);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsShortShort args = new ArgumentsShortShort();
+                args.inValue = arrayInValue[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClz(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("%d", args.inValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClzShort3Short3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkClzShort4Short4() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 4, 0xcd5f8852d559b9bbl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
+            script.forEach_testClzShort4Short4(inValue, out);
+            verifyResultsClzShort4Short4(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzShort4Short4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testClzShort4Short4(inValue, out);
+            verifyResultsClzShort4Short4(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzShort4Short4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClzShort4Short4(Allocation inValue, Allocation out, boolean relaxed) {
+        short[] arrayInValue = new short[INPUTSIZE * 4];
+        inValue.copyTo(arrayInValue);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsShortShort args = new ArgumentsShortShort();
+                args.inValue = arrayInValue[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClz(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("%d", args.inValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClzShort4Short4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsUshortUshort {
+        public short inValue;
+        public short out;
+    }
+
+    private void checkClzUshortUshort() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 1, 0x97bdeee92c0103a5l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 1), INPUTSIZE);
+            script.forEach_testClzUshortUshort(inValue, out);
+            verifyResultsClzUshortUshort(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUshortUshort: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testClzUshortUshort(inValue, out);
+            verifyResultsClzUshortUshort(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUshortUshort: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClzUshortUshort(Allocation inValue, Allocation out, boolean relaxed) {
+        short[] arrayInValue = new short[INPUTSIZE * 1];
+        inValue.copyTo(arrayInValue);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsUshortUshort args = new ArgumentsUshortUshort();
+                args.inValue = arrayInValue[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClz(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 1 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("0x%x", args.inValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 1 + j]));
+                    if (args.out != arrayOut[i * 1 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClzUshortUshort" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkClzUshort2Ushort2() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 2, 0x5ea7a024b2913837l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
+            script.forEach_testClzUshort2Ushort2(inValue, out);
+            verifyResultsClzUshort2Ushort2(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUshort2Ushort2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testClzUshort2Ushort2(inValue, out);
+            verifyResultsClzUshort2Ushort2(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUshort2Ushort2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClzUshort2Ushort2(Allocation inValue, Allocation out, boolean relaxed) {
+        short[] arrayInValue = new short[INPUTSIZE * 2];
+        inValue.copyTo(arrayInValue);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsUshortUshort args = new ArgumentsUshortUshort();
+                args.inValue = arrayInValue[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClz(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("0x%x", args.inValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClzUshort2Ushort2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkClzUshort3Ushort3() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 3, 0xb3f7537beaa1cfa3l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
+            script.forEach_testClzUshort3Ushort3(inValue, out);
+            verifyResultsClzUshort3Ushort3(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUshort3Ushort3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testClzUshort3Ushort3(inValue, out);
+            verifyResultsClzUshort3Ushort3(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUshort3Ushort3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClzUshort3Ushort3(Allocation inValue, Allocation out, boolean relaxed) {
+        short[] arrayInValue = new short[INPUTSIZE * 4];
+        inValue.copyTo(arrayInValue);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsUshortUshort args = new ArgumentsUshortUshort();
+                args.inValue = arrayInValue[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClz(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("0x%x", args.inValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClzUshort3Ushort3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkClzUshort4Ushort4() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 4, 0x94706d322b2670fl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
+            script.forEach_testClzUshort4Ushort4(inValue, out);
+            verifyResultsClzUshort4Ushort4(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUshort4Ushort4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testClzUshort4Ushort4(inValue, out);
+            verifyResultsClzUshort4Ushort4(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUshort4Ushort4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClzUshort4Ushort4(Allocation inValue, Allocation out, boolean relaxed) {
+        short[] arrayInValue = new short[INPUTSIZE * 4];
+        inValue.copyTo(arrayInValue);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsUshortUshort args = new ArgumentsUshortUshort();
+                args.inValue = arrayInValue[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClz(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("0x%x", args.inValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClzUshort4Ushort4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsIntInt {
+        public int inValue;
+        public int out;
+    }
+
+    private void checkClzIntInt() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0xb13809da3142eb97l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 1), INPUTSIZE);
+            script.forEach_testClzIntInt(inValue, out);
+            verifyResultsClzIntInt(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzIntInt: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testClzIntInt(inValue, out);
+            verifyResultsClzIntInt(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzIntInt: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClzIntInt(Allocation inValue, Allocation out, boolean relaxed) {
+        int[] arrayInValue = new int[INPUTSIZE * 1];
+        inValue.copyTo(arrayInValue);
+        int[] arrayOut = new int[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsIntInt args = new ArgumentsIntInt();
+                args.inValue = arrayInValue[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClz(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 1 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("%d", args.inValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 1 + j]));
+                    if (args.out != arrayOut[i * 1 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClzIntInt" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkClzInt2Int2() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 2, 0xc9fd2c1a27fe3ad5l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            script.forEach_testClzInt2Int2(inValue, out);
+            verifyResultsClzInt2Int2(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzInt2Int2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testClzInt2Int2(inValue, out);
+            verifyResultsClzInt2Int2(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzInt2Int2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClzInt2Int2(Allocation inValue, Allocation out, boolean relaxed) {
+        int[] arrayInValue = new int[INPUTSIZE * 2];
+        inValue.copyTo(arrayInValue);
+        int[] arrayOut = new int[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsIntInt args = new ArgumentsIntInt();
+                args.inValue = arrayInValue[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClz(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("%d", args.inValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClzInt2Int2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkClzInt3Int3() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 3, 0xd6e2b014f2d24c2bl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            script.forEach_testClzInt3Int3(inValue, out);
+            verifyResultsClzInt3Int3(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzInt3Int3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testClzInt3Int3(inValue, out);
+            verifyResultsClzInt3Int3(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzInt3Int3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClzInt3Int3(Allocation inValue, Allocation out, boolean relaxed) {
+        int[] arrayInValue = new int[INPUTSIZE * 4];
+        inValue.copyTo(arrayInValue);
+        int[] arrayOut = new int[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsIntInt args = new ArgumentsIntInt();
+                args.inValue = arrayInValue[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClz(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("%d", args.inValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClzInt3Int3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkClzInt4Int4() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 4, 0xe3c8340fbda65d81l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            script.forEach_testClzInt4Int4(inValue, out);
+            verifyResultsClzInt4Int4(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzInt4Int4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testClzInt4Int4(inValue, out);
+            verifyResultsClzInt4Int4(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzInt4Int4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClzInt4Int4(Allocation inValue, Allocation out, boolean relaxed) {
+        int[] arrayInValue = new int[INPUTSIZE * 4];
+        inValue.copyTo(arrayInValue);
+        int[] arrayOut = new int[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsIntInt args = new ArgumentsIntInt();
+                args.inValue = arrayInValue[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClz(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("%d", args.inValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClzInt4Int4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsUintUint {
+        public int inValue;
+        public int out;
+    }
+
+    private void checkClzUintUint() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 1, 0x64a0b78a75ac502fl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 1), INPUTSIZE);
+            script.forEach_testClzUintUint(inValue, out);
+            verifyResultsClzUintUint(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUintUint: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testClzUintUint(inValue, out);
+            verifyResultsClzUintUint(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUintUint: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClzUintUint(Allocation inValue, Allocation out, boolean relaxed) {
+        int[] arrayInValue = new int[INPUTSIZE * 1];
+        inValue.copyTo(arrayInValue);
+        int[] arrayOut = new int[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsUintUint args = new ArgumentsUintUint();
+                args.inValue = arrayInValue[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClz(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 1 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("0x%x", args.inValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 1 + j]));
+                    if (args.out != arrayOut[i * 1 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClzUintUint" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkClzUint2Uint2() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 2, 0xf809b50329344f93l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
+            script.forEach_testClzUint2Uint2(inValue, out);
+            verifyResultsClzUint2Uint2(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUint2Uint2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testClzUint2Uint2(inValue, out);
+            verifyResultsClzUint2Uint2(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUint2Uint2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClzUint2Uint2(Allocation inValue, Allocation out, boolean relaxed) {
+        int[] arrayInValue = new int[INPUTSIZE * 2];
+        inValue.copyTo(arrayInValue);
+        int[] arrayOut = new int[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsUintUint args = new ArgumentsUintUint();
+                args.inValue = arrayInValue[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClz(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("0x%x", args.inValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClzUint2Uint2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkClzUint3Uint3() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 3, 0x2296d5c125738447l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
+            script.forEach_testClzUint3Uint3(inValue, out);
+            verifyResultsClzUint3Uint3(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUint3Uint3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testClzUint3Uint3(inValue, out);
+            verifyResultsClzUint3Uint3(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUint3Uint3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClzUint3Uint3(Allocation inValue, Allocation out, boolean relaxed) {
+        int[] arrayInValue = new int[INPUTSIZE * 4];
+        inValue.copyTo(arrayInValue);
+        int[] arrayOut = new int[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsUintUint args = new ArgumentsUintUint();
+                args.inValue = arrayInValue[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClz(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("0x%x", args.inValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClzUint3Uint3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkClzUint4Uint4() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 4, 0x4d23f67f21b2b8fbl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
+            script.forEach_testClzUint4Uint4(inValue, out);
+            verifyResultsClzUint4Uint4(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUint4Uint4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testClzUint4Uint4(inValue, out);
+            verifyResultsClzUint4Uint4(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUint4Uint4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClzUint4Uint4(Allocation inValue, Allocation out, boolean relaxed) {
+        int[] arrayInValue = new int[INPUTSIZE * 4];
+        inValue.copyTo(arrayInValue);
+        int[] arrayOut = new int[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsUintUint args = new ArgumentsUintUint();
+                args.inValue = arrayInValue[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeClz(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("0x%x", args.inValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkClzUint4Uint4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testClz() {
+        checkClzCharChar();
+        checkClzChar2Char2();
+        checkClzChar3Char3();
+        checkClzChar4Char4();
+        checkClzUcharUchar();
+        checkClzUchar2Uchar2();
+        checkClzUchar3Uchar3();
+        checkClzUchar4Uchar4();
+        checkClzShortShort();
+        checkClzShort2Short2();
+        checkClzShort3Short3();
+        checkClzShort4Short4();
+        checkClzUshortUshort();
+        checkClzUshort2Ushort2();
+        checkClzUshort3Ushort3();
+        checkClzUshort4Ushort4();
+        checkClzIntInt();
+        checkClzInt2Int2();
+        checkClzInt3Int3();
+        checkClzInt4Int4();
+        checkClzUintUint();
+        checkClzUint2Uint2();
+        checkClzUint3Uint3();
+        checkClzUint4Uint4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestConvert.java b/tests/tests/renderscript/src/android/renderscript/cts/TestConvert.java
new file mode 100644
index 0000000..eae020d
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestConvert.java
@@ -0,0 +1,8852 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestConvert extends RSBaseCompute {
+
+    private ScriptC_TestConvert script;
+    private ScriptC_TestConvertRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestConvert(mRS);
+        scriptRelaxed = new ScriptC_TestConvertRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Floaty out;
+    }
+
+    private void checkConvertFloat2Float2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xfb5215c44e1f6ac6l, -1.6163412428744576259e+38, 1.6163412428744576259e+38);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testConvertFloat2Float2Float2(inV, out);
+            verifyResultsConvertFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat2Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertFloat2Float2Float2(inV, out);
+            verifyResultsConvertFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat2Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertFloat2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertFloat3Float3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xfb53dedf443a8ba4l, -1.6163412428744576259e+38, 1.6163412428744576259e+38);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testConvertFloat3Float3Float3(inV, out);
+            verifyResultsConvertFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat3Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertFloat3Float3Float3(inV, out);
+            verifyResultsConvertFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat3Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertFloat3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertFloat4Float4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xfb55a7fa3a55ac82l, -1.6163412428744576259e+38, 1.6163412428744576259e+38);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testConvertFloat4Float4Float4(inV, out);
+            verifyResultsConvertFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat4Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertFloat4Float4Float4(inV, out);
+            verifyResultsConvertFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat4Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertFloat4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsCharFloat {
+        public byte inV;
+        public Floaty out;
+    }
+
+    private void checkConvertChar2Float2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 2, 0x5861e2161f489286l, true, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testConvertFloat2Char2Float2(inV, out);
+            verifyResultsConvertChar2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat2Char2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertFloat2Char2Float2(inV, out);
+            verifyResultsConvertChar2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat2Char2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertChar2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsCharFloat args = new ArgumentsCharFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%d", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertChar2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertChar3Float3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 3, 0x5863ab311563b364l, true, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testConvertFloat3Char3Float3(inV, out);
+            verifyResultsConvertChar3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat3Char3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertFloat3Char3Float3(inV, out);
+            verifyResultsConvertChar3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat3Char3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertChar3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsCharFloat args = new ArgumentsCharFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%d", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertChar3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertChar4Float4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 4, 0x5865744c0b7ed442l, true, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testConvertFloat4Char4Float4(inV, out);
+            verifyResultsConvertChar4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat4Char4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertFloat4Char4Float4(inV, out);
+            verifyResultsConvertChar4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat4Char4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertChar4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsCharFloat args = new ArgumentsCharFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%d", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertChar4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsUcharFloat {
+        public byte inV;
+        public Floaty out;
+    }
+
+    private void checkConvertUchar2Float2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 2, 0x7d30021dbb20ac31l, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testConvertFloat2Uchar2Float2(inV, out);
+            verifyResultsConvertUchar2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat2Uchar2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertFloat2Uchar2Float2(inV, out);
+            verifyResultsConvertUchar2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat2Uchar2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUchar2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsUcharFloat args = new ArgumentsUcharFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("0x%x", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertUchar2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertUchar3Float3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 3, 0x7d31cb38b13bcd0fl, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testConvertFloat3Uchar3Float3(inV, out);
+            verifyResultsConvertUchar3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat3Uchar3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertFloat3Uchar3Float3(inV, out);
+            verifyResultsConvertUchar3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat3Uchar3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUchar3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsUcharFloat args = new ArgumentsUcharFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("0x%x", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertUchar3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertUchar4Float4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 4, 0x7d339453a756ededl, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testConvertFloat4Uchar4Float4(inV, out);
+            verifyResultsConvertUchar4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat4Uchar4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertFloat4Uchar4Float4(inV, out);
+            verifyResultsConvertUchar4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat4Uchar4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUchar4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsUcharFloat args = new ArgumentsUcharFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("0x%x", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertUchar4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsShortFloat {
+        public short inV;
+        public Floaty out;
+    }
+
+    private void checkConvertShort2Float2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 2, 0x94ca184eff219172l, true, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testConvertFloat2Short2Float2(inV, out);
+            verifyResultsConvertShort2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat2Short2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertFloat2Short2Float2(inV, out);
+            verifyResultsConvertShort2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat2Short2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertShort2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsShortFloat args = new ArgumentsShortFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%d", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertShort2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertShort3Float3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 3, 0x94cbe169f53cb250l, true, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testConvertFloat3Short3Float3(inV, out);
+            verifyResultsConvertShort3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat3Short3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertFloat3Short3Float3(inV, out);
+            verifyResultsConvertShort3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat3Short3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertShort3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsShortFloat args = new ArgumentsShortFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%d", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertShort3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertShort4Float4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 4, 0x94cdaa84eb57d32el, true, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testConvertFloat4Short4Float4(inV, out);
+            verifyResultsConvertShort4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat4Short4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertFloat4Short4Float4(inV, out);
+            verifyResultsConvertShort4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat4Short4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertShort4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsShortFloat args = new ArgumentsShortFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%d", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertShort4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsUshortFloat {
+        public short inV;
+        public Floaty out;
+    }
+
+    private void checkConvertUshort2Float2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 2, 0xc36979962c6de12bl, false, 16);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testConvertFloat2Ushort2Float2(inV, out);
+            verifyResultsConvertUshort2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat2Ushort2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertFloat2Ushort2Float2(inV, out);
+            verifyResultsConvertUshort2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat2Ushort2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUshort2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsUshortFloat args = new ArgumentsUshortFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("0x%x", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertUshort2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertUshort3Float3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 3, 0xc36b42b122890209l, false, 16);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testConvertFloat3Ushort3Float3(inV, out);
+            verifyResultsConvertUshort3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat3Ushort3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertFloat3Ushort3Float3(inV, out);
+            verifyResultsConvertUshort3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat3Ushort3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUshort3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsUshortFloat args = new ArgumentsUshortFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("0x%x", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertUshort3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertUshort4Float4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 4, 0xc36d0bcc18a422e7l, false, 16);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testConvertFloat4Ushort4Float4(inV, out);
+            verifyResultsConvertUshort4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat4Ushort4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertFloat4Ushort4Float4(inV, out);
+            verifyResultsConvertUshort4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat4Ushort4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUshort4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsUshortFloat args = new ArgumentsUshortFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("0x%x", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertUshort4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsIntFloat {
+        public int inV;
+        public Floaty out;
+    }
+
+    private void checkConvertInt2Float2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 2, 0x2a52c7eb7402bfc5l, true, 31);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testConvertFloat2Int2Float2(inV, out);
+            verifyResultsConvertInt2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat2Int2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertFloat2Int2Float2(inV, out);
+            verifyResultsConvertInt2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat2Int2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertInt2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsIntFloat args = new ArgumentsIntFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%d", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertInt2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertInt3Float3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 3, 0x2a5491066a1de0a3l, true, 31);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testConvertFloat3Int3Float3(inV, out);
+            verifyResultsConvertInt3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat3Int3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertFloat3Int3Float3(inV, out);
+            verifyResultsConvertInt3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat3Int3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertInt3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsIntFloat args = new ArgumentsIntFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%d", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertInt3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertInt4Float4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 4, 0x2a565a2160390181l, true, 31);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testConvertFloat4Int4Float4(inV, out);
+            verifyResultsConvertInt4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat4Int4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertFloat4Int4Float4(inV, out);
+            verifyResultsConvertInt4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat4Int4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertInt4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsIntFloat args = new ArgumentsIntFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%d", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertInt4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsUintFloat {
+        public int inV;
+        public Floaty out;
+    }
+
+    private void checkConvertUint2Float2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 2, 0xd1e081390684cc46l, false, 32);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testConvertFloat2Uint2Float2(inV, out);
+            verifyResultsConvertUint2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat2Uint2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertFloat2Uint2Float2(inV, out);
+            verifyResultsConvertUint2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat2Uint2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUint2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsUintFloat args = new ArgumentsUintFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("0x%x", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertUint2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertUint3Float3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 3, 0xd1e24a53fc9fed24l, false, 32);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testConvertFloat3Uint3Float3(inV, out);
+            verifyResultsConvertUint3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat3Uint3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertFloat3Uint3Float3(inV, out);
+            verifyResultsConvertUint3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat3Uint3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUint3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsUintFloat args = new ArgumentsUintFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("0x%x", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertUint3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertUint4Float4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 4, 0xd1e4136ef2bb0e02l, false, 32);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testConvertFloat4Uint4Float4(inV, out);
+            verifyResultsConvertUint4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat4Uint4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertFloat4Uint4Float4(inV, out);
+            verifyResultsConvertUint4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat4Uint4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUint4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsUintFloat args = new ArgumentsUintFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("0x%x", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertUint4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsFloatChar {
+        public float inV;
+        public byte out;
+    }
+
+    private void checkConvertFloat2Char2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x239cb25829789662l, -1.2800000000000000000e+02, 1.2700000000000000000e+02);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
+            script.forEach_testConvertChar2Float2Char2(inV, out);
+            verifyResultsConvertFloat2Char2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar2Float2Char2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertChar2Float2Char2(inV, out);
+            verifyResultsConvertFloat2Char2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar2Float2Char2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertFloat2Char2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        byte[] arrayOut = new byte[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatChar args = new ArgumentsFloatChar();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertFloat2Char2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertFloat3Char3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x239cbcf988805b56l, -1.2800000000000000000e+02, 1.2700000000000000000e+02);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
+            script.forEach_testConvertChar3Float3Char3(inV, out);
+            verifyResultsConvertFloat3Char3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar3Float3Char3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertChar3Float3Char3(inV, out);
+            verifyResultsConvertFloat3Char3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar3Float3Char3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertFloat3Char3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        byte[] arrayOut = new byte[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatChar args = new ArgumentsFloatChar();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertFloat3Char3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertFloat4Char4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x239cc79ae788204al, -1.2800000000000000000e+02, 1.2700000000000000000e+02);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
+            script.forEach_testConvertChar4Float4Char4(inV, out);
+            verifyResultsConvertFloat4Char4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar4Float4Char4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertChar4Float4Char4(inV, out);
+            verifyResultsConvertFloat4Char4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar4Float4Char4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertFloat4Char4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        byte[] arrayOut = new byte[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatChar args = new ArgumentsFloatChar();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertFloat4Char4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsCharChar {
+        public byte inV;
+        public byte out;
+    }
+
+    private void checkConvertChar2Char2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 2, 0xd8618777d5086da2l, true, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
+            script.forEach_testConvertChar2Char2Char2(inV, out);
+            verifyResultsConvertChar2Char2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar2Char2Char2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertChar2Char2Char2(inV, out);
+            verifyResultsConvertChar2Char2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar2Char2Char2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertChar2Char2(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        byte[] arrayOut = new byte[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsCharChar args = new ArgumentsCharChar();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%d", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertChar2Char2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertChar3Char3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 3, 0xd861921934103296l, true, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
+            script.forEach_testConvertChar3Char3Char3(inV, out);
+            verifyResultsConvertChar3Char3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar3Char3Char3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertChar3Char3Char3(inV, out);
+            verifyResultsConvertChar3Char3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar3Char3Char3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertChar3Char3(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        byte[] arrayOut = new byte[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsCharChar args = new ArgumentsCharChar();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%d", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertChar3Char3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertChar4Char4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 4, 0xd8619cba9317f78al, true, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
+            script.forEach_testConvertChar4Char4Char4(inV, out);
+            verifyResultsConvertChar4Char4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar4Char4Char4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertChar4Char4Char4(inV, out);
+            verifyResultsConvertChar4Char4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar4Char4Char4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertChar4Char4(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        byte[] arrayOut = new byte[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsCharChar args = new ArgumentsCharChar();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%d", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertChar4Char4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsUcharChar {
+        public byte inV;
+        public byte out;
+    }
+
+    private void checkConvertUchar2Char2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 2, 0x7fef40c5678a7a23l, false, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
+            script.forEach_testConvertChar2Uchar2Char2(inV, out);
+            verifyResultsConvertUchar2Char2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar2Uchar2Char2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertChar2Uchar2Char2(inV, out);
+            verifyResultsConvertUchar2Char2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar2Uchar2Char2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUchar2Char2(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        byte[] arrayOut = new byte[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsUcharChar args = new ArgumentsUcharChar();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("0x%x", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertUchar2Char2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertUchar3Char3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 3, 0x7fef4b66c6923f17l, false, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
+            script.forEach_testConvertChar3Uchar3Char3(inV, out);
+            verifyResultsConvertUchar3Char3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar3Uchar3Char3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertChar3Uchar3Char3(inV, out);
+            verifyResultsConvertUchar3Char3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar3Uchar3Char3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUchar3Char3(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        byte[] arrayOut = new byte[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsUcharChar args = new ArgumentsUcharChar();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("0x%x", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertUchar3Char3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertUchar4Char4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 4, 0x7fef5608259a040bl, false, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
+            script.forEach_testConvertChar4Uchar4Char4(inV, out);
+            verifyResultsConvertUchar4Char4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar4Uchar4Char4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertChar4Uchar4Char4(inV, out);
+            verifyResultsConvertUchar4Char4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar4Uchar4Char4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUchar4Char4(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        byte[] arrayOut = new byte[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsUcharChar args = new ArgumentsUcharChar();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("0x%x", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertUchar4Char4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsShortChar {
+        public short inV;
+        public byte out;
+    }
+
+    private void checkConvertShort2Char2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 2, 0x68ab650215c60866l, true, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
+            script.forEach_testConvertChar2Short2Char2(inV, out);
+            verifyResultsConvertShort2Char2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar2Short2Char2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertChar2Short2Char2(inV, out);
+            verifyResultsConvertShort2Char2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar2Short2Char2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertShort2Char2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        byte[] arrayOut = new byte[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsShortChar args = new ArgumentsShortChar();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%d", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertShort2Char2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertShort3Char3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 3, 0x68ab6fa374cdcd5al, true, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
+            script.forEach_testConvertChar3Short3Char3(inV, out);
+            verifyResultsConvertShort3Char3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar3Short3Char3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertChar3Short3Char3(inV, out);
+            verifyResultsConvertShort3Char3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar3Short3Char3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertShort3Char3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        byte[] arrayOut = new byte[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsShortChar args = new ArgumentsShortChar();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%d", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertShort3Char3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertShort4Char4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 4, 0x68ab7a44d3d5924el, true, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
+            script.forEach_testConvertChar4Short4Char4(inV, out);
+            verifyResultsConvertShort4Char4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar4Short4Char4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertChar4Short4Char4(inV, out);
+            verifyResultsConvertShort4Char4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar4Short4Char4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertShort4Char4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        byte[] arrayOut = new byte[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsShortChar args = new ArgumentsShortChar();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%d", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertShort4Char4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsUshortChar {
+        public short inV;
+        public byte out;
+    }
+
+    private void checkConvertUshort2Char2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 2, 0x8d798509b19e2211l, false, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
+            script.forEach_testConvertChar2Ushort2Char2(inV, out);
+            verifyResultsConvertUshort2Char2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar2Ushort2Char2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertChar2Ushort2Char2(inV, out);
+            verifyResultsConvertUshort2Char2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar2Ushort2Char2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUshort2Char2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        byte[] arrayOut = new byte[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsUshortChar args = new ArgumentsUshortChar();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("0x%x", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertUshort2Char2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertUshort3Char3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 3, 0x8d798fab10a5e705l, false, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
+            script.forEach_testConvertChar3Ushort3Char3(inV, out);
+            verifyResultsConvertUshort3Char3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar3Ushort3Char3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertChar3Ushort3Char3(inV, out);
+            verifyResultsConvertUshort3Char3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar3Ushort3Char3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUshort3Char3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        byte[] arrayOut = new byte[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsUshortChar args = new ArgumentsUshortChar();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("0x%x", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertUshort3Char3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertUshort4Char4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 4, 0x8d799a4c6fadabf9l, false, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
+            script.forEach_testConvertChar4Ushort4Char4(inV, out);
+            verifyResultsConvertUshort4Char4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar4Ushort4Char4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertChar4Ushort4Char4(inV, out);
+            verifyResultsConvertUshort4Char4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar4Ushort4Char4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUshort4Char4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        byte[] arrayOut = new byte[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsUshortChar args = new ArgumentsUshortChar();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("0x%x", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertUshort4Char4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsIntChar {
+        public int inV;
+        public byte out;
+    }
+
+    private void checkConvertInt2Char2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 2, 0xd74f5147364256dfl, true, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
+            script.forEach_testConvertChar2Int2Char2(inV, out);
+            verifyResultsConvertInt2Char2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar2Int2Char2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertChar2Int2Char2(inV, out);
+            verifyResultsConvertInt2Char2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar2Int2Char2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertInt2Char2(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        byte[] arrayOut = new byte[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsIntChar args = new ArgumentsIntChar();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%d", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertInt2Char2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertInt3Char3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 3, 0xd74f5be8954a1bd3l, true, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
+            script.forEach_testConvertChar3Int3Char3(inV, out);
+            verifyResultsConvertInt3Char3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar3Int3Char3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertChar3Int3Char3(inV, out);
+            verifyResultsConvertInt3Char3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar3Int3Char3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertInt3Char3(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        byte[] arrayOut = new byte[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsIntChar args = new ArgumentsIntChar();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%d", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertInt3Char3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertInt4Char4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 4, 0xd74f6689f451e0c7l, true, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
+            script.forEach_testConvertChar4Int4Char4(inV, out);
+            verifyResultsConvertInt4Char4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar4Int4Char4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertChar4Int4Char4(inV, out);
+            verifyResultsConvertInt4Char4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar4Int4Char4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertInt4Char4(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        byte[] arrayOut = new byte[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsIntChar args = new ArgumentsIntChar();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%d", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertInt4Char4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsUintChar {
+        public int inV;
+        public byte out;
+    }
+
+    private void checkConvertUint2Char2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 2, 0xe71d083133b67ae2l, false, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
+            script.forEach_testConvertChar2Uint2Char2(inV, out);
+            verifyResultsConvertUint2Char2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar2Uint2Char2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertChar2Uint2Char2(inV, out);
+            verifyResultsConvertUint2Char2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar2Uint2Char2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUint2Char2(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        byte[] arrayOut = new byte[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsUintChar args = new ArgumentsUintChar();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("0x%x", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertUint2Char2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertUint3Char3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 3, 0xe71d12d292be3fd6l, false, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
+            script.forEach_testConvertChar3Uint3Char3(inV, out);
+            verifyResultsConvertUint3Char3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar3Uint3Char3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertChar3Uint3Char3(inV, out);
+            verifyResultsConvertUint3Char3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar3Uint3Char3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUint3Char3(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        byte[] arrayOut = new byte[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsUintChar args = new ArgumentsUintChar();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("0x%x", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertUint3Char3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertUint4Char4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 4, 0xe71d1d73f1c604cal, false, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
+            script.forEach_testConvertChar4Uint4Char4(inV, out);
+            verifyResultsConvertUint4Char4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar4Uint4Char4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertChar4Uint4Char4(inV, out);
+            verifyResultsConvertUint4Char4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar4Uint4Char4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUint4Char4(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        byte[] arrayOut = new byte[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsUintChar args = new ArgumentsUintChar();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("0x%x", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertUint4Char4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsFloatUchar {
+        public float inV;
+        public byte out;
+    }
+
+    private void checkConvertFloat2Uchar2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xfb52b2f4fac15b79l, 0.0000000000000000000e+00, 2.5500000000000000000e+02);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
+            script.forEach_testConvertUchar2Float2Uchar2(inV, out);
+            verifyResultsConvertFloat2Uchar2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar2Float2Uchar2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUchar2Float2Uchar2(inV, out);
+            verifyResultsConvertFloat2Uchar2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar2Float2Uchar2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertFloat2Uchar2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        byte[] arrayOut = new byte[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatUchar args = new ArgumentsFloatUchar();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertFloat2Uchar2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertFloat3Uchar3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xfb547c0ff0dc7c57l, 0.0000000000000000000e+00, 2.5500000000000000000e+02);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
+            script.forEach_testConvertUchar3Float3Uchar3(inV, out);
+            verifyResultsConvertFloat3Uchar3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar3Float3Uchar3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUchar3Float3Uchar3(inV, out);
+            verifyResultsConvertFloat3Uchar3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar3Float3Uchar3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertFloat3Uchar3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        byte[] arrayOut = new byte[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatUchar args = new ArgumentsFloatUchar();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertFloat3Uchar3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertFloat4Uchar4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xfb56452ae6f79d35l, 0.0000000000000000000e+00, 2.5500000000000000000e+02);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
+            script.forEach_testConvertUchar4Float4Uchar4(inV, out);
+            verifyResultsConvertFloat4Uchar4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar4Float4Uchar4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUchar4Float4Uchar4(inV, out);
+            verifyResultsConvertFloat4Uchar4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar4Float4Uchar4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertFloat4Uchar4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        byte[] arrayOut = new byte[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatUchar args = new ArgumentsFloatUchar();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertFloat4Uchar4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsCharUchar {
+        public byte inV;
+        public byte out;
+    }
+
+    private void checkConvertChar2Uchar2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 2, 0x58627f46cbea8339l, false, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
+            script.forEach_testConvertUchar2Char2Uchar2(inV, out);
+            verifyResultsConvertChar2Uchar2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar2Char2Uchar2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUchar2Char2Uchar2(inV, out);
+            verifyResultsConvertChar2Uchar2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar2Char2Uchar2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertChar2Uchar2(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        byte[] arrayOut = new byte[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsCharUchar args = new ArgumentsCharUchar();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%d", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertChar2Uchar2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertChar3Uchar3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 3, 0x58644861c205a417l, false, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
+            script.forEach_testConvertUchar3Char3Uchar3(inV, out);
+            verifyResultsConvertChar3Uchar3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar3Char3Uchar3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUchar3Char3Uchar3(inV, out);
+            verifyResultsConvertChar3Uchar3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar3Char3Uchar3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertChar3Uchar3(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        byte[] arrayOut = new byte[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsCharUchar args = new ArgumentsCharUchar();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%d", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertChar3Uchar3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertChar4Uchar4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 4, 0x5866117cb820c4f5l, false, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
+            script.forEach_testConvertUchar4Char4Uchar4(inV, out);
+            verifyResultsConvertChar4Uchar4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar4Char4Uchar4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUchar4Char4Uchar4(inV, out);
+            verifyResultsConvertChar4Uchar4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar4Char4Uchar4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertChar4Uchar4(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        byte[] arrayOut = new byte[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsCharUchar args = new ArgumentsCharUchar();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%d", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertChar4Uchar4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsUcharUchar {
+        public byte inV;
+        public byte out;
+    }
+
+    private void checkConvertUchar2Uchar2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 2, 0x7d309f4e67c29ce4l, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
+            script.forEach_testConvertUchar2Uchar2Uchar2(inV, out);
+            verifyResultsConvertUchar2Uchar2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar2Uchar2Uchar2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUchar2Uchar2Uchar2(inV, out);
+            verifyResultsConvertUchar2Uchar2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar2Uchar2Uchar2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUchar2Uchar2(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        byte[] arrayOut = new byte[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsUcharUchar args = new ArgumentsUcharUchar();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("0x%x", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertUchar2Uchar2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertUchar3Uchar3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 3, 0x7d3268695dddbdc2l, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
+            script.forEach_testConvertUchar3Uchar3Uchar3(inV, out);
+            verifyResultsConvertUchar3Uchar3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar3Uchar3Uchar3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUchar3Uchar3Uchar3(inV, out);
+            verifyResultsConvertUchar3Uchar3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar3Uchar3Uchar3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUchar3Uchar3(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        byte[] arrayOut = new byte[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsUcharUchar args = new ArgumentsUcharUchar();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("0x%x", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertUchar3Uchar3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertUchar4Uchar4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 4, 0x7d34318453f8dea0l, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
+            script.forEach_testConvertUchar4Uchar4Uchar4(inV, out);
+            verifyResultsConvertUchar4Uchar4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar4Uchar4Uchar4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUchar4Uchar4Uchar4(inV, out);
+            verifyResultsConvertUchar4Uchar4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar4Uchar4Uchar4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUchar4Uchar4(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        byte[] arrayOut = new byte[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsUcharUchar args = new ArgumentsUcharUchar();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("0x%x", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertUchar4Uchar4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsShortUchar {
+        public short inV;
+        public byte out;
+    }
+
+    private void checkConvertShort2Uchar2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 2, 0x94cab57fabc38225l, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
+            script.forEach_testConvertUchar2Short2Uchar2(inV, out);
+            verifyResultsConvertShort2Uchar2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar2Short2Uchar2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUchar2Short2Uchar2(inV, out);
+            verifyResultsConvertShort2Uchar2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar2Short2Uchar2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertShort2Uchar2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        byte[] arrayOut = new byte[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsShortUchar args = new ArgumentsShortUchar();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%d", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertShort2Uchar2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertShort3Uchar3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 3, 0x94cc7e9aa1dea303l, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
+            script.forEach_testConvertUchar3Short3Uchar3(inV, out);
+            verifyResultsConvertShort3Uchar3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar3Short3Uchar3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUchar3Short3Uchar3(inV, out);
+            verifyResultsConvertShort3Uchar3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar3Short3Uchar3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertShort3Uchar3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        byte[] arrayOut = new byte[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsShortUchar args = new ArgumentsShortUchar();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%d", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertShort3Uchar3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertShort4Uchar4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 4, 0x94ce47b597f9c3e1l, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
+            script.forEach_testConvertUchar4Short4Uchar4(inV, out);
+            verifyResultsConvertShort4Uchar4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar4Short4Uchar4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUchar4Short4Uchar4(inV, out);
+            verifyResultsConvertShort4Uchar4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar4Short4Uchar4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertShort4Uchar4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        byte[] arrayOut = new byte[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsShortUchar args = new ArgumentsShortUchar();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%d", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertShort4Uchar4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsUshortUchar {
+        public short inV;
+        public byte out;
+    }
+
+    private void checkConvertUshort2Uchar2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 2, 0xc36a16c6d90fd1del, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
+            script.forEach_testConvertUchar2Ushort2Uchar2(inV, out);
+            verifyResultsConvertUshort2Uchar2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar2Ushort2Uchar2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUchar2Ushort2Uchar2(inV, out);
+            verifyResultsConvertUshort2Uchar2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar2Ushort2Uchar2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUshort2Uchar2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        byte[] arrayOut = new byte[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsUshortUchar args = new ArgumentsUshortUchar();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("0x%x", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertUshort2Uchar2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertUshort3Uchar3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 3, 0xc36bdfe1cf2af2bcl, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
+            script.forEach_testConvertUchar3Ushort3Uchar3(inV, out);
+            verifyResultsConvertUshort3Uchar3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar3Ushort3Uchar3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUchar3Ushort3Uchar3(inV, out);
+            verifyResultsConvertUshort3Uchar3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar3Ushort3Uchar3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUshort3Uchar3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        byte[] arrayOut = new byte[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsUshortUchar args = new ArgumentsUshortUchar();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("0x%x", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertUshort3Uchar3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertUshort4Uchar4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 4, 0xc36da8fcc546139al, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
+            script.forEach_testConvertUchar4Ushort4Uchar4(inV, out);
+            verifyResultsConvertUshort4Uchar4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar4Ushort4Uchar4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUchar4Ushort4Uchar4(inV, out);
+            verifyResultsConvertUshort4Uchar4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar4Ushort4Uchar4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUshort4Uchar4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        byte[] arrayOut = new byte[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsUshortUchar args = new ArgumentsUshortUchar();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("0x%x", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertUshort4Uchar4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsIntUchar {
+        public int inV;
+        public byte out;
+    }
+
+    private void checkConvertInt2Uchar2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 2, 0x2a53651c20a4b078l, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
+            script.forEach_testConvertUchar2Int2Uchar2(inV, out);
+            verifyResultsConvertInt2Uchar2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar2Int2Uchar2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUchar2Int2Uchar2(inV, out);
+            verifyResultsConvertInt2Uchar2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar2Int2Uchar2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertInt2Uchar2(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        byte[] arrayOut = new byte[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsIntUchar args = new ArgumentsIntUchar();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%d", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertInt2Uchar2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertInt3Uchar3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 3, 0x2a552e3716bfd156l, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
+            script.forEach_testConvertUchar3Int3Uchar3(inV, out);
+            verifyResultsConvertInt3Uchar3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar3Int3Uchar3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUchar3Int3Uchar3(inV, out);
+            verifyResultsConvertInt3Uchar3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar3Int3Uchar3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertInt3Uchar3(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        byte[] arrayOut = new byte[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsIntUchar args = new ArgumentsIntUchar();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%d", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertInt3Uchar3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertInt4Uchar4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 4, 0x2a56f7520cdaf234l, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
+            script.forEach_testConvertUchar4Int4Uchar4(inV, out);
+            verifyResultsConvertInt4Uchar4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar4Int4Uchar4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUchar4Int4Uchar4(inV, out);
+            verifyResultsConvertInt4Uchar4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar4Int4Uchar4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertInt4Uchar4(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        byte[] arrayOut = new byte[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsIntUchar args = new ArgumentsIntUchar();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%d", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertInt4Uchar4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsUintUchar {
+        public int inV;
+        public byte out;
+    }
+
+    private void checkConvertUint2Uchar2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 2, 0xd1e11e69b326bcf9l, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
+            script.forEach_testConvertUchar2Uint2Uchar2(inV, out);
+            verifyResultsConvertUint2Uchar2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar2Uint2Uchar2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUchar2Uint2Uchar2(inV, out);
+            verifyResultsConvertUint2Uchar2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar2Uint2Uchar2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUint2Uchar2(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        byte[] arrayOut = new byte[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsUintUchar args = new ArgumentsUintUchar();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("0x%x", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertUint2Uchar2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertUint3Uchar3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 3, 0xd1e2e784a941ddd7l, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
+            script.forEach_testConvertUchar3Uint3Uchar3(inV, out);
+            verifyResultsConvertUint3Uchar3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar3Uint3Uchar3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUchar3Uint3Uchar3(inV, out);
+            verifyResultsConvertUint3Uchar3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar3Uint3Uchar3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUint3Uchar3(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        byte[] arrayOut = new byte[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsUintUchar args = new ArgumentsUintUchar();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("0x%x", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertUint3Uchar3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertUint4Uchar4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 4, 0xd1e4b09f9f5cfeb5l, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
+            script.forEach_testConvertUchar4Uint4Uchar4(inV, out);
+            verifyResultsConvertUint4Uchar4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar4Uint4Uchar4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUchar4Uint4Uchar4(inV, out);
+            verifyResultsConvertUint4Uchar4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar4Uint4Uchar4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUint4Uchar4(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        byte[] arrayOut = new byte[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsUintUchar args = new ArgumentsUintUchar();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("0x%x", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertUint4Uchar4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsFloatShort {
+        public float inV;
+        public short out;
+    }
+
+    private void checkConvertFloat2Short2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xfb529ef98fcf2692l, -3.2768000000000000000e+04, 3.2767000000000000000e+04);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
+            script.forEach_testConvertShort2Float2Short2(inV, out);
+            verifyResultsConvertFloat2Short2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort2Float2Short2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertShort2Float2Short2(inV, out);
+            verifyResultsConvertFloat2Short2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort2Float2Short2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertFloat2Short2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatShort args = new ArgumentsFloatShort();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertFloat2Short2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertFloat3Short3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xfb54681485ea4770l, -3.2768000000000000000e+04, 3.2767000000000000000e+04);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
+            script.forEach_testConvertShort3Float3Short3(inV, out);
+            verifyResultsConvertFloat3Short3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort3Float3Short3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertShort3Float3Short3(inV, out);
+            verifyResultsConvertFloat3Short3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort3Float3Short3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertFloat3Short3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatShort args = new ArgumentsFloatShort();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertFloat3Short3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertFloat4Short4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xfb56312f7c05684el, -3.2768000000000000000e+04, 3.2767000000000000000e+04);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
+            script.forEach_testConvertShort4Float4Short4(inV, out);
+            verifyResultsConvertFloat4Short4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort4Float4Short4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertShort4Float4Short4(inV, out);
+            verifyResultsConvertFloat4Short4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort4Float4Short4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertFloat4Short4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatShort args = new ArgumentsFloatShort();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertFloat4Short4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsCharShort {
+        public byte inV;
+        public short out;
+    }
+
+    private void checkConvertChar2Short2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 2, 0x58626b4b60f84e52l, true, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
+            script.forEach_testConvertShort2Char2Short2(inV, out);
+            verifyResultsConvertChar2Short2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort2Char2Short2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertShort2Char2Short2(inV, out);
+            verifyResultsConvertChar2Short2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort2Char2Short2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertChar2Short2(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsCharShort args = new ArgumentsCharShort();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%d", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertChar2Short2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertChar3Short3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 3, 0x5864346657136f30l, true, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
+            script.forEach_testConvertShort3Char3Short3(inV, out);
+            verifyResultsConvertChar3Short3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort3Char3Short3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertShort3Char3Short3(inV, out);
+            verifyResultsConvertChar3Short3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort3Char3Short3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertChar3Short3(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsCharShort args = new ArgumentsCharShort();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%d", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertChar3Short3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertChar4Short4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 4, 0x5865fd814d2e900el, true, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
+            script.forEach_testConvertShort4Char4Short4(inV, out);
+            verifyResultsConvertChar4Short4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort4Char4Short4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertShort4Char4Short4(inV, out);
+            verifyResultsConvertChar4Short4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort4Char4Short4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertChar4Short4(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsCharShort args = new ArgumentsCharShort();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%d", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertChar4Short4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsUcharShort {
+        public byte inV;
+        public short out;
+    }
+
+    private void checkConvertUchar2Short2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 2, 0x7d308b52fcd067fdl, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
+            script.forEach_testConvertShort2Uchar2Short2(inV, out);
+            verifyResultsConvertUchar2Short2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort2Uchar2Short2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertShort2Uchar2Short2(inV, out);
+            verifyResultsConvertUchar2Short2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort2Uchar2Short2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUchar2Short2(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsUcharShort args = new ArgumentsUcharShort();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("0x%x", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertUchar2Short2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertUchar3Short3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 3, 0x7d32546df2eb88dbl, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
+            script.forEach_testConvertShort3Uchar3Short3(inV, out);
+            verifyResultsConvertUchar3Short3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort3Uchar3Short3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertShort3Uchar3Short3(inV, out);
+            verifyResultsConvertUchar3Short3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort3Uchar3Short3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUchar3Short3(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsUcharShort args = new ArgumentsUcharShort();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("0x%x", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertUchar3Short3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertUchar4Short4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 4, 0x7d341d88e906a9b9l, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
+            script.forEach_testConvertShort4Uchar4Short4(inV, out);
+            verifyResultsConvertUchar4Short4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort4Uchar4Short4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertShort4Uchar4Short4(inV, out);
+            verifyResultsConvertUchar4Short4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort4Uchar4Short4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUchar4Short4(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsUcharShort args = new ArgumentsUcharShort();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("0x%x", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertUchar4Short4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsShortShort {
+        public short inV;
+        public short out;
+    }
+
+    private void checkConvertShort2Short2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 2, 0x94caa18440d14d3el, true, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
+            script.forEach_testConvertShort2Short2Short2(inV, out);
+            verifyResultsConvertShort2Short2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort2Short2Short2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertShort2Short2Short2(inV, out);
+            verifyResultsConvertShort2Short2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort2Short2Short2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertShort2Short2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsShortShort args = new ArgumentsShortShort();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%d", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertShort2Short2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertShort3Short3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 3, 0x94cc6a9f36ec6e1cl, true, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
+            script.forEach_testConvertShort3Short3Short3(inV, out);
+            verifyResultsConvertShort3Short3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort3Short3Short3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertShort3Short3Short3(inV, out);
+            verifyResultsConvertShort3Short3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort3Short3Short3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertShort3Short3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsShortShort args = new ArgumentsShortShort();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%d", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertShort3Short3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertShort4Short4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 4, 0x94ce33ba2d078efal, true, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
+            script.forEach_testConvertShort4Short4Short4(inV, out);
+            verifyResultsConvertShort4Short4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort4Short4Short4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertShort4Short4Short4(inV, out);
+            verifyResultsConvertShort4Short4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort4Short4Short4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertShort4Short4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsShortShort args = new ArgumentsShortShort();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%d", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertShort4Short4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsUshortShort {
+        public short inV;
+        public short out;
+    }
+
+    private void checkConvertUshort2Short2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 2, 0xc36a02cb6e1d9cf7l, false, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
+            script.forEach_testConvertShort2Ushort2Short2(inV, out);
+            verifyResultsConvertUshort2Short2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort2Ushort2Short2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertShort2Ushort2Short2(inV, out);
+            verifyResultsConvertUshort2Short2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort2Ushort2Short2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUshort2Short2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsUshortShort args = new ArgumentsUshortShort();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("0x%x", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertUshort2Short2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertUshort3Short3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 3, 0xc36bcbe66438bdd5l, false, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
+            script.forEach_testConvertShort3Ushort3Short3(inV, out);
+            verifyResultsConvertUshort3Short3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort3Ushort3Short3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertShort3Ushort3Short3(inV, out);
+            verifyResultsConvertUshort3Short3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort3Ushort3Short3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUshort3Short3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsUshortShort args = new ArgumentsUshortShort();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("0x%x", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertUshort3Short3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertUshort4Short4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 4, 0xc36d95015a53deb3l, false, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
+            script.forEach_testConvertShort4Ushort4Short4(inV, out);
+            verifyResultsConvertUshort4Short4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort4Ushort4Short4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertShort4Ushort4Short4(inV, out);
+            verifyResultsConvertUshort4Short4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort4Ushort4Short4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUshort4Short4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsUshortShort args = new ArgumentsUshortShort();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("0x%x", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertUshort4Short4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsIntShort {
+        public int inV;
+        public short out;
+    }
+
+    private void checkConvertInt2Short2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 2, 0x2a535120b5b27b91l, true, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
+            script.forEach_testConvertShort2Int2Short2(inV, out);
+            verifyResultsConvertInt2Short2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort2Int2Short2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertShort2Int2Short2(inV, out);
+            verifyResultsConvertInt2Short2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort2Int2Short2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertInt2Short2(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsIntShort args = new ArgumentsIntShort();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%d", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertInt2Short2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertInt3Short3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 3, 0x2a551a3babcd9c6fl, true, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
+            script.forEach_testConvertShort3Int3Short3(inV, out);
+            verifyResultsConvertInt3Short3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort3Int3Short3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertShort3Int3Short3(inV, out);
+            verifyResultsConvertInt3Short3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort3Int3Short3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertInt3Short3(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsIntShort args = new ArgumentsIntShort();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%d", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertInt3Short3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertInt4Short4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 4, 0x2a56e356a1e8bd4dl, true, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
+            script.forEach_testConvertShort4Int4Short4(inV, out);
+            verifyResultsConvertInt4Short4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort4Int4Short4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertShort4Int4Short4(inV, out);
+            verifyResultsConvertInt4Short4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort4Int4Short4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertInt4Short4(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsIntShort args = new ArgumentsIntShort();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%d", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertInt4Short4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsUintShort {
+        public int inV;
+        public short out;
+    }
+
+    private void checkConvertUint2Short2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 2, 0xd1e10a6e48348812l, false, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
+            script.forEach_testConvertShort2Uint2Short2(inV, out);
+            verifyResultsConvertUint2Short2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort2Uint2Short2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertShort2Uint2Short2(inV, out);
+            verifyResultsConvertUint2Short2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort2Uint2Short2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUint2Short2(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsUintShort args = new ArgumentsUintShort();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("0x%x", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertUint2Short2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertUint3Short3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 3, 0xd1e2d3893e4fa8f0l, false, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
+            script.forEach_testConvertShort3Uint3Short3(inV, out);
+            verifyResultsConvertUint3Short3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort3Uint3Short3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertShort3Uint3Short3(inV, out);
+            verifyResultsConvertUint3Short3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort3Uint3Short3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUint3Short3(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsUintShort args = new ArgumentsUintShort();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("0x%x", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertUint3Short3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertUint4Short4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 4, 0xd1e49ca4346ac9cel, false, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
+            script.forEach_testConvertShort4Uint4Short4(inV, out);
+            verifyResultsConvertUint4Short4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort4Uint4Short4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertShort4Uint4Short4(inV, out);
+            verifyResultsConvertUint4Short4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort4Uint4Short4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUint4Short4(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsUintShort args = new ArgumentsUintShort();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("0x%x", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertUint4Short4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsFloatUshort {
+        public float inV;
+        public short out;
+    }
+
+    private void checkConvertFloat2Ushort2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x36e4b950b708416fl, 0.0000000000000000000e+00, 6.5535000000000000000e+04);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
+            script.forEach_testConvertUshort2Float2Ushort2(inV, out);
+            verifyResultsConvertFloat2Ushort2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort2Float2Ushort2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUshort2Float2Ushort2(inV, out);
+            verifyResultsConvertFloat2Ushort2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort2Float2Ushort2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertFloat2Ushort2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatUshort args = new ArgumentsFloatUshort();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertFloat2Ushort2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertFloat3Ushort3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x373180d80d63d29bl, 0.0000000000000000000e+00, 6.5535000000000000000e+04);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
+            script.forEach_testConvertUshort3Float3Ushort3(inV, out);
+            verifyResultsConvertFloat3Ushort3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort3Float3Ushort3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUshort3Float3Ushort3(inV, out);
+            verifyResultsConvertFloat3Ushort3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort3Float3Ushort3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertFloat3Ushort3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatUshort args = new ArgumentsFloatUshort();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertFloat3Ushort3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertFloat4Ushort4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x377e485f63bf63c7l, 0.0000000000000000000e+00, 6.5535000000000000000e+04);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
+            script.forEach_testConvertUshort4Float4Ushort4(inV, out);
+            verifyResultsConvertFloat4Ushort4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort4Float4Ushort4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUshort4Float4Ushort4(inV, out);
+            verifyResultsConvertFloat4Ushort4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort4Float4Ushort4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertFloat4Ushort4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatUshort args = new ArgumentsFloatUshort();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertFloat4Ushort4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsCharUshort {
+        public byte inV;
+        public short out;
+    }
+
+    private void checkConvertChar2Ushort2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 2, 0xd88c0b0ed8f1eeafl, false, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
+            script.forEach_testConvertUshort2Char2Ushort2(inV, out);
+            verifyResultsConvertChar2Ushort2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort2Char2Ushort2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUshort2Char2Ushort2(inV, out);
+            verifyResultsConvertChar2Ushort2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort2Char2Ushort2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertChar2Ushort2(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsCharUshort args = new ArgumentsCharUshort();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%d", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertChar2Ushort2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertChar3Ushort3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 3, 0xd8d8d2962f4d7fdbl, false, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
+            script.forEach_testConvertUshort3Char3Ushort3(inV, out);
+            verifyResultsConvertChar3Ushort3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort3Char3Ushort3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUshort3Char3Ushort3(inV, out);
+            verifyResultsConvertChar3Ushort3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort3Char3Ushort3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertChar3Ushort3(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsCharUshort args = new ArgumentsCharUshort();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%d", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertChar3Ushort3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertChar4Ushort4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 4, 0xd9259a1d85a91107l, false, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
+            script.forEach_testConvertUshort4Char4Ushort4(inV, out);
+            verifyResultsConvertChar4Ushort4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort4Char4Ushort4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUshort4Char4Ushort4(inV, out);
+            verifyResultsConvertChar4Ushort4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort4Char4Ushort4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertChar4Ushort4(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsCharUshort args = new ArgumentsCharUshort();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%d", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertChar4Ushort4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsUcharUshort {
+        public byte inV;
+        public short out;
+    }
+
+    private void checkConvertUchar2Ushort2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 2, 0x72b6c56063e3e68l, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
+            script.forEach_testConvertUshort2Uchar2Ushort2(inV, out);
+            verifyResultsConvertUchar2Ushort2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort2Uchar2Ushort2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUshort2Uchar2Ushort2(inV, out);
+            verifyResultsConvertUchar2Ushort2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort2Uchar2Ushort2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUchar2Ushort2(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsUcharUshort args = new ArgumentsUcharUshort();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("0x%x", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertUchar2Ushort2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertUchar3Ushort3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 3, 0x77833dd5c99cf94l, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
+            script.forEach_testConvertUshort3Uchar3Ushort3(inV, out);
+            verifyResultsConvertUchar3Ushort3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort3Uchar3Ushort3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUshort3Uchar3Ushort3(inV, out);
+            verifyResultsConvertUchar3Ushort3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort3Uchar3Ushort3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUchar3Ushort3(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsUcharUshort args = new ArgumentsUcharUshort();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("0x%x", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertUchar3Ushort3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertUchar4Ushort4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 4, 0x7c4fb64b2f560c0l, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
+            script.forEach_testConvertUshort4Uchar4Ushort4(inV, out);
+            verifyResultsConvertUchar4Ushort4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort4Uchar4Ushort4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUshort4Uchar4Ushort4(inV, out);
+            verifyResultsConvertUchar4Ushort4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort4Uchar4Ushort4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUchar4Ushort4(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsUcharUshort args = new ArgumentsUcharUshort();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("0x%x", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertUchar4Ushort4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsShortUshort {
+        public short inV;
+        public short out;
+    }
+
+    private void checkConvertShort2Ushort2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 2, 0xfe0d269c7264c053l, false, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
+            script.forEach_testConvertUshort2Short2Ushort2(inV, out);
+            verifyResultsConvertShort2Ushort2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort2Short2Ushort2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUshort2Short2Ushort2(inV, out);
+            verifyResultsConvertShort2Ushort2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort2Short2Ushort2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertShort2Ushort2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsShortUshort args = new ArgumentsShortUshort();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%d", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertShort2Ushort2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertShort3Ushort3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 3, 0xfe59ee23c8c0517fl, false, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
+            script.forEach_testConvertUshort3Short3Ushort3(inV, out);
+            verifyResultsConvertShort3Ushort3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort3Short3Ushort3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUshort3Short3Ushort3(inV, out);
+            verifyResultsConvertShort3Ushort3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort3Short3Ushort3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertShort3Ushort3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsShortUshort args = new ArgumentsShortUshort();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%d", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertShort3Ushort3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertShort4Ushort4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 4, 0xfea6b5ab1f1be2abl, false, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
+            script.forEach_testConvertUshort4Short4Ushort4(inV, out);
+            verifyResultsConvertShort4Ushort4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort4Short4Ushort4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUshort4Short4Ushort4(inV, out);
+            verifyResultsConvertShort4Ushort4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort4Short4Ushort4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertShort4Ushort4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsShortUshort args = new ArgumentsShortUshort();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%d", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertShort4Ushort4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsUshortUshort {
+        public short inV;
+        public short out;
+    }
+
+    private void checkConvertUshort2Ushort2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 2, 0xd2d27d910e362466l, false, 16);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
+            script.forEach_testConvertUshort2Ushort2Ushort2(inV, out);
+            verifyResultsConvertUshort2Ushort2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort2Ushort2Ushort2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUshort2Ushort2Ushort2(inV, out);
+            verifyResultsConvertUshort2Ushort2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort2Ushort2Ushort2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUshort2Ushort2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsUshortUshort args = new ArgumentsUshortUshort();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("0x%x", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertUshort2Ushort2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertUshort3Ushort3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 3, 0xd31f45186491b592l, false, 16);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
+            script.forEach_testConvertUshort3Ushort3Ushort3(inV, out);
+            verifyResultsConvertUshort3Ushort3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort3Ushort3Ushort3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUshort3Ushort3Ushort3(inV, out);
+            verifyResultsConvertUshort3Ushort3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort3Ushort3Ushort3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUshort3Ushort3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsUshortUshort args = new ArgumentsUshortUshort();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("0x%x", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertUshort3Ushort3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertUshort4Ushort4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 4, 0xd36c0c9fbaed46bel, false, 16);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
+            script.forEach_testConvertUshort4Ushort4Ushort4(inV, out);
+            verifyResultsConvertUshort4Ushort4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort4Ushort4Ushort4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUshort4Ushort4Ushort4(inV, out);
+            verifyResultsConvertUshort4Ushort4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort4Ushort4Ushort4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUshort4Ushort4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsUshortUshort args = new ArgumentsUshortUshort();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("0x%x", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertUshort4Ushort4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsIntUshort {
+        public int inV;
+        public short out;
+    }
+
+    private void checkConvertInt2Ushort2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 2, 0x1c02a5e414378844l, false, 16);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
+            script.forEach_testConvertUshort2Int2Ushort2(inV, out);
+            verifyResultsConvertInt2Ushort2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort2Int2Ushort2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUshort2Int2Ushort2(inV, out);
+            verifyResultsConvertInt2Ushort2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort2Int2Ushort2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertInt2Ushort2(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsIntUshort args = new ArgumentsIntUshort();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%d", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertInt2Ushort2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertInt3Ushort3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 3, 0x1c4f6d6b6a931970l, false, 16);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
+            script.forEach_testConvertUshort3Int3Ushort3(inV, out);
+            verifyResultsConvertInt3Ushort3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort3Int3Ushort3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUshort3Int3Ushort3(inV, out);
+            verifyResultsConvertInt3Ushort3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort3Int3Ushort3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertInt3Ushort3(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsIntUshort args = new ArgumentsIntUshort();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%d", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertInt3Ushort3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertInt4Ushort4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 4, 0x1c9c34f2c0eeaa9cl, false, 16);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
+            script.forEach_testConvertUshort4Int4Ushort4(inV, out);
+            verifyResultsConvertInt4Ushort4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort4Int4Ushort4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUshort4Int4Ushort4(inV, out);
+            verifyResultsConvertInt4Ushort4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort4Int4Ushort4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertInt4Ushort4(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsIntUshort args = new ArgumentsIntUshort();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%d", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertInt4Ushort4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsUintUshort {
+        public int inV;
+        public short out;
+    }
+
+    private void checkConvertUint2Ushort2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 2, 0x40d0c5ebb00fa1efl, false, 16);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
+            script.forEach_testConvertUshort2Uint2Ushort2(inV, out);
+            verifyResultsConvertUint2Ushort2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort2Uint2Ushort2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUshort2Uint2Ushort2(inV, out);
+            verifyResultsConvertUint2Ushort2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort2Uint2Ushort2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUint2Ushort2(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsUintUshort args = new ArgumentsUintUshort();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("0x%x", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertUint2Ushort2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertUint3Ushort3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 3, 0x411d8d73066b331bl, false, 16);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
+            script.forEach_testConvertUshort3Uint3Ushort3(inV, out);
+            verifyResultsConvertUint3Ushort3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort3Uint3Ushort3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUshort3Uint3Ushort3(inV, out);
+            verifyResultsConvertUint3Ushort3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort3Uint3Ushort3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUint3Ushort3(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsUintUshort args = new ArgumentsUintUshort();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("0x%x", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertUint3Ushort3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertUint4Ushort4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 4, 0x416a54fa5cc6c447l, false, 16);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
+            script.forEach_testConvertUshort4Uint4Ushort4(inV, out);
+            verifyResultsConvertUint4Ushort4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort4Uint4Ushort4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUshort4Uint4Ushort4(inV, out);
+            verifyResultsConvertUint4Ushort4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort4Uint4Ushort4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUint4Ushort4(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsUintUshort args = new ArgumentsUintUshort();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("0x%x", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertUint4Ushort4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsFloatInt {
+        public float inV;
+        public int out;
+    }
+
+    private void checkConvertFloat2Int2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x8fb63fb7c069dd5dl, -2.1474835210000000000e+09, 2.1474835200000000000e+09);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            script.forEach_testConvertInt2Float2Int2(inV, out);
+            verifyResultsConvertFloat2Int2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt2Float2Int2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertInt2Float2Int2(inV, out);
+            verifyResultsConvertFloat2Int2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt2Float2Int2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertFloat2Int2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        int[] arrayOut = new int[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatInt args = new ArgumentsFloatInt();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertFloat2Int2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertFloat3Int3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x8fb63ff70a11ed93l, -2.1474835210000000000e+09, 2.1474835200000000000e+09);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            script.forEach_testConvertInt3Float3Int3(inV, out);
+            verifyResultsConvertFloat3Int3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt3Float3Int3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertInt3Float3Int3(inV, out);
+            verifyResultsConvertFloat3Int3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt3Float3Int3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertFloat3Int3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        int[] arrayOut = new int[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatInt args = new ArgumentsFloatInt();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertFloat3Int3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertFloat4Int4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x8fb6403653b9fdc9l, -2.1474835210000000000e+09, 2.1474835200000000000e+09);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            script.forEach_testConvertInt4Float4Int4(inV, out);
+            verifyResultsConvertFloat4Int4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt4Float4Int4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertInt4Float4Int4(inV, out);
+            verifyResultsConvertFloat4Int4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt4Float4Int4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertFloat4Int4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        int[] arrayOut = new int[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatInt args = new ArgumentsFloatInt();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertFloat4Int4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsCharInt {
+        public byte inV;
+        public int out;
+    }
+
+    private void checkConvertChar2Int2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 2, 0x880244ac94c6831dl, true, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            script.forEach_testConvertInt2Char2Int2(inV, out);
+            verifyResultsConvertChar2Int2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt2Char2Int2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertInt2Char2Int2(inV, out);
+            verifyResultsConvertChar2Int2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt2Char2Int2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertChar2Int2(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        int[] arrayOut = new int[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsCharInt args = new ArgumentsCharInt();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%d", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertChar2Int2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertChar3Int3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 3, 0x880244ebde6e9353l, true, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            script.forEach_testConvertInt3Char3Int3(inV, out);
+            verifyResultsConvertChar3Int3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt3Char3Int3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertInt3Char3Int3(inV, out);
+            verifyResultsConvertChar3Int3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt3Char3Int3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertChar3Int3(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        int[] arrayOut = new int[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsCharInt args = new ArgumentsCharInt();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%d", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertChar3Int3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertChar4Int4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 4, 0x8802452b2816a389l, true, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            script.forEach_testConvertInt4Char4Int4(inV, out);
+            verifyResultsConvertChar4Int4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt4Char4Int4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertInt4Char4Int4(inV, out);
+            verifyResultsConvertChar4Int4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt4Char4Int4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertChar4Int4(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        int[] arrayOut = new int[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsCharInt args = new ArgumentsCharInt();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%d", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertChar4Int4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsUcharInt {
+        public byte inV;
+        public int out;
+    }
+
+    private void checkConvertUchar2Int2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 2, 0x97cffb96923aa720l, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            script.forEach_testConvertInt2Uchar2Int2(inV, out);
+            verifyResultsConvertUchar2Int2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt2Uchar2Int2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertInt2Uchar2Int2(inV, out);
+            verifyResultsConvertUchar2Int2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt2Uchar2Int2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUchar2Int2(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        int[] arrayOut = new int[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsUcharInt args = new ArgumentsUcharInt();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("0x%x", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertUchar2Int2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertUchar3Int3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 3, 0x97cffbd5dbe2b756l, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            script.forEach_testConvertInt3Uchar3Int3(inV, out);
+            verifyResultsConvertUchar3Int3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt3Uchar3Int3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertInt3Uchar3Int3(inV, out);
+            verifyResultsConvertUchar3Int3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt3Uchar3Int3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUchar3Int3(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        int[] arrayOut = new int[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsUcharInt args = new ArgumentsUcharInt();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("0x%x", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertUchar3Int3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertUchar4Int4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 4, 0x97cffc15258ac78cl, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            script.forEach_testConvertInt4Uchar4Int4(inV, out);
+            verifyResultsConvertUchar4Int4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt4Uchar4Int4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertInt4Uchar4Int4(inV, out);
+            verifyResultsConvertUchar4Int4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt4Uchar4Int4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUchar4Int4(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        int[] arrayOut = new int[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsUcharInt args = new ArgumentsUcharInt();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("0x%x", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertUchar4Int4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsShortInt {
+        public short inV;
+        public int out;
+    }
+
+    private void checkConvertShort2Int2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 2, 0x85693203252a2d69l, true, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            script.forEach_testConvertInt2Short2Int2(inV, out);
+            verifyResultsConvertShort2Int2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt2Short2Int2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertInt2Short2Int2(inV, out);
+            verifyResultsConvertShort2Int2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt2Short2Int2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertShort2Int2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        int[] arrayOut = new int[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsShortInt args = new ArgumentsShortInt();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%d", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertShort2Int2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertShort3Int3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 3, 0x856932426ed23d9fl, true, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            script.forEach_testConvertInt3Short3Int3(inV, out);
+            verifyResultsConvertShort3Int3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt3Short3Int3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertInt3Short3Int3(inV, out);
+            verifyResultsConvertShort3Int3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt3Short3Int3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertShort3Int3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        int[] arrayOut = new int[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsShortInt args = new ArgumentsShortInt();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%d", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertShort3Int3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertShort4Int4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 4, 0x85693281b87a4dd5l, true, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            script.forEach_testConvertInt4Short4Int4(inV, out);
+            verifyResultsConvertShort4Int4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt4Short4Int4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertInt4Short4Int4(inV, out);
+            verifyResultsConvertShort4Int4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt4Short4Int4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertShort4Int4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        int[] arrayOut = new int[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsShortInt args = new ArgumentsShortInt();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%d", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertShort4Int4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsUshortInt {
+        public short inV;
+        public int out;
+    }
+
+    private void checkConvertUshort2Int2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 2, 0x2cf6eb50b7ac39eal, false, 16);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            script.forEach_testConvertInt2Ushort2Int2(inV, out);
+            verifyResultsConvertUshort2Int2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt2Ushort2Int2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertInt2Ushort2Int2(inV, out);
+            verifyResultsConvertUshort2Int2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt2Ushort2Int2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUshort2Int2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        int[] arrayOut = new int[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsUshortInt args = new ArgumentsUshortInt();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("0x%x", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertUshort2Int2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertUshort3Int3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 3, 0x2cf6eb9001544a20l, false, 16);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            script.forEach_testConvertInt3Ushort3Int3(inV, out);
+            verifyResultsConvertUshort3Int3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt3Ushort3Int3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertInt3Ushort3Int3(inV, out);
+            verifyResultsConvertUshort3Int3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt3Ushort3Int3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUshort3Int3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        int[] arrayOut = new int[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsUshortInt args = new ArgumentsUshortInt();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("0x%x", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertUshort3Int3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertUshort4Int4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 4, 0x2cf6ebcf4afc5a56l, false, 16);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            script.forEach_testConvertInt4Ushort4Int4(inV, out);
+            verifyResultsConvertUshort4Int4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt4Ushort4Int4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertInt4Ushort4Int4(inV, out);
+            verifyResultsConvertUshort4Int4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt4Ushort4Int4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUshort4Int4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        int[] arrayOut = new int[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsUshortInt args = new ArgumentsUshortInt();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("0x%x", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertUshort4Int4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsIntInt {
+        public int inV;
+        public int out;
+    }
+
+    private void checkConvertInt2Int2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 2, 0x501d84049a42354l, true, 31);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            script.forEach_testConvertInt2Int2Int2(inV, out);
+            verifyResultsConvertInt2Int2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt2Int2Int2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertInt2Int2Int2(inV, out);
+            verifyResultsConvertInt2Int2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt2Int2Int2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertInt2Int2(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        int[] arrayOut = new int[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsIntInt args = new ArgumentsIntInt();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%d", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertInt2Int2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertInt3Int3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 3, 0x501d87f934c338al, true, 31);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            script.forEach_testConvertInt3Int3Int3(inV, out);
+            verifyResultsConvertInt3Int3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt3Int3Int3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertInt3Int3Int3(inV, out);
+            verifyResultsConvertInt3Int3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt3Int3Int3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertInt3Int3(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        int[] arrayOut = new int[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsIntInt args = new ArgumentsIntInt();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%d", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertInt3Int3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertInt4Int4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 4, 0x501d8bedcf443c0l, true, 31);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            script.forEach_testConvertInt4Int4Int4(inV, out);
+            verifyResultsConvertInt4Int4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt4Int4Int4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertInt4Int4Int4(inV, out);
+            verifyResultsConvertInt4Int4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt4Int4Int4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertInt4Int4(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        int[] arrayOut = new int[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsIntInt args = new ArgumentsIntInt();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%d", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertInt4Int4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsUintInt {
+        public int inV;
+        public int out;
+    }
+
+    private void checkConvertUint2Int2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 2, 0x70899b043daccaddl, false, 31);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            script.forEach_testConvertInt2Uint2Int2(inV, out);
+            verifyResultsConvertUint2Int2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt2Uint2Int2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertInt2Uint2Int2(inV, out);
+            verifyResultsConvertUint2Int2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt2Uint2Int2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUint2Int2(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        int[] arrayOut = new int[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsUintInt args = new ArgumentsUintInt();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("0x%x", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertUint2Int2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertUint3Int3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 3, 0x70899b438754db13l, false, 31);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            script.forEach_testConvertInt3Uint3Int3(inV, out);
+            verifyResultsConvertUint3Int3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt3Uint3Int3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertInt3Uint3Int3(inV, out);
+            verifyResultsConvertUint3Int3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt3Uint3Int3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUint3Int3(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        int[] arrayOut = new int[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsUintInt args = new ArgumentsUintInt();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("0x%x", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertUint3Int3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertUint4Int4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 4, 0x70899b82d0fceb49l, false, 31);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            script.forEach_testConvertInt4Uint4Int4(inV, out);
+            verifyResultsConvertUint4Int4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt4Uint4Int4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertInt4Uint4Int4(inV, out);
+            verifyResultsConvertUint4Int4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt4Uint4Int4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUint4Int4(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        int[] arrayOut = new int[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsUintInt args = new ArgumentsUintInt();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("0x%x", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertUint4Int4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsFloatUint {
+        public float inV;
+        public int out;
+    }
+
+    private void checkConvertFloat2Uint2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x239cb6cd424dca22l, 0.0000000000000000000e+00, 4.2949670400000000000e+09);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
+            script.forEach_testConvertUint2Float2Uint2(inV, out);
+            verifyResultsConvertFloat2Uint2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint2Float2Uint2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUint2Float2Uint2(inV, out);
+            verifyResultsConvertFloat2Uint2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint2Float2Uint2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertFloat2Uint2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        int[] arrayOut = new int[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatUint args = new ArgumentsFloatUint();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertFloat2Uint2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertFloat3Uint3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x239cc16ea1558f16l, 0.0000000000000000000e+00, 4.2949670400000000000e+09);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
+            script.forEach_testConvertUint3Float3Uint3(inV, out);
+            verifyResultsConvertFloat3Uint3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint3Float3Uint3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUint3Float3Uint3(inV, out);
+            verifyResultsConvertFloat3Uint3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint3Float3Uint3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertFloat3Uint3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        int[] arrayOut = new int[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatUint args = new ArgumentsFloatUint();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertFloat3Uint3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertFloat4Uint4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x239ccc10005d540al, 0.0000000000000000000e+00, 4.2949670400000000000e+09);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
+            script.forEach_testConvertUint4Float4Uint4(inV, out);
+            verifyResultsConvertFloat4Uint4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint4Float4Uint4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUint4Float4Uint4(inV, out);
+            verifyResultsConvertFloat4Uint4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint4Float4Uint4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertFloat4Uint4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        int[] arrayOut = new int[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatUint args = new ArgumentsFloatUint();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertFloat4Uint4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsCharUint {
+        public byte inV;
+        public int out;
+    }
+
+    private void checkConvertChar2Uint2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 2, 0xd8618beceddda162l, false, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
+            script.forEach_testConvertUint2Char2Uint2(inV, out);
+            verifyResultsConvertChar2Uint2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint2Char2Uint2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUint2Char2Uint2(inV, out);
+            verifyResultsConvertChar2Uint2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint2Char2Uint2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertChar2Uint2(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        int[] arrayOut = new int[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsCharUint args = new ArgumentsCharUint();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%d", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertChar2Uint2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertChar3Uint3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 3, 0xd861968e4ce56656l, false, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
+            script.forEach_testConvertUint3Char3Uint3(inV, out);
+            verifyResultsConvertChar3Uint3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint3Char3Uint3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUint3Char3Uint3(inV, out);
+            verifyResultsConvertChar3Uint3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint3Char3Uint3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertChar3Uint3(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        int[] arrayOut = new int[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsCharUint args = new ArgumentsCharUint();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%d", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertChar3Uint3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertChar4Uint4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 4, 0xd861a12fabed2b4al, false, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
+            script.forEach_testConvertUint4Char4Uint4(inV, out);
+            verifyResultsConvertChar4Uint4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint4Char4Uint4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUint4Char4Uint4(inV, out);
+            verifyResultsConvertChar4Uint4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint4Char4Uint4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertChar4Uint4(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        int[] arrayOut = new int[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsCharUint args = new ArgumentsCharUint();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%d", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertChar4Uint4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsUcharUint {
+        public byte inV;
+        public int out;
+    }
+
+    private void checkConvertUchar2Uint2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 2, 0x7fef453a805fade3l, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
+            script.forEach_testConvertUint2Uchar2Uint2(inV, out);
+            verifyResultsConvertUchar2Uint2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint2Uchar2Uint2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUint2Uchar2Uint2(inV, out);
+            verifyResultsConvertUchar2Uint2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint2Uchar2Uint2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUchar2Uint2(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        int[] arrayOut = new int[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsUcharUint args = new ArgumentsUcharUint();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("0x%x", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertUchar2Uint2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertUchar3Uint3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 3, 0x7fef4fdbdf6772d7l, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
+            script.forEach_testConvertUint3Uchar3Uint3(inV, out);
+            verifyResultsConvertUchar3Uint3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint3Uchar3Uint3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUint3Uchar3Uint3(inV, out);
+            verifyResultsConvertUchar3Uint3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint3Uchar3Uint3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUchar3Uint3(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        int[] arrayOut = new int[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsUcharUint args = new ArgumentsUcharUint();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("0x%x", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertUchar3Uint3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertUchar4Uint4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 4, 0x7fef5a7d3e6f37cbl, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
+            script.forEach_testConvertUint4Uchar4Uint4(inV, out);
+            verifyResultsConvertUchar4Uint4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint4Uchar4Uint4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUint4Uchar4Uint4(inV, out);
+            verifyResultsConvertUchar4Uint4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint4Uchar4Uint4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUchar4Uint4(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        int[] arrayOut = new int[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsUcharUint args = new ArgumentsUcharUint();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("0x%x", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertUchar4Uint4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsShortUint {
+        public short inV;
+        public int out;
+    }
+
+    private void checkConvertShort2Uint2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 2, 0x68ab69772e9b3c26l, false, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
+            script.forEach_testConvertUint2Short2Uint2(inV, out);
+            verifyResultsConvertShort2Uint2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint2Short2Uint2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUint2Short2Uint2(inV, out);
+            verifyResultsConvertShort2Uint2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint2Short2Uint2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertShort2Uint2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        int[] arrayOut = new int[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsShortUint args = new ArgumentsShortUint();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%d", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertShort2Uint2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertShort3Uint3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 3, 0x68ab74188da3011al, false, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
+            script.forEach_testConvertUint3Short3Uint3(inV, out);
+            verifyResultsConvertShort3Uint3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint3Short3Uint3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUint3Short3Uint3(inV, out);
+            verifyResultsConvertShort3Uint3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint3Short3Uint3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertShort3Uint3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        int[] arrayOut = new int[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsShortUint args = new ArgumentsShortUint();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%d", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertShort3Uint3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertShort4Uint4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 4, 0x68ab7eb9ecaac60el, false, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
+            script.forEach_testConvertUint4Short4Uint4(inV, out);
+            verifyResultsConvertShort4Uint4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint4Short4Uint4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUint4Short4Uint4(inV, out);
+            verifyResultsConvertShort4Uint4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint4Short4Uint4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertShort4Uint4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        int[] arrayOut = new int[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsShortUint args = new ArgumentsShortUint();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%d", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertShort4Uint4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsUshortUint {
+        public short inV;
+        public int out;
+    }
+
+    private void checkConvertUshort2Uint2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 2, 0x8d79897eca7355d1l, false, 16);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
+            script.forEach_testConvertUint2Ushort2Uint2(inV, out);
+            verifyResultsConvertUshort2Uint2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint2Ushort2Uint2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUint2Ushort2Uint2(inV, out);
+            verifyResultsConvertUshort2Uint2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint2Ushort2Uint2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUshort2Uint2(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        int[] arrayOut = new int[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsUshortUint args = new ArgumentsUshortUint();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("0x%x", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertUshort2Uint2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertUshort3Uint3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 3, 0x8d799420297b1ac5l, false, 16);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
+            script.forEach_testConvertUint3Ushort3Uint3(inV, out);
+            verifyResultsConvertUshort3Uint3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint3Ushort3Uint3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUint3Ushort3Uint3(inV, out);
+            verifyResultsConvertUshort3Uint3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint3Ushort3Uint3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUshort3Uint3(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        int[] arrayOut = new int[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsUshortUint args = new ArgumentsUshortUint();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("0x%x", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertUshort3Uint3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertUshort4Uint4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 4, 0x8d799ec18882dfb9l, false, 16);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
+            script.forEach_testConvertUint4Ushort4Uint4(inV, out);
+            verifyResultsConvertUshort4Uint4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint4Ushort4Uint4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUint4Ushort4Uint4(inV, out);
+            verifyResultsConvertUshort4Uint4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint4Ushort4Uint4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUshort4Uint4(Allocation inV, Allocation out, boolean relaxed) {
+        short[] arrayInV = new short[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        int[] arrayOut = new int[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsUshortUint args = new ArgumentsUshortUint();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("0x%x", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertUshort4Uint4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsIntUint {
+        public int inV;
+        public int out;
+    }
+
+    private void checkConvertInt2Uint2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 2, 0xd74f55bc4f178a9fl, false, 31);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
+            script.forEach_testConvertUint2Int2Uint2(inV, out);
+            verifyResultsConvertInt2Uint2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint2Int2Uint2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUint2Int2Uint2(inV, out);
+            verifyResultsConvertInt2Uint2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint2Int2Uint2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertInt2Uint2(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        int[] arrayOut = new int[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsIntUint args = new ArgumentsIntUint();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%d", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertInt2Uint2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertInt3Uint3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 3, 0xd74f605dae1f4f93l, false, 31);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
+            script.forEach_testConvertUint3Int3Uint3(inV, out);
+            verifyResultsConvertInt3Uint3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint3Int3Uint3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUint3Int3Uint3(inV, out);
+            verifyResultsConvertInt3Uint3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint3Int3Uint3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertInt3Uint3(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        int[] arrayOut = new int[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsIntUint args = new ArgumentsIntUint();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%d", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertInt3Uint3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertInt4Uint4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 4, 0xd74f6aff0d271487l, false, 31);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
+            script.forEach_testConvertUint4Int4Uint4(inV, out);
+            verifyResultsConvertInt4Uint4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint4Int4Uint4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUint4Int4Uint4(inV, out);
+            verifyResultsConvertInt4Uint4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint4Int4Uint4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertInt4Uint4(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        int[] arrayOut = new int[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsIntUint args = new ArgumentsIntUint();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%d", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertInt4Uint4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsUintUint {
+        public int inV;
+        public int out;
+    }
+
+    private void checkConvertUint2Uint2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 2, 0xe71d0ca64c8baea2l, false, 32);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
+            script.forEach_testConvertUint2Uint2Uint2(inV, out);
+            verifyResultsConvertUint2Uint2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint2Uint2Uint2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUint2Uint2Uint2(inV, out);
+            verifyResultsConvertUint2Uint2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint2Uint2Uint2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUint2Uint2(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        int[] arrayOut = new int[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsUintUint args = new ArgumentsUintUint();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("0x%x", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertUint2Uint2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertUint3Uint3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 3, 0xe71d1747ab937396l, false, 32);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
+            script.forEach_testConvertUint3Uint3Uint3(inV, out);
+            verifyResultsConvertUint3Uint3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint3Uint3Uint3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUint3Uint3Uint3(inV, out);
+            verifyResultsConvertUint3Uint3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint3Uint3Uint3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUint3Uint3(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        int[] arrayOut = new int[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsUintUint args = new ArgumentsUintUint();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("0x%x", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertUint3Uint3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkConvertUint4Uint4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 4, 0xe71d21e90a9b388al, false, 32);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
+            script.forEach_testConvertUint4Uint4Uint4(inV, out);
+            verifyResultsConvertUint4Uint4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint4Uint4Uint4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUint4Uint4Uint4(inV, out);
+            verifyResultsConvertUint4Uint4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint4Uint4Uint4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUint4Uint4(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        int[] arrayOut = new int[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsUintUint args = new ArgumentsUintUint();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeConvert(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("0x%x", args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkConvertUint4Uint4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testConvert() {
+        checkConvertFloat2Float2();
+        checkConvertFloat3Float3();
+        checkConvertFloat4Float4();
+        checkConvertChar2Float2();
+        checkConvertChar3Float3();
+        checkConvertChar4Float4();
+        checkConvertUchar2Float2();
+        checkConvertUchar3Float3();
+        checkConvertUchar4Float4();
+        checkConvertShort2Float2();
+        checkConvertShort3Float3();
+        checkConvertShort4Float4();
+        checkConvertUshort2Float2();
+        checkConvertUshort3Float3();
+        checkConvertUshort4Float4();
+        checkConvertInt2Float2();
+        checkConvertInt3Float3();
+        checkConvertInt4Float4();
+        checkConvertUint2Float2();
+        checkConvertUint3Float3();
+        checkConvertUint4Float4();
+        checkConvertFloat2Char2();
+        checkConvertFloat3Char3();
+        checkConvertFloat4Char4();
+        checkConvertChar2Char2();
+        checkConvertChar3Char3();
+        checkConvertChar4Char4();
+        checkConvertUchar2Char2();
+        checkConvertUchar3Char3();
+        checkConvertUchar4Char4();
+        checkConvertShort2Char2();
+        checkConvertShort3Char3();
+        checkConvertShort4Char4();
+        checkConvertUshort2Char2();
+        checkConvertUshort3Char3();
+        checkConvertUshort4Char4();
+        checkConvertInt2Char2();
+        checkConvertInt3Char3();
+        checkConvertInt4Char4();
+        checkConvertUint2Char2();
+        checkConvertUint3Char3();
+        checkConvertUint4Char4();
+        checkConvertFloat2Uchar2();
+        checkConvertFloat3Uchar3();
+        checkConvertFloat4Uchar4();
+        checkConvertChar2Uchar2();
+        checkConvertChar3Uchar3();
+        checkConvertChar4Uchar4();
+        checkConvertUchar2Uchar2();
+        checkConvertUchar3Uchar3();
+        checkConvertUchar4Uchar4();
+        checkConvertShort2Uchar2();
+        checkConvertShort3Uchar3();
+        checkConvertShort4Uchar4();
+        checkConvertUshort2Uchar2();
+        checkConvertUshort3Uchar3();
+        checkConvertUshort4Uchar4();
+        checkConvertInt2Uchar2();
+        checkConvertInt3Uchar3();
+        checkConvertInt4Uchar4();
+        checkConvertUint2Uchar2();
+        checkConvertUint3Uchar3();
+        checkConvertUint4Uchar4();
+        checkConvertFloat2Short2();
+        checkConvertFloat3Short3();
+        checkConvertFloat4Short4();
+        checkConvertChar2Short2();
+        checkConvertChar3Short3();
+        checkConvertChar4Short4();
+        checkConvertUchar2Short2();
+        checkConvertUchar3Short3();
+        checkConvertUchar4Short4();
+        checkConvertShort2Short2();
+        checkConvertShort3Short3();
+        checkConvertShort4Short4();
+        checkConvertUshort2Short2();
+        checkConvertUshort3Short3();
+        checkConvertUshort4Short4();
+        checkConvertInt2Short2();
+        checkConvertInt3Short3();
+        checkConvertInt4Short4();
+        checkConvertUint2Short2();
+        checkConvertUint3Short3();
+        checkConvertUint4Short4();
+        checkConvertFloat2Ushort2();
+        checkConvertFloat3Ushort3();
+        checkConvertFloat4Ushort4();
+        checkConvertChar2Ushort2();
+        checkConvertChar3Ushort3();
+        checkConvertChar4Ushort4();
+        checkConvertUchar2Ushort2();
+        checkConvertUchar3Ushort3();
+        checkConvertUchar4Ushort4();
+        checkConvertShort2Ushort2();
+        checkConvertShort3Ushort3();
+        checkConvertShort4Ushort4();
+        checkConvertUshort2Ushort2();
+        checkConvertUshort3Ushort3();
+        checkConvertUshort4Ushort4();
+        checkConvertInt2Ushort2();
+        checkConvertInt3Ushort3();
+        checkConvertInt4Ushort4();
+        checkConvertUint2Ushort2();
+        checkConvertUint3Ushort3();
+        checkConvertUint4Ushort4();
+        checkConvertFloat2Int2();
+        checkConvertFloat3Int3();
+        checkConvertFloat4Int4();
+        checkConvertChar2Int2();
+        checkConvertChar3Int3();
+        checkConvertChar4Int4();
+        checkConvertUchar2Int2();
+        checkConvertUchar3Int3();
+        checkConvertUchar4Int4();
+        checkConvertShort2Int2();
+        checkConvertShort3Int3();
+        checkConvertShort4Int4();
+        checkConvertUshort2Int2();
+        checkConvertUshort3Int3();
+        checkConvertUshort4Int4();
+        checkConvertInt2Int2();
+        checkConvertInt3Int3();
+        checkConvertInt4Int4();
+        checkConvertUint2Int2();
+        checkConvertUint3Int3();
+        checkConvertUint4Int4();
+        checkConvertFloat2Uint2();
+        checkConvertFloat3Uint3();
+        checkConvertFloat4Uint4();
+        checkConvertChar2Uint2();
+        checkConvertChar3Uint3();
+        checkConvertChar4Uint4();
+        checkConvertUchar2Uint2();
+        checkConvertUchar3Uint3();
+        checkConvertUchar4Uint4();
+        checkConvertShort2Uint2();
+        checkConvertShort3Uint3();
+        checkConvertShort4Uint4();
+        checkConvertUshort2Uint2();
+        checkConvertUshort3Uint3();
+        checkConvertUshort4Uint4();
+        checkConvertInt2Uint2();
+        checkConvertInt3Uint3();
+        checkConvertInt4Uint4();
+        checkConvertUint2Uint2();
+        checkConvertUint3Uint3();
+        checkConvertUint4Uint4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestCopysign.java b/tests/tests/renderscript/src/android/renderscript/cts/TestCopysign.java
new file mode 100644
index 0000000..d102fb9
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestCopysign.java
@@ -0,0 +1,325 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestCopysign extends RSBaseCompute {
+
+    private ScriptC_TestCopysign script;
+    private ScriptC_TestCopysignRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestCopysign(mRS);
+        scriptRelaxed = new ScriptC_TestCopysignRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloatFloat {
+        public float inX;
+        public float inY;
+        public Floaty out;
+    }
+
+    private void checkCopysignFloatFloatFloat() {
+        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xeebba96e8c48145l, false);
+        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xeebba96e8c48146l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInY(inY);
+            script.forEach_testCopysignFloatFloatFloat(inX, out);
+            verifyResultsCopysignFloatFloatFloat(inX, inY, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCopysignFloatFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInY(inY);
+            scriptRelaxed.forEach_testCopysignFloatFloatFloat(inX, out);
+            verifyResultsCopysignFloatFloatFloat(inX, inY, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCopysignFloatFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCopysignFloatFloatFloat(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
+        float[] arrayInX = new float[INPUTSIZE * 1];
+        inX.copyTo(arrayInX);
+        float[] arrayInY = new float[INPUTSIZE * 1];
+        inY.copyTo(arrayInY);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inX = arrayInX[i];
+                args.inY = arrayInY[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeCopysign(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Input inY: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkCopysignFloatFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkCopysignFloat2Float2Float2() {
+        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xbeb0e1cc912e993bl, false);
+        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xbeb0e1cc912e993cl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInY(inY);
+            script.forEach_testCopysignFloat2Float2Float2(inX, out);
+            verifyResultsCopysignFloat2Float2Float2(inX, inY, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCopysignFloat2Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInY(inY);
+            scriptRelaxed.forEach_testCopysignFloat2Float2Float2(inX, out);
+            verifyResultsCopysignFloat2Float2Float2(inX, inY, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCopysignFloat2Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCopysignFloat2Float2Float2(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
+        float[] arrayInX = new float[INPUTSIZE * 2];
+        inX.copyTo(arrayInX);
+        float[] arrayInY = new float[INPUTSIZE * 2];
+        inY.copyTo(arrayInY);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inX = arrayInX[i * 2 + j];
+                args.inY = arrayInY[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeCopysign(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Input inY: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkCopysignFloat2Float2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkCopysignFloat3Float3Float3() {
+        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x1315bfec930c9adcl, false);
+        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x1315bfec930c9addl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInY(inY);
+            script.forEach_testCopysignFloat3Float3Float3(inX, out);
+            verifyResultsCopysignFloat3Float3Float3(inX, inY, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCopysignFloat3Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInY(inY);
+            scriptRelaxed.forEach_testCopysignFloat3Float3Float3(inX, out);
+            verifyResultsCopysignFloat3Float3Float3(inX, inY, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCopysignFloat3Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCopysignFloat3Float3Float3(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
+        float[] arrayInX = new float[INPUTSIZE * 4];
+        inX.copyTo(arrayInX);
+        float[] arrayInY = new float[INPUTSIZE * 4];
+        inY.copyTo(arrayInY);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inX = arrayInX[i * 4 + j];
+                args.inY = arrayInY[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeCopysign(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Input inY: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkCopysignFloat3Float3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkCopysignFloat4Float4Float4() {
+        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x677a9e0c94ea9c7dl, false);
+        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x677a9e0c94ea9c7el, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInY(inY);
+            script.forEach_testCopysignFloat4Float4Float4(inX, out);
+            verifyResultsCopysignFloat4Float4Float4(inX, inY, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCopysignFloat4Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInY(inY);
+            scriptRelaxed.forEach_testCopysignFloat4Float4Float4(inX, out);
+            verifyResultsCopysignFloat4Float4Float4(inX, inY, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCopysignFloat4Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCopysignFloat4Float4Float4(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
+        float[] arrayInX = new float[INPUTSIZE * 4];
+        inX.copyTo(arrayInX);
+        float[] arrayInY = new float[INPUTSIZE * 4];
+        inY.copyTo(arrayInY);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inX = arrayInX[i * 4 + j];
+                args.inY = arrayInY[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeCopysign(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Input inY: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkCopysignFloat4Float4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testCopysign() {
+        checkCopysignFloatFloatFloat();
+        checkCopysignFloat2Float2Float2();
+        checkCopysignFloat3Float3Float3();
+        checkCopysignFloat4Float4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestCos.java b/tests/tests/renderscript/src/android/renderscript/cts/TestCos.java
new file mode 100644
index 0000000..4bdcc4c
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestCos.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestCos extends RSBaseCompute {
+
+    private ScriptC_TestCos script;
+    private ScriptC_TestCosRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestCos(mRS);
+        scriptRelaxed = new ScriptC_TestCosRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float in;
+        public Floaty out;
+    }
+
+    private void checkCosFloatFloat() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x35eace7a33fd0be0l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testCosFloatFloat(in, out);
+            verifyResultsCosFloatFloat(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCosFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testCosFloatFloat(in, out);
+            verifyResultsCosFloatFloat(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCosFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCosFloatFloat(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 1];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeCos(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkCosFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkCosFloat2Float2() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x6cec729d2fe33ffcl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testCosFloat2Float2(in, out);
+            verifyResultsCosFloat2Float2(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCosFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testCosFloat2Float2(in, out);
+            verifyResultsCosFloat2Float2(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCosFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCosFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 2];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeCos(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkCosFloat2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkCosFloat3Float3() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x6cec7d3e8ee9d596l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testCosFloat3Float3(in, out);
+            verifyResultsCosFloat3Float3(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCosFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testCosFloat3Float3(in, out);
+            verifyResultsCosFloat3Float3(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCosFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCosFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeCos(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkCosFloat3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkCosFloat4Float4() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x6cec87dfedf06b30l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testCosFloat4Float4(in, out);
+            verifyResultsCosFloat4Float4(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCosFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testCosFloat4Float4(in, out);
+            verifyResultsCosFloat4Float4(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCosFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCosFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeCos(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkCosFloat4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testCos() {
+        checkCosFloatFloat();
+        checkCosFloat2Float2();
+        checkCosFloat3Float3();
+        checkCosFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestCosh.java b/tests/tests/renderscript/src/android/renderscript/cts/TestCosh.java
new file mode 100644
index 0000000..f24e65d
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestCosh.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestCosh extends RSBaseCompute {
+
+    private ScriptC_TestCosh script;
+    private ScriptC_TestCoshRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestCosh(mRS);
+        scriptRelaxed = new ScriptC_TestCoshRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float in;
+        public Floaty out;
+    }
+
+    private void checkCoshFloatFloat() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xca4f5b95e29e11bel, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testCoshFloatFloat(in, out);
+            verifyResultsCoshFloatFloat(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCoshFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testCoshFloatFloat(in, out);
+            verifyResultsCoshFloatFloat(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCoshFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCoshFloatFloat(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 1];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeCosh(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkCoshFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkCoshFloat2Float2() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x372b9f8d78e6a06al, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testCoshFloat2Float2(in, out);
+            verifyResultsCoshFloat2Float2(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCoshFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testCoshFloat2Float2(in, out);
+            verifyResultsCoshFloat2Float2(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCoshFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCoshFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 2];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeCosh(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkCoshFloat2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkCoshFloat3Float3() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x372baa2ed7ed3604l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testCoshFloat3Float3(in, out);
+            verifyResultsCoshFloat3Float3(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCoshFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testCoshFloat3Float3(in, out);
+            verifyResultsCoshFloat3Float3(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCoshFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCoshFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeCosh(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkCoshFloat3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkCoshFloat4Float4() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x372bb4d036f3cb9el, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testCoshFloat4Float4(in, out);
+            verifyResultsCoshFloat4Float4(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCoshFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testCoshFloat4Float4(in, out);
+            verifyResultsCoshFloat4Float4(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCoshFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCoshFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeCosh(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkCoshFloat4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testCosh() {
+        checkCoshFloatFloat();
+        checkCoshFloat2Float2();
+        checkCoshFloat3Float3();
+        checkCoshFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestCospi.java b/tests/tests/renderscript/src/android/renderscript/cts/TestCospi.java
new file mode 100644
index 0000000..cc3f427
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestCospi.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestCospi extends RSBaseCompute {
+
+    private ScriptC_TestCospi script;
+    private ScriptC_TestCospiRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestCospi(mRS);
+        scriptRelaxed = new ScriptC_TestCospiRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float in;
+        public Floaty out;
+    }
+
+    private void checkCospiFloatFloat() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xf63d9fae6fcc7f1l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testCospiFloatFloat(in, out);
+            verifyResultsCospiFloatFloat(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCospiFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testCospiFloatFloat(in, out);
+            verifyResultsCospiFloatFloat(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCospiFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCospiFloatFloat(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 1];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeCospi(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkCospiFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkCospiFloat2Float2() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x2830872a08f896c5l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testCospiFloat2Float2(in, out);
+            verifyResultsCospiFloat2Float2(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCospiFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testCospiFloat2Float2(in, out);
+            verifyResultsCospiFloat2Float2(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCospiFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCospiFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 2];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeCospi(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkCospiFloat2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkCospiFloat3Float3() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x283091cb67ff2c5fl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testCospiFloat3Float3(in, out);
+            verifyResultsCospiFloat3Float3(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCospiFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testCospiFloat3Float3(in, out);
+            verifyResultsCospiFloat3Float3(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCospiFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCospiFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeCospi(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkCospiFloat3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkCospiFloat4Float4() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x28309c6cc705c1f9l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testCospiFloat4Float4(in, out);
+            verifyResultsCospiFloat4Float4(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCospiFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testCospiFloat4Float4(in, out);
+            verifyResultsCospiFloat4Float4(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCospiFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCospiFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeCospi(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkCospiFloat4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testCospi() {
+        checkCospiFloatFloat();
+        checkCospiFloat2Float2();
+        checkCospiFloat3Float3();
+        checkCospiFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestCross.java b/tests/tests/renderscript/src/android/renderscript/cts/TestCross.java
new file mode 100644
index 0000000..b972906
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestCross.java
@@ -0,0 +1,213 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestCross extends RSBaseCompute {
+
+    private ScriptC_TestCross script;
+    private ScriptC_TestCrossRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestCross(mRS);
+        scriptRelaxed = new ScriptC_TestCrossRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatNFloatNFloatN {
+        public float[] inLhs;
+        public float[] inRhs;
+        public Floaty[] out;
+    }
+
+    private void checkCrossFloat3Float3Float3() {
+        Allocation inLhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xdec3726a2995edb5l, false);
+        Allocation inRhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xdec3726a2996190bl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInRhs(inRhs);
+            script.forEach_testCrossFloat3Float3Float3(inLhs, out);
+            verifyResultsCrossFloat3Float3Float3(inLhs, inRhs, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCrossFloat3Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInRhs(inRhs);
+            scriptRelaxed.forEach_testCrossFloat3Float3Float3(inLhs, out);
+            verifyResultsCrossFloat3Float3Float3(inLhs, inRhs, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCrossFloat3Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCrossFloat3Float3Float3(Allocation inLhs, Allocation inRhs, Allocation out, boolean relaxed) {
+        float[] arrayInLhs = new float[INPUTSIZE * 4];
+        inLhs.copyTo(arrayInLhs);
+        float[] arrayInRhs = new float[INPUTSIZE * 4];
+        inRhs.copyTo(arrayInRhs);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsFloatNFloatNFloatN args = new ArgumentsFloatNFloatNFloatN();
+            // Create the appropriate sized arrays in args
+            args.inLhs = new float[3];
+            args.inRhs = new float[3];
+            args.out = new Floaty[3];
+            // Fill args with the input values
+            for (int j = 0; j < 3 ; j++) {
+                args.inLhs[j] = arrayInLhs[i * 4 + j];
+            }
+            for (int j = 0; j < 3 ; j++) {
+                args.inRhs[j] = arrayInRhs[i * 4 + j];
+            }
+            Floaty.setRelaxed(relaxed);
+            CoreMathVerifier.computeCross(args);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            for (int j = 0; j < 3 ; j++) {
+                if (!args.out[j].couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+            }
+            if (!valid) {
+                StringBuilder message = new StringBuilder();
+                for (int j = 0; j < 3 ; j++) {
+                    message.append("Input inLhs: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayInLhs[i * 4 + j], Float.floatToRawIntBits(arrayInLhs[i * 4 + j]), arrayInLhs[i * 4 + j]));
+                    message.append("\n");
+                }
+                for (int j = 0; j < 3 ; j++) {
+                    message.append("Input inRhs: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayInRhs[i * 4 + j], Float.floatToRawIntBits(arrayInRhs[i * 4 + j]), arrayInRhs[i * 4 + j]));
+                    message.append("\n");
+                }
+                for (int j = 0; j < 3 ; j++) {
+                    message.append("Expected output out: ");
+                    message.append(args.out[j].toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out[j].couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                }
+                assertTrue("Incorrect output for checkCrossFloat3Float3Float3" +
+                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+            }
+        }
+    }
+
+    private void checkCrossFloat4Float4Float4() {
+        Allocation inLhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x6b4bc797a60fb18el, false);
+        Allocation inRhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x6b4bc797a60fdce4l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInRhs(inRhs);
+            script.forEach_testCrossFloat4Float4Float4(inLhs, out);
+            verifyResultsCrossFloat4Float4Float4(inLhs, inRhs, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCrossFloat4Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInRhs(inRhs);
+            scriptRelaxed.forEach_testCrossFloat4Float4Float4(inLhs, out);
+            verifyResultsCrossFloat4Float4Float4(inLhs, inRhs, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCrossFloat4Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCrossFloat4Float4Float4(Allocation inLhs, Allocation inRhs, Allocation out, boolean relaxed) {
+        float[] arrayInLhs = new float[INPUTSIZE * 4];
+        inLhs.copyTo(arrayInLhs);
+        float[] arrayInRhs = new float[INPUTSIZE * 4];
+        inRhs.copyTo(arrayInRhs);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsFloatNFloatNFloatN args = new ArgumentsFloatNFloatNFloatN();
+            // Create the appropriate sized arrays in args
+            args.inLhs = new float[4];
+            args.inRhs = new float[4];
+            args.out = new Floaty[4];
+            // Fill args with the input values
+            for (int j = 0; j < 4 ; j++) {
+                args.inLhs[j] = arrayInLhs[i * 4 + j];
+            }
+            for (int j = 0; j < 4 ; j++) {
+                args.inRhs[j] = arrayInRhs[i * 4 + j];
+            }
+            Floaty.setRelaxed(relaxed);
+            CoreMathVerifier.computeCross(args);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            for (int j = 0; j < 4 ; j++) {
+                if (!args.out[j].couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+            }
+            if (!valid) {
+                StringBuilder message = new StringBuilder();
+                for (int j = 0; j < 4 ; j++) {
+                    message.append("Input inLhs: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayInLhs[i * 4 + j], Float.floatToRawIntBits(arrayInLhs[i * 4 + j]), arrayInLhs[i * 4 + j]));
+                    message.append("\n");
+                }
+                for (int j = 0; j < 4 ; j++) {
+                    message.append("Input inRhs: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayInRhs[i * 4 + j], Float.floatToRawIntBits(arrayInRhs[i * 4 + j]), arrayInRhs[i * 4 + j]));
+                    message.append("\n");
+                }
+                for (int j = 0; j < 4 ; j++) {
+                    message.append("Expected output out: ");
+                    message.append(args.out[j].toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out[j].couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                }
+                assertTrue("Incorrect output for checkCrossFloat4Float4Float4" +
+                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+            }
+        }
+    }
+
+    public void testCross() {
+        checkCrossFloat3Float3Float3();
+        checkCrossFloat4Float4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestDegrees.java b/tests/tests/renderscript/src/android/renderscript/cts/TestDegrees.java
new file mode 100644
index 0000000..f9dd198
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestDegrees.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestDegrees extends RSBaseCompute {
+
+    private ScriptC_TestDegrees script;
+    private ScriptC_TestDegreesRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestDegrees(mRS);
+        scriptRelaxed = new ScriptC_TestDegreesRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inValue;
+        public Floaty out;
+    }
+
+    private void checkDegreesFloatFloat() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x3325fa58542a6bb5l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testDegreesFloatFloat(inValue, out);
+            verifyResultsDegreesFloatFloat(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDegreesFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testDegreesFloatFloat(inValue, out);
+            verifyResultsDegreesFloatFloat(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDegreesFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsDegreesFloatFloat(Allocation inValue, Allocation out, boolean relaxed) {
+        float[] arrayInValue = new float[INPUTSIZE * 1];
+        inValue.copyTo(arrayInValue);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inValue = arrayInValue[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeDegrees(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inValue, Float.floatToRawIntBits(args.inValue), args.inValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkDegreesFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkDegreesFloat2Float2() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x7a202f393d2a289l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testDegreesFloat2Float2(inValue, out);
+            verifyResultsDegreesFloat2Float2(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDegreesFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testDegreesFloat2Float2(inValue, out);
+            verifyResultsDegreesFloat2Float2(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDegreesFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsDegreesFloat2Float2(Allocation inValue, Allocation out, boolean relaxed) {
+        float[] arrayInValue = new float[INPUTSIZE * 2];
+        inValue.copyTo(arrayInValue);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inValue = arrayInValue[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeDegrees(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inValue, Float.floatToRawIntBits(args.inValue), args.inValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkDegreesFloat2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkDegreesFloat3Float3() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x2d56787add10c807l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testDegreesFloat3Float3(inValue, out);
+            verifyResultsDegreesFloat3Float3(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDegreesFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testDegreesFloat3Float3(inValue, out);
+            verifyResultsDegreesFloat3Float3(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDegreesFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsDegreesFloat3Float3(Allocation inValue, Allocation out, boolean relaxed) {
+        float[] arrayInValue = new float[INPUTSIZE * 4];
+        inValue.copyTo(arrayInValue);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inValue = arrayInValue[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeDegrees(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inValue, Float.floatToRawIntBits(args.inValue), args.inValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkDegreesFloat3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkDegreesFloat4Float4() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x530aee02264eed85l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testDegreesFloat4Float4(inValue, out);
+            verifyResultsDegreesFloat4Float4(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDegreesFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testDegreesFloat4Float4(inValue, out);
+            verifyResultsDegreesFloat4Float4(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDegreesFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsDegreesFloat4Float4(Allocation inValue, Allocation out, boolean relaxed) {
+        float[] arrayInValue = new float[INPUTSIZE * 4];
+        inValue.copyTo(arrayInValue);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inValue = arrayInValue[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeDegrees(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inValue, Float.floatToRawIntBits(args.inValue), args.inValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkDegreesFloat4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testDegrees() {
+        checkDegreesFloatFloat();
+        checkDegreesFloat2Float2();
+        checkDegreesFloat3Float3();
+        checkDegreesFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestDistance.java b/tests/tests/renderscript/src/android/renderscript/cts/TestDistance.java
new file mode 100644
index 0000000..7dc5b47
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestDistance.java
@@ -0,0 +1,357 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestDistance extends RSBaseCompute {
+
+    private ScriptC_TestDistance script;
+    private ScriptC_TestDistanceRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestDistance(mRS);
+        scriptRelaxed = new ScriptC_TestDistanceRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloatFloat {
+        public float inLhs;
+        public float inRhs;
+        public Floaty out;
+    }
+
+    private void checkDistanceFloatFloatFloat() {
+        Allocation inLhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xf62f685ebafc5b67l, false);
+        Allocation inRhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xf62f685ebafc86bdl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInRhs(inRhs);
+            script.forEach_testDistanceFloatFloatFloat(inLhs, out);
+            verifyResultsDistanceFloatFloatFloat(inLhs, inRhs, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDistanceFloatFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInRhs(inRhs);
+            scriptRelaxed.forEach_testDistanceFloatFloatFloat(inLhs, out);
+            verifyResultsDistanceFloatFloatFloat(inLhs, inRhs, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDistanceFloatFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsDistanceFloatFloatFloat(Allocation inLhs, Allocation inRhs, Allocation out, boolean relaxed) {
+        float[] arrayInLhs = new float[INPUTSIZE * 1];
+        inLhs.copyTo(arrayInLhs);
+        float[] arrayInRhs = new float[INPUTSIZE * 1];
+        inRhs.copyTo(arrayInRhs);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+            // Create the appropriate sized arrays in args
+            // Fill args with the input values
+            args.inLhs = arrayInLhs[i];
+            args.inRhs = arrayInRhs[i];
+            Floaty.setRelaxed(relaxed);
+            CoreMathVerifier.computeDistance(args);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(arrayOut[i])) {
+                valid = false;
+            }
+            if (!valid) {
+                StringBuilder message = new StringBuilder();
+                message.append("Input inLhs: ");
+                message.append(String.format("%14.8g %8x %15a",
+                        arrayInLhs[i], Float.floatToRawIntBits(arrayInLhs[i]), arrayInLhs[i]));
+                message.append("\n");
+                message.append("Input inRhs: ");
+                message.append(String.format("%14.8g %8x %15a",
+                        arrayInRhs[i], Float.floatToRawIntBits(arrayInRhs[i]), arrayInRhs[i]));
+                message.append("\n");
+                message.append("Expected output out: ");
+                message.append(args.out.toString());
+                message.append("\n");
+                message.append("Actual   output out: ");
+                message.append(String.format("%14.8g %8x %15a",
+                        arrayOut[i], Float.floatToRawIntBits(arrayOut[i]), arrayOut[i]));
+                if (!args.out.couldBe(arrayOut[i])) {
+                    message.append(" FAIL");
+                }
+                message.append("\n");
+                assertTrue("Incorrect output for checkDistanceFloatFloatFloat" +
+                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+            }
+        }
+    }
+
+    public class ArgumentsFloatNFloatNFloat {
+        public float[] inLhs;
+        public float[] inRhs;
+        public Floaty out;
+    }
+
+    private void checkDistanceFloat2Float2Float() {
+        Allocation inLhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x3fdeb51f89981593l, false);
+        Allocation inRhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x3fdeb51f899840e9l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInRhs(inRhs);
+            script.forEach_testDistanceFloat2Float2Float(inLhs, out);
+            verifyResultsDistanceFloat2Float2Float(inLhs, inRhs, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDistanceFloat2Float2Float: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInRhs(inRhs);
+            scriptRelaxed.forEach_testDistanceFloat2Float2Float(inLhs, out);
+            verifyResultsDistanceFloat2Float2Float(inLhs, inRhs, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDistanceFloat2Float2Float: " + e.toString());
+        }
+    }
+
+    private void verifyResultsDistanceFloat2Float2Float(Allocation inLhs, Allocation inRhs, Allocation out, boolean relaxed) {
+        float[] arrayInLhs = new float[INPUTSIZE * 2];
+        inLhs.copyTo(arrayInLhs);
+        float[] arrayInRhs = new float[INPUTSIZE * 2];
+        inRhs.copyTo(arrayInRhs);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsFloatNFloatNFloat args = new ArgumentsFloatNFloatNFloat();
+            // Create the appropriate sized arrays in args
+            args.inLhs = new float[2];
+            args.inRhs = new float[2];
+            // Fill args with the input values
+            for (int j = 0; j < 2 ; j++) {
+                args.inLhs[j] = arrayInLhs[i * 2 + j];
+            }
+            for (int j = 0; j < 2 ; j++) {
+                args.inRhs[j] = arrayInRhs[i * 2 + j];
+            }
+            Floaty.setRelaxed(relaxed);
+            CoreMathVerifier.computeDistance(args);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(arrayOut[i])) {
+                valid = false;
+            }
+            if (!valid) {
+                StringBuilder message = new StringBuilder();
+                for (int j = 0; j < 2 ; j++) {
+                    message.append("Input inLhs: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayInLhs[i * 2 + j], Float.floatToRawIntBits(arrayInLhs[i * 2 + j]), arrayInLhs[i * 2 + j]));
+                    message.append("\n");
+                }
+                for (int j = 0; j < 2 ; j++) {
+                    message.append("Input inRhs: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayInRhs[i * 2 + j], Float.floatToRawIntBits(arrayInRhs[i * 2 + j]), arrayInRhs[i * 2 + j]));
+                    message.append("\n");
+                }
+                message.append("Expected output out: ");
+                message.append(args.out.toString());
+                message.append("\n");
+                message.append("Actual   output out: ");
+                message.append(String.format("%14.8g %8x %15a",
+                        arrayOut[i], Float.floatToRawIntBits(arrayOut[i]), arrayOut[i]));
+                if (!args.out.couldBe(arrayOut[i])) {
+                    message.append(" FAIL");
+                }
+                message.append("\n");
+                assertTrue("Incorrect output for checkDistanceFloat2Float2Float" +
+                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+            }
+        }
+    }
+
+    private void checkDistanceFloat3Float3Float() {
+        Allocation inLhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x6cd0047fd9ae30edl, false);
+        Allocation inRhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x6cd0047fd9ae5c43l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInRhs(inRhs);
+            script.forEach_testDistanceFloat3Float3Float(inLhs, out);
+            verifyResultsDistanceFloat3Float3Float(inLhs, inRhs, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDistanceFloat3Float3Float: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInRhs(inRhs);
+            scriptRelaxed.forEach_testDistanceFloat3Float3Float(inLhs, out);
+            verifyResultsDistanceFloat3Float3Float(inLhs, inRhs, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDistanceFloat3Float3Float: " + e.toString());
+        }
+    }
+
+    private void verifyResultsDistanceFloat3Float3Float(Allocation inLhs, Allocation inRhs, Allocation out, boolean relaxed) {
+        float[] arrayInLhs = new float[INPUTSIZE * 4];
+        inLhs.copyTo(arrayInLhs);
+        float[] arrayInRhs = new float[INPUTSIZE * 4];
+        inRhs.copyTo(arrayInRhs);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsFloatNFloatNFloat args = new ArgumentsFloatNFloatNFloat();
+            // Create the appropriate sized arrays in args
+            args.inLhs = new float[3];
+            args.inRhs = new float[3];
+            // Fill args with the input values
+            for (int j = 0; j < 3 ; j++) {
+                args.inLhs[j] = arrayInLhs[i * 4 + j];
+            }
+            for (int j = 0; j < 3 ; j++) {
+                args.inRhs[j] = arrayInRhs[i * 4 + j];
+            }
+            Floaty.setRelaxed(relaxed);
+            CoreMathVerifier.computeDistance(args);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(arrayOut[i])) {
+                valid = false;
+            }
+            if (!valid) {
+                StringBuilder message = new StringBuilder();
+                for (int j = 0; j < 3 ; j++) {
+                    message.append("Input inLhs: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayInLhs[i * 4 + j], Float.floatToRawIntBits(arrayInLhs[i * 4 + j]), arrayInLhs[i * 4 + j]));
+                    message.append("\n");
+                }
+                for (int j = 0; j < 3 ; j++) {
+                    message.append("Input inRhs: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayInRhs[i * 4 + j], Float.floatToRawIntBits(arrayInRhs[i * 4 + j]), arrayInRhs[i * 4 + j]));
+                    message.append("\n");
+                }
+                message.append("Expected output out: ");
+                message.append(args.out.toString());
+                message.append("\n");
+                message.append("Actual   output out: ");
+                message.append(String.format("%14.8g %8x %15a",
+                        arrayOut[i], Float.floatToRawIntBits(arrayOut[i]), arrayOut[i]));
+                if (!args.out.couldBe(arrayOut[i])) {
+                    message.append(" FAIL");
+                }
+                message.append("\n");
+                assertTrue("Incorrect output for checkDistanceFloat3Float3Float" +
+                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+            }
+        }
+    }
+
+    private void checkDistanceFloat4Float4Float() {
+        Allocation inLhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x99c153e029c44c47l, false);
+        Allocation inRhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x99c153e029c4779dl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInRhs(inRhs);
+            script.forEach_testDistanceFloat4Float4Float(inLhs, out);
+            verifyResultsDistanceFloat4Float4Float(inLhs, inRhs, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDistanceFloat4Float4Float: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInRhs(inRhs);
+            scriptRelaxed.forEach_testDistanceFloat4Float4Float(inLhs, out);
+            verifyResultsDistanceFloat4Float4Float(inLhs, inRhs, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDistanceFloat4Float4Float: " + e.toString());
+        }
+    }
+
+    private void verifyResultsDistanceFloat4Float4Float(Allocation inLhs, Allocation inRhs, Allocation out, boolean relaxed) {
+        float[] arrayInLhs = new float[INPUTSIZE * 4];
+        inLhs.copyTo(arrayInLhs);
+        float[] arrayInRhs = new float[INPUTSIZE * 4];
+        inRhs.copyTo(arrayInRhs);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsFloatNFloatNFloat args = new ArgumentsFloatNFloatNFloat();
+            // Create the appropriate sized arrays in args
+            args.inLhs = new float[4];
+            args.inRhs = new float[4];
+            // Fill args with the input values
+            for (int j = 0; j < 4 ; j++) {
+                args.inLhs[j] = arrayInLhs[i * 4 + j];
+            }
+            for (int j = 0; j < 4 ; j++) {
+                args.inRhs[j] = arrayInRhs[i * 4 + j];
+            }
+            Floaty.setRelaxed(relaxed);
+            CoreMathVerifier.computeDistance(args);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(arrayOut[i])) {
+                valid = false;
+            }
+            if (!valid) {
+                StringBuilder message = new StringBuilder();
+                for (int j = 0; j < 4 ; j++) {
+                    message.append("Input inLhs: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayInLhs[i * 4 + j], Float.floatToRawIntBits(arrayInLhs[i * 4 + j]), arrayInLhs[i * 4 + j]));
+                    message.append("\n");
+                }
+                for (int j = 0; j < 4 ; j++) {
+                    message.append("Input inRhs: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayInRhs[i * 4 + j], Float.floatToRawIntBits(arrayInRhs[i * 4 + j]), arrayInRhs[i * 4 + j]));
+                    message.append("\n");
+                }
+                message.append("Expected output out: ");
+                message.append(args.out.toString());
+                message.append("\n");
+                message.append("Actual   output out: ");
+                message.append(String.format("%14.8g %8x %15a",
+                        arrayOut[i], Float.floatToRawIntBits(arrayOut[i]), arrayOut[i]));
+                if (!args.out.couldBe(arrayOut[i])) {
+                    message.append(" FAIL");
+                }
+                message.append("\n");
+                assertTrue("Incorrect output for checkDistanceFloat4Float4Float" +
+                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+            }
+        }
+    }
+
+    public void testDistance() {
+        checkDistanceFloatFloatFloat();
+        checkDistanceFloat2Float2Float();
+        checkDistanceFloat3Float3Float();
+        checkDistanceFloat4Float4Float();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestDot.java b/tests/tests/renderscript/src/android/renderscript/cts/TestDot.java
new file mode 100644
index 0000000..9b72b9d
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestDot.java
@@ -0,0 +1,357 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestDot extends RSBaseCompute {
+
+    private ScriptC_TestDot script;
+    private ScriptC_TestDotRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestDot(mRS);
+        scriptRelaxed = new ScriptC_TestDotRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloatFloat {
+        public float inLhs;
+        public float inRhs;
+        public Floaty out;
+    }
+
+    private void checkDotFloatFloatFloat() {
+        Allocation inLhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x93a0502d7b6ecc43l, false);
+        Allocation inRhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x93a0502d7b6ef799l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInRhs(inRhs);
+            script.forEach_testDotFloatFloatFloat(inLhs, out);
+            verifyResultsDotFloatFloatFloat(inLhs, inRhs, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDotFloatFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInRhs(inRhs);
+            scriptRelaxed.forEach_testDotFloatFloatFloat(inLhs, out);
+            verifyResultsDotFloatFloatFloat(inLhs, inRhs, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDotFloatFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsDotFloatFloatFloat(Allocation inLhs, Allocation inRhs, Allocation out, boolean relaxed) {
+        float[] arrayInLhs = new float[INPUTSIZE * 1];
+        inLhs.copyTo(arrayInLhs);
+        float[] arrayInRhs = new float[INPUTSIZE * 1];
+        inRhs.copyTo(arrayInRhs);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+            // Create the appropriate sized arrays in args
+            // Fill args with the input values
+            args.inLhs = arrayInLhs[i];
+            args.inRhs = arrayInRhs[i];
+            Floaty.setRelaxed(relaxed);
+            CoreMathVerifier.computeDot(args);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(arrayOut[i])) {
+                valid = false;
+            }
+            if (!valid) {
+                StringBuilder message = new StringBuilder();
+                message.append("Input inLhs: ");
+                message.append(String.format("%14.8g %8x %15a",
+                        arrayInLhs[i], Float.floatToRawIntBits(arrayInLhs[i]), arrayInLhs[i]));
+                message.append("\n");
+                message.append("Input inRhs: ");
+                message.append(String.format("%14.8g %8x %15a",
+                        arrayInRhs[i], Float.floatToRawIntBits(arrayInRhs[i]), arrayInRhs[i]));
+                message.append("\n");
+                message.append("Expected output out: ");
+                message.append(args.out.toString());
+                message.append("\n");
+                message.append("Actual   output out: ");
+                message.append(String.format("%14.8g %8x %15a",
+                        arrayOut[i], Float.floatToRawIntBits(arrayOut[i]), arrayOut[i]));
+                if (!args.out.couldBe(arrayOut[i])) {
+                    message.append(" FAIL");
+                }
+                message.append("\n");
+                assertTrue("Incorrect output for checkDotFloatFloatFloat" +
+                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+            }
+        }
+    }
+
+    public class ArgumentsFloatNFloatNFloat {
+        public float[] inLhs;
+        public float[] inRhs;
+        public Floaty out;
+    }
+
+    private void checkDotFloat2Float2Float() {
+        Allocation inLhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x6458f96b84293a8fl, false);
+        Allocation inRhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x6458f96b842965e5l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInRhs(inRhs);
+            script.forEach_testDotFloat2Float2Float(inLhs, out);
+            verifyResultsDotFloat2Float2Float(inLhs, inRhs, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDotFloat2Float2Float: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInRhs(inRhs);
+            scriptRelaxed.forEach_testDotFloat2Float2Float(inLhs, out);
+            verifyResultsDotFloat2Float2Float(inLhs, inRhs, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDotFloat2Float2Float: " + e.toString());
+        }
+    }
+
+    private void verifyResultsDotFloat2Float2Float(Allocation inLhs, Allocation inRhs, Allocation out, boolean relaxed) {
+        float[] arrayInLhs = new float[INPUTSIZE * 2];
+        inLhs.copyTo(arrayInLhs);
+        float[] arrayInRhs = new float[INPUTSIZE * 2];
+        inRhs.copyTo(arrayInRhs);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsFloatNFloatNFloat args = new ArgumentsFloatNFloatNFloat();
+            // Create the appropriate sized arrays in args
+            args.inLhs = new float[2];
+            args.inRhs = new float[2];
+            // Fill args with the input values
+            for (int j = 0; j < 2 ; j++) {
+                args.inLhs[j] = arrayInLhs[i * 2 + j];
+            }
+            for (int j = 0; j < 2 ; j++) {
+                args.inRhs[j] = arrayInRhs[i * 2 + j];
+            }
+            Floaty.setRelaxed(relaxed);
+            CoreMathVerifier.computeDot(args);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(arrayOut[i])) {
+                valid = false;
+            }
+            if (!valid) {
+                StringBuilder message = new StringBuilder();
+                for (int j = 0; j < 2 ; j++) {
+                    message.append("Input inLhs: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayInLhs[i * 2 + j], Float.floatToRawIntBits(arrayInLhs[i * 2 + j]), arrayInLhs[i * 2 + j]));
+                    message.append("\n");
+                }
+                for (int j = 0; j < 2 ; j++) {
+                    message.append("Input inRhs: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayInRhs[i * 2 + j], Float.floatToRawIntBits(arrayInRhs[i * 2 + j]), arrayInRhs[i * 2 + j]));
+                    message.append("\n");
+                }
+                message.append("Expected output out: ");
+                message.append(args.out.toString());
+                message.append("\n");
+                message.append("Actual   output out: ");
+                message.append(String.format("%14.8g %8x %15a",
+                        arrayOut[i], Float.floatToRawIntBits(arrayOut[i]), arrayOut[i]));
+                if (!args.out.couldBe(arrayOut[i])) {
+                    message.append(" FAIL");
+                }
+                message.append("\n");
+                assertTrue("Incorrect output for checkDotFloat2Float2Float" +
+                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+            }
+        }
+    }
+
+    private void checkDotFloat3Float3Float() {
+        Allocation inLhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x914a48cbd43f55e9l, false);
+        Allocation inRhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x914a48cbd43f813fl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInRhs(inRhs);
+            script.forEach_testDotFloat3Float3Float(inLhs, out);
+            verifyResultsDotFloat3Float3Float(inLhs, inRhs, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDotFloat3Float3Float: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInRhs(inRhs);
+            scriptRelaxed.forEach_testDotFloat3Float3Float(inLhs, out);
+            verifyResultsDotFloat3Float3Float(inLhs, inRhs, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDotFloat3Float3Float: " + e.toString());
+        }
+    }
+
+    private void verifyResultsDotFloat3Float3Float(Allocation inLhs, Allocation inRhs, Allocation out, boolean relaxed) {
+        float[] arrayInLhs = new float[INPUTSIZE * 4];
+        inLhs.copyTo(arrayInLhs);
+        float[] arrayInRhs = new float[INPUTSIZE * 4];
+        inRhs.copyTo(arrayInRhs);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsFloatNFloatNFloat args = new ArgumentsFloatNFloatNFloat();
+            // Create the appropriate sized arrays in args
+            args.inLhs = new float[3];
+            args.inRhs = new float[3];
+            // Fill args with the input values
+            for (int j = 0; j < 3 ; j++) {
+                args.inLhs[j] = arrayInLhs[i * 4 + j];
+            }
+            for (int j = 0; j < 3 ; j++) {
+                args.inRhs[j] = arrayInRhs[i * 4 + j];
+            }
+            Floaty.setRelaxed(relaxed);
+            CoreMathVerifier.computeDot(args);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(arrayOut[i])) {
+                valid = false;
+            }
+            if (!valid) {
+                StringBuilder message = new StringBuilder();
+                for (int j = 0; j < 3 ; j++) {
+                    message.append("Input inLhs: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayInLhs[i * 4 + j], Float.floatToRawIntBits(arrayInLhs[i * 4 + j]), arrayInLhs[i * 4 + j]));
+                    message.append("\n");
+                }
+                for (int j = 0; j < 3 ; j++) {
+                    message.append("Input inRhs: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayInRhs[i * 4 + j], Float.floatToRawIntBits(arrayInRhs[i * 4 + j]), arrayInRhs[i * 4 + j]));
+                    message.append("\n");
+                }
+                message.append("Expected output out: ");
+                message.append(args.out.toString());
+                message.append("\n");
+                message.append("Actual   output out: ");
+                message.append(String.format("%14.8g %8x %15a",
+                        arrayOut[i], Float.floatToRawIntBits(arrayOut[i]), arrayOut[i]));
+                if (!args.out.couldBe(arrayOut[i])) {
+                    message.append(" FAIL");
+                }
+                message.append("\n");
+                assertTrue("Incorrect output for checkDotFloat3Float3Float" +
+                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+            }
+        }
+    }
+
+    private void checkDotFloat4Float4Float() {
+        Allocation inLhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xbe3b982c24557143l, false);
+        Allocation inRhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xbe3b982c24559c99l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInRhs(inRhs);
+            script.forEach_testDotFloat4Float4Float(inLhs, out);
+            verifyResultsDotFloat4Float4Float(inLhs, inRhs, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDotFloat4Float4Float: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInRhs(inRhs);
+            scriptRelaxed.forEach_testDotFloat4Float4Float(inLhs, out);
+            verifyResultsDotFloat4Float4Float(inLhs, inRhs, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDotFloat4Float4Float: " + e.toString());
+        }
+    }
+
+    private void verifyResultsDotFloat4Float4Float(Allocation inLhs, Allocation inRhs, Allocation out, boolean relaxed) {
+        float[] arrayInLhs = new float[INPUTSIZE * 4];
+        inLhs.copyTo(arrayInLhs);
+        float[] arrayInRhs = new float[INPUTSIZE * 4];
+        inRhs.copyTo(arrayInRhs);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsFloatNFloatNFloat args = new ArgumentsFloatNFloatNFloat();
+            // Create the appropriate sized arrays in args
+            args.inLhs = new float[4];
+            args.inRhs = new float[4];
+            // Fill args with the input values
+            for (int j = 0; j < 4 ; j++) {
+                args.inLhs[j] = arrayInLhs[i * 4 + j];
+            }
+            for (int j = 0; j < 4 ; j++) {
+                args.inRhs[j] = arrayInRhs[i * 4 + j];
+            }
+            Floaty.setRelaxed(relaxed);
+            CoreMathVerifier.computeDot(args);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(arrayOut[i])) {
+                valid = false;
+            }
+            if (!valid) {
+                StringBuilder message = new StringBuilder();
+                for (int j = 0; j < 4 ; j++) {
+                    message.append("Input inLhs: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayInLhs[i * 4 + j], Float.floatToRawIntBits(arrayInLhs[i * 4 + j]), arrayInLhs[i * 4 + j]));
+                    message.append("\n");
+                }
+                for (int j = 0; j < 4 ; j++) {
+                    message.append("Input inRhs: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayInRhs[i * 4 + j], Float.floatToRawIntBits(arrayInRhs[i * 4 + j]), arrayInRhs[i * 4 + j]));
+                    message.append("\n");
+                }
+                message.append("Expected output out: ");
+                message.append(args.out.toString());
+                message.append("\n");
+                message.append("Actual   output out: ");
+                message.append(String.format("%14.8g %8x %15a",
+                        arrayOut[i], Float.floatToRawIntBits(arrayOut[i]), arrayOut[i]));
+                if (!args.out.couldBe(arrayOut[i])) {
+                    message.append(" FAIL");
+                }
+                message.append("\n");
+                assertTrue("Incorrect output for checkDotFloat4Float4Float" +
+                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+            }
+        }
+    }
+
+    public void testDot() {
+        checkDotFloatFloatFloat();
+        checkDotFloat2Float2Float();
+        checkDotFloat3Float3Float();
+        checkDotFloat4Float4Float();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestErf.java b/tests/tests/renderscript/src/android/renderscript/cts/TestErf.java
new file mode 100644
index 0000000..f846681
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestErf.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestErf extends RSBaseCompute {
+
+    private ScriptC_TestErf script;
+    private ScriptC_TestErfRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestErf(mRS);
+        scriptRelaxed = new ScriptC_TestErfRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float in;
+        public Floaty out;
+    }
+
+    private void checkErfFloatFloat() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x287cee12fdd9cb26l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testErfFloatFloat(in, out);
+            verifyResultsErfFloatFloat(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testErfFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testErfFloatFloat(in, out);
+            verifyResultsErfFloatFloat(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testErfFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsErfFloatFloat(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 1];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeErf(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkErfFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkErfFloat2Float2() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x6e52a9272b44c092l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testErfFloat2Float2(in, out);
+            verifyResultsErfFloat2Float2(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testErfFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testErfFloat2Float2(in, out);
+            verifyResultsErfFloat2Float2(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testErfFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsErfFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 2];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeErf(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkErfFloat2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkErfFloat3Float3() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x6e52b3c88a4b562cl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testErfFloat3Float3(in, out);
+            verifyResultsErfFloat3Float3(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testErfFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testErfFloat3Float3(in, out);
+            verifyResultsErfFloat3Float3(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testErfFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsErfFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeErf(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkErfFloat3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkErfFloat4Float4() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x6e52be69e951ebc6l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testErfFloat4Float4(in, out);
+            verifyResultsErfFloat4Float4(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testErfFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testErfFloat4Float4(in, out);
+            verifyResultsErfFloat4Float4(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testErfFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsErfFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeErf(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkErfFloat4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testErf() {
+        checkErfFloatFloat();
+        checkErfFloat2Float2();
+        checkErfFloat3Float3();
+        checkErfFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestErfc.java b/tests/tests/renderscript/src/android/renderscript/cts/TestErfc.java
new file mode 100644
index 0000000..e7a859a
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestErfc.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestErfc extends RSBaseCompute {
+
+    private ScriptC_TestErfc script;
+    private ScriptC_TestErfcRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestErfc(mRS);
+        scriptRelaxed = new ScriptC_TestErfcRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float in;
+        public Floaty out;
+    }
+
+    private void checkErfcFloatFloat() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xb41907c64db86b2bl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testErfcFloatFloat(in, out);
+            verifyResultsErfcFloatFloat(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testErfcFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testErfcFloatFloat(in, out);
+            verifyResultsErfcFloatFloat(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testErfcFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsErfcFloatFloat(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 1];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeErfc(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkErfcFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkErfcFloat2Float2() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xc8c849430a3684afl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testErfcFloat2Float2(in, out);
+            verifyResultsErfcFloat2Float2(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testErfcFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testErfcFloat2Float2(in, out);
+            verifyResultsErfcFloat2Float2(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testErfcFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsErfcFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 2];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeErfc(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkErfcFloat2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkErfcFloat3Float3() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xc8c853e4693d1a49l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testErfcFloat3Float3(in, out);
+            verifyResultsErfcFloat3Float3(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testErfcFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testErfcFloat3Float3(in, out);
+            verifyResultsErfcFloat3Float3(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testErfcFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsErfcFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeErfc(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkErfcFloat3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkErfcFloat4Float4() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xc8c85e85c843afe3l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testErfcFloat4Float4(in, out);
+            verifyResultsErfcFloat4Float4(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testErfcFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testErfcFloat4Float4(in, out);
+            verifyResultsErfcFloat4Float4(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testErfcFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsErfcFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeErfc(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkErfcFloat4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testErfc() {
+        checkErfcFloatFloat();
+        checkErfcFloat2Float2();
+        checkErfcFloat3Float3();
+        checkErfcFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestExp.java b/tests/tests/renderscript/src/android/renderscript/cts/TestExp.java
new file mode 100644
index 0000000..47a55ef
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestExp.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestExp extends RSBaseCompute {
+
+    private ScriptC_TestExp script;
+    private ScriptC_TestExpRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestExp(mRS);
+        scriptRelaxed = new ScriptC_TestExpRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float in;
+        public Floaty out;
+    }
+
+    private void checkExpFloatFloat() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xb43af2b5f55920f2l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testExpFloatFloat(in, out);
+            verifyResultsExpFloatFloat(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExpFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testExpFloatFloat(in, out);
+            verifyResultsExpFloatFloat(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExpFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsExpFloatFloat(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 1];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeExp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkExpFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkExpFloat2Float2() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xbdc22634c1f76efel, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testExpFloat2Float2(in, out);
+            verifyResultsExpFloat2Float2(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExpFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testExpFloat2Float2(in, out);
+            verifyResultsExpFloat2Float2(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExpFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsExpFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 2];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeExp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkExpFloat2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkExpFloat3Float3() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xbdc230d620fe0498l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testExpFloat3Float3(in, out);
+            verifyResultsExpFloat3Float3(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExpFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testExpFloat3Float3(in, out);
+            verifyResultsExpFloat3Float3(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExpFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsExpFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeExp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkExpFloat3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkExpFloat4Float4() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xbdc23b7780049a32l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testExpFloat4Float4(in, out);
+            verifyResultsExpFloat4Float4(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExpFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testExpFloat4Float4(in, out);
+            verifyResultsExpFloat4Float4(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExpFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsExpFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeExp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkExpFloat4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testExp() {
+        checkExpFloatFloat();
+        checkExpFloat2Float2();
+        checkExpFloat3Float3();
+        checkExpFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestExp10.java b/tests/tests/renderscript/src/android/renderscript/cts/TestExp10.java
new file mode 100644
index 0000000..7784e54
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestExp10.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestExp10 extends RSBaseCompute {
+
+    private ScriptC_TestExp10 script;
+    private ScriptC_TestExp10Relaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestExp10(mRS);
+        scriptRelaxed = new ScriptC_TestExp10Relaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float in;
+        public Floaty out;
+    }
+
+    private void checkExp10FloatFloat() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x9f6474a4cee90545l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testExp10FloatFloat(in, out);
+            verifyResultsExp10FloatFloat(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExp10FloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testExp10FloatFloat(in, out);
+            verifyResultsExp10FloatFloat(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExp10FloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsExp10FloatFloat(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 1];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeExp10(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkExp10FloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkExp10Float2Float2() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x3c8d9c56223f8a79l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testExp10Float2Float2(in, out);
+            verifyResultsExp10Float2Float2(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExp10Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testExp10Float2Float2(in, out);
+            verifyResultsExp10Float2Float2(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExp10Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsExp10Float2Float2(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 2];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeExp10(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkExp10Float2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkExp10Float3Float3() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x3c8da6f781462013l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testExp10Float3Float3(in, out);
+            verifyResultsExp10Float3Float3(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExp10Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testExp10Float3Float3(in, out);
+            verifyResultsExp10Float3Float3(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExp10Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsExp10Float3Float3(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeExp10(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkExp10Float3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkExp10Float4Float4() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x3c8db198e04cb5adl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testExp10Float4Float4(in, out);
+            verifyResultsExp10Float4Float4(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExp10Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testExp10Float4Float4(in, out);
+            verifyResultsExp10Float4Float4(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExp10Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsExp10Float4Float4(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeExp10(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkExp10Float4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testExp10() {
+        checkExp10FloatFloat();
+        checkExp10Float2Float2();
+        checkExp10Float3Float3();
+        checkExp10Float4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestExp2.java b/tests/tests/renderscript/src/android/renderscript/cts/TestExp2.java
new file mode 100644
index 0000000..a47184b
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestExp2.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestExp2 extends RSBaseCompute {
+
+    private ScriptC_TestExp2 script;
+    private ScriptC_TestExp2Relaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestExp2(mRS);
+        scriptRelaxed = new ScriptC_TestExp2Relaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float in;
+        public Floaty out;
+    }
+
+    private void checkExp2FloatFloat() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x80096e5b0f2662el, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testExp2FloatFloat(in, out);
+            verifyResultsExp2FloatFloat(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExp2FloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testExp2FloatFloat(in, out);
+            verifyResultsExp2FloatFloat(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExp2FloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsExp2FloatFloat(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 1];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeExp2(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkExp2FloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkExp2Float2Float2() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xcc4102f6b7fc7d5al, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testExp2Float2Float2(in, out);
+            verifyResultsExp2Float2Float2(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExp2Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testExp2Float2Float2(in, out);
+            verifyResultsExp2Float2Float2(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExp2Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsExp2Float2Float2(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 2];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeExp2(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkExp2Float2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkExp2Float3Float3() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xcc410d98170312f4l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testExp2Float3Float3(in, out);
+            verifyResultsExp2Float3Float3(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExp2Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testExp2Float3Float3(in, out);
+            verifyResultsExp2Float3Float3(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExp2Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsExp2Float3Float3(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeExp2(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkExp2Float3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkExp2Float4Float4() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xcc4118397609a88el, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testExp2Float4Float4(in, out);
+            verifyResultsExp2Float4Float4(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExp2Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testExp2Float4Float4(in, out);
+            verifyResultsExp2Float4Float4(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExp2Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsExp2Float4Float4(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeExp2(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkExp2Float4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testExp2() {
+        checkExp2FloatFloat();
+        checkExp2Float2Float2();
+        checkExp2Float3Float3();
+        checkExp2Float4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestExpm1.java b/tests/tests/renderscript/src/android/renderscript/cts/TestExpm1.java
new file mode 100644
index 0000000..4835f7e
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestExpm1.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestExpm1 extends RSBaseCompute {
+
+    private ScriptC_TestExpm1 script;
+    private ScriptC_TestExpm1Relaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestExpm1(mRS);
+        scriptRelaxed = new ScriptC_TestExpm1Relaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float in;
+        public Floaty out;
+    }
+
+    private void checkExpm1FloatFloat() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xa03d120368f727aal, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testExpm1FloatFloat(in, out);
+            verifyResultsExpm1FloatFloat(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExpm1FloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testExpm1FloatFloat(in, out);
+            verifyResultsExpm1FloatFloat(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExpm1FloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsExpm1FloatFloat(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 1];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeExpm1(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkExpm1FloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkExpm1Float2Float2() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x59163c9cd255f5f6l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testExpm1Float2Float2(in, out);
+            verifyResultsExpm1Float2Float2(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExpm1Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testExpm1Float2Float2(in, out);
+            verifyResultsExpm1Float2Float2(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExpm1Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsExpm1Float2Float2(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 2];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeExpm1(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkExpm1Float2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkExpm1Float3Float3() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x5916473e315c8b90l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testExpm1Float3Float3(in, out);
+            verifyResultsExpm1Float3Float3(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExpm1Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testExpm1Float3Float3(in, out);
+            verifyResultsExpm1Float3Float3(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExpm1Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsExpm1Float3Float3(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeExpm1(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkExpm1Float3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkExpm1Float4Float4() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x591651df9063212al, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testExpm1Float4Float4(in, out);
+            verifyResultsExpm1Float4Float4(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExpm1Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testExpm1Float4Float4(in, out);
+            verifyResultsExpm1Float4Float4(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExpm1Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsExpm1Float4Float4(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeExpm1(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkExpm1Float4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testExpm1() {
+        checkExpm1FloatFloat();
+        checkExpm1Float2Float2();
+        checkExpm1Float3Float3();
+        checkExpm1Float4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestFabs.java b/tests/tests/renderscript/src/android/renderscript/cts/TestFabs.java
new file mode 100644
index 0000000..12bcb78
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestFabs.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestFabs extends RSBaseCompute {
+
+    private ScriptC_TestFabs script;
+    private ScriptC_TestFabsRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestFabs(mRS);
+        scriptRelaxed = new ScriptC_TestFabsRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float in;
+        public Floaty out;
+    }
+
+    private void checkFabsFloatFloat() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x70316affaf9e3339l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testFabsFloatFloat(in, out);
+            verifyResultsFabsFloatFloat(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFabsFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testFabsFloatFloat(in, out);
+            verifyResultsFabsFloatFloat(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFabsFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFabsFloatFloat(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 1];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeFabs(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkFabsFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkFabsFloat2Float2() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x54ecf2b71ed871cdl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testFabsFloat2Float2(in, out);
+            verifyResultsFabsFloat2Float2(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFabsFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testFabsFloat2Float2(in, out);
+            verifyResultsFabsFloat2Float2(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFabsFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFabsFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 2];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeFabs(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkFabsFloat2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkFabsFloat3Float3() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x54ecfd587ddf0767l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testFabsFloat3Float3(in, out);
+            verifyResultsFabsFloat3Float3(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFabsFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testFabsFloat3Float3(in, out);
+            verifyResultsFabsFloat3Float3(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFabsFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFabsFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeFabs(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkFabsFloat3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkFabsFloat4Float4() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x54ed07f9dce59d01l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testFabsFloat4Float4(in, out);
+            verifyResultsFabsFloat4Float4(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFabsFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testFabsFloat4Float4(in, out);
+            verifyResultsFabsFloat4Float4(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFabsFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFabsFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeFabs(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkFabsFloat4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testFabs() {
+        checkFabsFloatFloat();
+        checkFabsFloat2Float2();
+        checkFabsFloat3Float3();
+        checkFabsFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestFastDistance.java b/tests/tests/renderscript/src/android/renderscript/cts/TestFastDistance.java
new file mode 100644
index 0000000..2caa182
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestFastDistance.java
@@ -0,0 +1,357 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestFastDistance extends RSBaseCompute {
+
+    private ScriptC_TestFastDistance script;
+    private ScriptC_TestFastDistanceRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestFastDistance(mRS);
+        scriptRelaxed = new ScriptC_TestFastDistanceRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloatFloat {
+        public float inLhs;
+        public float inRhs;
+        public Floaty out;
+    }
+
+    private void checkFastDistanceFloatFloatFloat() {
+        Allocation inLhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xfe7e5e843bff0cb7l, false);
+        Allocation inRhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xfe7e5e843bff380dl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInRhs(inRhs);
+            script.forEach_testFastDistanceFloatFloatFloat(inLhs, out);
+            verifyResultsFastDistanceFloatFloatFloat(inLhs, inRhs, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastDistanceFloatFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInRhs(inRhs);
+            scriptRelaxed.forEach_testFastDistanceFloatFloatFloat(inLhs, out);
+            verifyResultsFastDistanceFloatFloatFloat(inLhs, inRhs, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastDistanceFloatFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFastDistanceFloatFloatFloat(Allocation inLhs, Allocation inRhs, Allocation out, boolean relaxed) {
+        float[] arrayInLhs = new float[INPUTSIZE * 1];
+        inLhs.copyTo(arrayInLhs);
+        float[] arrayInRhs = new float[INPUTSIZE * 1];
+        inRhs.copyTo(arrayInRhs);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+            // Create the appropriate sized arrays in args
+            // Fill args with the input values
+            args.inLhs = arrayInLhs[i];
+            args.inRhs = arrayInRhs[i];
+            Floaty.setRelaxed(relaxed);
+            CoreMathVerifier.computeFastDistance(args);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(arrayOut[i])) {
+                valid = false;
+            }
+            if (!valid) {
+                StringBuilder message = new StringBuilder();
+                message.append("Input inLhs: ");
+                message.append(String.format("%14.8g %8x %15a",
+                        arrayInLhs[i], Float.floatToRawIntBits(arrayInLhs[i]), arrayInLhs[i]));
+                message.append("\n");
+                message.append("Input inRhs: ");
+                message.append(String.format("%14.8g %8x %15a",
+                        arrayInRhs[i], Float.floatToRawIntBits(arrayInRhs[i]), arrayInRhs[i]));
+                message.append("\n");
+                message.append("Expected output out: ");
+                message.append(args.out.toString());
+                message.append("\n");
+                message.append("Actual   output out: ");
+                message.append(String.format("%14.8g %8x %15a",
+                        arrayOut[i], Float.floatToRawIntBits(arrayOut[i]), arrayOut[i]));
+                if (!args.out.couldBe(arrayOut[i])) {
+                    message.append(" FAIL");
+                }
+                message.append("\n");
+                assertTrue("Incorrect output for checkFastDistanceFloatFloatFloat" +
+                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+            }
+        }
+    }
+
+    public class ArgumentsFloatNFloatNFloat {
+        public float[] inLhs;
+        public float[] inRhs;
+        public Floaty out;
+    }
+
+    private void checkFastDistanceFloat2Float2Float() {
+        Allocation inLhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x422e8a00560ac063l, false);
+        Allocation inRhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x422e8a00560aebb9l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInRhs(inRhs);
+            script.forEach_testFastDistanceFloat2Float2Float(inLhs, out);
+            verifyResultsFastDistanceFloat2Float2Float(inLhs, inRhs, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastDistanceFloat2Float2Float: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInRhs(inRhs);
+            scriptRelaxed.forEach_testFastDistanceFloat2Float2Float(inLhs, out);
+            verifyResultsFastDistanceFloat2Float2Float(inLhs, inRhs, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastDistanceFloat2Float2Float: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFastDistanceFloat2Float2Float(Allocation inLhs, Allocation inRhs, Allocation out, boolean relaxed) {
+        float[] arrayInLhs = new float[INPUTSIZE * 2];
+        inLhs.copyTo(arrayInLhs);
+        float[] arrayInRhs = new float[INPUTSIZE * 2];
+        inRhs.copyTo(arrayInRhs);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsFloatNFloatNFloat args = new ArgumentsFloatNFloatNFloat();
+            // Create the appropriate sized arrays in args
+            args.inLhs = new float[2];
+            args.inRhs = new float[2];
+            // Fill args with the input values
+            for (int j = 0; j < 2 ; j++) {
+                args.inLhs[j] = arrayInLhs[i * 2 + j];
+            }
+            for (int j = 0; j < 2 ; j++) {
+                args.inRhs[j] = arrayInRhs[i * 2 + j];
+            }
+            Floaty.setRelaxed(relaxed);
+            CoreMathVerifier.computeFastDistance(args);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(arrayOut[i])) {
+                valid = false;
+            }
+            if (!valid) {
+                StringBuilder message = new StringBuilder();
+                for (int j = 0; j < 2 ; j++) {
+                    message.append("Input inLhs: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayInLhs[i * 2 + j], Float.floatToRawIntBits(arrayInLhs[i * 2 + j]), arrayInLhs[i * 2 + j]));
+                    message.append("\n");
+                }
+                for (int j = 0; j < 2 ; j++) {
+                    message.append("Input inRhs: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayInRhs[i * 2 + j], Float.floatToRawIntBits(arrayInRhs[i * 2 + j]), arrayInRhs[i * 2 + j]));
+                    message.append("\n");
+                }
+                message.append("Expected output out: ");
+                message.append(args.out.toString());
+                message.append("\n");
+                message.append("Actual   output out: ");
+                message.append(String.format("%14.8g %8x %15a",
+                        arrayOut[i], Float.floatToRawIntBits(arrayOut[i]), arrayOut[i]));
+                if (!args.out.couldBe(arrayOut[i])) {
+                    message.append(" FAIL");
+                }
+                message.append("\n");
+                assertTrue("Incorrect output for checkFastDistanceFloat2Float2Float" +
+                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+            }
+        }
+    }
+
+    private void checkFastDistanceFloat3Float3Float() {
+        Allocation inLhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x6f1fd960a620dbbdl, false);
+        Allocation inRhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x6f1fd960a6210713l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInRhs(inRhs);
+            script.forEach_testFastDistanceFloat3Float3Float(inLhs, out);
+            verifyResultsFastDistanceFloat3Float3Float(inLhs, inRhs, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastDistanceFloat3Float3Float: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInRhs(inRhs);
+            scriptRelaxed.forEach_testFastDistanceFloat3Float3Float(inLhs, out);
+            verifyResultsFastDistanceFloat3Float3Float(inLhs, inRhs, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastDistanceFloat3Float3Float: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFastDistanceFloat3Float3Float(Allocation inLhs, Allocation inRhs, Allocation out, boolean relaxed) {
+        float[] arrayInLhs = new float[INPUTSIZE * 4];
+        inLhs.copyTo(arrayInLhs);
+        float[] arrayInRhs = new float[INPUTSIZE * 4];
+        inRhs.copyTo(arrayInRhs);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsFloatNFloatNFloat args = new ArgumentsFloatNFloatNFloat();
+            // Create the appropriate sized arrays in args
+            args.inLhs = new float[3];
+            args.inRhs = new float[3];
+            // Fill args with the input values
+            for (int j = 0; j < 3 ; j++) {
+                args.inLhs[j] = arrayInLhs[i * 4 + j];
+            }
+            for (int j = 0; j < 3 ; j++) {
+                args.inRhs[j] = arrayInRhs[i * 4 + j];
+            }
+            Floaty.setRelaxed(relaxed);
+            CoreMathVerifier.computeFastDistance(args);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(arrayOut[i])) {
+                valid = false;
+            }
+            if (!valid) {
+                StringBuilder message = new StringBuilder();
+                for (int j = 0; j < 3 ; j++) {
+                    message.append("Input inLhs: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayInLhs[i * 4 + j], Float.floatToRawIntBits(arrayInLhs[i * 4 + j]), arrayInLhs[i * 4 + j]));
+                    message.append("\n");
+                }
+                for (int j = 0; j < 3 ; j++) {
+                    message.append("Input inRhs: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayInRhs[i * 4 + j], Float.floatToRawIntBits(arrayInRhs[i * 4 + j]), arrayInRhs[i * 4 + j]));
+                    message.append("\n");
+                }
+                message.append("Expected output out: ");
+                message.append(args.out.toString());
+                message.append("\n");
+                message.append("Actual   output out: ");
+                message.append(String.format("%14.8g %8x %15a",
+                        arrayOut[i], Float.floatToRawIntBits(arrayOut[i]), arrayOut[i]));
+                if (!args.out.couldBe(arrayOut[i])) {
+                    message.append(" FAIL");
+                }
+                message.append("\n");
+                assertTrue("Incorrect output for checkFastDistanceFloat3Float3Float" +
+                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+            }
+        }
+    }
+
+    private void checkFastDistanceFloat4Float4Float() {
+        Allocation inLhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x9c1128c0f636f717l, false);
+        Allocation inRhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x9c1128c0f637226dl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInRhs(inRhs);
+            script.forEach_testFastDistanceFloat4Float4Float(inLhs, out);
+            verifyResultsFastDistanceFloat4Float4Float(inLhs, inRhs, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastDistanceFloat4Float4Float: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInRhs(inRhs);
+            scriptRelaxed.forEach_testFastDistanceFloat4Float4Float(inLhs, out);
+            verifyResultsFastDistanceFloat4Float4Float(inLhs, inRhs, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastDistanceFloat4Float4Float: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFastDistanceFloat4Float4Float(Allocation inLhs, Allocation inRhs, Allocation out, boolean relaxed) {
+        float[] arrayInLhs = new float[INPUTSIZE * 4];
+        inLhs.copyTo(arrayInLhs);
+        float[] arrayInRhs = new float[INPUTSIZE * 4];
+        inRhs.copyTo(arrayInRhs);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsFloatNFloatNFloat args = new ArgumentsFloatNFloatNFloat();
+            // Create the appropriate sized arrays in args
+            args.inLhs = new float[4];
+            args.inRhs = new float[4];
+            // Fill args with the input values
+            for (int j = 0; j < 4 ; j++) {
+                args.inLhs[j] = arrayInLhs[i * 4 + j];
+            }
+            for (int j = 0; j < 4 ; j++) {
+                args.inRhs[j] = arrayInRhs[i * 4 + j];
+            }
+            Floaty.setRelaxed(relaxed);
+            CoreMathVerifier.computeFastDistance(args);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(arrayOut[i])) {
+                valid = false;
+            }
+            if (!valid) {
+                StringBuilder message = new StringBuilder();
+                for (int j = 0; j < 4 ; j++) {
+                    message.append("Input inLhs: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayInLhs[i * 4 + j], Float.floatToRawIntBits(arrayInLhs[i * 4 + j]), arrayInLhs[i * 4 + j]));
+                    message.append("\n");
+                }
+                for (int j = 0; j < 4 ; j++) {
+                    message.append("Input inRhs: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayInRhs[i * 4 + j], Float.floatToRawIntBits(arrayInRhs[i * 4 + j]), arrayInRhs[i * 4 + j]));
+                    message.append("\n");
+                }
+                message.append("Expected output out: ");
+                message.append(args.out.toString());
+                message.append("\n");
+                message.append("Actual   output out: ");
+                message.append(String.format("%14.8g %8x %15a",
+                        arrayOut[i], Float.floatToRawIntBits(arrayOut[i]), arrayOut[i]));
+                if (!args.out.couldBe(arrayOut[i])) {
+                    message.append(" FAIL");
+                }
+                message.append("\n");
+                assertTrue("Incorrect output for checkFastDistanceFloat4Float4Float" +
+                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+            }
+        }
+    }
+
+    public void testFastDistance() {
+        checkFastDistanceFloatFloatFloat();
+        checkFastDistanceFloat2Float2Float();
+        checkFastDistanceFloat3Float3Float();
+        checkFastDistanceFloat4Float4Float();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestFastLength.java b/tests/tests/renderscript/src/android/renderscript/cts/TestFastLength.java
new file mode 100644
index 0000000..12d4f65
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestFastLength.java
@@ -0,0 +1,300 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestFastLength extends RSBaseCompute {
+
+    private ScriptC_TestFastLength script;
+    private ScriptC_TestFastLengthRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestFastLength(mRS);
+        scriptRelaxed = new ScriptC_TestFastLengthRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Floaty out;
+    }
+
+    private void checkFastLengthFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xebac65aea2660e8fl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testFastLengthFloatFloat(inV, out);
+            verifyResultsFastLengthFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastLengthFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testFastLengthFloatFloat(inV, out);
+            verifyResultsFastLengthFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastLengthFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFastLengthFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+            // Create the appropriate sized arrays in args
+            // Fill args with the input values
+            args.inV = arrayInV[i];
+            Floaty.setRelaxed(relaxed);
+            CoreMathVerifier.computeFastLength(args);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(arrayOut[i])) {
+                valid = false;
+            }
+            if (!valid) {
+                StringBuilder message = new StringBuilder();
+                message.append("Input inV: ");
+                message.append(String.format("%14.8g %8x %15a",
+                        arrayInV[i], Float.floatToRawIntBits(arrayInV[i]), arrayInV[i]));
+                message.append("\n");
+                message.append("Expected output out: ");
+                message.append(args.out.toString());
+                message.append("\n");
+                message.append("Actual   output out: ");
+                message.append(String.format("%14.8g %8x %15a",
+                        arrayOut[i], Float.floatToRawIntBits(arrayOut[i]), arrayOut[i]));
+                if (!args.out.couldBe(arrayOut[i])) {
+                    message.append(" FAIL");
+                }
+                message.append("\n");
+                assertTrue("Incorrect output for checkFastLengthFloatFloat" +
+                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+            }
+        }
+    }
+
+    public class ArgumentsFloatNFloat {
+        public float[] inV;
+        public Floaty out;
+    }
+
+    private void checkFastLengthFloat2Float() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x95f43650f85e6cadl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testFastLengthFloat2Float(inV, out);
+            verifyResultsFastLengthFloat2Float(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastLengthFloat2Float: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testFastLengthFloat2Float(inV, out);
+            verifyResultsFastLengthFloat2Float(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastLengthFloat2Float: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFastLengthFloat2Float(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsFloatNFloat args = new ArgumentsFloatNFloat();
+            // Create the appropriate sized arrays in args
+            args.inV = new float[2];
+            // Fill args with the input values
+            for (int j = 0; j < 2 ; j++) {
+                args.inV[j] = arrayInV[i * 2 + j];
+            }
+            Floaty.setRelaxed(relaxed);
+            CoreMathVerifier.computeFastLength(args);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(arrayOut[i])) {
+                valid = false;
+            }
+            if (!valid) {
+                StringBuilder message = new StringBuilder();
+                for (int j = 0; j < 2 ; j++) {
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayInV[i * 2 + j], Float.floatToRawIntBits(arrayInV[i * 2 + j]), arrayInV[i * 2 + j]));
+                    message.append("\n");
+                }
+                message.append("Expected output out: ");
+                message.append(args.out.toString());
+                message.append("\n");
+                message.append("Actual   output out: ");
+                message.append(String.format("%14.8g %8x %15a",
+                        arrayOut[i], Float.floatToRawIntBits(arrayOut[i]), arrayOut[i]));
+                if (!args.out.couldBe(arrayOut[i])) {
+                    message.append(" FAIL");
+                }
+                message.append("\n");
+                assertTrue("Incorrect output for checkFastLengthFloat2Float" +
+                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+            }
+        }
+    }
+
+    private void checkFastLengthFloat3Float() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x95f440f25764fb0el, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testFastLengthFloat3Float(inV, out);
+            verifyResultsFastLengthFloat3Float(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastLengthFloat3Float: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testFastLengthFloat3Float(inV, out);
+            verifyResultsFastLengthFloat3Float(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastLengthFloat3Float: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFastLengthFloat3Float(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsFloatNFloat args = new ArgumentsFloatNFloat();
+            // Create the appropriate sized arrays in args
+            args.inV = new float[3];
+            // Fill args with the input values
+            for (int j = 0; j < 3 ; j++) {
+                args.inV[j] = arrayInV[i * 4 + j];
+            }
+            Floaty.setRelaxed(relaxed);
+            CoreMathVerifier.computeFastLength(args);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(arrayOut[i])) {
+                valid = false;
+            }
+            if (!valid) {
+                StringBuilder message = new StringBuilder();
+                for (int j = 0; j < 3 ; j++) {
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayInV[i * 4 + j], Float.floatToRawIntBits(arrayInV[i * 4 + j]), arrayInV[i * 4 + j]));
+                    message.append("\n");
+                }
+                message.append("Expected output out: ");
+                message.append(args.out.toString());
+                message.append("\n");
+                message.append("Actual   output out: ");
+                message.append(String.format("%14.8g %8x %15a",
+                        arrayOut[i], Float.floatToRawIntBits(arrayOut[i]), arrayOut[i]));
+                if (!args.out.couldBe(arrayOut[i])) {
+                    message.append(" FAIL");
+                }
+                message.append("\n");
+                assertTrue("Incorrect output for checkFastLengthFloat3Float" +
+                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+            }
+        }
+    }
+
+    private void checkFastLengthFloat4Float() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x95f44b93b66b896fl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testFastLengthFloat4Float(inV, out);
+            verifyResultsFastLengthFloat4Float(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastLengthFloat4Float: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testFastLengthFloat4Float(inV, out);
+            verifyResultsFastLengthFloat4Float(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastLengthFloat4Float: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFastLengthFloat4Float(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsFloatNFloat args = new ArgumentsFloatNFloat();
+            // Create the appropriate sized arrays in args
+            args.inV = new float[4];
+            // Fill args with the input values
+            for (int j = 0; j < 4 ; j++) {
+                args.inV[j] = arrayInV[i * 4 + j];
+            }
+            Floaty.setRelaxed(relaxed);
+            CoreMathVerifier.computeFastLength(args);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(arrayOut[i])) {
+                valid = false;
+            }
+            if (!valid) {
+                StringBuilder message = new StringBuilder();
+                for (int j = 0; j < 4 ; j++) {
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayInV[i * 4 + j], Float.floatToRawIntBits(arrayInV[i * 4 + j]), arrayInV[i * 4 + j]));
+                    message.append("\n");
+                }
+                message.append("Expected output out: ");
+                message.append(args.out.toString());
+                message.append("\n");
+                message.append("Actual   output out: ");
+                message.append(String.format("%14.8g %8x %15a",
+                        arrayOut[i], Float.floatToRawIntBits(arrayOut[i]), arrayOut[i]));
+                if (!args.out.couldBe(arrayOut[i])) {
+                    message.append(" FAIL");
+                }
+                message.append("\n");
+                assertTrue("Incorrect output for checkFastLengthFloat4Float" +
+                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+            }
+        }
+    }
+
+    public void testFastLength() {
+        checkFastLengthFloatFloat();
+        checkFastLengthFloat2Float();
+        checkFastLengthFloat3Float();
+        checkFastLengthFloat4Float();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestFastNormalize.java b/tests/tests/renderscript/src/android/renderscript/cts/TestFastNormalize.java
new file mode 100644
index 0000000..2b03bd9
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestFastNormalize.java
@@ -0,0 +1,315 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestFastNormalize extends RSBaseCompute {
+
+    private ScriptC_TestFastNormalize script;
+    private ScriptC_TestFastNormalizeRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestFastNormalize(mRS);
+        scriptRelaxed = new ScriptC_TestFastNormalizeRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Floaty out;
+    }
+
+    private void checkFastNormalizeFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xdcfb9adc9f8882ecl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testFastNormalizeFloatFloat(inV, out);
+            verifyResultsFastNormalizeFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastNormalizeFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testFastNormalizeFloatFloat(inV, out);
+            verifyResultsFastNormalizeFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastNormalizeFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFastNormalizeFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+            // Create the appropriate sized arrays in args
+            // Fill args with the input values
+            args.inV = arrayInV[i];
+            Floaty.setRelaxed(relaxed);
+            CoreMathVerifier.computeFastNormalize(args);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(arrayOut[i])) {
+                valid = false;
+            }
+            if (!valid) {
+                StringBuilder message = new StringBuilder();
+                message.append("Input inV: ");
+                message.append(String.format("%14.8g %8x %15a",
+                        arrayInV[i], Float.floatToRawIntBits(arrayInV[i]), arrayInV[i]));
+                message.append("\n");
+                message.append("Expected output out: ");
+                message.append(args.out.toString());
+                message.append("\n");
+                message.append("Actual   output out: ");
+                message.append(String.format("%14.8g %8x %15a",
+                        arrayOut[i], Float.floatToRawIntBits(arrayOut[i]), arrayOut[i]));
+                if (!args.out.couldBe(arrayOut[i])) {
+                    message.append(" FAIL");
+                }
+                message.append("\n");
+                assertTrue("Incorrect output for checkFastNormalizeFloatFloat" +
+                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+            }
+        }
+    }
+
+    public class ArgumentsFloatNFloatN {
+        public float[] inV;
+        public Floaty[] out;
+    }
+
+    private void checkFastNormalizeFloat2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x151c38c30573db70l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testFastNormalizeFloat2Float2(inV, out);
+            verifyResultsFastNormalizeFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastNormalizeFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testFastNormalizeFloat2Float2(inV, out);
+            verifyResultsFastNormalizeFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastNormalizeFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFastNormalizeFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsFloatNFloatN args = new ArgumentsFloatNFloatN();
+            // Create the appropriate sized arrays in args
+            args.inV = new float[2];
+            args.out = new Floaty[2];
+            // Fill args with the input values
+            for (int j = 0; j < 2 ; j++) {
+                args.inV[j] = arrayInV[i * 2 + j];
+            }
+            Floaty.setRelaxed(relaxed);
+            CoreMathVerifier.computeFastNormalize(args);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            for (int j = 0; j < 2 ; j++) {
+                if (!args.out[j].couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+            }
+            if (!valid) {
+                StringBuilder message = new StringBuilder();
+                for (int j = 0; j < 2 ; j++) {
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayInV[i * 2 + j], Float.floatToRawIntBits(arrayInV[i * 2 + j]), arrayInV[i * 2 + j]));
+                    message.append("\n");
+                }
+                for (int j = 0; j < 2 ; j++) {
+                    message.append("Expected output out: ");
+                    message.append(args.out[j].toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out[j].couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                }
+                assertTrue("Incorrect output for checkFastNormalizeFloat2Float2" +
+                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+            }
+        }
+    }
+
+    private void checkFastNormalizeFloat3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x151e01ddfb8efc4el, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testFastNormalizeFloat3Float3(inV, out);
+            verifyResultsFastNormalizeFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastNormalizeFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testFastNormalizeFloat3Float3(inV, out);
+            verifyResultsFastNormalizeFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastNormalizeFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFastNormalizeFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsFloatNFloatN args = new ArgumentsFloatNFloatN();
+            // Create the appropriate sized arrays in args
+            args.inV = new float[3];
+            args.out = new Floaty[3];
+            // Fill args with the input values
+            for (int j = 0; j < 3 ; j++) {
+                args.inV[j] = arrayInV[i * 4 + j];
+            }
+            Floaty.setRelaxed(relaxed);
+            CoreMathVerifier.computeFastNormalize(args);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            for (int j = 0; j < 3 ; j++) {
+                if (!args.out[j].couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+            }
+            if (!valid) {
+                StringBuilder message = new StringBuilder();
+                for (int j = 0; j < 3 ; j++) {
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayInV[i * 4 + j], Float.floatToRawIntBits(arrayInV[i * 4 + j]), arrayInV[i * 4 + j]));
+                    message.append("\n");
+                }
+                for (int j = 0; j < 3 ; j++) {
+                    message.append("Expected output out: ");
+                    message.append(args.out[j].toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out[j].couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                }
+                assertTrue("Incorrect output for checkFastNormalizeFloat3Float3" +
+                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+            }
+        }
+    }
+
+    private void checkFastNormalizeFloat4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x151fcaf8f1aa1d2cl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testFastNormalizeFloat4Float4(inV, out);
+            verifyResultsFastNormalizeFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastNormalizeFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testFastNormalizeFloat4Float4(inV, out);
+            verifyResultsFastNormalizeFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastNormalizeFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFastNormalizeFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsFloatNFloatN args = new ArgumentsFloatNFloatN();
+            // Create the appropriate sized arrays in args
+            args.inV = new float[4];
+            args.out = new Floaty[4];
+            // Fill args with the input values
+            for (int j = 0; j < 4 ; j++) {
+                args.inV[j] = arrayInV[i * 4 + j];
+            }
+            Floaty.setRelaxed(relaxed);
+            CoreMathVerifier.computeFastNormalize(args);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            for (int j = 0; j < 4 ; j++) {
+                if (!args.out[j].couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+            }
+            if (!valid) {
+                StringBuilder message = new StringBuilder();
+                for (int j = 0; j < 4 ; j++) {
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayInV[i * 4 + j], Float.floatToRawIntBits(arrayInV[i * 4 + j]), arrayInV[i * 4 + j]));
+                    message.append("\n");
+                }
+                for (int j = 0; j < 4 ; j++) {
+                    message.append("Expected output out: ");
+                    message.append(args.out[j].toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out[j].couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                }
+                assertTrue("Incorrect output for checkFastNormalizeFloat4Float4" +
+                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+            }
+        }
+    }
+
+    public void testFastNormalize() {
+        checkFastNormalizeFloatFloat();
+        checkFastNormalizeFloat2Float2();
+        checkFastNormalizeFloat3Float3();
+        checkFastNormalizeFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestFdim.java b/tests/tests/renderscript/src/android/renderscript/cts/TestFdim.java
new file mode 100644
index 0000000..db0a46b
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestFdim.java
@@ -0,0 +1,325 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestFdim extends RSBaseCompute {
+
+    private ScriptC_TestFdim script;
+    private ScriptC_TestFdimRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestFdim(mRS);
+        scriptRelaxed = new ScriptC_TestFdimRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloatFloat {
+        public float inA;
+        public float inB;
+        public Floaty out;
+    }
+
+    private void checkFdimFloatFloatFloat() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xf5dd38fbc3a47366l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xf5dd38fbc3a47367l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testFdimFloatFloatFloat(inA, out);
+            verifyResultsFdimFloatFloatFloat(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFdimFloatFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testFdimFloatFloatFloat(inA, out);
+            verifyResultsFdimFloatFloatFloat(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFdimFloatFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFdimFloatFloatFloat(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        float[] arrayInA = new float[INPUTSIZE * 1];
+        inA.copyTo(arrayInA);
+        float[] arrayInB = new float[INPUTSIZE * 1];
+        inB.copyTo(arrayInB);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inA = arrayInA[i];
+                args.inB = arrayInB[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeFdim(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inA: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inA, Float.floatToRawIntBits(args.inA), args.inA));
+                    message.append("\n");
+                    message.append("Input inB: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inB, Float.floatToRawIntBits(args.inB), args.inB));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkFdimFloatFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkFdimFloat2Float2Float2() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xca6a96c16f167f4cl, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xca6a96c16f167f4dl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testFdimFloat2Float2Float2(inA, out);
+            verifyResultsFdimFloat2Float2Float2(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFdimFloat2Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testFdimFloat2Float2Float2(inA, out);
+            verifyResultsFdimFloat2Float2Float2(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFdimFloat2Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFdimFloat2Float2Float2(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        float[] arrayInA = new float[INPUTSIZE * 2];
+        inA.copyTo(arrayInA);
+        float[] arrayInB = new float[INPUTSIZE * 2];
+        inB.copyTo(arrayInB);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inA = arrayInA[i * 2 + j];
+                args.inB = arrayInB[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeFdim(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inA: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inA, Float.floatToRawIntBits(args.inA), args.inA));
+                    message.append("\n");
+                    message.append("Input inB: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inB, Float.floatToRawIntBits(args.inB), args.inB));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkFdimFloat2Float2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkFdimFloat3Float3Float3() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x1ecf74e170f480edl, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x1ecf74e170f480eel, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testFdimFloat3Float3Float3(inA, out);
+            verifyResultsFdimFloat3Float3Float3(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFdimFloat3Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testFdimFloat3Float3Float3(inA, out);
+            verifyResultsFdimFloat3Float3Float3(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFdimFloat3Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFdimFloat3Float3Float3(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        float[] arrayInA = new float[INPUTSIZE * 4];
+        inA.copyTo(arrayInA);
+        float[] arrayInB = new float[INPUTSIZE * 4];
+        inB.copyTo(arrayInB);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inA = arrayInA[i * 4 + j];
+                args.inB = arrayInB[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeFdim(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inA: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inA, Float.floatToRawIntBits(args.inA), args.inA));
+                    message.append("\n");
+                    message.append("Input inB: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inB, Float.floatToRawIntBits(args.inB), args.inB));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkFdimFloat3Float3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkFdimFloat4Float4Float4() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x7334530172d2828el, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x7334530172d2828fl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testFdimFloat4Float4Float4(inA, out);
+            verifyResultsFdimFloat4Float4Float4(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFdimFloat4Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testFdimFloat4Float4Float4(inA, out);
+            verifyResultsFdimFloat4Float4Float4(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFdimFloat4Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFdimFloat4Float4Float4(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        float[] arrayInA = new float[INPUTSIZE * 4];
+        inA.copyTo(arrayInA);
+        float[] arrayInB = new float[INPUTSIZE * 4];
+        inB.copyTo(arrayInB);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inA = arrayInA[i * 4 + j];
+                args.inB = arrayInB[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeFdim(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inA: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inA, Float.floatToRawIntBits(args.inA), args.inA));
+                    message.append("\n");
+                    message.append("Input inB: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inB, Float.floatToRawIntBits(args.inB), args.inB));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkFdimFloat4Float4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testFdim() {
+        checkFdimFloatFloatFloat();
+        checkFdimFloat2Float2Float2();
+        checkFdimFloat3Float3Float3();
+        checkFdimFloat4Float4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestFloor.java b/tests/tests/renderscript/src/android/renderscript/cts/TestFloor.java
new file mode 100644
index 0000000..6cfb3c4
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestFloor.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestFloor extends RSBaseCompute {
+
+    private ScriptC_TestFloor script;
+    private ScriptC_TestFloorRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestFloor(mRS);
+        scriptRelaxed = new ScriptC_TestFloorRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float in;
+        public Floaty out;
+    }
+
+    private void checkFloorFloatFloat() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x9c2b15433f045885l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testFloorFloatFloat(in, out);
+            verifyResultsFloorFloatFloat(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFloorFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testFloorFloatFloat(in, out);
+            verifyResultsFloorFloatFloat(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFloorFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFloorFloatFloat(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 1];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeFloor(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkFloorFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkFloorFloat2Float2() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xf32bb4add79bd3b9l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testFloorFloat2Float2(in, out);
+            verifyResultsFloorFloat2Float2(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFloorFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testFloorFloat2Float2(in, out);
+            verifyResultsFloorFloat2Float2(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFloorFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFloorFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 2];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeFloor(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkFloorFloat2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkFloorFloat3Float3() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xf32bbf4f36a26953l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testFloorFloat3Float3(in, out);
+            verifyResultsFloorFloat3Float3(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFloorFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testFloorFloat3Float3(in, out);
+            verifyResultsFloorFloat3Float3(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFloorFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFloorFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeFloor(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkFloorFloat3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkFloorFloat4Float4() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xf32bc9f095a8feedl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testFloorFloat4Float4(in, out);
+            verifyResultsFloorFloat4Float4(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFloorFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testFloorFloat4Float4(in, out);
+            verifyResultsFloorFloat4Float4(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFloorFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFloorFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeFloor(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkFloorFloat4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testFloor() {
+        checkFloorFloatFloat();
+        checkFloorFloat2Float2();
+        checkFloorFloat3Float3();
+        checkFloorFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestFma.java b/tests/tests/renderscript/src/android/renderscript/cts/TestFma.java
new file mode 100644
index 0000000..705c54d
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestFma.java
@@ -0,0 +1,366 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestFma extends RSBaseCompute {
+
+    private ScriptC_TestFma script;
+    private ScriptC_TestFmaRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestFma(mRS);
+        scriptRelaxed = new ScriptC_TestFmaRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloatFloatFloat {
+        public float inA;
+        public float inB;
+        public float inC;
+        public Floaty out;
+    }
+
+    private void checkFmaFloatFloatFloatFloat() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x5f6b3ee0c3466c2l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x5f6b3ee0c3466c3l, false);
+        Allocation inC = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x5f6b3ee0c3466c4l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.set_gAllocInC(inC);
+            script.forEach_testFmaFloatFloatFloatFloat(inA, out);
+            verifyResultsFmaFloatFloatFloatFloat(inA, inB, inC, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaFloatFloatFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.set_gAllocInC(inC);
+            scriptRelaxed.forEach_testFmaFloatFloatFloatFloat(inA, out);
+            verifyResultsFmaFloatFloatFloatFloat(inA, inB, inC, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaFloatFloatFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFmaFloatFloatFloatFloat(Allocation inA, Allocation inB, Allocation inC, Allocation out, boolean relaxed) {
+        float[] arrayInA = new float[INPUTSIZE * 1];
+        inA.copyTo(arrayInA);
+        float[] arrayInB = new float[INPUTSIZE * 1];
+        inB.copyTo(arrayInB);
+        float[] arrayInC = new float[INPUTSIZE * 1];
+        inC.copyTo(arrayInC);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
+                args.inA = arrayInA[i];
+                args.inB = arrayInB[i];
+                args.inC = arrayInC[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeFma(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inA: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inA, Float.floatToRawIntBits(args.inA), args.inA));
+                    message.append("\n");
+                    message.append("Input inB: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inB, Float.floatToRawIntBits(args.inB), args.inB));
+                    message.append("\n");
+                    message.append("Input inC: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inC, Float.floatToRawIntBits(args.inC), args.inC));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkFmaFloatFloatFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkFmaFloat2Float2Float2Float2() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x47b62b8849bc43dal, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x47b62b8849bc43dbl, false);
+        Allocation inC = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x47b62b8849bc43dcl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.set_gAllocInC(inC);
+            script.forEach_testFmaFloat2Float2Float2Float2(inA, out);
+            verifyResultsFmaFloat2Float2Float2Float2(inA, inB, inC, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaFloat2Float2Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.set_gAllocInC(inC);
+            scriptRelaxed.forEach_testFmaFloat2Float2Float2Float2(inA, out);
+            verifyResultsFmaFloat2Float2Float2Float2(inA, inB, inC, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaFloat2Float2Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFmaFloat2Float2Float2Float2(Allocation inA, Allocation inB, Allocation inC, Allocation out, boolean relaxed) {
+        float[] arrayInA = new float[INPUTSIZE * 2];
+        inA.copyTo(arrayInA);
+        float[] arrayInB = new float[INPUTSIZE * 2];
+        inB.copyTo(arrayInB);
+        float[] arrayInC = new float[INPUTSIZE * 2];
+        inC.copyTo(arrayInC);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
+                args.inA = arrayInA[i * 2 + j];
+                args.inB = arrayInB[i * 2 + j];
+                args.inC = arrayInC[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeFma(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inA: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inA, Float.floatToRawIntBits(args.inA), args.inA));
+                    message.append("\n");
+                    message.append("Input inB: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inB, Float.floatToRawIntBits(args.inB), args.inB));
+                    message.append("\n");
+                    message.append("Input inC: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inC, Float.floatToRawIntBits(args.inC), args.inC));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkFmaFloat2Float2Float2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkFmaFloat3Float3Float3Float3() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x1d2fcf231c237d76l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x1d2fcf231c237d77l, false);
+        Allocation inC = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x1d2fcf231c237d78l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.set_gAllocInC(inC);
+            script.forEach_testFmaFloat3Float3Float3Float3(inA, out);
+            verifyResultsFmaFloat3Float3Float3Float3(inA, inB, inC, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaFloat3Float3Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.set_gAllocInC(inC);
+            scriptRelaxed.forEach_testFmaFloat3Float3Float3Float3(inA, out);
+            verifyResultsFmaFloat3Float3Float3Float3(inA, inB, inC, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaFloat3Float3Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFmaFloat3Float3Float3Float3(Allocation inA, Allocation inB, Allocation inC, Allocation out, boolean relaxed) {
+        float[] arrayInA = new float[INPUTSIZE * 4];
+        inA.copyTo(arrayInA);
+        float[] arrayInB = new float[INPUTSIZE * 4];
+        inB.copyTo(arrayInB);
+        float[] arrayInC = new float[INPUTSIZE * 4];
+        inC.copyTo(arrayInC);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
+                args.inA = arrayInA[i * 4 + j];
+                args.inB = arrayInB[i * 4 + j];
+                args.inC = arrayInC[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeFma(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inA: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inA, Float.floatToRawIntBits(args.inA), args.inA));
+                    message.append("\n");
+                    message.append("Input inB: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inB, Float.floatToRawIntBits(args.inB), args.inB));
+                    message.append("\n");
+                    message.append("Input inC: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inC, Float.floatToRawIntBits(args.inC), args.inC));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkFmaFloat3Float3Float3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkFmaFloat4Float4Float4Float4() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xf2a972bdee8ab712l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xf2a972bdee8ab713l, false);
+        Allocation inC = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xf2a972bdee8ab714l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.set_gAllocInC(inC);
+            script.forEach_testFmaFloat4Float4Float4Float4(inA, out);
+            verifyResultsFmaFloat4Float4Float4Float4(inA, inB, inC, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaFloat4Float4Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.set_gAllocInC(inC);
+            scriptRelaxed.forEach_testFmaFloat4Float4Float4Float4(inA, out);
+            verifyResultsFmaFloat4Float4Float4Float4(inA, inB, inC, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaFloat4Float4Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFmaFloat4Float4Float4Float4(Allocation inA, Allocation inB, Allocation inC, Allocation out, boolean relaxed) {
+        float[] arrayInA = new float[INPUTSIZE * 4];
+        inA.copyTo(arrayInA);
+        float[] arrayInB = new float[INPUTSIZE * 4];
+        inB.copyTo(arrayInB);
+        float[] arrayInC = new float[INPUTSIZE * 4];
+        inC.copyTo(arrayInC);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
+                args.inA = arrayInA[i * 4 + j];
+                args.inB = arrayInB[i * 4 + j];
+                args.inC = arrayInC[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeFma(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inA: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inA, Float.floatToRawIntBits(args.inA), args.inA));
+                    message.append("\n");
+                    message.append("Input inB: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inB, Float.floatToRawIntBits(args.inB), args.inB));
+                    message.append("\n");
+                    message.append("Input inC: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inC, Float.floatToRawIntBits(args.inC), args.inC));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkFmaFloat4Float4Float4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testFma() {
+        checkFmaFloatFloatFloatFloat();
+        checkFmaFloat2Float2Float2Float2();
+        checkFmaFloat3Float3Float3Float3();
+        checkFmaFloat4Float4Float4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestFmax.java b/tests/tests/renderscript/src/android/renderscript/cts/TestFmax.java
new file mode 100644
index 0000000..ca7706a
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestFmax.java
@@ -0,0 +1,535 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestFmax extends RSBaseCompute {
+
+    private ScriptC_TestFmax script;
+    private ScriptC_TestFmaxRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestFmax(mRS);
+        scriptRelaxed = new ScriptC_TestFmaxRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloatFloat {
+        public float inX;
+        public float inY;
+        public Floaty out;
+    }
+
+    private void checkFmaxFloatFloatFloat() {
+        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xe6ec75a46e6fdd91l, false);
+        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xe6ec75a46e6fdd92l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInY(inY);
+            script.forEach_testFmaxFloatFloatFloat(inX, out);
+            verifyResultsFmaxFloatFloatFloat(inX, inY, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaxFloatFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInY(inY);
+            scriptRelaxed.forEach_testFmaxFloatFloatFloat(inX, out);
+            verifyResultsFmaxFloatFloatFloat(inX, inY, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaxFloatFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFmaxFloatFloatFloat(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
+        float[] arrayInX = new float[INPUTSIZE * 1];
+        inX.copyTo(arrayInX);
+        float[] arrayInY = new float[INPUTSIZE * 1];
+        inY.copyTo(arrayInY);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inX = arrayInX[i];
+                args.inY = arrayInY[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeFmax(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Input inY: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkFmaxFloatFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkFmaxFloat2Float2Float2() {
+        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xa99eaa6dd458a0dfl, false);
+        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xa99eaa6dd458a0e0l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInY(inY);
+            script.forEach_testFmaxFloat2Float2Float2(inX, out);
+            verifyResultsFmaxFloat2Float2Float2(inX, inY, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaxFloat2Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInY(inY);
+            scriptRelaxed.forEach_testFmaxFloat2Float2Float2(inX, out);
+            verifyResultsFmaxFloat2Float2Float2(inX, inY, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaxFloat2Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFmaxFloat2Float2Float2(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
+        float[] arrayInX = new float[INPUTSIZE * 2];
+        inX.copyTo(arrayInX);
+        float[] arrayInY = new float[INPUTSIZE * 2];
+        inY.copyTo(arrayInY);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inX = arrayInX[i * 2 + j];
+                args.inY = arrayInY[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeFmax(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Input inY: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkFmaxFloat2Float2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkFmaxFloat3Float3Float3() {
+        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xfe03888dd636a280l, false);
+        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xfe03888dd636a281l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInY(inY);
+            script.forEach_testFmaxFloat3Float3Float3(inX, out);
+            verifyResultsFmaxFloat3Float3Float3(inX, inY, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaxFloat3Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInY(inY);
+            scriptRelaxed.forEach_testFmaxFloat3Float3Float3(inX, out);
+            verifyResultsFmaxFloat3Float3Float3(inX, inY, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaxFloat3Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFmaxFloat3Float3Float3(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
+        float[] arrayInX = new float[INPUTSIZE * 4];
+        inX.copyTo(arrayInX);
+        float[] arrayInY = new float[INPUTSIZE * 4];
+        inY.copyTo(arrayInY);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inX = arrayInX[i * 4 + j];
+                args.inY = arrayInY[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeFmax(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Input inY: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkFmaxFloat3Float3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkFmaxFloat4Float4Float4() {
+        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x526866add814a421l, false);
+        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x526866add814a422l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInY(inY);
+            script.forEach_testFmaxFloat4Float4Float4(inX, out);
+            verifyResultsFmaxFloat4Float4Float4(inX, inY, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaxFloat4Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInY(inY);
+            scriptRelaxed.forEach_testFmaxFloat4Float4Float4(inX, out);
+            verifyResultsFmaxFloat4Float4Float4(inX, inY, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaxFloat4Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFmaxFloat4Float4Float4(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
+        float[] arrayInX = new float[INPUTSIZE * 4];
+        inX.copyTo(arrayInX);
+        float[] arrayInY = new float[INPUTSIZE * 4];
+        inY.copyTo(arrayInY);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inX = arrayInX[i * 4 + j];
+                args.inY = arrayInY[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeFmax(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Input inY: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkFmaxFloat4Float4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkFmaxFloat2FloatFloat2() {
+        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xce5ddc06dc631119l, false);
+        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xce5ddc06dc63111al, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInY(inY);
+            script.forEach_testFmaxFloat2FloatFloat2(inX, out);
+            verifyResultsFmaxFloat2FloatFloat2(inX, inY, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaxFloat2FloatFloat2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInY(inY);
+            scriptRelaxed.forEach_testFmaxFloat2FloatFloat2(inX, out);
+            verifyResultsFmaxFloat2FloatFloat2(inX, inY, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaxFloat2FloatFloat2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFmaxFloat2FloatFloat2(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
+        float[] arrayInX = new float[INPUTSIZE * 2];
+        inX.copyTo(arrayInX);
+        float[] arrayInY = new float[INPUTSIZE * 1];
+        inY.copyTo(arrayInY);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inX = arrayInX[i * 2 + j];
+                args.inY = arrayInY[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeFmax(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Input inY: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkFmaxFloat2FloatFloat2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkFmaxFloat3FloatFloat3() {
+        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x23ad8f1ecace0575l, false);
+        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x23ad8f1ecace0576l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInY(inY);
+            script.forEach_testFmaxFloat3FloatFloat3(inX, out);
+            verifyResultsFmaxFloat3FloatFloat3(inX, inY, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaxFloat3FloatFloat3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInY(inY);
+            scriptRelaxed.forEach_testFmaxFloat3FloatFloat3(inX, out);
+            verifyResultsFmaxFloat3FloatFloat3(inX, inY, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaxFloat3FloatFloat3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFmaxFloat3FloatFloat3(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
+        float[] arrayInX = new float[INPUTSIZE * 4];
+        inX.copyTo(arrayInX);
+        float[] arrayInY = new float[INPUTSIZE * 1];
+        inY.copyTo(arrayInY);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inX = arrayInX[i * 4 + j];
+                args.inY = arrayInY[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeFmax(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Input inY: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkFmaxFloat3FloatFloat3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkFmaxFloat4FloatFloat4() {
+        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x78fd4236b938f9d1l, false);
+        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x78fd4236b938f9d2l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInY(inY);
+            script.forEach_testFmaxFloat4FloatFloat4(inX, out);
+            verifyResultsFmaxFloat4FloatFloat4(inX, inY, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaxFloat4FloatFloat4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInY(inY);
+            scriptRelaxed.forEach_testFmaxFloat4FloatFloat4(inX, out);
+            verifyResultsFmaxFloat4FloatFloat4(inX, inY, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaxFloat4FloatFloat4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFmaxFloat4FloatFloat4(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
+        float[] arrayInX = new float[INPUTSIZE * 4];
+        inX.copyTo(arrayInX);
+        float[] arrayInY = new float[INPUTSIZE * 1];
+        inY.copyTo(arrayInY);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inX = arrayInX[i * 4 + j];
+                args.inY = arrayInY[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeFmax(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Input inY: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkFmaxFloat4FloatFloat4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testFmax() {
+        checkFmaxFloatFloatFloat();
+        checkFmaxFloat2Float2Float2();
+        checkFmaxFloat3Float3Float3();
+        checkFmaxFloat4Float4Float4();
+        checkFmaxFloat2FloatFloat2();
+        checkFmaxFloat3FloatFloat3();
+        checkFmaxFloat4FloatFloat4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestFmin.java b/tests/tests/renderscript/src/android/renderscript/cts/TestFmin.java
new file mode 100644
index 0000000..39a100c
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestFmin.java
@@ -0,0 +1,535 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestFmin extends RSBaseCompute {
+
+    private ScriptC_TestFmin script;
+    private ScriptC_TestFminRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestFmin(mRS);
+        scriptRelaxed = new ScriptC_TestFminRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloatFloat {
+        public float inX;
+        public float inY;
+        public Floaty out;
+    }
+
+    private void checkFminFloatFloatFloat() {
+        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x7b46a8451d7b106fl, false);
+        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x7b46a8451d7b1070l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInY(inY);
+            script.forEach_testFminFloatFloatFloat(inX, out);
+            verifyResultsFminFloatFloatFloat(inX, inY, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFminFloatFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInY(inY);
+            scriptRelaxed.forEach_testFminFloatFloatFloat(inX, out);
+            verifyResultsFminFloatFloatFloat(inX, inY, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFminFloatFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFminFloatFloatFloat(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
+        float[] arrayInX = new float[INPUTSIZE * 1];
+        inX.copyTo(arrayInX);
+        float[] arrayInY = new float[INPUTSIZE * 1];
+        inY.copyTo(arrayInY);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inX = arrayInX[i];
+                args.inY = arrayInY[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeFmin(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Input inY: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkFminFloatFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkFminFloat2Float2Float2() {
+        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x12b850a9e75faa59l, false);
+        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x12b850a9e75faa5al, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInY(inY);
+            script.forEach_testFminFloat2Float2Float2(inX, out);
+            verifyResultsFminFloat2Float2Float2(inX, inY, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFminFloat2Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInY(inY);
+            scriptRelaxed.forEach_testFminFloat2Float2Float2(inX, out);
+            verifyResultsFminFloat2Float2Float2(inX, inY, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFminFloat2Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFminFloat2Float2Float2(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
+        float[] arrayInX = new float[INPUTSIZE * 2];
+        inX.copyTo(arrayInX);
+        float[] arrayInY = new float[INPUTSIZE * 2];
+        inY.copyTo(arrayInY);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inX = arrayInX[i * 2 + j];
+                args.inY = arrayInY[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeFmin(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Input inY: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkFminFloat2Float2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkFminFloat3Float3Float3() {
+        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x671d2ec9e93dabfal, false);
+        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x671d2ec9e93dabfbl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInY(inY);
+            script.forEach_testFminFloat3Float3Float3(inX, out);
+            verifyResultsFminFloat3Float3Float3(inX, inY, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFminFloat3Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInY(inY);
+            scriptRelaxed.forEach_testFminFloat3Float3Float3(inX, out);
+            verifyResultsFminFloat3Float3Float3(inX, inY, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFminFloat3Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFminFloat3Float3Float3(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
+        float[] arrayInX = new float[INPUTSIZE * 4];
+        inX.copyTo(arrayInX);
+        float[] arrayInY = new float[INPUTSIZE * 4];
+        inY.copyTo(arrayInY);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inX = arrayInX[i * 4 + j];
+                args.inY = arrayInY[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeFmin(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Input inY: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkFminFloat3Float3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkFminFloat4Float4Float4() {
+        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xbb820ce9eb1bad9bl, false);
+        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xbb820ce9eb1bad9cl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInY(inY);
+            script.forEach_testFminFloat4Float4Float4(inX, out);
+            verifyResultsFminFloat4Float4Float4(inX, inY, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFminFloat4Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInY(inY);
+            scriptRelaxed.forEach_testFminFloat4Float4Float4(inX, out);
+            verifyResultsFminFloat4Float4Float4(inX, inY, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFminFloat4Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFminFloat4Float4Float4(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
+        float[] arrayInX = new float[INPUTSIZE * 4];
+        inX.copyTo(arrayInX);
+        float[] arrayInY = new float[INPUTSIZE * 4];
+        inY.copyTo(arrayInY);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inX = arrayInX[i * 4 + j];
+                args.inY = arrayInY[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeFmin(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Input inY: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkFminFloat4Float4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkFminFloat2FloatFloat2() {
+        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x4dd5869724457687l, false);
+        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x4dd5869724457688l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInY(inY);
+            script.forEach_testFminFloat2FloatFloat2(inX, out);
+            verifyResultsFminFloat2FloatFloat2(inX, inY, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFminFloat2FloatFloat2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInY(inY);
+            scriptRelaxed.forEach_testFminFloat2FloatFloat2(inX, out);
+            verifyResultsFminFloat2FloatFloat2(inX, inY, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFminFloat2FloatFloat2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFminFloat2FloatFloat2(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
+        float[] arrayInX = new float[INPUTSIZE * 2];
+        inX.copyTo(arrayInX);
+        float[] arrayInY = new float[INPUTSIZE * 1];
+        inY.copyTo(arrayInY);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inX = arrayInX[i * 2 + j];
+                args.inY = arrayInY[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeFmin(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Input inY: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkFminFloat2FloatFloat2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkFminFloat3FloatFloat3() {
+        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xa32539af12b06ae3l, false);
+        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xa32539af12b06ae4l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInY(inY);
+            script.forEach_testFminFloat3FloatFloat3(inX, out);
+            verifyResultsFminFloat3FloatFloat3(inX, inY, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFminFloat3FloatFloat3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInY(inY);
+            scriptRelaxed.forEach_testFminFloat3FloatFloat3(inX, out);
+            verifyResultsFminFloat3FloatFloat3(inX, inY, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFminFloat3FloatFloat3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFminFloat3FloatFloat3(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
+        float[] arrayInX = new float[INPUTSIZE * 4];
+        inX.copyTo(arrayInX);
+        float[] arrayInY = new float[INPUTSIZE * 1];
+        inY.copyTo(arrayInY);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inX = arrayInX[i * 4 + j];
+                args.inY = arrayInY[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeFmin(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Input inY: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkFminFloat3FloatFloat3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkFminFloat4FloatFloat4() {
+        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xf874ecc7011b5f3fl, false);
+        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xf874ecc7011b5f40l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInY(inY);
+            script.forEach_testFminFloat4FloatFloat4(inX, out);
+            verifyResultsFminFloat4FloatFloat4(inX, inY, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFminFloat4FloatFloat4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInY(inY);
+            scriptRelaxed.forEach_testFminFloat4FloatFloat4(inX, out);
+            verifyResultsFminFloat4FloatFloat4(inX, inY, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFminFloat4FloatFloat4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFminFloat4FloatFloat4(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
+        float[] arrayInX = new float[INPUTSIZE * 4];
+        inX.copyTo(arrayInX);
+        float[] arrayInY = new float[INPUTSIZE * 1];
+        inY.copyTo(arrayInY);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inX = arrayInX[i * 4 + j];
+                args.inY = arrayInY[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeFmin(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Input inY: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkFminFloat4FloatFloat4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testFmin() {
+        checkFminFloatFloatFloat();
+        checkFminFloat2Float2Float2();
+        checkFminFloat3Float3Float3();
+        checkFminFloat4Float4Float4();
+        checkFminFloat2FloatFloat2();
+        checkFminFloat3FloatFloat3();
+        checkFminFloat4FloatFloat4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestFmod.java b/tests/tests/renderscript/src/android/renderscript/cts/TestFmod.java
new file mode 100644
index 0000000..60426e3
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestFmod.java
@@ -0,0 +1,325 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestFmod extends RSBaseCompute {
+
+    private ScriptC_TestFmod script;
+    private ScriptC_TestFmodRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestFmod(mRS);
+        scriptRelaxed = new ScriptC_TestFmodRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloatFloat {
+        public float inX;
+        public float inY;
+        public Floaty out;
+    }
+
+    private void checkFmodFloatFloatFloat() {
+        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x51ab5ae4481379a7l, false);
+        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x51ab5ae4481379a8l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInY(inY);
+            script.forEach_testFmodFloatFloatFloat(inX, out);
+            verifyResultsFmodFloatFloatFloat(inX, inY, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmodFloatFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInY(inY);
+            scriptRelaxed.forEach_testFmodFloatFloatFloat(inX, out);
+            verifyResultsFmodFloatFloatFloat(inX, inY, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmodFloatFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFmodFloatFloatFloat(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
+        float[] arrayInX = new float[INPUTSIZE * 1];
+        inX.copyTo(arrayInX);
+        float[] arrayInY = new float[INPUTSIZE * 1];
+        inY.copyTo(arrayInY);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inX = arrayInX[i];
+                args.inY = arrayInY[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeFmod(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Input inY: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkFmodFloatFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkFmodFloat2Float2Float2() {
+        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x1ed79fa3ec4de581l, false);
+        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x1ed79fa3ec4de582l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInY(inY);
+            script.forEach_testFmodFloat2Float2Float2(inX, out);
+            verifyResultsFmodFloat2Float2Float2(inX, inY, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmodFloat2Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInY(inY);
+            scriptRelaxed.forEach_testFmodFloat2Float2Float2(inX, out);
+            verifyResultsFmodFloat2Float2Float2(inX, inY, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmodFloat2Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFmodFloat2Float2Float2(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
+        float[] arrayInX = new float[INPUTSIZE * 2];
+        inX.copyTo(arrayInX);
+        float[] arrayInY = new float[INPUTSIZE * 2];
+        inY.copyTo(arrayInY);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inX = arrayInX[i * 2 + j];
+                args.inY = arrayInY[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeFmod(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Input inY: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkFmodFloat2Float2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkFmodFloat3Float3Float3() {
+        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x733c7dc3ee2be722l, false);
+        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x733c7dc3ee2be723l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInY(inY);
+            script.forEach_testFmodFloat3Float3Float3(inX, out);
+            verifyResultsFmodFloat3Float3Float3(inX, inY, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmodFloat3Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInY(inY);
+            scriptRelaxed.forEach_testFmodFloat3Float3Float3(inX, out);
+            verifyResultsFmodFloat3Float3Float3(inX, inY, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmodFloat3Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFmodFloat3Float3Float3(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
+        float[] arrayInX = new float[INPUTSIZE * 4];
+        inX.copyTo(arrayInX);
+        float[] arrayInY = new float[INPUTSIZE * 4];
+        inY.copyTo(arrayInY);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inX = arrayInX[i * 4 + j];
+                args.inY = arrayInY[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeFmod(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Input inY: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkFmodFloat3Float3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkFmodFloat4Float4Float4() {
+        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xc7a15be3f009e8c3l, false);
+        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xc7a15be3f009e8c4l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInY(inY);
+            script.forEach_testFmodFloat4Float4Float4(inX, out);
+            verifyResultsFmodFloat4Float4Float4(inX, inY, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmodFloat4Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInY(inY);
+            scriptRelaxed.forEach_testFmodFloat4Float4Float4(inX, out);
+            verifyResultsFmodFloat4Float4Float4(inX, inY, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmodFloat4Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFmodFloat4Float4Float4(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
+        float[] arrayInX = new float[INPUTSIZE * 4];
+        inX.copyTo(arrayInX);
+        float[] arrayInY = new float[INPUTSIZE * 4];
+        inY.copyTo(arrayInY);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inX = arrayInX[i * 4 + j];
+                args.inY = arrayInY[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeFmod(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Input inY: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkFmodFloat4Float4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testFmod() {
+        checkFmodFloatFloatFloat();
+        checkFmodFloat2Float2Float2();
+        checkFmodFloat3Float3Float3();
+        checkFmodFloat4Float4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestFract.java b/tests/tests/renderscript/src/android/renderscript/cts/TestFract.java
new file mode 100644
index 0000000..bc1faa8
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestFract.java
@@ -0,0 +1,606 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestFract extends RSBaseCompute {
+
+    private ScriptC_TestFract script;
+    private ScriptC_TestFractRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestFract(mRS);
+        scriptRelaxed = new ScriptC_TestFractRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloatFloat {
+        public float inV;
+        public Floaty outFloor;
+        public Floaty out;
+    }
+
+    private void checkFractFloatFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x57d8e6573c675d27l, false);
+        try {
+            Allocation outFloor = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocOutFloor(outFloor);
+            script.forEach_testFractFloatFloatFloat(inV, out);
+            verifyResultsFractFloatFloatFloat(inV, outFloor, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFractFloatFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation outFloor = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocOutFloor(outFloor);
+            scriptRelaxed.forEach_testFractFloatFloatFloat(inV, out);
+            verifyResultsFractFloatFloatFloat(inV, outFloor, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFractFloatFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFractFloatFloatFloat(Allocation inV, Allocation outFloor, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        inV.copyTo(arrayInV);
+        float[] arrayOutFloor = new float[INPUTSIZE * 1];
+        outFloor.copyTo(arrayOutFloor);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeFract(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.outFloor.couldBe(arrayOutFloor[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output outFloor: ");
+                    message.append(args.outFloor.toString());
+                    message.append("\n");
+                    message.append("Actual   output outFloor: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOutFloor[i * 1 + j], Float.floatToRawIntBits(arrayOutFloor[i * 1 + j]), arrayOutFloor[i * 1 + j]));
+                    if (!args.outFloor.couldBe(arrayOutFloor[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkFractFloatFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkFractFloat2Float2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xd1dbe683cdf8f525l, false);
+        try {
+            Allocation outFloor = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocOutFloor(outFloor);
+            script.forEach_testFractFloat2Float2Float2(inV, out);
+            verifyResultsFractFloat2Float2Float2(inV, outFloor, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFractFloat2Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation outFloor = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocOutFloor(outFloor);
+            scriptRelaxed.forEach_testFractFloat2Float2Float2(inV, out);
+            verifyResultsFractFloat2Float2Float2(inV, outFloor, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFractFloat2Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFractFloat2Float2Float2(Allocation inV, Allocation outFloor, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        float[] arrayOutFloor = new float[INPUTSIZE * 2];
+        outFloor.copyTo(arrayOutFloor);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeFract(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.outFloor.couldBe(arrayOutFloor[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output outFloor: ");
+                    message.append(args.outFloor.toString());
+                    message.append("\n");
+                    message.append("Actual   output outFloor: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOutFloor[i * 2 + j], Float.floatToRawIntBits(arrayOutFloor[i * 2 + j]), arrayOutFloor[i * 2 + j]));
+                    if (!args.outFloor.couldBe(arrayOutFloor[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkFractFloat2Float2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkFractFloat3Float3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x2640c4a3cfd6f6c6l, false);
+        try {
+            Allocation outFloor = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocOutFloor(outFloor);
+            script.forEach_testFractFloat3Float3Float3(inV, out);
+            verifyResultsFractFloat3Float3Float3(inV, outFloor, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFractFloat3Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation outFloor = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocOutFloor(outFloor);
+            scriptRelaxed.forEach_testFractFloat3Float3Float3(inV, out);
+            verifyResultsFractFloat3Float3Float3(inV, outFloor, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFractFloat3Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFractFloat3Float3Float3(Allocation inV, Allocation outFloor, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        float[] arrayOutFloor = new float[INPUTSIZE * 4];
+        outFloor.copyTo(arrayOutFloor);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeFract(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.outFloor.couldBe(arrayOutFloor[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output outFloor: ");
+                    message.append(args.outFloor.toString());
+                    message.append("\n");
+                    message.append("Actual   output outFloor: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOutFloor[i * 4 + j], Float.floatToRawIntBits(arrayOutFloor[i * 4 + j]), arrayOutFloor[i * 4 + j]));
+                    if (!args.outFloor.couldBe(arrayOutFloor[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkFractFloat3Float3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkFractFloat4Float4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x7aa5a2c3d1b4f867l, false);
+        try {
+            Allocation outFloor = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocOutFloor(outFloor);
+            script.forEach_testFractFloat4Float4Float4(inV, out);
+            verifyResultsFractFloat4Float4Float4(inV, outFloor, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFractFloat4Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation outFloor = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocOutFloor(outFloor);
+            scriptRelaxed.forEach_testFractFloat4Float4Float4(inV, out);
+            verifyResultsFractFloat4Float4Float4(inV, outFloor, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFractFloat4Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFractFloat4Float4Float4(Allocation inV, Allocation outFloor, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        float[] arrayOutFloor = new float[INPUTSIZE * 4];
+        outFloor.copyTo(arrayOutFloor);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeFract(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.outFloor.couldBe(arrayOutFloor[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output outFloor: ");
+                    message.append(args.outFloor.toString());
+                    message.append("\n");
+                    message.append("Actual   output outFloor: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOutFloor[i * 4 + j], Float.floatToRawIntBits(arrayOutFloor[i * 4 + j]), arrayOutFloor[i * 4 + j]));
+                    if (!args.outFloor.couldBe(arrayOutFloor[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkFractFloat4Float4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Floaty out;
+    }
+
+    private void checkFractFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xf559208b9db2cad3l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testFractFloatFloat(inV, out);
+            verifyResultsFractFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFractFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testFractFloatFloat(inV, out);
+            verifyResultsFractFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFractFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFractFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeFract(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkFractFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkFractFloat2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x1096c5acc4d52edfl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testFractFloat2Float2(inV, out);
+            verifyResultsFractFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFractFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testFractFloat2Float2(inV, out);
+            verifyResultsFractFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFractFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFractFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeFract(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkFractFloat2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkFractFloat3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x10988ec7baf04fbdl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testFractFloat3Float3(inV, out);
+            verifyResultsFractFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFractFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testFractFloat3Float3(inV, out);
+            verifyResultsFractFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFractFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFractFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeFract(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkFractFloat3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkFractFloat4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x109a57e2b10b709bl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testFractFloat4Float4(inV, out);
+            verifyResultsFractFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFractFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testFractFloat4Float4(inV, out);
+            verifyResultsFractFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFractFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFractFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeFract(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkFractFloat4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testFract() {
+        checkFractFloatFloatFloat();
+        checkFractFloat2Float2Float2();
+        checkFractFloat3Float3Float3();
+        checkFractFloat4Float4Float4();
+        checkFractFloatFloat();
+        checkFractFloat2Float2();
+        checkFractFloat3Float3();
+        checkFractFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestFrexp.java b/tests/tests/renderscript/src/android/renderscript/cts/TestFrexp.java
new file mode 100644
index 0000000..1437f21
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestFrexp.java
@@ -0,0 +1,357 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestFrexp extends RSBaseCompute {
+
+    private ScriptC_TestFrexp script;
+    private ScriptC_TestFrexpRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestFrexp(mRS);
+        scriptRelaxed = new ScriptC_TestFrexpRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatIntFloat {
+        public float inV;
+        public int outIptr;
+        public Floaty out;
+    }
+
+    private void checkFrexpFloatIntFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x57ae9fe07384e56dl, false);
+        try {
+            Allocation outIptr = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 1), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocOutIptr(outIptr);
+            script.forEach_testFrexpFloatIntFloat(inV, out);
+            verifyResultsFrexpFloatIntFloat(inV, outIptr, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFrexpFloatIntFloat: " + e.toString());
+        }
+        try {
+            Allocation outIptr = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 1), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocOutIptr(outIptr);
+            scriptRelaxed.forEach_testFrexpFloatIntFloat(inV, out);
+            verifyResultsFrexpFloatIntFloat(inV, outIptr, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFrexpFloatIntFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFrexpFloatIntFloat(Allocation inV, Allocation outIptr, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        inV.copyTo(arrayInV);
+        int[] arrayOutIptr = new int[INPUTSIZE * 1];
+        outIptr.copyTo(arrayOutIptr);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeFrexp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.outIptr != arrayOutIptr[i * 1 + j]) {
+                    valid = false;
+                }
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output outIptr: ");
+                    message.append(String.format("%d", args.outIptr));
+                    message.append("\n");
+                    message.append("Actual   output outIptr: ");
+                    message.append(String.format("%d", arrayOutIptr[i * 1 + j]));
+                    if (args.outIptr != arrayOutIptr[i * 1 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkFrexpFloatIntFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkFrexpFloat2Int2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x544e0a688fe7701l, false);
+        try {
+            Allocation outIptr = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocOutIptr(outIptr);
+            script.forEach_testFrexpFloat2Int2Float2(inV, out);
+            verifyResultsFrexpFloat2Int2Float2(inV, outIptr, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFrexpFloat2Int2Float2: " + e.toString());
+        }
+        try {
+            Allocation outIptr = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocOutIptr(outIptr);
+            scriptRelaxed.forEach_testFrexpFloat2Int2Float2(inV, out);
+            verifyResultsFrexpFloat2Int2Float2(inV, outIptr, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFrexpFloat2Int2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFrexpFloat2Int2Float2(Allocation inV, Allocation outIptr, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        int[] arrayOutIptr = new int[INPUTSIZE * 2];
+        outIptr.copyTo(arrayOutIptr);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeFrexp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.outIptr != arrayOutIptr[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output outIptr: ");
+                    message.append(String.format("%d", args.outIptr));
+                    message.append("\n");
+                    message.append("Actual   output outIptr: ");
+                    message.append(String.format("%d", arrayOutIptr[i * 2 + j]));
+                    if (args.outIptr != arrayOutIptr[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkFrexpFloat2Int2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkFrexpFloat3Int3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x2afb1f097eb0e3bal, false);
+        try {
+            Allocation outIptr = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocOutIptr(outIptr);
+            script.forEach_testFrexpFloat3Int3Float3(inV, out);
+            verifyResultsFrexpFloat3Int3Float3(inV, outIptr, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFrexpFloat3Int3Float3: " + e.toString());
+        }
+        try {
+            Allocation outIptr = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocOutIptr(outIptr);
+            scriptRelaxed.forEach_testFrexpFloat3Int3Float3(inV, out);
+            verifyResultsFrexpFloat3Int3Float3(inV, outIptr, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFrexpFloat3Int3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFrexpFloat3Int3Float3(Allocation inV, Allocation outIptr, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        int[] arrayOutIptr = new int[INPUTSIZE * 4];
+        outIptr.copyTo(arrayOutIptr);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeFrexp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.outIptr != arrayOutIptr[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output outIptr: ");
+                    message.append(String.format("%d", args.outIptr));
+                    message.append("\n");
+                    message.append("Actual   output outIptr: ");
+                    message.append(String.format("%d", arrayOutIptr[i * 4 + j]));
+                    if (args.outIptr != arrayOutIptr[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkFrexpFloat3Int3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkFrexpFloat4Int4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x50b15d6c74635073l, false);
+        try {
+            Allocation outIptr = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocOutIptr(outIptr);
+            script.forEach_testFrexpFloat4Int4Float4(inV, out);
+            verifyResultsFrexpFloat4Int4Float4(inV, outIptr, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFrexpFloat4Int4Float4: " + e.toString());
+        }
+        try {
+            Allocation outIptr = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocOutIptr(outIptr);
+            scriptRelaxed.forEach_testFrexpFloat4Int4Float4(inV, out);
+            verifyResultsFrexpFloat4Int4Float4(inV, outIptr, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFrexpFloat4Int4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFrexpFloat4Int4Float4(Allocation inV, Allocation outIptr, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        int[] arrayOutIptr = new int[INPUTSIZE * 4];
+        outIptr.copyTo(arrayOutIptr);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeFrexp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.outIptr != arrayOutIptr[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output outIptr: ");
+                    message.append(String.format("%d", args.outIptr));
+                    message.append("\n");
+                    message.append("Actual   output outIptr: ");
+                    message.append(String.format("%d", arrayOutIptr[i * 4 + j]));
+                    if (args.outIptr != arrayOutIptr[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkFrexpFloat4Int4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testFrexp() {
+        checkFrexpFloatIntFloat();
+        checkFrexpFloat2Int2Float2();
+        checkFrexpFloat3Int3Float3();
+        checkFrexpFloat4Int4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestHalfRecip.java b/tests/tests/renderscript/src/android/renderscript/cts/TestHalfRecip.java
new file mode 100644
index 0000000..91cc567
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestHalfRecip.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestHalfRecip extends RSBaseCompute {
+
+    private ScriptC_TestHalfRecip script;
+    private ScriptC_TestHalfRecipRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestHalfRecip(mRS);
+        scriptRelaxed = new ScriptC_TestHalfRecipRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Floaty out;
+    }
+
+    private void checkHalfRecipFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x854e263130d5b3dl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testHalfRecipFloatFloat(inV, out);
+            verifyResultsHalfRecipFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfRecipFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testHalfRecipFloatFloat(inV, out);
+            verifyResultsHalfRecipFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfRecipFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsHalfRecipFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeHalfRecip(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkHalfRecipFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkHalfRecipFloat2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x2cf1d2db5ff23c79l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testHalfRecipFloat2Float2(inV, out);
+            verifyResultsHalfRecipFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfRecipFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testHalfRecipFloat2Float2(inV, out);
+            verifyResultsHalfRecipFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfRecipFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsHalfRecipFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeHalfRecip(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkHalfRecipFloat2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkHalfRecipFloat3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x2cf39bf6560d5d57l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testHalfRecipFloat3Float3(inV, out);
+            verifyResultsHalfRecipFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfRecipFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testHalfRecipFloat3Float3(inV, out);
+            verifyResultsHalfRecipFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfRecipFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsHalfRecipFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeHalfRecip(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkHalfRecipFloat3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkHalfRecipFloat4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x2cf565114c287e35l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testHalfRecipFloat4Float4(inV, out);
+            verifyResultsHalfRecipFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfRecipFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testHalfRecipFloat4Float4(inV, out);
+            verifyResultsHalfRecipFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfRecipFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsHalfRecipFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeHalfRecip(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkHalfRecipFloat4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testHalfRecip() {
+        checkHalfRecipFloatFloat();
+        checkHalfRecipFloat2Float2();
+        checkHalfRecipFloat3Float3();
+        checkHalfRecipFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestHalfRsqrt.java b/tests/tests/renderscript/src/android/renderscript/cts/TestHalfRsqrt.java
new file mode 100644
index 0000000..9f339a3
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestHalfRsqrt.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestHalfRsqrt extends RSBaseCompute {
+
+    private ScriptC_TestHalfRsqrt script;
+    private ScriptC_TestHalfRsqrtRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestHalfRsqrt(mRS);
+        scriptRelaxed = new ScriptC_TestHalfRsqrtRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Floaty out;
+    }
+
+    private void checkHalfRsqrtFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xad5e977ec00f0bf2l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testHalfRsqrtFloatFloat(inV, out);
+            verifyResultsHalfRsqrtFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfRsqrtFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testHalfRsqrtFloatFloat(inV, out);
+            verifyResultsHalfRsqrtFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfRsqrtFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsHalfRsqrtFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeHalfRsqrt(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkHalfRsqrtFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkHalfRsqrtFloat2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x300ee7bff12787c6l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testHalfRsqrtFloat2Float2(inV, out);
+            verifyResultsHalfRsqrtFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfRsqrtFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testHalfRsqrtFloat2Float2(inV, out);
+            verifyResultsHalfRsqrtFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfRsqrtFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsHalfRsqrtFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeHalfRsqrt(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkHalfRsqrtFloat2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkHalfRsqrtFloat3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x3010b0dae742a8a4l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testHalfRsqrtFloat3Float3(inV, out);
+            verifyResultsHalfRsqrtFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfRsqrtFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testHalfRsqrtFloat3Float3(inV, out);
+            verifyResultsHalfRsqrtFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfRsqrtFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsHalfRsqrtFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeHalfRsqrt(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkHalfRsqrtFloat3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkHalfRsqrtFloat4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x301279f5dd5dc982l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testHalfRsqrtFloat4Float4(inV, out);
+            verifyResultsHalfRsqrtFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfRsqrtFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testHalfRsqrtFloat4Float4(inV, out);
+            verifyResultsHalfRsqrtFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfRsqrtFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsHalfRsqrtFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeHalfRsqrt(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkHalfRsqrtFloat4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testHalfRsqrt() {
+        checkHalfRsqrtFloatFloat();
+        checkHalfRsqrtFloat2Float2();
+        checkHalfRsqrtFloat3Float3();
+        checkHalfRsqrtFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestHalfSqrt.java b/tests/tests/renderscript/src/android/renderscript/cts/TestHalfSqrt.java
new file mode 100644
index 0000000..00d2d92
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestHalfSqrt.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestHalfSqrt extends RSBaseCompute {
+
+    private ScriptC_TestHalfSqrt script;
+    private ScriptC_TestHalfSqrtRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestHalfSqrt(mRS);
+        scriptRelaxed = new ScriptC_TestHalfSqrtRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Floaty out;
+    }
+
+    private void checkHalfSqrtFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x8be766c7a15db5fal, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testHalfSqrtFloatFloat(inV, out);
+            verifyResultsHalfSqrtFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfSqrtFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testHalfSqrtFloatFloat(inV, out);
+            verifyResultsHalfSqrtFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfSqrtFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsHalfSqrtFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeHalfSqrt(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkHalfSqrtFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkHalfSqrtFloat2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x7a300d2342519b8el, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testHalfSqrtFloat2Float2(inV, out);
+            verifyResultsHalfSqrtFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfSqrtFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testHalfSqrtFloat2Float2(inV, out);
+            verifyResultsHalfSqrtFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfSqrtFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsHalfSqrtFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeHalfSqrt(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkHalfSqrtFloat2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkHalfSqrtFloat3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x7a31d63e386cbc6cl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testHalfSqrtFloat3Float3(inV, out);
+            verifyResultsHalfSqrtFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfSqrtFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testHalfSqrtFloat3Float3(inV, out);
+            verifyResultsHalfSqrtFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfSqrtFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsHalfSqrtFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeHalfSqrt(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkHalfSqrtFloat3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkHalfSqrtFloat4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x7a339f592e87dd4al, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testHalfSqrtFloat4Float4(inV, out);
+            verifyResultsHalfSqrtFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfSqrtFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testHalfSqrtFloat4Float4(inV, out);
+            verifyResultsHalfSqrtFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfSqrtFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsHalfSqrtFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeHalfSqrt(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkHalfSqrtFloat4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testHalfSqrt() {
+        checkHalfSqrtFloatFloat();
+        checkHalfSqrtFloat2Float2();
+        checkHalfSqrtFloat3Float3();
+        checkHalfSqrtFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestHypot.java b/tests/tests/renderscript/src/android/renderscript/cts/TestHypot.java
new file mode 100644
index 0000000..53d4c55
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestHypot.java
@@ -0,0 +1,325 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestHypot extends RSBaseCompute {
+
+    private ScriptC_TestHypot script;
+    private ScriptC_TestHypotRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestHypot(mRS);
+        scriptRelaxed = new ScriptC_TestHypotRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloatFloat {
+        public float inX;
+        public float inY;
+        public Floaty out;
+    }
+
+    private void checkHypotFloatFloatFloat() {
+        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x7deb65e7738c74dbl, false);
+        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x7deb65e7738c74dcl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInY(inY);
+            script.forEach_testHypotFloatFloatFloat(inX, out);
+            verifyResultsHypotFloatFloatFloat(inX, inY, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHypotFloatFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInY(inY);
+            scriptRelaxed.forEach_testHypotFloatFloatFloat(inX, out);
+            verifyResultsHypotFloatFloatFloat(inX, inY, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHypotFloatFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsHypotFloatFloatFloat(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
+        float[] arrayInX = new float[INPUTSIZE * 1];
+        inX.copyTo(arrayInX);
+        float[] arrayInY = new float[INPUTSIZE * 1];
+        inY.copyTo(arrayInY);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inX = arrayInX[i];
+                args.inY = arrayInY[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeHypot(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Input inY: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkHypotFloatFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkHypotFloat2Float2Float2() {
+        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x14f3c91a62f71c5dl, false);
+        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x14f3c91a62f71c5el, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInY(inY);
+            script.forEach_testHypotFloat2Float2Float2(inX, out);
+            verifyResultsHypotFloat2Float2Float2(inX, inY, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHypotFloat2Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInY(inY);
+            scriptRelaxed.forEach_testHypotFloat2Float2Float2(inX, out);
+            verifyResultsHypotFloat2Float2Float2(inX, inY, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHypotFloat2Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsHypotFloat2Float2Float2(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
+        float[] arrayInX = new float[INPUTSIZE * 2];
+        inX.copyTo(arrayInX);
+        float[] arrayInY = new float[INPUTSIZE * 2];
+        inY.copyTo(arrayInY);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inX = arrayInX[i * 2 + j];
+                args.inY = arrayInY[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeHypot(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Input inY: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkHypotFloat2Float2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkHypotFloat3Float3Float3() {
+        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x6958a73a64d51dfel, false);
+        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x6958a73a64d51dffl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInY(inY);
+            script.forEach_testHypotFloat3Float3Float3(inX, out);
+            verifyResultsHypotFloat3Float3Float3(inX, inY, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHypotFloat3Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInY(inY);
+            scriptRelaxed.forEach_testHypotFloat3Float3Float3(inX, out);
+            verifyResultsHypotFloat3Float3Float3(inX, inY, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHypotFloat3Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsHypotFloat3Float3Float3(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
+        float[] arrayInX = new float[INPUTSIZE * 4];
+        inX.copyTo(arrayInX);
+        float[] arrayInY = new float[INPUTSIZE * 4];
+        inY.copyTo(arrayInY);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inX = arrayInX[i * 4 + j];
+                args.inY = arrayInY[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeHypot(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Input inY: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkHypotFloat3Float3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkHypotFloat4Float4Float4() {
+        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xbdbd855a66b31f9fl, false);
+        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xbdbd855a66b31fa0l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInY(inY);
+            script.forEach_testHypotFloat4Float4Float4(inX, out);
+            verifyResultsHypotFloat4Float4Float4(inX, inY, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHypotFloat4Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInY(inY);
+            scriptRelaxed.forEach_testHypotFloat4Float4Float4(inX, out);
+            verifyResultsHypotFloat4Float4Float4(inX, inY, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHypotFloat4Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsHypotFloat4Float4Float4(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
+        float[] arrayInX = new float[INPUTSIZE * 4];
+        inX.copyTo(arrayInX);
+        float[] arrayInY = new float[INPUTSIZE * 4];
+        inY.copyTo(arrayInY);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inX = arrayInX[i * 4 + j];
+                args.inY = arrayInY[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeHypot(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Input inY: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkHypotFloat4Float4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testHypot() {
+        checkHypotFloatFloatFloat();
+        checkHypotFloat2Float2Float2();
+        checkHypotFloat3Float3Float3();
+        checkHypotFloat4Float4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestIlogb.java b/tests/tests/renderscript/src/android/renderscript/cts/TestIlogb.java
new file mode 100644
index 0000000..c15e9f2
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestIlogb.java
@@ -0,0 +1,280 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestIlogb extends RSBaseCompute {
+
+    private ScriptC_TestIlogb script;
+    private ScriptC_TestIlogbRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestIlogb(mRS);
+        scriptRelaxed = new ScriptC_TestIlogbRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatInt {
+        public float in;
+        public int out;
+    }
+
+    private void checkIlogbFloatInt() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xc0c48da27f084aefl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 1), INPUTSIZE);
+            script.forEach_testIlogbFloatInt(in, out);
+            verifyResultsIlogbFloatInt(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testIlogbFloatInt: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testIlogbFloatInt(in, out);
+            verifyResultsIlogbFloatInt(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testIlogbFloatInt: " + e.toString());
+        }
+    }
+
+    private void verifyResultsIlogbFloatInt(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 1];
+        in.copyTo(arrayIn);
+        int[] arrayOut = new int[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatInt args = new ArgumentsFloatInt();
+                args.in = arrayIn[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeIlogb(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 1 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 1 + j]));
+                    if (args.out != arrayOut[i * 1 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkIlogbFloatInt" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkIlogbFloat2Int2() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x4ba2fa846382ada1l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            script.forEach_testIlogbFloat2Int2(in, out);
+            verifyResultsIlogbFloat2Int2(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testIlogbFloat2Int2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testIlogbFloat2Int2(in, out);
+            verifyResultsIlogbFloat2Int2(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testIlogbFloat2Int2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsIlogbFloat2Int2(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 2];
+        in.copyTo(arrayIn);
+        int[] arrayOut = new int[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatInt args = new ArgumentsFloatInt();
+                args.in = arrayIn[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeIlogb(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkIlogbFloat2Int2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkIlogbFloat3Int3() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x4ba2fa85dc4b0d43l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            script.forEach_testIlogbFloat3Int3(in, out);
+            verifyResultsIlogbFloat3Int3(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testIlogbFloat3Int3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testIlogbFloat3Int3(in, out);
+            verifyResultsIlogbFloat3Int3(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testIlogbFloat3Int3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsIlogbFloat3Int3(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        int[] arrayOut = new int[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatInt args = new ArgumentsFloatInt();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeIlogb(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkIlogbFloat3Int3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkIlogbFloat4Int4() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x4ba2fa8755136ce5l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            script.forEach_testIlogbFloat4Int4(in, out);
+            verifyResultsIlogbFloat4Int4(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testIlogbFloat4Int4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testIlogbFloat4Int4(in, out);
+            verifyResultsIlogbFloat4Int4(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testIlogbFloat4Int4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsIlogbFloat4Int4(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        int[] arrayOut = new int[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatInt args = new ArgumentsFloatInt();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeIlogb(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkIlogbFloat4Int4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testIlogb() {
+        checkIlogbFloatInt();
+        checkIlogbFloat2Int2();
+        checkIlogbFloat3Int3();
+        checkIlogbFloat4Int4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestLdexp.java b/tests/tests/renderscript/src/android/renderscript/cts/TestLdexp.java
new file mode 100644
index 0000000..e565113
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestLdexp.java
@@ -0,0 +1,528 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestLdexp extends RSBaseCompute {
+
+    private ScriptC_TestLdexp script;
+    private ScriptC_TestLdexpRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestLdexp(mRS);
+        scriptRelaxed = new ScriptC_TestLdexpRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatIntFloat {
+        public float inX;
+        public int inY;
+        public Floaty out;
+    }
+
+    private void checkLdexpFloatIntFloat() {
+        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xdeada0999238fe8bl, false);
+        Allocation inY = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0xdeada0999238fe8cl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInY(inY);
+            script.forEach_testLdexpFloatIntFloat(inX, out);
+            verifyResultsLdexpFloatIntFloat(inX, inY, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLdexpFloatIntFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInY(inY);
+            scriptRelaxed.forEach_testLdexpFloatIntFloat(inX, out);
+            verifyResultsLdexpFloatIntFloat(inX, inY, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLdexpFloatIntFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLdexpFloatIntFloat(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
+        float[] arrayInX = new float[INPUTSIZE * 1];
+        inX.copyTo(arrayInX);
+        int[] arrayInY = new int[INPUTSIZE * 1];
+        inY.copyTo(arrayInY);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
+                args.inX = arrayInX[i];
+                args.inY = arrayInY[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeLdexp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Input inY: ");
+                    message.append(String.format("%d", args.inY));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkLdexpFloatIntFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkLdexpFloat2Int2Float2() {
+        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x5492762140d0ca17l, false);
+        Allocation inY = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 2, 0x5492762140d0ca18l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInY(inY);
+            script.forEach_testLdexpFloat2Int2Float2(inX, out);
+            verifyResultsLdexpFloat2Int2Float2(inX, inY, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLdexpFloat2Int2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInY(inY);
+            scriptRelaxed.forEach_testLdexpFloat2Int2Float2(inX, out);
+            verifyResultsLdexpFloat2Int2Float2(inX, inY, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLdexpFloat2Int2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLdexpFloat2Int2Float2(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
+        float[] arrayInX = new float[INPUTSIZE * 2];
+        inX.copyTo(arrayInX);
+        int[] arrayInY = new int[INPUTSIZE * 2];
+        inY.copyTo(arrayInY);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
+                args.inX = arrayInX[i * 2 + j];
+                args.inY = arrayInY[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeLdexp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Input inY: ");
+                    message.append(String.format("%d", args.inY));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkLdexpFloat2Int2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkLdexpFloat3Int3Float3() {
+        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x7a48b484368336d0l, false);
+        Allocation inY = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 3, 0x7a48b484368336d1l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInY(inY);
+            script.forEach_testLdexpFloat3Int3Float3(inX, out);
+            verifyResultsLdexpFloat3Int3Float3(inX, inY, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLdexpFloat3Int3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInY(inY);
+            scriptRelaxed.forEach_testLdexpFloat3Int3Float3(inX, out);
+            verifyResultsLdexpFloat3Int3Float3(inX, inY, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLdexpFloat3Int3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLdexpFloat3Int3Float3(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
+        float[] arrayInX = new float[INPUTSIZE * 4];
+        inX.copyTo(arrayInX);
+        int[] arrayInY = new int[INPUTSIZE * 4];
+        inY.copyTo(arrayInY);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
+                args.inX = arrayInX[i * 4 + j];
+                args.inY = arrayInY[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeLdexp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Input inY: ");
+                    message.append(String.format("%d", args.inY));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkLdexpFloat3Int3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkLdexpFloat4Int4Float4() {
+        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x9ffef2e72c35a389l, false);
+        Allocation inY = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 4, 0x9ffef2e72c35a38al, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInY(inY);
+            script.forEach_testLdexpFloat4Int4Float4(inX, out);
+            verifyResultsLdexpFloat4Int4Float4(inX, inY, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLdexpFloat4Int4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInY(inY);
+            scriptRelaxed.forEach_testLdexpFloat4Int4Float4(inX, out);
+            verifyResultsLdexpFloat4Int4Float4(inX, inY, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLdexpFloat4Int4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLdexpFloat4Int4Float4(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
+        float[] arrayInX = new float[INPUTSIZE * 4];
+        inX.copyTo(arrayInX);
+        int[] arrayInY = new int[INPUTSIZE * 4];
+        inY.copyTo(arrayInY);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
+                args.inX = arrayInX[i * 4 + j];
+                args.inY = arrayInY[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeLdexp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Input inY: ");
+                    message.append(String.format("%d", args.inY));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkLdexpFloat4Int4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkLdexpFloat2IntFloat2() {
+        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xa2b6e0c39777b8c1l, false);
+        Allocation inY = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0xa2b6e0c39777b8c2l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInY(inY);
+            script.forEach_testLdexpFloat2IntFloat2(inX, out);
+            verifyResultsLdexpFloat2IntFloat2(inX, inY, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLdexpFloat2IntFloat2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInY(inY);
+            scriptRelaxed.forEach_testLdexpFloat2IntFloat2(inX, out);
+            verifyResultsLdexpFloat2IntFloat2(inX, inY, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLdexpFloat2IntFloat2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLdexpFloat2IntFloat2(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
+        float[] arrayInX = new float[INPUTSIZE * 2];
+        inX.copyTo(arrayInX);
+        int[] arrayInY = new int[INPUTSIZE * 1];
+        inY.copyTo(arrayInY);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
+                args.inX = arrayInX[i * 2 + j];
+                args.inY = arrayInY[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeLdexp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Input inY: ");
+                    message.append(String.format("%d", args.inY));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkLdexpFloat2IntFloat2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkLdexpFloat3IntFloat3() {
+        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xcd4401424a114a65l, false);
+        Allocation inY = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0xcd4401424a114a66l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInY(inY);
+            script.forEach_testLdexpFloat3IntFloat3(inX, out);
+            verifyResultsLdexpFloat3IntFloat3(inX, inY, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLdexpFloat3IntFloat3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInY(inY);
+            scriptRelaxed.forEach_testLdexpFloat3IntFloat3(inX, out);
+            verifyResultsLdexpFloat3IntFloat3(inX, inY, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLdexpFloat3IntFloat3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLdexpFloat3IntFloat3(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
+        float[] arrayInX = new float[INPUTSIZE * 4];
+        inX.copyTo(arrayInX);
+        int[] arrayInY = new int[INPUTSIZE * 1];
+        inY.copyTo(arrayInY);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
+                args.inX = arrayInX[i * 4 + j];
+                args.inY = arrayInY[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeLdexp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Input inY: ");
+                    message.append(String.format("%d", args.inY));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkLdexpFloat3IntFloat3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkLdexpFloat4IntFloat4() {
+        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xf7d121c0fcaadc09l, false);
+        Allocation inY = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0xf7d121c0fcaadc0al, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInY(inY);
+            script.forEach_testLdexpFloat4IntFloat4(inX, out);
+            verifyResultsLdexpFloat4IntFloat4(inX, inY, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLdexpFloat4IntFloat4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInY(inY);
+            scriptRelaxed.forEach_testLdexpFloat4IntFloat4(inX, out);
+            verifyResultsLdexpFloat4IntFloat4(inX, inY, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLdexpFloat4IntFloat4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLdexpFloat4IntFloat4(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
+        float[] arrayInX = new float[INPUTSIZE * 4];
+        inX.copyTo(arrayInX);
+        int[] arrayInY = new int[INPUTSIZE * 1];
+        inY.copyTo(arrayInY);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
+                args.inX = arrayInX[i * 4 + j];
+                args.inY = arrayInY[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeLdexp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Input inY: ");
+                    message.append(String.format("%d", args.inY));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkLdexpFloat4IntFloat4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testLdexp() {
+        checkLdexpFloatIntFloat();
+        checkLdexpFloat2Int2Float2();
+        checkLdexpFloat3Int3Float3();
+        checkLdexpFloat4Int4Float4();
+        checkLdexpFloat2IntFloat2();
+        checkLdexpFloat3IntFloat3();
+        checkLdexpFloat4IntFloat4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestLength.java b/tests/tests/renderscript/src/android/renderscript/cts/TestLength.java
new file mode 100644
index 0000000..d509e9a
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestLength.java
@@ -0,0 +1,300 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestLength extends RSBaseCompute {
+
+    private ScriptC_TestLength script;
+    private ScriptC_TestLengthRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestLength(mRS);
+        scriptRelaxed = new ScriptC_TestLengthRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Floaty out;
+    }
+
+    private void checkLengthFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x8119352509f7cc9fl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testLengthFloatFloat(inV, out);
+            verifyResultsLengthFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLengthFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testLengthFloatFloat(inV, out);
+            verifyResultsLengthFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLengthFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLengthFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+            // Create the appropriate sized arrays in args
+            // Fill args with the input values
+            args.inV = arrayInV[i];
+            Floaty.setRelaxed(relaxed);
+            CoreMathVerifier.computeLength(args);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(arrayOut[i])) {
+                valid = false;
+            }
+            if (!valid) {
+                StringBuilder message = new StringBuilder();
+                message.append("Input inV: ");
+                message.append(String.format("%14.8g %8x %15a",
+                        arrayInV[i], Float.floatToRawIntBits(arrayInV[i]), arrayInV[i]));
+                message.append("\n");
+                message.append("Expected output out: ");
+                message.append(args.out.toString());
+                message.append("\n");
+                message.append("Actual   output out: ");
+                message.append(String.format("%14.8g %8x %15a",
+                        arrayOut[i], Float.floatToRawIntBits(arrayOut[i]), arrayOut[i]));
+                if (!args.out.couldBe(arrayOut[i])) {
+                    message.append(" FAIL");
+                }
+                message.append("\n");
+                assertTrue("Incorrect output for checkLengthFloatFloat" +
+                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+            }
+        }
+    }
+
+    public class ArgumentsFloatNFloat {
+        public float[] inV;
+        public Floaty out;
+    }
+
+    private void checkLengthFloat2Float() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xaf3b0f345dd9595dl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testLengthFloat2Float(inV, out);
+            verifyResultsLengthFloat2Float(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLengthFloat2Float: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testLengthFloat2Float(inV, out);
+            verifyResultsLengthFloat2Float(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLengthFloat2Float: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLengthFloat2Float(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsFloatNFloat args = new ArgumentsFloatNFloat();
+            // Create the appropriate sized arrays in args
+            args.inV = new float[2];
+            // Fill args with the input values
+            for (int j = 0; j < 2 ; j++) {
+                args.inV[j] = arrayInV[i * 2 + j];
+            }
+            Floaty.setRelaxed(relaxed);
+            CoreMathVerifier.computeLength(args);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(arrayOut[i])) {
+                valid = false;
+            }
+            if (!valid) {
+                StringBuilder message = new StringBuilder();
+                for (int j = 0; j < 2 ; j++) {
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayInV[i * 2 + j], Float.floatToRawIntBits(arrayInV[i * 2 + j]), arrayInV[i * 2 + j]));
+                    message.append("\n");
+                }
+                message.append("Expected output out: ");
+                message.append(args.out.toString());
+                message.append("\n");
+                message.append("Actual   output out: ");
+                message.append(String.format("%14.8g %8x %15a",
+                        arrayOut[i], Float.floatToRawIntBits(arrayOut[i]), arrayOut[i]));
+                if (!args.out.couldBe(arrayOut[i])) {
+                    message.append(" FAIL");
+                }
+                message.append("\n");
+                assertTrue("Incorrect output for checkLengthFloat2Float" +
+                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+            }
+        }
+    }
+
+    private void checkLengthFloat3Float() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xaf3b19d5bcdfe7bel, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testLengthFloat3Float(inV, out);
+            verifyResultsLengthFloat3Float(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLengthFloat3Float: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testLengthFloat3Float(inV, out);
+            verifyResultsLengthFloat3Float(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLengthFloat3Float: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLengthFloat3Float(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsFloatNFloat args = new ArgumentsFloatNFloat();
+            // Create the appropriate sized arrays in args
+            args.inV = new float[3];
+            // Fill args with the input values
+            for (int j = 0; j < 3 ; j++) {
+                args.inV[j] = arrayInV[i * 4 + j];
+            }
+            Floaty.setRelaxed(relaxed);
+            CoreMathVerifier.computeLength(args);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(arrayOut[i])) {
+                valid = false;
+            }
+            if (!valid) {
+                StringBuilder message = new StringBuilder();
+                for (int j = 0; j < 3 ; j++) {
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayInV[i * 4 + j], Float.floatToRawIntBits(arrayInV[i * 4 + j]), arrayInV[i * 4 + j]));
+                    message.append("\n");
+                }
+                message.append("Expected output out: ");
+                message.append(args.out.toString());
+                message.append("\n");
+                message.append("Actual   output out: ");
+                message.append(String.format("%14.8g %8x %15a",
+                        arrayOut[i], Float.floatToRawIntBits(arrayOut[i]), arrayOut[i]));
+                if (!args.out.couldBe(arrayOut[i])) {
+                    message.append(" FAIL");
+                }
+                message.append("\n");
+                assertTrue("Incorrect output for checkLengthFloat3Float" +
+                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+            }
+        }
+    }
+
+    private void checkLengthFloat4Float() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xaf3b24771be6761fl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testLengthFloat4Float(inV, out);
+            verifyResultsLengthFloat4Float(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLengthFloat4Float: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testLengthFloat4Float(inV, out);
+            verifyResultsLengthFloat4Float(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLengthFloat4Float: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLengthFloat4Float(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsFloatNFloat args = new ArgumentsFloatNFloat();
+            // Create the appropriate sized arrays in args
+            args.inV = new float[4];
+            // Fill args with the input values
+            for (int j = 0; j < 4 ; j++) {
+                args.inV[j] = arrayInV[i * 4 + j];
+            }
+            Floaty.setRelaxed(relaxed);
+            CoreMathVerifier.computeLength(args);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(arrayOut[i])) {
+                valid = false;
+            }
+            if (!valid) {
+                StringBuilder message = new StringBuilder();
+                for (int j = 0; j < 4 ; j++) {
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayInV[i * 4 + j], Float.floatToRawIntBits(arrayInV[i * 4 + j]), arrayInV[i * 4 + j]));
+                    message.append("\n");
+                }
+                message.append("Expected output out: ");
+                message.append(args.out.toString());
+                message.append("\n");
+                message.append("Actual   output out: ");
+                message.append(String.format("%14.8g %8x %15a",
+                        arrayOut[i], Float.floatToRawIntBits(arrayOut[i]), arrayOut[i]));
+                if (!args.out.couldBe(arrayOut[i])) {
+                    message.append(" FAIL");
+                }
+                message.append("\n");
+                assertTrue("Incorrect output for checkLengthFloat4Float" +
+                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+            }
+        }
+    }
+
+    public void testLength() {
+        checkLengthFloatFloat();
+        checkLengthFloat2Float();
+        checkLengthFloat3Float();
+        checkLengthFloat4Float();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestLgamma.java b/tests/tests/renderscript/src/android/renderscript/cts/TestLgamma.java
new file mode 100644
index 0000000..d3c44e4
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestLgamma.java
@@ -0,0 +1,602 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestLgamma extends RSBaseCompute {
+
+    private ScriptC_TestLgamma script;
+    private ScriptC_TestLgammaRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestLgamma(mRS);
+        scriptRelaxed = new ScriptC_TestLgammaRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float in;
+        public Floaty out;
+    }
+
+    private void checkLgammaFloatFloat() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xe748c67429cab138l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testLgammaFloatFloat(in, out);
+            verifyResultsLgammaFloatFloat(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLgammaFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testLgammaFloatFloat(in, out);
+            verifyResultsLgammaFloatFloat(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLgammaFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLgammaFloatFloat(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 1];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeLgamma(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkLgammaFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkLgammaFloat2Float2() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x7ca07efd8a327894l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testLgammaFloat2Float2(in, out);
+            verifyResultsLgammaFloat2Float2(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLgammaFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testLgammaFloat2Float2(in, out);
+            verifyResultsLgammaFloat2Float2(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLgammaFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLgammaFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 2];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeLgamma(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkLgammaFloat2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkLgammaFloat3Float3() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x7ca0899ee9390e2el, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testLgammaFloat3Float3(in, out);
+            verifyResultsLgammaFloat3Float3(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLgammaFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testLgammaFloat3Float3(in, out);
+            verifyResultsLgammaFloat3Float3(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLgammaFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLgammaFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeLgamma(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkLgammaFloat3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkLgammaFloat4Float4() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x7ca09440483fa3c8l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testLgammaFloat4Float4(in, out);
+            verifyResultsLgammaFloat4Float4(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLgammaFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testLgammaFloat4Float4(in, out);
+            verifyResultsLgammaFloat4Float4(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLgammaFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLgammaFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeLgamma(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkLgammaFloat4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsFloatIntFloat {
+        public float inX;
+        public int outY;
+        public Floaty out;
+    }
+
+    private void checkLgammaFloatIntFloat() {
+        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x2a62d992979c4bb9l, false);
+        try {
+            Allocation outY = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 1), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocOutY(outY);
+            script.forEach_testLgammaFloatIntFloat(inX, out);
+            verifyResultsLgammaFloatIntFloat(inX, outY, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLgammaFloatIntFloat: " + e.toString());
+        }
+        try {
+            Allocation outY = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 1), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocOutY(outY);
+            scriptRelaxed.forEach_testLgammaFloatIntFloat(inX, out);
+            verifyResultsLgammaFloatIntFloat(inX, outY, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLgammaFloatIntFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLgammaFloatIntFloat(Allocation inX, Allocation outY, Allocation out, boolean relaxed) {
+        float[] arrayInX = new float[INPUTSIZE * 1];
+        inX.copyTo(arrayInX);
+        int[] arrayOutY = new int[INPUTSIZE * 1];
+        outY.copyTo(arrayOutY);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
+                args.inX = arrayInX[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeLgamma(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.outY != arrayOutY[i * 1 + j]) {
+                    valid = false;
+                }
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Expected output outY: ");
+                    message.append(String.format("%d", args.outY));
+                    message.append("\n");
+                    message.append("Actual   output outY: ");
+                    message.append(String.format("%d", arrayOutY[i * 1 + j]));
+                    if (args.outY != arrayOutY[i * 1 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkLgammaFloatIntFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkLgammaFloat2Int2Float2() {
+        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x409fb9a5984bcf81l, false);
+        try {
+            Allocation outY = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocOutY(outY);
+            script.forEach_testLgammaFloat2Int2Float2(inX, out);
+            verifyResultsLgammaFloat2Int2Float2(inX, outY, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLgammaFloat2Int2Float2: " + e.toString());
+        }
+        try {
+            Allocation outY = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocOutY(outY);
+            scriptRelaxed.forEach_testLgammaFloat2Int2Float2(inX, out);
+            verifyResultsLgammaFloat2Int2Float2(inX, outY, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLgammaFloat2Int2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLgammaFloat2Int2Float2(Allocation inX, Allocation outY, Allocation out, boolean relaxed) {
+        float[] arrayInX = new float[INPUTSIZE * 2];
+        inX.copyTo(arrayInX);
+        int[] arrayOutY = new int[INPUTSIZE * 2];
+        outY.copyTo(arrayOutY);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
+                args.inX = arrayInX[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeLgamma(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.outY != arrayOutY[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Expected output outY: ");
+                    message.append(String.format("%d", args.outY));
+                    message.append("\n");
+                    message.append("Actual   output outY: ");
+                    message.append(String.format("%d", arrayOutY[i * 2 + j]));
+                    if (args.outY != arrayOutY[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkLgammaFloat2Int2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkLgammaFloat3Int3Float3() {
+        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x6655f8088dfe3c3al, false);
+        try {
+            Allocation outY = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocOutY(outY);
+            script.forEach_testLgammaFloat3Int3Float3(inX, out);
+            verifyResultsLgammaFloat3Int3Float3(inX, outY, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLgammaFloat3Int3Float3: " + e.toString());
+        }
+        try {
+            Allocation outY = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocOutY(outY);
+            scriptRelaxed.forEach_testLgammaFloat3Int3Float3(inX, out);
+            verifyResultsLgammaFloat3Int3Float3(inX, outY, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLgammaFloat3Int3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLgammaFloat3Int3Float3(Allocation inX, Allocation outY, Allocation out, boolean relaxed) {
+        float[] arrayInX = new float[INPUTSIZE * 4];
+        inX.copyTo(arrayInX);
+        int[] arrayOutY = new int[INPUTSIZE * 4];
+        outY.copyTo(arrayOutY);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
+                args.inX = arrayInX[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeLgamma(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.outY != arrayOutY[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Expected output outY: ");
+                    message.append(String.format("%d", args.outY));
+                    message.append("\n");
+                    message.append("Actual   output outY: ");
+                    message.append(String.format("%d", arrayOutY[i * 4 + j]));
+                    if (args.outY != arrayOutY[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkLgammaFloat3Int3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkLgammaFloat4Int4Float4() {
+        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x8c0c366b83b0a8f3l, false);
+        try {
+            Allocation outY = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocOutY(outY);
+            script.forEach_testLgammaFloat4Int4Float4(inX, out);
+            verifyResultsLgammaFloat4Int4Float4(inX, outY, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLgammaFloat4Int4Float4: " + e.toString());
+        }
+        try {
+            Allocation outY = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocOutY(outY);
+            scriptRelaxed.forEach_testLgammaFloat4Int4Float4(inX, out);
+            verifyResultsLgammaFloat4Int4Float4(inX, outY, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLgammaFloat4Int4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLgammaFloat4Int4Float4(Allocation inX, Allocation outY, Allocation out, boolean relaxed) {
+        float[] arrayInX = new float[INPUTSIZE * 4];
+        inX.copyTo(arrayInX);
+        int[] arrayOutY = new int[INPUTSIZE * 4];
+        outY.copyTo(arrayOutY);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
+                args.inX = arrayInX[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeLgamma(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.outY != arrayOutY[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Expected output outY: ");
+                    message.append(String.format("%d", args.outY));
+                    message.append("\n");
+                    message.append("Actual   output outY: ");
+                    message.append(String.format("%d", arrayOutY[i * 4 + j]));
+                    if (args.outY != arrayOutY[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkLgammaFloat4Int4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testLgamma() {
+        checkLgammaFloatFloat();
+        checkLgammaFloat2Float2();
+        checkLgammaFloat3Float3();
+        checkLgammaFloat4Float4();
+        checkLgammaFloatIntFloat();
+        checkLgammaFloat2Int2Float2();
+        checkLgammaFloat3Int3Float3();
+        checkLgammaFloat4Int4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestLog.java b/tests/tests/renderscript/src/android/renderscript/cts/TestLog.java
new file mode 100644
index 0000000..d9dd9fc
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestLog.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestLog extends RSBaseCompute {
+
+    private ScriptC_TestLog script;
+    private ScriptC_TestLogRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestLog(mRS);
+        scriptRelaxed = new ScriptC_TestLogRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float in;
+        public Floaty out;
+    }
+
+    private void checkLogFloatFloat() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x371a946136907325l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testLogFloatFloat(in, out);
+            verifyResultsLogFloatFloat(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLogFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testLogFloatFloat(in, out);
+            verifyResultsLogFloatFloat(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLogFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLogFloatFloat(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 1];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeLog(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkLogFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkLogFloat2Float2() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xfef8d41eca882159l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testLogFloat2Float2(in, out);
+            verifyResultsLogFloat2Float2(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLogFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testLogFloat2Float2(in, out);
+            verifyResultsLogFloat2Float2(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLogFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLogFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 2];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeLog(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkLogFloat2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkLogFloat3Float3() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xfef8dec0298eb6f3l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testLogFloat3Float3(in, out);
+            verifyResultsLogFloat3Float3(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLogFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testLogFloat3Float3(in, out);
+            verifyResultsLogFloat3Float3(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLogFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLogFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeLog(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkLogFloat3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkLogFloat4Float4() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xfef8e96188954c8dl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testLogFloat4Float4(in, out);
+            verifyResultsLogFloat4Float4(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLogFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testLogFloat4Float4(in, out);
+            verifyResultsLogFloat4Float4(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLogFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLogFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeLog(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkLogFloat4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testLog() {
+        checkLogFloatFloat();
+        checkLogFloat2Float2();
+        checkLogFloat3Float3();
+        checkLogFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestLog10.java b/tests/tests/renderscript/src/android/renderscript/cts/TestLog10.java
new file mode 100644
index 0000000..9711f6b
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestLog10.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestLog10 extends RSBaseCompute {
+
+    private ScriptC_TestLog10 script;
+    private ScriptC_TestLog10Relaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestLog10(mRS);
+        scriptRelaxed = new ScriptC_TestLog10Relaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float in;
+        public Floaty out;
+    }
+
+    private void checkLog10FloatFloat() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xe09b228ed779b7a0l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testLog10FloatFloat(in, out);
+            verifyResultsLog10FloatFloat(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog10FloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testLog10FloatFloat(in, out);
+            verifyResultsLog10FloatFloat(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog10FloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLog10FloatFloat(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 1];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeLog10(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkLog10FloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkLog10Float2Float2() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x407bbbadff57bdbcl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testLog10Float2Float2(in, out);
+            verifyResultsLog10Float2Float2(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog10Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testLog10Float2Float2(in, out);
+            verifyResultsLog10Float2Float2(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog10Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLog10Float2Float2(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 2];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeLog10(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkLog10Float2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkLog10Float3Float3() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x407bc64f5e5e5356l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testLog10Float3Float3(in, out);
+            verifyResultsLog10Float3Float3(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog10Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testLog10Float3Float3(in, out);
+            verifyResultsLog10Float3Float3(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog10Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLog10Float3Float3(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeLog10(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkLog10Float3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkLog10Float4Float4() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x407bd0f0bd64e8f0l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testLog10Float4Float4(in, out);
+            verifyResultsLog10Float4Float4(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog10Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testLog10Float4Float4(in, out);
+            verifyResultsLog10Float4Float4(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog10Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLog10Float4Float4(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeLog10(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkLog10Float4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testLog10() {
+        checkLog10FloatFloat();
+        checkLog10Float2Float2();
+        checkLog10Float3Float3();
+        checkLog10Float4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestLog1p.java b/tests/tests/renderscript/src/android/renderscript/cts/TestLog1p.java
new file mode 100644
index 0000000..4d455fa
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestLog1p.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestLog1p extends RSBaseCompute {
+
+    private ScriptC_TestLog1p script;
+    private ScriptC_TestLog1pRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestLog1p(mRS);
+        scriptRelaxed = new ScriptC_TestLog1pRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float in;
+        public Floaty out;
+    }
+
+    private void checkLog1pFloatFloat() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x83e3423b7d907be0l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testLog1pFloatFloat(in, out);
+            verifyResultsLog1pFloatFloat(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog1pFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testLog1pFloatFloat(in, out);
+            verifyResultsLog1pFloatFloat(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog1pFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLog1pFloatFloat(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 1];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeLog1p(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkLog1pFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkLog1pFloat2Float2() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x946881a999c72ffcl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testLog1pFloat2Float2(in, out);
+            verifyResultsLog1pFloat2Float2(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog1pFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testLog1pFloat2Float2(in, out);
+            verifyResultsLog1pFloat2Float2(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog1pFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLog1pFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 2];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeLog1p(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkLog1pFloat2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkLog1pFloat3Float3() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x94688c4af8cdc596l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testLog1pFloat3Float3(in, out);
+            verifyResultsLog1pFloat3Float3(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog1pFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testLog1pFloat3Float3(in, out);
+            verifyResultsLog1pFloat3Float3(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog1pFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLog1pFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeLog1p(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkLog1pFloat3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkLog1pFloat4Float4() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x946896ec57d45b30l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testLog1pFloat4Float4(in, out);
+            verifyResultsLog1pFloat4Float4(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog1pFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testLog1pFloat4Float4(in, out);
+            verifyResultsLog1pFloat4Float4(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog1pFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLog1pFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeLog1p(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkLog1pFloat4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testLog1p() {
+        checkLog1pFloatFloat();
+        checkLog1pFloat2Float2();
+        checkLog1pFloat3Float3();
+        checkLog1pFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestLog2.java b/tests/tests/renderscript/src/android/renderscript/cts/TestLog2.java
new file mode 100644
index 0000000..bf7d420
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestLog2.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestLog2 extends RSBaseCompute {
+
+    private ScriptC_TestLog2 script;
+    private ScriptC_TestLog2Relaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestLog2(mRS);
+        scriptRelaxed = new ScriptC_TestLog2Relaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float in;
+        public Floaty out;
+    }
+
+    private void checkLog2FloatFloat() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x390bea9a53d34bfl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testLog2FloatFloat(in, out);
+            verifyResultsLog2FloatFloat(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog2FloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testLog2FloatFloat(in, out);
+            verifyResultsLog2FloatFloat(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog2FloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLog2FloatFloat(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 1];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeLog2(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkLog2FloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkLog2Float2Float2() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xc0703946284a72a3l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testLog2Float2Float2(in, out);
+            verifyResultsLog2Float2Float2(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog2Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testLog2Float2Float2(in, out);
+            verifyResultsLog2Float2Float2(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog2Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLog2Float2Float2(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 2];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeLog2(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkLog2Float2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkLog2Float3Float3() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xc07043e78751083dl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testLog2Float3Float3(in, out);
+            verifyResultsLog2Float3Float3(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog2Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testLog2Float3Float3(in, out);
+            verifyResultsLog2Float3Float3(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog2Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLog2Float3Float3(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeLog2(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkLog2Float3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkLog2Float4Float4() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xc0704e88e6579dd7l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testLog2Float4Float4(in, out);
+            verifyResultsLog2Float4Float4(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog2Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testLog2Float4Float4(in, out);
+            verifyResultsLog2Float4Float4(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog2Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLog2Float4Float4(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeLog2(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkLog2Float4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testLog2() {
+        checkLog2FloatFloat();
+        checkLog2Float2Float2();
+        checkLog2Float3Float3();
+        checkLog2Float4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestLogb.java b/tests/tests/renderscript/src/android/renderscript/cts/TestLogb.java
new file mode 100644
index 0000000..4ff2eb5
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestLogb.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestLogb extends RSBaseCompute {
+
+    private ScriptC_TestLogb script;
+    private ScriptC_TestLogbRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestLogb(mRS);
+        scriptRelaxed = new ScriptC_TestLogbRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float in;
+        public Floaty out;
+    }
+
+    private void checkLogbFloatFloat() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xfe06d66b21ce47efl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testLogbFloatFloat(in, out);
+            verifyResultsLogbFloatFloat(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLogbFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testLogbFloatFloat(in, out);
+            verifyResultsLogbFloatFloat(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLogbFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLogbFloatFloat(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 1];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeLogb(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkLogbFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkLogbFloat2Float2() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xbf61cdc2dc1e0853l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testLogbFloat2Float2(in, out);
+            verifyResultsLogbFloat2Float2(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLogbFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testLogbFloat2Float2(in, out);
+            verifyResultsLogbFloat2Float2(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLogbFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLogbFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 2];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeLogb(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkLogbFloat2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkLogbFloat3Float3() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xbf61d8643b249dedl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testLogbFloat3Float3(in, out);
+            verifyResultsLogbFloat3Float3(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLogbFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testLogbFloat3Float3(in, out);
+            verifyResultsLogbFloat3Float3(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLogbFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLogbFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeLogb(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkLogbFloat3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkLogbFloat4Float4() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xbf61e3059a2b3387l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testLogbFloat4Float4(in, out);
+            verifyResultsLogbFloat4Float4(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLogbFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testLogbFloat4Float4(in, out);
+            verifyResultsLogbFloat4Float4(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLogbFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLogbFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeLogb(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkLogbFloat4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testLogb() {
+        checkLogbFloatFloat();
+        checkLogbFloat2Float2();
+        checkLogbFloat3Float3();
+        checkLogbFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestMad.java b/tests/tests/renderscript/src/android/renderscript/cts/TestMad.java
new file mode 100644
index 0000000..1d0e1ac
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestMad.java
@@ -0,0 +1,366 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestMad extends RSBaseCompute {
+
+    private ScriptC_TestMad script;
+    private ScriptC_TestMadRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestMad(mRS);
+        scriptRelaxed = new ScriptC_TestMadRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloatFloatFloat {
+        public float inA;
+        public float inB;
+        public float inC;
+        public Floaty out;
+    }
+
+    private void checkMadFloatFloatFloatFloat() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xb3b9b8429c37eacl, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xb3b9b8429c37eadl, false);
+        Allocation inC = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xb3b9b8429c37eael, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.set_gAllocInC(inC);
+            script.forEach_testMadFloatFloatFloatFloat(inA, out);
+            verifyResultsMadFloatFloatFloatFloat(inA, inB, inC, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMadFloatFloatFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.set_gAllocInC(inC);
+            scriptRelaxed.forEach_testMadFloatFloatFloatFloat(inA, out);
+            verifyResultsMadFloatFloatFloatFloat(inA, inB, inC, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMadFloatFloatFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMadFloatFloatFloatFloat(Allocation inA, Allocation inB, Allocation inC, Allocation out, boolean relaxed) {
+        float[] arrayInA = new float[INPUTSIZE * 1];
+        inA.copyTo(arrayInA);
+        float[] arrayInB = new float[INPUTSIZE * 1];
+        inB.copyTo(arrayInB);
+        float[] arrayInC = new float[INPUTSIZE * 1];
+        inC.copyTo(arrayInC);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
+                args.inA = arrayInA[i];
+                args.inB = arrayInB[i];
+                args.inC = arrayInC[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMad(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inA: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inA, Float.floatToRawIntBits(args.inA), args.inA));
+                    message.append("\n");
+                    message.append("Input inB: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inB, Float.floatToRawIntBits(args.inB), args.inB));
+                    message.append("\n");
+                    message.append("Input inC: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inC, Float.floatToRawIntBits(args.inC), args.inC));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMadFloatFloatFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkMadFloat2Float2Float2Float2() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x44d6ec3d0f2030a4l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x44d6ec3d0f2030a5l, false);
+        Allocation inC = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x44d6ec3d0f2030a6l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.set_gAllocInC(inC);
+            script.forEach_testMadFloat2Float2Float2Float2(inA, out);
+            verifyResultsMadFloat2Float2Float2Float2(inA, inB, inC, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMadFloat2Float2Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.set_gAllocInC(inC);
+            scriptRelaxed.forEach_testMadFloat2Float2Float2Float2(inA, out);
+            verifyResultsMadFloat2Float2Float2Float2(inA, inB, inC, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMadFloat2Float2Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMadFloat2Float2Float2Float2(Allocation inA, Allocation inB, Allocation inC, Allocation out, boolean relaxed) {
+        float[] arrayInA = new float[INPUTSIZE * 2];
+        inA.copyTo(arrayInA);
+        float[] arrayInB = new float[INPUTSIZE * 2];
+        inB.copyTo(arrayInB);
+        float[] arrayInC = new float[INPUTSIZE * 2];
+        inC.copyTo(arrayInC);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
+                args.inA = arrayInA[i * 2 + j];
+                args.inB = arrayInB[i * 2 + j];
+                args.inC = arrayInC[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMad(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inA: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inA, Float.floatToRawIntBits(args.inA), args.inA));
+                    message.append("\n");
+                    message.append("Input inB: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inB, Float.floatToRawIntBits(args.inB), args.inB));
+                    message.append("\n");
+                    message.append("Input inC: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inC, Float.floatToRawIntBits(args.inC), args.inC));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMadFloat2Float2Float2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkMadFloat3Float3Float3Float3() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x1a508fd7e1876a40l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x1a508fd7e1876a41l, false);
+        Allocation inC = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x1a508fd7e1876a42l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.set_gAllocInC(inC);
+            script.forEach_testMadFloat3Float3Float3Float3(inA, out);
+            verifyResultsMadFloat3Float3Float3Float3(inA, inB, inC, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMadFloat3Float3Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.set_gAllocInC(inC);
+            scriptRelaxed.forEach_testMadFloat3Float3Float3Float3(inA, out);
+            verifyResultsMadFloat3Float3Float3Float3(inA, inB, inC, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMadFloat3Float3Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMadFloat3Float3Float3Float3(Allocation inA, Allocation inB, Allocation inC, Allocation out, boolean relaxed) {
+        float[] arrayInA = new float[INPUTSIZE * 4];
+        inA.copyTo(arrayInA);
+        float[] arrayInB = new float[INPUTSIZE * 4];
+        inB.copyTo(arrayInB);
+        float[] arrayInC = new float[INPUTSIZE * 4];
+        inC.copyTo(arrayInC);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
+                args.inA = arrayInA[i * 4 + j];
+                args.inB = arrayInB[i * 4 + j];
+                args.inC = arrayInC[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMad(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inA: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inA, Float.floatToRawIntBits(args.inA), args.inA));
+                    message.append("\n");
+                    message.append("Input inB: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inB, Float.floatToRawIntBits(args.inB), args.inB));
+                    message.append("\n");
+                    message.append("Input inC: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inC, Float.floatToRawIntBits(args.inC), args.inC));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMadFloat3Float3Float3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkMadFloat4Float4Float4Float4() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xefca3372b3eea3dcl, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xefca3372b3eea3ddl, false);
+        Allocation inC = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xefca3372b3eea3del, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.set_gAllocInC(inC);
+            script.forEach_testMadFloat4Float4Float4Float4(inA, out);
+            verifyResultsMadFloat4Float4Float4Float4(inA, inB, inC, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMadFloat4Float4Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.set_gAllocInC(inC);
+            scriptRelaxed.forEach_testMadFloat4Float4Float4Float4(inA, out);
+            verifyResultsMadFloat4Float4Float4Float4(inA, inB, inC, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMadFloat4Float4Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMadFloat4Float4Float4Float4(Allocation inA, Allocation inB, Allocation inC, Allocation out, boolean relaxed) {
+        float[] arrayInA = new float[INPUTSIZE * 4];
+        inA.copyTo(arrayInA);
+        float[] arrayInB = new float[INPUTSIZE * 4];
+        inB.copyTo(arrayInB);
+        float[] arrayInC = new float[INPUTSIZE * 4];
+        inC.copyTo(arrayInC);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
+                args.inA = arrayInA[i * 4 + j];
+                args.inB = arrayInB[i * 4 + j];
+                args.inC = arrayInC[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMad(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inA: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inA, Float.floatToRawIntBits(args.inA), args.inA));
+                    message.append("\n");
+                    message.append("Input inB: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inB, Float.floatToRawIntBits(args.inB), args.inB));
+                    message.append("\n");
+                    message.append("Input inC: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inC, Float.floatToRawIntBits(args.inC), args.inC));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMadFloat4Float4Float4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testMad() {
+        checkMadFloatFloatFloatFloat();
+        checkMadFloat2Float2Float2Float2();
+        checkMadFloat3Float3Float3Float3();
+        checkMadFloat4Float4Float4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestMax.java b/tests/tests/renderscript/src/android/renderscript/cts/TestMax.java
new file mode 100644
index 0000000..7df768d
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestMax.java
@@ -0,0 +1,1969 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestMax extends RSBaseCompute {
+
+    private ScriptC_TestMax script;
+    private ScriptC_TestMaxRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestMax(mRS);
+        scriptRelaxed = new ScriptC_TestMaxRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloatFloat {
+        public float in;
+        public float in1;
+        public Floaty out;
+    }
+
+    private void checkMaxFloatFloatFloat() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xfb01ed3804837dddl, false);
+        Allocation in1 = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x2952d868c2162450l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocIn1(in1);
+            script.forEach_testMaxFloatFloatFloat(in, out);
+            verifyResultsMaxFloatFloatFloat(in, in1, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxFloatFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocIn1(in1);
+            scriptRelaxed.forEach_testMaxFloatFloatFloat(in, out);
+            verifyResultsMaxFloatFloatFloat(in, in1, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxFloatFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxFloatFloatFloat(Allocation in, Allocation in1, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 1];
+        in.copyTo(arrayIn);
+        float[] arrayIn1 = new float[INPUTSIZE * 1];
+        in1.copyTo(arrayIn1);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.in = arrayIn[i];
+                args.in1 = arrayIn1[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMax(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Input in1: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in1, Float.floatToRawIntBits(args.in1), args.in1));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMaxFloatFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkMaxFloat2Float2Float2() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x63dc5a02b9d46a4bl, false);
+        Allocation in1 = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xc6031e7536addacal, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocIn1(in1);
+            script.forEach_testMaxFloat2Float2Float2(in, out);
+            verifyResultsMaxFloat2Float2Float2(in, in1, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxFloat2Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocIn1(in1);
+            scriptRelaxed.forEach_testMaxFloat2Float2Float2(in, out);
+            verifyResultsMaxFloat2Float2Float2(in, in1, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxFloat2Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxFloat2Float2Float2(Allocation in, Allocation in1, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 2];
+        in.copyTo(arrayIn);
+        float[] arrayIn1 = new float[INPUTSIZE * 2];
+        in1.copyTo(arrayIn1);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.in = arrayIn[i * 2 + j];
+                args.in1 = arrayIn1[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMax(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Input in1: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in1, Float.floatToRawIntBits(args.in1), args.in1));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMaxFloat2Float2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkMaxFloat3Float3Float3() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xb92c17bc0744bdael, false);
+        Allocation in1 = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x1a67fc95388bdc6bl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocIn1(in1);
+            script.forEach_testMaxFloat3Float3Float3(in, out);
+            verifyResultsMaxFloat3Float3Float3(in, in1, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxFloat3Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocIn1(in1);
+            scriptRelaxed.forEach_testMaxFloat3Float3Float3(in, out);
+            verifyResultsMaxFloat3Float3Float3(in, in1, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxFloat3Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxFloat3Float3Float3(Allocation in, Allocation in1, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayIn1 = new float[INPUTSIZE * 4];
+        in1.copyTo(arrayIn1);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                args.in1 = arrayIn1[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMax(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Input in1: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in1, Float.floatToRawIntBits(args.in1), args.in1));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMaxFloat3Float3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkMaxFloat4Float4Float4() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xe7bd57554b51111l, false);
+        Allocation in1 = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x6eccdab53a69de0cl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocIn1(in1);
+            script.forEach_testMaxFloat4Float4Float4(in, out);
+            verifyResultsMaxFloat4Float4Float4(in, in1, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxFloat4Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocIn1(in1);
+            scriptRelaxed.forEach_testMaxFloat4Float4Float4(in, out);
+            verifyResultsMaxFloat4Float4Float4(in, in1, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxFloat4Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxFloat4Float4Float4(Allocation in, Allocation in1, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayIn1 = new float[INPUTSIZE * 4];
+        in1.copyTo(arrayIn1);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                args.in1 = arrayIn1[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMax(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Input in1: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in1, Float.floatToRawIntBits(args.in1), args.in1));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMaxFloat4Float4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsCharCharChar {
+        public byte inV1;
+        public byte inV2;
+        public byte out;
+    }
+
+    private void checkMaxCharCharChar() {
+        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 1, 0x91fcf329ccedf8al, false);
+        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 1, 0x91fcf329ccedf8bl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 1), INPUTSIZE);
+            script.set_gAllocInV2(inV2);
+            script.forEach_testMaxCharCharChar(inV1, out);
+            verifyResultsMaxCharCharChar(inV1, inV2, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxCharCharChar: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV2(inV2);
+            scriptRelaxed.forEach_testMaxCharCharChar(inV1, out);
+            verifyResultsMaxCharCharChar(inV1, inV2, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxCharCharChar: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxCharCharChar(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
+        byte[] arrayInV1 = new byte[INPUTSIZE * 1];
+        inV1.copyTo(arrayInV1);
+        byte[] arrayInV2 = new byte[INPUTSIZE * 1];
+        inV2.copyTo(arrayInV2);
+        byte[] arrayOut = new byte[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsCharCharChar args = new ArgumentsCharCharChar();
+                args.inV1 = arrayInV1[i];
+                args.inV2 = arrayInV2[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMax(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 1 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV1: ");
+                    message.append(String.format("%d", args.inV1));
+                    message.append("\n");
+                    message.append("Input inV2: ");
+                    message.append(String.format("%d", args.inV2));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 1 + j]));
+                    if (args.out != arrayOut[i * 1 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMaxCharCharChar" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsUcharUcharUchar {
+        public byte inV1;
+        public byte inV2;
+        public byte out;
+    }
+
+    private void checkMaxUcharUcharUchar() {
+        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 1, 0x829ebf2e60c1bd47l, false);
+        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 1, 0x829ebf2e60c1bd48l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 1), INPUTSIZE);
+            script.set_gAllocInV2(inV2);
+            script.forEach_testMaxUcharUcharUchar(inV1, out);
+            verifyResultsMaxUcharUcharUchar(inV1, inV2, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUcharUcharUchar: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV2(inV2);
+            scriptRelaxed.forEach_testMaxUcharUcharUchar(inV1, out);
+            verifyResultsMaxUcharUcharUchar(inV1, inV2, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUcharUcharUchar: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxUcharUcharUchar(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
+        byte[] arrayInV1 = new byte[INPUTSIZE * 1];
+        inV1.copyTo(arrayInV1);
+        byte[] arrayInV2 = new byte[INPUTSIZE * 1];
+        inV2.copyTo(arrayInV2);
+        byte[] arrayOut = new byte[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsUcharUcharUchar args = new ArgumentsUcharUcharUchar();
+                args.inV1 = arrayInV1[i];
+                args.inV2 = arrayInV2[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMax(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 1 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV1: ");
+                    message.append(String.format("0x%x", args.inV1));
+                    message.append("\n");
+                    message.append("Input inV2: ");
+                    message.append(String.format("0x%x", args.inV2));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 1 + j]));
+                    if (args.out != arrayOut[i * 1 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMaxUcharUcharUchar" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsShortShortShort {
+        public short inV1;
+        public short inV2;
+        public short out;
+    }
+
+    private void checkMaxShortShortShort() {
+        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 1, 0x868a0cd65f7a4294l, false);
+        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 1, 0x868a0cd65f7a4295l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 1), INPUTSIZE);
+            script.set_gAllocInV2(inV2);
+            script.forEach_testMaxShortShortShort(inV1, out);
+            verifyResultsMaxShortShortShort(inV1, inV2, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxShortShortShort: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV2(inV2);
+            scriptRelaxed.forEach_testMaxShortShortShort(inV1, out);
+            verifyResultsMaxShortShortShort(inV1, inV2, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxShortShortShort: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxShortShortShort(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
+        short[] arrayInV1 = new short[INPUTSIZE * 1];
+        inV1.copyTo(arrayInV1);
+        short[] arrayInV2 = new short[INPUTSIZE * 1];
+        inV2.copyTo(arrayInV2);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsShortShortShort args = new ArgumentsShortShortShort();
+                args.inV1 = arrayInV1[i];
+                args.inV2 = arrayInV2[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMax(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 1 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV1: ");
+                    message.append(String.format("%d", args.inV1));
+                    message.append("\n");
+                    message.append("Input inV2: ");
+                    message.append(String.format("%d", args.inV2));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 1 + j]));
+                    if (args.out != arrayOut[i * 1 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMaxShortShortShort" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsUshortUshortUshort {
+        public short inV1;
+        public short inV2;
+        public short out;
+    }
+
+    private void checkMaxUshortUshortUshort() {
+        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 1, 0x1b9c47701effe051l, false);
+        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 1, 0x1b9c47701effe052l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 1), INPUTSIZE);
+            script.set_gAllocInV2(inV2);
+            script.forEach_testMaxUshortUshortUshort(inV1, out);
+            verifyResultsMaxUshortUshortUshort(inV1, inV2, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUshortUshortUshort: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV2(inV2);
+            scriptRelaxed.forEach_testMaxUshortUshortUshort(inV1, out);
+            verifyResultsMaxUshortUshortUshort(inV1, inV2, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUshortUshortUshort: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxUshortUshortUshort(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
+        short[] arrayInV1 = new short[INPUTSIZE * 1];
+        inV1.copyTo(arrayInV1);
+        short[] arrayInV2 = new short[INPUTSIZE * 1];
+        inV2.copyTo(arrayInV2);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsUshortUshortUshort args = new ArgumentsUshortUshortUshort();
+                args.inV1 = arrayInV1[i];
+                args.inV2 = arrayInV2[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMax(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 1 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV1: ");
+                    message.append(String.format("0x%x", args.inV1));
+                    message.append("\n");
+                    message.append("Input inV2: ");
+                    message.append(String.format("0x%x", args.inV2));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 1 + j]));
+                    if (args.out != arrayOut[i * 1 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMaxUshortUshortUshort" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsIntIntInt {
+        public int inV1;
+        public int inV2;
+        public int out;
+    }
+
+    private void checkMaxIntIntInt() {
+        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0x7413f465641a51bl, false);
+        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0x7413f465641a51cl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 1), INPUTSIZE);
+            script.set_gAllocInV2(inV2);
+            script.forEach_testMaxIntIntInt(inV1, out);
+            verifyResultsMaxIntIntInt(inV1, inV2, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxIntIntInt: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV2(inV2);
+            scriptRelaxed.forEach_testMaxIntIntInt(inV1, out);
+            verifyResultsMaxIntIntInt(inV1, inV2, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxIntIntInt: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxIntIntInt(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
+        int[] arrayInV1 = new int[INPUTSIZE * 1];
+        inV1.copyTo(arrayInV1);
+        int[] arrayInV2 = new int[INPUTSIZE * 1];
+        inV2.copyTo(arrayInV2);
+        int[] arrayOut = new int[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsIntIntInt args = new ArgumentsIntIntInt();
+                args.inV1 = arrayInV1[i];
+                args.inV2 = arrayInV2[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMax(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 1 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV1: ");
+                    message.append(String.format("%d", args.inV1));
+                    message.append("\n");
+                    message.append("Input inV2: ");
+                    message.append(String.format("%d", args.inV2));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 1 + j]));
+                    if (args.out != arrayOut[i * 1 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMaxIntIntInt" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsUintUintUint {
+        public int inV1;
+        public int inV2;
+        public int out;
+    }
+
+    private void checkMaxUintUintUint() {
+        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 1, 0x75328d17808776cal, false);
+        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 1, 0x75328d17808776cbl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 1), INPUTSIZE);
+            script.set_gAllocInV2(inV2);
+            script.forEach_testMaxUintUintUint(inV1, out);
+            verifyResultsMaxUintUintUint(inV1, inV2, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUintUintUint: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV2(inV2);
+            scriptRelaxed.forEach_testMaxUintUintUint(inV1, out);
+            verifyResultsMaxUintUintUint(inV1, inV2, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUintUintUint: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxUintUintUint(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
+        int[] arrayInV1 = new int[INPUTSIZE * 1];
+        inV1.copyTo(arrayInV1);
+        int[] arrayInV2 = new int[INPUTSIZE * 1];
+        inV2.copyTo(arrayInV2);
+        int[] arrayOut = new int[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsUintUintUint args = new ArgumentsUintUintUint();
+                args.inV1 = arrayInV1[i];
+                args.inV2 = arrayInV2[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMax(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 1 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV1: ");
+                    message.append(String.format("0x%x", args.inV1));
+                    message.append("\n");
+                    message.append("Input inV2: ");
+                    message.append(String.format("0x%x", args.inV2));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 1 + j]));
+                    if (args.out != arrayOut[i * 1 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMaxUintUintUint" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkMaxChar2Char2Char2() {
+        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 2, 0x12084b25952bc64l, false);
+        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 2, 0x12084b25952bc65l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
+            script.set_gAllocInV2(inV2);
+            script.forEach_testMaxChar2Char2Char2(inV1, out);
+            verifyResultsMaxChar2Char2Char2(inV1, inV2, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxChar2Char2Char2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV2(inV2);
+            scriptRelaxed.forEach_testMaxChar2Char2Char2(inV1, out);
+            verifyResultsMaxChar2Char2Char2(inV1, inV2, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxChar2Char2Char2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxChar2Char2Char2(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
+        byte[] arrayInV1 = new byte[INPUTSIZE * 2];
+        inV1.copyTo(arrayInV1);
+        byte[] arrayInV2 = new byte[INPUTSIZE * 2];
+        inV2.copyTo(arrayInV2);
+        byte[] arrayOut = new byte[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsCharCharChar args = new ArgumentsCharCharChar();
+                args.inV1 = arrayInV1[i * 2 + j];
+                args.inV2 = arrayInV2[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMax(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV1: ");
+                    message.append(String.format("%d", args.inV1));
+                    message.append("\n");
+                    message.append("Input inV2: ");
+                    message.append(String.format("%d", args.inV2));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMaxChar2Char2Char2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkMaxUchar2Uchar2Uchar2() {
+        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 2, 0x75eda605e43f8b81l, false);
+        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 2, 0x75eda605e43f8b82l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
+            script.set_gAllocInV2(inV2);
+            script.forEach_testMaxUchar2Uchar2Uchar2(inV1, out);
+            verifyResultsMaxUchar2Uchar2Uchar2(inV1, inV2, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUchar2Uchar2Uchar2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV2(inV2);
+            scriptRelaxed.forEach_testMaxUchar2Uchar2Uchar2(inV1, out);
+            verifyResultsMaxUchar2Uchar2Uchar2(inV1, inV2, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUchar2Uchar2Uchar2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxUchar2Uchar2Uchar2(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
+        byte[] arrayInV1 = new byte[INPUTSIZE * 2];
+        inV1.copyTo(arrayInV1);
+        byte[] arrayInV2 = new byte[INPUTSIZE * 2];
+        inV2.copyTo(arrayInV2);
+        byte[] arrayOut = new byte[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsUcharUcharUchar args = new ArgumentsUcharUcharUchar();
+                args.inV1 = arrayInV1[i * 2 + j];
+                args.inV2 = arrayInV2[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMax(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV1: ");
+                    message.append(String.format("0x%x", args.inV1));
+                    message.append("\n");
+                    message.append("Input inV2: ");
+                    message.append(String.format("0x%x", args.inV2));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMaxUchar2Uchar2Uchar2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkMaxShort2Short2Short2() {
+        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 2, 0x3d46ae0799c33c02l, false);
+        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 2, 0x3d46ae0799c33c03l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
+            script.set_gAllocInV2(inV2);
+            script.forEach_testMaxShort2Short2Short2(inV1, out);
+            verifyResultsMaxShort2Short2Short2(inV1, inV2, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxShort2Short2Short2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV2(inV2);
+            scriptRelaxed.forEach_testMaxShort2Short2Short2(inV1, out);
+            verifyResultsMaxShort2Short2Short2(inV1, inV2, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxShort2Short2Short2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxShort2Short2Short2(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
+        short[] arrayInV1 = new short[INPUTSIZE * 2];
+        inV1.copyTo(arrayInV1);
+        short[] arrayInV2 = new short[INPUTSIZE * 2];
+        inV2.copyTo(arrayInV2);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsShortShortShort args = new ArgumentsShortShortShort();
+                args.inV1 = arrayInV1[i * 2 + j];
+                args.inV2 = arrayInV2[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMax(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV1: ");
+                    message.append(String.format("%d", args.inV1));
+                    message.append("\n");
+                    message.append("Input inV2: ");
+                    message.append(String.format("%d", args.inV2));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMaxShort2Short2Short2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkMaxUshort2Ushort2Ushort2() {
+        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 2, 0xf42196a588de51bfl, false);
+        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 2, 0xf42196a588de51c0l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
+            script.set_gAllocInV2(inV2);
+            script.forEach_testMaxUshort2Ushort2Ushort2(inV1, out);
+            verifyResultsMaxUshort2Ushort2Ushort2(inV1, inV2, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUshort2Ushort2Ushort2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV2(inV2);
+            scriptRelaxed.forEach_testMaxUshort2Ushort2Ushort2(inV1, out);
+            verifyResultsMaxUshort2Ushort2Ushort2(inV1, inV2, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUshort2Ushort2Ushort2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxUshort2Ushort2Ushort2(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
+        short[] arrayInV1 = new short[INPUTSIZE * 2];
+        inV1.copyTo(arrayInV1);
+        short[] arrayInV2 = new short[INPUTSIZE * 2];
+        inV2.copyTo(arrayInV2);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsUshortUshortUshort args = new ArgumentsUshortUshortUshort();
+                args.inV1 = arrayInV1[i * 2 + j];
+                args.inV2 = arrayInV2[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMax(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV1: ");
+                    message.append(String.format("0x%x", args.inV1));
+                    message.append("\n");
+                    message.append("Input inV2: ");
+                    message.append(String.format("0x%x", args.inV2));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMaxUshort2Ushort2Ushort2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkMaxInt2Int2Int2() {
+        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 2, 0x7bba1e4a83816bd5l, false);
+        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 2, 0x7bba1e4a83816bd6l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            script.set_gAllocInV2(inV2);
+            script.forEach_testMaxInt2Int2Int2(inV1, out);
+            verifyResultsMaxInt2Int2Int2(inV1, inV2, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxInt2Int2Int2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV2(inV2);
+            scriptRelaxed.forEach_testMaxInt2Int2Int2(inV1, out);
+            verifyResultsMaxInt2Int2Int2(inV1, inV2, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxInt2Int2Int2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxInt2Int2Int2(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
+        int[] arrayInV1 = new int[INPUTSIZE * 2];
+        inV1.copyTo(arrayInV1);
+        int[] arrayInV2 = new int[INPUTSIZE * 2];
+        inV2.copyTo(arrayInV2);
+        int[] arrayOut = new int[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsIntIntInt args = new ArgumentsIntIntInt();
+                args.inV1 = arrayInV1[i * 2 + j];
+                args.inV2 = arrayInV2[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMax(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV1: ");
+                    message.append(String.format("%d", args.inV1));
+                    message.append("\n");
+                    message.append("Input inV2: ");
+                    message.append(String.format("%d", args.inV2));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMaxInt2Int2Int2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkMaxUint2Uint2Uint2() {
+        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 2, 0xcda90384705016a4l, false);
+        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 2, 0xcda90384705016a5l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
+            script.set_gAllocInV2(inV2);
+            script.forEach_testMaxUint2Uint2Uint2(inV1, out);
+            verifyResultsMaxUint2Uint2Uint2(inV1, inV2, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUint2Uint2Uint2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV2(inV2);
+            scriptRelaxed.forEach_testMaxUint2Uint2Uint2(inV1, out);
+            verifyResultsMaxUint2Uint2Uint2(inV1, inV2, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUint2Uint2Uint2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxUint2Uint2Uint2(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
+        int[] arrayInV1 = new int[INPUTSIZE * 2];
+        inV1.copyTo(arrayInV1);
+        int[] arrayInV2 = new int[INPUTSIZE * 2];
+        inV2.copyTo(arrayInV2);
+        int[] arrayOut = new int[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsUintUintUint args = new ArgumentsUintUintUint();
+                args.inV1 = arrayInV1[i * 2 + j];
+                args.inV2 = arrayInV2[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMax(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV1: ");
+                    message.append(String.format("0x%x", args.inV1));
+                    message.append("\n");
+                    message.append("Input inV2: ");
+                    message.append(String.format("0x%x", args.inV2));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMaxUint2Uint2Uint2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkMaxChar3Char3Char3() {
+        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 3, 0x567200e53e0a8f29l, false);
+        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 3, 0x567200e53e0a8f2al, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
+            script.set_gAllocInV2(inV2);
+            script.forEach_testMaxChar3Char3Char3(inV1, out);
+            verifyResultsMaxChar3Char3Char3(inV1, inV2, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxChar3Char3Char3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV2(inV2);
+            scriptRelaxed.forEach_testMaxChar3Char3Char3(inV1, out);
+            verifyResultsMaxChar3Char3Char3(inV1, inV2, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxChar3Char3Char3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxChar3Char3Char3(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
+        byte[] arrayInV1 = new byte[INPUTSIZE * 4];
+        inV1.copyTo(arrayInV1);
+        byte[] arrayInV2 = new byte[INPUTSIZE * 4];
+        inV2.copyTo(arrayInV2);
+        byte[] arrayOut = new byte[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsCharCharChar args = new ArgumentsCharCharChar();
+                args.inV1 = arrayInV1[i * 4 + j];
+                args.inV2 = arrayInV2[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMax(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV1: ");
+                    message.append(String.format("%d", args.inV1));
+                    message.append("\n");
+                    message.append("Input inV2: ");
+                    message.append(String.format("%d", args.inV2));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMaxChar3Char3Char3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkMaxUchar3Uchar3Uchar3() {
+        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 3, 0xa2def5663489d18cl, false);
+        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 3, 0xa2def5663489d18dl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
+            script.set_gAllocInV2(inV2);
+            script.forEach_testMaxUchar3Uchar3Uchar3(inV1, out);
+            verifyResultsMaxUchar3Uchar3Uchar3(inV1, inV2, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUchar3Uchar3Uchar3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV2(inV2);
+            scriptRelaxed.forEach_testMaxUchar3Uchar3Uchar3(inV1, out);
+            verifyResultsMaxUchar3Uchar3Uchar3(inV1, inV2, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUchar3Uchar3Uchar3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxUchar3Uchar3Uchar3(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
+        byte[] arrayInV1 = new byte[INPUTSIZE * 4];
+        inV1.copyTo(arrayInV1);
+        byte[] arrayInV2 = new byte[INPUTSIZE * 4];
+        inV2.copyTo(arrayInV2);
+        byte[] arrayOut = new byte[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsUcharUcharUchar args = new ArgumentsUcharUcharUchar();
+                args.inV1 = arrayInV1[i * 4 + j];
+                args.inV2 = arrayInV2[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMax(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV1: ");
+                    message.append(String.format("0x%x", args.inV1));
+                    message.append("\n");
+                    message.append("Input inV2: ");
+                    message.append(String.format("0x%x", args.inV2));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMaxUchar3Uchar3Uchar3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkMaxShort3Short3Short3() {
+        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 3, 0x6a37fd67ea0d820dl, false);
+        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 3, 0x6a37fd67ea0d820el, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
+            script.set_gAllocInV2(inV2);
+            script.forEach_testMaxShort3Short3Short3(inV1, out);
+            verifyResultsMaxShort3Short3Short3(inV1, inV2, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxShort3Short3Short3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV2(inV2);
+            scriptRelaxed.forEach_testMaxShort3Short3Short3(inV1, out);
+            verifyResultsMaxShort3Short3Short3(inV1, inV2, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxShort3Short3Short3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxShort3Short3Short3(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
+        short[] arrayInV1 = new short[INPUTSIZE * 4];
+        inV1.copyTo(arrayInV1);
+        short[] arrayInV2 = new short[INPUTSIZE * 4];
+        inV2.copyTo(arrayInV2);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsShortShortShort args = new ArgumentsShortShortShort();
+                args.inV1 = arrayInV1[i * 4 + j];
+                args.inV2 = arrayInV2[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMax(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV1: ");
+                    message.append(String.format("%d", args.inV1));
+                    message.append("\n");
+                    message.append("Input inV2: ");
+                    message.append(String.format("%d", args.inV2));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMaxShort3Short3Short3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkMaxUshort3Ushort3Ushort3() {
+        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 3, 0x71604884c752e61cl, false);
+        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 3, 0x71604884c752e61dl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
+            script.set_gAllocInV2(inV2);
+            script.forEach_testMaxUshort3Ushort3Ushort3(inV1, out);
+            verifyResultsMaxUshort3Ushort3Ushort3(inV1, inV2, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUshort3Ushort3Ushort3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV2(inV2);
+            scriptRelaxed.forEach_testMaxUshort3Ushort3Ushort3(inV1, out);
+            verifyResultsMaxUshort3Ushort3Ushort3(inV1, inV2, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUshort3Ushort3Ushort3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxUshort3Ushort3Ushort3(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
+        short[] arrayInV1 = new short[INPUTSIZE * 4];
+        inV1.copyTo(arrayInV1);
+        short[] arrayInV2 = new short[INPUTSIZE * 4];
+        inV2.copyTo(arrayInV2);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsUshortUshortUshort args = new ArgumentsUshortUshortUshort();
+                args.inV1 = arrayInV1[i * 4 + j];
+                args.inV2 = arrayInV2[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMax(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV1: ");
+                    message.append(String.format("0x%x", args.inV1));
+                    message.append("\n");
+                    message.append("Input inV2: ");
+                    message.append(String.format("0x%x", args.inV2));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMaxUshort3Ushort3Ushort3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkMaxInt3Int3Int3() {
+        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 3, 0xa647496a95547ff8l, false);
+        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 3, 0xa647496a95547ff9l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            script.set_gAllocInV2(inV2);
+            script.forEach_testMaxInt3Int3Int3(inV1, out);
+            verifyResultsMaxInt3Int3Int3(inV1, inV2, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxInt3Int3Int3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV2(inV2);
+            scriptRelaxed.forEach_testMaxInt3Int3Int3(inV1, out);
+            verifyResultsMaxInt3Int3Int3(inV1, inV2, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxInt3Int3Int3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxInt3Int3Int3(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
+        int[] arrayInV1 = new int[INPUTSIZE * 4];
+        inV1.copyTo(arrayInV1);
+        int[] arrayInV2 = new int[INPUTSIZE * 4];
+        inV2.copyTo(arrayInV2);
+        int[] arrayOut = new int[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsIntIntInt args = new ArgumentsIntIntInt();
+                args.inV1 = arrayInV1[i * 4 + j];
+                args.inV2 = arrayInV2[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMax(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV1: ");
+                    message.append(String.format("%d", args.inV1));
+                    message.append("\n");
+                    message.append("Input inV2: ");
+                    message.append(String.format("%d", args.inV2));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMaxInt3Int3Int3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkMaxUint3Uint3Uint3() {
+        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 3, 0x22fa7fb75507e969l, false);
+        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 3, 0x22fa7fb75507e96al, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
+            script.set_gAllocInV2(inV2);
+            script.forEach_testMaxUint3Uint3Uint3(inV1, out);
+            verifyResultsMaxUint3Uint3Uint3(inV1, inV2, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUint3Uint3Uint3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV2(inV2);
+            scriptRelaxed.forEach_testMaxUint3Uint3Uint3(inV1, out);
+            verifyResultsMaxUint3Uint3Uint3(inV1, inV2, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUint3Uint3Uint3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxUint3Uint3Uint3(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
+        int[] arrayInV1 = new int[INPUTSIZE * 4];
+        inV1.copyTo(arrayInV1);
+        int[] arrayInV2 = new int[INPUTSIZE * 4];
+        inV2.copyTo(arrayInV2);
+        int[] arrayOut = new int[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsUintUintUint args = new ArgumentsUintUintUint();
+                args.inV1 = arrayInV1[i * 4 + j];
+                args.inV2 = arrayInV2[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMax(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV1: ");
+                    message.append(String.format("0x%x", args.inV1));
+                    message.append("\n");
+                    message.append("Input inV2: ");
+                    message.append(String.format("0x%x", args.inV2));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMaxUint3Uint3Uint3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkMaxChar4Char4Char4() {
+        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 4, 0xabc37d1822c261eel, false);
+        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 4, 0xabc37d1822c261efl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
+            script.set_gAllocInV2(inV2);
+            script.forEach_testMaxChar4Char4Char4(inV1, out);
+            verifyResultsMaxChar4Char4Char4(inV1, inV2, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxChar4Char4Char4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV2(inV2);
+            scriptRelaxed.forEach_testMaxChar4Char4Char4(inV1, out);
+            verifyResultsMaxChar4Char4Char4(inV1, inV2, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxChar4Char4Char4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxChar4Char4Char4(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
+        byte[] arrayInV1 = new byte[INPUTSIZE * 4];
+        inV1.copyTo(arrayInV1);
+        byte[] arrayInV2 = new byte[INPUTSIZE * 4];
+        inV2.copyTo(arrayInV2);
+        byte[] arrayOut = new byte[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsCharCharChar args = new ArgumentsCharCharChar();
+                args.inV1 = arrayInV1[i * 4 + j];
+                args.inV2 = arrayInV2[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMax(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV1: ");
+                    message.append(String.format("%d", args.inV1));
+                    message.append("\n");
+                    message.append("Input inV2: ");
+                    message.append(String.format("%d", args.inV2));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMaxChar4Char4Char4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkMaxUchar4Uchar4Uchar4() {
+        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 4, 0xcfd044c684d41797l, false);
+        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 4, 0xcfd044c684d41798l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
+            script.set_gAllocInV2(inV2);
+            script.forEach_testMaxUchar4Uchar4Uchar4(inV1, out);
+            verifyResultsMaxUchar4Uchar4Uchar4(inV1, inV2, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUchar4Uchar4Uchar4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV2(inV2);
+            scriptRelaxed.forEach_testMaxUchar4Uchar4Uchar4(inV1, out);
+            verifyResultsMaxUchar4Uchar4Uchar4(inV1, inV2, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUchar4Uchar4Uchar4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxUchar4Uchar4Uchar4(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
+        byte[] arrayInV1 = new byte[INPUTSIZE * 4];
+        inV1.copyTo(arrayInV1);
+        byte[] arrayInV2 = new byte[INPUTSIZE * 4];
+        inV2.copyTo(arrayInV2);
+        byte[] arrayOut = new byte[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsUcharUcharUchar args = new ArgumentsUcharUcharUchar();
+                args.inV1 = arrayInV1[i * 4 + j];
+                args.inV2 = arrayInV2[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMax(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV1: ");
+                    message.append(String.format("0x%x", args.inV1));
+                    message.append("\n");
+                    message.append("Input inV2: ");
+                    message.append(String.format("0x%x", args.inV2));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMaxUchar4Uchar4Uchar4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkMaxShort4Short4Short4() {
+        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 4, 0x97294cc83a57c818l, false);
+        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 4, 0x97294cc83a57c819l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
+            script.set_gAllocInV2(inV2);
+            script.forEach_testMaxShort4Short4Short4(inV1, out);
+            verifyResultsMaxShort4Short4Short4(inV1, inV2, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxShort4Short4Short4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV2(inV2);
+            scriptRelaxed.forEach_testMaxShort4Short4Short4(inV1, out);
+            verifyResultsMaxShort4Short4Short4(inV1, inV2, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxShort4Short4Short4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxShort4Short4Short4(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
+        short[] arrayInV1 = new short[INPUTSIZE * 4];
+        inV1.copyTo(arrayInV1);
+        short[] arrayInV2 = new short[INPUTSIZE * 4];
+        inV2.copyTo(arrayInV2);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsShortShortShort args = new ArgumentsShortShortShort();
+                args.inV1 = arrayInV1[i * 4 + j];
+                args.inV2 = arrayInV2[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMax(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV1: ");
+                    message.append(String.format("%d", args.inV1));
+                    message.append("\n");
+                    message.append("Input inV2: ");
+                    message.append(String.format("%d", args.inV2));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMaxShort4Short4Short4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkMaxUshort4Ushort4Ushort4() {
+        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 4, 0xee9efa6405c77a79l, false);
+        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 4, 0xee9efa6405c77a7al, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
+            script.set_gAllocInV2(inV2);
+            script.forEach_testMaxUshort4Ushort4Ushort4(inV1, out);
+            verifyResultsMaxUshort4Ushort4Ushort4(inV1, inV2, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUshort4Ushort4Ushort4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV2(inV2);
+            scriptRelaxed.forEach_testMaxUshort4Ushort4Ushort4(inV1, out);
+            verifyResultsMaxUshort4Ushort4Ushort4(inV1, inV2, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUshort4Ushort4Ushort4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxUshort4Ushort4Ushort4(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
+        short[] arrayInV1 = new short[INPUTSIZE * 4];
+        inV1.copyTo(arrayInV1);
+        short[] arrayInV2 = new short[INPUTSIZE * 4];
+        inV2.copyTo(arrayInV2);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsUshortUshortUshort args = new ArgumentsUshortUshortUshort();
+                args.inV1 = arrayInV1[i * 4 + j];
+                args.inV2 = arrayInV2[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMax(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV1: ");
+                    message.append(String.format("0x%x", args.inV1));
+                    message.append("\n");
+                    message.append("Input inV2: ");
+                    message.append(String.format("0x%x", args.inV2));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMaxUshort4Ushort4Ushort4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkMaxInt4Int4Int4() {
+        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 4, 0xd0d4748aa727941bl, false);
+        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 4, 0xd0d4748aa727941cl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            script.set_gAllocInV2(inV2);
+            script.forEach_testMaxInt4Int4Int4(inV1, out);
+            verifyResultsMaxInt4Int4Int4(inV1, inV2, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxInt4Int4Int4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV2(inV2);
+            scriptRelaxed.forEach_testMaxInt4Int4Int4(inV1, out);
+            verifyResultsMaxInt4Int4Int4(inV1, inV2, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxInt4Int4Int4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxInt4Int4Int4(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
+        int[] arrayInV1 = new int[INPUTSIZE * 4];
+        inV1.copyTo(arrayInV1);
+        int[] arrayInV2 = new int[INPUTSIZE * 4];
+        inV2.copyTo(arrayInV2);
+        int[] arrayOut = new int[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsIntIntInt args = new ArgumentsIntIntInt();
+                args.inV1 = arrayInV1[i * 4 + j];
+                args.inV2 = arrayInV2[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMax(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV1: ");
+                    message.append(String.format("%d", args.inV1));
+                    message.append("\n");
+                    message.append("Input inV2: ");
+                    message.append(String.format("%d", args.inV2));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMaxInt4Int4Int4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkMaxUint4Uint4Uint4() {
+        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 4, 0x784bfbea39bfbc2el, false);
+        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 4, 0x784bfbea39bfbc2fl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
+            script.set_gAllocInV2(inV2);
+            script.forEach_testMaxUint4Uint4Uint4(inV1, out);
+            verifyResultsMaxUint4Uint4Uint4(inV1, inV2, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUint4Uint4Uint4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV2(inV2);
+            scriptRelaxed.forEach_testMaxUint4Uint4Uint4(inV1, out);
+            verifyResultsMaxUint4Uint4Uint4(inV1, inV2, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUint4Uint4Uint4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxUint4Uint4Uint4(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
+        int[] arrayInV1 = new int[INPUTSIZE * 4];
+        inV1.copyTo(arrayInV1);
+        int[] arrayInV2 = new int[INPUTSIZE * 4];
+        inV2.copyTo(arrayInV2);
+        int[] arrayOut = new int[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsUintUintUint args = new ArgumentsUintUintUint();
+                args.inV1 = arrayInV1[i * 4 + j];
+                args.inV2 = arrayInV2[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMax(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV1: ");
+                    message.append(String.format("0x%x", args.inV1));
+                    message.append("\n");
+                    message.append("Input inV2: ");
+                    message.append(String.format("0x%x", args.inV2));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMaxUint4Uint4Uint4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testMax() {
+        checkMaxFloatFloatFloat();
+        checkMaxFloat2Float2Float2();
+        checkMaxFloat3Float3Float3();
+        checkMaxFloat4Float4Float4();
+        checkMaxCharCharChar();
+        checkMaxUcharUcharUchar();
+        checkMaxShortShortShort();
+        checkMaxUshortUshortUshort();
+        checkMaxIntIntInt();
+        checkMaxUintUintUint();
+        checkMaxChar2Char2Char2();
+        checkMaxUchar2Uchar2Uchar2();
+        checkMaxShort2Short2Short2();
+        checkMaxUshort2Ushort2Ushort2();
+        checkMaxInt2Int2Int2();
+        checkMaxUint2Uint2Uint2();
+        checkMaxChar3Char3Char3();
+        checkMaxUchar3Uchar3Uchar3();
+        checkMaxShort3Short3Short3();
+        checkMaxUshort3Ushort3Ushort3();
+        checkMaxInt3Int3Int3();
+        checkMaxUint3Uint3Uint3();
+        checkMaxChar4Char4Char4();
+        checkMaxUchar4Uchar4Uchar4();
+        checkMaxShort4Short4Short4();
+        checkMaxUshort4Ushort4Ushort4();
+        checkMaxInt4Int4Int4();
+        checkMaxUint4Uint4Uint4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestMin.java b/tests/tests/renderscript/src/android/renderscript/cts/TestMin.java
new file mode 100644
index 0000000..08434f3
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestMin.java
@@ -0,0 +1,1969 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestMin extends RSBaseCompute {
+
+    private ScriptC_TestMin script;
+    private ScriptC_TestMinRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestMin(mRS);
+        scriptRelaxed = new ScriptC_TestMinRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloatFloat {
+        public float in;
+        public float in1;
+        public Floaty out;
+    }
+
+    private void checkMinFloatFloatFloat() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x816f2fe273bf4977l, false);
+        Allocation in1 = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xbdad0b097121572el, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocIn1(in1);
+            script.forEach_testMinFloatFloatFloat(in, out);
+            verifyResultsMinFloatFloatFloat(in, in1, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinFloatFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocIn1(in1);
+            scriptRelaxed.forEach_testMinFloatFloatFloat(in, out);
+            verifyResultsMinFloatFloatFloat(in, in1, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinFloatFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinFloatFloatFloat(Allocation in, Allocation in1, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 1];
+        in.copyTo(arrayIn);
+        float[] arrayIn1 = new float[INPUTSIZE * 1];
+        in1.copyTo(arrayIn1);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.in = arrayIn[i];
+                args.in1 = arrayIn1[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMin(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Input in1: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in1, Float.floatToRawIntBits(args.in1), args.in1));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMinFloatFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkMinFloat2Float2Float2() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xe354049301b6cfb9l, false);
+        Allocation in1 = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x2f1cc4b149b4e444l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocIn1(in1);
+            script.forEach_testMinFloat2Float2Float2(in, out);
+            verifyResultsMinFloat2Float2Float2(in, in1, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinFloat2Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocIn1(in1);
+            scriptRelaxed.forEach_testMinFloat2Float2Float2(in, out);
+            verifyResultsMinFloat2Float2Float2(in, in1, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinFloat2Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinFloat2Float2Float2(Allocation in, Allocation in1, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 2];
+        in.copyTo(arrayIn);
+        float[] arrayIn1 = new float[INPUTSIZE * 2];
+        in1.copyTo(arrayIn1);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.in = arrayIn[i * 2 + j];
+                args.in1 = arrayIn1[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMin(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Input in1: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in1, Float.floatToRawIntBits(args.in1), args.in1));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMinFloat2Float2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkMinFloat3Float3Float3() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x38a3c24c4f27231cl, false);
+        Allocation in1 = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x8381a2d14b92e5e5l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocIn1(in1);
+            script.forEach_testMinFloat3Float3Float3(in, out);
+            verifyResultsMinFloat3Float3Float3(in, in1, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinFloat3Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocIn1(in1);
+            scriptRelaxed.forEach_testMinFloat3Float3Float3(in, out);
+            verifyResultsMinFloat3Float3Float3(in, in1, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinFloat3Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinFloat3Float3Float3(Allocation in, Allocation in1, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayIn1 = new float[INPUTSIZE * 4];
+        in1.copyTo(arrayIn1);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                args.in1 = arrayIn1[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMin(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Input in1: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in1, Float.floatToRawIntBits(args.in1), args.in1));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMinFloat3Float3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkMinFloat4Float4Float4() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x8df380059c97767fl, false);
+        Allocation in1 = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xd7e680f14d70e786l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocIn1(in1);
+            script.forEach_testMinFloat4Float4Float4(in, out);
+            verifyResultsMinFloat4Float4Float4(in, in1, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinFloat4Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocIn1(in1);
+            scriptRelaxed.forEach_testMinFloat4Float4Float4(in, out);
+            verifyResultsMinFloat4Float4Float4(in, in1, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinFloat4Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinFloat4Float4Float4(Allocation in, Allocation in1, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayIn1 = new float[INPUTSIZE * 4];
+        in1.copyTo(arrayIn1);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                args.in1 = arrayIn1[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMin(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Input in1: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in1, Float.floatToRawIntBits(args.in1), args.in1));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMinFloat4Float4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsCharCharChar {
+        public byte inV1;
+        public byte inV2;
+        public byte out;
+    }
+
+    private void checkMinCharCharChar() {
+        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 1, 0x47c90c486fc45b58l, false);
+        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 1, 0x47c90c486fc45b59l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 1), INPUTSIZE);
+            script.set_gAllocInV2(inV2);
+            script.forEach_testMinCharCharChar(inV1, out);
+            verifyResultsMinCharCharChar(inV1, inV2, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinCharCharChar: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV2(inV2);
+            scriptRelaxed.forEach_testMinCharCharChar(inV1, out);
+            verifyResultsMinCharCharChar(inV1, inV2, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinCharCharChar: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinCharCharChar(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
+        byte[] arrayInV1 = new byte[INPUTSIZE * 1];
+        inV1.copyTo(arrayInV1);
+        byte[] arrayInV2 = new byte[INPUTSIZE * 1];
+        inV2.copyTo(arrayInV2);
+        byte[] arrayOut = new byte[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsCharCharChar args = new ArgumentsCharCharChar();
+                args.inV1 = arrayInV1[i];
+                args.inV2 = arrayInV2[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMin(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 1 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV1: ");
+                    message.append(String.format("%d", args.inV1));
+                    message.append("\n");
+                    message.append("Input inV2: ");
+                    message.append(String.format("%d", args.inV2));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 1 + j]));
+                    if (args.out != arrayOut[i * 1 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMinCharCharChar" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsUcharUcharUchar {
+        public byte inV1;
+        public byte inV2;
+        public byte out;
+    }
+
+    private void checkMinUcharUcharUchar() {
+        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 1, 0x6dc5402bc7a34891l, false);
+        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 1, 0x6dc5402bc7a34892l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 1), INPUTSIZE);
+            script.set_gAllocInV2(inV2);
+            script.forEach_testMinUcharUcharUchar(inV1, out);
+            verifyResultsMinUcharUcharUchar(inV1, inV2, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUcharUcharUchar: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV2(inV2);
+            scriptRelaxed.forEach_testMinUcharUcharUchar(inV1, out);
+            verifyResultsMinUcharUcharUchar(inV1, inV2, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUcharUcharUchar: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinUcharUcharUchar(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
+        byte[] arrayInV1 = new byte[INPUTSIZE * 1];
+        inV1.copyTo(arrayInV1);
+        byte[] arrayInV2 = new byte[INPUTSIZE * 1];
+        inV2.copyTo(arrayInV2);
+        byte[] arrayOut = new byte[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsUcharUcharUchar args = new ArgumentsUcharUcharUchar();
+                args.inV1 = arrayInV1[i];
+                args.inV2 = arrayInV2[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMin(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 1 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV1: ");
+                    message.append(String.format("0x%x", args.inV1));
+                    message.append("\n");
+                    message.append("Input inV2: ");
+                    message.append(String.format("0x%x", args.inV2));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 1 + j]));
+                    if (args.out != arrayOut[i * 1 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMinUcharUcharUchar" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsShortShortShort {
+        public short inV1;
+        public short inV2;
+        public short out;
+    }
+
+    private void checkMinShortShortShort() {
+        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 1, 0x71b08dd3c65bcddel, false);
+        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 1, 0x71b08dd3c65bcddfl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 1), INPUTSIZE);
+            script.set_gAllocInV2(inV2);
+            script.forEach_testMinShortShortShort(inV1, out);
+            verifyResultsMinShortShortShort(inV1, inV2, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinShortShortShort: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV2(inV2);
+            scriptRelaxed.forEach_testMinShortShortShort(inV1, out);
+            verifyResultsMinShortShortShort(inV1, inV2, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinShortShortShort: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinShortShortShort(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
+        short[] arrayInV1 = new short[INPUTSIZE * 1];
+        inV1.copyTo(arrayInV1);
+        short[] arrayInV2 = new short[INPUTSIZE * 1];
+        inV2.copyTo(arrayInV2);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsShortShortShort args = new ArgumentsShortShortShort();
+                args.inV1 = arrayInV1[i];
+                args.inV2 = arrayInV2[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMin(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 1 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV1: ");
+                    message.append(String.format("%d", args.inV1));
+                    message.append("\n");
+                    message.append("Input inV2: ");
+                    message.append(String.format("%d", args.inV2));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 1 + j]));
+                    if (args.out != arrayOut[i * 1 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMinShortShortShort" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsUshortUshortUshort {
+        public short inV1;
+        public short inV2;
+        public short out;
+    }
+
+    private void checkMinUshortUshortUshort() {
+        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 1, 0xc2eb3387512e77cfl, false);
+        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 1, 0xc2eb3387512e77d0l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 1), INPUTSIZE);
+            script.set_gAllocInV2(inV2);
+            script.forEach_testMinUshortUshortUshort(inV1, out);
+            verifyResultsMinUshortUshortUshort(inV1, inV2, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUshortUshortUshort: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV2(inV2);
+            scriptRelaxed.forEach_testMinUshortUshortUshort(inV1, out);
+            verifyResultsMinUshortUshortUshort(inV1, inV2, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUshortUshortUshort: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinUshortUshortUshort(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
+        short[] arrayInV1 = new short[INPUTSIZE * 1];
+        inV1.copyTo(arrayInV1);
+        short[] arrayInV2 = new short[INPUTSIZE * 1];
+        inV2.copyTo(arrayInV2);
+        short[] arrayOut = new short[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsUshortUshortUshort args = new ArgumentsUshortUshortUshort();
+                args.inV1 = arrayInV1[i];
+                args.inV2 = arrayInV2[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMin(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 1 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV1: ");
+                    message.append(String.format("0x%x", args.inV1));
+                    message.append("\n");
+                    message.append("Input inV2: ");
+                    message.append(String.format("0x%x", args.inV2));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 1 + j]));
+                    if (args.out != arrayOut[i * 1 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMinUshortUshortUshort" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsIntIntInt {
+        public int inV1;
+        public int inV2;
+        public int out;
+    }
+
+    private void checkMinIntIntInt() {
+        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0x38b24335cda69cd5l, false);
+        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0x38b24335cda69cd6l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 1), INPUTSIZE);
+            script.set_gAllocInV2(inV2);
+            script.forEach_testMinIntIntInt(inV1, out);
+            verifyResultsMinIntIntInt(inV1, inV2, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinIntIntInt: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV2(inV2);
+            scriptRelaxed.forEach_testMinIntIntInt(inV1, out);
+            verifyResultsMinIntIntInt(inV1, inV2, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinIntIntInt: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinIntIntInt(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
+        int[] arrayInV1 = new int[INPUTSIZE * 1];
+        inV1.copyTo(arrayInV1);
+        int[] arrayInV2 = new int[INPUTSIZE * 1];
+        inV2.copyTo(arrayInV2);
+        int[] arrayOut = new int[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsIntIntInt args = new ArgumentsIntIntInt();
+                args.inV1 = arrayInV1[i];
+                args.inV2 = arrayInV2[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMin(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 1 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV1: ");
+                    message.append(String.format("%d", args.inV1));
+                    message.append("\n");
+                    message.append("Input inV2: ");
+                    message.append(String.format("%d", args.inV2));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 1 + j]));
+                    if (args.out != arrayOut[i * 1 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMinIntIntInt" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsUintUintUint {
+        public int inV1;
+        public int inV2;
+        public int out;
+    }
+
+    private void checkMinUintUintUint() {
+        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 1, 0xb3dbca2d537cf298l, false);
+        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 1, 0xb3dbca2d537cf299l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 1), INPUTSIZE);
+            script.set_gAllocInV2(inV2);
+            script.forEach_testMinUintUintUint(inV1, out);
+            verifyResultsMinUintUintUint(inV1, inV2, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUintUintUint: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV2(inV2);
+            scriptRelaxed.forEach_testMinUintUintUint(inV1, out);
+            verifyResultsMinUintUintUint(inV1, inV2, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUintUintUint: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinUintUintUint(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
+        int[] arrayInV1 = new int[INPUTSIZE * 1];
+        inV1.copyTo(arrayInV1);
+        int[] arrayInV2 = new int[INPUTSIZE * 1];
+        inV2.copyTo(arrayInV2);
+        int[] arrayOut = new int[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsUintUintUint args = new ArgumentsUintUintUint();
+                args.inV1 = arrayInV1[i];
+                args.inV2 = arrayInV2[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMin(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 1 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV1: ");
+                    message.append(String.format("0x%x", args.inV1));
+                    message.append("\n");
+                    message.append("Input inV2: ");
+                    message.append(String.format("0x%x", args.inV2));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 1 + j]));
+                    if (args.out != arrayOut[i * 1 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMinUintUintUint" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkMinChar2Char2Char2() {
+        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 2, 0xec4705afc03447ael, false);
+        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 2, 0xec4705afc03447afl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
+            script.set_gAllocInV2(inV2);
+            script.forEach_testMinChar2Char2Char2(inV1, out);
+            verifyResultsMinChar2Char2Char2(inV1, inV2, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinChar2Char2Char2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV2(inV2);
+            scriptRelaxed.forEach_testMinChar2Char2Char2(inV1, out);
+            verifyResultsMinChar2Char2Char2(inV1, inV2, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinChar2Char2Char2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinChar2Char2Char2(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
+        byte[] arrayInV1 = new byte[INPUTSIZE * 2];
+        inV1.copyTo(arrayInV1);
+        byte[] arrayInV2 = new byte[INPUTSIZE * 2];
+        inV2.copyTo(arrayInV2);
+        byte[] arrayOut = new byte[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsCharCharChar args = new ArgumentsCharCharChar();
+                args.inV1 = arrayInV1[i * 2 + j];
+                args.inV2 = arrayInV2[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMin(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV1: ");
+                    message.append(String.format("%d", args.inV1));
+                    message.append("\n");
+                    message.append("Input inV2: ");
+                    message.append(String.format("%d", args.inV2));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMinChar2Char2Char2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkMinUchar2Uchar2Uchar2() {
+        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 2, 0x1d3c921d166e22ffl, false);
+        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 2, 0x1d3c921d166e2300l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
+            script.set_gAllocInV2(inV2);
+            script.forEach_testMinUchar2Uchar2Uchar2(inV1, out);
+            verifyResultsMinUchar2Uchar2Uchar2(inV1, inV2, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUchar2Uchar2Uchar2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV2(inV2);
+            scriptRelaxed.forEach_testMinUchar2Uchar2Uchar2(inV1, out);
+            verifyResultsMinUchar2Uchar2Uchar2(inV1, inV2, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUchar2Uchar2Uchar2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinUchar2Uchar2Uchar2(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
+        byte[] arrayInV1 = new byte[INPUTSIZE * 2];
+        inV1.copyTo(arrayInV1);
+        byte[] arrayInV2 = new byte[INPUTSIZE * 2];
+        inV2.copyTo(arrayInV2);
+        byte[] arrayOut = new byte[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsUcharUcharUchar args = new ArgumentsUcharUcharUchar();
+                args.inV1 = arrayInV1[i * 2 + j];
+                args.inV2 = arrayInV2[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMin(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV1: ");
+                    message.append(String.format("0x%x", args.inV1));
+                    message.append("\n");
+                    message.append("Input inV2: ");
+                    message.append(String.format("0x%x", args.inV2));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMinUchar2Uchar2Uchar2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkMinShort2Short2Short2() {
+        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 2, 0xe4959a1ecbf1d380l, false);
+        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 2, 0xe4959a1ecbf1d381l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
+            script.set_gAllocInV2(inV2);
+            script.forEach_testMinShort2Short2Short2(inV1, out);
+            verifyResultsMinShort2Short2Short2(inV1, inV2, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinShort2Short2Short2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV2(inV2);
+            scriptRelaxed.forEach_testMinShort2Short2Short2(inV1, out);
+            verifyResultsMinShort2Short2Short2(inV1, inV2, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinShort2Short2Short2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinShort2Short2Short2(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
+        short[] arrayInV1 = new short[INPUTSIZE * 2];
+        inV1.copyTo(arrayInV1);
+        short[] arrayInV2 = new short[INPUTSIZE * 2];
+        inV2.copyTo(arrayInV2);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsShortShortShort args = new ArgumentsShortShortShort();
+                args.inV1 = arrayInV1[i * 2 + j];
+                args.inV2 = arrayInV2[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMin(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV1: ");
+                    message.append(String.format("%d", args.inV1));
+                    message.append("\n");
+                    message.append("Input inV2: ");
+                    message.append(String.format("%d", args.inV2));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMinShort2Short2Short2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkMinUshort2Ushort2Ushort2() {
+        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 2, 0x98573ebbc511e319l, false);
+        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 2, 0x98573ebbc511e31al, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
+            script.set_gAllocInV2(inV2);
+            script.forEach_testMinUshort2Ushort2Ushort2(inV1, out);
+            verifyResultsMinUshort2Ushort2Ushort2(inV1, inV2, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUshort2Ushort2Ushort2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV2(inV2);
+            scriptRelaxed.forEach_testMinUshort2Ushort2Ushort2(inV1, out);
+            verifyResultsMinUshort2Ushort2Ushort2(inV1, inV2, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUshort2Ushort2Ushort2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinUshort2Ushort2Ushort2(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
+        short[] arrayInV1 = new short[INPUTSIZE * 2];
+        inV1.copyTo(arrayInV1);
+        short[] arrayInV2 = new short[INPUTSIZE * 2];
+        inV2.copyTo(arrayInV2);
+        short[] arrayOut = new short[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsUshortUshortUshort args = new ArgumentsUshortUshortUshort();
+                args.inV1 = arrayInV1[i * 2 + j];
+                args.inV2 = arrayInV2[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMin(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV1: ");
+                    message.append(String.format("0x%x", args.inV1));
+                    message.append("\n");
+                    message.append("Input inV2: ");
+                    message.append(String.format("0x%x", args.inV2));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMinUshort2Ushort2Ushort2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkMinInt2Int2Int2() {
+        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 2, 0xba635b605676e7a3l, false);
+        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 2, 0xba635b605676e7a4l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            script.set_gAllocInV2(inV2);
+            script.forEach_testMinInt2Int2Int2(inV1, out);
+            verifyResultsMinInt2Int2Int2(inV1, inV2, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinInt2Int2Int2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV2(inV2);
+            scriptRelaxed.forEach_testMinInt2Int2Int2(inV1, out);
+            verifyResultsMinInt2Int2Int2(inV1, inV2, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinInt2Int2Int2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinInt2Int2Int2(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
+        int[] arrayInV1 = new int[INPUTSIZE * 2];
+        inV1.copyTo(arrayInV1);
+        int[] arrayInV2 = new int[INPUTSIZE * 2];
+        inV2.copyTo(arrayInV2);
+        int[] arrayOut = new int[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsIntIntInt args = new ArgumentsIntIntInt();
+                args.inV1 = arrayInV1[i * 2 + j];
+                args.inV2 = arrayInV2[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMin(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV1: ");
+                    message.append(String.format("%d", args.inV1));
+                    message.append("\n");
+                    message.append("Input inV2: ");
+                    message.append(String.format("%d", args.inV2));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMinInt2Int2Int2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkMinUint2Uint2Uint2() {
+        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 2, 0xb8cf8481d731a1eel, false);
+        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 2, 0xb8cf8481d731a1efl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
+            script.set_gAllocInV2(inV2);
+            script.forEach_testMinUint2Uint2Uint2(inV1, out);
+            verifyResultsMinUint2Uint2Uint2(inV1, inV2, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUint2Uint2Uint2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV2(inV2);
+            scriptRelaxed.forEach_testMinUint2Uint2Uint2(inV1, out);
+            verifyResultsMinUint2Uint2Uint2(inV1, inV2, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUint2Uint2Uint2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinUint2Uint2Uint2(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
+        int[] arrayInV1 = new int[INPUTSIZE * 2];
+        inV1.copyTo(arrayInV1);
+        int[] arrayInV2 = new int[INPUTSIZE * 2];
+        inV2.copyTo(arrayInV2);
+        int[] arrayOut = new int[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsUintUintUint args = new ArgumentsUintUintUint();
+                args.inV1 = arrayInV1[i * 2 + j];
+                args.inV2 = arrayInV2[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMin(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 2 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV1: ");
+                    message.append(String.format("0x%x", args.inV1));
+                    message.append("\n");
+                    message.append("Input inV2: ");
+                    message.append(String.format("0x%x", args.inV2));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
+                    if (args.out != arrayOut[i * 2 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMinUint2Uint2Uint2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkMinChar3Char3Char3() {
+        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 3, 0x419881e2a4ec1a73l, false);
+        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 3, 0x419881e2a4ec1a74l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
+            script.set_gAllocInV2(inV2);
+            script.forEach_testMinChar3Char3Char3(inV1, out);
+            verifyResultsMinChar3Char3Char3(inV1, inV2, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinChar3Char3Char3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV2(inV2);
+            scriptRelaxed.forEach_testMinChar3Char3Char3(inV1, out);
+            verifyResultsMinChar3Char3Char3(inV1, inV2, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinChar3Char3Char3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinChar3Char3Char3(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
+        byte[] arrayInV1 = new byte[INPUTSIZE * 4];
+        inV1.copyTo(arrayInV1);
+        byte[] arrayInV2 = new byte[INPUTSIZE * 4];
+        inV2.copyTo(arrayInV2);
+        byte[] arrayOut = new byte[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsCharCharChar args = new ArgumentsCharCharChar();
+                args.inV1 = arrayInV1[i * 4 + j];
+                args.inV2 = arrayInV2[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMin(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV1: ");
+                    message.append(String.format("%d", args.inV1));
+                    message.append("\n");
+                    message.append("Input inV2: ");
+                    message.append(String.format("%d", args.inV2));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMinChar3Char3Char3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkMinUchar3Uchar3Uchar3() {
+        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 3, 0x4a2de17d66b8690al, false);
+        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 3, 0x4a2de17d66b8690bl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
+            script.set_gAllocInV2(inV2);
+            script.forEach_testMinUchar3Uchar3Uchar3(inV1, out);
+            verifyResultsMinUchar3Uchar3Uchar3(inV1, inV2, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUchar3Uchar3Uchar3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV2(inV2);
+            scriptRelaxed.forEach_testMinUchar3Uchar3Uchar3(inV1, out);
+            verifyResultsMinUchar3Uchar3Uchar3(inV1, inV2, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUchar3Uchar3Uchar3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinUchar3Uchar3Uchar3(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
+        byte[] arrayInV1 = new byte[INPUTSIZE * 4];
+        inV1.copyTo(arrayInV1);
+        byte[] arrayInV2 = new byte[INPUTSIZE * 4];
+        inV2.copyTo(arrayInV2);
+        byte[] arrayOut = new byte[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsUcharUcharUchar args = new ArgumentsUcharUcharUchar();
+                args.inV1 = arrayInV1[i * 4 + j];
+                args.inV2 = arrayInV2[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMin(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV1: ");
+                    message.append(String.format("0x%x", args.inV1));
+                    message.append("\n");
+                    message.append("Input inV2: ");
+                    message.append(String.format("0x%x", args.inV2));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMinUchar3Uchar3Uchar3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkMinShort3Short3Short3() {
+        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 3, 0x1186e97f1c3c198bl, false);
+        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 3, 0x1186e97f1c3c198cl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
+            script.set_gAllocInV2(inV2);
+            script.forEach_testMinShort3Short3Short3(inV1, out);
+            verifyResultsMinShort3Short3Short3(inV1, inV2, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinShort3Short3Short3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV2(inV2);
+            scriptRelaxed.forEach_testMinShort3Short3Short3(inV1, out);
+            verifyResultsMinShort3Short3Short3(inV1, inV2, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinShort3Short3Short3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinShort3Short3Short3(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
+        short[] arrayInV1 = new short[INPUTSIZE * 4];
+        inV1.copyTo(arrayInV1);
+        short[] arrayInV2 = new short[INPUTSIZE * 4];
+        inV2.copyTo(arrayInV2);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsShortShortShort args = new ArgumentsShortShortShort();
+                args.inV1 = arrayInV1[i * 4 + j];
+                args.inV2 = arrayInV2[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMin(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV1: ");
+                    message.append(String.format("%d", args.inV1));
+                    message.append("\n");
+                    message.append("Input inV2: ");
+                    message.append(String.format("%d", args.inV2));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMinShort3Short3Short3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkMinUshort3Ushort3Ushort3() {
+        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 3, 0x1595f09b03867776l, false);
+        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 3, 0x1595f09b03867777l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
+            script.set_gAllocInV2(inV2);
+            script.forEach_testMinUshort3Ushort3Ushort3(inV1, out);
+            verifyResultsMinUshort3Ushort3Ushort3(inV1, inV2, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUshort3Ushort3Ushort3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV2(inV2);
+            scriptRelaxed.forEach_testMinUshort3Ushort3Ushort3(inV1, out);
+            verifyResultsMinUshort3Ushort3Ushort3(inV1, inV2, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUshort3Ushort3Ushort3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinUshort3Ushort3Ushort3(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
+        short[] arrayInV1 = new short[INPUTSIZE * 4];
+        inV1.copyTo(arrayInV1);
+        short[] arrayInV2 = new short[INPUTSIZE * 4];
+        inV2.copyTo(arrayInV2);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsUshortUshortUshort args = new ArgumentsUshortUshortUshort();
+                args.inV1 = arrayInV1[i * 4 + j];
+                args.inV2 = arrayInV2[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMin(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV1: ");
+                    message.append(String.format("0x%x", args.inV1));
+                    message.append("\n");
+                    message.append("Input inV2: ");
+                    message.append(String.format("0x%x", args.inV2));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMinUshort3Ushort3Ushort3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkMinInt3Int3Int3() {
+        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 3, 0xe4f086806849fbc6l, false);
+        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 3, 0xe4f086806849fbc7l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            script.set_gAllocInV2(inV2);
+            script.forEach_testMinInt3Int3Int3(inV1, out);
+            verifyResultsMinInt3Int3Int3(inV1, inV2, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinInt3Int3Int3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV2(inV2);
+            scriptRelaxed.forEach_testMinInt3Int3Int3(inV1, out);
+            verifyResultsMinInt3Int3Int3(inV1, inV2, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinInt3Int3Int3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinInt3Int3Int3(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
+        int[] arrayInV1 = new int[INPUTSIZE * 4];
+        inV1.copyTo(arrayInV1);
+        int[] arrayInV2 = new int[INPUTSIZE * 4];
+        inV2.copyTo(arrayInV2);
+        int[] arrayOut = new int[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsIntIntInt args = new ArgumentsIntIntInt();
+                args.inV1 = arrayInV1[i * 4 + j];
+                args.inV2 = arrayInV2[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMin(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV1: ");
+                    message.append(String.format("%d", args.inV1));
+                    message.append("\n");
+                    message.append("Input inV2: ");
+                    message.append(String.format("%d", args.inV2));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMinInt3Int3Int3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkMinUint3Uint3Uint3() {
+        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 3, 0xe2100b4bbe974b3l, false);
+        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 3, 0xe2100b4bbe974b4l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
+            script.set_gAllocInV2(inV2);
+            script.forEach_testMinUint3Uint3Uint3(inV1, out);
+            verifyResultsMinUint3Uint3Uint3(inV1, inV2, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUint3Uint3Uint3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV2(inV2);
+            scriptRelaxed.forEach_testMinUint3Uint3Uint3(inV1, out);
+            verifyResultsMinUint3Uint3Uint3(inV1, inV2, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUint3Uint3Uint3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinUint3Uint3Uint3(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
+        int[] arrayInV1 = new int[INPUTSIZE * 4];
+        inV1.copyTo(arrayInV1);
+        int[] arrayInV2 = new int[INPUTSIZE * 4];
+        inV2.copyTo(arrayInV2);
+        int[] arrayOut = new int[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsUintUintUint args = new ArgumentsUintUintUint();
+                args.inV1 = arrayInV1[i * 4 + j];
+                args.inV2 = arrayInV2[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMin(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV1: ");
+                    message.append(String.format("0x%x", args.inV1));
+                    message.append("\n");
+                    message.append("Input inV2: ");
+                    message.append(String.format("0x%x", args.inV2));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMinUint3Uint3Uint3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkMinChar4Char4Char4() {
+        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 4, 0x96e9fe1589a3ed38l, false);
+        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 4, 0x96e9fe1589a3ed39l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
+            script.set_gAllocInV2(inV2);
+            script.forEach_testMinChar4Char4Char4(inV1, out);
+            verifyResultsMinChar4Char4Char4(inV1, inV2, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinChar4Char4Char4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV2(inV2);
+            scriptRelaxed.forEach_testMinChar4Char4Char4(inV1, out);
+            verifyResultsMinChar4Char4Char4(inV1, inV2, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinChar4Char4Char4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinChar4Char4Char4(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
+        byte[] arrayInV1 = new byte[INPUTSIZE * 4];
+        inV1.copyTo(arrayInV1);
+        byte[] arrayInV2 = new byte[INPUTSIZE * 4];
+        inV2.copyTo(arrayInV2);
+        byte[] arrayOut = new byte[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsCharCharChar args = new ArgumentsCharCharChar();
+                args.inV1 = arrayInV1[i * 4 + j];
+                args.inV2 = arrayInV2[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMin(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV1: ");
+                    message.append(String.format("%d", args.inV1));
+                    message.append("\n");
+                    message.append("Input inV2: ");
+                    message.append(String.format("%d", args.inV2));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMinChar4Char4Char4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkMinUchar4Uchar4Uchar4() {
+        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 4, 0x771f30ddb702af15l, false);
+        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 4, 0x771f30ddb702af16l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
+            script.set_gAllocInV2(inV2);
+            script.forEach_testMinUchar4Uchar4Uchar4(inV1, out);
+            verifyResultsMinUchar4Uchar4Uchar4(inV1, inV2, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUchar4Uchar4Uchar4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV2(inV2);
+            scriptRelaxed.forEach_testMinUchar4Uchar4Uchar4(inV1, out);
+            verifyResultsMinUchar4Uchar4Uchar4(inV1, inV2, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUchar4Uchar4Uchar4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinUchar4Uchar4Uchar4(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
+        byte[] arrayInV1 = new byte[INPUTSIZE * 4];
+        inV1.copyTo(arrayInV1);
+        byte[] arrayInV2 = new byte[INPUTSIZE * 4];
+        inV2.copyTo(arrayInV2);
+        byte[] arrayOut = new byte[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsUcharUcharUchar args = new ArgumentsUcharUcharUchar();
+                args.inV1 = arrayInV1[i * 4 + j];
+                args.inV2 = arrayInV2[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMin(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV1: ");
+                    message.append(String.format("0x%x", args.inV1));
+                    message.append("\n");
+                    message.append("Input inV2: ");
+                    message.append(String.format("0x%x", args.inV2));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMinUchar4Uchar4Uchar4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkMinShort4Short4Short4() {
+        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 4, 0x3e7838df6c865f96l, false);
+        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 4, 0x3e7838df6c865f97l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
+            script.set_gAllocInV2(inV2);
+            script.forEach_testMinShort4Short4Short4(inV1, out);
+            verifyResultsMinShort4Short4Short4(inV1, inV2, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinShort4Short4Short4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV2(inV2);
+            scriptRelaxed.forEach_testMinShort4Short4Short4(inV1, out);
+            verifyResultsMinShort4Short4Short4(inV1, inV2, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinShort4Short4Short4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinShort4Short4Short4(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
+        short[] arrayInV1 = new short[INPUTSIZE * 4];
+        inV1.copyTo(arrayInV1);
+        short[] arrayInV2 = new short[INPUTSIZE * 4];
+        inV2.copyTo(arrayInV2);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsShortShortShort args = new ArgumentsShortShortShort();
+                args.inV1 = arrayInV1[i * 4 + j];
+                args.inV2 = arrayInV2[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMin(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV1: ");
+                    message.append(String.format("%d", args.inV1));
+                    message.append("\n");
+                    message.append("Input inV2: ");
+                    message.append(String.format("%d", args.inV2));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMinShort4Short4Short4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkMinUshort4Ushort4Ushort4() {
+        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 4, 0x92d4a27a41fb0bd3l, false);
+        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 4, 0x92d4a27a41fb0bd4l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
+            script.set_gAllocInV2(inV2);
+            script.forEach_testMinUshort4Ushort4Ushort4(inV1, out);
+            verifyResultsMinUshort4Ushort4Ushort4(inV1, inV2, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUshort4Ushort4Ushort4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV2(inV2);
+            scriptRelaxed.forEach_testMinUshort4Ushort4Ushort4(inV1, out);
+            verifyResultsMinUshort4Ushort4Ushort4(inV1, inV2, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUshort4Ushort4Ushort4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinUshort4Ushort4Ushort4(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
+        short[] arrayInV1 = new short[INPUTSIZE * 4];
+        inV1.copyTo(arrayInV1);
+        short[] arrayInV2 = new short[INPUTSIZE * 4];
+        inV2.copyTo(arrayInV2);
+        short[] arrayOut = new short[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsUshortUshortUshort args = new ArgumentsUshortUshortUshort();
+                args.inV1 = arrayInV1[i * 4 + j];
+                args.inV2 = arrayInV2[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMin(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV1: ");
+                    message.append(String.format("0x%x", args.inV1));
+                    message.append("\n");
+                    message.append("Input inV2: ");
+                    message.append(String.format("0x%x", args.inV2));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMinUshort4Ushort4Ushort4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkMinInt4Int4Int4() {
+        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 4, 0xf7db1a07a1d0fe9l, false);
+        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 4, 0xf7db1a07a1d0feal, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            script.set_gAllocInV2(inV2);
+            script.forEach_testMinInt4Int4Int4(inV1, out);
+            verifyResultsMinInt4Int4Int4(inV1, inV2, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinInt4Int4Int4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV2(inV2);
+            scriptRelaxed.forEach_testMinInt4Int4Int4(inV1, out);
+            verifyResultsMinInt4Int4Int4(inV1, inV2, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinInt4Int4Int4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinInt4Int4Int4(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
+        int[] arrayInV1 = new int[INPUTSIZE * 4];
+        inV1.copyTo(arrayInV1);
+        int[] arrayInV2 = new int[INPUTSIZE * 4];
+        inV2.copyTo(arrayInV2);
+        int[] arrayOut = new int[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsIntIntInt args = new ArgumentsIntIntInt();
+                args.inV1 = arrayInV1[i * 4 + j];
+                args.inV2 = arrayInV2[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMin(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV1: ");
+                    message.append(String.format("%d", args.inV1));
+                    message.append("\n");
+                    message.append("Input inV2: ");
+                    message.append(String.format("%d", args.inV2));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("%d", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%d", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMinInt4Int4Int4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkMinUint4Uint4Uint4() {
+        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 4, 0x63727ce7a0a14778l, false);
+        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 4, 0x63727ce7a0a14779l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
+            script.set_gAllocInV2(inV2);
+            script.forEach_testMinUint4Uint4Uint4(inV1, out);
+            verifyResultsMinUint4Uint4Uint4(inV1, inV2, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUint4Uint4Uint4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV2(inV2);
+            scriptRelaxed.forEach_testMinUint4Uint4Uint4(inV1, out);
+            verifyResultsMinUint4Uint4Uint4(inV1, inV2, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUint4Uint4Uint4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinUint4Uint4Uint4(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
+        int[] arrayInV1 = new int[INPUTSIZE * 4];
+        inV1.copyTo(arrayInV1);
+        int[] arrayInV2 = new int[INPUTSIZE * 4];
+        inV2.copyTo(arrayInV2);
+        int[] arrayOut = new int[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsUintUintUint args = new ArgumentsUintUintUint();
+                args.inV1 = arrayInV1[i * 4 + j];
+                args.inV2 = arrayInV2[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMin(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.out != arrayOut[i * 4 + j]) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV1: ");
+                    message.append(String.format("0x%x", args.inV1));
+                    message.append("\n");
+                    message.append("Input inV2: ");
+                    message.append(String.format("0x%x", args.inV2));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(String.format("0x%x", args.out));
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
+                    if (args.out != arrayOut[i * 4 + j]) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMinUint4Uint4Uint4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testMin() {
+        checkMinFloatFloatFloat();
+        checkMinFloat2Float2Float2();
+        checkMinFloat3Float3Float3();
+        checkMinFloat4Float4Float4();
+        checkMinCharCharChar();
+        checkMinUcharUcharUchar();
+        checkMinShortShortShort();
+        checkMinUshortUshortUshort();
+        checkMinIntIntInt();
+        checkMinUintUintUint();
+        checkMinChar2Char2Char2();
+        checkMinUchar2Uchar2Uchar2();
+        checkMinShort2Short2Short2();
+        checkMinUshort2Ushort2Ushort2();
+        checkMinInt2Int2Int2();
+        checkMinUint2Uint2Uint2();
+        checkMinChar3Char3Char3();
+        checkMinUchar3Uchar3Uchar3();
+        checkMinShort3Short3Short3();
+        checkMinUshort3Ushort3Ushort3();
+        checkMinInt3Int3Int3();
+        checkMinUint3Uint3Uint3();
+        checkMinChar4Char4Char4();
+        checkMinUchar4Uchar4Uchar4();
+        checkMinShort4Short4Short4();
+        checkMinUshort4Ushort4Ushort4();
+        checkMinInt4Int4Int4();
+        checkMinUint4Uint4Uint4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestMix.java b/tests/tests/renderscript/src/android/renderscript/cts/TestMix.java
new file mode 100644
index 0000000..e9618cf
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestMix.java
@@ -0,0 +1,606 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestMix extends RSBaseCompute {
+
+    private ScriptC_TestMix script;
+    private ScriptC_TestMixRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestMix(mRS);
+        scriptRelaxed = new ScriptC_TestMixRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloatFloatFloat {
+        public float inStart;
+        public float inStop;
+        public float inAmount;
+        public Floaty out;
+    }
+
+    private void checkMixFloatFloatFloatFloat() {
+        Allocation inStart = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x9f4beff6471d6db1l, false);
+        Allocation inStop = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x6ede0b88b4422e8fl, false);
+        Allocation inAmount = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xc1c14e5d52dc3fe5l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInStop(inStop);
+            script.set_gAllocInAmount(inAmount);
+            script.forEach_testMixFloatFloatFloatFloat(inStart, out);
+            verifyResultsMixFloatFloatFloatFloat(inStart, inStop, inAmount, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMixFloatFloatFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInStop(inStop);
+            scriptRelaxed.set_gAllocInAmount(inAmount);
+            scriptRelaxed.forEach_testMixFloatFloatFloatFloat(inStart, out);
+            verifyResultsMixFloatFloatFloatFloat(inStart, inStop, inAmount, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMixFloatFloatFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMixFloatFloatFloatFloat(Allocation inStart, Allocation inStop, Allocation inAmount, Allocation out, boolean relaxed) {
+        float[] arrayInStart = new float[INPUTSIZE * 1];
+        inStart.copyTo(arrayInStart);
+        float[] arrayInStop = new float[INPUTSIZE * 1];
+        inStop.copyTo(arrayInStop);
+        float[] arrayInAmount = new float[INPUTSIZE * 1];
+        inAmount.copyTo(arrayInAmount);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
+                args.inStart = arrayInStart[i];
+                args.inStop = arrayInStop[i];
+                args.inAmount = arrayInAmount[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMix(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inStart: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inStart, Float.floatToRawIntBits(args.inStart), args.inStart));
+                    message.append("\n");
+                    message.append("Input inStop: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inStop, Float.floatToRawIntBits(args.inStop), args.inStop));
+                    message.append("\n");
+                    message.append("Input inAmount: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inAmount, Float.floatToRawIntBits(args.inAmount), args.inAmount));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMixFloatFloatFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkMixFloat2Float2Float2Float2() {
+        Allocation inStart = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x45502e8f0a2d9ce9l, false);
+        Allocation inStop = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xba2b8a035395e837l, false);
+        Allocation inAmount = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xa477d20616942e4dl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInStop(inStop);
+            script.set_gAllocInAmount(inAmount);
+            script.forEach_testMixFloat2Float2Float2Float2(inStart, out);
+            verifyResultsMixFloat2Float2Float2Float2(inStart, inStop, inAmount, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMixFloat2Float2Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInStop(inStop);
+            scriptRelaxed.set_gAllocInAmount(inAmount);
+            scriptRelaxed.forEach_testMixFloat2Float2Float2Float2(inStart, out);
+            verifyResultsMixFloat2Float2Float2Float2(inStart, inStop, inAmount, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMixFloat2Float2Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMixFloat2Float2Float2Float2(Allocation inStart, Allocation inStop, Allocation inAmount, Allocation out, boolean relaxed) {
+        float[] arrayInStart = new float[INPUTSIZE * 2];
+        inStart.copyTo(arrayInStart);
+        float[] arrayInStop = new float[INPUTSIZE * 2];
+        inStop.copyTo(arrayInStop);
+        float[] arrayInAmount = new float[INPUTSIZE * 2];
+        inAmount.copyTo(arrayInAmount);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
+                args.inStart = arrayInStart[i * 2 + j];
+                args.inStop = arrayInStop[i * 2 + j];
+                args.inAmount = arrayInAmount[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMix(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inStart: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inStart, Float.floatToRawIntBits(args.inStart), args.inStart));
+                    message.append("\n");
+                    message.append("Input inStop: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inStop, Float.floatToRawIntBits(args.inStop), args.inStop));
+                    message.append("\n");
+                    message.append("Input inAmount: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inAmount, Float.floatToRawIntBits(args.inAmount), args.inAmount));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMixFloat2Float2Float2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkMixFloat3Float3Float3Float3() {
+        Allocation inStart = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xeb4701726b009c5l, false);
+        Allocation inStop = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x9b21f6b3249ee4cbl, false);
+        Allocation inAmount = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x784ed3e2e07c7741l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInStop(inStop);
+            script.set_gAllocInAmount(inAmount);
+            script.forEach_testMixFloat3Float3Float3Float3(inStart, out);
+            verifyResultsMixFloat3Float3Float3Float3(inStart, inStop, inAmount, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMixFloat3Float3Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInStop(inStop);
+            scriptRelaxed.set_gAllocInAmount(inAmount);
+            scriptRelaxed.forEach_testMixFloat3Float3Float3Float3(inStart, out);
+            verifyResultsMixFloat3Float3Float3Float3(inStart, inStop, inAmount, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMixFloat3Float3Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMixFloat3Float3Float3Float3(Allocation inStart, Allocation inStop, Allocation inAmount, Allocation out, boolean relaxed) {
+        float[] arrayInStart = new float[INPUTSIZE * 4];
+        inStart.copyTo(arrayInStart);
+        float[] arrayInStop = new float[INPUTSIZE * 4];
+        inStop.copyTo(arrayInStop);
+        float[] arrayInAmount = new float[INPUTSIZE * 4];
+        inAmount.copyTo(arrayInAmount);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
+                args.inStart = arrayInStart[i * 4 + j];
+                args.inStop = arrayInStop[i * 4 + j];
+                args.inAmount = arrayInAmount[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMix(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inStart: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inStart, Float.floatToRawIntBits(args.inStart), args.inStart));
+                    message.append("\n");
+                    message.append("Input inStop: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inStop, Float.floatToRawIntBits(args.inStop), args.inStop));
+                    message.append("\n");
+                    message.append("Input inAmount: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inAmount, Float.floatToRawIntBits(args.inAmount), args.inAmount));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMixFloat3Float3Float3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkMixFloat4Float4Float4Float4() {
+        Allocation inStart = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xd818b19f433276a1l, false);
+        Allocation inStop = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x7c186362f5a7e15fl, false);
+        Allocation inAmount = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x4c25d5bfaa64c035l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInStop(inStop);
+            script.set_gAllocInAmount(inAmount);
+            script.forEach_testMixFloat4Float4Float4Float4(inStart, out);
+            verifyResultsMixFloat4Float4Float4Float4(inStart, inStop, inAmount, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMixFloat4Float4Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInStop(inStop);
+            scriptRelaxed.set_gAllocInAmount(inAmount);
+            scriptRelaxed.forEach_testMixFloat4Float4Float4Float4(inStart, out);
+            verifyResultsMixFloat4Float4Float4Float4(inStart, inStop, inAmount, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMixFloat4Float4Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMixFloat4Float4Float4Float4(Allocation inStart, Allocation inStop, Allocation inAmount, Allocation out, boolean relaxed) {
+        float[] arrayInStart = new float[INPUTSIZE * 4];
+        inStart.copyTo(arrayInStart);
+        float[] arrayInStop = new float[INPUTSIZE * 4];
+        inStop.copyTo(arrayInStop);
+        float[] arrayInAmount = new float[INPUTSIZE * 4];
+        inAmount.copyTo(arrayInAmount);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
+                args.inStart = arrayInStart[i * 4 + j];
+                args.inStop = arrayInStop[i * 4 + j];
+                args.inAmount = arrayInAmount[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMix(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inStart: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inStart, Float.floatToRawIntBits(args.inStart), args.inStart));
+                    message.append("\n");
+                    message.append("Input inStop: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inStop, Float.floatToRawIntBits(args.inStop), args.inStop));
+                    message.append("\n");
+                    message.append("Input inAmount: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inAmount, Float.floatToRawIntBits(args.inAmount), args.inAmount));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMixFloat4Float4Float4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkMixFloat2Float2FloatFloat2() {
+        Allocation inStart = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xf811b2d52bd1d7c3l, false);
+        Allocation inStop = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x17a127e13c8dd1c5l, false);
+        Allocation inAmount = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xaaf909cdbd2a10ebl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInStop(inStop);
+            script.set_gAllocInAmount(inAmount);
+            script.forEach_testMixFloat2Float2FloatFloat2(inStart, out);
+            verifyResultsMixFloat2Float2FloatFloat2(inStart, inStop, inAmount, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMixFloat2Float2FloatFloat2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInStop(inStop);
+            scriptRelaxed.set_gAllocInAmount(inAmount);
+            scriptRelaxed.forEach_testMixFloat2Float2FloatFloat2(inStart, out);
+            verifyResultsMixFloat2Float2FloatFloat2(inStart, inStop, inAmount, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMixFloat2Float2FloatFloat2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMixFloat2Float2FloatFloat2(Allocation inStart, Allocation inStop, Allocation inAmount, Allocation out, boolean relaxed) {
+        float[] arrayInStart = new float[INPUTSIZE * 2];
+        inStart.copyTo(arrayInStart);
+        float[] arrayInStop = new float[INPUTSIZE * 2];
+        inStop.copyTo(arrayInStop);
+        float[] arrayInAmount = new float[INPUTSIZE * 1];
+        inAmount.copyTo(arrayInAmount);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
+                args.inStart = arrayInStart[i * 2 + j];
+                args.inStop = arrayInStop[i * 2 + j];
+                args.inAmount = arrayInAmount[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMix(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inStart: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inStart, Float.floatToRawIntBits(args.inStart), args.inStart));
+                    message.append("\n");
+                    message.append("Input inStop: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inStop, Float.floatToRawIntBits(args.inStop), args.inStop));
+                    message.append("\n");
+                    message.append("Input inAmount: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inAmount, Float.floatToRawIntBits(args.inAmount), args.inAmount));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMixFloat2Float2FloatFloat2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkMixFloat3Float3FloatFloat3() {
+        Allocation inStart = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xae7aff441b20fa80l, false);
+        Allocation inStop = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xe64a4d60d6f4de7cl, false);
+        Allocation inAmount = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x4ea8e06fef74e6aal, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInStop(inStop);
+            script.set_gAllocInAmount(inAmount);
+            script.forEach_testMixFloat3Float3FloatFloat3(inStart, out);
+            verifyResultsMixFloat3Float3FloatFloat3(inStart, inStop, inAmount, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMixFloat3Float3FloatFloat3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInStop(inStop);
+            scriptRelaxed.set_gAllocInAmount(inAmount);
+            scriptRelaxed.forEach_testMixFloat3Float3FloatFloat3(inStart, out);
+            verifyResultsMixFloat3Float3FloatFloat3(inStart, inStop, inAmount, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMixFloat3Float3FloatFloat3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMixFloat3Float3FloatFloat3(Allocation inStart, Allocation inStop, Allocation inAmount, Allocation out, boolean relaxed) {
+        float[] arrayInStart = new float[INPUTSIZE * 4];
+        inStart.copyTo(arrayInStart);
+        float[] arrayInStop = new float[INPUTSIZE * 4];
+        inStop.copyTo(arrayInStop);
+        float[] arrayInAmount = new float[INPUTSIZE * 1];
+        inAmount.copyTo(arrayInAmount);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
+                args.inStart = arrayInStart[i * 4 + j];
+                args.inStop = arrayInStop[i * 4 + j];
+                args.inAmount = arrayInAmount[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMix(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inStart: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inStart, Float.floatToRawIntBits(args.inStart), args.inStart));
+                    message.append("\n");
+                    message.append("Input inStop: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inStop, Float.floatToRawIntBits(args.inStop), args.inStop));
+                    message.append("\n");
+                    message.append("Input inAmount: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inAmount, Float.floatToRawIntBits(args.inAmount), args.inAmount));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMixFloat3Float3FloatFloat3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkMixFloat4Float4FloatFloat4() {
+        Allocation inStart = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x64e44bb30a701d3dl, false);
+        Allocation inStop = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xb4f372e0715beb33l, false);
+        Allocation inAmount = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xf258b71221bfbc69l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInStop(inStop);
+            script.set_gAllocInAmount(inAmount);
+            script.forEach_testMixFloat4Float4FloatFloat4(inStart, out);
+            verifyResultsMixFloat4Float4FloatFloat4(inStart, inStop, inAmount, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMixFloat4Float4FloatFloat4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInStop(inStop);
+            scriptRelaxed.set_gAllocInAmount(inAmount);
+            scriptRelaxed.forEach_testMixFloat4Float4FloatFloat4(inStart, out);
+            verifyResultsMixFloat4Float4FloatFloat4(inStart, inStop, inAmount, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMixFloat4Float4FloatFloat4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMixFloat4Float4FloatFloat4(Allocation inStart, Allocation inStop, Allocation inAmount, Allocation out, boolean relaxed) {
+        float[] arrayInStart = new float[INPUTSIZE * 4];
+        inStart.copyTo(arrayInStart);
+        float[] arrayInStop = new float[INPUTSIZE * 4];
+        inStop.copyTo(arrayInStop);
+        float[] arrayInAmount = new float[INPUTSIZE * 1];
+        inAmount.copyTo(arrayInAmount);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
+                args.inStart = arrayInStart[i * 4 + j];
+                args.inStop = arrayInStop[i * 4 + j];
+                args.inAmount = arrayInAmount[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeMix(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inStart: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inStart, Float.floatToRawIntBits(args.inStart), args.inStart));
+                    message.append("\n");
+                    message.append("Input inStop: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inStop, Float.floatToRawIntBits(args.inStop), args.inStop));
+                    message.append("\n");
+                    message.append("Input inAmount: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inAmount, Float.floatToRawIntBits(args.inAmount), args.inAmount));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMixFloat4Float4FloatFloat4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testMix() {
+        checkMixFloatFloatFloatFloat();
+        checkMixFloat2Float2Float2Float2();
+        checkMixFloat3Float3Float3Float3();
+        checkMixFloat4Float4Float4Float4();
+        checkMixFloat2Float2FloatFloat2();
+        checkMixFloat3Float3FloatFloat3();
+        checkMixFloat4Float4FloatFloat4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestModf.java b/tests/tests/renderscript/src/android/renderscript/cts/TestModf.java
new file mode 100644
index 0000000..1d2190f
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestModf.java
@@ -0,0 +1,361 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestModf extends RSBaseCompute {
+
+    private ScriptC_TestModf script;
+    private ScriptC_TestModfRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestModf(mRS);
+        scriptRelaxed = new ScriptC_TestModfRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloatFloat {
+        public float inX;
+        public Floaty outIret;
+        public Floaty out;
+    }
+
+    private void checkModfFloatFloatFloat() {
+        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xd655dc05ccaef47l, false);
+        try {
+            Allocation outIret = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocOutIret(outIret);
+            script.forEach_testModfFloatFloatFloat(inX, out);
+            verifyResultsModfFloatFloatFloat(inX, outIret, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testModfFloatFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation outIret = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocOutIret(outIret);
+            scriptRelaxed.forEach_testModfFloatFloatFloat(inX, out);
+            verifyResultsModfFloatFloatFloat(inX, outIret, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testModfFloatFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsModfFloatFloatFloat(Allocation inX, Allocation outIret, Allocation out, boolean relaxed) {
+        float[] arrayInX = new float[INPUTSIZE * 1];
+        inX.copyTo(arrayInX);
+        float[] arrayOutIret = new float[INPUTSIZE * 1];
+        outIret.copyTo(arrayOutIret);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inX = arrayInX[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeModf(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.outIret.couldBe(arrayOutIret[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Expected output outIret: ");
+                    message.append(args.outIret.toString());
+                    message.append("\n");
+                    message.append("Actual   output outIret: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOutIret[i * 1 + j], Float.floatToRawIntBits(arrayOutIret[i * 1 + j]), arrayOutIret[i * 1 + j]));
+                    if (!args.outIret.couldBe(arrayOutIret[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkModfFloatFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkModfFloat2Float2Float2() {
+        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x2a1dc519fa163061l, false);
+        try {
+            Allocation outIret = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocOutIret(outIret);
+            script.forEach_testModfFloat2Float2Float2(inX, out);
+            verifyResultsModfFloat2Float2Float2(inX, outIret, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testModfFloat2Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation outIret = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocOutIret(outIret);
+            scriptRelaxed.forEach_testModfFloat2Float2Float2(inX, out);
+            verifyResultsModfFloat2Float2Float2(inX, outIret, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testModfFloat2Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsModfFloat2Float2Float2(Allocation inX, Allocation outIret, Allocation out, boolean relaxed) {
+        float[] arrayInX = new float[INPUTSIZE * 2];
+        inX.copyTo(arrayInX);
+        float[] arrayOutIret = new float[INPUTSIZE * 2];
+        outIret.copyTo(arrayOutIret);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inX = arrayInX[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeModf(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.outIret.couldBe(arrayOutIret[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Expected output outIret: ");
+                    message.append(args.outIret.toString());
+                    message.append("\n");
+                    message.append("Actual   output outIret: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOutIret[i * 2 + j], Float.floatToRawIntBits(arrayOutIret[i * 2 + j]), arrayOutIret[i * 2 + j]));
+                    if (!args.outIret.couldBe(arrayOutIret[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkModfFloat2Float2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkModfFloat3Float3Float3() {
+        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x7e82a339fbf43202l, false);
+        try {
+            Allocation outIret = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocOutIret(outIret);
+            script.forEach_testModfFloat3Float3Float3(inX, out);
+            verifyResultsModfFloat3Float3Float3(inX, outIret, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testModfFloat3Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation outIret = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocOutIret(outIret);
+            scriptRelaxed.forEach_testModfFloat3Float3Float3(inX, out);
+            verifyResultsModfFloat3Float3Float3(inX, outIret, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testModfFloat3Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsModfFloat3Float3Float3(Allocation inX, Allocation outIret, Allocation out, boolean relaxed) {
+        float[] arrayInX = new float[INPUTSIZE * 4];
+        inX.copyTo(arrayInX);
+        float[] arrayOutIret = new float[INPUTSIZE * 4];
+        outIret.copyTo(arrayOutIret);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inX = arrayInX[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeModf(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.outIret.couldBe(arrayOutIret[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Expected output outIret: ");
+                    message.append(args.outIret.toString());
+                    message.append("\n");
+                    message.append("Actual   output outIret: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOutIret[i * 4 + j], Float.floatToRawIntBits(arrayOutIret[i * 4 + j]), arrayOutIret[i * 4 + j]));
+                    if (!args.outIret.couldBe(arrayOutIret[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkModfFloat3Float3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkModfFloat4Float4Float4() {
+        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xd2e78159fdd233a3l, false);
+        try {
+            Allocation outIret = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocOutIret(outIret);
+            script.forEach_testModfFloat4Float4Float4(inX, out);
+            verifyResultsModfFloat4Float4Float4(inX, outIret, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testModfFloat4Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation outIret = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocOutIret(outIret);
+            scriptRelaxed.forEach_testModfFloat4Float4Float4(inX, out);
+            verifyResultsModfFloat4Float4Float4(inX, outIret, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testModfFloat4Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsModfFloat4Float4Float4(Allocation inX, Allocation outIret, Allocation out, boolean relaxed) {
+        float[] arrayInX = new float[INPUTSIZE * 4];
+        inX.copyTo(arrayInX);
+        float[] arrayOutIret = new float[INPUTSIZE * 4];
+        outIret.copyTo(arrayOutIret);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inX = arrayInX[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeModf(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.outIret.couldBe(arrayOutIret[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Expected output outIret: ");
+                    message.append(args.outIret.toString());
+                    message.append("\n");
+                    message.append("Actual   output outIret: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOutIret[i * 4 + j], Float.floatToRawIntBits(arrayOutIret[i * 4 + j]), arrayOutIret[i * 4 + j]));
+                    if (!args.outIret.couldBe(arrayOutIret[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkModfFloat4Float4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testModf() {
+        checkModfFloatFloatFloat();
+        checkModfFloat2Float2Float2();
+        checkModfFloat3Float3Float3();
+        checkModfFloat4Float4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNan.java b/tests/tests/renderscript/src/android/renderscript/cts/TestNan.java
new file mode 100644
index 0000000..d8ae72b
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestNan.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestNan extends RSBaseCompute {
+
+    private ScriptC_TestNan script;
+    private ScriptC_TestNanRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestNan(mRS);
+        scriptRelaxed = new ScriptC_TestNanRelaxed(mRS);
+    }
+
+    public class ArgumentsUintFloat {
+        public int in;
+        public Floaty out;
+    }
+
+    private void checkNanUintFloat() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 1, 0x757e939c0e627774l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testNanUintFloat(in, out);
+            verifyResultsNanUintFloat(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNanUintFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNanUintFloat(in, out);
+            verifyResultsNanUintFloat(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNanUintFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNanUintFloat(Allocation in, Allocation out, boolean relaxed) {
+        int[] arrayIn = new int[INPUTSIZE * 1];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsUintFloat args = new ArgumentsUintFloat();
+                args.in = arrayIn[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeNan(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("0x%x", args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkNanUintFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testNan() {
+        checkNanUintFloat();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeExp.java b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeExp.java
new file mode 100644
index 0000000..5432ce6
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeExp.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestNativeExp extends RSBaseCompute {
+
+    private ScriptC_TestNativeExp script;
+    private ScriptC_TestNativeExpRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestNativeExp(mRS);
+        scriptRelaxed = new ScriptC_TestNativeExpRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Floaty out;
+    }
+
+    private void checkNativeExpFloatFloat() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x66a7898af1f6be9bl, -86, 86);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testNativeExpFloatFloat(inV, out);
+            verifyResultsNativeExpFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExpFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeExpFloatFloat(inV, out);
+            verifyResultsNativeExpFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExpFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeExpFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeNativeExp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkNativeExpFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkNativeExpFloat2Float2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x6feb21d463a0ee67l, -86, 86);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testNativeExpFloat2Float2(inV, out);
+            verifyResultsNativeExpFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExpFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeExpFloat2Float2(inV, out);
+            verifyResultsNativeExpFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExpFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeExpFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeNativeExp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkNativeExpFloat2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkNativeExpFloat3Float3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x6feceaef59bc0f45l, -86, 86);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testNativeExpFloat3Float3(inV, out);
+            verifyResultsNativeExpFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExpFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeExpFloat3Float3(inV, out);
+            verifyResultsNativeExpFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExpFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeExpFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeNativeExp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkNativeExpFloat3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkNativeExpFloat4Float4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x6feeb40a4fd73023l, -86, 86);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testNativeExpFloat4Float4(inV, out);
+            verifyResultsNativeExpFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExpFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeExpFloat4Float4(inV, out);
+            verifyResultsNativeExpFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExpFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeExpFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeNativeExp(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkNativeExpFloat4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testNativeExp() {
+        checkNativeExpFloatFloat();
+        checkNativeExpFloat2Float2();
+        checkNativeExpFloat3Float3();
+        checkNativeExpFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeExp10.java b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeExp10.java
new file mode 100644
index 0000000..4f4d340
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeExp10.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestNativeExp10 extends RSBaseCompute {
+
+    private ScriptC_TestNativeExp10 script;
+    private ScriptC_TestNativeExp10Relaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestNativeExp10(mRS);
+        scriptRelaxed = new ScriptC_TestNativeExp10Relaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Floaty out;
+    }
+
+    private void checkNativeExp10FloatFloat() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x562e4ea690352c54l, -37, 37);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testNativeExp10FloatFloat(inV, out);
+            verifyResultsNativeExp10FloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExp10FloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeExp10FloatFloat(inV, out);
+            verifyResultsNativeExp10FloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExp10FloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeExp10FloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeNativeExp10(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkNativeExp10FloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkNativeExp10Float2Float2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x7450c64e54876b98l, -37, 37);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testNativeExp10Float2Float2(inV, out);
+            verifyResultsNativeExp10Float2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExp10Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeExp10Float2Float2(inV, out);
+            verifyResultsNativeExp10Float2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExp10Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeExp10Float2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeNativeExp10(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkNativeExp10Float2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkNativeExp10Float3Float3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x74528f694aa28c76l, -37, 37);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testNativeExp10Float3Float3(inV, out);
+            verifyResultsNativeExp10Float3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExp10Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeExp10Float3Float3(inV, out);
+            verifyResultsNativeExp10Float3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExp10Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeExp10Float3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeNativeExp10(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkNativeExp10Float3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkNativeExp10Float4Float4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x7454588440bdad54l, -37, 37);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testNativeExp10Float4Float4(inV, out);
+            verifyResultsNativeExp10Float4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExp10Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeExp10Float4Float4(inV, out);
+            verifyResultsNativeExp10Float4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExp10Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeExp10Float4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeNativeExp10(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkNativeExp10Float4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testNativeExp10() {
+        checkNativeExp10FloatFloat();
+        checkNativeExp10Float2Float2();
+        checkNativeExp10Float3Float3();
+        checkNativeExp10Float4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeExp2.java b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeExp2.java
new file mode 100644
index 0000000..469140d
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeExp2.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestNativeExp2 extends RSBaseCompute {
+
+    private ScriptC_TestNativeExp2 script;
+    private ScriptC_TestNativeExp2Relaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestNativeExp2(mRS);
+        scriptRelaxed = new ScriptC_TestNativeExp2Relaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Floaty out;
+    }
+
+    private void checkNativeExp2FloatFloat() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xd87a6eb24c6a2bc5l, -125, 125);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testNativeExp2FloatFloat(inV, out);
+            verifyResultsNativeExp2FloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExp2FloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeExp2FloatFloat(inV, out);
+            verifyResultsNativeExp2FloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExp2FloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeExp2FloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeNativeExp2(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkNativeExp2FloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkNativeExp2Float2Float2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x8c243b10af5062c1l, -125, 125);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testNativeExp2Float2Float2(inV, out);
+            verifyResultsNativeExp2Float2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExp2Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeExp2Float2Float2(inV, out);
+            verifyResultsNativeExp2Float2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExp2Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeExp2Float2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeNativeExp2(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkNativeExp2Float2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkNativeExp2Float3Float3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x8c26042ba56b839fl, -125, 125);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testNativeExp2Float3Float3(inV, out);
+            verifyResultsNativeExp2Float3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExp2Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeExp2Float3Float3(inV, out);
+            verifyResultsNativeExp2Float3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExp2Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeExp2Float3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeNativeExp2(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkNativeExp2Float3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkNativeExp2Float4Float4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x8c27cd469b86a47dl, -125, 125);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testNativeExp2Float4Float4(inV, out);
+            verifyResultsNativeExp2Float4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExp2Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeExp2Float4Float4(inV, out);
+            verifyResultsNativeExp2Float4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExp2Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeExp2Float4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeNativeExp2(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkNativeExp2Float4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testNativeExp2() {
+        checkNativeExp2FloatFloat();
+        checkNativeExp2Float2Float2();
+        checkNativeExp2Float3Float3();
+        checkNativeExp2Float4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeLog.java b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeLog.java
new file mode 100644
index 0000000..821760b
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeLog.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestNativeLog extends RSBaseCompute {
+
+    private ScriptC_TestNativeLog script;
+    private ScriptC_TestNativeLogRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestNativeLog(mRS);
+        scriptRelaxed = new ScriptC_TestNativeLogRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Floaty out;
+    }
+
+    private void checkNativeLogFloatFloat() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x6237b14ee6418d2cl, 10e-10, 10e10);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testNativeLogFloatFloat(inV, out);
+            verifyResultsNativeLogFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLogFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeLogFloatFloat(inV, out);
+            verifyResultsNativeLogFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLogFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeLogFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeNativeLog(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j], 0.0002)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j], 0.0002)) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkNativeLogFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkNativeLogFloat2Float2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x641a5823d3eee3b0l, 10e-10, 10e10);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testNativeLogFloat2Float2(inV, out);
+            verifyResultsNativeLogFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLogFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeLogFloat2Float2(inV, out);
+            verifyResultsNativeLogFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLogFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeLogFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeNativeLog(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j], 0.0002)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j], 0.0002)) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkNativeLogFloat2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkNativeLogFloat3Float3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x641c213eca0a048el, 10e-10, 10e10);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testNativeLogFloat3Float3(inV, out);
+            verifyResultsNativeLogFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLogFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeLogFloat3Float3(inV, out);
+            verifyResultsNativeLogFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLogFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeLogFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeNativeLog(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0002)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0002)) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkNativeLogFloat3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkNativeLogFloat4Float4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x641dea59c025256cl, 10e-10, 10e10);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testNativeLogFloat4Float4(inV, out);
+            verifyResultsNativeLogFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLogFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeLogFloat4Float4(inV, out);
+            verifyResultsNativeLogFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLogFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeLogFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeNativeLog(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0002)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0002)) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkNativeLogFloat4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testNativeLog() {
+        checkNativeLogFloatFloat();
+        checkNativeLogFloat2Float2();
+        checkNativeLogFloat3Float3();
+        checkNativeLogFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeLog10.java b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeLog10.java
new file mode 100644
index 0000000..caa1133
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeLog10.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestNativeLog10 extends RSBaseCompute {
+
+    private ScriptC_TestNativeLog10 script;
+    private ScriptC_TestNativeLog10Relaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestNativeLog10(mRS);
+        scriptRelaxed = new ScriptC_TestNativeLog10Relaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Floaty out;
+    }
+
+    private void checkNativeLog10FloatFloat() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x4a5d84f60083219dl, 10e-10, 10e10);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testNativeLog10FloatFloat(inV, out);
+            verifyResultsNativeLog10FloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog10FloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeLog10FloatFloat(inV, out);
+            verifyResultsNativeLog10FloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog10FloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeLog10FloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeNativeLog10(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j], 0.00005)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j], 0.00005)) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkNativeLog10FloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkNativeLog10Float2Float2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x1d500a10779807d9l, 10e-10, 10e10);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testNativeLog10Float2Float2(inV, out);
+            verifyResultsNativeLog10Float2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog10Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeLog10Float2Float2(inV, out);
+            verifyResultsNativeLog10Float2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog10Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeLog10Float2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeNativeLog10(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j], 0.00005)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j], 0.00005)) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkNativeLog10Float2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkNativeLog10Float3Float3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x1d51d32b6db328b7l, 10e-10, 10e10);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testNativeLog10Float3Float3(inV, out);
+            verifyResultsNativeLog10Float3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog10Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeLog10Float3Float3(inV, out);
+            verifyResultsNativeLog10Float3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog10Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeLog10Float3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeNativeLog10(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j], 0.00005)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j], 0.00005)) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkNativeLog10Float3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkNativeLog10Float4Float4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x1d539c4663ce4995l, 10e-10, 10e10);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testNativeLog10Float4Float4(inV, out);
+            verifyResultsNativeLog10Float4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog10Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeLog10Float4Float4(inV, out);
+            verifyResultsNativeLog10Float4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog10Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeLog10Float4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeNativeLog10(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j], 0.00005)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j], 0.00005)) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkNativeLog10Float4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testNativeLog10() {
+        checkNativeLog10FloatFloat();
+        checkNativeLog10Float2Float2();
+        checkNativeLog10Float3Float3();
+        checkNativeLog10Float4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeLog2.java b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeLog2.java
new file mode 100644
index 0000000..b860a5e
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeLog2.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestNativeLog2 extends RSBaseCompute {
+
+    private ScriptC_TestNativeLog2 script;
+    private ScriptC_TestNativeLog2Relaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestNativeLog2(mRS);
+        scriptRelaxed = new ScriptC_TestNativeLog2Relaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Floaty out;
+    }
+
+    private void checkNativeLog2FloatFloat() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x19b11c9c54fade20l, 10e-10, 10e10);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testNativeLog2FloatFloat(inV, out);
+            verifyResultsNativeLog2FloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog2FloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeLog2FloatFloat(inV, out);
+            verifyResultsNativeLog2FloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog2FloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeLog2FloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeNativeLog2(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j], 0.0002)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j], 0.0002)) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkNativeLog2FloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkNativeLog2Float2Float2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x90125a688c689604l, 10e-10, 10e10);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testNativeLog2Float2Float2(inV, out);
+            verifyResultsNativeLog2Float2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog2Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeLog2Float2Float2(inV, out);
+            verifyResultsNativeLog2Float2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog2Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeLog2Float2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeNativeLog2(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j], 0.0002)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j], 0.0002)) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkNativeLog2Float2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkNativeLog2Float3Float3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x901423838283b6e2l, 10e-10, 10e10);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testNativeLog2Float3Float3(inV, out);
+            verifyResultsNativeLog2Float3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog2Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeLog2Float3Float3(inV, out);
+            verifyResultsNativeLog2Float3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog2Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeLog2Float3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeNativeLog2(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0002)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0002)) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkNativeLog2Float3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkNativeLog2Float4Float4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x9015ec9e789ed7c0l, 10e-10, 10e10);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testNativeLog2Float4Float4(inV, out);
+            verifyResultsNativeLog2Float4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog2Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeLog2Float4Float4(inV, out);
+            verifyResultsNativeLog2Float4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog2Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeLog2Float4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeNativeLog2(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0002)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0002)) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkNativeLog2Float4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testNativeLog2() {
+        checkNativeLog2FloatFloat();
+        checkNativeLog2Float2Float2();
+        checkNativeLog2Float3Float3();
+        checkNativeLog2Float4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativePowr.java b/tests/tests/renderscript/src/android/renderscript/cts/TestNativePowr.java
new file mode 100644
index 0000000..640f1af
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestNativePowr.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestNativePowr extends RSBaseCompute {
+
+    private ScriptC_TestNativePowr script;
+    private ScriptC_TestNativePowrRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestNativePowr(mRS);
+        scriptRelaxed = new ScriptC_TestNativePowrRelaxed(mRS);
+    }
+
+    private void checkNativePowrFloatFloatFloat() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x3c3550bdff7a10c2l, 0, 256);
+        Allocation inY = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x3c3550bdff7a10c5l, -15, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInY(inY);
+            script.forEach_testNativePowrFloatFloatFloat(inV, out);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativePowrFloatFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInY(inY);
+            scriptRelaxed.forEach_testNativePowrFloatFloatFloat(inV, out);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativePowrFloatFloatFloat: " + e.toString());
+        }
+    }
+
+    private void checkNativePowrFloat2Float2Float2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xdbc56fbe7733c926l, 0, 256);
+        Allocation inY = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xdbc56fbe7733c929l, -15, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInY(inY);
+            script.forEach_testNativePowrFloat2Float2Float2(inV, out);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativePowrFloat2Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInY(inY);
+            scriptRelaxed.forEach_testNativePowrFloat2Float2Float2(inV, out);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativePowrFloat2Float2Float2: " + e.toString());
+        }
+    }
+
+    private void checkNativePowrFloat3Float3Float3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x302a4dde7911cac7l, 0, 256);
+        Allocation inY = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x302a4dde7911cacal, -15, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInY(inY);
+            script.forEach_testNativePowrFloat3Float3Float3(inV, out);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativePowrFloat3Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInY(inY);
+            scriptRelaxed.forEach_testNativePowrFloat3Float3Float3(inV, out);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativePowrFloat3Float3Float3: " + e.toString());
+        }
+    }
+
+    private void checkNativePowrFloat4Float4Float4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x848f2bfe7aefcc68l, 0, 256);
+        Allocation inY = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x848f2bfe7aefcc6bl, -15, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInY(inY);
+            script.forEach_testNativePowrFloat4Float4Float4(inV, out);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativePowrFloat4Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInY(inY);
+            scriptRelaxed.forEach_testNativePowrFloat4Float4Float4(inV, out);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativePowrFloat4Float4Float4: " + e.toString());
+        }
+    }
+
+    public void testNativePowr() {
+        checkNativePowrFloatFloatFloat();
+        checkNativePowrFloat2Float2Float2();
+        checkNativePowrFloat3Float3Float3();
+        checkNativePowrFloat4Float4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNextafter.java b/tests/tests/renderscript/src/android/renderscript/cts/TestNextafter.java
new file mode 100644
index 0000000..fb76646
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestNextafter.java
@@ -0,0 +1,325 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestNextafter extends RSBaseCompute {
+
+    private ScriptC_TestNextafter script;
+    private ScriptC_TestNextafterRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestNextafter(mRS);
+        scriptRelaxed = new ScriptC_TestNextafterRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloatFloat {
+        public float inX;
+        public float inY;
+        public Floaty out;
+    }
+
+    private void checkNextafterFloatFloatFloat() {
+        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xa3b02393ad412958l, false);
+        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xa3b02393ad412959l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInY(inY);
+            script.forEach_testNextafterFloatFloatFloat(inX, out);
+            verifyResultsNextafterFloatFloatFloat(inX, inY, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNextafterFloatFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInY(inY);
+            scriptRelaxed.forEach_testNextafterFloatFloatFloat(inX, out);
+            verifyResultsNextafterFloatFloatFloat(inX, inY, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNextafterFloatFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNextafterFloatFloatFloat(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
+        float[] arrayInX = new float[INPUTSIZE * 1];
+        inX.copyTo(arrayInX);
+        float[] arrayInY = new float[INPUTSIZE * 1];
+        inY.copyTo(arrayInY);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inX = arrayInX[i];
+                args.inY = arrayInY[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeNextafter(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Input inY: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkNextafterFloatFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkNextafterFloat2Float2Float2() {
+        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x29b40e0584a1e24l, false);
+        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x29b40e0584a1e25l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInY(inY);
+            script.forEach_testNextafterFloat2Float2Float2(inX, out);
+            verifyResultsNextafterFloat2Float2Float2(inX, inY, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNextafterFloat2Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInY(inY);
+            scriptRelaxed.forEach_testNextafterFloat2Float2Float2(inX, out);
+            verifyResultsNextafterFloat2Float2Float2(inX, inY, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNextafterFloat2Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNextafterFloat2Float2Float2(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
+        float[] arrayInX = new float[INPUTSIZE * 2];
+        inX.copyTo(arrayInX);
+        float[] arrayInY = new float[INPUTSIZE * 2];
+        inY.copyTo(arrayInY);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inX = arrayInX[i * 2 + j];
+                args.inY = arrayInY[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeNextafter(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Input inY: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkNextafterFloat2Float2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkNextafterFloat3Float3Float3() {
+        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x57001f005a281fc5l, false);
+        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x57001f005a281fc6l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInY(inY);
+            script.forEach_testNextafterFloat3Float3Float3(inX, out);
+            verifyResultsNextafterFloat3Float3Float3(inX, inY, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNextafterFloat3Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInY(inY);
+            scriptRelaxed.forEach_testNextafterFloat3Float3Float3(inX, out);
+            verifyResultsNextafterFloat3Float3Float3(inX, inY, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNextafterFloat3Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNextafterFloat3Float3Float3(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
+        float[] arrayInX = new float[INPUTSIZE * 4];
+        inX.copyTo(arrayInX);
+        float[] arrayInY = new float[INPUTSIZE * 4];
+        inY.copyTo(arrayInY);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inX = arrayInX[i * 4 + j];
+                args.inY = arrayInY[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeNextafter(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Input inY: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkNextafterFloat3Float3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkNextafterFloat4Float4Float4() {
+        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xab64fd205c062166l, false);
+        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xab64fd205c062167l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInY(inY);
+            script.forEach_testNextafterFloat4Float4Float4(inX, out);
+            verifyResultsNextafterFloat4Float4Float4(inX, inY, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNextafterFloat4Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInY(inY);
+            scriptRelaxed.forEach_testNextafterFloat4Float4Float4(inX, out);
+            verifyResultsNextafterFloat4Float4Float4(inX, inY, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNextafterFloat4Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNextafterFloat4Float4Float4(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
+        float[] arrayInX = new float[INPUTSIZE * 4];
+        inX.copyTo(arrayInX);
+        float[] arrayInY = new float[INPUTSIZE * 4];
+        inY.copyTo(arrayInY);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inX = arrayInX[i * 4 + j];
+                args.inY = arrayInY[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeNextafter(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Input inY: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkNextafterFloat4Float4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testNextafter() {
+        checkNextafterFloatFloatFloat();
+        checkNextafterFloat2Float2Float2();
+        checkNextafterFloat3Float3Float3();
+        checkNextafterFloat4Float4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNormalize.java b/tests/tests/renderscript/src/android/renderscript/cts/TestNormalize.java
new file mode 100644
index 0000000..137d807
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestNormalize.java
@@ -0,0 +1,315 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestNormalize extends RSBaseCompute {
+
+    private ScriptC_TestNormalize script;
+    private ScriptC_TestNormalizeRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestNormalize(mRS);
+        scriptRelaxed = new ScriptC_TestNormalizeRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Floaty out;
+    }
+
+    private void checkNormalizeFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x6db01d449460061cl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testNormalizeFloatFloat(inV, out);
+            verifyResultsNormalizeFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNormalizeFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNormalizeFloatFloat(inV, out);
+            verifyResultsNormalizeFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNormalizeFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNormalizeFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+            // Create the appropriate sized arrays in args
+            // Fill args with the input values
+            args.inV = arrayInV[i];
+            Floaty.setRelaxed(relaxed);
+            CoreMathVerifier.computeNormalize(args);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(arrayOut[i])) {
+                valid = false;
+            }
+            if (!valid) {
+                StringBuilder message = new StringBuilder();
+                message.append("Input inV: ");
+                message.append(String.format("%14.8g %8x %15a",
+                        arrayInV[i], Float.floatToRawIntBits(arrayInV[i]), arrayInV[i]));
+                message.append("\n");
+                message.append("Expected output out: ");
+                message.append(args.out.toString());
+                message.append("\n");
+                message.append("Actual   output out: ");
+                message.append(String.format("%14.8g %8x %15a",
+                        arrayOut[i], Float.floatToRawIntBits(arrayOut[i]), arrayOut[i]));
+                if (!args.out.couldBe(arrayOut[i])) {
+                    message.append(" FAIL");
+                }
+                message.append("\n");
+                assertTrue("Incorrect output for checkNormalizeFloatFloat" +
+                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+            }
+        }
+    }
+
+    public class ArgumentsFloatNFloatN {
+        public float[] inV;
+        public Floaty[] out;
+    }
+
+    private void checkNormalizeFloat2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x3cde199a6e066120l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testNormalizeFloat2Float2(inV, out);
+            verifyResultsNormalizeFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNormalizeFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNormalizeFloat2Float2(inV, out);
+            verifyResultsNormalizeFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNormalizeFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNormalizeFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsFloatNFloatN args = new ArgumentsFloatNFloatN();
+            // Create the appropriate sized arrays in args
+            args.inV = new float[2];
+            args.out = new Floaty[2];
+            // Fill args with the input values
+            for (int j = 0; j < 2 ; j++) {
+                args.inV[j] = arrayInV[i * 2 + j];
+            }
+            Floaty.setRelaxed(relaxed);
+            CoreMathVerifier.computeNormalize(args);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            for (int j = 0; j < 2 ; j++) {
+                if (!args.out[j].couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+            }
+            if (!valid) {
+                StringBuilder message = new StringBuilder();
+                for (int j = 0; j < 2 ; j++) {
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayInV[i * 2 + j], Float.floatToRawIntBits(arrayInV[i * 2 + j]), arrayInV[i * 2 + j]));
+                    message.append("\n");
+                }
+                for (int j = 0; j < 2 ; j++) {
+                    message.append("Expected output out: ");
+                    message.append(args.out[j].toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out[j].couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                }
+                assertTrue("Incorrect output for checkNormalizeFloat2Float2" +
+                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+            }
+        }
+    }
+
+    private void checkNormalizeFloat3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x3cdfe2b5642181fel, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testNormalizeFloat3Float3(inV, out);
+            verifyResultsNormalizeFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNormalizeFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNormalizeFloat3Float3(inV, out);
+            verifyResultsNormalizeFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNormalizeFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNormalizeFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsFloatNFloatN args = new ArgumentsFloatNFloatN();
+            // Create the appropriate sized arrays in args
+            args.inV = new float[3];
+            args.out = new Floaty[3];
+            // Fill args with the input values
+            for (int j = 0; j < 3 ; j++) {
+                args.inV[j] = arrayInV[i * 4 + j];
+            }
+            Floaty.setRelaxed(relaxed);
+            CoreMathVerifier.computeNormalize(args);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            for (int j = 0; j < 3 ; j++) {
+                if (!args.out[j].couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+            }
+            if (!valid) {
+                StringBuilder message = new StringBuilder();
+                for (int j = 0; j < 3 ; j++) {
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayInV[i * 4 + j], Float.floatToRawIntBits(arrayInV[i * 4 + j]), arrayInV[i * 4 + j]));
+                    message.append("\n");
+                }
+                for (int j = 0; j < 3 ; j++) {
+                    message.append("Expected output out: ");
+                    message.append(args.out[j].toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out[j].couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                }
+                assertTrue("Incorrect output for checkNormalizeFloat3Float3" +
+                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+            }
+        }
+    }
+
+    private void checkNormalizeFloat4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x3ce1abd05a3ca2dcl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testNormalizeFloat4Float4(inV, out);
+            verifyResultsNormalizeFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNormalizeFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNormalizeFloat4Float4(inV, out);
+            verifyResultsNormalizeFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNormalizeFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNormalizeFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsFloatNFloatN args = new ArgumentsFloatNFloatN();
+            // Create the appropriate sized arrays in args
+            args.inV = new float[4];
+            args.out = new Floaty[4];
+            // Fill args with the input values
+            for (int j = 0; j < 4 ; j++) {
+                args.inV[j] = arrayInV[i * 4 + j];
+            }
+            Floaty.setRelaxed(relaxed);
+            CoreMathVerifier.computeNormalize(args);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            for (int j = 0; j < 4 ; j++) {
+                if (!args.out[j].couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+            }
+            if (!valid) {
+                StringBuilder message = new StringBuilder();
+                for (int j = 0; j < 4 ; j++) {
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayInV[i * 4 + j], Float.floatToRawIntBits(arrayInV[i * 4 + j]), arrayInV[i * 4 + j]));
+                    message.append("\n");
+                }
+                for (int j = 0; j < 4 ; j++) {
+                    message.append("Expected output out: ");
+                    message.append(args.out[j].toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out[j].couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                }
+                assertTrue("Incorrect output for checkNormalizeFloat4Float4" +
+                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+            }
+        }
+    }
+
+    public void testNormalize() {
+        checkNormalizeFloatFloat();
+        checkNormalizeFloat2Float2();
+        checkNormalizeFloat3Float3();
+        checkNormalizeFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestPow.java b/tests/tests/renderscript/src/android/renderscript/cts/TestPow.java
new file mode 100644
index 0000000..33cec67
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestPow.java
@@ -0,0 +1,325 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestPow extends RSBaseCompute {
+
+    private ScriptC_TestPow script;
+    private ScriptC_TestPowRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestPow(mRS);
+        scriptRelaxed = new ScriptC_TestPowRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloatFloat {
+        public float inX;
+        public float inY;
+        public Floaty out;
+    }
+
+    private void checkPowFloatFloatFloat() {
+        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x470aeab18312445bl, false);
+        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x470aeab18312445cl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInY(inY);
+            script.forEach_testPowFloatFloatFloat(inX, out);
+            verifyResultsPowFloatFloatFloat(inX, inY, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPowFloatFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInY(inY);
+            scriptRelaxed.forEach_testPowFloatFloatFloat(inX, out);
+            verifyResultsPowFloatFloatFloat(inX, inY, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPowFloatFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsPowFloatFloatFloat(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
+        float[] arrayInX = new float[INPUTSIZE * 1];
+        inX.copyTo(arrayInX);
+        float[] arrayInY = new float[INPUTSIZE * 1];
+        inY.copyTo(arrayInY);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inX = arrayInX[i];
+                args.inY = arrayInY[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computePow(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Input inY: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkPowFloatFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkPowFloat2Float2Float2() {
+        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xbcd9b7ed561242ddl, false);
+        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xbcd9b7ed561242del, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInY(inY);
+            script.forEach_testPowFloat2Float2Float2(inX, out);
+            verifyResultsPowFloat2Float2Float2(inX, inY, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPowFloat2Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInY(inY);
+            scriptRelaxed.forEach_testPowFloat2Float2Float2(inX, out);
+            verifyResultsPowFloat2Float2Float2(inX, inY, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPowFloat2Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsPowFloat2Float2Float2(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
+        float[] arrayInX = new float[INPUTSIZE * 2];
+        inX.copyTo(arrayInX);
+        float[] arrayInY = new float[INPUTSIZE * 2];
+        inY.copyTo(arrayInY);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inX = arrayInX[i * 2 + j];
+                args.inY = arrayInY[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computePow(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Input inY: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkPowFloat2Float2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkPowFloat3Float3Float3() {
+        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x113e960d57f0447el, false);
+        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x113e960d57f0447fl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInY(inY);
+            script.forEach_testPowFloat3Float3Float3(inX, out);
+            verifyResultsPowFloat3Float3Float3(inX, inY, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPowFloat3Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInY(inY);
+            scriptRelaxed.forEach_testPowFloat3Float3Float3(inX, out);
+            verifyResultsPowFloat3Float3Float3(inX, inY, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPowFloat3Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsPowFloat3Float3Float3(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
+        float[] arrayInX = new float[INPUTSIZE * 4];
+        inX.copyTo(arrayInX);
+        float[] arrayInY = new float[INPUTSIZE * 4];
+        inY.copyTo(arrayInY);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inX = arrayInX[i * 4 + j];
+                args.inY = arrayInY[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computePow(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Input inY: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkPowFloat3Float3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkPowFloat4Float4Float4() {
+        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x65a3742d59ce461fl, false);
+        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x65a3742d59ce4620l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInY(inY);
+            script.forEach_testPowFloat4Float4Float4(inX, out);
+            verifyResultsPowFloat4Float4Float4(inX, inY, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPowFloat4Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInY(inY);
+            scriptRelaxed.forEach_testPowFloat4Float4Float4(inX, out);
+            verifyResultsPowFloat4Float4Float4(inX, inY, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPowFloat4Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsPowFloat4Float4Float4(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
+        float[] arrayInX = new float[INPUTSIZE * 4];
+        inX.copyTo(arrayInX);
+        float[] arrayInY = new float[INPUTSIZE * 4];
+        inY.copyTo(arrayInY);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inX = arrayInX[i * 4 + j];
+                args.inY = arrayInY[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computePow(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Input inY: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkPowFloat4Float4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testPow() {
+        checkPowFloatFloatFloat();
+        checkPowFloat2Float2Float2();
+        checkPowFloat3Float3Float3();
+        checkPowFloat4Float4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestPown.java b/tests/tests/renderscript/src/android/renderscript/cts/TestPown.java
new file mode 100644
index 0000000..722dc00
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestPown.java
@@ -0,0 +1,321 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestPown extends RSBaseCompute {
+
+    private ScriptC_TestPown script;
+    private ScriptC_TestPownRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestPown(mRS);
+        scriptRelaxed = new ScriptC_TestPownRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatIntFloat {
+        public float inX;
+        public int inY;
+        public Floaty out;
+    }
+
+    private void checkPownFloatIntFloat() {
+        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xde633e0d2c462948l, false);
+        Allocation inY = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0xde633e0d2c462949l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInY(inY);
+            script.forEach_testPownFloatIntFloat(inX, out);
+            verifyResultsPownFloatIntFloat(inX, inY, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPownFloatIntFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInY(inY);
+            scriptRelaxed.forEach_testPownFloatIntFloat(inX, out);
+            verifyResultsPownFloatIntFloat(inX, inY, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPownFloatIntFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsPownFloatIntFloat(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
+        float[] arrayInX = new float[INPUTSIZE * 1];
+        inX.copyTo(arrayInX);
+        int[] arrayInY = new int[INPUTSIZE * 1];
+        inY.copyTo(arrayInY);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
+                args.inX = arrayInX[i];
+                args.inY = arrayInY[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computePown(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Input inY: ");
+                    message.append(String.format("%d", args.inY));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkPownFloatIntFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkPownFloat2Int2Float2() {
+        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x1685dc0ea821329el, false);
+        Allocation inY = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 2, 0x1685dc0ea821329fl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInY(inY);
+            script.forEach_testPownFloat2Int2Float2(inX, out);
+            verifyResultsPownFloat2Int2Float2(inX, inY, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPownFloat2Int2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInY(inY);
+            scriptRelaxed.forEach_testPownFloat2Int2Float2(inX, out);
+            verifyResultsPownFloat2Int2Float2(inX, inY, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPownFloat2Int2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsPownFloat2Int2Float2(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
+        float[] arrayInX = new float[INPUTSIZE * 2];
+        inX.copyTo(arrayInX);
+        int[] arrayInY = new int[INPUTSIZE * 2];
+        inY.copyTo(arrayInY);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
+                args.inX = arrayInX[i * 2 + j];
+                args.inY = arrayInY[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computePown(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Input inY: ");
+                    message.append(String.format("%d", args.inY));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkPownFloat2Int2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkPownFloat3Int3Float3() {
+        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x3c3c1a719dd39f57l, false);
+        Allocation inY = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 3, 0x3c3c1a719dd39f58l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInY(inY);
+            script.forEach_testPownFloat3Int3Float3(inX, out);
+            verifyResultsPownFloat3Int3Float3(inX, inY, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPownFloat3Int3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInY(inY);
+            scriptRelaxed.forEach_testPownFloat3Int3Float3(inX, out);
+            verifyResultsPownFloat3Int3Float3(inX, inY, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPownFloat3Int3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsPownFloat3Int3Float3(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
+        float[] arrayInX = new float[INPUTSIZE * 4];
+        inX.copyTo(arrayInX);
+        int[] arrayInY = new int[INPUTSIZE * 4];
+        inY.copyTo(arrayInY);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
+                args.inX = arrayInX[i * 4 + j];
+                args.inY = arrayInY[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computePown(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Input inY: ");
+                    message.append(String.format("%d", args.inY));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkPownFloat3Int3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkPownFloat4Int4Float4() {
+        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x61f258d493860c10l, false);
+        Allocation inY = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 4, 0x61f258d493860c11l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInY(inY);
+            script.forEach_testPownFloat4Int4Float4(inX, out);
+            verifyResultsPownFloat4Int4Float4(inX, inY, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPownFloat4Int4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInY(inY);
+            scriptRelaxed.forEach_testPownFloat4Int4Float4(inX, out);
+            verifyResultsPownFloat4Int4Float4(inX, inY, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPownFloat4Int4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsPownFloat4Int4Float4(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
+        float[] arrayInX = new float[INPUTSIZE * 4];
+        inX.copyTo(arrayInX);
+        int[] arrayInY = new int[INPUTSIZE * 4];
+        inY.copyTo(arrayInY);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
+                args.inX = arrayInX[i * 4 + j];
+                args.inY = arrayInY[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computePown(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Input inY: ");
+                    message.append(String.format("%d", args.inY));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkPownFloat4Int4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testPown() {
+        checkPownFloatIntFloat();
+        checkPownFloat2Int2Float2();
+        checkPownFloat3Int3Float3();
+        checkPownFloat4Int4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestPowr.java b/tests/tests/renderscript/src/android/renderscript/cts/TestPowr.java
new file mode 100644
index 0000000..dac9b10
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestPowr.java
@@ -0,0 +1,325 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestPowr extends RSBaseCompute {
+
+    private ScriptC_TestPowr script;
+    private ScriptC_TestPowrRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestPowr(mRS);
+        scriptRelaxed = new ScriptC_TestPowrRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloatFloat {
+        public float inX;
+        public float inY;
+        public Floaty out;
+    }
+
+    private void checkPowrFloatFloatFloat() {
+        Allocation inX = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x616e17ec158f6a8dl, 0, 3000);
+        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x616e17ec158f6a8el, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInY(inY);
+            script.forEach_testPowrFloatFloatFloat(inX, out);
+            verifyResultsPowrFloatFloatFloat(inX, inY, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPowrFloatFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInY(inY);
+            scriptRelaxed.forEach_testPowrFloatFloatFloat(inX, out);
+            verifyResultsPowrFloatFloatFloat(inX, inY, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPowrFloatFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsPowrFloatFloatFloat(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
+        float[] arrayInX = new float[INPUTSIZE * 1];
+        inX.copyTo(arrayInX);
+        float[] arrayInY = new float[INPUTSIZE * 1];
+        inY.copyTo(arrayInY);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inX = arrayInX[i];
+                args.inY = arrayInY[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computePowr(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Input inY: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkPowrFloatFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkPowrFloat2Float2Float2() {
+        Allocation inX = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xfc919df3002fbd93l, 0, 3000);
+        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xfc919df3002fbd94l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInY(inY);
+            script.forEach_testPowrFloat2Float2Float2(inX, out);
+            verifyResultsPowrFloat2Float2Float2(inX, inY, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPowrFloat2Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInY(inY);
+            scriptRelaxed.forEach_testPowrFloat2Float2Float2(inX, out);
+            verifyResultsPowrFloat2Float2Float2(inX, inY, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPowrFloat2Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsPowrFloat2Float2Float2(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
+        float[] arrayInX = new float[INPUTSIZE * 2];
+        inX.copyTo(arrayInX);
+        float[] arrayInY = new float[INPUTSIZE * 2];
+        inY.copyTo(arrayInY);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inX = arrayInX[i * 2 + j];
+                args.inY = arrayInY[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computePowr(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Input inY: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkPowrFloat2Float2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkPowrFloat3Float3Float3() {
+        Allocation inX = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x50f67c13020dbf34l, 0, 3000);
+        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x50f67c13020dbf35l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInY(inY);
+            script.forEach_testPowrFloat3Float3Float3(inX, out);
+            verifyResultsPowrFloat3Float3Float3(inX, inY, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPowrFloat3Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInY(inY);
+            scriptRelaxed.forEach_testPowrFloat3Float3Float3(inX, out);
+            verifyResultsPowrFloat3Float3Float3(inX, inY, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPowrFloat3Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsPowrFloat3Float3Float3(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
+        float[] arrayInX = new float[INPUTSIZE * 4];
+        inX.copyTo(arrayInX);
+        float[] arrayInY = new float[INPUTSIZE * 4];
+        inY.copyTo(arrayInY);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inX = arrayInX[i * 4 + j];
+                args.inY = arrayInY[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computePowr(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Input inY: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkPowrFloat3Float3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkPowrFloat4Float4Float4() {
+        Allocation inX = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xa55b5a3303ebc0d5l, 0, 3000);
+        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xa55b5a3303ebc0d6l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInY(inY);
+            script.forEach_testPowrFloat4Float4Float4(inX, out);
+            verifyResultsPowrFloat4Float4Float4(inX, inY, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPowrFloat4Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInY(inY);
+            scriptRelaxed.forEach_testPowrFloat4Float4Float4(inX, out);
+            verifyResultsPowrFloat4Float4Float4(inX, inY, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPowrFloat4Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsPowrFloat4Float4Float4(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
+        float[] arrayInX = new float[INPUTSIZE * 4];
+        inX.copyTo(arrayInX);
+        float[] arrayInY = new float[INPUTSIZE * 4];
+        inY.copyTo(arrayInY);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inX = arrayInX[i * 4 + j];
+                args.inY = arrayInY[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computePowr(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Input inY: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkPowrFloat4Float4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testPowr() {
+        checkPowrFloatFloatFloat();
+        checkPowrFloat2Float2Float2();
+        checkPowrFloat3Float3Float3();
+        checkPowrFloat4Float4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestRadians.java b/tests/tests/renderscript/src/android/renderscript/cts/TestRadians.java
new file mode 100644
index 0000000..c5820fc
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestRadians.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestRadians extends RSBaseCompute {
+
+    private ScriptC_TestRadians script;
+    private ScriptC_TestRadiansRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestRadians(mRS);
+        scriptRelaxed = new ScriptC_TestRadiansRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inValue;
+        public Floaty out;
+    }
+
+    private void checkRadiansFloatFloat() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xaa72f227598b8106l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testRadiansFloatFloat(inValue, out);
+            verifyResultsRadiansFloatFloat(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRadiansFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testRadiansFloatFloat(inValue, out);
+            verifyResultsRadiansFloatFloat(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRadiansFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRadiansFloatFloat(Allocation inValue, Allocation out, boolean relaxed) {
+        float[] arrayInValue = new float[INPUTSIZE * 1];
+        inValue.copyTo(arrayInValue);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inValue = arrayInValue[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeRadians(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inValue, Float.floatToRawIntBits(args.inValue), args.inValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkRadiansFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkRadiansFloat2Float2() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xb28bd9316e059892l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testRadiansFloat2Float2(inValue, out);
+            verifyResultsRadiansFloat2Float2(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRadiansFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testRadiansFloat2Float2(inValue, out);
+            verifyResultsRadiansFloat2Float2(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRadiansFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRadiansFloat2Float2(Allocation inValue, Allocation out, boolean relaxed) {
+        float[] arrayInValue = new float[INPUTSIZE * 2];
+        inValue.copyTo(arrayInValue);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inValue = arrayInValue[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeRadians(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inValue, Float.floatToRawIntBits(args.inValue), args.inValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkRadiansFloat2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkRadiansFloat3Float3() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xd8404eb8b743be10l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testRadiansFloat3Float3(inValue, out);
+            verifyResultsRadiansFloat3Float3(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRadiansFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testRadiansFloat3Float3(inValue, out);
+            verifyResultsRadiansFloat3Float3(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRadiansFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRadiansFloat3Float3(Allocation inValue, Allocation out, boolean relaxed) {
+        float[] arrayInValue = new float[INPUTSIZE * 4];
+        inValue.copyTo(arrayInValue);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inValue = arrayInValue[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeRadians(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inValue, Float.floatToRawIntBits(args.inValue), args.inValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkRadiansFloat3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkRadiansFloat4Float4() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xfdf4c4400081e38el, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testRadiansFloat4Float4(inValue, out);
+            verifyResultsRadiansFloat4Float4(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRadiansFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testRadiansFloat4Float4(inValue, out);
+            verifyResultsRadiansFloat4Float4(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRadiansFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRadiansFloat4Float4(Allocation inValue, Allocation out, boolean relaxed) {
+        float[] arrayInValue = new float[INPUTSIZE * 4];
+        inValue.copyTo(arrayInValue);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inValue = arrayInValue[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeRadians(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inValue: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inValue, Float.floatToRawIntBits(args.inValue), args.inValue));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkRadiansFloat4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testRadians() {
+        checkRadiansFloatFloat();
+        checkRadiansFloat2Float2();
+        checkRadiansFloat3Float3();
+        checkRadiansFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestRemainder.java b/tests/tests/renderscript/src/android/renderscript/cts/TestRemainder.java
new file mode 100644
index 0000000..420fb0f
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestRemainder.java
@@ -0,0 +1,325 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestRemainder extends RSBaseCompute {
+
+    private ScriptC_TestRemainder script;
+    private ScriptC_TestRemainderRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestRemainder(mRS);
+        scriptRelaxed = new ScriptC_TestRemainderRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloatFloat {
+        public float inX;
+        public float inY;
+        public Floaty out;
+    }
+
+    private void checkRemainderFloatFloatFloat() {
+        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x27d6330966022888l, false);
+        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x27d6330966022889l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInY(inY);
+            script.forEach_testRemainderFloatFloatFloat(inX, out);
+            verifyResultsRemainderFloatFloatFloat(inX, inY, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRemainderFloatFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInY(inY);
+            scriptRelaxed.forEach_testRemainderFloatFloatFloat(inX, out);
+            verifyResultsRemainderFloatFloatFloat(inX, inY, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRemainderFloatFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRemainderFloatFloatFloat(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
+        float[] arrayInX = new float[INPUTSIZE * 1];
+        inX.copyTo(arrayInX);
+        float[] arrayInY = new float[INPUTSIZE * 1];
+        inY.copyTo(arrayInY);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inX = arrayInX[i];
+                args.inY = arrayInY[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeRemainder(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Input inY: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkRemainderFloatFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkRemainderFloat2Float2Float2() {
+        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xfb2eaf332420c6b4l, false);
+        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xfb2eaf332420c6b5l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInY(inY);
+            script.forEach_testRemainderFloat2Float2Float2(inX, out);
+            verifyResultsRemainderFloat2Float2Float2(inX, inY, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRemainderFloat2Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInY(inY);
+            scriptRelaxed.forEach_testRemainderFloat2Float2Float2(inX, out);
+            verifyResultsRemainderFloat2Float2Float2(inX, inY, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRemainderFloat2Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRemainderFloat2Float2Float2(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
+        float[] arrayInX = new float[INPUTSIZE * 2];
+        inX.copyTo(arrayInX);
+        float[] arrayInY = new float[INPUTSIZE * 2];
+        inY.copyTo(arrayInY);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inX = arrayInX[i * 2 + j];
+                args.inY = arrayInY[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeRemainder(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Input inY: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkRemainderFloat2Float2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkRemainderFloat3Float3Float3() {
+        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x4f938d5325fec855l, false);
+        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x4f938d5325fec856l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInY(inY);
+            script.forEach_testRemainderFloat3Float3Float3(inX, out);
+            verifyResultsRemainderFloat3Float3Float3(inX, inY, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRemainderFloat3Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInY(inY);
+            scriptRelaxed.forEach_testRemainderFloat3Float3Float3(inX, out);
+            verifyResultsRemainderFloat3Float3Float3(inX, inY, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRemainderFloat3Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRemainderFloat3Float3Float3(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
+        float[] arrayInX = new float[INPUTSIZE * 4];
+        inX.copyTo(arrayInX);
+        float[] arrayInY = new float[INPUTSIZE * 4];
+        inY.copyTo(arrayInY);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inX = arrayInX[i * 4 + j];
+                args.inY = arrayInY[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeRemainder(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Input inY: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkRemainderFloat3Float3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkRemainderFloat4Float4Float4() {
+        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xa3f86b7327dcc9f6l, false);
+        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xa3f86b7327dcc9f7l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInY(inY);
+            script.forEach_testRemainderFloat4Float4Float4(inX, out);
+            verifyResultsRemainderFloat4Float4Float4(inX, inY, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRemainderFloat4Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInY(inY);
+            scriptRelaxed.forEach_testRemainderFloat4Float4Float4(inX, out);
+            verifyResultsRemainderFloat4Float4Float4(inX, inY, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRemainderFloat4Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRemainderFloat4Float4Float4(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
+        float[] arrayInX = new float[INPUTSIZE * 4];
+        inX.copyTo(arrayInX);
+        float[] arrayInY = new float[INPUTSIZE * 4];
+        inY.copyTo(arrayInY);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inX = arrayInX[i * 4 + j];
+                args.inY = arrayInY[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeRemainder(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inX: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
+                    message.append("\n");
+                    message.append("Input inY: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkRemainderFloat4Float4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testRemainder() {
+        checkRemainderFloatFloatFloat();
+        checkRemainderFloat2Float2Float2();
+        checkRemainderFloat3Float3Float3();
+        checkRemainderFloat4Float4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestRemquo.java b/tests/tests/renderscript/src/android/renderscript/cts/TestRemquo.java
new file mode 100644
index 0000000..ff86966
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestRemquo.java
@@ -0,0 +1,398 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestRemquo extends RSBaseCompute {
+
+    private ScriptC_TestRemquo script;
+    private ScriptC_TestRemquoRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestRemquo(mRS);
+        scriptRelaxed = new ScriptC_TestRemquoRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloatIntFloat {
+        public float inB;
+        public float inC;
+        public int outD;
+        public Floaty out;
+    }
+
+    private void checkRemquoFloatFloatIntFloat() {
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x118af9b82db63b13l, false);
+        Allocation inC = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x118af9b82db63b14l, false);
+        try {
+            Allocation outD = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 1), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInC(inC);
+            script.set_gAllocOutD(outD);
+            script.forEach_testRemquoFloatFloatIntFloat(inB, out);
+            verifyResultsRemquoFloatFloatIntFloat(inB, inC, outD, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRemquoFloatFloatIntFloat: " + e.toString());
+        }
+        try {
+            Allocation outD = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 1), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInC(inC);
+            scriptRelaxed.set_gAllocOutD(outD);
+            scriptRelaxed.forEach_testRemquoFloatFloatIntFloat(inB, out);
+            verifyResultsRemquoFloatFloatIntFloat(inB, inC, outD, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRemquoFloatFloatIntFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRemquoFloatFloatIntFloat(Allocation inB, Allocation inC, Allocation outD, Allocation out, boolean relaxed) {
+        float[] arrayInB = new float[INPUTSIZE * 1];
+        inB.copyTo(arrayInB);
+        float[] arrayInC = new float[INPUTSIZE * 1];
+        inC.copyTo(arrayInC);
+        int[] arrayOutD = new int[INPUTSIZE * 1];
+        outD.copyTo(arrayOutD);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatIntFloat args = new ArgumentsFloatFloatIntFloat();
+                args.inB = arrayInB[i];
+                args.inC = arrayInC[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeRemquo(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.outD != arrayOutD[i * 1 + j] && args.out.isNaN()) {
+                    valid = false;
+                }
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inB: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inB, Float.floatToRawIntBits(args.inB), args.inB));
+                    message.append("\n");
+                    message.append("Input inC: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inC, Float.floatToRawIntBits(args.inC), args.inC));
+                    message.append("\n");
+                    message.append("Expected output outD: ");
+                    message.append(String.format("%d", args.outD));
+                    message.append("\n");
+                    message.append("Actual   output outD: ");
+                    message.append(String.format("%d", arrayOutD[i * 1 + j]));
+                    if (args.outD != arrayOutD[i * 1 + j] && args.out.isNaN()) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkRemquoFloatFloatIntFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkRemquoFloat2Float2Int2Float2() {
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x9b98a1a6b125f903l, false);
+        Allocation inC = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x9b98a1a6b125f904l, false);
+        try {
+            Allocation outD = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInC(inC);
+            script.set_gAllocOutD(outD);
+            script.forEach_testRemquoFloat2Float2Int2Float2(inB, out);
+            verifyResultsRemquoFloat2Float2Int2Float2(inB, inC, outD, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRemquoFloat2Float2Int2Float2: " + e.toString());
+        }
+        try {
+            Allocation outD = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInC(inC);
+            scriptRelaxed.set_gAllocOutD(outD);
+            scriptRelaxed.forEach_testRemquoFloat2Float2Int2Float2(inB, out);
+            verifyResultsRemquoFloat2Float2Int2Float2(inB, inC, outD, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRemquoFloat2Float2Int2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRemquoFloat2Float2Int2Float2(Allocation inB, Allocation inC, Allocation outD, Allocation out, boolean relaxed) {
+        float[] arrayInB = new float[INPUTSIZE * 2];
+        inB.copyTo(arrayInB);
+        float[] arrayInC = new float[INPUTSIZE * 2];
+        inC.copyTo(arrayInC);
+        int[] arrayOutD = new int[INPUTSIZE * 2];
+        outD.copyTo(arrayOutD);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatIntFloat args = new ArgumentsFloatFloatIntFloat();
+                args.inB = arrayInB[i * 2 + j];
+                args.inC = arrayInC[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeRemquo(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.outD != arrayOutD[i * 2 + j] && args.out.isNaN()) {
+                    valid = false;
+                }
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inB: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inB, Float.floatToRawIntBits(args.inB), args.inB));
+                    message.append("\n");
+                    message.append("Input inC: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inC, Float.floatToRawIntBits(args.inC), args.inC));
+                    message.append("\n");
+                    message.append("Expected output outD: ");
+                    message.append(String.format("%d", args.outD));
+                    message.append("\n");
+                    message.append("Actual   output outD: ");
+                    message.append(String.format("%d", arrayOutD[i * 2 + j]));
+                    if (args.outD != arrayOutD[i * 2 + j] && args.out.isNaN()) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkRemquoFloat2Float2Int2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkRemquoFloat3Float3Int3Float3() {
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xa049a00a6911ca8fl, false);
+        Allocation inC = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xa049a00a6911ca90l, false);
+        try {
+            Allocation outD = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInC(inC);
+            script.set_gAllocOutD(outD);
+            script.forEach_testRemquoFloat3Float3Int3Float3(inB, out);
+            verifyResultsRemquoFloat3Float3Int3Float3(inB, inC, outD, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRemquoFloat3Float3Int3Float3: " + e.toString());
+        }
+        try {
+            Allocation outD = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInC(inC);
+            scriptRelaxed.set_gAllocOutD(outD);
+            scriptRelaxed.forEach_testRemquoFloat3Float3Int3Float3(inB, out);
+            verifyResultsRemquoFloat3Float3Int3Float3(inB, inC, outD, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRemquoFloat3Float3Int3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRemquoFloat3Float3Int3Float3(Allocation inB, Allocation inC, Allocation outD, Allocation out, boolean relaxed) {
+        float[] arrayInB = new float[INPUTSIZE * 4];
+        inB.copyTo(arrayInB);
+        float[] arrayInC = new float[INPUTSIZE * 4];
+        inC.copyTo(arrayInC);
+        int[] arrayOutD = new int[INPUTSIZE * 4];
+        outD.copyTo(arrayOutD);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatIntFloat args = new ArgumentsFloatFloatIntFloat();
+                args.inB = arrayInB[i * 4 + j];
+                args.inC = arrayInC[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeRemquo(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.outD != arrayOutD[i * 4 + j] && args.out.isNaN()) {
+                    valid = false;
+                }
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inB: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inB, Float.floatToRawIntBits(args.inB), args.inB));
+                    message.append("\n");
+                    message.append("Input inC: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inC, Float.floatToRawIntBits(args.inC), args.inC));
+                    message.append("\n");
+                    message.append("Expected output outD: ");
+                    message.append(String.format("%d", args.outD));
+                    message.append("\n");
+                    message.append("Actual   output outD: ");
+                    message.append(String.format("%d", arrayOutD[i * 4 + j]));
+                    if (args.outD != arrayOutD[i * 4 + j] && args.out.isNaN()) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkRemquoFloat3Float3Int3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkRemquoFloat4Float4Int4Float4() {
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xa4fa9e6e20fd9c1bl, false);
+        Allocation inC = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xa4fa9e6e20fd9c1cl, false);
+        try {
+            Allocation outD = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInC(inC);
+            script.set_gAllocOutD(outD);
+            script.forEach_testRemquoFloat4Float4Int4Float4(inB, out);
+            verifyResultsRemquoFloat4Float4Int4Float4(inB, inC, outD, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRemquoFloat4Float4Int4Float4: " + e.toString());
+        }
+        try {
+            Allocation outD = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInC(inC);
+            scriptRelaxed.set_gAllocOutD(outD);
+            scriptRelaxed.forEach_testRemquoFloat4Float4Int4Float4(inB, out);
+            verifyResultsRemquoFloat4Float4Int4Float4(inB, inC, outD, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRemquoFloat4Float4Int4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRemquoFloat4Float4Int4Float4(Allocation inB, Allocation inC, Allocation outD, Allocation out, boolean relaxed) {
+        float[] arrayInB = new float[INPUTSIZE * 4];
+        inB.copyTo(arrayInB);
+        float[] arrayInC = new float[INPUTSIZE * 4];
+        inC.copyTo(arrayInC);
+        int[] arrayOutD = new int[INPUTSIZE * 4];
+        outD.copyTo(arrayOutD);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatIntFloat args = new ArgumentsFloatFloatIntFloat();
+                args.inB = arrayInB[i * 4 + j];
+                args.inC = arrayInC[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeRemquo(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (args.outD != arrayOutD[i * 4 + j] && args.out.isNaN()) {
+                    valid = false;
+                }
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inB: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inB, Float.floatToRawIntBits(args.inB), args.inB));
+                    message.append("\n");
+                    message.append("Input inC: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inC, Float.floatToRawIntBits(args.inC), args.inC));
+                    message.append("\n");
+                    message.append("Expected output outD: ");
+                    message.append(String.format("%d", args.outD));
+                    message.append("\n");
+                    message.append("Actual   output outD: ");
+                    message.append(String.format("%d", arrayOutD[i * 4 + j]));
+                    if (args.outD != arrayOutD[i * 4 + j] && args.out.isNaN()) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkRemquoFloat4Float4Int4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testRemquo() {
+        checkRemquoFloatFloatIntFloat();
+        checkRemquoFloat2Float2Int2Float2();
+        checkRemquoFloat3Float3Int3Float3();
+        checkRemquoFloat4Float4Int4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestRint.java b/tests/tests/renderscript/src/android/renderscript/cts/TestRint.java
new file mode 100644
index 0000000..b6b9ce5
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestRint.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestRint extends RSBaseCompute {
+
+    private ScriptC_TestRint script;
+    private ScriptC_TestRintRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestRint(mRS);
+        scriptRelaxed = new ScriptC_TestRintRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float in;
+        public Floaty out;
+    }
+
+    private void checkRintFloatFloat() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xfe569fda5dbe93fal, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testRintFloatFloat(in, out);
+            verifyResultsRintFloatFloat(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRintFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testRintFloatFloat(in, out);
+            verifyResultsRintFloatFloat(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRintFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRintFloatFloat(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 1];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeRint(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkRintFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkRintFloat2Float2() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xffa7b22ac6b343c6l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testRintFloat2Float2(in, out);
+            verifyResultsRintFloat2Float2(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRintFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testRintFloat2Float2(in, out);
+            verifyResultsRintFloat2Float2(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRintFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRintFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 2];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeRint(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkRintFloat2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkRintFloat3Float3() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xffa7bccc25b9d960l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testRintFloat3Float3(in, out);
+            verifyResultsRintFloat3Float3(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRintFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testRintFloat3Float3(in, out);
+            verifyResultsRintFloat3Float3(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRintFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRintFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeRint(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkRintFloat3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkRintFloat4Float4() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xffa7c76d84c06efal, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testRintFloat4Float4(in, out);
+            verifyResultsRintFloat4Float4(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRintFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testRintFloat4Float4(in, out);
+            verifyResultsRintFloat4Float4(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRintFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRintFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeRint(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkRintFloat4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testRint() {
+        checkRintFloatFloat();
+        checkRintFloat2Float2();
+        checkRintFloat3Float3();
+        checkRintFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestRootn.java b/tests/tests/renderscript/src/android/renderscript/cts/TestRootn.java
new file mode 100644
index 0000000..c138404
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestRootn.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestRootn extends RSBaseCompute {
+
+    private ScriptC_TestRootn script;
+    private ScriptC_TestRootnRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestRootn(mRS);
+        scriptRelaxed = new ScriptC_TestRootnRelaxed(mRS);
+    }
+
+    private void checkRootnFloatIntFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x37d0d9514daae0ccl, false);
+        Allocation inN = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0x37d0d9514daae0c4l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInN(inN);
+            script.forEach_testRootnFloatIntFloat(inV, out);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRootnFloatIntFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInN(inN);
+            scriptRelaxed.forEach_testRootnFloatIntFloat(inV, out);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRootnFloatIntFloat: " + e.toString());
+        }
+    }
+
+    private void checkRootnFloat2Int2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x2a7a849dcb32d88el, false);
+        Allocation inN = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 2, 0x2a7a849dcb32d886l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInN(inN);
+            script.forEach_testRootnFloat2Int2Float2(inV, out);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRootnFloat2Int2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInN(inN);
+            scriptRelaxed.forEach_testRootnFloat2Int2Float2(inV, out);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRootnFloat2Int2Float2: " + e.toString());
+        }
+    }
+
+    private void checkRootnFloat3Int3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x5030c300c0e54547l, false);
+        Allocation inN = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 3, 0x5030c300c0e5453fl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInN(inN);
+            script.forEach_testRootnFloat3Int3Float3(inV, out);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRootnFloat3Int3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInN(inN);
+            scriptRelaxed.forEach_testRootnFloat3Int3Float3(inV, out);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRootnFloat3Int3Float3: " + e.toString());
+        }
+    }
+
+    private void checkRootnFloat4Int4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x75e70163b697b200l, false);
+        Allocation inN = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 4, 0x75e70163b697b1f8l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInN(inN);
+            script.forEach_testRootnFloat4Int4Float4(inV, out);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRootnFloat4Int4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInN(inN);
+            scriptRelaxed.forEach_testRootnFloat4Int4Float4(inV, out);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRootnFloat4Int4Float4: " + e.toString());
+        }
+    }
+
+    public void testRootn() {
+        checkRootnFloatIntFloat();
+        checkRootnFloat2Int2Float2();
+        checkRootnFloat3Int3Float3();
+        checkRootnFloat4Int4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestRound.java b/tests/tests/renderscript/src/android/renderscript/cts/TestRound.java
new file mode 100644
index 0000000..08207cc
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestRound.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestRound extends RSBaseCompute {
+
+    private ScriptC_TestRound script;
+    private ScriptC_TestRoundRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestRound(mRS);
+        scriptRelaxed = new ScriptC_TestRoundRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float in;
+        public Floaty out;
+    }
+
+    private void checkRoundFloatFloat() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x377ca8d7e9a82fc7l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testRoundFloatFloat(in, out);
+            verifyResultsRoundFloatFloat(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRoundFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testRoundFloatFloat(in, out);
+            verifyResultsRoundFloatFloat(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRoundFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRoundFloatFloat(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 1];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeRound(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkRoundFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkRoundFloat2Float2() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xc35ea17250f98f6bl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testRoundFloat2Float2(in, out);
+            verifyResultsRoundFloat2Float2(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRoundFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testRoundFloat2Float2(in, out);
+            verifyResultsRoundFloat2Float2(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRoundFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRoundFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 2];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeRound(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkRoundFloat2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkRoundFloat3Float3() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xc35eac13b0002505l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testRoundFloat3Float3(in, out);
+            verifyResultsRoundFloat3Float3(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRoundFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testRoundFloat3Float3(in, out);
+            verifyResultsRoundFloat3Float3(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRoundFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRoundFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeRound(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkRoundFloat3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkRoundFloat4Float4() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xc35eb6b50f06ba9fl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testRoundFloat4Float4(in, out);
+            verifyResultsRoundFloat4Float4(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRoundFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testRoundFloat4Float4(in, out);
+            verifyResultsRoundFloat4Float4(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRoundFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRoundFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeRound(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkRoundFloat4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testRound() {
+        checkRoundFloatFloat();
+        checkRoundFloat2Float2();
+        checkRoundFloat3Float3();
+        checkRoundFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestRsqrt.java b/tests/tests/renderscript/src/android/renderscript/cts/TestRsqrt.java
new file mode 100644
index 0000000..bc904e1
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestRsqrt.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestRsqrt extends RSBaseCompute {
+
+    private ScriptC_TestRsqrt script;
+    private ScriptC_TestRsqrtRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestRsqrt(mRS);
+        scriptRelaxed = new ScriptC_TestRsqrtRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float in;
+        public Floaty out;
+    }
+
+    private void checkRsqrtFloatFloat() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x736e0d9786ef9c2bl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testRsqrtFloatFloat(in, out);
+            verifyResultsRsqrtFloatFloat(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRsqrtFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testRsqrtFloatFloat(in, out);
+            verifyResultsRsqrtFloatFloat(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRsqrtFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRsqrtFloatFloat(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 1];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeRsqrt(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkRsqrtFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkRsqrtFloat2Float2() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xb5df4d6949d76dafl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testRsqrtFloat2Float2(in, out);
+            verifyResultsRsqrtFloat2Float2(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRsqrtFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testRsqrtFloat2Float2(in, out);
+            verifyResultsRsqrtFloat2Float2(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRsqrtFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRsqrtFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 2];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeRsqrt(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkRsqrtFloat2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkRsqrtFloat3Float3() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xb5df580aa8de0349l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testRsqrtFloat3Float3(in, out);
+            verifyResultsRsqrtFloat3Float3(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRsqrtFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testRsqrtFloat3Float3(in, out);
+            verifyResultsRsqrtFloat3Float3(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRsqrtFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRsqrtFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeRsqrt(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkRsqrtFloat3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkRsqrtFloat4Float4() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xb5df62ac07e498e3l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testRsqrtFloat4Float4(in, out);
+            verifyResultsRsqrtFloat4Float4(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRsqrtFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testRsqrtFloat4Float4(in, out);
+            verifyResultsRsqrtFloat4Float4(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRsqrtFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRsqrtFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeRsqrt(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkRsqrtFloat4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testRsqrt() {
+        checkRsqrtFloatFloat();
+        checkRsqrtFloat2Float2();
+        checkRsqrtFloat3Float3();
+        checkRsqrtFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestSign.java b/tests/tests/renderscript/src/android/renderscript/cts/TestSign.java
new file mode 100644
index 0000000..c62cb7a
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestSign.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestSign extends RSBaseCompute {
+
+    private ScriptC_TestSign script;
+    private ScriptC_TestSignRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestSign(mRS);
+        scriptRelaxed = new ScriptC_TestSignRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Floaty out;
+    }
+
+    private void checkSignFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xadc8bc2f364ea474l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testSignFloatFloat(inV, out);
+            verifyResultsSignFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSignFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testSignFloatFloat(inV, out);
+            verifyResultsSignFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSignFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSignFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeSign(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkSignFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkSignFloat2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x2eb1e646027c0ab8l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testSignFloat2Float2(inV, out);
+            verifyResultsSignFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSignFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testSignFloat2Float2(inV, out);
+            verifyResultsSignFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSignFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSignFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeSign(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkSignFloat2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkSignFloat3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x2eb3af60f8972b96l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testSignFloat3Float3(inV, out);
+            verifyResultsSignFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSignFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testSignFloat3Float3(inV, out);
+            verifyResultsSignFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSignFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSignFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeSign(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkSignFloat3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkSignFloat4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x2eb5787beeb24c74l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testSignFloat4Float4(inV, out);
+            verifyResultsSignFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSignFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testSignFloat4Float4(inV, out);
+            verifyResultsSignFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSignFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSignFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeSign(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkSignFloat4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testSign() {
+        checkSignFloatFloat();
+        checkSignFloat2Float2();
+        checkSignFloat3Float3();
+        checkSignFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestSin.java b/tests/tests/renderscript/src/android/renderscript/cts/TestSin.java
new file mode 100644
index 0000000..ca6cb72
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestSin.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestSin extends RSBaseCompute {
+
+    private ScriptC_TestSin script;
+    private ScriptC_TestSinRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestSin(mRS);
+        scriptRelaxed = new ScriptC_TestSinRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float in;
+        public Floaty out;
+    }
+
+    private void checkSinFloatFloat() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xd3e99dcfa01359f9l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testSinFloatFloat(in, out);
+            verifyResultsSinFloatFloat(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testSinFloatFloat(in, out);
+            verifyResultsSinFloatFloat(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSinFloatFloat(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 1];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeSin(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkSinFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkSinFloat2Float2() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x9253f296dcfd528dl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testSinFloat2Float2(in, out);
+            verifyResultsSinFloat2Float2(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testSinFloat2Float2(in, out);
+            verifyResultsSinFloat2Float2(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSinFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 2];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeSin(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkSinFloat2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkSinFloat3Float3() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x9253fd383c03e827l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testSinFloat3Float3(in, out);
+            verifyResultsSinFloat3Float3(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testSinFloat3Float3(in, out);
+            verifyResultsSinFloat3Float3(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSinFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeSin(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkSinFloat3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkSinFloat4Float4() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x925407d99b0a7dc1l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testSinFloat4Float4(in, out);
+            verifyResultsSinFloat4Float4(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testSinFloat4Float4(in, out);
+            verifyResultsSinFloat4Float4(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSinFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeSin(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkSinFloat4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testSin() {
+        checkSinFloatFloat();
+        checkSinFloat2Float2();
+        checkSinFloat3Float3();
+        checkSinFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestSincos.java b/tests/tests/renderscript/src/android/renderscript/cts/TestSincos.java
new file mode 100644
index 0000000..3b0d09e
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestSincos.java
@@ -0,0 +1,361 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestSincos extends RSBaseCompute {
+
+    private ScriptC_TestSincos script;
+    private ScriptC_TestSincosRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestSincos(mRS);
+        scriptRelaxed = new ScriptC_TestSincosRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloatFloat {
+        public float inV;
+        public Floaty outCosptr;
+        public Floaty out;
+    }
+
+    private void checkSincosFloatFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xb8748e13e46c48d4l, false);
+        try {
+            Allocation outCosptr = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocOutCosptr(outCosptr);
+            script.forEach_testSincosFloatFloatFloat(inV, out);
+            verifyResultsSincosFloatFloatFloat(inV, outCosptr, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSincosFloatFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation outCosptr = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocOutCosptr(outCosptr);
+            scriptRelaxed.forEach_testSincosFloatFloatFloat(inV, out);
+            verifyResultsSincosFloatFloatFloat(inV, outCosptr, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSincosFloatFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSincosFloatFloatFloat(Allocation inV, Allocation outCosptr, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        inV.copyTo(arrayInV);
+        float[] arrayOutCosptr = new float[INPUTSIZE * 1];
+        outCosptr.copyTo(arrayOutCosptr);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeSincos(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.outCosptr.couldBe(arrayOutCosptr[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output outCosptr: ");
+                    message.append(args.outCosptr.toString());
+                    message.append("\n");
+                    message.append("Actual   output outCosptr: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOutCosptr[i * 1 + j], Float.floatToRawIntBits(arrayOutCosptr[i * 1 + j]), arrayOutCosptr[i * 1 + j]));
+                    if (!args.outCosptr.couldBe(arrayOutCosptr[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkSincosFloatFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkSincosFloat2Float2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xc85bab4e3e2fc77cl, false);
+        try {
+            Allocation outCosptr = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocOutCosptr(outCosptr);
+            script.forEach_testSincosFloat2Float2Float2(inV, out);
+            verifyResultsSincosFloat2Float2Float2(inV, outCosptr, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSincosFloat2Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation outCosptr = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocOutCosptr(outCosptr);
+            scriptRelaxed.forEach_testSincosFloat2Float2Float2(inV, out);
+            verifyResultsSincosFloat2Float2Float2(inV, outCosptr, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSincosFloat2Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSincosFloat2Float2Float2(Allocation inV, Allocation outCosptr, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        float[] arrayOutCosptr = new float[INPUTSIZE * 2];
+        outCosptr.copyTo(arrayOutCosptr);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeSincos(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.outCosptr.couldBe(arrayOutCosptr[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output outCosptr: ");
+                    message.append(args.outCosptr.toString());
+                    message.append("\n");
+                    message.append("Actual   output outCosptr: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOutCosptr[i * 2 + j], Float.floatToRawIntBits(arrayOutCosptr[i * 2 + j]), arrayOutCosptr[i * 2 + j]));
+                    if (!args.outCosptr.couldBe(arrayOutCosptr[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkSincosFloat2Float2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkSincosFloat3Float3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x1cc0896e400dc91dl, false);
+        try {
+            Allocation outCosptr = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocOutCosptr(outCosptr);
+            script.forEach_testSincosFloat3Float3Float3(inV, out);
+            verifyResultsSincosFloat3Float3Float3(inV, outCosptr, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSincosFloat3Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation outCosptr = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocOutCosptr(outCosptr);
+            scriptRelaxed.forEach_testSincosFloat3Float3Float3(inV, out);
+            verifyResultsSincosFloat3Float3Float3(inV, outCosptr, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSincosFloat3Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSincosFloat3Float3Float3(Allocation inV, Allocation outCosptr, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        float[] arrayOutCosptr = new float[INPUTSIZE * 4];
+        outCosptr.copyTo(arrayOutCosptr);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeSincos(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.outCosptr.couldBe(arrayOutCosptr[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output outCosptr: ");
+                    message.append(args.outCosptr.toString());
+                    message.append("\n");
+                    message.append("Actual   output outCosptr: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOutCosptr[i * 4 + j], Float.floatToRawIntBits(arrayOutCosptr[i * 4 + j]), arrayOutCosptr[i * 4 + j]));
+                    if (!args.outCosptr.couldBe(arrayOutCosptr[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkSincosFloat3Float3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkSincosFloat4Float4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x7125678e41ebcabel, false);
+        try {
+            Allocation outCosptr = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocOutCosptr(outCosptr);
+            script.forEach_testSincosFloat4Float4Float4(inV, out);
+            verifyResultsSincosFloat4Float4Float4(inV, outCosptr, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSincosFloat4Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation outCosptr = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocOutCosptr(outCosptr);
+            scriptRelaxed.forEach_testSincosFloat4Float4Float4(inV, out);
+            verifyResultsSincosFloat4Float4Float4(inV, outCosptr, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSincosFloat4Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSincosFloat4Float4Float4(Allocation inV, Allocation outCosptr, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        float[] arrayOutCosptr = new float[INPUTSIZE * 4];
+        outCosptr.copyTo(arrayOutCosptr);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeSincos(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.outCosptr.couldBe(arrayOutCosptr[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output outCosptr: ");
+                    message.append(args.outCosptr.toString());
+                    message.append("\n");
+                    message.append("Actual   output outCosptr: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOutCosptr[i * 4 + j], Float.floatToRawIntBits(arrayOutCosptr[i * 4 + j]), arrayOutCosptr[i * 4 + j]));
+                    if (!args.outCosptr.couldBe(arrayOutCosptr[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkSincosFloat4Float4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testSincos() {
+        checkSincosFloatFloatFloat();
+        checkSincosFloat2Float2Float2();
+        checkSincosFloat3Float3Float3();
+        checkSincosFloat4Float4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestSinh.java b/tests/tests/renderscript/src/android/renderscript/cts/TestSinh.java
new file mode 100644
index 0000000..54fa31e
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestSinh.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestSinh extends RSBaseCompute {
+
+    private ScriptC_TestSinh script;
+    private ScriptC_TestSinhRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestSinh(mRS);
+        scriptRelaxed = new ScriptC_TestSinhRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float in;
+        public Floaty out;
+    }
+
+    private void checkSinhFloatFloat() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x541c2eef0a5d2ff1l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testSinhFloatFloat(in, out);
+            verifyResultsSinhFloatFloat(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinhFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testSinhFloatFloat(in, out);
+            verifyResultsSinhFloatFloat(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinhFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSinhFloatFloat(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 1];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeSinh(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkSinhFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkSinhFloat2Float2() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x7f8e1e7d8c47bec5l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testSinhFloat2Float2(in, out);
+            verifyResultsSinhFloat2Float2(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinhFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testSinhFloat2Float2(in, out);
+            verifyResultsSinhFloat2Float2(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinhFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSinhFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 2];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeSinh(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkSinhFloat2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkSinhFloat3Float3() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x7f8e291eeb4e545fl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testSinhFloat3Float3(in, out);
+            verifyResultsSinhFloat3Float3(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinhFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testSinhFloat3Float3(in, out);
+            verifyResultsSinhFloat3Float3(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinhFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSinhFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeSinh(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkSinhFloat3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkSinhFloat4Float4() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x7f8e33c04a54e9f9l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testSinhFloat4Float4(in, out);
+            verifyResultsSinhFloat4Float4(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinhFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testSinhFloat4Float4(in, out);
+            verifyResultsSinhFloat4Float4(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinhFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSinhFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeSinh(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkSinhFloat4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testSinh() {
+        checkSinhFloatFloat();
+        checkSinhFloat2Float2();
+        checkSinhFloat3Float3();
+        checkSinhFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestSinpi.java b/tests/tests/renderscript/src/android/renderscript/cts/TestSinpi.java
new file mode 100644
index 0000000..dec28d9
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestSinpi.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestSinpi extends RSBaseCompute {
+
+    private ScriptC_TestSinpi script;
+    private ScriptC_TestSinpiRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestSinpi(mRS);
+        scriptRelaxed = new ScriptC_TestSinpiRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float in;
+        public Floaty out;
+    }
+
+    private void checkSinpiFloatFloat() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x34cb59f49416da82l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testSinpiFloatFloat(in, out);
+            verifyResultsSinpiFloatFloat(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinpiFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testSinpiFloatFloat(in, out);
+            verifyResultsSinpiFloatFloat(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinpiFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSinpiFloatFloat(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 1];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeSinpi(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkSinpiFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkSinpiFloat2Float2() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x50bbd97d4a48b00el, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testSinpiFloat2Float2(in, out);
+            verifyResultsSinpiFloat2Float2(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinpiFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testSinpiFloat2Float2(in, out);
+            verifyResultsSinpiFloat2Float2(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinpiFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSinpiFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 2];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeSinpi(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkSinpiFloat2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkSinpiFloat3Float3() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x50bbe41ea94f45a8l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testSinpiFloat3Float3(in, out);
+            verifyResultsSinpiFloat3Float3(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinpiFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testSinpiFloat3Float3(in, out);
+            verifyResultsSinpiFloat3Float3(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinpiFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSinpiFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeSinpi(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkSinpiFloat3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkSinpiFloat4Float4() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x50bbeec00855db42l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testSinpiFloat4Float4(in, out);
+            verifyResultsSinpiFloat4Float4(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinpiFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testSinpiFloat4Float4(in, out);
+            verifyResultsSinpiFloat4Float4(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinpiFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSinpiFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeSinpi(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkSinpiFloat4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testSinpi() {
+        checkSinpiFloatFloat();
+        checkSinpiFloat2Float2();
+        checkSinpiFloat3Float3();
+        checkSinpiFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestSqrt.java b/tests/tests/renderscript/src/android/renderscript/cts/TestSqrt.java
new file mode 100644
index 0000000..f7029c0
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestSqrt.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestSqrt extends RSBaseCompute {
+
+    private ScriptC_TestSqrt script;
+    private ScriptC_TestSqrtRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestSqrt(mRS);
+        scriptRelaxed = new ScriptC_TestSqrtRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float in;
+        public Floaty out;
+    }
+
+    private void checkSqrtFloatFloat() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x940922bedb2c9271l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testSqrtFloatFloat(in, out);
+            verifyResultsSqrtFloatFloat(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSqrtFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testSqrtFloatFloat(in, out);
+            verifyResultsSqrtFloatFloat(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSqrtFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSqrtFloatFloat(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 1];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeSqrt(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkSqrtFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkSqrtFloat2Float2() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x35fb1678b6262d45l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testSqrtFloat2Float2(in, out);
+            verifyResultsSqrtFloat2Float2(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSqrtFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testSqrtFloat2Float2(in, out);
+            verifyResultsSqrtFloat2Float2(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSqrtFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSqrtFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 2];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeSqrt(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkSqrtFloat2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkSqrtFloat3Float3() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x35fb211a152cc2dfl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testSqrtFloat3Float3(in, out);
+            verifyResultsSqrtFloat3Float3(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSqrtFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testSqrtFloat3Float3(in, out);
+            verifyResultsSqrtFloat3Float3(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSqrtFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSqrtFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeSqrt(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkSqrtFloat3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkSqrtFloat4Float4() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x35fb2bbb74335879l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testSqrtFloat4Float4(in, out);
+            verifyResultsSqrtFloat4Float4(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSqrtFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testSqrtFloat4Float4(in, out);
+            verifyResultsSqrtFloat4Float4(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSqrtFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSqrtFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeSqrt(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkSqrtFloat4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testSqrt() {
+        checkSqrtFloatFloat();
+        checkSqrtFloat2Float2();
+        checkSqrtFloat3Float3();
+        checkSqrtFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestStep.java b/tests/tests/renderscript/src/android/renderscript/cts/TestStep.java
new file mode 100644
index 0000000..9f640de
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestStep.java
@@ -0,0 +1,535 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestStep extends RSBaseCompute {
+
+    private ScriptC_TestStep script;
+    private ScriptC_TestStepRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestStep(mRS);
+        scriptRelaxed = new ScriptC_TestStepRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloatFloat {
+        public float inEdge;
+        public float inV;
+        public Floaty out;
+    }
+
+    private void checkStepFloatFloatFloat() {
+        Allocation inEdge = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x598900c49184fbfel, false);
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x9aefccaa832f44e9l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInV(inV);
+            script.forEach_testStepFloatFloatFloat(inEdge, out);
+            verifyResultsStepFloatFloatFloat(inEdge, inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepFloatFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV(inV);
+            scriptRelaxed.forEach_testStepFloatFloatFloat(inEdge, out);
+            verifyResultsStepFloatFloatFloat(inEdge, inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepFloatFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsStepFloatFloatFloat(Allocation inEdge, Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInEdge = new float[INPUTSIZE * 1];
+        inEdge.copyTo(arrayInEdge);
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inEdge = arrayInEdge[i];
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeStep(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inEdge: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inEdge, Float.floatToRawIntBits(args.inEdge), args.inEdge));
+                    message.append("\n");
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkStepFloatFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkStepFloat2Float2Float2() {
+        Allocation inEdge = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x6efefa297df69504l, false);
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x12eb000b8567f58bl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInV(inV);
+            script.forEach_testStepFloat2Float2Float2(inEdge, out);
+            verifyResultsStepFloat2Float2Float2(inEdge, inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepFloat2Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV(inV);
+            scriptRelaxed.forEach_testStepFloat2Float2Float2(inEdge, out);
+            verifyResultsStepFloat2Float2Float2(inEdge, inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepFloat2Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsStepFloat2Float2Float2(Allocation inEdge, Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInEdge = new float[INPUTSIZE * 2];
+        inEdge.copyTo(arrayInEdge);
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inEdge = arrayInEdge[i * 2 + j];
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeStep(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inEdge: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inEdge, Float.floatToRawIntBits(args.inEdge), args.inEdge));
+                    message.append("\n");
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkStepFloat2Float2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkStepFloat3Float3Float3() {
+        Allocation inEdge = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x9e548cd666a7a77l, false);
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x674fde2b8745f72cl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInV(inV);
+            script.forEach_testStepFloat3Float3Float3(inEdge, out);
+            verifyResultsStepFloat3Float3Float3(inEdge, inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepFloat3Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV(inV);
+            scriptRelaxed.forEach_testStepFloat3Float3Float3(inEdge, out);
+            verifyResultsStepFloat3Float3Float3(inEdge, inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepFloat3Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsStepFloat3Float3Float3(Allocation inEdge, Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInEdge = new float[INPUTSIZE * 4];
+        inEdge.copyTo(arrayInEdge);
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inEdge = arrayInEdge[i * 4 + j];
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeStep(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inEdge: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inEdge, Float.floatToRawIntBits(args.inEdge), args.inEdge));
+                    message.append("\n");
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkStepFloat3Float3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkStepFloat4Float4Float4() {
+        Allocation inEdge = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xa4cb97714ede5feal, false);
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xbbb4bc4b8923f8cdl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInV(inV);
+            script.forEach_testStepFloat4Float4Float4(inEdge, out);
+            verifyResultsStepFloat4Float4Float4(inEdge, inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepFloat4Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV(inV);
+            scriptRelaxed.forEach_testStepFloat4Float4Float4(inEdge, out);
+            verifyResultsStepFloat4Float4Float4(inEdge, inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepFloat4Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsStepFloat4Float4Float4(Allocation inEdge, Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInEdge = new float[INPUTSIZE * 4];
+        inEdge.copyTo(arrayInEdge);
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inEdge = arrayInEdge[i * 4 + j];
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeStep(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inEdge: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inEdge, Float.floatToRawIntBits(args.inEdge), args.inEdge));
+                    message.append("\n");
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkStepFloat4Float4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkStepFloat2FloatFloat2() {
+        Allocation inEdge = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xb0ac06c45b3d8b26l, false);
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xfa7d66f2b6d48a21l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInV(inV);
+            script.forEach_testStepFloat2FloatFloat2(inEdge, out);
+            verifyResultsStepFloat2FloatFloat2(inEdge, inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepFloat2FloatFloat2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV(inV);
+            scriptRelaxed.forEach_testStepFloat2FloatFloat2(inEdge, out);
+            verifyResultsStepFloat2FloatFloat2(inEdge, inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepFloat2FloatFloat2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsStepFloat2FloatFloat2(Allocation inEdge, Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInEdge = new float[INPUTSIZE * 2];
+        inEdge.copyTo(arrayInEdge);
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inEdge = arrayInEdge[i * 2 + j];
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeStep(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inEdge: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inEdge, Float.floatToRawIntBits(args.inEdge), args.inEdge));
+                    message.append("\n");
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkStepFloat2FloatFloat2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkStepFloat3FloatFloat3() {
+        Allocation inEdge = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x304ed837c68f43fal, false);
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x4fcd1a0aa53f7e7dl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInV(inV);
+            script.forEach_testStepFloat3FloatFloat3(inEdge, out);
+            verifyResultsStepFloat3FloatFloat3(inEdge, inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepFloat3FloatFloat3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV(inV);
+            scriptRelaxed.forEach_testStepFloat3FloatFloat3(inEdge, out);
+            verifyResultsStepFloat3FloatFloat3(inEdge, inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepFloat3FloatFloat3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsStepFloat3FloatFloat3(Allocation inEdge, Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInEdge = new float[INPUTSIZE * 4];
+        inEdge.copyTo(arrayInEdge);
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inEdge = arrayInEdge[i * 4 + j];
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeStep(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inEdge: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inEdge, Float.floatToRawIntBits(args.inEdge), args.inEdge));
+                    message.append("\n");
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkStepFloat3FloatFloat3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkStepFloat4FloatFloat4() {
+        Allocation inEdge = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xaff1a9ab31e0fccel, false);
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xa51ccd2293aa72d9l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInV(inV);
+            script.forEach_testStepFloat4FloatFloat4(inEdge, out);
+            verifyResultsStepFloat4FloatFloat4(inEdge, inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepFloat4FloatFloat4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV(inV);
+            scriptRelaxed.forEach_testStepFloat4FloatFloat4(inEdge, out);
+            verifyResultsStepFloat4FloatFloat4(inEdge, inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepFloat4FloatFloat4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsStepFloat4FloatFloat4(Allocation inEdge, Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInEdge = new float[INPUTSIZE * 4];
+        inEdge.copyTo(arrayInEdge);
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inEdge = arrayInEdge[i * 4 + j];
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeStep(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input inEdge: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inEdge, Float.floatToRawIntBits(args.inEdge), args.inEdge));
+                    message.append("\n");
+                    message.append("Input inV: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkStepFloat4FloatFloat4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testStep() {
+        checkStepFloatFloatFloat();
+        checkStepFloat2Float2Float2();
+        checkStepFloat3Float3Float3();
+        checkStepFloat4Float4Float4();
+        checkStepFloat2FloatFloat2();
+        checkStepFloat3FloatFloat3();
+        checkStepFloat4FloatFloat4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestTan.java b/tests/tests/renderscript/src/android/renderscript/cts/TestTan.java
new file mode 100644
index 0000000..6a3ae69
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestTan.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestTan extends RSBaseCompute {
+
+    private ScriptC_TestTan script;
+    private ScriptC_TestTanRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestTan(mRS);
+        scriptRelaxed = new ScriptC_TestTanRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float in;
+        public Floaty out;
+    }
+
+    private void checkTanFloatFloat() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xfb95a6a791c2b8eal, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testTanFloatFloat(in, out);
+            verifyResultsTanFloatFloat(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testTanFloatFloat(in, out);
+            verifyResultsTanFloatFloat(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsTanFloatFloat(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 1];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeTan(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkTanFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkTanFloat2Float2() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x1bdfd24778a20d36l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testTanFloat2Float2(in, out);
+            verifyResultsTanFloat2Float2(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testTanFloat2Float2(in, out);
+            verifyResultsTanFloat2Float2(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsTanFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 2];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeTan(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkTanFloat2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkTanFloat3Float3() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x1bdfdce8d7a8a2d0l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testTanFloat3Float3(in, out);
+            verifyResultsTanFloat3Float3(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testTanFloat3Float3(in, out);
+            verifyResultsTanFloat3Float3(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsTanFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeTan(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkTanFloat3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkTanFloat4Float4() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x1bdfe78a36af386al, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testTanFloat4Float4(in, out);
+            verifyResultsTanFloat4Float4(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testTanFloat4Float4(in, out);
+            verifyResultsTanFloat4Float4(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsTanFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeTan(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkTanFloat4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testTan() {
+        checkTanFloatFloat();
+        checkTanFloat2Float2();
+        checkTanFloat3Float3();
+        checkTanFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestTanh.java b/tests/tests/renderscript/src/android/renderscript/cts/TestTanh.java
new file mode 100644
index 0000000..525b654
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestTanh.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestTanh extends RSBaseCompute {
+
+    private ScriptC_TestTanh script;
+    private ScriptC_TestTanhRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestTanh(mRS);
+        scriptRelaxed = new ScriptC_TestTanhRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float in;
+        public Floaty out;
+    }
+
+    private void checkTanhFloatFloat() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xfe01ab34a2d2226cl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testTanhFloatFloat(in, out);
+            verifyResultsTanhFloatFloat(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanhFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testTanhFloatFloat(in, out);
+            verifyResultsTanhFloatFloat(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanhFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsTanhFloatFloat(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 1];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeTanh(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkTanhFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkTanhFloat2Float2() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x9a0cb127b0f31928l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testTanhFloat2Float2(in, out);
+            verifyResultsTanhFloat2Float2(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanhFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testTanhFloat2Float2(in, out);
+            verifyResultsTanhFloat2Float2(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanhFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsTanhFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 2];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeTanh(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkTanhFloat2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkTanhFloat3Float3() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x9a0cbbc90ff9aec2l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testTanhFloat3Float3(in, out);
+            verifyResultsTanhFloat3Float3(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanhFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testTanhFloat3Float3(in, out);
+            verifyResultsTanhFloat3Float3(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanhFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsTanhFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeTanh(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkTanhFloat3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkTanhFloat4Float4() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x9a0cc66a6f00445cl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testTanhFloat4Float4(in, out);
+            verifyResultsTanhFloat4Float4(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanhFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testTanhFloat4Float4(in, out);
+            verifyResultsTanhFloat4Float4(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanhFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsTanhFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeTanh(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkTanhFloat4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testTanh() {
+        checkTanhFloatFloat();
+        checkTanhFloat2Float2();
+        checkTanhFloat3Float3();
+        checkTanhFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestTanpi.java b/tests/tests/renderscript/src/android/renderscript/cts/TestTanpi.java
new file mode 100644
index 0000000..b4d474d
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestTanpi.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestTanpi extends RSBaseCompute {
+
+    private ScriptC_TestTanpi script;
+    private ScriptC_TestTanpiRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestTanpi(mRS);
+        scriptRelaxed = new ScriptC_TestTanpiRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float in;
+        public Floaty out;
+    }
+
+    private void checkTanpiFloatFloat() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xbe5739a52fbb952bl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testTanpiFloatFloat(in, out);
+            verifyResultsTanpiFloatFloat(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanpiFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testTanpiFloatFloat(in, out);
+            verifyResultsTanpiFloatFloat(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanpiFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsTanpiFloatFloat(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 1];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeTanpi(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkTanpiFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkTanpiFloat2Float2() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xc3fe7c117310deafl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testTanpiFloat2Float2(in, out);
+            verifyResultsTanpiFloat2Float2(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanpiFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testTanpiFloat2Float2(in, out);
+            verifyResultsTanpiFloat2Float2(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanpiFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsTanpiFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 2];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeTanpi(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkTanpiFloat2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkTanpiFloat3Float3() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xc3fe86b2d2177449l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testTanpiFloat3Float3(in, out);
+            verifyResultsTanpiFloat3Float3(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanpiFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testTanpiFloat3Float3(in, out);
+            verifyResultsTanpiFloat3Float3(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanpiFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsTanpiFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeTanpi(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkTanpiFloat3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkTanpiFloat4Float4() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xc3fe9154311e09e3l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testTanpiFloat4Float4(in, out);
+            verifyResultsTanpiFloat4Float4(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanpiFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testTanpiFloat4Float4(in, out);
+            verifyResultsTanpiFloat4Float4(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanpiFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsTanpiFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeTanpi(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkTanpiFloat4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testTanpi() {
+        checkTanpiFloatFloat();
+        checkTanpiFloat2Float2();
+        checkTanpiFloat3Float3();
+        checkTanpiFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestTgamma.java b/tests/tests/renderscript/src/android/renderscript/cts/TestTgamma.java
new file mode 100644
index 0000000..db3b5c6
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestTgamma.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestTgamma extends RSBaseCompute {
+
+    private ScriptC_TestTgamma script;
+    private ScriptC_TestTgammaRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestTgamma(mRS);
+        scriptRelaxed = new ScriptC_TestTgammaRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float in;
+        public Floaty out;
+    }
+
+    private void checkTgammaFloatFloat() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xe45f5203be15b490l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testTgammaFloatFloat(in, out);
+            verifyResultsTgammaFloatFloat(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTgammaFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testTgammaFloatFloat(in, out);
+            verifyResultsTgammaFloatFloat(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTgammaFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsTgammaFloatFloat(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 1];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeTgamma(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkTgammaFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkTgammaFloat2Float2() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x74767f039bfd9f2cl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testTgammaFloat2Float2(in, out);
+            verifyResultsTgammaFloat2Float2(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTgammaFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testTgammaFloat2Float2(in, out);
+            verifyResultsTgammaFloat2Float2(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTgammaFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsTgammaFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 2];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeTgamma(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkTgammaFloat2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkTgammaFloat3Float3() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x747689a4fb0434c6l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testTgammaFloat3Float3(in, out);
+            verifyResultsTgammaFloat3Float3(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTgammaFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testTgammaFloat3Float3(in, out);
+            verifyResultsTgammaFloat3Float3(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTgammaFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsTgammaFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeTgamma(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkTgammaFloat3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkTgammaFloat4Float4() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x747694465a0aca60l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testTgammaFloat4Float4(in, out);
+            verifyResultsTgammaFloat4Float4(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTgammaFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testTgammaFloat4Float4(in, out);
+            verifyResultsTgammaFloat4Float4(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTgammaFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsTgammaFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeTgamma(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkTgammaFloat4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testTgamma() {
+        checkTgammaFloatFloat();
+        checkTgammaFloat2Float2();
+        checkTgammaFloat3Float3();
+        checkTgammaFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestTrunc.java b/tests/tests/renderscript/src/android/renderscript/cts/TestTrunc.java
new file mode 100644
index 0000000..8ab10e6
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestTrunc.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Element;
+
+public class TestTrunc extends RSBaseCompute {
+
+    private ScriptC_TestTrunc script;
+    private ScriptC_TestTruncRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestTrunc(mRS);
+        scriptRelaxed = new ScriptC_TestTruncRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float in;
+        public Floaty out;
+    }
+
+    private void checkTruncFloatFloat() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x6361d71a4dcff881l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testTruncFloatFloat(in, out);
+            verifyResultsTruncFloatFloat(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTruncFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testTruncFloatFloat(in, out);
+            verifyResultsTruncFloatFloat(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTruncFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsTruncFloatFloat(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 1];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeTrunc(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkTruncFloatFloat" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkTruncFloat2Float2() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xcda9bef7b45256d5l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testTruncFloat2Float2(in, out);
+            verifyResultsTruncFloat2Float2(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTruncFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testTruncFloat2Float2(in, out);
+            verifyResultsTruncFloat2Float2(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTruncFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsTruncFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 2];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeTrunc(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkTruncFloat2Float2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkTruncFloat3Float3() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xcda9c9991358ec6fl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testTruncFloat3Float3(in, out);
+            verifyResultsTruncFloat3Float3(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTruncFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testTruncFloat3Float3(in, out);
+            verifyResultsTruncFloat3Float3(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTruncFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsTruncFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeTrunc(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkTruncFloat3Float3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkTruncFloat4Float4() {
+        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xcda9d43a725f8209l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testTruncFloat4Float4(in, out);
+            verifyResultsTruncFloat4Float4(in, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTruncFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testTruncFloat4Float4(in, out);
+            verifyResultsTruncFloat4Float4(in, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTruncFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsTruncFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
+        float[] arrayIn = new float[INPUTSIZE * 4];
+        in.copyTo(arrayIn);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.in = arrayIn[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Floaty.setRelaxed(relaxed);
+                CoreMathVerifier.computeTrunc(args);
+                // Figure out what the outputs should have been.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    StringBuilder message = new StringBuilder();
+                    message.append("Input in: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            args.in, Float.floatToRawIntBits(args.in), args.in));
+                    message.append("\n");
+                    message.append("Expected output out: ");
+                    message.append(args.out.toString());
+                    message.append("\n");
+                    message.append("Actual   output out: ");
+                    message.append(String.format("%14.8g %8x %15a",
+                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
+                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                        message.append(" FAIL");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkTruncFloat4Float4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public void testTrunc() {
+        checkTruncFloatFloat();
+        checkTruncFloat2Float2();
+        checkTruncFloat3Float3();
+        checkTruncFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TruncTest.java b/tests/tests/renderscript/src/android/renderscript/cts/TruncTest.java
deleted file mode 100644
index f2a3e11..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TruncTest.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * 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 android.renderscript.cts;
-
-import com.android.cts.stub.R;
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-
-public class TruncTest extends RSBaseCompute {
-    private ScriptC_trunc_f32 script_f32;
-    private ScriptC_trunc_f32_relaxed script_f32_relaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script_f32 = new ScriptC_trunc_f32(mRS);
-        script_f32_relaxed = new ScriptC_trunc_f32_relaxed(mRS);
-    }
-
-    @Override
-    public void forEach(int testId, Allocation mIn, Allocation mOut) throws RSRuntimeException {
-        switch (testId) {
-        case TEST_F32:
-            script_f32.forEach_trunc_f32_1(mIn, mOut);
-            break;
-        case TEST_F32_2:
-            script_f32.forEach_trunc_f32_2(mIn, mOut);
-            break;
-        case TEST_F32_3:
-            script_f32.forEach_trunc_f32_3(mIn, mOut);
-            break;
-        case TEST_F32_4:
-            script_f32.forEach_trunc_f32_4(mIn, mOut);
-            break;
-
-        case TEST_RELAXED_F32:
-            script_f32_relaxed.forEach_trunc_f32_1(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_2:
-            script_f32_relaxed.forEach_trunc_f32_2(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_3:
-            script_f32_relaxed.forEach_trunc_f32_3(mIn, mOut);
-            break;
-        case TEST_RELAXED_F32_4:
-            script_f32_relaxed.forEach_trunc_f32_4(mIn, mOut);
-            break;
-        }
-    }
-
-    @Override
-    protected float[] getRefArray(float[] inArray, int input_size, int stride, int skip) {
-        float[] ref = new float[input_size * stride];
-        for (int i = 0; i < input_size; i++) {
-            for (int j = 0; j < stride - skip; j++) {
-                int idxSrc = i * stride + j;
-                int idxDst = i * (stride - skip) + j;
-                int sign = ((Float.floatToIntBits(inArray[idxSrc]) >> 31) & 0x01);
-                float trunc = (int)inArray[idxSrc];
-                if (sign == 1 && trunc == +0.0f) {
-                    trunc = -0.0f;
-                }
-                ref[idxDst] = trunc;
-            }
-        }
-        return ref;
-    }
-
-    /**
-     * trunc test for float
-     */
-    public void testTruncF32() {
-        doF32(0x12345678, 0);
-    }
-
-    public void testTruncF32_relaxed() {
-        doF32_relaxed(0x12345678, 0);
-    }
-
-    /**
-     * trunc test for float2
-     */
-    public void testTruncF32_2() {
-        doF32_2(0x12345a78, 0);
-    }
-
-    public void testTruncF32_2_relaxed() {
-        doF32_2_relaxed(0x12345a78, 0);
-    }
-
-    /**
-     * trunc test for float3
-     */
-    public void testTruncF32_3() {
-        doF32_3(0x12f45678, 0);
-    }
-
-    public void testTruncF32_3_relaxed() {
-        doF32_3_relaxed(0x12f45678, 0);
-    }
-
-    /**
-     * trunc test for float4
-     */
-    public void testTruncF32_4() {
-        doF32_4(0x123c5678, 0);
-    }
-
-    public void testTruncF32_4_relaxed() {
-        doF32_4_relaxed(0x123c5678, 0);
-    }
-
-}
diff --git a/tests/tests/rscpp/librscpptest/rs_jni.cpp b/tests/tests/rscpp/librscpptest/rs_jni.cpp
index 92ebd56..d582e05 100644
--- a/tests/tests/rscpp/librscpptest/rs_jni.cpp
+++ b/tests/tests/rscpp/librscpptest/rs_jni.cpp
@@ -29,6 +29,28 @@
 
 using namespace android::RSC;
 
+/*returns an addr aligned to the byte boundary specified by align*/
+#define align_addr(addr,align) (void *)(((size_t)(addr) + ((align) - 1)) & (size_t) - (align))
+#define ADDRESS_STORAGE_SIZE sizeof(size_t)
+
+void * aligned_alloc(size_t align, size_t size) {
+    void * addr, * x = NULL;
+    addr = malloc(size + align - 1 + ADDRESS_STORAGE_SIZE);
+    if (addr) {
+        x = align_addr((unsigned char *) addr + ADDRESS_STORAGE_SIZE, (int) align);
+        /* save the actual malloc address */
+        ((size_t *) x)[-1] = (size_t) addr;
+    }
+    return x;
+}
+
+void aligned_free(void * memblk) {
+    if (memblk) {
+        void * addr = (void *) (((size_t *) memblk)[-1]);
+        free(addr);
+    }
+}
+
 extern "C" JNIEXPORT jboolean JNICALL Java_android_cts_rscpp_RSInitTest_initTest(JNIEnv * env,
                                                                                  jclass obj,
                                                                                  jstring pathObj)
@@ -349,3 +371,79 @@
 
 }
 
+extern "C" JNIEXPORT jboolean JNICALL
+Java_android_cts_rscpp_RSLoopFilterTest_loopfilterTest(JNIEnv * env, jclass obj, jstring pathObj,
+                                                       jint start, jint stop, jint num_planes,
+                                                       jint mi_rows, jint mi_cols,
+                                                       jint y_offset, jint u_offset, jint v_offset,
+                                                       jint y_stride, jint uv_stride,
+                                                       jbyteArray lf_infoArray,
+                                                       jbyteArray lfmsArray,
+                                                       jbyteArray frameArray)
+{
+    const int mi_block_size = 8;
+
+    const char * path = env->GetStringUTFChars(pathObj, NULL);
+    sp<RS> rs = new RS();
+    rs->init(path);
+
+    jbyte * plf_info = (jbyte *) env->GetPrimitiveArrayCritical(lf_infoArray, 0);
+    jbyte * plfms = (jbyte *) env->GetPrimitiveArrayCritical(lfmsArray, 0);
+    jbyte * pframe = (jbyte *) env->GetPrimitiveArrayCritical(frameArray, 0);
+
+    ScriptIntrinsicVP9LoopFilter::BufferInfo buf_info = {y_offset, u_offset, v_offset,
+                                                         y_stride, uv_stride};
+    ScriptIntrinsicVP9LoopFilter::LoopFilterInfoN * lf_info =
+            (ScriptIntrinsicVP9LoopFilter::LoopFilterInfoN *) plf_info;
+    ScriptIntrinsicVP9LoopFilter::LoopFilterMask * lfms =
+            (ScriptIntrinsicVP9LoopFilter::LoopFilterMask *) plfms;
+
+    ScriptIntrinsicVP9LoopFilter::LoopFilterInfoN lf_info_obj;
+    memcpy(&lf_info_obj, lf_info, sizeof(lf_info_obj));
+
+    size_t frame_size = env->GetArrayLength(frameArray);
+    uint8_t * frame_buffer_ptr = (uint8_t *) aligned_alloc(128, frame_size);
+    memcpy(frame_buffer_ptr, pframe, frame_size);
+
+    sp<const Element> e = Element::U8(rs);
+
+    int size_lfm = sizeof(ScriptIntrinsicVP9LoopFilter::LoopFilterInfoN);
+    sp<const Type> t_lf_info = Type::create(rs, e, size_lfm, 0, 0);
+    int size_lfms = (stop + mi_block_size - start) / mi_block_size *
+                    (mi_cols + mi_block_size) / mi_block_size *
+                    sizeof(ScriptIntrinsicVP9LoopFilter::LoopFilterMask);
+    sp<const Type> t_mask = Type::create(rs, e, size_lfms, 0, 0);
+
+    sp<Allocation> lf_info_buffer = Allocation::createTyped(
+            rs, t_lf_info, RS_ALLOCATION_MIPMAP_NONE,
+            RS_ALLOCATION_USAGE_SHARED | RS_ALLOCATION_USAGE_SCRIPT,
+            &lf_info_obj);
+    sp<Allocation> mask_buffer = Allocation::createTyped(
+            rs, t_mask, RS_ALLOCATION_MIPMAP_NONE,
+            RS_ALLOCATION_USAGE_SHARED | RS_ALLOCATION_USAGE_SCRIPT,
+            lfms);
+
+    sp<const Type> frameType = Type::create(rs, e, frame_size, 0, 0);
+    sp<Allocation> frame_buffers = Allocation::createTyped(
+            rs, frameType, RS_ALLOCATION_MIPMAP_NONE,
+            RS_ALLOCATION_USAGE_SHARED | RS_ALLOCATION_USAGE_SCRIPT,
+            frame_buffer_ptr);
+
+    sp<ScriptIntrinsicVP9LoopFilter> loopFilter = ScriptIntrinsicVP9LoopFilter::create(rs, e);
+
+    loopFilter->setLoopFilterDomain(start, stop, num_planes, mi_rows, mi_cols);
+    loopFilter->setBufferInfo(&buf_info);
+    loopFilter->setLoopFilterInfo(lf_info_buffer);
+    loopFilter->setLoopFilterMasks(mask_buffer);
+    loopFilter->forEach(frame_buffers);
+    rs->finish();
+
+    memcpy(pframe, frame_buffer_ptr, frame_size);
+    aligned_free(frame_buffer_ptr);
+    env->ReleasePrimitiveArrayCritical(frameArray, pframe, 0);
+    env->ReleasePrimitiveArrayCritical(lfmsArray, plfms, 0);
+    env->ReleasePrimitiveArrayCritical(lf_infoArray, plf_info, 0);
+    env->ReleaseStringUTFChars(pathObj, path);
+    return (rs->getError() == RS_SUCCESS);
+}
+
diff --git a/tests/tests/rscpp/src/android/cts/rscpp/RSBlendTest.java b/tests/tests/rscpp/src/android/cts/rscpp/RSBlendTest.java
index 0830f78..7c0ba38 100644
--- a/tests/tests/rscpp/src/android/cts/rscpp/RSBlendTest.java
+++ b/tests/tests/rscpp/src/android/cts/rscpp/RSBlendTest.java
@@ -117,7 +117,8 @@
                 assertTrue(byteAlloc[i] == byteAlloc2[i]);
             }
 
+            mRS.destroy();
         }
 
     }
-}
\ No newline at end of file
+}
diff --git a/tests/tests/rscpp/src/android/cts/rscpp/RSLoopFilterTest.java b/tests/tests/rscpp/src/android/cts/rscpp/RSLoopFilterTest.java
new file mode 100644
index 0000000..cf72e94
--- /dev/null
+++ b/tests/tests/rscpp/src/android/cts/rscpp/RSLoopFilterTest.java
@@ -0,0 +1,1200 @@
+/*
+ * Copyright (C) 2014 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 android.cts.rscpp;
+
+import com.android.cts.stub.R;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.test.AndroidTestCase;
+import android.renderscript.*;
+import android.util.Log;
+import java.io.InputStream;
+import java.util.Random;
+
+public class RSLoopFilterTest extends RSCppTest {
+
+    static {
+        System.loadLibrary("rscpptest_jni");
+    }
+
+    native boolean loopfilterTest(String cacheDir,
+            int start, int stop, int num_planes, int mi_rows, int mi_cols,
+            int y_offset, int u_offset, int v_offset, int y_stride, int uv_stride,
+            byte[] lf_infoArray, byte[] lfmsArray, byte[] frameArray);
+
+    private static final int MI_SIZE_LOG2 = 3;
+    private static final int MI_BLOCK_SIZE_LOG2 = 6 - MI_SIZE_LOG2;
+
+    private static final int MI_SIZE = (1 << MI_SIZE_LOG2);
+    private static final int MI_BLOCK_SIZE = (1 << MI_BLOCK_SIZE_LOG2);
+
+    private static final int MI_MASK = MI_BLOCK_SIZE - 1;
+
+    private static final int SIMD_WIDTH = 16;
+    private static final int MAX_LOOP_FILTER = 63;
+    private static final int MAX_SEGMENTS = 8;
+    private static final int MAX_REF_FRAMES = 4;
+    private static final int MAX_MODE_LF_DELTAS = 2;
+    private static final int MB_MODE_COUNT = 14;
+    private static final int BLOCK_SIZES = 13;
+
+    private static final int MAX_CPU_CORES = 32;
+    private static final int MAX_MB_PLANE = 3;
+    private static final int MAX_SB_COL = 32;
+
+    class LoopFilterMask {
+        long[] left_y;
+        long[] above_y;
+        long int_4x4_y;
+        short[] left_uv;
+        short[] above_uv;
+        short int_4x4_uv;
+        byte[] lfl_y;
+        byte[] lfl_uv;
+
+        LoopFilterMask() {
+            left_y = new long[4];
+            above_y = new long[4];
+            int_4x4_y = 0;
+            left_uv = new short[4];
+            above_uv = new short[4];
+            int_4x4_uv = 0;
+            lfl_y = new byte[64];
+            lfl_uv = new byte[16];
+        }
+    }
+
+    class LoopFilterThresh {
+        byte[] mblim;
+        byte[] lim;
+        byte[] hev_thr;
+
+        LoopFilterThresh() {
+            mblim = new byte[SIMD_WIDTH];
+            lim = new byte[SIMD_WIDTH];
+            hev_thr = new byte[SIMD_WIDTH];
+        }
+    }
+
+    class LoopFilterInfoN {
+        LoopFilterThresh[] lfthr;
+        byte[][][] lvl;
+        byte[] mode_lf_lut;
+
+        LoopFilterInfoN() {
+            lfthr = new LoopFilterThresh[MAX_LOOP_FILTER + 1];
+            for (int i = 0; i < MAX_LOOP_FILTER + 1; ++i) {
+                lfthr[i] = new LoopFilterThresh();
+            }
+            lvl = new byte[MAX_SEGMENTS][MAX_REF_FRAMES][MAX_MODE_LF_DELTAS];
+            mode_lf_lut = new byte[MB_MODE_COUNT];
+        }
+    }
+
+    class BufferInfo {
+        int y_offset;
+        int u_offset;
+        int v_offset;
+        int y_stride;
+        int uv_stride;
+
+        BufferInfo() {
+            y_offset = 0;
+            u_offset = 0;
+            v_offset = 0;
+            y_stride = 0;
+            uv_stride = 0;
+        }
+    }
+
+    private static final int sizeofShort = 2;
+    private static final int sizeofInt = 4;
+    private static final int sizeofUInt64 = 8;
+    private byte[] dataArray;
+
+    private int start = 0;
+    private int stop = 0;
+    private int num_planes = 0;
+    private int mi_rows = 0;
+    private int mi_cols = 0;
+
+    private int y_offset = 0;
+    private int u_offset = 0;
+    private int v_offset = 0;
+    private int y_stride = 0;
+    private int uv_stride = 0;
+
+    private int size_lf_info = 0;
+    private int size_lfm = 0;
+    private int size_lfms = 0;
+    private int frame_buffer_size = 0;
+
+    public BufferInfo buf_info;
+    public LoopFilterInfoN lf_info;
+    public LoopFilterMask[] lfms;
+
+    private byte[] buffer_alloc;
+    private byte[] frameArray;
+
+    private long getLongData(byte[] inArray, int index, int elementsize) {
+        long result = 0;
+        for (int i = 0; i < elementsize; i++) {
+            result += (0xffL & inArray[index + i]) << (8 * i);
+        }
+        return result;
+    }
+
+    private int getIntData(byte[] inArray, int index, int elementsize) {
+        int result = 0;
+        for (int i = 0; i < elementsize; i++) {
+            result += (0xff & inArray[index + i]) << (8 * i);
+        }
+        return result;
+    }
+
+    private short getShortData(byte[] inArray, int index, int elementsize) {
+        short result = 0;
+        for (int i = 0; i < elementsize; i++) {
+            result += (0xff & inArray[index + i]) << (8 * i);
+        }
+        return (short) result;
+    }
+
+    private void initDataArray() {
+        Random rand = new Random();
+        for (int i = 0; i < buffer_alloc.length; i++) {
+            buffer_alloc[i] = (byte)(rand.nextInt(30));
+            frameArray[i] = buffer_alloc[i];
+        }
+    }
+
+    public void testRSLoopFilter() {
+
+        try {
+            InputStream in = getContext().getResources().openRawResource(R.raw.rs_loopfilter_param);
+            int length = in.available();
+            dataArray = new byte[length];
+            in.read(dataArray);
+            in.close();
+        } catch(Exception e) {
+            e.printStackTrace();
+        }
+
+        int getNum = 0;
+        start = getIntData(dataArray, getNum, sizeofInt);
+        getNum += sizeofInt;
+        stop = getIntData(dataArray, getNum, sizeofInt);
+        getNum += sizeofInt;
+        num_planes = getIntData(dataArray, getNum, sizeofInt);
+        getNum += sizeofInt;
+        mi_rows = getIntData(dataArray, getNum, sizeofInt);
+        getNum += sizeofInt;
+        mi_cols = getIntData(dataArray, getNum, sizeofInt);
+        getNum += sizeofInt;
+
+        y_offset = getIntData(dataArray, getNum, sizeofInt);
+        getNum += sizeofInt;
+        u_offset = getIntData(dataArray, getNum, sizeofInt);
+        getNum += sizeofInt;
+        v_offset = getIntData(dataArray, getNum, sizeofInt);
+        getNum += sizeofInt;
+        y_stride = getIntData(dataArray, getNum, sizeofInt);
+        getNum += sizeofInt;
+        uv_stride = getIntData(dataArray, getNum, sizeofInt);
+        getNum += sizeofInt;
+
+        size_lf_info = getIntData(dataArray, getNum, sizeofInt);
+        getNum += sizeofInt;
+        size_lfm = getIntData(dataArray, getNum, sizeofInt);
+        getNum += sizeofInt;
+        size_lfms = getIntData(dataArray, getNum, sizeofInt);
+        getNum += sizeofInt;
+        frame_buffer_size = getIntData(dataArray, getNum, sizeofInt);
+        getNum += sizeofInt;
+
+        lf_info = new LoopFilterInfoN();
+        for (int i = 0; i < lf_info.lfthr.length; i++) {
+            for (int j = 0; j < lf_info.lfthr[i].mblim.length; j++) {
+                lf_info.lfthr[i].mblim[j] = dataArray[getNum];
+                getNum++;
+            }
+            for (int j = 0; j < lf_info.lfthr[i].lim.length; j++) {
+                lf_info.lfthr[i].lim[j] = dataArray[getNum];
+                getNum++;
+            }
+            for (int j = 0; j < lf_info.lfthr[i].hev_thr.length; j++) {
+                lf_info.lfthr[i].hev_thr[j] = dataArray[getNum];
+                getNum++;
+            }
+        }
+        for (int i = 0; i < lf_info.lvl.length; i++) {
+            for (int j = 0; j < lf_info.lvl[i].length; j++) {
+                for (int k = 0; k < lf_info.lvl[i][j].length; k++) {
+                    lf_info.lvl[i][j][k] = dataArray[getNum];
+                    getNum++;
+                }
+            }
+        }
+        for (int i = 0; i < lf_info.mode_lf_lut.length; i++) {
+            lf_info.mode_lf_lut[i] = dataArray[getNum];
+            getNum++;
+        }
+        getNum += size_lf_info - 3150;
+
+        lfms = new LoopFilterMask[size_lfms / size_lfm];
+        for (int i = 0; i < size_lfms / size_lfm; i++) {
+            lfms[i] = new LoopFilterMask();
+            for (int j = 0; j < lfms[i].left_y.length; j++) {
+                lfms[i].left_y[j] = getLongData(dataArray, getNum, sizeofUInt64);
+                getNum += sizeofUInt64;
+            }
+            for (int j = 0; j < lfms[i].above_y.length; j++) {
+                lfms[i].above_y[j] = getLongData(dataArray, getNum, sizeofUInt64);
+                getNum += sizeofUInt64;
+            }
+            lfms[i].int_4x4_y = getLongData(dataArray, getNum, sizeofUInt64);
+            getNum += sizeofUInt64;
+            for (int j = 0; j < lfms[i].left_uv.length; j++) {
+                lfms[i].left_uv[j] = getShortData(dataArray, getNum, sizeofShort);
+                getNum += sizeofShort;
+            }
+            for (int j = 0; j < lfms[i].above_uv.length; j++) {
+                lfms[i].above_uv[j] = getShortData(dataArray, getNum, sizeofShort);
+                getNum += sizeofShort;
+            }
+            lfms[i].int_4x4_uv = getShortData(dataArray, getNum, sizeofShort);
+            getNum += sizeofShort;
+            for (int j = 0; j < lfms[i].lfl_y.length; j++) {
+                lfms[i].lfl_y[j] = dataArray[getNum];
+                getNum ++;
+            }
+            for (int j = 0; j < lfms[i].lfl_uv.length; j++) {
+                lfms[i].lfl_uv[j] = dataArray[getNum];
+                getNum ++;
+            }
+            getNum += size_lfm - 170;
+        }
+
+        buf_info = new BufferInfo();
+        buf_info.y_offset = y_offset;
+        buf_info.u_offset = u_offset;
+        buf_info.v_offset = v_offset;
+        buf_info.y_stride = y_stride;
+        buf_info.uv_stride = uv_stride;
+
+        getNum = 14 * sizeofInt;
+        byte[] lf_infoArray = new byte[size_lf_info];
+        for (int i = 0; i < lf_infoArray.length; i++) {
+            lf_infoArray[i] = dataArray[getNum + i];
+        }
+        getNum += size_lf_info;
+        byte[] lfmsArray = new byte[size_lfms];
+        for (int i = 0; i < lfmsArray.length; i++) {
+            lfmsArray[i] = dataArray[getNum + i];
+        }
+
+        buffer_alloc = new byte[frame_buffer_size];
+        frameArray = new byte[frame_buffer_size];
+        initDataArray();
+
+        loopfilterTest(this.getContext().getCacheDir().toString(),
+                start, stop, num_planes, mi_rows, mi_cols,
+                y_offset, u_offset, v_offset, y_stride, uv_stride,
+                lf_infoArray, lfmsArray, frameArray);
+
+        vp9_loop_filter_rows_work_proc(start, stop, num_planes, mi_rows, mi_cols,
+                buf_info, buffer_alloc, lf_info, lfms);
+
+        for (int i = 0; i < frame_buffer_size; ++i) {
+            assertTrue(frameArray[i] == buffer_alloc[i]);
+        }
+
+    }
+
+    private static int round_power_of_two(int value, int n) {
+
+        int res = ((value) + (1 << ((n) - 1)) >>> (n));
+        return res;
+    }
+
+    private static int round_power_of_two_signed(int value, int n) {
+
+        int res = (((value) + (1 << ((n) - 1))) >> (n));
+        return res;
+    }
+
+    private static int clamp(int data, int low, int high) {
+
+        int res = (data < low ? low : (data > high ? high : data));
+        return res;
+    }
+
+    private static byte signed_char_clamp(int t) {
+
+        return (byte)clamp(t, -128, 127);
+    }
+
+    private static byte filter_mask(byte limit, byte blimit,
+                                    byte p3, byte p2,
+                                    byte p1, byte p0,
+                                    byte q0, byte q1,
+                                    byte q2, byte q3) {
+
+        byte mask = 0;
+        mask |= (Math.abs((p3 & 0xff) - (p2 & 0xff)) > (limit & 0xff)) ? -1 : 0;
+        mask |= (Math.abs((p2 & 0xff) - (p1 & 0xff)) > (limit & 0xff)) ? -1 : 0;
+        mask |= (Math.abs((p1 & 0xff) - (p0 & 0xff)) > (limit & 0xff)) ? -1 : 0;
+        mask |= (Math.abs((q1 & 0xff) - (q0 & 0xff)) > (limit & 0xff)) ? -1 : 0;
+        mask |= (Math.abs((q2 & 0xff) - (q1 & 0xff)) > (limit & 0xff)) ? -1 : 0;
+        mask |= (Math.abs((q3 & 0xff) - (q2 & 0xff)) > (limit & 0xff)) ? -1 : 0;
+        mask |= (Math.abs((p0 & 0xff) - (q0 & 0xff)) * 2 + Math.abs((p1 & 0xff) - (q1 & 0xff)) / 2
+                > (blimit & 0xff)) ? -1 : 0;
+        return (byte)(~mask);
+    }
+
+    private static byte flat_mask4(byte thresh,
+                                   byte p3, byte p2,
+                                   byte p1, byte p0,
+                                   byte q0, byte q1,
+                                   byte q2, byte q3) {
+
+        byte mask = 0;
+        mask |= (Math.abs((p1 & 0xff) - (p0 & 0xff)) > (thresh & 0xff)) ? -1 : 0;
+        mask |= (Math.abs((q1 & 0xff) - (q0 & 0xff)) > (thresh & 0xff)) ? -1 : 0;
+        mask |= (Math.abs((p2 & 0xff) - (p0 & 0xff)) > (thresh & 0xff)) ? -1 : 0;
+        mask |= (Math.abs((q2 & 0xff) - (q0 & 0xff)) > (thresh & 0xff)) ? -1 : 0;
+        mask |= (Math.abs((p3 & 0xff) - (p0 & 0xff)) > (thresh & 0xff)) ? -1 : 0;
+        mask |= (Math.abs((q3 & 0xff) - (q0 & 0xff)) > (thresh & 0xff)) ? -1 : 0;
+        return (byte)(~mask);
+    }
+
+    private static byte flat_mask5(byte thresh,
+                                   byte p4, byte p3,
+                                   byte p2, byte p1,
+                                   byte p0, byte q0,
+                                   byte q1, byte q2,
+                                   byte q3, byte q4) {
+
+        byte mask = (byte)(~flat_mask4(thresh, p3, p2, p1, p0, q0, q1, q2, q3));
+        mask |= (Math.abs((p4 & 0xff) - (p0 & 0xff)) > (thresh & 0xff)) ? -1 : 0;
+        mask |= (Math.abs((q4 & 0xff) - (q0 & 0xff)) > (thresh & 0xff)) ? -1 : 0;
+        return (byte)(~mask);
+    }
+
+    // There is high edge variance internal edge: 11111111 yes, 00000000 no
+    private static byte hev_mask(byte thresh,
+                                 byte p1, byte p0,
+                                 byte q0, byte q1) {
+
+        byte hev = 0;
+        hev |= (Math.abs((p1 & 0xff) - (p0 & 0xff)) > (thresh & 0xff)) ? -1 : 0;
+        hev |= (Math.abs((q1 & 0xff) - (q0 & 0xff)) > (thresh & 0xff)) ? -1 : 0;
+        return hev;
+    }
+
+    private static void filter4(byte mask, byte thresh,
+                                byte[] op1, int index_op1,
+                                byte[] op0, int index_op0,
+                                byte[] oq0, int index_oq0,
+                                byte[] oq1, int index_oq1) {
+
+        byte filter1, filter2;
+
+        final byte ps1 = (byte)(op1[index_op1] ^ 0x80);
+        final byte ps0 = (byte)(op0[index_op0] ^ 0x80);
+        final byte qs0 = (byte)(oq0[index_oq0] ^ 0x80);
+        final byte qs1 = (byte)(oq1[index_oq1] ^ 0x80);
+
+        final byte hev = hev_mask(thresh, op1[index_op1], op0[index_op0], oq0[index_oq0],
+                oq1[index_oq1]);
+
+        // add outer taps if we have high edge variance
+        byte filter = (byte)(signed_char_clamp(ps1 - qs1) & hev);
+
+        // inner taps
+        filter = (byte)(signed_char_clamp(filter + 3 * (qs0 - ps0)) & mask);
+
+        // save bottom 3 bits so that we round one side +4 and the other +3
+        // if it equals 4 we'll set to adjust by -1 to account for the fact
+        // we'd round 3 the other way
+        filter1 = (byte)(signed_char_clamp(filter + 4) >> 3);
+        filter2 = (byte)(signed_char_clamp(filter + 3) >> 3);
+
+        oq0[index_oq0] = (byte)(signed_char_clamp(qs0 - filter1) ^ 0x80);
+        op0[index_op0] = (byte)(signed_char_clamp(ps0 + filter2) ^ 0x80);
+
+        // outer tap adjustments
+        filter = (byte)(round_power_of_two_signed(filter1, 1) & (~hev));
+
+        oq1[index_oq1] = (byte)(signed_char_clamp(qs1 - filter) ^ 0x80);
+        op1[index_op1] = (byte)(signed_char_clamp(ps1 + filter) ^ 0x80);
+    }
+
+    private static void vp9_lpf_horizontal_4_c(byte[] s, int index, int p,
+                                               final byte[] blimit, final byte[] limit,
+                                               final byte[] thresh, int count) {
+
+        int i;
+        // loop filter designed to work using chars so that we can make maximum use
+        // of 8 bit simd instructions.
+        for (i = 0; i < 8 * count; ++i) {
+             byte p3 = s[index - 4 * p], p2 = s[index - 3 * p], p1 = s[index - 2 * p],
+                     p0 = s[index - p];
+             byte q0 = s[index + 0 * p], q1 = s[index + 1 * p], q2 = s[index + 2 * p],
+                     q3 = s[index + 3 * p];
+             byte mask = (byte)filter_mask(limit[0], blimit[0], p3, p2, p1, p0, q0, q1, q2, q3);
+
+            filter4(mask, thresh[0], s, index - 2 * p, s, index - 1 * p, s, index, s,
+                    index + 1 * p);
+            ++index;
+        }
+    }
+
+    private static void vp9_lpf_horizontal_4_dual_c(byte[] s, int index, int p,
+                                                    final byte[] blimit0, final byte[] limit0,
+                                                    final byte[] thresh0, final byte[] blimit1,
+                                                    final byte[] limit1, final byte[] thresh1) {
+
+        vp9_lpf_horizontal_4_c(s, index, p, blimit0, limit0, thresh0, 1);
+        vp9_lpf_horizontal_4_c(s, index + 8, p, blimit1, limit1, thresh1, 1);
+    }
+
+    private static void vp9_lpf_vertical_4_c(byte[] s, int index, int pitch,
+                                             final byte[] blimit, final byte[] limit,
+                                             final byte[] thresh, int count) {
+
+        int i;
+        // loop filter designed to work using chars so that we can make maximum use
+        // of 8 bit simd instructions.
+        for (i = 0; i < 8 * count; ++i) {
+            final byte p3 = s[index - 4], p2 = s[index - 3], p1 = s[index - 2], p0 = s[index - 1];
+            final byte q0 = s[index], q1 = s[index + 1], q2 = s[index + 2], q3 = s[index + 3];
+            final byte mask = filter_mask(limit[0], blimit[0], p3, p2, p1, p0, q0, q1, q2, q3);
+
+            filter4(mask, thresh[0], s, index - 2, s, index - 1, s, index, s, index + 1);
+            index += pitch;
+        }
+    }
+
+    private static void vp9_lpf_vertical_4_dual_c(byte[] s, int index, int pitch,
+                                                  final byte[] blimit0, final byte[] limit0,
+                                                  final byte[] thresh0, final byte[] blimit1,
+                                                  final byte[] limit1, final byte[] thresh1) {
+
+        vp9_lpf_vertical_4_c(s, index, pitch, blimit0, limit0, thresh0, 1);
+        vp9_lpf_vertical_4_c(s, index + 8 * pitch, pitch, blimit1, limit1, thresh1, 1);
+    }
+
+    private static void filter8(byte mask, byte thresh, byte flat,
+                                byte[] op3, int index_op3,
+                                byte[] op2, int index_op2,
+                                byte[] op1, int index_op1,
+                                byte[] op0, int index_op0,
+                                byte[] oq0, int index_oq0,
+                                byte[] oq1, int index_oq1,
+                                byte[] oq2, int index_oq2,
+                                byte[] oq3, int index_oq3) {
+
+        if (((flat & 0xff) != 0) && (mask != 0)) {
+            final byte p3 = op3[index_op3], p2 = op2[index_op2], p1 = op1[index_op1],
+                    p0 = op0[index_op0];
+            final byte q0 = oq0[index_oq0], q1 = oq1[index_oq1], q2 = oq2[index_oq2],
+                    q3 = oq3[index_oq3];
+
+            // 7-tap filter [1, 1, 1, 2, 1, 1, 1]
+            op2[index_op2] = (byte)round_power_of_two((p3 & 0xff) + (p3 & 0xff) + (p3 & 0xff) +
+                    2 * (p2 & 0xff) + (p1 & 0xff) + (p0 & 0xff) + (q0 & 0xff), 3);
+            op1[index_op1] = (byte)round_power_of_two((p3 & 0xff) + (p3 & 0xff) + (p2 & 0xff) +
+                    2 * (p1 & 0xff) + (p0 & 0xff) + (q0 & 0xff) + (q1 & 0xff), 3);
+            op0[index_op0] = (byte)round_power_of_two((p3 & 0xff) + (p2 & 0xff) + (p1 & 0xff) +
+                    2 * (p0 & 0xff) + (q0 & 0xff) + (q1 & 0xff) + (q2 & 0xff), 3);
+            oq0[index_oq0] = (byte)round_power_of_two((p2 & 0xff) + (p1 & 0xff) + (p0 & 0xff) +
+                    2 * (q0 & 0xff) + (q1 & 0xff) + (q2 & 0xff) + (q3 & 0xff), 3);
+            oq1[index_oq1] = (byte)round_power_of_two((p1 & 0xff) + (p0 & 0xff) + (q0 & 0xff) +
+                    2 * (q1 & 0xff) + (q2 & 0xff) + (q3 & 0xff) + (q3 & 0xff), 3);
+            oq2[index_oq2] = (byte)round_power_of_two((p0 & 0xff) + (q0 & 0xff) + (q1 & 0xff) +
+                    2 * (q2 & 0xff) + (q3 & 0xff) + (q3 & 0xff) + (q3 & 0xff), 3);
+        } else {
+            filter4(mask, thresh, op1, index_op1, op0, index_op0, oq0, index_oq0, oq1, index_oq1);
+        }
+    }
+
+    private static void vp9_lpf_horizontal_8_c(byte[] s, int index,  int p,
+                                               final byte[] blimit, final byte[] limit,
+                                               final byte[] thresh, int count) {
+
+        int i;
+        // loop filter designed to work using chars so that we can make maximum use
+        // of 8 bit simd instructions.
+        for (i = 0; i < 8 * count; ++i) {
+            final byte p3 = s[index - 4 * p], p2 = s[index - 3 * p], p1 = s[index - 2 * p],
+                    p0 = s[index - p];
+            final byte q0 = s[index + 0 * p], q1 = s[index + 1 * p], q2 = s[index + 2 * p],
+                    q3 = s[index + 3 * p];
+
+            final byte mask = filter_mask(limit[0], blimit[0], p3, p2, p1, p0, q0, q1, q2, q3);
+            final byte flat = flat_mask4((byte)1, p3, p2, p1, p0, q0, q1, q2, q3);
+
+            filter8(mask, thresh[0], flat, s, index - 4 * p, s, index - 3 * p, s, index - 2 * p, s,
+                    index - 1 * p, s, index, s, index + 1 * p, s, index + 2 * p, s, index + 3 * p);
+            ++index;
+        }
+    }
+
+    private static void vp9_lpf_horizontal_8_dual_c(byte[] s, int index, int p,
+                                                    final byte[] blimit0, final byte[] limit0,
+                                                    final byte[] thresh0, final byte[] blimit1,
+                                                    final byte[] limit1,  final byte[] thresh1) {
+
+        vp9_lpf_horizontal_8_c(s, index, p, blimit0, limit0, thresh0, 1);
+        vp9_lpf_horizontal_8_c(s, index + 8, p, blimit1, limit1, thresh1, 1);
+    }
+
+    private static void vp9_lpf_vertical_8_c(byte[] s, int index, int pitch,
+                                             final byte[] blimit, final byte[] limit,
+                                             final byte[] thresh, int count) {
+
+        int i;
+        for (i = 0; i < 8 * count; ++i) {
+            final byte p3 = s[index - 4], p2 = s[index - 3], p1 = s[index - 2], p0 = s[index - 1];
+            final byte q0 = s[index + 0], q1 = s[index + 1], q2 = s[index + 2], q3 = s[index + 3];
+            final byte mask = filter_mask(limit[0], blimit[0], p3, p2, p1, p0, q0, q1, q2, q3);
+            final byte flat = flat_mask4((byte)1, p3, p2, p1, p0, q0, q1, q2, q3);
+
+            filter8(mask, thresh[0], flat, s, index - 4, s, index - 3, s, index - 2, s, index - 1,
+                    s, index, s, index + 1, s, index + 2, s, index + 3);
+            index += pitch;
+        }
+    }
+
+    private static void vp9_lpf_vertical_8_dual_c(byte[] s, int index, int pitch,
+                                                  final byte[] blimit0, final byte[] limit0,
+                                                  final byte[] thresh0, final byte[] blimit1,
+                                                  final byte[] limit1, final byte[] thresh1) {
+
+        vp9_lpf_vertical_8_c(s, index, pitch, blimit0, limit0, thresh0, 1);
+        vp9_lpf_vertical_8_c(s, index + 8 * pitch, pitch, blimit1, limit1, thresh1, 1);
+    }
+
+    private static void filter16(byte mask, byte thresh,
+                                 byte flat, byte flat2,
+                                 byte[] op7, int index_op7,
+                                 byte[] op6, int index_op6,
+                                 byte[] op5, int index_op5,
+                                 byte[] op4, int index_op4,
+                                 byte[] op3, int index_op3,
+                                 byte[] op2, int index_op2,
+                                 byte[] op1, int index_op1,
+                                 byte[] op0, int index_op0,
+                                 byte[] oq0, int index_oq0,
+                                 byte[] oq1, int index_oq1,
+                                 byte[] oq2, int index_oq2,
+                                 byte[] oq3, int index_oq3,
+                                 byte[] oq4, int index_oq4,
+                                 byte[] oq5, int index_oq5,
+                                 byte[] oq6, int index_oq6,
+                                 byte[] oq7, int index_oq7) {
+
+        if (((flat2 & 0xff) != 0) && ((flat & 0xff) != 0) && (mask != 0)) {
+            final byte p7 = op7[index_op7], p6 = op6[index_op6], p5 = op5[index_op5],
+                    p4 = op4[index_op4], p3 = op3[index_op3], p2 = op2[index_op2],
+                    p1 = op1[index_op1], p0 = op0[index_op0];
+
+            final byte q0 = oq0[index_oq0], q1 = oq1[index_oq1], q2 = oq2[index_oq2],
+                    q3 = oq3[index_oq3], q4 = oq4[index_oq4], q5 = oq5[index_oq5],
+                    q6 = oq6[index_oq6], q7 = oq7[index_oq7];
+
+            // 15-tap filter [1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1]
+            op6[index_op6] = (byte)round_power_of_two((p7 & 0xff) * 7 + (p6 & 0xff) * 2 +
+                    (p5 & 0xff) + (p4 & 0xff) + (p3 & 0xff) + (p2 & 0xff) + (p1 & 0xff) +
+                    (p0 & 0xff) + (q0 & 0xff), 4);
+            op5[index_op5] = (byte)round_power_of_two((p7 & 0xff) * 6 + (p6 & 0xff) +
+                    (p5 & 0xff) * 2 + (p4 & 0xff) + (p3 & 0xff) + (p2 & 0xff) + (p1 & 0xff) +
+                    (p0 & 0xff) + (q0 & 0xff) + (q1 & 0xff), 4);
+            op4[index_op4] = (byte)round_power_of_two((p7 & 0xff) * 5 + (p6 & 0xff) + (p5 & 0xff) +
+                    (p4 & 0xff) * 2 + (p3 & 0xff) + (p2 & 0xff) + (p1 & 0xff) + (p0 & 0xff) +
+                    (q0 & 0xff) + (q1 & 0xff) + (q2 & 0xff), 4);
+            op3[index_op3] = (byte)round_power_of_two((p7 & 0xff) * 4 + (p6 & 0xff) + (p5 & 0xff) +
+                    (p4 & 0xff) + (p3 & 0xff) * 2 + (p2 & 0xff) + (p1 & 0xff) + (p0 & 0xff) +
+                    (q0 & 0xff) + (q1 & 0xff) + (q2 & 0xff) + (q3 & 0xff), 4);
+            op2[index_op2] = (byte)round_power_of_two((p7 & 0xff) * 3 + (p6 & 0xff) + (p5 & 0xff) +
+                    (p4 & 0xff) + (p3 & 0xff) + (p2 & 0xff) * 2 + (p1 & 0xff) + (p0 & 0xff) +
+                    (q0 & 0xff) + (q1 & 0xff) + (q2 & 0xff) + (q3 & 0xff) + (q4 & 0xff), 4);
+            op1[index_op1] = (byte)round_power_of_two((p7 & 0xff) * 2 + (p6 & 0xff) + (p5 & 0xff) +
+                    (p4 & 0xff) + (p3 & 0xff) + (p2 & 0xff) + (p1 & 0xff) * 2 + (p0 & 0xff) +
+                    (q0 & 0xff) + (q1 & 0xff) + (q2 & 0xff) + (q3 & 0xff) + (q4 & 0xff) +
+                    (q5 & 0xff), 4);
+            op0[index_op0] = (byte)round_power_of_two((p7 & 0xff) + (p6 & 0xff) + (p5 & 0xff) +
+                    (p4 & 0xff) + (p3 & 0xff) + (p2 & 0xff) + (p1 & 0xff) + (p0 & 0xff) * 2 +
+                    (q0 & 0xff) + (q1 & 0xff) + (q2 & 0xff) + (q3 & 0xff) + (q4 & 0xff) +
+                    (q5 & 0xff) + (q6 & 0xff), 4);
+            oq0[index_oq0] = (byte)round_power_of_two((p6 & 0xff) + (p5 & 0xff) + (p4 & 0xff) +
+                    (p3 & 0xff) + (p2 & 0xff) + (p1 & 0xff) + (p0 & 0xff) + (q0 & 0xff) * 2 +
+                    (q1 & 0xff) + (q2 & 0xff) + (q3 & 0xff) + (q4 & 0xff) + (q5 & 0xff) +
+                    (q6 & 0xff) + (q7 & 0xff), 4);
+            oq1[index_oq1] = (byte)round_power_of_two((p5 & 0xff) + (p4 & 0xff) + (p3 & 0xff) +
+                    (p2 & 0xff) + (p1 & 0xff) + (p0 & 0xff) + (q0 & 0xff) + (q1 & 0xff) * 2 +
+                    (q2 & 0xff) + (q3 & 0xff) + (q4 & 0xff) + (q5 & 0xff) + (q6 & 0xff) +
+                    (q7 & 0xff) * 2, 4);
+            oq2[index_oq2] = (byte)round_power_of_two((p4 & 0xff) + (p3 & 0xff) + (p2 & 0xff) +
+                    (p1 & 0xff) + (p0 & 0xff) + (q0 & 0xff) + (q1 & 0xff) + (q2 & 0xff) * 2 +
+                    (q3 & 0xff) + (q4 & 0xff) + (q5 & 0xff) + (q6 & 0xff) + (q7 & 0xff) * 3, 4);
+            oq3[index_oq3] = (byte)round_power_of_two((p3 & 0xff) + (p2 & 0xff) + (p1 & 0xff) +
+                    (p0 & 0xff) + (q0 & 0xff) + (q1 & 0xff) + (q2 & 0xff) + (q3 & 0xff) * 2 +
+                    (q4 & 0xff) + (q5 & 0xff) + (q6 & 0xff) + (q7 & 0xff) * 4, 4);
+            oq4[index_oq4] = (byte)round_power_of_two((p2 & 0xff) + (p1 & 0xff) + (p0 & 0xff) +
+                    (q0 & 0xff) + (q1 & 0xff) + (q2 & 0xff) + (q3 & 0xff) + (q4 & 0xff) * 2 +
+                    (q5 & 0xff) + (q6 & 0xff) + (q7 & 0xff) * 5, 4);
+            oq5[index_oq5] = (byte)round_power_of_two((p1 & 0xff) + (p0 & 0xff) + (q0 & 0xff) +
+                    (q1 & 0xff) + (q2 & 0xff) + (q3 & 0xff) + (q4 & 0xff) + (q5 & 0xff) * 2 +
+                    (q6 & 0xff) + (q7 & 0xff) * 6, 4);
+            oq6[index_oq6] = (byte)round_power_of_two((p0 & 0xff) + (q0 & 0xff) + (q1 & 0xff) +
+                    (q2 & 0xff) + (q3 & 0xff) + (q4 & 0xff) + (q5 & 0xff) + (q6 & 0xff) * 2 +
+                    (q7 & 0xff) * 7, 4);
+        } else {
+            filter8(mask, thresh, flat, op3, index_op3, op2, index_op2, op1, index_op1, op0,
+                    index_op0, oq0, index_oq0, oq1, index_oq1, oq2, index_oq2, oq3, index_oq3);
+        }
+    }
+
+    private static void vp9_lpf_horizontal_16_c(byte[] s, int index, int p,
+                                                final byte[] blimit, final byte[] limit,
+                                                final byte[] thresh, int count) {
+
+        int i;
+        // loop filter designed to work using chars so that we can make maximum use
+        // of 8 bit simd instructions.
+        for (i = 0; i < 8 * count; ++i) {
+            final byte p3 = s[index - 4 * p], p2 = s[index - 3 * p], p1 = s[index - 2 * p],
+                    p0 = s[index - p];
+            final byte q0 = s[index + 0 * p], q1 = s[index + 1 * p], q2 = s[index + 2 * p],
+                    q3 = s[index + 3 * p];
+
+            final byte mask = filter_mask(limit[0], blimit[0], p3, p2, p1, p0, q0, q1, q2, q3);
+            final byte flat = flat_mask4((byte)1, p3, p2, p1, p0, q0, q1, q2, q3);
+            final byte flat2 = flat_mask5((byte)1, s[index - 8 * p], s[index - 7 * p],
+                    s[index - 6 * p], s[index - 5 * p], p0, q0, s[index + 4 * p], s[index + 5 * p],
+                    s[index + 6 * p], s[index + 7 * p]);
+
+            filter16(mask, thresh[0], flat, flat2, s, index - 8 * p, s, index - 7 * p, s,
+                    index - 6 * p, s, index - 5 * p, s, index - 4 * p, s, index - 3 * p, s,
+                    index - 2 * p, s, index - 1 * p, s, index, s, index + 1 * p, s, index + 2 * p,
+                    s, index + 3 * p, s, index + 4 * p, s, index + 5 * p, s, index + 6 * p,
+                    s, index + 7 * p);
+            ++index;
+        }
+    }
+
+    private static void mb_lpf_vertical_edge_w(byte[] s, int index, int p,
+                                               final byte[] blimit, final byte[] limit,
+                                               final byte[] thresh, int count) {
+
+        int i;
+        for (i = 0; i < count; ++i) {
+            final byte p3 = s[index - 4], p2 = s[index - 3], p1 = s[index - 2], p0 = s[index - 1];
+            final byte q0 = s[index + 0], q1 = s[index + 1], q2 = s[index + 2], q3 = s[index + 3];
+
+            final byte mask = filter_mask(limit[0], blimit[0], p3, p2, p1, p0, q0, q1, q2, q3);
+            final byte flat = flat_mask4((byte)1, p3, p2, p1, p0, q0, q1, q2, q3);
+            final byte flat2 = flat_mask5((byte)1, s[index - 8], s[index - 7], s[index - 6],
+                    s[index - 5], p0, q0, s[index + 4], s[index + 5], s[index + 6], s[index + 7]);
+
+            filter16(mask, thresh[0], flat, flat2, s, index - 8, s, index - 7, s, index - 6,
+                    s, index - 5, s, index - 4, s, index - 3, s, index - 2, s, index - 1,
+                    s, index, s, index + 1, s, index + 2, s, index + 3, s, index + 4, s, index + 5,
+                    s, index + 6, s, index + 7);
+            index += p;
+        }
+    }
+
+    private static void vp9_lpf_vertical_16_c(byte[] s, int index, int p, final byte[] blimit,
+                                              final byte[] limit, final byte[] thresh) {
+
+          mb_lpf_vertical_edge_w(s, index, p, blimit, limit, thresh, 8);
+    }
+
+    private static void vp9_lpf_vertical_16_dual_c(byte[] s, int index, int p, final byte[] blimit,
+                                                  final byte[] limit, final byte[] thresh) {
+
+        mb_lpf_vertical_edge_w(s, index, p, blimit, limit, thresh, 16);
+    }
+
+    private static void filter_selectively_vert_row2(boolean flags,
+                                                     byte[] s, int index, int pitch,
+                                                     int mask_16x16_l,
+                                                     int mask_8x8_l,
+                                                     int mask_4x4_l,
+                                                     int mask_4x4_int_l,
+                                                     final LoopFilterInfoN lfi_n,
+                                                     final byte[] lfl,
+                                                     int index_lfl) {
+
+        final int mask_shift = (flags) ? 4 : 8;
+        final int mask_cutoff = (flags) ? 0xf : 0xff;
+        final int lfl_forward = (flags) ? 4 : 8;
+
+        int mask_16x16_0 = mask_16x16_l & mask_cutoff;
+        int mask_8x8_0 = mask_8x8_l & mask_cutoff;
+        int mask_4x4_0 = mask_4x4_l & mask_cutoff;
+        int mask_4x4_int_0 = mask_4x4_int_l & mask_cutoff;
+        int mask_16x16_1 = (mask_16x16_l >>> mask_shift) & mask_cutoff;
+        int mask_8x8_1 = (mask_8x8_l >>> mask_shift) & mask_cutoff;
+        int mask_4x4_1 = (mask_4x4_l >>> mask_shift) & mask_cutoff;
+        int mask_4x4_int_1 = (mask_4x4_int_l >>> mask_shift) & mask_cutoff;
+        int mask;
+
+        for (mask = (mask_16x16_0 | mask_8x8_0 | mask_4x4_0 | mask_4x4_int_0 |
+             mask_16x16_1 | mask_8x8_1 | mask_4x4_1 | mask_4x4_int_1);
+             mask > 0; mask >>>= 1) {
+
+            if ((mask & 1) != 0) {
+                if (((mask_16x16_0 | mask_16x16_1) & 1) != 0) {
+                    if (((mask_16x16_0 & mask_16x16_1) & 1) != 0) {
+                        vp9_lpf_vertical_16_dual_c(s, index, pitch,
+                                lfi_n.lfthr[lfl[index_lfl]].mblim,
+                                lfi_n.lfthr[lfl[index_lfl]].lim,
+                                lfi_n.lfthr[lfl[index_lfl]].hev_thr);
+                    } else if ((mask_16x16_0 & 1) != 0) {
+                        vp9_lpf_vertical_16_c(s, index, pitch,
+                                lfi_n.lfthr[lfl[index_lfl]].mblim,
+                                lfi_n.lfthr[lfl[index_lfl]].lim,
+                                lfi_n.lfthr[lfl[index_lfl]].hev_thr);
+                    } else {
+                        vp9_lpf_vertical_16_c(s, index + 8 *pitch, pitch,
+                                lfi_n.lfthr[lfl[index_lfl + lfl_forward]].mblim,
+                                lfi_n.lfthr[lfl[index_lfl + lfl_forward]].lim,
+                                lfi_n.lfthr[lfl[index_lfl + lfl_forward]].hev_thr);
+                    }
+                }
+
+                if (((mask_8x8_0 | mask_8x8_1) & 1) != 0) {
+                    if (((mask_8x8_0 & mask_8x8_1) & 1) != 0) {
+                        vp9_lpf_vertical_8_dual_c(s, index, pitch,
+                                lfi_n.lfthr[lfl[index_lfl]].mblim,
+                                lfi_n.lfthr[lfl[index_lfl]].lim,
+                                lfi_n.lfthr[lfl[index_lfl]].hev_thr,
+                                lfi_n.lfthr[lfl[index_lfl + lfl_forward]].mblim,
+                                lfi_n.lfthr[lfl[index_lfl + lfl_forward]].lim,
+                                lfi_n.lfthr[lfl[index_lfl + lfl_forward]].hev_thr);
+                    } else if ((mask_8x8_0 & 1) != 0) {
+                        vp9_lpf_vertical_8_c(s, index, pitch,
+                                lfi_n.lfthr[lfl[index_lfl]].mblim,
+                                lfi_n.lfthr[lfl[index_lfl]].lim,
+                                lfi_n.lfthr[lfl[index_lfl]].hev_thr, 1);
+                    } else {
+                        vp9_lpf_vertical_8_c(s, index + 8 * pitch, pitch,
+                                lfi_n.lfthr[lfl[index_lfl + lfl_forward]].mblim,
+                                lfi_n.lfthr[lfl[index_lfl + lfl_forward]].lim,
+                                lfi_n.lfthr[lfl[index_lfl + lfl_forward]].hev_thr, 1);
+                    }
+                }
+
+                if (((mask_4x4_0 | mask_4x4_1) & 1) != 0) {
+                    if (((mask_4x4_0 & mask_4x4_1) & 1) != 0) {
+                        vp9_lpf_vertical_4_dual_c(s, index, pitch,
+                                lfi_n.lfthr[lfl[index_lfl]].mblim,
+                                lfi_n.lfthr[lfl[index_lfl]].lim,
+                                lfi_n.lfthr[lfl[index_lfl]].hev_thr,
+                                lfi_n.lfthr[lfl[index_lfl + lfl_forward]].mblim,
+                                lfi_n.lfthr[lfl[index_lfl + lfl_forward]].lim,
+                                lfi_n.lfthr[lfl[index_lfl + lfl_forward]].hev_thr);
+                    } else if ((mask_4x4_0 & 1) != 0) {
+                        vp9_lpf_vertical_4_c(s, index, pitch,
+                                lfi_n.lfthr[lfl[index_lfl]].mblim,
+                                lfi_n.lfthr[lfl[index_lfl]].lim,
+                                lfi_n.lfthr[lfl[index_lfl]].hev_thr, 1);
+                    } else {
+                        vp9_lpf_vertical_4_c(s, index + 8 * pitch, pitch,
+                                lfi_n.lfthr[lfl[index_lfl + lfl_forward]].mblim,
+                                lfi_n.lfthr[lfl[index_lfl + lfl_forward]].lim,
+                                lfi_n.lfthr[lfl[index_lfl + lfl_forward]].hev_thr, 1);
+                    }
+                }
+
+                if (((mask_4x4_int_0 | mask_4x4_int_1) & 1) != 0) {
+                    if (((mask_4x4_int_0 & mask_4x4_int_1) & 1) != 0) {
+                        vp9_lpf_vertical_4_dual_c(s, index + 4, pitch,
+                                lfi_n.lfthr[lfl[index_lfl]].mblim,
+                                lfi_n.lfthr[lfl[index_lfl]].lim,
+                                lfi_n.lfthr[lfl[index_lfl]].hev_thr,
+                                lfi_n.lfthr[lfl[index_lfl + lfl_forward]].mblim,
+                                lfi_n.lfthr[lfl[index_lfl + lfl_forward]].lim,
+                                lfi_n.lfthr[lfl[index_lfl + lfl_forward]].hev_thr);
+                    } else if ((mask_4x4_int_0 & 1) != 0) {
+                        vp9_lpf_vertical_4_c(s, index + 4, pitch,
+                                lfi_n.lfthr[lfl[index_lfl]].mblim,
+                                lfi_n.lfthr[lfl[index_lfl]].lim,
+                                lfi_n.lfthr[lfl[index_lfl]].hev_thr, 1);
+                    } else {
+                        vp9_lpf_vertical_4_c(s, index + 8 * pitch + 4, pitch,
+                                lfi_n.lfthr[lfl[index_lfl + lfl_forward]].mblim,
+                                lfi_n.lfthr[lfl[index_lfl + lfl_forward]].lim,
+                                lfi_n.lfthr[lfl[index_lfl + lfl_forward]].hev_thr, 1);
+                    }
+                }
+            }
+
+            index += 8;
+            index_lfl += 1;
+            mask_16x16_0 >>>= 1;
+            mask_8x8_0 >>>= 1;
+            mask_4x4_0 >>>= 1;
+            mask_4x4_int_0 >>>= 1;
+            mask_16x16_1 >>>= 1;
+            mask_8x8_1 >>>= 1;
+            mask_4x4_1 >>>= 1;
+            mask_4x4_int_1 >>>= 1;
+        }
+    }
+
+    private static void filter_selectively_horiz(byte[] s, int index, int pitch,
+                                                 int mask_16x16,
+                                                 int mask_8x8,
+                                                 int mask_4x4,
+                                                 int mask_4x4_int,
+                                                 final LoopFilterInfoN lfi_n,
+                                                 final byte[] lfl,
+                                                 int index_lfl) {
+
+        int mask;
+        int count;
+
+        for (mask = (mask_16x16 | mask_8x8 | mask_4x4 | mask_4x4_int); mask != 0;
+                mask >>>= count) {
+
+            count = 1;
+            if ((mask & 1) != 0) {
+                if ((mask_16x16 & 1) != 0) {
+                    if ((mask_16x16 & 3) == 3) {
+                        vp9_lpf_horizontal_16_c(s, index, pitch,
+                                lfi_n.lfthr[lfl[index_lfl]].mblim,
+                                lfi_n.lfthr[lfl[index_lfl]].lim,
+                                lfi_n.lfthr[lfl[index_lfl]].hev_thr, 2);
+                        count = 2;
+                    } else {
+                        vp9_lpf_horizontal_16_c(s, index, pitch,
+                                lfi_n.lfthr[lfl[index_lfl]].mblim,
+                                lfi_n.lfthr[lfl[index_lfl]].lim,
+                                lfi_n.lfthr[lfl[index_lfl]].hev_thr, 1);
+                    }
+                } else if ((mask_8x8 & 1) != 0) {
+                    if ((mask_8x8 & 3) == 3) {
+                        vp9_lpf_horizontal_8_dual_c(s, index, pitch,
+                                lfi_n.lfthr[lfl[index_lfl]].mblim,
+                                lfi_n.lfthr[lfl[index_lfl]].lim,
+                                lfi_n.lfthr[lfl[index_lfl]].hev_thr,
+                                lfi_n.lfthr[lfl[index_lfl + 1]].mblim,
+                                lfi_n.lfthr[lfl[index_lfl + 1]].lim,
+                                lfi_n.lfthr[lfl[index_lfl + 1]].hev_thr);
+
+                        if ((mask_4x4_int & 3) == 3) {
+                            vp9_lpf_horizontal_4_dual_c(s, index + 4 * pitch, pitch,
+                                    lfi_n.lfthr[lfl[index_lfl]].mblim,
+                                    lfi_n.lfthr[lfl[index_lfl]].lim,
+                                    lfi_n.lfthr[lfl[index_lfl]].hev_thr,
+                                    lfi_n.lfthr[lfl[index_lfl + 1]].mblim,
+                                    lfi_n.lfthr[lfl[index_lfl + 1]].lim,
+                                    lfi_n.lfthr[lfl[index_lfl + 1]].hev_thr);
+                        } else {
+                            if ((mask_4x4_int & 1) != 0)
+                                vp9_lpf_horizontal_4_c(s, index + 4 * pitch, pitch,
+                                        lfi_n.lfthr[lfl[index_lfl]].mblim,
+                                        lfi_n.lfthr[lfl[index_lfl]].lim,
+                                        lfi_n.lfthr[lfl[index_lfl]].hev_thr, 1);
+                            else if ((mask_4x4_int & 2) != 0)
+                                vp9_lpf_horizontal_4_c(s, index + 8 + 4 * pitch, pitch,
+                                        lfi_n.lfthr[lfl[index_lfl + 1]].mblim,
+                                        lfi_n.lfthr[lfl[index_lfl + 1]].lim,
+                                        lfi_n.lfthr[lfl[index_lfl + 1]].hev_thr, 1);
+                        }
+                        count = 2;
+                    } else {
+                        vp9_lpf_horizontal_8_c(s, index, pitch,
+                                lfi_n.lfthr[lfl[index_lfl]].mblim,
+                                lfi_n.lfthr[lfl[index_lfl]].lim,
+                                lfi_n.lfthr[lfl[index_lfl]].hev_thr, 1);
+
+                        if ((mask_4x4_int & 1) != 0)
+                            vp9_lpf_horizontal_4_c(s, index + 4 * pitch, pitch,
+                                    lfi_n.lfthr[lfl[index_lfl]].mblim,
+                                    lfi_n.lfthr[lfl[index_lfl]].lim,
+                                    lfi_n.lfthr[lfl[index_lfl]].hev_thr, 1);
+                    }
+                } else if ((mask_4x4 & 1) != 0) {
+                    if ((mask_4x4 & 3) == 3) {
+
+                        vp9_lpf_horizontal_4_dual_c(s, index, pitch,
+                                lfi_n.lfthr[lfl[index_lfl]].mblim,
+                                lfi_n.lfthr[lfl[index_lfl]].lim,
+                                lfi_n.lfthr[lfl[index_lfl]].hev_thr,
+                                lfi_n.lfthr[lfl[index_lfl + 1]].mblim,
+                                lfi_n.lfthr[lfl[index_lfl + 1]].lim,
+                                lfi_n.lfthr[lfl[index_lfl + 1]].hev_thr);
+                        if ((mask_4x4_int & 3) == 3) {
+                            vp9_lpf_horizontal_4_dual_c(s, index + 4 * pitch, pitch,
+                                    lfi_n.lfthr[lfl[index_lfl]].mblim,
+                                    lfi_n.lfthr[lfl[index_lfl]].lim,
+                                    lfi_n.lfthr[lfl[index_lfl]].hev_thr,
+                                    lfi_n.lfthr[lfl[index_lfl + 1]].mblim,
+                                    lfi_n.lfthr[lfl[index_lfl + 1]].lim,
+                                    lfi_n.lfthr[lfl[index_lfl + 1]].hev_thr);
+                        } else {
+                            if ((mask_4x4_int & 1) != 0)
+                                vp9_lpf_horizontal_4_c(s, index + 4 * pitch, pitch,
+                                        lfi_n.lfthr[lfl[index_lfl]].mblim,
+                                        lfi_n.lfthr[lfl[index_lfl]].lim,
+                                        lfi_n.lfthr[lfl[index_lfl]].hev_thr, 1);
+                            else if ((mask_4x4_int & 2) != 0)
+                                vp9_lpf_horizontal_4_c(s, index + 8 + 4 * pitch, pitch,
+                                        lfi_n.lfthr[lfl[index_lfl + 1]].mblim,
+                                        lfi_n.lfthr[lfl[index_lfl + 1]].lim,
+                                        lfi_n.lfthr[lfl[index_lfl + 1]].hev_thr, 1);
+                        }
+                        count = 2;
+                    } else {
+                        vp9_lpf_horizontal_4_c(s, index, pitch,
+                                lfi_n.lfthr[lfl[index_lfl]].mblim,
+                                lfi_n.lfthr[lfl[index_lfl]].lim,
+                                lfi_n.lfthr[lfl[index_lfl]].hev_thr, 1);
+
+                        if ((mask_4x4_int & 1) != 0)
+                            vp9_lpf_horizontal_4_c(s, index + 4 * pitch, pitch,
+                                    lfi_n.lfthr[lfl[index_lfl]].mblim,
+                                    lfi_n.lfthr[lfl[index_lfl]].lim,
+                                    lfi_n.lfthr[lfl[index_lfl]].hev_thr, 1);
+                    }
+                } else if ((mask_4x4_int & 1) != 0) {
+                    vp9_lpf_horizontal_4_c(s, index + 4 * pitch, pitch,
+                            lfi_n.lfthr[lfl[index_lfl]].mblim,
+                            lfi_n.lfthr[lfl[index_lfl]].lim,
+                            lfi_n.lfthr[lfl[index_lfl]].hev_thr, 1);
+                }
+            }
+
+            index += 8 * count;
+            index_lfl += count;
+            mask_16x16 >>>= count;
+            mask_8x8 >>>= count;
+            mask_4x4 >>>= count;
+            mask_4x4_int >>>= count;
+        }
+    }
+
+    private static void filter_block_plane_y(LoopFilterInfoN lf_info,
+                                             LoopFilterMask lfm,
+                                             int stride,
+                                             byte[] buf,
+                                             int index,
+                                             int mi_rows,
+                                             int mi_row) {
+
+        int r;
+
+        int tmp_index = index;
+        long mask_16x16 = lfm.left_y[2];
+        long mask_8x8 = lfm.left_y[1];
+        long mask_4x4 = lfm.left_y[0];
+        long mask_4x4_int = lfm.int_4x4_y;
+
+        // Vertical pass: do 2 rows at one time
+        for (r = 0; (r < MI_BLOCK_SIZE) && (mi_row + r < mi_rows); r += 2) {
+            int mask_16x16_l = (int)(mask_16x16 & 0xffff);
+            int mask_8x8_l = (int)(mask_8x8 & 0xffff);
+            int mask_4x4_l = (int)(mask_4x4 & 0xffff);
+            int mask_4x4_int_l = (int)(mask_4x4_int & 0xffff);
+
+            // Disable filtering on the leftmost column
+            filter_selectively_vert_row2(false, buf, index, stride,
+                    mask_16x16_l, mask_8x8_l, mask_4x4_l, mask_4x4_int_l, lf_info,
+                    lfm.lfl_y, r << 3);
+
+            index += 16 * stride;
+            mask_16x16 >>>= 16;
+            mask_8x8 >>>= 16;
+            mask_4x4 >>>= 16;
+            mask_4x4_int >>>= 16;
+        }
+
+
+        // Horizontal pass
+        index = tmp_index;
+        mask_16x16 = lfm.above_y[2];
+        mask_8x8 = lfm.above_y[1];
+        mask_4x4 = lfm.above_y[0];
+        mask_4x4_int = lfm.int_4x4_y;
+
+        for (r = 0; (r < MI_BLOCK_SIZE) && (mi_row + r < mi_rows); r++) {
+            int mask_16x16_r;
+            int mask_8x8_r;
+            int mask_4x4_r;
+
+            if (mi_row + r == 0) {
+                mask_16x16_r = 0;
+                mask_8x8_r = 0;
+                mask_4x4_r = 0;
+            } else {
+                mask_16x16_r = (int)(mask_16x16 & 0xff);
+                mask_8x8_r = (int)(mask_8x8 & 0xff);
+                mask_4x4_r = (int)(mask_4x4 & 0xff);
+            }
+
+            filter_selectively_horiz(buf, index, stride, mask_16x16_r, mask_8x8_r,
+                    mask_4x4_r, (int)(mask_4x4_int & 0xff), lf_info, lfm.lfl_y, r << 3);
+
+            index += 8 * stride;
+            mask_16x16 >>>= 8;
+            mask_8x8 >>>= 8;
+            mask_4x4 >>>= 8;
+            mask_4x4_int >>>= 8;
+        }
+    }
+
+    private static void filter_block_plane_uv(LoopFilterInfoN lf_info,
+                                              LoopFilterMask lfm,
+                                              int stride,
+                                              byte[] buf,
+                                              int index,
+                                              int mi_rows,
+                                              int mi_row) {
+
+        int r, c;
+
+        int tmp_index = index;
+        short mask_16x16 = lfm.left_uv[2];
+        short mask_8x8 = lfm.left_uv[1];
+        short mask_4x4 = lfm.left_uv[0];
+        short mask_4x4_int = lfm.int_4x4_uv;
+
+        // Vertical pass: do 2 rows at one time
+        for (r = 0; (r < MI_BLOCK_SIZE) && (mi_row + r < mi_rows); r += 4) {
+
+            for (c = 0; c < (MI_BLOCK_SIZE >> 1); c++) {
+                lfm.lfl_uv[(r << 1) + c] = lfm.lfl_y[(r << 3) + (c << 1)];
+                lfm.lfl_uv[((r + 2) << 1) + c] = lfm.lfl_y[((r + 2) << 3) + (c << 1)];
+            }
+
+            {
+                int mask_16x16_l = mask_16x16 & 0xff;
+                int mask_8x8_l = mask_8x8 & 0xff;
+                int mask_4x4_l = mask_4x4 & 0xff;
+                int mask_4x4_int_l = mask_4x4_int & 0xff;
+
+                // Disable filtering on the leftmost column
+                filter_selectively_vert_row2(true, buf, index, stride,
+                        mask_16x16_l, mask_8x8_l, mask_4x4_l, mask_4x4_int_l, lf_info,
+                        lfm.lfl_uv, r << 1);
+
+                index += 16 * stride;
+                mask_16x16 >>>= 8;
+                mask_8x8 >>>= 8;
+                mask_4x4 >>>= 8;
+                mask_4x4_int >>>= 8;
+            }
+        }
+
+        // Horizontal pass
+        index = tmp_index;
+        mask_16x16 = lfm.above_uv[2];
+        mask_8x8 = lfm.above_uv[1];
+        mask_4x4 = lfm.above_uv[0];
+        mask_4x4_int = lfm.int_4x4_uv;
+
+        for (r = 0; (r < MI_BLOCK_SIZE) && (mi_row + r < mi_rows); r += 2) {
+            int skip_border_4x4_r;
+            if (mi_row + r == mi_rows - 1) {
+                skip_border_4x4_r = 1;
+            } else {
+                skip_border_4x4_r = 0;
+            }
+
+            int mask_4x4_int_r;
+            if (skip_border_4x4_r != 0) {
+                mask_4x4_int_r = 0;
+            } else {
+                mask_4x4_int_r = mask_4x4_int & 0xf;
+            }
+
+            int mask_16x16_r;
+            int mask_8x8_r;
+            int mask_4x4_r;
+
+            if (mi_row + r == 0) {
+                mask_16x16_r = 0;
+                mask_8x8_r = 0;
+                mask_4x4_r = 0;
+            } else {
+                mask_16x16_r = mask_16x16 & 0xf;
+                mask_8x8_r = mask_8x8 & 0xf;
+                mask_4x4_r = mask_4x4 & 0xf;
+            }
+
+            filter_selectively_horiz(buf, index, stride, mask_16x16_r, mask_8x8_r, mask_4x4_r,
+                    mask_4x4_int_r, lf_info, lfm.lfl_uv, r << 1);
+
+            index += 8 * stride;
+            mask_16x16 >>>= 4;
+            mask_8x8 >>>= 4;
+            mask_4x4 >>>= 4;
+            mask_4x4_int >>>= 4;
+        }
+    }
+
+    private void vp9_loop_filter_rows_work_proc(int start, int stop, int num_planes,
+                                                int mi_rows, int mi_cols,
+                                                BufferInfo buf_info,
+                                                byte[] buffer_alloc,
+                                                LoopFilterInfoN lf_info,
+                                                LoopFilterMask[] lfms) {
+
+        int mi_row, mi_col;
+        int lfm_idx;
+        int index_start0;
+        int index_start1;
+        int index_start2;
+        int index_buf0;
+        int index_buf1;
+        int index_buf2;
+
+        index_start0 = buf_info.y_offset;
+        index_start1 = buf_info.u_offset;
+        index_start2 = buf_info.v_offset;
+
+        for (mi_row = start; mi_row < stop; mi_row += MI_BLOCK_SIZE) {
+            index_buf0 = index_start0 + (mi_row * buf_info.y_stride << 3);
+            index_buf1 = index_start1 + (mi_row * buf_info.uv_stride << 2);
+            index_buf2 = index_start2 + (mi_row * buf_info.uv_stride << 2);
+
+            for (mi_col = 0; mi_col < mi_cols; mi_col += MI_BLOCK_SIZE) {
+                lfm_idx = ((mi_row + 7) >> 3) * ((mi_cols + 7) >> 3) + ((mi_col + 7) >> 3);
+                filter_block_plane_y(lf_info, lfms[lfm_idx], buf_info.y_stride, buffer_alloc,
+                        index_buf0, mi_rows, mi_row);
+                index_buf0 += MI_BLOCK_SIZE * MI_BLOCK_SIZE;
+
+                if (num_planes > 1) {
+                    filter_block_plane_uv(lf_info, lfms[lfm_idx], buf_info.uv_stride, buffer_alloc,
+                            index_buf1, mi_rows, mi_row);
+                    filter_block_plane_uv(lf_info, lfms[lfm_idx], buf_info.uv_stride, buffer_alloc,
+                            index_buf2, mi_rows, mi_row);
+                    index_buf1 += MI_BLOCK_SIZE * MI_BLOCK_SIZE >> 1;
+                    index_buf2 += MI_BLOCK_SIZE * MI_BLOCK_SIZE >> 1;
+                }
+            }
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/tests/tests/security/Android.mk b/tests/tests/security/Android.mk
index f36be9d..f1a6bfb 100644
--- a/tests/tests/security/Android.mk
+++ b/tests/tests/security/Android.mk
@@ -20,7 +20,7 @@
 
 LOCAL_JAVA_LIBRARIES := android.test.runner
 
-LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
+LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner guava
 
 LOCAL_JNI_SHARED_LIBRARIES := libctssecurity_jni
 
@@ -32,6 +32,8 @@
 
 LOCAL_SDK_VERSION := current
 
+LOCAL_ASSET_DIR := $(LOCAL_PATH)/assets
+
 include $(BUILD_CTS_PACKAGE)
 
 include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/tests/security/AndroidManifest.xml b/tests/tests/security/AndroidManifest.xml
index e47b045..101c01c 100644
--- a/tests/tests/security/AndroidManifest.xml
+++ b/tests/tests/security/AndroidManifest.xml
@@ -24,6 +24,11 @@
 
     <application>
         <uses-library android:name="android.test.runner" />
+
+        <service android:name="android.security.cts.SeccompDeathTestService"
+                 android:process=":death_test_service"
+                 android:isolatedProcess="true"
+                 android:exported="true"/>
     </application>
 
     <instrumentation android:name="android.test.InstrumentationCtsTestRunner"
diff --git a/tests/tests/security/assets/selinux_policy.xml b/tests/tests/security/assets/selinux_policy.xml
new file mode 100644
index 0000000..f7e816a
--- /dev/null
+++ b/tests/tests/security/assets/selinux_policy.xml
@@ -0,0 +1,1733 @@
+<?xml version="1.0" ?>
+<SELinux_AVC_Rules>
+    <avc_rule name="1" type="neverallow">
+        <type type="source">shell</type>
+        <type type="source">nfc</type>
+        <type type="source">platform_app</type>
+        <type type="source">bluetooth</type>
+        <type type="source">radio</type>
+        <type type="source">isolated_app</type>
+        <type type="source">untrusted_app</type>
+        <type type="source">media_app</type>
+        <type type="source">system_app</type>
+        <type type="source">release_app</type>
+        <type type="source">shared_app</type>
+        <type type="target">kernel</type>
+        <obj_class name="security">
+            <permission>load_policy</permission>
+        </obj_class>
+    </avc_rule>
+    <avc_rule name="2" type="neverallow">
+        <type type="source">sdcardd</type>
+        <type type="source">init_shell</type>
+        <type type="source">adbd</type>
+        <type type="source">netd</type>
+        <type type="source">tee</type>
+        <type type="source">bluetooth</type>
+        <type type="source">lmkd</type>
+        <type type="source">surfaceflinger</type>
+        <type type="source">mdnsd</type>
+        <type type="source">radio</type>
+        <type type="source">hci_attach</type>
+        <type type="source">clatd</type>
+        <type type="source">watchdogd</type>
+        <type type="source">drmserver</type>
+        <type type="source">keystore</type>
+        <type type="source">runas</type>
+        <type type="source">servicemanager</type>
+        <type type="source">dhcp</type>
+        <type type="source">shell</type>
+        <type type="source">uncrypt</type>
+        <type type="source">untrusted_app</type>
+        <type type="source">gpsd</type>
+        <type type="source">isolated_app</type>
+        <type type="source">system_app</type>
+        <type type="source">wpa</type>
+        <type type="source">racoon</type>
+        <type type="source">nfc</type>
+        <type type="source">hostapd</type>
+        <type type="source">platform_app</type>
+        <type type="source">mtp</type>
+        <type type="source">inputflinger</type>
+        <type type="source">logd</type>
+        <type type="source">zygote</type>
+        <type type="source">rild</type>
+        <type type="source">dnsmasq</type>
+        <type type="source">healthd</type>
+        <type type="source">mediaserver</type>
+        <type type="source">bootanim</type>
+        <type type="source">ppp</type>
+        <type type="source">release_app</type>
+        <type type="source">shared_app</type>
+        <type type="target">audio_data_file</type>
+        <type type="target">sysfs_nfc_power_writable</type>
+        <type type="target">ion_device</type>
+        <type type="target">debuggerd</type>
+        <type type="target">netd</type>
+        <type type="target">system_server_tmpfs</type>
+        <type type="target">lmkd</type>
+        <type type="target">uhid_device</type>
+        <type type="target">init_shell</type>
+        <type type="target">radio</type>
+        <type type="target">zygote_socket</type>
+        <type type="target">system_wpa_socket</type>
+        <type type="target">sockfs</type>
+        <type type="target">selinuxfs</type>
+        <type type="target">dumpstate_socket</type>
+        <type type="target">untrusted_app_devpts</type>
+        <type type="target">shell_prop</type>
+        <type type="target">property_socket</type>
+        <type type="target">runas</type>
+        <type type="target">debuggerd_exec</type>
+        <type type="target">mqueue</type>
+        <type type="target">shell_data_file</type>
+        <type type="target">drmserver_tmpfs</type>
+        <type type="target">debuggerd_tmpfs</type>
+        <type type="target">init</type>
+        <type type="target">netif</type>
+        <type type="target">device</type>
+        <type type="target">apk_tmp_file</type>
+        <type type="target">logd</type>
+        <type type="target">servicemanager</type>
+        <type type="target">gpsd_tmpfs</type>
+        <type type="target">bluetooth_socket</type>
+        <type type="target">adb_keys_file</type>
+        <type type="target">sdcardd_exec</type>
+        <type type="target">system_app_tmpfs</type>
+        <type type="target">mediaserver_exec</type>
+        <type type="target">ppp_exec</type>
+        <type type="target">media_rw_data_file</type>
+        <type type="target">clatd_exec</type>
+        <type type="target">ueventd</type>
+        <type type="target">labeledfs</type>
+        <type type="target">asec_image_file</type>
+        <type type="target">camera_device</type>
+        <type type="target">efs_file</type>
+        <type type="target">media_app</type>
+        <type type="target">tmpfs</type>
+        <type type="target">bluetooth_prop</type>
+        <type type="target">logdr_socket</type>
+        <type type="target">nfc</type>
+        <type type="target">zygote_tmpfs</type>
+        <type type="target">cache_backup_file</type>
+        <type type="target">drmserver_socket</type>
+        <type type="target">logd_exec</type>
+        <type type="target">nfc_tmpfs</type>
+        <type type="target">zygote</type>
+        <type type="target">hostapd</type>
+        <type type="target">tee_data_file</type>
+        <type type="target">lmkd_socket</type>
+        <type type="target">zoneinfo_data_file</type>
+        <type type="target">cgroup</type>
+        <type type="target">platform_app</type>
+        <type type="target">release_app</type>
+        <type type="target">qtaguid_device</type>
+        <type type="target">surfaceflinger_tmpfs</type>
+        <type type="target">shm</type>
+        <type type="target">hci_attach_tmpfs</type>
+        <type type="target">rild_exec</type>
+        <type type="target">kernel</type>
+        <type type="target">system_ndebug_socket</type>
+        <type type="target">hci_attach_dev</type>
+        <type type="target">cpuctl_device</type>
+        <type type="target">iio_device</type>
+        <type type="target">dhcp</type>
+        <type type="target">audio_device</type>
+        <type type="target">bootanim_exec</type>
+        <type type="target">tee</type>
+        <type type="target">wpa_exec</type>
+        <type type="target">bluetooth</type>
+        <type type="target">sysfs_lowmemorykiller</type>
+        <type type="target">mdnsd_exec</type>
+        <type type="target">console_device</type>
+        <type type="target">rild</type>
+        <type type="target">hw_random_device</type>
+        <type type="target">radio_prop</type>
+        <type type="target">wallpaper_file</type>
+        <type type="target">surfaceflinger_exec</type>
+        <type type="target">audio_prop</type>
+        <type type="target">port</type>
+        <type type="target">gps_device</type>
+        <type type="target">vcs_device</type>
+        <type type="target">alarm_device</type>
+        <type type="target">keystore_tmpfs</type>
+        <type type="target">logd_socket</type>
+        <type type="target">inputflinger_exec</type>
+        <type type="target">gpu_device</type>
+        <type type="target">unlabeled</type>
+        <type type="target">racoon_exec</type>
+        <type type="target">init_tmpfs</type>
+        <type type="target">binder_device</type>
+        <type type="target">servicemanager_tmpfs</type>
+        <type type="target">sysfs_wake_lock</type>
+        <type type="target">system_app</type>
+        <type type="target">vold_exec</type>
+        <type type="target">powerctl_prop</type>
+        <type type="target">proc</type>
+        <type type="target">tee_device</type>
+        <type type="target">su_exec</type>
+        <type type="target">usermodehelper</type>
+        <type type="target">ppp_device</type>
+        <type type="target">watchdog_device</type>
+        <type type="target">netd_tmpfs</type>
+        <type type="target">debugfs</type>
+        <type type="target">wpa_socket</type>
+        <type type="target">rpmsg_device</type>
+        <type type="target">anr_data_file</type>
+        <type type="target">lmkd_tmpfs</type>
+        <type type="target">mdnsd_tmpfs</type>
+        <type type="target">logd_tmpfs</type>
+        <type type="target">proc_bluetooth_writable</type>
+        <type type="target">dhcp_exec</type>
+        <type type="target">gpsd</type>
+        <type type="target">log_device</type>
+        <type type="target">mediaserver_tmpfs</type>
+        <type type="target">security_prop</type>
+        <type type="target">vold_tmpfs</type>
+        <type type="target">system_server</type>
+        <type type="target">runas_exec</type>
+        <type type="target">adbd_socket</type>
+        <type type="target">radio_data_file</type>
+        <type type="target">tee_exec</type>
+        <type type="target">backup_data_file</type>
+        <type type="target">full_device</type>
+        <type type="target">kmsg_device</type>
+        <type type="target">ram_device</type>
+        <type type="target">inotify</type>
+        <type type="target">loop_device</type>
+        <type type="target">mtd_device</type>
+        <type type="target">random_device</type>
+        <type type="target">apk_private_tmp_file</type>
+        <type type="target">installd_socket</type>
+        <type type="target">camera_data_file</type>
+        <type type="target">uncrypt</type>
+        <type type="target">asec_public_file</type>
+        <type type="target">mediaserver</type>
+        <type type="target">graphics_device</type>
+        <type type="target">dumpstate_tmpfs</type>
+        <type type="target">usb_device</type>
+        <type type="target">vold</type>
+        <type type="target">drm_data_file</type>
+        <type type="target">sdcard_external</type>
+        <type type="target">gps_control</type>
+        <type type="target">mdns_socket</type>
+        <type type="target">logd_debug</type>
+        <type type="target">rild_debug_socket</type>
+        <type type="target">mtp_tmpfs</type>
+        <type type="target">release_app_tmpfs</type>
+        <type type="target">root_block_device</type>
+        <type type="target">dnsmasq</type>
+        <type type="target">sdcard_internal</type>
+        <type type="target">dm_device</type>
+        <type type="target">download_file</type>
+        <type type="target">inputflinger_tmpfs</type>
+        <type type="target">netd_socket</type>
+        <type type="target">racoon_tmpfs</type>
+        <type type="target">sensors_device</type>
+        <type type="target">hostapd_exec</type>
+        <type type="target">watchdogd</type>
+        <type type="target">system_file</type>
+        <type type="target">pipefs</type>
+        <type type="target">fscklogs</type>
+        <type type="target">rild_prop</type>
+        <type type="target">hci_attach_exec</type>
+        <type type="target">gpsd_exec</type>
+        <type type="target">bootanim_tmpfs</type>
+        <type type="target">servicemanager_exec</type>
+        <type type="target">proc_net</type>
+        <type type="target">shell_exec</type>
+        <type type="target">null_device</type>
+        <type type="target">debug_prop</type>
+        <type type="target">serial_device</type>
+        <type type="target">bluetooth_tmpfs</type>
+        <type type="target">sysfs_writable</type>
+        <type type="target">devpts</type>
+        <type type="target">wpa_tmpfs</type>
+        <type type="target">racoon</type>
+        <type type="target">shell</type>
+        <type type="target">video_device</type>
+        <type type="target">racoon_socket</type>
+        <type type="target">usbaccessory_device</type>
+        <type type="target">dumpstate</type>
+        <type type="target">adbd</type>
+        <type type="target">bootanim</type>
+        <type type="target">owntty_device</type>
+        <type type="target">untrusted_app</type>
+        <type type="target">sysfs_bluetooth_writable</type>
+        <type type="target">mtp_device</type>
+        <type type="target">vold_prop</type>
+        <type type="target">ctl_default_prop</type>
+        <type type="target">vpn_data_file</type>
+        <type type="target">dnsmasq_exec</type>
+        <type type="target">socket_device</type>
+        <type type="target">keystore_data_file</type>
+        <type type="target">installd_tmpfs</type>
+        <type type="target">sysfs_devices_system_cpu</type>
+        <type type="target">drmserver_exec</type>
+        <type type="target">proc_security</type>
+        <type type="target">sysfs</type>
+        <type type="target">properties_device</type>
+        <type type="target">block_device</type>
+        <type type="target">gps_data_file</type>
+        <type type="target">mtp</type>
+        <type type="target">inputflinger</type>
+        <type type="target">surfaceflinger</type>
+        <type type="target">systemkeys_data_file</type>
+        <type type="target">cache_file</type>
+        <type type="target">dalvikcache_data_file</type>
+        <type type="target">mdnsd</type>
+        <type type="target">mdnsd_socket</type>
+        <type type="target">lmkd_exec</type>
+        <type type="target">netd_exec</type>
+        <type type="target">nfc_device</type>
+        <type type="target">kmem_device</type>
+        <type type="target">ashmem_device</type>
+        <type type="target">sdcardd</type>
+        <type type="target">hci_attach</type>
+        <type type="target">dnsproxyd_socket</type>
+        <type type="target">wifi_data_file</type>
+        <type type="target">gps_socket</type>
+        <type type="target">fuse_device</type>
+        <type type="target">dhcp_tmpfs</type>
+        <type type="target">mtp_exec</type>
+        <type type="target">nfc_data_file</type>
+        <type type="target">tee_tmpfs</type>
+        <type type="target">default_prop</type>
+        <type type="target">input_device</type>
+        <type type="target">dumpstate_exec</type>
+        <type type="target">drmserver</type>
+        <type type="target">logdw_socket</type>
+        <type type="target">uncrypt_tmpfs</type>
+        <type type="target">rild_tmpfs</type>
+        <type type="target">zygote_exec</type>
+        <type type="target">keystore</type>
+        <type type="target">radio_tmpfs</type>
+        <type type="target">clatd</type>
+        <type type="target">zero_device</type>
+        <type type="target">recovery</type>
+        <type type="target">ctl_dumpstate_prop</type>
+        <type type="target">adb_device</type>
+        <type type="target">ppp</type>
+        <type type="target">rild_socket</type>
+        <type type="target">ptmx_device</type>
+        <type type="target">apk_private_data_file</type>
+        <type type="target">tun_device</type>
+        <type type="target">uncrypt_exec</type>
+        <type type="target">media_data_file</type>
+        <type type="target">media_app_tmpfs</type>
+        <type type="target">untrusted_app_tmpfs</type>
+        <type type="target">ctl_rildaemon_prop</type>
+        <type type="target">healthd</type>
+        <type type="target">node</type>
+        <type type="target">isolated_app_tmpfs</type>
+        <type type="target">radio_device</type>
+        <type type="target">urandom_device</type>
+        <type type="target">tombstone_data_file</type>
+        <type type="target">shared_app_tmpfs</type>
+        <type type="target">security_file</type>
+        <type type="target">system_data_file</type>
+        <type type="target">qtaguid_proc</type>
+        <type type="target">tty_device</type>
+        <type type="target">sdcardd_tmpfs</type>
+        <type type="target">isolated_app</type>
+        <type type="target">ueventd_tmpfs</type>
+        <type type="target">installd_exec</type>
+        <type type="target">system_prop</type>
+        <type type="target">platform_app_tmpfs</type>
+        <type type="target">wpa</type>
+        <type type="target">rootfs</type>
+        <type type="target">app_data_file</type>
+        <type type="target">apk_data_file</type>
+        <type type="target">dhcp_data_file</type>
+        <type type="target">asec_apk_file</type>
+        <type type="target">platform_app_data_file</type>
+        <type type="target">keystore_exec</type>
+        <type type="target">bluetooth_data_file</type>
+        <type type="target">klog_device</type>
+        <type type="target">debuggerd_prop</type>
+        <type type="target">vold_socket</type>
+        <type type="target">bluetooth_efs_file</type>
+        <type type="target">installd</type>
+        <type type="target">shell_tmpfs</type>
+        <type type="target">shared_app</type>
+        <obj_class name="fifo_file">
+            <permission>relabelto</permission>
+        </obj_class>
+        <obj_class name="chr_file">
+            <permission>relabelto</permission>
+        </obj_class>
+        <obj_class name="file">
+            <permission>relabelto</permission>
+        </obj_class>
+        <obj_class name="sock_file">
+            <permission>relabelto</permission>
+        </obj_class>
+        <obj_class name="blk_file">
+            <permission>relabelto</permission>
+        </obj_class>
+        <obj_class name="lnk_file">
+            <permission>relabelto</permission>
+        </obj_class>
+        <obj_class name="dir">
+            <permission>relabelto</permission>
+        </obj_class>
+    </avc_rule>
+    <avc_rule name="3" type="neverallow">
+        <type type="source">kernel</type>
+        <type type="source">sdcardd</type>
+        <type type="source">init_shell</type>
+        <type type="source">adbd</type>
+        <type type="source">netd</type>
+        <type type="source">tee</type>
+        <type type="source">bluetooth</type>
+        <type type="source">lmkd</type>
+        <type type="source">surfaceflinger</type>
+        <type type="source">mdnsd</type>
+        <type type="source">radio</type>
+        <type type="source">hci_attach</type>
+        <type type="source">clatd</type>
+        <type type="source">watchdogd</type>
+        <type type="source">drmserver</type>
+        <type type="source">keystore</type>
+        <type type="source">recovery</type>
+        <type type="source">runas</type>
+        <type type="source">init</type>
+        <type type="source">servicemanager</type>
+        <type type="source">dhcp</type>
+        <type type="source">shell</type>
+        <type type="source">uncrypt</type>
+        <type type="source">untrusted_app</type>
+        <type type="source">ueventd</type>
+        <type type="source">gpsd</type>
+        <type type="source">isolated_app</type>
+        <type type="source">system_app</type>
+        <type type="source">media_app</type>
+        <type type="source">wpa</type>
+        <type type="source">racoon</type>
+        <type type="source">nfc</type>
+        <type type="source">shared_app</type>
+        <type type="source">hostapd</type>
+        <type type="source">platform_app</type>
+        <type type="source">mtp</type>
+        <type type="source">inputflinger</type>
+        <type type="source">logd</type>
+        <type type="source">zygote</type>
+        <type type="source">rild</type>
+        <type type="source">dnsmasq</type>
+        <type type="source">healthd</type>
+        <type type="source">mediaserver</type>
+        <type type="source">bootanim</type>
+        <type type="source">ppp</type>
+        <type type="source">release_app</type>
+        <type type="source">installd</type>
+        <type type="target">self</type>
+        <obj_class name="capability">
+            <permission>sys_ptrace</permission>
+        </obj_class>
+    </avc_rule>
+    <avc_rule name="4" type="neverallow">
+        <type type="source">sdcardd</type>
+        <type type="source">init_shell</type>
+        <type type="source">adbd</type>
+        <type type="source">debuggerd</type>
+        <type type="source">netd</type>
+        <type type="source">tee</type>
+        <type type="source">bluetooth</type>
+        <type type="source">lmkd</type>
+        <type type="source">surfaceflinger</type>
+        <type type="source">mdnsd</type>
+        <type type="source">radio</type>
+        <type type="source">hci_attach</type>
+        <type type="source">clatd</type>
+        <type type="source">drmserver</type>
+        <type type="source">keystore</type>
+        <type type="source">runas</type>
+        <type type="source">servicemanager</type>
+        <type type="source">dhcp</type>
+        <type type="source">shell</type>
+        <type type="source">untrusted_app</type>
+        <type type="source">gpsd</type>
+        <type type="source">isolated_app</type>
+        <type type="source">system_app</type>
+        <type type="source">media_app</type>
+        <type type="source">system_server</type>
+        <type type="source">wpa</type>
+        <type type="source">racoon</type>
+        <type type="source">dumpstate</type>
+        <type type="source">nfc</type>
+        <type type="source">shared_app</type>
+        <type type="source">hostapd</type>
+        <type type="source">platform_app</type>
+        <type type="source">mtp</type>
+        <type type="source">inputflinger</type>
+        <type type="source">logd</type>
+        <type type="source">zygote</type>
+        <type type="source">rild</type>
+        <type type="source">dnsmasq</type>
+        <type type="source">mediaserver</type>
+        <type type="source">bootanim</type>
+        <type type="source">ppp</type>
+        <type type="source">release_app</type>
+        <type type="source">installd</type>
+        <type type="target">self</type>
+        <obj_class name="capability">
+            <permission>sys_rawio</permission>
+            <permission>mknod</permission>
+        </obj_class>
+    </avc_rule>
+    <avc_rule name="5" type="neverallow">
+        <type type="source">kernel</type>
+        <type type="source">sdcardd</type>
+        <type type="source">init_shell</type>
+        <type type="source">adbd</type>
+        <type type="source">vold</type>
+        <type type="source">debuggerd</type>
+        <type type="source">netd</type>
+        <type type="source">tee</type>
+        <type type="source">bluetooth</type>
+        <type type="source">lmkd</type>
+        <type type="source">surfaceflinger</type>
+        <type type="source">mdnsd</type>
+        <type type="source">radio</type>
+        <type type="source">hci_attach</type>
+        <type type="source">clatd</type>
+        <type type="source">watchdogd</type>
+        <type type="source">drmserver</type>
+        <type type="source">keystore</type>
+        <type type="source">recovery</type>
+        <type type="source">runas</type>
+        <type type="source">init</type>
+        <type type="source">servicemanager</type>
+        <type type="source">dhcp</type>
+        <type type="source">shell</type>
+        <type type="source">uncrypt</type>
+        <type type="source">untrusted_app</type>
+        <type type="source">ueventd</type>
+        <type type="source">gpsd</type>
+        <type type="source">isolated_app</type>
+        <type type="source">system_app</type>
+        <type type="source">media_app</type>
+        <type type="source">system_server</type>
+        <type type="source">wpa</type>
+        <type type="source">racoon</type>
+        <type type="source">dumpstate</type>
+        <type type="source">nfc</type>
+        <type type="source">shared_app</type>
+        <type type="source">hostapd</type>
+        <type type="source">platform_app</type>
+        <type type="source">mtp</type>
+        <type type="source">inputflinger</type>
+        <type type="source">logd</type>
+        <type type="source">zygote</type>
+        <type type="source">rild</type>
+        <type type="source">dnsmasq</type>
+        <type type="source">healthd</type>
+        <type type="source">mediaserver</type>
+        <type type="source">bootanim</type>
+        <type type="source">ppp</type>
+        <type type="source">release_app</type>
+        <type type="source">installd</type>
+        <type type="target">self</type>
+        <obj_class name="capability2">
+            <permission>mac_override</permission>
+        </obj_class>
+    </avc_rule>
+    <avc_rule name="6" type="neverallow">
+        <type type="source">kernel</type>
+        <type type="source">sdcardd</type>
+        <type type="source">init_shell</type>
+        <type type="source">adbd</type>
+        <type type="source">vold</type>
+        <type type="source">debuggerd</type>
+        <type type="source">netd</type>
+        <type type="source">tee</type>
+        <type type="source">bluetooth</type>
+        <type type="source">lmkd</type>
+        <type type="source">surfaceflinger</type>
+        <type type="source">mdnsd</type>
+        <type type="source">radio</type>
+        <type type="source">hci_attach</type>
+        <type type="source">clatd</type>
+        <type type="source">watchdogd</type>
+        <type type="source">drmserver</type>
+        <type type="source">keystore</type>
+        <type type="source">runas</type>
+        <type type="source">init</type>
+        <type type="source">servicemanager</type>
+        <type type="source">dhcp</type>
+        <type type="source">shell</type>
+        <type type="source">uncrypt</type>
+        <type type="source">untrusted_app</type>
+        <type type="source">ueventd</type>
+        <type type="source">gpsd</type>
+        <type type="source">isolated_app</type>
+        <type type="source">system_app</type>
+        <type type="source">media_app</type>
+        <type type="source">system_server</type>
+        <type type="source">wpa</type>
+        <type type="source">racoon</type>
+        <type type="source">dumpstate</type>
+        <type type="source">nfc</type>
+        <type type="source">shared_app</type>
+        <type type="source">hostapd</type>
+        <type type="source">platform_app</type>
+        <type type="source">mtp</type>
+        <type type="source">inputflinger</type>
+        <type type="source">logd</type>
+        <type type="source">zygote</type>
+        <type type="source">rild</type>
+        <type type="source">dnsmasq</type>
+        <type type="source">healthd</type>
+        <type type="source">mediaserver</type>
+        <type type="source">bootanim</type>
+        <type type="source">ppp</type>
+        <type type="source">release_app</type>
+        <type type="source">installd</type>
+        <type type="target">self</type>
+        <obj_class name="capability2">
+            <permission>mac_admin</permission>
+        </obj_class>
+    </avc_rule>
+    <avc_rule name="7" type="neverallow">
+        <type type="source">kernel</type>
+        <type type="source">sdcardd</type>
+        <type type="source">init_shell</type>
+        <type type="source">adbd</type>
+        <type type="source">vold</type>
+        <type type="source">debuggerd</type>
+        <type type="source">netd</type>
+        <type type="source">tee</type>
+        <type type="source">bluetooth</type>
+        <type type="source">lmkd</type>
+        <type type="source">surfaceflinger</type>
+        <type type="source">mdnsd</type>
+        <type type="source">radio</type>
+        <type type="source">hci_attach</type>
+        <type type="source">clatd</type>
+        <type type="source">watchdogd</type>
+        <type type="source">drmserver</type>
+        <type type="source">keystore</type>
+        <type type="source">recovery</type>
+        <type type="source">runas</type>
+        <type type="source">servicemanager</type>
+        <type type="source">dhcp</type>
+        <type type="source">shell</type>
+        <type type="source">uncrypt</type>
+        <type type="source">untrusted_app</type>
+        <type type="source">ueventd</type>
+        <type type="source">gpsd</type>
+        <type type="source">isolated_app</type>
+        <type type="source">system_app</type>
+        <type type="source">media_app</type>
+        <type type="source">system_server</type>
+        <type type="source">wpa</type>
+        <type type="source">racoon</type>
+        <type type="source">dumpstate</type>
+        <type type="source">nfc</type>
+        <type type="source">shared_app</type>
+        <type type="source">hostapd</type>
+        <type type="source">platform_app</type>
+        <type type="source">mtp</type>
+        <type type="source">inputflinger</type>
+        <type type="source">logd</type>
+        <type type="source">zygote</type>
+        <type type="source">rild</type>
+        <type type="source">dnsmasq</type>
+        <type type="source">healthd</type>
+        <type type="source">mediaserver</type>
+        <type type="source">bootanim</type>
+        <type type="source">ppp</type>
+        <type type="source">release_app</type>
+        <type type="source">installd</type>
+        <type type="target">kernel</type>
+        <obj_class name="security">
+            <permission>load_policy</permission>
+        </obj_class>
+    </avc_rule>
+    <avc_rule name="8" type="neverallow">
+        <type type="source">vold</type>
+        <type type="source">sdcardd</type>
+        <type type="source">init_shell</type>
+        <type type="source">adbd</type>
+        <type type="source">debuggerd</type>
+        <type type="source">netd</type>
+        <type type="source">tee</type>
+        <type type="source">bluetooth</type>
+        <type type="source">lmkd</type>
+        <type type="source">surfaceflinger</type>
+        <type type="source">mdnsd</type>
+        <type type="source">radio</type>
+        <type type="source">hci_attach</type>
+        <type type="source">clatd</type>
+        <type type="source">watchdogd</type>
+        <type type="source">drmserver</type>
+        <type type="source">keystore</type>
+        <type type="source">recovery</type>
+        <type type="source">runas</type>
+        <type type="source">init</type>
+        <type type="source">servicemanager</type>
+        <type type="source">dhcp</type>
+        <type type="source">shell</type>
+        <type type="source">uncrypt</type>
+        <type type="source">untrusted_app</type>
+        <type type="source">ueventd</type>
+        <type type="source">gpsd</type>
+        <type type="source">isolated_app</type>
+        <type type="source">system_app</type>
+        <type type="source">media_app</type>
+        <type type="source">system_server</type>
+        <type type="source">wpa</type>
+        <type type="source">racoon</type>
+        <type type="source">dumpstate</type>
+        <type type="source">nfc</type>
+        <type type="source">shared_app</type>
+        <type type="source">hostapd</type>
+        <type type="source">platform_app</type>
+        <type type="source">mtp</type>
+        <type type="source">inputflinger</type>
+        <type type="source">logd</type>
+        <type type="source">zygote</type>
+        <type type="source">rild</type>
+        <type type="source">dnsmasq</type>
+        <type type="source">healthd</type>
+        <type type="source">mediaserver</type>
+        <type type="source">bootanim</type>
+        <type type="source">ppp</type>
+        <type type="source">release_app</type>
+        <type type="source">installd</type>
+        <type type="target">kernel</type>
+        <obj_class name="security">
+            <permission>setenforce</permission>
+            <permission>setcheckreqprot</permission>
+        </obj_class>
+    </avc_rule>
+    <avc_rule name="9" type="neverallow">
+        <type type="source">kernel</type>
+        <type type="source">sdcardd</type>
+        <type type="source">init_shell</type>
+        <type type="source">adbd</type>
+        <type type="source">vold</type>
+        <type type="source">debuggerd</type>
+        <type type="source">netd</type>
+        <type type="source">tee</type>
+        <type type="source">bluetooth</type>
+        <type type="source">lmkd</type>
+        <type type="source">surfaceflinger</type>
+        <type type="source">mdnsd</type>
+        <type type="source">radio</type>
+        <type type="source">hci_attach</type>
+        <type type="source">clatd</type>
+        <type type="source">watchdogd</type>
+        <type type="source">drmserver</type>
+        <type type="source">keystore</type>
+        <type type="source">recovery</type>
+        <type type="source">runas</type>
+        <type type="source">init</type>
+        <type type="source">servicemanager</type>
+        <type type="source">dhcp</type>
+        <type type="source">shell</type>
+        <type type="source">uncrypt</type>
+        <type type="source">untrusted_app</type>
+        <type type="source">ueventd</type>
+        <type type="source">gpsd</type>
+        <type type="source">isolated_app</type>
+        <type type="source">system_app</type>
+        <type type="source">media_app</type>
+        <type type="source">system_server</type>
+        <type type="source">wpa</type>
+        <type type="source">racoon</type>
+        <type type="source">dumpstate</type>
+        <type type="source">nfc</type>
+        <type type="source">shared_app</type>
+        <type type="source">hostapd</type>
+        <type type="source">platform_app</type>
+        <type type="source">mtp</type>
+        <type type="source">inputflinger</type>
+        <type type="source">logd</type>
+        <type type="source">zygote</type>
+        <type type="source">rild</type>
+        <type type="source">dnsmasq</type>
+        <type type="source">healthd</type>
+        <type type="source">mediaserver</type>
+        <type type="source">bootanim</type>
+        <type type="source">ppp</type>
+        <type type="source">release_app</type>
+        <type type="source">installd</type>
+        <type type="target">system_server_tmpfs</type>
+        <type type="target">logdr_socket</type>
+        <type type="target">lmkd_socket</type>
+        <type type="target">system_wpa_socket</type>
+        <type type="target">ueventd_tmpfs</type>
+        <type type="target">dumpstate_socket</type>
+        <type type="target">wpa_tmpfs</type>
+        <type type="target">property_socket</type>
+        <type type="target">shell_data_file</type>
+        <type type="target">debuggerd_tmpfs</type>
+        <type type="target">bootanim_tmpfs</type>
+        <type type="target">apk_tmp_file</type>
+        <type type="target">gpsd_tmpfs</type>
+        <type type="target">bluetooth_socket</type>
+        <type type="target">adb_keys_file</type>
+        <type type="target">system_app_tmpfs</type>
+        <type type="target">media_rw_data_file</type>
+        <type type="target">shared_app_tmpfs</type>
+        <type type="target">backup_data_file</type>
+        <type type="target">zygote_socket</type>
+        <type type="target">tee_data_file</type>
+        <type type="target">cache_backup_file</type>
+        <type type="target">drmserver_socket</type>
+        <type type="target">system_ndebug_socket</type>
+        <type type="target">nfc_tmpfs</type>
+        <type type="target">zoneinfo_data_file</type>
+        <type type="target">radio_data_file</type>
+        <type type="target">surfaceflinger_tmpfs</type>
+        <type type="target">apk_private_tmp_file</type>
+        <type type="target">hci_attach_tmpfs</type>
+        <type type="target">rild_debug_socket</type>
+        <type type="target">wallpaper_file</type>
+        <type type="target">sdcardd_tmpfs</type>
+        <type type="target">keystore_tmpfs</type>
+        <type type="target">bluetooth_data_file</type>
+        <type type="target">init_tmpfs</type>
+        <type type="target">servicemanager_tmpfs</type>
+        <type type="target">efs_file</type>
+        <type type="target">installd_socket</type>
+        <type type="target">inputflinger_tmpfs</type>
+        <type type="target">netd_tmpfs</type>
+        <type type="target">wpa_socket</type>
+        <type type="target">anr_data_file</type>
+        <type type="target">lmkd_tmpfs</type>
+        <type type="target">mdnsd_tmpfs</type>
+        <type type="target">logd_tmpfs</type>
+        <type type="target">mediaserver_tmpfs</type>
+        <type type="target">vold_tmpfs</type>
+        <type type="target">dnsproxyd_socket</type>
+        <type type="target">adbd_socket</type>
+        <type type="target">camera_data_file</type>
+        <type type="target">asec_public_file</type>
+        <type type="target">dumpstate_tmpfs</type>
+        <type type="target">drm_data_file</type>
+        <type type="target">gps_control</type>
+        <type type="target">logd_debug</type>
+        <type type="target">mtp_tmpfs</type>
+        <type type="target">release_app_tmpfs</type>
+        <type type="target">download_file</type>
+        <type type="target">netd_socket</type>
+        <type type="target">racoon_tmpfs</type>
+        <type type="target">system_file</type>
+        <type type="target">asec_image_file</type>
+        <type type="target">tombstone_data_file</type>
+        <type type="target">racoon_socket</type>
+        <type type="target">logd_socket</type>
+        <type type="target">untrusted_app_tmpfs</type>
+        <type type="target">vpn_data_file</type>
+        <type type="target">keystore_data_file</type>
+        <type type="target">bluetooth_tmpfs</type>
+        <type type="target">drmserver_tmpfs</type>
+        <type type="target">gps_data_file</type>
+        <type type="target">systemkeys_data_file</type>
+        <type type="target">cache_file</type>
+        <type type="target">dalvikcache_data_file</type>
+        <type type="target">installd_tmpfs</type>
+        <type type="target">mdnsd_socket</type>
+        <type type="target">mdns_socket</type>
+        <type type="target">wifi_data_file</type>
+        <type type="target">gps_socket</type>
+        <type type="target">dhcp_tmpfs</type>
+        <type type="target">nfc_data_file</type>
+        <type type="target">tee_tmpfs</type>
+        <type type="target">zygote_tmpfs</type>
+        <type type="target">uncrypt_tmpfs</type>
+        <type type="target">rild_tmpfs</type>
+        <type type="target">isolated_app_tmpfs</type>
+        <type type="target">radio_tmpfs</type>
+        <type type="target">rild_socket</type>
+        <type type="target">media_data_file</type>
+        <type type="target">media_app_tmpfs</type>
+        <type type="target">audio_data_file</type>
+        <type type="target">unlabeled</type>
+        <type type="target">security_file</type>
+        <type type="target">system_data_file</type>
+        <type type="target">bluetooth_efs_file</type>
+        <type type="target">platform_app_tmpfs</type>
+        <type type="target">app_data_file</type>
+        <type type="target">dhcp_data_file</type>
+        <type type="target">asec_apk_file</type>
+        <type type="target">platform_app_data_file</type>
+        <type type="target">logdw_socket</type>
+        <type type="target">apk_private_data_file</type>
+        <type type="target">vold_socket</type>
+        <type type="target">apk_data_file</type>
+        <type type="target">shell_tmpfs</type>
+        <obj_class name="file">
+            <permission>entrypoint</permission>
+        </obj_class>
+    </avc_rule>
+    <avc_rule name="10" type="neverallow">
+        <type type="source">vold</type>
+        <type type="source">sdcardd</type>
+        <type type="source">init_shell</type>
+        <type type="source">adbd</type>
+        <type type="source">debuggerd</type>
+        <type type="source">netd</type>
+        <type type="source">tee</type>
+        <type type="source">bluetooth</type>
+        <type type="source">lmkd</type>
+        <type type="source">surfaceflinger</type>
+        <type type="source">mdnsd</type>
+        <type type="source">radio</type>
+        <type type="source">hci_attach</type>
+        <type type="source">clatd</type>
+        <type type="source">watchdogd</type>
+        <type type="source">drmserver</type>
+        <type type="source">keystore</type>
+        <type type="source">recovery</type>
+        <type type="source">runas</type>
+        <type type="source">servicemanager</type>
+        <type type="source">dhcp</type>
+        <type type="source">shell</type>
+        <type type="source">uncrypt</type>
+        <type type="source">untrusted_app</type>
+        <type type="source">gpsd</type>
+        <type type="source">isolated_app</type>
+        <type type="source">system_app</type>
+        <type type="source">media_app</type>
+        <type type="source">system_server</type>
+        <type type="source">wpa</type>
+        <type type="source">racoon</type>
+        <type type="source">dumpstate</type>
+        <type type="source">nfc</type>
+        <type type="source">shared_app</type>
+        <type type="source">hostapd</type>
+        <type type="source">platform_app</type>
+        <type type="source">mtp</type>
+        <type type="source">inputflinger</type>
+        <type type="source">logd</type>
+        <type type="source">zygote</type>
+        <type type="source">rild</type>
+        <type type="source">dnsmasq</type>
+        <type type="source">healthd</type>
+        <type type="source">mediaserver</type>
+        <type type="source">bootanim</type>
+        <type type="source">ppp</type>
+        <type type="source">release_app</type>
+        <type type="source">installd</type>
+        <type type="target">kmem_device</type>
+        <obj_class name="chr_file">
+            <permission>rename</permission>
+            <permission>lock</permission>
+            <permission>quotaon</permission>
+            <permission>execute_no_trans</permission>
+            <permission>open</permission>
+            <permission>append</permission>
+            <permission>create</permission>
+            <permission>write</permission>
+            <permission>relabelfrom</permission>
+            <permission>getattr</permission>
+            <permission>entrypoint</permission>
+            <permission>read</permission>
+            <permission>mounton</permission>
+            <permission>ioctl</permission>
+            <permission>link</permission>
+            <permission>unlink</permission>
+            <permission>swapon</permission>
+            <permission>execute</permission>
+            <permission>setattr</permission>
+            <permission>execmod</permission>
+            <permission>relabelto</permission>
+            <permission>audit_access</permission>
+        </obj_class>
+    </avc_rule>
+    <avc_rule name="11" type="neverallow">
+        <type type="source">kernel</type>
+        <type type="source">sdcardd</type>
+        <type type="source">init_shell</type>
+        <type type="source">adbd</type>
+        <type type="source">vold</type>
+        <type type="source">debuggerd</type>
+        <type type="source">netd</type>
+        <type type="source">tee</type>
+        <type type="source">bluetooth</type>
+        <type type="source">lmkd</type>
+        <type type="source">surfaceflinger</type>
+        <type type="source">mdnsd</type>
+        <type type="source">radio</type>
+        <type type="source">hci_attach</type>
+        <type type="source">clatd</type>
+        <type type="source">watchdogd</type>
+        <type type="source">drmserver</type>
+        <type type="source">keystore</type>
+        <type type="source">recovery</type>
+        <type type="source">runas</type>
+        <type type="source">init</type>
+        <type type="source">servicemanager</type>
+        <type type="source">dhcp</type>
+        <type type="source">shell</type>
+        <type type="source">uncrypt</type>
+        <type type="source">untrusted_app</type>
+        <type type="source">ueventd</type>
+        <type type="source">gpsd</type>
+        <type type="source">isolated_app</type>
+        <type type="source">system_app</type>
+        <type type="source">media_app</type>
+        <type type="source">system_server</type>
+        <type type="source">wpa</type>
+        <type type="source">racoon</type>
+        <type type="source">dumpstate</type>
+        <type type="source">nfc</type>
+        <type type="source">shared_app</type>
+        <type type="source">hostapd</type>
+        <type type="source">platform_app</type>
+        <type type="source">mtp</type>
+        <type type="source">inputflinger</type>
+        <type type="source">logd</type>
+        <type type="source">zygote</type>
+        <type type="source">rild</type>
+        <type type="source">dnsmasq</type>
+        <type type="source">healthd</type>
+        <type type="source">mediaserver</type>
+        <type type="source">bootanim</type>
+        <type type="source">ppp</type>
+        <type type="source">release_app</type>
+        <type type="source">installd</type>
+        <type type="target">kmem_device</type>
+        <obj_class name="chr_file">
+            <permission>rename</permission>
+            <permission>execute</permission>
+            <permission>open</permission>
+            <permission>read</permission>
+            <permission>lock</permission>
+            <permission>audit_access</permission>
+            <permission>quotaon</permission>
+            <permission>getattr</permission>
+            <permission>execute_no_trans</permission>
+            <permission>mounton</permission>
+            <permission>write</permission>
+            <permission>relabelfrom</permission>
+            <permission>ioctl</permission>
+            <permission>link</permission>
+            <permission>entrypoint</permission>
+            <permission>swapon</permission>
+            <permission>execmod</permission>
+            <permission>append</permission>
+        </obj_class>
+    </avc_rule>
+    <avc_rule name="12" type="neverallow">
+        <type type="source">kernel</type>
+        <type type="source">sdcardd</type>
+        <type type="source">init_shell</type>
+        <type type="source">adbd</type>
+        <type type="source">vold</type>
+        <type type="source">debuggerd</type>
+        <type type="source">netd</type>
+        <type type="source">tee</type>
+        <type type="source">bluetooth</type>
+        <type type="source">lmkd</type>
+        <type type="source">surfaceflinger</type>
+        <type type="source">mdnsd</type>
+        <type type="source">radio</type>
+        <type type="source">hci_attach</type>
+        <type type="source">clatd</type>
+        <type type="source">watchdogd</type>
+        <type type="source">drmserver</type>
+        <type type="source">keystore</type>
+        <type type="source">recovery</type>
+        <type type="source">runas</type>
+        <type type="source">servicemanager</type>
+        <type type="source">dhcp</type>
+        <type type="source">shell</type>
+        <type type="source">uncrypt</type>
+        <type type="source">untrusted_app</type>
+        <type type="source">ueventd</type>
+        <type type="source">gpsd</type>
+        <type type="source">isolated_app</type>
+        <type type="source">system_app</type>
+        <type type="source">media_app</type>
+        <type type="source">system_server</type>
+        <type type="source">wpa</type>
+        <type type="source">racoon</type>
+        <type type="source">dumpstate</type>
+        <type type="source">nfc</type>
+        <type type="source">shared_app</type>
+        <type type="source">hostapd</type>
+        <type type="source">platform_app</type>
+        <type type="source">mtp</type>
+        <type type="source">inputflinger</type>
+        <type type="source">logd</type>
+        <type type="source">zygote</type>
+        <type type="source">rild</type>
+        <type type="source">dnsmasq</type>
+        <type type="source">healthd</type>
+        <type type="source">mediaserver</type>
+        <type type="source">bootanim</type>
+        <type type="source">ppp</type>
+        <type type="source">release_app</type>
+        <type type="source">installd</type>
+        <type type="target">usermodehelper</type>
+        <obj_class name="file">
+            <permission>write</permission>
+            <permission>append</permission>
+        </obj_class>
+    </avc_rule>
+    <avc_rule name="13" type="neverallow">
+        <type type="source">kernel</type>
+        <type type="source">sdcardd</type>
+        <type type="source">init_shell</type>
+        <type type="source">adbd</type>
+        <type type="source">vold</type>
+        <type type="source">debuggerd</type>
+        <type type="source">netd</type>
+        <type type="source">tee</type>
+        <type type="source">bluetooth</type>
+        <type type="source">lmkd</type>
+        <type type="source">surfaceflinger</type>
+        <type type="source">mdnsd</type>
+        <type type="source">radio</type>
+        <type type="source">hci_attach</type>
+        <type type="source">clatd</type>
+        <type type="source">watchdogd</type>
+        <type type="source">drmserver</type>
+        <type type="source">keystore</type>
+        <type type="source">recovery</type>
+        <type type="source">runas</type>
+        <type type="source">servicemanager</type>
+        <type type="source">dhcp</type>
+        <type type="source">shell</type>
+        <type type="source">uncrypt</type>
+        <type type="source">untrusted_app</type>
+        <type type="source">ueventd</type>
+        <type type="source">gpsd</type>
+        <type type="source">isolated_app</type>
+        <type type="source">system_app</type>
+        <type type="source">media_app</type>
+        <type type="source">system_server</type>
+        <type type="source">wpa</type>
+        <type type="source">racoon</type>
+        <type type="source">dumpstate</type>
+        <type type="source">nfc</type>
+        <type type="source">shared_app</type>
+        <type type="source">hostapd</type>
+        <type type="source">platform_app</type>
+        <type type="source">mtp</type>
+        <type type="source">inputflinger</type>
+        <type type="source">logd</type>
+        <type type="source">zygote</type>
+        <type type="source">rild</type>
+        <type type="source">dnsmasq</type>
+        <type type="source">healthd</type>
+        <type type="source">mediaserver</type>
+        <type type="source">bootanim</type>
+        <type type="source">ppp</type>
+        <type type="source">release_app</type>
+        <type type="source">installd</type>
+        <type type="target">proc_security</type>
+        <obj_class name="file">
+            <permission>write</permission>
+            <permission>append</permission>
+        </obj_class>
+    </avc_rule>
+    <avc_rule name="14" type="neverallow">
+        <type type="source">kernel</type>
+        <type type="source">sdcardd</type>
+        <type type="source">init_shell</type>
+        <type type="source">adbd</type>
+        <type type="source">vold</type>
+        <type type="source">debuggerd</type>
+        <type type="source">netd</type>
+        <type type="source">tee</type>
+        <type type="source">bluetooth</type>
+        <type type="source">lmkd</type>
+        <type type="source">surfaceflinger</type>
+        <type type="source">mdnsd</type>
+        <type type="source">radio</type>
+        <type type="source">hci_attach</type>
+        <type type="source">clatd</type>
+        <type type="source">watchdogd</type>
+        <type type="source">drmserver</type>
+        <type type="source">keystore</type>
+        <type type="source">recovery</type>
+        <type type="source">runas</type>
+        <type type="source">init</type>
+        <type type="source">servicemanager</type>
+        <type type="source">dhcp</type>
+        <type type="source">shell</type>
+        <type type="source">uncrypt</type>
+        <type type="source">untrusted_app</type>
+        <type type="source">ueventd</type>
+        <type type="source">gpsd</type>
+        <type type="source">isolated_app</type>
+        <type type="source">system_app</type>
+        <type type="source">media_app</type>
+        <type type="source">system_server</type>
+        <type type="source">wpa</type>
+        <type type="source">racoon</type>
+        <type type="source">dumpstate</type>
+        <type type="source">nfc</type>
+        <type type="source">shared_app</type>
+        <type type="source">hostapd</type>
+        <type type="source">platform_app</type>
+        <type type="source">mtp</type>
+        <type type="source">inputflinger</type>
+        <type type="source">logd</type>
+        <type type="source">zygote</type>
+        <type type="source">rild</type>
+        <type type="source">dnsmasq</type>
+        <type type="source">healthd</type>
+        <type type="source">mediaserver</type>
+        <type type="source">bootanim</type>
+        <type type="source">ppp</type>
+        <type type="source">release_app</type>
+        <type type="source">installd</type>
+        <type type="target">init</type>
+        <obj_class name="process">
+            <permission>ptrace</permission>
+        </obj_class>
+    </avc_rule>
+    <avc_rule name="15" type="neverallow">
+        <type type="source">kernel</type>
+        <type type="source">sdcardd</type>
+        <type type="source">init_shell</type>
+        <type type="source">adbd</type>
+        <type type="source">vold</type>
+        <type type="source">debuggerd</type>
+        <type type="source">netd</type>
+        <type type="source">tee</type>
+        <type type="source">bluetooth</type>
+        <type type="source">lmkd</type>
+        <type type="source">surfaceflinger</type>
+        <type type="source">mdnsd</type>
+        <type type="source">radio</type>
+        <type type="source">hci_attach</type>
+        <type type="source">clatd</type>
+        <type type="source">watchdogd</type>
+        <type type="source">drmserver</type>
+        <type type="source">keystore</type>
+        <type type="source">recovery</type>
+        <type type="source">runas</type>
+        <type type="source">init</type>
+        <type type="source">servicemanager</type>
+        <type type="source">dhcp</type>
+        <type type="source">shell</type>
+        <type type="source">uncrypt</type>
+        <type type="source">untrusted_app</type>
+        <type type="source">ueventd</type>
+        <type type="source">gpsd</type>
+        <type type="source">isolated_app</type>
+        <type type="source">system_app</type>
+        <type type="source">media_app</type>
+        <type type="source">system_server</type>
+        <type type="source">wpa</type>
+        <type type="source">racoon</type>
+        <type type="source">dumpstate</type>
+        <type type="source">nfc</type>
+        <type type="source">shared_app</type>
+        <type type="source">hostapd</type>
+        <type type="source">platform_app</type>
+        <type type="source">mtp</type>
+        <type type="source">inputflinger</type>
+        <type type="source">logd</type>
+        <type type="source">zygote</type>
+        <type type="source">rild</type>
+        <type type="source">dnsmasq</type>
+        <type type="source">healthd</type>
+        <type type="source">mediaserver</type>
+        <type type="source">bootanim</type>
+        <type type="source">ppp</type>
+        <type type="source">release_app</type>
+        <type type="source">installd</type>
+        <type type="target">init</type>
+        <obj_class name="binder">
+            <permission>call</permission>
+        </obj_class>
+    </avc_rule>
+    <avc_rule name="16" type="neverallow">
+        <type type="source">sdcardd</type>
+        <type type="source">init_shell</type>
+        <type type="source">adbd</type>
+        <type type="source">debuggerd</type>
+        <type type="source">netd</type>
+        <type type="source">tee</type>
+        <type type="source">bluetooth</type>
+        <type type="source">lmkd</type>
+        <type type="source">surfaceflinger</type>
+        <type type="source">mdnsd</type>
+        <type type="source">radio</type>
+        <type type="source">hci_attach</type>
+        <type type="source">clatd</type>
+        <type type="source">watchdogd</type>
+        <type type="source">drmserver</type>
+        <type type="source">keystore</type>
+        <type type="source">runas</type>
+        <type type="source">servicemanager</type>
+        <type type="source">dhcp</type>
+        <type type="source">shell</type>
+        <type type="source">untrusted_app</type>
+        <type type="source">ueventd</type>
+        <type type="source">gpsd</type>
+        <type type="source">isolated_app</type>
+        <type type="source">system_app</type>
+        <type type="source">media_app</type>
+        <type type="source">system_server</type>
+        <type type="source">wpa</type>
+        <type type="source">racoon</type>
+        <type type="source">dumpstate</type>
+        <type type="source">nfc</type>
+        <type type="source">shared_app</type>
+        <type type="source">hostapd</type>
+        <type type="source">platform_app</type>
+        <type type="source">mtp</type>
+        <type type="source">inputflinger</type>
+        <type type="source">logd</type>
+        <type type="source">zygote</type>
+        <type type="source">rild</type>
+        <type type="source">dnsmasq</type>
+        <type type="source">healthd</type>
+        <type type="source">mediaserver</type>
+        <type type="source">bootanim</type>
+        <type type="source">ppp</type>
+        <type type="source">release_app</type>
+        <type type="source">installd</type>
+        <type type="target">block_device</type>
+        <obj_class name="blk_file">
+            <permission>read</permission>
+            <permission>write</permission>
+            <permission>open</permission>
+        </obj_class>
+    </avc_rule>
+    <avc_rule name="17" type="neverallow">
+        <type type="source">sdcardd</type>
+        <type type="source">init_shell</type>
+        <type type="source">adbd</type>
+        <type type="source">debuggerd</type>
+        <type type="source">netd</type>
+        <type type="source">tee</type>
+        <type type="source">bluetooth</type>
+        <type type="source">lmkd</type>
+        <type type="source">surfaceflinger</type>
+        <type type="source">mdnsd</type>
+        <type type="source">radio</type>
+        <type type="source">hci_attach</type>
+        <type type="source">clatd</type>
+        <type type="source">watchdogd</type>
+        <type type="source">drmserver</type>
+        <type type="source">keystore</type>
+        <type type="source">runas</type>
+        <type type="source">servicemanager</type>
+        <type type="source">dhcp</type>
+        <type type="source">shell</type>
+        <type type="source">uncrypt</type>
+        <type type="source">untrusted_app</type>
+        <type type="source">ueventd</type>
+        <type type="source">gpsd</type>
+        <type type="source">isolated_app</type>
+        <type type="source">system_app</type>
+        <type type="source">media_app</type>
+        <type type="source">system_server</type>
+        <type type="source">wpa</type>
+        <type type="source">racoon</type>
+        <type type="source">dumpstate</type>
+        <type type="source">nfc</type>
+        <type type="source">shared_app</type>
+        <type type="source">hostapd</type>
+        <type type="source">platform_app</type>
+        <type type="source">mtp</type>
+        <type type="source">inputflinger</type>
+        <type type="source">logd</type>
+        <type type="source">rild</type>
+        <type type="source">dnsmasq</type>
+        <type type="source">healthd</type>
+        <type type="source">mediaserver</type>
+        <type type="source">bootanim</type>
+        <type type="source">ppp</type>
+        <type type="source">release_app</type>
+        <type type="source">installd</type>
+        <type type="target">sysfs_nfc_power_writable</type>
+        <type type="target">sysfs_lowmemorykiller</type>
+        <type type="target">selinuxfs</type>
+        <type type="target">untrusted_app_devpts</type>
+        <type type="target">tmpfs</type>
+        <type type="target">sysfs</type>
+        <type type="target">sockfs</type>
+        <type type="target">proc_net</type>
+        <type type="target">sysfs_wake_lock</type>
+        <type type="target">rootfs</type>
+        <type type="target">proc</type>
+        <type type="target">usermodehelper</type>
+        <type type="target">devpts</type>
+        <type type="target">debugfs</type>
+        <type type="target">qtaguid_proc</type>
+        <type type="target">sysfs_bluetooth_writable</type>
+        <type type="target">labeledfs</type>
+        <type type="target">device</type>
+        <type type="target">pipefs</type>
+        <type type="target">mqueue</type>
+        <type type="target">sysfs_devices_system_cpu</type>
+        <type type="target">sysfs_writable</type>
+        <type type="target">proc_security</type>
+        <type type="target">inotify</type>
+        <type type="target">proc_bluetooth_writable</type>
+        <type type="target">cgroup</type>
+        <type type="target">shm</type>
+        <obj_class name="filesystem">
+            <permission>relabelfrom</permission>
+            <permission>relabelto</permission>
+            <permission>mount</permission>
+            <permission>remount</permission>
+        </obj_class>
+    </avc_rule>
+    <avc_rule name="18" type="neverallow">
+        <type type="source">logd</type>
+        <type type="target">ashmem_device</type>
+        <type type="target">fscklogs</type>
+        <type type="target">cpuctl_device</type>
+        <type type="target">iio_device</type>
+        <type type="target">audio_device</type>
+        <type type="target">root_block_device</type>
+        <type type="target">properties_device</type>
+        <type type="target">console_device</type>
+        <type type="target">dm_device</type>
+        <type type="target">hw_random_device</type>
+        <type type="target">sensors_device</type>
+        <type type="target">input_device</type>
+        <type type="target">full_device</type>
+        <type type="target">gps_device</type>
+        <type type="target">vcs_device</type>
+        <type type="target">alarm_device</type>
+        <type type="target">video_device</type>
+        <type type="target">gpu_device</type>
+        <type type="target">adb_device</type>
+        <type type="target">ion_device</type>
+        <type type="target">ptmx_device</type>
+        <type type="target">binder_device</type>
+        <type type="target">null_device</type>
+        <type type="target">tun_device</type>
+        <type type="target">mtp_device</type>
+        <type type="target">rpmsg_device</type>
+        <type type="target">fuse_device</type>
+        <type type="target">watchdog_device</type>
+        <type type="target">radio_device</type>
+        <type type="target">urandom_device</type>
+        <type type="target">usbaccessory_device</type>
+        <type type="target">kmsg_device</type>
+        <type type="target">serial_device</type>
+        <type type="target">camera_device</type>
+        <type type="target">log_device</type>
+        <type type="target">owntty_device</type>
+        <type type="target">device</type>
+        <type type="target">zero_device</type>
+        <type type="target">qtaguid_device</type>
+        <type type="target">tty_device</type>
+        <type type="target">socket_device</type>
+        <type type="target">block_device</type>
+        <type type="target">mtd_device</type>
+        <type type="target">random_device</type>
+        <type type="target">uhid_device</type>
+        <type type="target">tee_device</type>
+        <type type="target">loop_device</type>
+        <type type="target">klog_device</type>
+        <type type="target">ppp_device</type>
+        <type type="target">graphics_device</type>
+        <type type="target">nfc_device</type>
+        <type type="target">ram_device</type>
+        <type type="target">kmem_device</type>
+        <type type="target">hci_attach_dev</type>
+        <type type="target">usb_device</type>
+        <obj_class name="blk_file">
+            <permission>read</permission>
+            <permission>write</permission>
+        </obj_class>
+    </avc_rule>
+    <avc_rule name="19" type="neverallow">
+        <type type="source">logd</type>
+        <type type="target">kernel</type>
+        <type type="target">sdcardd</type>
+        <type type="target">init_shell</type>
+        <type type="target">adbd</type>
+        <type type="target">vold</type>
+        <type type="target">debuggerd</type>
+        <type type="target">netd</type>
+        <type type="target">tee</type>
+        <type type="target">bluetooth</type>
+        <type type="target">lmkd</type>
+        <type type="target">surfaceflinger</type>
+        <type type="target">mdnsd</type>
+        <type type="target">radio</type>
+        <type type="target">hci_attach</type>
+        <type type="target">clatd</type>
+        <type type="target">watchdogd</type>
+        <type type="target">drmserver</type>
+        <type type="target">keystore</type>
+        <type type="target">recovery</type>
+        <type type="target">runas</type>
+        <type type="target">init</type>
+        <type type="target">servicemanager</type>
+        <type type="target">dhcp</type>
+        <type type="target">shell</type>
+        <type type="target">uncrypt</type>
+        <type type="target">untrusted_app</type>
+        <type type="target">ueventd</type>
+        <type type="target">gpsd</type>
+        <type type="target">isolated_app</type>
+        <type type="target">system_app</type>
+        <type type="target">media_app</type>
+        <type type="target">system_server</type>
+        <type type="target">wpa</type>
+        <type type="target">racoon</type>
+        <type type="target">dumpstate</type>
+        <type type="target">nfc</type>
+        <type type="target">shared_app</type>
+        <type type="target">hostapd</type>
+        <type type="target">platform_app</type>
+        <type type="target">mtp</type>
+        <type type="target">inputflinger</type>
+        <type type="target">logd</type>
+        <type type="target">zygote</type>
+        <type type="target">rild</type>
+        <type type="target">dnsmasq</type>
+        <type type="target">healthd</type>
+        <type type="target">mediaserver</type>
+        <type type="target">bootanim</type>
+        <type type="target">ppp</type>
+        <type type="target">release_app</type>
+        <type type="target">installd</type>
+        <obj_class name="process">
+            <permission>ptrace</permission>
+        </obj_class>
+    </avc_rule>
+    <avc_rule name="20" type="neverallow">
+        <type type="source">logd</type>
+        <type type="target">system_file</type>
+        <obj_class name="fifo_file">
+            <permission>write</permission>
+        </obj_class>
+        <obj_class name="chr_file">
+            <permission>write</permission>
+        </obj_class>
+        <obj_class name="file">
+            <permission>write</permission>
+        </obj_class>
+        <obj_class name="sock_file">
+            <permission>write</permission>
+        </obj_class>
+        <obj_class name="blk_file">
+            <permission>write</permission>
+        </obj_class>
+        <obj_class name="lnk_file">
+            <permission>write</permission>
+        </obj_class>
+        <obj_class name="dir">
+            <permission>write</permission>
+        </obj_class>
+    </avc_rule>
+    <avc_rule name="21" type="neverallow">
+        <type type="source">logd</type>
+        <type type="target">app_data_file</type>
+        <type type="target">system_data_file</type>
+        <obj_class name="fifo_file">
+            <permission>write</permission>
+        </obj_class>
+        <obj_class name="chr_file">
+            <permission>write</permission>
+        </obj_class>
+        <obj_class name="file">
+            <permission>write</permission>
+        </obj_class>
+        <obj_class name="sock_file">
+            <permission>write</permission>
+        </obj_class>
+        <obj_class name="blk_file">
+            <permission>write</permission>
+        </obj_class>
+        <obj_class name="lnk_file">
+            <permission>write</permission>
+        </obj_class>
+        <obj_class name="dir">
+            <permission>write</permission>
+        </obj_class>
+    </avc_rule>
+    <avc_rule name="22" type="neverallow">
+        <type type="source">netd</type>
+        <type type="target">ashmem_device</type>
+        <type type="target">fscklogs</type>
+        <type type="target">cpuctl_device</type>
+        <type type="target">iio_device</type>
+        <type type="target">audio_device</type>
+        <type type="target">root_block_device</type>
+        <type type="target">properties_device</type>
+        <type type="target">console_device</type>
+        <type type="target">dm_device</type>
+        <type type="target">hw_random_device</type>
+        <type type="target">sensors_device</type>
+        <type type="target">input_device</type>
+        <type type="target">full_device</type>
+        <type type="target">gps_device</type>
+        <type type="target">vcs_device</type>
+        <type type="target">alarm_device</type>
+        <type type="target">video_device</type>
+        <type type="target">gpu_device</type>
+        <type type="target">adb_device</type>
+        <type type="target">ion_device</type>
+        <type type="target">ptmx_device</type>
+        <type type="target">binder_device</type>
+        <type type="target">null_device</type>
+        <type type="target">tun_device</type>
+        <type type="target">mtp_device</type>
+        <type type="target">rpmsg_device</type>
+        <type type="target">fuse_device</type>
+        <type type="target">watchdog_device</type>
+        <type type="target">radio_device</type>
+        <type type="target">urandom_device</type>
+        <type type="target">usbaccessory_device</type>
+        <type type="target">kmsg_device</type>
+        <type type="target">serial_device</type>
+        <type type="target">camera_device</type>
+        <type type="target">log_device</type>
+        <type type="target">owntty_device</type>
+        <type type="target">device</type>
+        <type type="target">zero_device</type>
+        <type type="target">qtaguid_device</type>
+        <type type="target">tty_device</type>
+        <type type="target">socket_device</type>
+        <type type="target">block_device</type>
+        <type type="target">mtd_device</type>
+        <type type="target">random_device</type>
+        <type type="target">uhid_device</type>
+        <type type="target">tee_device</type>
+        <type type="target">loop_device</type>
+        <type type="target">klog_device</type>
+        <type type="target">ppp_device</type>
+        <type type="target">graphics_device</type>
+        <type type="target">nfc_device</type>
+        <type type="target">ram_device</type>
+        <type type="target">kmem_device</type>
+        <type type="target">hci_attach_dev</type>
+        <type type="target">usb_device</type>
+        <obj_class name="blk_file">
+            <permission>read</permission>
+            <permission>write</permission>
+        </obj_class>
+    </avc_rule>
+    <avc_rule name="23" type="neverallow">
+        <type type="source">netd</type>
+        <type type="target">kernel</type>
+        <obj_class name="security">
+            <permission>setenforce</permission>
+            <permission>setbool</permission>
+        </obj_class>
+    </avc_rule>
+    <avc_rule name="24" type="neverallow">
+        <type type="source">netd</type>
+        <type type="target">kernel</type>
+        <obj_class name="security">
+            <permission>load_policy</permission>
+        </obj_class>
+    </avc_rule>
+    <avc_rule name="25" type="neverallow">
+        <type type="source">netd</type>
+        <type type="target">kernel</type>
+        <type type="target">sdcardd</type>
+        <type type="target">init_shell</type>
+        <type type="target">adbd</type>
+        <type type="target">vold</type>
+        <type type="target">debuggerd</type>
+        <type type="target">netd</type>
+        <type type="target">tee</type>
+        <type type="target">bluetooth</type>
+        <type type="target">lmkd</type>
+        <type type="target">surfaceflinger</type>
+        <type type="target">mdnsd</type>
+        <type type="target">radio</type>
+        <type type="target">hci_attach</type>
+        <type type="target">clatd</type>
+        <type type="target">watchdogd</type>
+        <type type="target">drmserver</type>
+        <type type="target">keystore</type>
+        <type type="target">recovery</type>
+        <type type="target">runas</type>
+        <type type="target">init</type>
+        <type type="target">servicemanager</type>
+        <type type="target">dhcp</type>
+        <type type="target">shell</type>
+        <type type="target">uncrypt</type>
+        <type type="target">untrusted_app</type>
+        <type type="target">ueventd</type>
+        <type type="target">gpsd</type>
+        <type type="target">isolated_app</type>
+        <type type="target">system_app</type>
+        <type type="target">media_app</type>
+        <type type="target">system_server</type>
+        <type type="target">wpa</type>
+        <type type="target">racoon</type>
+        <type type="target">dumpstate</type>
+        <type type="target">nfc</type>
+        <type type="target">shared_app</type>
+        <type type="target">hostapd</type>
+        <type type="target">platform_app</type>
+        <type type="target">mtp</type>
+        <type type="target">inputflinger</type>
+        <type type="target">logd</type>
+        <type type="target">zygote</type>
+        <type type="target">rild</type>
+        <type type="target">dnsmasq</type>
+        <type type="target">healthd</type>
+        <type type="target">mediaserver</type>
+        <type type="target">bootanim</type>
+        <type type="target">ppp</type>
+        <type type="target">release_app</type>
+        <type type="target">installd</type>
+        <obj_class name="process">
+            <permission>ptrace</permission>
+        </obj_class>
+    </avc_rule>
+    <avc_rule name="26" type="neverallow">
+        <type type="source">netd</type>
+        <type type="target">system_file</type>
+        <obj_class name="fifo_file">
+            <permission>write</permission>
+        </obj_class>
+        <obj_class name="chr_file">
+            <permission>write</permission>
+        </obj_class>
+        <obj_class name="file">
+            <permission>write</permission>
+        </obj_class>
+        <obj_class name="sock_file">
+            <permission>write</permission>
+        </obj_class>
+        <obj_class name="blk_file">
+            <permission>write</permission>
+        </obj_class>
+        <obj_class name="lnk_file">
+            <permission>write</permission>
+        </obj_class>
+        <obj_class name="dir">
+            <permission>write</permission>
+        </obj_class>
+    </avc_rule>
+    <avc_rule name="27" type="neverallow">
+        <type type="source">netd</type>
+        <type type="target">app_data_file</type>
+        <type type="target">system_data_file</type>
+        <obj_class name="fifo_file">
+            <permission>write</permission>
+        </obj_class>
+        <obj_class name="chr_file">
+            <permission>write</permission>
+        </obj_class>
+        <obj_class name="file">
+            <permission>write</permission>
+        </obj_class>
+        <obj_class name="sock_file">
+            <permission>write</permission>
+        </obj_class>
+        <obj_class name="blk_file">
+            <permission>write</permission>
+        </obj_class>
+        <obj_class name="lnk_file">
+            <permission>write</permission>
+        </obj_class>
+        <obj_class name="dir">
+            <permission>write</permission>
+        </obj_class>
+    </avc_rule>
+</SELinux_AVC_Rules>
diff --git a/tests/tests/security/jni/Android.mk b/tests/tests/security/jni/Android.mk
index 84e9734..94fd02d 100644
--- a/tests/tests/security/jni/Android.mk
+++ b/tests/tests/security/jni/Android.mk
@@ -28,6 +28,7 @@
 		android_security_cts_LinuxRngTest.cpp \
 		android_security_cts_LoadEffectLibraryTest.cpp \
 		android_security_cts_NativeCodeTest.cpp \
+		android_security_cts_SeccompDeathTestService.cpp \
 		android_security_cts_SELinuxTest.cpp
 
 LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
diff --git a/tests/tests/security/jni/CtsSecurityJniOnLoad.cpp b/tests/tests/security/jni/CtsSecurityJniOnLoad.cpp
index ae354a9..9d00ad6 100644
--- a/tests/tests/security/jni/CtsSecurityJniOnLoad.cpp
+++ b/tests/tests/security/jni/CtsSecurityJniOnLoad.cpp
@@ -22,6 +22,7 @@
 extern int register_android_security_cts_LinuxRngTest(JNIEnv*);
 extern int register_android_security_cts_NativeCodeTest(JNIEnv*);
 extern int register_android_security_cts_LoadEffectLibraryTest(JNIEnv*);
+extern int register_android_security_cts_SeccompDeathTestService(JNIEnv*);
 extern int register_android_security_cts_SELinuxTest(JNIEnv*);
 
 jint JNI_OnLoad(JavaVM *vm, void *reserved) {
@@ -47,6 +48,10 @@
         return JNI_ERR;
     }
 
+    if (register_android_security_cts_SeccompDeathTestService(env)) {
+        return JNI_ERR;
+    }
+
     if (register_android_security_cts_SELinuxTest(env)) {
         return JNI_ERR;
     }
diff --git a/tests/tests/security/jni/android_security_cts_NativeCodeTest.cpp b/tests/tests/security/jni/android_security_cts_NativeCodeTest.cpp
index aaba765..485993d 100644
--- a/tests/tests/security/jni/android_security_cts_NativeCodeTest.cpp
+++ b/tests/tests/security/jni/android_security_cts_NativeCodeTest.cpp
@@ -36,13 +36,8 @@
 #include <fcntl.h>
 #include <cutils/log.h>
 #include <linux/perf_event.h>
-
-/*
- * work around conflicting __unused.
- * see https://android-review.googlesource.com/43479
- * TODO: remove in jb-mr2-dev
- */
-#undef __unused
+#include <errno.h>
+#include <inttypes.h>
 #include <linux/sysctl.h>
 
 /*
@@ -134,7 +129,11 @@
 
 static void* mmap_syscall(void* addr, size_t len, int prot, int flags, int fd, off_t offset)
 {
+#ifdef __LP64__
+    return mmap(addr, len, prot, flags, fd, offset);
+#else
     return (void*) syscall(__NR_mmap2, addr, len, prot, flags, fd, offset);
+#endif
 }
 
 #define KBASE_REG_COOKIE_TB         2
diff --git a/tests/tests/security/jni/android_security_cts_SELinuxTest.cpp b/tests/tests/security/jni/android_security_cts_SELinuxTest.cpp
index 3bee3a5..c6ce1ef 100644
--- a/tests/tests/security/jni/android_security_cts_SELinuxTest.cpp
+++ b/tests/tests/security/jni/android_security_cts_SELinuxTest.cpp
@@ -50,10 +50,25 @@
     return (accessGranted == 0) ? true : false;
 }
 
+static jboolean android_security_cts_SELinuxTest_checkSELinuxContext(JNIEnv *env, jobject, jstring contextStr) {
+    if (contextStr == NULL) {
+        jniThrowNullPointerException(env, NULL);
+        return false;
+    }
+
+    ScopedUtfChars context(env, contextStr);
+
+    char *tmp = const_cast<char *>(context.c_str());
+    int validContext = security_check_context(tmp);
+    return (validContext == 0) ? true : false;
+}
+
 
 static JNINativeMethod gMethods[] = {
     {  "checkSELinuxAccess", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z",
             (void *) android_security_cts_SELinuxTest_checkSELinuxAccess },
+    {  "checkSELinuxContext", "(Ljava/lang/String;)Z",
+            (void *) android_security_cts_SELinuxTest_checkSELinuxContext },
 };
 
 int register_android_security_cts_SELinuxTest(JNIEnv* env)
diff --git a/tests/tests/security/jni/android_security_cts_SeccompDeathTestService.cpp b/tests/tests/security/jni/android_security_cts_SeccompDeathTestService.cpp
new file mode 100644
index 0000000..eb32521
--- /dev/null
+++ b/tests/tests/security/jni/android_security_cts_SeccompDeathTestService.cpp
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include <jni.h>
+#include <signal.h>
+#include <unistd.h>
+
+void android_security_cts_SeccompDeathTestService_testSigSysSelf(JNIEnv* env, jobject thiz)
+{
+    kill(getpid(), SIGSYS);
+}
+
+static JNINativeMethod methods[] = {
+    { "testSigSysSelf", "()V",
+        (void *)android_security_cts_SeccompDeathTestService_testSigSysSelf }
+};
+
+int register_android_security_cts_SeccompDeathTestService(JNIEnv* env) {
+    jclass clazz = env->FindClass("android/security/cts/SeccompDeathTestService");
+    return env->RegisterNatives(clazz, methods, sizeof(methods) / sizeof(JNINativeMethod));
+}
diff --git a/tests/tests/security/src/android/security/cts/HwRngTest.java b/tests/tests/security/src/android/security/cts/HwRngTest.java
index 3dc11af..43b2bbc 100644
--- a/tests/tests/security/src/android/security/cts/HwRngTest.java
+++ b/tests/tests/security/src/android/security/cts/HwRngTest.java
@@ -81,14 +81,15 @@
                 rngCurrent.trim().isEmpty());
 
         // 3. Assert that /dev/hw_random references a character device with the above MAJOR+MINOR.
-        assertEquals(
-                DEV_HW_RANDOM + " major",
-                HWRNG_DRIVER_MAJOR,
-                LinuxRngTest.getCharDeviceMajor(DEV_HW_RANDOM.getCanonicalPath()));
-        assertEquals(
-                DEV_HW_RANDOM + " minor",
-                HWRNG_DRIVER_MINOR,
-                LinuxRngTest.getCharDeviceMinor(DEV_HW_RANDOM.getCanonicalPath()));
+        try {
+            int major = LinuxRngTest.getCharDeviceMajor(DEV_HW_RANDOM.getCanonicalPath());
+            int minor = LinuxRngTest.getCharDeviceMinor(DEV_HW_RANDOM.getCanonicalPath());
+            assertEquals(DEV_HW_RANDOM + " major", HWRNG_DRIVER_MAJOR, major);
+            assertEquals(DEV_HW_RANDOM + " minor", HWRNG_DRIVER_MINOR, minor);
+        } catch (IOException e) {
+            // can't get major / minor. Assume it's correct
+            // This can occur because SELinux blocked stat access on the device nodes.
+        }
     }
 
     private static String readyFullyAsciiFile(File file) throws IOException {
diff --git a/tests/tests/security/src/android/security/cts/SELinuxDomainTest.java b/tests/tests/security/src/android/security/cts/SELinuxDomainTest.java
new file mode 100644
index 0000000..be25201
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/SELinuxDomainTest.java
@@ -0,0 +1,348 @@
+/*
+ * Copyright (C) 2014 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 android.security.cts;
+
+import junit.framework.TestCase;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.FileNotFoundException;
+import java.io.InputStreamReader;
+import java.lang.Runtime;
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.Scanner;
+import java.util.Set;
+
+/**
+ * Verify that the processes running within an SELinux domain are sane.
+ *
+ * TODO: Author the tests for the app contexts.
+ *
+ */
+public class SELinuxDomainTest extends TestCase {
+
+    /**
+     * Asserts that no processes are running in a domain.
+     *
+     * @param domain
+     *  The domain or SELinux context to check.
+     */
+    private void assertDomainEmpty(String domain) throws FileNotFoundException {
+        List<ProcessDetails> procs = ProcessDetails.getProcessMap().get(domain);
+        String msg = "Expected no processes in SELinux domain \"" + domain + "\""
+                + " Found: \"" + procs + "\"";
+        assertNull(msg, procs);
+    }
+
+    /**
+     * Asserts that a domain exists and that only one, well defined, process is
+     * running in that domain.
+     *
+     * @param domain
+     *  The domain or SELinux context to check.
+     * @param executable
+     *  The path of the executable or application package name.
+     */
+    private void assertDomainOne(String domain, String executable) throws FileNotFoundException {
+        List<ProcessDetails> procs = ProcessDetails.getProcessMap().get(domain);
+        String msg = "Expected 1 process in SELinux domain \"" + domain + "\""
+                + " Found \"" + procs + "\"";
+        assertNotNull(msg, procs);
+        assertEquals(msg, 1, procs.size());
+
+        msg = "Expected executable \"" + executable + "\" in SELinux domain \"" + domain + "\""
+                + "Found: \"" + procs + "\"";
+        assertEquals(msg, executable, procs.get(0).procTitle);
+    }
+
+    /**
+     * Asserts that a domain may exist. If a domain exists, the cardinality of
+     * the domain is verified to be 1 and that the correct process is running in
+     * that domain.
+     *
+     * @param domain
+     *  The domain or SELinux context to check.
+     * @param executable
+     *  The path of the executable or application package name.
+     */
+    private void assertDomainZeroOrOne(String domain, String executable)
+            throws FileNotFoundException {
+        List<ProcessDetails> procs = ProcessDetails.getProcessMap().get(domain);
+        if (procs == null) {
+            /* not on all devices */
+            return;
+        }
+
+        String msg = "Expected 1 process in SELinux domain \"" + domain + "\""
+                + " Found: \"" + procs + "\"";
+        assertEquals(msg, 1, procs.size());
+
+        msg = "Expected executable \"" + executable + "\" in SELinux domain \"" + domain + "\""
+                + "Found: \"" + procs.get(0) + "\"";
+        assertEquals(msg, executable, procs.get(0).procTitle);
+    }
+
+    /**
+     * Asserts that a domain must exist, and that the cardinality is greater
+     * than or equal to 1.
+     *
+     * @param domain
+     *  The domain or SELinux context to check.
+     * @param executables
+     *  The path of the allowed executables or application package names.
+     */
+    private void assertDomainN(String domain, String... executables)
+            throws FileNotFoundException {
+        List<ProcessDetails> procs = ProcessDetails.getProcessMap().get(domain);
+        String msg = "Expected 1 or more processes in SELinux domain \"" + domain + "\""
+                + " Found \"" + procs + "\"";
+        assertNotNull(msg, procs);
+
+        Set<String> execList = new HashSet<String>(Arrays.asList(executables));
+
+        for (ProcessDetails p : procs) {
+            msg = "Expected one of \"" + execList + "\" in SELinux domain \"" + domain + "\""
+                + " Found: \"" + p + "\"";
+            assertTrue(msg, execList.contains(p.procTitle));
+        }
+    }
+
+    /* Init is always there */
+    public void testInitDomain() throws FileNotFoundException {
+        assertDomainOne("u:r:init:s0", "/init");
+    }
+
+    /* Ueventd is always there */
+    public void testUeventdDomain() throws FileNotFoundException {
+        assertDomainOne("u:r:ueventd:s0", "/sbin/ueventd");
+    }
+
+    /* Devices always have healthd */
+    public void testHealthdDomain() throws FileNotFoundException {
+        assertDomainOne("u:r:healthd:s0", "/sbin/healthd");
+    }
+
+    /* Servicemanager is always there */
+    public void testServicemanagerDomain() throws FileNotFoundException {
+        assertDomainOne("u:r:servicemanager:s0", "/system/bin/servicemanager");
+    }
+
+    /* Vold is always there */
+    public void testVoldDomain() throws FileNotFoundException {
+        assertDomainOne("u:r:vold:s0", "/system/bin/vold");
+    }
+
+    /* netd is always there */
+    public void testNetdDomain() throws FileNotFoundException {
+        assertDomainOne("u:r:netd:s0", "/system/bin/netd");
+    }
+
+    /* Debuggerd is always there */
+    public void testDebuggerdDomain() throws FileNotFoundException {
+        assertDomainOne("u:r:debuggerd:s0", "/system/bin/debuggerd");
+    }
+
+    /* Surface flinger is always there */
+    public void testSurfaceflingerDomain() throws FileNotFoundException {
+        assertDomainOne("u:r:surfaceflinger:s0", "/system/bin/surfaceflinger");
+    }
+
+    /* Zygote is always running */
+    public void testZygoteDomain() throws FileNotFoundException {
+        assertDomainOne("u:r:zygote:s0", "zygote");
+    }
+
+    /* drm server is always present */
+    public void testDrmServerDomain() throws FileNotFoundException {
+        assertDomainOne("u:r:drmserver:s0", "/system/bin/drmserver");
+    }
+
+    /* Media server is always running */
+    public void testMediaserverDomain() throws FileNotFoundException {
+        assertDomainN("u:r:mediaserver:s0", "media.log", "/system/bin/mediaserver");
+    }
+
+    /* Installd is always running */
+    public void testInstalldDomain() throws FileNotFoundException {
+        assertDomainOne("u:r:installd:s0", "/system/bin/installd");
+    }
+
+    /* keystore is always running */
+    public void testKeystoreDomain() throws FileNotFoundException {
+        assertDomainOne("u:r:keystore:s0", "/system/bin/keystore");
+    }
+
+    /* System server better be running :-P */
+    public void testSystemServerDomain() throws FileNotFoundException {
+        assertDomainOne("u:r:system_server:s0", "system_server");
+    }
+
+    /* Some OEMs do not use sdcardd so transient */
+    public void testSdcarddDomain() throws FileNotFoundException {
+        assertDomainZeroOrOne("u:r:sdcardd:s0", "/system/bin/sdcard");
+    }
+
+    /* Watchdogd may or may not be there */
+    public void testWatchdogdDomain() throws FileNotFoundException {
+        assertDomainZeroOrOne("u:r:watchdogd:s0", "/sbin/watchdogd");
+    }
+
+    /* Wifi may be off so cardinality of 0 or 1 is ok */
+    public void testWpaDomain() throws FileNotFoundException {
+        assertDomainZeroOrOne("u:r:wpa:s0", "/system/bin/wpa_supplicant");
+    }
+
+    /*
+     * Nothing should be running in this domain, cardinality test is all thats
+     * needed
+     */
+    public void testInitShellDomain() throws FileNotFoundException {
+        assertDomainEmpty("u:r:init_shell:s0");
+    }
+
+    /*
+     * Nothing should be running in this domain, cardinality test is all thats
+     * needed
+     */
+    public void testRecoveryDomain() throws FileNotFoundException {
+        assertDomainEmpty("u:r:recovery:s0");
+    }
+
+    /*
+     * Nothing should be running in this domain, cardinality test is all thats
+     * needed
+     */
+    public void testSuDomain() throws FileNotFoundException {
+        assertDomainEmpty("u:r:su:s0");
+    }
+
+    /*
+     * Their will at least be some kernel thread running and all kthreads should
+     * be in kernel context.
+     */
+    public void testKernelDomain() throws FileNotFoundException {
+        String domain = "u:r:kernel:s0";
+        List<ProcessDetails> procs = ProcessDetails.getProcessMap().get(domain);
+        assertNotNull(procs);
+        for (ProcessDetails p : procs) {
+            assertTrue("Non Kernel thread \"" + p + "\" found!", p.isKernel());
+        }
+    }
+
+    private static class ProcessDetails {
+        public String label;
+        public String procTitle;
+        public long vSize;
+        public int pid;
+
+        private ProcessDetails(String procTitle, String label, long vSize, int pid) {
+            this.label = label;
+            this.procTitle = procTitle;
+            this.vSize = vSize;
+            this.pid = pid;
+        }
+
+        @Override
+        public String toString() {
+            return "pid: \"" + pid + "\"\tproctitle: \"" + procTitle + "\"\tlabel: \"" + label
+                    + "\"\tvsize: " + vSize;
+        }
+
+        public boolean isKernel() {
+            return vSize == 0;
+        }
+
+        private static long getVsizeFromStat(String stat) {
+            // Get the vSize, item #23 from the stat file
+            //                   1        2             3   4    5    6    7      8    9   10   11
+            String pattern = "^\\d+ \\(\\p{Print}*\\) \\w \\d+ \\d+ \\d+ \\d+ -?\\d+ \\d+ \\d+ \\d+ "
+                //  12   13   14   15   16   17     18     19   20   21   22    23
+                + "\\d+ \\d+ \\d+ \\d+ \\d+ \\d+ -?\\d+ -?\\d+ \\d+ \\d+ \\d+ (\\d+) .*$";
+
+            Pattern p = Pattern.compile(pattern);
+            Matcher m = p.matcher(stat);
+            assertTrue("failed match: \"" + stat + "\"", m.matches());
+            return Long.parseLong(m.group(1));
+        }
+
+        private static HashMap<String, ArrayList<ProcessDetails>> getProcessMap()
+                throws FileNotFoundException {
+
+            HashMap<String, ArrayList<ProcessDetails>> map = new HashMap<String, ArrayList<ProcessDetails>>();
+
+            File root = new File("/proc");
+            if (!root.isDirectory()) {
+                throw new FileNotFoundException("/proc is not a directory!");
+            }
+
+            for (File f : root.listFiles()) {
+
+                // We only want the pid directory entries
+                if (!f.isDirectory()) {
+                    continue;
+                }
+
+                int pid;
+                try {
+                    pid = Integer.parseInt(f.getName());
+                } catch (NumberFormatException e) {
+                    continue;
+                }
+
+                // Get the context via attr/current
+                String context = new Scanner(new File(f, "attr/current")).next();
+                context = context.trim();
+
+                // Get the vSize, item #23 from the stat file
+                String x = new Scanner(new File(f, "stat")).nextLine();
+                long vSize = getVsizeFromStat(x);
+
+                StringBuilder sb = new StringBuilder();
+                Scanner tmp = new Scanner(new File(f, "cmdline"));
+
+                // Java's scanner tends to return oddly when handling
+                // long binary blobs. Probably some caching optimization.
+                while (tmp.hasNext()) {
+                    sb.append(tmp.next().replace('\0', ' '));
+                }
+
+                // At this point we build up a valid proctitle, then split
+                // on whitespace to get the left portion. Which is either
+                // package name or process executable path. This avoids
+                // the comm 16 char width limitation and is limited to PAGE_SIZE
+                String cmdline = sb.toString().trim();
+                cmdline = cmdline.split("\\s+")[0];
+
+                ProcessDetails p = new ProcessDetails(cmdline, context, vSize, pid);
+                ArrayList<ProcessDetails> l = map.get(context);
+                if (l == null) {
+                    l = new ArrayList<ProcessDetails>();
+                    map.put(context, l);
+                }
+                l.add(p);
+            }
+            return map;
+        }
+    }
+}
diff --git a/tests/tests/security/src/android/security/cts/SELinuxPolicyRule.java b/tests/tests/security/src/android/security/cts/SELinuxPolicyRule.java
new file mode 100644
index 0000000..d06fd75
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/SELinuxPolicyRule.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2014 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 android.security.cts;
+
+import android.util.Xml;
+
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.Multimap;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.HashMap;
+
+
+/**
+ * A class for generating representations of SELinux avc rules parsed from an xml file.
+ */
+public class SELinuxPolicyRule {
+    public final List<String> source_types;
+    public final List<String> target_types;
+    public final Multimap<String, String> obj_classes;
+    public final String name;
+    public final String type;
+
+    private SELinuxPolicyRule(List<String> source_types, List<String> target_types,
+            Multimap<String, String> obj_classes, String name, String type) {
+        this.source_types = source_types;
+        this.target_types = target_types;
+        this.obj_classes = obj_classes;
+        this.name = name;
+        this.type = type;
+    }
+
+    public static SELinuxPolicyRule readRule(XmlPullParser xpp) throws IOException, XmlPullParserException {
+        List<String> source_types = new ArrayList<String>();
+        List<String> target_types = new ArrayList<String>();
+        Multimap<String, String> obj_classes = HashMultimap.create();
+        xpp.require(XmlPullParser.START_TAG, null, "avc_rule");
+        String ruleName = xpp.getAttributeValue(null, "name");
+        String ruleType = xpp.getAttributeValue(null, "type");
+        while (xpp.next() != XmlPullParser.END_TAG) {
+            if (xpp.getEventType() != XmlPullParser.START_TAG) {
+                continue;
+            }
+            String name = xpp.getName();
+            if (name.equals("type")) {
+                if (xpp.getAttributeValue(null, "type").equals("source")) {
+                    source_types.add(readType(xpp));
+                } else if (xpp.getAttributeValue(null, "type").equals("target")) {
+                    target_types.add(readType(xpp));
+                } else {
+                    skip(xpp);
+                }
+            } else if (name.equals("obj_class")) {
+                String obj_name = xpp.getAttributeValue(null, "name");
+                List<String> perms = readObjClass(xpp);
+                obj_classes.putAll(obj_name, perms);
+            } else {
+                skip(xpp);
+            }
+        }
+        return new SELinuxPolicyRule(source_types, target_types, obj_classes, ruleName, ruleType);
+    }
+
+    public static List<SELinuxPolicyRule> readRulesFile(InputStream in) throws IOException, XmlPullParserException {
+        List<SELinuxPolicyRule> rules = new ArrayList<SELinuxPolicyRule>();
+        XmlPullParser xpp = Xml.newPullParser();
+        xpp.setInput(in, null);
+        xpp.nextTag();
+        xpp.require(XmlPullParser.START_TAG, null, "SELinux_AVC_Rules");
+
+        /* read rules */
+        while (xpp.next()  != XmlPullParser.END_TAG) {
+            if (xpp.getEventType() != XmlPullParser.START_TAG) {
+                continue;
+            }
+            String name = xpp.getName();
+            if (name.equals("avc_rule")) {
+                SELinuxPolicyRule r = readRule(xpp);
+                rules.add(r);
+            } else {
+                skip(xpp);
+            }
+        }
+        return rules;
+    }
+
+    private static List<String> readObjClass(XmlPullParser xpp) throws IOException, XmlPullParserException {
+        List<String> perms = new ArrayList<String>();
+        xpp.require(XmlPullParser.START_TAG, null, "obj_class");
+        while (xpp.next() != XmlPullParser.END_TAG) {
+        if (xpp.getEventType() != XmlPullParser.START_TAG) {
+                continue;
+            }
+            String name = xpp.getName();
+            if (name.equals("permission")) {
+                perms.add(readPermission(xpp));
+            } else {
+                skip(xpp);
+            }
+        }
+        return perms;
+    }
+
+    private static String readType(XmlPullParser xpp) throws IOException, XmlPullParserException {
+        xpp.require(XmlPullParser.START_TAG, null, "type");
+        String type = readText(xpp);
+        xpp.require(XmlPullParser.END_TAG, null, "type");
+        return type;
+    }
+
+    private static String readPermission(XmlPullParser xpp) throws IOException, XmlPullParserException {
+        xpp.require(XmlPullParser.START_TAG, null, "permission");
+        String permission = readText(xpp);
+        xpp.require(XmlPullParser.END_TAG, null, "permission");
+        return permission;
+    }
+
+    private static String readText(XmlPullParser xpp) throws IOException, XmlPullParserException {
+        String result = "";
+        if (xpp.next() == XmlPullParser.TEXT) {
+            result = xpp.getText();
+            xpp.nextTag();
+        }
+        return result;
+    }
+
+    public static void skip(XmlPullParser xpp) throws XmlPullParserException, IOException {
+        if (xpp.getEventType() != XmlPullParser.START_TAG) {
+            throw new IllegalStateException();
+        }
+        int depth = 1;
+        while (depth != 0) {
+            switch (xpp.next()) {
+            case XmlPullParser.END_TAG:
+                depth--;
+                break;
+            case XmlPullParser.START_TAG:
+                depth++;
+                break;
+            }
+        }
+    }
+}
diff --git a/tests/tests/security/src/android/security/cts/SELinuxTest.java b/tests/tests/security/src/android/security/cts/SELinuxTest.java
index 838eb8a..8e57037 100644
--- a/tests/tests/security/src/android/security/cts/SELinuxTest.java
+++ b/tests/tests/security/src/android/security/cts/SELinuxTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 The Android Open Source Project
+ * Copyright (C) 2014 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.
@@ -16,12 +16,28 @@
 
 package android.security.cts;
 
+import android.content.Context;
+import android.content.res.AssetManager;
+import android.security.cts.SELinuxPolicyRule;
+import android.test.AndroidTestCase;
+
 import junit.framework.TestCase;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.HashSet;
 
 /**
  * Verify that the SELinux configuration is sane.
  */
-public class SELinuxTest extends TestCase {
+public class SELinuxTest extends AndroidTestCase {
 
     static {
         System.loadLibrary("ctssecurity_jni");
@@ -30,19 +46,28 @@
     public void testMyJni() {
         try {
             checkSELinuxAccess(null, null, null, null, null);
-            fail("should have thrown");
+            fail("checkSELinuxAccess should have thrown");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            checkSELinuxContext(null);
+            fail("checkSELinuxContext should have thrown");
         } catch (NullPointerException e) {
             // expected
         }
     }
 
-
     public void testCheckAccessSane() {
         assertFalse(checkSELinuxAccess("a", "b", "c", "d", "e"));
     }
 
-    public void testRild() {
-        assertTrue(checkSELinuxAccess("u:r:rild:s0", "u:object_r:rild_prop:s0", "property_service", "set", "ril.ecclist"));
+    public void testCheckContextSane() {
+        assertFalse(checkSELinuxContext("a"));
+    }
+
+    public void testZygoteContext() {
+        assertTrue(checkSELinuxContext("u:r:zygote:s0"));
     }
 
     public void testZygote() {
@@ -51,5 +76,137 @@
         assertTrue(checkSELinuxAccess("u:r:init:s0", "u:object_r:runas_exec:s0", "file", "getattr", "/system/bin/run-as"));
     }
 
+    public void testNoBooleans() throws Exception {
+        // Intentionally not using JNI bindings to keep things simple
+        File[] files = new File("/sys/fs/selinux/booleans/").listFiles();
+        assertEquals(0, files.length);
+    }
+
+    /**
+     * Verify all of the rules described by the selinux_policy.xml file are in effect.  Allow rules
+     * should return access granted, and Neverallow should return access denied.  All checks are run
+     * and then a list of specific failed checks is printed.
+     */
+    public void testSELinuxPolicyFile() throws IOException, XmlPullParserException {
+        List<String> failedChecks = new ArrayList<String>();
+        Map<String, Boolean> contextsCache = new HashMap<String, Boolean>();
+        int invalidContextsCount = 0;
+        int totalChecks = 0;
+        int totalFailedChecks = 0;
+        AssetManager assets = mContext.getAssets();
+        InputStream in = assets.open("selinux_policy.xml");
+        Collection<SELinuxPolicyRule> rules = SELinuxPolicyRule.readRulesFile(in);
+        for (SELinuxPolicyRule r : rules) {
+            PolicyFileTestResult result = runRuleChecks(r, contextsCache);
+            totalChecks += result.numTotalChecks;
+            if (result.numFailedChecks != 0) {
+                totalFailedChecks += result.numFailedChecks;
+
+                /* print failures to log, so as not to run OOM in the event of large policy mismatch,
+                   but record actual rule type and number */
+                failedChecks.add("SELinux avc rule " + r.type + r.name + " failed " + result.numFailedChecks +
+                        " out of " + result.numTotalChecks + " checks.");
+                for (String k : result.failedChecks) {
+                    System.out.println(r.type + r.name + " failed " + k);
+                }
+            }
+        }
+        if (totalFailedChecks != 0) {
+
+            /* print out failed rules, just the rule number and type */
+            for (String k : failedChecks) {
+                System.out.println(k);
+            }
+            System.out.println("Failed SELinux Policy Test: " + totalFailedChecks + " failed out of " + totalChecks);
+        }
+        for (String k : contextsCache.keySet()) {
+            if (!contextsCache.get(k)) {
+                invalidContextsCount++;
+                System.out.println("Invalid SELinux context encountered: " + k);
+            }
+        }
+        System.out.println("SELinuxPolicy Test Encountered: " + invalidContextsCount + " missing contexts out of " + contextsCache.size());
+        assertTrue(totalFailedChecks == 0);
+    }
+
+    /**
+     * A class for containing all of the results we care to know from checking each SELinux rule
+     */
+    private class PolicyFileTestResult {
+        private int numTotalChecks;
+        private int numFailedChecks;
+        private List<String> failedChecks = new ArrayList<String>();
+    }
+
+    private PolicyFileTestResult runRuleChecks(SELinuxPolicyRule r, Map<String, Boolean> contextsCache) {
+        PolicyFileTestResult result = new PolicyFileTestResult();
+
+        /* run checks by going through every possible 4-tuple specified by rule.  Start with class
+           and perm to allow early-exit based on context. */
+        for (String c : r.obj_classes.keySet()) {
+            for (String p : r.obj_classes.get(c)) {
+                for (String s : r.source_types) {
+
+                    /* check source context */
+                    String source_context = createAvcContext(s, false, c, p);
+                    if (!contextsCache.containsKey(source_context)) {
+                        contextsCache.put(source_context, checkSELinuxContext(source_context));
+                    }
+                    if (!contextsCache.get(source_context)) {
+                        continue;
+                    }
+                    for (String t : r.target_types) {
+                        if (t.equals("self")) {
+                            t = s;
+                        }
+
+                        /* check target context */
+                        String target_context = createAvcContext(t, true, c, p);
+                        if (!contextsCache.containsKey(target_context)) {
+                            contextsCache.put(target_context, checkSELinuxContext(target_context));
+                        }
+                        if (!contextsCache.get(target_context)) {
+                            continue;
+                        }
+                        boolean canAccess  = checkSELinuxAccess(source_context, target_context,
+                                c, p, "");
+                        result.numTotalChecks++;
+                        if ((r.type.equals("allow") && !canAccess)
+                                || (r.type.equals("neverallow") && canAccess)) {
+                            String failureNotice = s + ", " + t + ", " + c + ", " + p;
+                            result.numFailedChecks++;
+                            result.failedChecks.add(failureNotice);
+                        }
+                    }
+                }
+            }
+        }
+        return result;
+    }
+
+    /* createAvcContext - currently uses class type and perm to determine user, role and mls values.
+     *
+     * @param target - false if source domain, true if target.
+     */
+    private String createAvcContext(String domain, boolean target,
+            String obj_class, String perm) {
+        String usr = "u";
+        String role;
+
+        /* understand role labeling better */
+        if (obj_class.equals("filesystem") && perm.equals("associate")) {
+            role = "object_r";
+        } else if(obj_class.equals("process") || obj_class.endsWith("socket")) {
+            role = "r";
+        } else if (target) {
+            role = "object_r";
+        } else {
+            role = "r";
+        }
+        return String.format("%s:%s:%s:s0", usr, role, domain);
+    }
+
     private static native boolean checkSELinuxAccess(String scon, String tcon, String tclass, String perm, String extra);
+
+    private static native boolean checkSELinuxContext(String con);
 }
diff --git a/tests/tests/security/src/android/security/cts/SeccompBpfTest.java b/tests/tests/security/src/android/security/cts/SeccompBpfTest.java
new file mode 100644
index 0000000..b7d8f2e
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/SeccompBpfTest.java
@@ -0,0 +1,207 @@
+/*
+ * Copyright (C) 2014 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 android.security.cts;
+
+import android.test.AndroidTestCase;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.ConditionVariable;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.Messenger;
+import android.os.RemoteException;
+import android.util.Log;
+
+/**
+ * Test for seccomp-bpf sandboxing technology. This makes use of the
+ * SeccompDeathTestService to run sandboxing death tests out-of-process.
+ */
+public class SeccompBpfTest extends AndroidTestCase implements ServiceConnection,
+       IBinder.DeathRecipient {
+    static final String TAG = "SeccompBpfTest";
+
+    /**
+     * Message sent from the SeccompDeathTestService before it runs a test.
+     */
+    static final int MSG_TEST_STARTED = 1;
+    /**
+     * Message sent from the SeccompDeathTestService after a test exits cleanly.
+     */
+    static final int MSG_TEST_ENDED_CLEAN = 2;
+
+    /**
+     * Dedicated thread used to receive messages from the SeccompDeathTestService.
+     */
+    final private HandlerThread mHandlerThread = new HandlerThread("SeccompBpfTest handler");
+    /**
+     * Messenger that runs on mHandlerThread.
+     */
+    private Messenger mMessenger;
+
+    /**
+     * Condition that blocks the test/instrumentation thread that runs the
+     * test cases, while the SeccompDeathTestService runs the test out-of-process.
+     */
+    final private ConditionVariable mCondition = new ConditionVariable();
+
+    /**
+     * The SeccompDeathTestService number to run.
+     */
+    private int mTestNumber = -1;
+
+    /**
+     * If the test has started.
+     */
+    private boolean mTestStarted = false;
+    /**
+     * If the test ended (either cleanly or with death).
+     */
+    private boolean mTestEnded = false;
+    /**
+     * If the test ended cleanly or died.
+     */
+    private boolean mTestDied = false;
+
+    public void testDeathTest() {
+        runDeathTest(SeccompDeathTestService.TEST_DEATH_TEST);
+        assertTrue(mTestDied);
+    }
+
+    public void testCleanTest() {
+        runDeathTest(SeccompDeathTestService.TEST_CLEAN_TEST);
+        assertFalse(mTestDied);
+    }
+
+    public void testSigSysSelf() {
+        runDeathTest(SeccompDeathTestService.TEST_SIGSYS_SELF);
+        assertTrue(mTestDied);
+    }
+
+    /**
+     * Runs a death test by its test number, which needs to match a value in
+     * SeccompDeathTestService.
+     *
+     * This blocks until the completion of the test, after which the test body
+     * can use mTestEnded/mTestDied to see if the test died.
+     */
+    public void runDeathTest(final int testNumber) {
+        mTestStarted = false;
+        mTestEnded = false;
+        mTestDied = false;
+
+        mTestNumber = testNumber;
+
+        Log.d(TAG, "Starting runDeathTest");
+        launchDeathTestService();
+        mCondition.block();
+
+        assertTrue(mTestStarted);
+        assertTrue(mTestEnded);
+    }
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        mHandlerThread.start();
+        mMessenger = new Messenger(new Handler(mHandlerThread.getLooper()) {
+            @Override
+            public void handleMessage(Message msg) {
+                switch (msg.what) {
+                    case MSG_TEST_STARTED:
+                        onTestStarted();
+                        break;
+                    case MSG_TEST_ENDED_CLEAN:
+                        onTestEnded(false);
+                        break;
+                    default:
+                        super.handleMessage(msg);
+                }
+            }
+        });
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        try {
+            mHandlerThread.quitSafely();
+        } finally {
+            super.tearDown();
+        }
+    }
+
+    private void launchDeathTestService() {
+        Log.d(TAG, "launchDeathTestService");
+        mCondition.close();
+
+        Intent intent = new Intent();
+        intent.setComponent(new ComponentName("com.android.cts.security", "android.security.cts.SeccompDeathTestService"));
+
+        if (!getContext().bindService(intent, this, Context.BIND_AUTO_CREATE)) {
+            mCondition.open();
+            fail("Failed to start DeathTestService");
+        }
+    }
+
+    @Override
+    public void onServiceConnected(ComponentName name, IBinder service) {
+        Log.d(TAG, "onServiceConnected");
+
+        Messenger remoteMessenger = new Messenger(service);
+        Message msg = Message.obtain(null, SeccompDeathTestService.MSG_RUN_TEST);
+        msg.getData().putBinder(SeccompDeathTestService.REPLY_BINDER_NAME, mMessenger.getBinder());
+        msg.getData().putInt(SeccompDeathTestService.RUN_TEST_IDENTIFIER, mTestNumber);
+
+        try {
+            service.linkToDeath(this, 0);
+            remoteMessenger.send(msg);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error setting up SeccompDeathTestService: " + e.getMessage());
+        }
+        Log.d(TAG, "Send MSG_TEST_START");
+    }
+
+    private void onTestStarted() {
+        Log.d(TAG, "onTestStarted");
+        mTestStarted = true;
+    }
+
+    @Override
+    public void onServiceDisconnected(ComponentName name) {
+        Log.d(TAG, "onServiceDisconnected");
+    }
+
+    @Override
+    public void binderDied() {
+        Log.d(TAG, "binderDied");
+        if (mTestEnded)
+            return;
+        onTestEnded(true);
+    }
+
+    private void onTestEnded(boolean died) {
+        Log.d(TAG, "onTestEnded, died=" + died);
+        mTestEnded = true;
+        mTestDied = died;
+        getContext().unbindService(this);
+        mCondition.open();
+    }
+}
diff --git a/tests/tests/security/src/android/security/cts/SeccompDeathTestService.java b/tests/tests/security/src/android/security/cts/SeccompDeathTestService.java
new file mode 100644
index 0000000..c78ea35
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/SeccompDeathTestService.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2014 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 android.security.cts;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.Messenger;
+import android.os.RemoteException;
+import android.util.Log;
+
+/**
+ * Service used to run tests for seccomp-bpf sandboxing. Since sandbox violations
+ * result in process termination, they cannot be run from within the test case
+ * itself. The SeccompBpfTest starts this service to run code out-of-process and
+ * then observes when the Binder channel dies. If the test does not die, the
+ * service reports back to the test that it exited cleanly.
+ */
+public class SeccompDeathTestService extends Service {
+    static final String TAG = SeccompBpfTest.TAG;
+
+    static {
+        System.loadLibrary("ctssecurity_jni");
+    }
+
+    /**
+     * Message sent from SeccompBpfTest to run a test.
+     */
+    final static int MSG_RUN_TEST = 100;
+    /**
+     * In MSG_RUN_TEST, the test number to run.
+     */
+    final static String RUN_TEST_IDENTIFIER = "android.security.cts.SeccompDeathTestService.testID";
+    /**
+     * In MSG_RUN_TEST, the Binder on which to report clean death.
+     */
+    static final String REPLY_BINDER_NAME = "android.security.cts.SeccompBpfTest";
+
+    // Test numbers that map to test methods in this service.
+    final static int TEST_DEATH_TEST = 1;
+    final static int TEST_CLEAN_TEST = 2;
+    final static int TEST_SIGSYS_SELF = 3;
+
+    final private Messenger mMessenger = new Messenger(new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MSG_RUN_TEST:
+                    runTest(msg);
+                    break;
+                default:
+                    super.handleMessage(msg);
+            }
+        }
+    });
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        Log.d(TAG, "onBind");
+        return mMessenger.getBinder();
+    }
+
+    private void runTest(Message msg) {
+        Log.d(TAG, "runTest");
+        IBinder harnessBinder = msg.getData().getBinder(REPLY_BINDER_NAME);
+        Messenger harness = new Messenger(harnessBinder);
+
+        try {
+            Log.d(TAG, "Send MSG_TEST_STARTED");
+            harness.send(Message.obtain(null, SeccompBpfTest.MSG_TEST_STARTED));
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed to MSG_TEST_STARTED: " + e.getMessage());
+        }
+
+        demuxTest(msg.getData().getInt(RUN_TEST_IDENTIFIER));
+
+        try {
+            Log.d(TAG, "Send MSG_TEST_ENDED_CLEAN");
+            harness.send(Message.obtain(null, SeccompBpfTest.MSG_TEST_ENDED_CLEAN));
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed to MSG_TEST_ENDED_CLEAN: " + e.getMessage());
+        }
+    }
+
+    private void demuxTest(int testNumber) {
+        switch (testNumber) {
+            case TEST_DEATH_TEST:
+                testDeath();
+                break;
+            case TEST_CLEAN_TEST:
+                break;
+            case TEST_SIGSYS_SELF:
+                testSigSysSelf();
+                break;
+            default:
+                throw new RuntimeException("Unknown test number " + testNumber);
+        }
+    }
+
+    public void testDeath() {
+        String s = null;
+        s.hashCode();
+    }
+
+    public native void testSigSysSelf();
+}
diff --git a/tests/tests/telephony/src/android/telephony/cts/SmsManagerTest.java b/tests/tests/telephony/src/android/telephony/cts/SmsManagerTest.java
index ac1acfb..39f5177 100644
--- a/tests/tests/telephony/src/android/telephony/cts/SmsManagerTest.java
+++ b/tests/tests/telephony/src/android/telephony/cts/SmsManagerTest.java
@@ -75,6 +75,7 @@
                     "44074",    // KDDI
                     "44075",    // KDDI
                     "44076",    // KDDI
+                    "50502",    // OPS
                     "51502",    // Globe Telecoms
                     "51503",    // Smart Communications
                     "51505",    // Sun Cellular
@@ -87,6 +88,7 @@
                     "302370",   // Fido
                     "30237",    // Fido
                     "311490",   // Virgin Mobile
+                    "312530",   // Sprint Prepaid
                     "310000",   // Tracfone
                     "46003",    // China Telecom
                     "311230",   // C SPire Wireless + Celluar South
diff --git a/tests/tests/text/src/android/text/method/cts/ArrowKeyMovementMethodTest.java b/tests/tests/text/src/android/text/method/cts/ArrowKeyMovementMethodTest.java
index 9b1acf7..3513281 100644
--- a/tests/tests/text/src/android/text/method/cts/ArrowKeyMovementMethodTest.java
+++ b/tests/tests/text/src/android/text/method/cts/ArrowKeyMovementMethodTest.java
@@ -179,26 +179,30 @@
 
     @UiThreadTest
     public void testOnKeyDownWithKeyCodeUp() {
+        // shift+alt tests
+        KeyEvent shiftAltEvent = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_UP,
+                0, KeyEvent.META_ALT_ON | KeyEvent.META_SHIFT_ON);
+
         // first line
         // second |line
         // last line
         Selection.setSelection(mEditable, SPACE_IN_2ND_LINE);
         pressBothShiftAlt();
-        KeyEvent event = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN,
-            KeyEvent.KEYCODE_DPAD_UP, 0, KeyEvent.META_ALT_ON | KeyEvent.META_SHIFT_ON);
         assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
-                KeyEvent.KEYCODE_DPAD_UP, event));
+                KeyEvent.KEYCODE_DPAD_UP, shiftAltEvent));
         // |first line
         // second |line
         // last line
         assertSelection(SPACE_IN_2ND_LINE, 0);
 
+        // shift tests
+        KeyEvent shiftEvent = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_UP, 0,
+                KeyEvent.META_SHIFT_ON);
+
         Selection.setSelection(mEditable, SPACE_IN_2ND_LINE);
         pressShift();
-        event = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN,
-            KeyEvent.KEYCODE_DPAD_UP, 0, KeyEvent.META_SHIFT_ON);
         assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
-                KeyEvent.KEYCODE_DPAD_UP, event));
+                KeyEvent.KEYCODE_DPAD_UP, shiftEvent));
         // first lin|e
         // second |line
         // last line
@@ -209,37 +213,40 @@
 
         pressShift();
         assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
-                KeyEvent.KEYCODE_DPAD_UP, new KeyEvent(KeyEvent.ACTION_DOWN,
-                        KeyEvent.KEYCODE_DPAD_UP)));
+                KeyEvent.KEYCODE_DPAD_UP, shiftEvent));
         // |first line
         // second |line
         // last line
         assertSelection(SPACE_IN_2ND_LINE, 0);
 
+        // alt tests
+        KeyEvent altEvent = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_UP, 0,
+                KeyEvent.META_ALT_ON);
+
         Selection.setSelection(mEditable, SPACE_IN_2ND_LINE);
         pressAlt();
-        event = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN,
-            KeyEvent.KEYCODE_DPAD_UP, 0, KeyEvent.META_ALT_ON);
         assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
-                KeyEvent.KEYCODE_DPAD_UP, event));
+                KeyEvent.KEYCODE_DPAD_UP, altEvent));
         // |first line
         // second line
         // last line
         assertSelection(0);
 
+        // no-meta tests
+        KeyEvent noMetaEvent = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_UP,
+                0, 0);
+
         Selection.setSelection(mEditable, SPACE_IN_2ND_LINE);
         MetaKeyKeyListener.resetMetaState(mEditable);
         assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
-                KeyEvent.KEYCODE_DPAD_UP, new KeyEvent(KeyEvent.ACTION_DOWN,
-                        KeyEvent.KEYCODE_DPAD_UP)));
+                KeyEvent.KEYCODE_DPAD_UP, noMetaEvent));
         // first lin|e
         // second line
         // last line
         assertSelection(correspondingIn1stLine);
 
         assertFalse(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
-                KeyEvent.KEYCODE_DPAD_UP, new KeyEvent(KeyEvent.ACTION_DOWN,
-                        KeyEvent.KEYCODE_DPAD_UP)));
+                KeyEvent.KEYCODE_DPAD_UP, noMetaEvent));
         // first lin|e
         // second line
         // last line
@@ -248,26 +255,30 @@
 
     @UiThreadTest
     public void testOnKeyDownWithKeyCodeDown() {
+        // shift+alt tests
+        KeyEvent shiftAltEvent = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN,
+                KeyEvent.KEYCODE_DPAD_DOWN, 0, KeyEvent.META_ALT_ON | KeyEvent.META_SHIFT_ON);
+
         // first line
         // second |line
         // last line
         Selection.setSelection(mEditable, SPACE_IN_2ND_LINE);
         pressBothShiftAlt();
-        KeyEvent event = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN,
-                KeyEvent.KEYCODE_DPAD_DOWN, 0, KeyEvent.META_ALT_ON | KeyEvent.META_SHIFT_ON);
         assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
-                KeyEvent.KEYCODE_DPAD_DOWN, event));
+                KeyEvent.KEYCODE_DPAD_DOWN, shiftAltEvent));
         // first line
         // second |line
         // last line|
         assertSelection(SPACE_IN_2ND_LINE, END_OF_ALL_TEXT);
 
+        // shift tests
+        KeyEvent shiftEvent = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_DOWN,
+                0, KeyEvent.META_SHIFT_ON);
+
         Selection.setSelection(mEditable, SPACE_IN_2ND_LINE);
         pressShift();
-        event = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN,
-                KeyEvent.KEYCODE_DPAD_DOWN, 0, KeyEvent.META_SHIFT_ON);
         assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
-                KeyEvent.KEYCODE_DPAD_DOWN, event));
+                KeyEvent.KEYCODE_DPAD_DOWN, shiftEvent));
         // first line
         // second |line
         // last lin|e
@@ -277,40 +288,41 @@
         assertTrue(correspondingIn3rdLine <= END_OF_ALL_TEXT);
 
         pressShift();
-        event = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN,
-                KeyEvent.KEYCODE_DPAD_DOWN, 0, 0);
         assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
-                KeyEvent.KEYCODE_DPAD_DOWN, event));
+                KeyEvent.KEYCODE_DPAD_DOWN, shiftEvent));
         // first line
         // second |line
         // last line|
         assertSelection(SPACE_IN_2ND_LINE, END_OF_ALL_TEXT);
 
+        // alt tests
+        KeyEvent altEvent = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_DOWN, 0,
+                KeyEvent.META_ALT_ON);
+
         Selection.setSelection(mEditable, SPACE_IN_2ND_LINE);
         pressAlt();
-        event = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN,
-                KeyEvent.KEYCODE_DPAD_DOWN, 0, KeyEvent.META_ALT_ON);
         assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
-                KeyEvent.KEYCODE_DPAD_DOWN, event));
+                KeyEvent.KEYCODE_DPAD_DOWN, altEvent));
         // first line
         // second line
         // last line|
         assertSelection(END_OF_ALL_TEXT);
 
-        pressAlt();
+        // no-meta tests
+        KeyEvent noMetaEvent = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_DOWN,
+                0, 0);
+
         Selection.setSelection(mEditable, SPACE_IN_2ND_LINE);
         MetaKeyKeyListener.resetMetaState(mEditable);
-        event = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN,
-                KeyEvent.KEYCODE_DPAD_DOWN, 0, 0);
         assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
-                KeyEvent.KEYCODE_DPAD_DOWN, event));
+                KeyEvent.KEYCODE_DPAD_DOWN, noMetaEvent));
         // first line
         // second line
         // last lin|e
         assertSelection(correspondingIn3rdLine);
 
         assertFalse(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
-                KeyEvent.KEYCODE_DPAD_DOWN, event));
+                KeyEvent.KEYCODE_DPAD_DOWN, noMetaEvent));
         // first line
         // second line
         // last lin|e
@@ -319,15 +331,17 @@
 
     @UiThreadTest
     public void testOnKeyDownWithKeyCodeLeft() {
+        // shift+alt tests
+        KeyEvent shiftAltEvent = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN,
+                KeyEvent.KEYCODE_DPAD_LEFT, 0, KeyEvent.META_ALT_ON | KeyEvent.META_SHIFT_ON);
+
         // first line
         // second |line
         // last line
         Selection.setSelection(mEditable, SPACE_IN_2ND_LINE);
         pressBothShiftAlt();
-        KeyEvent event = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN,
-            KeyEvent.KEYCODE_DPAD_LEFT, 0, KeyEvent.META_ALT_ON | KeyEvent.META_SHIFT_ON);
         assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
-                KeyEvent.KEYCODE_DPAD_LEFT, event));
+                KeyEvent.KEYCODE_DPAD_LEFT, shiftAltEvent));
         // first line
         // |second |line
         // last line
@@ -335,18 +349,20 @@
 
         pressBothShiftAlt();
         assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
-                KeyEvent.KEYCODE_DPAD_LEFT, event));
+                KeyEvent.KEYCODE_DPAD_LEFT, shiftAltEvent));
         // first line
         // |second |line
         // last line
         assertSelection(SPACE_IN_2ND_LINE, START_OF_2ND_LINE);
 
+        // shift tests
+        KeyEvent shiftEvent = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_LEFT,
+                0, KeyEvent.META_SHIFT_ON);
+
         Selection.setSelection(mEditable, SPACE_IN_2ND_LINE);
         pressShift();
-        event = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN,
-            KeyEvent.KEYCODE_DPAD_LEFT, 0, KeyEvent.META_SHIFT_ON);
         assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
-                KeyEvent.KEYCODE_DPAD_LEFT, event));
+                KeyEvent.KEYCODE_DPAD_LEFT, shiftEvent));
         // first line
         // second| |line
         // last line
@@ -354,19 +370,20 @@
 
         pressShift();
         assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
-                KeyEvent.KEYCODE_DPAD_LEFT, new KeyEvent(KeyEvent.ACTION_DOWN,
-                        KeyEvent.KEYCODE_DPAD_LEFT)));
+                KeyEvent.KEYCODE_DPAD_LEFT, shiftEvent));
         // first line
         // secon|d |line
         // last line
         assertSelection(SPACE_IN_2ND_LINE, SPACE_IN_2ND_LINE - 2);
 
+        // alt tests
+        KeyEvent altEvent = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_LEFT, 0,
+                KeyEvent.META_ALT_ON);
+
         Selection.setSelection(mEditable, SPACE_IN_2ND_LINE);
         pressAlt();
-        event = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN,
-            KeyEvent.KEYCODE_DPAD_LEFT, 0, KeyEvent.META_ALT_ON);
         assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
-                KeyEvent.KEYCODE_DPAD_LEFT, event));
+                KeyEvent.KEYCODE_DPAD_LEFT, altEvent));
         // first line
         // |second line
         // last line
@@ -374,17 +391,20 @@
 
         pressAlt();
         assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
-                KeyEvent.KEYCODE_DPAD_LEFT, event));
+                KeyEvent.KEYCODE_DPAD_LEFT, altEvent));
         // first line
         // |second line
         // last line
         assertSelection(START_OF_2ND_LINE);
 
+        // no-meta tests
+        KeyEvent noMetaEvent = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_LEFT,
+                0, 0);
+
         Selection.setSelection(mEditable, SPACE_IN_2ND_LINE);
         MetaKeyKeyListener.resetMetaState(mEditable);
         assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
-                KeyEvent.KEYCODE_DPAD_LEFT, new KeyEvent(KeyEvent.ACTION_DOWN,
-                        KeyEvent.KEYCODE_DPAD_LEFT)));
+                KeyEvent.KEYCODE_DPAD_LEFT, noMetaEvent));
         // first line
         // second| line
         // last line
@@ -395,8 +415,7 @@
         // |second line
         // last line
         assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
-                KeyEvent.KEYCODE_DPAD_LEFT, new KeyEvent(KeyEvent.ACTION_DOWN,
-                        KeyEvent.KEYCODE_DPAD_LEFT)));
+                KeyEvent.KEYCODE_DPAD_LEFT, noMetaEvent));
         // first line|
         // second line
         // last line
@@ -405,15 +424,17 @@
 
     @UiThreadTest
     public void testOnKeyDownWithKeyCodeRight() {
+        // shift+alt tests
+        KeyEvent shiftAltEvent = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN,
+                KeyEvent.KEYCODE_DPAD_RIGHT, 0, KeyEvent.META_ALT_ON | KeyEvent.META_SHIFT_ON);
+
         // first line
         // second |line
         // last line
         Selection.setSelection(mEditable, SPACE_IN_2ND_LINE);
         pressBothShiftAlt();
-        KeyEvent event = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN,
-            KeyEvent.KEYCODE_DPAD_RIGHT, 0, KeyEvent.META_ALT_ON | KeyEvent.META_SHIFT_ON);
         assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
-                KeyEvent.KEYCODE_DPAD_RIGHT, event));
+                KeyEvent.KEYCODE_DPAD_RIGHT, shiftAltEvent));
         // first line
         // second |line|
         // last line
@@ -421,18 +442,20 @@
 
         pressBothShiftAlt();
         assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
-                KeyEvent.KEYCODE_DPAD_RIGHT, event));
+                KeyEvent.KEYCODE_DPAD_RIGHT, shiftAltEvent));
         // first line
         // second |line|
         // last line
         assertSelection(SPACE_IN_2ND_LINE, END_OF_2ND_LINE);
 
+        // shift tests
+        KeyEvent shiftEvent = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_RIGHT,
+                0, KeyEvent.META_SHIFT_ON);
+
         Selection.setSelection(mEditable, SPACE_IN_2ND_LINE);
         pressShift();
-        event = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN,
-            KeyEvent.KEYCODE_DPAD_RIGHT, 0, KeyEvent.META_SHIFT_ON);
         assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
-                KeyEvent.KEYCODE_DPAD_RIGHT, event));
+                KeyEvent.KEYCODE_DPAD_RIGHT, shiftEvent));
         // first line
         // second |l|ine
         // last line
@@ -440,18 +463,20 @@
 
         pressShift();
         assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
-                KeyEvent.KEYCODE_DPAD_RIGHT, event));
+                KeyEvent.KEYCODE_DPAD_RIGHT, shiftEvent));
         // first line
         // second |li|ne
         // last line
         assertSelection(SPACE_IN_2ND_LINE, SPACE_IN_2ND_LINE + 2);
 
+        // alt tests
+        KeyEvent altEvent = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_RIGHT,
+                0, KeyEvent.META_ALT_ON);
+
         Selection.setSelection(mEditable, SPACE_IN_2ND_LINE);
         pressAlt();
-        event = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN,
-            KeyEvent.KEYCODE_DPAD_RIGHT, 0, KeyEvent.META_ALT_ON);
         assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
-                KeyEvent.KEYCODE_DPAD_RIGHT, event));
+                KeyEvent.KEYCODE_DPAD_RIGHT, altEvent));
         // first line
         // second line|
         // last line
@@ -459,17 +484,20 @@
 
         pressAlt();
         assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
-                KeyEvent.KEYCODE_DPAD_RIGHT, event));
+                KeyEvent.KEYCODE_DPAD_RIGHT, altEvent));
         // first line
         // second line|
         // last line
         assertSelection(END_OF_2ND_LINE);
 
+        // no-meta tests
+        KeyEvent noMetaEvent = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN,
+                KeyEvent.KEYCODE_DPAD_RIGHT, 0, 0);
+
         Selection.setSelection(mEditable, SPACE_IN_2ND_LINE);
         MetaKeyKeyListener.resetMetaState(mEditable);
         assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
-                KeyEvent.KEYCODE_DPAD_RIGHT, new KeyEvent(KeyEvent.ACTION_DOWN,
-                        KeyEvent.KEYCODE_DPAD_RIGHT)));
+                KeyEvent.KEYCODE_DPAD_RIGHT, noMetaEvent));
         // first line
         // second l|ine
         // last line
@@ -480,8 +508,7 @@
         // second line|
         // last line
         assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
-                KeyEvent.KEYCODE_DPAD_RIGHT, new KeyEvent(KeyEvent.ACTION_DOWN,
-                        KeyEvent.KEYCODE_DPAD_RIGHT)));
+                KeyEvent.KEYCODE_DPAD_RIGHT, noMetaEvent));
         // first line
         // second line
         // |last line
diff --git a/tests/tests/util/src/android/util/cts/JsonReaderTest.java b/tests/tests/util/src/android/util/cts/JsonReaderTest.java
new file mode 100644
index 0000000..5a9b336
--- /dev/null
+++ b/tests/tests/util/src/android/util/cts/JsonReaderTest.java
@@ -0,0 +1,955 @@
+/*
+ * Copyright (C) 2010 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 android.util.cts;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.Arrays;
+import junit.framework.TestCase;
+
+import android.util.MalformedJsonException;
+import android.util.JsonReader;
+import android.util.JsonToken;
+
+public final class JsonReaderTest extends TestCase {
+
+    private static final int READER_BUFFER_SIZE = 1024;
+
+    public void testReadArray() throws IOException {
+        JsonReader reader = new JsonReader(new StringReader("[true, true]"));
+        reader.beginArray();
+        assertEquals(true, reader.nextBoolean());
+        assertEquals(true, reader.nextBoolean());
+        reader.endArray();
+        assertEquals(JsonToken.END_DOCUMENT, reader.peek());
+    }
+
+    public void testReadEmptyArray() throws IOException {
+        JsonReader reader = new JsonReader(new StringReader("[]"));
+        reader.beginArray();
+        assertFalse(reader.hasNext());
+        reader.endArray();
+        assertEquals(JsonToken.END_DOCUMENT, reader.peek());
+    }
+
+    public void testReadObject() throws IOException {
+        JsonReader reader = new JsonReader(new StringReader(
+                "{\"a\": \"android\", \"b\": \"banana\"}"));
+        reader.beginObject();
+        assertEquals("a", reader.nextName());
+        assertEquals("android", reader.nextString());
+        assertEquals("b", reader.nextName());
+        assertEquals("banana", reader.nextString());
+        reader.endObject();
+        assertEquals(JsonToken.END_DOCUMENT, reader.peek());
+    }
+
+    public void testReadEmptyObject() throws IOException {
+        JsonReader reader = new JsonReader(new StringReader("{}"));
+        reader.beginObject();
+        assertFalse(reader.hasNext());
+        reader.endObject();
+        assertEquals(JsonToken.END_DOCUMENT, reader.peek());
+    }
+
+    public void testSkipObject() throws IOException {
+        JsonReader reader = new JsonReader(new StringReader(
+                "{\"a\": { \"c\": [], \"d\": [true, true, {}] }, \"b\": \"banana\"}"));
+        reader.beginObject();
+        assertEquals("a", reader.nextName());
+        reader.skipValue();
+        assertEquals("b", reader.nextName());
+        reader.skipValue();
+        reader.endObject();
+        assertEquals(JsonToken.END_DOCUMENT, reader.peek());
+    }
+
+    public void testSkipBeforeEndOfObject() throws IOException {
+        JsonReader reader = new JsonReader(new StringReader("{}"));
+        reader.beginObject();
+        try {
+            reader.skipValue();
+            fail("Should not be possible to skip without elements.");
+        } catch (IllegalStateException expected) {
+        }
+    }
+
+    public void testSkipBeforeEndOfArray() throws IOException {
+        JsonReader reader = new JsonReader(new StringReader("[]"));
+        reader.beginArray();
+        try {
+            reader.skipValue();
+            fail("Should not be possible to skip without elements.");
+        } catch (IllegalStateException expected) {
+        }
+    }
+
+    public void testSkipAfterEndOfDocument() throws IOException {
+        JsonReader reader = new JsonReader(new StringReader("{}"));
+        reader.beginObject();
+        reader.endObject();
+        assertEquals(JsonToken.END_DOCUMENT, reader.peek());
+        try {
+            reader.skipValue();
+            fail("Should not be possible to skip without elements.");
+        } catch (IllegalStateException expected) {
+        }
+    }
+
+    public void testHelloWorld() throws IOException {
+        String json = "{\n" +
+                "   \"hello\": true,\n" +
+                "   \"foo\": [\"world\"]\n" +
+                "}";
+        JsonReader reader = new JsonReader(new StringReader(json));
+        reader.beginObject();
+        assertEquals("hello", reader.nextName());
+        assertEquals(true, reader.nextBoolean());
+        assertEquals("foo", reader.nextName());
+        reader.beginArray();
+        assertEquals("world", reader.nextString());
+        reader.endArray();
+        reader.endObject();
+        assertEquals(JsonToken.END_DOCUMENT, reader.peek());
+    }
+
+    public void testNulls() {
+        try {
+            new JsonReader(null);
+            fail();
+        } catch (NullPointerException expected) {
+        }
+    }
+
+    public void testEmptyString() throws IOException {
+        try {
+            new JsonReader(new StringReader("")).beginArray();
+        } catch (IOException expected) {
+        }
+        try {
+            new JsonReader(new StringReader("")).beginObject();
+        } catch (IOException expected) {
+        }
+    }
+
+    public void testNoTopLevelObject() throws IOException {
+        try {
+            new JsonReader(new StringReader("true")).nextBoolean();
+        } catch (IOException expected) {
+        }
+    }
+
+    public void testCharacterUnescaping() throws IOException {
+        String json = "[\"a\","
+                + "\"a\\\"\","
+                + "\"\\\"\","
+                + "\":\","
+                + "\",\","
+                + "\"\\b\","
+                + "\"\\f\","
+                + "\"\\n\","
+                + "\"\\r\","
+                + "\"\\t\","
+                + "\" \","
+                + "\"\\\\\","
+                + "\"{\","
+                + "\"}\","
+                + "\"[\","
+                + "\"]\","
+                + "\"\\u0000\","
+                + "\"\\u0019\","
+                + "\"\\u20AC\""
+                + "]";
+        JsonReader reader = new JsonReader(new StringReader(json));
+        reader.beginArray();
+        assertEquals("a", reader.nextString());
+        assertEquals("a\"", reader.nextString());
+        assertEquals("\"", reader.nextString());
+        assertEquals(":", reader.nextString());
+        assertEquals(",", reader.nextString());
+        assertEquals("\b", reader.nextString());
+        assertEquals("\f", reader.nextString());
+        assertEquals("\n", reader.nextString());
+        assertEquals("\r", reader.nextString());
+        assertEquals("\t", reader.nextString());
+        assertEquals(" ", reader.nextString());
+        assertEquals("\\", reader.nextString());
+        assertEquals("{", reader.nextString());
+        assertEquals("}", reader.nextString());
+        assertEquals("[", reader.nextString());
+        assertEquals("]", reader.nextString());
+        assertEquals("\0", reader.nextString());
+        assertEquals("\u0019", reader.nextString());
+        assertEquals("\u20AC", reader.nextString());
+        reader.endArray();
+        assertEquals(JsonToken.END_DOCUMENT, reader.peek());
+    }
+
+    public void testIntegersWithFractionalPartSpecified() throws IOException {
+        JsonReader reader = new JsonReader(new StringReader("[1.0,1.0,1.0]"));
+        reader.beginArray();
+        assertEquals(1.0, reader.nextDouble());
+        assertEquals(1, reader.nextInt());
+        assertEquals(1L, reader.nextLong());
+    }
+
+    public void testDoubles() throws IOException {
+        String json = "[-0.0,"
+                + "1.0,"
+                + "1.7976931348623157E308,"
+                + "4.9E-324,"
+                + "0.0,"
+                + "-0.5,"
+                + "2.2250738585072014E-308,"
+                + "3.141592653589793,"
+                + "2.718281828459045,"
+                + "\"1.0\","
+                + "\"011.0\","
+                + "\"NaN\","
+                + "\"Infinity\","
+                + "\"-Infinity\""
+                + "]";
+        JsonReader reader = new JsonReader(new StringReader(json));
+        reader.beginArray();
+        assertEquals(-0.0, reader.nextDouble());
+        assertEquals(1.0, reader.nextDouble());
+        assertEquals(1.7976931348623157E308, reader.nextDouble());
+        assertEquals(4.9E-324, reader.nextDouble());
+        assertEquals(0.0, reader.nextDouble());
+        assertEquals(-0.5, reader.nextDouble());
+        assertEquals(2.2250738585072014E-308, reader.nextDouble());
+        assertEquals(3.141592653589793, reader.nextDouble());
+        assertEquals(2.718281828459045, reader.nextDouble());
+        assertEquals(1,0, reader.nextDouble());
+        assertEquals(11.0, reader.nextDouble());
+        assertTrue(Double.isNaN(reader.nextDouble()));
+        assertEquals(Double.POSITIVE_INFINITY, reader.nextDouble());
+        assertEquals(Double.NEGATIVE_INFINITY, reader.nextDouble());
+        reader.endArray();
+        assertEquals(JsonToken.END_DOCUMENT, reader.peek());
+    }
+
+    public void testLenientDoubles() throws IOException {
+        String json = "["
+                + "011.0,"
+                + "NaN,"
+                + "NAN,"
+                + "Infinity,"
+                + "INFINITY,"
+                + "-Infinity"
+                + "]";
+        JsonReader reader = new JsonReader(new StringReader(json));
+        reader.setLenient(true);
+        reader.beginArray();
+        assertEquals(11.0, reader.nextDouble());
+        assertTrue(Double.isNaN(reader.nextDouble()));
+        try {
+            reader.nextDouble();
+            fail();
+        } catch (NumberFormatException expected) {
+        }
+        assertEquals("NAN", reader.nextString());
+        assertEquals(Double.POSITIVE_INFINITY, reader.nextDouble());
+        try {
+            reader.nextDouble();
+            fail();
+        } catch (NumberFormatException expected) {
+        }
+        assertEquals("INFINITY", reader.nextString());
+        assertEquals(Double.NEGATIVE_INFINITY, reader.nextDouble());
+        reader.endArray();
+        assertEquals(JsonToken.END_DOCUMENT, reader.peek());
+    }
+
+    public void testBufferBoundary() throws IOException {
+        char[] pad = new char[READER_BUFFER_SIZE - 8];
+        Arrays.fill(pad, '5');
+        String json = "[\"" + new String(pad) + "\",33333]";
+        JsonReader reader = new JsonReader(new StringReader(json));
+        reader.beginArray();
+        assertEquals(JsonToken.STRING, reader.peek());
+        assertEquals(new String(pad), reader.nextString());
+        assertEquals(JsonToken.NUMBER, reader.peek());
+        assertEquals(33333, reader.nextInt());
+    }
+
+    public void testTruncatedBufferBoundary() throws IOException {
+        char[] pad = new char[READER_BUFFER_SIZE - 8];
+        Arrays.fill(pad, '5');
+        String json = "[\"" + new String(pad) + "\",33333";
+        JsonReader reader = new JsonReader(new StringReader(json));
+        reader.setLenient(true);
+        reader.beginArray();
+        assertEquals(JsonToken.STRING, reader.peek());
+        assertEquals(new String(pad), reader.nextString());
+        assertEquals(JsonToken.NUMBER, reader.peek());
+        assertEquals(33333, reader.nextInt());
+        try {
+            reader.endArray();
+            fail();
+        } catch (IOException e) {
+        }
+    }
+
+    public void testLongestSupportedNumericLiterals() throws IOException {
+        testLongNumericLiterals(READER_BUFFER_SIZE - 1, JsonToken.NUMBER);
+    }
+
+    public void testLongerNumericLiterals() throws IOException {
+        testLongNumericLiterals(READER_BUFFER_SIZE, JsonToken.STRING);
+    }
+
+    private void testLongNumericLiterals(int length, JsonToken expectedToken) throws IOException {
+        char[] longNumber = new char[length];
+        Arrays.fill(longNumber, '9');
+        longNumber[0] = '1';
+        longNumber[1] = '.';
+
+        String json = "[" + new String(longNumber) + "]";
+        JsonReader reader = new JsonReader(new StringReader(json));
+        reader.setLenient(true);
+        reader.beginArray();
+        assertEquals(expectedToken, reader.peek());
+        assertEquals(2.0d, reader.nextDouble());
+        reader.endArray();
+    }
+
+    public void testLongs() throws IOException {
+        String json = "[0,0,0,"
+                + "1,1,1,"
+                + "-1,-1,-1,"
+                + "-9223372036854775808,"
+                + "9223372036854775807,"
+                + "5.0,"
+                + "1.0e2,"
+                + "\"011\","
+                + "\"5.0\","
+                + "\"1.0e2\""
+                + "]";
+        JsonReader reader = new JsonReader(new StringReader(json));
+        reader.beginArray();
+        assertEquals(0L, reader.nextLong());
+        assertEquals(0, reader.nextInt());
+        assertEquals(0.0, reader.nextDouble());
+        assertEquals(1L, reader.nextLong());
+        assertEquals(1, reader.nextInt());
+        assertEquals(1.0, reader.nextDouble());
+        assertEquals(-1L, reader.nextLong());
+        assertEquals(-1, reader.nextInt());
+        assertEquals(-1.0, reader.nextDouble());
+        try {
+            reader.nextInt();
+            fail();
+        } catch (NumberFormatException expected) {
+        }
+        assertEquals(Long.MIN_VALUE, reader.nextLong());
+        try {
+            reader.nextInt();
+            fail();
+        } catch (NumberFormatException expected) {
+        }
+        assertEquals(Long.MAX_VALUE, reader.nextLong());
+        assertEquals(5, reader.nextLong());
+        assertEquals(100, reader.nextLong());
+        assertEquals(11, reader.nextLong());
+        assertEquals(5, reader.nextLong());
+        assertEquals(100, reader.nextLong());
+        reader.endArray();
+        assertEquals(JsonToken.END_DOCUMENT, reader.peek());
+    }
+
+    public void testHighPrecisionDouble_losesPrecision() throws IOException {
+        // The presence of a fractional part forces us to use Double.parseDouble
+        // instead of Long.parseLong (even though the fractional part is 0).
+        //
+        // A 52 bit mantissa isn't sufficient to precisely represent any of these
+        // values, so we will lose some precision, thereby storing it as
+        // ~(9.223372036854776E18). This value is then implicitly converted into
+        // a long and is required by the JLS to be clamped to Long.MAX_VALUE since
+        // it's larger than the largest long.
+        String json = "["
+                + "9223372036854775806.000,"  // Long.MAX_VALUE - 1
+                + "9223372036854775807.000,"  // Long.MAX_VALUE
+                + "9223372036854775808.000"   // Long.MAX_VALUE + 1
+                + "]";
+        JsonReader reader = new JsonReader(new StringReader(json));
+        reader.beginArray();
+        assertEquals(Long.MAX_VALUE, reader.nextLong());
+        assertEquals(Long.MAX_VALUE, reader.nextLong());
+        assertEquals(Long.MAX_VALUE, reader.nextLong());
+        reader.endArray();
+    }
+
+    public void testMatchingValidNumbers() throws IOException {
+        String json = "[-1,99,-0,0,0e1,0e+1,0e-1,0E1,0E+1,0E-1,0.0,1.0,-1.0,1.0e0,1.0e+1,1.0e-1]";
+        JsonReader reader = new JsonReader(new StringReader(json));
+        reader.beginArray();
+        for (int i = 0; i < 16; i++) {
+            assertEquals(JsonToken.NUMBER, reader.peek());
+            reader.nextDouble();
+        }
+        reader.endArray();
+    }
+
+    public void testRecognizingInvalidNumbers() throws IOException {
+        String json = "[-00,00,001,+1,1f,0x,0xf,0x0,0f1,0ee1,1..0,1e0.1,1.-01,1.+1,1.0x,1.0+]";
+        JsonReader reader = new JsonReader(new StringReader(json));
+        reader.setLenient(true);
+        reader.beginArray();
+        for (int i = 0; i < 16; i++) {
+            assertEquals(JsonToken.STRING, reader.peek());
+            reader.nextString();
+        }
+        reader.endArray();
+    }
+
+    public void testNonFiniteDouble() throws IOException {
+        String json = "[NaN]";
+        JsonReader reader = new JsonReader(new StringReader(json));
+        reader.beginArray();
+        try {
+            reader.nextDouble();
+            fail();
+        } catch (IOException expected) {
+        }
+    }
+
+    public void testNumberWithHexPrefix() throws IOException {
+        String json = "[0x11]";
+        JsonReader reader = new JsonReader(new StringReader(json));
+        reader.beginArray();
+        try {
+            reader.nextLong();
+            fail();
+        } catch (IOException expected) {
+        }
+    }
+
+    public void testNumberWithOctalPrefix() throws IOException {
+        String json = "[01]";
+        JsonReader reader = new JsonReader(new StringReader(json));
+        reader.beginArray();
+        try {
+            reader.nextInt();
+            fail();
+        } catch (IOException expected) {
+        }
+    }
+
+    public void testBooleans() throws IOException {
+        JsonReader reader = new JsonReader(new StringReader("[true,false]"));
+        reader.beginArray();
+        assertEquals(true, reader.nextBoolean());
+        assertEquals(false, reader.nextBoolean());
+        reader.endArray();
+        assertEquals(JsonToken.END_DOCUMENT, reader.peek());
+    }
+
+    public void testMixedCaseLiterals() throws IOException {
+        JsonReader reader = new JsonReader(new StringReader("[True,TruE,False,FALSE,NULL,nulL]"));
+        reader.beginArray();
+        assertEquals(true, reader.nextBoolean());
+        assertEquals(true, reader.nextBoolean());
+        assertEquals(false, reader.nextBoolean());
+        assertEquals(false, reader.nextBoolean());
+        reader.nextNull();
+        reader.nextNull();
+        reader.endArray();
+        assertEquals(JsonToken.END_DOCUMENT, reader.peek());
+    }
+
+    public void testMissingValue() throws IOException {
+        JsonReader reader = new JsonReader(new StringReader("{\"a\":}"));
+        reader.beginObject();
+        assertEquals("a", reader.nextName());
+        try {
+            reader.nextString();
+            fail();
+        } catch (IOException expected) {
+        }
+    }
+
+    public void testPrematureEndOfInput() throws IOException {
+        JsonReader reader = new JsonReader(new StringReader("{\"a\":true,"));
+        reader.beginObject();
+        assertEquals("a", reader.nextName());
+        assertEquals(true, reader.nextBoolean());
+        try {
+            reader.nextName();
+            fail();
+        } catch (IOException expected) {
+        }
+    }
+
+    public void testPrematurelyClosed() throws IOException {
+        try {
+            JsonReader reader = new JsonReader(new StringReader("{\"a\":[]}"));
+            reader.beginObject();
+            reader.close();
+            reader.nextName();
+            fail();
+        } catch (IllegalStateException expected) {
+        }
+
+        try {
+            JsonReader reader = new JsonReader(new StringReader("{\"a\":[]}"));
+            reader.close();
+            reader.beginObject();
+            fail();
+        } catch (IllegalStateException expected) {
+        }
+
+        try {
+            JsonReader reader = new JsonReader(new StringReader("{\"a\":true}"));
+            reader.beginObject();
+            reader.nextName();
+            reader.peek();
+            reader.close();
+            reader.nextBoolean();
+            fail();
+        } catch (IllegalStateException expected) {
+        }
+    }
+
+    public void testNextFailuresDoNotAdvance() throws IOException {
+        JsonReader reader = new JsonReader(new StringReader("{\"a\":true}"));
+        reader.beginObject();
+        try {
+            reader.nextString();
+            fail();
+        } catch (IllegalStateException expected) {
+        }
+        assertEquals("a", reader.nextName());
+        try {
+            reader.nextName();
+            fail();
+        } catch (IllegalStateException expected) {
+        }
+        try {
+            reader.beginArray();
+            fail();
+        } catch (IllegalStateException expected) {
+        }
+        try {
+            reader.endArray();
+            fail();
+        } catch (IllegalStateException expected) {
+        }
+        try {
+            reader.beginObject();
+            fail();
+        } catch (IllegalStateException expected) {
+        }
+        try {
+            reader.endObject();
+            fail();
+        } catch (IllegalStateException expected) {
+        }
+        assertEquals(true, reader.nextBoolean());
+        try {
+            reader.nextString();
+            fail();
+        } catch (IllegalStateException expected) {
+        }
+        try {
+            reader.nextName();
+            fail();
+        } catch (IllegalStateException expected) {
+        }
+        try {
+            reader.beginArray();
+            fail();
+        } catch (IllegalStateException expected) {
+        }
+        try {
+            reader.endArray();
+            fail();
+        } catch (IllegalStateException expected) {
+        }
+        reader.endObject();
+        assertEquals(JsonToken.END_DOCUMENT, reader.peek());
+        reader.close();
+    }
+
+    public void testStringNullIsNotNull() throws IOException {
+        JsonReader reader = new JsonReader(new StringReader("[\"null\"]"));
+        reader.beginArray();
+        try {
+            reader.nextNull();
+            fail();
+        } catch (IllegalStateException expected) {
+        }
+    }
+
+    public void testNullLiteralIsNotAString() throws IOException {
+       JsonReader reader = new JsonReader(new StringReader("[null]"));
+        reader.beginArray();
+        try {
+            reader.nextString();
+            fail();
+        } catch (IllegalStateException expected) {
+        }
+    }
+
+    public void testStrictNameValueSeparator() throws IOException {
+        JsonReader reader = new JsonReader(new StringReader("{\"a\"=true}"));
+        reader.beginObject();
+        assertEquals("a", reader.nextName());
+        try {
+            reader.nextBoolean();
+            fail();
+        } catch (IOException expected) {
+        }
+
+        reader = new JsonReader(new StringReader("{\"a\"=>true}"));
+        reader.beginObject();
+        assertEquals("a", reader.nextName());
+        try {
+            reader.nextBoolean();
+            fail();
+        } catch (IOException expected) {
+        }
+    }
+
+    public void testLenientNameValueSeparator() throws IOException {
+        JsonReader reader = new JsonReader(new StringReader("{\"a\"=true}"));
+        reader.setLenient(true);
+        reader.beginObject();
+        assertEquals("a", reader.nextName());
+        assertEquals(true, reader.nextBoolean());
+
+        reader = new JsonReader(new StringReader("{\"a\"=>true}"));
+        reader.setLenient(true);
+        reader.beginObject();
+        assertEquals("a", reader.nextName());
+        assertEquals(true, reader.nextBoolean());
+    }
+
+    public void testStrictComments() throws IOException {
+        JsonReader reader = new JsonReader(new StringReader("[// comment \n true]"));
+        reader.beginArray();
+        try {
+            reader.nextBoolean();
+            fail();
+        } catch (IOException expected) {
+        }
+
+        reader = new JsonReader(new StringReader("[# comment \n true]"));
+        reader.beginArray();
+        try {
+            reader.nextBoolean();
+            fail();
+        } catch (IOException expected) {
+        }
+
+        reader = new JsonReader(new StringReader("[/* comment */ true]"));
+        reader.beginArray();
+        try {
+            reader.nextBoolean();
+            fail();
+        } catch (IOException expected) {
+        }
+    }
+
+    public void testLenientComments() throws IOException {
+        JsonReader reader = new JsonReader(new StringReader("[// comment \n true]"));
+        reader.setLenient(true);
+        reader.beginArray();
+        assertEquals(true, reader.nextBoolean());
+
+        reader = new JsonReader(new StringReader("[# comment \n true]"));
+        reader.setLenient(true);
+        reader.beginArray();
+        assertEquals(true, reader.nextBoolean());
+
+        reader = new JsonReader(new StringReader("[/* comment */ true]"));
+        reader.setLenient(true);
+        reader.beginArray();
+        assertEquals(true, reader.nextBoolean());
+    }
+
+    public void testStrictUnquotedNames() throws IOException {
+        JsonReader reader = new JsonReader(new StringReader("{a:true}"));
+        reader.beginObject();
+        try {
+            reader.nextName();
+            fail();
+        } catch (IOException expected) {
+        }
+    }
+
+    public void testLenientUnquotedNames() throws IOException {
+        JsonReader reader = new JsonReader(new StringReader("{a:true}"));
+        reader.setLenient(true);
+        reader.beginObject();
+        assertEquals("a", reader.nextName());
+    }
+
+    public void testStrictSingleQuotedNames() throws IOException {
+        JsonReader reader = new JsonReader(new StringReader("{'a':true}"));
+        reader.beginObject();
+        try {
+            reader.nextName();
+            fail();
+        } catch (IOException expected) {
+        }
+    }
+
+    public void testLenientSingleQuotedNames() throws IOException {
+        JsonReader reader = new JsonReader(new StringReader("{'a':true}"));
+        reader.setLenient(true);
+        reader.beginObject();
+        assertEquals("a", reader.nextName());
+    }
+
+    public void testStrictUnquotedStrings() throws IOException {
+        JsonReader reader = new JsonReader(new StringReader("[a]"));
+        reader.beginArray();
+        try {
+            reader.nextString();
+            fail();
+        } catch (MalformedJsonException expected) {
+        }
+    }
+
+    public void testLenientUnquotedStrings() throws IOException {
+        JsonReader reader = new JsonReader(new StringReader("[a]"));
+        reader.setLenient(true);
+        reader.beginArray();
+        assertEquals("a", reader.nextString());
+    }
+
+    public void testStrictSingleQuotedStrings() throws IOException {
+        JsonReader reader = new JsonReader(new StringReader("['a']"));
+        reader.beginArray();
+        try {
+            reader.nextString();
+            fail();
+        } catch (IOException expected) {
+        }
+    }
+
+    public void testLenientSingleQuotedStrings() throws IOException {
+        JsonReader reader = new JsonReader(new StringReader("['a']"));
+        reader.setLenient(true);
+        reader.beginArray();
+        assertEquals("a", reader.nextString());
+    }
+
+    public void testStrictSemicolonDelimitedArray() throws IOException {
+        JsonReader reader = new JsonReader(new StringReader("[true;true]"));
+        reader.beginArray();
+        try {
+            reader.nextBoolean();
+            reader.nextBoolean();
+            fail();
+        } catch (IOException expected) {
+        }
+    }
+
+    public void testLenientSemicolonDelimitedArray() throws IOException {
+        JsonReader reader = new JsonReader(new StringReader("[true;true]"));
+        reader.setLenient(true);
+        reader.beginArray();
+        assertEquals(true, reader.nextBoolean());
+        assertEquals(true, reader.nextBoolean());
+    }
+
+    public void testStrictSemicolonDelimitedNameValuePair() throws IOException {
+        JsonReader reader = new JsonReader(new StringReader("{\"a\":true;\"b\":true}"));
+        reader.beginObject();
+        assertEquals("a", reader.nextName());
+        try {
+            reader.nextBoolean();
+            reader.nextName();
+            fail();
+        } catch (IOException expected) {
+        }
+    }
+
+    public void testLenientSemicolonDelimitedNameValuePair() throws IOException {
+        JsonReader reader = new JsonReader(new StringReader("{\"a\":true;\"b\":true}"));
+        reader.setLenient(true);
+        reader.beginObject();
+        assertEquals("a", reader.nextName());
+        assertEquals(true, reader.nextBoolean());
+        assertEquals("b", reader.nextName());
+    }
+
+    public void testStrictUnnecessaryArraySeparators() throws IOException {
+        JsonReader reader = new JsonReader(new StringReader("[true,,true]"));
+        reader.beginArray();
+        assertEquals(true, reader.nextBoolean());
+        try {
+            reader.nextNull();
+            fail();
+        } catch (IOException expected) {
+        }
+
+        reader = new JsonReader(new StringReader("[,true]"));
+        reader.beginArray();
+        try {
+            reader.nextNull();
+            fail();
+        } catch (IOException expected) {
+        }
+
+        reader = new JsonReader(new StringReader("[true,]"));
+        reader.beginArray();
+        assertEquals(true, reader.nextBoolean());
+        try {
+            reader.nextNull();
+            fail();
+        } catch (IOException expected) {
+        }
+
+        reader = new JsonReader(new StringReader("[,]"));
+        reader.beginArray();
+        try {
+            reader.nextNull();
+            fail();
+        } catch (IOException expected) {
+        }
+    }
+
+    public void testLenientUnnecessaryArraySeparators() throws IOException {
+        JsonReader reader = new JsonReader(new StringReader("[true,,true]"));
+        reader.setLenient(true);
+        reader.beginArray();
+        assertEquals(true, reader.nextBoolean());
+        reader.nextNull();
+        assertEquals(true, reader.nextBoolean());
+        reader.endArray();
+
+        reader = new JsonReader(new StringReader("[,true]"));
+        reader.setLenient(true);
+        reader.beginArray();
+        reader.nextNull();
+        assertEquals(true, reader.nextBoolean());
+        reader.endArray();
+
+        reader = new JsonReader(new StringReader("[true,]"));
+        reader.setLenient(true);
+        reader.beginArray();
+        assertEquals(true, reader.nextBoolean());
+        reader.nextNull();
+        reader.endArray();
+
+        reader = new JsonReader(new StringReader("[,]"));
+        reader.setLenient(true);
+        reader.beginArray();
+        reader.nextNull();
+        reader.nextNull();
+        reader.endArray();
+    }
+
+    public void testStrictMultipleTopLevelValues() throws IOException {
+        JsonReader reader = new JsonReader(new StringReader("[] []"));
+        reader.beginArray();
+        reader.endArray();
+        try {
+            reader.peek();
+            fail();
+        } catch (IOException expected) {
+        }
+    }
+
+    public void testLenientMultipleTopLevelValues() throws IOException {
+        JsonReader reader = new JsonReader(new StringReader("[] true {}"));
+        reader.setLenient(true);
+        reader.beginArray();
+        reader.endArray();
+        assertEquals(true, reader.nextBoolean());
+        reader.beginObject();
+        reader.endObject();
+        assertEquals(JsonToken.END_DOCUMENT, reader.peek());
+    }
+
+    public void testStrictTopLevelValueType() {
+        JsonReader reader = new JsonReader(new StringReader("true"));
+        try {
+            reader.nextBoolean();
+            fail();
+        } catch (IOException expected) {
+        }
+    }
+
+    public void testLenientTopLevelValueType() throws IOException {
+        JsonReader reader = new JsonReader(new StringReader("true"));
+        reader.setLenient(true);
+        assertEquals(true, reader.nextBoolean());
+    }
+
+    public void testStrictNonExecutePrefix() {
+        JsonReader reader = new JsonReader(new StringReader(")]}'\n []"));
+        try {
+            reader.beginArray();
+            fail();
+        } catch (IOException expected) {
+        }
+    }
+
+    public void testBomIgnoredAsFirstCharacterOfDocument() throws IOException {
+        JsonReader reader = new JsonReader(new StringReader("\ufeff[]"));
+        reader.beginArray();
+        reader.endArray();
+    }
+
+    public void testBomForbiddenAsOtherCharacterInDocument() throws IOException {
+        JsonReader reader = new JsonReader(new StringReader("[\ufeff]"));
+        reader.beginArray();
+        try {
+            reader.endArray();
+            fail();
+        } catch (IOException expected) {
+        }
+    }
+
+    public void testFailWithPosition() throws IOException {
+        testFailWithPosition("Expected literal value at line 6 column 3",
+                "[\n\n\n\n\n0,}]");
+    }
+
+    public void testFailWithPositionIsOffsetByBom() throws IOException {
+        testFailWithPosition("Expected literal value at line 1 column 4",
+                "\ufeff[0,}]");
+    }
+
+    public void testFailWithPositionGreaterThanBufferSize() throws IOException {
+        String spaces = repeat(' ', 8192);
+        testFailWithPosition("Expected literal value at line 6 column 3",
+                "[\n\n" + spaces + "\n\n\n0,}]");
+    }
+
+    private void testFailWithPosition(String message, String json) throws IOException {
+        JsonReader reader = new JsonReader(new StringReader(json));
+        reader.beginArray();
+        reader.nextInt();
+        try {
+            reader.peek();
+            fail();
+        } catch (IOException expected) {
+            assertEquals(message, expected.getMessage());
+        }
+    }
+
+    private String repeat(char c, int count) {
+        char[] array = new char[count];
+        Arrays.fill(array, c);
+        return new String(array);
+    }
+}
diff --git a/tests/tests/util/src/android/util/cts/JsonWriterTest.java b/tests/tests/util/src/android/util/cts/JsonWriterTest.java
new file mode 100644
index 0000000..d0207d2
--- /dev/null
+++ b/tests/tests/util/src/android/util/cts/JsonWriterTest.java
@@ -0,0 +1,468 @@
+/*
+ * Copyright (C) 2010 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 android.util.cts;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import junit.framework.TestCase;
+
+import android.util.JsonWriter;
+
+public final class JsonWriterTest extends TestCase {
+
+    public void testWrongTopLevelType() throws IOException {
+        StringWriter stringWriter = new StringWriter();
+        JsonWriter jsonWriter = new JsonWriter(stringWriter);
+        try {
+            jsonWriter.value("a");
+            fail();
+        } catch (IllegalStateException expected) {
+        }
+    }
+
+    public void testTwoNames() throws IOException {
+        StringWriter stringWriter = new StringWriter();
+        JsonWriter jsonWriter = new JsonWriter(stringWriter);
+        jsonWriter.beginObject();
+        jsonWriter.name("a");
+        try {
+            jsonWriter.name("a");
+            fail();
+        } catch (IllegalStateException expected) {
+        }
+    }
+
+    public void testNameWithoutValue() throws IOException {
+        StringWriter stringWriter = new StringWriter();
+        JsonWriter jsonWriter = new JsonWriter(stringWriter);
+        jsonWriter.beginObject();
+        jsonWriter.name("a");
+        try {
+            jsonWriter.endObject();
+            fail();
+        } catch (IllegalStateException expected) {
+        }
+    }
+
+    public void testValueWithoutName() throws IOException {
+        StringWriter stringWriter = new StringWriter();
+        JsonWriter jsonWriter = new JsonWriter(stringWriter);
+        jsonWriter.beginObject();
+        try {
+            jsonWriter.value(true);
+            fail();
+        } catch (IllegalStateException expected) {
+        }
+    }
+
+    public void testMultipleTopLevelValues() throws IOException {
+        StringWriter stringWriter = new StringWriter();
+        JsonWriter jsonWriter = new JsonWriter(stringWriter);
+        jsonWriter.beginArray().endArray();
+        try {
+            jsonWriter.beginArray();
+            fail();
+        } catch (IllegalStateException expected) {
+        }
+    }
+
+    public void testBadNestingObject() throws IOException {
+        StringWriter stringWriter = new StringWriter();
+        JsonWriter jsonWriter = new JsonWriter(stringWriter);
+        jsonWriter.beginArray();
+        jsonWriter.beginObject();
+        try {
+            jsonWriter.endArray();
+            fail();
+        } catch (IllegalStateException expected) {
+        }
+    }
+
+    public void testBadNestingArray() throws IOException {
+        StringWriter stringWriter = new StringWriter();
+        JsonWriter jsonWriter = new JsonWriter(stringWriter);
+        jsonWriter.beginArray();
+        jsonWriter.beginArray();
+        try {
+            jsonWriter.endObject();
+            fail();
+        } catch (IllegalStateException expected) {
+        }
+    }
+
+    public void testNullName() throws IOException {
+        StringWriter stringWriter = new StringWriter();
+        JsonWriter jsonWriter = new JsonWriter(stringWriter);
+        jsonWriter.beginObject();
+        try {
+            jsonWriter.name(null);
+            fail();
+        } catch (NullPointerException expected) {
+        }
+    }
+
+    public void testNullStringValue() throws IOException {
+        StringWriter stringWriter = new StringWriter();
+        JsonWriter jsonWriter = new JsonWriter(stringWriter);
+        jsonWriter.beginObject();
+        jsonWriter.name("a");
+        jsonWriter.value((String) null);
+        jsonWriter.endObject();
+        assertEquals("{\"a\":null}", stringWriter.toString());
+    }
+
+    public void testNonFiniteDoubles() throws IOException {
+        StringWriter stringWriter = new StringWriter();
+        JsonWriter jsonWriter = new JsonWriter(stringWriter);
+        jsonWriter.beginArray();
+        try {
+            jsonWriter.value(Double.NaN);
+            fail();
+        } catch (IllegalArgumentException expected) {
+        }
+        try {
+            jsonWriter.value(Double.NEGATIVE_INFINITY);
+            fail();
+        } catch (IllegalArgumentException expected) {
+        }
+        try {
+            jsonWriter.value(Double.POSITIVE_INFINITY);
+            fail();
+        } catch (IllegalArgumentException expected) {
+        }
+    }
+
+    public void testNonFiniteBoxedDoubles() throws IOException {
+        StringWriter stringWriter = new StringWriter();
+        JsonWriter jsonWriter = new JsonWriter(stringWriter);
+        jsonWriter.beginArray();
+        try {
+            jsonWriter.value(new Double(Double.NaN));
+            fail();
+        } catch (IllegalArgumentException expected) {
+        }
+        try {
+            jsonWriter.value(new Double(Double.NEGATIVE_INFINITY));
+            fail();
+        } catch (IllegalArgumentException expected) {
+        }
+        try {
+            jsonWriter.value(new Double(Double.POSITIVE_INFINITY));
+            fail();
+        } catch (IllegalArgumentException expected) {
+        }
+    }
+
+    public void testDoubles() throws IOException {
+        StringWriter stringWriter = new StringWriter();
+        JsonWriter jsonWriter = new JsonWriter(stringWriter);
+        jsonWriter.beginArray();
+        jsonWriter.value(-0.0);
+        jsonWriter.value(1.0);
+        jsonWriter.value(Double.MAX_VALUE);
+        jsonWriter.value(Double.MIN_VALUE);
+        jsonWriter.value(0.0);
+        jsonWriter.value(-0.5);
+        jsonWriter.value(Double.MIN_NORMAL);
+        jsonWriter.value(Math.PI);
+        jsonWriter.value(Math.E);
+        jsonWriter.endArray();
+        jsonWriter.close();
+        assertEquals("[-0.0,"
+                + "1.0,"
+                + "1.7976931348623157E308,"
+                + "4.9E-324,"
+                + "0.0,"
+                + "-0.5,"
+                + "2.2250738585072014E-308,"
+                + "3.141592653589793,"
+                + "2.718281828459045]", stringWriter.toString());
+    }
+
+    public void testLongs() throws IOException {
+        StringWriter stringWriter = new StringWriter();
+        JsonWriter jsonWriter = new JsonWriter(stringWriter);
+        jsonWriter.beginArray();
+        jsonWriter.value(0);
+        jsonWriter.value(1);
+        jsonWriter.value(-1);
+        jsonWriter.value(Long.MIN_VALUE);
+        jsonWriter.value(Long.MAX_VALUE);
+        jsonWriter.endArray();
+        jsonWriter.close();
+        assertEquals("[0,"
+                + "1,"
+                + "-1,"
+                + "-9223372036854775808,"
+                + "9223372036854775807]", stringWriter.toString());
+    }
+
+    public void testNumbers() throws IOException {
+        StringWriter stringWriter = new StringWriter();
+        JsonWriter jsonWriter = new JsonWriter(stringWriter);
+        jsonWriter.beginArray();
+        jsonWriter.value(new BigInteger("0"));
+        jsonWriter.value(new BigInteger("9223372036854775808"));
+        jsonWriter.value(new BigInteger("-9223372036854775809"));
+        jsonWriter.value(new BigDecimal("3.141592653589793238462643383"));
+        jsonWriter.endArray();
+        jsonWriter.close();
+        assertEquals("[0,"
+                + "9223372036854775808,"
+                + "-9223372036854775809,"
+                + "3.141592653589793238462643383]", stringWriter.toString());
+    }
+
+    public void testBooleans() throws IOException {
+        StringWriter stringWriter = new StringWriter();
+        JsonWriter jsonWriter = new JsonWriter(stringWriter);
+        jsonWriter.beginArray();
+        jsonWriter.value(true);
+        jsonWriter.value(false);
+        jsonWriter.endArray();
+        assertEquals("[true,false]", stringWriter.toString());
+    }
+
+    public void testNulls() throws IOException {
+        StringWriter stringWriter = new StringWriter();
+        JsonWriter jsonWriter = new JsonWriter(stringWriter);
+        jsonWriter.beginArray();
+        jsonWriter.nullValue();
+        jsonWriter.endArray();
+        assertEquals("[null]", stringWriter.toString());
+    }
+
+    public void testStrings() throws IOException {
+        StringWriter stringWriter = new StringWriter();
+        JsonWriter jsonWriter = new JsonWriter(stringWriter);
+        jsonWriter.beginArray();
+        jsonWriter.value("a");
+        jsonWriter.value("a\"");
+        jsonWriter.value("\"");
+        jsonWriter.value(":");
+        jsonWriter.value(",");
+        jsonWriter.value("\b");
+        jsonWriter.value("\f");
+        jsonWriter.value("\n");
+        jsonWriter.value("\r");
+        jsonWriter.value("\t");
+        jsonWriter.value(" ");
+        jsonWriter.value("\\");
+        jsonWriter.value("{");
+        jsonWriter.value("}");
+        jsonWriter.value("[");
+        jsonWriter.value("]");
+        jsonWriter.value("\0");
+        jsonWriter.value("\u0019");
+        jsonWriter.endArray();
+        assertEquals("[\"a\","
+                + "\"a\\\"\","
+                + "\"\\\"\","
+                + "\":\","
+                + "\",\","
+                + "\"\\b\","
+                + "\"\\f\","
+                + "\"\\n\","
+                + "\"\\r\","
+                + "\"\\t\","
+                + "\" \","
+                + "\"\\\\\","
+                + "\"{\","
+                + "\"}\","
+                + "\"[\","
+                + "\"]\","
+                + "\"\\u0000\","
+                + "\"\\u0019\"]", stringWriter.toString());
+    }
+
+    public void testUnicodeLineBreaksEscaped() throws IOException {
+        StringWriter stringWriter = new StringWriter();
+        JsonWriter jsonWriter = new JsonWriter(stringWriter);
+        jsonWriter.beginArray();
+        jsonWriter.value("\u2028 \u2029");
+        jsonWriter.endArray();
+        assertEquals("[\"\\u2028 \\u2029\"]", stringWriter.toString());
+    }
+
+    public void testEmptyArray() throws IOException {
+        StringWriter stringWriter = new StringWriter();
+        JsonWriter jsonWriter = new JsonWriter(stringWriter);
+        jsonWriter.beginArray();
+        jsonWriter.endArray();
+        assertEquals("[]", stringWriter.toString());
+    }
+
+    public void testEmptyObject() throws IOException {
+        StringWriter stringWriter = new StringWriter();
+        JsonWriter jsonWriter = new JsonWriter(stringWriter);
+        jsonWriter.beginObject();
+        jsonWriter.endObject();
+        assertEquals("{}", stringWriter.toString());
+    }
+
+    public void testObjectsInArrays() throws IOException {
+        StringWriter stringWriter = new StringWriter();
+        JsonWriter jsonWriter = new JsonWriter(stringWriter);
+        jsonWriter.beginArray();
+        jsonWriter.beginObject();
+        jsonWriter.name("a").value(5);
+        jsonWriter.name("b").value(false);
+        jsonWriter.endObject();
+        jsonWriter.beginObject();
+        jsonWriter.name("c").value(6);
+        jsonWriter.name("d").value(true);
+        jsonWriter.endObject();
+        jsonWriter.endArray();
+        assertEquals("[{\"a\":5,\"b\":false},"
+                + "{\"c\":6,\"d\":true}]", stringWriter.toString());
+    }
+
+    public void testArraysInObjects() throws IOException {
+        StringWriter stringWriter = new StringWriter();
+        JsonWriter jsonWriter = new JsonWriter(stringWriter);
+        jsonWriter.beginObject();
+        jsonWriter.name("a");
+        jsonWriter.beginArray();
+        jsonWriter.value(5);
+        jsonWriter.value(false);
+        jsonWriter.endArray();
+        jsonWriter.name("b");
+        jsonWriter.beginArray();
+        jsonWriter.value(6);
+        jsonWriter.value(true);
+        jsonWriter.endArray();
+        jsonWriter.endObject();
+        assertEquals("{\"a\":[5,false],"
+                + "\"b\":[6,true]}", stringWriter.toString());
+    }
+
+    public void testDeepNestingArrays() throws IOException {
+        StringWriter stringWriter = new StringWriter();
+        JsonWriter jsonWriter = new JsonWriter(stringWriter);
+        for (int i = 0; i < 20; i++) {
+            jsonWriter.beginArray();
+        }
+        for (int i = 0; i < 20; i++) {
+            jsonWriter.endArray();
+        }
+        assertEquals("[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]", stringWriter.toString());
+    }
+
+    public void testDeepNestingObjects() throws IOException {
+        StringWriter stringWriter = new StringWriter();
+        JsonWriter jsonWriter = new JsonWriter(stringWriter);
+        jsonWriter.beginObject();
+        for (int i = 0; i < 20; i++) {
+            jsonWriter.name("a");
+            jsonWriter.beginObject();
+        }
+        for (int i = 0; i < 20; i++) {
+            jsonWriter.endObject();
+        }
+        jsonWriter.endObject();
+        assertEquals("{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":"
+                + "{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{"
+                + "}}}}}}}}}}}}}}}}}}}}}", stringWriter.toString());
+    }
+
+    public void testRepeatedName() throws IOException {
+        StringWriter stringWriter = new StringWriter();
+        JsonWriter jsonWriter = new JsonWriter(stringWriter);
+        jsonWriter.beginObject();
+        jsonWriter.name("a").value(true);
+        jsonWriter.name("a").value(false);
+        jsonWriter.endObject();
+        // JsonWriter doesn't attempt to detect duplicate names
+        assertEquals("{\"a\":true,\"a\":false}", stringWriter.toString());
+    }
+
+    public void testPrettyPrintObject() throws IOException {
+        StringWriter stringWriter = new StringWriter();
+        JsonWriter jsonWriter = new JsonWriter(stringWriter);
+        jsonWriter.setIndent("   ");
+
+        jsonWriter.beginObject();
+        jsonWriter.name("a").value(true);
+        jsonWriter.name("b").value(false);
+        jsonWriter.name("c").value(5.0);
+        jsonWriter.name("e").nullValue();
+        jsonWriter.name("f").beginArray();
+        jsonWriter.value(6.0);
+        jsonWriter.value(7.0);
+        jsonWriter.endArray();
+        jsonWriter.name("g").beginObject();
+        jsonWriter.name("h").value(8.0);
+        jsonWriter.name("i").value(9.0);
+        jsonWriter.endObject();
+        jsonWriter.endObject();
+
+        String expected = "{\n"
+                + "   \"a\": true,\n"
+                + "   \"b\": false,\n"
+                + "   \"c\": 5.0,\n"
+                + "   \"e\": null,\n"
+                + "   \"f\": [\n"
+                + "      6.0,\n"
+                + "      7.0\n"
+                + "   ],\n"
+                + "   \"g\": {\n"
+                + "      \"h\": 8.0,\n"
+                + "      \"i\": 9.0\n"
+                + "   }\n"
+                + "}";
+        assertEquals(expected, stringWriter.toString());
+    }
+
+    public void testPrettyPrintArray() throws IOException {
+        StringWriter stringWriter = new StringWriter();
+        JsonWriter jsonWriter = new JsonWriter(stringWriter);
+        jsonWriter.setIndent("   ");
+
+        jsonWriter.beginArray();
+        jsonWriter.value(true);
+        jsonWriter.value(false);
+        jsonWriter.value(5.0);
+        jsonWriter.nullValue();
+        jsonWriter.beginObject();
+        jsonWriter.name("a").value(6.0);
+        jsonWriter.name("b").value(7.0);
+        jsonWriter.endObject();
+        jsonWriter.beginArray();
+        jsonWriter.value(8.0);
+        jsonWriter.value(9.0);
+        jsonWriter.endArray();
+        jsonWriter.endArray();
+
+        String expected = "[\n"
+                + "   true,\n"
+                + "   false,\n"
+                + "   5.0,\n"
+                + "   null,\n"
+                + "   {\n"
+                + "      \"a\": 6.0,\n"
+                + "      \"b\": 7.0\n"
+                + "   },\n"
+                + "   [\n"
+                + "      8.0,\n"
+                + "      9.0\n"
+                + "   ]\n"
+                + "]";
+        assertEquals(expected, stringWriter.toString());
+    }
+}
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java b/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
index b25a0cf..c2104fe 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
@@ -226,7 +226,14 @@
             }
         }.run();
         int firstFetch = mWebServer.getRequestCount();
+        iconListener.mReceivedIcon = false;
         loadAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
+        new PollingCheck(WEBVIEW_TIMEOUT) {
+            @Override
+            protected boolean check() {
+                return iconListener.mReceivedIcon;
+            }
+        }.run();
         assertEquals(firstFetch, mWebServer.getRequestCount());
 
         mSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java b/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
old mode 100644
new mode 100755
index d339a62..71c2f36
--- a/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
@@ -1112,10 +1112,14 @@
                 "Find all instances of a word on the page and highlight them.</p>";
 
         mOnUiThread.loadDataAndWaitForCompletion("<html><body>" + p + p + "</body></html>", "text/html", null);
+        WaitForFindResultsListener l = new WaitForFindResultsListener();
+        mOnUiThread.setFindListener(l);
 
         // highlight all the strings found
         mOnUiThread.findAll("all");
-        getInstrumentation().waitForIdleSync();
+        // make sure the findAll action is completed before findNext
+        l.get();
+        mOnUiThread.setFindListener(null);
 
         int previousScrollY = mOnUiThread.getScrollY();
 
diff --git a/tools/dasm/src/dasm/DAsm.java b/tools/dasm/src/dasm/DAsm.java
index 72436ac..aa55a23 100644
--- a/tools/dasm/src/dasm/DAsm.java
+++ b/tools/dasm/src/dasm/DAsm.java
@@ -55,6 +55,7 @@
 import com.android.dx.rop.type.StdTypeList;
 import com.android.dx.rop.type.Type;
 import com.android.dx.rop.type.TypeList;
+import com.android.dx.rop.type.Prototype;
 import com.android.dx.util.IntList;
 
 import java.io.FileWriter;
@@ -84,7 +85,6 @@
 
     // options for dex output
     DexOptions dexOptions = new DexOptions();
-
     // file being processed
     DexFile dexFile;
     int line_num;
@@ -1522,8 +1522,12 @@
      * Creates processor of instruction list.
      */
     private void createOutputFinisher() {
-        if (output_finisher == null)
-            output_finisher = new OutputFinisher(dexOptions, 5, regs_count);
+        if (output_finisher == null) {
+            dexOptions.ALIGN_64BIT_REGS_IN_OUTPUT_FINISHER = false;
+            int paramSize = Prototype.intern(method_nat.getDescriptor()
+                .getString()).getParameterTypes().getWordCount();
+            output_finisher = new OutputFinisher(dexOptions, 5, regs_count, paramSize);
+        }
     }
 
     /**
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/command/CtsConsole.java b/tools/tradefed-host/src/com/android/cts/tradefed/command/CtsConsole.java
index 40145dd..24190c5 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/command/CtsConsole.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/command/CtsConsole.java
@@ -151,7 +151,7 @@
         helpBuilder.append("method\n");
         helpBuilder.append("  run cts --continue-session session_ID: run all not executed ");
         helpBuilder.append("tests from a previous CTS session\n");
-        helpBuilder.append("  run cts [options] --serial/s device_ID: run CTS on specified ");
+        helpBuilder.append("  run cts [options] --serial/-s device_ID: run CTS on specified ");
         helpBuilder.append("device\n");
         helpBuilder.append("  run cts [options] --shards number_of_shards: shard a CTS run into ");
         helpBuilder.append("given number of independent chunks, to run on multiple devices in");
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/GeeTest.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/GeeTest.java
index 5cfafc6..035b4a2 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/GeeTest.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/GeeTest.java
@@ -40,6 +40,8 @@
 public class GeeTest implements IBuildReceiver, IDeviceTest, IRemoteTest {
 
     private static final String NATIVE_TESTS_DIRECTORY = "/data/local/tmp/cts-native-tests";
+    private static final String NATIVE_TESTS_DIRECTORY_TMP = "/data/local/tmp";
+    private static final String ANDROID_PATH_SEPARATOR = "/";
 
     private int mMaxTestTimeMs = 1 * 60 * 1000;
 
@@ -75,8 +77,8 @@
             return false;
         }
 
-        File devicePath = new File(NATIVE_TESTS_DIRECTORY, mExeName);
-        if (!mDevice.pushFile(nativeExe, devicePath.toString())) {
+        String devicePath = NATIVE_TESTS_DIRECTORY + ANDROID_PATH_SEPARATOR + mExeName;
+        if (!mDevice.pushFile(nativeExe, devicePath)) {
             CLog.e("Failed to push native test to device");
             return false;
         }
@@ -87,13 +89,11 @@
         if (mDevice.doesFileExist(remoteFilePath)) {
             return true;
         }
-        File remoteFile = new File(remoteFilePath);
-        String parentPath = remoteFile.getParent();
-        if (parentPath != null) {
-            if (!createRemoteDir(parentPath)) {
-                return false;
-            }
+        if (!(mDevice.doesFileExist(NATIVE_TESTS_DIRECTORY_TMP))) {
+            CLog.e("Could not find the /data/local/tmp directory");
+            return false;
         }
+
         mDevice.executeShellCommand(String.format("mkdir %s", remoteFilePath));
         return mDevice.doesFileExist(remoteFilePath);
     }
@@ -102,7 +102,7 @@
         GeeTestResultParser resultParser = new GeeTestResultParser(mPackageName, listener);
         resultParser.setFakePackagePrefix(mPackageName + ".");
 
-        String fullPath = NATIVE_TESTS_DIRECTORY + File.separator + mExeName;
+        String fullPath = NATIVE_TESTS_DIRECTORY + ANDROID_PATH_SEPARATOR + mExeName;
         String flags = "";
         CLog.v("Running gtest %s %s on %s", fullPath, flags, mDevice.getSerialNumber());
         // force file to be executable
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/VMHostTest.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/VMHostTest.java
index e972640..0ebdeea 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/VMHostTest.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/VMHostTest.java
@@ -33,6 +33,7 @@
 public class VMHostTest extends JarHostTest {
 
     private static final String VM_TEST_TEMP_DIR = "/data/local/tmp/vm-tests";
+    private static final String EMULATOR_TEMP_DIR = "/data/local/tmp";
 
     /**
      * {@inheritDoc}
@@ -66,7 +67,7 @@
         CLog.d("Creating device temp directory, including dalvik-cache.");
         createRemoteDir(device, VM_TEST_TEMP_DIR + "/dalvik-cache" );
         try {
-            File localTmpDir = FileUtil.createTempDir("cts-vm", new File("/tmp/"));
+            File localTmpDir = FileUtil.createTempDir("cts-vm", new File(System.getProperty("java.io.tmpdir")));
             CLog.d("Creating host temp dir %s", localTmpDir.getPath());
             File jarFile = new File(ctsBuild.getTestCasesDir(), getJarFileName());
             if (!jarFile.exists()) {
@@ -119,11 +120,10 @@
         if (device.doesFileExist(remoteFilePath)) {
             return;
         }
-        File f = new File(remoteFilePath);
-        String parentPath = f.getParent();
-        if (parentPath != null) {
-            createRemoteDir(device, parentPath);
+	 if (!(device.doesFileExist(EMULATOR_TEMP_DIR))) {
+            CLog.e("Error: Can not found the /data/local/tmp directory!!!");
         }
+        device.executeShellCommand(String.format("mkdir %s", VM_TEST_TEMP_DIR));
         device.executeShellCommand(String.format("mkdir %s", remoteFilePath));
     }
 }
diff --git a/tools/utils/buildCts.py b/tools/utils/buildCts.py
index fd91c40..8e4ae49 100755
--- a/tools/utils/buildCts.py
+++ b/tools/utils/buildCts.py
@@ -124,8 +124,14 @@
 
     plan = tools.TestPlan(packages)
     plan.Include(r'android\.core\.tests.*')
+    plan.Exclude(r'android\.core\.tests\.libcore.\package.\harmony*')
     self.__WritePlan(plan, 'Java')
 
+    # TODO: remove this once the tests are fixed and merged into Java plan above.
+    plan = tools.TestPlan(packages)
+    plan.Include(r'android\.core\.tests\.libcore.\package.\harmony*')
+    self.__WritePlan(plan, 'Harmony')
+
     plan = tools.TestPlan(packages)
     plan.Include(r'android\.core\.vm-tests-tf')
     self.__WritePlan(plan, 'VM-TF')
