Metropoli BBS
VIEWER: tempad.pas MODE: TEXT (CP437)
{****************************************************************************

                   Copyright (c) 1993,95 by Florian Klämpfl

 ****************************************************************************}

unit tempad;

  interface

    uses
       cobjects,globals,tree,asmgen;

    const
       usablereg32 : byte = 4;

    function getregister32 : tregister;
    procedure ungetregister32(r : tregister);

    procedure ungetregister(r : tregister);

    procedure cleartempgen;

    { für Generator für lokale, temporäre Variablen }
    procedure resettempgen;
    procedure setfirsttemp(l : longint);
    function gettempsize : longint;
    function gettempofsize(l : longint) : longint;
    procedure gettempofsizereferenz(l : longint;var ref : treferenz);
    procedure ungettemp(pos : longint;s : longint);
    function gettempstr(l : longint) : string;

    procedure del_referenz(const ref : treferenz);

    type
       tregisterset = set of tregister;

    var
       unused,usableregs : tregisterset;
       firsttemp,c_usableregs : longint;

       { Pseudomenge }
       usedinproc : byte;

  implementation

    procedure ungetregister(r : tregister);

      begin
         if r in [R_EAX,R_ECX,R_EDX,R_EBX,R_ESP,R_EBP,R_ESI,R_EDI] then
           ungetregister32(r)
         else if r in [R_AX,R_CX,R_DX,R_BX,R_SP,R_BP,R_SI,R_DI] then
           ungetregister32(reg16toreg32(r))
         else if r in [R_AL,R_BL,R_CL,R_DL] then
           ungetregister32(reg8toreg32(r))
         else internalerror(18);
      end;

    procedure ungetregister32(r : tregister);

      begin
         if not(r in [R_EAX,R_ECX,R_EDX,R_EBX]) then exit;
         unused:=unused+[r];
         inc(usablereg32);
      end;

    procedure del_referenz(const ref : treferenz);

      begin
         if ref.isintvalue then
           exit;
         ungetregister32(ref.base);
         ungetregister32(ref.index);
      end;

    function getregister32 : tregister;

      begin
         dec(usablereg32);
         if R_EAX in unused then
           begin
              unused:=unused-[R_EAX];
              usedinproc:=usedinproc or ($80 shr byte(R_EAX));
              getregister32:=R_EAX;
           end
         else if R_EDX in unused then
           begin
              unused:=unused-[R_EDX];
              usedinproc:=usedinproc or ($80 shr byte(R_EDX));
              getregister32:=R_EDX;
           end
         else if R_EBX in unused then
           begin
              unused:=unused-[R_EBX];
              usedinproc:=usedinproc or ($80 shr byte(R_EBX));
              getregister32:=R_EBX;
           end
         else if R_ECX in unused then
           begin
              unused:=unused-[R_ECX];
              usedinproc:=usedinproc or ($80 shr byte(R_ECX));
              getregister32:=R_ECX;
           end
         else internalerror(10);
      end;

    procedure cleartempgen;

      begin
         unused:=usableregs;
         usablereg32:=c_usableregs;
      end;

    procedure resettempgen;

      begin
         firsttemp:=0;
      end;

    procedure setfirsttemp(l : longint);

      begin
         firsttemp:=l;
      end;

    function gettempofsize(l : longint) : longint;

      begin
         dec(firsttemp,l);
         if (firsttemp mod 4)<>0 then
           dec(firsttemp,4-(firsttemp mod 4));
         gettempofsize:=firsttemp;
      end;

    function gettempsize : longint;

      begin
         gettempsize:=-firsttemp;
      end;

    procedure ungettemp(pos : longint;s : longint);

      begin
         { !!!!!! Nur Dummy, wird später vebessert }
      end;

    function gettempstr(l : longint) : string;

      begin
         gettempstr:=tostr(l)+'(%ebp)';
      end;

    procedure gettempofsizereferenz(l : longint;var ref : treferenz);

      begin
         clear_referenz(ref);
         ref.offset:=gettempofsize(l);
         ref.base:=R_EBP;
      end;

begin
   usableregs:=[R_EAX,R_EBX,R_ECX,R_EDX];
   c_usableregs:=4;
end.
[ RETURN TO DIRECTORY ]