sections in this module City College of San Francisco - CS270
Computer Architecture

Module: MIPS-II (Decisions)
module list

Branches and Translating the if statement

Branch instructions in MIPS

There are basically two native branch statements in MIPS:

beq  rs,rt,label
bne  rs,rt,label

The use of these instructions should be straightforward. The label can be a label either forward or backward in the current module. For our purposes it can be anywhere, but in reality there are restrictions, which we will discuss later.

Of course there are many other branch conditions - greater than, for example. These branch instructions (bgt, blt, ble, bge) are pseudoinstructions, but we will use them as if they are native - they have the same form as beq and bne. The pseudoinstructions are implemented using a special instruction - slt. Before we discuss it, lets consider how we can substitute the less-than operator for each of our three other comparison operators  <=, >, >=:

operation
substitute operation
a <= b
 ! (b < a)
a > b
  b < a
a >= b
 ! (a < b)

The native slt instruction slt  reg,rega,regb  sets register reg to 0 or 1 depending on whether rega is less than regb. The branch instruction follows the slt instruction and uses either bne or beq (comparing reg to 0) to do the actual branch. Let's look at the simplest example

pseudoinstruction
becomes
bgt   rega,regb,label
slt  $at,regb,rega
bne $at,$zero,label

Using the table above, you can derive the translation for each of the other pseudoinstruction (though it takes a bit of confused thinking for most of us).

For our purposes, feel free to use the pseudoinstructions, but understand how they are derived, and be aware of which MIPS instructions are pseudoinstructions, especially when comparing instruction sequences for efficiency.

Condition Codes

As indicated in a previous section, MIPS does not have condition codes. However, their use is so common that we should discuss them. Condition codes, which may be part of a more general set of flags, are status bits which are set in most processors as the result of any arithmetic operation. Although these processors have comparison instructions, those instructions merely exist to set the condition codes. The instruction following the arithmetic or comparison instruction then branches if the condition codes are set a certain way.

Let's look at a simple example for the code that follows

if ((a-b) < 0 ) goto label;

A [dumb] straightforward translation of this code on MIPS, where a is in $t0 and b is in $t1 would be

sub  $t3,$t0,$t1
slt  $t2,$t3,$zero      # set $t2 to 1 if $t3 is less than 0. set $t2 to 0 otherwise
bne  $t2,$zero,label # effectively branches to label if $t3 (a-b) is < 0

If we were on a processor with condition codes, the sequence would be

subtract  $t3,$t0,$t1
branchlt  label

In other words, the condition code for result less than 0 would be automatically set by the subtract operation. Note that the branch instruction must immediately follow the arithmetic operation, as intervening instructions will alter the condition codes! This is not true on MIPS - since the slt instruction sets a register, the branch can be delayed.

Such processors also have explicit compare instructions to explicitly set the condition codes. In those code sequences the MIPS code may actually be shorter.

Addressing mode

As you might expect, the branch instructions are I-type. The label address is encoded in the 16-bit field of the I-type instruction. Of course, 16-bits is insufficient for a full address. The field contains a relative address, which is part of the branching instructions new addressing mode - pc-relative.

Remember, the pc holds the address of the next instruction to be executed. By default, if you are executing an instruction at address N, pc is set to the address N+4 (the next instruction is 4 bytes forward). The branch instruction's 16-bit constant contains a number that indicates how to adjust the pc - but it is not measured in bytes. To give the branch a longer range, the adjustment is measured in words. Thus, in the sequence

label: some other instruction
sub  $t3,$t0,$t1
slt  $t2,$t3,$zero
bne  $t2,$zero,label
whatever instruction follows the branch

the bne instruction would hold the constant -4. This number would be multiplied by 4 (read: left-shifted by 2), then added to the pc. Originally the pc had the address of the instruction whatever. After the adjustment by 16 bytes, it has the address of label.

This use of word-offsets in a branch instruction enables branches to have a range of 65536 instructions, centered on the current instruction. This is 256kB of code - which, in most cases, is much larger than the size of a function.

Other branching instructions

In cases where the branch target is too far away, a jump instruction must be used instead. The jump instruction is simple

address

As you might expect, the jump instruction uses a new instruction format - J-type. A J-type instruction is simple: there are 6 bits of opcode followed by a 26-bit constant. This 26-bit constant is again a 28-bit constant in disguise (it is a word address and the low-order 2 zero-bits are suppressed), but the result is not PC-relative. Rather, the 28-bit result replaces the low-order 28-bits of the current PC. This gives the jump instruction the ability to jump anywhere within the current 256MB (2^28 byte) segment of code. Let's look at an example. If the current PC is 0x20012C58:

31
30
29
28
27
26
25
24
23
22
21
20
19
18
17
16
15
14
13
12 11
10
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
1
0
0
1
0
1
1
0
0
0
1
0
1
1
0
0
0
2
0
0
1
2
C
5
8

and we need to jump to the address 0x20053C58, we can't use a branch instruction because the target PC is 41000 bytes (or 10400 words) away. Instead, we must alter the PC using a jump instruction. The new PC must look like this

31
30
29
28
27
26
25
24
23
22
21
20
19
18
17
16
15
14
13
12 11
10
0
0
1
0
0
0
0
0
0
0
0
0
0
1
0
1
0
0
1
1
1
1
0
0
0
1
0
1
1
0
0
0
2
0
0
5
3
C
5
8

where we have highlighted bits 2-27 of the target PC to indicate the bits encoded in the jump instruction. The jump instruction would then be

j  0x0014F16

For a completely general jump instruction that can jump to anywhere, MIPS has the jr reg instruction. In this case, the new PC is placed in a register and the jr reg instruction indicates to jump to the address in the register. Here, of course, there is no adjustment of the address - it is a real [byte] address. (Of course the low-order 2 bits of the address must be zero to avoid an alignment fault.)

In the problems section of this module, Problem One compares these three techniques of branching. You may want to review it now.

Translating if-statements

Translating if-then-else statements proceeds much the same way as it did for the simple machine, but MIPS assembly language is much easier to use. Let's look at a simple example:

if (a < b) {
temp = b;
b = a;
a = temp;
}

Doing our standard translation to gotos:

if (a >= b) goto .L4 
temp = b;
b = a;
a = temp;
.L4:

And the final translation assuming a is in $t0 and b is in $t1, and using pseudoinstructions to make life easier:

bge  $t0,$t1,.L4  # pseudoinstruction
move $t2,$t1      # temp = b
move $t1,$t0      # b = a
move $t0,$t2      # a = temp
.L4:


Prev This page was made entirely with free software on linux:  
the Mozilla Project
and Openoffice.org    
Next

Copyright 2015 Greg Boyd - All Rights Reserved.