ncgflw.pas 49 KB

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