According to the C99 standard, <fenv.h> may not define FE_INVALID and
the likes. Even if C++11 mandate them, musl and emscripten don't provide
them, so handle that case.
IEEE_ARITHMETIC intrinsic module procedures IEEE_NEXT_AFTER,
IEEE_NEXT_DOWN, and IEEE_NEXT_UP, and intrinsic NEAREST return larger or
smaller values adjacent to their primary REAL argument. The four
procedures vary in how the direction is chosen, in how special cases are
treated, and in what exceptions are generated. Implement the three
IEEE_ARITHMETIC procedures. Update the NEAREST implementation to support
all six REAL kinds 2,3,4,8,10,16, and fix several bugs.
IEEE_NEXT_AFTER(X,Y) returns a NaN when Y is a NaN as that seems to be
the universal choice of other compilers.
Change the front end compile time implementation of these procedures to
return normal (HUGE) values for infinities when applicable, rather than
always returning the input infinity.
Even after 13e2200fa426faffb62bdaf8b2f1f5699eee1511 (Solaris lacks
`femode_t`, too), the Solaris `flang` build is still broken:
```
/vol/llvm/src/llvm-project/local/flang/runtime/exceptions.cpp:87:5: error: static assertion failed due to requirement 'sizeof(fenv_t) <= sizeof(int) * 8': increase ieee_status_type size
87 | sizeof(fenv_t) <= sizeof(int) * _FORTRAN_RUNTIME_IEEE_FENV_T_EXTENT, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/vol/llvm/src/llvm-project/local/flang/runtime/exceptions.cpp:87:20: note: expression evaluates to '200 <= 32'
87 | sizeof(fenv_t) <= sizeof(int) * _FORTRAN_RUNTIME_IEEE_FENV_T_EXTENT, | ~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
```
This patch fixes this by removing the assertion.
Tested on `amd64-pc-solaris2.11` and `sparcv9-sun-solaris2.11`.
AIX does not have `femode_t` in `<cfenv>` header, removing the assert to
fix build failures
---------
Co-authored-by: Mark Danial <mark.danial@ibm.com>