summaryrefslogtreecommitdiffstats
path: root/target/s390x/fpu_helper.c
diff options
context:
space:
mode:
Diffstat (limited to 'target/s390x/fpu_helper.c')
-rw-r--r--target/s390x/fpu_helper.c38
1 files changed, 32 insertions, 6 deletions
diff --git a/target/s390x/fpu_helper.c b/target/s390x/fpu_helper.c
index de02cf792d..dcad9c367a 100644
--- a/target/s390x/fpu_helper.c
+++ b/target/s390x/fpu_helper.c
@@ -63,13 +63,39 @@ static void handle_exceptions(CPUS390XState *env, uintptr_t retaddr)
env->fpu_status.float_exception_flags = 0;
s390_exc = s390_softfloat_exc_to_ieee(qemu_exc);
- /* Install the exceptions that we raised. */
- env->fpc |= s390_exc << 16;
+ /*
+ * FIXME:
+ * 1. Right now, all inexact conditions are inidicated as
+ * "truncated" (0) and never as "incremented" (1) in the DXC.
+ * 2. Only traps due to invalid/divbyzero are suppressing. Other traps
+ * are completing, meaning the target register has to be written!
+ * This, however will mean that we have to write the register before
+ * triggering the trap - impossible right now.
+ */
+
+ /*
+ * invalid/divbyzero cannot coexist with other conditions.
+ * overflow/underflow however can coexist with inexact, we have to
+ * handle it separatly.
+ */
+ if (s390_exc & ~S390_IEEE_MASK_INEXACT) {
+ if (s390_exc & ~S390_IEEE_MASK_INEXACT & env->fpc >> 24) {
+ /* trap condition - inexact reported along */
+ tcg_s390_data_exception(env, s390_exc, retaddr);
+ }
+ /* nontrap condition - inexact handled differently */
+ env->fpc |= (s390_exc & ~S390_IEEE_MASK_INEXACT) << 16;
+ }
- /* Send signals for enabled exceptions. */
- s390_exc &= env->fpc >> 24;
- if (s390_exc) {
- tcg_s390_data_exception(env, s390_exc, retaddr);
+ /* inexact handling */
+ if (s390_exc & S390_IEEE_MASK_INEXACT) {
+ /* trap condition - overflow/underflow _not_ reported along */
+ if (s390_exc & S390_IEEE_MASK_INEXACT & env->fpc >> 24) {
+ tcg_s390_data_exception(env, s390_exc & S390_IEEE_MASK_INEXACT,
+ retaddr);
+ }
+ /* nontrap condition */
+ env->fpc |= (s390_exc & S390_IEEE_MASK_INEXACT) << 16;
}
}