IEEE-FP EXCEPTIONS (EXPERIMENTAL) --dnw 04-Oct-09 9 IEEE FLOATING-POINT EXTENSION WORDS This is an optional word set. 9.1 FLOATING-POINT EXCEPTIONS All words have normal interpretation and compilation semantics. A floating-point status flag is raised, but never lowered, as a side effect of an fp operation. The default side effect also provides a default fp datum and does not interrupt program flow. The words that deal with the flags are: GET-FFLAGS SET-FFLAGS CLEAR-FFLAGS [**These words are an alternative to GET-FSTATUS and SET-FSTATUS in version 0.5.5 of the IEEE-FP proposal. I find SET-FSTATUS confusing, and the factors SET-FFLAGS and CLEAR-FFLAGS seem clearer.] IEEE also recommends the implementation of alternate fp exception handling, with action to be specified by the language. The words that deal with that are: INSTALL-FHANDLING SET-FHANDLER GET-FHANDLER FENABLE FDISABLE FENABLED The next section lists constant exception masks used by both sets of words. 9.1.1 Exception constants ------------------------- FDIVBYZERO ( -- except ) FINEXACT ( -- except ) FINVALID ( -- except ) FOVERFLOW ( -- except ) FUNDERFLOW ( -- except ) ALL-FEXCEPTS ( -- excepts ) In the above words, each "except" (singular) is an implementation-defined, constant flag mask, unique to the corresponding IEEE fp exception. The individual masks may be bitwise OR'd to define collective "excepts". ALL-FEXCEPTS leaves the OR of all five individual masks. See Section A.9.1.1 for more information. 9.1.2 Status flags ------------------ GET-FFLAGS ( excepts -- flags ) The flags output is the bitwise OR of the fp exception constants corresponding to those flags that are both on in the current fp state and present in excepts. SET-FFLAGS ( excepts -- ) Turn on the fp exception status flags corresponding to the fp exceptions present in excepts. It is implementation-dependent whether the inexact fp flag is also set when the overflow or underflow fp flags are set. CLEAR-FFLAGS ( excepts -- ) Clear the fp exception status flags corresponding to the fp exceptions present in excepts. 9.1.3 Alternate handling ------------------------ See Section A.9.1.3 for an overview of alternate fp exception handling. INSTALL-FHANDLING ( -- ) Establish the system handler for alternate floating-point exceptions, and initialize the xt it executes to that of THROW. Thereafter the handler shall fire on any of the five IEEE floating-point exceptions for which alternate handling is enabled. This word is to be executed when the IEEE-FP Extensions word set is loaded. It may also be executed by an application, which may be necessary to reestablish the handler after an ABORT on some systems. The system handler shall execute the xt of the current Forth alternate fp handler, with the appropriate throw code topmost on the data stack. A Forth fp handler shall have the following stack effect: ( i*x n -- j*x ) ( f: r*x -- r'*x ) where i*x n and r*x are supplied by the system handler when it does the callback to the Forth handler. Here the possibly empty i*x and r*x contain implementation-dependent information about the exception, and n is a Forth throw code, with the corresponding IEEE exception and POSIX SIGFPE code shown in Table XXX. It is an ambiguous condition if the Forth handler terminates neither with THROW nor with the equivalent of ABORT. See Section A.9.1.3 for further information. [** Some fp exceptions raise more than one flag, as specified by IEEE 754-2008. How that is dealt with is implementation dependent. In the experimental pfe implementation, INSTALL-FHANDLING is in the ENVIRONMENT word set, which is not in the default search order. ] Table XXX: Floating-point exception codes IEEE SIGFPE Forth THROW ------------------------------------------------------------------- divideByZero FPE_FLTDIV -42 floating-point divide by zero invalid FPE_FLTINV -46 floating-point invalid argument overflow FPE_FLTOVF -43 floating-point result out of range underflow FPE_FLTUND -54 floating-point underflow inexact FPE_FLTRES -41 loss of precision -55 floating point-unidentified fault ------------------------------------------------------------------- SET-FHANDLER ( xt -- ) Set the execution token of the current Forth alternate fp handler to xt. The old xt is not saved. GET-FHANDLER ( -- xt ) Leave the execution token of the current Forth alternate fp handler. [**The above two words could be replaced by one if it were practical to make the Forth handler vector a named, deferred word, say FHANDLER. I didn't readily see how to make a pfe system deferred word and do a callback on it in the experimental implementation. Besides, the "SET-"/"GET-" style is traditional in DPANS94.] FENABLE ( excepts -- ) FDISABLE ( excepts -- ) FENABLE and FDISABLE first clear all fp exception flags. They then turn alternate handling on/off, repectively, for those fp exceptions present in excepts, without changing the handling of those not present in the mask. When an exception is turned off by FDISABLE, default IEEE handling for that exception is restored. It is an ambiguous condition if excepts is not the bitwise OR of a subset of the five constants: FDIVBYZERO FINEXACT FINVALID FOVERFLOW FUNDERFLOW An ambiguous condition exists if an enabled exception occurs when no Forth fp handler is installed. FENABLED ( -- excepts ) The output excepts is the bitwise OR all fp exceptions for which alternate handling is enabled. A. RATIONALE (INFORMATIVE ANNEX) A.9.1.1 Exception constants --------------------------- The excepts data type serves a dual purpose. Underneath, it gets translated as appropriate to manipulate either fpu exception mask bits or status flag bits. The style of having one data type for both enabling and flag masks is used by the the GNU C Library. The same POSIX/C macros, FE_DIVBYZERO, etc., are used for both types of function. A.9.1.3 Alternate handling -------------------------- Alternate fp exception handling has several aspects. At the lowest level, alternate handling for each of the five fp exceptions generally has to be turned on by hardware instructions. Otherwise cpu's like ppc and intel do IEEE 754 default handling. There is currently no POSIX interface for this [**AFAIK]. The GNU C Library has three functions, fegetexcept(), feenableexcept(), and fedisableexcept(), which do the trick; but they are not universally present. For example, they are present in GNU/Linux, but not implemented in OS X Leopard. To get alternate handling for enabled exceptions, a handler has to be installed. There is a POSIX interface for installing signal handlers, but the coding of a handler that does more than report an error and abort is highly system dependent. In the scheme proposed here, the handler furthermore needs to do a callback on a Forth xt, which requires carnal knowledge of the Forth implementation. The basic idea is that there is a single system alternate handler plus a vectored Forth alternate handler xt which the system handler executes. Ideally, the system handler needs to be installed only once; but in fact that may be tricky. The system handler is called if and only if an fp exception for which alternate handling is turned on occurs. The system handler determines which of the five IEEE exceptions invoked it, and executes the vectored xt with the appropriate Forth throw code on the data stack.