ncgflw.pas 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 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. implementation
  50. uses
  51. verbose,globals,systems,globtype,
  52. symconst,symsym,aasm,types,
  53. cginfo,cgbase,pass_2,
  54. cpubase,cpuasm,cpuinfo,
  55. nld,ncon,
  56. tgobj,rgobj,
  57. ncgutil,
  58. regvars,cgobj,cgcpu,cg64f32;
  59. {*****************************************************************************
  60. Second_While_RepeatN
  61. *****************************************************************************}
  62. procedure tcgwhilerepeatnode.pass_2;
  63. var
  64. lcont,lbreak,lloop,
  65. oldclabel,oldblabel : tasmlabel;
  66. otlabel,oflabel : tasmlabel;
  67. begin
  68. getlabel(lloop);
  69. getlabel(lcont);
  70. getlabel(lbreak);
  71. { arrange continue and breaklabels: }
  72. oldclabel:=aktcontinuelabel;
  73. oldblabel:=aktbreaklabel;
  74. load_all_regvars(exprasmlist);
  75. { handling code at the end as it is much more efficient, and makes
  76. while equal to repeat loop, only the end true/false is swapped (PFV) }
  77. if nodetype=whilen then
  78. cg.a_jmp_always(exprasmlist,lcont);
  79. { align loop target }
  80. exprasmList.concat(Tai_align.Create(aktalignment.loopalign));
  81. cg.a_label(exprasmlist,lloop);
  82. aktcontinuelabel:=lcont;
  83. aktbreaklabel:=lbreak;
  84. rg.cleartempgen;
  85. if assigned(right) then
  86. secondpass(right);
  87. load_all_regvars(exprasmlist);
  88. cg.a_label(exprasmlist,lcont);
  89. otlabel:=truelabel;
  90. oflabel:=falselabel;
  91. if nodetype=whilen then
  92. begin
  93. truelabel:=lloop;
  94. falselabel:=lbreak;
  95. end
  96. { repeatn }
  97. else
  98. begin
  99. truelabel:=lbreak;
  100. falselabel:=lloop;
  101. end;
  102. rg.cleartempgen;
  103. secondpass(left);
  104. maketojumpbool(exprasmlist,left,lr_load_regvars);
  105. cg.a_label(exprasmlist,lbreak);
  106. truelabel:=otlabel;
  107. falselabel:=oflabel;
  108. aktcontinuelabel:=oldclabel;
  109. aktbreaklabel:=oldblabel;
  110. { a break/continue in a while/repeat block can't be seen outside }
  111. flowcontrol:=flowcontrol-[fc_break,fc_continue];
  112. end;
  113. {*****************************************************************************
  114. tcgIFNODE
  115. *****************************************************************************}
  116. procedure tcgifnode.pass_2;
  117. var
  118. hl,otlabel,oflabel : tasmlabel;
  119. org_regvar_loaded,
  120. then_regvar_loaded,
  121. else_regvar_loaded : regvar_booleanarray;
  122. org_list,
  123. then_list,
  124. else_list : taasmoutput;
  125. begin
  126. otlabel:=truelabel;
  127. oflabel:=falselabel;
  128. getlabel(truelabel);
  129. getlabel(falselabel);
  130. rg.cleartempgen;
  131. secondpass(left);
  132. { save regvars loaded in the beginning so that we can restore them }
  133. { when processing the else-block }
  134. if cs_regalloc in aktglobalswitches then
  135. begin
  136. org_list := exprasmlist;
  137. exprasmlist := taasmoutput.create;
  138. end;
  139. maketojumpbool(exprasmlist,left,lr_dont_load_regvars);
  140. if cs_regalloc in aktglobalswitches then
  141. org_regvar_loaded := rg.regvar_loaded;
  142. if assigned(right) then
  143. begin
  144. cg.a_label(exprasmlist,truelabel);
  145. rg.cleartempgen;
  146. secondpass(right);
  147. end;
  148. { save current asmlist (previous instructions + then-block) and }
  149. { loaded regvar state and create new clean ones }
  150. if cs_regalloc in aktglobalswitches then
  151. begin
  152. then_regvar_loaded := rg.regvar_loaded;
  153. rg.regvar_loaded := org_regvar_loaded;
  154. then_list := exprasmlist;
  155. exprasmlist := taasmoutput.create;
  156. end;
  157. if assigned(t1) then
  158. begin
  159. if assigned(right) then
  160. begin
  161. getlabel(hl);
  162. { do go back to if line !! }
  163. if not(cs_regalloc in aktglobalswitches) then
  164. aktfilepos:=exprasmList.getlasttaifilepos^
  165. else
  166. aktfilepos:=then_list.getlasttaifilepos^;
  167. cg.a_jmp_always(exprasmlist,hl);
  168. end;
  169. cg.a_label(exprasmlist,falselabel);
  170. rg.cleartempgen;
  171. secondpass(t1);
  172. { save current asmlist (previous instructions + else-block) }
  173. { and loaded regvar state and create a new clean list }
  174. if cs_regalloc in aktglobalswitches then
  175. begin
  176. else_regvar_loaded := rg.regvar_loaded;
  177. else_list := exprasmlist;
  178. exprasmlist := taasmoutput.create;
  179. end;
  180. if assigned(right) then
  181. cg.a_label(exprasmlist,hl);
  182. end
  183. else
  184. begin
  185. if cs_regalloc in aktglobalswitches then
  186. begin
  187. else_regvar_loaded := rg.regvar_loaded;
  188. else_list := exprasmlist;
  189. exprasmlist := taasmoutput.create;
  190. end;
  191. cg.a_label(exprasmlist,falselabel);
  192. end;
  193. if not(assigned(right)) then
  194. begin
  195. cg.a_label(exprasmlist,truelabel);
  196. end;
  197. if cs_regalloc in aktglobalswitches then
  198. begin
  199. { add loads of regvars at the end of the then- and else-blocks }
  200. { so that at the end of both blocks the same regvars are loaded }
  201. { no else block? }
  202. if not assigned(t1) then
  203. sync_regvars(org_list,then_list,org_regvar_loaded,
  204. then_regvar_loaded)
  205. { no then block? }
  206. else if not assigned(right) then
  207. sync_regvars(org_list,else_list,org_regvar_loaded,
  208. else_regvar_loaded)
  209. { both else and then blocks }
  210. else
  211. sync_regvars(then_list,else_list,then_regvar_loaded,
  212. else_regvar_loaded);
  213. { add all lists together }
  214. org_list.concatlist(then_list);
  215. then_list.free;
  216. org_list.concatlist(else_list);
  217. else_list.free;
  218. org_list.concatlist(exprasmlist);
  219. exprasmlist.free;
  220. exprasmlist := org_list;
  221. end;
  222. truelabel:=otlabel;
  223. falselabel:=oflabel;
  224. end;
  225. {*****************************************************************************
  226. SecondFor
  227. *****************************************************************************}
  228. procedure tcgfornode.pass_2;
  229. var
  230. l3,oldclabel,oldblabel : tasmlabel;
  231. omitfirstcomp,temptovalue : boolean;
  232. hs : byte;
  233. temp1 : treference;
  234. hop : topcg;
  235. hcond : topcmp;
  236. opsize : tcgsize;
  237. count_var_is_signed : boolean;
  238. begin
  239. oldclabel:=aktcontinuelabel;
  240. oldblabel:=aktbreaklabel;
  241. getlabel(aktcontinuelabel);
  242. getlabel(aktbreaklabel);
  243. getlabel(l3);
  244. { could we spare the first comparison ? }
  245. omitfirstcomp:=false;
  246. if right.nodetype=ordconstn then
  247. if tassignmentnode(left).right.nodetype=ordconstn then
  248. omitfirstcomp:=((nf_backward in flags) and
  249. (tordconstnode(tassignmentnode(left).right).value>=tordconstnode(right).value))
  250. or (not(nf_backward in flags) and
  251. (tordconstnode(tassignmentnode(left).right).value<=tordconstnode(right).value));
  252. { only calculate reference }
  253. rg.cleartempgen;
  254. secondpass(t2);
  255. hs := t2.resulttype.def.size;
  256. opsize := def_cgsize(t2.resulttype.def);
  257. { first set the to value
  258. because the count var can be in the expression !! }
  259. rg.cleartempgen;
  260. secondpass(right);
  261. { calculate pointer value and check if changeable and if so }
  262. { load into temporary variable }
  263. if right.nodetype<>ordconstn then
  264. begin
  265. temp1.symbol:=nil;
  266. tg.gettempofsizereference(exprasmlist,hs,temp1);
  267. temptovalue:=true;
  268. if (right.location.loc=LOC_REGISTER) or
  269. (right.location.loc=LOC_CREGISTER) then
  270. begin
  271. cg.a_load_reg_ref(exprasmlist,opsize,
  272. right.location.register,temp1);
  273. rg.ungetregister(exprasmlist,right.location.register);
  274. end
  275. else
  276. cg.g_concatcopy(exprasmlist,right.location.reference,temp1,
  277. hs,true,false);
  278. end
  279. else
  280. temptovalue:=false;
  281. { produce start assignment }
  282. rg.cleartempgen;
  283. secondpass(left);
  284. count_var_is_signed:=is_signed(t2.resulttype.def);
  285. if nf_backward in flags then
  286. if count_var_is_signed then
  287. hcond:=OC_LT
  288. else
  289. hcond:=OC_B
  290. else
  291. if count_var_is_signed then
  292. hcond:=OC_GT
  293. else
  294. hcond:=OC_A;
  295. load_all_regvars(exprasmlist);
  296. if temptovalue then
  297. begin
  298. cg.a_cmp_ref_loc_label(exprasmlist,opsize,hcond,
  299. temp1,t2.location,aktbreaklabel);
  300. end
  301. else
  302. begin
  303. if not(omitfirstcomp) then
  304. begin
  305. cg.a_cmp_const_loc_label(exprasmlist,opsize,hcond,
  306. aword(tordconstnode(right).value),
  307. t2.location,aktbreaklabel);
  308. end;
  309. end;
  310. { align loop target }
  311. exprasmList.concat(Tai_align.Create(aktalignment.loopalign));
  312. cg.a_label(exprasmlist,l3);
  313. { help register must not be in instruction block }
  314. rg.cleartempgen;
  315. if assigned(t1) then
  316. begin
  317. secondpass(t1);
  318. load_all_regvars(exprasmlist);
  319. end;
  320. cg.a_label(exprasmlist,aktcontinuelabel);
  321. { makes no problems there }
  322. rg.cleartempgen;
  323. if nf_backward in flags then
  324. if count_var_is_signed then
  325. hcond:=OC_LTE
  326. else
  327. hcond:=OC_BE
  328. else
  329. if count_var_is_signed then
  330. hcond:=OC_GTE
  331. else
  332. hcond:=OC_AE;
  333. load_all_regvars(exprasmlist);
  334. { produce comparison and the corresponding }
  335. { jump }
  336. if temptovalue then
  337. begin
  338. cg.a_cmp_ref_loc_label(exprasmlist,opsize,hcond,temp1,
  339. t2.location,aktbreaklabel);
  340. end
  341. else
  342. begin
  343. cg.a_cmp_const_loc_label(exprasmlist,opsize,hcond,
  344. aword(tordconstnode(right).value),t2.location,aktbreaklabel);
  345. end;
  346. { according to count direction DEC or INC... }
  347. { must be after the test because of 0 to 255 for bytes !! }
  348. if nf_backward in flags then
  349. hop:=OP_SUB
  350. else
  351. hop:=OP_ADD;
  352. cg.a_op_const_loc(exprasmlist,hop,1,t2.location);
  353. cg.a_jmp_always(exprasmlist,l3);
  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. tcg64f32(cg).a_load64_loc_reg(exprasmlist,left.location,
  450. 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. begin
  523. cwhilerepeatnode:=tcgwhilerepeatnode;
  524. cifnode:=tcgifnode;
  525. cfornode:=tcgfornode;
  526. cexitnode:=tcgexitnode;
  527. cbreaknode:=tcgbreaknode;
  528. ccontinuenode:=tcgcontinuenode;
  529. cgotonode:=tcggotonode;
  530. clabelnode:=tcglabelnode;
  531. end.
  532. {
  533. $Log$
  534. Revision 1.17 2002-05-16 19:46:37 carl
  535. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  536. + try to fix temp allocation (still in ifdef)
  537. + generic constructor calls
  538. + start of tassembler / tmodulebase class cleanup
  539. Revision 1.15 2002/05/13 19:54:37 peter
  540. * removed n386ld and n386util units
  541. * maybe_save/maybe_restore added instead of the old maybe_push
  542. Revision 1.14 2002/05/12 16:53:07 peter
  543. * moved entry and exitcode to ncgutil and cgobj
  544. * foreach gets extra argument for passing local data to the
  545. iterator function
  546. * -CR checks also class typecasts at runtime by changing them
  547. into as
  548. * fixed compiler to cycle with the -CR option
  549. * fixed stabs with elf writer, finally the global variables can
  550. be watched
  551. * removed a lot of routines from cga unit and replaced them by
  552. calls to cgobj
  553. * u32bit-s32bit updates for and,or,xor nodes. When one element is
  554. u32bit then the other is typecasted also to u32bit without giving
  555. a rangecheck warning/error.
  556. * fixed pascal calling method with reversing also the high tree in
  557. the parast, detected by tcalcst3 test
  558. Revision 1.13 2002/04/21 15:24:38 carl
  559. + a_jmp_cond -> a_jmp_always (a_jmp_cond is NOT portable)
  560. + changeregsize -> rg.makeregsize
  561. Revision 1.12 2002/04/15 19:44:19 peter
  562. * fixed stackcheck that would be called recursively when a stack
  563. error was found
  564. * generic changeregsize(reg,size) for i386 register resizing
  565. * removed some more routines from cga unit
  566. * fixed returnvalue handling
  567. * fixed default stacksize of linux and go32v2, 8kb was a bit small :-)
  568. Revision 1.11 2002/04/04 19:05:57 peter
  569. * removed unused units
  570. * use tlocation.size in cg.a_*loc*() routines
  571. Revision 1.10 2002/04/02 17:11:28 peter
  572. * tlocation,treference update
  573. * LOC_CONSTANT added for better constant handling
  574. * secondadd splitted in multiple routines
  575. * location_force_reg added for loading a location to a register
  576. of a specified size
  577. * secondassignment parses now first the right and then the left node
  578. (this is compatible with Kylix). This saves a lot of push/pop especially
  579. with string operations
  580. * adapted some routines to use the new cg methods
  581. Revision 1.9 2002/03/31 20:26:34 jonas
  582. + a_loadfpu_* and a_loadmm_* methods in tcg
  583. * register allocation is now handled by a class and is mostly processor
  584. independent (+rgobj.pas and i386/rgcpu.pas)
  585. * temp allocation is now handled by a class (+tgobj.pas, -i386\tgcpu.pas)
  586. * some small improvements and fixes to the optimizer
  587. * some register allocation fixes
  588. * some fpuvaroffset fixes in the unary minus node
  589. * push/popusedregisters is now called rg.save/restoreusedregisters and
  590. (for i386) uses temps instead of push/pop's when using -Op3 (that code is
  591. also better optimizable)
  592. * fixed and optimized register saving/restoring for new/dispose nodes
  593. * LOC_FPU locations now also require their "register" field to be set to
  594. R_ST, not R_ST0 (the latter is used for LOC_CFPUREGISTER locations only)
  595. - list field removed of the tnode class because it's not used currently
  596. and can cause hard-to-find bugs
  597. Revision 1.8 2002/03/04 19:10:11 peter
  598. * removed compiler warnings
  599. Revision 1.7 2001/12/30 17:24:48 jonas
  600. * range checking is now processor independent (part in cgobj,
  601. part in cg64f32) and should work correctly again (it needed
  602. some changes after the changes of the low and high of
  603. tordef's to int64)
  604. * maketojumpbool() is now processor independent (in ncgutil)
  605. * getregister32 is now called getregisterint
  606. Revision 1.6 2001/12/29 15:28:57 jonas
  607. * powerpc/cgcpu.pas compiles :)
  608. * several powerpc-related fixes
  609. * cpuasm unit is now based on common tainst unit
  610. + nppcmat unit for powerpc (almost complete)
  611. Revision 1.4 2001/11/02 22:58:01 peter
  612. * procsym definition rewrite
  613. Revision 1.3 2001/10/04 14:33:28 jonas
  614. * fixed range check errors
  615. Revision 1.2 2001/09/30 16:19:58 jonas
  616. - removed unused units
  617. Revision 1.1 2001/09/28 20:39:33 jonas
  618. * changed all flow control structures (except for exception handling
  619. related things) to processor independent code (in new ncgflw unit)
  620. + generic cgobj unit which contains lots of code generator helpers with
  621. global "cg" class instance variable
  622. + cgcpu unit for i386 (implements processor specific routines of the above
  623. unit)
  624. * updated cgbase and cpubase for the new code generator units
  625. * include ncgflw unit in cpunode unit
  626. Revision 1.4 2001/09/09 17:10:25 jonas
  627. * some more things implemented
  628. Revision 1.3 2001/09/06 15:25:55 jonas
  629. * changed type of tcg from object to class -> abstract methods are now
  630. a lot cleaner :)
  631. + more updates: load_*_loc methods, op_*_* methods, g_flags2reg method
  632. (if possible with geenric implementation and necessary ppc
  633. implementations)
  634. * worked a bit further on cgflw, now working on exitnode
  635. Revision 1.2 2001/09/05 20:21:03 jonas
  636. * new cgflow based on n386flw with all nodes until forn "translated"
  637. + a_cmp_*_loc_label methods for tcg
  638. + base implementatino for a_cmp_ref_*_label methods
  639. * small bugfixes to powerpc cg
  640. }