ncgflw.pas 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757
  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 nf_testatbegin in flags 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 nf_checknegate in flags 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 nf_testatbegin in flags 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,FPU_RESULT_REG);
  436. {$endif not i386}
  437. cg.a_loadfpu_loc_reg(exprasmlist,left.location,FPU_RESULT_REG);
  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,FPU_RESULT_REG);
  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.29 2002-07-25 17:56:29 carl
  543. + FPURESULTREG -> FPU_RESULT_REG
  544. Revision 1.28 2002/07/21 06:58:49 daniel
  545. * Changed booleans into flags
  546. Revision 1.27 2002/07/20 12:54:53 daniel
  547. * Optimized the code generated for for nodes. The shootout/nestloop benchmark
  548. now runs 5% faster on my computer.
  549. Revision 1.26 2002/07/20 11:57:54 florian
  550. * types.pas renamed to defbase.pas because D6 contains a types
  551. unit so this would conflicts if D6 programms are compiled
  552. + Willamette/SSE2 instructions to assembler added
  553. Revision 1.25 2002/07/20 11:15:51 daniel
  554. * The for node does a check if the first comparision can be skipped. I moved
  555. the check from the second pass to the resulttype pass. The advantage is
  556. that the state tracker can now decide to skip the first comparision too.
  557. Revision 1.24 2002/07/20 08:14:24 daniel
  558. * Loops should not be aligned when optimizing for size
  559. Revision 1.23 2002/07/19 11:41:35 daniel
  560. * State tracker work
  561. * The whilen and repeatn are now completely unified into whilerepeatn. This
  562. allows the state tracker to change while nodes automatically into
  563. repeat nodes.
  564. * Resulttypepass improvements to the notn. 'not not a' is optimized away and
  565. 'not(a>b)' is optimized into 'a<=b'.
  566. * Resulttypepass improvements to the whilerepeatn. 'while not a' is optimized
  567. by removing the notn and later switchting the true and falselabels. The
  568. same is done with 'repeat until not a'.
  569. Revision 1.22 2002/07/04 20:43:01 florian
  570. * first x86-64 patches
  571. Revision 1.21 2002/07/01 18:46:22 peter
  572. * internal linker
  573. * reorganized aasm layer
  574. Revision 1.20 2002/07/01 16:23:53 peter
  575. * cg64 patch
  576. * basics for currency
  577. * asnode updates for class and interface (not finished)
  578. Revision 1.19 2002/05/20 13:30:40 carl
  579. * bugfix of hdisponen (base must be set, not index)
  580. * more portability fixes
  581. Revision 1.18 2002/05/18 13:34:09 peter
  582. * readded missing revisions
  583. Revision 1.17 2002/05/16 19:46:37 carl
  584. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  585. + try to fix temp allocation (still in ifdef)
  586. + generic constructor calls
  587. + start of tassembler / tmodulebase class cleanup
  588. Revision 1.15 2002/05/13 19:54:37 peter
  589. * removed n386ld and n386util units
  590. * maybe_save/maybe_restore added instead of the old maybe_push
  591. Revision 1.14 2002/05/12 16:53:07 peter
  592. * moved entry and exitcode to ncgutil and cgobj
  593. * foreach gets extra argument for passing local data to the
  594. iterator function
  595. * -CR checks also class typecasts at runtime by changing them
  596. into as
  597. * fixed compiler to cycle with the -CR option
  598. * fixed stabs with elf writer, finally the global variables can
  599. be watched
  600. * removed a lot of routines from cga unit and replaced them by
  601. calls to cgobj
  602. * u32bit-s32bit updates for and,or,xor nodes. When one element is
  603. u32bit then the other is typecasted also to u32bit without giving
  604. a rangecheck warning/error.
  605. * fixed pascal calling method with reversing also the high tree in
  606. the parast, detected by tcalcst3 test
  607. Revision 1.13 2002/04/21 15:24:38 carl
  608. + a_jmp_cond -> a_jmp_always (a_jmp_cond is NOT portable)
  609. + changeregsize -> rg.makeregsize
  610. Revision 1.12 2002/04/15 19:44:19 peter
  611. * fixed stackcheck that would be called recursively when a stack
  612. error was found
  613. * generic changeregsize(reg,size) for i386 register resizing
  614. * removed some more routines from cga unit
  615. * fixed returnvalue handling
  616. * fixed default stacksize of linux and go32v2, 8kb was a bit small :-)
  617. Revision 1.11 2002/04/04 19:05:57 peter
  618. * removed unused units
  619. * use tlocation.size in cg.a_*loc*() routines
  620. Revision 1.10 2002/04/02 17:11:28 peter
  621. * tlocation,treference update
  622. * LOC_CONSTANT added for better constant handling
  623. * secondadd splitted in multiple routines
  624. * location_force_reg added for loading a location to a register
  625. of a specified size
  626. * secondassignment parses now first the right and then the left node
  627. (this is compatible with Kylix). This saves a lot of push/pop especially
  628. with string operations
  629. * adapted some routines to use the new cg methods
  630. Revision 1.9 2002/03/31 20:26:34 jonas
  631. + a_loadfpu_* and a_loadmm_* methods in tcg
  632. * register allocation is now handled by a class and is mostly processor
  633. independent (+rgobj.pas and i386/rgcpu.pas)
  634. * temp allocation is now handled by a class (+tgobj.pas, -i386\tgcpu.pas)
  635. * some small improvements and fixes to the optimizer
  636. * some register allocation fixes
  637. * some fpuvaroffset fixes in the unary minus node
  638. * push/popusedregisters is now called rg.save/restoreusedregisters and
  639. (for i386) uses temps instead of push/pop's when using -Op3 (that code is
  640. also better optimizable)
  641. * fixed and optimized register saving/restoring for new/dispose nodes
  642. * LOC_FPU locations now also require their "register" field to be set to
  643. R_ST, not R_ST0 (the latter is used for LOC_CFPUREGISTER locations only)
  644. - list field removed of the tnode class because it's not used currently
  645. and can cause hard-to-find bugs
  646. Revision 1.8 2002/03/04 19:10:11 peter
  647. * removed compiler warnings
  648. }