hp.com home products and services support and drivers solutions how to buy
cd-rom home
End of Jump to page title
HP OpenVMS systems
documentation

Jump to content


HP OpenVMS MACRO Compiler Porting and User's Guide

HP OpenVMS MACRO Compiler
Porting and User's Guide


Previous Contents Index


.SET_REGISTERS

This directive allows you to override the compiler's alignment assumptions, and also allows implicit reads/writes of registers to be declared.

Format

.SET_REGISTERS argument-list


Parameters

argument-list

One or more of the arguments listed in the following table. For each argument, you can specify one or more registers:
Option Description
aligned=<> Declares one or more registers to be aligned on longword boundaries.
unaligned=<> Declares one or more registers to be unaligned. Because this is an explicit declaration, this unaligned condition will not produce a fault at run time.
read=<> Declares one or more registers, which otherwise the compiler could not detect as input registers, to be read.
written=<> Declares one or more registers, which otherwise the compiler could not detect as output registers, to be written to.

Description

The aligned and unaligned qualifiers to this directive allow you to override the compiler's alignment assumptions. Using the directive for this purpose in certain cases can produce more efficient code. (See Section 4.1.)

The read and written qualifiers to this directive allow implicit reads and writes of registers to be declared. They are generally used to declare the register usage of called routines and are useful for documenting your program.

With one exception, the .SET_REGISTERS directive remains in effect (ensuring proper alignment processing) until the routine ends, unless you change the value in the register. The exception can occur under certain conditions when a flow path joins the code following a .SET_REGISTERS directive.

The following example illustrates such an exception. R2 is declared aligned, and at a subsequent label, 10$, which is before the next write access to the register, a flow path joins the code. R2 will be treated as unaligned following the label, because it is unaligned from the other path.


        INCL R2          ; R2 is now unaligned 
         . 
         . 
         . 
        BLBC R0, 10$ 
         . 
         . 
         . 
        MOVL R5, R2 
        .SET_REGISTERS ALIGNED=R2 
        MOVL R0, 4(R2) 
  10$:  MOVL 4(R2), R3   ; R2 considered unaligned    
                         ; due to BLBC branch 

The .SET_REGISTERS directive and its read and written qualifiers are required on every routine call that passes or returns data in any register from R2 through R12, if you specify the command line qualifier and option /OPTIMIZE=VAXREGS (OpenVMS Alpha only). That is because the compiler allows the use of unused VAX registers as temporary registers when you specify /OPTIMIZE=VAXREGS.


Examples

#1

DIVL R0,R1 
 
.SET_REGISTERS ALIGNED=R1 
MOVL     8(R1), R2          ; Compiler will use aligned load. 
 
      

In this example, the compiler would normally consider R1 unaligned after the division. Any memory references using R1 as a base register (until it is changed again) would use unaligned load/stores. If it is known that the actual value will always be aligned, performance could be improved by adding a .SET_REGISTERS directive, as shown.

#2

MOV1     4(R0), R1          ;Stored memory addresses assumed 
.SET_REGISTERS UNALIGNED=R1 ;aligned so explicitly set it un- 
MOVL     4(R1), R2          ;aligned to avoid run-time fault. 
      

In this example, R1 would be considered longword aligned after the MOVL. If it is actually unaligned, an alignment fault would occur on memory reference that follows at run time. To prevent this, the .SET_REGISTERS directive can be used, as shown.

#3

.SET_REGISTERS READ=<R3,R4>, WRITTEN=R5 
JSB     DO_SOMETHING_USEFUL  
      

In this example, the read/written attributes are used to explicitly declare register uses which the compiler cannot detect. R3 and R4 are input registers to the JSB target routine, and R5 is an output register. This is particularly useful if the routine containing this JSB does not use these registers itself, or if the SET_REGISTERS directive and JSB are embedded in a macro. When compiled with /FLAG=HINTS, routines which use the macro would then have R3 and R4 listed as possible input registers, even if they are not used in that routine.


.SYMBOL_ALIGNMENT

This directive associates an alignment attribute with a symbol definition for a register offset. You can use this directive when you know the alignment of the base register. This attribute guarantees to the compiler that the base register has the same alignment, which enables the compiler to generate optimal code.

Format

.SYMBOL_ALIGNMENT argument-list


Parameters

argument-list

One of the arguments listed in the following table:
Option Description
long Declares longword alignment for any symbol that you declare after this directive.
quad Declares quadword alignment for any symbol that you declare after this directive.
none Turns off the alignment specified by the preceding .SYMBOL_ALIGNMENT directive.

Description

The .SYMBOL_ALIGNMENT directive is used to associate an alignment attribute with the fields in a structure when you know the base alignment. It is used in pairs. The first .SYMBOL_ALIGNMENT directive associates either longword (long) or quadword (quad) alignment with the symbol or symbols that follow. The second directive, .SYMBOL_ALIGNMENT none, turns it off.

Any time a reference is made with a symbol with an alignment attribute, the base register of that reference, in effect, inherits the symbol's alignment. The compiler also resets the base register's alignment to longword for subsequent alignment tracking. This alignment guarantee enables the compiler to produce more efficient code sequences.


Example


OFFSET1 = 4 
.SYMBOL_ALIGNMENT LONG 
OFFSET2 = 8 
OFFSET3 = 12 
.SYMBOL_ALIGNMENT QUAD  
OFFSET4 = 16 
.SYMBOL_ALIGNMENT NONE 
OFFSET5 = 20 
    . 
    . 
    . 
CLR1 OFFSET2(R8) 
    . 
    . 
    . 
MOVL R2, OFFSET4(R6) 
 
      

For OFFSET1 and OFFSET5, the compiler will use only its tracking information for deciding if Rn in OFFSET1(Rn) is aligned or not. For the other references, the base register will be treated as longword (OFFSET2 and OFFSET3) or quadword (OFFSET4) aligned.

After each use of OFFSET2 or OFFSET4, the base register in the reference is reset to longword alignment. In this example, the alignment of R8 and R6 will be reset to longword, although the reference to OFFSET4 will use the stronger quadword alignment.


.USE_LINKAGE (OpenVMS I64 only)

Establishes a temporary named or anonymous linkage that will be used by the compiler for the next CALLS, CALLG, JSB, BSBB, or BSBW instruction processed in lexical order. This directive is used when the target of the next CALLS, CALLG, JSB, BSBB, or BSBW instruction is not a name, but a run-time value (for example, CALLS #0, (R6)). When the compiler sees the next CALLS, CALLG, JSB, BSBB, or BSBW instruction, it will use the associated linkage to decide which registers need to be saved and restored around the call. After the instruction is processed, the temporary linkage is reset to null.

Format

.USE_LINKAGE [linkage_name] [,input] [,output] [,scratch] [,preserve]


Parameters

linkage_name

The name of a linkage previously defined with the .DEFINE_LINKAGE directive. If you specify a linkage_name, you cannot specify an input, output, scratch or preserve clause.

input=<>

Register set that indicates those registers from which the routine called by the next CALLS, CALLG, JSB, BSBB, or BSBW instruction receives input values.

output=<>

Register set that indicates those registers to which the routine called by the next CALLS, CALLG, JSB, BSBB, or BSBW instruction assigns values that are returned to the routine's caller. Registers included in this register set are not saved and restored around the call.

scratch=<>

Register set that indicates registers that are used within the routine called by the next CALLS, CALLG, JSB, BSBB, or BSBW instruction. This parameter is for documentation purposes only.

preserve=<>

Register set that indicates those registers which the routine called by the next CALLS, CALLG, JSB, BSBB, or BSBW instruction will preserve. Registers included in this register set are not saved and restored around a call to the routine, since the called routine will perform that task.


Appendix C
MACRO Compiler Built-Ins

This appendix describes the built-ins provided with the MACRO Compiler for OpenVMS Systems.

On OpenVMS Alpha systems, the compiler provides two sets of built-ins:

On OpenVMS I64 systems, the compiler provides two sets of built-ins:

On OpenVMS I64 systems, all of the Alpha PALcode built-ins are emulated by means of macros provided by the system.

Both sets of built-ins are presented in tables. The second column of each table specifies the operands the built-in expects, where:

WL = write longword
ML = modify longword
AL = address of longword
WQ = write quadword
RQ = read quadword
MQ = modify quadword
AQ = address of quadword
AB = address of byte
AW = address of word
WB = write byte
WW = write word

Note

Be careful when mixing built-ins with VAX MACRO instructions on the same registers. The code generated by the compiler expects registers to contain 32-bit sign-extended values, but it is possible to create 64-bit register values that are not in this format. Subsequent longword operations on these registers could produce incorrect results.

Therefore, make sure to return registers to 32-bit sign-extended format before using them in VAX MACRO instructions as source operands. Note that loading the register with a new value using a VAX MACRO instruction (such as MOVL) returns it to this format.

C.1 Alpha Instruction Built-Ins for OpenVMS Alpha and OpenVMS I64 Systems

Ported VAX MACRO code sometimes requires access to Alpha native instructions to deal directly with a 64-bit quantity or to include an Alpha instruction that has no VAX equivalent. The compiler provides built-ins to allow you access to these instructions. On OpenVMS I64 systems, the compiler generates equivalent Itanium instructions.

The following byte and word built-ins are included in the MACRO compiler:

You use these built-ins in the same way that you use native VAX instructions, using any VAX operand mode. For example, EVAX_ADDQ 8(R0),(SP)+,R1 is legal. The only exception is that the first operand of any Alpha load/store built-in (EVAX_LD*, EVAX_ST*) must be a register.

On OpenVMS Alpha, the best environment in which to run code that contains the byte and word built-ins is on a system that implements these instructions in hardware. If you run such code on an Alpha system that implements them by software emulation, the following limitations exist:

Furthermore, if the code with these built-ins executes on a system without either the byte and word software emulator or a processor that implements the byte and word instructions in hardware, it will incur a fatal exception, such as the following:


%SYSTEM-F-OPCDEC, opcode reserved to Digital fault at 
PC=00000000000020068,PS=0000001B 

Note

Memory references in the MACRO compiler built-ins are always assumed to be quadword aligned except in EVAX_SEXTB, EVAX_SEXTW, EVAX_LDBU, EVAX_LDWU, EVAX_STB, EVAX_STW, EVAX_LDQU, and EVAX_STQU.

Table C-1 summarizes the Alpha built-ins supported by the compiler. The built-ins that are Alpha-only (cannot be used to generate or access Itanium instructions) are noted in the table.

Table C-1 Alpha Instruction Built-Ins for OpenVMS Alpha and OpenVMS I64 Systems
Built-in Operands Description Functional on OpenVMS I64?
EVAX_SEXTB <RQ,WB> Sign-extend byte Yes
EVAX_SEXTW <RQ,WW> Sign-extend word Yes
EVAX_SEXTL <RQ,WL> Sign-extend longword Yes
       
EVAX_LDBU <WQ,AB> Load zero-extended byte from memory Yes
EVAX_LDWU <WQ,AQ> Load zero-extended word from memory Yes
EVAX_LDLL <WL,AL> Load longword locked Yes
EVAX_LDAQ <WQ,AQ> Load address of quadword Yes
EVAX_LDQ <WQ,AQ> Load quadword Yes
EVAX_LDQL <WQ,AQ> Load quadword locked Yes
EVAX_LDQU <WQ,AQ> Load unaligned quadword Yes
       
EVAX_STB <RQ,AB> Store byte from register to memory Yes
EVAX_STW <RQ,AW> Store word from register to memory Yes
EVAX_STLC <ML,AL> Store longword conditional Yes
EVAX_STQ <RQ,AQ> Store quadword Yes
EVAX_STQC <MQ,AQ> Store quadword conditional Yes
EVAX_STQU <RQ,AQ> Store unaligned quadword Yes
       
EVAX_ADDQ <RQ,RQ,WQ> Quadword add Yes
EVAX_SUBQ <RQ,RQ,WQ> Quadword subtract Yes
EVAX_MULQ <RQ,RQ,WQ> Quadword multiply Yes
EVAX_UMULH <RQ,RQ,WQ> Unsigned quadword multiply high Yes
       
EVAX_AND <RQ,RQ,WQ> Logical product Yes
EVAX_OR <RQ,RQ,WQ> Logical sum Yes
EVAX_XOR <RQ,RQ,WQ> Logical difference Yes
EVAX_BIC <RQ,RQ,WQ> Bit clear Yes
EVAX_ORNOT <RQ,RQ,WQ> Logical sum with complement Yes
EVAX_EQV <RQ,RQ,WQ> Logical equivalence Yes
EVAX_SLL <RQ,RQ,WQ> Shift left logical Yes
EVAX_SRL <RQ,RQ,WQ> Shift right logical Yes
EVAX_SRA <RQ,RQ,WQ> Shift right arithmetic Yes
       
EVAX_EXTBL <RQ,RQ,WQ> Extract byte low Yes
EVAX_EXTWL <RQ,RQ,WQ> Extract word low Yes
EVAX_EXTLL <RQ,RQ,WQ> Extract longword low Yes
EVAX_EXTQL <RQ,RQ,WQ> Extract quadword low Yes
EVAX_EXTBH <RQ,RQ,WQ> Extract byte high Yes
EVAX_EXTWH <RQ,RQ,WQ> Extract word high Yes
EVAX_EXTLH <RQ,RQ,WQ> Extract longword high Yes
EVAX_EXTQH <RQ,RQ,WQ> Extract quadword high Yes
       
EVAX_INSBL <RQ,RQ,WQ> Insert byte low Yes
EVAX_INSWL <RQ,RQ,WQ> Insert word low Yes
EVAX_INSLL <RQ,RQ,WQ> Insert longword low Yes
EVAX_INSQL <RQ,RQ,WQ> Insert quadword low Yes
EVAX_INSBH <RQ,RQ,WQ> Insert byte high Yes
EVAX_INSWH <RQ,RQ,WQ> Insert word high Yes
EVAX_INSLH <RQ,RQ,WQ> Insert longword high Yes
EVAX_INSQH <RQ,RQ,WQ> Insert quadword high Yes
       
EVAX_TRAPB <> Trap barrier No
EVAX_MB <> Memory barrier Yes
EVAX_RPCC <WQ> Read process cycle counter No
       
EVAX_CMPEQ <RQ,RQ,WQ> Integer signed compare, equal Yes
EVAX_CMPLT <RQ,RQ,WQ> Integer signed compare, less than Yes
EVAX_CMPLE <RQ,RQ,WQ> Integer signed compare, less equal Yes
EVAX_CMPULT <RQ,RQ,WQ> Integer unsigned compare, less than Yes
EVAX_CMPULE <RQ,RQ,WQ> Integer unsigned compare, less equal Yes
       
EVAX_BEQ <RQ,AQ> Branch equal Yes
EVAX_BLT <RQ,AQ> Branch less than Yes
EVAX_BNE <RQ,AQ> Branch not equal Yes
       
EVAX_CMOVEQ <RQ,RQ,WQ> Conditional move/equal Yes
EVAX_CMOVNE <RQ,RQ,WQ> Conditional move/not equal Yes
EVAX_CMOVLT <RQ,RQ,WQ> Conditional move/less than Yes
EVAX_CMOVLE <RQ,RQ,WQ> Conditional move/less or equal Yes
EVAX_CMOVGT <RQ,RQ,WQ> Conditional move/greater than Yes
EVAX_CMOVGE <RQ,RQ,WQ> Conditional move/greater or equal Yes
EVAX_CMOVLBC <RQ,RQ,WQ> Conditional move/low bit clear Yes
EVAX_CMOVLBS <RQ,RQ,WQ> Conditional move/low bit set Yes
       
EVAX_MF_FPCR <WQ> Move from floating-point control register No
EVAX_MT_FPCR <WQ,RQ> Move to floating-point control register No
EVAX_ZAP <RQ,RQ,WQ> Zero bytes Yes
EVAX_ZAPNOT <RQ,RQ,WQ> Zero bytes with NOT mask Yes


Previous Next Contents Index