 |
OpenVMS Debugger Manual
16.5.1 Using VMR as the Default Mask
By default, if you do not specify a mask with the EXAMINE/TMASK or
EXAMINE/FMASK command, VMR is used as the mask. That is, the EXAMINE
command is applied only to the elements of the vector register that
correspond to the set bits (in the case of /TMASK) or clear bits (in
the case of /FMASK) of VMR.
In the following examples, VLR has the value 6 and VMR(0:VLR--1) has
the following set of values:
DBG> EXAMINE %VMR(0:%VLR-1)
0\%VMR
(0): 1
(1): 0
(2): 1
(3): 0
(4): 1
(5): 0
DBG>
|
The following command displays the value of V3 without using a mask.
All elements of V3 from 0 to VLR--1 are displayed:
DBG> EXAMINE %V3
0\%V3
(0): 17
(1): 138
(2): 3
(3): 9
(4): 51
(5): 252
DBG>
|
The following command displays the elements of V3 (in the range from 0
to VLR--1) for which VMR(i) has the value 1:
DBG> EXAMINE/TMASK %V3
0\%V3
(0): 17
(2): 3
(4): 51
DBG>
|
The following command displays the elements of V3 (in the range from 0
to VLR--1) for which VMR(i) has the value 0:
DBG> EXAMINE/FMASK %V3
0\%V3
(1): 138
(3): 9
(5): 252
DBG>
|
In the following example, the /FMASK qualifier is used when examining
an instruction and its vector-register operands. The
EXAMINE/OPERANDS/FMASK command displays the register-operand elements
(in the range from 0 to VLR--1) for which VMR(i) has the value
0:
DBG> EXAMINE/OPERANDS/FMASK .%PC
PROG$MAIN\%LINE 341+16: VVEQLL V0,V1
V0 contains:
0\%V0(1): 0
0\%V0(3): 0
0\%V0(5): 0
V1 contains:
0\%V1(1): 0
0\%V1(3): 0
0\%V1(5): 0
DBG>
|
16.5.2 Using a Slice of VMR as the Mask
If you specify a slice of VMR with the EXAMINE/TMASK or EXAMINE/FMASK
command, the output is displayed according to the following conventions:
- The number of mask elements specified limits the number of register
elements that you can examine. For example:
DBG> EXAMINE %VLR
0\%VLR: 12
DBG> EXAMINE %VMR(3:5)
0\%VMR
(3): 1
(4): 1
(5): 1
DBG> EXAMINE/TMASK=(%VMR(3:5)) %V0(3:10)
0\%V0
(3): 9
(4): 51
(5): 252
DBG>
|
Use parentheses when specifying a mask with the /TMASK qualifier.
- The lowest specified element of the mask is applied to the lowest
specified element of the register. For example, EXAMINE/TMASK %V0(4:7)
applies VMR(0) to V0(4), VMR(1) to V0(5), and so on. If the lowest
specified elements of the mask and register do not match, the debugger
lists both the mask elements and the register elements that are
operated on and issues a message. For example:
DBG> EXAMINE %VLR
0\%VLR: 12
DBG> EXAMINE %VMR(4:7)
0\%VMR
(4): 1
(5): 0
(6): 1
(7): 1
DBG> EXAMINE/TMASK=(%VMR(4:7)) %V0(3:10)
%DEBUG-I-MASKMISMATCH, mask/target subscripts do not match,
displaying mask
0\%V0
%VMR(4): 1
%V0(3): 9
%VMR(6): 1
%V0(5): 252
%VMR(7): 1
%V0(6): 56
DBG>
|
16.5.3 Using a Mask Other Than VMR
If you specify a mask address expression other than VMR with the
EXAMINE/TMASK or EXAMINE/FMASK command, the value at that address is
used as the mask subject to the following conventions:
- If the mask address expression denotes a Boolean array, its values
are used as the mask in the same basic way that VMR is used in the
default case. In the following example, BOOL_ARR, a 4-element Boolean
array variable, is used as the mask:
DBG> EXAMINE %VLR
0\%VLR: 6
DBG> EXAMINE BOOL_ARR
PROG$MAIN\BOOL_ARR
(0): 0
(1): 0
(2): 1
(3): 0
DBG> EXAMINE/FMASK=(BOOL_ARR) %V0
%DEBUG-I-MASKNOTVMR, mask used is not %VMR, displaying
specified mask
0\%V0
BOOL_ARR(0): 0
%V0(0): 17
BOOL_ARR(1): 0
%V0(1): 138
BOOL_ARR(3): 0
%V0(3): 9
DBG>
|
As shown in the example, when you use a mask other than VMR, the
debugger displays both the mask elements and the register elements that
are operated on and issues a message.
- If the mask address expression denotes a non-Boolean array, the
least significant bit of each array element is used as the mask for the
corresponding element of the register.
- If the mask address expression denotes a Boolean scalar type, its
value is used as the mask for the first element of the register. No
other elements are examined. In the following example, BOOL_VAR, a
single-element Boolean variable, is used as the mask:
DBG> EXAMINE BOOL_VAR
PROG$MAIN\BOOL_VAR: 1
DBG> EXAMINE/TMASK=(BOOL_VAR) %V0
%DEBUG-I-MASKNOTVMR, mask used is not %VMR, displaying
specified mask
0\%V0
BOOL_VAR: 1
%V0(0): 17
DBG>
|
- If the mask address expression denotes any other type, its least
significant bit value is used as the mask for the first element of the
register. No other elements are examined.
- The number of mask elements specified limits the number of register
elements that you can examine, as when the mask is VMR (see
Section 16.5.2).
- For a multi-element mask, the lowest specified element of the mask
is applied to the lowest specified element of the register, as when the
mask is VMR (see Section 16.5.2).
16.6 Examining Composite Vector Address Expressions
When using the EXAMINE command, you can specify various forms of
composite address expressions---expressions that include byte offsets
from a given address. For example, if X is an integer variable, the
following EXAMINE command displays the value currently stored at the
memory location that is 6 bytes beyond the address of X:
DBG> EXAMINE X + 6
MOD3\X+6: 274903
DBG>
|
The examples in this section show how to specify composite address
expressions of a form that might be appropriate for a vectorized
program.
The following example shows how you might verify the effect of a VSCATL
instruction. The instructions shown are decoded from a Fortran program.
DBG> EXAMINE %VLR
0\%VLR: 5
DBG> EXAMINE/OPERANDS .%PC (1)
PROG1$MAIN\%LINE 9+32: VSCATL V7,W^-804(R11),V9
V7 contains:
0\%V7(0): 11 (2)
0\%V7(1): 13
0\%V7(2): 15
0\%V7(3): 17
0\%V7(4): 19
W^-804(R11)PROG1$MAIN\ARRX(1) (address 1820) contains 0 (3)
V9 contains:
0\%V9(0): 0 (4)
0\%V9(1): 8
0\%V9(2): 16
0\%V9(3): 24
0\%V9(4): 32
DBG> SHOW SYMBOL/TYPE ARRX (5)
data PROG1$MAIN\ARRX
array descriptor type, 1 dimension, bounds: [1:200], size: 800 bytes
cell type: atomic type, longword integer, size: 4 bytes
DBG> EXAMINE ARRX(1) + .%V9(0:%VLR-1) (6)
PROG1$MAIN\ARRX(1): 0
PROG1$MAIN\ARRX(3): 0
PROG1$MAIN\ARRX(5): 0
PROG1$MAIN\ARRX(7): 0
PROG1$MAIN\ARRX(9): 0
DBG> STEP/INSTRUCTION (7)
stepped to PROG1$MAIN\%LINE 9+40: MOVZBL I^#64,AP
DBG> EXAMINE ARRX(1) + .%V9(0:%VLR-1) (8)
PROG1$MAIN\ARRX(1): 11
PROG1$MAIN\ARRX(3): 13
PROG1$MAIN\ARRX(5): 15
PROG1$MAIN\ARRX(7): 17
PROG1$MAIN\ARRX(9): 19
DBG>
|
The following comments refer to the callouts in the previous example:
- The EXAMINE/OPERANDS command shows that a
VSCATL instruction is about to be executed. The instruction will
transfer longword-integer (4-byte) data from register V7 into memory
locations. These locations are determined by adding offset values,
contained in register V9, to a base address.
- Register V7 contains the longword-integer
values to be transferred to memory.
- The base address specified as an operand to
the VSCATL instruction is symbolized as ARRX(1), which denotes element
1 of array ARRX.
- Register V9 contains the offset from the
base address, in bytes, of each target vector element in memory.
- The SHOW SYMBOL/TYPE command indicates that
ARRX is an array of contiguous longword integers.
- The EXAMINE command displays the values of
the target vector elements in memory. The address expression specified
uses the offset values contained in register V9 to set the start
address of successive vector elements in memory, relative to ARRX(1),
the base address. The debugger symbolizes the locations of vector
elements in memory in terms of the elements of array ARRX. In this
example, vector elements begin every 8 bytes, coinciding with every
other element of array ARRX. Because the VSCATL instruction has not yet
been executed, all of the vector elements in memory contain the value 0.
- The STEP/INSTRUCTION command executes the
VSCATL instruction and suspends execution at the next instruction,
MOVZBL.
- As in item , the
EXAMINE command displays the values of the target vector elements in
memory. Now the contents of memory show that the values have been
transferred from register V7.
The next example shows how to specify a more complex vector address
expression with the EXAMINE command.
Assume that array ARRZ has contiguous quadword-integer (8-byte)
elements. The fourth EXAMINE command in the example displays the values
of vector elements in memory, starting at element ARRZ(1). As in the
previous example, the debugger symbolizes the locations of vector
elements in terms of the array elements. The location of successive
vector elements relative to ARRZ(1) is computed by adding the values
contained in registers V1 and V3 to specify a combined offset for a
particular element. The order in which vector elements are displayed is
determined by cycling through all the values in the last specified
register (V3(0:2)) for each value in the first specified register (V1).
In this example, the values of all vector elements are 0.
DBG> EXAMINE %VLR
0\%VLR: 4
DBG> EXAMINE %V1
0\%V1
(0): 0
(1): 4
(2): 8
(3): 12
DBG> EXAMINE %V3
0\%V1
(0): 0
(1): 8
(2): 16
(3): 24
DBG> EXAMINE ARRZ(1) + .%V1(0:3) + .%V3(0:2)
PROG4$MAIN\ARRZ(1): 0 ! ARRZ(1)+0+0
PROG4$MAIN\ARRZ(2): 0 ! ARRZ(1)+0+8
PROG4$MAIN\ARRZ(3): 0 ! ARRZ(1)+0+16
PROG4$MAIN\ARRZ(1)+4: 0 ! ARRZ(1)+4+0
PROG4$MAIN\ARRZ(2)+4: 0 ! ARRZ(1)+4+8
PROG4$MAIN\ARRZ(3)+4: 0 ! ARRZ(1)+4+16
PROG4$MAIN\ARRZ(2): 0 ! ARRZ(1)+8+0
PROG4$MAIN\ARRZ(3): 0 ! ARRZ(1)+8+8
PROG4$MAIN\ARRZ(4): 0 ! ARRZ(1)+8+16
PROG4$MAIN\ARRZ(2)+4: 0 ! ARRZ(1)+12+0
PROG4$MAIN\ARRZ(3)+4: 0 ! ARRZ(1)+12+8
PROG4$MAIN\ARRZ(4)+4: 0 ! ARRZ(1)+12+16
DBG>
|
16.7 Displaying the Results of Vector Floating-Point Exceptions
When a vector instruction causes a floating-point exception in a vector
element, the exception result is encoded into the corresponding element
of the destination register.
In such cases, you can use the EXAMINE/FLOAT command to display the
decoded exception message in the associated register element. This
technique enables you to identify a floating-point exception that is
still pending delivery, as shown in Section 16.8. The following
example shows that a vector instruction caused a floating
divide-by-zero exception in element 2 of register V5:
DBG> EXAMINE/FLOAT %V5
0\%V5
(0): 297.2800
(1): 87.41499
(2): Reserved operand, encoded as floating divide by zero
(3): 173.8650
DBG>
|
If the program copies values from vector registers into memory, you can
apply the EXAMINE/FLOAT command to the memory location and display the
decoded information, as you would for a vector register.
The following table identifies the decoded debugger message for each
type of vector floating-point exception:
Exception |
Debugger Message |
Floating underflow
|
Reserved operand, encoded as floating underflow
|
Floating divide by zero
|
Reserved operand, encoded as floating divide by zero
|
Floating reserved operand
|
Reserved operand, encoded as floating reserved operand
|
Floating overflow
|
Reserved operand, encoded as floating overflow
|
16.8 Controlling Scalar-Vector Synchronization
To achieve high performance, the VAX scalar and vector processors
operate concurrently as much as possible. The scalar processor passes
any vector instructions to the vector processor and then continues
executing scalar instructions while the vector processor executes
vector instructions.
In some cases, the operation of the two processors must be synchronized
to ensure correct program results. By using synchronizing instructions
such as SYNC, MSYNC, and VSYNC, the program forces certain operations
to complete before others are initiated. See the OpenVMS MACRO and
Instruction Set Reference Manual for more information about these
instructions and scalar-vector synchronization.
If the program has been vectorized by the compiler (for example, the
Compaq Fortran compiler), the necessary synchronizing instructions are
automatically generated. However, MACRO programmers need to code
synchronizing instructions explicitly.
By default, the debugger does not force scalar-vector synchronization
during program execution except for its own internal purposes. The
program executes as if it were running without debugger control, and
synchronization is controlled entirely by the program. This default
mode of operation is established by the SET VECTOR_MODE NOSYNCHRONIZED
command.
When you use the debugger in the default, nonsynchronized vector mode,
certain vector operations might be in an interrupted state when program
execution is suspended at a breakpoint, watchpoint, or at the
completion of a STEP command. For example:
- An exception caused by a vector instruction might be pending
delivery.
- An operation that transfers data between vector registers and
scalar memory might not be completed. Therefore, examining the contents
of memory or vector registers might yield unpredictable results.
To eliminate potential confusion in such cases, enter the command
SYNCHRONIZE VECTOR_MODE. It forces immediate synchronization between
the scalar and vector processors. Entering this command is equivalent
to entering a SYNC and an MSYNC instruction at the location in the
program at which execution is paused. The effect is as follows:
- Any exception that was caused by a vector instruction and was still
pending delivery is immediately delivered. Forcing the delivery of a
pending exception triggers an exception breakpoint or tracepoint (if
one was set) or invokes an exception handler (if one is available at
that location in the program).
- Any read or write operation between vector registers and either the
general registers or memory is completed immediately---that is, any
vector memory instruction that was still being executed completes
execution.
The following MACRO example shows the effect of the SYNCHRONIZE
VECTOR_MODE command:
DBG> STEP (1)
stepped to .MAIN.\SUB\%LINE 99
99: VVDIVD V1,V0,V2
DBG> STEP (2)
stepped to .MAIN.\SUB\%LINE 100
100: CLRL R0
DBG> EXAMINE/FLOAT %V2 (3)
0\%V2
[0]: 13.53400
[1]: Reserved operand, encoded as floating divide by zero
[2]: 247.2450
.
.
.
DBG> SYNCHRONIZE VECTOR_MODE (4)
%SYSTEM-F-VARITH, vector arithmetic fault, summary=00000002,
mask=00000004, PC=000002E1, PSL=03C00010
break on unhandled exception preceding .MAIN.\SUB\%LINE 100
100: CLRL R0
DBG>
|
The following comments refer to the callouts in the previous example:
- This STEP command suspends program execution
on line 99 just before a VVDIVD instruction is executed. Assume that,
in this example, the instruction will trigger a floating-point
divide-by-zero exception.
- This STEP command executes the VVDIVD
instruction. However, the exception is not delivered at this point in
the execution of the program.
- The EXAMINE/FLOAT command displays a decoded
exception message in element 1 of the destination register, V2 (see
Section 16.7). This confirms that a floating-point divide-by-zero
exception was triggered and is pending delivery.
- The SYNCHRONIZE VECTOR_MODE command forces
the immediate delivery of the pending vector exception. (You might
obtain a different set of diagnostic messages if your program were
using the VVIEF rather than vector processor hardware.)
An alternative to using the SYNCHRONIZE VECTOR_MODE command is to
operate the debugger in the synchronized vector mode by entering the
SET VECTOR_MODE SYNCHRONIZED command. This command causes the debugger
to force automatic synchronization between the scalar and vector
processors whenever a vector instruction is executed. Specifically, the
debugger issues a SYNC instruction after every vector instruction and,
in addition, an MSYNC instruction after any vector instruction that
accesses memory. This forces the completion of all activities
associated with the vector instruction that is being synchronized as
follows:
- Any exception that was caused by a vector instruction is delivered
before the next scalar instruction is executed. Forcing the delivery of
a pending exception triggers an exception breakpoint or tracepoint (if
one was set) or invokes an exception handler (if one is available at
that location in the program).
- Any read or write operation between vector registers and either the
general registers or memory is completed before the next scalar
instruction is executed.
The following example shows the effect of the SET VECTOR_MODE
SYNCHRONIZED command on the same instruction stream that was used in
the previous example:
DBG> SHOW VECTOR_MODE
Vector mode is nonsynchronized
DBG> SET VECTOR_MODE SYNCHRONIZED (1)
DBG> SHOW VECTOR_MODE
Vector mode is synchronized
DBG> STEP (2)
stepped to .MAIN.\SUB\%LINE 99
99: VVDIVD V1,V0,V2
DBG> STEP (3)
%SYSTEM-F-VARITH, vector arithmetic fault, summary=00000002,
mask=00000004, PC=000002E1, PSL=03C00010
break on unhandled exception preceding .MAIN.\SUB\%LINE 100
100: CLRL R0
DBG>
|
The following comments refer to the callouts in the previous example:
- The command SET VECTOR_MODE SYNCHRONIZED
causes the debugger to force automatic synchronization between the
scalar and vector processors whenever a vector instruction is executed.
- This STEP command suspends program execution
on line 99 just before a VVDIVD instruction is executed. Assume that,
as in the previous example, the instruction will trigger a
floating-point divide-by-zero exception.
- This STEP command executes the VVDIVD
instruction, which triggers the exception. The vector exception is
delivered immediately because the debugger is being operated in
synchronized vector mode.
In addition to SYNCHRONIZE VECTOR_MODE and SET VECTOR_MODE
SYNCHRONIZED, a few other debugger commands can affect
synchronization---for example, SET WATCH.
16.9 Calling Routines That Might Affect the Program's Vector State
The CALL command's /[NO]SAVE_VECTOR_STATE qualifiers enable you to
control whether the current state of the vector processor is saved and
then restored when a routine is called.
The state of the VAX vector processor comprises the following:
- The values of the vector registers and vector control registers
- Any vector exception (an exception caused by the execution of a
vector instruction) that might be pending delivery
When you use the CALL command to execute a routine, execution of the
routine might change the state of the vector processor as follows:
- By changing the values of vector registers or vector control
registers
- By causing a vector exception
- By causing the delivery of a vector exception that was pending when
the CALL command was entered
The CALL/SAVE_VECTOR_STATE command specifies that the state of the
vector processor that exists before the CALL command is entered be
restored by the debugger after the called routine has completed
execution. This ensures that, after the called routine has completed
execution:
- Any vector exception that was pending delivery before the CALL
command was entered is still pending delivery
- No vector exception that was triggered during the routine call is
still pending delivery
- The values of the vector registers are identical to their values
before the CALL command was entered
The CALL/NOSAVE_VECTOR_STATE command, which is the default, specifies
that the state of the vector processor that exists before the CALL
command is entered is not restored by the debugger after the called
routine has completed execution. In this case, the state of the vector
processor after the routine call depends on the effect (if any) of the
called routine.
The /[NO]SAVE_VECTOR_STATE qualifiers have no effect on the VAX general
(scalar) registers. The values of these registers are always saved and
restored when you execute a routine with the CALL command.
|