From 020ca55e257c3b3f354211dbeb9f992730578d99 Mon Sep 17 00:00:00 2001 From: Karoly Balogh Date: Mon, 8 Jan 2024 15:06:38 +0100 Subject: [PATCH] m68k: add more cases, where TST instructions can beoptimized away, because the previous instruction already sets all the required flags --- compiler/m68k/aoptcpu.pas | 59 ++++++++++++++++++++++++++++----------- 1 file changed, 43 insertions(+), 16 deletions(-) diff --git a/compiler/m68k/aoptcpu.pas b/compiler/m68k/aoptcpu.pas index 8f4120decc..b292821073 100644 --- a/compiler/m68k/aoptcpu.pas +++ b/compiler/m68k/aoptcpu.pas @@ -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