Go to the first, previous, next, last section, table of contents.

The LANai3 Assembler

General Assembler Info

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:

  1. ps is explicitly named in an instruction as a destination register.
  2. Flag updates are specified by the presence of `.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.

Operand Types

@cindex op2 The following operand types may appear in assembly instructions:

brabs
An unsigned, 23-bit, immediate absolute branch address or a register. Note that the 2 lsb's must be 0.
broff
A signed, 23-bit, immediate relative branch offset or a register. Note that the 2 lsb's must be 0.
and_const
A 32 bit unsigned constant with either the high or low halfword == 0xffff
const
A 32 bit unsigned constant with either the high or low halfword == 0
lconst
A 21 bit unsinged constant
signed_const_10
A 10 bit signed constant
signed_const
A 16 bit signed constant
shift_const
A 6 bit signed constant in the range [-31,31]
op1
One of "add, addc, sub, subc, and, or, xor, sha"
op2
One of "add, addc, sub, subc, and, or, xor, sh, sha"
rdest
A register
rdest_ld
A register other than 2 (pc) or 31 (isr).
rdest_put
A register other than 2 (pc) or 31 (isr).
src1
A register
src2
A register
src3
A register

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.

Instruction Formats

In this section:

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)

Notes

  1. If the destination register is pc, one more instruction will be executed before execution continues at the location specified by the addresse store to pc by this instruction.
    1. Memory loads into 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.
    2. The byte loaded by a 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.
    3. rdest in a ld instruction is not changed until after the following instruction. For further information, see section Register Memory (RM).
  2. .h => halfword memory access
    .b => byte memory access
  3. .f => modify the flags
  4. For more details about the timing of relative branch instructions, see section Modifying 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.
  5. Branches have a shadow. For futher information, see section Conditional Branch (BR) and section Modifying pc (Program Counter).
  6. Here, a right shift is performed if shift_const is negative.

Go to the first, previous, next, last section, table of contents.