mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-14 10:49:09 +02:00
* factored out PrePeepholeOptSxx
+ x86-64 uses PrePeepholeOptSxx now as well git-svn-id: trunk@36158 -
This commit is contained in:
parent
9fc420b546
commit
06c4c651fd
@ -607,67 +607,9 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
A_SAR, A_SHR:
|
A_SAR,A_SHR:
|
||||||
{changes the code sequence
|
if PrePeepholeOptSxx(p) then
|
||||||
shr/sar const1, x
|
continue;
|
||||||
shl const2, x
|
|
||||||
to either "sar/and", "shl/and" or just "and" depending on const1 and const2}
|
|
||||||
begin
|
|
||||||
if GetNextInstruction(p, hp1) and
|
|
||||||
(tai(hp1).typ = ait_instruction) and
|
|
||||||
(taicpu(hp1).opcode = A_SHL) and
|
|
||||||
(taicpu(p).oper[0]^.typ = top_const) and
|
|
||||||
(taicpu(hp1).oper[0]^.typ = top_const) and
|
|
||||||
(taicpu(hp1).opsize = taicpu(p).opsize) and
|
|
||||||
(taicpu(hp1).oper[1]^.typ = taicpu(p).oper[1]^.typ) and
|
|
||||||
OpsEqual(taicpu(hp1).oper[1]^, taicpu(p).oper[1]^) then
|
|
||||||
if (taicpu(p).oper[0]^.val > taicpu(hp1).oper[0]^.val) and
|
|
||||||
not(cs_opt_size in current_settings.optimizerswitches) then
|
|
||||||
{ shr/sar const1, %reg
|
|
||||||
shl const2, %reg
|
|
||||||
with const1 > const2 }
|
|
||||||
begin
|
|
||||||
taicpu(p).loadConst(0,taicpu(p).oper[0]^.val-taicpu(hp1).oper[0]^.val);
|
|
||||||
taicpu(hp1).opcode := A_AND;
|
|
||||||
l := (1 shl (taicpu(hp1).oper[0]^.val)) - 1;
|
|
||||||
case taicpu(p).opsize Of
|
|
||||||
S_L: taicpu(hp1).loadConst(0,l Xor aint($ffffffff));
|
|
||||||
S_B: taicpu(hp1).loadConst(0,l Xor $ff);
|
|
||||||
S_W: taicpu(hp1).loadConst(0,l Xor $ffff);
|
|
||||||
end;
|
|
||||||
end
|
|
||||||
else if (taicpu(p).oper[0]^.val<taicpu(hp1).oper[0]^.val) and
|
|
||||||
not(cs_opt_size in current_settings.optimizerswitches) then
|
|
||||||
{ shr/sar const1, %reg
|
|
||||||
shl const2, %reg
|
|
||||||
with const1 < const2 }
|
|
||||||
begin
|
|
||||||
taicpu(hp1).loadConst(0,taicpu(hp1).oper[0]^.val-taicpu(p).oper[0]^.val);
|
|
||||||
taicpu(p).opcode := A_AND;
|
|
||||||
l := (1 shl (taicpu(p).oper[0]^.val))-1;
|
|
||||||
case taicpu(p).opsize Of
|
|
||||||
S_L: taicpu(p).loadConst(0,l Xor aint($ffffffff));
|
|
||||||
S_B: taicpu(p).loadConst(0,l Xor $ff);
|
|
||||||
S_W: taicpu(p).loadConst(0,l Xor $ffff);
|
|
||||||
end;
|
|
||||||
end
|
|
||||||
else
|
|
||||||
{ shr/sar const1, %reg
|
|
||||||
shl const2, %reg
|
|
||||||
with const1 = const2 }
|
|
||||||
if (taicpu(p).oper[0]^.val = taicpu(hp1).oper[0]^.val) then
|
|
||||||
begin
|
|
||||||
taicpu(p).opcode := A_AND;
|
|
||||||
l := (1 shl (taicpu(p).oper[0]^.val))-1;
|
|
||||||
case taicpu(p).opsize Of
|
|
||||||
S_B: taicpu(p).loadConst(0,l Xor $ff);
|
|
||||||
S_W: taicpu(p).loadConst(0,l Xor $ffff);
|
|
||||||
S_L: taicpu(p).loadConst(0,l Xor aint($ffffffff));
|
|
||||||
end;
|
|
||||||
asml.remove(hp1);
|
|
||||||
hp1.free;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
A_XOR:
|
A_XOR:
|
||||||
if (taicpu(p).oper[0]^.typ = top_reg) and
|
if (taicpu(p).oper[0]^.typ = top_reg) and
|
||||||
(taicpu(p).oper[1]^.typ = top_reg) and
|
(taicpu(p).oper[1]^.typ = top_reg) and
|
||||||
|
@ -46,7 +46,14 @@ unit aoptx86;
|
|||||||
depend on the value in AH). }
|
depend on the value in AH). }
|
||||||
function Reg1ReadDependsOnReg2(reg1, reg2: tregister): boolean;
|
function Reg1ReadDependsOnReg2(reg1, reg2: tregister): boolean;
|
||||||
|
|
||||||
procedure PostPeepholeOptMov(const p : tai);
|
procedure DebugMsg(const s : string; p : tai);inline;
|
||||||
|
|
||||||
|
procedure AllocRegBetween(reg : tregister; p1,p2 : tai;var initialusedregs : TAllUsedRegs);
|
||||||
|
class function IsExitCode(p : tai) : boolean;
|
||||||
|
class function isFoldableArithOp(hp1 : taicpu; reg : tregister) : boolean;
|
||||||
|
procedure RemoveLastDeallocForFuncRes(p : tai);
|
||||||
|
|
||||||
|
function PrePeepholeOptSxx(var p : tai) : boolean;
|
||||||
|
|
||||||
function OptPass1AND(var p : tai) : boolean;
|
function OptPass1AND(var p : tai) : boolean;
|
||||||
function OptPass1VMOVAP(var p : tai) : boolean;
|
function OptPass1VMOVAP(var p : tai) : boolean;
|
||||||
@ -58,12 +65,7 @@ unit aoptx86;
|
|||||||
function OptPass2Jmp(var p : tai) : boolean;
|
function OptPass2Jmp(var p : tai) : boolean;
|
||||||
function OptPass2Jcc(var p : tai) : boolean;
|
function OptPass2Jcc(var p : tai) : boolean;
|
||||||
|
|
||||||
procedure DebugMsg(const s : string; p : tai);inline;
|
procedure PostPeepholeOptMov(const p : tai);
|
||||||
|
|
||||||
procedure AllocRegBetween(reg : tregister; p1,p2 : tai;var initialusedregs : TAllUsedRegs);
|
|
||||||
class function IsExitCode(p : tai) : boolean;
|
|
||||||
class function isFoldableArithOp(hp1 : taicpu; reg : tregister) : boolean;
|
|
||||||
procedure RemoveLastDeallocForFuncRes(p : tai);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function MatchInstruction(const instr: tai; const op: TAsmOp; const opsize: topsizes): boolean;
|
function MatchInstruction(const instr: tai; const op: TAsmOp; const opsize: topsizes): boolean;
|
||||||
@ -284,6 +286,85 @@ unit aoptx86;
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function TX86AsmOptimizer.PrePeepholeOptSxx(var p : tai) : boolean;
|
||||||
|
var
|
||||||
|
hp1 : tai;
|
||||||
|
l : TCGInt;
|
||||||
|
begin
|
||||||
|
result:=false;
|
||||||
|
{ changes the code sequence
|
||||||
|
shr/sar const1, x
|
||||||
|
shl const2, x
|
||||||
|
|
||||||
|
to
|
||||||
|
|
||||||
|
either "sar/and", "shl/and" or just "and" depending on const1 and const2 }
|
||||||
|
if GetNextInstruction(p, hp1) and
|
||||||
|
MatchInstruction(hp1,A_SHL,[]) and
|
||||||
|
(taicpu(p).oper[0]^.typ = top_const) and
|
||||||
|
(taicpu(hp1).oper[0]^.typ = top_const) and
|
||||||
|
(taicpu(hp1).opsize = taicpu(p).opsize) and
|
||||||
|
(taicpu(hp1).oper[1]^.typ = taicpu(p).oper[1]^.typ) and
|
||||||
|
OpsEqual(taicpu(hp1).oper[1]^, taicpu(p).oper[1]^) then
|
||||||
|
begin
|
||||||
|
if (taicpu(p).oper[0]^.val > taicpu(hp1).oper[0]^.val) and
|
||||||
|
not(cs_opt_size in current_settings.optimizerswitches) then
|
||||||
|
begin
|
||||||
|
{ shr/sar const1, %reg
|
||||||
|
shl const2, %reg
|
||||||
|
with const1 > const2 }
|
||||||
|
taicpu(p).loadConst(0,taicpu(p).oper[0]^.val-taicpu(hp1).oper[0]^.val);
|
||||||
|
taicpu(hp1).opcode := A_AND;
|
||||||
|
l := (1 shl (taicpu(hp1).oper[0]^.val)) - 1;
|
||||||
|
case taicpu(p).opsize Of
|
||||||
|
S_B: taicpu(hp1).loadConst(0,l Xor $ff);
|
||||||
|
S_W: taicpu(hp1).loadConst(0,l Xor $ffff);
|
||||||
|
S_L: taicpu(hp1).loadConst(0,l Xor aint($ffffffff));
|
||||||
|
S_Q: taicpu(hp1).loadConst(0,l Xor aint($ffffffffffffffff));
|
||||||
|
else
|
||||||
|
Internalerror(2017050703)
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
else if (taicpu(p).oper[0]^.val<taicpu(hp1).oper[0]^.val) and
|
||||||
|
not(cs_opt_size in current_settings.optimizerswitches) then
|
||||||
|
begin
|
||||||
|
{ shr/sar const1, %reg
|
||||||
|
shl const2, %reg
|
||||||
|
with const1 < const2 }
|
||||||
|
taicpu(hp1).loadConst(0,taicpu(hp1).oper[0]^.val-taicpu(p).oper[0]^.val);
|
||||||
|
taicpu(p).opcode := A_AND;
|
||||||
|
l := (1 shl (taicpu(p).oper[0]^.val))-1;
|
||||||
|
case taicpu(p).opsize Of
|
||||||
|
S_B: taicpu(p).loadConst(0,l Xor $ff);
|
||||||
|
S_W: taicpu(p).loadConst(0,l Xor $ffff);
|
||||||
|
S_L: taicpu(p).loadConst(0,l Xor aint($ffffffff));
|
||||||
|
S_Q: taicpu(p).loadConst(0,l Xor aint($ffffffffffffffff));
|
||||||
|
else
|
||||||
|
Internalerror(2017050702)
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
else if (taicpu(p).oper[0]^.val = taicpu(hp1).oper[0]^.val) then
|
||||||
|
begin
|
||||||
|
{ shr/sar const1, %reg
|
||||||
|
shl const2, %reg
|
||||||
|
with const1 = const2 }
|
||||||
|
taicpu(p).opcode := A_AND;
|
||||||
|
l := (1 shl (taicpu(p).oper[0]^.val))-1;
|
||||||
|
case taicpu(p).opsize Of
|
||||||
|
S_B: taicpu(p).loadConst(0,l Xor $ff);
|
||||||
|
S_W: taicpu(p).loadConst(0,l Xor $ffff);
|
||||||
|
S_L: taicpu(p).loadConst(0,l Xor aint($ffffffff));
|
||||||
|
S_Q: taicpu(p).loadConst(0,l Xor aint($ffffffffffffffff));
|
||||||
|
else
|
||||||
|
Internalerror(2017050701)
|
||||||
|
end;
|
||||||
|
asml.remove(hp1);
|
||||||
|
hp1.free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
{ allocates register reg between (and including) instructions p1 and p2
|
{ allocates register reg between (and including) instructions p1 and p2
|
||||||
the type of p1 and p2 must not be in SkipInstr
|
the type of p1 and p2 must not be in SkipInstr
|
||||||
note that this routine is both called from the peephole optimizer
|
note that this routine is both called from the peephole optimizer
|
||||||
|
@ -31,6 +31,7 @@ uses cgbase, cpubase, aasmtai, aopt, aoptx86, aoptcpub;
|
|||||||
|
|
||||||
type
|
type
|
||||||
TCpuAsmOptimizer = class(TX86AsmOptimizer)
|
TCpuAsmOptimizer = class(TX86AsmOptimizer)
|
||||||
|
function PrePeepHoleOptsCpu(var p: tai): boolean; override;
|
||||||
function PeepHoleOptPass1Cpu(var p: tai): boolean; override;
|
function PeepHoleOptPass1Cpu(var p: tai): boolean; override;
|
||||||
function PeepHoleOptPass2Cpu(var p: tai): boolean; override;
|
function PeepHoleOptPass2Cpu(var p: tai): boolean; override;
|
||||||
function PostPeepHoleOptsCpu(var p : tai) : boolean; override;
|
function PostPeepHoleOptsCpu(var p : tai) : boolean; override;
|
||||||
@ -47,6 +48,20 @@ uses
|
|||||||
aasmbase, aasmdata, aasmcpu,
|
aasmbase, aasmdata, aasmcpu,
|
||||||
itcpugas;
|
itcpugas;
|
||||||
|
|
||||||
|
function TCpuAsmOptimizer.PrePeepHoleOptsCpu(var p : tai) : boolean;
|
||||||
|
begin
|
||||||
|
result := false;
|
||||||
|
case p.typ of
|
||||||
|
ait_instruction:
|
||||||
|
begin
|
||||||
|
case taicpu(p).opcode of
|
||||||
|
A_SAR,A_SHR:
|
||||||
|
result:=PrePeepholeOptSxx(p);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
function TCpuAsmOptimizer.PeepHoleOptPass1Cpu(var p: tai): boolean;
|
function TCpuAsmOptimizer.PeepHoleOptPass1Cpu(var p: tai): boolean;
|
||||||
var
|
var
|
||||||
hp1, hp2: tai;
|
hp1, hp2: tai;
|
||||||
|
Loading…
Reference in New Issue
Block a user