From 9176efbab4ef437703b08d88958ab3506accaca0 Mon Sep 17 00:00:00 2001 From: florian Date: Thu, 16 Apr 2020 21:19:14 +0000 Subject: [PATCH] * factored out TARMAsmOptimizer.OptPass1SXTH * AArch64: use TARMAsmOptimizer.OptPass1SXTH git-svn-id: trunk@44739 - --- compiler/aarch64/aoptcpu.pas | 2 + compiler/arm/aoptcpu.pas | 90 +--------------------------------- compiler/armgen/aoptarm.pas | 95 ++++++++++++++++++++++++++++++++++++ 3 files changed, 98 insertions(+), 89 deletions(-) diff --git a/compiler/aarch64/aoptcpu.pas b/compiler/aarch64/aoptcpu.pas index 450bbbcbc8..d3dc440481 100644 --- a/compiler/aarch64/aoptcpu.pas +++ b/compiler/aarch64/aoptcpu.pas @@ -378,6 +378,8 @@ Implementation Result:=OptPass1UXTB(p); A_SXTB: Result:=OptPass1SXTB(p); + A_SXTH: + Result:=OptPass1SXTH(p); else ; end; diff --git a/compiler/arm/aoptcpu.pas b/compiler/arm/aoptcpu.pas index 113a896b2a..9be9c9b1ce 100644 --- a/compiler/arm/aoptcpu.pas +++ b/compiler/arm/aoptcpu.pas @@ -1896,95 +1896,7 @@ Implementation A_SXTB: Result:=OptPass1SXTB(p); A_SXTH: - begin - { - 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 - DebugMsg('Peephole SXTHStrh2Strh done', p); - taicpu(hp1).loadReg(0,taicpu(p).oper[1]^.reg); - GetNextInstruction(p, hp1); - asml.remove(p); - p.free; - p:=hp1; - result:=true; - end - { - change - sxth reg2,reg1 - sxth reg3,reg2 - dealloc reg2 - to - sxth reg3,reg1 - } - else if MatchInstruction(p, A_SXTH, [C_None], [PF_None]) and - (taicpu(p).ops=2) and - GetNextInstructionUsingReg(p,hp1,taicpu(p).oper[0]^.reg) 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); - GetNextInstruction(p, hp1); - asml.remove(p); - p.free; - p:=hp1; - result:=true; - end - { - change - sxth reg2,reg1 - and reg3,reg2,#65535 - dealloc reg2 - to - sxth reg3,reg1 - } - else if MatchInstruction(p, A_SXTH, [C_None], [PF_None]) and - (taicpu(p).ops=2) and - GetNextInstructionUsingReg(p,hp1,taicpu(p).oper[0]^.reg) and - MatchInstruction(hp1, A_AND, [C_None], [PF_None]) and - (taicpu(hp1).ops=3) and - (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 SxthAndImm2Sxth done', p); - taicpu(hp1).opcode:=A_SXTH; - taicpu(hp1).ops:=2; - taicpu(hp1).loadReg(1,taicpu(p).oper[1]^.reg); - GetNextInstruction(p, hp1); - asml.remove(p); - p.free; - p:=hp1; - result:=true; - end - else if GetNextInstructionUsingReg(p, hp1, taicpu(p).oper[0]^.reg) and - RemoveSuperfluousMove(p, hp1, 'SxthMov2Data') then - Result:=true; - end; + Result:=OptPass1SXTH(p); A_CMP: begin { diff --git a/compiler/armgen/aoptarm.pas b/compiler/armgen/aoptarm.pas index 98f1a94939..3112dd7f23 100644 --- a/compiler/armgen/aoptarm.pas +++ b/compiler/armgen/aoptarm.pas @@ -45,6 +45,7 @@ Type function OptPass1UXTB(var p: tai): Boolean; function OptPass1UXTH(var p: tai): Boolean; function OptPass1SXTB(var p: tai): Boolean; + function OptPass1SXTH(var p: tai): Boolean; End; function MatchInstruction(const instr: tai; const op: TCommonAsmOps; const cond: TAsmConds; const postfix: TOpPostfixes): boolean; @@ -597,5 +598,99 @@ Implementation Result:=true; end; + + function TARMAsmOptimizer.OptPass1SXTH(var p : tai) : Boolean; + var + hp1: tai; + begin + Result:=false; + { + 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 + DebugMsg('Peephole SXTHStrh2Strh done', p); + taicpu(hp1).loadReg(0,taicpu(p).oper[1]^.reg); + GetNextInstruction(p, hp1); + asml.remove(p); + p.free; + p:=hp1; + result:=true; + end + { + change + sxth reg2,reg1 + sxth reg3,reg2 + dealloc reg2 + to + sxth reg3,reg1 + } + else if MatchInstruction(p, A_SXTH, [C_None], [PF_None]) and + (taicpu(p).ops=2) and + GetNextInstructionUsingReg(p,hp1,taicpu(p).oper[0]^.reg) 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); + GetNextInstruction(p, hp1); + asml.remove(p); + p.free; + p:=hp1; + result:=true; + end + { + change + sxth reg2,reg1 + and reg3,reg2,#65535 + dealloc reg2 + to + sxth reg3,reg1 + } + else if MatchInstruction(p, A_SXTH, [C_None], [PF_None]) and + (taicpu(p).ops=2) and + GetNextInstructionUsingReg(p,hp1,taicpu(p).oper[0]^.reg) and + MatchInstruction(hp1, A_AND, [C_None], [PF_None]) and + (taicpu(hp1).ops=3) and + (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 SxthAndImm2Sxth done', p); + taicpu(hp1).opcode:=A_SXTH; + taicpu(hp1).ops:=2; + taicpu(hp1).loadReg(1,taicpu(p).oper[1]^.reg); + GetNextInstruction(p, hp1); + asml.remove(p); + p.free; + p:=hp1; + result:=true; + end + else if GetNextInstructionUsingReg(p, hp1, taicpu(p).oper[0]^.reg) and + RemoveSuperfluousMove(p, hp1, 'SxthMov2Data') then + Result:=true; + end; end.