aoptcpud.pas 8.3 KB

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