[Oberon] Numeric CASE vs IF THEN ELSE Performance

Andreas Pirklbauer andreas_pirklbauer at yahoo.com
Tue Jun 12 22:20:49 CEST 2018

    > I have some example code and output to illustrate all of this but
    > unfortunately this mailing list is not a suitable medium:

    > * Attaching files, showing screenshots and including formatted 
    > code snippets are problematic.
    > * Everybody is bombarded with copies of the files even 
    > if they have 0%interest in the discussion.
    > Consequently I have relaunched this discussion on the Astrobe forum:
    > http://www.astrobe.com/forum/viewforum.php?f=13

A few comments / questions:

1) I understand that line .112 in the Soundex listing below is your
new BR instruction, i.e. BR,cond PC,[Rn], where the target of the
branch is computed by adding the contents of register in to the
current program counter.

In my compiler on “regular” RISC (i.e. without the above instruction)
I first issue a BR, 7, 0 instruction to load the current program counter
into the LNK register, and then simply add THAT to [Rn].

2) Why did you “embed” the jump table in the code itself in the form
of BR instructions. This is of course simple and probably faster, but
not space-efficient. But I can see why you might have chosen this
approach: because the maximum value for label is 255, so the absolute
maximum size of the jump table is only 1 KB anyway. Negligible..

My compiler currently generates a jump table in the “data” area
of a module (actually, i sneak it under the “strings" part of it),
following the approach chosen in Lilith-Modula and Ceres-Oberon.
I will now try your approach.. it is simpler.. 

3) How should one handle jump table entries which do *not* correspond
to any case label value in the source text or case expression values
*outside* the case label limits? The language definition does not seem
to specify that. I have currently chosen to treat such events as *empty*
actions - fully knowing that this is in contrast to some other implementations
of the Oberon language where a trap instruction or similar may be generated
in such cases. Any thoughts?

4) Have you implemented an ELSE clause to the CASE statement? It’s
not part of the language definition, but I think it makes sense. And it’s
only a few lines of extra code in the compiler?

5) Is the instructions in lines .111 and .113 in the following code
ALWAYS generated? (index check, trap) or optional?

    PROCEDURE SoundexCase(ch: CHAR): INTEGER;
      VAR value: INTEGER;
    . 105   4EE9000CH  SUB   sp,  sp, 12
    . 106   AFE00000H  STW  lnk,  sp, 0
    . 107   A0E00004H  STW   r0,  sp, 4
      CASE ch OF
       "A", "E", "I", "O", "U", "H", "W", "Y":
    . 108   90E00004H  LDB   r0,  sp, 4                    ;  R0 := ch
    . 109   42090041H  SUB   r2,  r0, 65                   ;  R2 := R0 - ORD(“A)  = R0 - 65 = index to branch table
    . 110   41280016H  ADD   r1,  r2, 22                   ;  R1 := R2 + 22  =  R2 + (x.a - pc*4)  = R2 + “distance to line .135
    . 111   4229001AH  SUB   r2,  r2, 26                   ; index check
    . 112   C2000081H  B,CS  pc,  r1                        ; branch to PC + R1 = to the “right” entry in the branch table
    . 113   D707CC1CH  BL    r12 trap #1, pos: 1996
      value := 0 |


     135   E7FFFFEAH  B     -22 -> 114             ; jump table (=list of branch instructions) with 26 entries, one for “A” to “Z"
    . 136   E7FFFFECH  B     -20 -> 117
    . 137   E7FFFFEEH  B     -18 -> 120
   . 160   E7FFFFD7H  B     -41 -> 120


   END SoundexCase;
   . 161   80E00008H  LDW   r0,  sp, 8
   . 162   8FE00000H  LDW  lnk,  sp, 0
   . 163   4EE8000CH  ADD   sp,  sp, 12
   . 164   C700000FH  B     lnk

More information about the Oberon mailing list