mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-15 18:19:45 +02:00
* 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:
parent
5eb184ef8d
commit
a1b2701e5f
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user