mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-11 10:26:05 +02:00
* moved InstructionLoadsFromReg and RegReadByInstruction from TCpuAsmOptimizer (i386) to TX86AsmOptimizer
git-svn-id: trunk@36200 -
This commit is contained in:
parent
b7fab7d39c
commit
f4a29bb75d
@ -41,8 +41,6 @@ unit aoptcpu;
|
|||||||
procedure PeepHoleOptPass2; override;
|
procedure PeepHoleOptPass2; override;
|
||||||
procedure PostPeepHoleOpts; override;
|
procedure PostPeepHoleOpts; override;
|
||||||
function DoFpuLoadStoreOpt(var p : tai) : boolean;
|
function DoFpuLoadStoreOpt(var p : tai) : boolean;
|
||||||
function RegReadByInstruction(reg : TRegister; hp : tai) : boolean;
|
|
||||||
function InstructionLoadsFromReg(const reg : TRegister;const hp : tai) : boolean;override;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
Var
|
Var
|
||||||
@ -138,222 +136,6 @@ unit aoptcpu;
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
function TCpuAsmOptimizer.InstructionLoadsFromReg(const reg: TRegister;const hp: tai): boolean;
|
|
||||||
begin
|
|
||||||
Result:=RegReadByInstruction(reg,hp);
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
function TCpuAsmOptimizer.RegReadByInstruction(reg: TRegister; hp: tai): boolean;
|
|
||||||
var
|
|
||||||
p: taicpu;
|
|
||||||
opcount: longint;
|
|
||||||
begin
|
|
||||||
RegReadByInstruction := false;
|
|
||||||
if hp.typ <> ait_instruction then
|
|
||||||
exit;
|
|
||||||
p := taicpu(hp);
|
|
||||||
case p.opcode of
|
|
||||||
A_CALL:
|
|
||||||
regreadbyinstruction := true;
|
|
||||||
A_IMUL:
|
|
||||||
case p.ops of
|
|
||||||
1:
|
|
||||||
regReadByInstruction := RegInOp(reg,p.oper[0]^) or
|
|
||||||
(
|
|
||||||
((getregtype(reg)=R_INTREGISTER) and (getsupreg(reg)=RS_EAX)) and
|
|
||||||
((getsubreg(reg)<>R_SUBH) or (p.opsize<>S_B))
|
|
||||||
);
|
|
||||||
2,3:
|
|
||||||
regReadByInstruction :=
|
|
||||||
reginop(reg,p.oper[0]^) or
|
|
||||||
reginop(reg,p.oper[1]^);
|
|
||||||
end;
|
|
||||||
A_MUL:
|
|
||||||
begin
|
|
||||||
regReadByInstruction := RegInOp(reg,p.oper[0]^) or
|
|
||||||
(
|
|
||||||
((getregtype(reg)=R_INTREGISTER) and (getsupreg(reg)=RS_EAX)) and
|
|
||||||
((getsubreg(reg)<>R_SUBH) or (p.opsize<>S_B))
|
|
||||||
);
|
|
||||||
end;
|
|
||||||
A_IDIV,A_DIV:
|
|
||||||
begin
|
|
||||||
regReadByInstruction := RegInOp(reg,p.oper[0]^) or
|
|
||||||
(
|
|
||||||
(getregtype(reg)=R_INTREGISTER) and
|
|
||||||
(
|
|
||||||
(getsupreg(reg)=RS_EAX) or ((getsupreg(reg)=RS_EDX) and (p.opsize<>S_B))
|
|
||||||
)
|
|
||||||
);
|
|
||||||
end;
|
|
||||||
else
|
|
||||||
begin
|
|
||||||
if (p.opcode=A_LEA) and is_segment_reg(reg) then
|
|
||||||
begin
|
|
||||||
RegReadByInstruction := false;
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
for opcount := 0 to p.ops-1 do
|
|
||||||
if (p.oper[opCount]^.typ = top_ref) and
|
|
||||||
RegInRef(reg,p.oper[opcount]^.ref^) then
|
|
||||||
begin
|
|
||||||
RegReadByInstruction := true;
|
|
||||||
exit
|
|
||||||
end;
|
|
||||||
{ special handling for SSE MOVSD }
|
|
||||||
if (p.opcode=A_MOVSD) and (p.ops>0) then
|
|
||||||
begin
|
|
||||||
if p.ops<>2 then
|
|
||||||
internalerror(2017042702);
|
|
||||||
regReadByInstruction := reginop(reg,p.oper[0]^) or
|
|
||||||
(
|
|
||||||
(p.oper[1]^.typ=top_reg) and (p.oper[0]^.typ=top_reg) and reginop(reg, p.oper[1]^)
|
|
||||||
);
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
with insprop[p.opcode] do
|
|
||||||
begin
|
|
||||||
if getregtype(reg)=R_INTREGISTER then
|
|
||||||
begin
|
|
||||||
case getsupreg(reg) of
|
|
||||||
RS_EAX:
|
|
||||||
if [Ch_REAX,Ch_RWEAX,Ch_MEAX]*Ch<>[] then
|
|
||||||
begin
|
|
||||||
RegReadByInstruction := true;
|
|
||||||
exit
|
|
||||||
end;
|
|
||||||
RS_ECX:
|
|
||||||
if [Ch_RECX,Ch_RWECX,Ch_MECX]*Ch<>[] then
|
|
||||||
begin
|
|
||||||
RegReadByInstruction := true;
|
|
||||||
exit
|
|
||||||
end;
|
|
||||||
RS_EDX:
|
|
||||||
if [Ch_REDX,Ch_RWEDX,Ch_MEDX]*Ch<>[] then
|
|
||||||
begin
|
|
||||||
RegReadByInstruction := true;
|
|
||||||
exit
|
|
||||||
end;
|
|
||||||
RS_EBX:
|
|
||||||
if [Ch_REBX,Ch_RWEBX,Ch_MEBX]*Ch<>[] then
|
|
||||||
begin
|
|
||||||
RegReadByInstruction := true;
|
|
||||||
exit
|
|
||||||
end;
|
|
||||||
RS_ESP:
|
|
||||||
if [Ch_RESP,Ch_RWESP,Ch_MESP]*Ch<>[] then
|
|
||||||
begin
|
|
||||||
RegReadByInstruction := true;
|
|
||||||
exit
|
|
||||||
end;
|
|
||||||
RS_EBP:
|
|
||||||
if [Ch_REBP,Ch_RWEBP,Ch_MEBP]*Ch<>[] then
|
|
||||||
begin
|
|
||||||
RegReadByInstruction := true;
|
|
||||||
exit
|
|
||||||
end;
|
|
||||||
RS_ESI:
|
|
||||||
if [Ch_RESI,Ch_RWESI,Ch_MESI]*Ch<>[] then
|
|
||||||
begin
|
|
||||||
RegReadByInstruction := true;
|
|
||||||
exit
|
|
||||||
end;
|
|
||||||
RS_EDI:
|
|
||||||
if [Ch_REDI,Ch_RWEDI,Ch_MEDI]*Ch<>[] then
|
|
||||||
begin
|
|
||||||
RegReadByInstruction := true;
|
|
||||||
exit
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
if SuperRegistersEqual(reg,NR_DEFAULTFLAGS) then
|
|
||||||
begin
|
|
||||||
if (Ch_RFLAGScc in Ch) and not(getsubreg(reg) in [R_SUBW,R_SUBD,R_SUBQ]) then
|
|
||||||
begin
|
|
||||||
case p.condition of
|
|
||||||
C_A,C_NBE, { CF=0 and ZF=0 }
|
|
||||||
C_BE,C_NA: { CF=1 or ZF=1 }
|
|
||||||
RegReadByInstruction:=getsubreg(reg) in [R_SUBFLAGCARRY,R_SUBFLAGZERO];
|
|
||||||
C_AE,C_NB,C_NC, { CF=0 }
|
|
||||||
C_B,C_NAE,C_C: { CF=1 }
|
|
||||||
RegReadByInstruction:=getsubreg(reg) in [R_SUBFLAGCARRY];
|
|
||||||
C_NE,C_NZ, { ZF=0 }
|
|
||||||
C_E,C_Z: { ZF=1 }
|
|
||||||
RegReadByInstruction:=getsubreg(reg) in [R_SUBFLAGZERO];
|
|
||||||
C_G,C_NLE, { ZF=0 and SF=OF }
|
|
||||||
C_LE,C_NG: { ZF=1 or SF<>OF }
|
|
||||||
RegReadByInstruction:=getsubreg(reg) in [R_SUBFLAGZERO,R_SUBFLAGSIGN,R_SUBFLAGOVERFLOW];
|
|
||||||
C_GE,C_NL, { SF=OF }
|
|
||||||
C_L,C_NGE: { SF<>OF }
|
|
||||||
RegReadByInstruction:=getsubreg(reg) in [R_SUBFLAGSIGN,R_SUBFLAGOVERFLOW];
|
|
||||||
C_NO, { OF=0 }
|
|
||||||
C_O: { OF=1 }
|
|
||||||
RegReadByInstruction:=getsubreg(reg) in [R_SUBFLAGOVERFLOW];
|
|
||||||
C_NP,C_PO, { PF=0 }
|
|
||||||
C_P,C_PE: { PF=1 }
|
|
||||||
RegReadByInstruction:=getsubreg(reg) in [R_SUBFLAGPARITY];
|
|
||||||
C_NS, { SF=0 }
|
|
||||||
C_S: { SF=1 }
|
|
||||||
RegReadByInstruction:=getsubreg(reg) in [R_SUBFLAGSIGN];
|
|
||||||
else
|
|
||||||
internalerror(2017042701);
|
|
||||||
end;
|
|
||||||
if RegReadByInstruction then
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
case getsubreg(reg) of
|
|
||||||
R_SUBW,R_SUBD,R_SUBQ:
|
|
||||||
RegReadByInstruction :=
|
|
||||||
[Ch_RCarryFlag,Ch_RParityFlag,Ch_RAuxiliaryFlag,Ch_RZeroFlag,Ch_RSignFlag,Ch_ROverflowFlag,
|
|
||||||
Ch_RWCarryFlag,Ch_RWParityFlag,Ch_RWAuxiliaryFlag,Ch_RWZeroFlag,Ch_RWSignFlag,Ch_RWOverflowFlag,
|
|
||||||
Ch_RDirFlag,Ch_RFlags,Ch_RWFlags,Ch_RFLAGScc]*Ch<>[];
|
|
||||||
R_SUBFLAGCARRY:
|
|
||||||
RegReadByInstruction:=[Ch_RCarryFlag,Ch_RWCarryFlag,Ch_RFlags,Ch_RWFlags]*Ch<>[];
|
|
||||||
R_SUBFLAGPARITY:
|
|
||||||
RegReadByInstruction:=[Ch_RParityFlag,Ch_RWParityFlag,Ch_RFlags,Ch_RWFlags]*Ch<>[];
|
|
||||||
R_SUBFLAGAUXILIARY:
|
|
||||||
RegReadByInstruction:=[Ch_RAuxiliaryFlag,Ch_RWAuxiliaryFlag,Ch_RFlags,Ch_RWFlags]*Ch<>[];
|
|
||||||
R_SUBFLAGZERO:
|
|
||||||
RegReadByInstruction:=[Ch_RZeroFlag,Ch_RWZeroFlag,Ch_RFlags,Ch_RWFlags]*Ch<>[];
|
|
||||||
R_SUBFLAGSIGN:
|
|
||||||
RegReadByInstruction:=[Ch_RSignFlag,Ch_RWSignFlag,Ch_RFlags,Ch_RWFlags]*Ch<>[];
|
|
||||||
R_SUBFLAGOVERFLOW:
|
|
||||||
RegReadByInstruction:=[Ch_ROverflowFlag,Ch_RWOverflowFlag,Ch_RFlags,Ch_RWFlags]*Ch<>[];
|
|
||||||
R_SUBFLAGINTERRUPT:
|
|
||||||
RegReadByInstruction:=[Ch_RFlags,Ch_RWFlags]*Ch<>[];
|
|
||||||
R_SUBFLAGDIRECTION:
|
|
||||||
RegReadByInstruction:=[Ch_RDirFlag,Ch_RFlags,Ch_RWFlags]*Ch<>[];
|
|
||||||
else
|
|
||||||
internalerror(2017042601);
|
|
||||||
end;
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
if (Ch_NoReadIfEqualRegs in Ch) and (p.ops=2) and
|
|
||||||
(p.oper[0]^.typ=top_reg) and (p.oper[1]^.typ=top_reg) and
|
|
||||||
(p.oper[0]^.reg=p.oper[1]^.reg) then
|
|
||||||
exit;
|
|
||||||
if ([CH_RWOP1,CH_ROP1,CH_MOP1]*Ch<>[]) and reginop(reg,p.oper[0]^) then
|
|
||||||
begin
|
|
||||||
RegReadByInstruction := true;
|
|
||||||
exit
|
|
||||||
end;
|
|
||||||
if ([Ch_RWOP2,Ch_ROP2,Ch_MOP2]*Ch<>[]) and reginop(reg,p.oper[1]^) then
|
|
||||||
begin
|
|
||||||
RegReadByInstruction := true;
|
|
||||||
exit
|
|
||||||
end;
|
|
||||||
if ([Ch_RWOP3,Ch_ROP3,Ch_MOP3]*Ch<>[]) and reginop(reg,p.oper[2]^) then
|
|
||||||
begin
|
|
||||||
RegReadByInstruction := true;
|
|
||||||
exit
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
{ returns true if p contains a memory operand with a segment set }
|
{ returns true if p contains a memory operand with a segment set }
|
||||||
function InsContainsSegRef(p: taicpu): boolean;
|
function InsContainsSegRef(p: taicpu): boolean;
|
||||||
var
|
var
|
||||||
|
@ -37,6 +37,8 @@ unit aoptx86;
|
|||||||
type
|
type
|
||||||
TX86AsmOptimizer = class(TAsmOptimizer)
|
TX86AsmOptimizer = class(TAsmOptimizer)
|
||||||
function RegLoadedWithNewValue(reg : tregister; hp : tai) : boolean; override;
|
function RegLoadedWithNewValue(reg : tregister; hp : tai) : boolean; override;
|
||||||
|
function InstructionLoadsFromReg(const reg : TRegister; const hp : tai) : boolean; override;
|
||||||
|
function RegReadByInstruction(reg : TRegister; hp : tai) : boolean;
|
||||||
protected
|
protected
|
||||||
{ checks whether loading a new value in reg1 overwrites the entirety of reg2 }
|
{ checks whether loading a new value in reg1 overwrites the entirety of reg2 }
|
||||||
function Reg1WriteOverwritesReg2Entirely(reg1, reg2: tregister): boolean;
|
function Reg1WriteOverwritesReg2Entirely(reg1, reg2: tregister): boolean;
|
||||||
@ -217,6 +219,222 @@ unit aoptx86;
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function TX86AsmOptimizer.InstructionLoadsFromReg(const reg: TRegister;const hp: tai): boolean;
|
||||||
|
begin
|
||||||
|
Result:=RegReadByInstruction(reg,hp);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function TX86AsmOptimizer.RegReadByInstruction(reg: TRegister; hp: tai): boolean;
|
||||||
|
var
|
||||||
|
p: taicpu;
|
||||||
|
opcount: longint;
|
||||||
|
begin
|
||||||
|
RegReadByInstruction := false;
|
||||||
|
if hp.typ <> ait_instruction then
|
||||||
|
exit;
|
||||||
|
p := taicpu(hp);
|
||||||
|
case p.opcode of
|
||||||
|
A_CALL:
|
||||||
|
regreadbyinstruction := true;
|
||||||
|
A_IMUL:
|
||||||
|
case p.ops of
|
||||||
|
1:
|
||||||
|
regReadByInstruction := RegInOp(reg,p.oper[0]^) or
|
||||||
|
(
|
||||||
|
((getregtype(reg)=R_INTREGISTER) and (getsupreg(reg)=RS_EAX)) and
|
||||||
|
((getsubreg(reg)<>R_SUBH) or (p.opsize<>S_B))
|
||||||
|
);
|
||||||
|
2,3:
|
||||||
|
regReadByInstruction :=
|
||||||
|
reginop(reg,p.oper[0]^) or
|
||||||
|
reginop(reg,p.oper[1]^);
|
||||||
|
end;
|
||||||
|
A_MUL:
|
||||||
|
begin
|
||||||
|
regReadByInstruction := RegInOp(reg,p.oper[0]^) or
|
||||||
|
(
|
||||||
|
((getregtype(reg)=R_INTREGISTER) and (getsupreg(reg)=RS_EAX)) and
|
||||||
|
((getsubreg(reg)<>R_SUBH) or (p.opsize<>S_B))
|
||||||
|
);
|
||||||
|
end;
|
||||||
|
A_IDIV,A_DIV:
|
||||||
|
begin
|
||||||
|
regReadByInstruction := RegInOp(reg,p.oper[0]^) or
|
||||||
|
(
|
||||||
|
(getregtype(reg)=R_INTREGISTER) and
|
||||||
|
(
|
||||||
|
(getsupreg(reg)=RS_EAX) or ((getsupreg(reg)=RS_EDX) and (p.opsize<>S_B))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
end;
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
if (p.opcode=A_LEA) and is_segment_reg(reg) then
|
||||||
|
begin
|
||||||
|
RegReadByInstruction := false;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
for opcount := 0 to p.ops-1 do
|
||||||
|
if (p.oper[opCount]^.typ = top_ref) and
|
||||||
|
RegInRef(reg,p.oper[opcount]^.ref^) then
|
||||||
|
begin
|
||||||
|
RegReadByInstruction := true;
|
||||||
|
exit
|
||||||
|
end;
|
||||||
|
{ special handling for SSE MOVSD }
|
||||||
|
if (p.opcode=A_MOVSD) and (p.ops>0) then
|
||||||
|
begin
|
||||||
|
if p.ops<>2 then
|
||||||
|
internalerror(2017042702);
|
||||||
|
regReadByInstruction := reginop(reg,p.oper[0]^) or
|
||||||
|
(
|
||||||
|
(p.oper[1]^.typ=top_reg) and (p.oper[0]^.typ=top_reg) and reginop(reg, p.oper[1]^)
|
||||||
|
);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
with insprop[p.opcode] do
|
||||||
|
begin
|
||||||
|
if getregtype(reg)=R_INTREGISTER then
|
||||||
|
begin
|
||||||
|
case getsupreg(reg) of
|
||||||
|
RS_EAX:
|
||||||
|
if [Ch_REAX,Ch_RWEAX,Ch_MEAX]*Ch<>[] then
|
||||||
|
begin
|
||||||
|
RegReadByInstruction := true;
|
||||||
|
exit
|
||||||
|
end;
|
||||||
|
RS_ECX:
|
||||||
|
if [Ch_RECX,Ch_RWECX,Ch_MECX]*Ch<>[] then
|
||||||
|
begin
|
||||||
|
RegReadByInstruction := true;
|
||||||
|
exit
|
||||||
|
end;
|
||||||
|
RS_EDX:
|
||||||
|
if [Ch_REDX,Ch_RWEDX,Ch_MEDX]*Ch<>[] then
|
||||||
|
begin
|
||||||
|
RegReadByInstruction := true;
|
||||||
|
exit
|
||||||
|
end;
|
||||||
|
RS_EBX:
|
||||||
|
if [Ch_REBX,Ch_RWEBX,Ch_MEBX]*Ch<>[] then
|
||||||
|
begin
|
||||||
|
RegReadByInstruction := true;
|
||||||
|
exit
|
||||||
|
end;
|
||||||
|
RS_ESP:
|
||||||
|
if [Ch_RESP,Ch_RWESP,Ch_MESP]*Ch<>[] then
|
||||||
|
begin
|
||||||
|
RegReadByInstruction := true;
|
||||||
|
exit
|
||||||
|
end;
|
||||||
|
RS_EBP:
|
||||||
|
if [Ch_REBP,Ch_RWEBP,Ch_MEBP]*Ch<>[] then
|
||||||
|
begin
|
||||||
|
RegReadByInstruction := true;
|
||||||
|
exit
|
||||||
|
end;
|
||||||
|
RS_ESI:
|
||||||
|
if [Ch_RESI,Ch_RWESI,Ch_MESI]*Ch<>[] then
|
||||||
|
begin
|
||||||
|
RegReadByInstruction := true;
|
||||||
|
exit
|
||||||
|
end;
|
||||||
|
RS_EDI:
|
||||||
|
if [Ch_REDI,Ch_RWEDI,Ch_MEDI]*Ch<>[] then
|
||||||
|
begin
|
||||||
|
RegReadByInstruction := true;
|
||||||
|
exit
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
if SuperRegistersEqual(reg,NR_DEFAULTFLAGS) then
|
||||||
|
begin
|
||||||
|
if (Ch_RFLAGScc in Ch) and not(getsubreg(reg) in [R_SUBW,R_SUBD,R_SUBQ]) then
|
||||||
|
begin
|
||||||
|
case p.condition of
|
||||||
|
C_A,C_NBE, { CF=0 and ZF=0 }
|
||||||
|
C_BE,C_NA: { CF=1 or ZF=1 }
|
||||||
|
RegReadByInstruction:=getsubreg(reg) in [R_SUBFLAGCARRY,R_SUBFLAGZERO];
|
||||||
|
C_AE,C_NB,C_NC, { CF=0 }
|
||||||
|
C_B,C_NAE,C_C: { CF=1 }
|
||||||
|
RegReadByInstruction:=getsubreg(reg) in [R_SUBFLAGCARRY];
|
||||||
|
C_NE,C_NZ, { ZF=0 }
|
||||||
|
C_E,C_Z: { ZF=1 }
|
||||||
|
RegReadByInstruction:=getsubreg(reg) in [R_SUBFLAGZERO];
|
||||||
|
C_G,C_NLE, { ZF=0 and SF=OF }
|
||||||
|
C_LE,C_NG: { ZF=1 or SF<>OF }
|
||||||
|
RegReadByInstruction:=getsubreg(reg) in [R_SUBFLAGZERO,R_SUBFLAGSIGN,R_SUBFLAGOVERFLOW];
|
||||||
|
C_GE,C_NL, { SF=OF }
|
||||||
|
C_L,C_NGE: { SF<>OF }
|
||||||
|
RegReadByInstruction:=getsubreg(reg) in [R_SUBFLAGSIGN,R_SUBFLAGOVERFLOW];
|
||||||
|
C_NO, { OF=0 }
|
||||||
|
C_O: { OF=1 }
|
||||||
|
RegReadByInstruction:=getsubreg(reg) in [R_SUBFLAGOVERFLOW];
|
||||||
|
C_NP,C_PO, { PF=0 }
|
||||||
|
C_P,C_PE: { PF=1 }
|
||||||
|
RegReadByInstruction:=getsubreg(reg) in [R_SUBFLAGPARITY];
|
||||||
|
C_NS, { SF=0 }
|
||||||
|
C_S: { SF=1 }
|
||||||
|
RegReadByInstruction:=getsubreg(reg) in [R_SUBFLAGSIGN];
|
||||||
|
else
|
||||||
|
internalerror(2017042701);
|
||||||
|
end;
|
||||||
|
if RegReadByInstruction then
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
case getsubreg(reg) of
|
||||||
|
R_SUBW,R_SUBD,R_SUBQ:
|
||||||
|
RegReadByInstruction :=
|
||||||
|
[Ch_RCarryFlag,Ch_RParityFlag,Ch_RAuxiliaryFlag,Ch_RZeroFlag,Ch_RSignFlag,Ch_ROverflowFlag,
|
||||||
|
Ch_RWCarryFlag,Ch_RWParityFlag,Ch_RWAuxiliaryFlag,Ch_RWZeroFlag,Ch_RWSignFlag,Ch_RWOverflowFlag,
|
||||||
|
Ch_RDirFlag,Ch_RFlags,Ch_RWFlags,Ch_RFLAGScc]*Ch<>[];
|
||||||
|
R_SUBFLAGCARRY:
|
||||||
|
RegReadByInstruction:=[Ch_RCarryFlag,Ch_RWCarryFlag,Ch_RFlags,Ch_RWFlags]*Ch<>[];
|
||||||
|
R_SUBFLAGPARITY:
|
||||||
|
RegReadByInstruction:=[Ch_RParityFlag,Ch_RWParityFlag,Ch_RFlags,Ch_RWFlags]*Ch<>[];
|
||||||
|
R_SUBFLAGAUXILIARY:
|
||||||
|
RegReadByInstruction:=[Ch_RAuxiliaryFlag,Ch_RWAuxiliaryFlag,Ch_RFlags,Ch_RWFlags]*Ch<>[];
|
||||||
|
R_SUBFLAGZERO:
|
||||||
|
RegReadByInstruction:=[Ch_RZeroFlag,Ch_RWZeroFlag,Ch_RFlags,Ch_RWFlags]*Ch<>[];
|
||||||
|
R_SUBFLAGSIGN:
|
||||||
|
RegReadByInstruction:=[Ch_RSignFlag,Ch_RWSignFlag,Ch_RFlags,Ch_RWFlags]*Ch<>[];
|
||||||
|
R_SUBFLAGOVERFLOW:
|
||||||
|
RegReadByInstruction:=[Ch_ROverflowFlag,Ch_RWOverflowFlag,Ch_RFlags,Ch_RWFlags]*Ch<>[];
|
||||||
|
R_SUBFLAGINTERRUPT:
|
||||||
|
RegReadByInstruction:=[Ch_RFlags,Ch_RWFlags]*Ch<>[];
|
||||||
|
R_SUBFLAGDIRECTION:
|
||||||
|
RegReadByInstruction:=[Ch_RDirFlag,Ch_RFlags,Ch_RWFlags]*Ch<>[];
|
||||||
|
else
|
||||||
|
internalerror(2017042601);
|
||||||
|
end;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
if (Ch_NoReadIfEqualRegs in Ch) and (p.ops=2) and
|
||||||
|
(p.oper[0]^.typ=top_reg) and (p.oper[1]^.typ=top_reg) and
|
||||||
|
(p.oper[0]^.reg=p.oper[1]^.reg) then
|
||||||
|
exit;
|
||||||
|
if ([CH_RWOP1,CH_ROP1,CH_MOP1]*Ch<>[]) and reginop(reg,p.oper[0]^) then
|
||||||
|
begin
|
||||||
|
RegReadByInstruction := true;
|
||||||
|
exit
|
||||||
|
end;
|
||||||
|
if ([Ch_RWOP2,Ch_ROP2,Ch_MOP2]*Ch<>[]) and reginop(reg,p.oper[1]^) then
|
||||||
|
begin
|
||||||
|
RegReadByInstruction := true;
|
||||||
|
exit
|
||||||
|
end;
|
||||||
|
if ([Ch_RWOP3,Ch_ROP3,Ch_MOP3]*Ch<>[]) and reginop(reg,p.oper[2]^) then
|
||||||
|
begin
|
||||||
|
RegReadByInstruction := true;
|
||||||
|
exit
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
{$ifdef DEBUG_AOPTCPU}
|
{$ifdef DEBUG_AOPTCPU}
|
||||||
procedure TX86AsmOptimizer.DebugMsg(const s: string;p : tai);
|
procedure TX86AsmOptimizer.DebugMsg(const s: string;p : tai);
|
||||||
begin
|
begin
|
||||||
|
Loading…
Reference in New Issue
Block a user