This routine is not available to native OpenVMS Alpha and I64 programs
but is available to translated VAX images.
The Description section of the LIB$DECODE_FAULT routine is divided into
the following parts:
Guidelines for Using LIB$DECODE_FAULT
LIB$DECODE_FAULT is a tool for building condition handlers that process
instruction fault exceptions. Called from a condition handler,
LIB$DECODE_FAULT performs the following actions:
- Unwinds intermediate stack frames back to that of the exception
- Decodes the instruction stream to determine the operation and its
operands
- Calls a user-supplied action routine and passes it a consistent and
easy-to-access description of the instruction's context
Your user action routine performs whatever tasks are necessary to
handle the fault and returns to LIB$DECODE_FAULT. LIB$DECODE_FAULT then
restores the context as modified by your user action routine and
continues execution.
Your condition handler must first decide whether or not it wants to
handle the exception. The signal arguments list contains the exception
code and the address of the program context (PC) that is usually
sufficient for this determination. Once LIB$DECODE_FAULT is called, if
the exception is a fault LIB$DECODE_FAULT can analyze, control does not
return to the condition handler. Therefore, your handler must not
depend on regaining control by a routine return once it has called
LIB$DECODE_FAULT. With your user action routine, LIB$DECODE_FAULT makes
the original fault disappear.
Note
Your user action routine is capable of generating a new exception,
including one that looks identical to the original exception. Your user
action routine may also resignal, but if the decision to resignal is
made inside the user action routine, all post-signal stack frames are
lost.
|
Once your condition handler has decided that it wants to handle the
exception, it calls LIB$DECODE_FAULT, passing as arguments the
addresses of the signal and mechanism argument lists and a descriptor
for your user action routine entry point. LIB$DECODE_FAULT then
performs the following actions:
- Determines if the exception is a fault it understands. If not, it
returns SS$_RESIGNAL.
- Determines the context in which the exception occurred, including
register and processor status longword (PSL) contents, and saves it.
- Unwinds all stack frames back to that frame in which the exception
occurred.
- Evaluates each operand's addressing mode, computing the resulting
location for the operand. Immediate mode operands are expanded into
their full form. If an invalid addressing mode is found, an SS$_RADRMOD
exception is generated.
- Unless the original exception was SS$_ACCVIO, tests each operand
for accessibility. If necessary, an access violation is signaled as if
the instruction had tried to execute normally. See the paragraph
following this list for more information.
- Unless the original exception was SS$_ROPRAND, tests each
floating-point operand that is to be read for a reserved floating
operand. If necessary, a reserved operand fault is signaled. See the
paragraph following this list for more information.
- Determines the address of the next sequential instruction.
- Calls your user action routine with arguments as described below.
- Upon return from your user action routine, reflects changes to the
registers and PSL and continues execution at the instruction address
specified by your user action routine. Optionally, your user action
routine may resignal the original exception.
Some instructions can generate more than one fault if evaluation of one
operand causes a fault that occurs before a later operand (which would
also cause a fault). An example of this is the possibility that a
floating-point divide instruction might report a divide-by-zero fault
upon seeing a zero divisor before noticing that the dividend was a
reserved operand or was inaccessible.
In these cases, operand-specific faults are signaled immediately by
LIB$DECODE_FAULT in the expectation that another condition handler (or
the same one) can repair the situation. This may reorder the sequence
of exceptions as seen by a program. If the operand exception is
corrected, the original exception reoccurs, and the proper action is
taken.
If at all possible, try to determine if a resignal is necessary inside
the condition handler that calls LIB$DECODE_FAULT, rather than inside
your user action routine. The reason for this is that LIB$DECODE_FAULT
removes all post-signal stack frames before calling your user action
routine.
Your user action routine may fetch and store the operands,
registers, and PSL as necessary for
handling the exception. You should follow the VAX architecture rule of
reading all input operands in left-to-right order, then writing all
output operands in left-to-right order, to avoid inconsistent results
with overlapping operands. This is especially necessary with register
operands.
PSL may be modified in a manner consistent with the
VAX architecture. If the T-bit in the PSL was set at the beginning of
the instruction, LIB$DECODE_FAULT sets the TP bit. To initiate tracing,
you must set only the T bit. To disable tracing, you must clear both
the T and TP bits. See the VAX Architecture Reference Manual for more information.
If the first-part-done (FPD) bit in the PSL was set when the
instruction faulted, LIB$DECODE_FAULT only advances the PC over the
instruction; it does not reevaluate the operands, and it sets
operand-count to zero. It is assumed that if FPD is
set, the operands are in known locations (typically the registers).
For the CASEB, CASEW, and CASEL instructions, only the
selector, base, and
limit operands are represented in
operand-count and
read-operand-locations. The element of registers that
corresponds to the PC, described in the following text as R15, points
to the first of the word-length displacements. Your user action routine
must modify R15 to reflect the location of the next instruction to
execute.
The standard instruction definitions used by LIB$DECODE_FAULT specify
the XFC instruction (which causes an SS$_OPCCUS fault) as having zero
operands. You may redefine XFC if needed using the
instruction-definitions argument to LIB$DECODE_FAULT.
If you do not want instruction execution to resume with the next
sequential instruction, you must modify R15 appropriately. Your user
action routine then returns to LIB$DECODE_FAULT, which restores the
registers and PSL, and resumes instruction execution. See also the
LIB$_RESTART condition value in the section called Condition Values Returned from the User Action Routine.
Note
Vector context is not saved or restored.
|
Exceptions Recognized by LIB$DECODE_FAULT
LIB$DECODE_FAULT recognizes the following VAX faults:
- SS$_ACCVIO, access violation.
- SS$_BREAK, breakpoint fault.
- SS$_FLTDIV_F, floating divide by zero.
- SS$_FLTOVF_F, floating overflow.
- SS$_FLTUND_F, floating underflow.
- SS$_OPCCUS, opcode reserved to customers.
- SS$_OPCDEC, opcode reserved to HP.
- SS$_ROPRAND, reserved operand.
- SS$_TBIT, T-bit pending trap. This is actually a fault caused by
the TP bit being set at the beginning of instruction execution. It
allows you to interpret all instructions by setting the PSL T-bit and
allowing each instruction to trace-fault.
All other exceptions, including SS$_COMPAT and SS$_RADRMOD, cause
LIB$DECODE_FAULT to return immediately with the return status
SS$_RESIGNAL.
SS$_COMPAT is generated by compatibility-mode instructions.
LIB$DECODE_FAULT does not handle compatibility-mode instructions.
SS$_RADRMOD is generated by a reserved addressing-mode fault.
LIB$DECODE_FAULT assumes that all instructions follow VAX
addressing-mode specifications.
Instruction Operand Definition Codes
Each instruction operand has an access type (read, write, ...) and a
data type (byte, word, ...) associated with it. The operand definition
codes used in both the instruction-definitions
argument passed to LIB$DECODE_FAULT and in the
operand-types argument passed to the user action
routine encode the access and data types in a byte. The fields and
values for operand access and data types are described using the
symbols in Table lib-3. These symbols are defined in definition
libraries supplied by HP as macro or module name $LIBDCFDEF.
Table lib-3 Symbols for Fields and Values for Operand Access and Data Types Using LIB$DECODE_FAULT
Symbol |
Description |
LIB$V_DCFACC
|
The field of the operand description code that describes the operand
access type (bits 0--2).
|
LIB$S_DCFACC
|
The size of the access type field (3 bits).
|
LIB$M_DCFACC
|
The mask for the access type field. This is a 3-bit field that can
contain any binary value from 000 through 111. The integer value of
these bit settings defines the operand access type code for the
LIB$M_DCFACC field. Currently, six codes are defined. These codes have
symbolic names and are explained below. It is important to remember
that LIB$M_DCFACC is not a bit mask. The values 0 through 6 do not
refer to bits 0 through 6. They represent the binary values 001 through
110 as contained in the 3-bit field.
The operand access type codes defined for the LIB$M_DCFACC field
are:
LIB$K_DCFACC_R = 1
|
Operand is read-only.
|
LIB$K_DCFACC_M = 2
|
Operand is to be modified.
|
LIB$K_DCFACC_W = 3
|
Operand is write-only.
|
LIB$K_DCFACC_A = 4
|
Operand is an address (must not be a register).
|
LIB$K_DCFACC_V = 5
|
Operand is the base of a bit field (same as address except that it may
be a register).
|
LIB$K_DCFACC_B = 6
|
Operand is a branch address.
|
|
LIB$V_DCFTYP
|
The field of the operand descriptor code that describes the operand
data type (bits 3--7).
|
LIB$S_DCFTYP
|
The size of the operand data type field (5 bits).
|
LIB$M_DCFTYP
|
The mask for the operand data type field. This is a 5-bit field (bits
3--7) that can contain any binary value from 00000 through 11111. The
integer value of these bit settings defines the operand access type
code for the LIB$M_DCFACC field. Currently, nine codes are defined.
These codes have symbolic names and are explained below. It is
important to remember that LIB$M_DCFTYP is not a bit mask. The values 0
through 9 do not refer to bits 0 through 9. They represent the binary
values 00001 through 01001 as contained in the 5-bit field. The operand
access type codes defined for the LIB$V_DCFTYP field are:
LIB$K_DCFTYP_B = 1
|
Operand is a byte.
|
LIB$K_DCFTYP_W = 2
|
Operand is a word.
|
LIB$K_DCFTYP_L = 3
|
Operand is a longword.
|
LIB$K_DCFTYP_Q = 4
|
Operand is a quadword.
|
LIB$K_DCFTYP_O = 5
|
Operand is an octaword.
|
LIB$K_DCFTYP_F = 6
|
Operand is F_floating.
|
LIB$K_DCFTYP_D = 7
|
Operand is D_floating.
|
LIB$K_DCFTYP_G = 8
|
Operand is G_floating.
|
LIB$K_DCFTYP_H = 9
|
Operand is H_floating.
|
|
Symbols of the form LIB$K_DCFOPR_xy, where x is the
access type and y is the data type, are also defined.
These combine the notions of access and data type. For example,
LIB$K_DCFOPR_MF has the following value:
It denotes modify access of an F_floating item. For the branch access
type, only the types BB, BW, and BL are defined; otherwise, all
combinations are available.
Call Format for a User Action Routine
LIB$DECODE_FAULT calls the user action routine when it finds an
exception to be handled. Your user action routine handles the exception
in any manner that you specify and then returns to LIB$DECODE_FAULT.
action-routine opcode ,instr-PC ,PSL ,registers
,operand-count
,operand-types ,read-operand-locations
,write-operand-locations ,signal-arguments
,signal-procedure ,context
,unspecified-user-argument ,original-registers
opcode
OpenVMS usage: |
longword_unsigned |
type: |
longword (unsigned) |
access: |
read only |
mechanism: |
by reference |
Opcode of the instruction that caused the fault. The
opcode argument is the address of a longword that
contains this opcode. LIB$DECODE_FAULT supplies this opcode when it
calls the user action routine.