From d6ff4ed9673ab5a0cd0ec8fd4c1df23429755d17 Mon Sep 17 00:00:00 2001 From: "J. Gareth \"Curious Kit\" Moreton" Date: Sun, 15 May 2022 20:29:55 +0100 Subject: [PATCH] * arm/a64: New sbfx/ubfx -> mov optimisation --- compiler/aarch64/aoptcpu.pas | 17 +++++++++++++++ compiler/arm/aoptcpu.pas | 17 +++++++++++++++ compiler/armgen/aoptarm.pas | 41 ++++++++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+) diff --git a/compiler/aarch64/aoptcpu.pas b/compiler/aarch64/aoptcpu.pas index edbe6d2e71..c289650eaf 100644 --- a/compiler/aarch64/aoptcpu.pas +++ b/compiler/aarch64/aoptcpu.pas @@ -40,6 +40,7 @@ Interface Type TCpuAsmOptimizer = class(TARMAsmOptimizer) { uses the same constructor as TAopObj } + function PrePeepHoleOptsCpu(var p: tai): boolean; override; function PeepHoleOptPass1Cpu(var p: tai): boolean; override; function PeepHoleOptPass2Cpu(var p: tai): boolean; override; function PostPeepHoleOptsCpu(var p: tai): boolean; override; @@ -945,6 +946,22 @@ Implementation end; + function TCpuAsmOptimizer.PrePeepHoleOptsCpu(var p: tai): boolean; + begin + result := false; + if p.typ=ait_instruction then + begin + case taicpu(p).opcode of + A_SBFX, + A_UBFX: + Result:=OptPreSBFXUBFX(p); + else + ; + end; + end; + end; + + function TCpuAsmOptimizer.PeepHoleOptPass1Cpu(var p: tai): boolean; begin result := false; diff --git a/compiler/arm/aoptcpu.pas b/compiler/arm/aoptcpu.pas index 4a3ef1e596..f7444321ae 100644 --- a/compiler/arm/aoptcpu.pas +++ b/compiler/arm/aoptcpu.pas @@ -44,6 +44,7 @@ Type function CanDoJumpOpts: Boolean; override; { uses the same constructor as TAopObj } + function PrePeepHoleOptsCpu(var p: tai): Boolean; override; function PeepHoleOptPass1Cpu(var p: tai): boolean; override; function PeepHoleOptPass2Cpu(var p: tai): boolean; override; Function RegInInstruction(Reg: TRegister; p1: tai): Boolean;override; @@ -2280,6 +2281,22 @@ Implementation end; + function TCpuAsmOptimizer.PrePeepHoleOptsCpu(var p: tai): Boolean; + begin + result := false; + if p.typ=ait_instruction then + begin + case taicpu(p).opcode of + A_SBFX, + A_UBFX: + Result:=OptPreSBFXUBFX(p); + else + ; + end; + end; + end; + + function TCpuAsmOptimizer.PeepHoleOptPass1Cpu(var p: tai): boolean; begin result := false; diff --git a/compiler/armgen/aoptarm.pas b/compiler/armgen/aoptarm.pas index 9c0ae62699..01023dda99 100644 --- a/compiler/armgen/aoptarm.pas +++ b/compiler/armgen/aoptarm.pas @@ -45,11 +45,14 @@ Type function RedundantMovProcess(var p: tai; var hp1: tai): boolean; function GetNextInstructionUsingReg(Current: tai; out Next: tai; const reg: TRegister): Boolean; + function OptPreSBFXUBFX(var p: tai): Boolean; + function OptPass1UXTB(var p: tai): Boolean; function OptPass1UXTH(var p: tai): Boolean; function OptPass1SXTB(var p: tai): Boolean; function OptPass1SXTH(var p: tai): Boolean; + function OptPass1LDR(var p: tai): Boolean; virtual; function OptPass1STR(var p: tai): Boolean; virtual; function OptPass1And(var p: tai): Boolean; virtual; @@ -1070,6 +1073,44 @@ Implementation end; + function TARMAsmOptimizer.OptPreSBFXUBFX(var p: tai): Boolean; + begin + Result := False; + { Convert: + s/ubfx reg1,reg2,#0,#64 (or #32 for 32-bit registers) + To: + mov reg1,reg2 + } + if (taicpu(p).oper[2]^.val = 0) and +{$ifdef AARCH64} + ( + ( + (getsubreg(taicpu(p).oper[0]^.reg) = R_SUBQ) and + (taicpu(p).oper[3]^.val = 64) + ) or + ( + (getsubreg(taicpu(p).oper[0]^.reg) = R_SUBD) and + (taicpu(p).oper[3]^.val = 32) + ) + ) +{$else AARCH64} + (taicpu(p).oper[3]^.val = 32) +{$endif AARCH64} + then + begin + DebugMsg(SPeepholeOptimization + 'SBFX or UBFX -> MOV (full bitfield extract)', p); + taicpu(p).opcode := A_MOV; + taicpu(p).ops := 2; + taicpu(p).clearop(2); + taicpu(p).clearop(3); + + Result := True; + Exit; + end; + + end; + + function TARMAsmOptimizer.OptPass1LDR(var p : tai) : Boolean; var hp1: tai;