|
HP OpenVMS Calling Standard
The fields in these records are used as follows:
- RMASK, FRMASK, GRMASK, BRMASK---Identify which preserved
floating-point registers, general registers, and branch registers are
saved by the prologue region. The fr_mem record uses a short RMASK
field, which can be used when a subset of floating-point registers from
the range F2-F5 is saved. The FRGR_MEM record can be used for any
number of saved floating-point and general registers. The GR_MEM record
can be used when only general registers (R4-R7) are saved.
- IMASK---Identifies when each preserved floating-point, general,
and branch register is saved. It contains a two-bit field for each
instruction slot in the prologue, that indicates whether the
instruction in that slot saves one of these preserved registers. The
length of this field is implied by the size of the prologue region as
given in the region header record. It contains two bits for each
instruction slot in the region, and the length of the field is rounded
up to the next whole byte boundary.
If a prologue saves one or more preserved floating-point, general, or
branch registers, and the SPILL_MASK record is omitted, the unwinder
can assume that both of the following are true:
- The original contents of these preserved registers are valid
through the end of the prologue region.
- The saved copies of the registers are valid by the end of the
prologue region.
There can be only one SPILL_BASE and one SPILL_MASK record per prologue
region. Each GR_GR and BR_GR record describes a set of registers that
is saved to a consecutive set of general registers (typically in the
local register stack frame). To represent registers saved to
nonconsecutive general registers, two or more of each of these records
can be used.
Table A-8 describes the descriptor records used to record the state
of the User NaT Collection register (AR.UNAT).
Table A-8 Prologue Descriptor Records for the User NaT Collection Register
Record Type |
Fields |
Format |
Description |
UNAT_WHEN
|
T
|
P7
|
Specifies when AR.UNAT is saved.
|
UNAT_GR
|
GR
|
P3
|
Specifies the general register where AR.UNAT is saved.
|
UNAT_PSPREL
|
PSPOFF
|
P7
|
Specifies (as a PSP-relative offset) the memory location where AR.UNAT
is saved.
|
UNAT_SPREL
|
SPOFF
|
P8
|
Specifies (as an SP-relative offset) the memory location where AR.UNAT
is saved.
|
Table A-9 describes the descriptor records that are used to record
the state of the loop counter register (AR.LC).
Table A-9 Prologue Descriptor Records for the Loop Counter Register
Record Type |
Fields |
Format |
Description |
LC_WHEN
|
T
|
P7
|
Specifies when AR.LC is saved.
|
LC_GR
|
GR
|
P3
|
Specifies general register where AR.LC is saved.
|
LC_PSPREL
|
PSPOFF
|
P7
|
Specifies (as a PSP-relative offset) the memory location where AR.LC is
saved.
|
LC_SPREL
|
SPOFF
|
P8
|
Specifies (as an SP-relative offset) the memory location where AR.LC is
saved.
|
Note
The FPSR-related descriptor records (FPSR_WHEN, FPSR_GR, FPSR_PSPREL,
FPSR_SPREL) defined in the Itanium® Software Conventions and
Runtime Architecture Guide are not supported on OpenVMS I64.
|
Table A-10 describes the descriptor records that are used to record
the state of the primary UNaT collection.
Table A-10 Prologue Descriptor Records for the Primary UNaT Collection
Record Type |
Fields |
Format |
Description |
PRIUNAT_WHEN_GR
|
T
|
P8
|
Specifies when the primary UNaT collection is copied to a general
register.
|
PRIUNAT_WHEN_MEM
|
T
|
P8
|
Specifies when the primary UNaT collection is saved in memory.
|
PRIUNAT_GR
|
GR
|
P3
|
Specifies the general register where the primary UNaT collection is
copied.
|
PRIUNAT_PSPREL
|
PSPOFF
|
P8
|
Specifies (as a PSP-relative offset) the memory location where the
primary UNaT collection is saved.
|
PRIUNAT_SPREL
|
SPOFF
|
P8
|
Specifies (as an SP-relative offset) the memory location where the
primary UNaT collection is saved.
|
Table A-11 describes the descriptor records that are used to record
the state of the backing store, when it is necessary to record a
discontinuity.
Table A-11 Prologue Descriptor Records for the Backing Store
Record Type |
Fields |
Format |
Description |
BSP_WHEN
|
T
|
P8
|
Specifies when AR.BSP is saved. The backing store pointer can be saved,
along with the AR.BSPSTORE pointer and the AR.RNAT register, to
indicate a discontinuity in the backing store.
|
BSP_GR
|
GR
|
P3
|
Specifies the general register where AR.BSP is saved.
|
BSP_PSPREL
|
PSPOFF
|
P8
|
Specifies (as a PSP-relative offset) the memory location where AR.BSP
is saved.
|
BSP_SPREL
|
SPOFF
|
P8
|
Specifies (as an SP-relative offset) the memory location where AR.BSP
is saved.
|
BSPSTORE_WHEN
|
T
|
P8
|
Specifies when AR.BSPSTORE is saved.
|
BSPSTORE_GR
|
GR
|
P3
|
Specifies the general register where AR.BSPSTORE is saved.
|
BSPSTORE_PSPREL
|
PSPOFF
|
P8
|
Specifies (as a PSP-relative offset) the memory location where
AR.BSPSTORE is saved.
|
BSPSTORE_SPREL
|
SPOFF
|
P8
|
Specifies (as an SP-relative offset) the memory location where
AR.BSPSTORE is saved.
|
RNAT_WHEN
|
T
|
P8
|
Specifies when AR.RNAT is saved.
|
RNAT_GR
|
GR
|
P3
|
Specifies the general register where AR.RNAT is saved.
|
RNAT_PSPREL
|
PSPOFF
|
P8
|
Specifies (as a PSP-relative offset) the memory location where AR.RNAT
is saved.
|
RNAT_SPREL
|
SPOFF
|
P8
|
Specifies (as an SP-relative offset) the memory location where AR.RNAT
is saved.
|
A.4.1.4 Descriptor Records for Body Regions
Table A-12 lists the optional descriptor records that may be used to
describe body regions. In addition, the descriptor records described in
Section A.4.1.5 can also be used. In the absence of these descriptors, a
body region is assumed to inherit its entry state from the previous
region.
Table A-12 Body Region Descriptor Records
Record Type |
Fields |
Format |
Description |
EPILOGUE
|
T, ECOUNT
|
B2/B3
|
Body region contains epilogue code for one or more prologues.
|
LABEL_STATE
|
LABEL
|
B1/B4
|
Labels the entry state for future reference.
|
COPY_STATE
|
LABEL
|
B1/B4
|
Use the labeled entry state as entry state for this region.
|
- T---Indicates the location (relative to the end of the region) of
the instruction that restores the previous SP value. The number is a
count of the remaining instruction slots to the end of the region
(thus, a value of zero indicates the final slot in the region).
- ECOUNT---Indicates how many additional levels of nested
shrink-wrap regions are being popped at the end of a body region with
epilogue code. A value of zero indicates that one level must be popped.
When OpenVMS handler semantics apply, this value must be zero.
- LABEL---Identifies a previously-specified body region, whose entry
state must be copied for this body region.
Prologue regions nest within other prologue regions, and are balanced
by body regions with an epilogue descriptor. An epilogue descriptor
with an ECOUNT of n serves to balance (n+1) earlier
prologue regions. When OpenVMS handler semantics apply, prologue
nesting is not allowed.
When the LABEL_STATE descriptor is used to label an entry state, it
must appear prior to any general unwind descriptors in the same body
region.
A COPY_STATE descriptor must appear prior to any general unwind
descriptors in the same body region.
A labelled entry state includes not only the record of where current
valid copies of all preserved values can be found, but also references
the states that are currently on the stack of nested prologues. For
example, consider the following sequence of regions:
- Prologue region A
- Body region B (no epilogue)
- Prologue region C
- Body region C (label_state 1, epilogue count 2)
- Body region D (copy_state 1, epilogue count 2)
The effect of the COPY_STATE in body region D restores the entry state
of body region C, as well as the two prologue regions within which the
body region is nested.
The scope of a label is restricted to a single unwind descriptor area.
A.4.1.5 Descriptor Records for Body or Prologue Regions
This section lists the descriptor records that can be used to describe
either prologue or body regions. These descriptors provide complete
generality for compilers to perform register spills and restores
anywhere in the procedure, without creating an arbitrary boundary
between prologue and body.
If a SPILL record (see Table A-13) is used in a prologue for a given
preserved register, then only SPILL records can be used for that
preserved register in that prologue region. In other words, you must
not mix X format and P format descriptors for the same preserved
register in the same prologue.
Table A-13 General Unwind Descriptors
Record Type |
Fields |
Format |
Description |
SPILL_PSPREL
|
T, REG, PSPOFF
|
X1
|
Specifies (as a PSP-relative offset) when and where REG is saved.
|
SPILL_SPREL
|
T, REG, SPOFF
|
X1
|
Specifies (as an SP-relative offset) when and where REG is saved.
|
SPILL_REG
|
T, REG, TREG
|
X2
|
Specifies when and where REG is saved in another register, TREG, or
restored.
|
SPILL_PSPREL_P
|
QP, T, REG, PSPOFF
|
X3
|
Specifies (as a PSP-relative offset) when and where REG is saved, under
predicate QP.
|
SPILL_SPREL_P
|
QP, T, REG, SPOFF
|
X3
|
Specifies (as an SP-relative offset) when and where REG is saved, under
predicate QP.
|
SPILL_REG_P
|
QP, T, REG, TREG
|
X4
|
Specifies when and where REG is saved in another register, TREG, or
restored, under predicate QP.
|
- T---Describes a time, T, when a particular action occurs within
the prologue or body. The time is specified as an instruction slot
number, counting three slots per bundle. The first slot in the
containing prologue or body is numbered zero.
- REG---Identifies the register being spilled or restored at the
given point in the code. This field may indicate any of the preserved
general registers, floating-point registers, branch registers,
application registers, predicate registers, previous SP, primary UNaT
collection, or return pointer. See Appendix B for the encoding of
this field.
- TREG---Identifies a target register to which the value being
spilled is copied. This field may indicate any general register,
floating-point register, or branch register; it may also contain the
special Restore target, indicating the point at which a register is
restored. See Appendix B for the encoding of this field.
- QP---Identifies a qualifying predicate register, which determines
whether the indicated spill or restore instruction executes. The
qualifying predicate register must be a preserved predicate if there
are any procedure calls in the range between the spill and restore, and
it must remain live throughout the range.
If a body region contains any general descriptors and an epilogue
descriptor, the effects of the general descriptors are undone when the
unwind state is restored by popping one or more prologues. By the end
of the body region, the code must have restored any preserved registers
that the new unwind state indicates are restored. It is not necessary,
however, to record the points at which registers are restored unless
the locations used to save the values are modified before the end of
the region.
A.4.1.6 Rules for Using Unwind Descriptors
Preserved registers that are saved in the prologue region must be
specified with one or more of the following descriptor records:
- PROLOGUE_GR (RP, AR.PFS, PSP, and the predicate registers)
- MEM_STACK_V (PSP is saved in a general register)
- RP_WHEN, RP_GR, RP_PSPREL, or RP_SPREL (RP)
- PFS_WHEN, PFS_GR, PFS_PSPREL, or (AR.PFS)
- UNAT_WHEN, UNAT_GR, UNAT_PSPREL, or UNAT_SPREL (AR.UNAT)
- LC_WHEN, LC_GR, LC_PSPREL, or LC_SPREL (AR.LC)
- FR_MEM, FRGR_MEM, or GR_MEM (floating-point registers and general
registers)
- BR_MEM or BR_GR (branch registers)
- SPILL_PSPREL, SPILL_SPREL, SPILL_REG, SPILL_PSPREL_P,
SPILL_SPREL_P, SPILL_REG_P (any register)
If a preserved register is not named by one or more of these records,
it is assumed that the prologue does not save or modify that register.
The locations where preserved registers are saved are determined
according to the following rules:
- Certain descriptor records explicitly name a save location for a
register (records whose names end with _GR, PSPREL, or _SPREL). If a
register is described by one of these records, the unwinder uses the
named location.
- Some descriptor records specify that registers are saved to the
spill area (FR_MEM, FRGR_MEM, GR_MEM, BR_MEM). These locations are
determined by the conventions for the spill area.
- Any remaining registers that are named as saved but do not have an
explicit save location are assigned consecutive general registers,
beginning with the general register identified by the PROLOGUE_GR
region header record. If the prologue region uses a prologue header
record, the first general register is assumed to be R32. The registers
are saved as needed in the following order:
- Return pointer, RP
- Previous function state, AR.PFS
- Previous stack pointer, PSP
- Predicate registers
- User NaT collection register, AR.UNAT
- Loop counter, AR.LC
- Primary UNaT collection
Note
Without explicitly specifying a save location, the only way to indicate
that any of the last four groups of registers (e through h) is saved is
to use one of the corresponding _WHEN descriptor records.
|
A.4.1.7 Processing Unwind Descriptors
The unwind process for a frame begins by locating the unwind table
entry for a given PC. (A leaf procedure may have no unwind table entry;
see Section A.4.)
If there is an unwind table entry, the unwinder then locates the unwind
information block and checks the size of the unwind descriptor area. If
this area is zero length, the unwinder must use the default conditions
as above.
In preparation for reading the unwind descriptor records, the unwinder
must start with an initial current state record, and an empty stack of
state records. A state record describes the locations of all preserved
registers at entry to a region. The initial value of the current state
record must describe the frame in its default condition.
The unwind descriptor records must be read and processed sequentially,
beginning with the first descriptor record for a procedure, continuing
until the PC is contained within the current region. For each prologue
region header, the current state record must be pushed on the stack,
and the descriptor records for the prologue region must be applied to
the current state record. When a body region with epilogue code is
seen, one or more states must be popped from the stack, and the entry
state for the next region is taken as the last state popped. This
restores the current state to the entry state of the matching prologue.
When a body region contains a LABEL_STATE descriptor, the unwind
processor must replicate the current unwind state, including the
current stack of prologues. When a body region contains a COPY_STATE
descriptor, the unwind processor must discard the current state and
stack, and restore the replicated state and stack that corresponds with
the label.
When the current PC is within a body region, the unwinder can generate
the context of the previous frame by restoring registers as indicated
by the current state record. If the body region has epilogue code and
the PC is beyond the indicated point where SP is restored, the unwinder
must assume that SP has already been restored, and that all registers
spilled to the memory stack frame (except those between PSP and PSP+16)
have also been restored. Registers spilled to the scratch area in the
caller's frame may not have been restored at that point, and the
unwinder must use the values in memory.
When the current PC is within a prologue region, the unwinder must look
for descriptor records that specify a time parameter that is at or
beyond the current PC. The unwinder must ignore these state
modifications when applying descriptor records to the current state. If
a register is saved but does not have a specified time, the unwinder
can assume that the original value is not modified within the prologue
and can ignore it.
The layout and size of the preserved register spill area cannot be
determined without reading all the prologue region descriptor records
in the procedure, and merging the save masks for the general,
floating-point, and branch registers.
A.4.2 Condition Handler
The condition handler identifier is accessed by adding the size of the
unwind descriptor area (ULEN, which is the count of quadwords), plus
the size of the header quadword, to the information block pointer. The
value in that location is the GP-relative offset for the global offset
table entry that contains the function pointer (address of a function
descriptor) for the condition handler. The dispatcher calls this
routine during the first unwind only if the EHANDLER bit is set, and
during the second unwind only if the UHANDLER bit is set.
Because the operating system-specific data area immediately follows the
condition handler identifier, the address of this area must be made
available to the condition handler.
A.4.3 Operating System-Specific Data Area
If an operating system-specific data area is present, it is located
immediately following the condition handler (if any) and before the
language-specific data area (if any). If there is no condition handler,
the operating system-specific data area is located immediately
following the unwind descriptors (where the condition handler would
have been). The operating system-specific data area must be aligned at
a quadword boundary.
The following field of the mechanism vector passed to a condition
handler (see Sections 8.5.1 and 8.5.1.2.3) may be helpful
in interpreting the contents of operating system-specific data:
CHF$PH_MCH_OSSD
|
The virtual address of the operating system-specific data area.
|
The OpenVMS-specific data area is present if the UNW_IVMS_MODE field in
the unwind information block has the value 3 (see Table A-1).
An OpenVMS-specific data area consists of one or more segments, where
each segment begins with a 15-bit TYPE code field followed by a 1-bit
SUCCESSOR flag as shown in Figure A-2.
Figure A-2 OpenVMS Operating System-Specific Data Area
Segment
The segment types defined for OpenVMS are described in the following
sections. They are identified by the codes shown in the following table:
Name |
Value |
Use |
OSSD$K_GENERAL_INFO
|
1
|
General information
|
OSSD$K_CALL_SPILL_INFO
|
2
|
Caller spill register information
|
Unless otherwise stated, each kind of segment data can occur at most
once in any given data area.
|