[Oberon] Question on ORG.SaveRegs / ORG.RestoreRegs in the FPGA Oberon compiler
Andreas Pirklbauer
andreas_pirklbauer at yahoo.com
Tue Dec 18 21:05:16 CET 2018
Question regarding the FPGA compiler:
The book "Project Oberon 2013 Edition" states (ch.12.7.7, p.47 of PO.Applications.pdf) that registers are saved prior to a *function* call and restored upon return, using procedures ORG.SaveRegs and ORG.RestoreRegs.
PROCEDURE SaveRegs(r: LONGINT); (* R[0 .. r-1]*)
VAR r0: LONGINT;
BEGIN (*r > 0*) r0 := 0;
Put1(Sub, SP, SP, r*4); INC(frame, 4*r);
REPEAT Put2(Str, r0, SP, (r-r0-1)*4); INC(r0) UNTIL r0 = r
END SaveRegs;
PROCEDURE RestoreRegs(r: LONGINT); (*R[0 .. r-1]*)
VAR r0: LONGINT;
BEGIN (*r > 0*) r0 := r;
REPEAT DEC(r0); Put2(Ldr, r0, SP, (r-r0-1)*4) UNTIL r0 = 0;
Put1(Add, SP, SP, r*4); DEC(frame, 4*r)
END RestoreRegs;
However, procedure ORG.PrepCall (which calls ORG.SaveRegs):
PROCEDURE PrepCall*(VAR x: Item; VAR r: LONGINT);
BEGIN (*x.type.form = ORB.Proc*)
IF x.mode > ORB.Par THEN load(x) END ;
r := RH;
IF RH > 0 THEN SaveRegs(RH); RH := 0 END
END PrepCall;
is called not only for *function* procedures, i.e. in ORP.factor:
PROCEDURE factor(VAR x: ORG.Item);
...
IF (x.type.form = ORB.Proc) & (x.type.base.form # ORB.NoTyp) THEN
ORG.PrepCall(x, rx); ParamList(x); ORG.Call(x, rx); x.type := x.type.base
but ALSO for *regular* procedures, i.e. in ORP.StatSequence:
PROCEDURE StatSequence;
...
IF (x.type.form = ORB.Proc) & (x.type.base.form = ORB.NoTyp) THEN
ORG.PrepCall(x, rx); ParamList(x); ORG.Call(x, rx)
whereas after a procedure has been called, the registers are *only* restored for *function* procedures in ORG.Call
PROCEDURE Call*(VAR x: Item; r: LONGINT);
…
IF x.type.base.form = ORB.NoTyp THEN (*procedure*) RH := 0
ELSE (*function*)
IF r > 0 THEN Put0(Mov, r, 0, 0); RestoreRegs(r) END ;
x.mode := Reg; x.r := r; RH := r+1
END
but not for regular procedures.
Can someone explain this asymmetry? Shouldn’t there be a "frame error" for regular procedures if the registers are not restored (i.e. if frame is not adjusted)?
PS: In Ceres-Oberon, OCC.SaveRegisters is called only in Factor (i.e. for function procedures), but not in StatSequence (i.e. for regular procedures) ... as one would expect.
AP
More information about the Oberon
mailing list