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:
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
If we were on a processor with condition codes, the sequence would be
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
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
j 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 |
9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
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 |
9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
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:
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:
Prev | This page was made entirely
with free software on linux: the Mozilla Project and Openoffice.org |
Next |