summary refs log tree commit diff stats
path: root/tests/tcg/i386/test-i386-sse-exceptions.c
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2020-07-11 16:52:24 +0100
committerPeter Maydell <peter.maydell@linaro.org>2020-07-11 16:52:24 +0100
commit2033cc6efa98b831d7839e367aa7d5aa74d0750f (patch)
treee05ba39af3087251a84c33e7ad6c9b03033eb9e5 /tests/tcg/i386/test-i386-sse-exceptions.c
parentd4a6bab1ecf23d86e20e2f08a144e4e48643a6e4 (diff)
parent56908dc5041aa424fd1495b6c6beb78c539d93e1 (diff)
downloadfocaccia-qemu-2033cc6efa98b831d7839e367aa7d5aa74d0750f.tar.gz
focaccia-qemu-2033cc6efa98b831d7839e367aa7d5aa74d0750f.zip
Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
* Make checkpatch say 'qemu' instead of 'kernel' (Aleksandar)
* Fix PSE guests with emulated NPT (Alexander B. #1)
* Fix leak (Alexander B. #2)
* HVF fixes (Roman, Cameron)
* New Sapphire Rapids CPUID bits (Cathy)
* cpus.c and softmmu/ cleanups (Claudio)
* TAP driver tweaks (Daniel, Havard)
* object-add bugfix and testcases (Eric A.)
* Fix Coverity MIN_CONST and MAX_CONST (Eric B.)
* "info lapic" improvement (Jan)
* SSE fixes (Joseph)
* "-msg guest-name" option (Mario)
* support for AMD nested live migration (myself)
* Small i386 TCG fixes (myself)
* improved error reporting for Xen (myself)
* fix "-cpu host -overcommit cpu-pm=on" (myself)
* Add accel/Kconfig (Philippe)
* iscsi sense handling fixes (Yongji)
* Misc bugfixes

# gpg: Signature made Sat 11 Jul 2020 00:33:41 BST
# gpg:                using RSA key F13338574B662389866C7682BFFBD25F78C7AE83
# gpg:                issuer "pbonzini@redhat.com"
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" [full]
# gpg:                 aka "Paolo Bonzini <pbonzini@redhat.com>" [full]
# Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4  E2F7 7E15 100C CD36 69B1
#      Subkey fingerprint: F133 3857 4B66 2389 866C  7682 BFFB D25F 78C7 AE83

* remotes/bonzini/tags/for-upstream: (47 commits)
  linux-headers: update again to 5.8
  apic: Report current_count via 'info lapic'
  scripts: improve message when TAP based tests fail
  target/i386: Enable TSX Suspend Load Address Tracking feature
  target/i386: Add SERIALIZE cpu feature
  softmmu/vl: Remove the check for colons in -accel parameters
  cpu-throttle: new module, extracted from cpus.c
  softmmu: move softmmu only files from root
  pc: fix leak in pc_system_flash_cleanup_unused
  cpus: Move CPU code from exec.c to cpus-common.c
  target/i386: Correct the warning message of Intel PT
  checkpatch: Change occurences of 'kernel' to 'qemu' in user messages
  iscsi: return -EIO when sense fields are meaningless
  iscsi: handle check condition status in retry loop
  target/i386: sev: fail query-sev-capabilities if QEMU cannot use SEV
  target/i386: sev: provide proper error reporting for query-sev-capabilities
  KVM: x86: believe what KVM says about WAITPKG
  target/i386: implement undocumented "smsw r32" behavior
  target/i386: remove gen_io_end
  Makefile: simplify MINIKCONF rules
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'tests/tcg/i386/test-i386-sse-exceptions.c')
-rw-r--r--tests/tcg/i386/test-i386-sse-exceptions.c813
1 files changed, 813 insertions, 0 deletions
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;
+}