mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-12 12:46:11 +02:00
* i386 peephole assembler uses largely the common peephole optimizer infrastructure, the resulting code is besides a few improvements the same
git-svn-id: trunk@33542 -
This commit is contained in:
parent
4ac3953c34
commit
3c2dab9878
6
.gitattributes
vendored
6
.gitattributes
vendored
@ -188,7 +188,9 @@ compiler/hlcgobj.pas svneol=native#text/plain
|
|||||||
compiler/html/i386/readme.txt svneol=native#text/plain
|
compiler/html/i386/readme.txt svneol=native#text/plain
|
||||||
compiler/html/powerpc/readme.txt svneol=native#text/plain
|
compiler/html/powerpc/readme.txt svneol=native#text/plain
|
||||||
compiler/htypechk.pas svneol=native#text/plain
|
compiler/htypechk.pas svneol=native#text/plain
|
||||||
compiler/i386/aopt386.pas svneol=native#text/plain
|
compiler/i386/aoptcpu.pas svneol=native#text/plain
|
||||||
|
compiler/i386/aoptcpub.pas svneol=native#text/plain
|
||||||
|
compiler/i386/aoptcpud.pas svneol=native#text/plain
|
||||||
compiler/i386/cgcpu.pas svneol=native#text/plain
|
compiler/i386/cgcpu.pas svneol=native#text/plain
|
||||||
compiler/i386/cpubase.inc svneol=native#text/plain
|
compiler/i386/cpubase.inc svneol=native#text/plain
|
||||||
compiler/i386/cpuelf.pas svneol=native#text/plain
|
compiler/i386/cpuelf.pas svneol=native#text/plain
|
||||||
@ -197,7 +199,6 @@ compiler/i386/cpunode.pas svneol=native#text/plain
|
|||||||
compiler/i386/cpupara.pas svneol=native#text/plain
|
compiler/i386/cpupara.pas svneol=native#text/plain
|
||||||
compiler/i386/cpupi.pas svneol=native#text/plain
|
compiler/i386/cpupi.pas svneol=native#text/plain
|
||||||
compiler/i386/cputarg.pas svneol=native#text/plain
|
compiler/i386/cputarg.pas svneol=native#text/plain
|
||||||
compiler/i386/daopt386.pas svneol=native#text/plain
|
|
||||||
compiler/i386/hlcgcpu.pas svneol=native#text/plain
|
compiler/i386/hlcgcpu.pas svneol=native#text/plain
|
||||||
compiler/i386/i386att.inc svneol=native#text/plain
|
compiler/i386/i386att.inc svneol=native#text/plain
|
||||||
compiler/i386/i386atts.inc svneol=native#text/plain
|
compiler/i386/i386atts.inc svneol=native#text/plain
|
||||||
@ -214,7 +215,6 @@ compiler/i386/n386ld.pas svneol=native#text/plain
|
|||||||
compiler/i386/n386mat.pas svneol=native#text/plain
|
compiler/i386/n386mat.pas svneol=native#text/plain
|
||||||
compiler/i386/n386mem.pas svneol=native#text/plain
|
compiler/i386/n386mem.pas svneol=native#text/plain
|
||||||
compiler/i386/n386set.pas svneol=native#text/plain
|
compiler/i386/n386set.pas svneol=native#text/plain
|
||||||
compiler/i386/popt386.pas svneol=native#text/plain
|
|
||||||
compiler/i386/r386ari.inc svneol=native#text/plain
|
compiler/i386/r386ari.inc svneol=native#text/plain
|
||||||
compiler/i386/r386att.inc svneol=native#text/plain
|
compiler/i386/r386att.inc svneol=native#text/plain
|
||||||
compiler/i386/r386con.inc svneol=native#text/plain
|
compiler/i386/r386con.inc svneol=native#text/plain
|
||||||
|
@ -40,7 +40,7 @@ Unit aopt;
|
|||||||
Constructor create(_AsmL: TAsmList); virtual; reintroduce;
|
Constructor create(_AsmL: TAsmList); virtual; reintroduce;
|
||||||
|
|
||||||
{ call the necessary optimizer procedures }
|
{ call the necessary optimizer procedures }
|
||||||
Procedure Optimize;
|
Procedure Optimize;virtual;
|
||||||
Destructor destroy;override;
|
Destructor destroy;override;
|
||||||
|
|
||||||
private
|
private
|
||||||
@ -50,6 +50,7 @@ Unit aopt;
|
|||||||
Also fixes some RegDeallocs like "# %eax released; push (%eax)" }
|
Also fixes some RegDeallocs like "# %eax released; push (%eax)" }
|
||||||
Procedure BuildLabelTableAndFixRegAlloc;
|
Procedure BuildLabelTableAndFixRegAlloc;
|
||||||
procedure clear;
|
procedure clear;
|
||||||
|
protected
|
||||||
procedure pass_1;
|
procedure pass_1;
|
||||||
End;
|
End;
|
||||||
TAsmOptimizerClass = class of TAsmOptimizer;
|
TAsmOptimizerClass = class of TAsmOptimizer;
|
||||||
|
@ -339,10 +339,10 @@ Unit AoptObj;
|
|||||||
procedure RemoveDelaySlot(hp1: tai);
|
procedure RemoveDelaySlot(hp1: tai);
|
||||||
|
|
||||||
{ peephole optimizer }
|
{ peephole optimizer }
|
||||||
procedure PrePeepHoleOpts;
|
procedure PrePeepHoleOpts; virtual;
|
||||||
procedure PeepHoleOptPass1;
|
procedure PeepHoleOptPass1; virtual;
|
||||||
procedure PeepHoleOptPass2; virtual;
|
procedure PeepHoleOptPass2; virtual;
|
||||||
procedure PostPeepHoleOpts;
|
procedure PostPeepHoleOpts; virtual;
|
||||||
|
|
||||||
{ processor dependent methods }
|
{ processor dependent methods }
|
||||||
// if it returns true, perform a "continue"
|
// if it returns true, perform a "continue"
|
||||||
|
@ -1,118 +0,0 @@
|
|||||||
{
|
|
||||||
Copyright (c) 1998-2002 by Jonas Maebe
|
|
||||||
|
|
||||||
This unit calls the optimization procedures to optimize the assembler
|
|
||||||
code for i386+
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
|
|
||||||
****************************************************************************
|
|
||||||
}
|
|
||||||
Unit aopt386;
|
|
||||||
|
|
||||||
{$i fpcdefs.inc}
|
|
||||||
|
|
||||||
Interface
|
|
||||||
|
|
||||||
Uses
|
|
||||||
aasmbase,aasmtai,aasmdata,aasmcpu;
|
|
||||||
|
|
||||||
Procedure Optimize(AsmL: TAsmList);
|
|
||||||
|
|
||||||
|
|
||||||
Implementation
|
|
||||||
|
|
||||||
Uses
|
|
||||||
globtype,
|
|
||||||
globals,
|
|
||||||
DAOpt386,POpt386;
|
|
||||||
|
|
||||||
|
|
||||||
Procedure Optimize(AsmL: TAsmList);
|
|
||||||
Var
|
|
||||||
BlockStart, BlockEnd, HP: Tai;
|
|
||||||
pass: longint;
|
|
||||||
slowopt, changed, lastLoop: boolean;
|
|
||||||
Begin
|
|
||||||
slowopt := (cs_opt_level3 in current_settings.optimizerswitches);
|
|
||||||
pass := 0;
|
|
||||||
changed := false;
|
|
||||||
dfa := TDFAObj.create(asml);
|
|
||||||
repeat
|
|
||||||
lastLoop :=
|
|
||||||
not(slowopt) or
|
|
||||||
(not changed and (pass > 2)) or
|
|
||||||
{ prevent endless loops }
|
|
||||||
(pass = 4);
|
|
||||||
changed := false;
|
|
||||||
{ Setup labeltable, always necessary }
|
|
||||||
blockstart := tai(asml.first);
|
|
||||||
blockend := dfa.pass_1(blockstart);
|
|
||||||
{ Blockend now either contains an ait_marker with Kind = mark_AsmBlockStart, }
|
|
||||||
{ or nil }
|
|
||||||
While Assigned(BlockStart) Do
|
|
||||||
Begin
|
|
||||||
if (cs_opt_peephole in current_settings.optimizerswitches) then
|
|
||||||
begin
|
|
||||||
if (pass = 0) then
|
|
||||||
PrePeepHoleOpts(AsmL, BlockStart, BlockEnd);
|
|
||||||
{ Peephole optimizations }
|
|
||||||
PeepHoleOptPass1(AsmL, BlockStart, BlockEnd);
|
|
||||||
{ Only perform them twice in the first pass }
|
|
||||||
if pass = 0 then
|
|
||||||
PeepHoleOptPass1(AsmL, BlockStart, BlockEnd);
|
|
||||||
end;
|
|
||||||
{ More peephole optimizations }
|
|
||||||
if (cs_opt_peephole in current_settings.optimizerswitches) then
|
|
||||||
begin
|
|
||||||
PeepHoleOptPass2(AsmL, BlockStart, BlockEnd);
|
|
||||||
if lastLoop then
|
|
||||||
PostPeepHoleOpts(AsmL, BlockStart, BlockEnd);
|
|
||||||
end;
|
|
||||||
|
|
||||||
{ Free memory }
|
|
||||||
dfa.clear;
|
|
||||||
|
|
||||||
{ Continue where we left off, BlockEnd is either the start of an }
|
|
||||||
{ assembler block or nil }
|
|
||||||
BlockStart := BlockEnd;
|
|
||||||
While Assigned(BlockStart) And
|
|
||||||
(BlockStart.typ = ait_Marker) And
|
|
||||||
(Tai_Marker(BlockStart).Kind = mark_AsmBlockStart) Do
|
|
||||||
Begin
|
|
||||||
{ We stopped at an assembler block, so skip it }
|
|
||||||
Repeat
|
|
||||||
BlockStart := Tai(BlockStart.Next);
|
|
||||||
Until (BlockStart.Typ = Ait_Marker) And
|
|
||||||
(Tai_Marker(Blockstart).Kind = mark_AsmBlockEnd);
|
|
||||||
{ Blockstart now contains a Tai_marker(mark_AsmBlockEnd) }
|
|
||||||
If GetNextInstruction(BlockStart, HP) And
|
|
||||||
((HP.typ <> ait_Marker) Or
|
|
||||||
(Tai_Marker(HP).Kind <> mark_AsmBlockStart)) Then
|
|
||||||
{ There is no assembler block anymore after the current one, so }
|
|
||||||
{ optimize the next block of "normal" instructions }
|
|
||||||
BlockEnd := dfa.pass_1(blockstart)
|
|
||||||
{ Otherwise, skip the next assembler block }
|
|
||||||
else
|
|
||||||
blockStart := hp;
|
|
||||||
End;
|
|
||||||
End;
|
|
||||||
inc(pass);
|
|
||||||
until lastLoop;
|
|
||||||
dfa.free;
|
|
||||||
|
|
||||||
End;
|
|
||||||
|
|
||||||
End.
|
|
File diff suppressed because it is too large
Load Diff
113
compiler/i386/aoptcpub.pas
Normal file
113
compiler/i386/aoptcpub.pas
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
{
|
||||||
|
Copyright (c) 1998-2004 by Jonas Maebe, member of the Free Pascal
|
||||||
|
Development Team
|
||||||
|
|
||||||
|
This unit contains several types and constants necessary for the
|
||||||
|
optimizer to work on the sparc architecture
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
|
||||||
|
****************************************************************************
|
||||||
|
}
|
||||||
|
Unit aoptcpub; { Assembler OPTimizer CPU specific Base }
|
||||||
|
|
||||||
|
{$i fpcdefs.inc}
|
||||||
|
|
||||||
|
{ enable the following define if memory references can have a scaled index }
|
||||||
|
{ define RefsHaveScale}
|
||||||
|
|
||||||
|
{ enable the following define if memory references can have a segment }
|
||||||
|
{ override }
|
||||||
|
{ define RefsHaveSegment}
|
||||||
|
|
||||||
|
Interface
|
||||||
|
|
||||||
|
Uses
|
||||||
|
cpubase,aasmcpu,AOptBase;
|
||||||
|
|
||||||
|
Type
|
||||||
|
|
||||||
|
{ type of a normal instruction }
|
||||||
|
TInstr = Taicpu;
|
||||||
|
PInstr = ^TInstr;
|
||||||
|
|
||||||
|
{ ************************************************************************* }
|
||||||
|
{ **************************** TCondRegs ********************************** }
|
||||||
|
{ ************************************************************************* }
|
||||||
|
{ Info about the conditional registers }
|
||||||
|
TCondRegs = Object
|
||||||
|
Constructor Init;
|
||||||
|
Destructor Done;
|
||||||
|
End;
|
||||||
|
|
||||||
|
{ ************************************************************************* }
|
||||||
|
{ **************************** TAoptBaseCpu ******************************* }
|
||||||
|
{ ************************************************************************* }
|
||||||
|
|
||||||
|
TAoptBaseCpu = class(TAoptBase)
|
||||||
|
End;
|
||||||
|
|
||||||
|
|
||||||
|
{ ************************************************************************* }
|
||||||
|
{ ******************************* Constants ******************************* }
|
||||||
|
{ ************************************************************************* }
|
||||||
|
Const
|
||||||
|
|
||||||
|
{ the maximum number of things (registers, memory, ...) a single instruction }
|
||||||
|
{ changes }
|
||||||
|
|
||||||
|
MaxCh = 3;
|
||||||
|
|
||||||
|
{ the maximum number of operands an instruction has }
|
||||||
|
|
||||||
|
MaxOps = 3;
|
||||||
|
|
||||||
|
{Oper index of operand that contains the source (reference) with a load }
|
||||||
|
{instruction }
|
||||||
|
|
||||||
|
LoadSrc = 0;
|
||||||
|
|
||||||
|
{Oper index of operand that contains the destination (register) with a load }
|
||||||
|
{instruction }
|
||||||
|
|
||||||
|
LoadDst = 1;
|
||||||
|
|
||||||
|
{Oper index of operand that contains the source (register) with a store }
|
||||||
|
{instruction }
|
||||||
|
|
||||||
|
StoreSrc = 0;
|
||||||
|
|
||||||
|
{Oper index of operand that contains the destination (reference) with a load }
|
||||||
|
{instruction }
|
||||||
|
|
||||||
|
StoreDst = 1;
|
||||||
|
|
||||||
|
aopt_uncondjmp = A_JMP;
|
||||||
|
aopt_condjmp = A_Jcc;
|
||||||
|
|
||||||
|
Implementation
|
||||||
|
|
||||||
|
{ ************************************************************************* }
|
||||||
|
{ **************************** TCondRegs ********************************** }
|
||||||
|
{ ************************************************************************* }
|
||||||
|
Constructor TCondRegs.init;
|
||||||
|
Begin
|
||||||
|
End;
|
||||||
|
|
||||||
|
Destructor TCondRegs.Done; {$ifdef inl} inline; {$endif inl}
|
||||||
|
Begin
|
||||||
|
End;
|
||||||
|
|
||||||
|
End.
|
36
compiler/i386/aoptcpud.pas
Normal file
36
compiler/i386/aoptcpud.pas
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
{
|
||||||
|
Copyright (c) 1998-2004 by Jonas Maebe, member of the Free Pascal
|
||||||
|
Development Team
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
|
||||||
|
****************************************************************************
|
||||||
|
}
|
||||||
|
Unit aoptcpud;
|
||||||
|
|
||||||
|
{$i fpcdefs.inc}
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
uses
|
||||||
|
aoptda;
|
||||||
|
|
||||||
|
type
|
||||||
|
TAOptDFACpu = class(TAOptDFA)
|
||||||
|
end;
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
end.
|
File diff suppressed because it is too large
Load Diff
@ -133,11 +133,7 @@ implementation
|
|||||||
,cpuinfo
|
,cpuinfo
|
||||||
{$endif arm}
|
{$endif arm}
|
||||||
{$ifndef NOOPT}
|
{$ifndef NOOPT}
|
||||||
{$ifdef i386}
|
,aopt
|
||||||
,aopt386
|
|
||||||
{$else i386}
|
|
||||||
,aopt
|
|
||||||
{$endif i386}
|
|
||||||
{$endif}
|
{$endif}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -31,7 +31,13 @@ unit aoptx86;
|
|||||||
globtype,
|
globtype,
|
||||||
cpubase,
|
cpubase,
|
||||||
aasmtai,
|
aasmtai,
|
||||||
cgbase,cgutils;
|
cgbase,cgutils,
|
||||||
|
aopt;
|
||||||
|
|
||||||
|
type
|
||||||
|
TX86AsmOptimizer = class(TAsmOptimizer)
|
||||||
|
function RegLoadedWithNewValue(reg : tregister; hp : tai) : boolean; override;
|
||||||
|
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;
|
||||||
function MatchInstruction(const instr: tai; const op1,op2: TAsmOp; const opsize: topsizes): boolean;
|
function MatchInstruction(const instr: tai; const op1,op2: TAsmOp; const opsize: topsizes): boolean;
|
||||||
@ -147,5 +153,40 @@ unit aoptx86;
|
|||||||
(taicpu(instr).oper[1]^.typ=ot1);
|
(taicpu(instr).oper[1]^.typ=ot1);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function TX86AsmOptimizer.RegLoadedWithNewValue(reg: tregister; hp: tai): boolean;
|
||||||
|
var
|
||||||
|
p: taicpu;
|
||||||
|
begin
|
||||||
|
if not assigned(hp) or
|
||||||
|
(hp.typ <> ait_instruction) then
|
||||||
|
begin
|
||||||
|
Result := false;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
p := taicpu(hp);
|
||||||
|
Result :=
|
||||||
|
(((p.opcode = A_MOV) or
|
||||||
|
(p.opcode = A_MOVZX) or
|
||||||
|
(p.opcode = A_MOVSX) or
|
||||||
|
(p.opcode = A_LEA) or
|
||||||
|
(p.opcode = A_VMOVSS) or
|
||||||
|
(p.opcode = A_VMOVSD) or
|
||||||
|
(p.opcode = A_VMOVQ) or
|
||||||
|
(p.opcode = A_MOVSS) or
|
||||||
|
(p.opcode = A_MOVSD) or
|
||||||
|
(p.opcode = A_MOVQ)) and
|
||||||
|
(p.oper[1]^.typ = top_reg) and
|
||||||
|
(getsupreg(p.oper[1]^.reg) = getsupreg(reg)) and
|
||||||
|
((p.oper[0]^.typ = top_const) or
|
||||||
|
((p.oper[0]^.typ = top_reg) and
|
||||||
|
(getsupreg(p.oper[0]^.reg) <> getsupreg(reg))) or
|
||||||
|
((p.oper[0]^.typ = top_ref) and
|
||||||
|
not RegInRef(reg,p.oper[0]^.ref^)))) or
|
||||||
|
((p.opcode = A_POP) and
|
||||||
|
(getsupreg(p.oper[0]^.reg) = getsupreg(reg)));
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
@ -27,12 +27,11 @@ unit aoptcpu;
|
|||||||
|
|
||||||
interface
|
interface
|
||||||
|
|
||||||
uses cgbase, cpubase, aasmtai, aopt, aoptcpub;
|
uses cgbase, cpubase, aasmtai, aopt, aoptx86, aoptcpub;
|
||||||
|
|
||||||
type
|
type
|
||||||
TCpuAsmOptimizer = class(TAsmOptimizer)
|
TCpuAsmOptimizer = class(TX86AsmOptimizer)
|
||||||
function PeepHoleOptPass1Cpu(var p: tai): boolean; override;
|
function PeepHoleOptPass1Cpu(var p: tai): boolean; override;
|
||||||
function RegLoadedWithNewValue(reg : tregister; hp : tai) : boolean; override;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
@ -44,7 +43,6 @@ uses
|
|||||||
cgutils,
|
cgutils,
|
||||||
aoptobj,
|
aoptobj,
|
||||||
aasmbase, aasmdata, aasmcpu,
|
aasmbase, aasmdata, aasmcpu,
|
||||||
aoptx86,
|
|
||||||
itcpugas;
|
itcpugas;
|
||||||
|
|
||||||
function isFoldableArithOp(hp1: taicpu; reg: tregister): boolean;
|
function isFoldableArithOp(hp1: taicpu; reg: tregister): boolean;
|
||||||
@ -66,40 +64,6 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
function TCpuAsmOptimizer.RegLoadedWithNewValue(reg: tregister; hp: tai): boolean;
|
|
||||||
var
|
|
||||||
p: taicpu;
|
|
||||||
begin
|
|
||||||
if not assigned(hp) or
|
|
||||||
(hp.typ <> ait_instruction) then
|
|
||||||
begin
|
|
||||||
Result := false;
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
p := taicpu(hp);
|
|
||||||
Result :=
|
|
||||||
(((p.opcode = A_MOV) or
|
|
||||||
(p.opcode = A_MOVZX) or
|
|
||||||
(p.opcode = A_MOVSX) or
|
|
||||||
(p.opcode = A_LEA) or
|
|
||||||
(p.opcode = A_VMOVSS) or
|
|
||||||
(p.opcode = A_VMOVSD) or
|
|
||||||
(p.opcode = A_VMOVQ) or
|
|
||||||
(p.opcode = A_MOVSS) or
|
|
||||||
(p.opcode = A_MOVSD) or
|
|
||||||
(p.opcode = A_MOVQ)) and
|
|
||||||
(p.oper[1]^.typ = top_reg) and
|
|
||||||
(getsupreg(p.oper[1]^.reg) = getsupreg(reg)) and
|
|
||||||
((p.oper[0]^.typ = top_const) or
|
|
||||||
((p.oper[0]^.typ = top_reg) and
|
|
||||||
(getsupreg(p.oper[0]^.reg) <> getsupreg(reg))) or
|
|
||||||
((p.oper[0]^.typ = top_ref) and
|
|
||||||
not RegInRef(reg,p.oper[0]^.ref^)))) or
|
|
||||||
((p.opcode = A_POP) and
|
|
||||||
(getsupreg(p.oper[0]^.reg) = getsupreg(reg)));
|
|
||||||
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