ncgflw.pas 66 KB

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