n386flw.pas 46 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 by Florian Klaempfl
  4. Generate i386 assembler for nodes that influence the flow
  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. unit n386flw;
  19. {$i defines.inc}
  20. interface
  21. uses
  22. node,nflw;
  23. type
  24. ti386whilerepeatnode = class(twhilerepeatnode)
  25. procedure pass_2;override;
  26. end;
  27. ti386ifnode = class(tifnode)
  28. procedure pass_2;override;
  29. end;
  30. ti386fornode = class(tfornode)
  31. procedure pass_2;override;
  32. end;
  33. ti386exitnode = class(texitnode)
  34. procedure pass_2;override;
  35. end;
  36. ti386breaknode = class(tbreaknode)
  37. procedure pass_2;override;
  38. end;
  39. ti386continuenode = class(tcontinuenode)
  40. procedure pass_2;override;
  41. end;
  42. ti386gotonode = class(tgotonode)
  43. procedure pass_2;override;
  44. end;
  45. ti386labelnode = class(tlabelnode)
  46. procedure pass_2;override;
  47. end;
  48. ti386raisenode = class(traisenode)
  49. procedure pass_2;override;
  50. end;
  51. ti386tryexceptnode = class(ttryexceptnode)
  52. procedure pass_2;override;
  53. end;
  54. ti386tryfinallynode = class(ttryfinallynode)
  55. procedure pass_2;override;
  56. end;
  57. ti386onnode = class(tonnode)
  58. procedure pass_2;override;
  59. end;
  60. ti386failnode = class(tfailnode)
  61. procedure pass_2;override;
  62. end;
  63. implementation
  64. uses
  65. verbose,globtype,globals,systems,
  66. symconst,symdef,symsym,aasm,types,
  67. hcodegen,temp_gen,pass_2,
  68. cpubase,cpuasm,
  69. pass_1,nld,ncon,
  70. cgai386,tgcpu,n386util,regvars;
  71. {*****************************************************************************
  72. Second_While_RepeatN
  73. *****************************************************************************}
  74. procedure ti386whilerepeatnode.pass_2;
  75. var
  76. lcont,lbreak,lloop,
  77. oldclabel,oldblabel : tasmlabel;
  78. otlabel,oflabel : tasmlabel;
  79. //start_regvars_loaded,
  80. //then_regvars_loaded: regvar_booleanarray;
  81. begin
  82. getlabel(lloop);
  83. getlabel(lcont);
  84. getlabel(lbreak);
  85. { arrange continue and breaklabels: }
  86. oldclabel:=aktcontinuelabel;
  87. oldblabel:=aktbreaklabel;
  88. load_all_regvars(exprasmlist);
  89. { handling code at the end as it is much more efficient, and makes
  90. while equal to repeat loop, only the end true/false is swapped (PFV) }
  91. if nodetype=whilen then
  92. emitjmp(C_None,lcont);
  93. { align loop target }
  94. exprasmList.concat(Tai_align.Create(aktalignment.loopalign));
  95. emitlab(lloop);
  96. aktcontinuelabel:=lcont;
  97. aktbreaklabel:=lbreak;
  98. cleartempgen;
  99. if assigned(right) then
  100. secondpass(right);
  101. load_all_regvars(exprasmlist);
  102. emitlab(lcont);
  103. otlabel:=truelabel;
  104. oflabel:=falselabel;
  105. if nodetype=whilen then
  106. begin
  107. truelabel:=lloop;
  108. falselabel:=lbreak;
  109. end
  110. { repeatn }
  111. else
  112. begin
  113. truelabel:=lbreak;
  114. falselabel:=lloop;
  115. end;
  116. cleartempgen;
  117. secondpass(left);
  118. load_all_regvars(exprasmlist);
  119. maketojumpbool(left);
  120. emitlab(lbreak);
  121. truelabel:=otlabel;
  122. falselabel:=oflabel;
  123. aktcontinuelabel:=oldclabel;
  124. aktbreaklabel:=oldblabel;
  125. { a break/continue in a while/repeat block can't be seen outside }
  126. flowcontrol:=flowcontrol-[fc_break,fc_continue];
  127. end;
  128. {*****************************************************************************
  129. TI386IFNODE
  130. *****************************************************************************}
  131. procedure ti386ifnode.pass_2;
  132. var
  133. hl,otlabel,oflabel : tasmlabel;
  134. begin
  135. otlabel:=truelabel;
  136. oflabel:=falselabel;
  137. getlabel(truelabel);
  138. getlabel(falselabel);
  139. cleartempgen;
  140. secondpass(left);
  141. load_all_regvars(exprasmlist);
  142. maketojumpbool(left);
  143. if assigned(right) then
  144. begin
  145. emitlab(truelabel);
  146. cleartempgen;
  147. secondpass(right);
  148. { automatically done for blocks, but not for statements (JM) }
  149. load_all_regvars(exprasmlist);
  150. end;
  151. if assigned(t1) then
  152. begin
  153. if assigned(right) then
  154. begin
  155. getlabel(hl);
  156. { do go back to if line !! }
  157. aktfilepos:=exprasmList.getlasttaifilepos^;
  158. emitjmp(C_None,hl);
  159. end;
  160. emitlab(falselabel);
  161. cleartempgen;
  162. secondpass(t1);
  163. load_all_regvars(exprasmlist);
  164. if assigned(right) then
  165. emitlab(hl);
  166. end
  167. else
  168. begin
  169. emitlab(falselabel);
  170. end;
  171. if not(assigned(right)) then
  172. begin
  173. emitlab(truelabel);
  174. end;
  175. truelabel:=otlabel;
  176. falselabel:=oflabel;
  177. end;
  178. {*****************************************************************************
  179. SecondFor
  180. *****************************************************************************}
  181. procedure ti386fornode.pass_2;
  182. var
  183. l3,oldclabel,oldblabel : tasmlabel;
  184. omitfirstcomp,temptovalue : boolean;
  185. hs : byte;
  186. temp1 : treference;
  187. hop : tasmop;
  188. hcond : tasmcond;
  189. cmpreg,cmp32 : tregister;
  190. opsize : topsize;
  191. count_var_is_signed : boolean;
  192. begin
  193. oldclabel:=aktcontinuelabel;
  194. oldblabel:=aktbreaklabel;
  195. getlabel(aktcontinuelabel);
  196. getlabel(aktbreaklabel);
  197. getlabel(l3);
  198. { could we spare the first comparison ? }
  199. omitfirstcomp:=false;
  200. if right.nodetype=ordconstn then
  201. if tassignmentnode(left).right.nodetype=ordconstn then
  202. omitfirstcomp:=((nf_backward in flags) and
  203. (tordconstnode(tassignmentnode(left).right).value>=tordconstnode(right).value))
  204. or (not(nf_backward in flags) and
  205. (tordconstnode(tassignmentnode(left).right).value<=tordconstnode(right).value));
  206. { only calculate reference }
  207. cleartempgen;
  208. secondpass(t2);
  209. hs:=t2.resulttype.def.size;
  210. if t2.location.loc <> LOC_CREGISTER then
  211. cmp32:=getregister32;
  212. case hs of
  213. 1 : begin
  214. opsize:=S_B;
  215. if t2.location.loc <> LOC_CREGISTER then
  216. cmpreg:=reg32toreg8(cmp32);
  217. end;
  218. 2 : begin
  219. opsize:=S_W;
  220. if t2.location.loc <> LOC_CREGISTER then
  221. cmpreg:=reg32toreg16(cmp32);
  222. end;
  223. 4 : begin
  224. opsize:=S_L;
  225. if t2.location.loc <> LOC_CREGISTER then
  226. cmpreg:=cmp32;
  227. end;
  228. end;
  229. { first set the to value
  230. because the count var can be in the expression !! }
  231. cleartempgen;
  232. secondpass(right);
  233. { calculate pointer value and check if changeable and if so }
  234. { load into temporary variable }
  235. if right.nodetype<>ordconstn then
  236. begin
  237. temp1.symbol:=nil;
  238. gettempofsizereference(hs,temp1);
  239. temptovalue:=true;
  240. if (right.location.loc=LOC_REGISTER) or
  241. (right.location.loc=LOC_CREGISTER) then
  242. begin
  243. emit_reg_ref(A_MOV,opsize,right.location.register,
  244. newreference(temp1));
  245. end
  246. else
  247. concatcopy(right.location.reference,temp1,hs,false,false);
  248. end
  249. else
  250. temptovalue:=false;
  251. { produce start assignment }
  252. cleartempgen;
  253. secondpass(left);
  254. count_var_is_signed:=is_signed(torddef(t2.resulttype.def));
  255. if temptovalue then
  256. begin
  257. if t2.location.loc=LOC_CREGISTER then
  258. begin
  259. emit_ref_reg(A_CMP,opsize,newreference(temp1),
  260. t2.location.register);
  261. end
  262. else
  263. begin
  264. emit_ref_reg(A_MOV,opsize,newreference(t2.location.reference),
  265. cmpreg);
  266. emit_ref_reg(A_CMP,opsize,newreference(temp1),
  267. cmpreg);
  268. { temp register not necessary anymore currently (JM) }
  269. ungetregister32(cmp32);
  270. end;
  271. end
  272. else
  273. begin
  274. if not(omitfirstcomp) then
  275. begin
  276. if t2.location.loc=LOC_CREGISTER then
  277. emit_const_reg(A_CMP,opsize,tordconstnode(right).value,
  278. t2.location.register)
  279. else
  280. emit_const_ref(A_CMP,opsize,tordconstnode(right).value,
  281. newreference(t2.location.reference));
  282. end;
  283. end;
  284. if nf_backward in flags then
  285. if count_var_is_signed then
  286. hcond:=C_L
  287. else
  288. hcond:=C_B
  289. else
  290. if count_var_is_signed then
  291. hcond:=C_G
  292. else
  293. hcond:=C_A;
  294. load_all_regvars(exprasmlist);
  295. if not(omitfirstcomp) or temptovalue then
  296. emitjmp(hcond,aktbreaklabel);
  297. { align loop target }
  298. exprasmList.concat(Tai_align.Create(aktalignment.loopalign));
  299. emitlab(l3);
  300. { help register must not be in instruction block }
  301. cleartempgen;
  302. if assigned(t1) then
  303. begin
  304. secondpass(t1);
  305. load_all_regvars(exprasmlist);
  306. end;
  307. emitlab(aktcontinuelabel);
  308. { makes no problems there }
  309. cleartempgen;
  310. if (t2.location.loc <> LOC_CREGISTER) then
  311. begin
  312. { demand help register again }
  313. cmp32:=getregister32;
  314. case hs of
  315. 1 : cmpreg:=reg32toreg8(cmp32);
  316. 2 : cmpreg:=reg32toreg16(cmp32);
  317. 4 : cmpreg:=cmp32;
  318. end;
  319. end;
  320. { produce comparison and the corresponding }
  321. { jump }
  322. if temptovalue then
  323. begin
  324. if t2.location.loc=LOC_CREGISTER then
  325. begin
  326. emit_ref_reg(A_CMP,opsize,newreference(temp1),
  327. t2.location.register);
  328. end
  329. else
  330. begin
  331. emit_ref_reg(A_MOV,opsize,newreference(t2.location.reference),
  332. cmpreg);
  333. emit_ref_reg(A_CMP,opsize,newreference(temp1),
  334. cmpreg);
  335. end;
  336. end
  337. else
  338. begin
  339. if t2.location.loc=LOC_CREGISTER then
  340. emit_const_reg(A_CMP,opsize,tordconstnode(right).value,
  341. t2.location.register)
  342. else
  343. emit_const_ref(A_CMP,opsize,tordconstnode(right).value,
  344. newreference(t2.location.reference));
  345. end;
  346. if nf_backward in flags then
  347. if count_var_is_signed then
  348. hcond:=C_LE
  349. else
  350. hcond:=C_BE
  351. else
  352. if count_var_is_signed then
  353. hcond:=C_GE
  354. else
  355. hcond:=C_AE;
  356. load_all_regvars(exprasmlist);
  357. emitjmp(hcond,aktbreaklabel);
  358. { according to count direction DEC or INC... }
  359. { must be after the test because of 0 to 255 for bytes !! }
  360. if nf_backward in flags then
  361. hop:=A_DEC
  362. else
  363. hop:=A_INC;
  364. if t2.location.loc=LOC_CREGISTER then
  365. emit_reg(hop,opsize,t2.location.register)
  366. else
  367. emit_ref(hop,opsize,newreference(t2.location.reference));
  368. emitjmp(C_None,l3);
  369. if (t2.location.loc <> LOC_CREGISTER) then
  370. ungetregister32(cmp32);
  371. if temptovalue then
  372. ungetiftemp(temp1);
  373. { this is the break label: }
  374. emitlab(aktbreaklabel);
  375. aktcontinuelabel:=oldclabel;
  376. aktbreaklabel:=oldblabel;
  377. { a break/continue in a for block can't be seen outside }
  378. flowcontrol:=flowcontrol-[fc_break,fc_continue];
  379. end;
  380. {*****************************************************************************
  381. SecondExitN
  382. *****************************************************************************}
  383. procedure ti386exitnode.pass_2;
  384. var
  385. {op : tasmop;
  386. s : topsize;}
  387. otlabel,oflabel : tasmlabel;
  388. r : preference;
  389. is_mem,
  390. allocated_eax,
  391. allocated_edx: boolean;
  392. procedure cleanleft;
  393. begin
  394. if is_mem then
  395. begin
  396. del_reference(left.location.reference);
  397. ungetiftemp(left.location.reference);
  398. end
  399. else
  400. begin
  401. ungetregister(left.location.register);
  402. if left.location.registerhigh <> R_NO then
  403. ungetregister(left.location.registerhigh);
  404. end;
  405. end;
  406. label
  407. do_jmp;
  408. begin
  409. load_all_regvars(exprasmlist);
  410. include(flowcontrol,fc_exit);
  411. if assigned(left) then
  412. if left.nodetype=assignn then
  413. begin
  414. { just do a normal assignment followed by exit }
  415. secondpass(left);
  416. emitjmp(C_None,aktexitlabel);
  417. end
  418. else
  419. begin
  420. allocated_eax := false;
  421. allocated_edx := false;
  422. otlabel:=truelabel;
  423. oflabel:=falselabel;
  424. getlabel(truelabel);
  425. getlabel(falselabel);
  426. secondpass(left);
  427. case left.location.loc of
  428. LOC_FPU : goto do_jmp;
  429. LOC_MEM,
  430. LOC_REFERENCE : is_mem:=true;
  431. LOC_CREGISTER,
  432. LOC_REGISTER : is_mem:=false;
  433. LOC_FLAGS : begin
  434. exprasmlist.concat(tairegalloc.alloc(R_EAX));
  435. allocated_eax := true;
  436. emit_flag2reg(left.location.resflags,R_AL);
  437. goto do_jmp;
  438. end;
  439. LOC_JUMP : begin
  440. exprasmlist.concat(tairegalloc.alloc(R_EAX));
  441. allocated_eax := true;
  442. emitlab(truelabel);
  443. emit_const_reg(A_MOV,S_B,1,R_AL);
  444. emitjmp(C_None,aktexit2label);
  445. emitlab(falselabel);
  446. emit_reg_reg(A_XOR,S_B,R_AL,R_AL);
  447. goto do_jmp;
  448. end;
  449. else
  450. internalerror(2001);
  451. end;
  452. case procinfo^.returntype.def.deftype of
  453. pointerdef,
  454. procvardef : begin
  455. cleanleft;
  456. exprasmlist.concat(tairegalloc.alloc(R_EAX));
  457. allocated_eax := true;
  458. if is_mem then
  459. emit_ref_reg(A_MOV,S_L,
  460. newreference(left.location.reference),R_EAX)
  461. else
  462. emit_reg_reg(A_MOV,S_L,
  463. left.location.register,R_EAX);
  464. end;
  465. floatdef : begin
  466. cleanleft;
  467. if is_mem then
  468. floatload(tfloatdef(procinfo^.returntype.def).typ,left.location.reference);
  469. end;
  470. { orddef,
  471. enumdef : }
  472. else
  473. { it can be anything shorter than 4 bytes PM
  474. this caused form bug 711 }
  475. begin
  476. cleanleft;
  477. exprasmlist.concat(tairegalloc.alloc(R_EAX));
  478. allocated_eax := true;
  479. case procinfo^.returntype.def.size of
  480. { it can be a qword/int64 too ... }
  481. 8 : if is_mem then
  482. begin
  483. emit_ref_reg(A_MOV,S_L,
  484. newreference(left.location.reference),R_EAX);
  485. r:=newreference(left.location.reference);
  486. inc(r^.offset,4);
  487. exprasmlist.concat(tairegalloc.alloc(R_EDX));
  488. allocated_edx := true;
  489. emit_ref_reg(A_MOV,S_L,r,R_EDX);
  490. end
  491. else
  492. begin
  493. emit_reg_reg(A_MOV,S_L,left.location.registerlow,R_EAX);
  494. exprasmlist.concat(tairegalloc.alloc(R_EDX));
  495. allocated_edx := true;
  496. emit_reg_reg(A_MOV,S_L,left.location.registerhigh,R_EDX);
  497. end;
  498. { if its 3 bytes only we can still
  499. copy one of garbage ! PM }
  500. 4,3 : if is_mem then
  501. emit_ref_reg(A_MOV,S_L,
  502. newreference(left.location.reference),R_EAX)
  503. else
  504. emit_reg_reg(A_MOV,S_L,left.location.register,R_EAX);
  505. 2 : if is_mem then
  506. emit_ref_reg(A_MOV,S_W,
  507. newreference(left.location.reference),R_AX)
  508. else
  509. emit_reg_reg(A_MOV,S_W,makereg16(left.location.register),R_AX);
  510. 1 : if is_mem then
  511. emit_ref_reg(A_MOV,S_B,
  512. newreference(left.location.reference),R_AL)
  513. else
  514. emit_reg_reg(A_MOV,S_B,makereg8(left.location.register),R_AL);
  515. else internalerror(605001);
  516. end;
  517. end;
  518. end;
  519. do_jmp:
  520. truelabel:=otlabel;
  521. falselabel:=oflabel;
  522. emitjmp(C_None,aktexit2label);
  523. if allocated_eax then
  524. exprasmlist.concat(tairegalloc.dealloc(R_EAX));
  525. if allocated_edx then
  526. exprasmlist.concat(tairegalloc.dealloc(R_EDX));
  527. end
  528. else
  529. emitjmp(C_None,aktexitlabel);
  530. end;
  531. {*****************************************************************************
  532. SecondBreakN
  533. *****************************************************************************}
  534. procedure ti386breaknode.pass_2;
  535. begin
  536. include(flowcontrol,fc_break);
  537. if aktbreaklabel<>nil then
  538. begin
  539. load_all_regvars(exprasmlist);
  540. emitjmp(C_None,aktbreaklabel)
  541. end
  542. else
  543. CGMessage(cg_e_break_not_allowed);
  544. end;
  545. {*****************************************************************************
  546. SecondContinueN
  547. *****************************************************************************}
  548. procedure ti386continuenode.pass_2;
  549. begin
  550. include(flowcontrol,fc_continue);
  551. if aktcontinuelabel<>nil then
  552. begin
  553. load_all_regvars(exprasmlist);
  554. emitjmp(C_None,aktcontinuelabel)
  555. end
  556. else
  557. CGMessage(cg_e_continue_not_allowed);
  558. end;
  559. {*****************************************************************************
  560. SecondGoto
  561. *****************************************************************************}
  562. procedure ti386gotonode.pass_2;
  563. begin
  564. load_all_regvars(exprasmlist);
  565. emitjmp(C_None,labelnr);
  566. end;
  567. {*****************************************************************************
  568. SecondLabel
  569. *****************************************************************************}
  570. procedure ti386labelnode.pass_2;
  571. begin
  572. load_all_regvars(exprasmlist);
  573. emitlab(labelnr);
  574. cleartempgen;
  575. secondpass(left);
  576. end;
  577. {*****************************************************************************
  578. SecondRaise
  579. *****************************************************************************}
  580. procedure ti386raisenode.pass_2;
  581. var
  582. a : tasmlabel;
  583. begin
  584. if assigned(left) then
  585. begin
  586. { multiple parameters? }
  587. if assigned(right) then
  588. begin
  589. { push frame }
  590. if assigned(frametree) then
  591. begin
  592. secondpass(frametree);
  593. if codegenerror then
  594. exit;
  595. emit_push_loc(frametree.location);
  596. end
  597. else
  598. emit_const(A_PUSH,S_L,0);
  599. { push address }
  600. secondpass(right);
  601. if codegenerror then
  602. exit;
  603. emit_push_loc(right.location);
  604. end
  605. else
  606. begin
  607. getaddrlabel(a);
  608. emitlab(a);
  609. emit_reg(A_PUSH,S_L,R_EBP);
  610. emit_sym(A_PUSH,S_L,a);
  611. end;
  612. { push object }
  613. secondpass(left);
  614. if codegenerror then
  615. exit;
  616. emit_push_loc(left.location);
  617. emitcall('FPC_RAISEEXCEPTION');
  618. end
  619. else
  620. begin
  621. emitcall('FPC_POPADDRSTACK');
  622. emitcall('FPC_RERAISE');
  623. end;
  624. end;
  625. {*****************************************************************************
  626. SecondTryExcept
  627. *****************************************************************************}
  628. var
  629. endexceptlabel : tasmlabel;
  630. { does the necessary things to clean up the object stack }
  631. { in the except block }
  632. procedure cleanupobjectstack;
  633. begin
  634. emitcall('FPC_POPOBJECTSTACK');
  635. exprasmList.concat(Tairegalloc.Alloc(R_EAX));
  636. emit_reg(A_PUSH,S_L,R_EAX);
  637. emitcall('FPC_DESTROYEXCEPTION');
  638. exprasmList.concat(Tairegalloc.DeAlloc(R_EAX));
  639. maybe_loadself;
  640. end;
  641. { pops one element from the exception address stack }
  642. { and removes the flag }
  643. procedure cleanupaddrstack;
  644. begin
  645. emitcall('FPC_POPADDRSTACK');
  646. { allocate eax }
  647. exprasmList.concat(Tairegalloc.Alloc(R_EAX));
  648. emit_reg(A_POP,S_L,R_EAX);
  649. { deallocate eax }
  650. exprasmList.concat(Tairegalloc.DeAlloc(R_EAX));
  651. end;
  652. procedure ti386tryexceptnode.pass_2;
  653. var
  654. exceptlabel,doexceptlabel,oldendexceptlabel,
  655. lastonlabel,
  656. exitexceptlabel,
  657. continueexceptlabel,
  658. breakexceptlabel,
  659. exittrylabel,
  660. continuetrylabel,
  661. breaktrylabel,
  662. doobjectdestroy,
  663. doobjectdestroyandreraise,
  664. oldaktexitlabel,
  665. oldaktexit2label,
  666. oldaktcontinuelabel,
  667. oldaktbreaklabel : tasmlabel;
  668. oldflowcontrol,tryflowcontrol,
  669. exceptflowcontrol : tflowcontrol;
  670. tempbuf,tempaddr : treference;
  671. label
  672. errorexit;
  673. begin
  674. oldflowcontrol:=flowcontrol;
  675. flowcontrol:=[];
  676. { this can be called recursivly }
  677. oldendexceptlabel:=endexceptlabel;
  678. { we modify EAX }
  679. usedinproc:=usedinproc or ($80 shr byte(R_EAX));
  680. { save the old labels for control flow statements }
  681. oldaktexitlabel:=aktexitlabel;
  682. oldaktexit2label:=aktexit2label;
  683. if assigned(aktbreaklabel) then
  684. begin
  685. oldaktcontinuelabel:=aktcontinuelabel;
  686. oldaktbreaklabel:=aktbreaklabel;
  687. end;
  688. { get new labels for the control flow statements }
  689. getlabel(exittrylabel);
  690. getlabel(exitexceptlabel);
  691. if assigned(aktbreaklabel) then
  692. begin
  693. getlabel(breaktrylabel);
  694. getlabel(continuetrylabel);
  695. getlabel(breakexceptlabel);
  696. getlabel(continueexceptlabel);
  697. end;
  698. getlabel(exceptlabel);
  699. getlabel(doexceptlabel);
  700. getlabel(endexceptlabel);
  701. getlabel(lastonlabel);
  702. gettempofsizereferencepersistant(24,tempbuf);
  703. gettempofsizereferencepersistant(12,tempaddr);
  704. emitpushreferenceaddr(tempaddr);
  705. emitpushreferenceaddr(tempbuf);
  706. push_int (1); { push type of exceptionframe }
  707. emitcall('FPC_PUSHEXCEPTADDR');
  708. { allocate eax }
  709. exprasmList.concat(Tairegalloc.Alloc(R_EAX));
  710. emit_reg(A_PUSH,S_L,R_EAX);
  711. emitcall('FPC_SETJMP');
  712. emit_reg(A_PUSH,S_L,R_EAX);
  713. emit_reg_reg(A_TEST,S_L,R_EAX,R_EAX);
  714. { deallocate eax }
  715. exprasmList.concat(Tairegalloc.DeAlloc(R_EAX));
  716. emitjmp(C_NE,exceptlabel);
  717. { try block }
  718. { set control flow labels for the try block }
  719. aktexitlabel:=exittrylabel;
  720. aktexit2label:=exittrylabel;
  721. if assigned(oldaktbreaklabel) then
  722. begin
  723. aktcontinuelabel:=continuetrylabel;
  724. aktbreaklabel:=breaktrylabel;
  725. end;
  726. flowcontrol:=[];
  727. secondpass(left);
  728. tryflowcontrol:=flowcontrol;
  729. if codegenerror then
  730. goto errorexit;
  731. emitlab(exceptlabel);
  732. emitcall('FPC_POPADDRSTACK');
  733. ungetpersistanttempreference(tempaddr);
  734. ungetpersistanttempreference(tempbuf);
  735. exprasmList.concat(Tairegalloc.Alloc(R_EAX));
  736. emit_reg(A_POP,S_L,R_EAX);
  737. emit_reg_reg(A_TEST,S_L,R_EAX,R_EAX);
  738. exprasmList.concat(Tairegalloc.DeAlloc(R_EAX));
  739. emitjmp(C_E,endexceptlabel);
  740. emitlab(doexceptlabel);
  741. { set control flow labels for the except block }
  742. { and the on statements }
  743. aktexitlabel:=exitexceptlabel;
  744. aktexit2label:=exitexceptlabel;
  745. if assigned(oldaktbreaklabel) then
  746. begin
  747. aktcontinuelabel:=continueexceptlabel;
  748. aktbreaklabel:=breakexceptlabel;
  749. end;
  750. flowcontrol:=[];
  751. { on statements }
  752. if assigned(right) then
  753. secondpass(right);
  754. emitlab(lastonlabel);
  755. { default handling except handling }
  756. if assigned(t1) then
  757. begin
  758. { FPC_CATCHES must be called with
  759. 'default handler' flag (=-1)
  760. }
  761. push_int (-1);
  762. emitcall('FPC_CATCHES');
  763. maybe_loadself;
  764. { the destruction of the exception object must be also }
  765. { guarded by an exception frame }
  766. getlabel(doobjectdestroy);
  767. getlabel(doobjectdestroyandreraise);
  768. gettempofsizereferencepersistant(12,tempaddr);
  769. gettempofsizereferencepersistant(24,tempbuf);
  770. emitpushreferenceaddr(tempaddr);
  771. emitpushreferenceaddr(tempbuf);
  772. exprasmList.concat(Taicpu.Op_const(A_PUSH,S_L,1));
  773. emitcall('FPC_PUSHEXCEPTADDR');
  774. exprasmList.concat(Tairegalloc.Alloc(R_EAX));
  775. exprasmList.concat(Taicpu.op_reg(A_PUSH,S_L,R_EAX));
  776. exprasmList.concat(Tairegalloc.DeAlloc(R_EAX));
  777. emitcall('FPC_SETJMP');
  778. exprasmList.concat(Tairegalloc.Alloc(R_EAX));
  779. exprasmList.concat(Taicpu.op_reg(A_PUSH,S_L,R_EAX));
  780. exprasmList.concat(Taicpu.op_reg_reg(A_TEST,S_L,R_EAX,R_EAX));
  781. exprasmList.concat(Tairegalloc.DeAlloc(R_EAX));
  782. emitjmp(C_NE,doobjectdestroyandreraise);
  783. { here we don't have to reset flowcontrol }
  784. { the default and on flowcontrols are handled equal }
  785. secondpass(t1);
  786. exceptflowcontrol:=flowcontrol;
  787. emitlab(doobjectdestroyandreraise);
  788. emitcall('FPC_POPADDRSTACK');
  789. ungetpersistanttempreference(tempaddr);
  790. ungetpersistanttempreference(tempbuf);
  791. exprasmList.concat(Tairegalloc.Alloc(R_EAX));
  792. exprasmList.concat(Taicpu.op_reg(A_POP,S_L,R_EAX));
  793. exprasmList.concat(Taicpu.op_reg_reg(A_TEST,S_L,R_EAX,R_EAX));
  794. exprasmList.concat(Tairegalloc.DeAlloc(R_EAX));
  795. emitjmp(C_E,doobjectdestroy);
  796. emitcall('FPC_POPSECONDOBJECTSTACK');
  797. exprasmList.concat(Tairegalloc.Alloc(R_EAX));
  798. emit_reg(A_PUSH,S_L,R_EAX);
  799. emitcall('FPC_DESTROYEXCEPTION');
  800. exprasmList.concat(Tairegalloc.DeAlloc(R_EAX));
  801. { we don't need to restore esi here because reraise never }
  802. { returns }
  803. emitcall('FPC_RERAISE');
  804. emitlab(doobjectdestroy);
  805. cleanupobjectstack;
  806. emitjmp(C_None,endexceptlabel);
  807. end
  808. else
  809. begin
  810. emitcall('FPC_RERAISE');
  811. exceptflowcontrol:=flowcontrol;
  812. end;
  813. if fc_exit in exceptflowcontrol then
  814. begin
  815. { do some magic for exit in the try block }
  816. emitlab(exitexceptlabel);
  817. { we must also destroy the address frame which guards }
  818. { exception object }
  819. cleanupaddrstack;
  820. cleanupobjectstack;
  821. emitjmp(C_None,oldaktexitlabel);
  822. end;
  823. if fc_break in exceptflowcontrol then
  824. begin
  825. emitlab(breakexceptlabel);
  826. { we must also destroy the address frame which guards }
  827. { exception object }
  828. cleanupaddrstack;
  829. cleanupobjectstack;
  830. emitjmp(C_None,oldaktbreaklabel);
  831. end;
  832. if fc_continue in exceptflowcontrol then
  833. begin
  834. emitlab(continueexceptlabel);
  835. { we must also destroy the address frame which guards }
  836. { exception object }
  837. cleanupaddrstack;
  838. cleanupobjectstack;
  839. emitjmp(C_None,oldaktcontinuelabel);
  840. end;
  841. if fc_exit in tryflowcontrol then
  842. begin
  843. { do some magic for exit in the try block }
  844. emitlab(exittrylabel);
  845. cleanupaddrstack;
  846. emitjmp(C_None,oldaktexitlabel);
  847. end;
  848. if fc_break in tryflowcontrol then
  849. begin
  850. emitlab(breaktrylabel);
  851. cleanupaddrstack;
  852. emitjmp(C_None,oldaktbreaklabel);
  853. end;
  854. if fc_continue in tryflowcontrol then
  855. begin
  856. emitlab(continuetrylabel);
  857. cleanupaddrstack;
  858. emitjmp(C_None,oldaktcontinuelabel);
  859. end;
  860. emitlab(endexceptlabel);
  861. errorexit:
  862. { restore all saved labels }
  863. endexceptlabel:=oldendexceptlabel;
  864. { restore the control flow labels }
  865. aktexitlabel:=oldaktexitlabel;
  866. aktexit2label:=oldaktexit2label;
  867. if assigned(oldaktbreaklabel) then
  868. begin
  869. aktcontinuelabel:=oldaktcontinuelabel;
  870. aktbreaklabel:=oldaktbreaklabel;
  871. end;
  872. { return all used control flow statements }
  873. flowcontrol:=oldflowcontrol+exceptflowcontrol+
  874. tryflowcontrol;
  875. end;
  876. procedure ti386onnode.pass_2;
  877. var
  878. nextonlabel,
  879. exitonlabel,
  880. continueonlabel,
  881. breakonlabel,
  882. oldaktexitlabel,
  883. oldaktexit2label,
  884. oldaktcontinuelabel,
  885. doobjectdestroyandreraise,
  886. doobjectdestroy,
  887. oldaktbreaklabel : tasmlabel;
  888. ref : treference;
  889. oldflowcontrol : tflowcontrol;
  890. tempbuf,tempaddr : treference;
  891. begin
  892. oldflowcontrol:=flowcontrol;
  893. flowcontrol:=[];
  894. getlabel(nextonlabel);
  895. { push the vmt }
  896. emit_sym(A_PUSH,S_L,
  897. newasmsymbol(excepttype.vmt_mangledname));
  898. emitcall('FPC_CATCHES');
  899. { allocate eax }
  900. exprasmList.concat(Tairegalloc.Alloc(R_EAX));
  901. emit_reg_reg(A_TEST,S_L,R_EAX,R_EAX);
  902. emitjmp(C_E,nextonlabel);
  903. ref.symbol:=nil;
  904. gettempofsizereference(4,ref);
  905. { what a hack ! }
  906. if assigned(exceptsymtable) then
  907. tvarsym(exceptsymtable.symindex.first).address:=ref.offset;
  908. emit_reg_ref(A_MOV,S_L,
  909. R_EAX,newreference(ref));
  910. { deallocate eax }
  911. exprasmList.concat(Tairegalloc.DeAlloc(R_EAX));
  912. { in the case that another exception is risen }
  913. { we've to destroy the old one }
  914. getlabel(doobjectdestroyandreraise);
  915. gettempofsizereferencepersistant(12,tempaddr);
  916. gettempofsizereferencepersistant(24,tempbuf);
  917. emitpushreferenceaddr(tempaddr);
  918. emitpushreferenceaddr(tempbuf);
  919. exprasmList.concat(Taicpu.Op_const(A_PUSH,S_L,1));
  920. emitcall('FPC_PUSHEXCEPTADDR');
  921. exprasmList.concat(Tairegalloc.Alloc(R_EAX));
  922. exprasmList.concat(Taicpu.op_reg(A_PUSH,S_L,R_EAX));
  923. exprasmList.concat(Tairegalloc.DeAlloc(R_EAX));
  924. emitcall('FPC_SETJMP');
  925. exprasmList.concat(Tairegalloc.Alloc(R_EAX));
  926. exprasmList.concat(Taicpu.op_reg(A_PUSH,S_L,R_EAX));
  927. exprasmList.concat(Taicpu.op_reg_reg(A_TEST,S_L,R_EAX,R_EAX));
  928. exprasmList.concat(Tairegalloc.DeAlloc(R_EAX));
  929. emitjmp(C_NE,doobjectdestroyandreraise);
  930. if assigned(right) then
  931. begin
  932. oldaktexitlabel:=aktexitlabel;
  933. oldaktexit2label:=aktexit2label;
  934. getlabel(exitonlabel);
  935. aktexitlabel:=exitonlabel;
  936. aktexit2label:=exitonlabel;
  937. if assigned(aktbreaklabel) then
  938. begin
  939. oldaktcontinuelabel:=aktcontinuelabel;
  940. oldaktbreaklabel:=aktbreaklabel;
  941. getlabel(breakonlabel);
  942. getlabel(continueonlabel);
  943. aktcontinuelabel:=continueonlabel;
  944. aktbreaklabel:=breakonlabel;
  945. end;
  946. { esi is destroyed by FPC_CATCHES }
  947. maybe_loadself;
  948. secondpass(right);
  949. end;
  950. getlabel(doobjectdestroy);
  951. emitlab(doobjectdestroyandreraise);
  952. emitcall('FPC_POPADDRSTACK');
  953. ungetpersistanttempreference(tempaddr);
  954. ungetpersistanttempreference(tempbuf);
  955. exprasmList.concat(Tairegalloc.Alloc(R_EAX));
  956. exprasmList.concat(Taicpu.op_reg(A_POP,S_L,R_EAX));
  957. exprasmList.concat(Taicpu.op_reg_reg(A_TEST,S_L,R_EAX,R_EAX));
  958. exprasmList.concat(Tairegalloc.DeAlloc(R_EAX));
  959. emitjmp(C_E,doobjectdestroy);
  960. emitcall('FPC_POPSECONDOBJECTSTACK');
  961. exprasmList.concat(Tairegalloc.Alloc(R_EAX));
  962. emit_reg(A_PUSH,S_L,R_EAX);
  963. emitcall('FPC_DESTROYEXCEPTION');
  964. exprasmList.concat(Tairegalloc.DeAlloc(R_EAX));
  965. { we don't need to restore esi here because reraise never }
  966. { returns }
  967. emitcall('FPC_RERAISE');
  968. emitlab(doobjectdestroy);
  969. cleanupobjectstack;
  970. { clear some stuff }
  971. ungetiftemp(ref);
  972. emitjmp(C_None,endexceptlabel);
  973. if assigned(right) then
  974. begin
  975. { special handling for control flow instructions }
  976. if fc_exit in flowcontrol then
  977. begin
  978. { the address and object pop does secondtryexcept }
  979. emitlab(exitonlabel);
  980. emitjmp(C_None,oldaktexitlabel);
  981. end;
  982. if fc_break in flowcontrol then
  983. begin
  984. { the address and object pop does secondtryexcept }
  985. emitlab(breakonlabel);
  986. emitjmp(C_None,oldaktbreaklabel);
  987. end;
  988. if fc_continue in flowcontrol then
  989. begin
  990. { the address and object pop does secondtryexcept }
  991. emitlab(continueonlabel);
  992. emitjmp(C_None,oldaktcontinuelabel);
  993. end;
  994. aktexitlabel:=oldaktexitlabel;
  995. aktexit2label:=oldaktexit2label;
  996. if assigned(oldaktbreaklabel) then
  997. begin
  998. aktcontinuelabel:=oldaktcontinuelabel;
  999. aktbreaklabel:=oldaktbreaklabel;
  1000. end;
  1001. end;
  1002. emitlab(nextonlabel);
  1003. flowcontrol:=oldflowcontrol+flowcontrol;
  1004. { next on node }
  1005. if assigned(left) then
  1006. begin
  1007. cleartempgen;
  1008. secondpass(left);
  1009. end;
  1010. end;
  1011. {*****************************************************************************
  1012. SecondTryFinally
  1013. *****************************************************************************}
  1014. procedure ti386tryfinallynode.pass_2;
  1015. var
  1016. reraiselabel,
  1017. finallylabel,
  1018. endfinallylabel,
  1019. exitfinallylabel,
  1020. continuefinallylabel,
  1021. breakfinallylabel,
  1022. oldaktexitlabel,
  1023. oldaktexit2label,
  1024. oldaktcontinuelabel,
  1025. oldaktbreaklabel : tasmlabel;
  1026. oldflowcontrol,tryflowcontrol : tflowcontrol;
  1027. decconst : longint;
  1028. tempbuf,tempaddr : treference;
  1029. begin
  1030. { check if child nodes do a break/continue/exit }
  1031. oldflowcontrol:=flowcontrol;
  1032. flowcontrol:=[];
  1033. { we modify EAX }
  1034. usedinproc:=usedinproc or ($80 shr byte(R_EAX));
  1035. getlabel(finallylabel);
  1036. getlabel(endfinallylabel);
  1037. getlabel(reraiselabel);
  1038. { the finally block must catch break, continue and exit }
  1039. { statements }
  1040. oldaktexitlabel:=aktexitlabel;
  1041. oldaktexit2label:=aktexit2label;
  1042. getlabel(exitfinallylabel);
  1043. aktexitlabel:=exitfinallylabel;
  1044. aktexit2label:=exitfinallylabel;
  1045. if assigned(aktbreaklabel) then
  1046. begin
  1047. oldaktcontinuelabel:=aktcontinuelabel;
  1048. oldaktbreaklabel:=aktbreaklabel;
  1049. getlabel(breakfinallylabel);
  1050. getlabel(continuefinallylabel);
  1051. aktcontinuelabel:=continuefinallylabel;
  1052. aktbreaklabel:=breakfinallylabel;
  1053. end;
  1054. gettempofsizereferencepersistant(12,tempaddr);
  1055. gettempofsizereferencepersistant(24,tempbuf);
  1056. emitpushreferenceaddr(tempaddr);
  1057. emitpushreferenceaddr(tempbuf);
  1058. push_int(1); { Type of stack-frame must be pushed}
  1059. emitcall('FPC_PUSHEXCEPTADDR');
  1060. { allocate eax }
  1061. exprasmList.concat(Tairegalloc.Alloc(R_EAX));
  1062. emit_reg(A_PUSH,S_L,R_EAX);
  1063. emitcall('FPC_SETJMP');
  1064. emit_reg(A_PUSH,S_L,R_EAX);
  1065. emit_reg_reg(A_TEST,S_L,R_EAX,R_EAX);
  1066. { deallocate eax }
  1067. exprasmList.concat(Tairegalloc.DeAlloc(R_EAX));
  1068. emitjmp(C_NE,finallylabel);
  1069. { try code }
  1070. if assigned(left) then
  1071. begin
  1072. secondpass(left);
  1073. tryflowcontrol:=flowcontrol;
  1074. if codegenerror then
  1075. exit;
  1076. end;
  1077. emitlab(finallylabel);
  1078. emitcall('FPC_POPADDRSTACK');
  1079. ungetpersistanttempreference(tempaddr);
  1080. ungetpersistanttempreference(tempbuf);
  1081. { finally code }
  1082. flowcontrol:=[];
  1083. secondpass(right);
  1084. if flowcontrol<>[] then
  1085. CGMessage(cg_e_control_flow_outside_finally);
  1086. if codegenerror then
  1087. exit;
  1088. { allocate eax }
  1089. exprasmList.concat(Tairegalloc.Alloc(R_EAX));
  1090. emit_reg(A_POP,S_L,R_EAX);
  1091. emit_reg_reg(A_TEST,S_L,R_EAX,R_EAX);
  1092. emitjmp(C_E,endfinallylabel);
  1093. emit_reg(A_DEC,S_L,R_EAX);
  1094. emitjmp(C_Z,reraiselabel);
  1095. if fc_exit in tryflowcontrol then
  1096. begin
  1097. emit_reg(A_DEC,S_L,R_EAX);
  1098. emitjmp(C_Z,oldaktexitlabel);
  1099. decconst:=1;
  1100. end
  1101. else
  1102. decconst:=2;
  1103. if fc_break in tryflowcontrol then
  1104. begin
  1105. emit_const_reg(A_SUB,S_L,decconst,R_EAX);
  1106. emitjmp(C_Z,oldaktbreaklabel);
  1107. decconst:=1;
  1108. end
  1109. else
  1110. inc(decconst);
  1111. if fc_continue in tryflowcontrol then
  1112. begin
  1113. emit_const_reg(A_SUB,S_L,decconst,R_EAX);
  1114. emitjmp(C_Z,oldaktcontinuelabel);
  1115. end;
  1116. { deallocate eax }
  1117. exprasmList.concat(Tairegalloc.DeAlloc(R_EAX));
  1118. emitlab(reraiselabel);
  1119. emitcall('FPC_RERAISE');
  1120. { do some magic for exit,break,continue in the try block }
  1121. if fc_exit in tryflowcontrol then
  1122. begin
  1123. emitlab(exitfinallylabel);
  1124. { allocate eax }
  1125. exprasmList.concat(Tairegalloc.Alloc(R_EAX));
  1126. emit_reg(A_POP,S_L,R_EAX);
  1127. exprasmList.concat(Tairegalloc.Alloc(R_EAX));
  1128. emit_const(A_PUSH,S_L,2);
  1129. emitjmp(C_NONE,finallylabel);
  1130. end;
  1131. if fc_break in tryflowcontrol then
  1132. begin
  1133. emitlab(breakfinallylabel);
  1134. { allocate eax }
  1135. exprasmList.concat(Tairegalloc.Alloc(R_EAX));
  1136. emit_reg(A_POP,S_L,R_EAX);
  1137. { deallocate eax }
  1138. exprasmList.concat(Tairegalloc.DeAlloc(R_EAX));
  1139. emit_const(A_PUSH,S_L,3);
  1140. emitjmp(C_NONE,finallylabel);
  1141. end;
  1142. if fc_continue in tryflowcontrol then
  1143. begin
  1144. emitlab(continuefinallylabel);
  1145. exprasmList.concat(Tairegalloc.Alloc(R_EAX));
  1146. emit_reg(A_POP,S_L,R_EAX);
  1147. exprasmList.concat(Tairegalloc.Alloc(R_EAX));
  1148. emit_const(A_PUSH,S_L,4);
  1149. emitjmp(C_NONE,finallylabel);
  1150. end;
  1151. emitlab(endfinallylabel);
  1152. aktexitlabel:=oldaktexitlabel;
  1153. aktexit2label:=oldaktexit2label;
  1154. if assigned(aktbreaklabel) then
  1155. begin
  1156. aktcontinuelabel:=oldaktcontinuelabel;
  1157. aktbreaklabel:=oldaktbreaklabel;
  1158. end;
  1159. flowcontrol:=oldflowcontrol+tryflowcontrol;
  1160. end;
  1161. {*****************************************************************************
  1162. SecondFail
  1163. *****************************************************************************}
  1164. procedure ti386failnode.pass_2;
  1165. begin
  1166. emitjmp(C_None,faillabel);
  1167. end;
  1168. begin
  1169. cwhilerepeatnode:=ti386whilerepeatnode;
  1170. cifnode:=ti386ifnode;
  1171. cfornode:=ti386fornode;
  1172. cexitnode:=ti386exitnode;
  1173. cbreaknode:=ti386breaknode;
  1174. ccontinuenode:=ti386continuenode;
  1175. cgotonode:=ti386gotonode;
  1176. clabelnode:=ti386labelnode;
  1177. craisenode:=ti386raisenode;
  1178. ctryexceptnode:=ti386tryexceptnode;
  1179. ctryfinallynode:=ti386tryfinallynode;
  1180. connode:=ti386onnode;
  1181. cfailnode:=ti386failnode;
  1182. end.
  1183. {
  1184. $Log$
  1185. Revision 1.13 2001-07-01 20:16:20 peter
  1186. * alignmentinfo record added
  1187. * -Oa argument supports more alignment settings that can be specified
  1188. per type: PROC,LOOP,VARMIN,VARMAX,CONSTMIN,CONSTMAX,RECORDMIN
  1189. RECORDMAX,LOCALMIN,LOCALMAX. It is possible to set the mimimum
  1190. required alignment and the maximum usefull alignment. The final
  1191. alignment will be choosen per variable size dependent on these
  1192. settings
  1193. Revision 1.12 2001/04/15 09:48:31 peter
  1194. * fixed crash in labelnode
  1195. * easier detection of goto and label in try blocks
  1196. Revision 1.11 2001/04/14 14:07:11 peter
  1197. * moved more code from pass_1 to det_resulttype
  1198. Revision 1.10 2001/04/13 01:22:19 peter
  1199. * symtable change to classes
  1200. * range check generation and errors fixed, make cycle DEBUG=1 works
  1201. * memory leaks fixed
  1202. Revision 1.9 2001/04/02 21:20:37 peter
  1203. * resulttype rewrite
  1204. Revision 1.8 2001/01/27 21:29:35 florian
  1205. * behavior -Oa optimized
  1206. Revision 1.7 2001/01/06 23:35:05 jonas
  1207. * fixed webbug 1323
  1208. Revision 1.6 2001/01/05 17:36:58 florian
  1209. * the info about exception frames is stored now on the stack
  1210. instead on the heap
  1211. Revision 1.5 2000/12/25 00:07:32 peter
  1212. + new tlinkedlist class (merge of old tstringqueue,tcontainer and
  1213. tlinkedlist objects)
  1214. Revision 1.4 2000/12/05 11:44:33 jonas
  1215. + new integer regvar handling, should be much more efficient
  1216. Revision 1.3 2000/11/29 00:30:47 florian
  1217. * unused units removed from uses clause
  1218. * some changes for widestrings
  1219. Revision 1.2 2000/10/31 22:02:56 peter
  1220. * symtable splitted, no real code changes
  1221. Revision 1.1 2000/10/15 09:33:31 peter
  1222. * moved n386*.pas to i386/ cpu_target dir
  1223. Revision 1.1 2000/10/14 10:14:48 peter
  1224. * moehrendorf oct 2000 rewrite
  1225. }