{****************************************************************************
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.