mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2026-01-06 07:50:47 +01:00
- disable removal of dead loads before a call, because register
parameters are released before a call
* fix storeback of registers in case of different sizes (e.g., first
a "movl %eax,%edx" and later a "movb %dl,%al")
This commit is contained in:
parent
2057dbd01a
commit
6abc491796
@ -33,7 +33,7 @@ function CSE(asml: TAAsmoutput; first, last: tai; pass: longint): boolean;
|
||||
|
||||
function doReplaceReg(hp: taicpu; newReg, orgReg: tsuperregister): boolean;
|
||||
function changeOp(var o: toper; newReg, orgReg: tsuperregister): boolean;
|
||||
function storeBack(p1: tai; orgReg, newReg: tsuperregister): boolean;
|
||||
function storeBack(start, current: tai; orgReg, newReg: tsuperregister): boolean;
|
||||
function NoHardCodedRegs(p: taicpu; orgReg, newReg: tsuperregister): boolean;
|
||||
function RegSizesOK(oldReg,newReg: tsuperregister; p: taicpu): boolean;
|
||||
|
||||
@ -1135,17 +1135,27 @@ begin
|
||||
end;
|
||||
|
||||
|
||||
function storeBack(p1: tai; orgReg, newReg: tsuperregister): boolean;
|
||||
function storeBack(start, current: tai; orgReg, newReg: tsuperregister): boolean;
|
||||
{ returns true if p1 contains an instruction that stores the contents }
|
||||
{ of newReg back to orgReg }
|
||||
begin
|
||||
storeBack :=
|
||||
(p1.typ = ait_instruction) and
|
||||
(taicpu(p1).opcode = A_MOV) and
|
||||
(taicpu(p1).oper[0]^.typ = top_reg) and
|
||||
(getsupreg(taicpu(p1).oper[0]^.reg) = newReg) and
|
||||
(taicpu(p1).oper[1]^.typ = top_reg) and
|
||||
(getsupreg(taicpu(p1).oper[1]^.reg) = orgReg);
|
||||
storeback := false;
|
||||
if (current.typ = ait_instruction) and
|
||||
(taicpu(current).opcode = A_MOV) and
|
||||
(taicpu(current).oper[0]^.typ = top_reg) and
|
||||
(getsupreg(taicpu(current).oper[0]^.reg) = newReg) and
|
||||
(taicpu(current).oper[1]^.typ = top_reg) and
|
||||
(getsupreg(taicpu(current).oper[1]^.reg) = orgReg) then
|
||||
case taicpu(current).opsize of
|
||||
S_B:
|
||||
storeback := true;
|
||||
S_W:
|
||||
storeback := taicpu(start).opsize <> S_B;
|
||||
S_L:
|
||||
storeback := taicpu(start).opsize = S_L;
|
||||
else
|
||||
internalerror(2003121501);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
@ -1196,7 +1206,7 @@ begin
|
||||
{ if the newsupreg gets stored back to the oldReg, we can change }
|
||||
{ "mov %oldReg,%newReg; <operations on %newReg>; mov %newReg, }
|
||||
{ %oldReg" to "<operations on %oldReg>" }
|
||||
removeLast := storeBack(endP, orgsupreg, newsupreg);
|
||||
removeLast := storeBack(p,endP, orgsupreg, newsupreg);
|
||||
sequenceEnd :=
|
||||
{ no support for (i)div, mul and imul with hardcoded operands }
|
||||
noHardCodedRegs(taicpu(endP),orgsupreg,newsupreg) and
|
||||
@ -1670,9 +1680,13 @@ begin
|
||||
ait_instruction:
|
||||
begin
|
||||
case taicpu(p).opcode of
|
||||
{
|
||||
Does not work anymore with register calling because the registers are
|
||||
released before the call
|
||||
A_CALL:
|
||||
for regCounter := RS_EAX to RS_EBX do
|
||||
removePrevNotUsedLoad(p,regCounter,true);
|
||||
}
|
||||
A_CLD: if GetLastInstruction(p, hp1) and
|
||||
(ptaiprop(hp1.optinfo)^.DirFlag = F_NotSet) then
|
||||
ptaiprop(tai(p).optinfo)^.CanBeRemoved := True;
|
||||
@ -2060,7 +2074,13 @@ end.
|
||||
|
||||
{
|
||||
$Log$
|
||||
Revision 1.56 2003-12-14 22:42:14 peter
|
||||
Revision 1.57 2003-12-15 16:08:15 jonas
|
||||
- disable removal of dead loads before a call, because register
|
||||
parameters are released before a call
|
||||
* fix storeback of registers in case of different sizes (e.g., first
|
||||
a "movl %eax,%edx" and later a "movb %dl,%al")
|
||||
|
||||
Revision 1.56 2003/12/14 22:42:14 peter
|
||||
* fixed csdebug
|
||||
|
||||
Revision 1.55 2003/12/14 14:18:59 peter
|
||||
|
||||
@ -209,7 +209,7 @@ begin
|
||||
{ if the newReg gets stored back to the oldReg, we can change }
|
||||
{ "mov %oldReg,%newReg; <operations on %newReg>; mov %newReg, }
|
||||
{ %oldReg" to "<operations on %oldReg>" }
|
||||
switchLast := storeBack(endP,reg1,reg2);
|
||||
switchLast := storeBack(start,endP,reg1,reg2);
|
||||
reg1StillUsed := reg1 in pTaiprop(endp.optinfo)^.usedregs;
|
||||
reg2StillUsed := reg2 in pTaiprop(endp.optinfo)^.usedregs;
|
||||
isInstruction := endp.typ = ait_instruction;
|
||||
@ -303,7 +303,17 @@ begin
|
||||
getNextInstruction(hp,hp);
|
||||
end;
|
||||
if switchLast then
|
||||
doSwitchReg(taicpu(hp),reg1,reg2)
|
||||
begin
|
||||
{ this is in case of a storeback, make sure the same size of register }
|
||||
{ contents as the initial move is transfered }
|
||||
doSwitchReg(taicpu(hp),reg1,reg2);
|
||||
if taicpu(hp).opsize <> taicpu(start).opsize then
|
||||
begin
|
||||
taicpu(hp).opsize := taicpu(start).opsize;
|
||||
taicpu(hp).oper[0]^.reg := taicpu(start).oper[0]^.reg;
|
||||
taicpu(hp).oper[1]^.reg := taicpu(start).oper[1]^.reg;
|
||||
end;
|
||||
end
|
||||
else
|
||||
getLastInstruction(hp,hp);
|
||||
allocRegBetween(asmL,newreg(R_INTREGISTER,reg1,R_SUBWHOLE),start,lastreg1);
|
||||
@ -350,7 +360,13 @@ End.
|
||||
|
||||
{
|
||||
$Log$
|
||||
Revision 1.24 2003-12-07 19:19:56 jonas
|
||||
Revision 1.25 2003-12-15 16:08:16 jonas
|
||||
- disable removal of dead loads before a call, because register
|
||||
parameters are released before a call
|
||||
* fix storeback of registers in case of different sizes (e.g., first
|
||||
a "movl %eax,%edx" and later a "movb %dl,%al")
|
||||
|
||||
Revision 1.24 2003/12/07 19:19:56 jonas
|
||||
* fixed some more bugs which only showed up in a ppc cross compiler
|
||||
|
||||
Revision 1.23 2003/11/22 00:40:19 jonas
|
||||
|
||||
Loading…
Reference in New Issue
Block a user