ncgflw.pas 46 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 by Florian Klaempfl
  4. Generate assembler for nodes that influence the flow which are
  5. the same for all (most?) processors
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2 of the License, or
  9. (at your option) any later version.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with this program; if not, write to the Free Software
  16. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. ****************************************************************************
  18. }
  19. unit ncgflw;
  20. {$i fpcdefs.inc}
  21. interface
  22. uses
  23. node,nflw;
  24. type
  25. tcgwhilerepeatnode = class(twhilerepeatnode)
  26. procedure pass_2;override;
  27. end;
  28. tcgifnode = class(tifnode)
  29. procedure pass_2;override;
  30. end;
  31. tcgfornode = class(tfornode)
  32. procedure pass_2;override;
  33. end;
  34. tcgexitnode = class(texitnode)
  35. procedure pass_2;override;
  36. end;
  37. tcgbreaknode = class(tbreaknode)
  38. procedure pass_2;override;
  39. end;
  40. tcgcontinuenode = class(tcontinuenode)
  41. procedure pass_2;override;
  42. end;
  43. tcggotonode = class(tgotonode)
  44. procedure pass_2;override;
  45. end;
  46. tcglabelnode = class(tlabelnode)
  47. procedure pass_2;override;
  48. end;
  49. tcgfailnode = class(tfailnode)
  50. procedure pass_2;override;
  51. end;
  52. tcgraisenode = class(traisenode)
  53. procedure pass_2;override;
  54. end;
  55. tcgtryexceptnode = class(ttryexceptnode)
  56. procedure pass_2;override;
  57. end;
  58. tcgtryfinallynode = class(ttryfinallynode)
  59. procedure pass_2;override;
  60. end;
  61. tcgonnode = class(tonnode)
  62. procedure pass_2;override;
  63. end;
  64. implementation
  65. uses
  66. verbose,globals,systems,globtype,
  67. symconst,symsym,aasmbase,aasmtai,aasmcpu,defbase,
  68. cginfo,cgbase,pass_2,
  69. cpubase,cpuinfo,
  70. nld,ncon,
  71. ncgutil,
  72. tgobj,rgobj,paramgr,
  73. regvars,cgobj,cgcpu,cg64f32;
  74. const
  75. EXCEPT_BUF_SIZE = 12;
  76. {*****************************************************************************
  77. Second_While_RepeatN
  78. *****************************************************************************}
  79. procedure tcgwhilerepeatnode.pass_2;
  80. var
  81. lcont,lbreak,lloop,
  82. oldclabel,oldblabel : tasmlabel;
  83. otlabel,oflabel : tasmlabel;
  84. begin
  85. objectlibrary.getlabel(lloop);
  86. objectlibrary.getlabel(lcont);
  87. objectlibrary.getlabel(lbreak);
  88. { arrange continue and breaklabels: }
  89. oldclabel:=aktcontinuelabel;
  90. oldblabel:=aktbreaklabel;
  91. load_all_regvars(exprasmlist);
  92. { handling code at the end as it is much more efficient, and makes
  93. while equal to repeat loop, only the end true/false is swapped (PFV) }
  94. if nf_testatbegin in flags then
  95. cg.a_jmp_always(exprasmlist,lcont);
  96. if not(cs_littlesize in aktglobalswitches) then
  97. { align loop target }
  98. exprasmList.concat(Tai_align.Create(aktalignment.loopalign));
  99. cg.a_label(exprasmlist,lloop);
  100. aktcontinuelabel:=lcont;
  101. aktbreaklabel:=lbreak;
  102. rg.cleartempgen;
  103. if assigned(right) then
  104. secondpass(right);
  105. load_all_regvars(exprasmlist);
  106. cg.a_label(exprasmlist,lcont);
  107. otlabel:=truelabel;
  108. oflabel:=falselabel;
  109. if nf_checknegate in flags then
  110. begin
  111. truelabel:=lbreak;
  112. falselabel:=lloop;
  113. end
  114. else
  115. begin
  116. truelabel:=lloop;
  117. falselabel:=lbreak;
  118. end;
  119. rg.cleartempgen;
  120. secondpass(left);
  121. maketojumpbool(exprasmlist,left,lr_load_regvars);
  122. cg.a_label(exprasmlist,lbreak);
  123. truelabel:=otlabel;
  124. falselabel:=oflabel;
  125. aktcontinuelabel:=oldclabel;
  126. aktbreaklabel:=oldblabel;
  127. { a break/continue in a while/repeat block can't be seen outside }
  128. flowcontrol:=flowcontrol-[fc_break,fc_continue];
  129. end;
  130. {*****************************************************************************
  131. tcgIFNODE
  132. *****************************************************************************}
  133. procedure tcgifnode.pass_2;
  134. var
  135. hl,otlabel,oflabel : tasmlabel;
  136. org_regvar_loaded,
  137. then_regvar_loaded,
  138. else_regvar_loaded : regvar_booleanarray;
  139. org_list,
  140. then_list,
  141. else_list : taasmoutput;
  142. begin
  143. otlabel:=truelabel;
  144. oflabel:=falselabel;
  145. objectlibrary.getlabel(truelabel);
  146. objectlibrary.getlabel(falselabel);
  147. rg.cleartempgen;
  148. secondpass(left);
  149. { save regvars loaded in the beginning so that we can restore them }
  150. { when processing the else-block }
  151. if cs_regalloc in aktglobalswitches then
  152. begin
  153. org_list := exprasmlist;
  154. exprasmlist := taasmoutput.create;
  155. end;
  156. maketojumpbool(exprasmlist,left,lr_dont_load_regvars);
  157. if cs_regalloc in aktglobalswitches then
  158. org_regvar_loaded := rg.regvar_loaded;
  159. if assigned(right) then
  160. begin
  161. cg.a_label(exprasmlist,truelabel);
  162. rg.cleartempgen;
  163. secondpass(right);
  164. end;
  165. { save current asmlist (previous instructions + then-block) and }
  166. { loaded regvar state and create new clean ones }
  167. if cs_regalloc in aktglobalswitches then
  168. begin
  169. then_regvar_loaded := rg.regvar_loaded;
  170. rg.regvar_loaded := org_regvar_loaded;
  171. then_list := exprasmlist;
  172. exprasmlist := taasmoutput.create;
  173. end;
  174. if assigned(t1) then
  175. begin
  176. if assigned(right) then
  177. begin
  178. objectlibrary.getlabel(hl);
  179. { do go back to if line !! }
  180. if not(cs_regalloc in aktglobalswitches) then
  181. aktfilepos:=exprasmList.getlasttaifilepos^
  182. else
  183. aktfilepos:=then_list.getlasttaifilepos^;
  184. cg.a_jmp_always(exprasmlist,hl);
  185. end;
  186. cg.a_label(exprasmlist,falselabel);
  187. rg.cleartempgen;
  188. secondpass(t1);
  189. { save current asmlist (previous instructions + else-block) }
  190. { and loaded regvar state and create a new clean list }
  191. if cs_regalloc in aktglobalswitches then
  192. begin
  193. else_regvar_loaded := rg.regvar_loaded;
  194. else_list := exprasmlist;
  195. exprasmlist := taasmoutput.create;
  196. end;
  197. if assigned(right) then
  198. cg.a_label(exprasmlist,hl);
  199. end
  200. else
  201. begin
  202. if cs_regalloc in aktglobalswitches then
  203. begin
  204. else_regvar_loaded := rg.regvar_loaded;
  205. else_list := exprasmlist;
  206. exprasmlist := taasmoutput.create;
  207. end;
  208. cg.a_label(exprasmlist,falselabel);
  209. end;
  210. if not(assigned(right)) then
  211. begin
  212. cg.a_label(exprasmlist,truelabel);
  213. end;
  214. if cs_regalloc in aktglobalswitches then
  215. begin
  216. { add loads of regvars at the end of the then- and else-blocks }
  217. { so that at the end of both blocks the same regvars are loaded }
  218. { no else block? }
  219. if not assigned(t1) then
  220. sync_regvars(org_list,then_list,org_regvar_loaded,
  221. then_regvar_loaded)
  222. { no then block? }
  223. else if not assigned(right) then
  224. sync_regvars(org_list,else_list,org_regvar_loaded,
  225. else_regvar_loaded)
  226. { both else and then blocks }
  227. else
  228. sync_regvars(then_list,else_list,then_regvar_loaded,
  229. else_regvar_loaded);
  230. { add all lists together }
  231. org_list.concatlist(then_list);
  232. then_list.free;
  233. org_list.concatlist(else_list);
  234. else_list.free;
  235. org_list.concatlist(exprasmlist);
  236. exprasmlist.free;
  237. exprasmlist := org_list;
  238. end;
  239. truelabel:=otlabel;
  240. falselabel:=oflabel;
  241. end;
  242. {*****************************************************************************
  243. SecondFor
  244. *****************************************************************************}
  245. procedure tcgfornode.pass_2;
  246. var
  247. l3,oldclabel,oldblabel : tasmlabel;
  248. temptovalue : boolean;
  249. hs : byte;
  250. temp1 : treference;
  251. hop : topcg;
  252. hcond : topcmp;
  253. opsize : tcgsize;
  254. count_var_is_signed : boolean;
  255. begin
  256. oldclabel:=aktcontinuelabel;
  257. oldblabel:=aktbreaklabel;
  258. objectlibrary.getlabel(aktcontinuelabel);
  259. objectlibrary.getlabel(aktbreaklabel);
  260. objectlibrary.getlabel(l3);
  261. { only calculate reference }
  262. rg.cleartempgen;
  263. secondpass(t2);
  264. hs := t2.resulttype.def.size;
  265. opsize := def_cgsize(t2.resulttype.def);
  266. { first set the to value
  267. because the count var can be in the expression !! }
  268. rg.cleartempgen;
  269. secondpass(right);
  270. { calculate pointer value and check if changeable and if so }
  271. { load into temporary variable }
  272. if right.nodetype<>ordconstn then
  273. begin
  274. tg.GetTemp(exprasmlist,hs,tt_normal,temp1);
  275. temptovalue:=true;
  276. if (right.location.loc=LOC_REGISTER) or
  277. (right.location.loc=LOC_CREGISTER) then
  278. begin
  279. cg.a_load_reg_ref(exprasmlist,opsize,
  280. right.location.register,temp1);
  281. rg.ungetregister(exprasmlist,right.location.register);
  282. end
  283. else
  284. cg.g_concatcopy(exprasmlist,right.location.reference,temp1,
  285. hs,true,false);
  286. end
  287. else
  288. temptovalue:=false;
  289. { produce start assignment }
  290. rg.cleartempgen;
  291. secondpass(left);
  292. count_var_is_signed:=is_signed(t2.resulttype.def);
  293. if nf_backward in flags then
  294. if count_var_is_signed then
  295. hcond:=OC_LT
  296. else
  297. hcond:=OC_B
  298. else
  299. if count_var_is_signed then
  300. hcond:=OC_GT
  301. else
  302. hcond:=OC_A;
  303. load_all_regvars(exprasmlist);
  304. if temptovalue then
  305. begin
  306. cg.a_cmp_ref_loc_label(exprasmlist,opsize,hcond,
  307. temp1,t2.location,aktbreaklabel);
  308. end
  309. else
  310. begin
  311. if nf_testatbegin in flags then
  312. begin
  313. cg.a_cmp_const_loc_label(exprasmlist,opsize,hcond,
  314. aword(tordconstnode(right).value),
  315. t2.location,aktbreaklabel);
  316. end;
  317. end;
  318. if nf_backward in flags then
  319. hop:=OP_ADD
  320. else
  321. hop:=OP_SUB;
  322. cg.a_op_const_loc(exprasmlist,hop,1,t2.location);
  323. if not(cs_littlesize in aktglobalswitches) then
  324. { align loop target }
  325. exprasmList.concat(Tai_align.Create(aktalignment.loopalign));
  326. cg.a_label(exprasmlist,l3);
  327. { according to count direction DEC or INC... }
  328. if nf_backward in flags then
  329. hop:=OP_SUB
  330. else
  331. hop:=OP_ADD;
  332. cg.a_op_const_loc(exprasmlist,hop,1,t2.location);
  333. { help register must not be in instruction block }
  334. rg.cleartempgen;
  335. if assigned(t1) then
  336. begin
  337. secondpass(t1);
  338. load_all_regvars(exprasmlist);
  339. end;
  340. cg.a_label(exprasmlist,aktcontinuelabel);
  341. { makes no problems there }
  342. rg.cleartempgen;
  343. if nf_backward in flags then
  344. if count_var_is_signed then
  345. hcond:=OC_GT
  346. else
  347. hcond:=OC_A
  348. else
  349. if count_var_is_signed then
  350. hcond:=OC_LT
  351. else
  352. hcond:=OC_B;
  353. load_all_regvars(exprasmlist);
  354. { produce comparison and the corresponding }
  355. { jump }
  356. if temptovalue then
  357. begin
  358. cg.a_cmp_ref_loc_label(exprasmlist,opsize,hcond,temp1,
  359. t2.location,l3);
  360. end
  361. else
  362. begin
  363. cg.a_cmp_const_loc_label(exprasmlist,opsize,hcond,
  364. aword(tordconstnode(right).value),t2.location,l3);
  365. end;
  366. if temptovalue then
  367. tg.ungetiftemp(exprasmlist,temp1);
  368. { this is the break label: }
  369. cg.a_label(exprasmlist,aktbreaklabel);
  370. aktcontinuelabel:=oldclabel;
  371. aktbreaklabel:=oldblabel;
  372. { a break/continue in a for block can't be seen outside }
  373. flowcontrol:=flowcontrol-[fc_break,fc_continue];
  374. end;
  375. {*****************************************************************************
  376. SecondExitN
  377. *****************************************************************************}
  378. procedure tcgexitnode.pass_2;
  379. var
  380. {op : tasmop;
  381. s : topsize;}
  382. otlabel,oflabel : tasmlabel;
  383. cgsize : tcgsize;
  384. hreg : tregister;
  385. allocated_acc,
  386. allocated_acchigh: boolean;
  387. label
  388. do_jmp;
  389. begin
  390. include(flowcontrol,fc_exit);
  391. if assigned(left) then
  392. begin
  393. if onlyassign then
  394. begin
  395. { just do a normal assignment followed by exit }
  396. secondpass(left);
  397. cg.a_jmp_always(exprasmlist,aktexitlabel);
  398. end
  399. else
  400. begin
  401. allocated_acc := false;
  402. allocated_acchigh := false;
  403. otlabel:=truelabel;
  404. oflabel:=falselabel;
  405. objectlibrary.getlabel(truelabel);
  406. objectlibrary.getlabel(falselabel);
  407. secondpass(left);
  408. { increment reference counter, this is
  409. useless for string constants }
  410. if (left.resulttype.def.needs_inittable) and
  411. (left.nodetype<>stringconstn) then
  412. cg.g_incrrefcount(exprasmlist,left.resulttype.def,left.location.reference);
  413. { the result of left is not needed anymore after this
  414. node }
  415. location_freetemp(exprasmlist,left.location);
  416. location_release(exprasmlist,left.location);
  417. case left.location.loc of
  418. LOC_FPUREGISTER :
  419. goto do_jmp;
  420. LOC_FLAGS :
  421. begin
  422. cg.a_reg_alloc(exprasmlist,accumulator);
  423. allocated_acc := true;
  424. cg.g_flags2reg(exprasmlist,OS_INT,left.location.resflags,accumulator);
  425. goto do_jmp;
  426. end;
  427. LOC_JUMP :
  428. begin
  429. cg.a_reg_alloc(exprasmlist,accumulator);
  430. { get an 8-bit register }
  431. hreg:=rg.makeregsize(accumulator,OS_8);
  432. allocated_acc := true;
  433. cg.a_label(exprasmlist,truelabel);
  434. cg.a_load_const_reg(exprasmlist,OS_8,1,hreg);
  435. cg.a_jmp_always(exprasmlist,aktexit2label);
  436. cg.a_label(exprasmlist,falselabel);
  437. cg.a_load_const_reg(exprasmlist,OS_8,0,hreg);
  438. goto do_jmp;
  439. end;
  440. end;
  441. case aktprocdef.rettype.def.deftype of
  442. pointerdef,
  443. procvardef :
  444. begin
  445. cg.a_reg_alloc(exprasmlist,accumulator);
  446. allocated_acc := true;
  447. cg.a_load_loc_reg(exprasmlist,left.location,accumulator);
  448. end;
  449. floatdef :
  450. begin
  451. {$ifndef i386}
  452. cg.a_reg_alloc(exprasmlist,FPU_RESULT_REG);
  453. {$endif not i386}
  454. cg.a_loadfpu_loc_reg(exprasmlist,left.location,FPU_RESULT_REG);
  455. end;
  456. else
  457. begin
  458. cgsize:=def_cgsize(aktprocdef.rettype.def);
  459. cg.a_reg_alloc(exprasmlist,accumulator);
  460. allocated_acc := true;
  461. case cgsize of
  462. OS_64,OS_S64 :
  463. begin
  464. cg.a_reg_alloc(exprasmlist,accumulatorhigh);
  465. allocated_acchigh := true;
  466. cg64.a_load64_loc_reg(exprasmlist,left.location,
  467. joinreg64(accumulator,accumulatorhigh));
  468. end
  469. else
  470. begin
  471. hreg:=rg.makeregsize(accumulator,cgsize);
  472. cg.a_load_loc_reg(exprasmlist,left.location,hreg);
  473. end;
  474. end;
  475. end;
  476. end;
  477. do_jmp:
  478. truelabel:=otlabel;
  479. falselabel:=oflabel;
  480. cg.a_jmp_always(exprasmlist,aktexit2label);
  481. if allocated_acc then
  482. cg.a_reg_dealloc(exprasmlist,accumulator);
  483. if allocated_acchigh then
  484. cg.a_reg_dealloc(exprasmlist,accumulatorhigh);
  485. {$ifndef i386}
  486. if (aktprocdef.rettype.def.deftype = floatdef) then
  487. cg.a_reg_dealloc(exprasmlist,FPU_RESULT_REG);
  488. {$endif not i386}
  489. end;
  490. end
  491. else
  492. cg.a_jmp_always(exprasmlist,aktexitlabel);
  493. end;
  494. {*****************************************************************************
  495. SecondBreakN
  496. *****************************************************************************}
  497. procedure tcgbreaknode.pass_2;
  498. begin
  499. include(flowcontrol,fc_break);
  500. if aktbreaklabel<>nil then
  501. begin
  502. load_all_regvars(exprasmlist);
  503. cg.a_jmp_always(exprasmlist,aktbreaklabel)
  504. end
  505. else
  506. CGMessage(cg_e_break_not_allowed);
  507. end;
  508. {*****************************************************************************
  509. SecondContinueN
  510. *****************************************************************************}
  511. procedure tcgcontinuenode.pass_2;
  512. begin
  513. include(flowcontrol,fc_continue);
  514. if aktcontinuelabel<>nil then
  515. begin
  516. load_all_regvars(exprasmlist);
  517. cg.a_jmp_always(exprasmlist,aktcontinuelabel)
  518. end
  519. else
  520. CGMessage(cg_e_continue_not_allowed);
  521. end;
  522. {*****************************************************************************
  523. SecondGoto
  524. *****************************************************************************}
  525. procedure tcggotonode.pass_2;
  526. begin
  527. load_all_regvars(exprasmlist);
  528. cg.a_jmp_always(exprasmlist,labsym.lab)
  529. end;
  530. {*****************************************************************************
  531. SecondLabel
  532. *****************************************************************************}
  533. procedure tcglabelnode.pass_2;
  534. begin
  535. load_all_regvars(exprasmlist);
  536. cg.a_label(exprasmlist,labelnr);
  537. rg.cleartempgen;
  538. secondpass(left);
  539. end;
  540. {*****************************************************************************
  541. SecondFail
  542. *****************************************************************************}
  543. procedure tcgfailnode.pass_2;
  544. begin
  545. cg.a_jmp_always(exprasmlist,faillabel);
  546. end;
  547. {*****************************************************************************
  548. SecondRaise
  549. *****************************************************************************}
  550. procedure tcgraisenode.pass_2;
  551. var
  552. a : tasmlabel;
  553. href : treference;
  554. href2: treference;
  555. begin
  556. if assigned(left) then
  557. begin
  558. { multiple parameters? }
  559. if assigned(right) then
  560. begin
  561. { push frame }
  562. if assigned(frametree) then
  563. begin
  564. secondpass(frametree);
  565. if codegenerror then
  566. exit;
  567. cg.a_param_loc(exprasmlist,frametree.location,paramanager.getintparaloc(2));
  568. end
  569. else
  570. cg.a_param_const(exprasmlist,OS_INT,0,paramanager.getintparaloc(2));
  571. { push address }
  572. secondpass(right);
  573. if codegenerror then
  574. exit;
  575. cg.a_param_loc(exprasmlist,right.location,paramanager.getintparaloc(1));
  576. end
  577. else
  578. begin
  579. { get current address }
  580. objectlibrary.getaddrlabel(a);
  581. cg.a_label(exprasmlist,a);
  582. reference_reset_symbol(href2,a,0);
  583. { push current frame }
  584. cg.a_param_reg(exprasmlist,OS_ADDR,FRAME_POINTER_REG,paramanager.getintparaloc(2));
  585. { push current address }
  586. cg.a_paramaddr_ref(exprasmlist,href2,paramanager.getintparaloc(1));
  587. end;
  588. { push object }
  589. secondpass(left);
  590. if codegenerror then
  591. exit;
  592. cg.a_param_loc(exprasmlist,left.location,paramanager.getintparaloc(1));
  593. cg.a_call_name(exprasmlist,'FPC_RAISEEXCEPTION');
  594. end
  595. else
  596. begin
  597. cg.a_call_name(exprasmlist,'FPC_POPADDRSTACK');
  598. cg.a_call_name(exprasmlist,'FPC_RERAISE');
  599. end;
  600. end;
  601. {*****************************************************************************
  602. SecondTryExcept
  603. *****************************************************************************}
  604. var
  605. endexceptlabel : tasmlabel;
  606. procedure try_new_exception(list : taasmoutput;var jmpbuf,envbuf, href : treference;
  607. a : aword; exceptlabel : tasmlabel);
  608. begin
  609. tg.GetTemp(list,EXCEPT_BUF_SIZE,tt_persistant,envbuf);
  610. tg.GetTemp(list,JMP_BUF_SIZE,tt_persistant,jmpbuf);
  611. tg.GetTemp(list,sizeof(aword),tt_persistant,href);
  612. new_exception(list, jmpbuf,envbuf, href, a, exceptlabel);
  613. end;
  614. procedure try_free_exception(list : taasmoutput;var jmpbuf, envbuf, href : treference;
  615. a : aword ; endexceptlabel : tasmlabel; onlyfree : boolean);
  616. begin
  617. free_exception(list, jmpbuf, envbuf, href, a, endexceptlabel, onlyfree);
  618. tg.ungettemp(list,href);
  619. tg.Ungettemp(list,jmpbuf);
  620. tg.ungettemp(list,envbuf);
  621. end;
  622. { does the necessary things to clean up the object stack }
  623. { in the except block }
  624. procedure cleanupobjectstack;
  625. begin
  626. cg.a_call_name(exprasmlist,'FPC_POPOBJECTSTACK');
  627. cg.a_param_reg(exprasmlist,OS_ADDR,accumulator,paramanager.getintparaloc(1));
  628. cg.a_call_name(exprasmlist,'FPC_DESTROYEXCEPTION');
  629. cg.g_maybe_loadself(exprasmlist);
  630. end;
  631. procedure tcgtryexceptnode.pass_2;
  632. var
  633. exceptlabel,doexceptlabel,oldendexceptlabel,
  634. lastonlabel,
  635. exitexceptlabel,
  636. continueexceptlabel,
  637. breakexceptlabel,
  638. exittrylabel,
  639. continuetrylabel,
  640. breaktrylabel,
  641. doobjectdestroy,
  642. doobjectdestroyandreraise,
  643. oldaktexitlabel,
  644. oldaktexit2label,
  645. oldaktcontinuelabel,
  646. oldaktbreaklabel : tasmlabel;
  647. oldflowcontrol,tryflowcontrol,
  648. exceptflowcontrol : tflowcontrol;
  649. tempbuf,tempaddr : treference;
  650. href : treference;
  651. label
  652. errorexit;
  653. begin
  654. oldflowcontrol:=flowcontrol;
  655. flowcontrol:=[];
  656. { this can be called recursivly }
  657. oldendexceptlabel:=endexceptlabel;
  658. { save the old labels for control flow statements }
  659. oldaktexitlabel:=aktexitlabel;
  660. oldaktexit2label:=aktexit2label;
  661. if assigned(aktbreaklabel) then
  662. begin
  663. oldaktcontinuelabel:=aktcontinuelabel;
  664. oldaktbreaklabel:=aktbreaklabel;
  665. end;
  666. { get new labels for the control flow statements }
  667. objectlibrary.getlabel(exittrylabel);
  668. objectlibrary.getlabel(exitexceptlabel);
  669. if assigned(aktbreaklabel) then
  670. begin
  671. objectlibrary.getlabel(breaktrylabel);
  672. objectlibrary.getlabel(continuetrylabel);
  673. objectlibrary.getlabel(breakexceptlabel);
  674. objectlibrary.getlabel(continueexceptlabel);
  675. end;
  676. objectlibrary.getlabel(exceptlabel);
  677. objectlibrary.getlabel(doexceptlabel);
  678. objectlibrary.getlabel(endexceptlabel);
  679. objectlibrary.getlabel(lastonlabel);
  680. try_new_exception(exprasmlist,tempbuf,tempaddr,href,1,exceptlabel);
  681. { try block }
  682. { set control flow labels for the try block }
  683. aktexitlabel:=exittrylabel;
  684. aktexit2label:=exittrylabel;
  685. if assigned(oldaktbreaklabel) then
  686. begin
  687. aktcontinuelabel:=continuetrylabel;
  688. aktbreaklabel:=breaktrylabel;
  689. end;
  690. flowcontrol:=[];
  691. secondpass(left);
  692. tryflowcontrol:=flowcontrol;
  693. if codegenerror then
  694. goto errorexit;
  695. cg.a_label(exprasmlist,exceptlabel);
  696. try_free_exception(exprasmlist,tempbuf,tempaddr,href,0,endexceptlabel,false);
  697. cg.a_label(exprasmlist,doexceptlabel);
  698. { set control flow labels for the except block }
  699. { and the on statements }
  700. aktexitlabel:=exitexceptlabel;
  701. aktexit2label:=exitexceptlabel;
  702. if assigned(oldaktbreaklabel) then
  703. begin
  704. aktcontinuelabel:=continueexceptlabel;
  705. aktbreaklabel:=breakexceptlabel;
  706. end;
  707. flowcontrol:=[];
  708. { on statements }
  709. if assigned(right) then
  710. secondpass(right);
  711. cg.a_label(exprasmlist,lastonlabel);
  712. { default handling except handling }
  713. if assigned(t1) then
  714. begin
  715. { FPC_CATCHES must be called with
  716. 'default handler' flag (=-1)
  717. }
  718. cg.a_param_const(exprasmlist,OS_ADDR,aword(-1),paramanager.getintparaloc(1));
  719. cg.a_call_name(exprasmlist,'FPC_CATCHES');
  720. cg.g_maybe_loadself(exprasmlist);
  721. { the destruction of the exception object must be also }
  722. { guarded by an exception frame }
  723. objectlibrary.getlabel(doobjectdestroy);
  724. objectlibrary.getlabel(doobjectdestroyandreraise);
  725. try_new_exception(exprasmlist,tempbuf,tempaddr,href,1,doobjectdestroyandreraise);
  726. { here we don't have to reset flowcontrol }
  727. { the default and on flowcontrols are handled equal }
  728. secondpass(t1);
  729. exceptflowcontrol:=flowcontrol;
  730. cg.a_label(exprasmlist,doobjectdestroyandreraise);
  731. try_free_exception(exprasmlist,tempbuf,tempaddr,href,0,doobjectdestroy,false);
  732. cg.a_call_name(exprasmlist,'FPC_POPSECONDOBJECTSTACK');
  733. cg.a_param_reg(exprasmlist, OS_ADDR, accumulator, paramanager.getintparaloc(1));
  734. cg.a_call_name(exprasmlist,'FPC_DESTROYEXCEPTION');
  735. { we don't need to restore esi here because reraise never }
  736. { returns }
  737. cg.a_call_name(exprasmlist,'FPC_RERAISE');
  738. cg.a_label(exprasmlist,doobjectdestroy);
  739. cleanupobjectstack;
  740. cg.a_jmp_always(exprasmlist,endexceptlabel);
  741. end
  742. else
  743. begin
  744. cg.a_call_name(exprasmlist,'FPC_RERAISE');
  745. exceptflowcontrol:=flowcontrol;
  746. end;
  747. if fc_exit in exceptflowcontrol then
  748. begin
  749. { do some magic for exit in the try block }
  750. cg.a_label(exprasmlist,exitexceptlabel);
  751. { we must also destroy the address frame which guards }
  752. { exception object }
  753. cg.a_call_name(exprasmlist,'FPC_POPADDRSTACK');
  754. cg.g_exception_reason_load(exprasmlist,href);
  755. cleanupobjectstack;
  756. cg.a_jmp_always(exprasmlist,oldaktexitlabel);
  757. end;
  758. if fc_break in exceptflowcontrol then
  759. begin
  760. cg.a_label(exprasmlist,breakexceptlabel);
  761. { we must also destroy the address frame which guards }
  762. { exception object }
  763. cg.a_call_name(exprasmlist,'FPC_POPADDRSTACK');
  764. cg.g_exception_reason_load(exprasmlist,href);
  765. cleanupobjectstack;
  766. cg.a_jmp_always(exprasmlist,oldaktbreaklabel);
  767. end;
  768. if fc_continue in exceptflowcontrol then
  769. begin
  770. cg.a_label(exprasmlist,continueexceptlabel);
  771. { we must also destroy the address frame which guards }
  772. { exception object }
  773. cg.a_call_name(exprasmlist,'FPC_POPADDRSTACK');
  774. cg.g_exception_reason_load(exprasmlist,href);
  775. cleanupobjectstack;
  776. cg.a_jmp_always(exprasmlist,oldaktcontinuelabel);
  777. end;
  778. if fc_exit in tryflowcontrol then
  779. begin
  780. { do some magic for exit in the try block }
  781. cg.a_label(exprasmlist,exittrylabel);
  782. cg.a_call_name(exprasmlist,'FPC_POPADDRSTACK');
  783. cg.g_exception_reason_load(exprasmlist,href);
  784. cg.a_jmp_always(exprasmlist,oldaktexitlabel);
  785. end;
  786. if fc_break in tryflowcontrol then
  787. begin
  788. cg.a_label(exprasmlist,breaktrylabel);
  789. cg.a_call_name(exprasmlist,'FPC_POPADDRSTACK');
  790. cg.g_exception_reason_load(exprasmlist,href);
  791. cg.a_jmp_always(exprasmlist,oldaktbreaklabel);
  792. end;
  793. if fc_continue in tryflowcontrol then
  794. begin
  795. cg.a_label(exprasmlist,continuetrylabel);
  796. cg.a_call_name(exprasmlist,'FPC_POPADDRSTACK');
  797. cg.g_exception_reason_load(exprasmlist,href);
  798. cg.a_jmp_always(exprasmlist,oldaktcontinuelabel);
  799. end;
  800. cg.a_label(exprasmlist,endexceptlabel);
  801. errorexit:
  802. { restore all saved labels }
  803. endexceptlabel:=oldendexceptlabel;
  804. { restore the control flow labels }
  805. aktexitlabel:=oldaktexitlabel;
  806. aktexit2label:=oldaktexit2label;
  807. if assigned(oldaktbreaklabel) then
  808. begin
  809. aktcontinuelabel:=oldaktcontinuelabel;
  810. aktbreaklabel:=oldaktbreaklabel;
  811. end;
  812. { return all used control flow statements }
  813. flowcontrol:=oldflowcontrol+exceptflowcontrol+
  814. tryflowcontrol;
  815. end;
  816. procedure tcgonnode.pass_2;
  817. var
  818. nextonlabel,
  819. exitonlabel,
  820. continueonlabel,
  821. breakonlabel,
  822. oldaktexitlabel,
  823. oldaktexit2label,
  824. oldaktcontinuelabel,
  825. doobjectdestroyandreraise,
  826. doobjectdestroy,
  827. oldaktbreaklabel : tasmlabel;
  828. ref : treference;
  829. oldflowcontrol : tflowcontrol;
  830. tempbuf,tempaddr : treference;
  831. href : treference;
  832. href2: treference;
  833. begin
  834. oldflowcontrol:=flowcontrol;
  835. flowcontrol:=[];
  836. objectlibrary.getlabel(nextonlabel);
  837. { send the vmt parameter }
  838. reference_reset_symbol(href2,objectlibrary.newasmsymbol(excepttype.vmt_mangledname),0);
  839. cg.a_paramaddr_ref(exprasmlist,href2,paramanager.getintparaloc(1));
  840. cg.a_call_name(exprasmlist,'FPC_CATCHES');
  841. { is it this catch? No. go to next onlabel }
  842. cg.a_cmp_const_reg_label(exprasmlist,OS_ADDR,OC_EQ,0,accumulator,nextonlabel);
  843. ref.symbol:=nil;
  844. tg.GetTemp(exprasmlist,pointer_size,tt_normal,ref);
  845. { what a hack ! }
  846. if assigned(exceptsymtable) then
  847. tvarsym(exceptsymtable.symindex.first).address:=ref.offset;
  848. cg.a_load_reg_ref(exprasmlist, OS_ADDR, accumulator, ref);
  849. { in the case that another exception is risen }
  850. { we've to destroy the old one }
  851. objectlibrary.getlabel(doobjectdestroyandreraise);
  852. { call setjmp, and jump to finally label on non-zero result }
  853. try_new_exception(exprasmlist,tempbuf,tempaddr,href,1,doobjectdestroyandreraise);
  854. if assigned(right) then
  855. begin
  856. oldaktexitlabel:=aktexitlabel;
  857. oldaktexit2label:=aktexit2label;
  858. objectlibrary.getlabel(exitonlabel);
  859. aktexitlabel:=exitonlabel;
  860. aktexit2label:=exitonlabel;
  861. if assigned(aktbreaklabel) then
  862. begin
  863. oldaktcontinuelabel:=aktcontinuelabel;
  864. oldaktbreaklabel:=aktbreaklabel;
  865. objectlibrary.getlabel(breakonlabel);
  866. objectlibrary.getlabel(continueonlabel);
  867. aktcontinuelabel:=continueonlabel;
  868. aktbreaklabel:=breakonlabel;
  869. end;
  870. { esi is destroyed by FPC_CATCHES }
  871. cg.g_maybe_loadself(exprasmlist);
  872. secondpass(right);
  873. end;
  874. objectlibrary.getlabel(doobjectdestroy);
  875. cg.a_label(exprasmlist,doobjectdestroyandreraise);
  876. try_free_exception(exprasmlist,tempbuf,tempaddr,href,0,doobjectdestroy,false);
  877. cg.a_call_name(exprasmlist,'FPC_POPSECONDOBJECTSTACK');
  878. cg.a_param_reg(exprasmlist, OS_ADDR, accumulator, paramanager.getintparaloc(1));
  879. cg.a_call_name(exprasmlist,'FPC_DESTROYEXCEPTION');
  880. { we don't need to restore esi here because reraise never }
  881. { returns }
  882. cg.a_call_name(exprasmlist,'FPC_RERAISE');
  883. cg.a_label(exprasmlist,doobjectdestroy);
  884. cleanupobjectstack;
  885. { clear some stuff }
  886. tg.ungetiftemp(exprasmlist,ref);
  887. cg.a_jmp_always(exprasmlist,endexceptlabel);
  888. if assigned(right) then
  889. begin
  890. { special handling for control flow instructions }
  891. if fc_exit in flowcontrol then
  892. begin
  893. { the address and object pop does secondtryexcept }
  894. cg.a_label(exprasmlist,exitonlabel);
  895. cg.a_jmp_always(exprasmlist,oldaktexitlabel);
  896. end;
  897. if fc_break in flowcontrol then
  898. begin
  899. { the address and object pop does secondtryexcept }
  900. cg.a_label(exprasmlist,breakonlabel);
  901. cg.a_jmp_always(exprasmlist,oldaktbreaklabel);
  902. end;
  903. if fc_continue in flowcontrol then
  904. begin
  905. { the address and object pop does secondtryexcept }
  906. cg.a_label(exprasmlist,continueonlabel);
  907. cg.a_jmp_always(exprasmlist,oldaktcontinuelabel);
  908. end;
  909. aktexitlabel:=oldaktexitlabel;
  910. aktexit2label:=oldaktexit2label;
  911. if assigned(oldaktbreaklabel) then
  912. begin
  913. aktcontinuelabel:=oldaktcontinuelabel;
  914. aktbreaklabel:=oldaktbreaklabel;
  915. end;
  916. end;
  917. cg.a_label(exprasmlist,nextonlabel);
  918. flowcontrol:=oldflowcontrol+flowcontrol;
  919. { next on node }
  920. if assigned(left) then
  921. begin
  922. rg.cleartempgen;
  923. secondpass(left);
  924. end;
  925. end;
  926. {*****************************************************************************
  927. SecondTryFinally
  928. *****************************************************************************}
  929. procedure tcgtryfinallynode.pass_2;
  930. var
  931. reraiselabel,
  932. finallylabel,
  933. endfinallylabel,
  934. exitfinallylabel,
  935. continuefinallylabel,
  936. breakfinallylabel,
  937. oldaktexitlabel,
  938. oldaktexit2label,
  939. oldaktcontinuelabel,
  940. oldaktbreaklabel : tasmlabel;
  941. oldflowcontrol,tryflowcontrol : tflowcontrol;
  942. decconst : longint;
  943. tempbuf,tempaddr : treference;
  944. href : treference;
  945. begin
  946. { check if child nodes do a break/continue/exit }
  947. oldflowcontrol:=flowcontrol;
  948. flowcontrol:=[];
  949. objectlibrary.getlabel(finallylabel);
  950. objectlibrary.getlabel(endfinallylabel);
  951. objectlibrary.getlabel(reraiselabel);
  952. { the finally block must catch break, continue and exit }
  953. { statements }
  954. oldaktexitlabel:=aktexitlabel;
  955. oldaktexit2label:=aktexit2label;
  956. objectlibrary.getlabel(exitfinallylabel);
  957. aktexitlabel:=exitfinallylabel;
  958. aktexit2label:=exitfinallylabel;
  959. if assigned(aktbreaklabel) then
  960. begin
  961. oldaktcontinuelabel:=aktcontinuelabel;
  962. oldaktbreaklabel:=aktbreaklabel;
  963. objectlibrary.getlabel(breakfinallylabel);
  964. objectlibrary.getlabel(continuefinallylabel);
  965. aktcontinuelabel:=continuefinallylabel;
  966. aktbreaklabel:=breakfinallylabel;
  967. end;
  968. { call setjmp, and jump to finally label on non-zero result }
  969. try_new_exception(exprasmlist,tempbuf,tempaddr,href,1,finallylabel);
  970. { try code }
  971. if assigned(left) then
  972. begin
  973. secondpass(left);
  974. tryflowcontrol:=flowcontrol;
  975. if codegenerror then
  976. exit;
  977. end;
  978. cg.a_label(exprasmlist,finallylabel);
  979. { just free the frame information }
  980. try_free_exception(exprasmlist,tempbuf,tempaddr,href,1,finallylabel,true);
  981. { finally code }
  982. flowcontrol:=[];
  983. secondpass(right);
  984. if flowcontrol<>[] then
  985. CGMessage(cg_e_control_flow_outside_finally);
  986. if codegenerror then
  987. exit;
  988. { the value should now be in the exception handler }
  989. cg.g_exception_reason_load(exprasmlist,href);
  990. cg.a_cmp_const_reg_label(exprasmlist,OS_S32,OC_EQ,0,accumulator,endfinallylabel);
  991. cg.a_op_const_reg(exprasmlist,OP_SUB,1,accumulator);
  992. cg.a_cmp_const_reg_label(exprasmlist,OS_S32,OC_EQ,0,accumulator,reraiselabel);
  993. if fc_exit in tryflowcontrol then
  994. begin
  995. cg.a_op_const_reg(exprasmlist,OP_SUB,1,accumulator);
  996. cg.a_cmp_const_reg_label(exprasmlist,OS_S32,OC_EQ,0,accumulator,oldaktexitlabel);
  997. decconst:=1;
  998. end
  999. else
  1000. decconst:=2;
  1001. if fc_break in tryflowcontrol then
  1002. begin
  1003. cg.a_op_const_reg(exprasmlist,OP_SUB,decconst,accumulator);
  1004. cg.a_cmp_const_reg_label(exprasmlist,OS_S32,OC_EQ,0,accumulator,oldaktbreaklabel);
  1005. decconst:=1;
  1006. end
  1007. else
  1008. inc(decconst);
  1009. if fc_continue in tryflowcontrol then
  1010. begin
  1011. cg.a_op_const_reg(exprasmlist,OP_SUB,decconst,accumulator);
  1012. cg.a_cmp_const_reg_label(exprasmlist,OS_S32,OC_EQ,0,accumulator,oldaktcontinuelabel);
  1013. end;
  1014. cg.a_label(exprasmlist,reraiselabel);
  1015. cg.a_call_name(exprasmlist,'FPC_RERAISE');
  1016. { do some magic for exit,break,continue in the try block }
  1017. if fc_exit in tryflowcontrol then
  1018. begin
  1019. cg.a_label(exprasmlist,exitfinallylabel);
  1020. cg.g_exception_reason_load(exprasmlist,href);
  1021. cg.g_exception_reason_save_const(exprasmlist,href,2);
  1022. cg.a_jmp_always(exprasmlist,finallylabel);
  1023. end;
  1024. if fc_break in tryflowcontrol then
  1025. begin
  1026. cg.a_label(exprasmlist,breakfinallylabel);
  1027. cg.g_exception_reason_load(exprasmlist,href);
  1028. cg.g_exception_reason_save_const(exprasmlist,href,3);
  1029. cg.a_jmp_always(exprasmlist,finallylabel);
  1030. end;
  1031. if fc_continue in tryflowcontrol then
  1032. begin
  1033. cg.a_label(exprasmlist,continuefinallylabel);
  1034. cg.g_exception_reason_load(exprasmlist,href);
  1035. cg.g_exception_reason_save_const(exprasmlist,href,4);
  1036. cg.a_jmp_always(exprasmlist,finallylabel);
  1037. end;
  1038. cg.a_label(exprasmlist,endfinallylabel);
  1039. aktexitlabel:=oldaktexitlabel;
  1040. aktexit2label:=oldaktexit2label;
  1041. if assigned(aktbreaklabel) then
  1042. begin
  1043. aktcontinuelabel:=oldaktcontinuelabel;
  1044. aktbreaklabel:=oldaktbreaklabel;
  1045. end;
  1046. flowcontrol:=oldflowcontrol+tryflowcontrol;
  1047. end;
  1048. begin
  1049. cwhilerepeatnode:=tcgwhilerepeatnode;
  1050. cifnode:=tcgifnode;
  1051. cfornode:=tcgfornode;
  1052. cexitnode:=tcgexitnode;
  1053. cbreaknode:=tcgbreaknode;
  1054. ccontinuenode:=tcgcontinuenode;
  1055. cgotonode:=tcggotonode;
  1056. clabelnode:=tcglabelnode;
  1057. cfailnode:=tcgfailnode;
  1058. craisenode:=tcgraisenode;
  1059. ctryexceptnode:=tcgtryexceptnode;
  1060. ctryfinallynode:=tcgtryfinallynode;
  1061. connode:=tcgonnode;
  1062. end.
  1063. {
  1064. $Log$
  1065. Revision 1.42 2002-09-07 15:25:02 peter
  1066. * old logs removed and tabs fixed
  1067. Revision 1.41 2002/09/01 18:47:00 peter
  1068. * assignn check in exitnode changed to use a separate boolean as the
  1069. assignn can be changed to a calln
  1070. Revision 1.40 2002/09/01 14:41:47 peter
  1071. * increase refcount in exit(arg) for arg
  1072. Revision 1.39 2002/08/24 18:41:52 peter
  1073. * fixed wrong label in jump of except block (was also in n386flw wrong)
  1074. * fixed wrong pushing of raise parameters
  1075. * fixed wrong compare in finally
  1076. Revision 1.38 2002/08/23 16:14:48 peter
  1077. * tempgen cleanup
  1078. * tt_noreuse temp type added that will be used in genentrycode
  1079. Revision 1.37 2002/08/19 19:36:43 peter
  1080. * More fixes for cross unit inlining, all tnodes are now implemented
  1081. * Moved pocall_internconst to po_internconst because it is not a
  1082. calling type at all and it conflicted when inlining of these small
  1083. functions was requested
  1084. Revision 1.36 2002/08/15 15:15:55 carl
  1085. * jmpbuf size allocation for exceptions is now cpu specific (as it should)
  1086. * more generic nodes for maths
  1087. * several fixes for better m68k support
  1088. Revision 1.35 2002/08/13 18:01:52 carl
  1089. * rename swatoperands to swapoperands
  1090. + m68k first compilable version (still needs a lot of testing):
  1091. assembler generator, system information , inline
  1092. assembler reader.
  1093. Revision 1.34 2002/08/11 14:32:26 peter
  1094. * renamed current_library to objectlibrary
  1095. Revision 1.33 2002/08/11 13:24:11 peter
  1096. * saving of asmsymbols in ppu supported
  1097. * asmsymbollist global is removed and moved into a new class
  1098. tasmlibrarydata that will hold the info of a .a file which
  1099. corresponds with a single module. Added librarydata to tmodule
  1100. to keep the library info stored for the module. In the future the
  1101. objectfiles will also be stored to the tasmlibrarydata class
  1102. * all getlabel/newasmsymbol and friends are moved to the new class
  1103. Revision 1.32 2002/08/09 19:10:59 carl
  1104. * fixed generic exception management
  1105. Revision 1.31 2002/08/04 19:06:41 carl
  1106. + added generic exception support (still does not work!)
  1107. + more documentation
  1108. Revision 1.30 2002/07/27 19:53:51 jonas
  1109. + generic implementation of tcg.g_flags2ref()
  1110. * tcg.flags2xxx() now also needs a size parameter
  1111. Revision 1.29 2002/07/25 17:56:29 carl
  1112. + FPURESULTREG -> FPU_RESULT_REG
  1113. Revision 1.28 2002/07/21 06:58:49 daniel
  1114. * Changed booleans into flags
  1115. Revision 1.27 2002/07/20 12:54:53 daniel
  1116. * Optimized the code generated for for nodes. The shootout/nestloop benchmark
  1117. now runs 5% faster on my computer.
  1118. Revision 1.26 2002/07/20 11:57:54 florian
  1119. * types.pas renamed to defbase.pas because D6 contains a types
  1120. unit so this would conflicts if D6 programms are compiled
  1121. + Willamette/SSE2 instructions to assembler added
  1122. Revision 1.25 2002/07/20 11:15:51 daniel
  1123. * The for node does a check if the first comparision can be skipped. I moved
  1124. the check from the second pass to the resulttype pass. The advantage is
  1125. that the state tracker can now decide to skip the first comparision too.
  1126. Revision 1.24 2002/07/20 08:14:24 daniel
  1127. * Loops should not be aligned when optimizing for size
  1128. Revision 1.23 2002/07/19 11:41:35 daniel
  1129. * State tracker work
  1130. * The whilen and repeatn are now completely unified into whilerepeatn. This
  1131. allows the state tracker to change while nodes automatically into
  1132. repeat nodes.
  1133. * Resulttypepass improvements to the notn. 'not not a' is optimized away and
  1134. 'not(a>b)' is optimized into 'a<=b'.
  1135. * Resulttypepass improvements to the whilerepeatn. 'while not a' is optimized
  1136. by removing the notn and later switchting the true and falselabels. The
  1137. same is done with 'repeat until not a'.
  1138. Revision 1.22 2002/07/04 20:43:01 florian
  1139. * first x86-64 patches
  1140. }