+ first version, added TAsmDFACpu object and CpuDFA method

This commit is contained in:
Jonas Maebe 1999-08-11 14:22:56 +00:00
parent dbb0bebac9
commit 265f3c09be

View File

@ -0,0 +1,182 @@
{
$Id $
Copyright (c) 1999 by Jonas Maebe, member of the Free Pascal
Development Team
This unit contains the processor specific implementation of the
assembler optimizer data flow analyzer.
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;
Interface
uses Aasm, AoptCpub, AoptObj, AoptDA;
Type TAsmDFACpu = Object(TAsmDFA)
{ uses the same constructor as TAoptDFA = constructor from TAoptObj }
{ handles the processor dependent dataflow analizing }
Procedure CpuDFA(p: PInstr); Virtual;
End;
Implementation
Procedure TAsmDFACpu(p: PInstr);
{ Analyzes the Data Flow of an assembler list. Analyses the reg contents }
{ for the instructions between blockstart and blockend. Returns the last pai }
{ which has been processed }
Var CurProp: PPaiProp;
InstrProp: TAsmInstrucProp;
Cnt: Byte;
Begin
CurProp := PPaiProp(p^.OptInfo);
Case p^.Opcode Of
A_DIV, A_IDIV, A_MUL:
Begin
CurProp^.ReadOp(p^.oper[0]);
CurProp^.ReadReg(R_EAX);
If (p^.OpCode = A_IDIV) or
(p^.OpCode = A_DIV) Then
CurProp^.ReadReg(R_EDX);
DestroyReg(R_EAX)
End;
A_IMUL:
Begin
CurProp^.ReadOp(p^.oper[0]);
CurProp^.ReadOp(p^.oper[1]);
If (p^.oper[2].typ = top_none) Then
If (p^.oper[1].typ = top_none) Then
Begin
CurProp^.ReadReg(R_EAX);
CurProp^.DestroyReg(R_EAX, InstrSinceLastMod);
CurProp^.DestroyReg(R_EDX, InstrSinceLastMod)
End
Else
{$ifdef arithopt}
CurProp^.ModifyOp(p^.oper[1], InstrSinceLastMod)
{$else arithopt}
CurProp^.DestroyOp(p^.oper[1], InstrSinceLastMod)
{$endif arithopt}
Else
{$ifdef arithopt}
CurProp^.ModifyOp(p^.oper[2], InstrSinceLastMod);
{$else arithopt}
CurProp^.DestroyOp(p^.oper[2], InstrsinceLastMod);
{$endif arithopt}
End;
A_XOR:
Begin
CurProp^.ReadOp(p^.oper[0]);
CurProp^.ReadOp(p^.oper[1]);
If (p^.oper[0].typ = top_reg) And
(p^.oper[1].typ = top_reg) And
(p^.oper[0].reg = p^.oper[1].reg) Then
Begin
CurProp^.DestroyReg(p^.oper[0].reg, InstrSinceLastMod);
CurProp^.Regs[RegMaxSize(p^.oper[0].reg)].typ := Con_Const;
CurProp^.Regs[RegMaxSize(p^.oper[0].reg)].StartMod := Pointer(0)
End
Else
{$Ifdef ArithOpt}
CurProp^.ModifyOp(p^.oper[1], InstrSinceLastMod);
{$Else ArithOpt}
CurProp^.DestroyOp(p^.oper[1], InstrSinceLastMod);
{$EndIf ArithOpt}
End
Else
Begin
InstrProp := AsmInstr[p^.OpCode];
Cnt := 1;
While (Cnt <= MaxCh) And
(InstrProp.Ch[Cnt] <> C_None) Do
Begin
Case InstrProp.Ch[Cnt] Of
C_REAX..C_REDI:
CurProp^.ReadReg(TCh2Reg(InstrProp.Ch[Cnt]));
C_WEAX..C_RWEDI:
Begin
If (InstrProp.Ch[Cnt] >= C_RWEAX) Then
CurProp^.ReadReg(TCh2Reg(InstrProp.Ch[Cnt]));
CurProp^.DestroyReg(TCh2Reg(InstrProp.Ch[Cnt]),InstrSinceLastMod);
End;
{$ifdef arithopt}
C_MEAX..C_MEDI:
CurProp^.ModifyReg(TCh2Reg(InstrProp.Ch[Cnt]), InstrSinceLastMod);
{$endif arithopt}
C_CDirFlag: CurProp^.CondRegs.ClearFlag(DirFlag);
C_SDirFlag: CurProp^.CondRegs.SetFlag(DirFlag);
C_Rop1: ReadOp(CurProp, p^.oper[0]);
C_Rop2: ReadOp(CurProp, p^.oper[1]);
C_ROp3: ReadOp(CurProp, p^.oper[2]);
C_Wop1..C_RWop1:
Begin
If (InstrProp.Ch[Cnt] = C_RWop1) Then
ReadOp(CurProp, p^.oper[0]);
DestroyOp(p, p^.oper[0], InstrSinceLastMod);
End;
{$ifdef arithopt}
C_Mop1:
CurProp^.ModifyOp(p^.oper[0], InstrSinceLastMod);
{$endif arithopt}
C_Wop2..C_RWop2:
Begin
If (InstrProp.Ch[Cnt] = C_RWop2) Then
ReadOp(CurProp, p^.oper[1]);
DestroyOp(p, p^.oper[1], InstrSinceLastMod);
End;
{$ifdef arithopt}
C_Mop2:
CurProp^.ModifyOp(p^.oper[1], InstrSinceLastMod);
{$endif arithopt}
C_Wop3..C_RWop3:
Begin
If (InstrProp.Ch[Cnt] = C_RWop3) Then
ReadOp(CurProp, p^.oper[2]);
DestroyOp(p, p^.oper[2], InstrSinceLastMod);
End;
{$ifdef arithopt}
C_Mop3:
CurProp^.ModifyOp(p^.oper[2], InstrSinceLastMod);
{$endif arithopt}
C_WMemEDI:
Begin
CurProp^.ReadReg(R_EDI);
FillChar(TmpRef, SizeOf(TmpRef), 0);
TmpRef.Base := R_EDI;
DestroyRefs(p, TmpRef, R_NO, InstrSinceLastMod)
End;
C_RFlags, C_WFlags, C_RWFlags, C_FPU:;
Else DestroyAllRegs(CurProp, InstrSinceLastMod)
End;
Inc(Cnt)
End
End
End
End;
End.
{
$Log$
Revision 1.1 1999-08-11 14:22:56 jonas
+ first version, added TAsmDFACpu object and CpuDFA method
}