This document describes a useful subset of SPARC (version 8 or 9) instructions; it is by no means complete. Reference to the SPARC Assembly Reference Manual (available from the course web page) is also important; in particular the list of assembler pseudo-operators in Appendix A. Instruction syntax conforms to the notation used in that manual. Only actual instructions are shown here; see also the list of synthetic instructions in manual section 5.5
Many of the following instructions take a reg as first operand and either a reg or a 13 bit signed immediate value (simm13) as second operand. The value of the second operand, op2, is either the contents of the register or the sign extended value of the immediate value.
Many of these instructions have one form that doesn't affect condition codes and the other (with cc appended to it), that does. The SPARC's condition codes are:
N | (last result negative) |
Z | (last result 0) |
V | (last result overflowed in two's complement) |
C | (last result carried) |
The codes are tested by the various conditional branch instructions.
Register %g0 (%r0) behaves specially. If it is a source operand, the constant value 0 is read; if it is a destination operand, the data written is discarded.
add{cc} | reg , reg_or_immed, reg | add |
---|---|---|
sub{cc} | reg , reg_or_immed, reg | subtract |
umul{cc} | reg , reg_or_immed, reg | unsigned multiply |
smul{cc} | reg , reg_or_immed, reg | signed multiply |
udiv{cc} | reg , reg_or_immed, reg | unsigned divide |
sdiv{cc} | reg , reg_or_immed, reg | signed divide |
and{cc} | reg , reg_or_immed, reg | bitwise and |
---|---|---|
andn{cc} | reg , reg_or_immed, reg | bitwise and with NOT(op2) |
or{cc} | reg , reg_or_immed, reg | bitwise or |
orn{cc} | reg , reg_or_immed, reg | bitwise or with NOT(op2) |
xor{cc} | reg , reg_or_immed, reg | bitwise xor |
xnor{cc} | reg , reg_or_immed, reg | bitwise xor with NOT(op2) |
sll | reg , reg_or_immed, reg | shift left by op2 |
---|---|---|
srl | reg , reg_or_immed, reg | shift right by op2; zero fill |
sra | reg , reg_or_immed, reg | shift right by op2; sign extend |
Only the five low-order bits of the shift count (op2) matter.
sethi | const22, reg |
---|---|
sethi | %hi (value), reg |
Zero low-order 10 bits of reg and set high-order 22 bits to const22. The %hi pseudo-op can be used to extract and right-shift the high-order 22 bits of a literal value.
nop |
---|
No operation.
save | reg , reg_or_immed, reg | |
---|---|---|
restore | reg , reg_or_immed, reg |
Adjust register window as described in class notes. Otherwise, instructions act like add, except that source operands are read from old window, and result is written into target register in new window.
call | label |
---|
Write %pc to %o7 and perform a delayed jump to specified label. Any address in whole 32-bit space is legal.
jmpl | address, reg |
---|
Write %pc to rd and perform a delayed jump to specified address,
ba{,a} | label | branch always |
bn{,a} | label | branch never |
bne{,a} | label | branch on not equal |
be{,a} | label | branch on equal |
bg{,a} | label | branch on greater |
ble{,a} | label | branch on less or equal |
bge{,a} | label | branch on greater or equal |
bl{,a} | label | branch on less |
bgu{,a} | label | branch on greater unsigned |
bleu{,a} | label | branch on less or equal unsigned |
bcc{,a} | label | branch on carry clear (greater or equal unsigned) |
bcs{,a} | label | branch on carry set (less unsigned) |
bpos{,a} | label | branch on positive |
bneg{,a} | label | branch on negative |
bvc{,a} | label | branch on overflow clear |
bvs{,a} | label | branch on overflow set |
If condition is met (according to current condition codes), perform PC-relative, delayed branch to label, which must be expressible as . Appending ,a sets the ``annul'' bit for these instructions, which has this effect: if a conditional branch is executed and the branch is not taken, or if a ba or bn is executed, the delay slot instruction is annulled (not executed).
ldsb | [address], reg | load signed byte |
---|---|---|
ldsh | [address], reg | load signed halfword (2 bytes) |
ldub | [address], reg | load unsigned byte |
lduh | [address], reg | load unsigned halfword |
ld | [address], reg | load word (4 bytes) |
ldd | [address], reg | load double word (8 bytes) |
stb | reg , [address] | store byte |
sth | reg , [address] | store halfword |
st | reg , [address] | store word |
std | reg , [address] | store double word |
All addresses must be aligned (i.e., halfword addresses must be divisible by 2, word addresses by 4, and double-word address by 8. Unsigned loads zero-fill high-order bits; signed loads sign-extend. Register numbers for double word instructions must be even, and two registers are read/written.
This lists only the double-precision (8 byte) operations; there are also single and quad precision operations. Double-precision operators act on pairs of floating registers, specified by the (lower) even-numbered register. Loads and stores of doubles must be to 8-byte aligned memory addresses. Note that there is no way to move a value directly between integer and float registers; it must transmitted through memory.
faddd | freg , freg ,freg | add double |
---|---|---|
fsubd | freg , freg ,freg | subtract double |
fmuld | freg , freg , freg | multiply double |
fdivd | freg , freg , freg | divide double |
fmovd | freg , freg | move |
fnegd | freg , freg | negate |
fabsd | freg , freg | absolute value |
fitod | freg , freg | convert integer to double |
fdtoi | freg , freg | convert double to integer |
std | freg , [address] | store double |
ldd | [address], freg | load double |
fcmpd | freg , freg | compare double |
fba{,a} | label | branch always |
fbn{,a} | label | branch never |
fbu{,a} | label | branch on unordered |
fbg{,a} | label | branch on greater |
fbug{,a} | label | branch on unordered or greater |
fbl{,a} | label | branch on less |
fbul{,a} | label | branch on unordered or less |
fblg{,a} | label | branch on less or greater |
fbne{,a} | label | branch on not equal |
fbe{,a} | label | branch on equal |
fbue{,a} | label | branch on unordered or equal |
fbge{,a} | label | branch on greater or equal |
fbuge{,a} | label | branch on unordered or greater or equal |
fble{,a} | label | branch on less or equal |
fbule{,a} | label | branch on unordered or less or equal |
fbo{,a} | label | branch on ordered |
Floating point comparisons are made explicitly using fcmpd, which sets the floating point condition codes; the results are then tested by the floating conditional branchs. A comparison returns ``unordered'' if one or both operands is NaN (``not a number''). The annul bit operates the same way as for integer branches.