[Oberon] Static variable overflow (bug?)
skulski at pas.rochester.edu
Thu Feb 27 16:05:08 CET 2020
thank you! I am suggesting to use global CONST because looking at the Oberon code I can see these literals and I do not know which 10000H is due to what? What happens if someone ports the compiler to the open source ARM core which is now available for FPGAs? Which 10000H is due to RISC5 architecture and should be changed to something else when porting? Which 10000H is due to something else and it should stay?
So I am suggesting to take every opportunity to factor out these constants. Just put the declaration at the start of the module and put a comment why it is defined (the particular RISC5 instruction). This will improve the clarity in a big way.
From: Oberon [oberon-bounces at lists.inf.ethz.ch] on behalf of Andreas Pirklbauer [andreas_pirklbauer at yahoo.com]
Sent: Thursday, February 27, 2020 9:47 AM
To: Oberon List
Subject: Re: [Oberon] Static variable overflow (bug?)
Thx. On a separate note: The fix below for ORG.Put1a only works for *non-imported*
global variables. There, the offset from the static base can now be >64KB, both
for loading the value of such variables and for determining their address.
For *imported* global variables, there still is the 64KB restriction (actually, loading
works, but not accessing the address of such variables). This could also be fixed.
> On 27 Feb 2020, at 14:35, Skulski, Wojciech <skulski at pas.rochester.edu> wrote:
>> Below is a slightly more elaborate variant that fixes the current bug in ORG.Put1a
>> and makes MyViewers.Mod (see below) work on a Project Oberon 2013 system:
> How about
> CONST LIMIT = 10000H; ULIMIT = 0FFFFH; (* Upper limit = LIMIT -1 = 0FFFFH; *)
> PROCEDURE Put1a(op, a, b, im: LONGINT);
> VAR r: INTEGER;
> (*same as Put1, but with range test -10000H<= im < 10000H*)
> (*same as Put1, but with range test -LIMIT <= im < LIMIT *)
> IF (im >= -LIMIT ) & (im <= ULIMIT) THEN Put1(op, a, b, im)
> ELSIF op = Mov THEN
> Put1(Mov+U, a, 0, im DIV LIMIT );
> IF im MOD LIMIT # 0 THEN Put1(Ior, a, a, im MOD LIMIT ) END
> ELSE r := RH;
> IF b = RH THEN incR END ;
> Put1(Mov+U, RH, 0, im DIV LIMIT );
> IF im MOD LIMIT # 0 THEN Put1(Ior, RH, RH, im MOD LIMIT ) END ;
> Put0(op, a, b, RH);
> IF RH > r THEN DEC(RH) END
> END Put1a;
> 0. Using literal constants in the code is a universally condemned programming practice.
> 1. Procedure incR is to be moved up to before procedure ORG.Put0
> 2. The use of incR ensures that in fact we do have enough registers available
> 3. Register optimization: But a new register is used only when needed (when b = RH)
> 4. Instruction optimization: For op = Mov, the extra MOV instruction at the end is avoided
More information about the Oberon