ncgflw.pas 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751
  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. implementation
  53. uses
  54. verbose,globals,systems,globtype,
  55. symconst,symsym,aasmbase,aasmtai,aasmcpu,defbase,
  56. cginfo,cgbase,pass_2,
  57. cpubase,cpuinfo,
  58. nld,ncon,
  59. ncgutil,
  60. cga,
  61. tgobj,rgobj,
  62. regvars,cgobj,cgcpu,cg64f32;
  63. {*****************************************************************************
  64. Second_While_RepeatN
  65. *****************************************************************************}
  66. procedure tcgwhilerepeatnode.pass_2;
  67. var
  68. lcont,lbreak,lloop,
  69. oldclabel,oldblabel : tasmlabel;
  70. otlabel,oflabel : tasmlabel;
  71. begin
  72. getlabel(lloop);
  73. getlabel(lcont);
  74. getlabel(lbreak);
  75. { arrange continue and breaklabels: }
  76. oldclabel:=aktcontinuelabel;
  77. oldblabel:=aktbreaklabel;
  78. load_all_regvars(exprasmlist);
  79. { handling code at the end as it is much more efficient, and makes
  80. while equal to repeat loop, only the end true/false is swapped (PFV) }
  81. if testatbegin then
  82. cg.a_jmp_always(exprasmlist,lcont);
  83. if not(cs_littlesize in aktglobalswitches) then
  84. { align loop target }
  85. exprasmList.concat(Tai_align.Create(aktalignment.loopalign));
  86. cg.a_label(exprasmlist,lloop);
  87. aktcontinuelabel:=lcont;
  88. aktbreaklabel:=lbreak;
  89. rg.cleartempgen;
  90. if assigned(right) then
  91. secondpass(right);
  92. load_all_regvars(exprasmlist);
  93. cg.a_label(exprasmlist,lcont);
  94. otlabel:=truelabel;
  95. oflabel:=falselabel;
  96. if checknegate then
  97. begin
  98. truelabel:=lbreak;
  99. falselabel:=lloop;
  100. end
  101. else
  102. begin
  103. truelabel:=lloop;
  104. falselabel:=lbreak;
  105. end;
  106. rg.cleartempgen;
  107. secondpass(left);
  108. maketojumpbool(exprasmlist,left,lr_load_regvars);
  109. cg.a_label(exprasmlist,lbreak);
  110. truelabel:=otlabel;
  111. falselabel:=oflabel;
  112. aktcontinuelabel:=oldclabel;
  113. aktbreaklabel:=oldblabel;
  114. { a break/continue in a while/repeat block can't be seen outside }
  115. flowcontrol:=flowcontrol-[fc_break,fc_continue];
  116. end;
  117. {*****************************************************************************
  118. tcgIFNODE
  119. *****************************************************************************}
  120. procedure tcgifnode.pass_2;
  121. var
  122. hl,otlabel,oflabel : tasmlabel;
  123. org_regvar_loaded,
  124. then_regvar_loaded,
  125. else_regvar_loaded : regvar_booleanarray;
  126. org_list,
  127. then_list,
  128. else_list : taasmoutput;
  129. begin
  130. otlabel:=truelabel;
  131. oflabel:=falselabel;
  132. getlabel(truelabel);
  133. getlabel(falselabel);
  134. rg.cleartempgen;
  135. secondpass(left);
  136. { save regvars loaded in the beginning so that we can restore them }
  137. { when processing the else-block }
  138. if cs_regalloc in aktglobalswitches then
  139. begin
  140. org_list := exprasmlist;
  141. exprasmlist := taasmoutput.create;
  142. end;
  143. maketojumpbool(exprasmlist,left,lr_dont_load_regvars);
  144. if cs_regalloc in aktglobalswitches then
  145. org_regvar_loaded := rg.regvar_loaded;
  146. if assigned(right) then
  147. begin
  148. cg.a_label(exprasmlist,truelabel);
  149. rg.cleartempgen;
  150. secondpass(right);
  151. end;
  152. { save current asmlist (previous instructions + then-block) and }
  153. { loaded regvar state and create new clean ones }
  154. if cs_regalloc in aktglobalswitches then
  155. begin
  156. then_regvar_loaded := rg.regvar_loaded;
  157. rg.regvar_loaded := org_regvar_loaded;
  158. then_list := exprasmlist;
  159. exprasmlist := taasmoutput.create;
  160. end;
  161. if assigned(t1) then
  162. begin
  163. if assigned(right) then
  164. begin
  165. getlabel(hl);
  166. { do go back to if line !! }
  167. if not(cs_regalloc in aktglobalswitches) then
  168. aktfilepos:=exprasmList.getlasttaifilepos^
  169. else
  170. aktfilepos:=then_list.getlasttaifilepos^;
  171. cg.a_jmp_always(exprasmlist,hl);
  172. end;
  173. cg.a_label(exprasmlist,falselabel);
  174. rg.cleartempgen;
  175. secondpass(t1);
  176. { save current asmlist (previous instructions + else-block) }
  177. { and loaded regvar state and create a new clean list }
  178. if cs_regalloc in aktglobalswitches then
  179. begin
  180. else_regvar_loaded := rg.regvar_loaded;
  181. else_list := exprasmlist;
  182. exprasmlist := taasmoutput.create;
  183. end;
  184. if assigned(right) then
  185. cg.a_label(exprasmlist,hl);
  186. end
  187. else
  188. begin
  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. cg.a_label(exprasmlist,falselabel);
  196. end;
  197. if not(assigned(right)) then
  198. begin
  199. cg.a_label(exprasmlist,truelabel);
  200. end;
  201. if cs_regalloc in aktglobalswitches then
  202. begin
  203. { add loads of regvars at the end of the then- and else-blocks }
  204. { so that at the end of both blocks the same regvars are loaded }
  205. { no else block? }
  206. if not assigned(t1) then
  207. sync_regvars(org_list,then_list,org_regvar_loaded,
  208. then_regvar_loaded)
  209. { no then block? }
  210. else if not assigned(right) then
  211. sync_regvars(org_list,else_list,org_regvar_loaded,
  212. else_regvar_loaded)
  213. { both else and then blocks }
  214. else
  215. sync_regvars(then_list,else_list,then_regvar_loaded,
  216. else_regvar_loaded);
  217. { add all lists together }
  218. org_list.concatlist(then_list);
  219. then_list.free;
  220. org_list.concatlist(else_list);
  221. else_list.free;
  222. org_list.concatlist(exprasmlist);
  223. exprasmlist.free;
  224. exprasmlist := org_list;
  225. end;
  226. truelabel:=otlabel;
  227. falselabel:=oflabel;
  228. end;
  229. {*****************************************************************************
  230. SecondFor
  231. *****************************************************************************}
  232. procedure tcgfornode.pass_2;
  233. var
  234. l3,oldclabel,oldblabel : tasmlabel;
  235. temptovalue : boolean;
  236. hs : byte;
  237. temp1 : treference;
  238. hop : topcg;
  239. hcond : topcmp;
  240. opsize : tcgsize;
  241. count_var_is_signed : boolean;
  242. begin
  243. oldclabel:=aktcontinuelabel;
  244. oldblabel:=aktbreaklabel;
  245. getlabel(aktcontinuelabel);
  246. getlabel(aktbreaklabel);
  247. getlabel(l3);
  248. { only calculate reference }
  249. rg.cleartempgen;
  250. secondpass(t2);
  251. hs := t2.resulttype.def.size;
  252. opsize := def_cgsize(t2.resulttype.def);
  253. { first set the to value
  254. because the count var can be in the expression !! }
  255. rg.cleartempgen;
  256. secondpass(right);
  257. { calculate pointer value and check if changeable and if so }
  258. { load into temporary variable }
  259. if right.nodetype<>ordconstn then
  260. begin
  261. temp1.symbol:=nil;
  262. tg.gettempofsizereference(exprasmlist,hs,temp1);
  263. temptovalue:=true;
  264. if (right.location.loc=LOC_REGISTER) or
  265. (right.location.loc=LOC_CREGISTER) then
  266. begin
  267. cg.a_load_reg_ref(exprasmlist,opsize,
  268. right.location.register,temp1);
  269. rg.ungetregister(exprasmlist,right.location.register);
  270. end
  271. else
  272. cg.g_concatcopy(exprasmlist,right.location.reference,temp1,
  273. hs,true,false);
  274. end
  275. else
  276. temptovalue:=false;
  277. { produce start assignment }
  278. rg.cleartempgen;
  279. secondpass(left);
  280. count_var_is_signed:=is_signed(t2.resulttype.def);
  281. if nf_backward in flags then
  282. if count_var_is_signed then
  283. hcond:=OC_LT
  284. else
  285. hcond:=OC_B
  286. else
  287. if count_var_is_signed then
  288. hcond:=OC_GT
  289. else
  290. hcond:=OC_A;
  291. load_all_regvars(exprasmlist);
  292. if temptovalue then
  293. begin
  294. cg.a_cmp_ref_loc_label(exprasmlist,opsize,hcond,
  295. temp1,t2.location,aktbreaklabel);
  296. end
  297. else
  298. begin
  299. if testatbegin then
  300. begin
  301. cg.a_cmp_const_loc_label(exprasmlist,opsize,hcond,
  302. aword(tordconstnode(right).value),
  303. t2.location,aktbreaklabel);
  304. end;
  305. end;
  306. if nf_backward in flags then
  307. hop:=OP_ADD
  308. else
  309. hop:=OP_SUB;
  310. cg.a_op_const_loc(exprasmlist,hop,1,t2.location);
  311. if not(cs_littlesize in aktglobalswitches) then
  312. { align loop target }
  313. exprasmList.concat(Tai_align.Create(aktalignment.loopalign));
  314. cg.a_label(exprasmlist,l3);
  315. { according to count direction DEC or INC... }
  316. if nf_backward in flags then
  317. hop:=OP_SUB
  318. else
  319. hop:=OP_ADD;
  320. cg.a_op_const_loc(exprasmlist,hop,1,t2.location);
  321. { help register must not be in instruction block }
  322. rg.cleartempgen;
  323. if assigned(t1) then
  324. begin
  325. secondpass(t1);
  326. load_all_regvars(exprasmlist);
  327. end;
  328. cg.a_label(exprasmlist,aktcontinuelabel);
  329. { makes no problems there }
  330. rg.cleartempgen;
  331. if nf_backward in flags then
  332. if count_var_is_signed then
  333. hcond:=OC_GT
  334. else
  335. hcond:=OC_A
  336. else
  337. if count_var_is_signed then
  338. hcond:=OC_LT
  339. else
  340. hcond:=OC_B;
  341. load_all_regvars(exprasmlist);
  342. { produce comparison and the corresponding }
  343. { jump }
  344. if temptovalue then
  345. begin
  346. cg.a_cmp_ref_loc_label(exprasmlist,opsize,hcond,temp1,
  347. t2.location,l3);
  348. end
  349. else
  350. begin
  351. cg.a_cmp_const_loc_label(exprasmlist,opsize,hcond,
  352. aword(tordconstnode(right).value),t2.location,l3);
  353. end;
  354. if temptovalue then
  355. tg.ungetiftemp(exprasmlist,temp1);
  356. { this is the break label: }
  357. cg.a_label(exprasmlist,aktbreaklabel);
  358. aktcontinuelabel:=oldclabel;
  359. aktbreaklabel:=oldblabel;
  360. { a break/continue in a for block can't be seen outside }
  361. flowcontrol:=flowcontrol-[fc_break,fc_continue];
  362. end;
  363. {*****************************************************************************
  364. SecondExitN
  365. *****************************************************************************}
  366. procedure tcgexitnode.pass_2;
  367. var
  368. {op : tasmop;
  369. s : topsize;}
  370. otlabel,oflabel : tasmlabel;
  371. cgsize : tcgsize;
  372. hreg : tregister;
  373. allocated_acc,
  374. allocated_acchigh: boolean;
  375. label
  376. do_jmp;
  377. begin
  378. { load_all_regvars(exprasmlist); }
  379. include(flowcontrol,fc_exit);
  380. if assigned(left) then
  381. if left.nodetype=assignn then
  382. begin
  383. { just do a normal assignment followed by exit }
  384. secondpass(left);
  385. cg.a_jmp_always(exprasmlist,aktexitlabel);
  386. end
  387. else
  388. begin
  389. allocated_acc := false;
  390. allocated_acchigh := false;
  391. otlabel:=truelabel;
  392. oflabel:=falselabel;
  393. getlabel(truelabel);
  394. getlabel(falselabel);
  395. secondpass(left);
  396. { the result of left is not needed anymore after this
  397. node }
  398. location_freetemp(exprasmlist,left.location);
  399. location_release(exprasmlist,left.location);
  400. case left.location.loc of
  401. LOC_FPUREGISTER :
  402. goto do_jmp;
  403. LOC_FLAGS :
  404. begin
  405. cg.a_reg_alloc(exprasmlist,accumulator);
  406. allocated_acc := true;
  407. cg.g_flags2reg(exprasmlist,left.location.resflags,accumulator);
  408. goto do_jmp;
  409. end;
  410. LOC_JUMP :
  411. begin
  412. cg.a_reg_alloc(exprasmlist,accumulator);
  413. { get an 8-bit register }
  414. hreg:=rg.makeregsize(accumulator,OS_8);
  415. allocated_acc := true;
  416. cg.a_label(exprasmlist,truelabel);
  417. cg.a_load_const_reg(exprasmlist,OS_8,1,hreg);
  418. cg.a_jmp_always(exprasmlist,aktexit2label);
  419. cg.a_label(exprasmlist,falselabel);
  420. cg.a_load_const_reg(exprasmlist,OS_8,0,hreg);
  421. goto do_jmp;
  422. end;
  423. end;
  424. case aktprocdef.rettype.def.deftype of
  425. pointerdef,
  426. procvardef :
  427. begin
  428. cg.a_reg_alloc(exprasmlist,accumulator);
  429. allocated_acc := true;
  430. cg.a_load_loc_reg(exprasmlist,left.location,accumulator);
  431. end;
  432. floatdef :
  433. begin
  434. {$ifndef i386}
  435. cg.a_reg_alloc(exprasmlist,fpuresultreg);
  436. {$endif not i386}
  437. cg.a_loadfpu_loc_reg(exprasmlist,left.location,fpuresultreg);
  438. end;
  439. else
  440. begin
  441. cgsize:=def_cgsize(aktprocdef.rettype.def);
  442. cg.a_reg_alloc(exprasmlist,accumulator);
  443. allocated_acc := true;
  444. case cgsize of
  445. OS_64,OS_S64 :
  446. begin
  447. cg.a_reg_alloc(exprasmlist,accumulatorhigh);
  448. allocated_acchigh := true;
  449. cg64.a_load64_loc_reg(exprasmlist,left.location,
  450. joinreg64(accumulator,accumulatorhigh));
  451. end
  452. else
  453. begin
  454. hreg:=rg.makeregsize(accumulator,cgsize);
  455. cg.a_load_loc_reg(exprasmlist,left.location,hreg);
  456. end;
  457. end;
  458. end;
  459. end;
  460. do_jmp:
  461. truelabel:=otlabel;
  462. falselabel:=oflabel;
  463. cg.a_jmp_always(exprasmlist,aktexit2label);
  464. if allocated_acc then
  465. cg.a_reg_dealloc(exprasmlist,accumulator);
  466. if allocated_acchigh then
  467. cg.a_reg_dealloc(exprasmlist,accumulatorhigh);
  468. {$ifndef i386}
  469. if (aktprocdef.rettype.def.deftype = floatdef) then
  470. cg.a_reg_dealloc(exprasmlist,fpuresultreg);
  471. {$endif not i386}
  472. end
  473. else
  474. cg.a_jmp_always(exprasmlist,aktexitlabel);
  475. end;
  476. {*****************************************************************************
  477. SecondBreakN
  478. *****************************************************************************}
  479. procedure tcgbreaknode.pass_2;
  480. begin
  481. include(flowcontrol,fc_break);
  482. if aktbreaklabel<>nil then
  483. begin
  484. load_all_regvars(exprasmlist);
  485. cg.a_jmp_always(exprasmlist,aktbreaklabel)
  486. end
  487. else
  488. CGMessage(cg_e_break_not_allowed);
  489. end;
  490. {*****************************************************************************
  491. SecondContinueN
  492. *****************************************************************************}
  493. procedure tcgcontinuenode.pass_2;
  494. begin
  495. include(flowcontrol,fc_continue);
  496. if aktcontinuelabel<>nil then
  497. begin
  498. load_all_regvars(exprasmlist);
  499. cg.a_jmp_always(exprasmlist,aktcontinuelabel)
  500. end
  501. else
  502. CGMessage(cg_e_continue_not_allowed);
  503. end;
  504. {*****************************************************************************
  505. SecondGoto
  506. *****************************************************************************}
  507. procedure tcggotonode.pass_2;
  508. begin
  509. load_all_regvars(exprasmlist);
  510. cg.a_jmp_always(exprasmlist,labelnr)
  511. end;
  512. {*****************************************************************************
  513. SecondLabel
  514. *****************************************************************************}
  515. procedure tcglabelnode.pass_2;
  516. begin
  517. load_all_regvars(exprasmlist);
  518. cg.a_label(exprasmlist,labelnr);
  519. rg.cleartempgen;
  520. secondpass(left);
  521. end;
  522. {*****************************************************************************
  523. SecondFail
  524. *****************************************************************************}
  525. procedure tcgfailnode.pass_2;
  526. begin
  527. cg.a_jmp_always(exprasmlist,faillabel);
  528. end;
  529. begin
  530. cwhilerepeatnode:=tcgwhilerepeatnode;
  531. cifnode:=tcgifnode;
  532. cfornode:=tcgfornode;
  533. cexitnode:=tcgexitnode;
  534. cbreaknode:=tcgbreaknode;
  535. ccontinuenode:=tcgcontinuenode;
  536. cgotonode:=tcggotonode;
  537. clabelnode:=tcglabelnode;
  538. cfailnode:=tcgfailnode;
  539. end.
  540. {
  541. $Log$
  542. Revision 1.27 2002-07-20 12:54:53 daniel
  543. * Optimized the code generated for for nodes. The shootout/nestloop benchmark
  544. now runs 5% faster on my computer.
  545. Revision 1.26 2002/07/20 11:57:54 florian
  546. * types.pas renamed to defbase.pas because D6 contains a types
  547. unit so this would conflicts if D6 programms are compiled
  548. + Willamette/SSE2 instructions to assembler added
  549. Revision 1.25 2002/07/20 11:15:51 daniel
  550. * The for node does a check if the first comparision can be skipped. I moved
  551. the check from the second pass to the resulttype pass. The advantage is
  552. that the state tracker can now decide to skip the first comparision too.
  553. Revision 1.24 2002/07/20 08:14:24 daniel
  554. * Loops should not be aligned when optimizing for size
  555. Revision 1.23 2002/07/19 11:41:35 daniel
  556. * State tracker work
  557. * The whilen and repeatn are now completely unified into whilerepeatn. This
  558. allows the state tracker to change while nodes automatically into
  559. repeat nodes.
  560. * Resulttypepass improvements to the notn. 'not not a' is optimized away and
  561. 'not(a>b)' is optimized into 'a<=b'.
  562. * Resulttypepass improvements to the whilerepeatn. 'while not a' is optimized
  563. by removing the notn and later switchting the true and falselabels. The
  564. same is done with 'repeat until not a'.
  565. Revision 1.22 2002/07/04 20:43:01 florian
  566. * first x86-64 patches
  567. Revision 1.21 2002/07/01 18:46:22 peter
  568. * internal linker
  569. * reorganized aasm layer
  570. Revision 1.20 2002/07/01 16:23:53 peter
  571. * cg64 patch
  572. * basics for currency
  573. * asnode updates for class and interface (not finished)
  574. Revision 1.19 2002/05/20 13:30:40 carl
  575. * bugfix of hdisponen (base must be set, not index)
  576. * more portability fixes
  577. Revision 1.18 2002/05/18 13:34:09 peter
  578. * readded missing revisions
  579. Revision 1.17 2002/05/16 19:46:37 carl
  580. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  581. + try to fix temp allocation (still in ifdef)
  582. + generic constructor calls
  583. + start of tassembler / tmodulebase class cleanup
  584. Revision 1.15 2002/05/13 19:54:37 peter
  585. * removed n386ld and n386util units
  586. * maybe_save/maybe_restore added instead of the old maybe_push
  587. Revision 1.14 2002/05/12 16:53:07 peter
  588. * moved entry and exitcode to ncgutil and cgobj
  589. * foreach gets extra argument for passing local data to the
  590. iterator function
  591. * -CR checks also class typecasts at runtime by changing them
  592. into as
  593. * fixed compiler to cycle with the -CR option
  594. * fixed stabs with elf writer, finally the global variables can
  595. be watched
  596. * removed a lot of routines from cga unit and replaced them by
  597. calls to cgobj
  598. * u32bit-s32bit updates for and,or,xor nodes. When one element is
  599. u32bit then the other is typecasted also to u32bit without giving
  600. a rangecheck warning/error.
  601. * fixed pascal calling method with reversing also the high tree in
  602. the parast, detected by tcalcst3 test
  603. Revision 1.13 2002/04/21 15:24:38 carl
  604. + a_jmp_cond -> a_jmp_always (a_jmp_cond is NOT portable)
  605. + changeregsize -> rg.makeregsize
  606. Revision 1.12 2002/04/15 19:44:19 peter
  607. * fixed stackcheck that would be called recursively when a stack
  608. error was found
  609. * generic changeregsize(reg,size) for i386 register resizing
  610. * removed some more routines from cga unit
  611. * fixed returnvalue handling
  612. * fixed default stacksize of linux and go32v2, 8kb was a bit small :-)
  613. Revision 1.11 2002/04/04 19:05:57 peter
  614. * removed unused units
  615. * use tlocation.size in cg.a_*loc*() routines
  616. Revision 1.10 2002/04/02 17:11:28 peter
  617. * tlocation,treference update
  618. * LOC_CONSTANT added for better constant handling
  619. * secondadd splitted in multiple routines
  620. * location_force_reg added for loading a location to a register
  621. of a specified size
  622. * secondassignment parses now first the right and then the left node
  623. (this is compatible with Kylix). This saves a lot of push/pop especially
  624. with string operations
  625. * adapted some routines to use the new cg methods
  626. Revision 1.9 2002/03/31 20:26:34 jonas
  627. + a_loadfpu_* and a_loadmm_* methods in tcg
  628. * register allocation is now handled by a class and is mostly processor
  629. independent (+rgobj.pas and i386/rgcpu.pas)
  630. * temp allocation is now handled by a class (+tgobj.pas, -i386\tgcpu.pas)
  631. * some small improvements and fixes to the optimizer
  632. * some register allocation fixes
  633. * some fpuvaroffset fixes in the unary minus node
  634. * push/popusedregisters is now called rg.save/restoreusedregisters and
  635. (for i386) uses temps instead of push/pop's when using -Op3 (that code is
  636. also better optimizable)
  637. * fixed and optimized register saving/restoring for new/dispose nodes
  638. * LOC_FPU locations now also require their "register" field to be set to
  639. R_ST, not R_ST0 (the latter is used for LOC_CFPUREGISTER locations only)
  640. - list field removed of the tnode class because it's not used currently
  641. and can cause hard-to-find bugs
  642. Revision 1.8 2002/03/04 19:10:11 peter
  643. * removed compiler warnings
  644. }