mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-10 22:26:00 +02:00
m68k: add more cases, where TST instructions can beoptimized away, because the previous instruction already sets all the required flags
This commit is contained in:
parent
3c57eb42f9
commit
020ca55e25
@ -38,10 +38,12 @@ unit aoptcpu;
|
||||
function RegLoadedWithNewValue(reg: tregister; hp: tai): boolean; override;
|
||||
function PeepHoleOptPass1Cpu(var p: tai): boolean; override;
|
||||
|
||||
function TryToRemoveTST(var p: tai): boolean;
|
||||
function TryToOptimizeMove(var p: tai): boolean;
|
||||
function MaybeRealConstOperSimplify(var p: tai): boolean;
|
||||
function OptPass1LEA(var p: tai): Boolean;
|
||||
function OptPass1MOVEM(var p: tai): Boolean;
|
||||
function OptPass1Bitwise(var p: tai): Boolean;
|
||||
|
||||
{ outputs a debug message into the assembler file }
|
||||
procedure DebugMsg(const s: string; p: tai);
|
||||
@ -217,6 +219,29 @@ unit aoptcpu;
|
||||
end;
|
||||
{$endif DEBUG_AOPTCPU}
|
||||
|
||||
function TCpuAsmOptimizer.TryToRemoveTST(var p: tai): boolean;
|
||||
var
|
||||
next, next2: tai;
|
||||
opstr: string[15];
|
||||
begin
|
||||
result:=false;
|
||||
|
||||
if not((taicpu(p).oper[1]^.typ=top_reg) and isaddressregister(taicpu(p).oper[1]^.reg)) and
|
||||
GetNextInstruction(p,next) and
|
||||
MatchInstruction(next,A_TST,[taicpu(p).opsize]) and
|
||||
MatchOperand(taicpu(p).oper[1]^,taicpu(next).oper[0]^) and
|
||||
GetNextInstruction(next,next2) and
|
||||
MatchInstruction(next2,[A_BXX,A_SXX],[S_NO]) and
|
||||
(taicpu(next2).condition in [C_NE,C_EQ,C_PL,C_MI]) then
|
||||
begin
|
||||
opstr:=opname(p);
|
||||
DebugMsg('Optimizer: '+opstr+', TST, Jxx/Sxx to '+opstr+', Jxx/Sxx',p);
|
||||
asml.remove(next);
|
||||
next.free;
|
||||
result:=true;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TCpuAsmOptimizer.TryToOptimizeMove(var p: tai): boolean;
|
||||
var
|
||||
next, next2: tai;
|
||||
@ -224,21 +249,11 @@ unit aoptcpu;
|
||||
begin
|
||||
result:=false;
|
||||
|
||||
if (taicpu(p).opcode=A_MOVE) and
|
||||
GetNextInstruction(p,next) and
|
||||
MatchInstruction(next,A_TST,[taicpu(p).opsize]) and
|
||||
MatchOperand(taicpu(p).oper[1]^,taicpu(next).oper[0]^) and
|
||||
{ for movea, it won't work }
|
||||
not((taicpu(p).oper[1]^.typ=top_reg) and isaddressregister(taicpu(p).oper[1]^.reg)) and
|
||||
GetNextInstruction(next,next2) and
|
||||
MatchInstruction(next2,[A_BXX,A_SXX],[S_NO]) and
|
||||
(taicpu(next2).condition in [C_NE,C_EQ,C_PL,C_MI]) then
|
||||
if (taicpu(p).opcode=A_MOVE) then
|
||||
begin
|
||||
DebugMsg('Optimizer: MOVE, TST, Jxx/Sxx to MOVE, Jxx',p);
|
||||
asml.remove(next);
|
||||
next.free;
|
||||
result:=true;
|
||||
exit;
|
||||
result:=TryToRemoveTST(p);
|
||||
if result then
|
||||
exit;
|
||||
end;
|
||||
if GetNextInstruction(p,next) and
|
||||
(next.typ = ait_instruction) and
|
||||
@ -426,6 +441,11 @@ unit aoptcpu;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TCpuAsmOptimizer.OptPass1Bitwise(var p: tai): Boolean;
|
||||
begin
|
||||
Result:=TryToRemoveTST(p);
|
||||
end;
|
||||
|
||||
function TCpuAsmOptimizer.PeepHoleOptPass1Cpu(var p: tai): boolean;
|
||||
var
|
||||
next: tai;
|
||||
@ -443,7 +463,10 @@ unit aoptcpu;
|
||||
A_MOVEM:
|
||||
result:=OptPass1MOVEM(p);
|
||||
A_LEA:
|
||||
Result:=OptPass1LEA(p);
|
||||
result:=OptPass1LEA(p);
|
||||
{ Bitwise operations }
|
||||
A_AND,A_OR,A_EOR:
|
||||
result:=OptPass1Bitwise(p);
|
||||
{ Address register sub/add can be replaced with ADDQ/SUBQ or LEA if the value is in the
|
||||
SmallInt range, which is shorter to encode and faster to execute on most 68k }
|
||||
A_SUB,A_SUBA,A_ADD,A_ADDA:
|
||||
@ -473,7 +496,11 @@ unit aoptcpu;
|
||||
taicpu(p).loadref(0,tmpref);
|
||||
result:=true;
|
||||
end;
|
||||
end;
|
||||
end
|
||||
else
|
||||
result:=TryToRemoveTST(p);
|
||||
A_SUBQ,A_ADDQ:
|
||||
result:=TryToRemoveTST(p);
|
||||
{ MOVEA #0,Ax to SUBA Ax,Ax, because it's shorter }
|
||||
A_MOVEA:
|
||||
if (taicpu(p).oper[0]^.typ = top_const) and
|
||||
|
Loading…
Reference in New Issue
Block a user