Instruction Variations

This example shows that the assembler can identify whether operations, such as add, should be register-format or immediate-format. We tested this with several examples from the reference. See the disassembly listing.

add

    add  $t0,$a0,$a1
           add    t0,a0,a1

    add  $t0,$a0,6         
           addi   t0,a0,6

    add  $t0,$a0,0x1234
           addi   t0,a0,4660

    add  $t0,$a0,0x12340000      
           lui    at,0x1234
           add    t0,a0,at

    add  $t0,$a0,0x12345678
           lui    at,0x1234
           ori    at,at,0x5678
           add    t0,a0,at

shifts

    srl  $t0,$a0,$a1
           srlv   t0,a0,a1

    srl $t0,$a0,6         
           srl    t0,a0,0x6

    rol $t0,$a0,$a1        
           subu   t0,zero,a1       
           rotrv  t0,a0,t0

    rol $t0,$a0,8
           rotr   t0,a0,0x18

    ror $t0,$a0,4       
           rotr   t0,a0,0x4          

branches

     bge  $a0,$a1,main
     nop
           slt    at,a0,a1         
           beq    at,zero,0x9d000018
           nop

      bge  $a0,4,main
      nop
           slti   at,a0,4          
           beq    at,zero,0x9d000018
           nop

      bge  $a0,0x1234,main
      nop
           slti   at,a0,4660       
           beq    at,zero,0x9d000018
           nop

     bge  $a0,0x12340000,main
     nop
           lui    at,0x1234        
           slt    at,a0,at
           beq    at,zero,0x9d000018
           nop

      bge    $a0,0x12345678,main
      nop
           lui    at,0x1234   
           ori    at,at,0x5678
           slt    at,a0,at
           beq    at,zero,0x9d000018
           nop

Reference

Erin Farquhar and Philip Bunce, The MIPS Programmer's Handbook,
Morgan Kaufman, 1994. ISBN 1-55860-297-6.
See chapter 5.

This book talks about an older MIPS processor, but the idea that the assembler should be able to convert automatically to immediate-mode instructions seems to be still valid.

Assembly Code

Download mips4.zip

# mips4.s illustrates instruction variations

    .global main

    .text

    /* This directive tells the assembler don't optimize
     * the order of the instructions and don't insert
     * 'nop' instructions after jumps and branches.
    */
    .set noreorder

/*********************************************************************
 * main()
 * This is where the PIC32 start-up code will jump to after initial
 * set-up.
 ********************************************************************/

.ent main   # directive that marks symbol 'main' as function in ELF output

main:
    li    $a0,24
    li    $a1,4

adds:
    add    $t0,$a0,$a1
    add    $t0,$a0,6
    add    $t0,$a0,0x1234
    add    $t0,$a0,0x12340000
    add    $t0,$a0,0x12345678

shifts:
    srl    $t0,$a0,$a1
    srl    $t0,$a0,6
    rol    $t0,$a0,$a1
    rol $t0,$a0,8
    ror    $t0,$a0,4

branches:
    bge    $a0,$a1,main
    nop
    bge    $a0,4,main
    nop
    bge    $a0,0x1234,main
    nop
    bge    $a0,0x12340000,main
    nop
    bge    $a0,0x12345678,main
    
    jr   $ra
    nop

.end main   #  directive that marks end of 'main' function 
            # and registers size in ELF output

Disassembly Listing

---  C:\pic32\test\mips4.s  ----------------------------------------------------------------------
                                                  1:     # mips4.s illustrates instruction variations
                                                  2:     
                                                  3:         .global main
                                                  4:     
                                                  5:         .text
                                                  6:     
                                                  7:         /* This directive tells the assembler don't optimize
                                                  8:          * the order of the instructions and don't insert
                                                  9:          * 'nop' instructions after jumps and branches.
                                                  10:        */
                                                  11:        .set noreorder
                                                  12:    
                                                  13:    /*********************************************************************
                                                  14:     * main()
                                                  15:     * This is where the PIC32 start-up code will jump to after initial
                                                  16:     * set-up.
                                                  17:     ********************************************************************/
                                                  18:    
                                                  19:    .ent main   # directive that marks symbol 'main' as function in ELF output
                                                  20:    
                                                  21:    main:
9D000018  24040018   addiu       a0,zero,24       22:        li    $a0,24
9D00001C  24050004   addiu       a1,zero,4        23:        li    $a1,4
                                                  24:    
                                                  25:    adds:
9D000020  00854020   add         t0,a0,a1         26:        add    $t0,$a0,$a1
9D000024  20880006   addi        t0,a0,6          27:        add    $t0,$a0,6
9D000028  20881234   addi        t0,a0,4660       28:        add    $t0,$a0,0x1234
9D00002C  3C011234   lui         at,0x1234        29:        add    $t0,$a0,0x12340000
9D000030  00814020   add         t0,a0,at
9D000034  3C011234   lui         at,0x1234        30:        add    $t0,$a0,0x12345678
9D000038  34215678   ori         at,at,0x5678
9D00003C  00814020   add         t0,a0,at
                                                  31:    
                                                  32:    shifts:
9D000040  00A44006   srlv        t0,a0,a1         33:        srl    $t0,$a0,$a1
9D000044  00044182   srl         t0,a0,0x6        34:        srl    $t0,$a0,6
9D000048  00054023   subu        t0,zero,a1       35:        rol    $t0,$a0,$a1
9D00004C  01044046   rotrv       t0,a0,t0
9D000050  00244602   rotr        t0,a0,0x18       36:        rol $t0,$a0,8
9D000054  00244102   rotr        t0,a0,0x4        37:        ror    $t0,$a0,4
                                                  38:    
                                                  39:    branches:
9D000058  0085082A   slt         at,a0,a1         40:        bge    $a0,$a1,main
9D00005C  1020FFEE   beq         at,zero,0x9d000018
9D000060  00000000   nop                          41:        nop
9D000064  28810004   slti        at,a0,4          42:        bge    $a0,4,main
9D000068  1020FFEB   beq         at,zero,0x9d000018
9D00006C  00000000   nop                          43:        nop
9D000070  28811234   slti        at,a0,4660       44:        bge    $a0,0x1234,main
9D000074  1020FFE8   beq         at,zero,0x9d000018
9D000078  00000000   nop                          45:        nop
9D00007C  3C011234   lui         at,0x1234        46:        bge    $a0,0x12340000,main
9D000080  0081082A   slt         at,a0,at
9D000084  1020FFE4   beq         at,zero,0x9d000018
9D000088  00000000   nop                          47:        nop
9D00008C  3C011234   lui         at,0x1234        48:        bge    $a0,0x12345678,main
9D000090  34215678   ori         at,at,0x5678
9D000094  0081082A   slt         at,a0,at
9D000098  1020FFDF   beq         at,zero,0x9d000018
                                                  49:        
9D00009C  03E00008   jr          ra               50:        jr   $ra
9D0000A0  00000000   nop                          51:        nop


Maintained by John Loomis, last updated 19 August 2008