Heading:
Mesa Floating Point Instructions
Page Numbers: Yes X: 527 Y: 10.5"
DRAFT - DRAFT - DRAFT - DRAFT
DRAFT - DRAFT - DRAFT - DRAFT
Inter-Office Memorandum
ToMesa Floating Point CommitteeDateJuly 9, 1980
FromL. StewartLocationPalo Alto
SubjectMesa Floating PointOrganizationPARC/CSL
Instructions
XEROX
Filed on: [Maxc]<LStewart>MesaFP3.bravo
Introduction
This memo presents a proposal for a floating point instruction set for Mesa.
Architectural principles:
Full IEEE Standard Floating Point (KCS proposal - see January 1980 Computer). Single and double precision.
Exception enable flags and sticky flags on a per-process basis.
Arguments passed on Mesa evaluation stack (expanded to 14 words by the time double precision comes along).
The results of an instruction should be predictible (static modes - see below).
Static modes and enables
It has been recommended (SDD Architecture Board), that the modes of a floating point operation (rounding, normalization, infinity) and the enable flags (fixOverflow, inexactResult, invalidOperation, divisionByZero, overflow, underflow) which determine whether exceptional conditions cause a SIGNAL, be part of the instruction. The modes determine the ’preliminary result’ of an operation. If exceptional conditions arise during the operation or if the preliminary result will not fit into the destination, then the enable flags determine whether a SIGNAL is generated. If a SIGNAL is raised, generally the client gets control (or the compilation fails), if not, then the standard specifies the result, generally as a special bit pattern Not-A-Number[reason].
Whether or not exceptional conditions cause a SIGNAL (based on the enable flags), the conditions set the ’sticky’ flags, so that the client can later tell if any exceptions occurred. (Apparently the standards committee feels that not only should there be a flag bit, but a reference to some information about the first offending operation -- but this is not written down anywhere.) The sticky flags are global state information and might be changed by the actions of a procedure call that, unknown to the client, used floating point.
In order to conform completely to the standard, some mechanism for dynamically set modes and enable flags must be provided.
Static modes seem to have two great advantages: compile time optimizations, and predictible program behavior. In the absence of knowledge of how to form the preliminary result (modes), the compiler cannot evaluate expressions (or indeed, perform any floating point operations except conversion to LONG REAL). In addition, the results of a procedure would not be changed as a result of a caller changing the modes.
Including the enable flags in the instruction does not seem to have nearly as high utility as including the mode; while a compile time operation producing an exception would not have to form the Real.Extended record associated with a Real.FloatingPointException, the compiler would still have to generate code to set the sticky flags at the appropriate moment at runtime. In any case, the compiler is free to evaluate any expression which does not produce exceptions.
If evaluation of an expression at compile time produces conditions like fixOverflow, divideByZero, invalidOperation, or overflow, probably the most reasonable response is to produce a compilation error. It is almost as reasonable that underflow produce a compilation error. The most difficult case is inexactResult, which indicates that rounding has taken place.
Proposal
This proposal for floating point instructions provides two opcodes per operation. The default instruction set, described by the interface Real, uses the modes round-to-nearest, warning-normalization, and projective-infinity. The exception enable flags are also fixed, as
Real.UsualExceptions: ExceptionFlags = [overflow: TRUE, invalidOperation: TRUE, divideByZero: TRUE, fixOverflow: TRUE];
The disabled traps are inexactResult and underflow.
The second, more general instructions take their modes and enable flags off the stack. The interface RealOps describes these operations.
For static modes and trap enables, the compiler can generate load immediate instructions to set up the mode, for clients wishing to use dynamic modes, an instruction will be provided that pushes the dynamic mode (kept in the process state) onto the stack.
Use of static modes and dynamic enables is not so easy, but could be done by loading the mode from a variable. Finally, to handle the case of a compile time operation which produces exceptions which are not enabled, an instruction will be provided that sets the sticky flags from a word on the stack.
Double precision is not fixed yet, but the general outline should be similar. Double cannot be implemented until the mesa stack size is increased.
Compiler and language
Normally, the compiler uses the default modes and attempts to evaluate constant expressions. If any exceptions other than inexact-result occur, compilation errors are produced. Inexact-result is not reported, but the runtime system sets up the initial state of the sticky flags so that the inexact-result flag is turned on.
Some (as yet unspecified) language construct attached to a block allows the programmer to specify either constant modes and enable flags or use of the values in the process state. In the latter case, the compiler would not evaluate any constant expressions. Possibly a way could be found of associating a variable of type RealOps.Mode (a one-word record containing the modes and enables) with a particular block.
In the case of non-default but constant modes, the compiler can evaluate expressions. Expressions which produce no exceptions are, of course, fine. Expressions which produce enabled exceptions should cause compilation errors. Expressions which produce exceptions which are not enabled should evaluate and also generate an instruction to set the sticky flags. (Of course the compiler could defer the evaluation of such expressions until runtime.)
Conversion of decimal constants presents some interesting problems, as the conversion can produce exceptions. In the case of known constant modes, the conversion should be done using those modes as for any other operation. In the case of dynamic modes, the decimal value should be not be converted until runtime.
Runtime
Because conversion from decimal to floating point may take place at compile time or at run time, the runtime conversion procedure must behave the same way as the compiler procedure. To allow this, the conversion procedure will have an extra parameter specifying the modes. Explicit calls to the conversion procedure inside a block with constant non-default modes will have to explicitly pass those modes.
The same problem (and solution) applies to other operations such as RoundLI, RoundI and RoundC implemented by procedures rather than instructions.
References
Definitions files:
[Ivy]<CedarLib>Real>Real.mesa
[Ivy]<CedarLib>Real>RealOps.mesa