aopt386.inc 54 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326
  1. {
  2. $Id$
  3. Copyright (c) 1993-98 by Florian Klaempfl and Jonas Maebe
  4. This include file contains the reloading optimizer for i386+
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************
  17. }
  18. {$Define OptimizeMovs}
  19. Type TwoWords = Record
  20. Word1, Word2: Word
  21. End;
  22. Function Reg32(Reg: TRegister): TRegister;
  23. {Returns the 32 bit component of Reg if it exists, otherwise Reg is returned}
  24. Begin
  25. Reg32 := Reg;
  26. If (Reg >= R_AX)
  27. Then
  28. If (Reg <= R_DI)
  29. Then Reg32 := Reg16ToReg32(Reg)
  30. Else
  31. If (Reg <= R_BL)
  32. Then Reg32 := Reg8toReg32(Reg);
  33. End;
  34. Function RegInRef(Reg: TRegister; Const Ref: TReference): Boolean;
  35. Begin {checks whether Ref contains a reference to Reg}
  36. Reg := Reg32(Reg);
  37. RegInRef := (Ref.Base = Reg) Or (Ref.Index = Reg)
  38. End;
  39. Function RegInInstruction(Reg: TRegister; p1: Pai): Boolean;
  40. {checks if Reg is used by the instruction p1}
  41. Var TmpResult: Boolean;
  42. Begin
  43. TmpResult := False;
  44. If (Pai(p1)^.typ = ait_instruction) Then
  45. Begin
  46. Case Pai386(p1)^.op1t Of
  47. Top_Reg: TmpResult := Reg = TRegister(Pai386(p1)^.op1);
  48. Top_Ref: TmpResult := RegInRef(Reg, TReference(Pai386(p1)^.op1^))
  49. End;
  50. If Not(TmpResult) Then
  51. Case Pai386(p1)^.op2t Of
  52. Top_Reg:
  53. if Pai386(p1)^.op3t<>Top_reg
  54. then TmpResult := Reg = TRegister(Pai386(p1)^.op2)
  55. else TmpResult := longint(Reg) = twowords(Pai386(p1)^.op2).word1;
  56. Top_Ref: TmpResult := RegInRef(Reg, TReference(Pai386(p1)^.op2^))
  57. End;
  58. If Not(TmpResult) Then
  59. Case Pai386(p1)^.op3t Of
  60. Top_Reg: TmpResult := longint(Reg) =twowords(Pai386(p1)^.op2).word2;
  61. Top_none:;
  62. else
  63. internalerror($Da);
  64. End
  65. End;
  66. RegInInstruction := TmpResult
  67. End;
  68. Procedure ReloadOpt(AsmL: PaasmOutput);
  69. Const MaxCh = 3;
  70. {content types}
  71. con_Unknown = 0;
  72. con_ref = 1;
  73. con_const = 2;
  74. con_symbol = 3;
  75. Type TChange = (C_None,
  76. C_EAX, C_ECX, C_EDX, C_EBX, C_ESP, C_EBP, C_ESI, C_EDI,
  77. C_CDirFlag, C_SDirFlag, C_Flags, C_FPU,
  78. C_Op1, C_Op2, C_Op3,
  79. C_MemEDI);
  80. TFlagContents = (F_Unknown, F_NotSet, F_Set);
  81. TAsmInstrucProp = Record
  82. NCh: Byte;
  83. Ch: Array[1..MaxCh] of TChange;
  84. End;
  85. TContent = Record
  86. StartMod: Pointer; {start and end of block instructions that defines the
  87. content of this register; If Typ = con_const, then
  88. Longint(StartMod) = value of the constant)}
  89. State: Word; {starts at 0, gets increased everytime the register is modified}
  90. NrOfMods: Byte;
  91. { ModReg: TRegister; }{if one register gets a block assigned from an other register,
  92. this variable holds the name of that register (so it can be
  93. substituted when checking the block afterwards)}
  94. Typ: Byte; {con_*}
  95. { CanBeDestroyed: Boolean;} {if it's a register modified by the optimizer}
  96. End;
  97. TRegContent = Array[R_NO..R_EDI] Of TContent;
  98. TRegFPUContent = Array[R_ST..R_ST7] Of TContent;
  99. TPaiProp = Record
  100. Regs: TRegContent;
  101. { FPURegs: TRegFPUContent;} {currently not yet used}
  102. LineSave: Longint;
  103. DirFlag: TFlagContents;
  104. {can this instruction be removed?}
  105. CanBeRemoved: Boolean;
  106. End;
  107. PPaiProp = ^TPaiProp;
  108. {$IfDef TP}
  109. TPaiPropBlock = Array[1..(65520 div (((SizeOf(TPaiProp)+1)div 2)*2))] Of TPaiProp;
  110. {$else}
  111. TPaiPropBlock = Array[1..250000] Of TPaiProp;
  112. {$EndIf TP}
  113. PPaiPropBlock = ^TPaiPropBlock;
  114. Const AsmInstr: Array[tasmop] Of TAsmInstrucProp = (
  115. {MOV} (NCh: 1; Ch: (C_Op2, C_None, C_None)),
  116. {MOVZX} (NCh: 1; Ch: (C_Op2, C_None, C_None)),
  117. {MOVSX} (NCh: 1; Ch: (C_Op2, C_None, C_None)),
  118. {LABEL} (NCh: 255; Ch: (C_None, C_None, C_None)), {don't know value of any register}
  119. {ADD} (NCh: 2; Ch: (C_Op2, C_Flags, C_None)),
  120. {CALL} (NCh: 255; Ch: (C_None, C_None, C_None)), {don't know value of any register}
  121. {IDIV} (NCh: 3; Ch: (C_EAX, C_EDX, C_Flags)),
  122. {IMUL} (NCh: 3; Ch: (C_EAX, C_EDX, C_Flags)), {handled separately, because several forms exist}
  123. {JMP} (NCh: 255; Ch: (C_None, C_None, C_None)), {don't know value of any register}
  124. {LEA} (NCh: 1; Ch: (C_Op2, C_None, C_None)),
  125. {MUL} (NCh: 3; Ch: (C_EAX, C_EDX, C_Flags)),
  126. {NEG} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  127. {NOT} (NCh: 2; Ch: (C_Op1, C_Flags, C_None)),
  128. {POP} (NCh: 2; Ch: (C_Op1, C_ESP, C_None)),
  129. {POPAD} (NCh: 255; Ch: (C_None, C_None, C_None)), {don't know value of any register}
  130. {PUSH} (NCh: 1; Ch: (C_ESP, C_None, C_None)),
  131. {PUSHAD} (NCh: 1; Ch: (C_ESP, C_None, C_None)),
  132. {RET} (NCh: 255; Ch: (C_None, C_None, C_None)), {don't know value of any register}
  133. {SUB} (NCh: 2; Ch: (C_Op2, C_Flags, C_None)),
  134. {XCHG} (NCh: 2; Ch: (C_Op1, C_Op2, C_None)), {(will be) handled seperately}
  135. {XOR} (NCh: 2; Ch: (C_Op2, C_Flags, C_None)),
  136. {FILD} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  137. {CMP} (NCh: 1; Ch: (C_Flags, C_None, C_None)),
  138. {JZ} (NCh: 0; Ch: (C_None, C_None, C_None)),
  139. {INC} (NCh: 2; Ch: (C_Op1, C_Flags, C_None)),
  140. {DEC} (NCh: 2; Ch: (C_Op1, C_Flags, C_None)),
  141. {SETE} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  142. {SETNE} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  143. {SETL} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  144. {SETG} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  145. {SETLE} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  146. {SETGE} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  147. {JE} (NCh: 0; Ch: (C_None, C_None, C_None)),
  148. {JNE} (NCh: 0; Ch: (C_None, C_None, C_None)),
  149. {JL} (NCh: 0; Ch: (C_None, C_None, C_None)),
  150. {JG} (NCh: 0; Ch: (C_None, C_None, C_None)),
  151. {JLE} (NCh: 0; Ch: (C_None, C_None, C_None)),
  152. {JGE} (NCh: 0; Ch: (C_None, C_None, C_None)),
  153. {OR} (NCh: 2; Ch: (C_Op2, C_Flags, C_None)),
  154. {FLD} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  155. {FADD} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  156. {FMUL} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  157. {FSUB} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  158. {FDIV} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  159. {FCHS} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  160. {FLD1} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  161. {FIDIV} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  162. {CLTD} (NCh: 1; Ch: (C_EDX, C_None, C_None)),
  163. {JNZ} (NCh: 0; Ch: (C_None, C_None, C_None)),
  164. {FSTP} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  165. {AND} (NCh: 2; Ch: (C_Op2, C_Flags, C_None)),
  166. {JNO} (NCh: 0; Ch: (C_None, C_None, C_None)),
  167. {NOTH} (NCh: 0; Ch: (C_None, C_None, C_None)), {***???***}
  168. {NONE} (NCh: 0; Ch: (C_None, C_None, C_None)),
  169. {ENTER} (NCh: 1; Ch: (C_ESP, C_None, C_None)),
  170. {LEAVE} (NCh: 1; Ch: (C_ESP, C_None, C_None)),
  171. {CLD} (NCh: 1; Ch: (C_CDirFlag, C_None, C_None)),
  172. {MOVS} (NCh: 3; Ch: (C_ESI, C_EDI, C_MemEDI)),
  173. {REP} (NCh: 1; Ch: (C_ECX, C_None, C_None)),
  174. {SHL} (NCh: 2; Ch: (C_Op2, C_Flags, C_None)),
  175. {SHR} (NCh: 2; Ch: (C_Op2, C_Flags, C_None)),
  176. {BOUND} (NCh: 0; Ch: (C_None, C_None, C_None)),
  177. {JNS} (NCh: 0; Ch: (C_None, C_None, C_None)),
  178. {JS} (NCh: 0; Ch: (C_None, C_None, C_None)),
  179. {JO} (NCh: 0; Ch: (C_None, C_None, C_None)),
  180. {SAR} (NCh: 2; Ch: (C_Op2, C_Flags, C_None)),
  181. {TEST} (NCh: 1; Ch: (C_Flags, C_None, C_None)),
  182. {FCOM} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  183. {FCOMP} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  184. {FCOMPP} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  185. {FXCH} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  186. {FADDP} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  187. {FMULP} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  188. {FSUBP} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  189. {FDIVP} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  190. {FNSTS} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  191. {SAHF} (NCh: 1; Ch: (C_Flags, C_None, C_None)),
  192. {FDIVRP} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  193. {FSUBRP} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  194. {SETC} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  195. {SETNC} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  196. {JC} (NCh: 0; Ch: (C_None, C_None, C_None)),
  197. {JNC} (NCh: 0; Ch: (C_None, C_None, C_None)),
  198. {JA} (NCh: 0; Ch: (C_None, C_None, C_None)),
  199. {JAE} (NCh: 0; Ch: (C_None, C_None, C_None)),
  200. {JB} (NCh: 0; Ch: (C_None, C_None, C_None)),
  201. {JBE} (NCh: 0; Ch: (C_None, C_None, C_None)),
  202. {SETA} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  203. {SETAE} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  204. {SETB} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  205. {SETBE} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  206. {AAA} (NCh: 2; Ch: (C_EAX, C_Flags, C_None)),
  207. {AAD} (NCh: 2; Ch: (C_EAX, C_Flags, C_None)),
  208. {AAM} (NCh: 2; Ch: (C_EAX, C_Flags, C_None)),
  209. {AAS} (NCh: 2; Ch: (C_EAX, C_Flags, C_None)),
  210. {CBW} (NCh: 1; Ch: (C_EAX, C_None, C_None)),
  211. {CDQ} (NCh: 2; Ch: (C_EAX, C_EDX, C_None)),
  212. {CLC} (NCh: 1; Ch: (C_Flags, C_None, C_None)),
  213. {CLI} (NCh: 1; Ch: (C_Flags, C_None, C_None)),
  214. {CLTS} (NCh: 0; Ch: (C_None, C_None, C_None)),
  215. {CMC} (NCh: 1; Ch: (C_Flags, C_None, C_None)),
  216. {CWD} (NCh: 2; Ch: (C_EAX, C_EDX, C_None)),
  217. {CWDE} (NCh: 1; Ch: (C_EAX, C_None, C_None)),
  218. {DAA} (NCh: 1; Ch: (C_EAX, C_None, C_None)),
  219. {DAS} (NCh: 1; Ch: (C_EAX, C_None, C_None)),
  220. {HLT} (NCh: 0; Ch: (C_None, C_None, C_None)),
  221. {IRET} (NCh: 255; Ch: (C_None, C_None, C_None)), {don't know value of any register}
  222. {LAHF} (NCh: 1; Ch: (C_EAX, C_None, C_None)),
  223. {LODS} (NCh: 2; Ch: (C_EAX, C_ESI, C_None)),
  224. {LOCK} (NCh: 0; Ch: (C_None, C_None, C_None)),
  225. {NOP} (NCh: 0; Ch: (C_None, C_None, C_None)),
  226. {PUSHA} (NCh: 1; Ch: (C_ESP, C_None, C_None)),
  227. {PUSHF} (NCh: 1; Ch: (C_ESP, C_None, C_None)),
  228. {PUSHFD} (NCh: 1; Ch: (C_ESP, C_None, C_None)),
  229. {STC} (NCh: 1; Ch: (C_Flags, C_None, C_None)),
  230. {STD} (NCh: 1; Ch: (C_SDirFlag, C_None, C_None)),
  231. {STI} (NCh: 1; Ch: (C_Flags, C_None, C_None)),
  232. {STOS} (NCh: 2; Ch: (C_MemEDI, C_EDI, C_None)),
  233. {WAIT} (NCh: 0; Ch: (C_None, C_None, C_None)),
  234. {XLAT} (NCh: 1; Ch: (C_EAX, C_None, C_None)),
  235. {XLATB} (NCh: 1; Ch: (C_EAX, C_None, C_None)),
  236. {MOVSB} (NCh: 1; Ch: (C_Op2, C_None, C_None)),
  237. {MOVSBL} (NCh: 1; Ch: (C_Op2, C_None, C_None)),
  238. {MOVSBW} (NCh: 1; Ch: (C_Op2, C_None, C_None)),
  239. {MOVSWL} (NCh: 1; Ch: (C_Op2, C_None, C_None)),
  240. {MOVZB} (NCh: 1; Ch: (C_Op2, C_None, C_None)),
  241. {MOVZWL} (NCh: 1; Ch: (C_Op2, C_None, C_None)),
  242. {POPA} (NCh: 255; Ch: (C_None, C_None, C_None)), {don't know value of any register}
  243. {IN} (NCh: 1; Ch: (C_Op2, C_None, C_None)),
  244. {OUT} (NCh: 0; Ch: (C_None, C_None, C_None)),
  245. {LDS} (NCh: 2; Ch: (C_Op2, C_None, C_None)),
  246. {LCS} (NCh: 2; Ch: (C_Op2, C_None, C_None)),
  247. {LES} (NCh: 2; Ch: (C_Op2, C_None, C_None)),
  248. {LFS} (NCh: 2; Ch: (C_Op2, C_None, C_None)),
  249. {LGS} (NCh: 2; Ch: (C_Op2, C_None, C_None)),
  250. {LSS} (NCh: 2; Ch: (C_Op2, C_None, C_None)),
  251. {POPF} (NCh: 2; Ch: (C_Flags, C_ESP, C_None)),
  252. {SBB} (NCh: 2; Ch: (C_Op2, C_Flags, C_None)),
  253. {ADC} (NCh: 2; Ch: (C_Op2, C_Flags, C_None)),
  254. {DIV} (NCh: 3; Ch: (C_EAX, C_EDX, C_Flags)),
  255. {ROR} (NCh: 2; Ch: (C_Op2, C_Flags, C_None)),
  256. {ROL} (NCh: 2; Ch: (C_Op2, C_Flags, C_None)),
  257. {RCL} (NCh: 2; Ch: (C_Op2, C_Flags, C_None)),
  258. {RCR} (NCh: 2; Ch: (C_Op2, C_Flags, C_None)),
  259. {SAL} (NCh: 2; Ch: (C_Op2, C_Flags, C_None)),
  260. {SHLD} (NCh: 2; Ch: (C_Op3, C_Flags, C_None)),
  261. {SHRD} (NCh: 2; Ch: (C_Op3, C_Flags, C_None)),
  262. {LCALL} (NCh: 255; Ch: (C_None, C_None, C_None)), {don't know value of any register}
  263. {LJMP} (NCh: 255; Ch: (C_None, C_None, C_None)), {don't know value of any register}
  264. {LRET} (NCh: 255; Ch: (C_None, C_None, C_None)), {don't know value of any register}
  265. {JNAE} (NCh: 0; Ch: (C_None, C_None, C_None)),
  266. {JNB} (NCh: 0; Ch: (C_None, C_None, C_None)),
  267. {JNA} (NCh: 0; Ch: (C_None, C_None, C_None)),
  268. {JNBE} (NCh: 0; Ch: (C_None, C_None, C_None)),
  269. {JP} (NCh: 0; Ch: (C_None, C_None, C_None)),
  270. {JNP} (NCh: 0; Ch: (C_None, C_None, C_None)),
  271. {JPE} (NCh: 0; Ch: (C_None, C_None, C_None)),
  272. {JPO} (NCh: 0; Ch: (C_None, C_None, C_None)),
  273. {JNGE} (NCh: 0; Ch: (C_None, C_None, C_None)),
  274. {JNG} (NCh: 0; Ch: (C_None, C_None, C_None)),
  275. {JNL} (NCh: 0; Ch: (C_None, C_None, C_None)),
  276. {JNLE} (NCh: 0; Ch: (C_None, C_None, C_None)),
  277. {JCXZ} (NCh: 0; Ch: (C_None, C_None, C_None)),
  278. {JECXZ} (NCh: 0; Ch: (C_None, C_None, C_None)),
  279. {LOOP} (NCh: 1; Ch: (C_ECX, C_None, C_None)),
  280. {CMPS} (NCh: 3; Ch: (C_ESI, C_EDI, C_Flags)),
  281. {INS} (NCh: 1; Ch: (C_EDI, C_None, C_None)),
  282. {OUTS} (NCh: 1; Ch: (C_ESI, C_None, C_None)),
  283. {SCAS} (NCh: 2; Ch: (C_EDI, C_Flags, C_None)),
  284. {BSF} (NCh: 2; Ch: (C_Op2, C_Flags, C_None)),
  285. {BSR} (NCh: 2; Ch: (C_Op2, C_Flags, C_None)),
  286. {BT} (NCh: 1; Ch: (C_Flags, C_None, C_None)),
  287. {BTC} (NCh: 2; Ch: (C_Op2, C_Flags, C_None)),
  288. {BTR} (NCh: 2; Ch: (C_Op2, C_Flags, C_None)),
  289. {BTS} (NCh: 2; Ch: (C_Op2, C_Flags, C_None)),
  290. {INT} (NCh: 255; Ch: (C_None, C_None, C_None)), {don't know value of any register}
  291. {INT3} (NCh: 0; Ch: (C_None, C_None, C_None)),
  292. {INTO} (NCh: 255; Ch: (C_None, C_None, C_None)), {don't know value of any register}
  293. {BOUNDL} (NCh: 0; Ch: (C_None, C_None, C_None)),
  294. {BOUNDW} (NCh: 0; Ch: (C_None, C_None, C_None)),
  295. {LOOPZ} (NCh: 1; Ch: (C_ECX, C_None, C_None)),
  296. {LOOPE} (NCh: 1; Ch: (C_ECX, C_None, C_None)),
  297. {LOOPNZ} (NCh: 1; Ch: (C_ECX, C_None, C_None)),
  298. {LOOPNE} (NCh: 1; Ch: (C_ECX, C_None, C_None)),
  299. {SETO} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  300. {SETNO} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  301. {SETNAE} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  302. {SETNB} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  303. {SETZ} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  304. {SETNZ} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  305. {SETNA} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  306. {SETNBE} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  307. {SETS} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  308. {SETNS} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  309. {SETP} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  310. {SETPE} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  311. {SETNP} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  312. {SETPO} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  313. {SETNGE} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  314. {SETNL} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  315. {SETNG} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  316. {SETNLE} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  317. {ARPL} (NCh: 1; Ch: (C_Flags, C_None, C_None)),
  318. {LAR} (NCh: 1; Ch: (C_Op2, C_None, C_None)),
  319. {LGDT} (NCh: 0; Ch: (C_None, C_None, C_None)),
  320. {LIDT} (NCh: 0; Ch: (C_None, C_None, C_None)),
  321. {LLDT} (NCh: 0; Ch: (C_None, C_None, C_None)),
  322. {LMSW} (NCh: 0; Ch: (C_None, C_None, C_None)),
  323. {LSL} (NCh: 2; Ch: (C_Op2, C_Flags, C_None)),
  324. {LTR} (NCh: 0; Ch: (C_None, C_None, C_None)),
  325. {SGDT} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  326. {SIDT} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  327. {SLDT} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  328. {SMSW} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  329. {STR} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  330. {VERR} (NCh: 1; Ch: (C_Flags, C_None, C_None)),
  331. {VERW} (NCh: 1; Ch: (C_Flags, C_None, C_None)),
  332. {FABS} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  333. {FBLD} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  334. {FBSTP} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  335. {FCLEX} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  336. {FNCLEX} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  337. {FCOS} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  338. {FDECSTP}(NCh: 1; Ch: (C_FPU, C_None, C_None)),
  339. {FDISI} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  340. {FNDISI} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  341. {FDIVR} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  342. {FENI} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  343. {FNENI} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  344. {FFREE} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  345. {FIADD} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  346. {FICOM} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  347. {FICOMP} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  348. {FIDIVR} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  349. {FIMUL} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  350. {FINCSTP}(NCh: 1; Ch: (C_FPU, C_None, C_None)),
  351. {FINIT} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  352. {FNINIT} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  353. {FIST} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  354. {FISTP} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  355. {FISUB} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  356. {FSUBR} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  357. {FLDCW} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  358. {FLDENV} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  359. {FLDLG2} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  360. {FLDLN2} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  361. {FLDL2E} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  362. {FLDL2T} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  363. {FLDPI} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  364. {FLDS} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  365. {FLDZ} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  366. {FNOP} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  367. {FPATAN} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  368. {FPREM} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  369. {FPREM1} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  370. {FPTAN} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  371. {FRNDINT}(NCh: 1; Ch: (C_FPU, C_None, C_None)),
  372. {FRSTOR} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  373. {FSAVE} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  374. {FNSAVE} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  375. {FSCALE} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  376. {FSETPM} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  377. {FSIN} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  378. {FSINCOS}(NCh: 1; Ch: (C_FPU, C_None, C_None)),
  379. {FSQRT} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  380. {FST} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  381. {FSTCW} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  382. {FNSTCW} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  383. {FSTENV} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  384. {FNSTENV}(NCh: 1; Ch: (C_Op1, C_None, C_None)),
  385. {FSTSW} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  386. {FNSTSW} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  387. {FTST} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  388. {FUCOM} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  389. {FUCOMP} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  390. {FUCOMPP}(NCh: 1; Ch: (C_FPU, C_None, C_None)),
  391. {FWAIT} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  392. {FXAM} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  393. {FXTRACT}(NCh: 1; Ch: (C_FPU, C_None, C_None)),
  394. {FYL2X} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  395. {FYL2XP1}(NCh: 1; Ch: (C_FPU, C_None, C_None)),
  396. {F2XM1} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  397. {FILDQ} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  398. {FILDS} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  399. {FILDL} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  400. {FLDL} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  401. {FLDT} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  402. {FISTQ} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  403. {FISTS} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  404. {FISTL} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  405. {FSTL} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  406. {FSTS} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  407. {FSTPS} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  408. {FISTPL} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  409. {FSTPL} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  410. {FISTPS} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  411. {FISTPQ} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  412. {FSTPT} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  413. {FCOMPS} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  414. {FICOMPL}(NCh: 1; Ch: (C_FPU, C_None, C_None)),
  415. {FCOMPL} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  416. {FICOMPS}(NCh: 1; Ch: (C_FPU, C_None, C_None)),
  417. {FCOMS} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  418. {FICOML} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  419. {FCOML} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  420. {FICOMS} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  421. {FIADDL} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  422. {FADDL} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  423. {FIADDS} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  424. {FISUBL} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  425. {FSUBL} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  426. {FISUBS} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  427. {FSUBS} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  428. {FSUBR} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  429. {FSUBRS} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  430. {FISUBRL}(NCh: 1; Ch: (C_FPU, C_None, C_None)),
  431. {FSUBRL} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  432. {FISUBRS}(NCh: 1; Ch: (C_FPU, C_None, C_None)),
  433. {FMULS} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  434. {FIMUL} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  435. {FMULL} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  436. {FIMULS} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  437. {FIDIVS} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  438. {FIDIVL} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  439. {FDIVL} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  440. {FIDIVS} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  441. {FDIVRS} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  442. {FIDIVRL}(NCh: 1; Ch: (C_FPU, C_None, C_None)),
  443. {FDIVRL} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  444. {FIDIVRS}(NCh: 1; Ch: (C_FPU, C_None, C_None)),
  445. {REPE} (NCh: 0; Ch: (C_ECX, C_None, C_None)),
  446. {REPNE} (NCh: 0; Ch: (C_ECX, C_None, C_None)),
  447. {FADDS} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  448. {POPFD} (NCh: 2; Ch: (C_ESP, C_Flags, C_None)),
  449. {below are the MMX instructions}
  450. {A_EMMS} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  451. {A_MOVD} (NCh: 1; Ch: (C_Op2, C_None, C_None)),
  452. {A_MOVQ} (NCh: 1; Ch: (C_Op2, C_None, C_None)),
  453. {A_PACKSSDW} (NCh: 255; Ch: (C_FPU, C_None, C_None)),
  454. {A_PACKSSWB} (NCh: 255; Ch: (C_FPU, C_None, C_None)),
  455. {A_PACKUSWB} (NCh: 255; Ch: (C_FPU, C_None, C_None)),
  456. {A_PADDB} (NCh: 1; Ch: (C_Op2, C_None, C_None)),
  457. {A_PADDD} (NCh: 1; Ch: (C_Op2, C_None, C_None)),
  458. {A_PADDSB} (NCh: 1; Ch: (C_Op2, C_None, C_None)),
  459. {A_PADDSW} (NCh: 1; Ch: (C_Op2, C_None, C_None)),
  460. {A_PADDUSB} (NCh: 1; Ch: (C_Op2, C_None, C_None)),
  461. {A_PADDUSW} (NCh: 1; Ch: (C_Op2, C_None, C_None)),
  462. {A_PADDW} (NCh: 1; Ch: (C_Op2, C_None, C_None)),
  463. {A_PAND} (NCh: 1; Ch: (C_Op2, C_None, C_None)),
  464. {A_PANDN} (NCh: 1; Ch: (C_Op2, C_None, C_None)),
  465. {A_PCMPEQB} (NCh: 255; Ch: (C_FPU, C_None, C_None)),
  466. {A_PCMPEQD} (NCh: 255; Ch: (C_FPU, C_None, C_None)),
  467. {A_PCMPEQW} (NCh: 255; Ch: (C_FPU, C_None, C_None)),
  468. {A_PCMPGTB} (NCh: 255; Ch: (C_FPU, C_None, C_None)),
  469. {A_PCMPGTD} (NCh: 255; Ch: (C_FPU, C_None, C_None)),
  470. {A_PCMPGTW} (NCh: 255; Ch: (C_FPU, C_None, C_None)),
  471. {A_PMADDWD} (NCh: 1; Ch: (C_Op2, C_None, C_None)),
  472. {A_PMULHW} (NCh: 255; Ch: (C_FPU, C_None, C_None)),
  473. {A_PMULLW} (NCh: 255; Ch: (C_FPU, C_None, C_None)),
  474. {A_POR} (NCh: 1; Ch: (C_Op2, C_None, C_None)),
  475. {A_PSLLD} (NCh: 1; Ch: (C_Op2, C_None, C_None)),
  476. {A_PSLLQ} (NCh: 1; Ch: (C_Op2, C_None, C_None)),
  477. {A_PSLLW} (NCh: 1; Ch: (C_Op2, C_None, C_None)),
  478. {A_PSRAD} (NCh: 1; Ch: (C_Op2, C_None, C_None)),
  479. {A_PSRAW} (NCh: 1; Ch: (C_Op2, C_None, C_None)),
  480. {A_PSRLD} (NCh: 1; Ch: (C_Op2, C_None, C_None)),
  481. {A_PSRLQ} (NCh: 1; Ch: (C_Op2, C_None, C_None)),
  482. {A_PSRLW} (NCh: 1; Ch: (C_Op2, C_None, C_None)),
  483. {A_PSUBB} (NCh: 1; Ch: (C_Op2, C_None, C_None)),
  484. {A_PSUBD} (NCh: 1; Ch: (C_Op2, C_None, C_None)),
  485. {A_PSUBSB} (NCh: 1; Ch: (C_Op2, C_None, C_None)),
  486. {A_PSUBSW} (NCh: 1; Ch: (C_Op2, C_None, C_None)),
  487. {A_PSUBUSB} (NCh: 1; Ch: (C_Op2, C_None, C_None)),
  488. {A_PSUBUSW} (NCh: 1; Ch: (C_Op2, C_None, C_None)),
  489. {A_PSUBW} (NCh: 1; Ch: (C_Op2, C_None, C_None)),
  490. {A_PUNPCKHBW} (NCh: 255; Ch: (C_FPU, C_None, C_None)),
  491. {A_PUNPCKHDQ} (NCh: 255; Ch: (C_FPU, C_None, C_None)),
  492. {A_PUNPCKHWD} (NCh: 255; Ch: (C_FPU, C_None, C_None)),
  493. {A_PUNPCKLBW} (NCh: 255; Ch: (C_FPU, C_None, C_None)),
  494. {A_PUNPCKLDQ} (NCh: 255; Ch: (C_FPU, C_None, C_None)),
  495. {A_PUNPCKLWD} (NCh: 255; Ch: (C_FPU, C_None, C_None)),
  496. {A_PXOR} (NCh: 1; Ch: (C_Op2, C_None, C_None)));
  497. Var NrOfPaiObjs, NrOfPaiFast: Longint;
  498. PaiPropBlock: PPaiPropBlock;
  499. NrOfInstrSinceLastMod: Array[R_EAX..R_EDI] Of Byte;
  500. Function TCh2Reg(Ch: TChange): TRegister;
  501. {converts a TChange variable to a TRegister}
  502. Begin
  503. If (CH <= C_EDI)
  504. Then TCh2Reg := TRegister(Byte(Ch))
  505. Else InternalError($db)
  506. End;
  507. Procedure DestroyReg(p1: pai; Reg: TRegister);
  508. {Destroys the contents of the register Reg in the PPaiProp of P}
  509. Var TmpState: Longint;
  510. Begin
  511. Reg := Reg32(Reg);
  512. NrOfInstrSinceLastMod[Reg] := 0;
  513. If (Reg >= R_EAX) And (Reg <= R_EDI)
  514. Then
  515. Begin
  516. TmpState := PPaiProp(p1^.line)^.Regs[Reg].State+1;
  517. FillChar(PPaiProp(p1^.line)^.Regs[Reg], SizeOf(TContent), 0);
  518. PPaiProp(p1^.line)^.Regs[Reg].State := TmpState;
  519. End;
  520. End;
  521. (*Function FindZeroreg(p: Pai; Var Result: TRegister): Boolean;
  522. {Finds a register which contains the constant zero}
  523. Var Counter: TRegister;
  524. Begin
  525. Counter := R_EAX;
  526. FindZeroReg := True;
  527. While (Counter <= R_EDI) And
  528. ((PPaiProp(p^.line)^.Regs[Counter].Typ <> Con_Const) or
  529. (PPaiProp(p^.line)^.Regs[Counter].StartMod <> Pointer(0))) Do
  530. Inc(Byte(Counter));
  531. If (PPaiProp(p^.line)^.Regs[Counter].Typ = Con_Const) And
  532. (PPaiProp(p^.line)^.Regs[Counter].StartMod = Pointer(0))
  533. Then Result := Counter
  534. Else FindZeroReg := False;
  535. End;*)
  536. Procedure DestroyRefs(p: pai; Const Ref: TReference; WhichRegNot: TRegister);
  537. {destroys all registers which possibly contain a reference to Ref}
  538. Var Counter: TRegister;
  539. Begin
  540. WhichRegNot := Reg32(WhichRegNot);
  541. If (Ref.base <> R_NO) Or
  542. (Ref.index <> R_NO)
  543. Then
  544. Begin
  545. If (Ref.base = ProcInfo.FramePointer)
  546. Then
  547. {write something to a parameter or a local variable}
  548. For Counter := R_EAX to R_EDI Do
  549. With PPaiProp(p^.line)^.Regs[Counter] Do
  550. Begin
  551. If (Counter <> WhichRegNot) And
  552. (typ = Con_Ref) And
  553. (Pai(StartMod)^.typ = ait_instruction) And
  554. (Pai386(StartMod)^.op1t = top_ref) And
  555. (RefsEqual(TReference(Pai386(StartMod)^.op1^), Ref) Or
  556. (Not(cs_UncertainOpts in AktSwitches) And
  557. (NrOfMods <> 1)))
  558. Then DestroyReg(p, Counter)
  559. End
  560. Else
  561. {writing something to a pointer location}
  562. For Counter := R_EAX to R_EDI Do
  563. With PPaiProp(p^.line)^.Regs[Counter] Do
  564. If (Counter <> WhichRegNot) And
  565. (typ = Con_Ref) And
  566. (Not(cs_UncertainOpts in AktSwitches) Or
  567. (Ref.Base = R_EDI) Or
  568. (Not((NrOfMods = 1) And
  569. (Pai(StartMod)^.typ = ait_instruction) And
  570. (Pai386(StartMod)^.op1t = top_ref) And
  571. (PReference(Pai386(StartMod)^.op1)^.base = ProcInfo.FramePointer))))
  572. Then
  573. DestroyReg(p, Counter) {we don't know what memory location the reference points to,
  574. so we just destroy every register which contains a memory
  575. reference}
  576. End
  577. Else {the ref is a var name or we just have a reference an absolute offset}
  578. Begin
  579. For Counter := R_EAX to R_EDI Do
  580. If (Counter <> WhichRegNot) And
  581. (PPaiProp(p^.line)^.Regs[Counter].typ = Con_Ref) And
  582. (Not(cs_UncertainOpts in AktSwitches) Or
  583. RefsEqual(Ref,
  584. TReference(Pai386(PPaiProp(p^.line)^.Regs[Counter].StartMod)^.op1^))) Then
  585. DestroyReg(p, Counter)
  586. End;
  587. End;
  588. {$IfDef OptimizeMovs}
  589. Function OpsEqual(typ: Longint; op1, op2: Pointer): Boolean;
  590. Begin {checks whether the two ops are equal}
  591. Case typ Of
  592. Top_Reg, Top_Const: OpsEqual := op1 = op2;
  593. Top_Ref: OpsEqual := RefsEqual(TReference(op1^), TReference(op2^));
  594. Top_None: OpsEqual := True
  595. Else OpsEqual := False
  596. End;
  597. End;
  598. Function RegsSameContent(p1, p2: Pai; Reg: TRegister): Boolean;
  599. {checks whether Reg has the same content in the PPaiProp of p1 and p2}
  600. Begin
  601. Reg := Reg32(Reg);
  602. RegsSameContent :=
  603. PPaiProp(p1^.line)^.Regs[Reg].State =
  604. PPaiProp(p2^.line)^.Regs[Reg].State;
  605. End;
  606. Function InstructionsEqual(p1, p2: Pai): Boolean;
  607. Begin {checks whether two Pai386 instructions are equal}
  608. InstructionsEqual :=
  609. Assigned(p1) And Assigned(p2) And
  610. (Pai(p1)^.typ = ait_instruction) And
  611. (Pai(p1)^.typ = ait_instruction) And
  612. (Pai386(p1)^._operator = Pai386(p2)^._operator) And
  613. (Pai386(p1)^.op1t = Pai386(p2)^.op1t) And
  614. (Pai386(p1)^.op2t = Pai386(p2)^.op2t) And
  615. OpsEqual(Pai386(p1)^.op1t, Pai386(p1)^.op1, Pai386(p2)^.op1) And
  616. OpsEqual(Pai386(p1)^.op2t, Pai386(p1)^.op2, Pai386(p2)^.op2)
  617. End;
  618. Function CheckSequence(p: Pai; Reg: TRegister; Var Found: Longint): Boolean;
  619. {checks whether the current instruction sequence (starting with p) and the
  620. one between StartMod and EndMod of Reg are the same. If so, the number of
  621. instructions that match is stored in Found and true is returned, otherwise
  622. Found holds the number of instructions between StartMod and EndMod and false
  623. is returned}
  624. Var hp2, hp3, EndMod: Pai;
  625. TmpResult: Boolean;
  626. RegsNotYetChecked: Set Of TRegister;
  627. Counter: Byte;
  628. Function NoChangedRegInRef(oldp, newp: Pai): Boolean;
  629. Var TmpP: Pai;
  630. {checks if the first operator of newp is a reference and in that case checks
  631. whether that reference includes regs that have been changed since oldp. This
  632. to avoid wrong optimizations like
  633. movl 8(%epb), %eax movl 8(%epb), %eax
  634. movl 12(%epb), %edx movl 12(%epb), %edx
  635. movl (%eax,%edx,1), %edi movl (%eax,%edx,1), %edi
  636. pushl %edi being converted to pushl %edi
  637. movl 8(%epb), %eax movl 16(%ebp), %edx
  638. movl 16(%epb), %edx pushl %edi
  639. movl (%eax,%edx,1), %edi
  640. pushl %edi
  641. because first is checked whether %eax isn't changed (it isn't) and
  642. consequently all instructions containg %eax are removed}
  643. Begin
  644. TmpResult := True;
  645. If (Pai(oldp)^.typ = ait_instruction) Then {oldp and newp are the same instruction}
  646. Case Pai386(oldp)^.op1t Of
  647. Top_Reg:
  648. If (Reg32(TRegister(Pai386(oldp)^.op1)) in RegsNotYetChecked) Then
  649. Begin
  650. RegsNotYetChecked := RegsNotYetChecked - [Reg32(TRegister(Pai386(oldp)^.op1))];
  651. If Assigned(newp^.Last)
  652. Then
  653. Begin
  654. TmpP := Pai(newp^.last);
  655. While Assigned (TmpP^.Last) And
  656. PPaiProp(TmpP^.Line)^.CanBeRemoved Do
  657. TmpP := Pai(TmpP^.Last);
  658. TmpResult := Assigned(TmpP) And
  659. RegsSameContent(oldp, TmpP, Reg32(TRegister(Pai386(oldp)^.op1)))
  660. End
  661. Else TmpResult := False;
  662. End;
  663. Top_Ref:
  664. With TReference(Pai386(oldp)^.op1^) Do
  665. Begin
  666. If (Base in RegsNotYetChecked) And
  667. (Base <> R_NO) Then
  668. Begin
  669. RegsNotYetChecked := RegsNotYetChecked - [Base];
  670. If Assigned(newp^.Last)
  671. Then
  672. Begin
  673. TmpP := Pai(newp^.last);
  674. While Assigned (TmpP^.Last) And
  675. PPaiProp(TmpP^.Line)^.CanBeRemoved Do
  676. TmpP := Pai(TmpP^.Last);
  677. TmpResult := Assigned(TmpP) And
  678. RegsSameContent(oldp, TmpP, Base)
  679. End
  680. Else TmpResult := False;
  681. End;
  682. If TmpResult And
  683. (Index <> R_NO) And
  684. (Index in RegsNotYetChecked) Then
  685. Begin
  686. RegsNotYetChecked := RegsNotYetChecked - [Index];
  687. If Assigned(newp^.Last)
  688. Then
  689. Begin
  690. TmpP := Pai(newp^.last);
  691. While Assigned (TmpP^.Last) And
  692. PPaiProp(TmpP^.Line)^.CanBeRemoved Do
  693. TmpP := Pai(TmpP^.Last);
  694. TmpResult := Assigned(TmpP) And
  695. RegsSameContent(oldp, TmpP, Index)
  696. End
  697. Else TmpResult := False;
  698. End;
  699. End;
  700. End;
  701. NoChangedRegInRef := TmpResult;
  702. End;
  703. Begin {CheckSequence}
  704. Reg := Reg32(Reg);
  705. Found := 0;
  706. hp2 := p;
  707. hp3 := PPaiProp(Pai(p^.last)^.line)^.Regs[Reg].StartMod;
  708. EndMod := PPaiProp(Pai(p^.last)^.line)^.Regs[Reg].StartMod;
  709. RegsNotYetChecked := [R_EAX..R_EDI];
  710. For Counter := 2 to PPaiProp(Pai(p^.last)^.line)^.Regs[Reg].NrOfMods Do
  711. EndMod := Pai(EndMod^.Next);
  712. While (Found <> PPaiProp(Pai(p^.last)^.line)^.Regs[Reg].NrOfMods) And
  713. InstructionsEqual(hp2, hp3) And
  714. NoChangedRegInRef(EndMod, hp2) Do
  715. Begin
  716. hp2 := Pai(hp2^.next);
  717. hp3 := Pai(hp3^.next);
  718. Inc(Found)
  719. End;
  720. If (Found <> PPaiProp(Pai(p^.last)^.line)^.Regs[Reg].NrOfMods)
  721. Then
  722. Begin
  723. CheckSequence := False;
  724. If (found > 0) then
  725. {this is correct because we only need to turn off the CanBeRemoved flag
  726. when an instruction has already been processed by CheckSequence
  727. (otherwise CanBeRemoved can't be true, or can't have to be turned off).
  728. If it has already been processed by checkSequence and flagged to be
  729. removed, it means that it has been checked against a previous sequence
  730. and that it was equal (otherwise CheckSequence would have returned false
  731. and the instruction wouldn't have been removed). If this "If found > 0"
  732. check is left out, incorrect optimizations are performed.}
  733. Found := PPaiProp(Pai(p)^.line)^.Regs[Reg].NrOfMods
  734. End
  735. Else CheckSequence := True;
  736. End; {CheckSequence}
  737. {$Endif OptimizeMovs}
  738. Procedure DestroyAllRegs(p: Pai);
  739. Var Counter: TRegister;
  740. Begin {initializes/desrtoys all registers}
  741. For Counter := R_EAX To R_EDI Do
  742. DestroyReg(p, Counter);
  743. PPaiProp(p^.line)^.DirFlag := F_Unknown;
  744. End;
  745. Procedure Destroy(PaiObj: Pai; opt: Longint; Op: Pointer);
  746. Begin
  747. Case opt Of
  748. top_reg: DestroyReg(PaiObj, TRegister(Op));
  749. top_ref: DestroyRefs(PaiObj, TReference(Op^), R_NO);
  750. top_symbol:;
  751. End;
  752. End;
  753. Function CreateRegs(First: Pai): Pai;
  754. {Starts creating the reg contents for the instructions starting with p.
  755. Returns the last pai which has been processed}
  756. Var
  757. TmpProp: PPaiProp;
  758. Cnt, InstrCnt: Longint;
  759. InstrProp: TAsmInstrucProp;
  760. p: Pai;
  761. TmpRef: TReference;
  762. TmpReg: TRegister;
  763. Begin
  764. p := First;
  765. InstrCnt := 1;
  766. FillChar(NrOfInstrSinceLastMod, SizeOf(NrOfInstrSinceLastMod), 0);
  767. While Assigned(p) Do
  768. Begin
  769. CreateRegs := p;
  770. If (InstrCnt <= NrOfPaiFast)
  771. Then TmpProp := @PaiPropBlock^[InstrCnt]
  772. Else New(TmpProp);
  773. If (p <> First)
  774. Then TmpProp^ := PPaiProp(Pai(p^.last)^.line)^
  775. Else FillChar(TmpProp^, SizeOf(TmpProp^), 0);
  776. TmpProp^.LineSave := p^.line;
  777. PPaiProp(p^.line) := TmpProp;
  778. For TmpReg := R_EAX To R_EDI Do
  779. Inc(NrOfInstrSinceLastMod[TmpReg]);
  780. Case p^.typ Of
  781. ait_label: DestroyAllRegs(p);
  782. ait_labeled_instruction, ait_stabs, ait_stabn,
  783. ait_stab_function_name:; {nothing changes}
  784. ait_instruction:
  785. Begin
  786. InstrProp := AsmInstr[Pai386(p)^._operator];
  787. Case Pai386(p)^._operator Of
  788. {$IfDef OptimizeMovs}
  789. A_MOV, A_MOVZX, A_MOVSX:
  790. Begin
  791. Case Pai386(p)^.op1t Of
  792. Top_Reg:
  793. Case Pai386(p)^.op2t Of
  794. Top_Reg:
  795. Begin
  796. DestroyReg(p, TRegister(Pai386(p)^.op2));
  797. { TmpProp^.Regs[TRegister(Pai386(p)^.op2)] :=
  798. TmpProp^.Regs[TRegister(Pai386(p)^.op1)];
  799. If (TmpProp^.Regs[TRegister(Pai386(p)^.op2)].ModReg = R_NO) Then
  800. TmpProp^.Regs[TRegister(Pai386(p)^.op2)].ModReg :=
  801. Tregister(Pai386(p)^.op1);}
  802. End;
  803. Top_Ref: DestroyRefs(p, TReference(Pai386(p)^.op2^), TRegister(Pai386(p)^.op1));
  804. End;
  805. Top_Ref:
  806. Begin {destination is always a register in this case}
  807. TmpReg := Reg32(TRegister(Pai386(p)^.op2));
  808. If (RegInRef(TmpReg, TReference(Pai386(p)^.op1^)))
  809. Then
  810. Begin
  811. With PPaiProp(Pai(p)^.line)^.Regs[TmpReg] Do
  812. Begin
  813. Inc(State);
  814. {also store how many instructions are part of the sequence in the first
  815. instructions PPaiProp, so it can be easily accessed from within
  816. CheckSequence}
  817. If (typ <> Con_Ref) Then
  818. Begin
  819. typ := Con_Ref;
  820. StartMod := p;
  821. End;
  822. Inc(NrOfMods, NrOfInstrSinceLastMod[TmpReg]);
  823. PPaiProp(Pai(StartMod)^.line)^.Regs[TmpReg].NrOfMods := NrOfMods;
  824. NrOfInstrSinceLastMod[TmpReg] := 0;
  825. End;
  826. End
  827. Else
  828. Begin
  829. DestroyReg(p, TmpReg);
  830. With PPaiProp(Pai(p)^.line)^.Regs[TmpReg] Do
  831. Begin
  832. Typ := Con_Ref;
  833. StartMod := p;
  834. NrOfMods := 1;
  835. End;
  836. End;
  837. End;
  838. Top_Const:
  839. Begin
  840. Case Pai386(p)^.op2t Of
  841. Top_Reg:
  842. Begin
  843. TmpReg := Reg32(TRegister(Pai386(p)^.op2));
  844. With TmpProp^.Regs[TmpReg] Do
  845. Begin
  846. {it doesn't matter that the state is changed,
  847. it isn't looked at when removing constant reloads}
  848. DestroyReg(p, TmpReg);
  849. typ := Con_Const;
  850. StartMod := Pai386(p)^.op1;
  851. End
  852. End;
  853. Top_Ref: DestroyRefs(P, TReference(Pai386(p)^.op2^), R_NO);
  854. End;
  855. End;
  856. End;
  857. End;
  858. {$EndIf OptimizeMovs}
  859. A_IMUL:
  860. Begin
  861. If (Pai386(p)^.Op3t = top_none)
  862. Then
  863. If (Pai386(p)^.Op2t = top_none)
  864. Then
  865. Begin
  866. DestroyReg(p, R_EAX);
  867. DestroyReg(p, R_EDX)
  868. End
  869. Else
  870. Begin
  871. If (Pai386(p)^.Op2t = top_reg) Then
  872. DestroyReg(p, TRegister(Pai386(p)^.Op2));
  873. End
  874. Else If (Pai386(p)^.Op3t = top_reg) Then
  875. DestroyReg(p, TRegister(longint(twowords(Pai386(p)^.Op2).word2)));
  876. End;
  877. A_XOR:
  878. Begin
  879. If (Pai386(p)^.op1t = top_reg) And
  880. (Pai386(p)^.op2t = top_reg) And
  881. (Pai386(p)^.op1 = Pai386(p)^.op2)
  882. Then
  883. Begin
  884. DestroyReg(p, Tregister(Pai386(p)^.op1));
  885. TmpProp^.Regs[Reg32(Tregister(Pai386(p)^.op1))].typ := Con_Const;
  886. TmpProp^.Regs[Reg32(Tregister(Pai386(p)^.op1))].StartMod := Pointer(0)
  887. End
  888. Else Destroy(p, Pai386(p)^.op2t, Pai386(p)^.op2);
  889. End
  890. Else
  891. Begin
  892. If InstrProp.NCh <> 255
  893. Then
  894. For Cnt := 1 To InstrProp.NCh Do
  895. Case InstrProp.Ch[Cnt] Of
  896. C_None:;
  897. C_EAX..C_EDI: DestroyReg(p, TCh2Reg(InstrProp.Ch[Cnt]));
  898. C_CDirFlag: PPaiProp(Pai(p)^.line)^.DirFlag := F_NotSet;
  899. C_SDirFlag: PPaiProp(Pai(p)^.line)^.DirFlag := F_Set;
  900. C_Op1: Destroy(p, Pai386(p)^.op1t, Pai386(p)^.op1);
  901. C_Op2: Destroy(p, Pai386(p)^.op2t, Pai386(p)^.op2);
  902. C_Op3: Destroy(p, Pai386(p)^.op2t, Pointer(Longint(TwoWords(Pai386(p)^.op2).word2)));
  903. C_MemEDI:
  904. Begin
  905. FillChar(TmpRef, SizeOf(TmpRef), 0);
  906. TmpRef.Base := R_EDI;
  907. DestroyRefs(p, TmpRef, R_NO)
  908. End;
  909. C_Flags, C_FPU:;
  910. End
  911. Else
  912. Begin
  913. DestroyAllRegs(p);
  914. End;
  915. End;
  916. End;
  917. End
  918. Else
  919. Begin
  920. DestroyAllRegs(p);
  921. End;
  922. End;
  923. Inc(InstrCnt);
  924. p := Pai(p^.next);
  925. End;
  926. End;
  927. Procedure OptimizeBlock(First, Last: Pai);
  928. {marks the instructions that can be removed by RemoveInstructs. They're not
  929. removed immediately because sometimes an instruction needs to be checked in
  930. two different sequences}
  931. Var Cnt, Cnt2: Longint;
  932. p, hp1, hp2: Pai;
  933. Begin
  934. p := First;
  935. While (p <> Pai(Last^.Next)) Do
  936. Begin
  937. Case p^.typ Of
  938. ait_label, ait_labeled_instruction:;
  939. ait_instruction:
  940. Begin
  941. Case Pai386(p)^._operator Of
  942. A_CLD: If Assigned(p^.last) And
  943. (PPaiProp(Pai(p^.last)^.line)^.DirFlag = F_NotSet) Then
  944. PPaiProp(Pai(p)^.line)^.CanBeRemoved := True;
  945. {$IfDef OptimizeMovs}
  946. A_MOV{, A_MOVZX, A_MOVSX}:
  947. Begin
  948. Case Pai386(p)^.op1t Of
  949. { Top_Reg:
  950. Case Pai386(p)^.op2t Of
  951. Top_Reg:;
  952. Top_Ref:;
  953. End;}
  954. Top_Ref:
  955. Begin {destination is always a register in this case}
  956. With PPaiProp(p^.line)^.Regs[Reg32(Tregister(Pai386(p)^.op2))] Do
  957. Begin
  958. If Assigned(p^.last) And
  959. (PPaiProp(Pai(p^.last)^.line)^.Regs[Reg32(TRegister(Pai386(p)^.op2))].typ = con_ref) Then
  960. {so we don't try to check a sequence when the register only contains a constant}
  961. If CheckSequence(p, TRegister(Pai386(p)^.op2), Cnt) And
  962. (Cnt > 0)
  963. Then
  964. Begin
  965. hp1 := nil;
  966. {although it's perfectly ok to remove an instruction which doesn't contain
  967. the register that we've just checked (CheckSequence takes care of that),
  968. the sequence containing this other register should also be completely
  969. checked and removed, otherwise we may get situations like this:
  970. movl 12(%ebp), %edx movl 12(%ebp), %edx
  971. movl 16(%ebp), %eax movl 16(%ebp), %eax
  972. movl 8(%edx), %edx movl 8(%edx), %edx
  973. movl (%eax), eax movl (%eax), eax
  974. cmpl %eax, %edx cmpl %eax, %edx
  975. jnz l123 getting converted to jnz l123
  976. movl 12(%ebp), %edx movl 4(%eax), eax
  977. movl 16(%ebp), %eax
  978. movl 8(%edx), %edx
  979. movl 4(%eax), eax}
  980. hp2 := p;
  981. For Cnt2 := 1 to Cnt Do
  982. Begin
  983. If Not(Pai(p)^.typ In [ait_stabs, ait_stabn, ait_stab_function_name]) Then
  984. Begin
  985. If (hp1 = nil) And
  986. Not(RegInInstruction(Tregister(Pai386(hp2)^.op2), p))
  987. Then hp1 := p;
  988. PPaiProp(p^.line)^.CanBeRemoved := True;
  989. End;
  990. p := Pai(p^.next);
  991. End;
  992. If hp1 <> nil Then p := hp1;
  993. Continue;
  994. End
  995. Else
  996. If (Cnt > 0) And
  997. (PPaiProp(p^.line)^.CanBeRemoved) Then
  998. Begin
  999. hp2 := p;
  1000. For Cnt2 := 1 to Cnt Do
  1001. Begin
  1002. If RegInInstruction(Tregister(Pai386(hp2)^.op2), p)
  1003. Then PPaiProp(p^.Line)^.CanBeRemoved := False;
  1004. p := Pai(p^.Next)
  1005. End;
  1006. Continue;
  1007. End;
  1008. End;
  1009. End;
  1010. Top_Const:
  1011. Begin
  1012. Case Pai386(p)^.op2t Of
  1013. Top_Reg:
  1014. Begin
  1015. If Assigned(p^.last) Then
  1016. With PPaiProp(Pai(p^.last)^.line)^.Regs[Reg32(TRegister(Pai386(p)^.op2))] Do
  1017. If (Typ = Con_Const) And
  1018. (StartMod = Pai386(p)^.op1) Then
  1019. PPaiProp(p^.line)^.CanBeRemoved := True;
  1020. End;
  1021. Top_Ref:;
  1022. End;
  1023. End;
  1024. End;
  1025. End;
  1026. {$EndIf OptimizeMovs}
  1027. A_STD: If Assigned(p^.last) And
  1028. (PPaiProp(Pai(p^.last)^.line)^.DirFlag = F_Set) Then
  1029. PPaiProp(Pai(p)^.line)^.CanBeRemoved := True;
  1030. A_XOR:
  1031. Begin
  1032. If (Pai386(p)^.op1t = top_reg) And
  1033. (Pai386(p)^.op2t = top_reg) And
  1034. (Pai386(p)^.op1 = Pai386(p)^.op2) And
  1035. Assigned(p^.last) And
  1036. (PPaiProp(Pai(p^.last)^.line)^.Regs[Reg32(Tregister(Pai386(p)^.op1))].typ = con_const) And
  1037. (PPaiProp(Pai(p^.last)^.line)^.Regs[Reg32(Tregister(Pai386(p)^.op1))].StartMod = Pointer(0))
  1038. Then PPaiProp(p^.line)^.CanBeRemoved := True
  1039. End
  1040. End
  1041. End;
  1042. End;
  1043. p := Pai(p^.next);
  1044. End;
  1045. End;
  1046. Procedure RemoveInstructs(First, Last: Pai);
  1047. {Removes the marked instructions and disposes the PPaiProps of the other
  1048. instructions, restoring theirline number}
  1049. Var p, hp1: Pai;
  1050. TmpLine, InstrCnt: Longint;
  1051. Begin
  1052. p := First;
  1053. InstrCnt := 1;
  1054. While (p <> Pai(Last^.Next)) Do
  1055. If PPaiProp(p^.line)^.CanBeRemoved
  1056. Then
  1057. Begin
  1058. If (InstrCnt > NrOfPaiFast) Then
  1059. Dispose(PPaiProp(p^.Line));
  1060. hp1 := Pai(p^.Next);
  1061. AsmL^.Remove(p);
  1062. Dispose(p, Done);
  1063. p := hp1;
  1064. Inc(InstrCnt)
  1065. End
  1066. Else
  1067. Begin
  1068. If (InstrCnt > NrOfPaiFast)
  1069. Then
  1070. Begin
  1071. TmpLine := PPaiProp(p^.Line)^.LineSave;
  1072. Dispose(PPaiProp(p^.Line));
  1073. p^.Line := TmpLine;
  1074. End
  1075. Else p^.Line := PPaiProp(p^.Line)^.LineSave;
  1076. p := Pai(p^.Next);
  1077. Inc(InstrCnt)
  1078. End;
  1079. If (NrOfPaiFast > 0) Then
  1080. {$IfDef TP}
  1081. Freemem(PaiPropBlock, NrOfPaiFast*(((SizeOf(TPaiProp)+1)div 2)*2))
  1082. {$Else}
  1083. FreeMem(PaiPropBlock, NrOfPaiFast*(((SizeOf(TPaiProp)+3)div 4)*4))
  1084. {$EndIf TP}
  1085. End;
  1086. Function InitReloadOpt(AsmL: PAasmOutput): Boolean;
  1087. {reserves memory for the PPaiProps in one big memory block when not using
  1088. TP, returns False if not enough memory is available for the optimizer in all
  1089. cases}
  1090. Var p: Pai;
  1091. Begin
  1092. P := Pai(AsmL^.First);
  1093. NrOfPaiObjs := 1;
  1094. While (P <> Pai(AsmL^.Last)) Do
  1095. Begin
  1096. Inc(NrOfPaiObjs);
  1097. P := Pai(P^.next)
  1098. End;
  1099. {$IfDef TP}
  1100. If (MemAvail < (SizeOf(TPaiProp)*NrOfPaiObjs))
  1101. {this doesn't have to be one contiguous block}
  1102. Then InitReloadOpt := False
  1103. Else
  1104. Begin
  1105. InitReloadOpt := True;
  1106. If (MaxAvail < 65520)
  1107. Then NrOfPaiFast := MaxAvail Div (((SizeOf(TPaiProp)+1) div 2)*2)
  1108. Else NrOfPaiFast := 65520 Div (((SizeOf(TPaiProp)+1) div 2)*2);
  1109. If (NrOfPaiFast > 0) Then
  1110. GetMem(PaiPropBlock, NrOfPaiFast*(((SizeOf(TPaiProp)+1) div 2)*2));
  1111. End;
  1112. {$Else}
  1113. {Uncomment the next line to see how much memory the reloading optimizer needs}
  1114. { Writeln((NrOfPaiObjs*(((SizeOf(TPaiProp)+3)div 4)*4)));}
  1115. {no need to check mem/maxavail, we've got as much virtual memory as we want}
  1116. InitReloadOpt := True;
  1117. GetMem(PaiPropBlock, NrOfPaiObjs*(((SizeOf(TPaiProp)+3)div 4)*4));
  1118. InitReloadOpt := True;
  1119. NrOfPaiFast := NrOfPaiObjs;
  1120. {$EndIf TP}
  1121. End;
  1122. Var BlockEnd: Pai;
  1123. Begin {ReloadOpt}
  1124. If InitReloadOpt(AsmL)
  1125. Then
  1126. Begin
  1127. BlockEnd := CreateRegs(Pai(AsmL^.First));
  1128. OptimizeBlock(Pai(AsmL^.First), BlockEnd);
  1129. RemoveInstructs(Pai(AsmL^.First), BlockEnd)
  1130. End;
  1131. End;
  1132. {
  1133. $Log$
  1134. Revision 1.2 1998-04-06 22:42:32 jonas
  1135. + removal of superflouos cld/std instructions
  1136. Revision 1.1.1.1 1998/03/25 11:18:12 root
  1137. * Restored version
  1138. Revision 1.22 1998/03/24 21:48:29 florian
  1139. * just a couple of fixes applied:
  1140. - problem with fixed16 solved
  1141. - internalerror 10005 problem fixed
  1142. - patch for assembler reading
  1143. - small optimizer fix
  1144. - mem is now supported
  1145. Revision 1.21 1998/03/11 15:45:35 florian
  1146. * -Oa problem solved
  1147. Revision 1.20 1998/03/10 01:17:13 peter
  1148. * all files have the same header
  1149. * messages are fully implemented, EXTDEBUG uses Comment()
  1150. + AG... files for the Assembler generation
  1151. Revision 1.19 1998/03/09 16:46:27 jonas
  1152. * fixed bug with uncertain optimizations when moving data among variables using movsl
  1153. Revision 1.18 1998/03/04 16:42:00 jonas
  1154. * bugfix in destroyrefs and fixed a potential bug in createregs
  1155. Revision 1.17 1998/03/03 20:33:29 jonas
  1156. * TContent record now only occupies 8 bytes anymore
  1157. Revision 1.15 1998/03/03 01:08:13 florian
  1158. * bug0105 and bug0106 problem solved
  1159. Revision 1.14 1998/03/02 21:35:16 jonas
  1160. * added comments from last update
  1161. Revision 1.13 1998/03/02 21:29:06 jonas
  1162. * redesigned TContent record so it occupies only 13 bytes anymore (was about 18)
  1163. * store TPaiProps of 16 and 8 bit registers in those of the 32 bit regs
  1164. * fixed a small bug which prevented some optimizes from being performed
  1165. * store TPaiProps in one big array instead of in seperate records
  1166. * warning: TP version not tested because I only have TP, not BP (-> no proteced mode apps)
  1167. Revision 1.12 1998/02/24 21:18:13 jonas
  1168. * file name back to lower case
  1169. Revision 1.4 1998/02/24 20:32:12 jonas
  1170. * added comments from latest commit
  1171. Revision 1.3 1998/02/24 20:27:51 jonas
  1172. * if a register is being written to memory, it's contents aren't destroyed
  1173. (wherever it's been written to, its contents are up-to-date)
  1174. * changed the order in which some functions/procedure are defined, because some
  1175. of them are now used by aopt386.pas
  1176. Revision 1.11 1998/02/19 22:46:54 peter
  1177. * Fixed linebreaks
  1178. Revision 1.10 1998/02/13 10:34:31 daniel
  1179. * Made Motorola version compilable.
  1180. * Fixed optimizer
  1181. Revision 1.9 1998/02/12 17:18:49 florian
  1182. * fixed to get remake3 work, but needs additional fixes (output, I don't like
  1183. also that aktswitches isn't a pointer)
  1184. Revision 1.8 1998/02/12 11:49:37 daniel
  1185. Yes! Finally! After three retries, my patch!
  1186. Changes:
  1187. Complete rewrite of psub.pas.
  1188. Added support for DLL's.
  1189. Compiler requires less memory.
  1190. Platform units for each platform.
  1191. Revision 1.7 1998/02/07 10:11:19 michael
  1192. * RefsEqual made less harsh:
  1193. * when something is written to x(%ebp), registers which contain
  1194. a pointer that isn't "x(%ebp)"-based isn't destroyed
  1195. * when something is written to a pointer location, registers
  1196. which contain the contents of x(%ebp) aren't destroyed
  1197. Revision 1.6 1998/01/12 17:45:20 jonas
  1198. * merged DisposeProps and RemoveInstructs procedures (speed!)
  1199. Revision 1.5 1998/01/11 22:51:30 jonas
  1200. * back to unix linebreaks...(hate it! :)
  1201. Revision 1.4 1998/01/11 22:50:10 jonas
  1202. * all floating point store operations now change op1 instead of the fpu regs
  1203. Revision 1.3 1998/01/11 14:40:04 jonas
  1204. * bugfix in optimize procedure (too many instructions were removed in certain cases)
  1205. Revision 1.1 1997/12/30 21:10:34 jonas
  1206. * changed back to unix/linux line breaks
  1207. Pre-CVS log:
  1208. JM Jonas Maebe
  1209. + feature added
  1210. - removed
  1211. * bug fixed or changed
  1212. History (started on 2nd December 1997):
  1213. 2nd December 1997:
  1214. + initial version (JM)
  1215. + removes redundant "xor %reg, %reg"'s (JM)
  1216. 3rd December 1997:
  1217. + removes certain redundant movs (still bugged) (JM)
  1218. * A_REP now destroys ECX
  1219. 4th December 1997:
  1220. * fixed bugs in mov-removal (still bugged) (JM)
  1221. 5th December 1997:
  1222. * fixed more bugs in mov-removal (a compiler compiled with these
  1223. optimizations now can compile itself suyccessfully!) and enhanced
  1224. it (introducing new bugs, which have to be fixed again...) (JM)
  1225. * A_AND and A_OR now destroy op2 instead of op1 <g> (JM)
  1226. 6th December 1997:
  1227. * A_PUSHAD now only destroys ESP instead of all registers (JM)
  1228. * A_REPE and A_REPNE now also destroy ECX (JM)
  1229. * Rewrote some procedures so it's a bit more modular and easier/
  1230. cleaner/possible to do some optimizations, but it's slower (JM)
  1231. * enabled mov-reloading optimization for A_MOVZX and A_MOVSX
  1232. (actually it's already 7 December, 1:25 am in the mean time :) (JM)
  1233. 7th December 1997:
  1234. * All instructions okayed by CheckSequence are now being removed (JM)
  1235. To Do:
  1236. * special case for A_XCHG
  1237. * implementation of ModReg comparing
  1238. * special case for lea
  1239. * fpu optimizing
  1240. * active optimizing (ie. change certain register allocations)
  1241. * make DestroyRefs a little less harsh
  1242. * bug fixes?
  1243. }