The assembly-language instructions described in this book are a superset of the actual machine-code instructions. Generally, the assembly-language instructions match the machine-code instructions; however, in some cases the assembly-language instructions are macros that generate more than one machine-code instruction (the division instructions in assembly language are examples). This appendix describes the assembly-language instructions that generate more than one machine-code instruction.
You can, in most instances, consider the assembly-language instructions as machine-code instructions; however, for routines that require tight coding for performance reasons, you must be aware of the assembly-language instructions that generate more than one machine-code instruction.
Register
$28
($at
)
is reserved as a temporary register for use by the assembler.
Some assembly-language instructions require additional temporary
registers. For these instructions, the assembler uses one or more of
the general-purpose temporary registers
(t0
-
t12
).
The following table lists the instructions
that require additional temporary registers and the specific registers
that they use:
Instruction | Registers Used |
ldb
|
AT,t9
|
ldbu
|
AT,t9
|
ldw
|
AT,t9
|
ldwu
|
AT,t9
|
stb
|
AT,t9,t10
|
stw
|
AT,t9,t10
|
ustw
|
AT,t9,t10,t11,t12
|
ustl
|
AT,t9,t10,t11,t12
|
ustq
|
AT,t9,t10,t11,t12
|
uldw
|
AT,t9,t10
|
uldwu
|
AT,t9,t10
|
uldl
|
AT,t9,t10
|
uldq
|
AT,t9,t10
|
divl
|
AT,t9,t10,t11,t12
|
divq
|
AT,t9,t10,t11,t12
|
divlu
|
AT,t9,t10,t11,t12
|
divqu
|
AT,t9,t10,t11,t12
|
reml
|
AT,t9,t10,t11,t12
|
remq
|
AT,t9,t10,t11,t12
|
remlu
|
AT,t9,t10,t11,t12
|
remqu
|
AT,t9,t10,t11,t12
|
Table Notes:
.arch
directive
or the
-arch
flag on the
cc
command line.
The registers that equate to the software names (from
regdef.h
)
in the preceding table are as follows:
Software | Register |
Name | |
AT
|
$28
or
$at
|
t9
|
$23
|
t10
|
$24
|
t11
|
$25
|
t12
or
pv
|
$27
|
Note
The
div
andrem
instructions destroy the contents oft12
only if the third operand is a register other thant12
. See Section C.5 for more details.
If you use an address as an operand and it references a data item
that does not have an absolute address in the range -32768 to 32767,
the assembler may generate a machine-code instruction to load the
address of the data (from the literal address section) into
$at
.
The assembler's
ldgp
(load global pointer) instruction generates an
lda
and
ldah
instruction. The assembler requires the
ldgp
instruction because
ldgp
couples relocation information with the instruction.
If you use an immediate value as an operand and the immediate value
falls outside the range -32768 to 32767 for the
ldil
and
ldiq
instructions or the range 0 - 255 for other instructions, multiple
machine instructions are generated to load the immediate value into
the destination register or
$at
.
On most processors that implement the Alpha architecture, loading and storing unaligned data or data less than 32 bits is done with multiple machine-code instructions. Except on EV56 Alpha processors, the following assembler instructions generate multiple machine-code instructions:
ldb
)
ldbu
)
ldw
)
ldwu
)
uldw
)
uldwu
)
uldl
)
uldq
)
stb
)
stw
)
ustw
)
ustl
)
ustq
)
Signed loads may require one more instruction than an unsigned load.
On EV56 Alpha processors, the following instructions from the preceding list generate a single instruction:
ldbu
)
ldwu
)
stb
)
stw
)
Multiply operations using constant powers of two are turned into
sll
or scaled add instructions.
There are no machine instructions for performing integer division
(divl
,
divlu
,
divq
,
and
divqu
)
or remainder operations
(reml
,
remlu
,
remq
,
and
remqu
).
The machine instructions generated for these assembler
instructions depend on the operands specified on the instructions.
Division and remainder operations involving constant values are replaced by an instruction sequence that depends on the data type of the numerator and the value of the constant.
Division and remainder operations involving nonconstant values are
replaced with a procedure call to a library routine to perform
the operation. The library routines are in the C run-time library
(libc
).
The library routines use a nonstandard parameter
passing mechanism. The first operand is passed in register
t10
and the second operand is passed in
t11
.
The result is returned in
t12
.
If the operands specified are other than those just described, the
assembler moves them to the correct registers. The library routines
expect the return address in
t9
;
therefore, a routine that uses divide instructions does not need to
save register
ra
just because it uses divide instructions.
The
absl
and
absq
(absolute value) instructions generate two machine instructions.
There are no floating-point instructions that accept an immediate value (except for 0.0). Whenever the assembler encounters a floating-point load immediate instruction, the immediate value is stored in the data section and a load instruction is generated to load the value.
Some assembler instructions generate single machine instructions. Such assembler instructions are sometimes referred to as pseudo-instructions. The following table lists these assembler instructions and their equivalent machine instructions:
Assembler Instruction | Machine Instruction | ||
andnot
|
$rx,$ry,$rz
|
bic
|
$rx,$ry,$rz
|
clr
|
$rx
|
bis
|
$31,$31,$rx
|
fabs
|
$fx,$fy
|
cpys
|
$f31,$fx,$fy
|
fclr
|
$fx
|
cpys
|
$f31,$f31,$fx
|
fmov
|
$fx,$fy
|
cpys
|
$fx,$fx,$fy
|
fneg
|
$fx,$fy
|
cpysn
|
$fx,$fx,$fy
|
fnop
|
|
cpys
|
$f31,$f31,$f31
|
mov
|
$rx,$ry
|
bis
|
$rx,$rx,$ry
|
mov
|
|
bis
|
|
negf
|
$fx,$fy
|
subf
|
$f31,$fx,$fy
|
negfs
|
$fx,$fy
|
subfs
|
$f31,$fx,$fy
|
negg
|
$fx,$fy
|
subg
|
$f31,$fx,$fy
|
neggs
|
$fx,$fy
|
subgs
|
$f31,$fx,$fy
|
negl
|
$rx,$ry
|
subl
|
$31,$rx,$ry
|
neglv
|
$rx,$ry
|
sublv
|
$31,$rx,$ry
|
negq
|
$rx,$ry
|
subq
|
$31,$rx,$ry
|
negqv
|
$rx,$ry
|
subqv
|
$31,$rx,$ry
|
negs
|
$fx,$fy
|
subs
|
$f31,$fx,$fy
|
negssu
|
$fx,$fy
|
subssu
|
$f31,$fx,$fy
|
negt
|
$fx,$fy
|
subt
|
$f31,$fx,$fy
|
negtsu
|
$fx,$fy
|
subtsu
|
$f31,$fx,$fy
|
nop
|
|
bis
|
$31,$31,$31
|
not
|
$rx,$ry
|
ornot
|
$31,$rx,$ry
|
or
|
$rx,$ry,$rz
|
bis
|
$rx,$ry,$rz
|
sextl
|
$rx,$ry
|
addl
|
$rx,0,$ry
|
unop
|
|
ldq_u
|
$31,0($sp)
|
xornot
|
$rx,$ry,$rz
|
eqv
|
$rx,$ry,$rz
|