ncgflw.pas 48 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384
  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. tcgfailnode = class(tfailnode)
  50. procedure pass_2;override;
  51. end;
  52. tcgraisenode = class(traisenode)
  53. procedure pass_2;override;
  54. end;
  55. tcgtryexceptnode = class(ttryexceptnode)
  56. procedure pass_2;override;
  57. end;
  58. tcgtryfinallynode = class(ttryfinallynode)
  59. procedure pass_2;override;
  60. end;
  61. tcgonnode = class(tonnode)
  62. procedure pass_2;override;
  63. end;
  64. implementation
  65. uses
  66. verbose,globals,systems,globtype,
  67. symconst,symsym,aasmbase,aasmtai,aasmcpu,defbase,
  68. cginfo,cgbase,pass_2,
  69. cpubase,cpuinfo,
  70. nld,ncon,
  71. ncgutil,
  72. tgobj,rgobj,paramgr,
  73. regvars,cgobj,cgcpu,cg64f32;
  74. {*****************************************************************************
  75. Second_While_RepeatN
  76. *****************************************************************************}
  77. procedure tcgwhilerepeatnode.pass_2;
  78. var
  79. lcont,lbreak,lloop,
  80. oldclabel,oldblabel : tasmlabel;
  81. otlabel,oflabel : tasmlabel;
  82. begin
  83. objectlibrary.getlabel(lloop);
  84. objectlibrary.getlabel(lcont);
  85. objectlibrary.getlabel(lbreak);
  86. { arrange continue and breaklabels: }
  87. oldclabel:=aktcontinuelabel;
  88. oldblabel:=aktbreaklabel;
  89. load_all_regvars(exprasmlist);
  90. { handling code at the end as it is much more efficient, and makes
  91. while equal to repeat loop, only the end true/false is swapped (PFV) }
  92. if nf_testatbegin in flags then
  93. cg.a_jmp_always(exprasmlist,lcont);
  94. if not(cs_littlesize in aktglobalswitches) then
  95. { align loop target }
  96. exprasmList.concat(Tai_align.Create(aktalignment.loopalign));
  97. cg.a_label(exprasmlist,lloop);
  98. aktcontinuelabel:=lcont;
  99. aktbreaklabel:=lbreak;
  100. rg.cleartempgen;
  101. if assigned(right) then
  102. secondpass(right);
  103. load_all_regvars(exprasmlist);
  104. cg.a_label(exprasmlist,lcont);
  105. otlabel:=truelabel;
  106. oflabel:=falselabel;
  107. if nf_checknegate in flags then
  108. begin
  109. truelabel:=lbreak;
  110. falselabel:=lloop;
  111. end
  112. else
  113. begin
  114. truelabel:=lloop;
  115. falselabel:=lbreak;
  116. end;
  117. rg.cleartempgen;
  118. secondpass(left);
  119. maketojumpbool(exprasmlist,left,lr_load_regvars);
  120. cg.a_label(exprasmlist,lbreak);
  121. truelabel:=otlabel;
  122. falselabel:=oflabel;
  123. aktcontinuelabel:=oldclabel;
  124. aktbreaklabel:=oldblabel;
  125. { a break/continue in a while/repeat block can't be seen outside }
  126. flowcontrol:=flowcontrol-[fc_break,fc_continue];
  127. end;
  128. {*****************************************************************************
  129. tcgIFNODE
  130. *****************************************************************************}
  131. procedure tcgifnode.pass_2;
  132. var
  133. hl,otlabel,oflabel : tasmlabel;
  134. org_regvar_loaded,
  135. then_regvar_loaded,
  136. else_regvar_loaded : regvar_booleanarray;
  137. org_list,
  138. then_list,
  139. else_list : taasmoutput;
  140. begin
  141. otlabel:=truelabel;
  142. oflabel:=falselabel;
  143. objectlibrary.getlabel(truelabel);
  144. objectlibrary.getlabel(falselabel);
  145. rg.cleartempgen;
  146. secondpass(left);
  147. { save regvars loaded in the beginning so that we can restore them }
  148. { when processing the else-block }
  149. if cs_regalloc in aktglobalswitches then
  150. begin
  151. org_list := exprasmlist;
  152. exprasmlist := taasmoutput.create;
  153. end;
  154. maketojumpbool(exprasmlist,left,lr_dont_load_regvars);
  155. if cs_regalloc in aktglobalswitches then
  156. org_regvar_loaded := rg.regvar_loaded;
  157. if assigned(right) then
  158. begin
  159. cg.a_label(exprasmlist,truelabel);
  160. rg.cleartempgen;
  161. secondpass(right);
  162. end;
  163. { save current asmlist (previous instructions + then-block) and }
  164. { loaded regvar state and create new clean ones }
  165. if cs_regalloc in aktglobalswitches then
  166. begin
  167. then_regvar_loaded := rg.regvar_loaded;
  168. rg.regvar_loaded := org_regvar_loaded;
  169. then_list := exprasmlist;
  170. exprasmlist := taasmoutput.create;
  171. end;
  172. if assigned(t1) then
  173. begin
  174. if assigned(right) then
  175. begin
  176. objectlibrary.getlabel(hl);
  177. { do go back to if line !! }
  178. if not(cs_regalloc in aktglobalswitches) then
  179. aktfilepos:=exprasmList.getlasttaifilepos^
  180. else
  181. aktfilepos:=then_list.getlasttaifilepos^;
  182. cg.a_jmp_always(exprasmlist,hl);
  183. end;
  184. cg.a_label(exprasmlist,falselabel);
  185. rg.cleartempgen;
  186. secondpass(t1);
  187. { save current asmlist (previous instructions + else-block) }
  188. { and loaded regvar state and create a new clean list }
  189. if cs_regalloc in aktglobalswitches then
  190. begin
  191. else_regvar_loaded := rg.regvar_loaded;
  192. else_list := exprasmlist;
  193. exprasmlist := taasmoutput.create;
  194. end;
  195. if assigned(right) then
  196. cg.a_label(exprasmlist,hl);
  197. end
  198. else
  199. begin
  200. if cs_regalloc in aktglobalswitches then
  201. begin
  202. else_regvar_loaded := rg.regvar_loaded;
  203. else_list := exprasmlist;
  204. exprasmlist := taasmoutput.create;
  205. end;
  206. cg.a_label(exprasmlist,falselabel);
  207. end;
  208. if not(assigned(right)) then
  209. begin
  210. cg.a_label(exprasmlist,truelabel);
  211. end;
  212. if cs_regalloc in aktglobalswitches then
  213. begin
  214. { add loads of regvars at the end of the then- and else-blocks }
  215. { so that at the end of both blocks the same regvars are loaded }
  216. { no else block? }
  217. if not assigned(t1) then
  218. sync_regvars(org_list,then_list,org_regvar_loaded,
  219. then_regvar_loaded)
  220. { no then block? }
  221. else if not assigned(right) then
  222. sync_regvars(org_list,else_list,org_regvar_loaded,
  223. else_regvar_loaded)
  224. { both else and then blocks }
  225. else
  226. sync_regvars(then_list,else_list,then_regvar_loaded,
  227. else_regvar_loaded);
  228. { add all lists together }
  229. org_list.concatlist(then_list);
  230. then_list.free;
  231. org_list.concatlist(else_list);
  232. else_list.free;
  233. org_list.concatlist(exprasmlist);
  234. exprasmlist.free;
  235. exprasmlist := org_list;
  236. end;
  237. truelabel:=otlabel;
  238. falselabel:=oflabel;
  239. end;
  240. {*****************************************************************************
  241. SecondFor
  242. *****************************************************************************}
  243. procedure tcgfornode.pass_2;
  244. var
  245. l3,oldclabel,oldblabel : tasmlabel;
  246. temptovalue : boolean;
  247. hs : byte;
  248. temp1 : treference;
  249. hop : topcg;
  250. hcond : topcmp;
  251. opsize : tcgsize;
  252. count_var_is_signed : boolean;
  253. begin
  254. oldclabel:=aktcontinuelabel;
  255. oldblabel:=aktbreaklabel;
  256. objectlibrary.getlabel(aktcontinuelabel);
  257. objectlibrary.getlabel(aktbreaklabel);
  258. objectlibrary.getlabel(l3);
  259. { only calculate reference }
  260. rg.cleartempgen;
  261. secondpass(t2);
  262. hs := t2.resulttype.def.size;
  263. opsize := def_cgsize(t2.resulttype.def);
  264. { first set the to value
  265. because the count var can be in the expression !! }
  266. rg.cleartempgen;
  267. secondpass(right);
  268. { calculate pointer value and check if changeable and if so }
  269. { load into temporary variable }
  270. if right.nodetype<>ordconstn then
  271. begin
  272. temp1.symbol:=nil;
  273. tg.gettempofsizereference(exprasmlist,hs,temp1);
  274. temptovalue:=true;
  275. if (right.location.loc=LOC_REGISTER) or
  276. (right.location.loc=LOC_CREGISTER) then
  277. begin
  278. cg.a_load_reg_ref(exprasmlist,opsize,
  279. right.location.register,temp1);
  280. rg.ungetregister(exprasmlist,right.location.register);
  281. end
  282. else
  283. cg.g_concatcopy(exprasmlist,right.location.reference,temp1,
  284. hs,true,false);
  285. end
  286. else
  287. temptovalue:=false;
  288. { produce start assignment }
  289. rg.cleartempgen;
  290. secondpass(left);
  291. count_var_is_signed:=is_signed(t2.resulttype.def);
  292. if nf_backward in flags then
  293. if count_var_is_signed then
  294. hcond:=OC_LT
  295. else
  296. hcond:=OC_B
  297. else
  298. if count_var_is_signed then
  299. hcond:=OC_GT
  300. else
  301. hcond:=OC_A;
  302. load_all_regvars(exprasmlist);
  303. if temptovalue then
  304. begin
  305. cg.a_cmp_ref_loc_label(exprasmlist,opsize,hcond,
  306. temp1,t2.location,aktbreaklabel);
  307. end
  308. else
  309. begin
  310. if nf_testatbegin in flags then
  311. begin
  312. cg.a_cmp_const_loc_label(exprasmlist,opsize,hcond,
  313. aword(tordconstnode(right).value),
  314. t2.location,aktbreaklabel);
  315. end;
  316. end;
  317. if nf_backward in flags then
  318. hop:=OP_ADD
  319. else
  320. hop:=OP_SUB;
  321. cg.a_op_const_loc(exprasmlist,hop,1,t2.location);
  322. if not(cs_littlesize in aktglobalswitches) then
  323. { align loop target }
  324. exprasmList.concat(Tai_align.Create(aktalignment.loopalign));
  325. cg.a_label(exprasmlist,l3);
  326. { according to count direction DEC or INC... }
  327. if nf_backward in flags then
  328. hop:=OP_SUB
  329. else
  330. hop:=OP_ADD;
  331. cg.a_op_const_loc(exprasmlist,hop,1,t2.location);
  332. { help register must not be in instruction block }
  333. rg.cleartempgen;
  334. if assigned(t1) then
  335. begin
  336. secondpass(t1);
  337. load_all_regvars(exprasmlist);
  338. end;
  339. cg.a_label(exprasmlist,aktcontinuelabel);
  340. { makes no problems there }
  341. rg.cleartempgen;
  342. if nf_backward in flags then
  343. if count_var_is_signed then
  344. hcond:=OC_GT
  345. else
  346. hcond:=OC_A
  347. else
  348. if count_var_is_signed then
  349. hcond:=OC_LT
  350. else
  351. hcond:=OC_B;
  352. load_all_regvars(exprasmlist);
  353. { produce comparison and the corresponding }
  354. { jump }
  355. if temptovalue then
  356. begin
  357. cg.a_cmp_ref_loc_label(exprasmlist,opsize,hcond,temp1,
  358. t2.location,l3);
  359. end
  360. else
  361. begin
  362. cg.a_cmp_const_loc_label(exprasmlist,opsize,hcond,
  363. aword(tordconstnode(right).value),t2.location,l3);
  364. end;
  365. if temptovalue then
  366. tg.ungetiftemp(exprasmlist,temp1);
  367. { this is the break label: }
  368. cg.a_label(exprasmlist,aktbreaklabel);
  369. aktcontinuelabel:=oldclabel;
  370. aktbreaklabel:=oldblabel;
  371. { a break/continue in a for block can't be seen outside }
  372. flowcontrol:=flowcontrol-[fc_break,fc_continue];
  373. end;
  374. {*****************************************************************************
  375. SecondExitN
  376. *****************************************************************************}
  377. procedure tcgexitnode.pass_2;
  378. var
  379. {op : tasmop;
  380. s : topsize;}
  381. otlabel,oflabel : tasmlabel;
  382. cgsize : tcgsize;
  383. hreg : tregister;
  384. allocated_acc,
  385. allocated_acchigh: boolean;
  386. label
  387. do_jmp;
  388. begin
  389. { load_all_regvars(exprasmlist); }
  390. include(flowcontrol,fc_exit);
  391. if assigned(left) then
  392. if left.nodetype=assignn then
  393. begin
  394. { just do a normal assignment followed by exit }
  395. secondpass(left);
  396. cg.a_jmp_always(exprasmlist,aktexitlabel);
  397. end
  398. else
  399. begin
  400. allocated_acc := false;
  401. allocated_acchigh := false;
  402. otlabel:=truelabel;
  403. oflabel:=falselabel;
  404. objectlibrary.getlabel(truelabel);
  405. objectlibrary.getlabel(falselabel);
  406. secondpass(left);
  407. { the result of left is not needed anymore after this
  408. node }
  409. location_freetemp(exprasmlist,left.location);
  410. location_release(exprasmlist,left.location);
  411. case left.location.loc of
  412. LOC_FPUREGISTER :
  413. goto do_jmp;
  414. LOC_FLAGS :
  415. begin
  416. cg.a_reg_alloc(exprasmlist,accumulator);
  417. allocated_acc := true;
  418. cg.g_flags2reg(exprasmlist,OS_INT,left.location.resflags,accumulator);
  419. goto do_jmp;
  420. end;
  421. LOC_JUMP :
  422. begin
  423. cg.a_reg_alloc(exprasmlist,accumulator);
  424. { get an 8-bit register }
  425. hreg:=rg.makeregsize(accumulator,OS_8);
  426. allocated_acc := true;
  427. cg.a_label(exprasmlist,truelabel);
  428. cg.a_load_const_reg(exprasmlist,OS_8,1,hreg);
  429. cg.a_jmp_always(exprasmlist,aktexit2label);
  430. cg.a_label(exprasmlist,falselabel);
  431. cg.a_load_const_reg(exprasmlist,OS_8,0,hreg);
  432. goto do_jmp;
  433. end;
  434. end;
  435. case aktprocdef.rettype.def.deftype of
  436. pointerdef,
  437. procvardef :
  438. begin
  439. cg.a_reg_alloc(exprasmlist,accumulator);
  440. allocated_acc := true;
  441. cg.a_load_loc_reg(exprasmlist,left.location,accumulator);
  442. end;
  443. floatdef :
  444. begin
  445. {$ifndef i386}
  446. cg.a_reg_alloc(exprasmlist,FPU_RESULT_REG);
  447. {$endif not i386}
  448. cg.a_loadfpu_loc_reg(exprasmlist,left.location,FPU_RESULT_REG);
  449. end;
  450. else
  451. begin
  452. cgsize:=def_cgsize(aktprocdef.rettype.def);
  453. cg.a_reg_alloc(exprasmlist,accumulator);
  454. allocated_acc := true;
  455. case cgsize of
  456. OS_64,OS_S64 :
  457. begin
  458. cg.a_reg_alloc(exprasmlist,accumulatorhigh);
  459. allocated_acchigh := true;
  460. cg64.a_load64_loc_reg(exprasmlist,left.location,
  461. joinreg64(accumulator,accumulatorhigh));
  462. end
  463. else
  464. begin
  465. hreg:=rg.makeregsize(accumulator,cgsize);
  466. cg.a_load_loc_reg(exprasmlist,left.location,hreg);
  467. end;
  468. end;
  469. end;
  470. end;
  471. do_jmp:
  472. truelabel:=otlabel;
  473. falselabel:=oflabel;
  474. cg.a_jmp_always(exprasmlist,aktexit2label);
  475. if allocated_acc then
  476. cg.a_reg_dealloc(exprasmlist,accumulator);
  477. if allocated_acchigh then
  478. cg.a_reg_dealloc(exprasmlist,accumulatorhigh);
  479. {$ifndef i386}
  480. if (aktprocdef.rettype.def.deftype = floatdef) then
  481. cg.a_reg_dealloc(exprasmlist,FPU_RESULT_REG);
  482. {$endif not i386}
  483. end
  484. else
  485. cg.a_jmp_always(exprasmlist,aktexitlabel);
  486. end;
  487. {*****************************************************************************
  488. SecondBreakN
  489. *****************************************************************************}
  490. procedure tcgbreaknode.pass_2;
  491. begin
  492. include(flowcontrol,fc_break);
  493. if aktbreaklabel<>nil then
  494. begin
  495. load_all_regvars(exprasmlist);
  496. cg.a_jmp_always(exprasmlist,aktbreaklabel)
  497. end
  498. else
  499. CGMessage(cg_e_break_not_allowed);
  500. end;
  501. {*****************************************************************************
  502. SecondContinueN
  503. *****************************************************************************}
  504. procedure tcgcontinuenode.pass_2;
  505. begin
  506. include(flowcontrol,fc_continue);
  507. if aktcontinuelabel<>nil then
  508. begin
  509. load_all_regvars(exprasmlist);
  510. cg.a_jmp_always(exprasmlist,aktcontinuelabel)
  511. end
  512. else
  513. CGMessage(cg_e_continue_not_allowed);
  514. end;
  515. {*****************************************************************************
  516. SecondGoto
  517. *****************************************************************************}
  518. procedure tcggotonode.pass_2;
  519. begin
  520. load_all_regvars(exprasmlist);
  521. cg.a_jmp_always(exprasmlist,labelnr)
  522. end;
  523. {*****************************************************************************
  524. SecondLabel
  525. *****************************************************************************}
  526. procedure tcglabelnode.pass_2;
  527. begin
  528. load_all_regvars(exprasmlist);
  529. cg.a_label(exprasmlist,labelnr);
  530. rg.cleartempgen;
  531. secondpass(left);
  532. end;
  533. {*****************************************************************************
  534. SecondFail
  535. *****************************************************************************}
  536. procedure tcgfailnode.pass_2;
  537. begin
  538. cg.a_jmp_always(exprasmlist,faillabel);
  539. end;
  540. {*****************************************************************************
  541. SecondRaise
  542. *****************************************************************************}
  543. procedure tcgraisenode.pass_2;
  544. var
  545. a : tasmlabel;
  546. href : treference;
  547. href2: treference;
  548. begin
  549. if assigned(left) then
  550. begin
  551. { multiple parameters? }
  552. if assigned(right) then
  553. begin
  554. { push frame }
  555. if assigned(frametree) then
  556. begin
  557. secondpass(frametree);
  558. if codegenerror then
  559. exit;
  560. cg.a_param_loc(exprasmlist,frametree.location,paramanager.getintparaloc(2));
  561. end
  562. else
  563. cg.a_param_const(exprasmlist,OS_INT,0,paramanager.getintparaloc(2));
  564. { push address }
  565. secondpass(right);
  566. if codegenerror then
  567. exit;
  568. cg.a_param_loc(exprasmlist,right.location,paramanager.getintparaloc(1));
  569. end
  570. else
  571. begin
  572. objectlibrary.getaddrlabel(a);
  573. cg.a_label(exprasmlist,a);
  574. reference_reset_symbol(href2,a,0);
  575. cg.a_paramaddr_ref(exprasmlist,href2,paramanager.getintparaloc(2));
  576. cg.a_param_reg(exprasmlist,OS_ADDR,FRAME_POINTER_REG,paramanager.getintparaloc(3));
  577. end;
  578. { push object }
  579. secondpass(left);
  580. if codegenerror then
  581. exit;
  582. cg.a_param_loc(exprasmlist,left.location,paramanager.getintparaloc(1));
  583. cg.a_call_name(exprasmlist,'FPC_RAISEEXCEPTION');
  584. end
  585. else
  586. begin
  587. cg.a_call_name(exprasmlist,'FPC_POPADDRSTACK');
  588. cg.a_call_name(exprasmlist,'FPC_RERAISE');
  589. end;
  590. end;
  591. {*****************************************************************************
  592. SecondTryExcept
  593. *****************************************************************************}
  594. var
  595. endexceptlabel : tasmlabel;
  596. procedure try_new_exception(list : taasmoutput;var jmpbuf,envbuf, href : treference;
  597. a : aword; exceptlabel : tasmlabel);
  598. begin
  599. tg.gettempofsizereferencepersistant(list,24,jmpbuf);
  600. tg.gettempofsizereferencepersistant(list,12,envbuf);
  601. tg.gettempofsizereferencepersistant(list,sizeof(aword),href);
  602. new_exception(list, jmpbuf,envbuf, href, a, exceptlabel);
  603. end;
  604. procedure try_free_exception(list : taasmoutput;var jmpbuf, envbuf, href : treference;
  605. a : aword ; endexceptlabel : tasmlabel; onlyfree : boolean);
  606. begin
  607. free_exception(list, jmpbuf, envbuf, href, a, endexceptlabel, onlyfree);
  608. tg.ungetpersistanttempreference(list,jmpbuf);
  609. tg.ungetpersistanttempreference(list,envbuf);
  610. end;
  611. { does the necessary things to clean up the object stack }
  612. { in the except block }
  613. procedure cleanupobjectstack;
  614. begin
  615. cg.a_call_name(exprasmlist,'FPC_POPOBJECTSTACK');
  616. cg.a_param_reg(exprasmlist,OS_ADDR,accumulator,paramanager.getintparaloc(1));
  617. cg.a_call_name(exprasmlist,'FPC_DESTROYEXCEPTION');
  618. cg.g_maybe_loadself(exprasmlist);
  619. end;
  620. procedure tcgtryexceptnode.pass_2;
  621. var
  622. exceptlabel,doexceptlabel,oldendexceptlabel,
  623. lastonlabel,
  624. exitexceptlabel,
  625. continueexceptlabel,
  626. breakexceptlabel,
  627. exittrylabel,
  628. continuetrylabel,
  629. breaktrylabel,
  630. doobjectdestroy,
  631. doobjectdestroyandreraise,
  632. oldaktexitlabel,
  633. oldaktexit2label,
  634. oldaktcontinuelabel,
  635. oldaktbreaklabel : tasmlabel;
  636. oldflowcontrol,tryflowcontrol,
  637. exceptflowcontrol : tflowcontrol;
  638. tempbuf,tempaddr : treference;
  639. href : treference;
  640. label
  641. errorexit;
  642. begin
  643. oldflowcontrol:=flowcontrol;
  644. flowcontrol:=[];
  645. { this can be called recursivly }
  646. oldendexceptlabel:=endexceptlabel;
  647. { save the old labels for control flow statements }
  648. oldaktexitlabel:=aktexitlabel;
  649. oldaktexit2label:=aktexit2label;
  650. if assigned(aktbreaklabel) then
  651. begin
  652. oldaktcontinuelabel:=aktcontinuelabel;
  653. oldaktbreaklabel:=aktbreaklabel;
  654. end;
  655. { get new labels for the control flow statements }
  656. objectlibrary.getlabel(exittrylabel);
  657. objectlibrary.getlabel(exitexceptlabel);
  658. if assigned(aktbreaklabel) then
  659. begin
  660. objectlibrary.getlabel(breaktrylabel);
  661. objectlibrary.getlabel(continuetrylabel);
  662. objectlibrary.getlabel(breakexceptlabel);
  663. objectlibrary.getlabel(continueexceptlabel);
  664. end;
  665. objectlibrary.getlabel(exceptlabel);
  666. objectlibrary.getlabel(doexceptlabel);
  667. objectlibrary.getlabel(endexceptlabel);
  668. objectlibrary.getlabel(lastonlabel);
  669. try_new_exception(exprasmlist,tempbuf,tempaddr,href,1,exceptlabel);
  670. { try block }
  671. { set control flow labels for the try block }
  672. aktexitlabel:=exittrylabel;
  673. aktexit2label:=exittrylabel;
  674. if assigned(oldaktbreaklabel) then
  675. begin
  676. aktcontinuelabel:=continuetrylabel;
  677. aktbreaklabel:=breaktrylabel;
  678. end;
  679. flowcontrol:=[];
  680. secondpass(left);
  681. tryflowcontrol:=flowcontrol;
  682. if codegenerror then
  683. goto errorexit;
  684. cg.a_label(exprasmlist,exceptlabel);
  685. try_free_exception(exprasmlist,tempbuf,tempaddr,href,0,endexceptlabel,false);
  686. cg.a_label(exprasmlist,doexceptlabel);
  687. { set control flow labels for the except block }
  688. { and the on statements }
  689. aktexitlabel:=exitexceptlabel;
  690. aktexit2label:=exitexceptlabel;
  691. if assigned(oldaktbreaklabel) then
  692. begin
  693. aktcontinuelabel:=continueexceptlabel;
  694. aktbreaklabel:=breakexceptlabel;
  695. end;
  696. flowcontrol:=[];
  697. { on statements }
  698. if assigned(right) then
  699. secondpass(right);
  700. cg.a_label(exprasmlist,lastonlabel);
  701. { default handling except handling }
  702. if assigned(t1) then
  703. begin
  704. { FPC_CATCHES must be called with
  705. 'default handler' flag (=-1)
  706. }
  707. cg.a_param_const(exprasmlist,OS_ADDR,aword(-1),paramanager.getintparaloc(1));
  708. cg.a_call_name(exprasmlist,'FPC_CATCHES');
  709. cg.g_maybe_loadself(exprasmlist);
  710. { the destruction of the exception object must be also }
  711. { guarded by an exception frame }
  712. objectlibrary.getlabel(doobjectdestroy);
  713. objectlibrary.getlabel(doobjectdestroyandreraise);
  714. try_new_exception(exprasmlist,tempbuf,tempaddr,href,1,exceptlabel);
  715. { here we don't have to reset flowcontrol }
  716. { the default and on flowcontrols are handled equal }
  717. secondpass(t1);
  718. exceptflowcontrol:=flowcontrol;
  719. cg.a_label(exprasmlist,doobjectdestroyandreraise);
  720. try_free_exception(exprasmlist,tempbuf,tempaddr,href,0,doobjectdestroy,false);
  721. cg.a_call_name(exprasmlist,'FPC_POPSECONDOBJECTSTACK');
  722. cg.a_param_reg(exprasmlist, OS_ADDR, accumulator, paramanager.getintparaloc(1));
  723. cg.a_call_name(exprasmlist,'FPC_DESTROYEXCEPTION');
  724. { we don't need to restore esi here because reraise never }
  725. { returns }
  726. cg.a_call_name(exprasmlist,'FPC_RERAISE');
  727. cg.a_label(exprasmlist,doobjectdestroy);
  728. cleanupobjectstack;
  729. cg.a_jmp_always(exprasmlist,endexceptlabel);
  730. end
  731. else
  732. begin
  733. cg.a_call_name(exprasmlist,'FPC_RERAISE');
  734. exceptflowcontrol:=flowcontrol;
  735. end;
  736. if fc_exit in exceptflowcontrol then
  737. begin
  738. { do some magic for exit in the try block }
  739. cg.a_label(exprasmlist,exitexceptlabel);
  740. { we must also destroy the address frame which guards }
  741. { exception object }
  742. cg.a_call_name(exprasmlist,'FPC_POPADDRSTACK');
  743. cg.g_exception_reason_load(exprasmlist,href);
  744. cleanupobjectstack;
  745. cg.a_jmp_always(exprasmlist,oldaktexitlabel);
  746. end;
  747. if fc_break in exceptflowcontrol then
  748. begin
  749. cg.a_label(exprasmlist,breakexceptlabel);
  750. { we must also destroy the address frame which guards }
  751. { exception object }
  752. cg.a_call_name(exprasmlist,'FPC_POPADDRSTACK');
  753. cg.g_exception_reason_load(exprasmlist,href);
  754. cleanupobjectstack;
  755. cg.a_jmp_always(exprasmlist,oldaktbreaklabel);
  756. end;
  757. if fc_continue in exceptflowcontrol then
  758. begin
  759. cg.a_label(exprasmlist,continueexceptlabel);
  760. { we must also destroy the address frame which guards }
  761. { exception object }
  762. cg.a_call_name(exprasmlist,'FPC_POPADDRSTACK');
  763. cg.g_exception_reason_load(exprasmlist,href);
  764. cleanupobjectstack;
  765. cg.a_jmp_always(exprasmlist,oldaktcontinuelabel);
  766. end;
  767. if fc_exit in tryflowcontrol then
  768. begin
  769. { do some magic for exit in the try block }
  770. cg.a_label(exprasmlist,exittrylabel);
  771. cg.a_call_name(exprasmlist,'FPC_POPADDRSTACK');
  772. cg.g_exception_reason_load(exprasmlist,href);
  773. cg.a_jmp_always(exprasmlist,oldaktexitlabel);
  774. end;
  775. if fc_break in tryflowcontrol then
  776. begin
  777. cg.a_label(exprasmlist,breaktrylabel);
  778. cg.a_call_name(exprasmlist,'FPC_POPADDRSTACK');
  779. cg.g_exception_reason_load(exprasmlist,href);
  780. cg.a_jmp_always(exprasmlist,oldaktbreaklabel);
  781. end;
  782. if fc_continue in tryflowcontrol then
  783. begin
  784. cg.a_label(exprasmlist,continuetrylabel);
  785. cg.a_call_name(exprasmlist,'FPC_POPADDRSTACK');
  786. cg.g_exception_reason_load(exprasmlist,href);
  787. cg.a_jmp_always(exprasmlist,oldaktcontinuelabel);
  788. end;
  789. cg.a_label(exprasmlist,endexceptlabel);
  790. errorexit:
  791. { restore all saved labels }
  792. endexceptlabel:=oldendexceptlabel;
  793. { restore the control flow labels }
  794. aktexitlabel:=oldaktexitlabel;
  795. aktexit2label:=oldaktexit2label;
  796. if assigned(oldaktbreaklabel) then
  797. begin
  798. aktcontinuelabel:=oldaktcontinuelabel;
  799. aktbreaklabel:=oldaktbreaklabel;
  800. end;
  801. { return all used control flow statements }
  802. flowcontrol:=oldflowcontrol+exceptflowcontrol+
  803. tryflowcontrol;
  804. end;
  805. procedure tcgonnode.pass_2;
  806. var
  807. nextonlabel,
  808. exitonlabel,
  809. continueonlabel,
  810. breakonlabel,
  811. oldaktexitlabel,
  812. oldaktexit2label,
  813. oldaktcontinuelabel,
  814. doobjectdestroyandreraise,
  815. doobjectdestroy,
  816. oldaktbreaklabel : tasmlabel;
  817. ref : treference;
  818. oldflowcontrol : tflowcontrol;
  819. tempbuf,tempaddr : treference;
  820. href : treference;
  821. href2: treference;
  822. begin
  823. oldflowcontrol:=flowcontrol;
  824. flowcontrol:=[];
  825. objectlibrary.getlabel(nextonlabel);
  826. { send the vmt parameter }
  827. reference_reset_symbol(href2,objectlibrary.newasmsymbol(excepttype.vmt_mangledname),0);
  828. cg.a_paramaddr_ref(exprasmlist,href2,paramanager.getintparaloc(1));
  829. cg.a_call_name(exprasmlist,'FPC_CATCHES');
  830. { is it this catch? No. go to next onlabel }
  831. cg.a_cmp_const_reg_label(exprasmlist,OS_ADDR,OC_EQ,0,accumulator,nextonlabel);
  832. ref.symbol:=nil;
  833. tg.gettempofsizereference(exprasmlist,pointer_size,ref);
  834. { what a hack ! }
  835. if assigned(exceptsymtable) then
  836. tvarsym(exceptsymtable.symindex.first).address:=ref.offset;
  837. cg.a_load_reg_ref(exprasmlist, OS_ADDR, accumulator, ref);
  838. { in the case that another exception is risen }
  839. { we've to destroy the old one }
  840. objectlibrary.getlabel(doobjectdestroyandreraise);
  841. { call setjmp, and jump to finally label on non-zero result }
  842. try_new_exception(exprasmlist,tempbuf,tempaddr,href,1,doobjectdestroyandreraise);
  843. if assigned(right) then
  844. begin
  845. oldaktexitlabel:=aktexitlabel;
  846. oldaktexit2label:=aktexit2label;
  847. objectlibrary.getlabel(exitonlabel);
  848. aktexitlabel:=exitonlabel;
  849. aktexit2label:=exitonlabel;
  850. if assigned(aktbreaklabel) then
  851. begin
  852. oldaktcontinuelabel:=aktcontinuelabel;
  853. oldaktbreaklabel:=aktbreaklabel;
  854. objectlibrary.getlabel(breakonlabel);
  855. objectlibrary.getlabel(continueonlabel);
  856. aktcontinuelabel:=continueonlabel;
  857. aktbreaklabel:=breakonlabel;
  858. end;
  859. { esi is destroyed by FPC_CATCHES }
  860. cg.g_maybe_loadself(exprasmlist);
  861. secondpass(right);
  862. end;
  863. objectlibrary.getlabel(doobjectdestroy);
  864. cg.a_label(exprasmlist,doobjectdestroyandreraise);
  865. try_free_exception(exprasmlist,tempbuf,tempaddr,href,0,doobjectdestroy,false);
  866. cg.a_call_name(exprasmlist,'FPC_POPSECONDOBJECTSTACK');
  867. cg.a_param_reg(exprasmlist, OS_ADDR, accumulator, paramanager.getintparaloc(1));
  868. cg.a_call_name(exprasmlist,'FPC_DESTROYEXCEPTION');
  869. { we don't need to restore esi here because reraise never }
  870. { returns }
  871. cg.a_call_name(exprasmlist,'FPC_RERAISE');
  872. cg.a_label(exprasmlist,doobjectdestroy);
  873. cleanupobjectstack;
  874. { clear some stuff }
  875. tg.ungetiftemp(exprasmlist,ref);
  876. cg.a_jmp_always(exprasmlist,endexceptlabel);
  877. if assigned(right) then
  878. begin
  879. { special handling for control flow instructions }
  880. if fc_exit in flowcontrol then
  881. begin
  882. { the address and object pop does secondtryexcept }
  883. cg.a_label(exprasmlist,exitonlabel);
  884. cg.a_jmp_always(exprasmlist,oldaktexitlabel);
  885. end;
  886. if fc_break in flowcontrol then
  887. begin
  888. { the address and object pop does secondtryexcept }
  889. cg.a_label(exprasmlist,breakonlabel);
  890. cg.a_jmp_always(exprasmlist,oldaktbreaklabel);
  891. end;
  892. if fc_continue in flowcontrol then
  893. begin
  894. { the address and object pop does secondtryexcept }
  895. cg.a_label(exprasmlist,continueonlabel);
  896. cg.a_jmp_always(exprasmlist,oldaktcontinuelabel);
  897. end;
  898. aktexitlabel:=oldaktexitlabel;
  899. aktexit2label:=oldaktexit2label;
  900. if assigned(oldaktbreaklabel) then
  901. begin
  902. aktcontinuelabel:=oldaktcontinuelabel;
  903. aktbreaklabel:=oldaktbreaklabel;
  904. end;
  905. end;
  906. cg.a_label(exprasmlist,nextonlabel);
  907. flowcontrol:=oldflowcontrol+flowcontrol;
  908. { next on node }
  909. if assigned(left) then
  910. begin
  911. rg.cleartempgen;
  912. secondpass(left);
  913. end;
  914. end;
  915. {*****************************************************************************
  916. SecondTryFinally
  917. *****************************************************************************}
  918. procedure tcgtryfinallynode.pass_2;
  919. var
  920. reraiselabel,
  921. finallylabel,
  922. endfinallylabel,
  923. exitfinallylabel,
  924. continuefinallylabel,
  925. breakfinallylabel,
  926. oldaktexitlabel,
  927. oldaktexit2label,
  928. oldaktcontinuelabel,
  929. oldaktbreaklabel : tasmlabel;
  930. oldflowcontrol,tryflowcontrol : tflowcontrol;
  931. decconst : longint;
  932. tempbuf,tempaddr : treference;
  933. href : treference;
  934. begin
  935. { check if child nodes do a break/continue/exit }
  936. oldflowcontrol:=flowcontrol;
  937. flowcontrol:=[];
  938. objectlibrary.getlabel(finallylabel);
  939. objectlibrary.getlabel(endfinallylabel);
  940. objectlibrary.getlabel(reraiselabel);
  941. { the finally block must catch break, continue and exit }
  942. { statements }
  943. oldaktexitlabel:=aktexitlabel;
  944. oldaktexit2label:=aktexit2label;
  945. objectlibrary.getlabel(exitfinallylabel);
  946. aktexitlabel:=exitfinallylabel;
  947. aktexit2label:=exitfinallylabel;
  948. if assigned(aktbreaklabel) then
  949. begin
  950. oldaktcontinuelabel:=aktcontinuelabel;
  951. oldaktbreaklabel:=aktbreaklabel;
  952. objectlibrary.getlabel(breakfinallylabel);
  953. objectlibrary.getlabel(continuefinallylabel);
  954. aktcontinuelabel:=continuefinallylabel;
  955. aktbreaklabel:=breakfinallylabel;
  956. end;
  957. { call setjmp, and jump to finally label on non-zero result }
  958. try_new_exception(exprasmlist,tempbuf,tempaddr,href,1,finallylabel);
  959. { try code }
  960. if assigned(left) then
  961. begin
  962. secondpass(left);
  963. tryflowcontrol:=flowcontrol;
  964. if codegenerror then
  965. exit;
  966. end;
  967. cg.a_label(exprasmlist,finallylabel);
  968. { just free the frame information }
  969. try_free_exception(exprasmlist,tempbuf,tempaddr,href,1,finallylabel,true);
  970. { finally code }
  971. flowcontrol:=[];
  972. secondpass(right);
  973. if flowcontrol<>[] then
  974. CGMessage(cg_e_control_flow_outside_finally);
  975. if codegenerror then
  976. exit;
  977. { the value should now be in the exception handler }
  978. cg.g_exception_reason_load(exprasmlist,href);
  979. cg.a_cmp_reg_reg_label(exprasmlist,OS_S32,OC_NE,accumulator,accumulator,finallylabel);
  980. cg.a_op_const_reg(exprasmlist,OP_SUB,1,accumulator);
  981. cg.a_cmp_const_reg_label(exprasmlist,OS_S32,OC_EQ,0,accumulator,reraiselabel);
  982. if fc_exit in tryflowcontrol then
  983. begin
  984. cg.a_op_const_reg(exprasmlist,OP_SUB,1,accumulator);
  985. cg.a_cmp_const_reg_label(exprasmlist,OS_S32,OC_EQ,0,accumulator,oldaktexitlabel);
  986. decconst:=1;
  987. end
  988. else
  989. decconst:=2;
  990. if fc_break in tryflowcontrol then
  991. begin
  992. cg.a_op_const_reg(exprasmlist,OP_SUB,decconst,accumulator);
  993. cg.a_cmp_const_reg_label(exprasmlist,OS_S32,OC_EQ,0,accumulator,oldaktbreaklabel);
  994. decconst:=1;
  995. end
  996. else
  997. inc(decconst);
  998. if fc_continue in tryflowcontrol then
  999. begin
  1000. cg.a_op_const_reg(exprasmlist,OP_SUB,decconst,accumulator);
  1001. cg.a_cmp_const_reg_label(exprasmlist,OS_S32,OC_EQ,0,accumulator,oldaktcontinuelabel);
  1002. end;
  1003. cg.a_label(exprasmlist,reraiselabel);
  1004. cg.a_call_name(exprasmlist,'FPC_RERAISE');
  1005. { do some magic for exit,break,continue in the try block }
  1006. if fc_exit in tryflowcontrol then
  1007. begin
  1008. cg.a_label(exprasmlist,exitfinallylabel);
  1009. cg.g_exception_reason_load(exprasmlist,href);
  1010. cg.g_exception_reason_save_const(exprasmlist,href,2);
  1011. cg.a_jmp_always(exprasmlist,finallylabel);
  1012. end;
  1013. if fc_break in tryflowcontrol then
  1014. begin
  1015. cg.a_label(exprasmlist,breakfinallylabel);
  1016. cg.g_exception_reason_load(exprasmlist,href);
  1017. cg.g_exception_reason_save_const(exprasmlist,href,3);
  1018. cg.a_jmp_always(exprasmlist,finallylabel);
  1019. end;
  1020. if fc_continue in tryflowcontrol then
  1021. begin
  1022. cg.a_label(exprasmlist,continuefinallylabel);
  1023. cg.g_exception_reason_load(exprasmlist,href);
  1024. cg.g_exception_reason_save_const(exprasmlist,href,4);
  1025. cg.a_jmp_always(exprasmlist,finallylabel);
  1026. end;
  1027. cg.a_label(exprasmlist,endfinallylabel);
  1028. aktexitlabel:=oldaktexitlabel;
  1029. aktexit2label:=oldaktexit2label;
  1030. if assigned(aktbreaklabel) then
  1031. begin
  1032. aktcontinuelabel:=oldaktcontinuelabel;
  1033. aktbreaklabel:=oldaktbreaklabel;
  1034. end;
  1035. flowcontrol:=oldflowcontrol+tryflowcontrol;
  1036. end;
  1037. begin
  1038. cwhilerepeatnode:=tcgwhilerepeatnode;
  1039. cifnode:=tcgifnode;
  1040. cfornode:=tcgfornode;
  1041. cexitnode:=tcgexitnode;
  1042. cbreaknode:=tcgbreaknode;
  1043. ccontinuenode:=tcgcontinuenode;
  1044. cgotonode:=tcggotonode;
  1045. clabelnode:=tcglabelnode;
  1046. cfailnode:=tcgfailnode;
  1047. craisenode:=tcgraisenode;
  1048. ctryexceptnode:=tcgtryexceptnode;
  1049. ctryfinallynode:=tcgtryfinallynode;
  1050. connode:=tcgonnode;
  1051. end.
  1052. {
  1053. $Log$
  1054. Revision 1.35 2002-08-13 18:01:52 carl
  1055. * rename swatoperands to swapoperands
  1056. + m68k first compilable version (still needs a lot of testing):
  1057. assembler generator, system information , inline
  1058. assembler reader.
  1059. Revision 1.34 2002/08/11 14:32:26 peter
  1060. * renamed current_library to objectlibrary
  1061. Revision 1.33 2002/08/11 13:24:11 peter
  1062. * saving of asmsymbols in ppu supported
  1063. * asmsymbollist global is removed and moved into a new class
  1064. tasmlibrarydata that will hold the info of a .a file which
  1065. corresponds with a single module. Added librarydata to tmodule
  1066. to keep the library info stored for the module. In the future the
  1067. objectfiles will also be stored to the tasmlibrarydata class
  1068. * all getlabel/newasmsymbol and friends are moved to the new class
  1069. Revision 1.32 2002/08/09 19:10:59 carl
  1070. * fixed generic exception management
  1071. Revision 1.31 2002/08/04 19:06:41 carl
  1072. + added generic exception support (still does not work!)
  1073. + more documentation
  1074. Revision 1.30 2002/07/27 19:53:51 jonas
  1075. + generic implementation of tcg.g_flags2ref()
  1076. * tcg.flags2xxx() now also needs a size parameter
  1077. Revision 1.29 2002/07/25 17:56:29 carl
  1078. + FPURESULTREG -> FPU_RESULT_REG
  1079. Revision 1.28 2002/07/21 06:58:49 daniel
  1080. * Changed booleans into flags
  1081. Revision 1.27 2002/07/20 12:54:53 daniel
  1082. * Optimized the code generated for for nodes. The shootout/nestloop benchmark
  1083. now runs 5% faster on my computer.
  1084. Revision 1.26 2002/07/20 11:57:54 florian
  1085. * types.pas renamed to defbase.pas because D6 contains a types
  1086. unit so this would conflicts if D6 programms are compiled
  1087. + Willamette/SSE2 instructions to assembler added
  1088. Revision 1.25 2002/07/20 11:15:51 daniel
  1089. * The for node does a check if the first comparision can be skipped. I moved
  1090. the check from the second pass to the resulttype pass. The advantage is
  1091. that the state tracker can now decide to skip the first comparision too.
  1092. Revision 1.24 2002/07/20 08:14:24 daniel
  1093. * Loops should not be aligned when optimizing for size
  1094. Revision 1.23 2002/07/19 11:41:35 daniel
  1095. * State tracker work
  1096. * The whilen and repeatn are now completely unified into whilerepeatn. This
  1097. allows the state tracker to change while nodes automatically into
  1098. repeat nodes.
  1099. * Resulttypepass improvements to the notn. 'not not a' is optimized away and
  1100. 'not(a>b)' is optimized into 'a<=b'.
  1101. * Resulttypepass improvements to the whilerepeatn. 'while not a' is optimized
  1102. by removing the notn and later switchting the true and falselabels. The
  1103. same is done with 'repeat until not a'.
  1104. Revision 1.22 2002/07/04 20:43:01 florian
  1105. * first x86-64 patches
  1106. Revision 1.21 2002/07/01 18:46:22 peter
  1107. * internal linker
  1108. * reorganized aasm layer
  1109. Revision 1.20 2002/07/01 16:23:53 peter
  1110. * cg64 patch
  1111. * basics for currency
  1112. * asnode updates for class and interface (not finished)
  1113. Revision 1.19 2002/05/20 13:30:40 carl
  1114. * bugfix of hdisponen (base must be set, not index)
  1115. * more portability fixes
  1116. Revision 1.18 2002/05/18 13:34:09 peter
  1117. * readded missing revisions
  1118. Revision 1.17 2002/05/16 19:46:37 carl
  1119. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  1120. + try to fix temp allocation (still in ifdef)
  1121. + generic constructor calls
  1122. + start of tassembler / tmodulebase class cleanup
  1123. Revision 1.15 2002/05/13 19:54:37 peter
  1124. * removed n386ld and n386util units
  1125. * maybe_save/maybe_restore added instead of the old maybe_push
  1126. Revision 1.14 2002/05/12 16:53:07 peter
  1127. * moved entry and exitcode to ncgutil and cgobj
  1128. * foreach gets extra argument for passing local data to the
  1129. iterator function
  1130. * -CR checks also class typecasts at runtime by changing them
  1131. into as
  1132. * fixed compiler to cycle with the -CR option
  1133. * fixed stabs with elf writer, finally the global variables can
  1134. be watched
  1135. * removed a lot of routines from cga unit and replaced them by
  1136. calls to cgobj
  1137. * u32bit-s32bit updates for and,or,xor nodes. When one element is
  1138. u32bit then the other is typecasted also to u32bit without giving
  1139. a rangecheck warning/error.
  1140. * fixed pascal calling method with reversing also the high tree in
  1141. the parast, detected by tcalcst3 test
  1142. Revision 1.13 2002/04/21 15:24:38 carl
  1143. + a_jmp_cond -> a_jmp_always (a_jmp_cond is NOT portable)
  1144. + changeregsize -> rg.makeregsize
  1145. Revision 1.12 2002/04/15 19:44:19 peter
  1146. * fixed stackcheck that would be called recursively when a stack
  1147. error was found
  1148. * generic changeregsize(reg,size) for i386 register resizing
  1149. * removed some more routines from cga unit
  1150. * fixed returnvalue handling
  1151. * fixed default stacksize of linux and go32v2, 8kb was a bit small :-)
  1152. Revision 1.11 2002/04/04 19:05:57 peter
  1153. * removed unused units
  1154. * use tlocation.size in cg.a_*loc*() routines
  1155. Revision 1.10 2002/04/02 17:11:28 peter
  1156. * tlocation,treference update
  1157. * LOC_CONSTANT added for better constant handling
  1158. * secondadd splitted in multiple routines
  1159. * location_force_reg added for loading a location to a register
  1160. of a specified size
  1161. * secondassignment parses now first the right and then the left node
  1162. (this is compatible with Kylix). This saves a lot of push/pop especially
  1163. with string operations
  1164. * adapted some routines to use the new cg methods
  1165. Revision 1.9 2002/03/31 20:26:34 jonas
  1166. + a_loadfpu_* and a_loadmm_* methods in tcg
  1167. * register allocation is now handled by a class and is mostly processor
  1168. independent (+rgobj.pas and i386/rgcpu.pas)
  1169. * temp allocation is now handled by a class (+tgobj.pas, -i386\tgcpu.pas)
  1170. * some small improvements and fixes to the optimizer
  1171. * some register allocation fixes
  1172. * some fpuvaroffset fixes in the unary minus node
  1173. * push/popusedregisters is now called rg.save/restoreusedregisters and
  1174. (for i386) uses temps instead of push/pop's when using -Op3 (that code is
  1175. also better optimizable)
  1176. * fixed and optimized register saving/restoring for new/dispose nodes
  1177. * LOC_FPU locations now also require their "register" field to be set to
  1178. R_ST, not R_ST0 (the latter is used for LOC_CFPUREGISTER locations only)
  1179. - list field removed of the tnode class because it's not used currently
  1180. and can cause hard-to-find bugs
  1181. Revision 1.8 2002/03/04 19:10:11 peter
  1182. * removed compiler warnings
  1183. }