Check that DR with a non-representable quotient raises SIGFPE rather than
crashing the emulator.
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
---
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 6ad9900e082..124c9ecc339 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