~ubuntu-branches/ubuntu/dapper/fpc/dapper

« back to all changes in this revision

Viewing changes to compiler/new/i386/aoptcpud.pas

  • Committer: Bazaar Package Importer
  • Author(s): Carlos Laviola
  • Date: 2004-08-12 16:29:37 UTC
  • mfrom: (1.2.1 upstream) (2.1.1 warty)
  • Revision ID: james.westby@ubuntu.com-20040812162937-moo8ulvysp1ln771
Tags: 1.9.4-5
fp-compiler: needs ld, adding dependency on binutils.  (Closes: #265265)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
{
 
2
    $Id: aoptcpud.pas,v 1.3 2002/09/07 15:25:14 peter Exp $
 
3
    Copyright (c) 1998-2000 by Jonas Maebe, member of the Free Pascal
 
4
    Development Team
 
5
 
 
6
    This unit contains the processor specific implementation of the
 
7
    assembler optimizer data flow analyzer.
 
8
 
 
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.
 
13
 
 
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.
 
18
 
 
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.
 
22
 
 
23
 ****************************************************************************
 
24
}
 
25
Unit aoptcpud;
 
26
 
 
27
Interface
 
28
 
 
29
uses Aasm, cpubase, AoptCpub, AoptObj, AoptDA;
 
30
 
 
31
Type
 
32
  PAOptDFACpu = ^TAOptDFACpu;
 
33
  TAOptDFACpu = Object(TAOptDFA)
 
34
    { uses the same constructor as TAoptDFA = constructor from TAoptObj }
 
35
 
 
36
    { handles the processor dependent dataflow analizing               }
 
37
    Procedure CpuDFA(p: PInstr); Virtual;
 
38
    Function TCh2Reg(Ch: TInsChange): TRegister; Virtual;
 
39
    Function RegReadByInstr(Reg: TRegister; p: Pai): Boolean; Virtual;
 
40
  End;
 
41
 
 
42
Implementation
 
43
 
 
44
uses cpuinfo;
 
45
 
 
46
Procedure TAOptDFACpu.CpuDFA(p: PInstr);
 
47
{ Analyzes the Data Flow of an assembler list. Analyses the reg contents     }
 
48
{ for the instructions between blockstart and blockend. Returns the last pai }
 
49
{ which has been processed                                                   }
 
50
Var CurProp: PPaiProp;
 
51
    InstrProp: TInsProp;
 
52
    TmpRef: TReference;
 
53
    Cnt: Byte;
 
54
Begin
 
55
  CurProp := PPaiProp(p^.OptInfo);
 
56
  Case p^.Opcode Of
 
57
    A_DIV, A_IDIV, A_MUL:
 
58
      Begin
 
59
        CurProp^.ReadOp(p^.oper[0]);
 
60
        CurProp^.ReadReg(R_EAX);
 
61
        If (p^.OpCode = A_IDIV) or
 
62
           (p^.OpCode = A_DIV) Then
 
63
          CurProp^.ReadReg(R_EDX);
 
64
        CurProp^.DestroyReg(R_EAX, InstrSinceLastMod)
 
65
      End;
 
66
    A_IMUL:
 
67
      Begin
 
68
        CurProp^.ReadOp(p^.oper[0]);
 
69
        CurProp^.ReadOp(p^.oper[1]);
 
70
        If (p^.oper[2].typ = top_none) Then
 
71
          If (p^.oper[1].typ = top_none) Then
 
72
            Begin
 
73
              CurProp^.ReadReg(R_EAX);
 
74
              CurProp^.DestroyReg(R_EAX, InstrSinceLastMod);
 
75
              CurProp^.DestroyReg(R_EDX, InstrSinceLastMod)
 
76
            End
 
77
          Else
 
78
            CurProp^.ModifyOp(p^.oper[1], InstrSinceLastMod)
 
79
        Else
 
80
          CurProp^.ModifyOp(p^.oper[2], InstrSinceLastMod);
 
81
      End;
 
82
    A_XOR:
 
83
      Begin
 
84
        CurProp^.ReadOp(p^.oper[0]);
 
85
        CurProp^.ReadOp(p^.oper[1]);
 
86
        If (p^.oper[0].typ = top_reg) And
 
87
           (p^.oper[1].typ = top_reg) And
 
88
           (p^.oper[0].reg = p^.oper[1].reg) Then
 
89
          Begin
 
90
            CurProp^.DestroyReg(p^.oper[0].reg, InstrSinceLastMod);
 
91
            CurProp^.Regs[RegMaxSize(p^.oper[0].reg)].typ := Con_Const;
 
92
            CurProp^.Regs[RegMaxSize(p^.oper[0].reg)].StartMod := Pointer(0)
 
93
          End
 
94
        Else
 
95
          CurProp^.ModifyOp(p^.oper[1], InstrSinceLastMod);
 
96
        End
 
97
    Else
 
98
      Begin
 
99
        InstrProp := InsProp[p^.OpCode];
 
100
        Cnt := 1;
 
101
        While (Cnt <= MaxCh) And
 
102
              (InstrProp.Ch[Cnt] <> Ch_None) Do
 
103
          Begin
 
104
            Case InstrProp.Ch[Cnt] Of
 
105
              Ch_REAX..Ch_REDI:
 
106
                CurProp^.ReadReg(TCh2Reg(InstrProp.Ch[Cnt]));
 
107
              Ch_WEAX..Ch_RWEDI:
 
108
                Begin
 
109
                  If (InstrProp.Ch[Cnt] >= Ch_RWEAX) Then
 
110
                    CurProp^.ReadReg(TCh2Reg(InstrProp.Ch[Cnt]));
 
111
                  CurProp^.DestroyReg(TCh2Reg(InstrProp.Ch[Cnt]),InstrSinceLastMod);
 
112
                End;
 
113
              Ch_MEAX..Ch_MEDI:
 
114
                CurProp^.ModifyReg(TCh2Reg(InstrProp.Ch[Cnt]), InstrSinceLastMod);
 
115
              Ch_CDirFlag: CurProp^.CondRegs.ClearFlag(DirFlag);
 
116
              Ch_SDirFlag: CurProp^.CondRegs.SetFlag(DirFlag);
 
117
              Ch_Rop1: CurProp^.ReadOp(p^.oper[0]);
 
118
              Ch_Rop2: CurProp^.ReadOp(p^.oper[1]);
 
119
              Ch_Rop3: CurProp^.ReadOp(p^.oper[2]);
 
120
              Ch_Wop1..Ch_RWop1:
 
121
                Begin
 
122
                  If (InstrProp.Ch[Cnt] = Ch_RWop1) Then
 
123
                    CurProp^.ReadOp(p^.oper[0]);
 
124
                  CurProp^.DestroyOp(p^.oper[0], InstrSinceLastMod);
 
125
                End;
 
126
              Ch_Mop1:
 
127
                CurProp^.ModifyOp(p^.oper[0], InstrSinceLastMod);
 
128
              Ch_Wop2..Ch_RWop2:
 
129
                Begin
 
130
                  If (InstrProp.Ch[Cnt] = Ch_RWop2) Then
 
131
                    CurProp^.ReadOp(p^.oper[1]);
 
132
                  CurProp^.DestroyOp(p^.oper[1], InstrSinceLastMod);
 
133
                End;
 
134
              Ch_Mop2:
 
135
                CurProp^.ModifyOp(p^.oper[1], InstrSinceLastMod);
 
136
              Ch_Wop3..Ch_RWop3:
 
137
                Begin
 
138
                  If (InstrProp.Ch[Cnt] = Ch_RWop3) Then
 
139
                    CurProp^.ReadOp(p^.oper[2]);
 
140
                  CurProp^.DestroyOp(p^.oper[2], InstrSinceLastMod);
 
141
                End;
 
142
              Ch_Mop3:
 
143
                CurProp^.ModifyOp(p^.oper[2], InstrSinceLastMod);
 
144
              Ch_WMemEDI:
 
145
                Begin
 
146
                  CurProp^.ReadReg(R_EDI);
 
147
                  FillChar(TmpRef, SizeOf(TmpRef), 0);
 
148
                  TmpRef.Base := R_EDI;
 
149
                  CurProp^.DestroyRefs(TmpRef, R_NO, InstrSinceLastMod)
 
150
                End;
 
151
              Ch_RFlags, Ch_WFlags, Ch_RWFlags, Ch_FPU:;
 
152
              Else CurProp^.DestroyAllRegs(InstrSinceLastMod)
 
153
            End;
 
154
            Inc(Cnt)
 
155
          End
 
156
      End
 
157
  End
 
158
End;
 
159
 
 
160
Function TAOptDFACpu.RegReadByInstr(Reg: TRegister; p: Pai): Boolean;
 
161
Var Cnt: AWord;
 
162
    InstrProp: TInsProp;
 
163
    TmpResult: Boolean;
 
164
Begin
 
165
  TmpResult := False;
 
166
  If (p^.typ = ait_instruction) Then
 
167
    Case PInstr(p)^.opcode of
 
168
      A_IMUL:
 
169
        With PInstr(p)^ Do
 
170
          TmpResult :=
 
171
            RegInOp(Reg,oper[0]) or
 
172
            RegInOp(Reg,oper[1]) or
 
173
            ((ops = 1) and
 
174
             (reg = R_EAX));
 
175
      A_DIV, A_IDIV, A_MUL:
 
176
        With PInstr(p)^ Do
 
177
          TmpResult :=
 
178
            RegInOp(Reg,oper[0]) or
 
179
            (Reg = R_EAX) or
 
180
            ((Reg = R_EDX) and
 
181
             ((opcode = A_DIV) or
 
182
              (opcode = A_IDIV)) and
 
183
             (opsize = S_L))
 
184
      Else
 
185
        Begin
 
186
          Cnt := 1;
 
187
          InstrProp := InsProp[PInstr(p)^.OpCode];
 
188
          While (Cnt <= MaxCh) And
 
189
                (InstrProp.Ch[Cnt] <> Ch_None) And
 
190
                Not(TmpResult) Do
 
191
            Begin
 
192
              Case InstrProp.Ch[Cnt] Of
 
193
                Ch_REAX..Ch_REDI,Ch_RWEAX..Ch_RWEDI
 
194
                ,Ch_MEAX..Ch_MEDI
 
195
                  TmpResult := Reg = TCh2Reg(InstrProp.Ch[Cnt]);
 
196
                Ch_ROp1,Ch_RWOp1,Ch_Mop1:
 
197
                  TmpResult := RegInOp(Reg,PInstr(p)^.oper[0]);
 
198
                Ch_ROp2,Ch_RWOp2,Ch_Mop2:
 
199
                  TmpResult := RegInOp(Reg,PInstr(p)^.oper[1]);
 
200
                Ch_ROp3,Ch_RWOp3,Ch_Mop3:
 
201
                  TmpResult := RegInOp(Reg,PInstr(p)^.oper[2]);
 
202
                Ch_WOp1: TmpResult := (PInstr(p)^.oper[0].typ = top_ref) And
 
203
                                     RegInRef(Reg,PInstr(p)^.oper[0].ref^);
 
204
                Ch_WOp2: TmpResult := (PInstr(p)^.oper[1].typ = top_ref) And
 
205
                                     RegInRef(Reg,PInstr(p)^.oper[1].ref^);
 
206
                Ch_WOp3: TmpResult := (PInstr(p)^.oper[2].typ = top_ref) And
 
207
                                     RegInRef(Reg,PInstr(p)^.oper[2].ref^);
 
208
                Ch_WMemEDI: TmpResult := (Reg = R_EDI);
 
209
                Ch_FPU: TmpResult := Reg in [R_ST..R_ST7,R_MM0..R_MM7]
 
210
              End;
 
211
              Inc(Cnt)
 
212
            End
 
213
        End
 
214
    End;
 
215
  RegReadByInstr := TmpResult
 
216
End;
 
217
 
 
218
Function TAOptDFACpu.TCh2Reg(Ch: TInsChange): TRegister;
 
219
Begin
 
220
  If (Ch <= Ch_REDI) Then
 
221
    TCh2Reg := TRegister(Byte(Ch))
 
222
  Else
 
223
    If (Ch <= Ch_WEDI) Then
 
224
      TCh2Reg := TRegister(Byte(Ch) - Byte(Ch_REDI))
 
225
    Else
 
226
      If (Ch <= Ch_RWEDI) Then
 
227
        TCh2Reg := TRegister(Byte(Ch) - Byte(Ch_WEDI))
 
228
      Else
 
229
        If (Ch <= Ch_MEDI) Then
 
230
          TCh2Reg := TRegister(Byte(Ch) - Byte(Ch_RWEDI))
 
231
End;
 
232
 
 
233
 
 
234
End.
 
235
 
 
236
{
 
237
  $Log: aoptcpud.pas,v $
 
238
  Revision 1.3  2002/09/07 15:25:14  peter
 
239
    * old logs removed and tabs fixed
 
240
 
 
241
}