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

Module: MIPS-II
module list

Translating switch statements

Conceptually, there is nothing exciting about translating switch statements. For example, the simple switch statement

switch (i) {
case 1:  a=1;  break;
case 2:  b=1; break;
default:  c=1;
}

can be translated as a set of if statements

if (i ==1) a=1;
else if (i==2) b=1;
else c=1;

No big surprises here. We know how to translate if statements and this would just be messy.

Things get a bit more interesting in the case of a large switch that is dense. By dense we mean the cases are packed tightly together. This kind of a switch statement is more interesting when we consider how to translate it efficiently.

Suppose we have a really stupid switch statement that simply does this:

switch (i) {
case 1: a=1; break;
case 2: a=2; break;
case 3: a=3; break;
...
default: a= 0; break;
}

and let's suppose each value of i from 1 to 20 is included in the switch statement. We will ignore the silly code attached to each case, and just imagine that the code for each case was arbitrarily complex. Translating this switch statement as a series of if-then-else-if's is time-consuming. If, for example, the value of i is 20, we have to execute code to compare i to each of 1...19 before we find the right match! Wouldn't it be nice if a solution was available that was independent of the value of i?

There is! It is called a jump table. Here is how it works. First, we create the sequence of entries for each case like this (we will assume that the address of a is in $t9 and i is in $t1):

L1:  # case 1
li  $t0,1
sw  $t0,0($t9)
b  Lend
L2:  # case 2
li  $t0,2
sw  $t0,0($t9)
b  Lend
L3:  # case 3
li  $t0,3
sw  $t0,0($t9)
b   Lend
L4:  # case 4
li  $t0,4
sw  $t0,0($t9)
b   Lend
...
#default
Ld:
li   $t0,0
sw  $t0,0($t9)
Lend: # end of the switch statement

Now we have a sequence of labels L1 ... L20 and Ld for each case. We now construct our jump table in .data

Jumptbl: .data  .word  Ld,L1,L2,L3,L4,L5.........

where Ld takes the 0th entry (since it would be the default case as well) We now use the following preamble code to branch to the default case if i does not have a value that falls in our jump table:

blt  $t1,$zero,Ld    # remember i is in $t1. if i < 0, use default
li   $t0,20          # compare to 20. if i > 20, use default
bgt  $t1,$t0,Ld

Now we load the correct entry from our jump table and jump to it!

sll  $t2,$t1,2       # make i a byte offset
la   $t3,Jumptbl     # load base of jump table
add  $t3,$t3,$t2     # &Jumptbl[i]
lw   $t4,0($t3)      # Jumptbl[i] - the address of a label
jr   $t4             # and jump to the label.

Question: what is the maximum number of instructions that it takes to get to the correct entry in the switch statement?

Answer: 11. If you answered 8 you forgot to expand the three pseudoinstructions!


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.