* factor out GetNextInstructionUsingReg calls in TARMAsmOptimizer.OptPass1*XT*

This commit is contained in:
florian 2022-09-02 21:26:20 +02:00
parent 9061fba9ff
commit cebb47fe9a

View File

@ -624,107 +624,105 @@ Implementation
hp1, hp2: tai; hp1, hp2: tai;
begin begin
Result:=false; Result:=false;
{ if GetNextInstructionUsingReg(p,hp1,taicpu(p).oper[0]^.reg) then
change
uxtb reg2,reg1
strb reg2,[...]
dealloc reg2
to
strb reg1,[...]
}
if MatchInstruction(p, taicpu(p).opcode, [C_None], [PF_None]) and
(taicpu(p).ops=2) and
GetNextInstructionUsingReg(p,hp1,taicpu(p).oper[0]^.reg) and
MatchInstruction(hp1, A_STR, [C_None], [PF_B]) and
assigned(FindRegDealloc(taicpu(p).oper[0]^.reg,tai(hp1.Next))) and
{ the reference in strb might not use reg2 }
not(RegInRef(taicpu(p).oper[0]^.reg,taicpu(hp1).oper[1]^.ref^)) and
{ reg1 might not be modified inbetween }
not(RegModifiedBetween(taicpu(p).oper[1]^.reg,p,hp1)) then
begin begin
DebugMsg('Peephole UxtbStrb2Strb done', p); {
taicpu(hp1).loadReg(0,taicpu(p).oper[1]^.reg); change
result:=RemoveCurrentP(p); uxtb reg2,reg1
end strb reg2,[...]
{ dealloc reg2
change to
uxtb reg2,reg1 strb reg1,[...]
uxth reg3,reg2 }
dealloc reg2 if MatchInstruction(p, taicpu(p).opcode, [C_None], [PF_None]) and
to (taicpu(p).ops=2) and
uxtb reg3,reg1 MatchInstruction(hp1, A_STR, [C_None], [PF_B]) and
} assigned(FindRegDealloc(taicpu(p).oper[0]^.reg,tai(hp1.Next))) and
else if MatchInstruction(p, A_UXTB, [C_None], [PF_None]) and { the reference in strb might not use reg2 }
(taicpu(p).ops=2) and not(RegInRef(taicpu(p).oper[0]^.reg,taicpu(hp1).oper[1]^.ref^)) and
GetNextInstructionUsingReg(p,hp1,taicpu(p).oper[0]^.reg) and { reg1 might not be modified inbetween }
MatchInstruction(hp1, A_UXTH, [C_None], [PF_None]) and not(RegModifiedBetween(taicpu(p).oper[1]^.reg,p,hp1)) then
(taicpu(hp1).ops = 2) and begin
MatchOperand(taicpu(hp1).oper[1]^, taicpu(p).oper[0]^.reg) and DebugMsg('Peephole UxtbStrb2Strb done', p);
RegEndofLife(taicpu(p).oper[0]^.reg,taicpu(hp1)) and taicpu(hp1).loadReg(0,taicpu(p).oper[1]^.reg);
{ reg1 might not be modified inbetween } result:=RemoveCurrentP(p);
not(RegModifiedBetween(taicpu(p).oper[1]^.reg,p,hp1)) then end
begin {
DebugMsg('Peephole UxtbUxth2Uxtb done', p); change
AllocRegBetween(taicpu(hp1).oper[0]^.reg,p,hp1,UsedRegs); uxtb reg2,reg1
taicpu(p).loadReg(0,taicpu(hp1).oper[0]^.reg); uxth reg3,reg2
asml.remove(hp1); dealloc reg2
hp1.free; to
result:=true; uxtb reg3,reg1
end }
{ else if MatchInstruction(p, A_UXTB, [C_None], [PF_None]) and
change (taicpu(p).ops=2) and
uxtb reg2,reg1 MatchInstruction(hp1, A_UXTH, [C_None], [PF_None]) and
uxtb reg3,reg2 (taicpu(hp1).ops = 2) and
dealloc reg2 MatchOperand(taicpu(hp1).oper[1]^, taicpu(p).oper[0]^.reg) and
to RegEndofLife(taicpu(p).oper[0]^.reg,taicpu(hp1)) and
uxtb reg3,reg1 { reg1 might not be modified inbetween }
} not(RegModifiedBetween(taicpu(p).oper[1]^.reg,p,hp1)) then
else if MatchInstruction(p, A_UXTB, [C_None], [PF_None]) and begin
(taicpu(p).ops=2) and DebugMsg('Peephole UxtbUxth2Uxtb done', p);
GetNextInstructionUsingReg(p,hp1,taicpu(p).oper[0]^.reg) and AllocRegBetween(taicpu(hp1).oper[0]^.reg,p,hp1,UsedRegs);
MatchInstruction(hp1, A_UXTB, [C_None], [PF_None]) and taicpu(p).loadReg(0,taicpu(hp1).oper[0]^.reg);
(taicpu(hp1).ops = 2) and asml.remove(hp1);
MatchOperand(taicpu(hp1).oper[1]^, taicpu(p).oper[0]^.reg) and hp1.free;
RegEndofLife(taicpu(p).oper[0]^.reg,taicpu(hp1)) and result:=true;
{ reg1 might not be modified inbetween } end
not(RegModifiedBetween(taicpu(p).oper[1]^.reg,p,hp1)) then {
begin change
DebugMsg('Peephole UxtbUxtb2Uxtb done', p); uxtb reg2,reg1
AllocRegBetween(taicpu(hp1).oper[0]^.reg,p,hp1,UsedRegs); uxtb reg3,reg2
taicpu(p).loadReg(0,taicpu(hp1).oper[0]^.reg); dealloc reg2
asml.remove(hp1); to
hp1.free; uxtb reg3,reg1
result:=true; }
end else if MatchInstruction(p, A_UXTB, [C_None], [PF_None]) and
{ (taicpu(p).ops=2) and
change MatchInstruction(hp1, A_UXTB, [C_None], [PF_None]) and
uxtb reg2,reg1 (taicpu(hp1).ops = 2) and
and reg3,reg2,#0x*FF MatchOperand(taicpu(hp1).oper[1]^, taicpu(p).oper[0]^.reg) and
dealloc reg2 RegEndofLife(taicpu(p).oper[0]^.reg,taicpu(hp1)) and
to { reg1 might not be modified inbetween }
uxtb reg3,reg1 not(RegModifiedBetween(taicpu(p).oper[1]^.reg,p,hp1)) then
} begin
else if MatchInstruction(p, A_UXTB, [C_None], [PF_None]) and DebugMsg('Peephole UxtbUxtb2Uxtb done', p);
(taicpu(p).ops=2) and AllocRegBetween(taicpu(hp1).oper[0]^.reg,p,hp1,UsedRegs);
GetNextInstructionUsingReg(p,hp1,taicpu(p).oper[0]^.reg) and taicpu(p).loadReg(0,taicpu(hp1).oper[0]^.reg);
MatchInstruction(hp1, A_AND, [C_None], [PF_None]) and asml.remove(hp1);
(taicpu(hp1).ops=3) and hp1.free;
(taicpu(hp1).oper[2]^.typ=top_const) and result:=true;
((taicpu(hp1).oper[2]^.val and $FF)=$FF) and end
MatchOperand(taicpu(hp1).oper[1]^, taicpu(p).oper[0]^.reg) and {
RegEndofLife(taicpu(p).oper[0]^.reg,taicpu(hp1)) and change
{ reg1 might not be modified inbetween } uxtb reg2,reg1
not(RegModifiedBetween(taicpu(p).oper[1]^.reg,p,hp1)) then and reg3,reg2,#0x*FF
begin dealloc reg2
DebugMsg('Peephole UxtbAndImm2Uxtb done', p); to
taicpu(hp1).opcode:=A_UXTB; uxtb reg3,reg1
taicpu(hp1).ops:=2; }
taicpu(hp1).loadReg(1,taicpu(p).oper[1]^.reg); else if MatchInstruction(p, A_UXTB, [C_None], [PF_None]) and
result:=RemoveCurrentP(p); (taicpu(p).ops=2) and
end MatchInstruction(hp1, A_AND, [C_None], [PF_None]) and
else if GetNextInstructionUsingReg(p, hp1, taicpu(p).oper[0]^.reg) and (taicpu(hp1).ops=3) and
RemoveSuperfluousMove(p, hp1, 'UxtbMov2Uxtb') then (taicpu(hp1).oper[2]^.typ=top_const) and
Result:=true; ((taicpu(hp1).oper[2]^.val and $FF)=$FF) and
MatchOperand(taicpu(hp1).oper[1]^, taicpu(p).oper[0]^.reg) and
RegEndofLife(taicpu(p).oper[0]^.reg,taicpu(hp1)) and
{ reg1 might not be modified inbetween }
not(RegModifiedBetween(taicpu(p).oper[1]^.reg,p,hp1)) then
begin
DebugMsg('Peephole UxtbAndImm2Uxtb done', p);
taicpu(hp1).opcode:=A_UXTB;
taicpu(hp1).ops:=2;
taicpu(hp1).loadReg(1,taicpu(p).oper[1]^.reg);
result:=RemoveCurrentP(p);
end
else if RemoveSuperfluousMove(p, hp1, 'UxtbMov2Uxtb') then
Result:=true;
end;
end; end;
@ -733,81 +731,80 @@ Implementation
hp1: tai; hp1: tai;
begin begin
Result:=false; Result:=false;
{ if GetNextInstructionUsingReg(p,hp1,taicpu(p).oper[0]^.reg) then
change
uxth reg2,reg1
strh reg2,[...]
dealloc reg2
to
strh reg1,[...]
}
if MatchInstruction(p, taicpu(p).opcode, [C_None], [PF_None]) and
(taicpu(p).ops=2) and
GetNextInstructionUsingReg(p,hp1,taicpu(p).oper[0]^.reg) and
MatchInstruction(hp1, A_STR, [C_None], [PF_H]) and
RegEndofLife(taicpu(p).oper[0]^.reg,taicpu(hp1)) and
{ the reference in strb might not use reg2 }
not(RegInRef(taicpu(p).oper[0]^.reg,taicpu(hp1).oper[1]^.ref^)) and
{ reg1 might not be modified inbetween }
not(RegModifiedBetween(taicpu(p).oper[1]^.reg,p,hp1)) then
begin begin
DebugMsg('Peephole UXTHStrh2Strh done', p); {
taicpu(hp1).loadReg(0,taicpu(p).oper[1]^.reg); change
result:=RemoveCurrentP(p); uxth reg2,reg1
end strh reg2,[...]
{ dealloc reg2
change to
uxth reg2,reg1 strh reg1,[...]
uxth reg3,reg2 }
dealloc reg2 if MatchInstruction(p, taicpu(p).opcode, [C_None], [PF_None]) and
to (taicpu(p).ops=2) and
uxth reg3,reg1 MatchInstruction(hp1, A_STR, [C_None], [PF_H]) and
} RegEndofLife(taicpu(p).oper[0]^.reg,taicpu(hp1)) and
else if MatchInstruction(p, A_UXTH, [C_None], [PF_None]) and { the reference in strb might not use reg2 }
(taicpu(p).ops=2) and not(RegInRef(taicpu(p).oper[0]^.reg,taicpu(hp1).oper[1]^.ref^)) and
GetNextInstructionUsingReg(p,hp1,taicpu(p).oper[0]^.reg) and { reg1 might not be modified inbetween }
MatchInstruction(hp1, A_UXTH, [C_None], [PF_None]) and not(RegModifiedBetween(taicpu(p).oper[1]^.reg,p,hp1)) then
(taicpu(hp1).ops=2) and begin
MatchOperand(taicpu(hp1).oper[1]^, taicpu(p).oper[0]^.reg) and DebugMsg('Peephole UXTHStrh2Strh done', p);
RegEndofLife(taicpu(p).oper[0]^.reg,taicpu(hp1)) and taicpu(hp1).loadReg(0,taicpu(p).oper[1]^.reg);
{ reg1 might not be modified inbetween } result:=RemoveCurrentP(p);
not(RegModifiedBetween(taicpu(p).oper[1]^.reg,p,hp1)) then end
begin {
DebugMsg('Peephole UxthUxth2Uxth done', p); change
AllocRegBetween(taicpu(p).oper[1]^.reg,p,hp1,UsedRegs); uxth reg2,reg1
taicpu(hp1).opcode:=A_UXTH; uxth reg3,reg2
taicpu(hp1).loadReg(1,taicpu(p).oper[1]^.reg); dealloc reg2
result:=RemoveCurrentP(p); to
end uxth reg3,reg1
{ }
change else if MatchInstruction(p, A_UXTH, [C_None], [PF_None]) and
uxth reg2,reg1 (taicpu(p).ops=2) and
and reg3,reg2,#65535 MatchInstruction(hp1, A_UXTH, [C_None], [PF_None]) and
dealloc reg2 (taicpu(hp1).ops=2) and
to MatchOperand(taicpu(hp1).oper[1]^, taicpu(p).oper[0]^.reg) and
uxth reg3,reg1 RegEndofLife(taicpu(p).oper[0]^.reg,taicpu(hp1)) and
} { reg1 might not be modified inbetween }
else if MatchInstruction(p, A_UXTH, [C_None], [PF_None]) and not(RegModifiedBetween(taicpu(p).oper[1]^.reg,p,hp1)) then
(taicpu(p).ops=2) and begin
GetNextInstructionUsingReg(p,hp1,taicpu(p).oper[0]^.reg) and DebugMsg('Peephole UxthUxth2Uxth done', p);
MatchInstruction(hp1, A_AND, [C_None], [PF_None]) and AllocRegBetween(taicpu(p).oper[1]^.reg,p,hp1,UsedRegs);
(taicpu(hp1).ops=3) and taicpu(hp1).opcode:=A_UXTH;
(taicpu(hp1).oper[2]^.typ=top_const) and taicpu(hp1).loadReg(1,taicpu(p).oper[1]^.reg);
((taicpu(hp1).oper[2]^.val and $FFFF)=$FFFF) and result:=RemoveCurrentP(p);
MatchOperand(taicpu(hp1).oper[1]^, taicpu(p).oper[0]^.reg) and end
RegEndofLife(taicpu(p).oper[0]^.reg,taicpu(hp1)) and {
{ reg1 might not be modified inbetween } change
not(RegModifiedBetween(taicpu(p).oper[1]^.reg,p,hp1)) then uxth reg2,reg1
begin and reg3,reg2,#65535
DebugMsg('Peephole UxthAndImm2Uxth done', p); dealloc reg2
taicpu(hp1).opcode:=A_UXTH; to
taicpu(hp1).ops:=2; uxth reg3,reg1
taicpu(hp1).loadReg(1,taicpu(p).oper[1]^.reg); }
result:=RemoveCurrentP(p); else if MatchInstruction(p, A_UXTH, [C_None], [PF_None]) and
end (taicpu(p).ops=2) and
else if GetNextInstructionUsingReg(p, hp1, taicpu(p).oper[0]^.reg) and MatchInstruction(hp1, A_AND, [C_None], [PF_None]) and
RemoveSuperfluousMove(p, hp1, 'UxthMov2Data') then (taicpu(hp1).ops=3) and
Result:=true; (taicpu(hp1).oper[2]^.typ=top_const) and
((taicpu(hp1).oper[2]^.val and $FFFF)=$FFFF) and
MatchOperand(taicpu(hp1).oper[1]^, taicpu(p).oper[0]^.reg) and
RegEndofLife(taicpu(p).oper[0]^.reg,taicpu(hp1)) and
{ reg1 might not be modified inbetween }
not(RegModifiedBetween(taicpu(p).oper[1]^.reg,p,hp1)) then
begin
DebugMsg('Peephole UxthAndImm2Uxth done', p);
taicpu(hp1).opcode:=A_UXTH;
taicpu(hp1).ops:=2;
taicpu(hp1).loadReg(1,taicpu(p).oper[1]^.reg);
result:=RemoveCurrentP(p);
end
else if RemoveSuperfluousMove(p, hp1, 'UxthMov2Data') then
Result:=true;
end;
end; end;
@ -816,107 +813,106 @@ Implementation
hp1, hp2: tai; hp1, hp2: tai;
begin begin
Result:=false; Result:=false;
{ if GetNextInstructionUsingReg(p,hp1,taicpu(p).oper[0]^.reg) then
change
sxtb reg2,reg1
strb reg2,[...]
dealloc reg2
to
strb reg1,[...]
}
if MatchInstruction(p, taicpu(p).opcode, [C_None], [PF_None]) and
(taicpu(p).ops=2) and
GetNextInstructionUsingReg(p,hp1,taicpu(p).oper[0]^.reg) and
MatchInstruction(hp1, A_STR, [C_None], [PF_B]) and
assigned(FindRegDealloc(taicpu(p).oper[0]^.reg,tai(hp1.Next))) and
{ the reference in strb might not use reg2 }
not(RegInRef(taicpu(p).oper[0]^.reg,taicpu(hp1).oper[1]^.ref^)) and
{ reg1 might not be modified inbetween }
not(RegModifiedBetween(taicpu(p).oper[1]^.reg,p,hp1)) then
begin begin
DebugMsg('Peephole SxtbStrb2Strb done', p); {
taicpu(hp1).loadReg(0,taicpu(p).oper[1]^.reg); change
result:=RemoveCurrentP(p); sxtb reg2,reg1
end strb reg2,[...]
{ dealloc reg2
change to
sxtb reg2,reg1 strb reg1,[...]
sxth reg3,reg2 }
dealloc reg2 if MatchInstruction(p, taicpu(p).opcode, [C_None], [PF_None]) and
to (taicpu(p).ops=2) and
sxtb reg3,reg1 MatchInstruction(hp1, A_STR, [C_None], [PF_B]) and
} assigned(FindRegDealloc(taicpu(p).oper[0]^.reg,tai(hp1.Next))) and
else if MatchInstruction(p, A_SXTB, [C_None], [PF_None]) and { the reference in strb might not use reg2 }
(taicpu(p).ops=2) and not(RegInRef(taicpu(p).oper[0]^.reg,taicpu(hp1).oper[1]^.ref^)) and
GetNextInstructionUsingReg(p,hp1,taicpu(p).oper[0]^.reg) and { reg1 might not be modified inbetween }
MatchInstruction(hp1, A_SXTH, [C_None], [PF_None]) and not(RegModifiedBetween(taicpu(p).oper[1]^.reg,p,hp1)) then
(taicpu(hp1).ops = 2) and begin
MatchOperand(taicpu(hp1).oper[1]^, taicpu(p).oper[0]^.reg) and DebugMsg('Peephole SxtbStrb2Strb done', p);
RegEndofLife(taicpu(p).oper[0]^.reg,taicpu(hp1)) and taicpu(hp1).loadReg(0,taicpu(p).oper[1]^.reg);
{ reg1 might not be modified inbetween } result:=RemoveCurrentP(p);
not(RegModifiedBetween(taicpu(p).oper[1]^.reg,p,hp1)) then end
begin {
DebugMsg('Peephole SxtbSxth2Sxtb done', p); change
AllocRegBetween(taicpu(hp1).oper[0]^.reg,p,hp1,UsedRegs); sxtb reg2,reg1
taicpu(p).loadReg(0,taicpu(hp1).oper[0]^.reg); sxth reg3,reg2
asml.remove(hp1); dealloc reg2
hp1.free; to
result:=true; sxtb reg3,reg1
end }
{ else if MatchInstruction(p, A_SXTB, [C_None], [PF_None]) and
change (taicpu(p).ops=2) and
sxtb reg2,reg1 MatchInstruction(hp1, A_SXTH, [C_None], [PF_None]) and
sxtb reg3,reg2 (taicpu(hp1).ops = 2) and
dealloc reg2 MatchOperand(taicpu(hp1).oper[1]^, taicpu(p).oper[0]^.reg) and
to RegEndofLife(taicpu(p).oper[0]^.reg,taicpu(hp1)) and
uxtb reg3,reg1 { reg1 might not be modified inbetween }
} not(RegModifiedBetween(taicpu(p).oper[1]^.reg,p,hp1)) then
else if MatchInstruction(p, A_SXTB, [C_None], [PF_None]) and begin
(taicpu(p).ops=2) and DebugMsg('Peephole SxtbSxth2Sxtb done', p);
GetNextInstructionUsingReg(p,hp1,taicpu(p).oper[0]^.reg) and AllocRegBetween(taicpu(hp1).oper[0]^.reg,p,hp1,UsedRegs);
MatchInstruction(hp1, A_SXTB, [C_None], [PF_None]) and taicpu(p).loadReg(0,taicpu(hp1).oper[0]^.reg);
(taicpu(hp1).ops = 2) and asml.remove(hp1);
MatchOperand(taicpu(hp1).oper[1]^, taicpu(p).oper[0]^.reg) and hp1.free;
RegEndofLife(taicpu(p).oper[0]^.reg,taicpu(hp1)) and result:=true;
{ reg1 might not be modified inbetween } end
not(RegModifiedBetween(taicpu(p).oper[1]^.reg,p,hp1)) then {
begin change
DebugMsg('Peephole SxtbSxtb2Sxtb done', p); sxtb reg2,reg1
AllocRegBetween(taicpu(hp1).oper[0]^.reg,p,hp1,UsedRegs); sxtb reg3,reg2
taicpu(p).loadReg(0,taicpu(hp1).oper[0]^.reg); dealloc reg2
asml.remove(hp1); to
hp1.free; uxtb reg3,reg1
result:=true; }
end else if MatchInstruction(p, A_SXTB, [C_None], [PF_None]) and
{ (taicpu(p).ops=2) and
change MatchInstruction(hp1, A_SXTB, [C_None], [PF_None]) and
sxtb reg2,reg1 (taicpu(hp1).ops = 2) and
and reg3,reg2,#0x*FF MatchOperand(taicpu(hp1).oper[1]^, taicpu(p).oper[0]^.reg) and
dealloc reg2 RegEndofLife(taicpu(p).oper[0]^.reg,taicpu(hp1)) and
to { reg1 might not be modified inbetween }
uxtb reg3,reg1 not(RegModifiedBetween(taicpu(p).oper[1]^.reg,p,hp1)) then
} begin
else if MatchInstruction(p, A_SXTB, [C_None], [PF_None]) and DebugMsg('Peephole SxtbSxtb2Sxtb done', p);
(taicpu(p).ops=2) and AllocRegBetween(taicpu(hp1).oper[0]^.reg,p,hp1,UsedRegs);
GetNextInstructionUsingReg(p,hp1,taicpu(p).oper[0]^.reg) and taicpu(p).loadReg(0,taicpu(hp1).oper[0]^.reg);
MatchInstruction(hp1, A_AND, [C_None], [PF_None]) and asml.remove(hp1);
(taicpu(hp1).ops=3) and hp1.free;
(taicpu(hp1).oper[2]^.typ=top_const) and result:=true;
((taicpu(hp1).oper[2]^.val and $FF)=$FF) and end
MatchOperand(taicpu(hp1).oper[1]^, taicpu(p).oper[0]^.reg) and {
RegEndofLife(taicpu(p).oper[0]^.reg,taicpu(hp1)) and change
{ reg1 might not be modified inbetween } sxtb reg2,reg1
not(RegModifiedBetween(taicpu(p).oper[1]^.reg,p,hp1)) then and reg3,reg2,#0x*FF
begin dealloc reg2
DebugMsg('Peephole SxtbAndImm2Uxtb done', p); to
taicpu(hp1).opcode:=A_UXTB; uxtb reg3,reg1
taicpu(hp1).ops:=2; }
taicpu(hp1).loadReg(1,taicpu(p).oper[1]^.reg); else if MatchInstruction(p, A_SXTB, [C_None], [PF_None]) and
result:=RemoveCurrentP(p); (taicpu(p).ops=2) and
end MatchInstruction(hp1, A_AND, [C_None], [PF_None]) and
else if GetNextInstructionUsingReg(p, hp1, taicpu(p).oper[0]^.reg) and (taicpu(hp1).ops=3) and
RemoveSuperfluousMove(p, hp1, 'SxtbMov2Sxtb') then (taicpu(hp1).oper[2]^.typ=top_const) and
Result:=true; ((taicpu(hp1).oper[2]^.val and $FF)=$FF) and
MatchOperand(taicpu(hp1).oper[1]^, taicpu(p).oper[0]^.reg) and
RegEndofLife(taicpu(p).oper[0]^.reg,taicpu(hp1)) and
{ reg1 might not be modified inbetween }
not(RegModifiedBetween(taicpu(p).oper[1]^.reg,p,hp1)) then
begin
DebugMsg('Peephole SxtbAndImm2Uxtb done', p);
taicpu(hp1).opcode:=A_UXTB;
taicpu(hp1).ops:=2;
taicpu(hp1).loadReg(1,taicpu(p).oper[1]^.reg);
result:=RemoveCurrentP(p);
end
else if GetNextInstructionUsingReg(p, hp1, taicpu(p).oper[0]^.reg) and
RemoveSuperfluousMove(p, hp1, 'SxtbMov2Sxtb') then
Result:=true;
end;
end; end;
@ -925,107 +921,106 @@ Implementation
hp1: tai; hp1: tai;
begin begin
Result:=false; Result:=false;
{ if GetNextInstructionUsingReg(p,hp1,taicpu(p).oper[0]^.reg) then
change
sxth reg2,reg1
strh reg2,[...]
dealloc reg2
to
strh reg1,[...]
}
if MatchInstruction(p, taicpu(p).opcode, [C_None], [PF_None]) and
(taicpu(p).ops=2) and
GetNextInstructionUsingReg(p,hp1,taicpu(p).oper[0]^.reg) and
MatchInstruction(hp1, A_STR, [C_None], [PF_H]) and
RegEndofLife(taicpu(p).oper[0]^.reg,taicpu(hp1)) and
{ the reference in strb might not use reg2 }
not(RegInRef(taicpu(p).oper[0]^.reg,taicpu(hp1).oper[1]^.ref^)) and
{ reg1 might not be modified inbetween }
not(RegModifiedBetween(taicpu(p).oper[1]^.reg,p,hp1)) then
begin begin
DebugMsg('Peephole SxthStrh2Strh done', p); {
taicpu(hp1).loadReg(0,taicpu(p).oper[1]^.reg); change
result:=RemoveCurrentP(p); sxth reg2,reg1
end strh reg2,[...]
{ dealloc reg2
change to
sxth reg2,reg1 strh reg1,[...]
sxth reg3,reg2 }
dealloc reg2 if MatchInstruction(p, taicpu(p).opcode, [C_None], [PF_None]) and
to (taicpu(p).ops=2) and
sxth reg3,reg1 MatchInstruction(hp1, A_STR, [C_None], [PF_H]) and
} RegEndofLife(taicpu(p).oper[0]^.reg,taicpu(hp1)) and
else if MatchInstruction(p, A_SXTH, [C_None], [PF_None]) and { the reference in strb might not use reg2 }
(taicpu(p).ops=2) and not(RegInRef(taicpu(p).oper[0]^.reg,taicpu(hp1).oper[1]^.ref^)) and
GetNextInstructionUsingReg(p,hp1,taicpu(p).oper[0]^.reg) and { reg1 might not be modified inbetween }
MatchInstruction(hp1, A_SXTH, [C_None], [PF_None]) and not(RegModifiedBetween(taicpu(p).oper[1]^.reg,p,hp1)) then
(taicpu(hp1).ops=2) and begin
MatchOperand(taicpu(hp1).oper[1]^, taicpu(p).oper[0]^.reg) and DebugMsg('Peephole SxthStrh2Strh done', p);
RegEndofLife(taicpu(p).oper[0]^.reg,taicpu(hp1)) and taicpu(hp1).loadReg(0,taicpu(p).oper[1]^.reg);
{ reg1 might not be modified inbetween } result:=RemoveCurrentP(p);
not(RegModifiedBetween(taicpu(p).oper[1]^.reg,p,hp1)) then end
begin {
DebugMsg('Peephole SxthSxth2Sxth done', p); change
AllocRegBetween(taicpu(p).oper[1]^.reg,p,hp1,UsedRegs); sxth reg2,reg1
taicpu(hp1).opcode:=A_SXTH; sxth reg3,reg2
taicpu(hp1).loadReg(1,taicpu(p).oper[1]^.reg); dealloc reg2
result:=RemoveCurrentP(p); to
end sxth reg3,reg1
}
else if MatchInstruction(p, A_SXTH, [C_None], [PF_None]) and
(taicpu(p).ops=2) and
MatchInstruction(hp1, A_SXTH, [C_None], [PF_None]) and
(taicpu(hp1).ops=2) and
MatchOperand(taicpu(hp1).oper[1]^, taicpu(p).oper[0]^.reg) and
RegEndofLife(taicpu(p).oper[0]^.reg,taicpu(hp1)) and
{ reg1 might not be modified inbetween }
not(RegModifiedBetween(taicpu(p).oper[1]^.reg,p,hp1)) then
begin
DebugMsg('Peephole SxthSxth2Sxth done', p);
AllocRegBetween(taicpu(p).oper[1]^.reg,p,hp1,UsedRegs);
taicpu(hp1).opcode:=A_SXTH;
taicpu(hp1).loadReg(1,taicpu(p).oper[1]^.reg);
result:=RemoveCurrentP(p);
end
{$ifdef AARCH64} {$ifdef AARCH64}
{ {
change change
sxth reg2,reg1 sxth reg2,reg1
sxtw reg3,reg2 sxtw reg3,reg2
dealloc reg2 dealloc reg2
to to
sxth reg3,reg1 sxth reg3,reg1
} }
else if MatchInstruction(p, A_SXTH, [C_None], [PF_None]) and else if MatchInstruction(p, A_SXTH, [C_None], [PF_None]) and
(taicpu(p).ops=2) and (taicpu(p).ops=2) and
GetNextInstructionUsingReg(p,hp1,taicpu(p).oper[0]^.reg) and MatchInstruction(hp1, A_SXTW, [C_None], [PF_None]) and
MatchInstruction(hp1, A_SXTW, [C_None], [PF_None]) and (taicpu(hp1).ops=2) and
(taicpu(hp1).ops=2) and MatchOperand(taicpu(hp1).oper[1]^, taicpu(p).oper[0]^.reg) and
MatchOperand(taicpu(hp1).oper[1]^, taicpu(p).oper[0]^.reg) and RegEndofLife(taicpu(p).oper[0]^.reg,taicpu(hp1)) and
RegEndofLife(taicpu(p).oper[0]^.reg,taicpu(hp1)) and { reg1 might not be modified inbetween }
{ reg1 might not be modified inbetween } not(RegModifiedBetween(taicpu(p).oper[1]^.reg,p,hp1)) then
not(RegModifiedBetween(taicpu(p).oper[1]^.reg,p,hp1)) then begin
begin DebugMsg('Peephole SxthSxtw2Sxth done', p);
DebugMsg('Peephole SxthSxtw2Sxth done', p); AllocRegBetween(taicpu(p).oper[1]^.reg,p,hp1,UsedRegs);
AllocRegBetween(taicpu(p).oper[1]^.reg,p,hp1,UsedRegs); taicpu(hp1).opcode:=A_SXTH;
taicpu(hp1).opcode:=A_SXTH; taicpu(hp1).loadReg(1,taicpu(p).oper[1]^.reg);
taicpu(hp1).loadReg(1,taicpu(p).oper[1]^.reg); result:=RemoveCurrentP(p);
result:=RemoveCurrentP(p); end
end {$endif AARCH64}
{$endif AARCH64} {
{ change
change sxth reg2,reg1
sxth reg2,reg1 and reg3,reg2,#65535
and reg3,reg2,#65535 dealloc reg2
dealloc reg2 to
to uxth reg3,reg1
uxth reg3,reg1 }
} else if MatchInstruction(p, A_SXTH, [C_None], [PF_None]) and
else if MatchInstruction(p, A_SXTH, [C_None], [PF_None]) and (taicpu(p).ops=2) and
(taicpu(p).ops=2) and MatchInstruction(hp1, A_AND, [C_None], [PF_None]) and
GetNextInstructionUsingReg(p,hp1,taicpu(p).oper[0]^.reg) and (taicpu(hp1).ops=3) and
MatchInstruction(hp1, A_AND, [C_None], [PF_None]) and (taicpu(hp1).oper[2]^.typ=top_const) and
(taicpu(hp1).ops=3) and ((taicpu(hp1).oper[2]^.val and $FFFF)=$FFFF) and
(taicpu(hp1).oper[2]^.typ=top_const) and MatchOperand(taicpu(hp1).oper[1]^, taicpu(p).oper[0]^.reg) and
((taicpu(hp1).oper[2]^.val and $FFFF)=$FFFF) and RegEndofLife(taicpu(p).oper[0]^.reg,taicpu(hp1)) and
MatchOperand(taicpu(hp1).oper[1]^, taicpu(p).oper[0]^.reg) and { reg1 might not be modified inbetween }
RegEndofLife(taicpu(p).oper[0]^.reg,taicpu(hp1)) and not(RegModifiedBetween(taicpu(p).oper[1]^.reg,p,hp1)) then
{ reg1 might not be modified inbetween } begin
not(RegModifiedBetween(taicpu(p).oper[1]^.reg,p,hp1)) then DebugMsg('Peephole SxthAndImm2Uxth done', p);
begin taicpu(hp1).opcode:=A_UXTH;
DebugMsg('Peephole SxthAndImm2Uxth done', p); taicpu(hp1).ops:=2;
taicpu(hp1).opcode:=A_UXTH; taicpu(hp1).loadReg(1,taicpu(p).oper[1]^.reg);
taicpu(hp1).ops:=2; result:=RemoveCurrentP(p);
taicpu(hp1).loadReg(1,taicpu(p).oper[1]^.reg); end
result:=RemoveCurrentP(p); else if GetNextInstructionUsingReg(p, hp1, taicpu(p).oper[0]^.reg) and
end RemoveSuperfluousMove(p, hp1, 'SxthMov2Sxth') then
else if GetNextInstructionUsingReg(p, hp1, taicpu(p).oper[0]^.reg) and Result:=true;
RemoveSuperfluousMove(p, hp1, 'SxthMov2Sxth') then end;
Result:=true;
end; end;