Mark Smotherman. Last updated September 2002.
The Alpha is a 64-bit RISC architecture introduced in 1992. There are three calling standards: Tru64 (Digital) UNIX, OpenVMS, and Windows NT.
(JA: Compare and contrast Alpha PALs with Subroutines; rationale, function, capabilities and implementation of)
v0 ($0) - return value from integer functions
t0-t7 ($1-$8) - temporaries
s0-s5 ($9-$14) - callee saved
fp ($15) - frame pointer
a0-a5 ($16-$21) - integer arguments
t8-t11 ($22-$25) - temporaries
ra ($26) - return address
pv ($27) - address of current procedure
at ($28) - reserved for assembler
GP ($29) - global pointer
SP ($30) - stack pointer
zero ($31) - constant 0 (hardware)
Note that there are differences among the conventions, e.g., in OpenVMS
the frame pointer is $29 instead of $15 and the parameter count is placed
in $25.
bsr register,target - register <- return address; PC <- target
jsr register,($PV) - register <- return address; PC <- PV
ret (register) - PC <- register
br and bsr are identical operations with regards to the register set and
PC; they differ in hints to the branch prediction hardware. Also, jmp,
jsr, ret, and jsr_couroutine are also identical operations with different
branch hint semantics. Alpha assemblers use $26 as the default return
address register if one is not specified.
...
... place parameters in $a0-$a5 ...
ldq $PV,target
jsr $RA,($PV)
...
subr:
ldah GP, off_hi($27) # Compute the correct GP value.
lda GP, off_lo(GP)
lda SP,-SIZE(SP) # Allocate space for a new stack frame.
stq $26,16(SP) # Save the return address.
stq $9,24(SP) # Save the first integer register.
stq $10,32(SP) # Save the next integer register.
stq $11,40(SP) # Save the next integer register.
stt $f2,48(SP) # Save the first floating-point register.
stt $f3,56(SP) # Save the last floating-point register.
trapb # Force any pending hardware exceptions
# to be raised.
... body of subroutine ...
mov $11,GP # Restore this routine's GP value.
ldq $26,16(SP) # Get the return address.
ldq $9,24(SP) # Restore the first integer register.
ldq $10,32(SP) # Restore the next integer register.
ldq $11,40(SP) # Restore the next integer register.
ldt $f2,48(SP) # Restore the first floating-point register.
ldt $f3,56(SP) # Restore the last floating-point register.
trapb # Force any pending hardware exceptions to be
# raised.
lda SP,SIZE(SP) # Restore the SP.
ret $31,($26),0001 # Return to the caller with the usage hint.
(example taken from the Tru64 manual, see below; optimizations of prolog
and epilog code are also discussed there)
[History of subroutines page] [Mark's homepage] [CPSC homepage] [Clemson Univ. homepage]
mark@cs.clemson.edu