[an error occurred while processing this directive]

HP OpenVMS Systems Documentation

Content starts here

HP OpenVMS Calling Standard


Previous Contents Index

8.5.3.4 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:

  • Save the floating-point control status in effect on entry and restore that status when it returns.
  • Establish a handler that will restore the floating-point control status if either an exception is resignalled or if the routine terminates due to an unwind operation.

    Note

    The means by which the saved floating-point control status of the establisher is communicated to its handler is not specified here.

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:

  • For SS$_CONTINUE64 and SS$_RESIGNAL64, the 32-bit signal vector is simply derived again from the 64-bit signal vector. In particular, no hidden copy of the 64-bit signal vector is kept. It is not necessary to determine if there was a change or not---if there was, it is properly reflected in the 32-bit vector.
  • For SS$_CONTINUE and SS$_RESIGNAL, let SIGVEC32[I] and SIGVEC64[I] be corresponding entries in the two vectors, for I from 1 to length. (Recall that the length[s] cannot be changed.) For each entry, do the following:


      if SIGVEC32[I] /= SIGVEC64[I]<0,32>
      then
          SIGVEC64[I] = sign-extend(SIGVEC32[I])
    

    That is, if the 32-bit entry is still the same as the low-order 32 bits of the 64-bit entry, then it did not change and thus the 64-bit entry is not changed. Otherwise, update the 64-bit entry with the sign-extended contents of the 32-bit entry.

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.

8.7 Request to Unwind from a Signal

To unwind, the handler or any procedure that it calls can make a call to SYS$UNWIND. The format is as follows:


SYS$UNWIND(depadr, new_PC)

Argument OpenVMS Usage Type Access Mechanism
depadr integer longword read by reference
new_PC address longword read by reference

Arguments:

  depadr
Optional number of presignal frames (depth) to be removed.
  new_PC
Optional address of the location to receive control after the unwind operation is completed.

Function Value Returned:

  Success or failure status (see text that follows).

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:

  • No signal active (SS$_NOSIGNAL)
  • Already unwinding (SS$_UNWINDING)
  • Insufficient frames for depth (SS$_INSFRAME)

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:

  • signal_args: for a handler for a procedure other than the target invocation of the unwind---an argument count (CHF$L_SIG_ARGS) of 1 and a condition value (CHF$L_SIG_NAME) of SS$_UNWIND.
    For a handler on Alpha or I64 systems for a procedure that is the target invocation of the unwind---an argument count (CHF$L_SIG_ARGS) of 2 and two condition values consisting of SS$_UNWIND followed by SS$_TARGET_UNWIND.
  • mechanism_args: same as for the original call except for a depth of 0 (that is, unwinding self) and any other changes made by prior handlers.

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:

SYS$UNWIND(0,0) Unwind to the establisher's caller.
SYS$UNWIND( depth,0) Unwind to the establisher at the point of the call that resulted in the exception.
SYS$UNWIND( depth, location) Unwind to the specified procedure activation and transfer to a specified location.

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 to LIB$STOP.

8.7.1 Signaler's Registers

Because the handler is called and can in turn call routines, the actual register values in use at the time of the signal or exception can be scattered on the stack.

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:

R0, R1 In mechanism_args
R2--11 Last frame saving it
AP Old AP of SYS$CALL_HANDL+4 frame
FP Old FP of SYS$CALL_HANDL+4 frame
SP Equal to end of signal_args vector+4
PC, PSL At end of signal_args vector

On Alpha or I64 systems, to find the contents of the registers, use the invocation context routines described in Sections 3.5.3 or 4.8.3, respectively.

8.7.2 Unwind Completion

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 8.5.1.2.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 8.5.1.2.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 8.5.1.2.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.

SYS$SET_RETURN_VALUE (Alpha and I64 systems only)


SYS$SET_RETURN_VALUE(mechanism_arg, return_type, return_value)

Argument OpenVMS Usage Type Access Mechanism
mechanism_arg mechanism vector address quadword (unsigned) read by value
return_type integer longword (unsigned) read by reference
return_value buffer scalar read by reference

Arguments:

  mechanism_arg
Address of mechanism vector. If zero, the mechanism vector for the currently active signal will be used. 1
  return_type
Address of a longword that contains one of the function return signature codes found in Table 5-4. 1
  return_value
Address of a value of the appropriate type. The referenced value will be read as a longword, quadword, or octaword, depending on the return_type. 1

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:

  status
(Success or failure) The given return value is placed in the appropriate fields of the specified mechanism vector, according to the return type.

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).

Note

OpenVMS Alpha uses different registers than OpenVMS I64 systems. This section uses the terms RetVal, RetVal2, NewRetVal, and NewRetVal2 to describe the generic unwind operation. The following table translates these terms for each system:
Symbol Alpha Systems I64 Systems
RetVal R0 R8
RetVal2 R1 R9
NewRetVal New_R0 New_R8
NewRetVal2 New_R1 New_R9
     

A thread can initiate a GOTO unwind operation by calling SYS$GOTO_UNWIND_64, defined as:


SYS$GOTO_UNWIND_64(target_invo, target_pc, NewRetVal, NewRetVal2)

On Alpha systems, the following backward compatible form is also provided:


SYS$GOTO_UNWIND(target_invo, target_pc, New_R0, New_R1)

Argument OpenVMS Usage Type Access Mechanism
target_invo invo_handle longword or quadword (unsigned) 1 read by reference
target_pc address longword or quadword (unsigned) 1 read by reference
NewRetVal quadword_unsigned quadword (unsigned) read by reference
NewRetVal2 quadword_unsigned quadword (unsigned) read by reference

1Type is longword (unsigned) for SYS$GOTO_UNWIND; quadword (unsigned) for SYS$GOTO_UNWIND_64

Arguments:

  target_invo
Address of a location that contains a handle for the target invocation.

If omitted or the address of the handle is zero, then the effect of the call is undefined.

  target_pc
Address of a location that contains the address at which execution should continue in the target invocation.

If omitted or if the address is 0, then execution resumes at the location specified by the return address for the call frame of the target procedure invocation.

If the target_invo argument is omitted or is 0, then this argument is ignored. In this case, a system-defined target PC is assumed.

  NewRetVal
Address of a location that contains the value to place in the saved RetVal location of the mechanism argument vector. The contents of this location are then loaded into RetVal at the time that execution continues in the target invocation.

If this argument is omitted, then the contents of RetVal at the time of the call to SYS$GOTO_UNWIND_64 are used.

This argument is called New_R0 in SYS$GOTO_UNWIND for compatibility with Alpha.

  NewRetVal2
Address of a location that contains the value to place in the saved RetVal2 location of the mechanism argument vector. The contents of this location are then loaded into RetVal2 at the time that execution continues in the target invocation.

If this argument is omitted, then the contents of RetVal2 at the time of the call to SYS$GOTO_UNWIND_64 are used.

This argument is called New_R1 in SYS$GOTO_UNWIND for compatibility with Alpha.

Condition Value Returned:

  SS$_ACCVIO
An invalid address was given.

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.


Previous Next Contents Index