[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