Document revision date: 19 July 1999
[Compaq] [Go to the documentation home page] [How to order documentation] [Help on this site] [How to contact us]
[OpenVMS documentation]

Porting VAX MACRO Code to OpenVMS Alpha


Previous Contents Index

2.13 Debugging

The compiler provides full debugger support. The debug session for compiled VAX MACRO code is similar to that for assembled VAX MACRO code. However, there are some important differences that are described in this section. For a complete description of debugging, see the OpenVMS Debugger Manual.

2.13.1 Code Relocation

One major difference is that the code is compiled rather than assembled. On a VAX system, each VAX MACRO instruction is a single machine instruction. On an Alpha system, each VAX MACRO instruction may be compiled into many Alpha machine instructions. A major side effect of this difference is the relocation and rescheduling of code if you do not specify /NOOPTIMIZE in your compile command.

By default, several optimizations are performed that cause the movement of generated code across source boundaries (see Section 1.2, Section 4.3, and Appendix A). For most code modules, debugging is simplified if you compile with /NOOPTIMIZE, which prevents this relocation from happening. After you have debugged your code, you can recompile without /NOOPTIMIZE to improve performance.

2.13.2 Symbolic Variables for Routine Arguments

Another major difference between debugging compiled code and debugging assembled code is a new concept to VAX MACRO, the definition of symbolic variables for examining routine arguments. On VAX systems, when you are debugging a routine and want to examine the arguments, you typically do something like the following:


        DBG> EXAMINE @AP        ; to see the argument count 
        DBG> EXAMINE @AP+4      ; to examine the first arg 

or


        DBG> EXAMINE @AP        ; to see arg count 
        DBG> EXAMINE .+4:.+20   ; to see first 5 args 

On Alpha systems, the arguments do not reside in a vector in memory as they do on VAX systems. Furthermore, there is no AP register on Alpha systems. If you type EXAMINE @AP when debugging VAX MACRO compiled code, the debugger reports that AP is an undefined symbol.

In the compiled code, the arguments can reside in some combination of:

The compiler does not require that you figure out where the arguments are by reading the generated code. Instead, it provides $ARGn symbols that point to the correct argument locations. The $ARG0 symbol is the same as @AP+0 is on VAX systems, that is, the argument count. The $ARG1 symbol is the first argument, $ARG2 is the second argument, and so forth. These symbols are defined in CALL_ENTRY and JSB_ENTRY directives, but not in EXCEPTION_ENTRY directives.

2.13.3 Locating Arguments Without $ARGn Symbols

There may be additional arguments in your code for which the compiler did not generate a $ARGn symbol. The number of $ARGn symbols defined for a .CALL_ENTRY routine is the maximum number detected by the compiler (either by automatic detection or as specified by MAX_ARGS) or 16, whichever is less. For a .JSB_ENTRY routine, since the arguments are homed in the caller's stack frame and the compiler cannot detect the actual number, it always creates eight $ARGn symbols.

In most cases, you can easily find any additional arguments, but in some cases you cannot.

2.13.3.1 Additional Arguments That Are Easy to Locate

You can easily find additional arguments if:

For example, you can examine arguments beyond the eighth argument in a JSB routine (where the argument list must be homed in the caller), as follows:


  DBG> EX $ARG8  ; highest defined $ARGn
  . 
  . 
  . 
  DBG> EX .+4  ; next arg is in next longword 
  . 
  . 
  . 
  DBG> EX .+4  ; and so on 
 

This example assumes that the caller detected at least 10 arguments when homing the argument list.

To find arguments beyond the last $ARGn symbol in a routine that did not home the arguments, proceed exactly as in the previous example except substitute EX .+8 for EX .+4.

2.13.3.2 Additional Arguments That Are Not Easy to Locate

You cannot easily find additional arguments if:

The only way to find the additional arguments in these cases is to examine the compiled machine code to determine where the arguments reside. Both of these problems are eliminated if MAX_ARGS is specified correctly for the maximum argument that you want to examine.

2.13.4 Debugging Code with Packed Decimal Data

The following list provides important information about debugging compiled VAX MACRO code with packed decimal data on an Alpha system:

  1. When using the EXAMINE command to examine a location that was declared with a .PACKED directive, the debugger automatically displays the value as a packed decimal data type.
  2. You can deposit packed decimal data. The syntax is the same as it is on VAX.

2.13.5 Debugging Code with Floating-Point Data

The following list provides important information about debugging compiled VAX MACRO code with floating-point data on an Alpha system:

  1. You can use the EXAMINE/FLOAT command to examine an Alpha integer register for a floating-point value.
    Even though there is a set of registers for floating-point operations on Alpha systems, those registers are not used by compiled VAX MACRO code that contains floating-point operations. Only the Alpha integer registers are used.
    Floating-point operations in compiled VAX MACRO code are performed by emulation routines that operate outside the compiler. Therefore, performing VAX MACRO floating-point operations on, say, R7, has no effect on Alpha floating-point Register 7.
  2. When using the EXAMINE command to examine a location that was declared with a .FLOAT directive or other floating-point storage directives, the debugger automatically displays the value as floating-point data.
  3. When using the EXAMINE command to examine the G_FLOAT data type, the debugger does not use the contents of two registers to build the value for VAX data.
    Consider the following example:


    EXAMINE/G_FLOAT   R4 
    

    In this example, the lower longwords of R4 and R5 are not used to build the value as is the case on VAX. Instead, the quadword contents of R4 are used.
    The code the compiler generates for D_FLOAT and G_FLOAT operations preserves the VAX format of the data in the low longwords of two consecutive registers. Therefore, using EXAMINE/G_FLOAT on either of these two registers will not give the true floating-point value, and issuing DEPOSIT/G_FLOAT to one of these registers will not give the desired results. You can manually combine the two halves of such a value, however. For example, assume you executed the following instruction:


    MOVG    DATA, R6 
    

    You could then read the G_FLOAT value which now resides in R6 and R7 with a sequence like the following:


    DBG> EX R6 
    .MAIN.\%LINE 100\%R6:   0FFFFFFFF D8E640D1 
    DBG> EX R7 
    .MAIN.\%LINE 100\%R7:   00000000 2F1B24DD 
    DBG> DEP R0 = 2F1B24DDD8E640D1 
    DBG> EX/G_FLOAT R0 
    .MAIN.\%LINE 100\%R0:   4568.89900000000 
    

  4. You can deposit floating-point data in an Alpha integer register with the DEPOSIT command. The syntax is the same as it is on a VAX system.
  5. H_FLOAT is unsupported.


Chapter 3
Recommended and Required Source Changes

This chapter describes the coding constructs you should examine when porting VAX MACRO code to OpenVMS Alpha. The occurrence of any of these in a module can make porting take longer than it would otherwise. Although the compiler can identify many of these practices and flag them with diagnostic messages, recognizing them yourself will speed up the porting effort.

In most cases, it will be necessary to change your source code. The exceptions are noted.

The coding constructs described in this chapter are:

3.1 Stack Usage

The OpenVMS calling standard defines a stack frame format for Alpha systems substantially different from that defined for VAX systems. If your code relies on the format of the VAX stack frame you will need to change it when porting it to an Alpha system.

3.1.1 References to the Procedure Stack Frame

The compiler disallows references to positive stack offsets from FP, and flags them as errors. A single exception to this rule is the practice whereby VAX MACRO code establishes a dynamic condition handler by moving a routine address to the stack location pointed to by FP. The compiler detects this and generates the appropriate Alpha code for establishing such a handler. However, if the write to 0(FP) occurs inside a JSB routine, the compiler will flag it as an error. The compiler allows negative FP offsets, as used for referring to stack storage allocated at procedure entry.

Recommended Change

If possible, remove stack frame references entirely, rather than converting to the Alpha format. For example, if the offending code was attempting to change saved register values, store the new value in a stack temporary and set the register value on routine exit (removing the register from the entry register mask).

3.1.2 References Outside the Current Stack Frame

By monitoring stack depth throughout a VAX MACRO module, the compiler detects references in a routine to data pushed on the stack by its caller and flags them as errors.

Recommended Change

You must eliminate references in a routine to data pushed on the stack by its caller. Instead, pass the required data as parameters or pass a pointer to the stack base from which the data can be read.

3.1.3 Nonaligned Stack References

At routine calls, the compiler octaword-aligns the stack, if the stack is not already octaword-aligned. Some code, when building structures on the stack, makes unaligned stack references or causes the stack pointer to become unaligned. The compiler flags both of these with information-level messages.

Recommended Change

Provide sufficient padding in data elements or structures pushed onto the stack, or change data structure sizes. Because unaligned stack references also have an impact on VAX performance, you should apply these fixes to code designed for both the VAX and Alpha architectures.

3.1.4 Building Data Structures on the Stack

A common coding practice is to produce a structure on the stack by pushing the elements and relying on auto decrement to move the stack pointer to allocate space. The problems with this technique follow:

Recommended Change

To correct the first problem and detect the second, use the coding technique illustrated in this example. Consider the following code example:


; Build a descriptor on the stack. 
; 
MOVW    length, -(SP) 
MOVB    type,   -(SP) 
MOVB    class,  -(SP) 
MOVAL   buffer, -(SP) 
Replace this code with the following:


SUBL2   DSC$S_DSCDEF, SP  ; pre-allocate space on stack 
MOVW    length, DSC$W_LENGTH(SP) 
MOVB    type,   DSC$B_DTYPE(SP) 
MOVB    size,   DSC$B_CLASS(SP) 
MOVAL   buffer, DSC$A_POINTER(SP) 

3.1.5 Quadword Moves Into the VAX SP and PC

Due to architectural differences between VAX and Alpha computers, it is not possible to completely emulate quadword moves into the VAX stack pointer (SP) and the program counter (PC) without programmer intervention. The VAX architecture defines R14 as the SP and R15 as the PC. A MOVQ instruction with SP as the target would simultaneously load the VAX SP and PC, as shown in the following example:


MOVQ    R0,SP   ; Contents of R0 to SP, R1 to PC 
 
MOVQ    REGDATA, SP   ; REGDATA to SP 
                      ; REGDATA+4 to PC 

If the compiler encounters a MOVQ instruction with SP as the destination, it generates a sign-extended longword load from the supplied source into R30 (the Alpha stack pointer) and issues the following informational message:


%AMAC-I-CODGENINF, (1) Longword update of Alpha SP, PC untouched 

Recommended Change

If the intended use of the MOVQ instruction was to achieve the VAX behavior, a MOVL instruction should be used, followed by a branch to the intended address, as shown next:


MOVL    REGDATA, SP   ; Load the SP 
JMP     @REGDATA+4    ; And branch 

If the intended use of the MOVQ instruction was to load the stack pointer with an 8 byte value, the EVAX_LDQ built-in should be used instead, as shown next:


EVAX_LDQ        SP, REGDATA 

3.2 Instruction Stream

The following VAX MACRO coding practices and VAX instructions either do not work on OpenVMS Alpha or they can produce unexpected results.

3.2.1 Data Embedded in the Instruction Stream

The compiler detects data embedded in the instruction stream, and reports it as an error.

Data in the instruction stream often takes the form of a JSB instruction followed by a .LONG. This construct allows VAX MACRO code to implicitly pass a parameter to a JSB routine which locates the data by using the return address on the stack. Another occasional use of data in the code stream is to make the data contiguous with the code in memory, so that it can be relocated as a unit.

Recommended Change

For implicit JSB parameters, pass the parameter value in a register. For values larger than a longword, put the data in another program section (psect) and explicitly pass its address.

Because static data must reside in a separate data psect, any code that tries to relocate code and data together must be rewritten.

3.2.2 Run-Time Code Generation

The compiler detects branches to stack locations and to static data areas and flags them as errors.

Recommended Change

You must either remove or modify code that builds instructions for later execution, branches to stack locations, or branches to static data areas. If the code is absolutely necessary, you should conditionalize it for VAX, and generate corresponding, suitable Alpha code.

3.2.3 Dependencies on Instruction Size

Code that computes branch offsets based on instruction lengths, for example, must be changed.

Recommended Change

Use a label and standard branch or a CASE instruction for computed GOTOs.

3.2.4 Incomplete Instructions

Some CASE instructions in OpenVMS VAX code are not followed by offset tables, but instead depend on psect placement by the linker to complete the instruction. The compiler will flag the incomplete instruction as an error.

Recommended Change

Complete the instruction in the module or build a table of addresses in a data psect, and replace the CASE instruction with code to select a destination address from the table and branch.

3.2.5 Untranslatable VAX Instructions

Because the compiler cannot translate the following VAX instructions, it flags them as errors:

Recommended Change

These instructions usually appear in code that is highly dependent on the VAX architecture. You will need to rewrite such code to port it to Alpha systems.

3.2.6 References to Internal Processor Registers

Pay special attention to the following instructions:

Recommended Change

Verify that they reference valid Alpha internal processor registers (IPRs). If they do not, they will be flagged. For more information about the Alpha internal processor registers, refer to the Alpha Architecture Reference Manual.

3.2.7 Use of Z and N Condition Codes with the BICPSW Instruction

The BICPSW instruction is supported, but the Z and N condition codes cannot be set at the same time. Setting the Z condition code will clear the N condition code and vice versa.

Recommended Change

If you find that your code sets both condition codes at the same time, modify the code.

3.3 Flow Control Mechanisms

Certain flow control mechanisms used with VAX MACRO do not produce the desired results on Alpha systems. Therefore, some changes to your code are either recommended or required.

Included in this category are several frequently used variations of modifying the return address on the stack, from within a JSB routine, to change the flow of control. All must be recoded.

3.3.1 Communication by Condition Codes

The compiler detects a JSB instruction followed immediately by a conditional branch, or a conditional branch as the first instruction in a routine, and generates an error message.

Recommended Change

Return a status value or a flag parameter to take the place of implicit communication by means of condition codes.

For example:


BSBW    GET_CHAR 
BNEQ    ERROR           ; Or BEQL, or BLSS or BGTR, etc 

can be replaced with:


BSBW    GET_CHAR 
BLBC    R0, ERROR       ; Or BLBS 

If you are already using R0, you must push it onto the stack and restore it later when you have handled the error.


Previous Next Contents Index

  [Go to the documentation home page] [How to order documentation] [Help on this site] [How to contact us]  
  privacy and legal statement  
5601PRO_005.HTML