target/i386: fix IEEE x87 floating-point exception raising
commit975af797f1e04e4d1b1a12f1731141d3770fdbce
authorJoseph Myers <joseph@codesourcery.com>
Fri, 15 May 2020 21:21:24 +0000 (15 21:21 +0000)
committerPaolo Bonzini <pbonzini@redhat.com>
Wed, 10 Jun 2020 16:10:51 +0000 (10 12:10 -0400)
treebef4471e60353d06949c94e0a3a8f00da9f6bbd5
parent77f55eac6c433e23e82a1b88b2d74f385c4c7d82
target/i386: fix IEEE x87 floating-point exception raising

Most x87 instruction implementations fail to raise the expected IEEE
floating-point exceptions because they do nothing to convert the
exception state from the softfloat machinery into the exception flags
in the x87 status word.  There is special-case handling of division to
raise the divide-by-zero exception, but that handling is itself buggy:
it raises the exception in inappropriate cases (inf / 0 and nan / 0,
which should not raise any exceptions, and 0 / 0, which should raise
"invalid" instead).

Fix this by converting the floating-point exceptions raised during an
operation by the softfloat machinery into exceptions in the x87 status
word (passing through the existing fpu_set_exception function for
handling related to trapping exceptions).  There are special cases
where some functions convert to integer internally but exceptions from
that conversion are not always correct exceptions for the instruction
to raise.

There might be scope for some simplification if the softfloat
exception state either could always be assumed to be in sync with the
state in the status word, or could always be ignored at the start of
each instruction and just set to 0 then; I haven't looked into that in
detail, and it might run into interactions with the various ways the
emulation does not yet handle trapping exceptions properly.  I think
the approach taken here, of saving the softfloat state, setting
exceptions there to 0 and then merging the old exceptions back in
after carrying out the operation, is conservatively safe.

Signed-off-by: Joseph Myers <joseph@codesourcery.com>
Message-Id: <alpine.DEB.2.21.2005152120280.3469@digraph.polyomino.org.uk>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
target/i386/fpu_helper.c
tests/tcg/i386/test-i386-fp-exceptions.c [new file with mode: 0644]