aoptda.pas 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581
  1. Unit aoptda;
  2. Interface
  3. uses Aasm;
  4. Type TAsmDFA = Object
  5. Constructor Init(_AsmL: PaasmOutPut; _Blockstart, _Blockend: Pai);
  6. { returns a pointer to the LabelInfo table }
  7. Function GetLabelInfo: PLabelInfo;
  8. Destructor Done;
  9. private
  10. AsmL: PAasmOutput;
  11. LabelInfo: TLabelInfo;
  12. { How many instructions are between the current instruction and the last one }
  13. { that modified the register }
  14. NrOfInstrSinceLastMod: TInstrSinceLastMod;
  15. Procedure BuildLabelTableAndFixRegAlloc;
  16. Function FindLoHiLabels(BlockStart: Pai): Pai;
  17. End;
  18. Implementation
  19. uses aoptmsc
  20. {$ifdef i386}
  21. , ao386msc
  22. {$endif i386}
  23. ;
  24. Constructor TAsmDFA.Init(_AsmL: PaasmOutPut; _Blockstart: Pai;
  25. Var _BlockEnd: Pai);
  26. Begin
  27. AsmL := _AsmL;
  28. LabelInfo.Lowabel := High(AWord);
  29. BlockStart := _BlockStart;
  30. { initializes BlockEnd and through the methodcall also the labeltable, }
  31. { lolab, hilab and labeldif. Also, the regalloc info gets corrected. }
  32. BlockEnd := FindLoHiLabels;
  33. BuildLabelTableAndFixRegAlloc;
  34. End;
  35. Function TAsmDFA.GetLabelInfo: TLabelInfo;
  36. Begin
  37. GetLabelInfo := LabelInfo;
  38. End;
  39. Function TAsmDFA.FindLoHiLabels: Pai;
  40. { Walks through the paasmlist to find the lowest and highest label number. }
  41. { Returns the last Pai object of the current block }
  42. Var LabelFound: Boolean;
  43. P: Pai;
  44. Begin
  45. LabelFound := False;
  46. P := BlockStart;
  47. While Assigned(P) And
  48. ((P^.typ <> Ait_Marker) Or
  49. (Pai_Marker(P)^.Kind <> AsmBlockStart)) Do
  50. Begin
  51. If (Pai(p)^.typ = ait_label) Then
  52. If (Pai_Label(p)^.l^.is_used)
  53. Then
  54. Begin
  55. LabelFound := True;
  56. If (Pai_Label(p)^.l^.labelnr < LowLabel) Then
  57. LowLabel := Pai_Label(p)^.l^.labelnr;
  58. If (Pai_Label(p)^.l^.labelnr > HighLabel) Then
  59. HighLabel := Pai_Label(p)^.l^.labelnr;
  60. End;
  61. GetNextInstruction(p, p);
  62. End;
  63. FindLoHiLabels := p;
  64. If LabelFound
  65. Then LabelDif := HighLabel-LowLabel+1
  66. Else LabelDif := 0;
  67. End;
  68. Procedure TAsmDFA.BuildLabelTableAndFixRegAlloc;
  69. { Builds a table with the locations of the labels in the paasmoutput. }
  70. { Also fixes some RegDeallocs like "# %eax released; push (%eax)" }
  71. Var p, hp1, hp2: Pai;
  72. UsedRegs: TRegSet;
  73. Begin
  74. UsedRegs := [];
  75. With LabelInfo Do
  76. If (LabelDif <> 0) Then
  77. Begin
  78. GetMem(LabelTable, LabelDif*SizeOf(TLabelTableItem));
  79. FillChar(LabelTable^, LabelDif*SizeOf(TLabelTableItem), 0);
  80. p := BlockStart;
  81. While (P <> BlockEnd) Do
  82. Begin
  83. Case p^.typ Of
  84. ait_Label:
  85. If Pai_Label(p)^.l^.is_used Then
  86. LabelTable^[Pai_Label(p)^.l^.labelnr-LowLabel].PaiObj := p;
  87. ait_regAlloc:
  88. begin
  89. if PairegAlloc(p)^.Allocation then
  90. Begin
  91. If Not(PaiRegAlloc(p)^.Reg in UsedRegs) Then
  92. UsedRegs := UsedRegs + [PaiRegAlloc(p)^.Reg]
  93. Else
  94. Begin
  95. hp1 := p;
  96. hp2 := nil;
  97. While GetLastInstruction(hp1, hp1) And
  98. Not(RegInInstruction(PaiRegAlloc(p)^.Reg, hp1)) Do
  99. hp2 := hp1;
  100. If hp2 <> nil Then
  101. Begin
  102. hp1 := New(PaiRegAlloc, DeAlloc(PaiRegAlloc(p)^.Reg));
  103. InsertLLItem(AsmL, Pai(hp2^.previous), hp2, hp1);
  104. End;
  105. End;
  106. End
  107. else
  108. Begin
  109. UsedRegs := UsedRegs - [PaiRegAlloc(p)^.Reg];
  110. hp1 := p;
  111. hp2 := nil;
  112. While Not(FindRegAlloc(PaiRegAlloc(p)^.Reg, Pai(hp1^.Next))) And
  113. GetNextInstruction(hp1, hp1) And
  114. RegInInstruction(PaiRegAlloc(p)^.Reg, hp1) Do
  115. hp2 := hp1;
  116. If hp2 <> nil Then
  117. Begin
  118. hp1 := Pai(p^.previous);
  119. AsmL^.Remove(p);
  120. InsertLLItem(AsmL, hp2, Pai(hp2^.Next), p);
  121. p := hp1;
  122. End;
  123. End;
  124. end;
  125. End;
  126. P := Pai(p^.Next);
  127. While Assigned(p) And
  128. (p^.typ in (SkipInstr - [ait_regalloc])) Do
  129. P := Pai(P^.Next);
  130. End;
  131. End;
  132. Destructor TAsmDFA.Done;
  133. Begin
  134. If Assigned(LabelInfo.LabelTable) Then Dispose(LabelInfo.LabelTable);
  135. End;
  136. Procedure TAsmOptimizer.DoDFAPass2;
  137. { Analyzes the Data Flow of an assembler list. Analyses the reg contents }
  138. { for the instructions between blockstart and blockend. Returns the last pai }
  139. { which has been processed }
  140. Var
  141. CurProp: PPaiProp;
  142. Cnt, InstrCnt : Longint;
  143. InstrProp: TAsmInstrucProp;
  144. UsedRegs: TRegSet;
  145. p, hp, NewBlockStart : Pai;
  146. TmpRef: TReference;
  147. TmpReg: TRegister;
  148. {$ifdef AnalyzeLoops}
  149. TmpState: Byte;
  150. {$endif AnalyzeLoops}
  151. Begin
  152. p := BlockStart;
  153. UsedRegs.init;
  154. UsedRegs.Update(p);
  155. NewBlockStart := SkipHead(p);
  156. InstrCnt := 1;
  157. { done implicitely by the constructor
  158. FillChar(NrOfInstrSinceLastMod, SizeOf(NrOfInstrSinceLastMod), 0); }
  159. While (P <> BlockEnd) Do
  160. Begin
  161. CurProp := New(PPaiProp, init);
  162. If (p <> NewBlockStart)
  163. Then
  164. Begin
  165. {$ifdef JumpAnal}
  166. If (p^.Typ <> ait_label) Then
  167. {$endif JumpAnal}
  168. Begin
  169. GetLastInstruction(p, hp);
  170. CurProp^.Regs := PPaiProp(hp^.OptInfo)^.Regs;
  171. CurProp^.CondRegs.Flags :=
  172. PPaiProp(hp^.OptInfo)^.CondRegs.Flags;
  173. End
  174. End;
  175. CurProp^.UsedRegs.InitWithValue(UsedRegs.GetUsedRegs);
  176. { CurProp^.CanBeRemoved := False;}
  177. UsedRegs.Update(Pai(p^.Next)));
  178. PPaiProp(p^.OptInfo) := CurProp;
  179. For TmpReg := R_EAX To R_EDI Do
  180. Inc(NrOfInstrSinceLastMod[TmpReg]);
  181. Case p^.typ Of
  182. ait_label:
  183. {$Ifndef JumpAnal}
  184. If (Pai_label(p)^.l^.is_used) Then
  185. CurProp^.DestroyAllRegs;
  186. {$Else JumpAnal}
  187. Begin
  188. If (Pai_Label(p)^.is_used) Then
  189. With LTable^[Pai_Label(p)^.l^.labelnr-LoLab] Do
  190. {$IfDef AnalyzeLoops}
  191. If (RefsFound = Pai_Label(p)^.l^.RefCount)
  192. {$Else AnalyzeLoops}
  193. If (JmpsProcessed = Pai_Label(p)^.l^.RefCount)
  194. {$EndIf AnalyzeLoops}
  195. Then
  196. {all jumps to this label have been found}
  197. {$IfDef AnalyzeLoops}
  198. If (JmpsProcessed > 0)
  199. Then
  200. {$EndIf AnalyzeLoops}
  201. {we've processed at least one jump to this label}
  202. Begin
  203. If (GetLastInstruction(p, hp) And
  204. Not(((hp^.typ = ait_instruction)) And
  205. (pai386_labeled(hp)^.is_jmp))
  206. Then
  207. {previous instruction not a JMP -> the contents of the registers after the
  208. previous intruction has been executed have to be taken into account as well}
  209. For TmpReg := R_EAX to R_EDI Do
  210. Begin
  211. If (CurProp^.Regs[TmpReg].WState <>
  212. PPaiProp(hp^.OptInfo)^.Regs[TmpReg].WState)
  213. Then DestroyReg(CurProp, TmpReg)
  214. End
  215. End
  216. {$IfDef AnalyzeLoops}
  217. Else
  218. {a label from a backward jump (e.g. a loop), no jump to this label has
  219. already been processed}
  220. If GetLastInstruction(p, hp) And
  221. Not(hp^.typ = ait_instruction) And
  222. (pai386_labeled(hp)^.opcode = A_JMP))
  223. Then
  224. {previous instruction not a jmp, so keep all the registers' contents from the
  225. previous instruction}
  226. Begin
  227. CurProp^.Regs := PPaiProp(hp^.OptInfo)^.Regs;
  228. CurProp^.DirFlag := PPaiProp(hp^.OptInfo)^.DirFlag;
  229. End
  230. Else
  231. {previous instruction a jmp and no jump to this label processed yet}
  232. Begin
  233. hp := p;
  234. Cnt := InstrCnt;
  235. {continue until we find a jump to the label or a label which has already
  236. been processed}
  237. While GetNextInstruction(hp, hp) And
  238. Not((hp^.typ = ait_instruction) And
  239. (pai386(hp)^.is_jmp) and
  240. (pasmlabel(pai386(hp)^.oper[0].sym)^.labelnr = Pai_Label(p)^.l^.labelnr)) And
  241. Not((hp^.typ = ait_label) And
  242. (LTable^[Pai_Label(hp)^.l^.labelnr-LoLab].RefsFound
  243. = Pai_Label(hp)^.l^.RefCount) And
  244. (LTable^[Pai_Label(hp)^.l^.labelnr-LoLab].JmpsProcessed > 0)) Do
  245. Inc(Cnt);
  246. If (hp^.typ = ait_label)
  247. Then
  248. {there's a processed label after the current one}
  249. Begin
  250. CurProp^.Regs := PaiPropBlock^[Cnt].Regs;
  251. CurProp^.DirFlag := PaiPropBlock^[Cnt].DirFlag;
  252. End
  253. Else
  254. {there's no label anymore after the current one, or they haven't been
  255. processed yet}
  256. Begin
  257. GetLastInstruction(p, hp);
  258. CurProp^.Regs := PPaiProp(hp^.OptInfo)^.Regs;
  259. CurProp^.DirFlag := PPaiProp(hp^.OptInfo)^.DirFlag;
  260. DestroyAllRegs(PPaiProp(hp^.OptInfo))
  261. End
  262. End
  263. {$EndIf AnalyzeLoops}
  264. Else
  265. {not all references to this label have been found, so destroy all registers}
  266. Begin
  267. GetLastInstruction(p, hp);
  268. CurProp^.Regs := PPaiProp(hp^.OptInfo)^.Regs;
  269. CurProp^.DirFlag := PPaiProp(hp^.OptInfo)^.DirFlag;
  270. DestroyAllRegs(CurProp)
  271. End;
  272. End;
  273. {$EndIf JumpAnal}
  274. {$ifdef GDB}
  275. ait_stabs, ait_stabn, ait_stab_function_name:;
  276. {$endif GDB}
  277. ait_instruction:
  278. Begin
  279. if pai386(p)^.is_jmp then
  280. begin
  281. {$IfNDef JumpAnal}
  282. ;
  283. {$Else JumpAnal}
  284. With LTable^[pasmlabel(pai386(p)^.oper[0].sym)^.labelnr-LoLab] Do
  285. If (RefsFound = pasmlabel(pai386(p)^.oper[0].sym)^.RefCount) Then
  286. Begin
  287. If (InstrCnt < InstrNr)
  288. Then
  289. {forward jump}
  290. If (JmpsProcessed = 0) Then
  291. {no jump to this label has been processed yet}
  292. Begin
  293. PaiPropBlock^[InstrNr].Regs := CurProp^.Regs;
  294. PaiPropBlock^[InstrNr].DirFlag := CurProp^.DirFlag;
  295. Inc(JmpsProcessed);
  296. End
  297. Else
  298. Begin
  299. For TmpReg := R_EAX to R_EDI Do
  300. If (PaiPropBlock^[InstrNr].Regs[TmpReg].WState <>
  301. CurProp^.Regs[TmpReg].WState) Then
  302. DestroyReg(@PaiPropBlock^[InstrNr], TmpReg);
  303. Inc(JmpsProcessed);
  304. End
  305. {$ifdef AnalyzeLoops}
  306. Else
  307. { backward jump, a loop for example}
  308. { If (JmpsProcessed > 0) Or
  309. Not(GetLastInstruction(PaiObj, hp) And
  310. (hp^.typ = ait_labeled_instruction) And
  311. (pai386_labeled(hp)^.opcode = A_JMP))
  312. Then}
  313. {instruction prior to label is not a jmp, or at least one jump to the label
  314. has yet been processed}
  315. Begin
  316. Inc(JmpsProcessed);
  317. For TmpReg := R_EAX to R_EDI Do
  318. If (PaiPropBlock^[InstrNr].Regs[TmpReg].WState <>
  319. CurProp^.Regs[TmpReg].WState)
  320. Then
  321. Begin
  322. TmpState := PaiPropBlock^[InstrNr].Regs[TmpReg].WState;
  323. Cnt := InstrNr;
  324. While (TmpState = PaiPropBlock^[Cnt].Regs[TmpReg].WState) Do
  325. Begin
  326. DestroyReg(@PaiPropBlock^[Cnt], TmpReg);
  327. Inc(Cnt);
  328. End;
  329. While (Cnt <= InstrCnt) Do
  330. Begin
  331. Inc(PaiPropBlock^[Cnt].Regs[TmpReg].WState);
  332. Inc(Cnt)
  333. End
  334. End;
  335. End
  336. { Else }
  337. {instruction prior to label is a jmp and no jumps to the label have yet been
  338. processed}
  339. { Begin
  340. Inc(JmpsProcessed);
  341. For TmpReg := R_EAX to R_EDI Do
  342. Begin
  343. TmpState := PaiPropBlock^[InstrNr].Regs[TmpReg].WState;
  344. Cnt := InstrNr;
  345. While (TmpState = PaiPropBlock^[Cnt].Regs[TmpReg].WState) Do
  346. Begin
  347. PaiPropBlock^[Cnt].Regs[TmpReg] := CurProp^.Regs[TmpReg];
  348. Inc(Cnt);
  349. End;
  350. TmpState := PaiPropBlock^[InstrNr].Regs[TmpReg].WState;
  351. While (TmpState = PaiPropBlock^[Cnt].Regs[TmpReg].WState) Do
  352. Begin
  353. DestroyReg(@PaiPropBlock^[Cnt], TmpReg);
  354. Inc(Cnt);
  355. End;
  356. While (Cnt <= InstrCnt) Do
  357. Begin
  358. Inc(PaiPropBlock^[Cnt].Regs[TmpReg].WState);
  359. Inc(Cnt)
  360. End
  361. End
  362. End}
  363. {$endif AnalyzeLoops}
  364. End;
  365. {$EndIf JumpAnal}
  366. end
  367. else
  368. begin
  369. InstrProp := AsmInstr[PInstr(p)^.opcode];
  370. If IsStoreInstr(p) Then
  371. Begin
  372. CurProp^.ReadReg(PInstr(p)^.oper[StoreSrc].reg);
  373. CurProp^.ReadRef(PInstr(p)^.oper[StoreDst].ref);
  374. CurProp^.DestroyRefs(PInstr(p)^.oper[StoreDst].ref^,
  375. PInstr(p)^.oper[StoreSrc].reg);
  376. End
  377. Else If IsLoadInstr(p) Then
  378. Begin
  379. CurProp^.ReadRef(PInstr(p)^.oper[LoadSrc].ref);
  380. CurProp^.ReadReg(PInstr(p)^.oper[LoadDst].reg);
  381. TmpReg := RegMaxSize(PInstr(p)^.oper[1].reg);
  382. If RegInRef(TmpReg, Pai386(p)^.oper[0].ref^) And
  383. (CurProp^.Regs[TmpReg].Typ = Con_Ref)
  384. Then
  385. Begin
  386. With CurProp^.Regs[TmpReg] Do
  387. Begin
  388. IncState(WState);
  389. {also store how many instructions are part of the sequence in the first
  390. instructions PPaiProp, so it can be easily accessed from within
  391. CheckSequence}
  392. Inc(NrOfMods, NrOfInstrSinceLastMod[TmpReg]);
  393. PPaiProp(Pai(StartMod)^.OptInfo)^.Regs[TmpReg].NrOfMods := NrOfMods;
  394. NrOfInstrSinceLastMod[TmpReg] := 0;
  395. End;
  396. End
  397. Else
  398. Begin
  399. DestroyReg(CurProp, TmpReg);
  400. If Not(RegInRef(TmpReg, Pai386(p)^.oper[0].ref^)) Then
  401. With CurProp^.Regs[TmpReg] Do
  402. Begin
  403. Typ := Con_Ref;
  404. StartMod := p;
  405. NrOfMods := 1;
  406. End
  407. End;
  408. {$ifdef StateDebug}
  409. hp := new(pai_asm_comment,init(strpnew(att_reg2str[TmpReg]+': '+tostr(CurProp^.Regs[TmpReg].WState))));
  410. InsertLLItem(AsmL, p, p^.next, hp);
  411. {$endif StateDebug}
  412. End;
  413. Top_Const:
  414. Begin
  415. Case Pai386(p)^.oper[1].typ Of
  416. Top_Reg:
  417. Begin
  418. TmpReg := Reg32(Pai386(p)^.oper[1].reg);
  419. With CurProp^.Regs[TmpReg] Do
  420. Begin
  421. DestroyReg(CurProp, TmpReg);
  422. typ := Con_Const;
  423. StartMod := p;
  424. End
  425. End;
  426. Top_Ref:
  427. Begin
  428. ReadRef(CurProp, Pai386(p)^.oper[1].ref);
  429. DestroyRefs(P, Pai386(p)^.oper[1].ref^, R_NO);
  430. End;
  431. End;
  432. End;
  433. End;
  434. End;
  435. A_IMUL:
  436. Begin
  437. ReadOp(CurProp, Pai386(p)^.oper[0]);
  438. ReadOp(CurProp, Pai386(p)^.oper[1]);
  439. If (Pai386(p)^.oper[2].typ = top_none) Then
  440. If (Pai386(p)^.oper[1].typ = top_none) Then
  441. Begin
  442. DestroyReg(CurProp, R_EAX);
  443. DestroyReg(CurProp, R_EDX)
  444. End
  445. Else
  446. {$ifdef arithopt}
  447. AddInstr2OpContents(Pai386(p), Pai386(p)^.oper[1])
  448. {$else arithopt}
  449. DestroyOp(p, Pai386(p)^.oper[1])
  450. {$endif arithopt}
  451. Else
  452. {$ifdef arithopt}
  453. AddInstr2OpContents(Pai386(p), Pai386(p)^.oper[2]);
  454. {$else arithopt}
  455. DestroyOp(p, Pai386(p)^.oper[2]);
  456. {$endif arithopt}
  457. End;
  458. A_XOR:
  459. Begin
  460. ReadOp(CurProp, Pai386(p)^.oper[0]);
  461. ReadOp(CurProp, Pai386(p)^.oper[1]);
  462. If (Pai386(p)^.oper[0].typ = top_reg) And
  463. (Pai386(p)^.oper[1].typ = top_reg) And
  464. (Pai386(p)^.oper[0].reg = Pai386(p)^.oper[1].reg)
  465. Then
  466. Begin
  467. DestroyReg(CurProp, Pai386(p)^.oper[0].reg);
  468. CurProp^.Regs[Reg32(Pai386(p)^.oper[0].reg)].typ := Con_Const;
  469. CurProp^.Regs[Reg32(Pai386(p)^.oper[0].reg)].StartMod := Pointer(0)
  470. End
  471. Else
  472. DestroyOp(p, Pai386(p)^.oper[1]);
  473. End
  474. Else
  475. Begin
  476. Cnt := 1;
  477. While (Cnt <= MaxCh) And
  478. (InstrProp.Ch[Cnt] <> C_None) Do
  479. Begin
  480. Case InstrProp.Ch[Cnt] Of
  481. C_REAX..C_REDI: ReadReg(CurProp,TCh2Reg(InstrProp.Ch[Cnt]));
  482. C_WEAX..C_RWEDI:
  483. Begin
  484. If (InstrProp.Ch[Cnt] >= C_RWEAX) Then
  485. ReadReg(CurProp, TCh2Reg(InstrProp.Ch[Cnt]));
  486. DestroyReg(CurProp, TCh2Reg(InstrProp.Ch[Cnt]));
  487. End;
  488. {$ifdef arithopt}
  489. C_MEAX..C_MEDI:
  490. AddInstr2RegContents({$ifdef statedebug} asml, {$endif}
  491. Pai386(p),
  492. TCh2Reg(InstrProp.Ch[Cnt]));
  493. {$endif arithopt}
  494. C_CDirFlag: CurProp^.DirFlag := F_NotSet;
  495. C_SDirFlag: CurProp^.DirFlag := F_Set;
  496. C_Rop1: ReadOp(CurProp, Pai386(p)^.oper[0]);
  497. C_Rop2: ReadOp(CurProp, Pai386(p)^.oper[1]);
  498. C_ROp3: ReadOp(CurProp, Pai386(p)^.oper[2]);
  499. C_Wop1..C_RWop1:
  500. Begin
  501. If (InstrProp.Ch[Cnt] in [C_RWop1]) Then
  502. ReadOp(CurProp, Pai386(p)^.oper[0]);
  503. DestroyOp(p, Pai386(p)^.oper[0]);
  504. End;
  505. {$ifdef arithopt}
  506. C_Mop1:
  507. AddInstr2OpContents({$ifdef statedebug} asml, {$endif}
  508. Pai386(p), Pai386(p)^.oper[0]);
  509. {$endif arithopt}
  510. C_Wop2..C_RWop2:
  511. Begin
  512. If (InstrProp.Ch[Cnt] = C_RWop2) Then
  513. ReadOp(CurProp, Pai386(p)^.oper[1]);
  514. DestroyOp(p, Pai386(p)^.oper[1]);
  515. End;
  516. {$ifdef arithopt}
  517. C_Mop2:
  518. AddInstr2OpContents({$ifdef statedebug} asml, {$endif}
  519. Pai386(p), Pai386(p)^.oper[1]);
  520. {$endif arithopt}
  521. C_WOp3..C_RWOp3:
  522. Begin
  523. If (InstrProp.Ch[Cnt] = C_RWOp3) Then
  524. ReadOp(CurProp, Pai386(p)^.oper[2]);
  525. DestroyOp(p, Pai386(p)^.oper[2]);
  526. End;
  527. {$ifdef arithopt}
  528. C_Mop3:
  529. AddInstr2OpContents({$ifdef statedebug} asml, {$endif}
  530. Pai386(p), Pai386(p)^.oper[2]);
  531. {$endif arithopt}
  532. C_WMemEDI:
  533. Begin
  534. ReadReg(CurProp, R_EDI);
  535. FillChar(TmpRef, SizeOf(TmpRef), 0);
  536. TmpRef.Base := R_EDI;
  537. DestroyRefs(p, TmpRef, R_NO)
  538. End;
  539. C_RFlags, C_WFlags, C_RWFlags, C_FPU:
  540. Else
  541. Begin
  542. DestroyAllRegs(CurProp);
  543. End;
  544. End;
  545. Inc(Cnt);
  546. End
  547. End;
  548. end;
  549. End;
  550. End
  551. Else
  552. Begin
  553. DestroyAllRegs(CurProp);
  554. End;
  555. End;
  556. Inc(InstrCnt);
  557. GetNextInstruction(p, p);
  558. End;
  559. End;
  560. End.