From 6abc491796e027ff73426cae0ea13cec1f7774d7 Mon Sep 17 00:00:00 2001 From: Jonas Maebe Date: Mon, 15 Dec 2003 16:08:15 +0000 Subject: [PATCH] - 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") --- compiler/i386/csopt386.pas | 42 ++++++++++++++++++++++++++++---------- compiler/i386/rropt386.pas | 22 +++++++++++++++++--- 2 files changed, 50 insertions(+), 14 deletions(-) diff --git a/compiler/i386/csopt386.pas b/compiler/i386/csopt386.pas index 9f63f64e02..690705114f 100644 --- a/compiler/i386/csopt386.pas +++ b/compiler/i386/csopt386.pas @@ -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; ; mov %newReg, } { %oldReg" to "" } - 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 diff --git a/compiler/i386/rropt386.pas b/compiler/i386/rropt386.pas index 45871243bc..13c12a4402 100644 --- a/compiler/i386/rropt386.pas +++ b/compiler/i386/rropt386.pas @@ -209,7 +209,7 @@ begin { if the newReg gets stored back to the oldReg, we can change } { "mov %oldReg,%newReg; ; mov %newReg, } { %oldReg" to "" } - 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