diff --git a/compiler/new/i386/aoptcpud.pas b/compiler/new/i386/aoptcpud.pas new file mode 100644 index 0000000000..45abfe0681 --- /dev/null +++ b/compiler/new/i386/aoptcpud.pas @@ -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 + +}