ncgflw.pas 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715
  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 defines.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,symdef,symsym,aasm,types,
  53. cginfo,cgbase,pass_2,
  54. cpubase,cpuasm,cpuinfo,
  55. nld,ncon,
  56. cga,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_cond(exprasmlist,OC_None,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(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(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_cond(exprasmlist,OC_None,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(torddef(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_cond(exprasmlist,OC_None,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_cond(exprasmlist,OC_NONE,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. {$ifdef i386}
  414. hreg:=makereg8(accumulator);
  415. {$else i386}
  416. hreg:=accumulator;
  417. {$endif i386}
  418. allocated_acc := true;
  419. cg.a_label(exprasmlist,truelabel);
  420. cg.a_load_const_reg(exprasmlist,OS_8,1,hreg);
  421. cg.a_jmp_cond(exprasmlist,OC_NONE,aktexit2label);
  422. cg.a_label(exprasmlist,falselabel);
  423. cg.a_load_const_reg(exprasmlist,OS_8,0,hreg);
  424. goto do_jmp;
  425. end;
  426. end;
  427. case aktprocdef.rettype.def.deftype of
  428. pointerdef,
  429. procvardef :
  430. begin
  431. cg.a_reg_alloc(exprasmlist,accumulator);
  432. allocated_acc := true;
  433. cg.a_load_loc_reg(exprasmlist,left.location,accumulator);
  434. end;
  435. floatdef :
  436. begin
  437. {$ifndef i386}
  438. cg.a_reg_alloc(exprasmlist,fpuresultreg);
  439. {$endif not i386}
  440. cg.a_loadfpu_loc_reg(exprasmlist,left.location,fpuresultreg);
  441. end;
  442. else
  443. begin
  444. cgsize:=def_cgsize(aktprocdef.rettype.def);
  445. cg.a_reg_alloc(exprasmlist,accumulator);
  446. allocated_acc := true;
  447. case cgsize of
  448. OS_64,OS_S64 :
  449. begin
  450. cg.a_reg_alloc(exprasmlist,accumulatorhigh);
  451. allocated_acchigh := true;
  452. tcg64f32(cg).a_load64_loc_reg(exprasmlist,left.location,
  453. accumulator,accumulatorhigh);
  454. end
  455. else
  456. begin
  457. {$ifdef i386}
  458. case cgsize of
  459. OS_8,OS_S8 :
  460. hreg:=makereg8(accumulator);
  461. OS_16,OS_S16 :
  462. hreg:=makereg16(accumulator);
  463. else
  464. hreg:=accumulator;
  465. end;
  466. {$else}
  467. hreg:=accumulator;
  468. {$endif}
  469. cg.a_load_loc_reg(exprasmlist,left.location,hreg);
  470. end;
  471. end;
  472. end;
  473. end;
  474. do_jmp:
  475. truelabel:=otlabel;
  476. falselabel:=oflabel;
  477. cg.a_jmp_cond(exprasmlist,OC_None,aktexit2label);
  478. if allocated_acc then
  479. cg.a_reg_dealloc(exprasmlist,accumulator);
  480. if allocated_acchigh then
  481. cg.a_reg_dealloc(exprasmlist,accumulatorhigh);
  482. {$ifndef i386}
  483. if (aktprocdef.rettype.def.deftype = floatdef) then
  484. cg.a_reg_dealloc(exprasmlist,fpuresultreg);
  485. {$endif not i386}
  486. end
  487. else
  488. cg.a_jmp_cond(exprasmlist,OC_None,aktexitlabel);
  489. end;
  490. {*****************************************************************************
  491. SecondBreakN
  492. *****************************************************************************}
  493. procedure tcgbreaknode.pass_2;
  494. begin
  495. include(flowcontrol,fc_break);
  496. if aktbreaklabel<>nil then
  497. begin
  498. load_all_regvars(exprasmlist);
  499. cg.a_jmp_cond(exprasmlist,OC_None,aktbreaklabel)
  500. end
  501. else
  502. CGMessage(cg_e_break_not_allowed);
  503. end;
  504. {*****************************************************************************
  505. SecondContinueN
  506. *****************************************************************************}
  507. procedure tcgcontinuenode.pass_2;
  508. begin
  509. include(flowcontrol,fc_continue);
  510. if aktcontinuelabel<>nil then
  511. begin
  512. load_all_regvars(exprasmlist);
  513. cg.a_jmp_cond(exprasmlist,OC_None,aktcontinuelabel)
  514. end
  515. else
  516. CGMessage(cg_e_continue_not_allowed);
  517. end;
  518. {*****************************************************************************
  519. SecondGoto
  520. *****************************************************************************}
  521. procedure tcggotonode.pass_2;
  522. begin
  523. load_all_regvars(exprasmlist);
  524. cg.a_jmp_cond(exprasmlist,OC_None,labelnr)
  525. end;
  526. {*****************************************************************************
  527. SecondLabel
  528. *****************************************************************************}
  529. procedure tcglabelnode.pass_2;
  530. begin
  531. load_all_regvars(exprasmlist);
  532. cg.a_label(exprasmlist,labelnr);
  533. rg.cleartempgen;
  534. secondpass(left);
  535. end;
  536. begin
  537. cwhilerepeatnode:=tcgwhilerepeatnode;
  538. cifnode:=tcgifnode;
  539. cfornode:=tcgfornode;
  540. cexitnode:=tcgexitnode;
  541. cbreaknode:=tcgbreaknode;
  542. ccontinuenode:=tcgcontinuenode;
  543. cgotonode:=tcggotonode;
  544. clabelnode:=tcglabelnode;
  545. end.
  546. {
  547. $Log$
  548. Revision 1.11 2002-04-04 19:05:57 peter
  549. * removed unused units
  550. * use tlocation.size in cg.a_*loc*() routines
  551. Revision 1.10 2002/04/02 17:11:28 peter
  552. * tlocation,treference update
  553. * LOC_CONSTANT added for better constant handling
  554. * secondadd splitted in multiple routines
  555. * location_force_reg added for loading a location to a register
  556. of a specified size
  557. * secondassignment parses now first the right and then the left node
  558. (this is compatible with Kylix). This saves a lot of push/pop especially
  559. with string operations
  560. * adapted some routines to use the new cg methods
  561. Revision 1.9 2002/03/31 20:26:34 jonas
  562. + a_loadfpu_* and a_loadmm_* methods in tcg
  563. * register allocation is now handled by a class and is mostly processor
  564. independent (+rgobj.pas and i386/rgcpu.pas)
  565. * temp allocation is now handled by a class (+tgobj.pas, -i386\tgcpu.pas)
  566. * some small improvements and fixes to the optimizer
  567. * some register allocation fixes
  568. * some fpuvaroffset fixes in the unary minus node
  569. * push/popusedregisters is now called rg.save/restoreusedregisters and
  570. (for i386) uses temps instead of push/pop's when using -Op3 (that code is
  571. also better optimizable)
  572. * fixed and optimized register saving/restoring for new/dispose nodes
  573. * LOC_FPU locations now also require their "register" field to be set to
  574. R_ST, not R_ST0 (the latter is used for LOC_CFPUREGISTER locations only)
  575. - list field removed of the tnode class because it's not used currently
  576. and can cause hard-to-find bugs
  577. Revision 1.8 2002/03/04 19:10:11 peter
  578. * removed compiler warnings
  579. Revision 1.7 2001/12/30 17:24:48 jonas
  580. * range checking is now processor independent (part in cgobj,
  581. part in cg64f32) and should work correctly again (it needed
  582. some changes after the changes of the low and high of
  583. tordef's to int64)
  584. * maketojumpbool() is now processor independent (in ncgutil)
  585. * getregister32 is now called getregisterint
  586. Revision 1.6 2001/12/29 15:28:57 jonas
  587. * powerpc/cgcpu.pas compiles :)
  588. * several powerpc-related fixes
  589. * cpuasm unit is now based on common tainst unit
  590. + nppcmat unit for powerpc (almost complete)
  591. Revision 1.4 2001/11/02 22:58:01 peter
  592. * procsym definition rewrite
  593. Revision 1.3 2001/10/04 14:33:28 jonas
  594. * fixed range check errors
  595. Revision 1.2 2001/09/30 16:19:58 jonas
  596. - removed unused units
  597. Revision 1.1 2001/09/28 20:39:33 jonas
  598. * changed all flow control structures (except for exception handling
  599. related things) to processor independent code (in new ncgflw unit)
  600. + generic cgobj unit which contains lots of code generator helpers with
  601. global "cg" class instance variable
  602. + cgcpu unit for i386 (implements processor specific routines of the above
  603. unit)
  604. * updated cgbase and cpubase for the new code generator units
  605. * include ncgflw unit in cpunode unit
  606. Revision 1.4 2001/09/09 17:10:25 jonas
  607. * some more things implemented
  608. Revision 1.3 2001/09/06 15:25:55 jonas
  609. * changed type of tcg from object to class -> abstract methods are now
  610. a lot cleaner :)
  611. + more updates: load_*_loc methods, op_*_* methods, g_flags2reg method
  612. (if possible with geenric implementation and necessary ppc
  613. implementations)
  614. * worked a bit further on cgflw, now working on exitnode
  615. Revision 1.2 2001/09/05 20:21:03 jonas
  616. * new cgflow based on n386flw with all nodes until forn "translated"
  617. + a_cmp_*_loc_label methods for tcg
  618. + base implementatino for a_cmp_ref_*_label methods
  619. * small bugfixes to powerpc cg
  620. }