The LANai3 assember is `gas', the Gnu assembler from the Free Software Foundation. For most details about the assembler, see the `gas' documentation which comes with the assembler in the following formats: Gnu `info', Adobe PostScript, and plain text. The `gas' documentation is also available via the world wide web at `http://www.ns.utk.edu/gnu/gnu.html'
Registers 0 to 31 are referred to, respectively, as %r0 to
%r31. Other recognized names are %ps (%r3),
%sp (%r4), %fp (%r5), %rv
(%r8), %rca (%r15), %aps (%r28),
%apc (%r29), %imr (%r30), and %isr
(%r31). They stand for, respectively, "process
status word," "stack pointer," "frame
pointer," "rreturn value," "register
for constant addresses," "alternate
process status word," "alternate program
counter," "interrupt status register,"
and "interrupt mask register."
To prevent label-name-space polution, labels generated by the C compiler
start with `_' if they correspond to a user variable or
`L' if they correspond to a compiler-generated label.
The LANai3 is a pipelined processor. Assembly programmers should understand the material in the sections section Pipeline Operation, section Registers, and section Instruction Interpretation before attempting to program this processor.
Instructions modify the flags in the ps register under the
following circumstances:
ps is explicitly named in an instruction as a destination register.
.f' in the
instruction.
If both (1) and (2) hold for an instruction, the updates occur sequentially: First the
destination value is written to ps, and then the flag values in ps
are updated to reflect the value written to ps.
@cindex op2 The following operand types may appear in assembly instructions:
add, addc, sub, subc, and,
or, xor, sha"
add, addc, sub, subc, and,
or, xor, sh, sha"
pc) or 31 (isr).
pc) or 31 (isr).
Negative constants may be written with a `-' sign or as a 32-bit constant, which will be truncated appropriately. For example, `-4' and `0xFFFFFFFC' are valid shift_consts.
In this section:
pc <- pc + 4 .
Instruction Machine Instruction
-------------------------------------------------------------------
add<.f> SRC1, CONST, RDEST RI
RDEST <- SRC1 + CONST
NOTES: (1),(4)
add<.f> SRC1, SRC2, RDEST RR
RDEST <- SRC1 + SRC2
NOTES: (1),(4)
addc<.f> SRC1, SRC2, RDEST RI
RDEST <- SRC1 + SRC2 + C
NOTES: (1),(4) C is the carry flag from %ps
addc<.f> SRC1, CONST, RDEST RR
RDEST <- SRC1 + CONST + C
NOTES: (1),(4) C is the carry flag from %ps
and<.f> SRC1, AND_CONST, RDEST RI
RDEST <- SRC1 & AND_CONST
NOTES: (1),(4)
and<.f> SRC1, SRC2, RDEST RR
RDEST <- SRC1 & SRC2
NOTES: (1),(4)
b?? BRABS BR
if ( ?? condition is true )
then %pc <- BRABS
NOTES: (6)
b?? SRC3 SBR
if ( ?? condition is true )
then %pc <- SRC3
NOTES: (6)
b??.r BROFF BR
if (?? condition is true)
then %pc <- %pc + BROFF
NOTES: (5), (6)
b?? SRC1 add SRC3 SBR
if (?? condition is true)
then %pc <- SRC1 + SRC2
NOTES: (6), (7)
In the `b??' instructions above, `b??' must
be replaced with one of the branch mnemonics in the table below. Each
of these branch mnemonics specifies the conditions under which the
branch is taken. See section Conditional Branch (BR)
inst. branch condition branches if true ----- ---------------- ---------------- bt true 1 bf false 0 bhi|bugt high C AND Z' bls|bule low or same C' OR Z bcc|bult carry clear C' bcs|buge carry set C bne not equal Z' beq equal Z bvc overflow cleared V' bvs overflow set V bpl plus N' bmi minus N bge greater than or equal (N AND V) OR (N' AND V') blt less than (N AND V') OR (N' AND V) bgt greater than (N AND V AND Z') OR (N' AND V' AND Z')
Instruction Machine Instruction
-------------------------------------------------------------------
<u>ld SIGNED_CONST[SRC1], RDEST_LD RM
RDEST_LD <- mem(SRC1+SIGNED_CONST)
NOTES: (2), (3)
<u>ld SRC2[SRC1], RDEST_LD RRM
RDEST_LD <- mem(SRC1+SRC2)
NOTES: (2),(3)
<u>ld{.h|.b} SIGNED_CONST_10[SRC1], RDEST_LD SPLS
RDEST_LD <- mem(SRC1+SIGNED_CONST_10)
NOTES: (2),(3)
<u>ld SIGNED_CONST[*SRC1], RDEST_LD RM
RDEST_LD <- mem(SRC1+SIGNED_CONST)
SRC1 <- SRC1+SIGNED_CONST
NOTES: (2),(3)
ld [{--|++}SRC1], RDEST_LD RM
RDEST_LD <- mem(SRC1 {-|+} 4)
SRC1 <- SRC1 {-|+} 4
NOTES: (2),(3)
<u>ld.h [{--|++}SRC1], RDEST_LD SPLS
RDEST_LD <- mem(SRC1 {-|+} 2)
SRC1 <- SRC1 {-|+} 2
NOTES: (2),(3)
<u>ld.b [{--|++}SRC1], RDEST_LD SPLS
RDEST_LD <- mem(SRC1 {-|+} 1)
SRC1 <- SRC1 {-|+} 1
NOTES: (2),(3)
<u>ld SRC2[*SRC1], RDEST_LD RRM
RDEST_LD <- mem(SRC1+SRC2)
SRC1 <- SRC1+SRC2
NOTES: (2),(3)
<u>ld{.h|.b} SIGNED_CONST_10[*SRC1], RDEST_LD SPLS
RDEST_LD <- mem(SRC1+SIGNED_CONST_10)
SRC1 <- SRC1+SIGNED_CONST_10
NOTES: (2),(3)
<u>ld SIGNED_CONST[SRC1*], RDEST_LD RM
RDEST_LD <- mem(SRC1)
SRC1 <- SRC1+SIGNED_CONST
NOTES: (2),(3)
ld [SRC1{--|++}], RDEST_LD RM
RDEST_LD <- mem(SRC1)
SRC1 <- SRC1 {-|+} 4
NOTES: (2),(3)
<u>ld.h [SRC1{--|++}], RDEST_LD SPLS
RDEST_LD <- mem(SRC1)
SRC1 <- SRC1 {-|+} 2
NOTES: (2),(3)
<u>ld.b [SRC1{--|++}], RDEST_LD SPLS
RDEST_LD <- mem(SRC1)
SRC1 <- SRC1 {-|+} 1
NOTES: (2),(3)
<u>ld SRC2[SRC1*], RDEST_LD RRM
RDEST_LD <- mem(SRC1)
SRC1 <- SRC1+SRC2
NOTES: (2),(3)
<u>ld{.h|.b} SIGNED_CONST_10[SRC1*], RDEST_LD SPLS
RDEST_LD <- mem(SRC1)
SRC1 <- SRC1+SIGNED_CONST_10
NOTES: (2),(3)
ld [SRC1 OP2 SRC2], RDEST_LD RRM
RDEST_LD <- mem(SRC1 OP2 SRC2)
NOTES: (2),(3)
ld [*SRC1 OP2 SRC2], RDEST_LD RRM
RDEST_LD <- mem(SRC1 OP2 SRC2)
SRC1 <- SRC1 OP2 SRC2
NOTES: (2),(3)
ld [SRC1* OP2 SRC2], RDEST_LD RRM
RDEST_LD <- mem(SRC1)
SRC1 <- SRC1 OP2 SRC2
NOTES: (2),(3)
ld [LCONST], RDEST_LD SLS
RDEST <- mem(LCONST)
NOTES: (2),(3)
Instruction Machine Instruction
-------------------------------------------------------------------
mov CONST,SRC1 RI
SRC1 <- CONST
NOTES: (1)
mov SRC2,SRC1 RR
SRC1 <- SRC2
NOTES: (1)
mov LCONST,SRC1 SLI
SRC1 <- LCONST
NOTES: (1)
mov AND_CONST,SRC1 RI
SRC1 <- AND_CONST
NOTES: (1)
nop RI
(does nothing)
or<.f> SRC1, CONST, RDEST RI
RDEST <- SRC1 | SRC2
NOTES: (1),(4)
or<.f> SRC1, SRC2, RDEST RR
RDEST <- SRC1 | SRC2
NOTES: (1),(4)
put SRC1 OP2<.F> ( SRC2 OP1 SRC3 ), RDEST_PUT RRR
RDEST <- SRC1 OP2 ( SRC2 OP1 SRC3 )
NOTES: (1)
* Flags set by result of op2
sh<.f> SRC1, SHIFT_CONST, RDEST RI
RDEST <- SRC1 << SHIFT_CONST
NOTES: (1),(4), (7) logical shift performed
sh<.f> SRC1, SRC2, RDEST RR
IF(31>=SRC2>=0)THEN
RDEST <- SRC1 << SHIFT_CONST
ELSE IF(0>SRC2>=-31)
RDEST <- SRC1 >> -SHIFT_CONST
ELSE
result undefined
NOTES: (1),(4), logical shift performed
sha<.f> SRC1, SHIFT_CONST, RDEST RI
RDEST <- SRC1 << SHIFT_CONST
NOTES: (1),(4), (7) arithmetic shift performed
sha<.f> SRC1, SRC2, RDEST RR
IF(31>=SRC2>=0)THEN
RDEST <- SRC1 << SHIFT_CONST
ELSE IF(0>SRC2>=-31)
RDEST <- SRC1 >> -SHIFT_CONST
ELSE
result is undefined
NOTES: (1),(4)
Instruction Machine Instruction
-------------------------------------------------------------------
st SRC1, SIGNED_CONST[SRC3] RM
mem(SRC3+SIGNED_CONST) <- SRC1
NOTES: (3)
st{.h|.b} SRC1, SIGNED_CONST_10[SRC3] SPLS
mem(SRC3+SIGNED_CONST_10) <- SRC1
NOTES: (3)
st<.h|.b> SRC1, SRC2[SRC3] RRM
mem(SRC3+SRC2) <- SRC1
NOTES: (3)
st SRC1, SIGNED_CONST[*SRC3] RM
mem(SRC3+SIGNED_CONST) <- SRC1
SRC3 <- SRC3+SIGNED_CONST
NOTES: (3)
st{.h|.b} SRC1, SIGNED_CONST_10[*SRC3] SPLS
mem(SRC3+SIGNED_CONST_10) <- SRC1
SRC3 <- SRC3+SIGNED_CONST_10
NOTES: (3)
st SRC1, [{--|++}SRC3] RM
mem(SRC3 {-|+} 4) <- SRC1
SRC3 <- SRC3 {-|+} 4
NOTES: (3)
st.h SRC1, [{--|++}SRC3] SPLS
mem(SRC3 {-|+} 2) <- SRC1
SRC3 <- SRC3 {-|+} 2
NOTES: (3)
st.b SRC1, [{--|++}SRC3] SPLS
mem(SRC3 {-|+} 1) <- SRC1
SRC3 <- SRC3 {-|+} 1
NOTES: (3)
st<.h|.b> SRC1, SRC2[*SRC3] RRM
mem(SRC3+SRC2) <- SRC1
SRC3 <- SRC3+SRC2
NOTES: (3)
st SRC1, SIGNED_CONST[SRC3*] RM
mem(SRC3) <- SRC1
SRC3 <- SRC3+SIGNED_CONST
NOTES: (3)
st{.h|.b} SRC1, SIGNED_CONST[SRC3*] SPLS
mem(SRC3) <- SRC1
SRC3 <- SRC3+SIGNED_CONST
NOTES: (3)
st SRC1, [SRC3{--|++}] RM
mem(SRC3) <- SRC1
SRC3 <- SRC3 {-|+} 4
NOTES: (3)
st.h SRC1, [SRC3{--|++}] SPLS
mem(SRC3) <- SRC1
SRC3 <- SRC3 {-|+} 2
NOTES: (3)
st.b SRC1, [SRC3{--|++}] SPLS
mem(SRC3) <- SRC1
SRC3 <- SRC3 {-|+} 1
NOTES: (3)
st<.h|.b> SRC1, SRC2[SRC3*] RRM
mem(SRC3) <- SRC1
SRC3 <- SRC3+SRC2
NOTES: (3)
st<.h|.b> RDEST, [SRC1 OP2 SRC2] RRM
mem(SRC1 OP2 SRC2) <- RDEST
st<.h|.b> RDEST, [*SRC1 OP1 SRC2] RRM
mem(SRC1 OP1 SRC2) <- RDEST
src1 <- src1 op2 src2
st<.h|.b> RDEST, [SRC1* OP2 SRC2] RRM
mem(SRC1) <- RDEST
src1 <- src1 op2 src2
st RDEST, [LCONST] SLS
mem(LCONST) <- RDEST
Instruction Machine Instruction
-------------------------------------------------------------------
sub<.f> SRC1, CONST, RDEST RI
RDEST <- SRC1 - CONST
NOTES: (1),(4)
sub<.f> SRC1, SRC2, RDEST RR
RDEST <- SRC1 - SRC2
NOTES: (1),(4)
subb<.f> SRC1, CONST, RDEST RI
RDEST <- SRC1 - CONST + C
NOTES: (1),(4) C is the carry bit from %ps
subb<.f> SRC1, SRC2, RDEST RR
RDEST <- SRC1 - SRC2 + C
NOTES: (1),(4) C is the carry bit from %ps
xor<.f> SRC1, CONST, RDEST RI
RDEST <- SRC1 XOR CONST
NOTES: (1),(4)
xor<.f> SRC1, SRC2, RDEST RR
RDEST <- SRC1 XOR SRC2
NOTES: (1),(4)
pc, one more instruction will be
executed before execution continues at the location specified by the
addresse store to pc by this instruction.
pc have two shadows. That is, two more
instructions will be executed after the instruction performing the load
before execution resumes at the location specified by the value loaded
into pc.
ld.b or the halfword loaded by a ld.h
instruction is sign-extended to 32 bits before being saved in
rdest. The byte loaded by a uld.b or the halfword loaded
by a uld.h instruction is zero-extended to 32 bits before being
saved in rdest.
ld instruction is not changed until after the following
instruction. For further information, see section Register Memory (RM).
.h => halfword memory access.b => byte memory access.f => modify the flags
pc (Program Counter). Relative branches branch relative to the current
pc. The current pc contains the address of the
next instruction to be executed. This is usually 4
greater than the address of the current instruction unless (a) the
previous instruction was a branch, (b) the previous instruction was an
ALU operation with pc as its destination register, or (c)
the instruction before the previous instruction was any variant
of ld with rdest == pc.
pc (Program Counter).