ncgflw.pas 48 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395
  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,labsym.lab)
  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,JMP_BUF_SIZE,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.37 2002-08-19 19:36:43 peter
  1055. * More fixes for cross unit inlining, all tnodes are now implemented
  1056. * Moved pocall_internconst to po_internconst because it is not a
  1057. calling type at all and it conflicted when inlining of these small
  1058. functions was requested
  1059. Revision 1.36 2002/08/15 15:15:55 carl
  1060. * jmpbuf size allocation for exceptions is now cpu specific (as it should)
  1061. * more generic nodes for maths
  1062. * several fixes for better m68k support
  1063. Revision 1.35 2002/08/13 18:01:52 carl
  1064. * rename swatoperands to swapoperands
  1065. + m68k first compilable version (still needs a lot of testing):
  1066. assembler generator, system information , inline
  1067. assembler reader.
  1068. Revision 1.34 2002/08/11 14:32:26 peter
  1069. * renamed current_library to objectlibrary
  1070. Revision 1.33 2002/08/11 13:24:11 peter
  1071. * saving of asmsymbols in ppu supported
  1072. * asmsymbollist global is removed and moved into a new class
  1073. tasmlibrarydata that will hold the info of a .a file which
  1074. corresponds with a single module. Added librarydata to tmodule
  1075. to keep the library info stored for the module. In the future the
  1076. objectfiles will also be stored to the tasmlibrarydata class
  1077. * all getlabel/newasmsymbol and friends are moved to the new class
  1078. Revision 1.32 2002/08/09 19:10:59 carl
  1079. * fixed generic exception management
  1080. Revision 1.31 2002/08/04 19:06:41 carl
  1081. + added generic exception support (still does not work!)
  1082. + more documentation
  1083. Revision 1.30 2002/07/27 19:53:51 jonas
  1084. + generic implementation of tcg.g_flags2ref()
  1085. * tcg.flags2xxx() now also needs a size parameter
  1086. Revision 1.29 2002/07/25 17:56:29 carl
  1087. + FPURESULTREG -> FPU_RESULT_REG
  1088. Revision 1.28 2002/07/21 06:58:49 daniel
  1089. * Changed booleans into flags
  1090. Revision 1.27 2002/07/20 12:54:53 daniel
  1091. * Optimized the code generated for for nodes. The shootout/nestloop benchmark
  1092. now runs 5% faster on my computer.
  1093. Revision 1.26 2002/07/20 11:57:54 florian
  1094. * types.pas renamed to defbase.pas because D6 contains a types
  1095. unit so this would conflicts if D6 programms are compiled
  1096. + Willamette/SSE2 instructions to assembler added
  1097. Revision 1.25 2002/07/20 11:15:51 daniel
  1098. * The for node does a check if the first comparision can be skipped. I moved
  1099. the check from the second pass to the resulttype pass. The advantage is
  1100. that the state tracker can now decide to skip the first comparision too.
  1101. Revision 1.24 2002/07/20 08:14:24 daniel
  1102. * Loops should not be aligned when optimizing for size
  1103. Revision 1.23 2002/07/19 11:41:35 daniel
  1104. * State tracker work
  1105. * The whilen and repeatn are now completely unified into whilerepeatn. This
  1106. allows the state tracker to change while nodes automatically into
  1107. repeat nodes.
  1108. * Resulttypepass improvements to the notn. 'not not a' is optimized away and
  1109. 'not(a>b)' is optimized into 'a<=b'.
  1110. * Resulttypepass improvements to the whilerepeatn. 'while not a' is optimized
  1111. by removing the notn and later switchting the true and falselabels. The
  1112. same is done with 'repeat until not a'.
  1113. Revision 1.22 2002/07/04 20:43:01 florian
  1114. * first x86-64 patches
  1115. Revision 1.21 2002/07/01 18:46:22 peter
  1116. * internal linker
  1117. * reorganized aasm layer
  1118. Revision 1.20 2002/07/01 16:23:53 peter
  1119. * cg64 patch
  1120. * basics for currency
  1121. * asnode updates for class and interface (not finished)
  1122. Revision 1.19 2002/05/20 13:30:40 carl
  1123. * bugfix of hdisponen (base must be set, not index)
  1124. * more portability fixes
  1125. Revision 1.18 2002/05/18 13:34:09 peter
  1126. * readded missing revisions
  1127. Revision 1.17 2002/05/16 19:46:37 carl
  1128. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  1129. + try to fix temp allocation (still in ifdef)
  1130. + generic constructor calls
  1131. + start of tassembler / tmodulebase class cleanup
  1132. Revision 1.15 2002/05/13 19:54:37 peter
  1133. * removed n386ld and n386util units
  1134. * maybe_save/maybe_restore added instead of the old maybe_push
  1135. Revision 1.14 2002/05/12 16:53:07 peter
  1136. * moved entry and exitcode to ncgutil and cgobj
  1137. * foreach gets extra argument for passing local data to the
  1138. iterator function
  1139. * -CR checks also class typecasts at runtime by changing them
  1140. into as
  1141. * fixed compiler to cycle with the -CR option
  1142. * fixed stabs with elf writer, finally the global variables can
  1143. be watched
  1144. * removed a lot of routines from cga unit and replaced them by
  1145. calls to cgobj
  1146. * u32bit-s32bit updates for and,or,xor nodes. When one element is
  1147. u32bit then the other is typecasted also to u32bit without giving
  1148. a rangecheck warning/error.
  1149. * fixed pascal calling method with reversing also the high tree in
  1150. the parast, detected by tcalcst3 test
  1151. Revision 1.13 2002/04/21 15:24:38 carl
  1152. + a_jmp_cond -> a_jmp_always (a_jmp_cond is NOT portable)
  1153. + changeregsize -> rg.makeregsize
  1154. Revision 1.12 2002/04/15 19:44:19 peter
  1155. * fixed stackcheck that would be called recursively when a stack
  1156. error was found
  1157. * generic changeregsize(reg,size) for i386 register resizing
  1158. * removed some more routines from cga unit
  1159. * fixed returnvalue handling
  1160. * fixed default stacksize of linux and go32v2, 8kb was a bit small :-)
  1161. Revision 1.11 2002/04/04 19:05:57 peter
  1162. * removed unused units
  1163. * use tlocation.size in cg.a_*loc*() routines
  1164. Revision 1.10 2002/04/02 17:11:28 peter
  1165. * tlocation,treference update
  1166. * LOC_CONSTANT added for better constant handling
  1167. * secondadd splitted in multiple routines
  1168. * location_force_reg added for loading a location to a register
  1169. of a specified size
  1170. * secondassignment parses now first the right and then the left node
  1171. (this is compatible with Kylix). This saves a lot of push/pop especially
  1172. with string operations
  1173. * adapted some routines to use the new cg methods
  1174. Revision 1.9 2002/03/31 20:26:34 jonas
  1175. + a_loadfpu_* and a_loadmm_* methods in tcg
  1176. * register allocation is now handled by a class and is mostly processor
  1177. independent (+rgobj.pas and i386/rgcpu.pas)
  1178. * temp allocation is now handled by a class (+tgobj.pas, -i386\tgcpu.pas)
  1179. * some small improvements and fixes to the optimizer
  1180. * some register allocation fixes
  1181. * some fpuvaroffset fixes in the unary minus node
  1182. * push/popusedregisters is now called rg.save/restoreusedregisters and
  1183. (for i386) uses temps instead of push/pop's when using -Op3 (that code is
  1184. also better optimizable)
  1185. * fixed and optimized register saving/restoring for new/dispose nodes
  1186. * LOC_FPU locations now also require their "register" field to be set to
  1187. R_ST, not R_ST0 (the latter is used for LOC_CFPUREGISTER locations only)
  1188. - list field removed of the tnode class because it's not used currently
  1189. and can cause hard-to-find bugs
  1190. Revision 1.8 2002/03/04 19:10:11 peter
  1191. * removed compiler warnings
  1192. }