ncgflw.pas 47 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367
  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. cga,
  73. tgobj,rgobj,paramgr,
  74. regvars,cgobj,cgcpu,cg64f32;
  75. {*****************************************************************************
  76. Second_While_RepeatN
  77. *****************************************************************************}
  78. procedure tcgwhilerepeatnode.pass_2;
  79. var
  80. lcont,lbreak,lloop,
  81. oldclabel,oldblabel : tasmlabel;
  82. otlabel,oflabel : tasmlabel;
  83. begin
  84. getlabel(lloop);
  85. getlabel(lcont);
  86. getlabel(lbreak);
  87. { arrange continue and breaklabels: }
  88. oldclabel:=aktcontinuelabel;
  89. oldblabel:=aktbreaklabel;
  90. load_all_regvars(exprasmlist);
  91. { handling code at the end as it is much more efficient, and makes
  92. while equal to repeat loop, only the end true/false is swapped (PFV) }
  93. if nf_testatbegin in flags then
  94. cg.a_jmp_always(exprasmlist,lcont);
  95. if not(cs_littlesize in aktglobalswitches) then
  96. { align loop target }
  97. exprasmList.concat(Tai_align.Create(aktalignment.loopalign));
  98. cg.a_label(exprasmlist,lloop);
  99. aktcontinuelabel:=lcont;
  100. aktbreaklabel:=lbreak;
  101. rg.cleartempgen;
  102. if assigned(right) then
  103. secondpass(right);
  104. load_all_regvars(exprasmlist);
  105. cg.a_label(exprasmlist,lcont);
  106. otlabel:=truelabel;
  107. oflabel:=falselabel;
  108. if nf_checknegate in flags then
  109. begin
  110. truelabel:=lbreak;
  111. falselabel:=lloop;
  112. end
  113. else
  114. begin
  115. truelabel:=lloop;
  116. falselabel:=lbreak;
  117. end;
  118. rg.cleartempgen;
  119. secondpass(left);
  120. maketojumpbool(exprasmlist,left,lr_load_regvars);
  121. cg.a_label(exprasmlist,lbreak);
  122. truelabel:=otlabel;
  123. falselabel:=oflabel;
  124. aktcontinuelabel:=oldclabel;
  125. aktbreaklabel:=oldblabel;
  126. { a break/continue in a while/repeat block can't be seen outside }
  127. flowcontrol:=flowcontrol-[fc_break,fc_continue];
  128. end;
  129. {*****************************************************************************
  130. tcgIFNODE
  131. *****************************************************************************}
  132. procedure tcgifnode.pass_2;
  133. var
  134. hl,otlabel,oflabel : tasmlabel;
  135. org_regvar_loaded,
  136. then_regvar_loaded,
  137. else_regvar_loaded : regvar_booleanarray;
  138. org_list,
  139. then_list,
  140. else_list : taasmoutput;
  141. begin
  142. otlabel:=truelabel;
  143. oflabel:=falselabel;
  144. getlabel(truelabel);
  145. getlabel(falselabel);
  146. rg.cleartempgen;
  147. secondpass(left);
  148. { save regvars loaded in the beginning so that we can restore them }
  149. { when processing the else-block }
  150. if cs_regalloc in aktglobalswitches then
  151. begin
  152. org_list := exprasmlist;
  153. exprasmlist := taasmoutput.create;
  154. end;
  155. maketojumpbool(exprasmlist,left,lr_dont_load_regvars);
  156. if cs_regalloc in aktglobalswitches then
  157. org_regvar_loaded := rg.regvar_loaded;
  158. if assigned(right) then
  159. begin
  160. cg.a_label(exprasmlist,truelabel);
  161. rg.cleartempgen;
  162. secondpass(right);
  163. end;
  164. { save current asmlist (previous instructions + then-block) and }
  165. { loaded regvar state and create new clean ones }
  166. if cs_regalloc in aktglobalswitches then
  167. begin
  168. then_regvar_loaded := rg.regvar_loaded;
  169. rg.regvar_loaded := org_regvar_loaded;
  170. then_list := exprasmlist;
  171. exprasmlist := taasmoutput.create;
  172. end;
  173. if assigned(t1) then
  174. begin
  175. if assigned(right) then
  176. begin
  177. getlabel(hl);
  178. { do go back to if line !! }
  179. if not(cs_regalloc in aktglobalswitches) then
  180. aktfilepos:=exprasmList.getlasttaifilepos^
  181. else
  182. aktfilepos:=then_list.getlasttaifilepos^;
  183. cg.a_jmp_always(exprasmlist,hl);
  184. end;
  185. cg.a_label(exprasmlist,falselabel);
  186. rg.cleartempgen;
  187. secondpass(t1);
  188. { save current asmlist (previous instructions + else-block) }
  189. { and loaded regvar state and create a new clean list }
  190. if cs_regalloc in aktglobalswitches then
  191. begin
  192. else_regvar_loaded := rg.regvar_loaded;
  193. else_list := exprasmlist;
  194. exprasmlist := taasmoutput.create;
  195. end;
  196. if assigned(right) then
  197. cg.a_label(exprasmlist,hl);
  198. end
  199. else
  200. begin
  201. if cs_regalloc in aktglobalswitches then
  202. begin
  203. else_regvar_loaded := rg.regvar_loaded;
  204. else_list := exprasmlist;
  205. exprasmlist := taasmoutput.create;
  206. end;
  207. cg.a_label(exprasmlist,falselabel);
  208. end;
  209. if not(assigned(right)) then
  210. begin
  211. cg.a_label(exprasmlist,truelabel);
  212. end;
  213. if cs_regalloc in aktglobalswitches then
  214. begin
  215. { add loads of regvars at the end of the then- and else-blocks }
  216. { so that at the end of both blocks the same regvars are loaded }
  217. { no else block? }
  218. if not assigned(t1) then
  219. sync_regvars(org_list,then_list,org_regvar_loaded,
  220. then_regvar_loaded)
  221. { no then block? }
  222. else if not assigned(right) then
  223. sync_regvars(org_list,else_list,org_regvar_loaded,
  224. else_regvar_loaded)
  225. { both else and then blocks }
  226. else
  227. sync_regvars(then_list,else_list,then_regvar_loaded,
  228. else_regvar_loaded);
  229. { add all lists together }
  230. org_list.concatlist(then_list);
  231. then_list.free;
  232. org_list.concatlist(else_list);
  233. else_list.free;
  234. org_list.concatlist(exprasmlist);
  235. exprasmlist.free;
  236. exprasmlist := org_list;
  237. end;
  238. truelabel:=otlabel;
  239. falselabel:=oflabel;
  240. end;
  241. {*****************************************************************************
  242. SecondFor
  243. *****************************************************************************}
  244. procedure tcgfornode.pass_2;
  245. var
  246. l3,oldclabel,oldblabel : tasmlabel;
  247. temptovalue : boolean;
  248. hs : byte;
  249. temp1 : treference;
  250. hop : topcg;
  251. hcond : topcmp;
  252. opsize : tcgsize;
  253. count_var_is_signed : boolean;
  254. begin
  255. oldclabel:=aktcontinuelabel;
  256. oldblabel:=aktbreaklabel;
  257. getlabel(aktcontinuelabel);
  258. getlabel(aktbreaklabel);
  259. getlabel(l3);
  260. { only calculate reference }
  261. rg.cleartempgen;
  262. secondpass(t2);
  263. hs := t2.resulttype.def.size;
  264. opsize := def_cgsize(t2.resulttype.def);
  265. { first set the to value
  266. because the count var can be in the expression !! }
  267. rg.cleartempgen;
  268. secondpass(right);
  269. { calculate pointer value and check if changeable and if so }
  270. { load into temporary variable }
  271. if right.nodetype<>ordconstn then
  272. begin
  273. temp1.symbol:=nil;
  274. tg.gettempofsizereference(exprasmlist,hs,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. { load_all_regvars(exprasmlist); }
  391. include(flowcontrol,fc_exit);
  392. if assigned(left) then
  393. if left.nodetype=assignn 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. getlabel(truelabel);
  406. getlabel(falselabel);
  407. secondpass(left);
  408. { the result of left is not needed anymore after this
  409. node }
  410. location_freetemp(exprasmlist,left.location);
  411. location_release(exprasmlist,left.location);
  412. case left.location.loc of
  413. LOC_FPUREGISTER :
  414. goto do_jmp;
  415. LOC_FLAGS :
  416. begin
  417. cg.a_reg_alloc(exprasmlist,accumulator);
  418. allocated_acc := true;
  419. cg.g_flags2reg(exprasmlist,OS_INT,left.location.resflags,accumulator);
  420. goto do_jmp;
  421. end;
  422. LOC_JUMP :
  423. begin
  424. cg.a_reg_alloc(exprasmlist,accumulator);
  425. { get an 8-bit register }
  426. hreg:=rg.makeregsize(accumulator,OS_8);
  427. allocated_acc := true;
  428. cg.a_label(exprasmlist,truelabel);
  429. cg.a_load_const_reg(exprasmlist,OS_8,1,hreg);
  430. cg.a_jmp_always(exprasmlist,aktexit2label);
  431. cg.a_label(exprasmlist,falselabel);
  432. cg.a_load_const_reg(exprasmlist,OS_8,0,hreg);
  433. goto do_jmp;
  434. end;
  435. end;
  436. case aktprocdef.rettype.def.deftype of
  437. pointerdef,
  438. procvardef :
  439. begin
  440. cg.a_reg_alloc(exprasmlist,accumulator);
  441. allocated_acc := true;
  442. cg.a_load_loc_reg(exprasmlist,left.location,accumulator);
  443. end;
  444. floatdef :
  445. begin
  446. {$ifndef i386}
  447. cg.a_reg_alloc(exprasmlist,FPU_RESULT_REG);
  448. {$endif not i386}
  449. cg.a_loadfpu_loc_reg(exprasmlist,left.location,FPU_RESULT_REG);
  450. end;
  451. else
  452. begin
  453. cgsize:=def_cgsize(aktprocdef.rettype.def);
  454. cg.a_reg_alloc(exprasmlist,accumulator);
  455. allocated_acc := true;
  456. case cgsize of
  457. OS_64,OS_S64 :
  458. begin
  459. cg.a_reg_alloc(exprasmlist,accumulatorhigh);
  460. allocated_acchigh := true;
  461. cg64.a_load64_loc_reg(exprasmlist,left.location,
  462. joinreg64(accumulator,accumulatorhigh));
  463. end
  464. else
  465. begin
  466. hreg:=rg.makeregsize(accumulator,cgsize);
  467. cg.a_load_loc_reg(exprasmlist,left.location,hreg);
  468. end;
  469. end;
  470. end;
  471. end;
  472. do_jmp:
  473. truelabel:=otlabel;
  474. falselabel:=oflabel;
  475. cg.a_jmp_always(exprasmlist,aktexit2label);
  476. if allocated_acc then
  477. cg.a_reg_dealloc(exprasmlist,accumulator);
  478. if allocated_acchigh then
  479. cg.a_reg_dealloc(exprasmlist,accumulatorhigh);
  480. {$ifndef i386}
  481. if (aktprocdef.rettype.def.deftype = floatdef) then
  482. cg.a_reg_dealloc(exprasmlist,FPU_RESULT_REG);
  483. {$endif not i386}
  484. end
  485. else
  486. cg.a_jmp_always(exprasmlist,aktexitlabel);
  487. end;
  488. {*****************************************************************************
  489. SecondBreakN
  490. *****************************************************************************}
  491. procedure tcgbreaknode.pass_2;
  492. begin
  493. include(flowcontrol,fc_break);
  494. if aktbreaklabel<>nil then
  495. begin
  496. load_all_regvars(exprasmlist);
  497. cg.a_jmp_always(exprasmlist,aktbreaklabel)
  498. end
  499. else
  500. CGMessage(cg_e_break_not_allowed);
  501. end;
  502. {*****************************************************************************
  503. SecondContinueN
  504. *****************************************************************************}
  505. procedure tcgcontinuenode.pass_2;
  506. begin
  507. include(flowcontrol,fc_continue);
  508. if aktcontinuelabel<>nil then
  509. begin
  510. load_all_regvars(exprasmlist);
  511. cg.a_jmp_always(exprasmlist,aktcontinuelabel)
  512. end
  513. else
  514. CGMessage(cg_e_continue_not_allowed);
  515. end;
  516. {*****************************************************************************
  517. SecondGoto
  518. *****************************************************************************}
  519. procedure tcggotonode.pass_2;
  520. begin
  521. load_all_regvars(exprasmlist);
  522. cg.a_jmp_always(exprasmlist,labelnr)
  523. end;
  524. {*****************************************************************************
  525. SecondLabel
  526. *****************************************************************************}
  527. procedure tcglabelnode.pass_2;
  528. begin
  529. load_all_regvars(exprasmlist);
  530. cg.a_label(exprasmlist,labelnr);
  531. rg.cleartempgen;
  532. secondpass(left);
  533. end;
  534. {*****************************************************************************
  535. SecondFail
  536. *****************************************************************************}
  537. procedure tcgfailnode.pass_2;
  538. begin
  539. cg.a_jmp_always(exprasmlist,faillabel);
  540. end;
  541. {*****************************************************************************
  542. SecondRaise
  543. *****************************************************************************}
  544. procedure tcgraisenode.pass_2;
  545. var
  546. a : tasmlabel;
  547. href : treference;
  548. href2: treference;
  549. begin
  550. if assigned(left) then
  551. begin
  552. { multiple parameters? }
  553. if assigned(right) then
  554. begin
  555. { push frame }
  556. if assigned(frametree) then
  557. begin
  558. secondpass(frametree);
  559. if codegenerror then
  560. exit;
  561. cg.a_param_loc(exprasmlist,frametree.location,paramanager.getintparaloc(2));
  562. end
  563. else
  564. cg.a_param_const(exprasmlist,OS_INT,0,paramanager.getintparaloc(2));
  565. { push address }
  566. secondpass(right);
  567. if codegenerror then
  568. exit;
  569. cg.a_param_loc(exprasmlist,right.location,paramanager.getintparaloc(1));
  570. end
  571. else
  572. begin
  573. getaddrlabel(a);
  574. cg.a_label(exprasmlist,a);
  575. reference_reset_symbol(href2,a,0);
  576. cg.a_paramaddr_ref(exprasmlist,href2,paramanager.getintparaloc(2));
  577. cg.a_param_reg(exprasmlist,OS_ADDR,FRAME_POINTER_REG,paramanager.getintparaloc(3));
  578. end;
  579. { push object }
  580. secondpass(left);
  581. if codegenerror then
  582. exit;
  583. cg.a_param_loc(exprasmlist,left.location,paramanager.getintparaloc(1));
  584. cg.a_call_name(exprasmlist,'FPC_RAISEEXCEPTION');
  585. end
  586. else
  587. begin
  588. cg.a_call_name(exprasmlist,'FPC_POPADDRSTACK');
  589. cg.a_call_name(exprasmlist,'FPC_RERAISE');
  590. end;
  591. end;
  592. {*****************************************************************************
  593. SecondTryExcept
  594. *****************************************************************************}
  595. var
  596. endexceptlabel : tasmlabel;
  597. procedure try_new_exception(list : taasmoutput;var jmpbuf,envbuf, href : treference;
  598. a : aword; exceptlabel : tasmlabel);
  599. begin
  600. tg.gettempofsizereferencepersistant(list,24,jmpbuf);
  601. tg.gettempofsizereferencepersistant(list,12,envbuf);
  602. tg.gettempofsizereferencepersistant(list,sizeof(aword),href);
  603. new_exception(list, jmpbuf,envbuf, href, a, exceptlabel);
  604. end;
  605. procedure try_free_exception(list : taasmoutput;var jmpbuf, envbuf, href : treference;
  606. a : aword ; endexceptlabel : tasmlabel; onlyfree : boolean);
  607. begin
  608. free_exception(list, jmpbuf, envbuf, href, a, endexceptlabel, onlyfree);
  609. tg.ungetpersistanttempreference(list,jmpbuf);
  610. tg.ungetpersistanttempreference(list,envbuf);
  611. end;
  612. { does the necessary things to clean up the object stack }
  613. { in the except block }
  614. procedure cleanupobjectstack;
  615. begin
  616. cg.a_call_name(exprasmlist,'FPC_POPOBJECTSTACK');
  617. cg.a_param_reg(exprasmlist,OS_ADDR,accumulator,paramanager.getintparaloc(1));
  618. cg.a_call_name(exprasmlist,'FPC_DESTROYEXCEPTION');
  619. cg.g_maybe_loadself(exprasmlist);
  620. end;
  621. procedure tcgtryexceptnode.pass_2;
  622. var
  623. exceptlabel,doexceptlabel,oldendexceptlabel,
  624. lastonlabel,
  625. exitexceptlabel,
  626. continueexceptlabel,
  627. breakexceptlabel,
  628. exittrylabel,
  629. continuetrylabel,
  630. breaktrylabel,
  631. doobjectdestroy,
  632. doobjectdestroyandreraise,
  633. oldaktexitlabel,
  634. oldaktexit2label,
  635. oldaktcontinuelabel,
  636. oldaktbreaklabel : tasmlabel;
  637. oldflowcontrol,tryflowcontrol,
  638. exceptflowcontrol : tflowcontrol;
  639. tempbuf,tempaddr : treference;
  640. href : treference;
  641. label
  642. errorexit;
  643. begin
  644. oldflowcontrol:=flowcontrol;
  645. flowcontrol:=[];
  646. { this can be called recursivly }
  647. oldendexceptlabel:=endexceptlabel;
  648. { save the old labels for control flow statements }
  649. oldaktexitlabel:=aktexitlabel;
  650. oldaktexit2label:=aktexit2label;
  651. if assigned(aktbreaklabel) then
  652. begin
  653. oldaktcontinuelabel:=aktcontinuelabel;
  654. oldaktbreaklabel:=aktbreaklabel;
  655. end;
  656. { get new labels for the control flow statements }
  657. getlabel(exittrylabel);
  658. getlabel(exitexceptlabel);
  659. if assigned(aktbreaklabel) then
  660. begin
  661. getlabel(breaktrylabel);
  662. getlabel(continuetrylabel);
  663. getlabel(breakexceptlabel);
  664. getlabel(continueexceptlabel);
  665. end;
  666. getlabel(exceptlabel);
  667. getlabel(doexceptlabel);
  668. getlabel(endexceptlabel);
  669. getlabel(lastonlabel);
  670. try_new_exception(exprasmlist,tempbuf,tempaddr,href,1,exceptlabel);
  671. { try block }
  672. { set control flow labels for the try block }
  673. aktexitlabel:=exittrylabel;
  674. aktexit2label:=exittrylabel;
  675. if assigned(oldaktbreaklabel) then
  676. begin
  677. aktcontinuelabel:=continuetrylabel;
  678. aktbreaklabel:=breaktrylabel;
  679. end;
  680. flowcontrol:=[];
  681. secondpass(left);
  682. tryflowcontrol:=flowcontrol;
  683. if codegenerror then
  684. goto errorexit;
  685. cg.a_label(exprasmlist,exceptlabel);
  686. try_free_exception(exprasmlist,tempbuf,tempaddr,href,0,endexceptlabel,false);
  687. cg.a_label(exprasmlist,doexceptlabel);
  688. { set control flow labels for the except block }
  689. { and the on statements }
  690. aktexitlabel:=exitexceptlabel;
  691. aktexit2label:=exitexceptlabel;
  692. if assigned(oldaktbreaklabel) then
  693. begin
  694. aktcontinuelabel:=continueexceptlabel;
  695. aktbreaklabel:=breakexceptlabel;
  696. end;
  697. flowcontrol:=[];
  698. { on statements }
  699. if assigned(right) then
  700. secondpass(right);
  701. cg.a_label(exprasmlist,lastonlabel);
  702. { default handling except handling }
  703. if assigned(t1) then
  704. begin
  705. { FPC_CATCHES must be called with
  706. 'default handler' flag (=-1)
  707. }
  708. cg.a_param_const(exprasmlist,OS_ADDR,aword(-1),paramanager.getintparaloc(1));
  709. cg.a_call_name(exprasmlist,'FPC_CATCHES');
  710. cg.g_maybe_loadself(exprasmlist);
  711. { the destruction of the exception object must be also }
  712. { guarded by an exception frame }
  713. getlabel(doobjectdestroy);
  714. getlabel(doobjectdestroyandreraise);
  715. try_new_exception(exprasmlist,tempbuf,tempaddr,href,1,exceptlabel);
  716. { here we don't have to reset flowcontrol }
  717. { the default and on flowcontrols are handled equal }
  718. secondpass(t1);
  719. exceptflowcontrol:=flowcontrol;
  720. cg.a_label(exprasmlist,doobjectdestroyandreraise);
  721. try_free_exception(exprasmlist,tempbuf,tempaddr,href,0,doobjectdestroy,false);
  722. cg.a_call_name(exprasmlist,'FPC_POPSECONDOBJECTSTACK');
  723. cg.a_param_reg(exprasmlist, OS_ADDR, accumulator, paramanager.getintparaloc(1));
  724. cg.a_call_name(exprasmlist,'FPC_DESTROYEXCEPTION');
  725. { we don't need to restore esi here because reraise never }
  726. { returns }
  727. cg.a_call_name(exprasmlist,'FPC_RERAISE');
  728. cg.a_label(exprasmlist,doobjectdestroy);
  729. cleanupobjectstack;
  730. cg.a_jmp_always(exprasmlist,endexceptlabel);
  731. end
  732. else
  733. begin
  734. cg.a_call_name(exprasmlist,'FPC_RERAISE');
  735. exceptflowcontrol:=flowcontrol;
  736. end;
  737. if fc_exit in exceptflowcontrol then
  738. begin
  739. { do some magic for exit in the try block }
  740. cg.a_label(exprasmlist,exitexceptlabel);
  741. { we must also destroy the address frame which guards }
  742. { exception object }
  743. cg.a_call_name(exprasmlist,'FPC_POPADDRSTACK');
  744. cg.g_exception_reason_load(exprasmlist,href);
  745. cleanupobjectstack;
  746. cg.a_jmp_always(exprasmlist,oldaktexitlabel);
  747. end;
  748. if fc_break in exceptflowcontrol then
  749. begin
  750. cg.a_label(exprasmlist,breakexceptlabel);
  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,oldaktbreaklabel);
  757. end;
  758. if fc_continue in exceptflowcontrol then
  759. begin
  760. cg.a_label(exprasmlist,continueexceptlabel);
  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,oldaktcontinuelabel);
  767. end;
  768. if fc_exit in tryflowcontrol then
  769. begin
  770. { do some magic for exit in the try block }
  771. cg.a_label(exprasmlist,exittrylabel);
  772. cg.a_call_name(exprasmlist,'FPC_POPADDRSTACK');
  773. cg.g_exception_reason_load(exprasmlist,href);
  774. cg.a_jmp_always(exprasmlist,oldaktexitlabel);
  775. end;
  776. if fc_break in tryflowcontrol then
  777. begin
  778. cg.a_label(exprasmlist,breaktrylabel);
  779. cg.a_call_name(exprasmlist,'FPC_POPADDRSTACK');
  780. cg.g_exception_reason_load(exprasmlist,href);
  781. cg.a_jmp_always(exprasmlist,oldaktbreaklabel);
  782. end;
  783. if fc_continue in tryflowcontrol then
  784. begin
  785. cg.a_label(exprasmlist,continuetrylabel);
  786. cg.a_call_name(exprasmlist,'FPC_POPADDRSTACK');
  787. cg.g_exception_reason_load(exprasmlist,href);
  788. cg.a_jmp_always(exprasmlist,oldaktcontinuelabel);
  789. end;
  790. cg.a_label(exprasmlist,endexceptlabel);
  791. errorexit:
  792. { restore all saved labels }
  793. endexceptlabel:=oldendexceptlabel;
  794. { restore the control flow labels }
  795. aktexitlabel:=oldaktexitlabel;
  796. aktexit2label:=oldaktexit2label;
  797. if assigned(oldaktbreaklabel) then
  798. begin
  799. aktcontinuelabel:=oldaktcontinuelabel;
  800. aktbreaklabel:=oldaktbreaklabel;
  801. end;
  802. { return all used control flow statements }
  803. flowcontrol:=oldflowcontrol+exceptflowcontrol+
  804. tryflowcontrol;
  805. end;
  806. procedure tcgonnode.pass_2;
  807. var
  808. nextonlabel,
  809. exitonlabel,
  810. continueonlabel,
  811. breakonlabel,
  812. oldaktexitlabel,
  813. oldaktexit2label,
  814. oldaktcontinuelabel,
  815. doobjectdestroyandreraise,
  816. doobjectdestroy,
  817. oldaktbreaklabel : tasmlabel;
  818. ref : treference;
  819. oldflowcontrol : tflowcontrol;
  820. tempbuf,tempaddr : treference;
  821. href : treference;
  822. href2: treference;
  823. begin
  824. oldflowcontrol:=flowcontrol;
  825. flowcontrol:=[];
  826. getlabel(nextonlabel);
  827. { send the vmt parameter }
  828. reference_reset_symbol(href2,newasmsymbol(excepttype.vmt_mangledname),0);
  829. cg.a_paramaddr_ref(exprasmlist,href2,paramanager.getintparaloc(1));
  830. cg.a_call_name(exprasmlist,'FPC_CATCHES');
  831. { is it this catch? No. go to next onlabel }
  832. cg.a_cmp_const_reg_label(exprasmlist,OS_ADDR,OC_EQ,0,accumulator,nextonlabel);
  833. ref.symbol:=nil;
  834. tg.gettempofsizereference(exprasmlist,pointer_size,ref);
  835. { what a hack ! }
  836. if assigned(exceptsymtable) then
  837. tvarsym(exceptsymtable.symindex.first).address:=ref.offset;
  838. cg.a_load_reg_ref(exprasmlist, OS_ADDR, accumulator, ref);
  839. { in the case that another exception is risen }
  840. { we've to destroy the old one }
  841. getlabel(doobjectdestroyandreraise);
  842. { call setjmp, and jump to finally label on non-zero result }
  843. try_new_exception(exprasmlist,tempbuf,tempaddr,href,1,doobjectdestroyandreraise);
  844. if assigned(right) then
  845. begin
  846. oldaktexitlabel:=aktexitlabel;
  847. oldaktexit2label:=aktexit2label;
  848. getlabel(exitonlabel);
  849. aktexitlabel:=exitonlabel;
  850. aktexit2label:=exitonlabel;
  851. if assigned(aktbreaklabel) then
  852. begin
  853. oldaktcontinuelabel:=aktcontinuelabel;
  854. oldaktbreaklabel:=aktbreaklabel;
  855. getlabel(breakonlabel);
  856. getlabel(continueonlabel);
  857. aktcontinuelabel:=continueonlabel;
  858. aktbreaklabel:=breakonlabel;
  859. end;
  860. { esi is destroyed by FPC_CATCHES }
  861. cg.g_maybe_loadself(exprasmlist);
  862. secondpass(right);
  863. end;
  864. getlabel(doobjectdestroy);
  865. cg.a_label(exprasmlist,doobjectdestroyandreraise);
  866. try_free_exception(exprasmlist,tempbuf,tempaddr,href,0,doobjectdestroy,false);
  867. cg.a_call_name(exprasmlist,'FPC_POPSECONDOBJECTSTACK');
  868. cg.a_param_reg(exprasmlist, OS_ADDR, accumulator, paramanager.getintparaloc(1));
  869. cg.a_call_name(exprasmlist,'FPC_DESTROYEXCEPTION');
  870. { we don't need to restore esi here because reraise never }
  871. { returns }
  872. cg.a_call_name(exprasmlist,'FPC_RERAISE');
  873. cg.a_label(exprasmlist,doobjectdestroy);
  874. cleanupobjectstack;
  875. { clear some stuff }
  876. tg.ungetiftemp(exprasmlist,ref);
  877. cg.a_jmp_always(exprasmlist,endexceptlabel);
  878. if assigned(right) then
  879. begin
  880. { special handling for control flow instructions }
  881. if fc_exit in flowcontrol then
  882. begin
  883. { the address and object pop does secondtryexcept }
  884. cg.a_label(exprasmlist,exitonlabel);
  885. cg.a_jmp_always(exprasmlist,oldaktexitlabel);
  886. end;
  887. if fc_break in flowcontrol then
  888. begin
  889. { the address and object pop does secondtryexcept }
  890. cg.a_label(exprasmlist,breakonlabel);
  891. cg.a_jmp_always(exprasmlist,oldaktbreaklabel);
  892. end;
  893. if fc_continue in flowcontrol then
  894. begin
  895. { the address and object pop does secondtryexcept }
  896. cg.a_label(exprasmlist,continueonlabel);
  897. cg.a_jmp_always(exprasmlist,oldaktcontinuelabel);
  898. end;
  899. aktexitlabel:=oldaktexitlabel;
  900. aktexit2label:=oldaktexit2label;
  901. if assigned(oldaktbreaklabel) then
  902. begin
  903. aktcontinuelabel:=oldaktcontinuelabel;
  904. aktbreaklabel:=oldaktbreaklabel;
  905. end;
  906. end;
  907. cg.a_label(exprasmlist,nextonlabel);
  908. flowcontrol:=oldflowcontrol+flowcontrol;
  909. { next on node }
  910. if assigned(left) then
  911. begin
  912. rg.cleartempgen;
  913. secondpass(left);
  914. end;
  915. end;
  916. {*****************************************************************************
  917. SecondTryFinally
  918. *****************************************************************************}
  919. procedure tcgtryfinallynode.pass_2;
  920. var
  921. reraiselabel,
  922. finallylabel,
  923. endfinallylabel,
  924. exitfinallylabel,
  925. continuefinallylabel,
  926. breakfinallylabel,
  927. oldaktexitlabel,
  928. oldaktexit2label,
  929. oldaktcontinuelabel,
  930. oldaktbreaklabel : tasmlabel;
  931. oldflowcontrol,tryflowcontrol : tflowcontrol;
  932. decconst : longint;
  933. tempbuf,tempaddr : treference;
  934. href : treference;
  935. begin
  936. { check if child nodes do a break/continue/exit }
  937. oldflowcontrol:=flowcontrol;
  938. flowcontrol:=[];
  939. getlabel(finallylabel);
  940. getlabel(endfinallylabel);
  941. getlabel(reraiselabel);
  942. { the finally block must catch break, continue and exit }
  943. { statements }
  944. oldaktexitlabel:=aktexitlabel;
  945. oldaktexit2label:=aktexit2label;
  946. getlabel(exitfinallylabel);
  947. aktexitlabel:=exitfinallylabel;
  948. aktexit2label:=exitfinallylabel;
  949. if assigned(aktbreaklabel) then
  950. begin
  951. oldaktcontinuelabel:=aktcontinuelabel;
  952. oldaktbreaklabel:=aktbreaklabel;
  953. getlabel(breakfinallylabel);
  954. getlabel(continuefinallylabel);
  955. aktcontinuelabel:=continuefinallylabel;
  956. aktbreaklabel:=breakfinallylabel;
  957. end;
  958. { call setjmp, and jump to finally label on non-zero result }
  959. try_new_exception(exprasmlist,tempbuf,tempaddr,href,1,finallylabel);
  960. { try code }
  961. if assigned(left) then
  962. begin
  963. secondpass(left);
  964. tryflowcontrol:=flowcontrol;
  965. if codegenerror then
  966. exit;
  967. end;
  968. cg.a_label(exprasmlist,finallylabel);
  969. { just free the frame information }
  970. try_free_exception(exprasmlist,tempbuf,tempaddr,href,1,finallylabel,true);
  971. { finally code }
  972. flowcontrol:=[];
  973. secondpass(right);
  974. if flowcontrol<>[] then
  975. CGMessage(cg_e_control_flow_outside_finally);
  976. if codegenerror then
  977. exit;
  978. { the value should now be in the exception handler }
  979. cg.g_exception_reason_load(exprasmlist,href);
  980. cg.a_cmp_reg_reg_label(exprasmlist,OS_S32,OC_NE,accumulator,accumulator,finallylabel);
  981. cg.a_op_const_reg(exprasmlist,OP_SUB,1,accumulator);
  982. cg.a_cmp_const_reg_label(exprasmlist,OS_S32,OC_EQ,0,accumulator,reraiselabel);
  983. if fc_exit in tryflowcontrol then
  984. begin
  985. cg.a_op_const_reg(exprasmlist,OP_SUB,1,accumulator);
  986. cg.a_cmp_const_reg_label(exprasmlist,OS_S32,OC_EQ,0,accumulator,oldaktexitlabel);
  987. decconst:=1;
  988. end
  989. else
  990. decconst:=2;
  991. if fc_break in tryflowcontrol then
  992. begin
  993. cg.a_op_const_reg(exprasmlist,OP_SUB,decconst,accumulator);
  994. cg.a_cmp_const_reg_label(exprasmlist,OS_S32,OC_EQ,0,accumulator,oldaktbreaklabel);
  995. decconst:=1;
  996. end
  997. else
  998. inc(decconst);
  999. if fc_continue in tryflowcontrol then
  1000. begin
  1001. cg.a_op_const_reg(exprasmlist,OP_SUB,decconst,accumulator);
  1002. cg.a_cmp_const_reg_label(exprasmlist,OS_S32,OC_EQ,0,accumulator,oldaktcontinuelabel);
  1003. end;
  1004. cg.a_label(exprasmlist,reraiselabel);
  1005. cg.a_call_name(exprasmlist,'FPC_RERAISE');
  1006. { do some magic for exit,break,continue in the try block }
  1007. if fc_exit in tryflowcontrol then
  1008. begin
  1009. cg.a_label(exprasmlist,exitfinallylabel);
  1010. cg.g_exception_reason_load(exprasmlist,href);
  1011. cg.g_exception_reason_save_const(exprasmlist,href,2);
  1012. cg.a_jmp_always(exprasmlist,finallylabel);
  1013. end;
  1014. if fc_break in tryflowcontrol then
  1015. begin
  1016. cg.a_label(exprasmlist,breakfinallylabel);
  1017. cg.g_exception_reason_load(exprasmlist,href);
  1018. cg.g_exception_reason_save_const(exprasmlist,href,3);
  1019. cg.a_jmp_always(exprasmlist,finallylabel);
  1020. end;
  1021. if fc_continue in tryflowcontrol then
  1022. begin
  1023. cg.a_label(exprasmlist,continuefinallylabel);
  1024. cg.g_exception_reason_load(exprasmlist,href);
  1025. cg.g_exception_reason_save_const(exprasmlist,href,4);
  1026. cg.a_jmp_always(exprasmlist,finallylabel);
  1027. end;
  1028. cg.a_label(exprasmlist,endfinallylabel);
  1029. aktexitlabel:=oldaktexitlabel;
  1030. aktexit2label:=oldaktexit2label;
  1031. if assigned(aktbreaklabel) then
  1032. begin
  1033. aktcontinuelabel:=oldaktcontinuelabel;
  1034. aktbreaklabel:=oldaktbreaklabel;
  1035. end;
  1036. flowcontrol:=oldflowcontrol+tryflowcontrol;
  1037. end;
  1038. begin
  1039. cwhilerepeatnode:=tcgwhilerepeatnode;
  1040. cifnode:=tcgifnode;
  1041. cfornode:=tcgfornode;
  1042. cexitnode:=tcgexitnode;
  1043. cbreaknode:=tcgbreaknode;
  1044. ccontinuenode:=tcgcontinuenode;
  1045. cgotonode:=tcggotonode;
  1046. clabelnode:=tcglabelnode;
  1047. cfailnode:=tcgfailnode;
  1048. craisenode:=tcgraisenode;
  1049. ctryexceptnode:=tcgtryexceptnode;
  1050. ctryfinallynode:=tcgtryfinallynode;
  1051. connode:=tcgonnode;
  1052. end.
  1053. {
  1054. $Log$
  1055. Revision 1.32 2002-08-09 19:10:59 carl
  1056. * fixed generic exception management
  1057. Revision 1.31 2002/08/04 19:06:41 carl
  1058. + added generic exception support (still does not work!)
  1059. + more documentation
  1060. Revision 1.30 2002/07/27 19:53:51 jonas
  1061. + generic implementation of tcg.g_flags2ref()
  1062. * tcg.flags2xxx() now also needs a size parameter
  1063. Revision 1.29 2002/07/25 17:56:29 carl
  1064. + FPURESULTREG -> FPU_RESULT_REG
  1065. Revision 1.28 2002/07/21 06:58:49 daniel
  1066. * Changed booleans into flags
  1067. Revision 1.27 2002/07/20 12:54:53 daniel
  1068. * Optimized the code generated for for nodes. The shootout/nestloop benchmark
  1069. now runs 5% faster on my computer.
  1070. Revision 1.26 2002/07/20 11:57:54 florian
  1071. * types.pas renamed to defbase.pas because D6 contains a types
  1072. unit so this would conflicts if D6 programms are compiled
  1073. + Willamette/SSE2 instructions to assembler added
  1074. Revision 1.25 2002/07/20 11:15:51 daniel
  1075. * The for node does a check if the first comparision can be skipped. I moved
  1076. the check from the second pass to the resulttype pass. The advantage is
  1077. that the state tracker can now decide to skip the first comparision too.
  1078. Revision 1.24 2002/07/20 08:14:24 daniel
  1079. * Loops should not be aligned when optimizing for size
  1080. Revision 1.23 2002/07/19 11:41:35 daniel
  1081. * State tracker work
  1082. * The whilen and repeatn are now completely unified into whilerepeatn. This
  1083. allows the state tracker to change while nodes automatically into
  1084. repeat nodes.
  1085. * Resulttypepass improvements to the notn. 'not not a' is optimized away and
  1086. 'not(a>b)' is optimized into 'a<=b'.
  1087. * Resulttypepass improvements to the whilerepeatn. 'while not a' is optimized
  1088. by removing the notn and later switchting the true and falselabels. The
  1089. same is done with 'repeat until not a'.
  1090. Revision 1.22 2002/07/04 20:43:01 florian
  1091. * first x86-64 patches
  1092. Revision 1.21 2002/07/01 18:46:22 peter
  1093. * internal linker
  1094. * reorganized aasm layer
  1095. Revision 1.20 2002/07/01 16:23:53 peter
  1096. * cg64 patch
  1097. * basics for currency
  1098. * asnode updates for class and interface (not finished)
  1099. Revision 1.19 2002/05/20 13:30:40 carl
  1100. * bugfix of hdisponen (base must be set, not index)
  1101. * more portability fixes
  1102. Revision 1.18 2002/05/18 13:34:09 peter
  1103. * readded missing revisions
  1104. Revision 1.17 2002/05/16 19:46:37 carl
  1105. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  1106. + try to fix temp allocation (still in ifdef)
  1107. + generic constructor calls
  1108. + start of tassembler / tmodulebase class cleanup
  1109. Revision 1.15 2002/05/13 19:54:37 peter
  1110. * removed n386ld and n386util units
  1111. * maybe_save/maybe_restore added instead of the old maybe_push
  1112. Revision 1.14 2002/05/12 16:53:07 peter
  1113. * moved entry and exitcode to ncgutil and cgobj
  1114. * foreach gets extra argument for passing local data to the
  1115. iterator function
  1116. * -CR checks also class typecasts at runtime by changing them
  1117. into as
  1118. * fixed compiler to cycle with the -CR option
  1119. * fixed stabs with elf writer, finally the global variables can
  1120. be watched
  1121. * removed a lot of routines from cga unit and replaced them by
  1122. calls to cgobj
  1123. * u32bit-s32bit updates for and,or,xor nodes. When one element is
  1124. u32bit then the other is typecasted also to u32bit without giving
  1125. a rangecheck warning/error.
  1126. * fixed pascal calling method with reversing also the high tree in
  1127. the parast, detected by tcalcst3 test
  1128. Revision 1.13 2002/04/21 15:24:38 carl
  1129. + a_jmp_cond -> a_jmp_always (a_jmp_cond is NOT portable)
  1130. + changeregsize -> rg.makeregsize
  1131. Revision 1.12 2002/04/15 19:44:19 peter
  1132. * fixed stackcheck that would be called recursively when a stack
  1133. error was found
  1134. * generic changeregsize(reg,size) for i386 register resizing
  1135. * removed some more routines from cga unit
  1136. * fixed returnvalue handling
  1137. * fixed default stacksize of linux and go32v2, 8kb was a bit small :-)
  1138. Revision 1.11 2002/04/04 19:05:57 peter
  1139. * removed unused units
  1140. * use tlocation.size in cg.a_*loc*() routines
  1141. Revision 1.10 2002/04/02 17:11:28 peter
  1142. * tlocation,treference update
  1143. * LOC_CONSTANT added for better constant handling
  1144. * secondadd splitted in multiple routines
  1145. * location_force_reg added for loading a location to a register
  1146. of a specified size
  1147. * secondassignment parses now first the right and then the left node
  1148. (this is compatible with Kylix). This saves a lot of push/pop especially
  1149. with string operations
  1150. * adapted some routines to use the new cg methods
  1151. Revision 1.9 2002/03/31 20:26:34 jonas
  1152. + a_loadfpu_* and a_loadmm_* methods in tcg
  1153. * register allocation is now handled by a class and is mostly processor
  1154. independent (+rgobj.pas and i386/rgcpu.pas)
  1155. * temp allocation is now handled by a class (+tgobj.pas, -i386\tgcpu.pas)
  1156. * some small improvements and fixes to the optimizer
  1157. * some register allocation fixes
  1158. * some fpuvaroffset fixes in the unary minus node
  1159. * push/popusedregisters is now called rg.save/restoreusedregisters and
  1160. (for i386) uses temps instead of push/pop's when using -Op3 (that code is
  1161. also better optimizable)
  1162. * fixed and optimized register saving/restoring for new/dispose nodes
  1163. * LOC_FPU locations now also require their "register" field to be set to
  1164. R_ST, not R_ST0 (the latter is used for LOC_CFPUREGISTER locations only)
  1165. - list field removed of the tnode class because it's not used currently
  1166. and can cause hard-to-find bugs
  1167. Revision 1.8 2002/03/04 19:10:11 peter
  1168. * removed compiler warnings
  1169. }