ncgflw.pas 65 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 by Florian Klaempfl
  4. Generate assembler for nodes that influence the flow which are
  5. the same for all (most?) processors
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2 of the License, or
  9. (at your option) any later version.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with this program; if not, write to the Free Software
  16. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. ****************************************************************************
  18. }
  19. unit ncgflw;
  20. {$i fpcdefs.inc}
  21. interface
  22. uses
  23. node,nflw;
  24. type
  25. tcgwhilerepeatnode = class(twhilerepeatnode)
  26. procedure pass_2;override;
  27. end;
  28. tcgifnode = class(tifnode)
  29. procedure pass_2;override;
  30. end;
  31. tcgfornode = class(tfornode)
  32. procedure pass_2;override;
  33. end;
  34. tcgexitnode = class(texitnode)
  35. procedure pass_2;override;
  36. end;
  37. tcgbreaknode = class(tbreaknode)
  38. procedure pass_2;override;
  39. end;
  40. tcgcontinuenode = class(tcontinuenode)
  41. procedure pass_2;override;
  42. end;
  43. tcggotonode = class(tgotonode)
  44. procedure pass_2;override;
  45. end;
  46. tcglabelnode = class(tlabelnode)
  47. procedure pass_2;override;
  48. end;
  49. tcgraisenode = class(traisenode)
  50. procedure pass_2;override;
  51. end;
  52. tcgtryexceptnode = class(ttryexceptnode)
  53. procedure pass_2;override;
  54. end;
  55. tcgtryfinallynode = class(ttryfinallynode)
  56. procedure pass_2;override;
  57. end;
  58. tcgonnode = class(tonnode)
  59. procedure pass_2;override;
  60. end;
  61. implementation
  62. uses
  63. verbose,globals,systems,globtype,
  64. symconst,symdef,symsym,aasmbase,aasmtai,aasmcpu,defutil,
  65. procinfo,cgbase,pass_2,
  66. cpubase,cpuinfo,
  67. nld,ncon,
  68. ncgutil,
  69. tgobj,paramgr,
  70. regvars,
  71. cgutils,cgobj
  72. {$ifndef cpu64bit}
  73. ,cg64f32
  74. {$endif cpu64bit}
  75. ;
  76. {*****************************************************************************
  77. Second_While_RepeatN
  78. *****************************************************************************}
  79. procedure tcgwhilerepeatnode.pass_2;
  80. var
  81. lcont,lbreak,lloop,
  82. oldclabel,oldblabel : tasmlabel;
  83. otlabel,oflabel : tasmlabel;
  84. oldflowcontrol : tflowcontrol;
  85. begin
  86. location_reset(location,LOC_VOID,OS_NO);
  87. objectlibrary.getlabel(lloop);
  88. objectlibrary.getlabel(lcont);
  89. objectlibrary.getlabel(lbreak);
  90. { arrange continue and breaklabels: }
  91. oldflowcontrol:=flowcontrol;
  92. oldclabel:=aktcontinuelabel;
  93. oldblabel:=aktbreaklabel;
  94. {$ifdef OLDREGVARS}
  95. load_all_regvars(exprasmlist);
  96. {$endif OLDREGVARS}
  97. { handling code at the end as it is much more efficient, and makes
  98. while equal to repeat loop, only the end true/false is swapped (PFV) }
  99. if lnf_testatbegin in loopflags then
  100. cg.a_jmp_always(exprasmlist,lcont);
  101. if not(cs_littlesize in aktglobalswitches) then
  102. { align loop target }
  103. exprasmList.concat(Tai_align.Create(aktalignment.loopalign));
  104. cg.a_label(exprasmlist,lloop);
  105. aktcontinuelabel:=lcont;
  106. aktbreaklabel:=lbreak;
  107. if assigned(right) then
  108. secondpass(right);
  109. {$ifdef OLDREGVARS}
  110. load_all_regvars(exprasmlist);
  111. {$endif OLDREGVARS}
  112. cg.a_label(exprasmlist,lcont);
  113. otlabel:=truelabel;
  114. oflabel:=falselabel;
  115. if lnf_checknegate in loopflags then
  116. begin
  117. truelabel:=lbreak;
  118. falselabel:=lloop;
  119. end
  120. else
  121. begin
  122. truelabel:=lloop;
  123. falselabel:=lbreak;
  124. end;
  125. secondpass(left);
  126. maketojumpbool(exprasmlist,left,lr_load_regvars);
  127. cg.a_label(exprasmlist,lbreak);
  128. truelabel:=otlabel;
  129. falselabel:=oflabel;
  130. aktcontinuelabel:=oldclabel;
  131. aktbreaklabel:=oldblabel;
  132. { a break/continue in a while/repeat block can't be seen outside }
  133. flowcontrol:=oldflowcontrol+(flowcontrol-[fc_break,fc_continue]);
  134. end;
  135. {*****************************************************************************
  136. tcgIFNODE
  137. *****************************************************************************}
  138. procedure tcgifnode.pass_2;
  139. var
  140. hl,otlabel,oflabel : tasmlabel;
  141. (*
  142. org_regvar_loaded_other,
  143. then_regvar_loaded_other,
  144. else_regvar_loaded_other : regvarother_booleanarray;
  145. org_regvar_loaded_int,
  146. then_regvar_loaded_int,
  147. else_regvar_loaded_int : Tsuperregisterset;
  148. org_list,
  149. then_list,
  150. else_list : taasmoutput;
  151. *)
  152. begin
  153. location_reset(location,LOC_VOID,OS_NO);
  154. otlabel:=truelabel;
  155. oflabel:=falselabel;
  156. objectlibrary.getlabel(truelabel);
  157. objectlibrary.getlabel(falselabel);
  158. secondpass(left);
  159. (*
  160. { save regvars loaded in the beginning so that we can restore them }
  161. { when processing the else-block }
  162. if cs_regvars in aktglobalswitches then
  163. begin
  164. org_list := exprasmlist;
  165. exprasmlist := taasmoutput.create;
  166. end;
  167. *)
  168. maketojumpbool(exprasmlist,left,lr_dont_load_regvars);
  169. (*
  170. if cs_regvars in aktglobalswitches then
  171. begin
  172. org_regvar_loaded_int := rg.regvar_loaded_int;
  173. org_regvar_loaded_other := rg.regvar_loaded_other;
  174. end;
  175. *)
  176. if assigned(right) then
  177. begin
  178. cg.a_label(exprasmlist,truelabel);
  179. secondpass(right);
  180. end;
  181. { save current asmlist (previous instructions + then-block) and }
  182. { loaded regvar state and create new clean ones }
  183. if cs_regvars in aktglobalswitches then
  184. begin
  185. { then_regvar_loaded_int := rg.regvar_loaded_int;
  186. then_regvar_loaded_other := rg.regvar_loaded_other;
  187. rg.regvar_loaded_int := org_regvar_loaded_int;
  188. rg.regvar_loaded_other := org_regvar_loaded_other;
  189. then_list := exprasmlist;
  190. exprasmlist := taasmoutput.create;}
  191. end;
  192. if assigned(t1) then
  193. begin
  194. if assigned(right) then
  195. begin
  196. objectlibrary.getlabel(hl);
  197. { do go back to if line !! }
  198. (*
  199. if not(cs_regvars in aktglobalswitches) then
  200. *)
  201. aktfilepos:=exprasmList.getlasttaifilepos^
  202. (*
  203. else
  204. aktfilepos:=then_list.getlasttaifilepos^
  205. *)
  206. ;
  207. cg.a_jmp_always(exprasmlist,hl);
  208. end;
  209. cg.a_label(exprasmlist,falselabel);
  210. secondpass(t1);
  211. (*
  212. { save current asmlist (previous instructions + else-block) }
  213. { and loaded regvar state and create a new clean list }
  214. if cs_regvars in aktglobalswitches then
  215. begin
  216. { else_regvar_loaded_int := rg.regvar_loaded_int;
  217. else_regvar_loaded_other := rg.regvar_loaded_other;}
  218. else_list := exprasmlist;
  219. exprasmlist := taasmoutput.create;
  220. end;
  221. *)
  222. if assigned(right) then
  223. cg.a_label(exprasmlist,hl);
  224. end
  225. else
  226. begin
  227. (*
  228. if cs_regvars in aktglobalswitches then
  229. begin
  230. { else_regvar_loaded_int := rg.regvar_loaded_int;
  231. else_regvar_loaded_other := rg.regvar_loaded_other;}
  232. else_list := exprasmlist;
  233. exprasmlist := taasmoutput.create;
  234. end;
  235. *)
  236. cg.a_label(exprasmlist,falselabel);
  237. end;
  238. if not(assigned(right)) then
  239. begin
  240. cg.a_label(exprasmlist,truelabel);
  241. end;
  242. (*
  243. if cs_regvars in aktglobalswitches then
  244. begin
  245. { add loads of regvars at the end of the then- and else-blocks }
  246. { so that at the end of both blocks the same regvars are loaded }
  247. { no else block? }
  248. if not assigned(t1) then
  249. begin
  250. sync_regvars_int(org_list,then_list,org_regvar_loaded_int,then_regvar_loaded_int);
  251. sync_regvars_other(org_list,then_list,org_regvar_loaded_other,then_regvar_loaded_other);
  252. end
  253. { no then block? }
  254. else if not assigned(right) then
  255. begin
  256. sync_regvars_int(org_list,else_list,org_regvar_loaded_int,else_regvar_loaded_int);
  257. sync_regvars_other(org_list,else_list,org_regvar_loaded_other,else_regvar_loaded_other);
  258. end
  259. { both else and then blocks }
  260. else
  261. begin
  262. sync_regvars_int(then_list,else_list,then_regvar_loaded_int,else_regvar_loaded_int);
  263. sync_regvars_other(then_list,else_list,then_regvar_loaded_other,else_regvar_loaded_other);
  264. end;
  265. { add all lists together }
  266. org_list.concatlist(then_list);
  267. then_list.free;
  268. org_list.concatlist(else_list);
  269. else_list.free;
  270. org_list.concatlist(exprasmlist);
  271. exprasmlist.free;
  272. exprasmlist := org_list;
  273. end;
  274. *)
  275. truelabel:=otlabel;
  276. falselabel:=oflabel;
  277. end;
  278. {*****************************************************************************
  279. SecondFor
  280. *****************************************************************************}
  281. procedure tcgfornode.pass_2;
  282. var
  283. l3,oldclabel,oldblabel : tasmlabel;
  284. temptovalue : boolean;
  285. hs : byte;
  286. temp1 : treference;
  287. hop : topcg;
  288. hcond : topcmp;
  289. opsize : tcgsize;
  290. count_var_is_signed,do_loopvar_at_end : boolean;
  291. cmp_const:Tconstexprint;
  292. oldflowcontrol : tflowcontrol;
  293. begin
  294. location_reset(location,LOC_VOID,OS_NO);
  295. oldflowcontrol:=flowcontrol;
  296. oldclabel:=aktcontinuelabel;
  297. oldblabel:=aktbreaklabel;
  298. objectlibrary.getlabel(aktcontinuelabel);
  299. objectlibrary.getlabel(aktbreaklabel);
  300. objectlibrary.getlabel(l3);
  301. { only calculate reference }
  302. secondpass(t2);
  303. hs := t2.resulttype.def.size;
  304. opsize := def_cgsize(t2.resulttype.def);
  305. { first set the to value
  306. because the count var can be in the expression !! }
  307. do_loopvar_at_end:=lnf_dont_mind_loopvar_on_exit in loopflags;
  308. secondpass(right);
  309. { calculate pointer value and check if changeable and if so }
  310. { load into temporary variable }
  311. if right.nodetype<>ordconstn then
  312. begin
  313. do_loopvar_at_end:=false;
  314. tg.GetTemp(exprasmlist,hs,tt_normal,temp1);
  315. temptovalue:=true;
  316. if (right.location.loc=LOC_REGISTER) or
  317. (right.location.loc=LOC_CREGISTER) then
  318. begin
  319. cg.a_load_reg_ref(exprasmlist,opsize,opsize,right.location.register,temp1);
  320. cg.ungetregister(exprasmlist,right.location.register);
  321. end
  322. else
  323. cg.g_concatcopy(exprasmlist,right.location.reference,temp1,
  324. hs,true,false);
  325. end
  326. else
  327. temptovalue:=false;
  328. { produce start assignment }
  329. secondpass(left);
  330. count_var_is_signed:=is_signed(t2.resulttype.def);
  331. if lnf_backward in loopflags then
  332. if count_var_is_signed then
  333. hcond:=OC_LT
  334. else
  335. hcond:=OC_B
  336. else
  337. if count_var_is_signed then
  338. hcond:=OC_GT
  339. else
  340. hcond:=OC_A;
  341. {$ifdef OLDREGVARS}
  342. load_all_regvars(exprasmlist);
  343. {$endif OLDREGVARS}
  344. if temptovalue then
  345. begin
  346. cg.a_cmp_ref_loc_label(exprasmlist,opsize,hcond,
  347. temp1,t2.location,aktbreaklabel);
  348. end
  349. else
  350. begin
  351. if lnf_testatbegin in loopflags then
  352. begin
  353. cg.a_cmp_const_loc_label(exprasmlist,opsize,hcond,
  354. aword(tordconstnode(right).value),
  355. t2.location,aktbreaklabel);
  356. end;
  357. end;
  358. {If the loopvar doesn't mind on exit, we avoid this ugly
  359. dec instruction and do the loopvar inc/dec after the loop
  360. body.}
  361. if not do_loopvar_at_end then
  362. begin
  363. if lnf_backward in loopflags then
  364. hop:=OP_ADD
  365. else
  366. hop:=OP_SUB;
  367. cg.a_op_const_loc(exprasmlist,hop,1,t2.location);
  368. end;
  369. if not(cs_littlesize in aktglobalswitches) then
  370. { align loop target }
  371. exprasmList.concat(Tai_align.Create(aktalignment.loopalign));
  372. cg.a_label(exprasmlist,l3);
  373. {If the loopvar doesn't mind on exit, we avoid the loopvar inc/dec
  374. after the loop body instead of here.}
  375. if not do_loopvar_at_end then
  376. begin
  377. { according to count direction DEC or INC... }
  378. if lnf_backward in loopflags then
  379. hop:=OP_SUB
  380. else
  381. hop:=OP_ADD;
  382. cg.a_op_const_loc(exprasmlist,hop,1,t2.location);
  383. end;
  384. { help register must not be in instruction block }
  385. if assigned(t1) then
  386. begin
  387. secondpass(t1);
  388. {$ifdef OLDREGVARS}
  389. load_all_regvars(exprasmlist);
  390. {$endif OLDREGVARS}
  391. end;
  392. {If the loopvar doesn't mind on exit, we do the loopvar inc/dec
  393. after the loop body instead of here.}
  394. if do_loopvar_at_end then
  395. begin
  396. { according to count direction DEC or INC... }
  397. if lnf_backward in loopflags then
  398. hop:=OP_SUB
  399. else
  400. hop:=OP_ADD;
  401. cg.a_op_const_loc(exprasmlist,hop,1,t2.location);
  402. end;
  403. cg.a_label(exprasmlist,aktcontinuelabel);
  404. if do_loopvar_at_end then
  405. if lnf_backward in loopflags then
  406. if count_var_is_signed then
  407. hcond:=OC_GTE
  408. else
  409. hcond:=OC_AE
  410. else
  411. if count_var_is_signed then
  412. hcond:=OC_LTE
  413. else
  414. hcond:=OC_BE
  415. else
  416. if lnf_backward in loopflags then
  417. if count_var_is_signed then
  418. hcond:=OC_GT
  419. else
  420. hcond:=OC_A
  421. else
  422. if count_var_is_signed then
  423. hcond:=OC_LT
  424. else
  425. hcond:=OC_B;
  426. {$ifdef OLDREGVARS}
  427. load_all_regvars(exprasmlist);
  428. {$endif OLDREGVARS}
  429. { produce comparison and the corresponding }
  430. { jump }
  431. if temptovalue then
  432. begin
  433. cg.a_cmp_ref_loc_label(exprasmlist,opsize,hcond,temp1,
  434. t2.location,l3);
  435. tg.ungetiftemp(exprasmlist,temp1);
  436. end
  437. else
  438. begin
  439. cmp_const:=Tordconstnode(right).value;
  440. if do_loopvar_at_end then
  441. begin
  442. {Watch out for wrap around 255 -> 0.}
  443. {Ugly: This code is way to long... Use tables?}
  444. case opsize of
  445. OS_8:
  446. begin
  447. if lnf_backward in loopflags then
  448. begin
  449. if byte(cmp_const)=low(byte) then
  450. begin
  451. hcond:=OC_NE;
  452. cmp_const:=high(byte);
  453. end
  454. end
  455. else
  456. begin
  457. if byte(cmp_const)=high(byte) then
  458. begin
  459. hcond:=OC_NE;
  460. cmp_const:=low(byte);
  461. end
  462. end
  463. end;
  464. OS_16:
  465. begin
  466. if lnf_backward in loopflags then
  467. begin
  468. if word(cmp_const)=high(word) then
  469. begin
  470. hcond:=OC_NE;
  471. cmp_const:=low(word);
  472. end
  473. end
  474. else
  475. begin
  476. if word(cmp_const)=low(word) then
  477. begin
  478. hcond:=OC_NE;
  479. cmp_const:=high(word);
  480. end
  481. end
  482. end;
  483. OS_32:
  484. begin
  485. if lnf_backward in loopflags then
  486. begin
  487. if cardinal(cmp_const)=high(cardinal) then
  488. begin
  489. hcond:=OC_NE;
  490. cmp_const:=low(cardinal);
  491. end
  492. end
  493. else
  494. begin
  495. if cardinal(cmp_const)=low(cardinal) then
  496. begin
  497. hcond:=OC_NE;
  498. cmp_const:=high(cardinal);
  499. end
  500. end
  501. end;
  502. OS_64:
  503. begin
  504. if lnf_backward in loopflags then
  505. begin
  506. if qword(cmp_const)=high(qword) then
  507. begin
  508. hcond:=OC_NE;
  509. cmp_const:=low(qword);
  510. end
  511. end
  512. else
  513. begin
  514. if qword(cmp_const)=low(qword) then
  515. begin
  516. hcond:=OC_NE;
  517. cmp_const:=high(qword);
  518. end
  519. end
  520. end;
  521. OS_S8:
  522. begin
  523. if lnf_backward in loopflags then
  524. begin
  525. if shortint(cmp_const)=low(shortint) then
  526. begin
  527. hcond:=OC_NE;
  528. cmp_const:=high(shortint);
  529. end
  530. end
  531. else
  532. begin
  533. if shortint(cmp_const)=high(shortint) then
  534. begin
  535. hcond:=OC_NE;
  536. cmp_const:=low(shortint);
  537. end
  538. end
  539. end;
  540. OS_S16:
  541. begin
  542. if lnf_backward in loopflags then
  543. begin
  544. if integer(cmp_const)=high(integer) then
  545. begin
  546. hcond:=OC_NE;
  547. cmp_const:=low(integer);
  548. end
  549. end
  550. else
  551. begin
  552. if integer(cmp_const)=low(integer) then
  553. begin
  554. hcond:=OC_NE;
  555. cmp_const:=high(integer);
  556. end
  557. end
  558. end;
  559. OS_S32:
  560. begin
  561. if lnf_backward in loopflags then
  562. begin
  563. if longint(cmp_const)=high(longint) then
  564. begin
  565. hcond:=OC_NE;
  566. cmp_const:=low(longint);
  567. end
  568. end
  569. else
  570. begin
  571. if longint(cmp_const)=low(longint) then
  572. begin
  573. hcond:=OC_NE;
  574. cmp_const:=high(longint);
  575. end
  576. end
  577. end;
  578. OS_S64:
  579. begin
  580. if lnf_backward in loopflags then
  581. begin
  582. if int64(cmp_const)=high(int64) then
  583. begin
  584. hcond:=OC_NE;
  585. cmp_const:=low(int64);
  586. end
  587. end
  588. else
  589. begin
  590. if int64(cmp_const)=low(int64) then
  591. begin
  592. hcond:=OC_NE;
  593. cmp_const:=high(int64);
  594. end
  595. end
  596. end;
  597. else
  598. internalerror(200201021);
  599. end;
  600. end;
  601. cg.a_cmp_const_loc_label(exprasmlist,opsize,hcond,
  602. cmp_const,t2.location,l3);
  603. end;
  604. { this is the break label: }
  605. cg.a_label(exprasmlist,aktbreaklabel);
  606. aktcontinuelabel:=oldclabel;
  607. aktbreaklabel:=oldblabel;
  608. { a break/continue in a while/repeat block can't be seen outside }
  609. flowcontrol:=oldflowcontrol+(flowcontrol-[fc_break,fc_continue]);
  610. end;
  611. {*****************************************************************************
  612. SecondExitN
  613. *****************************************************************************}
  614. procedure tcgexitnode.pass_2;
  615. begin
  616. location_reset(location,LOC_VOID,OS_NO);
  617. include(flowcontrol,fc_exit);
  618. if assigned(left) then
  619. secondpass(left);
  620. cg.a_jmp_always(exprasmlist,current_procinfo.aktexitlabel);
  621. end;
  622. {*****************************************************************************
  623. SecondBreakN
  624. *****************************************************************************}
  625. procedure tcgbreaknode.pass_2;
  626. begin
  627. location_reset(location,LOC_VOID,OS_NO);
  628. include(flowcontrol,fc_break);
  629. if aktbreaklabel<>nil then
  630. begin
  631. {$ifdef OLDREGVARS}
  632. load_all_regvars(exprasmlist);
  633. {$endif OLDREGVARS}
  634. cg.a_jmp_always(exprasmlist,aktbreaklabel)
  635. end
  636. else
  637. CGMessage(cg_e_break_not_allowed);
  638. end;
  639. {*****************************************************************************
  640. SecondContinueN
  641. *****************************************************************************}
  642. procedure tcgcontinuenode.pass_2;
  643. begin
  644. location_reset(location,LOC_VOID,OS_NO);
  645. include(flowcontrol,fc_continue);
  646. if aktcontinuelabel<>nil then
  647. begin
  648. {$ifdef OLDREGVARS}
  649. load_all_regvars(exprasmlist);
  650. {$endif OLDREGVARS}
  651. cg.a_jmp_always(exprasmlist,aktcontinuelabel)
  652. end
  653. else
  654. CGMessage(cg_e_continue_not_allowed);
  655. end;
  656. {*****************************************************************************
  657. SecondGoto
  658. *****************************************************************************}
  659. procedure tcggotonode.pass_2;
  660. begin
  661. location_reset(location,LOC_VOID,OS_NO);
  662. {$ifdef OLDREGVARS}
  663. load_all_regvars(exprasmlist);
  664. {$endif OLDREGVARS}
  665. cg.a_jmp_always(exprasmlist,labsym.lab)
  666. end;
  667. {*****************************************************************************
  668. SecondLabel
  669. *****************************************************************************}
  670. procedure tcglabelnode.pass_2;
  671. begin
  672. location_reset(location,LOC_VOID,OS_NO);
  673. {$ifdef OLDREGVARS}
  674. load_all_regvars(exprasmlist);
  675. {$endif OLDREGVARS}
  676. cg.a_label(exprasmlist,labelnr);
  677. secondpass(left);
  678. end;
  679. {*****************************************************************************
  680. SecondRaise
  681. *****************************************************************************}
  682. procedure tcgraisenode.pass_2;
  683. var
  684. a : tasmlabel;
  685. href2: treference;
  686. paraloc1,paraloc2,paraloc3 : tparalocation;
  687. begin
  688. paraloc1:=paramanager.getintparaloc(pocall_default,1);
  689. paraloc2:=paramanager.getintparaloc(pocall_default,2);
  690. paraloc3:=paramanager.getintparaloc(pocall_default,3);
  691. location_reset(location,LOC_VOID,OS_NO);
  692. if assigned(left) then
  693. begin
  694. { multiple parameters? }
  695. if assigned(right) then
  696. begin
  697. if assigned(frametree) then
  698. secondpass(frametree);
  699. secondpass(right);
  700. end;
  701. secondpass(left);
  702. if codegenerror then
  703. exit;
  704. { Push parameters }
  705. if assigned(right) then
  706. begin
  707. paramanager.allocparaloc(exprasmlist,paraloc3);
  708. if assigned(frametree) then
  709. begin
  710. location_release(exprasmlist,frametree.location);
  711. cg.a_param_loc(exprasmlist,frametree.location,paraloc3)
  712. end
  713. else
  714. cg.a_param_const(exprasmlist,OS_INT,0,paraloc3);
  715. { push address }
  716. location_release(exprasmlist,right.location);
  717. paramanager.allocparaloc(exprasmlist,paraloc2);
  718. cg.a_param_loc(exprasmlist,right.location,paraloc2);
  719. end
  720. else
  721. begin
  722. { get current address }
  723. objectlibrary.getaddrlabel(a);
  724. cg.a_label(exprasmlist,a);
  725. reference_reset_symbol(href2,a,0);
  726. { push current frame }
  727. paramanager.allocparaloc(exprasmlist,paraloc3);
  728. cg.a_param_reg(exprasmlist,OS_ADDR,NR_FRAME_POINTER_REG,paraloc3);
  729. { push current address }
  730. paramanager.allocparaloc(exprasmlist,paraloc2);
  731. if target_info.system <> system_powerpc_macos then
  732. cg.a_paramaddr_ref(exprasmlist,href2,paraloc2)
  733. else
  734. cg.a_param_const(exprasmlist,OS_INT,0,paraloc2);
  735. end;
  736. location_release(exprasmlist,left.location);
  737. paramanager.allocparaloc(exprasmlist,paraloc1);
  738. cg.a_param_loc(exprasmlist,left.location,paraloc1);
  739. paramanager.freeparaloc(exprasmlist,paraloc1);
  740. paramanager.freeparaloc(exprasmlist,paraloc2);
  741. paramanager.freeparaloc(exprasmlist,paraloc3);
  742. cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
  743. cg.a_call_name(exprasmlist,'FPC_RAISEEXCEPTION');
  744. cg.deallocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
  745. end
  746. else
  747. begin
  748. cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
  749. cg.a_call_name(exprasmlist,'FPC_POPADDRSTACK');
  750. cg.a_call_name(exprasmlist,'FPC_RERAISE');
  751. cg.deallocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
  752. end;
  753. end;
  754. {*****************************************************************************
  755. SecondTryExcept
  756. *****************************************************************************}
  757. var
  758. endexceptlabel : tasmlabel;
  759. { does the necessary things to clean up the object stack }
  760. { in the except block }
  761. procedure cleanupobjectstack;
  762. var
  763. paraloc1 : tparalocation;
  764. begin
  765. cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
  766. cg.a_call_name(exprasmlist,'FPC_POPOBJECTSTACK');
  767. cg.deallocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
  768. paraloc1:=paramanager.getintparaloc(pocall_default,1);
  769. paramanager.allocparaloc(exprasmlist,paraloc1);
  770. cg.a_param_reg(exprasmlist,OS_ADDR,NR_FUNCTION_RESULT_REG,paraloc1);
  771. paramanager.freeparaloc(exprasmlist,paraloc1);
  772. cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
  773. cg.a_call_name(exprasmlist,'FPC_DESTROYEXCEPTION');
  774. cg.deallocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
  775. end;
  776. procedure tcgtryexceptnode.pass_2;
  777. var
  778. exceptlabel,doexceptlabel,oldendexceptlabel,
  779. lastonlabel,
  780. exitexceptlabel,
  781. continueexceptlabel,
  782. breakexceptlabel,
  783. exittrylabel,
  784. continuetrylabel,
  785. breaktrylabel,
  786. doobjectdestroy,
  787. doobjectdestroyandreraise,
  788. oldaktexitlabel,
  789. oldaktcontinuelabel,
  790. oldaktbreaklabel : tasmlabel;
  791. oldflowcontrol,tryflowcontrol,
  792. exceptflowcontrol : tflowcontrol;
  793. destroytemps,
  794. excepttemps : texceptiontemps;
  795. paraloc1 : tparalocation;
  796. label
  797. errorexit;
  798. begin
  799. location_reset(location,LOC_VOID,OS_NO);
  800. oldflowcontrol:=flowcontrol;
  801. flowcontrol:=[];
  802. { this can be called recursivly }
  803. oldendexceptlabel:=endexceptlabel;
  804. { save the old labels for control flow statements }
  805. oldaktexitlabel:=current_procinfo.aktexitlabel;
  806. if assigned(aktbreaklabel) then
  807. begin
  808. oldaktcontinuelabel:=aktcontinuelabel;
  809. oldaktbreaklabel:=aktbreaklabel;
  810. end;
  811. { get new labels for the control flow statements }
  812. objectlibrary.getlabel(exittrylabel);
  813. objectlibrary.getlabel(exitexceptlabel);
  814. if assigned(aktbreaklabel) then
  815. begin
  816. objectlibrary.getlabel(breaktrylabel);
  817. objectlibrary.getlabel(continuetrylabel);
  818. objectlibrary.getlabel(breakexceptlabel);
  819. objectlibrary.getlabel(continueexceptlabel);
  820. end;
  821. objectlibrary.getlabel(exceptlabel);
  822. objectlibrary.getlabel(doexceptlabel);
  823. objectlibrary.getlabel(endexceptlabel);
  824. objectlibrary.getlabel(lastonlabel);
  825. get_exception_temps(exprasmlist,excepttemps);
  826. new_exception(exprasmlist,excepttemps,1,exceptlabel);
  827. { try block }
  828. { set control flow labels for the try block }
  829. current_procinfo.aktexitlabel:=exittrylabel;
  830. if assigned(oldaktbreaklabel) then
  831. begin
  832. aktcontinuelabel:=continuetrylabel;
  833. aktbreaklabel:=breaktrylabel;
  834. end;
  835. flowcontrol:=[];
  836. secondpass(left);
  837. tryflowcontrol:=flowcontrol;
  838. if codegenerror then
  839. goto errorexit;
  840. cg.a_label(exprasmlist,exceptlabel);
  841. free_exception(exprasmlist, excepttemps, 0, endexceptlabel, false);
  842. cg.a_label(exprasmlist,doexceptlabel);
  843. { set control flow labels for the except block }
  844. { and the on statements }
  845. current_procinfo.aktexitlabel:=exitexceptlabel;
  846. if assigned(oldaktbreaklabel) then
  847. begin
  848. aktcontinuelabel:=continueexceptlabel;
  849. aktbreaklabel:=breakexceptlabel;
  850. end;
  851. flowcontrol:=[];
  852. { on statements }
  853. if assigned(right) then
  854. secondpass(right);
  855. cg.a_label(exprasmlist,lastonlabel);
  856. { default handling except handling }
  857. if assigned(t1) then
  858. begin
  859. { FPC_CATCHES must be called with
  860. 'default handler' flag (=-1)
  861. }
  862. paraloc1:=paramanager.getintparaloc(pocall_default,1);
  863. paramanager.allocparaloc(exprasmlist,paraloc1);
  864. cg.a_param_const(exprasmlist,OS_ADDR,aword(-1),paraloc1);
  865. paramanager.freeparaloc(exprasmlist,paraloc1);
  866. cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
  867. cg.a_call_name(exprasmlist,'FPC_CATCHES');
  868. cg.deallocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
  869. { the destruction of the exception object must be also }
  870. { guarded by an exception frame }
  871. objectlibrary.getlabel(doobjectdestroy);
  872. objectlibrary.getlabel(doobjectdestroyandreraise);
  873. get_exception_temps(exprasmlist,destroytemps);
  874. new_exception(exprasmlist,destroytemps,1,doobjectdestroyandreraise);
  875. { here we don't have to reset flowcontrol }
  876. { the default and on flowcontrols are handled equal }
  877. secondpass(t1);
  878. exceptflowcontrol:=flowcontrol;
  879. cg.a_label(exprasmlist,doobjectdestroyandreraise);
  880. free_exception(exprasmlist,destroytemps,0,doobjectdestroy,false);
  881. cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
  882. cg.a_call_name(exprasmlist,'FPC_POPSECONDOBJECTSTACK');
  883. cg.deallocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
  884. paraloc1:=paramanager.getintparaloc(pocall_default,1);
  885. paramanager.allocparaloc(exprasmlist,paraloc1);
  886. cg.a_param_reg(exprasmlist, OS_ADDR, NR_FUNCTION_RESULT_REG, paraloc1);
  887. paramanager.freeparaloc(exprasmlist,paraloc1);
  888. cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
  889. cg.a_call_name(exprasmlist,'FPC_DESTROYEXCEPTION');
  890. cg.deallocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
  891. { we don't need to restore esi here because reraise never }
  892. { returns }
  893. cg.a_call_name(exprasmlist,'FPC_RERAISE');
  894. cg.a_label(exprasmlist,doobjectdestroy);
  895. cleanupobjectstack;
  896. unget_exception_temps(exprasmlist,destroytemps);
  897. cg.a_jmp_always(exprasmlist,endexceptlabel);
  898. end
  899. else
  900. begin
  901. cg.a_call_name(exprasmlist,'FPC_RERAISE');
  902. exceptflowcontrol:=flowcontrol;
  903. end;
  904. if fc_exit in exceptflowcontrol then
  905. begin
  906. { do some magic for exit in the try block }
  907. cg.a_label(exprasmlist,exitexceptlabel);
  908. { we must also destroy the address frame which guards }
  909. { exception object }
  910. cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
  911. cg.a_call_name(exprasmlist,'FPC_POPADDRSTACK');
  912. cg.deallocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
  913. cg.g_exception_reason_load(exprasmlist,excepttemps.reasonbuf);
  914. cleanupobjectstack;
  915. cg.a_jmp_always(exprasmlist,oldaktexitlabel);
  916. end;
  917. if fc_break in exceptflowcontrol then
  918. begin
  919. cg.a_label(exprasmlist,breakexceptlabel);
  920. { we must also destroy the address frame which guards }
  921. { exception object }
  922. cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
  923. cg.a_call_name(exprasmlist,'FPC_POPADDRSTACK');
  924. cg.deallocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
  925. cg.g_exception_reason_load(exprasmlist,excepttemps.reasonbuf);
  926. cleanupobjectstack;
  927. cg.a_jmp_always(exprasmlist,oldaktbreaklabel);
  928. end;
  929. if fc_continue in exceptflowcontrol then
  930. begin
  931. cg.a_label(exprasmlist,continueexceptlabel);
  932. { we must also destroy the address frame which guards }
  933. { exception object }
  934. cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
  935. cg.a_call_name(exprasmlist,'FPC_POPADDRSTACK');
  936. cg.deallocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
  937. cg.g_exception_reason_load(exprasmlist,excepttemps.reasonbuf);
  938. cleanupobjectstack;
  939. cg.a_jmp_always(exprasmlist,oldaktcontinuelabel);
  940. end;
  941. if fc_exit in tryflowcontrol then
  942. begin
  943. { do some magic for exit in the try block }
  944. cg.a_label(exprasmlist,exittrylabel);
  945. cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
  946. cg.a_call_name(exprasmlist,'FPC_POPADDRSTACK');
  947. cg.deallocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
  948. cg.g_exception_reason_load(exprasmlist,excepttemps.reasonbuf);
  949. cg.a_jmp_always(exprasmlist,oldaktexitlabel);
  950. end;
  951. if fc_break in tryflowcontrol then
  952. begin
  953. cg.a_label(exprasmlist,breaktrylabel);
  954. cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
  955. cg.a_call_name(exprasmlist,'FPC_POPADDRSTACK');
  956. cg.deallocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
  957. cg.g_exception_reason_load(exprasmlist,excepttemps.reasonbuf);
  958. cg.a_jmp_always(exprasmlist,oldaktbreaklabel);
  959. end;
  960. if fc_continue in tryflowcontrol then
  961. begin
  962. cg.a_label(exprasmlist,continuetrylabel);
  963. cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
  964. cg.a_call_name(exprasmlist,'FPC_POPADDRSTACK');
  965. cg.deallocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
  966. cg.g_exception_reason_load(exprasmlist,excepttemps.reasonbuf);
  967. cg.a_jmp_always(exprasmlist,oldaktcontinuelabel);
  968. end;
  969. unget_exception_temps(exprasmlist,excepttemps);
  970. cg.a_label(exprasmlist,endexceptlabel);
  971. errorexit:
  972. { restore all saved labels }
  973. endexceptlabel:=oldendexceptlabel;
  974. { restore the control flow labels }
  975. current_procinfo.aktexitlabel:=oldaktexitlabel;
  976. if assigned(oldaktbreaklabel) then
  977. begin
  978. aktcontinuelabel:=oldaktcontinuelabel;
  979. aktbreaklabel:=oldaktbreaklabel;
  980. end;
  981. { return all used control flow statements }
  982. flowcontrol:=oldflowcontrol+exceptflowcontrol+
  983. tryflowcontrol;
  984. end;
  985. procedure tcgonnode.pass_2;
  986. var
  987. nextonlabel,
  988. exitonlabel,
  989. continueonlabel,
  990. breakonlabel,
  991. oldaktexitlabel,
  992. oldaktcontinuelabel,
  993. doobjectdestroyandreraise,
  994. doobjectdestroy,
  995. oldaktbreaklabel : tasmlabel;
  996. oldflowcontrol : tflowcontrol;
  997. excepttemps : texceptiontemps;
  998. exceptref,
  999. href2: treference;
  1000. paraloc1 : tparalocation;
  1001. begin
  1002. location_reset(location,LOC_VOID,OS_NO);
  1003. oldflowcontrol:=flowcontrol;
  1004. flowcontrol:=[];
  1005. objectlibrary.getlabel(nextonlabel);
  1006. { send the vmt parameter }
  1007. reference_reset_symbol(href2,objectlibrary.newasmsymbol(excepttype.vmt_mangledname,AB_EXTERNAL,AT_DATA),0);
  1008. paraloc1:=paramanager.getintparaloc(pocall_default,1);
  1009. paramanager.allocparaloc(exprasmlist,paraloc1);
  1010. cg.a_paramaddr_ref(exprasmlist,href2,paraloc1);
  1011. paramanager.freeparaloc(exprasmlist,paraloc1);
  1012. cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
  1013. cg.a_call_name(exprasmlist,'FPC_CATCHES');
  1014. cg.deallocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
  1015. { is it this catch? No. go to next onlabel }
  1016. cg.a_cmp_const_reg_label(exprasmlist,OS_ADDR,OC_EQ,0,NR_FUNCTION_RESULT_REG,nextonlabel);
  1017. { what a hack ! }
  1018. if assigned(exceptsymtable) then
  1019. begin
  1020. tvarsym(exceptsymtable.symindex.first).localloc.loc:=LOC_REFERENCE;
  1021. tg.GetLocal(exprasmlist,POINTER_SIZE,voidpointertype.def,
  1022. tvarsym(exceptsymtable.symindex.first).localloc.reference);
  1023. reference_reset_base(href2,tvarsym(exceptsymtable.symindex.first).localloc.reference.index,
  1024. tvarsym(exceptsymtable.symindex.first).localloc.reference.offset);
  1025. cg.a_load_reg_ref(exprasmlist,OS_ADDR,OS_ADDR,NR_FUNCTION_RESULT_REG,href2);
  1026. end
  1027. else
  1028. begin
  1029. tg.GetTemp(exprasmlist,POINTER_SIZE,tt_normal,exceptref);
  1030. cg.a_load_reg_ref(exprasmlist,OS_ADDR,OS_ADDR,NR_FUNCTION_RESULT_REG,exceptref);
  1031. end;
  1032. { in the case that another exception is risen }
  1033. { we've to destroy the old one }
  1034. objectlibrary.getlabel(doobjectdestroyandreraise);
  1035. { call setjmp, and jump to finally label on non-zero result }
  1036. get_exception_temps(exprasmlist,excepttemps);
  1037. new_exception(exprasmlist,excepttemps,1,doobjectdestroyandreraise);
  1038. if assigned(right) then
  1039. begin
  1040. oldaktexitlabel:=current_procinfo.aktexitlabel;
  1041. objectlibrary.getlabel(exitonlabel);
  1042. current_procinfo.aktexitlabel:=exitonlabel;
  1043. if assigned(aktbreaklabel) then
  1044. begin
  1045. oldaktcontinuelabel:=aktcontinuelabel;
  1046. oldaktbreaklabel:=aktbreaklabel;
  1047. objectlibrary.getlabel(breakonlabel);
  1048. objectlibrary.getlabel(continueonlabel);
  1049. aktcontinuelabel:=continueonlabel;
  1050. aktbreaklabel:=breakonlabel;
  1051. end;
  1052. secondpass(right);
  1053. end;
  1054. objectlibrary.getlabel(doobjectdestroy);
  1055. cg.a_label(exprasmlist,doobjectdestroyandreraise);
  1056. free_exception(exprasmlist,excepttemps,0,doobjectdestroy,false);
  1057. cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
  1058. cg.a_call_name(exprasmlist,'FPC_POPSECONDOBJECTSTACK');
  1059. cg.deallocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
  1060. paraloc1:=paramanager.getintparaloc(pocall_default,1);
  1061. paramanager.allocparaloc(exprasmlist,paraloc1);
  1062. cg.a_param_reg(exprasmlist, OS_ADDR, NR_FUNCTION_RESULT_REG, paraloc1);
  1063. paramanager.freeparaloc(exprasmlist,paraloc1);
  1064. cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
  1065. cg.a_call_name(exprasmlist,'FPC_DESTROYEXCEPTION');
  1066. cg.deallocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
  1067. { we don't need to restore esi here because reraise never }
  1068. { returns }
  1069. cg.a_call_name(exprasmlist,'FPC_RERAISE');
  1070. cg.a_label(exprasmlist,doobjectdestroy);
  1071. cleanupobjectstack;
  1072. { clear some stuff }
  1073. if assigned(exceptsymtable) then
  1074. begin
  1075. tg.UngetLocal(exprasmlist,tvarsym(exceptsymtable.symindex.first).localloc.reference);
  1076. tvarsym(exceptsymtable.symindex.first).localloc.loc:=LOC_INVALID;
  1077. end
  1078. else
  1079. tg.Ungettemp(exprasmlist,exceptref);
  1080. cg.a_jmp_always(exprasmlist,endexceptlabel);
  1081. if assigned(right) then
  1082. begin
  1083. { special handling for control flow instructions }
  1084. if fc_exit in flowcontrol then
  1085. begin
  1086. { the address and object pop does secondtryexcept }
  1087. cg.a_label(exprasmlist,exitonlabel);
  1088. cg.a_jmp_always(exprasmlist,oldaktexitlabel);
  1089. end;
  1090. if fc_break in flowcontrol then
  1091. begin
  1092. { the address and object pop does secondtryexcept }
  1093. cg.a_label(exprasmlist,breakonlabel);
  1094. cg.a_jmp_always(exprasmlist,oldaktbreaklabel);
  1095. end;
  1096. if fc_continue in flowcontrol then
  1097. begin
  1098. { the address and object pop does secondtryexcept }
  1099. cg.a_label(exprasmlist,continueonlabel);
  1100. cg.a_jmp_always(exprasmlist,oldaktcontinuelabel);
  1101. end;
  1102. current_procinfo.aktexitlabel:=oldaktexitlabel;
  1103. if assigned(oldaktbreaklabel) then
  1104. begin
  1105. aktcontinuelabel:=oldaktcontinuelabel;
  1106. aktbreaklabel:=oldaktbreaklabel;
  1107. end;
  1108. end;
  1109. unget_exception_temps(exprasmlist,excepttemps);
  1110. cg.a_label(exprasmlist,nextonlabel);
  1111. flowcontrol:=oldflowcontrol+flowcontrol;
  1112. { next on node }
  1113. if assigned(left) then
  1114. secondpass(left);
  1115. end;
  1116. {*****************************************************************************
  1117. SecondTryFinally
  1118. *****************************************************************************}
  1119. procedure tcgtryfinallynode.pass_2;
  1120. var
  1121. reraiselabel,
  1122. finallylabel,
  1123. endfinallylabel,
  1124. exitfinallylabel,
  1125. continuefinallylabel,
  1126. breakfinallylabel,
  1127. oldaktexitlabel,
  1128. oldaktcontinuelabel,
  1129. oldaktbreaklabel : tasmlabel;
  1130. oldflowcontrol,tryflowcontrol : tflowcontrol;
  1131. decconst : longint;
  1132. excepttemps : texceptiontemps;
  1133. begin
  1134. location_reset(location,LOC_VOID,OS_NO);
  1135. { check if child nodes do a break/continue/exit }
  1136. oldflowcontrol:=flowcontrol;
  1137. flowcontrol:=[];
  1138. objectlibrary.getlabel(finallylabel);
  1139. objectlibrary.getlabel(endfinallylabel);
  1140. objectlibrary.getlabel(reraiselabel);
  1141. { the finally block must catch break, continue and exit }
  1142. { statements }
  1143. oldaktexitlabel:=current_procinfo.aktexitlabel;
  1144. if implicitframe then
  1145. exitfinallylabel:=finallylabel
  1146. else
  1147. objectlibrary.getlabel(exitfinallylabel);
  1148. current_procinfo.aktexitlabel:=exitfinallylabel;
  1149. if assigned(aktbreaklabel) then
  1150. begin
  1151. oldaktcontinuelabel:=aktcontinuelabel;
  1152. oldaktbreaklabel:=aktbreaklabel;
  1153. if implicitframe then
  1154. begin
  1155. breakfinallylabel:=finallylabel;
  1156. continuefinallylabel:=finallylabel;
  1157. end
  1158. else
  1159. begin
  1160. objectlibrary.getlabel(breakfinallylabel);
  1161. objectlibrary.getlabel(continuefinallylabel);
  1162. end;
  1163. aktcontinuelabel:=continuefinallylabel;
  1164. aktbreaklabel:=breakfinallylabel;
  1165. end;
  1166. { call setjmp, and jump to finally label on non-zero result }
  1167. get_exception_temps(exprasmlist,excepttemps);
  1168. new_exception(exprasmlist,excepttemps,1,finallylabel);
  1169. { try code }
  1170. if assigned(left) then
  1171. begin
  1172. secondpass(left);
  1173. tryflowcontrol:=flowcontrol;
  1174. if codegenerror then
  1175. exit;
  1176. end;
  1177. cg.a_label(exprasmlist,finallylabel);
  1178. { just free the frame information }
  1179. free_exception(exprasmlist,excepttemps,1,finallylabel,true);
  1180. { finally code }
  1181. flowcontrol:=[];
  1182. secondpass(right);
  1183. if flowcontrol<>[] then
  1184. CGMessage(cg_e_control_flow_outside_finally);
  1185. if codegenerror then
  1186. exit;
  1187. { the value should now be in the exception handler }
  1188. cg.g_exception_reason_load(exprasmlist,excepttemps.reasonbuf);
  1189. if implicitframe then
  1190. begin
  1191. cg.a_cmp_const_reg_label(exprasmlist,OS_INT,OC_EQ,0,NR_FUNCTION_RESULT_REG,endfinallylabel);
  1192. { finally code only needed to be executed on exception }
  1193. flowcontrol:=[];
  1194. secondpass(t1);
  1195. if flowcontrol<>[] then
  1196. CGMessage(cg_e_control_flow_outside_finally);
  1197. if codegenerror then
  1198. exit;
  1199. cg.a_call_name(exprasmlist,'FPC_RERAISE');
  1200. end
  1201. else
  1202. begin
  1203. cg.a_cmp_const_reg_label(exprasmlist,OS_INT,OC_EQ,0,NR_FUNCTION_RESULT_REG,endfinallylabel);
  1204. cg.a_op_const_reg(exprasmlist,OP_SUB,OS_INT,1,NR_FUNCTION_RESULT_REG);
  1205. cg.a_cmp_const_reg_label(exprasmlist,OS_INT,OC_EQ,0,NR_FUNCTION_RESULT_REG,reraiselabel);
  1206. if fc_exit in tryflowcontrol then
  1207. begin
  1208. cg.a_op_const_reg(exprasmlist,OP_SUB,OS_INT,1,NR_FUNCTION_RESULT_REG);
  1209. cg.a_cmp_const_reg_label(exprasmlist,OS_INT,OC_EQ,0,NR_FUNCTION_RESULT_REG,oldaktexitlabel);
  1210. decconst:=1;
  1211. end
  1212. else
  1213. decconst:=2;
  1214. if fc_break in tryflowcontrol then
  1215. begin
  1216. cg.a_op_const_reg(exprasmlist,OP_SUB,OS_INT,decconst,NR_FUNCTION_RESULT_REG);
  1217. cg.a_cmp_const_reg_label(exprasmlist,OS_INT,OC_EQ,0,NR_FUNCTION_RESULT_REG,oldaktbreaklabel);
  1218. decconst:=1;
  1219. end
  1220. else
  1221. inc(decconst);
  1222. if fc_continue in tryflowcontrol then
  1223. begin
  1224. cg.a_op_const_reg(exprasmlist,OP_SUB,OS_INT,decconst,NR_FUNCTION_RESULT_REG);
  1225. cg.a_cmp_const_reg_label(exprasmlist,OS_INT,OC_EQ,0,NR_FUNCTION_RESULT_REG,oldaktcontinuelabel);
  1226. end;
  1227. cg.a_label(exprasmlist,reraiselabel);
  1228. cg.a_call_name(exprasmlist,'FPC_RERAISE');
  1229. { do some magic for exit,break,continue in the try block }
  1230. if fc_exit in tryflowcontrol then
  1231. begin
  1232. cg.a_label(exprasmlist,exitfinallylabel);
  1233. cg.g_exception_reason_load(exprasmlist,excepttemps.reasonbuf);
  1234. cg.g_exception_reason_save_const(exprasmlist,excepttemps.reasonbuf,2);
  1235. cg.a_jmp_always(exprasmlist,finallylabel);
  1236. end;
  1237. if fc_break in tryflowcontrol then
  1238. begin
  1239. cg.a_label(exprasmlist,breakfinallylabel);
  1240. cg.g_exception_reason_load(exprasmlist,excepttemps.reasonbuf);
  1241. cg.g_exception_reason_save_const(exprasmlist,excepttemps.reasonbuf,3);
  1242. cg.a_jmp_always(exprasmlist,finallylabel);
  1243. end;
  1244. if fc_continue in tryflowcontrol then
  1245. begin
  1246. cg.a_label(exprasmlist,continuefinallylabel);
  1247. cg.g_exception_reason_load(exprasmlist,excepttemps.reasonbuf);
  1248. cg.g_exception_reason_save_const(exprasmlist,excepttemps.reasonbuf,4);
  1249. cg.a_jmp_always(exprasmlist,finallylabel);
  1250. end;
  1251. end;
  1252. unget_exception_temps(exprasmlist,excepttemps);
  1253. cg.a_label(exprasmlist,endfinallylabel);
  1254. current_procinfo.aktexitlabel:=oldaktexitlabel;
  1255. if assigned(aktbreaklabel) then
  1256. begin
  1257. aktcontinuelabel:=oldaktcontinuelabel;
  1258. aktbreaklabel:=oldaktbreaklabel;
  1259. end;
  1260. flowcontrol:=oldflowcontrol+tryflowcontrol;
  1261. end;
  1262. begin
  1263. cwhilerepeatnode:=tcgwhilerepeatnode;
  1264. cifnode:=tcgifnode;
  1265. cfornode:=tcgfornode;
  1266. cexitnode:=tcgexitnode;
  1267. cbreaknode:=tcgbreaknode;
  1268. ccontinuenode:=tcgcontinuenode;
  1269. cgotonode:=tcggotonode;
  1270. clabelnode:=tcglabelnode;
  1271. craisenode:=tcgraisenode;
  1272. ctryexceptnode:=tcgtryexceptnode;
  1273. ctryfinallynode:=tcgtryfinallynode;
  1274. connode:=tcgonnode;
  1275. end.
  1276. {
  1277. $Log$
  1278. Revision 1.95 2004-03-29 14:43:47 peter
  1279. * cleaner temp get/unget for exceptions
  1280. Revision 1.94 2004/03/02 00:36:33 olle
  1281. * big transformation of Tai_[const_]Symbol.Create[data]name*
  1282. Revision 1.93 2004/02/27 10:21:05 florian
  1283. * top_symbol killed
  1284. + refaddr to treference added
  1285. + refsymbol to treference added
  1286. * top_local stuff moved to an extra record to save memory
  1287. + aint introduced
  1288. * tppufile.get/putint64/aint implemented
  1289. Revision 1.92 2004/02/12 15:54:03 peter
  1290. * make extcycle is working again
  1291. Revision 1.91 2004/02/05 18:28:37 peter
  1292. * x86_64 fixes for opsize
  1293. Revision 1.90 2004/01/31 17:45:17 peter
  1294. * Change several $ifdef i386 to x86
  1295. * Change several OS_32 to OS_INT/OS_ADDR
  1296. Revision 1.89 2004/01/12 22:11:38 peter
  1297. * use localalign info for alignment for locals and temps
  1298. * sparc fpu flags branching added
  1299. * moved powerpc copy_valye_openarray to generic
  1300. Revision 1.88 2004/01/01 17:23:16 florian
  1301. * fixed wrong temp. usage in generic exception handling
  1302. Revision 1.87 2003/12/06 01:15:22 florian
  1303. * reverted Peter's alloctemp patch; hopefully properly
  1304. Revision 1.86 2003/12/03 23:13:20 peter
  1305. * delayed paraloc allocation, a_param_*() gets extra parameter
  1306. if it needs to allocate temp or real paralocation
  1307. * optimized/simplified int-real loading
  1308. Revision 1.85 2003/10/17 14:38:32 peter
  1309. * 64k registers supported
  1310. * fixed some memory leaks
  1311. Revision 1.84 2003/10/10 17:48:13 peter
  1312. * old trgobj moved to x86/rgcpu and renamed to trgx86fpu
  1313. * tregisteralloctor renamed to trgobj
  1314. * removed rgobj from a lot of units
  1315. * moved location_* and reference_* to cgobj
  1316. * first things for mmx register allocation
  1317. Revision 1.83 2003/10/09 21:31:37 daniel
  1318. * Register allocator splitted, ans abstract now
  1319. Revision 1.82 2003/10/01 20:34:48 peter
  1320. * procinfo unit contains tprocinfo
  1321. * cginfo renamed to cgbase
  1322. * moved cgmessage to verbose
  1323. * fixed ppc and sparc compiles
  1324. Revision 1.81 2003/09/23 17:56:05 peter
  1325. * locals and paras are allocated in the code generation
  1326. * tvarsym.localloc contains the location of para/local when
  1327. generating code for the current procedure
  1328. Revision 1.80 2003/09/10 08:31:47 marco
  1329. * Patch from Peter for paraloc
  1330. Revision 1.79 2003/09/07 22:09:35 peter
  1331. * preparations for different default calling conventions
  1332. * various RA fixes
  1333. Revision 1.78 2003/09/03 15:55:00 peter
  1334. * NEWRA branch merged
  1335. Revision 1.77 2003/09/03 11:18:36 florian
  1336. * fixed arm concatcopy
  1337. + arm support in the common compiler sources added
  1338. * moved some generic cg code around
  1339. + tfputype added
  1340. * ...
  1341. Revision 1.76.2.4 2003/09/02 17:48:28 peter
  1342. * first process all parameters for raise before pushing the values
  1343. Revision 1.76.2.3 2003/08/31 21:07:44 daniel
  1344. * callparatemp ripped
  1345. Revision 1.76.2.2 2003/08/29 17:28:59 peter
  1346. * next batch of updates
  1347. Revision 1.76.2.1 2003/08/27 20:23:55 peter
  1348. * remove old ra code
  1349. Revision 1.76 2003/08/24 21:38:43 olle
  1350. * made FPC_RAISEEXCEPTION compatible with MacOS
  1351. Revision 1.75 2003/08/10 17:25:23 peter
  1352. * fixed some reported bugs
  1353. Revision 1.74 2003/08/09 18:56:54 daniel
  1354. * cs_regalloc renamed to cs_regvars to avoid confusion with register
  1355. allocator
  1356. * Some preventive changes to i386 spillinh code
  1357. Revision 1.73 2003/07/23 11:01:14 jonas
  1358. * several rg.allocexplicitregistersint/rg.deallocexplicitregistersint
  1359. pairs round calls to helpers
  1360. Revision 1.72 2003/06/13 21:19:30 peter
  1361. * current_procdef removed, use current_procinfo.procdef instead
  1362. Revision 1.71 2003/06/09 14:38:52 jonas
  1363. * fixed for callparatemp
  1364. Revision 1.70 2003/06/09 12:23:30 peter
  1365. * init/final of procedure data splitted from genentrycode
  1366. * use asmnode getposition to insert final at the correct position
  1367. als for the implicit try...finally
  1368. Revision 1.69 2003/06/07 18:57:04 jonas
  1369. + added freeintparaloc
  1370. * ppc get/freeintparaloc now check whether the parameter regs are
  1371. properly allocated/deallocated (and get an extra list para)
  1372. * ppc a_call_* now internalerrors if pi_do_call is not yet set
  1373. * fixed lot of missing pi_do_call's
  1374. Revision 1.68 2003/06/03 21:11:09 peter
  1375. * cg.a_load_* get a from and to size specifier
  1376. * makeregsize only accepts newregister
  1377. * i386 uses generic tcgnotnode,tcgunaryminus
  1378. Revision 1.67 2003/06/01 21:38:06 peter
  1379. * getregisterfpu size parameter added
  1380. * op_const_reg size parameter added
  1381. * sparc updates
  1382. Revision 1.66 2003/05/30 23:57:08 peter
  1383. * more sparc cleanup
  1384. * accumulator removed, splitted in function_return_reg (called) and
  1385. function_result_reg (caller)
  1386. Revision 1.65 2003/05/30 18:55:21 jonas
  1387. * fixed several regvar related bugs for non-i386. make cycle with -Or now
  1388. works for ppc
  1389. Revision 1.64 2003/05/26 21:17:17 peter
  1390. * procinlinenode removed
  1391. * aktexit2label removed, fast exit removed
  1392. + tcallnode.inlined_pass_2 added
  1393. Revision 1.63 2003/05/23 14:27:35 peter
  1394. * remove some unit dependencies
  1395. * current_procinfo changes to store more info
  1396. Revision 1.62 2003/05/17 13:30:08 jonas
  1397. * changed tt_persistant to tt_persistent :)
  1398. * tempcreatenode now doesn't accept a boolean anymore for persistent
  1399. temps, but a ttemptype, so you can also create ansistring temps etc
  1400. Revision 1.61 2003/05/16 14:33:31 peter
  1401. * regvar fixes
  1402. Revision 1.60 2003/05/13 19:14:41 peter
  1403. * failn removed
  1404. * inherited result code check moven to pexpr
  1405. Revision 1.59 2003/05/11 21:37:03 peter
  1406. * moved implicit exception frame from ncgutil to psub
  1407. * constructor/destructor helpers moved from cobj/ncgutil to psub
  1408. Revision 1.58 2003/04/30 15:45:35 florian
  1409. * merged more x86-64/i386 code
  1410. Revision 1.57 2003/04/29 07:29:14 michael
  1411. + Patch from peter to fix wrong pushing of ansistring function results in open array
  1412. Revision 1.56 2003/04/27 11:21:33 peter
  1413. * aktprocdef renamed to current_procinfo.procdef
  1414. * procinfo renamed to current_procinfo
  1415. * procinfo will now be stored in current_module so it can be
  1416. cleaned up properly
  1417. * gen_main_procsym changed to create_main_proc and release_main_proc
  1418. to also generate a tprocinfo structure
  1419. * fixed unit implicit initfinal
  1420. Revision 1.55 2003/04/22 23:50:22 peter
  1421. * firstpass uses expectloc
  1422. * checks if there are differences between the expectloc and
  1423. location.loc from secondpass in EXTDEBUG
  1424. Revision 1.54 2003/04/17 07:50:24 daniel
  1425. * Some work on interference graph construction
  1426. Revision 1.53 2003/04/06 21:11:23 olle
  1427. * changed newasmsymbol to newasmsymboldata for data symbols
  1428. Revision 1.52 2003/03/28 19:16:56 peter
  1429. * generic constructor working for i386
  1430. * remove fixed self register
  1431. * esi added as address register for i386
  1432. Revision 1.51 2003/02/19 22:00:14 daniel
  1433. * Code generator converted to new register notation
  1434. - Horribily outdated todo.txt removed
  1435. Revision 1.50 2003/02/15 22:17:38 carl
  1436. * bugfix of FPU emulation code
  1437. Revision 1.49 2003/01/08 18:43:56 daniel
  1438. * Tregister changed into a record
  1439. Revision 1.48 2003/01/03 09:51:58 daniel
  1440. * Compiler now cycles with var_notification
  1441. Revision 1.47 2003/01/02 15:29:25 daniel
  1442. * Some debugging on for loop optimization
  1443. Revision 1.46 2002/12/31 09:55:58 daniel
  1444. + Notification implementation complete
  1445. + Add for loop code optimization using notifications
  1446. results in 1.5-1.9% speed improvement in nestloop benchmark
  1447. Optimization incomplete, compiler does not cycle yet with
  1448. notifications enabled.
  1449. Revision 1.45 2002/11/28 11:17:01 florian
  1450. * loop node flags from node flags splitted
  1451. Revision 1.44 2002/11/25 17:43:17 peter
  1452. * splitted defbase in defutil,symutil,defcmp
  1453. * merged isconvertable and is_equal into compare_defs(_ext)
  1454. * made operator search faster by walking the list only once
  1455. Revision 1.43 2002/09/30 07:00:45 florian
  1456. * fixes to common code to get the alpha compiler compiled applied
  1457. Revision 1.42 2002/09/07 15:25:02 peter
  1458. * old logs removed and tabs fixed
  1459. Revision 1.41 2002/09/01 18:47:00 peter
  1460. * assignn check in exitnode changed to use a separate boolean as the
  1461. assignn can be changed to a calln
  1462. Revision 1.40 2002/09/01 14:41:47 peter
  1463. * increase refcount in exit(arg) for arg
  1464. Revision 1.39 2002/08/24 18:41:52 peter
  1465. * fixed wrong label in jump of except block (was also in n386flw wrong)
  1466. * fixed wrong pushing of raise parameters
  1467. * fixed wrong compare in finally
  1468. Revision 1.38 2002/08/23 16:14:48 peter
  1469. * tempgen cleanup
  1470. * tt_noreuse temp type added that will be used in genentrycode
  1471. Revision 1.37 2002/08/19 19:36:43 peter
  1472. * More fixes for cross unit inlining, all tnodes are now implemented
  1473. * Moved pocall_internconst to po_internconst because it is not a
  1474. calling type at all and it conflicted when inlining of these small
  1475. functions was requested
  1476. Revision 1.36 2002/08/15 15:15:55 carl
  1477. * jmpbuf size allocation for exceptions is now cpu specific (as it should)
  1478. * more generic nodes for maths
  1479. * several fixes for better m68k support
  1480. Revision 1.35 2002/08/13 18:01:52 carl
  1481. * rename swatoperands to swapoperands
  1482. + m68k first compilable version (still needs a lot of testing):
  1483. assembler generator, system information , inline
  1484. assembler reader.
  1485. Revision 1.34 2002/08/11 14:32:26 peter
  1486. * renamed current_library to objectlibrary
  1487. Revision 1.33 2002/08/11 13:24:11 peter
  1488. * saving of asmsymbols in ppu supported
  1489. * asmsymbollist global is removed and moved into a new class
  1490. tasmlibrarydata that will hold the info of a .a file which
  1491. corresponds with a single module. Added librarydata to tmodule
  1492. to keep the library info stored for the module. In the future the
  1493. objectfiles will also be stored to the tasmlibrarydata class
  1494. * all getlabel/newasmsymbol and friends are moved to the new class
  1495. Revision 1.32 2002/08/09 19:10:59 carl
  1496. * fixed generic exception management
  1497. Revision 1.31 2002/08/04 19:06:41 carl
  1498. + added generic exception support (still does not work!)
  1499. + more documentation
  1500. Revision 1.30 2002/07/27 19:53:51 jonas
  1501. + generic implementation of tcg.g_flags2ref()
  1502. * tcg.flags2xxx() now also needs a size parameter
  1503. Revision 1.29 2002/07/25 17:56:29 carl
  1504. + FPURESULTREG -> FPU_RESULT_REG
  1505. Revision 1.28 2002/07/21 06:58:49 daniel
  1506. * Changed booleans into flags
  1507. Revision 1.27 2002/07/20 12:54:53 daniel
  1508. * Optimized the code generated for for nodes. The shootout/nestloop benchmark
  1509. now runs 5% faster on my computer.
  1510. Revision 1.26 2002/07/20 11:57:54 florian
  1511. * types.pas renamed to defbase.pas because D6 contains a types
  1512. unit so this would conflicts if D6 programms are compiled
  1513. + Willamette/SSE2 instructions to assembler added
  1514. Revision 1.25 2002/07/20 11:15:51 daniel
  1515. * The for node does a check if the first comparision can be skipped. I moved
  1516. the check from the second pass to the resulttype pass. The advantage is
  1517. that the state tracker can now decide to skip the first comparision too.
  1518. Revision 1.24 2002/07/20 08:14:24 daniel
  1519. * Loops should not be aligned when optimizing for size
  1520. Revision 1.23 2002/07/19 11:41:35 daniel
  1521. * State tracker work
  1522. * The whilen and repeatn are now completely unified into whilerepeatn. This
  1523. allows the state tracker to change while nodes automatically into
  1524. repeat nodes.
  1525. * Resulttypepass improvements to the notn. 'not not a' is optimized away and
  1526. 'not(a>b)' is optimized into 'a<=b'.
  1527. * Resulttypepass improvements to the whilerepeatn. 'while not a' is optimized
  1528. by removing the notn and later switchting the true and falselabels. The
  1529. same is done with 'repeat until not a'.
  1530. Revision 1.22 2002/07/04 20:43:01 florian
  1531. * first x86-64 patches
  1532. }