HP OpenVMS Systems Documentation
HP OpenVMS Calling Standard
188.8.131.52 Floating-Point Control Status (I64 Only)
Normally the floating-point control status (see Section 4.1.7) of a program is established at the beginning of program execution and remains unchanged throughout execution of the whole program.
However, a procedure (or cooperating group of procedures) may temporarily modify the floating-point control status provided the following rules are followed. Such a procedure must:
8.6 Returning from a Condition Handler
Condition handlers are invoked by the OpenVMS Condition Handling Facility (CHF). Therefore, the return from the condition handler is to the CHF.
To continue from the instruction following the signal, the handler must return with a function value of either SS$_CONTINUE or SS$_CONTINUE64 (both of which have bit <0> set). If, however, the condition is signaled with a call to LIB$STOP, the image exits. To resignal the condition, the condition handler returns with a function value of either SS$_RESIGNAL or SS$_RESIGNAL64 (both of which have the bit <0> clear).
The difference between SS$_CONTINUE and SS$_CONTINUE64, and similarly between SS$_RESIGNAL and SS$_RESIGNAL64, is of significance only if the handler has made an alteration to the signal vector that is intended to be taken into account by the CHF. When SS$_CONTINUE or SS$_RESIGNAL is returned, then any modification to the 32-bit signal vector is propagated (in sign-extended form) to the corresponding position in the 64-bit vector. When SS$_CONTINUE64 or SS$_RESIGNAL64 is returned, any modification in the 64-bit signal vector is propagated (in truncated form) to the corresponding position in the 32-bit vector. If no modification has been made, then the two forms of continuation or resignal are equivalent.
The algorithm for detecting change is as follows:
To alter the severity of the signal, the handler modifies the low-order three bits of the condition value longword in the signal_args vector and resignals. If the condition handler wants to alter the defined control bits of the signal, the handler modifies bits <31:28> of the condition value and resignals.
To unwind, the handler calls SYS$UNWIND and then returns. In this case, the handler function value is ignored.
For I64, if the establisher of the handler changes the floating-point
control status and either the handler resignals an exception or the
handler is called for an unwind exception (see Section 8.7), the
handler must reset the floating-point control status to the value saved
by the establisher.
To unwind, the handler or any procedure that it calls can make a call to SYS$UNWIND. The format is as follows:
Function Value Returned:
The depadr argument specifies the address of the longword that contains the number of presignal frames (depth) to be removed. The deepest procedure invocation whose frame is not removed is called the target invocation of the unwind. If that number is less than or equal to 0, nothing is to be unwound. The default (address = 0) is to return to the caller of the procedure that established the handler that issued the $UNWIND service. To unwind to the establisher, specify the depth from the call to the handler, which can be found in the CHF$IS_MCH_DEPTH field of the Mechanism Array. When the handler is at depth 0, it can achieve the equivalent of an unwind operation to an arbitrary place in its establisher by altering the PC in its signal_args vector and returning with SS$_CONTINUE, or SS$_CONTINUE64 if the 64-bit signal vector is altered, instead of performing an unwind.
The new_PC argument specifies the location to receive control when the unwinding operation is complete. The default is to continue at the instruction following the call to the last procedure activation that is removed from the stack.
The function value success either is a standard success code (SS$_NORMAL) or it indicates failure with one of the following return status condition values:
If SYS$UNWIND is invoked by a handler that has already invoked SYS$UNWIND, then the effect of the second invocation is undefined.
The unwinding operation occurs when the handler returns to the CHF. Unwinding is done by scanning back through the stack and calling each handler associated with a frame. The handler is called with the exception SS$_UNWIND to perform any application-specific cleanup. If the depth specified includes unwinding the establisher's frame, the current handler is recalled with this unwind exception.
When the target invocation is reached on Alpha or I64 systems, unwind completion depends on the PDSC$V_TARGET_INVO flag of the associated procedure descriptor or unwind information, respectively. If that flag is set to 1, then the handler for that procedure invocation is called; otherwise, no handler is called. Control then resumes in the target invocation.
The call to the handler takes the same form as described in Section 8.5.1 with the following values:
After each handler is called, the stack is logically cut back to the previous frame.
On Alpha or I64 systems, the stack is not actually cut back until after the last handler is called.
The exception vectors are not checked because they are not being removed. Any function value from the handler is ignored.
To specify the value of the top-level function being unwound, the handler should modify the appropriate saved register locations in the mechanism_args vector. They are restored from the mechanism_args vector at the end of the unwind.
Depending on the arguments to SYS$UNWIND, the unwinding operation is terminated as follows:
The only recommended values for depth are the default (address of 0), which unwinds to the caller of the establisher, and the value of depth taken from the mechanism vector, which unwinds to the establisher. Other values depend on implementation details that can change at any time.
You can call SYS$UNWIND whether the condition was a software exception
signaled by calling LIB$SIGNAL or LIB$STOP or was a hardware exception.
Calling SYS$UNWIND is the only way to continue execution after a call
On VAX systems, to find registers R2 through FP, a scan of stack frames must be performed starting with the current frame and ending with the call to the handler. During the scan, the last frame found to save a register contains that register's contents at the time of the exception. If no frame saved the register, the register is still active in the current procedure. The frame of the call to the handler can be identified by the return address of SYS$CALL_HANDL+4. In this case, the registers are in the following states:
On VAX systems, the values that exist in R0 and R1 when the unwind completes are the values passed implicitly to the unwinder in the mechanism array (see Section 184.108.40.206.1). If desired, these values can be modified by an exception handler before the unwind is initiated.
On Alpha systems, the values that exist in R0, R1, F0, and F1 when the unwind completes are the values passed implicitly to the unwinder in the mechanism array (see Section 220.127.116.11.2). If desired, these values can be modified by an exception handler using SYS$SET_RETURN_VALUE before the unwind is initiated. Note that, unlike VAX systems, an Alpha system does not use R1 for returning any type of return values.
On I64 systems, the values that exist in R8, R9, F8, and F9 when the unwind completes are the values passed implicitly to the unwinder in the mechanism array (see Section 18.104.22.168.3). If desired, these values can be modified by an exception handler using SYS$SET_RETURN_VALUE before the unwind is initiated.
The effect of handler modification of any mechanism vector field other than described above is undefined.
1If the address of the return_type argument is zero, then the return_value argument is fetched by value and is treated as return-type PSIG$K_FR_U32. This combination of arguments can be used to set a condition code such as SS$_ACCVIO as a return value.
Function Value Returned:
8.8 GOTO Unwind Operations (Alpha and I64 Systems Only)
A GOTO unwind is a transfer of control that leaves one procedure invocation and continues execution in a prior, currently active procedure invocation. Modular and reliable support of the nonlocal GOTO requires procedure invocations that are terminated to have an opportunity to clean up in an orderly way (just like a procedure that is terminated as a result of an unwind from a condition handler).
Performing a GOTO unwind operation in a thread causes a transfer of control from the location at which the GOTO unwind operation is initiated to a target location in a target invocation. This transfer of control also results in the termination of all procedure invocations, including the invocation in which the unwind request was initiated, up to the target procedure invocation. Thread execution then continues at the target location.
Before control is transferred to the unwind target location, the unwind support code invokes all frame-based handlers that were established by procedure invocations being terminated. These handlers are invoked with an indication of an unwind in progress. This gives each procedure invocation being terminated the chance to perform cleanup processing before its context is lost.
When the target invocation is reached, unwind completion depends on the PDSC$V_TARGET_INVO flag of the associated procedure descriptor (Alpha) or OSSD$V_TARGET_INVO flag of the associated unwind information block (I64). If that flag is set to 1, then the handler for that procedure invocation is called; otherwise, no handler is called.
After all the relevant frame-based handlers have been called and the appropriate frames have been removed from existence, the target invocation's saved context is restored and execution is resumed at the specified location.
A GOTO unwind procedure can be initiated while an exception is active (from within a condition handler) or while no exception is active. If the GOTO unwind transfers control out of an exception handler (resulting in the termination of current handler invocation), it also terminates handling of the corresponding condition (like SYS$UNWIND).
A thread can initiate a GOTO unwind operation by calling SYS$GOTO_UNWIND_64, defined as:
On Alpha systems, the following backward compatible form is also provided:
1Type is longword (unsigned) for SYS$GOTO_UNWIND; quadword (unsigned) for SYS$GOTO_UNWIND_64
Condition Value Returned:
When a GOTO unwind is initiated, control almost never returns to the point at which the unwind was initiated. Control returns with an error status only if a GOTO unwind cannot be started. If SYS$GOTO_UNWIND_64 (or SYS$GOTO_UNWIND) is invoked by a handler that has already invoked SYS$UNWIND, then the effect of calling SYS$GOTO_UNWIND_64 (or SYS$GOTO_UNWIND) is undefined.