2
$Id: aoptda.pas,v 1.7 2004/01/31 17:45:16 peter Exp $
3
Copyright (c) 1998-2002 by Jonas Maebe, member of the Free Pascal
6
This unit contains the data flow analyzer object of the assembler
9
This program is free software; you can redistribute it and/or modify
10
it under the terms of the GNU General Public License as published by
11
the Free Software Foundation; either version 2 of the License, or
12
(at your option) any later version.
14
This program is distributed in the hope that it will be useful,
15
but WITHOUT ANY WARRANTY; without even the implied warranty of
16
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
GNU General Public License for more details.
19
You should have received a copy of the GNU General Public License
20
along with this program; if not, write to the Free Software
21
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23
****************************************************************************
29
uses aasm, cpubase, aoptcpub, aoptbase, aoptcpu;
32
TAOptDFA = Object(TAoptCpu)
33
{ uses the same constructor as TAoptCpu = constructor from TAoptObj }
35
{ gathers the information regarding the contents of every register }
36
{ at the end of every instruction }
39
{ handles the processor dependent dataflow analizing }
40
Procedure CpuDFA(p: PInstr); Virtual;
42
{ How many instructions are between the current instruction and the }
43
{ last one that modified the register }
44
InstrSinceLastMod: TInstrSinceLastMod;
46
{ convert a TInsChange value into the corresponding register }
47
Function TCh2Reg(Ch: TInsChange): TRegister; Virtual;
48
{ returns whether the instruction P reads from register Reg }
49
Function RegReadByInstr(Reg: TRegister; p: Pai): Boolean; Virtual;
54
uses globals, aoptobj;
56
Procedure TAOptDFA.DoDFA;
57
{ Analyzes the Data Flow of an assembler list. Analyses the reg contents }
58
{ for the instructions between blockstart and blockend. Returns the last pai }
59
{ which has been processed }
63
p, hp, NewBlockStart : Pai;
69
NewBlockStart := SkipHead(p);
70
{ done implicitely by the constructor
71
FillChar(InstrSinceLastMod, SizeOf(InstrSinceLastMod), 0); }
72
While (P <> BlockEnd) Do
74
CurProp := New(PPaiProp, init);
75
If (p <> NewBlockStart) Then
77
GetLastInstruction(p, hp);
78
CurProp^.Regs := PPaiProp(hp^.OptInfo)^.Regs;
81
CurProp^.CondRegs.Flags :=
82
PPaiProp(hp^.OptInfo)^.CondRegs.Flags;
85
CurProp^.UsedRegs.InitWithValue(UsedRegs.GetUsedRegs);
86
UsedRegs.Update(Pai(p^.Next));
87
PPaiProp(p^.OptInfo) := CurProp;
88
For TmpReg := LoGPReg To HiGPReg Do
89
Inc(InstrSinceLastMod[TmpReg]);
92
If (Pai_label(p)^.l^.is_used) Then
93
CurProp^.DestroyAllRegs(InstrSinceLastMod);
95
ait_stabs, ait_stabn, ait_stab_function_name:;
98
if not(PInstr(p)^.is_jmp) then
100
If IsLoadMemReg(p) Then
102
CurProp^.ReadRef(PInstr(p)^.oper[LoadSrc].ref);
103
TmpReg := RegMaxSize(PInstr(p)^.oper[LoadDst].reg);
104
If RegInRef(TmpReg, PInstr(p)^.oper[LoadSrc].ref^) And
105
(CurProp^.GetRegContentType(TmpReg) = Con_Ref) Then
107
{ a load based on the value this register already }
109
With CurProp^.Regs[TmpReg] Do
111
CurProp^.IncWState(TmpReg);
112
{also store how many instructions are part of the }
113
{ sequence in the first instruction's PPaiProp, so }
114
{ it can be easily accessed from within }
116
Inc(NrOfMods, InstrSinceLastMod[TmpReg]);
117
PPaiProp(Pai(StartMod)^.OptInfo)^.Regs[TmpReg].NrOfMods := NrOfMods;
118
InstrSinceLastMod[TmpReg] := 0
123
{ load of a register with a completely new value }
124
CurProp^.DestroyReg(TmpReg, InstrSinceLastMod);
125
If Not(RegInRef(TmpReg, PInstr(p)^.oper[LoadSrc].ref^)) Then
126
With CurProp^.Regs[TmpReg] Do
134
hp := new(pai_asm_comment,init(strpnew(std_reg2str[TmpReg]+': '+tostr(CurProp^.Regs[TmpReg].WState))));
135
InsertLLItem(AsmL, p, p^.next, hp);
139
Else if IsLoadConstReg(p) Then
141
TmpReg := RegMaxSize(PInstr(p)^.oper[LoadDst].reg);
142
With CurProp^.Regs[TmpReg] Do
144
CurProp^.DestroyReg(TmpReg, InstrSinceLastMod);
146
StartMod := Pointer(PInstr(p)^.oper[LoadSrc].val);
149
Else CpuDFA(Pinstr(p));
151
Else CurProp^.DestroyAllRegs(InstrSinceLastMod);
154
GetNextInstruction(p, p);
158
Procedure TAoptDFA.CpuDFA(p: PInstr);
163
Function TAOptDFA.TCh2Reg(Ch: TInsChange): TRegister;
169
Function TAOptDFA.RegReadByInstr(Reg: TRegister; p: Pai): Boolean;
171
RegReadByInstr:=false;
180
Revision 1.7 2004/01/31 17:45:16 peter
181
* Change several $ifdef i386 to x86
182
* Change several OS_32 to OS_INT/OS_ADDR
184
Revision 1.6 2002/05/18 13:34:05 peter
185
* readded missing revisions
187
Revision 1.5 2002/05/16 19:46:35 carl
188
+ defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
189
+ try to fix temp allocation (still in ifdef)
190
+ generic constructor calls
191
+ start of tassembler / tmodulebase class cleanup
193
Revision 1.3 2002/04/15 18:55:40 carl
194
+ change reg2str array use
196
Revision 1.2 2002/04/14 16:49:30 carl
197
+ att_reg2str -> gas_reg2str