On OpenVMS Alpha systems, the compiler provides two sets of
built-ins:
o Alpha instruction built-ins that are used to access Alpha
instructions for which there are no VAX equivalents.
o Alpha PALcode built-ins that are used to emulate the VAX
instructions for which there are no Alpha equivalents and to
perform other functions such as quadword queue manipulations.
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.
1 – Alpha Instruction Built-Ins
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.
The following byte and word built-ins are included in the MACRO
compiler:
o EVAX_LDBU
o EVAX_LDWU
o EVAX_STB
o EVAX_STW
o EVAX_SEXTB
o EVAX_SEXTW
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:
o Significant performance loss
The overhead of handling the exception to trigger the software
emulation causes a significant performance loss. If software
emulation is in effect, you will see this message:
%SYSTEM-I-EMULATED,
an instruction not implemented on this processor was emulated
o Some capabilities not present in the software emulation
The software emulation is not capable of providing all
the capabilities that would be present on a system that
implemented the the instructions in hardware. Code that
executes in inner access modes and at elevated IPL is allowed
to use these instructions. For example, activation of the
software emulator above IPL 2 will not cause a bug check.
However, certain applications where these instructions
might be useful, such as direct writes to hardware control
registers, will be impossible, because such applications
require the presence of address lines whose function cannot
be emulated.
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.
The following table 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.
Functional on
Built-in Operands Description 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 Yes
byte from memory
EVAX_LDWU <WQ,AQ> Load zero-extended Yes
word from memory
EVAX_LDLL <WL,AL> Load longword locked Yes
EVAX_LDAQ <WQ,AQ> Load address of Yes
quadword
EVAX_LDQ <WQ,AQ> Load quadword Yes
EVAX_LDQL <WQ,AQ> Load quadword locked Yes
EVAX_LDQU <WQ,AQ> Load unaligned Yes
quadword
EVAX_STB <RQ,AB> Store byte from Yes
register to memory
EVAX_STW <RQ,AW> Store word from Yes
register to memory
EVAX_STLC <ML,AL> Store longword Yes
conditional
EVAX_STQ <RQ,AQ> Store quadword Yes
EVAX_STQC <MQ,AQ> Store quadword Yes
conditional
EVAX_STQU <RQ,AQ> Store unaligned Yes
quadword
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 Yes
multiply high
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 Yes
complement
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 Yes
arithmetic
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 No
counter
EVAX_CMPEQ <RQ,RQ,WQ> Integer signed Yes
compare, equal
EVAX_CMPLT <RQ,RQ,WQ> Integer signed Yes
compare, less than
EVAX_CMPLE <RQ,RQ,WQ> Integer signed Yes
compare, less equal
EVAX_CMPULT <RQ,RQ,WQ> Integer unsigned Yes
compare, less than
EVAX_CMPULE <RQ,RQ,WQ> Integer unsigned Yes
compare, less equal
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 Yes
move/equal
EVAX_CMOVNE <RQ,RQ,WQ> Conditional move/not Yes
equal
EVAX_CMOVLT <RQ,RQ,WQ> Conditional move/less Yes
than
EVAX_CMOVLE <RQ,RQ,WQ> Conditional move/less Yes
or equal
EVAX_CMOVGT <RQ,RQ,WQ> Conditional Yes
move/greater than
EVAX_CMOVGE <RQ,RQ,WQ> Conditional Yes
move/greater or equal
EVAX_CMOVLBC <RQ,RQ,WQ> Conditional move/low Yes
bit clear
EVAX_CMOVLBS <RQ,RQ,WQ> Conditional move/low Yes
bit set
EVAX_MF_FPCR <WQ> Move from floating- No
point control
register
EVAX_MT_FPCR <WQ,RQ> Move to floating- No
point control
register
EVAX_ZAP <RQ,RQ,WQ> Zero bytes Yes
EVAX_ZAPNOT <RQ,RQ,WQ> Zero bytes with NOT Yes
mask
2 – Alpha PALcode Built-Ins
Alpha PALcode built-ins, primarily for privileged code, are used
in the same way that Alpha instruction built-ins are used with
two exceptions:
o For the queue PAL functions, the compiler does not move the
input arguments to the Alpha registers before issuing the PAL
call as it does for all other functions. Therefore, you must
supply the code to do that.
o When using a built-in for a PAL call that returns a value, the
source code must explicitly read R0 for the return value.
Certain Alpha PALcode built-ins, EVAX_INSQHIQR, EVAX_INSQTIQR,
EVAX_REMQHIQR, and EVAX_REMQHITR, support the manipulation of
quadword queues, a function that VAX MACRO does not support. If
you use these built-ins, you must supply the code to move the
input arguments to R16 (and R17, for EVAX_INSQxxxx), as shown in
the following example:
MOVAB Q_header, R16 ; Set up address of queue header for PAL call
EVAX_REMQHIQR ; Remove quadword queue entry
EVAX_STQ R0, entry ; Save entry address returned in R0
The Alpha PALcode built-ins are listed in the following table.
NOTE
You can use the .DEFINE_PAL compiler directive to custom-
define a built-in for an Alpha PALcode operation that is not
listed in this table.
Built-in Operands Description
EVAX_CFLUSH <RQ> Cache flush
EVAX_DRAINA <> Drain aborts
EVAX_LDQP <AQ> Load quadword physical
EVAX_STQP <AQ,RQ> Store quadword physical
EVAX_SWPCTX <AQ> Swap privileged context
EVAX_BUGCHK <RQ> Bugcheck
EVAX_CHMS <> Change mode supervisor
EVAX_CHMU <> Change mode user
EVAX_IMB <> Instruction memory barrier
EVAX_SWASTEN <RQ> Swap AST enable
EVAX_WR_PS_SW <RQ> Write processor status software field
EVAX_MTPR_ASTEN <RQ> Move to processor register ASTEN
EVAX_MTPR_ASTSR <RQ> Move to processor register ASTSR
EVAX_MTPR_AT <RQ> Move to processor register AT
EVAX_MTPR_FEN <RQ> Move to processor register FEN
EVAX_MTPR_IPIR <RQ> Move to processor register IPIR
EVAX_MTPR_IPL <RQ> Move to processor register IPL
EVAX_MTPR_PRBR <RQ> Move to processor register PRBR
EVAX_MTPR_SCBB <RQ> Move to processor register SCBB
EVAX_MTPR_SIRR <RQ> Move to processor register SIRR
EVAX_MTPR_TBIA <> Move to processor register TBIA
EVAX_MTPR_TBIAP <> Move to processor register TBIAP
EVAX_MTPR_TBIS <AQ> Move to processor register TBIS
EVAX_MTPR_TBISD <AQ> Move to processor register, TB
invalidate single DATA
EVAX_MTPR_TBISI <AQ> Move to processor register, TB
invalidate single ISTREAM
EVAX_MTPR_ESP <AQ> Move to processor register ESP
EVAX_MTPR_SSP <AQ> Move to processor register SSP
EVAX_MTPR_USP <AQ> Move to processor register USP
EVAX_MFPR_ASN <> Move from processor register ASN
EVAX_MFPR_AT <> Move from processor register AT
EVAX_MFPR_FEN <> Move from processor register FEN
EVAX_MFPR_IPL <> Move from processor register IPL
EVAX_MFPR_MCES <> Move from processor register MCES
EVAX_MFPR_PCBB <> Move from processor register PCBB
EVAX_MFPR_PRBR <> Move from processor register PRBR
EVAX_MFPR_PTBR <> Move from processor register PTBR
EVAX_MFPR_SCBB <> Move from processor register SCBB
EVAX_MFPR_SISR <> Move from processor register SISR
EVAX_MFPR_TBCHK <AQ> Move from processor register TBCHK
EVAX_MFPR_ESP <> Move from processor register ESP
EVAX_MFPR_SSP <> Move from processor register SSP
EVAX_MFPR_USP <> Move from processor register USP
EVAX_MFPR_WHAMI <> Move from processor register WHAMI
EVAX_INSQHILR <> Insert entry into longword queue at
head interlocked-resident
EVAX_INSQTILR <> Insert entry into longword queue at
tail interlocked-resident
EVAX_INSQHIQR <> Insert entry into quadword queue at
head interlocked-resident
EVAX_INSQTIQR <> Insert entry into quadword queue at
tail interlocked-resident
EVAX_REMQHILR <> Remove entry from longword queue at
head interlocked-resident
EVAX_REMQTILR <> Remove entry from longword queue at
tail interlocked-resident
EVAX_REMQHIQR <> Remove entry from quadword queue at
head interlocked-resident
EVAX_REMQTIQR <> Remove entry from quadword queue at
tail interlocked-resident
EVAX_GENTRAP <> Generate trap exception
EVAX_READ_UNQ <> Read unique context
EVAX_WRITE_UNQ <RQ> Write unique context