[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
https://github.com/andreaspirklbauer/Oberon-forward-references-of-procedures
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);
VAR v: 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);
VAR L1: LONGINT;
BEGIN
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
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.
HTH,
-ap
More information about the Oberon
mailing list