Branch Operations

Branch operations are a combination of machine instructions and pseudo-instructions. There are six instructions (see branch instructions). The remainder are pseudo-instructions or macros (see disassembly listing). Here they are divided into four groups.

The first group involves a comparison of a register to zero:

namemacrodescription
beqz $a0,done macrobranch if equal to zero
bnez $a0,done macrobranch if not equal to zero
bgez $a0,done instructionbranch if greater than equal to zero
bgtz $a0,done instructionbranch if greater than zero
bltz $a0,done instructionbranch if less than zero
blez $a0,done instructionbranch if less than or equal to zero

The second group is a signed comparision of one register with another.

namemacrodescription
beq $a0,$a1,done instructionBranch if a0 == a1
bne $a0,$a1,done instructionBranch if a0 != a1
bgt $a0,$a1,done macroBranch if a0 > a1
bge $a0,$a1,done macroBranch if a0 >= a1
blt $a0,$a1,done macroBranch if a0 < a1
ble $a0,$a1,done macroBranch if a0 <= a1

The third group assumes the register values are unsigned. Note that comparison for equality is the same for either signed or unsigned values, so an instruction bequ is not necessary.

namemacrodescription
bgtu $a0,$a1,done macroBranch if (unsigned) a0 > (unsigned) a1
bgeu $a0,$a1,done macroBranch if (unsigned) a0 >= (unsigned) a1
bltu $a0,$a1,done macroBranch if (unsigned) a0 < (unsigned) a1
bleu $a0,$a1,done macroBranch if (unsigned) a0 <= (unsigned) a1

Signed comparisons use slt and unsigned comparisons use sltu. (See disassembly listing).

Finally, there is the unconditional branch:

namemacrodescription
b done macrobranch unconditionally

The unconditional branch actually belongs to all groups: it compares a register (zero) to zero, it compares two registers (both zero), and it works for both signed and unsigned values since it compares for equality.

absolute value

There is a macro or pseudo-instruction called abs that returns Rd <= |Rs|. It is implemented via a branch that copies the source to the destination if the source is non-negative and copies minus the source to the destination if the source is negative. (See disassembly listing.)

In reading the resulting code, note that the instruction after a branch (in the so-called delay slot) is always executed.

Assembly Source

Source: mips2.zip

# mips2.s illustrates branch instructions

    .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:
    beqz    $a0,done  # macro
    nop
    bnez    $a0,done  # macro
    nop
    bgez    $a0,done  # instruction
    nop
    bgtz    $a0,done  # instruction
    nop
    bltz    $a0,done  # instruction
    nop
    blez    $a0,done  # instruction
    nop
    
    beq    $a0,$a1,done  # instruction
    nop
    bne    $a0,$a1,done  # instruction
    nop
    bgt    $a0,$a1,done  # macro
    nop
    bge    $a0,$a1,done  # macro
    nop
    blt    $a0,$a1,done  # macro
    nop
    ble    $a0,$a1,done  # macro
    nop

    bgtu    $a0,$a1,done # macro
    nop
    bgeu    $a0,$a1,done # macro
    nop
    bltu    $a0,$a1,done # macro
    nop
    bleu    $a0,$a1,done # macro
    nop
    
    b    done           # macro
    nop

done:
    li $a0,-20
    abs $a1,$a0     # macro (absolute value)
    
    move $v0,$a1
    jr   $ra
    nop

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

Disassembly Listing

---  C:\pic32\test\mips2.s  ----------------------------------------------------------------------
                                                  1:     # mips2.s illustrates branch instructions
                                                  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  10800029   beq         a0,zero,0x9d0000c22:        beqz    $a0,done  # macro
9D00001C  00000000   nop                          23:        nop
9D000020  14800027   bne         a0,zero,0x9d0000c24:        bnez    $a0,done  # macro
9D000024  00000000   nop                          25:        nop
9D000028  04810025   bgez        a0,0x9d0000c0    26:        bgez    $a0,done  # instruction
9D00002C  00000000   nop                          27:        nop
9D000030  1C800023   bgtz        a0,0x9d0000c0    28:        bgtz    $a0,done  # instruction
9D000034  00000000   nop                          29:        nop
9D000038  04800021   bltz        a0,0x9d0000c0    30:        bltz    $a0,done  # instruction
9D00003C  00000000   nop                          31:        nop
9D000040  1880001F   blez        a0,0x9d0000c0    32:        blez    $a0,done  # instruction
9D000044  00000000   nop                          33:        nop
                                                  34:        
9D000048  1085001D   beq         a0,a1,0x9d0000c0 35:        beq    $a0,$a1,done  # instruction
9D00004C  00000000   nop                          36:        nop
9D000050  1485001B   bne         a0,a1,0x9d0000c0 37:        bne    $a0,$a1,done  # instruction
9D000054  00000000   nop                          38:        nop
9D000058  00A4082A   slt         at,a1,a0         39:        bgt    $a0,$a1,done  # macro
9D00005C  14200018   bne         at,zero,0x9d0000c0
9D000060  00000000   nop                          40:        nop
9D000064  0085082A   slt         at,a0,a1         41:        bge    $a0,$a1,done  # macro
9D000068  10200015   beq         at,zero,0x9d0000c0
9D00006C  00000000   nop                          42:        nop
9D000070  0085082A   slt         at,a0,a1         43:        blt    $a0,$a1,done  # macro
9D000074  14200012   bne         at,zero,0x9d0000c0
9D000078  00000000   nop                          44:        nop
9D00007C  00A4082A   slt         at,a1,a0         45:        ble    $a0,$a1,done  # macro
9D000080  1020000F   beq         at,zero,0x9d0000c0
9D000084  00000000   nop                          46:        nop
                                                  47:    
9D000088  00A4082B   sltu        at,a1,a0         48:        bgtu    $a0,$a1,done # macro
9D00008C  1420000C   bne         at,zero,0x9d0000c0
9D000090  00000000   nop                          49:        nop
9D000094  0085082B   sltu        at,a0,a1         50:        bgeu    $a0,$a1,done # macro
9D000098  10200009   beq         at,zero,0x9d0000c0
9D00009C  00000000   nop                          51:        nop
9D0000A0  0085082B   sltu        at,a0,a1         52:        bltu    $a0,$a1,done # macro
9D0000A4  14200006   bne         at,zero,0x9d0000c0
9D0000A8  00000000   nop                          53:        nop
9D0000AC  00A4082B   sltu        at,a1,a0         54:        bleu    $a0,$a1,done # macro
9D0000B0  10200003   beq         at,zero,0x9d0000c0
9D0000B4  00000000   nop                          55:        nop
                                                  56:        
9D0000B8  10000001   beq         zero,zero,0x9d00057:        b    done           # macro
9D0000BC  00000000   nop                          58:        nop
                                                  59:    
                                                  60:    done:
9D0000C0  2404FFEC   addiu       a0,zero,-20      61:        li $a0,-20
9D0000C4  04810002   bgez        a0,0x9d0000d0    62:        abs $a1,$a0     # macro (absolute value)
9D0000C8  00802821   addu        a1,a0,zero
9D0000CC  00042822   sub         a1,zero,a0
                                                  63:        
9D0000D0  00A01021   addu        v0,a1,zero       64:        move $v0,$a1
9D0000D4  03E00008   jr          ra               65:        jr   $ra
9D0000D8  00000000   nop                          66:        nop


Maintained by John Loomis, last updated 18 August 2008