[Oberon] FJump and FixLink

Andreas Pirklbauer andreas_pirklbauer at yahoo.com
Tue Jul 3 09:57:51 CEST 2018

    > But in FixLink() we see L1 := code[L] MOD 40000H;
    > Why we extract only 18 bits to L1?
    > >   - are branch offsets in words or bytes?
    > In words.
    > >   - how much RAM does the board have? 
    > 1MB SRAM.
    > Now I see. To address 1MB we need = 20 bits
    > If we present offset in words, we need = 20 - 2 = 18 bit. :-)

I don’t think it is actually necessary to hardwire the 18 bit restriction
(=1MB) into the compiler, as done in the official RISC Oberon compiler.

The array ORG.code already restricts the code size to 8000 words
= 32KB. So the offsets cannot be larger than anyway, when the
instruction to be fixed up is generated (Put3 will put 0’s in bits 19-23).

Thus, I think changing the instruction to L1 := code[L] MOD C24
works equally well AND has the advantage that the compiler now
also works for boards with larger memory (up to 2^24 = 16MB).

    > [But what about offset in Memory instructions? Didn't find mentioned anywhere…
    > Did I miss it somewhere?]
    > Srinivas Nayak

Only branch (i.e. format-3) instructions are ever fixed up in the
Oberon compiler, and ORG.fix *only* works for those instructions.

If you need the “fixup" mechanism to work for *other* instruction formats,
you’d simply have to add it. For an example of how this can be done, see


which adds the fixup mechanism for format-1 register instructions (e.g. Add),
which have 16-bit offsets, in addition to format-3 branch instructions:

  PROCEDURE fix1(at, with: LONGINT);
  BEGIN (*fix format-1 register instruction*)
    IF with < 0 THEN v := C28 (*v modifier bit*) ELSE v := 0 END ;
    code[at] := code[at] DIV C16 * C16 + (with MOD C16) + v
  END fix1;

  PROCEDURE fix3(at, with: LONGINT);
  BEGIN (*fix format-3 branch instruction*)
    code[at] := code[at] DIV C24 * C24 + (with MOD C24)
  END fix3;

  PROCEDURE FixLinkWith(L, dst: LONGINT);
    WHILE L # 0 DO
      IF code[L] DIV C30 = 1 THEN (*format-1*) L1 := code[L] MOD C16; fix1(L, (dst-L)*4)
      ELSE (*format-3*) L1 := code[L] MOD C24; fix3(L, dst-L-1)
      END ;
      L := L1
  END FixLinkWith;

PS: As you can see, I don’t use "MOD 40000H" but "MOD C24” for
format-3 branch instructions. And for format-1 I use C16 instead.

So, if you need to “fix up” format-2 memory instructions (which
have 20-bit offsets), you can just just add it...

  PROCEDURE fix2(at, with: LONGINT);
  BEGIN (*fix format-2 memory instruction*)
    code[at] := code[at] DIV C20 * C20 + (with MOD C20)
  END fix2;

and adjust ORG.FixLinkWith accordingly.


More information about the Oberon mailing list