From afb68dbcf35ecfb9a3b5671ae481981423b4e0e5 Mon Sep 17 00:00:00 2001 From: florian Date: Sun, 24 May 2020 17:52:07 +0000 Subject: [PATCH] * factored out OptPass1VPXor git-svn-id: trunk@45487 - --- compiler/i386/aoptcpu.pas | 3 ++- compiler/x86/aoptx86.pas | 54 +++++++++++++++++++++++++++++++++++-- compiler/x86_64/aoptcpu.pas | 3 ++- 3 files changed, 56 insertions(+), 4 deletions(-) diff --git a/compiler/i386/aoptcpu.pas b/compiler/i386/aoptcpu.pas index b6d5da1eb0..13db1f0870 100644 --- a/compiler/i386/aoptcpu.pas +++ b/compiler/i386/aoptcpu.pas @@ -141,7 +141,8 @@ unit aoptcpu; Result:=OptPass1And(p); A_CMP: Result:=OptPass1Cmp(p); - A_VPXOR, + A_VPXOR: + Result:=OptPass1VPXor(p); A_PXOR: Result:=OptPass1PXor(p); A_FLD: diff --git a/compiler/x86/aoptx86.pas b/compiler/x86/aoptx86.pas index 9038e07740..a3e050349d 100644 --- a/compiler/x86/aoptx86.pas +++ b/compiler/x86/aoptx86.pas @@ -133,6 +133,7 @@ unit aoptx86; function OptPass1FLD(var p : tai) : boolean; function OptPass1Cmp(var p : tai) : boolean; function OptPass1PXor(var p : tai) : boolean; + function OptPass1VPXor(var p: tai): boolean; function OptPass2MOV(var p : tai) : boolean; function OptPass2Imul(var p : tai) : boolean; @@ -167,6 +168,9 @@ unit aoptx86; function MatchOperand(const oper: TOper; const reg: TRegister): boolean; inline; function MatchOperand(const oper: TOper; const a: tcgint): boolean; inline; function MatchOperand(const oper1: TOper; const oper2: TOper): boolean; +{$if max_operands>2} + function MatchOperand(const oper1: TOper; const oper2: TOper; const oper3: TOper): boolean; +{$endif max_operands>2} function RefsEqual(const r1, r2: treference): boolean; @@ -282,6 +286,24 @@ unit aoptx86; end; + function MatchOperand(const oper1: TOper; const oper2: TOper; const oper3: TOper): boolean; + begin + result := (oper1.typ = oper2.typ) and (oper1.typ = oper3.typ); + + if result then + case oper1.typ of + top_const: + Result:=(oper1.val = oper2.val) and (oper1.val = oper3.val); + top_reg: + Result:=(oper1.reg = oper2.reg) and (oper1.reg = oper3.reg); + top_ref: + Result:=RefsEqual(oper1.ref^, oper2.ref^) and RefsEqual(oper1.ref^, oper3.ref^); + else + internalerror(2020052401); + end + end; + + function RefsEqual(const r1, r2: treference): boolean; begin RefsEqual := @@ -3960,9 +3982,9 @@ unit aoptx86; { remove the second (v)pxor from - (v)pxor reg,reg + pxor reg,reg ... - (v)pxor reg,reg + pxor reg,reg } Result:=false; if MatchOperand(taicpu(p).oper[0]^,taicpu(p).oper[1]^) and @@ -3981,6 +4003,34 @@ unit aoptx86; end; + function TX86AsmOptimizer.OptPass1VPXor(var p: tai): boolean; + var + hp1: tai; + begin + { + remove the second (v)pxor from + + (v)pxor reg,reg + ... + (v)pxor reg,reg + } + Result:=false; + if MatchOperand(taicpu(p).oper[0]^,taicpu(p).oper[1]^,taicpu(p).oper[2]^) and + MatchOpType(taicpu(p),top_reg,top_reg,top_reg) and + GetNextInstructionUsingReg(p,hp1,taicpu(p).oper[0]^.reg) and + MatchInstruction(taicpu(hp1),taicpu(p).opcode,[taicpu(p).opsize]) and + MatchOperand(taicpu(p).oper[0]^,taicpu(hp1).oper[0]^) and + MatchOperand(taicpu(hp1).oper[0]^,taicpu(hp1).oper[1]^,taicpu(hp1).oper[2]^) then + begin + DebugMsg(SPeepholeOptimization + 'VPXorVPXor2PXor done',hp1); + asml.Remove(hp1); + hp1.Free; + Result:=true; + Exit; + end; + end; + + function TX86AsmOptimizer.OptPass2MOV(var p : tai) : boolean; function IsXCHGAcceptable: Boolean; inline; diff --git a/compiler/x86_64/aoptcpu.pas b/compiler/x86_64/aoptcpu.pas index a8d0819a71..e5bf72b6de 100644 --- a/compiler/x86_64/aoptcpu.pas +++ b/compiler/x86_64/aoptcpu.pas @@ -127,7 +127,8 @@ uses result:=OptPass1FLD(p); A_CMP: result:=OptPass1Cmp(p); - A_VPXOR, + A_VPXOR: + Result:=OptPass1VPXor(p); A_PXOR: Result:=OptPass1PXor(p); else