+ Z80: implemented TCpuAsmOptimizer.InstructionLoadsFromReg

git-svn-id: trunk@45344 -
This commit is contained in:
nickysn 2020-05-11 22:24:20 +00:00
parent 05091cf0dd
commit bb4d7a7a50

View File

@ -176,44 +176,108 @@ Implementation
function TCpuAsmOptimizer.InstructionLoadsFromReg(const reg: TRegister; const hp: tai): boolean;
var
p: taicpu;
i: longint;
begin
Result := false;
if not (assigned(hp) and (hp.typ = ait_instruction)) then
exit;
p:=taicpu(hp);
internalerror(2017032607);
//if not (assigned(hp) and (hp.typ = ait_instruction)) then
// exit;
//p:=taicpu(hp);
//
//i:=0;
//
//{ we do not care about the stack pointer }
//if p.opcode in [A_POP] then
// exit;
//
//{ first operand only written?
// then skip it }
//if p.opcode in [A_MOV,A_LD,A_LDD,A_LDS,A_LPM,A_LDI,A_MOVW] then
// i:=1;
//
//while(i<p.ops) do
// begin
// case p.oper[I]^.typ of
// top_reg:
// Result := (p.oper[I]^.reg = reg) or
// { MOVW }
// ((i=1) and (p.opcode=A_MOVW) and (getsupreg(p.oper[0]^.reg)+1=getsupreg(reg)));
// top_ref:
// Result :=
// (p.oper[I]^.ref^.base = reg) or
// (p.oper[I]^.ref^.index = reg);
// end;
// { Bailout if we found something }
// if Result then
// exit;
// Inc(I);
// end;
case p.opcode of
A_LD,A_BIT,A_SET,A_RES:
begin
if p.ops<>2 then
internalerror(2020051102);
result:=((p.oper[0]^.typ=top_ref) and RegInRef(reg,p.oper[0]^.ref^)) or
RegInOp(reg,p.oper[1]^);
end;
A_PUSH,A_INC,A_DEC,A_RLC,A_RRC,A_SLA,A_SRA,A_SRL:
begin
if p.ops<>1 then
internalerror(2020051103);
result:=RegInOp(reg,p.oper[0]^);
end;
A_POP:
result:=(reg=NR_SP);
A_EX,A_ADD,A_SUB,A_AND,A_OR,A_XOR,A_CP:
begin
if p.ops<>2 then
internalerror(2020051104);
result:=RegInOp(reg,p.oper[0]^) or
RegInOp(reg,p.oper[1]^);
end;
A_EXX:
result:=SuperRegistersEqual(reg,NR_BC) or SuperRegistersEqual(reg,NR_DE) or SuperRegistersEqual(reg,NR_HL) or
SuperRegistersEqual(reg,NR_BC_) or SuperRegistersEqual(reg,NR_DE_) or SuperRegistersEqual(reg,NR_HL_);
A_LDI,A_LDIR,A_LDD,A_LDDR:
result:=SuperRegistersEqual(reg,NR_BC) or SuperRegistersEqual(reg,NR_DE) or SuperRegistersEqual(reg,NR_HL);
A_CPI,A_CPIR,A_CPD,A_CPDR:
result:=SuperRegistersEqual(reg,NR_BC) or SuperRegistersEqual(reg,NR_HL) or RegistersInterfere(reg,NR_A);
A_ADC,A_SBC:
begin
if p.ops<>2 then
internalerror(2020051105);
result:=RegInOp(reg,p.oper[0]^) or
RegInOp(reg,p.oper[1]^) or (reg=NR_CARRYFLAG) or (reg=NR_DEFAULTFLAGS);
end;
A_DAA:
result:=RegistersInterfere(reg,NR_A) or (reg=NR_CARRYFLAG) or (reg=NR_HALFCARRYFLAG) or (reg=NR_ADDSUBTRACTFLAG) or (reg=NR_DEFAULTFLAGS);
A_CPL,A_NEG,A_RLCA,A_RRCA:
result:=RegistersInterfere(reg,NR_A);
A_CCF:
result:=(reg=NR_CARRYFLAG) or (reg=NR_DEFAULTFLAGS);
A_SCF,A_NOP,A_HALT,A_DI,A_EI,A_IM:
result:=false;
A_RLA,A_RRA:
result:=RegistersInterfere(reg,NR_A) or (reg=NR_CARRYFLAG) or (reg=NR_DEFAULTFLAGS);
A_RL,A_RR:
begin
if p.ops<>1 then
internalerror(2020051106);
result:=RegInOp(reg,p.oper[0]^) or (reg=NR_CARRYFLAG) or (reg=NR_DEFAULTFLAGS);
end;
A_RLD,A_RRD:
result:=RegistersInterfere(reg,NR_A) or RegistersInterfere(reg,NR_HL);
A_JP,A_JR:
begin
if p.ops<>1 then
internalerror(2020051107);
if RegInOp(reg,p.oper[0]^) then
result:=true
else
case p.condition of
C_None:
result:=false;
C_NZ,C_Z:
result:=(reg=NR_ZEROFLAG) or (reg=NR_DEFAULTFLAGS);
C_NC,C_C:
result:=(reg=NR_CARRYFLAG) or (reg=NR_DEFAULTFLAGS);
C_PO,C_PE:
result:=(reg=NR_PARITYOVERFLOWFLAG) or (reg=NR_DEFAULTFLAGS);
C_P,C_M:
result:=(reg=NR_SIGNFLAG) or (reg=NR_DEFAULTFLAGS);
end;
end;
A_DJNZ:
result:=RegistersInterfere(reg,NR_B);
A_CALL,A_RET,A_RETI,A_RETN,A_RST:
result:=true;
A_IN:
begin
if p.ops<>2 then
internalerror(2020051109);
result:=(p.oper[1]^.typ=top_ref) and (p.oper[1]^.ref^.base=NR_C) and RegistersInterfere(reg,NR_BC);
end;
A_OUT:
begin
if p.ops<>2 then
internalerror(2020051110);
result:=RegInOp(reg,p.oper[1]^) or (p.oper[0]^.typ=top_ref) and (p.oper[0]^.ref^.base=NR_C) and RegistersInterfere(reg,NR_BC);
end;
A_INI,A_INIR,A_IND,A_INDR,A_OUTI,A_OTIR,A_OUTD,A_OTDR:
result:=SuperRegistersEqual(reg,NR_BC) or SuperRegistersEqual(reg,NR_HL);
else
internalerror(2020051101);
end;
end;
function TCpuAsmOptimizer.PeepHoleOptPass1Cpu(var p: tai): boolean;