aopt386.inc 57 KB

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