|
@@ -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,28 +219,41 @@ unit aoptcpu;
|
|
|
end;
|
|
|
{$endif DEBUG_AOPTCPU}
|
|
|
|
|
|
- function TCpuAsmOptimizer.TryToOptimizeMove(var p: tai): boolean;
|
|
|
+ function TCpuAsmOptimizer.TryToRemoveTST(var p: tai): boolean;
|
|
|
var
|
|
|
next, next2: tai;
|
|
|
opstr: string[15];
|
|
|
begin
|
|
|
result:=false;
|
|
|
|
|
|
- if (taicpu(p).opcode=A_MOVE) and
|
|
|
+ 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
|
|
|
- { 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
|
|
|
- DebugMsg('Optimizer: MOVE, TST, Jxx/Sxx to MOVE, Jxx',p);
|
|
|
+ opstr:=opname(p);
|
|
|
+ DebugMsg('Optimizer: '+opstr+', TST, Jxx/Sxx to '+opstr+', Jxx/Sxx',p);
|
|
|
asml.remove(next);
|
|
|
next.free;
|
|
|
result:=true;
|
|
|
- exit;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+
|
|
|
+ function TCpuAsmOptimizer.TryToOptimizeMove(var p: tai): boolean;
|
|
|
+ var
|
|
|
+ next, next2: tai;
|
|
|
+ opstr: string[15];
|
|
|
+ begin
|
|
|
+ result:=false;
|
|
|
+
|
|
|
+ if (taicpu(p).opcode=A_MOVE) then
|
|
|
+ begin
|
|
|
+ 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
|