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