aopt386.inc 54 KB

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