summary refs log tree commit diff stats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/Makefile.include2
-rw-r--r--tests/acceptance/machine_avr6.py50
-rw-r--r--tests/qtest/Makefile.include2
-rw-r--r--tests/qtest/boot-serial-test.c11
-rw-r--r--tests/qtest/machine-none-test.c1
-rw-r--r--tests/qtest/qmp-cmd-test.c109
-rw-r--r--tests/tcg/i386/Makefile.target4
-rw-r--r--tests/tcg/i386/test-i386-sse-exceptions.c813
8 files changed, 986 insertions, 6 deletions
diff --git a/tests/Makefile.include b/tests/Makefile.include
index 94b1cc8302..c7e4646ded 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -639,7 +639,7 @@ define do_test_tap
           { export MALLOC_PERTURB_=$${MALLOC_PERTURB_:-$$(( $${RANDOM:-0} % 255 + 1))} $2; \
             $(foreach COMMAND, $1, \
 	      $(COMMAND) -m=$(SPEED) -k --tap < /dev/null \
-	      | sed "s/^[a-z][a-z]* [0-9]* /&$(notdir $(COMMAND)) /" || true; ) } \
+	      | sed "s/^\(not \)\?ok [0-9]* /&$(notdir $(COMMAND)) /" || true; ) } \
 	      | ./scripts/tap-merge.pl | tee "$@" \
 	      | ./scripts/tap-driver.pl $(if $(V),, --show-failures-only), \
 	  "TAP","$@")
diff --git a/tests/acceptance/machine_avr6.py b/tests/acceptance/machine_avr6.py
new file mode 100644
index 0000000000..6baf4e9c7f
--- /dev/null
+++ b/tests/acceptance/machine_avr6.py
@@ -0,0 +1,50 @@
+#
+# QEMU AVR acceptance tests
+#
+# Copyright (c) 2019-2020 Michael Rolnik <mrolnik@gmail.com>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+import time
+
+from avocado_qemu import Test
+
+class AVR6Machine(Test):
+    timeout = 5
+
+    def test_freertos(self):
+        """
+        :avocado: tags=arch:avr
+        :avocado: tags=machine:arduino-mega-2560-v3
+        """
+        """
+        https://github.com/seharris/qemu-avr-tests/raw/master/free-rtos/Demo/AVR_ATMega2560_GCC/demo.elf
+        constantly prints out 'ABCDEFGHIJKLMNOPQRSTUVWXABCDEFGHIJKLMNOPQRSTUVWX'
+        """
+        rom_url = ('https://github.com/seharris/qemu-avr-tests'
+                   '/raw/36c3e67b8755dcf/free-rtos/Demo'
+                   '/AVR_ATMega2560_GCC/demo.elf')
+        rom_hash = '7eb521f511ca8f2622e0a3c5e8dd686efbb911d4'
+        rom_path = self.fetch_asset(rom_url, asset_hash=rom_hash)
+
+        self.vm.add_args('-bios', rom_path)
+        self.vm.add_args('-nographic')
+        self.vm.launch()
+
+        time.sleep(2)
+        self.vm.shutdown()
+
+        self.assertIn('ABCDEFGHIJKLMNOPQRSTUVWXABCDEFGHIJKLMNOPQRSTUVWX',
+                self.vm.get_log())
diff --git a/tests/qtest/Makefile.include b/tests/qtest/Makefile.include
index 6a0276fd42..b0204e44f2 100644
--- a/tests/qtest/Makefile.include
+++ b/tests/qtest/Makefile.include
@@ -66,6 +66,8 @@ check-qtest-i386-y += numa-test
 
 check-qtest-x86_64-y += $(check-qtest-i386-y)
 
+check-qtest-avr-y += boot-serial-test
+
 check-qtest-alpha-y += boot-serial-test
 check-qtest-alpha-$(CONFIG_VGA) += display-vga-test
 
diff --git a/tests/qtest/boot-serial-test.c b/tests/qtest/boot-serial-test.c
index 85a3614286..bfe7624dc6 100644
--- a/tests/qtest/boot-serial-test.c
+++ b/tests/qtest/boot-serial-test.c
@@ -17,6 +17,15 @@
 #include "libqtest.h"
 #include "libqos/libqos-spapr.h"
 
+static const uint8_t bios_avr[] = {
+    0x88, 0xe0,             /* ldi r24, 0x08   */
+    0x80, 0x93, 0xc1, 0x00, /* sts 0x00C1, r24 ; Enable tx */
+    0x86, 0xe0,             /* ldi r24, 0x06   */
+    0x80, 0x93, 0xc2, 0x00, /* sts 0x00C2, r24 ; Set the data bits to 8 */
+    0x84, 0xe5,             /* ldi r24, 0x54   */
+    0x80, 0x93, 0xc6, 0x00, /* sts 0x00C6, r24 ; Output 'T' */
+};
+
 static const uint8_t kernel_mcf5208[] = {
     0x41, 0xf9, 0xfc, 0x06, 0x00, 0x00,     /* lea 0xfc060000,%a0 */
     0x10, 0x3c, 0x00, 0x54,                 /* move.b #'T',%d0 */
@@ -104,6 +113,8 @@ typedef struct testdef {
 
 static testdef_t tests[] = {
     { "alpha", "clipper", "", "PCI:" },
+    { "avr", "arduino-duemilanove", "", "T", sizeof(bios_avr), NULL, bios_avr },
+    { "avr", "arduino-mega-2560-v3", "", "T", sizeof(bios_avr), NULL, bios_avr},
     { "ppc", "ppce500", "", "U-Boot" },
     { "ppc", "40p", "-vga none -boot d", "Trying cd:," },
     { "ppc", "g3beige", "", "PowerPC,750" },
diff --git a/tests/qtest/machine-none-test.c b/tests/qtest/machine-none-test.c
index 8b7abea8af..57107f1aec 100644
--- a/tests/qtest/machine-none-test.c
+++ b/tests/qtest/machine-none-test.c
@@ -27,6 +27,7 @@ static struct arch2cpu cpus_map[] = {
     /* tested targets list */
     { "arm", "cortex-a15" },
     { "aarch64", "cortex-a57" },
+    { "avr", "avr6-avr-cpu" },
     { "x86_64", "qemu64,apic-id=0" },
     { "i386", "qemu32,apic-id=0" },
     { "alpha", "ev67" },
diff --git a/tests/qtest/qmp-cmd-test.c b/tests/qtest/qmp-cmd-test.c
index 9f5228cd99..c68f99f659 100644
--- a/tests/qtest/qmp-cmd-test.c
+++ b/tests/qtest/qmp-cmd-test.c
@@ -200,16 +200,116 @@ static void add_query_tests(QmpSchema *schema)
     }
 }
 
-static void test_object_add_without_props(void)
+static void test_object_add_failure_modes(void)
 {
     QTestState *qts;
     QDict *resp;
 
+    /* attempt to create an object without props */
     qts = qtest_init(common_args);
     resp = qtest_qmp(qts, "{'execute': 'object-add', 'arguments':"
-                    " {'qom-type': 'memory-backend-ram', 'id': 'ram1' } }");
+                     " {'qom-type': 'memory-backend-ram', 'id': 'ram1' } }");
     g_assert_nonnull(resp);
     qmp_assert_error_class(resp, "GenericError");
+
+    /* attempt to create an object without qom-type */
+    resp = qtest_qmp(qts, "{'execute': 'object-add', 'arguments':"
+                     " {'id': 'ram1' } }");
+    g_assert_nonnull(resp);
+    qmp_assert_error_class(resp, "GenericError");
+
+    /* attempt to delete an object that does not exist */
+    resp = qtest_qmp(qts, "{'execute': 'object-del', 'arguments':"
+                     " {'id': 'ram1' } }");
+    g_assert_nonnull(resp);
+    qmp_assert_error_class(resp, "GenericError");
+
+    /* attempt to create 2 objects with duplicate id */
+    resp = qtest_qmp(qts, "{'execute': 'object-add', 'arguments':"
+                     " {'qom-type': 'memory-backend-ram', 'id': 'ram1',"
+                     " 'props': {'size': 1048576 } } }");
+    g_assert_nonnull(resp);
+    g_assert(qdict_haskey(resp, "return"));
+    resp = qtest_qmp(qts, "{'execute': 'object-add', 'arguments':"
+                     " {'qom-type': 'memory-backend-ram', 'id': 'ram1',"
+                     " 'props': {'size': 1048576 } } }");
+    g_assert_nonnull(resp);
+    qmp_assert_error_class(resp, "GenericError");
+
+    /* delete ram1 object */
+    resp = qtest_qmp(qts, "{'execute': 'object-del', 'arguments':"
+                     " {'id': 'ram1' } }");
+    g_assert_nonnull(resp);
+    g_assert(qdict_haskey(resp, "return"));
+
+    /* attempt to create an object with a property of a wrong type */
+    resp = qtest_qmp(qts, "{'execute': 'object-add', 'arguments':"
+                     " {'qom-type': 'memory-backend-ram', 'id': 'ram1',"
+                     " 'props': {'size': '1048576' } } }");
+    g_assert_nonnull(resp);
+    /* now do it right */
+    qmp_assert_error_class(resp, "GenericError");
+    resp = qtest_qmp(qts, "{'execute': 'object-add', 'arguments':"
+                     " {'qom-type': 'memory-backend-ram', 'id': 'ram1',"
+                     " 'props': {'size': 1048576 } } }");
+    g_assert_nonnull(resp);
+    g_assert(qdict_haskey(resp, "return"));
+
+    /* delete ram1 object */
+    resp = qtest_qmp(qts, "{'execute': 'object-del', 'arguments':"
+                     " {'id': 'ram1' } }");
+    g_assert_nonnull(resp);
+    g_assert(qdict_haskey(resp, "return"));
+
+    /* attempt to create an object without the id */
+    resp = qtest_qmp(qts, "{'execute': 'object-add', 'arguments':"
+                     " {'qom-type': 'memory-backend-ram',"
+                     " 'props': {'size': 1048576 } } }");
+    g_assert_nonnull(resp);
+    qmp_assert_error_class(resp, "GenericError");
+    /* now do it right */
+    resp = qtest_qmp(qts, "{'execute': 'object-add', 'arguments':"
+                     " {'qom-type': 'memory-backend-ram', 'id': 'ram1',"
+                     " 'props': {'size': 1048576 } } }");
+    g_assert_nonnull(resp);
+    g_assert(qdict_haskey(resp, "return"));
+
+    /* delete ram1 object */
+    resp = qtest_qmp(qts, "{'execute': 'object-del', 'arguments':"
+                     " {'id': 'ram1' } }");
+    g_assert_nonnull(resp);
+    g_assert(qdict_haskey(resp, "return"));
+
+    /* attempt to set a non existing property */
+    resp = qtest_qmp(qts, "{'execute': 'object-add', 'arguments':"
+                     " {'qom-type': 'memory-backend-ram', 'id': 'ram1',"
+                     " 'props': {'sized': 1048576 } } }");
+    g_assert_nonnull(resp);
+    qmp_assert_error_class(resp, "GenericError");
+    /* now do it right */
+    resp = qtest_qmp(qts, "{'execute': 'object-add', 'arguments':"
+                     " {'qom-type': 'memory-backend-ram', 'id': 'ram1',"
+                     " 'props': {'size': 1048576 } } }");
+    g_assert_nonnull(resp);
+    g_assert(qdict_haskey(resp, "return"));
+
+    /* delete ram1 object without id */
+    resp = qtest_qmp(qts, "{'execute': 'object-del', 'arguments':"
+                     " {'ida': 'ram1' } }");
+    g_assert_nonnull(resp);
+
+    /* delete ram1 object */
+    resp = qtest_qmp(qts, "{'execute': 'object-del', 'arguments':"
+                     " {'id': 'ram1' } }");
+    g_assert_nonnull(resp);
+    g_assert(qdict_haskey(resp, "return"));
+
+    /* delete ram1 object that does not exist anymore*/
+    resp = qtest_qmp(qts, "{'execute': 'object-del', 'arguments':"
+                     " {'id': 'ram1' } }");
+    g_assert_nonnull(resp);
+    qmp_assert_error_class(resp, "GenericError");
+
     qtest_quit(qts);
 }
 
@@ -223,9 +323,8 @@ int main(int argc, char *argv[])
     qmp_schema_init(&schema);
     add_query_tests(&schema);
 
-    qtest_add_func("qmp/object-add-without-props",
-                   test_object_add_without_props);
-    /* TODO: add coverage of generic object-add failure modes */
+    qtest_add_func("qmp/object-add-failure-modes",
+                   test_object_add_failure_modes);
 
     ret = g_test_run();
 
diff --git a/tests/tcg/i386/Makefile.target b/tests/tcg/i386/Makefile.target
index 1a6463a7dc..a66232a67d 100644
--- a/tests/tcg/i386/Makefile.target
+++ b/tests/tcg/i386/Makefile.target
@@ -10,6 +10,10 @@ ALL_X86_TESTS=$(I386_SRCS:.c=)
 SKIP_I386_TESTS=test-i386-ssse3
 X86_64_TESTS:=$(filter test-i386-ssse3, $(ALL_X86_TESTS))
 
+test-i386-sse-exceptions: CFLAGS += -msse4.1 -mfpmath=sse
+run-test-i386-sse-exceptions: QEMU_OPTS += -cpu max
+run-plugin-test-i386-sse-exceptions-%: QEMU_OPTS += -cpu max
+
 test-i386-pcmpistri: CFLAGS += -msse4.2
 run-test-i386-pcmpistri: QEMU_OPTS += -cpu max
 run-plugin-test-i386-pcmpistri-%: QEMU_OPTS += -cpu max
diff --git a/tests/tcg/i386/test-i386-sse-exceptions.c b/tests/tcg/i386/test-i386-sse-exceptions.c
new file mode 100644
index 0000000000..a104f46c11
--- /dev/null
+++ b/tests/tcg/i386/test-i386-sse-exceptions.c
@@ -0,0 +1,813 @@
+/* Test SSE exceptions.  */
+
+#include <float.h>
+#include <stdint.h>
+#include <stdio.h>
+
+volatile float f_res;
+volatile double d_res;
+
+volatile float f_snan = __builtin_nansf("");
+volatile float f_half = 0.5f;
+volatile float f_third = 1.0f / 3.0f;
+volatile float f_nan = __builtin_nanl("");
+volatile float f_inf = __builtin_inff();
+volatile float f_ninf = -__builtin_inff();
+volatile float f_one = 1.0f;
+volatile float f_two = 2.0f;
+volatile float f_zero = 0.0f;
+volatile float f_nzero = -0.0f;
+volatile float f_min = FLT_MIN;
+volatile float f_true_min = 0x1p-149f;
+volatile float f_max = FLT_MAX;
+volatile float f_nmax = -FLT_MAX;
+
+volatile double d_snan = __builtin_nans("");
+volatile double d_half = 0.5;
+volatile double d_third = 1.0 / 3.0;
+volatile double d_nan = __builtin_nan("");
+volatile double d_inf = __builtin_inf();
+volatile double d_ninf = -__builtin_inf();
+volatile double d_one = 1.0;
+volatile double d_two = 2.0;
+volatile double d_zero = 0.0;
+volatile double d_nzero = -0.0;
+volatile double d_min = DBL_MIN;
+volatile double d_true_min = 0x1p-1074;
+volatile double d_max = DBL_MAX;
+volatile double d_nmax = -DBL_MAX;
+
+volatile int32_t i32_max = INT32_MAX;
+
+#define IE (1 << 0)
+#define ZE (1 << 2)
+#define OE (1 << 3)
+#define UE (1 << 4)
+#define PE (1 << 5)
+#define EXC (IE | ZE | OE | UE | PE)
+
+uint32_t mxcsr_default = 0x1f80;
+uint32_t mxcsr_ftz = 0x9f80;
+
+int main(void)
+{
+    uint32_t mxcsr;
+    int32_t i32_res;
+    int ret = 0;
+
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    d_res = f_snan;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: widen float snan\n");
+        ret = 1;
+    }
+
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    f_res = d_min;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != (UE | PE)) {
+        printf("FAIL: narrow float underflow\n");
+        ret = 1;
+    }
+
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    f_res = d_max;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != (OE | PE)) {
+        printf("FAIL: narrow float overflow\n");
+        ret = 1;
+    }
+
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    f_res = d_third;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != PE) {
+        printf("FAIL: narrow float inexact\n");
+        ret = 1;
+    }
+
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    f_res = d_snan;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: narrow float snan\n");
+        ret = 1;
+    }
+
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("roundss $4, %0, %0" : "=x" (f_res) : "0" (f_min));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != PE) {
+        printf("FAIL: roundss min\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("roundss $12, %0, %0" : "=x" (f_res) : "0" (f_min));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != 0) {
+        printf("FAIL: roundss no-inexact min\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("roundss $4, %0, %0" : "=x" (f_res) : "0" (f_snan));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: roundss snan\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("roundss $12, %0, %0" : "=x" (f_res) : "0" (f_snan));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: roundss no-inexact snan\n");
+        ret = 1;
+    }
+
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("roundsd $4, %0, %0" : "=x" (d_res) : "0" (d_min));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != PE) {
+        printf("FAIL: roundsd min\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("roundsd $12, %0, %0" : "=x" (d_res) : "0" (d_min));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != 0) {
+        printf("FAIL: roundsd no-inexact min\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("roundsd $4, %0, %0" : "=x" (d_res) : "0" (d_snan));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: roundsd snan\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("roundsd $12, %0, %0" : "=x" (d_res) : "0" (d_snan));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: roundsd no-inexact snan\n");
+        ret = 1;
+    }
+
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("comiss %1, %0" : : "x" (f_nan), "x" (f_zero));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: comiss nan\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("ucomiss %1, %0" : : "x" (f_nan), "x" (f_zero));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != 0) {
+        printf("FAIL: ucomiss nan\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("ucomiss %1, %0" : : "x" (f_snan), "x" (f_zero));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: ucomiss snan\n");
+        ret = 1;
+    }
+
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("comisd %1, %0" : : "x" (d_nan), "x" (d_zero));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: comisd nan\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("ucomisd %1, %0" : : "x" (d_nan), "x" (d_zero));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != 0) {
+        printf("FAIL: ucomisd nan\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("ucomisd %1, %0" : : "x" (d_snan), "x" (d_zero));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: ucomisd snan\n");
+        ret = 1;
+    }
+
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    f_res = f_max + f_max;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != (OE | PE)) {
+        printf("FAIL: float add overflow\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    f_res = f_max + f_min;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != PE) {
+        printf("FAIL: float add inexact\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    f_res = f_inf + f_ninf;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: float add inf -inf\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    f_res = f_snan + f_third;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: float add snan\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_ftz));
+    f_res = f_true_min + f_true_min;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != (UE | PE)) {
+        printf("FAIL: float add FTZ underflow\n");
+        ret = 1;
+    }
+
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    d_res = d_max + d_max;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != (OE | PE)) {
+        printf("FAIL: double add overflow\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    d_res = d_max + d_min;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != PE) {
+        printf("FAIL: double add inexact\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    d_res = d_inf + d_ninf;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: double add inf -inf\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    d_res = d_snan + d_third;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: double add snan\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_ftz));
+    d_res = d_true_min + d_true_min;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != (UE | PE)) {
+        printf("FAIL: double add FTZ underflow\n");
+        ret = 1;
+    }
+
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    f_res = f_max - f_nmax;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != (OE | PE)) {
+        printf("FAIL: float sub overflow\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    f_res = f_max - f_min;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != PE) {
+        printf("FAIL: float sub inexact\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    f_res = f_inf - f_inf;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: float sub inf inf\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    f_res = f_snan - f_third;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: float sub snan\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_ftz));
+    f_res = f_min - f_true_min;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != (UE | PE)) {
+        printf("FAIL: float sub FTZ underflow\n");
+        ret = 1;
+    }
+
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    d_res = d_max - d_nmax;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != (OE | PE)) {
+        printf("FAIL: double sub overflow\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    d_res = d_max - d_min;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != PE) {
+        printf("FAIL: double sub inexact\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    d_res = d_inf - d_inf;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: double sub inf inf\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    d_res = d_snan - d_third;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: double sub snan\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_ftz));
+    d_res = d_min - d_true_min;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != (UE | PE)) {
+        printf("FAIL: double sub FTZ underflow\n");
+        ret = 1;
+    }
+
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    f_res = f_max * f_max;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != (OE | PE)) {
+        printf("FAIL: float mul overflow\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    f_res = f_third * f_third;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != PE) {
+        printf("FAIL: float mul inexact\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    f_res = f_min * f_min;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != (UE | PE)) {
+        printf("FAIL: float mul underflow\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    f_res = f_inf * f_zero;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: float mul inf 0\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    f_res = f_snan * f_third;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: float mul snan\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_ftz));
+    f_res = f_min * f_half;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != (UE | PE)) {
+        printf("FAIL: float mul FTZ underflow\n");
+        ret = 1;
+    }
+
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    d_res = d_max * d_max;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != (OE | PE)) {
+        printf("FAIL: double mul overflow\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    d_res = d_third * d_third;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != PE) {
+        printf("FAIL: double mul inexact\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    d_res = d_min * d_min;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != (UE | PE)) {
+        printf("FAIL: double mul underflow\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    d_res = d_inf * d_zero;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: double mul inf 0\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    d_res = d_snan * d_third;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: double mul snan\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_ftz));
+    d_res = d_min * d_half;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != (UE | PE)) {
+        printf("FAIL: double mul FTZ underflow\n");
+        ret = 1;
+    }
+
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    f_res = f_max / f_min;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != (OE | PE)) {
+        printf("FAIL: float div overflow\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    f_res = f_one / f_third;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != PE) {
+        printf("FAIL: float div inexact\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    f_res = f_min / f_max;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != (UE | PE)) {
+        printf("FAIL: float div underflow\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    f_res = f_one / f_zero;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != ZE) {
+        printf("FAIL: float div 1 0\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    f_res = f_inf / f_zero;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != 0) {
+        printf("FAIL: float div inf 0\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    f_res = f_nan / f_zero;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != 0) {
+        printf("FAIL: float div nan 0\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    f_res = f_zero / f_zero;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: float div 0 0\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    f_res = f_inf / f_inf;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: float div inf inf\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    f_res = f_snan / f_third;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: float div snan\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_ftz));
+    f_res = f_min / f_two;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != (UE | PE)) {
+        printf("FAIL: float div FTZ underflow\n");
+        ret = 1;
+    }
+
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    d_res = d_max / d_min;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != (OE | PE)) {
+        printf("FAIL: double div overflow\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    d_res = d_one / d_third;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != PE) {
+        printf("FAIL: double div inexact\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    d_res = d_min / d_max;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != (UE | PE)) {
+        printf("FAIL: double div underflow\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    d_res = d_one / d_zero;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != ZE) {
+        printf("FAIL: double div 1 0\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    d_res = d_inf / d_zero;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != 0) {
+        printf("FAIL: double div inf 0\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    d_res = d_nan / d_zero;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != 0) {
+        printf("FAIL: double div nan 0\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    d_res = d_zero / d_zero;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: double div 0 0\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    d_res = d_inf / d_inf;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: double div inf inf\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    d_res = d_snan / d_third;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: double div snan\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_ftz));
+    d_res = d_min / d_two;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != (UE | PE)) {
+        printf("FAIL: double div FTZ underflow\n");
+        ret = 1;
+    }
+
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("sqrtss %0, %0" : "=x" (f_res) : "0" (f_max));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != PE) {
+        printf("FAIL: sqrtss inexact\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("sqrtss %0, %0" : "=x" (f_res) : "0" (f_nmax));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: sqrtss -max\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("sqrtss %0, %0" : "=x" (f_res) : "0" (f_ninf));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: sqrtss -inf\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("sqrtss %0, %0" : "=x" (f_res) : "0" (f_snan));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: sqrtss snan\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("sqrtss %0, %0" : "=x" (f_res) : "0" (f_nzero));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != 0) {
+        printf("FAIL: sqrtss -0\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("sqrtss %0, %0" : "=x" (f_res) :
+                      "0" (-__builtin_nanf("")));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != 0) {
+        printf("FAIL: sqrtss -nan\n");
+        ret = 1;
+    }
+
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("sqrtsd %0, %0" : "=x" (d_res) : "0" (d_max));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != PE) {
+        printf("FAIL: sqrtsd inexact\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("sqrtsd %0, %0" : "=x" (d_res) : "0" (d_nmax));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: sqrtsd -max\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("sqrtsd %0, %0" : "=x" (d_res) : "0" (d_ninf));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: sqrtsd -inf\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("sqrtsd %0, %0" : "=x" (d_res) : "0" (d_snan));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: sqrtsd snan\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("sqrtsd %0, %0" : "=x" (d_res) : "0" (d_nzero));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != 0) {
+        printf("FAIL: sqrtsd -0\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("sqrtsd %0, %0" : "=x" (d_res) :
+                      "0" (-__builtin_nan("")));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != 0) {
+        printf("FAIL: sqrtsd -nan\n");
+        ret = 1;
+    }
+
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("maxss %1, %0" : : "x" (f_nan), "x" (f_zero));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: maxss nan\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("minss %1, %0" : : "x" (f_nan), "x" (f_zero));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: minss nan\n");
+        ret = 1;
+    }
+
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("maxsd %1, %0" : : "x" (d_nan), "x" (d_zero));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: maxsd nan\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("minsd %1, %0" : : "x" (d_nan), "x" (d_zero));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: minsd nan\n");
+        ret = 1;
+    }
+
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("cvtsi2ss %1, %0" : "=x" (f_res) : "m" (i32_max));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != PE) {
+        printf("FAIL: cvtsi2ss inexact\n");
+        ret = 1;
+    }
+
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("cvtsi2sd %1, %0" : "=x" (d_res) : "m" (i32_max));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != 0) {
+        printf("FAIL: cvtsi2sd exact\n");
+        ret = 1;
+    }
+
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("cvtss2si %1, %0" : "=r" (i32_res) : "x" (1.5f));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != PE) {
+        printf("FAIL: cvtss2si inexact\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("cvtss2si %1, %0" : "=r" (i32_res) : "x" (0x1p31f));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: cvtss2si 0x1p31\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("cvtss2si %1, %0" : "=r" (i32_res) : "x" (f_inf));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: cvtss2si inf\n");
+        ret = 1;
+    }
+
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("cvtsd2si %1, %0" : "=r" (i32_res) : "x" (1.5));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != PE) {
+        printf("FAIL: cvtsd2si inexact\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("cvtsd2si %1, %0" : "=r" (i32_res) : "x" (0x1p31));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: cvtsd2si 0x1p31\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("cvtsd2si %1, %0" : "=r" (i32_res) : "x" (d_inf));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: cvtsd2si inf\n");
+        ret = 1;
+    }
+
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("cvttss2si %1, %0" : "=r" (i32_res) : "x" (1.5f));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != PE) {
+        printf("FAIL: cvttss2si inexact\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("cvttss2si %1, %0" : "=r" (i32_res) : "x" (0x1p31f));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: cvttss2si 0x1p31\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("cvttss2si %1, %0" : "=r" (i32_res) : "x" (f_inf));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: cvttss2si inf\n");
+        ret = 1;
+    }
+
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("cvttsd2si %1, %0" : "=r" (i32_res) : "x" (1.5));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != PE) {
+        printf("FAIL: cvttsd2si inexact\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("cvttsd2si %1, %0" : "=r" (i32_res) : "x" (0x1p31));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: cvttsd2si 0x1p31\n");
+        ret = 1;
+    }
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("cvttsd2si %1, %0" : "=r" (i32_res) : "x" (d_inf));
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != IE) {
+        printf("FAIL: cvttsd2si inf\n");
+        ret = 1;
+    }
+
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("rcpss %0, %0" : "=x" (f_res) : "0" (f_snan));
+    f_res += f_one;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != 0) {
+        printf("FAIL: rcpss snan\n");
+        ret = 1;
+    }
+
+    __asm__ volatile ("ldmxcsr %0" : : "m" (mxcsr_default));
+    __asm__ volatile ("rsqrtss %0, %0" : "=x" (f_res) : "0" (f_snan));
+    f_res += f_one;
+    __asm__ volatile ("stmxcsr %0" : "=m" (mxcsr));
+    if ((mxcsr & EXC) != 0) {
+        printf("FAIL: rsqrtss snan\n");
+        ret = 1;
+    }
+
+    return ret;
+}