summaryrefslogtreecommitdiff
path: root/compiler/z80/aoptcpu.pas
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/z80/aoptcpu.pas')
-rw-r--r--compiler/z80/aoptcpu.pas242
1 files changed, 242 insertions, 0 deletions
diff --git a/compiler/z80/aoptcpu.pas b/compiler/z80/aoptcpu.pas
new file mode 100644
index 0000000000..39fa614c73
--- /dev/null
+++ b/compiler/z80/aoptcpu.pas
@@ -0,0 +1,242 @@
+{
+ Copyright (c) 1998-2002 by Jonas Maebe, member of the Free Pascal
+ Development Team
+
+ This unit implements the Z80 optimizer object
+
+ 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 aoptcpu;
+
+{$i fpcdefs.inc}
+
+{$define DEBUG_AOPTCPU}
+
+Interface
+
+uses cpubase, cgbase, aasmtai, aopt,AoptObj, aoptcpub;
+
+Type
+ TCpuAsmOptimizer = class(TAsmOptimizer)
+ { outputs a debug message into the assembler file }
+ procedure DebugMsg(const s: string; p: tai);
+
+ Function GetNextInstructionUsingReg(Current: tai; Var Next: tai;reg : TRegister): Boolean;
+ function RegLoadedWithNewValue(reg : tregister; hp : tai) : boolean; override;
+ function InstructionLoadsFromReg(const reg : TRegister; const hp : tai) : boolean; override;
+
+ { uses the same constructor as TAopObj }
+ function PeepHoleOptPass1Cpu(var p: tai): boolean; override;
+ procedure PeepHoleOptPass2;override;
+ End;
+
+Implementation
+
+ uses
+ cutils,
+ verbose,
+ cpuinfo,
+ aasmbase,aasmcpu,aasmdata,
+ globals,globtype,
+ cgutils;
+
+ type
+ TAsmOpSet = set of TAsmOp;
+
+ function CanBeCond(p : tai) : boolean;
+ begin
+ result:=(p.typ=ait_instruction) and (taicpu(p).condition=C_None);
+ end;
+
+
+ function RefsEqual(const r1, r2: treference): boolean;
+ begin
+ refsequal :=
+ (r1.offset = r2.offset) and
+ (r1.base = r2.base) and
+ (r1.index = r2.index) and (r1.scalefactor = r2.scalefactor) and
+ (r1.symbol=r2.symbol) and (r1.refaddr = r2.refaddr) and
+ (r1.relsymbol = r2.relsymbol);
+ end;
+
+
+ function MatchOperand(const oper1: TOper; const oper2: TOper): boolean; inline;
+ begin
+ result:=oper1.typ=oper2.typ;
+
+ if result then
+ case oper1.typ of
+ top_const:
+ Result:=oper1.val = oper2.val;
+ top_reg:
+ Result:=oper1.reg = oper2.reg;
+ top_ref:
+ Result:=RefsEqual(oper1.ref^, oper2.ref^);
+ else Result:=false;
+ end
+ end;
+
+
+ function MatchOperand(const oper: TOper; const reg: TRegister): boolean; inline;
+ begin
+ result := (oper.typ = top_reg) and (oper.reg = reg);
+ end;
+
+
+ function MatchInstruction(const instr: tai; const op: TAsmOp): boolean;
+ begin
+ result :=
+ (instr.typ = ait_instruction) and
+ (taicpu(instr).opcode = op);
+ end;
+
+
+ function MatchInstruction(const instr: tai; const ops: TAsmOpSet): boolean;
+ begin
+ result :=
+ (instr.typ = ait_instruction) and
+ (taicpu(instr).opcode in ops);
+ end;
+
+
+ function MatchInstruction(const instr: tai; const ops: TAsmOpSet;opcount : byte): boolean;
+ begin
+ result :=
+ (instr.typ = ait_instruction) and
+ (taicpu(instr).opcode in ops) and
+ (taicpu(instr).ops=opcount);
+ end;
+
+
+ function MatchOpType(const instr : tai;ot0,ot1 : toptype) : Boolean;
+ begin
+ Result:=(taicpu(instr).ops=2) and
+ (taicpu(instr).oper[0]^.typ=ot0) and
+ (taicpu(instr).oper[1]^.typ=ot1);
+ end;
+
+{$ifdef DEBUG_AOPTCPU}
+ procedure TCpuAsmOptimizer.DebugMsg(const s: string;p : tai);
+ begin
+ asml.insertbefore(tai_comment.Create(strpnew(s)), p);
+ end;
+{$else DEBUG_AOPTCPU}
+ procedure TCpuAsmOptimizer.DebugMsg(const s: string;p : tai);inline;
+ begin
+ end;
+{$endif DEBUG_AOPTCPU}
+
+
+ function TCpuAsmOptimizer.GetNextInstructionUsingReg(Current: tai;
+ var Next: tai; reg: TRegister): Boolean;
+ begin
+ Next:=Current;
+ repeat
+ Result:=GetNextInstruction(Next,Next);
+ until not(cs_opt_level3 in current_settings.optimizerswitches) or not(Result) or (Next.typ<>ait_instruction) or (RegInInstruction(reg,Next)) or
+ (is_calljmp(taicpu(Next).opcode));
+ 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;
+ internalerror(2017032606);
+ //p := taicpu(hp);
+ //Result := ((p.opcode in [A_LDI,A_MOV,A_LDS]) and (reg=p.oper[0]^.reg) and ((p.oper[1]^.typ<>top_reg) or (reg<>p.oper[0]^.reg))) or
+ // ((p.opcode in [A_LD,A_LDD,A_LPM]) and (reg=p.oper[0]^.reg) and not(RegInRef(reg,p.oper[1]^.ref^))) or
+ // ((p.opcode in [A_MOVW]) and ((reg=p.oper[0]^.reg) or (TRegister(ord(reg)+1)=p.oper[0]^.reg)) and not(reg=p.oper[1]^.reg) and not(TRegister(ord(reg)+1)=p.oper[1]^.reg)) or
+ // ((p.opcode in [A_POP]) and (reg=p.oper[0]^.reg));
+ end;
+
+
+ function TCpuAsmOptimizer.InstructionLoadsFromReg(const reg: TRegister; const hp: tai): boolean;
+ var
+ p: taicpu;
+ i: longint;
+ begin
+ Result := false;
+
+ 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;
+ end;
+
+ function TCpuAsmOptimizer.PeepHoleOptPass1Cpu(var p: tai): boolean;
+ var
+ hp1,hp2,hp3,hp4,hp5: tai;
+ alloc, dealloc: tai_regalloc;
+ i: integer;
+ l: TAsmLabel;
+ //TmpUsedRegs : TAllUsedRegs;
+ begin
+ result := false;
+ //case p.typ of
+ // ait_instruction:
+ // begin
+ // end;
+ //end;
+ end;
+
+
+ procedure TCpuAsmOptimizer.PeepHoleOptPass2;
+ begin
+ end;
+
+begin
+ casmoptimizer:=TCpuAsmOptimizer;
+End.