mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-11 19:25:58 +02:00
Support more operators in FoldShiftProcess on ARM
Now we can also fold shifts into teq, tst, cmp, cmn instructions. git-svn-id: trunk@22023 -
This commit is contained in:
parent
b20c4cfe87
commit
9e039936bf
@ -261,7 +261,7 @@ Implementation
|
|||||||
function TCpuAsmOptimizer.PeepHoleOptPass1Cpu(var p: tai): boolean;
|
function TCpuAsmOptimizer.PeepHoleOptPass1Cpu(var p: tai): boolean;
|
||||||
var
|
var
|
||||||
hp1,hp2: tai;
|
hp1,hp2: tai;
|
||||||
i: longint;
|
i, i2: longint;
|
||||||
TmpUsedRegs: TAllUsedRegs;
|
TmpUsedRegs: TAllUsedRegs;
|
||||||
tempop: tasmop;
|
tempop: tasmop;
|
||||||
|
|
||||||
@ -686,25 +686,34 @@ Implementation
|
|||||||
(taicpu(p).oppostfix = PF_NONE) and
|
(taicpu(p).oppostfix = PF_NONE) and
|
||||||
GetNextInstruction(p, hp1) and
|
GetNextInstruction(p, hp1) and
|
||||||
(tai(hp1).typ = ait_instruction) and
|
(tai(hp1).typ = ait_instruction) and
|
||||||
(taicpu(hp1).ops = 3) and {Currently we can't fold into another shifterop}
|
(taicpu(hp1).ops >= 2) and {Currently we can't fold into another shifterop}
|
||||||
(taicpu(hp1).oper[2]^.typ = top_reg) and
|
(taicpu(hp1).oper[taicpu(hp1).ops-1]^.typ = top_reg) and
|
||||||
(taicpu(hp1).oppostfix = PF_NONE) and
|
(taicpu(hp1).oppostfix = PF_NONE) and
|
||||||
(taicpu(hp1).condition = taicpu(p).condition) and
|
(taicpu(hp1).condition = taicpu(p).condition) and
|
||||||
(taicpu(hp1).opcode in [A_ADD, A_ADC, A_RSB, A_RSC, A_SUB, A_SBC,
|
(taicpu(hp1).opcode in [A_ADD, A_ADC, A_RSB, A_RSC, A_SUB, A_SBC,
|
||||||
A_AND, A_BIC, A_EOR, A_ORR, A_TEQ, A_TST]) and
|
A_AND, A_BIC, A_EOR, A_ORR, A_TEQ, A_TST,
|
||||||
|
A_CMP, A_CMN]) and
|
||||||
(
|
(
|
||||||
{Only ONE of the two src operands is allowed to match}
|
{Only ONE of the two src operands is allowed to match}
|
||||||
MatchOperand(taicpu(p).oper[0]^, taicpu(hp1).oper[1]^) xor
|
MatchOperand(taicpu(p).oper[0]^, taicpu(hp1).oper[taicpu(hp1).ops-2]^) xor
|
||||||
MatchOperand(taicpu(p).oper[0]^, taicpu(hp1).oper[2]^)
|
MatchOperand(taicpu(p).oper[0]^, taicpu(hp1).oper[taicpu(hp1).ops-1]^)
|
||||||
) then
|
) then
|
||||||
begin
|
begin
|
||||||
CopyUsedRegs(TmpUsedRegs);
|
CopyUsedRegs(TmpUsedRegs);
|
||||||
UpdateUsedRegs(TmpUsedRegs, tai(p.next));
|
UpdateUsedRegs(TmpUsedRegs, tai(p.next));
|
||||||
|
if taicpu(hp1).opcode in [A_TST, A_TEQ, A_CMN] then
|
||||||
|
I2:=0
|
||||||
|
else
|
||||||
|
I2:=1;
|
||||||
if not(RegUsedAfterInstruction(taicpu(p).oper[0]^.reg,hp1,TmpUsedRegs)) then
|
if not(RegUsedAfterInstruction(taicpu(p).oper[0]^.reg,hp1,TmpUsedRegs)) then
|
||||||
for I:=1 to 2 do
|
for I:=I2 to taicpu(hp1).ops-1 do
|
||||||
if MatchOperand(taicpu(p).oper[0]^, taicpu(hp1).oper[I]^.reg) then
|
if MatchOperand(taicpu(p).oper[0]^, taicpu(hp1).oper[I]^.reg) then
|
||||||
begin
|
begin
|
||||||
if I = 1 then
|
{ If the parameter matched on the second op from the RIGHT
|
||||||
|
we have to switch the parameters, this will not happen for CMP
|
||||||
|
were we're only evaluating the most right parameter
|
||||||
|
}
|
||||||
|
if I <> taicpu(hp1).ops-1 then
|
||||||
begin
|
begin
|
||||||
{The SUB operators need to be changed when we swap parameters}
|
{The SUB operators need to be changed when we swap parameters}
|
||||||
case taicpu(hp1).opcode of
|
case taicpu(hp1).opcode of
|
||||||
@ -714,14 +723,24 @@ Implementation
|
|||||||
A_RSC: tempop:=A_SBC;
|
A_RSC: tempop:=A_SBC;
|
||||||
else tempop:=taicpu(hp1).opcode;
|
else tempop:=taicpu(hp1).opcode;
|
||||||
end;
|
end;
|
||||||
hp2:=taicpu.op_reg_reg_reg_shifterop(tempop,
|
if taicpu(hp1).ops = 3 then
|
||||||
taicpu(hp1).oper[0]^.reg, taicpu(hp1).oper[2]^.reg,
|
hp2:=taicpu.op_reg_reg_reg_shifterop(tempop,
|
||||||
taicpu(p).oper[1]^.reg, taicpu(p).oper[2]^.shifterop^);
|
taicpu(hp1).oper[0]^.reg, taicpu(hp1).oper[2]^.reg,
|
||||||
|
taicpu(p).oper[1]^.reg, taicpu(p).oper[2]^.shifterop^)
|
||||||
|
else
|
||||||
|
hp2:=taicpu.op_reg_reg_shifterop(tempop,
|
||||||
|
taicpu(hp1).oper[0]^.reg, taicpu(p).oper[1]^.reg,
|
||||||
|
taicpu(p).oper[2]^.shifterop^);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
hp2:=taicpu.op_reg_reg_reg_shifterop(taicpu(hp1).opcode,
|
if taicpu(hp1).ops = 3 then
|
||||||
taicpu(hp1).oper[0]^.reg, taicpu(hp1).oper[1]^.reg,
|
hp2:=taicpu.op_reg_reg_reg_shifterop(taicpu(hp1).opcode,
|
||||||
taicpu(p).oper[1]^.reg, taicpu(p).oper[2]^.shifterop^);
|
taicpu(hp1).oper[0]^.reg, taicpu(hp1).oper[1]^.reg,
|
||||||
|
taicpu(p).oper[1]^.reg, taicpu(p).oper[2]^.shifterop^)
|
||||||
|
else
|
||||||
|
hp2:=taicpu.op_reg_reg_shifterop(taicpu(hp1).opcode,
|
||||||
|
taicpu(hp1).oper[0]^.reg, taicpu(p).oper[1]^.reg,
|
||||||
|
taicpu(p).oper[2]^.shifterop^);
|
||||||
asml.insertbefore(hp2, p);
|
asml.insertbefore(hp2, p);
|
||||||
asml.remove(p);
|
asml.remove(p);
|
||||||
asml.remove(hp1);
|
asml.remove(hp1);
|
||||||
|
Loading…
Reference in New Issue
Block a user