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