ncgflw.pas 46 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347
  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. cga,
  73. tgobj,rgobj,paramgr,
  74. regvars,cgobj,cgcpu,cg64f32;
  75. {*****************************************************************************
  76. Second_While_RepeatN
  77. *****************************************************************************}
  78. procedure tcgwhilerepeatnode.pass_2;
  79. var
  80. lcont,lbreak,lloop,
  81. oldclabel,oldblabel : tasmlabel;
  82. otlabel,oflabel : tasmlabel;
  83. begin
  84. getlabel(lloop);
  85. getlabel(lcont);
  86. getlabel(lbreak);
  87. { arrange continue and breaklabels: }
  88. oldclabel:=aktcontinuelabel;
  89. oldblabel:=aktbreaklabel;
  90. load_all_regvars(exprasmlist);
  91. { handling code at the end as it is much more efficient, and makes
  92. while equal to repeat loop, only the end true/false is swapped (PFV) }
  93. if nf_testatbegin in flags then
  94. cg.a_jmp_always(exprasmlist,lcont);
  95. if not(cs_littlesize in aktglobalswitches) then
  96. { align loop target }
  97. exprasmList.concat(Tai_align.Create(aktalignment.loopalign));
  98. cg.a_label(exprasmlist,lloop);
  99. aktcontinuelabel:=lcont;
  100. aktbreaklabel:=lbreak;
  101. rg.cleartempgen;
  102. if assigned(right) then
  103. secondpass(right);
  104. load_all_regvars(exprasmlist);
  105. cg.a_label(exprasmlist,lcont);
  106. otlabel:=truelabel;
  107. oflabel:=falselabel;
  108. if nf_checknegate in flags then
  109. begin
  110. truelabel:=lbreak;
  111. falselabel:=lloop;
  112. end
  113. else
  114. begin
  115. truelabel:=lloop;
  116. falselabel:=lbreak;
  117. end;
  118. rg.cleartempgen;
  119. secondpass(left);
  120. maketojumpbool(exprasmlist,left,lr_load_regvars);
  121. cg.a_label(exprasmlist,lbreak);
  122. truelabel:=otlabel;
  123. falselabel:=oflabel;
  124. aktcontinuelabel:=oldclabel;
  125. aktbreaklabel:=oldblabel;
  126. { a break/continue in a while/repeat block can't be seen outside }
  127. flowcontrol:=flowcontrol-[fc_break,fc_continue];
  128. end;
  129. {*****************************************************************************
  130. tcgIFNODE
  131. *****************************************************************************}
  132. procedure tcgifnode.pass_2;
  133. var
  134. hl,otlabel,oflabel : tasmlabel;
  135. org_regvar_loaded,
  136. then_regvar_loaded,
  137. else_regvar_loaded : regvar_booleanarray;
  138. org_list,
  139. then_list,
  140. else_list : taasmoutput;
  141. begin
  142. otlabel:=truelabel;
  143. oflabel:=falselabel;
  144. getlabel(truelabel);
  145. getlabel(falselabel);
  146. rg.cleartempgen;
  147. secondpass(left);
  148. { save regvars loaded in the beginning so that we can restore them }
  149. { when processing the else-block }
  150. if cs_regalloc in aktglobalswitches then
  151. begin
  152. org_list := exprasmlist;
  153. exprasmlist := taasmoutput.create;
  154. end;
  155. maketojumpbool(exprasmlist,left,lr_dont_load_regvars);
  156. if cs_regalloc in aktglobalswitches then
  157. org_regvar_loaded := rg.regvar_loaded;
  158. if assigned(right) then
  159. begin
  160. cg.a_label(exprasmlist,truelabel);
  161. rg.cleartempgen;
  162. secondpass(right);
  163. end;
  164. { save current asmlist (previous instructions + then-block) and }
  165. { loaded regvar state and create new clean ones }
  166. if cs_regalloc in aktglobalswitches then
  167. begin
  168. then_regvar_loaded := rg.regvar_loaded;
  169. rg.regvar_loaded := org_regvar_loaded;
  170. then_list := exprasmlist;
  171. exprasmlist := taasmoutput.create;
  172. end;
  173. if assigned(t1) then
  174. begin
  175. if assigned(right) then
  176. begin
  177. getlabel(hl);
  178. { do go back to if line !! }
  179. if not(cs_regalloc in aktglobalswitches) then
  180. aktfilepos:=exprasmList.getlasttaifilepos^
  181. else
  182. aktfilepos:=then_list.getlasttaifilepos^;
  183. cg.a_jmp_always(exprasmlist,hl);
  184. end;
  185. cg.a_label(exprasmlist,falselabel);
  186. rg.cleartempgen;
  187. secondpass(t1);
  188. { save current asmlist (previous instructions + else-block) }
  189. { and loaded regvar state and create a new clean list }
  190. if cs_regalloc in aktglobalswitches then
  191. begin
  192. else_regvar_loaded := rg.regvar_loaded;
  193. else_list := exprasmlist;
  194. exprasmlist := taasmoutput.create;
  195. end;
  196. if assigned(right) then
  197. cg.a_label(exprasmlist,hl);
  198. end
  199. else
  200. begin
  201. if cs_regalloc in aktglobalswitches then
  202. begin
  203. else_regvar_loaded := rg.regvar_loaded;
  204. else_list := exprasmlist;
  205. exprasmlist := taasmoutput.create;
  206. end;
  207. cg.a_label(exprasmlist,falselabel);
  208. end;
  209. if not(assigned(right)) then
  210. begin
  211. cg.a_label(exprasmlist,truelabel);
  212. end;
  213. if cs_regalloc in aktglobalswitches then
  214. begin
  215. { add loads of regvars at the end of the then- and else-blocks }
  216. { so that at the end of both blocks the same regvars are loaded }
  217. { no else block? }
  218. if not assigned(t1) then
  219. sync_regvars(org_list,then_list,org_regvar_loaded,
  220. then_regvar_loaded)
  221. { no then block? }
  222. else if not assigned(right) then
  223. sync_regvars(org_list,else_list,org_regvar_loaded,
  224. else_regvar_loaded)
  225. { both else and then blocks }
  226. else
  227. sync_regvars(then_list,else_list,then_regvar_loaded,
  228. else_regvar_loaded);
  229. { add all lists together }
  230. org_list.concatlist(then_list);
  231. then_list.free;
  232. org_list.concatlist(else_list);
  233. else_list.free;
  234. org_list.concatlist(exprasmlist);
  235. exprasmlist.free;
  236. exprasmlist := org_list;
  237. end;
  238. truelabel:=otlabel;
  239. falselabel:=oflabel;
  240. end;
  241. {*****************************************************************************
  242. SecondFor
  243. *****************************************************************************}
  244. procedure tcgfornode.pass_2;
  245. var
  246. l3,oldclabel,oldblabel : tasmlabel;
  247. temptovalue : boolean;
  248. hs : byte;
  249. temp1 : treference;
  250. hop : topcg;
  251. hcond : topcmp;
  252. opsize : tcgsize;
  253. count_var_is_signed : boolean;
  254. begin
  255. oldclabel:=aktcontinuelabel;
  256. oldblabel:=aktbreaklabel;
  257. getlabel(aktcontinuelabel);
  258. getlabel(aktbreaklabel);
  259. getlabel(l3);
  260. { only calculate reference }
  261. rg.cleartempgen;
  262. secondpass(t2);
  263. hs := t2.resulttype.def.size;
  264. opsize := def_cgsize(t2.resulttype.def);
  265. { first set the to value
  266. because the count var can be in the expression !! }
  267. rg.cleartempgen;
  268. secondpass(right);
  269. { calculate pointer value and check if changeable and if so }
  270. { load into temporary variable }
  271. if right.nodetype<>ordconstn then
  272. begin
  273. temp1.symbol:=nil;
  274. tg.gettempofsizereference(exprasmlist,hs,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. getlabel(truelabel);
  406. 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,labelnr)
  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. getaddrlabel(a);
  574. cg.a_label(exprasmlist,a);
  575. reference_reset_symbol(href2,a,0);
  576. cg.a_paramaddr_ref(exprasmlist,href2,paramanager.getintparaloc(2));
  577. cg.a_param_reg(exprasmlist,OS_ADDR,FRAME_POINTER_REG,paramanager.getintparaloc(3));
  578. end;
  579. { push object }
  580. secondpass(left);
  581. if codegenerror then
  582. exit;
  583. cg.a_param_loc(exprasmlist,left.location,paramanager.getintparaloc(1));
  584. cg.a_call_name(exprasmlist,'FPC_RAISEEXCEPTION');
  585. end
  586. else
  587. begin
  588. cg.a_call_name(exprasmlist,'FPC_POPADDRSTACK');
  589. cg.a_call_name(exprasmlist,'FPC_RERAISE');
  590. end;
  591. end;
  592. {*****************************************************************************
  593. SecondTryExcept
  594. *****************************************************************************}
  595. var
  596. endexceptlabel : tasmlabel;
  597. { does the necessary things to clean up the object stack }
  598. { in the except block }
  599. procedure cleanupobjectstack;
  600. begin
  601. cg.a_call_name(exprasmlist,'FPC_POPOBJECTSTACK');
  602. cg.a_param_reg(exprasmlist,OS_ADDR,accumulator,paramanager.getintparaloc(1));
  603. cg.a_call_name(exprasmlist,'FPC_DESTROYEXCEPTION');
  604. cg.g_maybe_loadself(exprasmlist);
  605. end;
  606. procedure tcgtryexceptnode.pass_2;
  607. var
  608. exceptlabel,doexceptlabel,oldendexceptlabel,
  609. lastonlabel,
  610. exitexceptlabel,
  611. continueexceptlabel,
  612. breakexceptlabel,
  613. exittrylabel,
  614. continuetrylabel,
  615. breaktrylabel,
  616. doobjectdestroy,
  617. doobjectdestroyandreraise,
  618. oldaktexitlabel,
  619. oldaktexit2label,
  620. oldaktcontinuelabel,
  621. oldaktbreaklabel : tasmlabel;
  622. oldflowcontrol,tryflowcontrol,
  623. exceptflowcontrol : tflowcontrol;
  624. tempbuf,tempaddr : treference;
  625. href : treference;
  626. label
  627. errorexit;
  628. begin
  629. oldflowcontrol:=flowcontrol;
  630. flowcontrol:=[];
  631. { this can be called recursivly }
  632. oldendexceptlabel:=endexceptlabel;
  633. { save the old labels for control flow statements }
  634. oldaktexitlabel:=aktexitlabel;
  635. oldaktexit2label:=aktexit2label;
  636. if assigned(aktbreaklabel) then
  637. begin
  638. oldaktcontinuelabel:=aktcontinuelabel;
  639. oldaktbreaklabel:=aktbreaklabel;
  640. end;
  641. { get new labels for the control flow statements }
  642. getlabel(exittrylabel);
  643. getlabel(exitexceptlabel);
  644. if assigned(aktbreaklabel) then
  645. begin
  646. getlabel(breaktrylabel);
  647. getlabel(continuetrylabel);
  648. getlabel(breakexceptlabel);
  649. getlabel(continueexceptlabel);
  650. end;
  651. getlabel(exceptlabel);
  652. getlabel(doexceptlabel);
  653. getlabel(endexceptlabel);
  654. getlabel(lastonlabel);
  655. cg.g_new_exception(exprasmlist,tempbuf,tempaddr,href,1,exceptlabel);
  656. { try block }
  657. { set control flow labels for the try block }
  658. aktexitlabel:=exittrylabel;
  659. aktexit2label:=exittrylabel;
  660. if assigned(oldaktbreaklabel) then
  661. begin
  662. aktcontinuelabel:=continuetrylabel;
  663. aktbreaklabel:=breaktrylabel;
  664. end;
  665. flowcontrol:=[];
  666. secondpass(left);
  667. tryflowcontrol:=flowcontrol;
  668. if codegenerror then
  669. goto errorexit;
  670. cg.a_label(exprasmlist,exceptlabel);
  671. cg.g_free_exception(exprasmlist,tempbuf,tempaddr,href,0,endexceptlabel,false);
  672. cg.a_label(exprasmlist,doexceptlabel);
  673. { set control flow labels for the except block }
  674. { and the on statements }
  675. aktexitlabel:=exitexceptlabel;
  676. aktexit2label:=exitexceptlabel;
  677. if assigned(oldaktbreaklabel) then
  678. begin
  679. aktcontinuelabel:=continueexceptlabel;
  680. aktbreaklabel:=breakexceptlabel;
  681. end;
  682. flowcontrol:=[];
  683. { on statements }
  684. if assigned(right) then
  685. secondpass(right);
  686. cg.a_label(exprasmlist,lastonlabel);
  687. { default handling except handling }
  688. if assigned(t1) then
  689. begin
  690. { FPC_CATCHES must be called with
  691. 'default handler' flag (=-1)
  692. }
  693. cg.a_param_const(exprasmlist,OS_ADDR,aword(-1),paramanager.getintparaloc(1));
  694. cg.a_call_name(exprasmlist,'FPC_CATCHES');
  695. cg.g_maybe_loadself(exprasmlist);
  696. { the destruction of the exception object must be also }
  697. { guarded by an exception frame }
  698. getlabel(doobjectdestroy);
  699. getlabel(doobjectdestroyandreraise);
  700. cg.g_new_exception(exprasmlist,tempbuf,tempaddr,href,1,exceptlabel);
  701. { here we don't have to reset flowcontrol }
  702. { the default and on flowcontrols are handled equal }
  703. secondpass(t1);
  704. exceptflowcontrol:=flowcontrol;
  705. cg.a_label(exprasmlist,doobjectdestroyandreraise);
  706. cg.g_free_exception(exprasmlist,tempbuf,tempaddr,href,0,doobjectdestroy,false);
  707. cg.a_call_name(exprasmlist,'FPC_POPSECONDOBJECTSTACK');
  708. cg.a_param_reg(exprasmlist, OS_ADDR, accumulator, paramanager.getintparaloc(1));
  709. cg.a_call_name(exprasmlist,'FPC_DESTROYEXCEPTION');
  710. { we don't need to restore esi here because reraise never }
  711. { returns }
  712. cg.a_call_name(exprasmlist,'FPC_RERAISE');
  713. cg.a_label(exprasmlist,doobjectdestroy);
  714. cleanupobjectstack;
  715. cg.a_jmp_always(exprasmlist,endexceptlabel);
  716. end
  717. else
  718. begin
  719. cg.a_call_name(exprasmlist,'FPC_RERAISE');
  720. exceptflowcontrol:=flowcontrol;
  721. end;
  722. if fc_exit in exceptflowcontrol then
  723. begin
  724. { do some magic for exit in the try block }
  725. cg.a_label(exprasmlist,exitexceptlabel);
  726. { we must also destroy the address frame which guards }
  727. { exception object }
  728. cg.a_call_name(exprasmlist,'FPC_POPADDRSTACK');
  729. cg.g_exception_reason_load(exprasmlist,href);
  730. cleanupobjectstack;
  731. cg.a_jmp_always(exprasmlist,oldaktexitlabel);
  732. end;
  733. if fc_break in exceptflowcontrol then
  734. begin
  735. cg.a_label(exprasmlist,breakexceptlabel);
  736. { we must also destroy the address frame which guards }
  737. { exception object }
  738. cg.a_call_name(exprasmlist,'FPC_POPADDRSTACK');
  739. cg.g_exception_reason_load(exprasmlist,href);
  740. cleanupobjectstack;
  741. cg.a_jmp_always(exprasmlist,oldaktbreaklabel);
  742. end;
  743. if fc_continue in exceptflowcontrol then
  744. begin
  745. cg.a_label(exprasmlist,continueexceptlabel);
  746. { we must also destroy the address frame which guards }
  747. { exception object }
  748. cg.a_call_name(exprasmlist,'FPC_POPADDRSTACK');
  749. cg.g_exception_reason_load(exprasmlist,href);
  750. cleanupobjectstack;
  751. cg.a_jmp_always(exprasmlist,oldaktcontinuelabel);
  752. end;
  753. if fc_exit in tryflowcontrol then
  754. begin
  755. { do some magic for exit in the try block }
  756. cg.a_label(exprasmlist,exittrylabel);
  757. cg.a_call_name(exprasmlist,'FPC_POPADDRSTACK');
  758. cg.g_exception_reason_load(exprasmlist,href);
  759. cg.a_jmp_always(exprasmlist,oldaktexitlabel);
  760. end;
  761. if fc_break in tryflowcontrol then
  762. begin
  763. cg.a_label(exprasmlist,breaktrylabel);
  764. cg.a_call_name(exprasmlist,'FPC_POPADDRSTACK');
  765. cg.g_exception_reason_load(exprasmlist,href);
  766. cg.a_jmp_always(exprasmlist,oldaktbreaklabel);
  767. end;
  768. if fc_continue in tryflowcontrol then
  769. begin
  770. cg.a_label(exprasmlist,continuetrylabel);
  771. cg.a_call_name(exprasmlist,'FPC_POPADDRSTACK');
  772. cg.g_exception_reason_load(exprasmlist,href);
  773. cg.a_jmp_always(exprasmlist,oldaktcontinuelabel);
  774. end;
  775. cg.a_label(exprasmlist,endexceptlabel);
  776. errorexit:
  777. { restore all saved labels }
  778. endexceptlabel:=oldendexceptlabel;
  779. { restore the control flow labels }
  780. aktexitlabel:=oldaktexitlabel;
  781. aktexit2label:=oldaktexit2label;
  782. if assigned(oldaktbreaklabel) then
  783. begin
  784. aktcontinuelabel:=oldaktcontinuelabel;
  785. aktbreaklabel:=oldaktbreaklabel;
  786. end;
  787. { return all used control flow statements }
  788. flowcontrol:=oldflowcontrol+exceptflowcontrol+
  789. tryflowcontrol;
  790. end;
  791. procedure tcgonnode.pass_2;
  792. var
  793. nextonlabel,
  794. exitonlabel,
  795. continueonlabel,
  796. breakonlabel,
  797. oldaktexitlabel,
  798. oldaktexit2label,
  799. oldaktcontinuelabel,
  800. doobjectdestroyandreraise,
  801. doobjectdestroy,
  802. oldaktbreaklabel : tasmlabel;
  803. ref : treference;
  804. oldflowcontrol : tflowcontrol;
  805. tempbuf,tempaddr : treference;
  806. href : treference;
  807. href2: treference;
  808. begin
  809. oldflowcontrol:=flowcontrol;
  810. flowcontrol:=[];
  811. getlabel(nextonlabel);
  812. { send the vmt parameter }
  813. reference_reset_symbol(href2,newasmsymbol(excepttype.vmt_mangledname),0);
  814. cg.a_paramaddr_ref(exprasmlist,href2,paramanager.getintparaloc(1));
  815. cg.a_call_name(exprasmlist,'FPC_CATCHES');
  816. { is it this catch? No. go to next onlabel }
  817. cg.a_cmp_const_reg_label(exprasmlist,OS_ADDR,OC_EQ,0,accumulator,nextonlabel);
  818. ref.symbol:=nil;
  819. tg.gettempofsizereference(exprasmlist,pointer_size,ref);
  820. { what a hack ! }
  821. if assigned(exceptsymtable) then
  822. tvarsym(exceptsymtable.symindex.first).address:=ref.offset;
  823. cg.a_load_reg_ref(exprasmlist, OS_ADDR, accumulator, ref);
  824. { in the case that another exception is risen }
  825. { we've to destroy the old one }
  826. getlabel(doobjectdestroyandreraise);
  827. { call setjmp, and jump to finally label on non-zero result }
  828. cg.g_new_exception(exprasmlist,tempbuf,tempaddr,href,1,doobjectdestroyandreraise);
  829. if assigned(right) then
  830. begin
  831. oldaktexitlabel:=aktexitlabel;
  832. oldaktexit2label:=aktexit2label;
  833. getlabel(exitonlabel);
  834. aktexitlabel:=exitonlabel;
  835. aktexit2label:=exitonlabel;
  836. if assigned(aktbreaklabel) then
  837. begin
  838. oldaktcontinuelabel:=aktcontinuelabel;
  839. oldaktbreaklabel:=aktbreaklabel;
  840. getlabel(breakonlabel);
  841. getlabel(continueonlabel);
  842. aktcontinuelabel:=continueonlabel;
  843. aktbreaklabel:=breakonlabel;
  844. end;
  845. { esi is destroyed by FPC_CATCHES }
  846. cg.g_maybe_loadself(exprasmlist);
  847. secondpass(right);
  848. end;
  849. getlabel(doobjectdestroy);
  850. cg.a_label(exprasmlist,doobjectdestroyandreraise);
  851. cg.g_free_exception(exprasmlist,tempbuf,tempaddr,href,0,doobjectdestroy,false);
  852. cg.a_call_name(exprasmlist,'FPC_POPSECONDOBJECTSTACK');
  853. cg.a_param_reg(exprasmlist, OS_ADDR, accumulator, paramanager.getintparaloc(1));
  854. cg.a_call_name(exprasmlist,'FPC_DESTROYEXCEPTION');
  855. { we don't need to restore esi here because reraise never }
  856. { returns }
  857. cg.a_call_name(exprasmlist,'FPC_RERAISE');
  858. cg.a_label(exprasmlist,doobjectdestroy);
  859. cleanupobjectstack;
  860. { clear some stuff }
  861. tg.ungetiftemp(exprasmlist,ref);
  862. cg.a_jmp_always(exprasmlist,endexceptlabel);
  863. if assigned(right) then
  864. begin
  865. { special handling for control flow instructions }
  866. if fc_exit in flowcontrol then
  867. begin
  868. { the address and object pop does secondtryexcept }
  869. cg.a_label(exprasmlist,exitonlabel);
  870. cg.a_jmp_always(exprasmlist,oldaktexitlabel);
  871. end;
  872. if fc_break in flowcontrol then
  873. begin
  874. { the address and object pop does secondtryexcept }
  875. cg.a_label(exprasmlist,breakonlabel);
  876. cg.a_jmp_always(exprasmlist,oldaktbreaklabel);
  877. end;
  878. if fc_continue in flowcontrol then
  879. begin
  880. { the address and object pop does secondtryexcept }
  881. cg.a_label(exprasmlist,continueonlabel);
  882. cg.a_jmp_always(exprasmlist,oldaktcontinuelabel);
  883. end;
  884. aktexitlabel:=oldaktexitlabel;
  885. aktexit2label:=oldaktexit2label;
  886. if assigned(oldaktbreaklabel) then
  887. begin
  888. aktcontinuelabel:=oldaktcontinuelabel;
  889. aktbreaklabel:=oldaktbreaklabel;
  890. end;
  891. end;
  892. cg.a_label(exprasmlist,nextonlabel);
  893. flowcontrol:=oldflowcontrol+flowcontrol;
  894. { next on node }
  895. if assigned(left) then
  896. begin
  897. rg.cleartempgen;
  898. secondpass(left);
  899. end;
  900. end;
  901. {*****************************************************************************
  902. SecondTryFinally
  903. *****************************************************************************}
  904. procedure tcgtryfinallynode.pass_2;
  905. var
  906. reraiselabel,
  907. finallylabel,
  908. endfinallylabel,
  909. exitfinallylabel,
  910. continuefinallylabel,
  911. breakfinallylabel,
  912. oldaktexitlabel,
  913. oldaktexit2label,
  914. oldaktcontinuelabel,
  915. oldaktbreaklabel : tasmlabel;
  916. oldflowcontrol,tryflowcontrol : tflowcontrol;
  917. decconst : longint;
  918. tempbuf,tempaddr : treference;
  919. href : treference;
  920. begin
  921. { check if child nodes do a break/continue/exit }
  922. oldflowcontrol:=flowcontrol;
  923. flowcontrol:=[];
  924. getlabel(finallylabel);
  925. getlabel(endfinallylabel);
  926. getlabel(reraiselabel);
  927. { the finally block must catch break, continue and exit }
  928. { statements }
  929. oldaktexitlabel:=aktexitlabel;
  930. oldaktexit2label:=aktexit2label;
  931. getlabel(exitfinallylabel);
  932. aktexitlabel:=exitfinallylabel;
  933. aktexit2label:=exitfinallylabel;
  934. if assigned(aktbreaklabel) then
  935. begin
  936. oldaktcontinuelabel:=aktcontinuelabel;
  937. oldaktbreaklabel:=aktbreaklabel;
  938. getlabel(breakfinallylabel);
  939. getlabel(continuefinallylabel);
  940. aktcontinuelabel:=continuefinallylabel;
  941. aktbreaklabel:=breakfinallylabel;
  942. end;
  943. { call setjmp, and jump to finally label on non-zero result }
  944. cg.g_new_exception(exprasmlist,tempbuf,tempaddr,href,1,finallylabel);
  945. { try code }
  946. if assigned(left) then
  947. begin
  948. secondpass(left);
  949. tryflowcontrol:=flowcontrol;
  950. if codegenerror then
  951. exit;
  952. end;
  953. cg.a_label(exprasmlist,finallylabel);
  954. { just free the frame information }
  955. cg.g_free_exception(exprasmlist,tempbuf,tempaddr,href,1,finallylabel,true);
  956. { finally code }
  957. flowcontrol:=[];
  958. secondpass(right);
  959. if flowcontrol<>[] then
  960. CGMessage(cg_e_control_flow_outside_finally);
  961. if codegenerror then
  962. exit;
  963. { the value should now be in the exception handler }
  964. cg.g_exception_reason_load(exprasmlist,href);
  965. cg.a_cmp_reg_reg_label(exprasmlist,OS_S32,OC_NE,accumulator,accumulator,finallylabel);
  966. cg.a_op_const_reg(exprasmlist,OP_SUB,1,accumulator);
  967. cg.a_cmp_const_reg_label(exprasmlist,OS_S32,OC_EQ,0,accumulator,reraiselabel);
  968. if fc_exit in tryflowcontrol then
  969. begin
  970. cg.a_op_const_reg(exprasmlist,OP_SUB,1,accumulator);
  971. cg.a_cmp_const_reg_label(exprasmlist,OS_S32,OC_EQ,0,accumulator,oldaktexitlabel);
  972. decconst:=1;
  973. end
  974. else
  975. decconst:=2;
  976. if fc_break in tryflowcontrol then
  977. begin
  978. cg.a_op_const_reg(exprasmlist,OP_SUB,decconst,accumulator);
  979. cg.a_cmp_const_reg_label(exprasmlist,OS_S32,OC_EQ,0,accumulator,oldaktbreaklabel);
  980. decconst:=1;
  981. end
  982. else
  983. inc(decconst);
  984. if fc_continue in tryflowcontrol then
  985. begin
  986. cg.a_op_const_reg(exprasmlist,OP_SUB,decconst,accumulator);
  987. cg.a_cmp_const_reg_label(exprasmlist,OS_S32,OC_EQ,0,accumulator,oldaktcontinuelabel);
  988. end;
  989. cg.a_label(exprasmlist,reraiselabel);
  990. cg.a_call_name(exprasmlist,'FPC_RERAISE');
  991. { do some magic for exit,break,continue in the try block }
  992. if fc_exit in tryflowcontrol then
  993. begin
  994. cg.a_label(exprasmlist,exitfinallylabel);
  995. cg.g_exception_reason_load(exprasmlist,href);
  996. cg.g_exception_reason_save_const(exprasmlist,href,2);
  997. cg.a_jmp_always(exprasmlist,finallylabel);
  998. end;
  999. if fc_break in tryflowcontrol then
  1000. begin
  1001. cg.a_label(exprasmlist,breakfinallylabel);
  1002. cg.g_exception_reason_load(exprasmlist,href);
  1003. cg.g_exception_reason_save_const(exprasmlist,href,3);
  1004. cg.a_jmp_always(exprasmlist,finallylabel);
  1005. end;
  1006. if fc_continue in tryflowcontrol then
  1007. begin
  1008. cg.a_label(exprasmlist,continuefinallylabel);
  1009. cg.g_exception_reason_load(exprasmlist,href);
  1010. cg.g_exception_reason_save_const(exprasmlist,href,4);
  1011. cg.a_jmp_always(exprasmlist,finallylabel);
  1012. end;
  1013. cg.a_label(exprasmlist,endfinallylabel);
  1014. aktexitlabel:=oldaktexitlabel;
  1015. aktexit2label:=oldaktexit2label;
  1016. if assigned(aktbreaklabel) then
  1017. begin
  1018. aktcontinuelabel:=oldaktcontinuelabel;
  1019. aktbreaklabel:=oldaktbreaklabel;
  1020. end;
  1021. flowcontrol:=oldflowcontrol+tryflowcontrol;
  1022. end;
  1023. begin
  1024. cwhilerepeatnode:=tcgwhilerepeatnode;
  1025. cifnode:=tcgifnode;
  1026. cfornode:=tcgfornode;
  1027. cexitnode:=tcgexitnode;
  1028. cbreaknode:=tcgbreaknode;
  1029. ccontinuenode:=tcgcontinuenode;
  1030. cgotonode:=tcggotonode;
  1031. clabelnode:=tcglabelnode;
  1032. cfailnode:=tcgfailnode;
  1033. craisenode:=tcgraisenode;
  1034. ctryexceptnode:=tcgtryexceptnode;
  1035. ctryfinallynode:=tcgtryfinallynode;
  1036. connode:=tcgonnode;
  1037. end.
  1038. {
  1039. $Log$
  1040. Revision 1.31 2002-08-04 19:06:41 carl
  1041. + added generic exception support (still does not work!)
  1042. + more documentation
  1043. Revision 1.30 2002/07/27 19:53:51 jonas
  1044. + generic implementation of tcg.g_flags2ref()
  1045. * tcg.flags2xxx() now also needs a size parameter
  1046. Revision 1.29 2002/07/25 17:56:29 carl
  1047. + FPURESULTREG -> FPU_RESULT_REG
  1048. Revision 1.28 2002/07/21 06:58:49 daniel
  1049. * Changed booleans into flags
  1050. Revision 1.27 2002/07/20 12:54:53 daniel
  1051. * Optimized the code generated for for nodes. The shootout/nestloop benchmark
  1052. now runs 5% faster on my computer.
  1053. Revision 1.26 2002/07/20 11:57:54 florian
  1054. * types.pas renamed to defbase.pas because D6 contains a types
  1055. unit so this would conflicts if D6 programms are compiled
  1056. + Willamette/SSE2 instructions to assembler added
  1057. Revision 1.25 2002/07/20 11:15:51 daniel
  1058. * The for node does a check if the first comparision can be skipped. I moved
  1059. the check from the second pass to the resulttype pass. The advantage is
  1060. that the state tracker can now decide to skip the first comparision too.
  1061. Revision 1.24 2002/07/20 08:14:24 daniel
  1062. * Loops should not be aligned when optimizing for size
  1063. Revision 1.23 2002/07/19 11:41:35 daniel
  1064. * State tracker work
  1065. * The whilen and repeatn are now completely unified into whilerepeatn. This
  1066. allows the state tracker to change while nodes automatically into
  1067. repeat nodes.
  1068. * Resulttypepass improvements to the notn. 'not not a' is optimized away and
  1069. 'not(a>b)' is optimized into 'a<=b'.
  1070. * Resulttypepass improvements to the whilerepeatn. 'while not a' is optimized
  1071. by removing the notn and later switchting the true and falselabels. The
  1072. same is done with 'repeat until not a'.
  1073. Revision 1.22 2002/07/04 20:43:01 florian
  1074. * first x86-64 patches
  1075. Revision 1.21 2002/07/01 18:46:22 peter
  1076. * internal linker
  1077. * reorganized aasm layer
  1078. Revision 1.20 2002/07/01 16:23:53 peter
  1079. * cg64 patch
  1080. * basics for currency
  1081. * asnode updates for class and interface (not finished)
  1082. Revision 1.19 2002/05/20 13:30:40 carl
  1083. * bugfix of hdisponen (base must be set, not index)
  1084. * more portability fixes
  1085. Revision 1.18 2002/05/18 13:34:09 peter
  1086. * readded missing revisions
  1087. Revision 1.17 2002/05/16 19:46:37 carl
  1088. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  1089. + try to fix temp allocation (still in ifdef)
  1090. + generic constructor calls
  1091. + start of tassembler / tmodulebase class cleanup
  1092. Revision 1.15 2002/05/13 19:54:37 peter
  1093. * removed n386ld and n386util units
  1094. * maybe_save/maybe_restore added instead of the old maybe_push
  1095. Revision 1.14 2002/05/12 16:53:07 peter
  1096. * moved entry and exitcode to ncgutil and cgobj
  1097. * foreach gets extra argument for passing local data to the
  1098. iterator function
  1099. * -CR checks also class typecasts at runtime by changing them
  1100. into as
  1101. * fixed compiler to cycle with the -CR option
  1102. * fixed stabs with elf writer, finally the global variables can
  1103. be watched
  1104. * removed a lot of routines from cga unit and replaced them by
  1105. calls to cgobj
  1106. * u32bit-s32bit updates for and,or,xor nodes. When one element is
  1107. u32bit then the other is typecasted also to u32bit without giving
  1108. a rangecheck warning/error.
  1109. * fixed pascal calling method with reversing also the high tree in
  1110. the parast, detected by tcalcst3 test
  1111. Revision 1.13 2002/04/21 15:24:38 carl
  1112. + a_jmp_cond -> a_jmp_always (a_jmp_cond is NOT portable)
  1113. + changeregsize -> rg.makeregsize
  1114. Revision 1.12 2002/04/15 19:44:19 peter
  1115. * fixed stackcheck that would be called recursively when a stack
  1116. error was found
  1117. * generic changeregsize(reg,size) for i386 register resizing
  1118. * removed some more routines from cga unit
  1119. * fixed returnvalue handling
  1120. * fixed default stacksize of linux and go32v2, 8kb was a bit small :-)
  1121. Revision 1.11 2002/04/04 19:05:57 peter
  1122. * removed unused units
  1123. * use tlocation.size in cg.a_*loc*() routines
  1124. Revision 1.10 2002/04/02 17:11:28 peter
  1125. * tlocation,treference update
  1126. * LOC_CONSTANT added for better constant handling
  1127. * secondadd splitted in multiple routines
  1128. * location_force_reg added for loading a location to a register
  1129. of a specified size
  1130. * secondassignment parses now first the right and then the left node
  1131. (this is compatible with Kylix). This saves a lot of push/pop especially
  1132. with string operations
  1133. * adapted some routines to use the new cg methods
  1134. Revision 1.9 2002/03/31 20:26:34 jonas
  1135. + a_loadfpu_* and a_loadmm_* methods in tcg
  1136. * register allocation is now handled by a class and is mostly processor
  1137. independent (+rgobj.pas and i386/rgcpu.pas)
  1138. * temp allocation is now handled by a class (+tgobj.pas, -i386\tgcpu.pas)
  1139. * some small improvements and fixes to the optimizer
  1140. * some register allocation fixes
  1141. * some fpuvaroffset fixes in the unary minus node
  1142. * push/popusedregisters is now called rg.save/restoreusedregisters and
  1143. (for i386) uses temps instead of push/pop's when using -Op3 (that code is
  1144. also better optimizable)
  1145. * fixed and optimized register saving/restoring for new/dispose nodes
  1146. * LOC_FPU locations now also require their "register" field to be set to
  1147. R_ST, not R_ST0 (the latter is used for LOC_CFPUREGISTER locations only)
  1148. - list field removed of the tnode class because it's not used currently
  1149. and can cause hard-to-find bugs
  1150. Revision 1.8 2002/03/04 19:10:11 peter
  1151. * removed compiler warnings
  1152. }