* if while we are restoring the contents of a register, we encounter an

operation which changes a register, clear the contents of all registers
    which depend on this register

git-svn-id: trunk@3480 -
This commit is contained in:
Jonas Maebe 2006-05-11 16:46:58 +00:00
parent 5eb184ef8d
commit a1b2701e5f
2 changed files with 53 additions and 16 deletions

View File

@ -842,6 +842,7 @@ var
{$endif replaceregdebug}
regcounter: tsuperregister;
oldStartmod: tai;
regstoclear: tregset;
begin
{$ifdef replaceregdebug}
l := random(1000);
@ -850,26 +851,43 @@ begin
insertllitem(asml,p.previous,p,hp);
{$endif replaceregdebug}
ptaiprop(p.optinfo)^.Regs[supreg].typ := con_unknown;
regstoclear := [supreg];
while (p <> endP) do
begin
for regcounter := RS_EAX to RS_EDI do
if (regcounter <> supreg) and
assigned(ptaiprop(p.optinfo)^.regs[supreg].memwrite) and
reginref(regcounter,ptaiprop(p.optinfo)^.regs[supreg].memwrite.oper[1]^.ref^) then
clearmemwrites(p,regcounter);
with ptaiprop(p.optinfo)^.Regs[supreg] do
begin
typ := con_unknown;
memwrite := nil;
if (regcounter <> supreg) and
assigned(ptaiprop(p.optinfo)^.regs[supreg].memwrite) and
reginref(regcounter,ptaiprop(p.optinfo)^.regs[supreg].memwrite.oper[1]^.ref^) then
clearmemwrites(p,regcounter);
{ needs double loop to cheack for each dependency combination? }
if assigned(ptaiprop(p.optinfo)^.regs[regcounter].startmod) and
sequencedependsonreg(ptaiprop(p.optinfo)^.regs[regcounter],regcounter,supreg) then
include(regstoclear,regcounter);
if regcounter in regstoclear then
with ptaiprop(p.optinfo)^.Regs[regcounter] do
begin
typ := con_unknown;
memwrite := nil;
end;
end;
getNextInstruction(p,p);
end;
oldStartmod := ptaiprop(p.optinfo)^.Regs[supreg].startmod;
repeat
with ptaiprop(p.optinfo)^.Regs[supreg] do
for regcounter := RS_EAX to RS_EDI do
begin
typ := con_unknown;
memwrite := nil;
{ needs double loop to cheack for each dependency combination? }
if assigned(ptaiprop(p.optinfo)^.regs[regcounter].startmod) and
sequencedependsonreg(ptaiprop(p.optinfo)^.regs[regcounter],regcounter,supreg) then
include(regstoclear,regcounter);
with ptaiprop(p.optinfo)^.Regs[supreg] do
if regcounter in regstoclear then
begin
typ := con_unknown;
memwrite := nil;
end;
end;
until not getNextInstruction(p,p) or
(ptaiprop(p.optinfo)^.Regs[supreg].startmod <> oldStartmod);
@ -889,7 +907,8 @@ var
l: longint;
{$endif replaceregdebug}
hp: tai;
dummyregs: tregset;
validregs, prevvalidregs: tregset;
regcounter: tsuperregister;
tmpState, newrstate: byte;
prevcontenttyp: byte;
memconflict: boolean;
@ -906,6 +925,8 @@ begin
incstate(newrstate,$7f);
memconflict := false;
invalsmemwrite := false;
validregs := [RS_EAX..RS_EDI];
prevvalidregs := validregs;
while (p <> endP) and
not(memconflict) and
not(invalsmemwrite) do
@ -914,8 +935,16 @@ begin
regreadbyinstruction(supreg,p) then
incstate(newrstate,1);
// is this a write to memory that destroys the contents we are restoring?
memconflict := modifiesConflictingMemLocation(p,supreg,ptaiprop(p.optinfo)^.regs,dummyregs,true,invalsmemwrite);
if not memconflict and not invalsmemwrite then
memconflict := modifiesConflictingMemLocation(p,supreg,ptaiprop(p.optinfo)^.regs,validregs,false,invalsmemwrite);
if (validregs <> prevvalidregs) then
begin
prevvalidregs := validregs >< prevvalidregs;
for regcounter := RS_EAX to RS_EDI do
if regcounter in prevvalidregs then
clearRegContentsFrom(asml,regcounter,p,endP);
end;
prevvalidregs := validregs;
if (not memconflict and not invalsmemwrite) then
begin
ptaiprop(p.optinfo)^.Regs[supreg] := c;
ptaiprop(p.optinfo)^.Regs[supreg].rstate := newrstate;
@ -946,13 +975,20 @@ begin
if (ptaiprop(hp.optinfo)^.regs[supreg].rstate = ptaiprop(p.optinfo)^.regs[supreg].rstate) then
internalerror(2004122710);
end;
dummyregs := [supreg];
repeat
newrstate := ptaiprop(p.optinfo)^.Regs[supreg].rState;
prevcontenttyp := ptaiprop(p.optinfo)^.Regs[supreg].typ;
// is this a write to memory that destroys the contents we are restoring?
memconflict := modifiesConflictingMemLocation(p,supreg,ptaiprop(p.optinfo)^.regs,dummyregs,true,invalsmemwrite);
if not memconflict and not invalsmemwrite then
memconflict := modifiesConflictingMemLocation(p,supreg,ptaiprop(p.optinfo)^.regs,validregs,false,invalsmemwrite);
if (validregs <> prevvalidregs) then
begin
prevvalidregs := validregs >< prevvalidregs;
for regcounter := RS_EAX to RS_EDI do
if regcounter in prevvalidregs then
clearRegContentsFrom(asml,regcounter,p,p);
end;
prevvalidregs := validregs;
if (not memconflict and not invalsmemwrite) then
begin
ptaiprop(p.optinfo)^.Regs[supreg] := c;
ptaiprop(p.optinfo)^.Regs[supreg].rstate := newrstate;

View File

@ -187,6 +187,7 @@ function writeToRegDestroysContents(destReg, supreg: tsuperregister;
function writeDestroysContents(const op: toper; supreg: tsuperregister; size: tcgsize;
const c: tcontent; var memwritedestroyed: boolean): boolean;
function sequenceDependsonReg(const Content: TContent; seqreg: tsuperregister; supreg: tsuperregister): Boolean;
function GetNextInstruction(Current: tai; var Next: tai): Boolean;
function GetLastInstruction(Current: tai; var Last: tai): Boolean;