generate code for case

case src (c), lo (a), hi (b)
< jump table >
$

jump table is a table of displacements (32 bits each). The size is (hi-lo+1).  We want to align the end of table ($) at even address (to conform to 64-bit address boundary of a real 64-bit processor). So, the table is patched to be even(hi-lo+1), where even is the "round-up" to even number (2 to 2, 3 to 4 ...). However in order to avoid calculating even(hi-lo+1) every time to know where the end of table is, a displacement of jump to end of table can be put as the first item in the jump table.

case src (c), lo (a), hi (b)
<disp to end>
<jump table>
$

As a by-product, the "else" of case can use this displacement to jump to the end of table. This displacement can be used as the size of jump table. Now the size of whole table is 

even(hi-lo+2).

Note: the reference address of the jump displacement is the "current" instruction, that is, the address of "case". For example, the actual size of <jmp table> is <disp to end> -2.

structure of code for case is:

"case"
<  
  $end
  $case_lo
  $case_lo+1  or $else
  $...
  $case_hi
  [optional patch]
>
$end:  jmp else    (here is even address)
$case_lo:  ... jmp exit
$case...
$case_hi:  ... jmp exit
$else: ...
$exit:

else clause is optional. Trying to optimise the last "jmp exit" when there is no else clause is quite logical.  However, it will have to undo lastCP with a lot of consequences (in the compiler, gencode-s.txt).  Therefore I will leave it out for the time being and do it when I have time to consider that it is really safe.

18 Dec 2010
 