ncgflw.pas 50 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424
  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.41 2002-09-01 18:47:00 peter
  1066. * assignn check in exitnode changed to use a separate boolean as the
  1067. assignn can be changed to a calln
  1068. Revision 1.40 2002/09/01 14:41:47 peter
  1069. * increase refcount in exit(arg) for arg
  1070. Revision 1.39 2002/08/24 18:41:52 peter
  1071. * fixed wrong label in jump of except block (was also in n386flw wrong)
  1072. * fixed wrong pushing of raise parameters
  1073. * fixed wrong compare in finally
  1074. Revision 1.38 2002/08/23 16:14:48 peter
  1075. * tempgen cleanup
  1076. * tt_noreuse temp type added that will be used in genentrycode
  1077. Revision 1.37 2002/08/19 19:36:43 peter
  1078. * More fixes for cross unit inlining, all tnodes are now implemented
  1079. * Moved pocall_internconst to po_internconst because it is not a
  1080. calling type at all and it conflicted when inlining of these small
  1081. functions was requested
  1082. Revision 1.36 2002/08/15 15:15:55 carl
  1083. * jmpbuf size allocation for exceptions is now cpu specific (as it should)
  1084. * more generic nodes for maths
  1085. * several fixes for better m68k support
  1086. Revision 1.35 2002/08/13 18:01:52 carl
  1087. * rename swatoperands to swapoperands
  1088. + m68k first compilable version (still needs a lot of testing):
  1089. assembler generator, system information , inline
  1090. assembler reader.
  1091. Revision 1.34 2002/08/11 14:32:26 peter
  1092. * renamed current_library to objectlibrary
  1093. Revision 1.33 2002/08/11 13:24:11 peter
  1094. * saving of asmsymbols in ppu supported
  1095. * asmsymbollist global is removed and moved into a new class
  1096. tasmlibrarydata that will hold the info of a .a file which
  1097. corresponds with a single module. Added librarydata to tmodule
  1098. to keep the library info stored for the module. In the future the
  1099. objectfiles will also be stored to the tasmlibrarydata class
  1100. * all getlabel/newasmsymbol and friends are moved to the new class
  1101. Revision 1.32 2002/08/09 19:10:59 carl
  1102. * fixed generic exception management
  1103. Revision 1.31 2002/08/04 19:06:41 carl
  1104. + added generic exception support (still does not work!)
  1105. + more documentation
  1106. Revision 1.30 2002/07/27 19:53:51 jonas
  1107. + generic implementation of tcg.g_flags2ref()
  1108. * tcg.flags2xxx() now also needs a size parameter
  1109. Revision 1.29 2002/07/25 17:56:29 carl
  1110. + FPURESULTREG -> FPU_RESULT_REG
  1111. Revision 1.28 2002/07/21 06:58:49 daniel
  1112. * Changed booleans into flags
  1113. Revision 1.27 2002/07/20 12:54:53 daniel
  1114. * Optimized the code generated for for nodes. The shootout/nestloop benchmark
  1115. now runs 5% faster on my computer.
  1116. Revision 1.26 2002/07/20 11:57:54 florian
  1117. * types.pas renamed to defbase.pas because D6 contains a types
  1118. unit so this would conflicts if D6 programms are compiled
  1119. + Willamette/SSE2 instructions to assembler added
  1120. Revision 1.25 2002/07/20 11:15:51 daniel
  1121. * The for node does a check if the first comparision can be skipped. I moved
  1122. the check from the second pass to the resulttype pass. The advantage is
  1123. that the state tracker can now decide to skip the first comparision too.
  1124. Revision 1.24 2002/07/20 08:14:24 daniel
  1125. * Loops should not be aligned when optimizing for size
  1126. Revision 1.23 2002/07/19 11:41:35 daniel
  1127. * State tracker work
  1128. * The whilen and repeatn are now completely unified into whilerepeatn. This
  1129. allows the state tracker to change while nodes automatically into
  1130. repeat nodes.
  1131. * Resulttypepass improvements to the notn. 'not not a' is optimized away and
  1132. 'not(a>b)' is optimized into 'a<=b'.
  1133. * Resulttypepass improvements to the whilerepeatn. 'while not a' is optimized
  1134. by removing the notn and later switchting the true and falselabels. The
  1135. same is done with 'repeat until not a'.
  1136. Revision 1.22 2002/07/04 20:43:01 florian
  1137. * first x86-64 patches
  1138. Revision 1.21 2002/07/01 18:46:22 peter
  1139. * internal linker
  1140. * reorganized aasm layer
  1141. Revision 1.20 2002/07/01 16:23:53 peter
  1142. * cg64 patch
  1143. * basics for currency
  1144. * asnode updates for class and interface (not finished)
  1145. Revision 1.19 2002/05/20 13:30:40 carl
  1146. * bugfix of hdisponen (base must be set, not index)
  1147. * more portability fixes
  1148. Revision 1.18 2002/05/18 13:34:09 peter
  1149. * readded missing revisions
  1150. Revision 1.17 2002/05/16 19:46:37 carl
  1151. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  1152. + try to fix temp allocation (still in ifdef)
  1153. + generic constructor calls
  1154. + start of tassembler / tmodulebase class cleanup
  1155. Revision 1.15 2002/05/13 19:54:37 peter
  1156. * removed n386ld and n386util units
  1157. * maybe_save/maybe_restore added instead of the old maybe_push
  1158. Revision 1.14 2002/05/12 16:53:07 peter
  1159. * moved entry and exitcode to ncgutil and cgobj
  1160. * foreach gets extra argument for passing local data to the
  1161. iterator function
  1162. * -CR checks also class typecasts at runtime by changing them
  1163. into as
  1164. * fixed compiler to cycle with the -CR option
  1165. * fixed stabs with elf writer, finally the global variables can
  1166. be watched
  1167. * removed a lot of routines from cga unit and replaced them by
  1168. calls to cgobj
  1169. * u32bit-s32bit updates for and,or,xor nodes. When one element is
  1170. u32bit then the other is typecasted also to u32bit without giving
  1171. a rangecheck warning/error.
  1172. * fixed pascal calling method with reversing also the high tree in
  1173. the parast, detected by tcalcst3 test
  1174. Revision 1.13 2002/04/21 15:24:38 carl
  1175. + a_jmp_cond -> a_jmp_always (a_jmp_cond is NOT portable)
  1176. + changeregsize -> rg.makeregsize
  1177. Revision 1.12 2002/04/15 19:44:19 peter
  1178. * fixed stackcheck that would be called recursively when a stack
  1179. error was found
  1180. * generic changeregsize(reg,size) for i386 register resizing
  1181. * removed some more routines from cga unit
  1182. * fixed returnvalue handling
  1183. * fixed default stacksize of linux and go32v2, 8kb was a bit small :-)
  1184. Revision 1.11 2002/04/04 19:05:57 peter
  1185. * removed unused units
  1186. * use tlocation.size in cg.a_*loc*() routines
  1187. Revision 1.10 2002/04/02 17:11:28 peter
  1188. * tlocation,treference update
  1189. * LOC_CONSTANT added for better constant handling
  1190. * secondadd splitted in multiple routines
  1191. * location_force_reg added for loading a location to a register
  1192. of a specified size
  1193. * secondassignment parses now first the right and then the left node
  1194. (this is compatible with Kylix). This saves a lot of push/pop especially
  1195. with string operations
  1196. * adapted some routines to use the new cg methods
  1197. Revision 1.9 2002/03/31 20:26:34 jonas
  1198. + a_loadfpu_* and a_loadmm_* methods in tcg
  1199. * register allocation is now handled by a class and is mostly processor
  1200. independent (+rgobj.pas and i386/rgcpu.pas)
  1201. * temp allocation is now handled by a class (+tgobj.pas, -i386\tgcpu.pas)
  1202. * some small improvements and fixes to the optimizer
  1203. * some register allocation fixes
  1204. * some fpuvaroffset fixes in the unary minus node
  1205. * push/popusedregisters is now called rg.save/restoreusedregisters and
  1206. (for i386) uses temps instead of push/pop's when using -Op3 (that code is
  1207. also better optimizable)
  1208. * fixed and optimized register saving/restoring for new/dispose nodes
  1209. * LOC_FPU locations now also require their "register" field to be set to
  1210. R_ST, not R_ST0 (the latter is used for LOC_CFPUREGISTER locations only)
  1211. - list field removed of the tnode class because it's not used currently
  1212. and can cause hard-to-find bugs
  1213. Revision 1.8 2002/03/04 19:10:11 peter
  1214. * removed compiler warnings
  1215. }