From: Ilya Leoshkevich <[email protected]> Check that DR with a non-representable quotient raises SIGFPE rather than crashing the emulator.
Signed-off-by: Ilya Leoshkevich <[email protected]> Reviewed-by: Richard Henderson <[email protected]> Link: https://lore.kernel.org/qemu-devel/[email protected] Signed-off-by: Eric Farman <[email protected]> --- tests/tcg/s390x/div.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/tests/tcg/s390x/div.c b/tests/tcg/s390x/div.c index 6ad9900e08..124c9ecc33 100644 --- a/tests/tcg/s390x/div.c +++ b/tests/tcg/s390x/div.c @@ -1,6 +1,15 @@ #include <assert.h> +#include <signal.h> #include <stdint.h> +/* Set asynchronously by the signal handler. */ +static volatile int signum; + +static void signal_handler(int n) +{ + signum = n; +} + static void test_dr(void) { register int32_t r0 asm("r0") = -1; @@ -65,11 +74,39 @@ static void test_dlgr(void) assert(r == 1); } +/* + * The most negative dividend divided by -1 yields a quotient that does not + * fit into 32 bits, so DR must raise a fixed-point-divide exception. + */ +static void test_dr_overflow(void) +{ + struct sigaction act = { .sa_handler = signal_handler }; + register int32_t r0 asm("r0"); + register int32_t r1 asm("r1"); + int32_t b = -1; + int err; + + err = sigaction(SIGFPE, &act, NULL); + assert(err == 0); + signum = -1; + + r0 = 0x80000000; + r1 = 0; + asm volatile("dr %[r0],%[b]" + : [r0] "+r" (r0), [r1] "+r" (r1) + : [b] "r" (b) + : "cc"); + assert(signum == SIGFPE); + + signal(SIGFPE, SIG_DFL); +} + int main(void) { test_dr(); test_dlr(); test_dsgr(); test_dlgr(); + test_dr_overflow(); return 0; } -- 2.55.0
