mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-12 07:26:24 +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 RegLoadedWithNewValue(reg: tregister; hp: tai): boolean; override;
|
||||||
function PeepHoleOptPass1Cpu(var p: tai): boolean; override;
|
function PeepHoleOptPass1Cpu(var p: tai): boolean; override;
|
||||||
|
|
||||||
|
function TryToRemoveTST(var p: tai): boolean;
|
||||||
function TryToOptimizeMove(var p: tai): boolean;
|
function TryToOptimizeMove(var p: tai): boolean;
|
||||||
function MaybeRealConstOperSimplify(var p: tai): boolean;
|
function MaybeRealConstOperSimplify(var p: tai): boolean;
|
||||||
function OptPass1LEA(var p: tai): Boolean;
|
function OptPass1LEA(var p: tai): Boolean;
|
||||||
function OptPass1MOVEM(var p: tai): Boolean;
|
function OptPass1MOVEM(var p: tai): Boolean;
|
||||||
|
function OptPass1Bitwise(var p: tai): Boolean;
|
||||||
|
|
||||||
{ outputs a debug message into the assembler file }
|
{ outputs a debug message into the assembler file }
|
||||||
procedure DebugMsg(const s: string; p: tai);
|
procedure DebugMsg(const s: string; p: tai);
|
||||||
@ -217,6 +219,29 @@ unit aoptcpu;
|
|||||||
end;
|
end;
|
||||||
{$endif DEBUG_AOPTCPU}
|
{$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;
|
function TCpuAsmOptimizer.TryToOptimizeMove(var p: tai): boolean;
|
||||||
var
|
var
|
||||||
next, next2: tai;
|
next, next2: tai;
|
||||||
@ -224,21 +249,11 @@ unit aoptcpu;
|
|||||||
begin
|
begin
|
||||||
result:=false;
|
result:=false;
|
||||||
|
|
||||||
if (taicpu(p).opcode=A_MOVE) and
|
if (taicpu(p).opcode=A_MOVE) then
|
||||||
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
|
|
||||||
begin
|
begin
|
||||||
DebugMsg('Optimizer: MOVE, TST, Jxx/Sxx to MOVE, Jxx',p);
|
result:=TryToRemoveTST(p);
|
||||||
asml.remove(next);
|
if result then
|
||||||
next.free;
|
exit;
|
||||||
result:=true;
|
|
||||||
exit;
|
|
||||||
end;
|
end;
|
||||||
if GetNextInstruction(p,next) and
|
if GetNextInstruction(p,next) and
|
||||||
(next.typ = ait_instruction) and
|
(next.typ = ait_instruction) and
|
||||||
@ -426,6 +441,11 @@ unit aoptcpu;
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TCpuAsmOptimizer.OptPass1Bitwise(var p: tai): Boolean;
|
||||||
|
begin
|
||||||
|
Result:=TryToRemoveTST(p);
|
||||||
|
end;
|
||||||
|
|
||||||
function TCpuAsmOptimizer.PeepHoleOptPass1Cpu(var p: tai): boolean;
|
function TCpuAsmOptimizer.PeepHoleOptPass1Cpu(var p: tai): boolean;
|
||||||
var
|
var
|
||||||
next: tai;
|
next: tai;
|
||||||
@ -443,7 +463,10 @@ unit aoptcpu;
|
|||||||
A_MOVEM:
|
A_MOVEM:
|
||||||
result:=OptPass1MOVEM(p);
|
result:=OptPass1MOVEM(p);
|
||||||
A_LEA:
|
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
|
{ 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 }
|
SmallInt range, which is shorter to encode and faster to execute on most 68k }
|
||||||
A_SUB,A_SUBA,A_ADD,A_ADDA:
|
A_SUB,A_SUBA,A_ADD,A_ADDA:
|
||||||
@ -473,7 +496,11 @@ unit aoptcpu;
|
|||||||
taicpu(p).loadref(0,tmpref);
|
taicpu(p).loadref(0,tmpref);
|
||||||
result:=true;
|
result:=true;
|
||||||
end;
|
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 }
|
{ MOVEA #0,Ax to SUBA Ax,Ax, because it's shorter }
|
||||||
A_MOVEA:
|
A_MOVEA:
|
||||||
if (taicpu(p).oper[0]^.typ = top_const) and
|
if (taicpu(p).oper[0]^.typ = top_const) and
|
||||||
|
Loading…
Reference in New Issue
Block a user