diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/tcg/i386/Makefile.target | 4 | ||||
-rw-r--r-- | tests/tcg/i386/test-i386-sse-exceptions.c | 813 |
2 files changed, 817 insertions, 0 deletions
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; +} |