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:
name | macro | description |
---|---|---|
beqz $a0,done | macro | branch if equal to zero |
bnez $a0,done | macro | branch if not equal to zero |
bgez $a0,done | instruction | branch if greater than equal to zero |
bgtz $a0,done | instruction | branch if greater than zero |
bltz $a0,done | instruction | branch if less than zero |
blez $a0,done | instruction | branch if less than or equal to zero |
The second group is a signed comparision of one register with another.
name | macro | description |
---|---|---|
beq $a0,$a1,done | instruction | Branch if a0 == a1 |
bne $a0,$a1,done | instruction | Branch if a0 != a1 |
bgt $a0,$a1,done | macro | Branch if a0 > a1 |
bge $a0,$a1,done | macro | Branch if a0 >= a1 |
blt $a0,$a1,done | macro | Branch if a0 < a1 |
ble $a0,$a1,done | macro | Branch 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.
name | macro | description |
---|---|---|
bgtu $a0,$a1,done | macro | Branch if (unsigned) a0 > (unsigned) a1 |
bgeu $a0,$a1,done | macro | Branch if (unsigned) a0 >= (unsigned) a1 |
bltu $a0,$a1,done | macro | Branch if (unsigned) a0 < (unsigned) a1 |
bleu $a0,$a1,done | macro | Branch if (unsigned) a0 <= (unsigned) a1 |
Signed comparisons use slt and unsigned comparisons use sltu. (See disassembly listing).
Finally, there is the unconditional branch:
name | macro | description |
---|---|---|
b done | macro | branch 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.
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.
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
--- 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