mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-09 23:46:00 +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;
|
||||
A_SAR, A_SHR:
|
||||
{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}
|
||||
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_SAR,A_SHR:
|
||||
if PrePeepholeOptSxx(p) then
|
||||
continue;
|
||||
A_XOR:
|
||||
if (taicpu(p).oper[0]^.typ = top_reg) and
|
||||
(taicpu(p).oper[1]^.typ = top_reg) and
|
||||
|
@ -46,7 +46,14 @@ unit aoptx86;
|
||||
depend on the value in AH). }
|
||||
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 OptPass1VMOVAP(var p : tai) : boolean;
|
||||
@ -58,12 +65,7 @@ unit aoptx86;
|
||||
function OptPass2Jmp(var p : tai) : boolean;
|
||||
function OptPass2Jcc(var p : tai) : boolean;
|
||||
|
||||
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);
|
||||
procedure PostPeepholeOptMov(const p : tai);
|
||||
end;
|
||||
|
||||
function MatchInstruction(const instr: tai; const op: TAsmOp; const opsize: topsizes): boolean;
|
||||
@ -284,6 +286,85 @@ unit aoptx86;
|
||||
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
|
||||
the type of p1 and p2 must not be in SkipInstr
|
||||
note that this routine is both called from the peephole optimizer
|
||||
|
@ -31,6 +31,7 @@ uses cgbase, cpubase, aasmtai, aopt, aoptx86, aoptcpub;
|
||||
|
||||
type
|
||||
TCpuAsmOptimizer = class(TX86AsmOptimizer)
|
||||
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;
|
||||
@ -47,6 +48,20 @@ uses
|
||||
aasmbase, aasmdata, aasmcpu,
|
||||
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;
|
||||
var
|
||||
hp1, hp2: tai;
|
||||
|
Loading…
Reference in New Issue
Block a user