nflw.pas 49 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 by Florian Klaempfl
  4. Type checking and register allocation for nodes that influence
  5. the flow
  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 nflw;
  20. {$i fpcdefs.inc}
  21. interface
  22. uses
  23. node,cpubase,
  24. aasmbase,aasmtai,aasmcpu,symnot,
  25. symppu,symtype,symbase,symdef,symsym;
  26. type
  27. { flags used by loop nodes }
  28. tloopflag = (
  29. { set if it is a for ... downto ... do loop }
  30. lnf_backward,
  31. { Do we need to parse childs to set var state? }
  32. lnf_varstate,
  33. { Do a test at the begin of the loop?}
  34. lnf_testatbegin,
  35. { Negate the loop test? }
  36. lnf_checknegate,
  37. { Should the value of the loop variable on exit be correct. }
  38. lnf_dont_mind_loopvar_on_exit);
  39. tloopflags = set of tloopflag;
  40. const
  41. { loop flags which must match to consider loop nodes equal regarding the flags }
  42. loopflagsequal = [lnf_backward];
  43. type
  44. tloopnode = class(tbinarynode)
  45. t1,t2 : tnode;
  46. loopflags : tloopflags;
  47. constructor create(tt : tnodetype;l,r,_t1,_t2 : tnode);virtual;
  48. destructor destroy;override;
  49. function getcopy : tnode;override;
  50. constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override;
  51. procedure ppuwrite(ppufile:tcompilerppufile);override;
  52. procedure derefimpl;override;
  53. procedure insertintolist(l : tnodelist);override;
  54. procedure printnodetree(var t:text);override;
  55. function docompare(p: tnode): boolean; override;
  56. end;
  57. twhilerepeatnode = class(tloopnode)
  58. constructor create(l,r,_t1:Tnode;tab,cn:boolean);virtual;
  59. function det_resulttype:tnode;override;
  60. function pass_1 : tnode;override;
  61. {$ifdef state_tracking}
  62. function track_state_pass(exec_known:boolean):boolean;override;
  63. {$endif}
  64. end;
  65. twhilerepeatnodeclass = class of twhilerepeatnode;
  66. tifnode = class(tloopnode)
  67. constructor create(l,r,_t1 : tnode);virtual;
  68. function det_resulttype:tnode;override;
  69. function pass_1 : tnode;override;
  70. end;
  71. tifnodeclass = class of tifnode;
  72. tfornode = class(tloopnode)
  73. loopvar_notid:cardinal;
  74. constructor create(l,r,_t1,_t2 : tnode;back : boolean);virtual;
  75. procedure loop_var_access(not_type:Tnotification_flag;symbol:Tsym);
  76. function det_resulttype:tnode;override;
  77. function pass_1 : tnode;override;
  78. end;
  79. tfornodeclass = class of tfornode;
  80. texitnode = class(tunarynode)
  81. constructor create(l:tnode);virtual;
  82. constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override;
  83. procedure ppuwrite(ppufile:tcompilerppufile);override;
  84. function det_resulttype:tnode;override;
  85. function pass_1 : tnode;override;
  86. end;
  87. texitnodeclass = class of texitnode;
  88. tbreaknode = class(tnode)
  89. constructor create;virtual;
  90. function det_resulttype:tnode;override;
  91. function pass_1 : tnode;override;
  92. end;
  93. tbreaknodeclass = class of tbreaknode;
  94. tcontinuenode = class(tnode)
  95. constructor create;virtual;
  96. function det_resulttype:tnode;override;
  97. function pass_1 : tnode;override;
  98. end;
  99. tcontinuenodeclass = class of tcontinuenode;
  100. tgotonode = class(tnode)
  101. labsym : tlabelsym;
  102. labsymderef : tderef;
  103. exceptionblock : integer;
  104. { internlab : tinterngotolabel;}
  105. constructor create(p : tlabelsym);virtual;
  106. { constructor createintern(g:tinterngotolabel);}
  107. constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override;
  108. procedure ppuwrite(ppufile:tcompilerppufile);override;
  109. procedure derefimpl;override;
  110. function getcopy : tnode;override;
  111. function det_resulttype:tnode;override;
  112. function pass_1 : tnode;override;
  113. function docompare(p: tnode): boolean; override;
  114. end;
  115. tgotonodeclass = class of tgotonode;
  116. tlabelnode = class(tunarynode)
  117. labelnr : tasmlabel;
  118. labsym : tlabelsym;
  119. labsymderef : tderef;
  120. exceptionblock : integer;
  121. constructor createcase(p : tasmlabel;l:tnode);virtual;
  122. constructor create(p : tlabelsym;l:tnode);virtual;
  123. constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override;
  124. procedure ppuwrite(ppufile:tcompilerppufile);override;
  125. procedure derefimpl;override;
  126. function getcopy : tnode;override;
  127. function det_resulttype:tnode;override;
  128. function pass_1 : tnode;override;
  129. function docompare(p: tnode): boolean; override;
  130. end;
  131. tlabelnodeclass = class of tlabelnode;
  132. traisenode = class(tbinarynode)
  133. frametree : tnode;
  134. constructor create(l,taddr,tframe:tnode);virtual;
  135. constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override;
  136. procedure ppuwrite(ppufile:tcompilerppufile);override;
  137. procedure derefimpl;override;
  138. function getcopy : tnode;override;
  139. procedure insertintolist(l : tnodelist);override;
  140. function det_resulttype:tnode;override;
  141. function pass_1 : tnode;override;
  142. function docompare(p: tnode): boolean; override;
  143. end;
  144. traisenodeclass = class of traisenode;
  145. ttryexceptnode = class(tloopnode)
  146. constructor create(l,r,_t1 : tnode);virtual;
  147. function det_resulttype:tnode;override;
  148. function pass_1 : tnode;override;
  149. end;
  150. ttryexceptnodeclass = class of ttryexceptnode;
  151. ttryfinallynode = class(tloopnode)
  152. implicitframe : boolean;
  153. constructor create(l,r:tnode);virtual;
  154. constructor create_implicit(l,r,_t1:tnode);virtual;
  155. function det_resulttype:tnode;override;
  156. function pass_1 : tnode;override;
  157. end;
  158. ttryfinallynodeclass = class of ttryfinallynode;
  159. tonnode = class(tbinarynode)
  160. exceptsymtable : tsymtable;
  161. excepttype : tobjectdef;
  162. constructor create(l,r:tnode);virtual;
  163. destructor destroy;override;
  164. constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override;
  165. function det_resulttype:tnode;override;
  166. function pass_1 : tnode;override;
  167. function getcopy : tnode;override;
  168. function docompare(p: tnode): boolean; override;
  169. end;
  170. tonnodeclass = class of tonnode;
  171. { for compatibilty }
  172. function genloopnode(t : tnodetype;l,r,n1 : tnode;back : boolean) : tnode;
  173. var
  174. cwhilerepeatnode : twhilerepeatnodeclass;
  175. cifnode : tifnodeclass;
  176. cfornode : tfornodeclass;
  177. cexitnode : texitnodeclass;
  178. cbreaknode : tbreaknodeclass;
  179. ccontinuenode : tcontinuenodeclass;
  180. cgotonode : tgotonodeclass;
  181. clabelnode : tlabelnodeclass;
  182. craisenode : traisenodeclass;
  183. ctryexceptnode : ttryexceptnodeclass;
  184. ctryfinallynode : ttryfinallynodeclass;
  185. connode : tonnodeclass;
  186. implementation
  187. uses
  188. globtype,systems,
  189. cutils,verbose,globals,
  190. symconst,symtable,paramgr,defutil,htypechk,pass_1,
  191. ncal,nadd,ncon,nmem,nld,ncnv,nbas,rgobj,
  192. {$ifdef state_tracking}
  193. nstate,
  194. {$endif}
  195. cgbase,procinfo
  196. ;
  197. function genloopnode(t : tnodetype;l,r,n1 : tnode;back : boolean) : tnode;
  198. var
  199. p : tnode;
  200. begin
  201. case t of
  202. ifn:
  203. p:=cifnode.create(l,r,n1);
  204. whilerepeatn:
  205. if back then
  206. {Repeat until.}
  207. p:=cwhilerepeatnode.create(l,r,n1,false,true)
  208. else
  209. {While do.}
  210. p:=cwhilerepeatnode.create(l,r,n1,true,false);
  211. forn:
  212. p:=cfornode.create(l,r,n1,nil,back);
  213. end;
  214. genloopnode:=p;
  215. end;
  216. {****************************************************************************
  217. TLOOPNODE
  218. *****************************************************************************}
  219. constructor tloopnode.create(tt : tnodetype;l,r,_t1,_t2 : tnode);
  220. begin
  221. inherited create(tt,l,r);
  222. t1:=_t1;
  223. t2:=_t2;
  224. set_file_line(l);
  225. end;
  226. destructor tloopnode.destroy;
  227. begin
  228. t1.free;
  229. t2.free;
  230. inherited destroy;
  231. end;
  232. constructor tloopnode.ppuload(t:tnodetype;ppufile:tcompilerppufile);
  233. begin
  234. inherited ppuload(t,ppufile);
  235. t1:=ppuloadnode(ppufile);
  236. t2:=ppuloadnode(ppufile);
  237. end;
  238. procedure tloopnode.ppuwrite(ppufile:tcompilerppufile);
  239. begin
  240. inherited ppuwrite(ppufile);
  241. ppuwritenode(ppufile,t1);
  242. ppuwritenode(ppufile,t2);
  243. end;
  244. procedure tloopnode.derefimpl;
  245. begin
  246. inherited derefimpl;
  247. if assigned(t1) then
  248. t1.derefimpl;
  249. if assigned(t2) then
  250. t2.derefimpl;
  251. end;
  252. function tloopnode.getcopy : tnode;
  253. var
  254. p : tloopnode;
  255. begin
  256. p:=tloopnode(inherited getcopy);
  257. if assigned(t1) then
  258. p.t1:=t1.getcopy
  259. else
  260. p.t1:=nil;
  261. if assigned(t2) then
  262. p.t2:=t2.getcopy
  263. else
  264. p.t2:=nil;
  265. getcopy:=p;
  266. end;
  267. procedure tloopnode.insertintolist(l : tnodelist);
  268. begin
  269. end;
  270. procedure tloopnode.printnodetree(var t:text);
  271. begin
  272. printnodeinfo(t);
  273. printnodeindent;
  274. printnode(t,left);
  275. printnode(t,right);
  276. printnode(t,t1);
  277. printnode(t,t2);
  278. printnodeunindent;
  279. end;
  280. function tloopnode.docompare(p: tnode): boolean;
  281. begin
  282. docompare :=
  283. inherited docompare(p) and
  284. (loopflags*loopflagsequal=tloopnode(p).loopflags*loopflagsequal) and
  285. t1.isequal(tloopnode(p).t1) and
  286. t2.isequal(tloopnode(p).t2);
  287. end;
  288. {****************************************************************************
  289. TWHILEREPEATNODE
  290. *****************************************************************************}
  291. constructor Twhilerepeatnode.create(l,r,_t1:Tnode;tab,cn:boolean);
  292. begin
  293. inherited create(whilerepeatn,l,r,_t1,nil);
  294. if tab then
  295. include(loopflags, lnf_testatbegin);
  296. if cn then
  297. include(loopflags,lnf_checknegate);
  298. end;
  299. function twhilerepeatnode.det_resulttype:tnode;
  300. var
  301. t:Tunarynode;
  302. begin
  303. result:=nil;
  304. resulttype:=voidtype;
  305. resulttypepass(left);
  306. {A not node can be removed.}
  307. if left.nodetype=notn then
  308. begin
  309. t:=Tunarynode(left);
  310. left:=Tunarynode(left).left;
  311. t.left:=nil;
  312. t.destroy;
  313. {$ifdef Delphi}
  314. { How can this be handled in Delphi ? }
  315. RunError(255);
  316. {$else}
  317. {Symdif operator, in case you are wondering:}
  318. loopflags:=loopflags >< [lnf_checknegate];
  319. {$endif}
  320. end;
  321. { loop instruction }
  322. if assigned(right) then
  323. resulttypepass(right);
  324. set_varstate(left,true);
  325. if codegenerror then
  326. exit;
  327. if not is_boolean(left.resulttype.def) then
  328. begin
  329. CGMessage(type_e_mismatch);
  330. exit;
  331. end;
  332. end;
  333. function twhilerepeatnode.pass_1 : tnode;
  334. var
  335. old_t_times : longint;
  336. begin
  337. result:=nil;
  338. expectloc:=LOC_VOID;
  339. old_t_times:=rg.t_times;
  340. { calc register weight }
  341. if not(cs_littlesize in aktglobalswitches ) then
  342. rg.t_times:=rg.t_times*8;
  343. firstpass(left);
  344. if codegenerror then
  345. exit;
  346. registers32:=left.registers32;
  347. registersfpu:=left.registersfpu;
  348. {$ifdef SUPPORT_MMX}
  349. registersmmx:=left.registersmmx;
  350. {$endif SUPPORT_MMX}
  351. { loop instruction }
  352. if assigned(right) then
  353. begin
  354. firstpass(right);
  355. if codegenerror then
  356. exit;
  357. if registers32<right.registers32 then
  358. registers32:=right.registers32;
  359. if registersfpu<right.registersfpu then
  360. registersfpu:=right.registersfpu;
  361. {$ifdef SUPPORT_MMX}
  362. if registersmmx<right.registersmmx then
  363. registersmmx:=right.registersmmx;
  364. {$endif SUPPORT_MMX}
  365. end;
  366. rg.t_times:=old_t_times;
  367. end;
  368. {$ifdef state_tracking}
  369. function Twhilerepeatnode.track_state_pass(exec_known:boolean):boolean;
  370. var condition:Tnode;
  371. code:Tnode;
  372. done:boolean;
  373. value:boolean;
  374. change:boolean;
  375. firsttest:boolean;
  376. factval:Tnode;
  377. begin
  378. track_state_pass:=false;
  379. done:=false;
  380. firsttest:=true;
  381. {For repeat until statements, first do a pass through the code.}
  382. if not(lnf_testatbegin in flags) then
  383. begin
  384. code:=right.getcopy;
  385. if code.track_state_pass(exec_known) then
  386. track_state_pass:=true;
  387. code.destroy;
  388. end;
  389. repeat
  390. condition:=left.getcopy;
  391. code:=right.getcopy;
  392. change:=condition.track_state_pass(exec_known);
  393. factval:=aktstate.find_fact(left);
  394. if factval<>nil then
  395. begin
  396. condition.destroy;
  397. condition:=factval.getcopy;
  398. change:=true;
  399. end;
  400. if change then
  401. begin
  402. track_state_pass:=true;
  403. {Force new resulttype pass.}
  404. condition.resulttype.def:=nil;
  405. do_resulttypepass(condition);
  406. end;
  407. if is_constboolnode(condition) then
  408. begin
  409. {Try to turn a while loop into a repeat loop.}
  410. if firsttest then
  411. exclude(flags,testatbegin);
  412. value:=(Tordconstnode(condition).value<>0) xor checknegate;
  413. if value then
  414. begin
  415. if code.track_state_pass(exec_known) then
  416. track_state_pass:=true;
  417. end
  418. else
  419. done:=true;
  420. end
  421. else
  422. begin
  423. {Remove any modified variables from the state.}
  424. code.track_state_pass(false);
  425. done:=true;
  426. end;
  427. code.destroy;
  428. condition.destroy;
  429. firsttest:=false;
  430. until done;
  431. {The loop condition is also known, for example:
  432. while i<10 do
  433. begin
  434. ...
  435. end;
  436. When the loop is done, we do know that i<10 = false.
  437. }
  438. condition:=left.getcopy;
  439. if condition.track_state_pass(exec_known) then
  440. begin
  441. track_state_pass:=true;
  442. {Force new resulttype pass.}
  443. condition.resulttype.def:=nil;
  444. do_resulttypepass(condition);
  445. end;
  446. if not is_constboolnode(condition) then
  447. aktstate.store_fact(condition,
  448. cordconstnode.create(byte(checknegate),booltype,true))
  449. else
  450. condition.destroy;
  451. end;
  452. {$endif}
  453. {*****************************************************************************
  454. TIFNODE
  455. *****************************************************************************}
  456. constructor tifnode.create(l,r,_t1 : tnode);
  457. begin
  458. inherited create(ifn,l,r,_t1,nil);
  459. end;
  460. function tifnode.det_resulttype:tnode;
  461. begin
  462. result:=nil;
  463. resulttype:=voidtype;
  464. resulttypepass(left);
  465. { if path }
  466. if assigned(right) then
  467. resulttypepass(right);
  468. { else path }
  469. if assigned(t1) then
  470. resulttypepass(t1);
  471. set_varstate(left,true);
  472. if codegenerror then
  473. exit;
  474. if not is_boolean(left.resulttype.def) then
  475. Message1(type_e_boolean_expr_expected,left.resulttype.def.typename);
  476. end;
  477. function tifnode.pass_1 : tnode;
  478. var
  479. old_t_times : longint;
  480. hp : tnode;
  481. begin
  482. result:=nil;
  483. expectloc:=LOC_VOID;
  484. old_t_times:=rg.t_times;
  485. firstpass(left);
  486. registers32:=left.registers32;
  487. registersfpu:=left.registersfpu;
  488. {$ifdef SUPPORT_MMX}
  489. registersmmx:=left.registersmmx;
  490. {$endif SUPPORT_MMX}
  491. { determines registers weigths }
  492. if not(cs_littlesize in aktglobalswitches) then
  493. rg.t_times:=rg.t_times div 2;
  494. if rg.t_times=0 then
  495. rg.t_times:=1;
  496. { if path }
  497. if assigned(right) then
  498. begin
  499. firstpass(right);
  500. if registers32<right.registers32 then
  501. registers32:=right.registers32;
  502. if registersfpu<right.registersfpu then
  503. registersfpu:=right.registersfpu;
  504. {$ifdef SUPPORT_MMX}
  505. if registersmmx<right.registersmmx then
  506. registersmmx:=right.registersmmx;
  507. {$endif SUPPORT_MMX}
  508. end;
  509. { else path }
  510. if assigned(t1) then
  511. begin
  512. firstpass(t1);
  513. if registers32<t1.registers32 then
  514. registers32:=t1.registers32;
  515. if registersfpu<t1.registersfpu then
  516. registersfpu:=t1.registersfpu;
  517. {$ifdef SUPPORT_MMX}
  518. if registersmmx<t1.registersmmx then
  519. registersmmx:=t1.registersmmx;
  520. {$endif SUPPORT_MMX}
  521. end;
  522. { leave if we've got an error in one of the paths }
  523. if codegenerror then
  524. exit;
  525. if left.nodetype=ordconstn then
  526. begin
  527. { optimize }
  528. if tordconstnode(left).value=1 then
  529. begin
  530. hp:=right;
  531. right:=nil;
  532. { we cannot set p to nil !!! }
  533. if assigned(hp) then
  534. result:=hp
  535. else
  536. result:=cnothingnode.create;
  537. end
  538. else
  539. begin
  540. hp:=t1;
  541. t1:=nil;
  542. { we cannot set p to nil !!! }
  543. if assigned(hp) then
  544. result:=hp
  545. else
  546. result:=cnothingnode.create;
  547. end;
  548. end;
  549. rg.t_times:=old_t_times;
  550. end;
  551. {*****************************************************************************
  552. TFORNODE
  553. *****************************************************************************}
  554. constructor tfornode.create(l,r,_t1,_t2 : tnode;back : boolean);
  555. begin
  556. inherited create(forn,l,r,_t1,_t2);
  557. if back then
  558. include(loopflags,lnf_backward);
  559. include(loopflags,lnf_testatbegin);
  560. end;
  561. procedure Tfornode.loop_var_access(not_type:Tnotification_flag;
  562. symbol:Tsym);
  563. begin
  564. {If there is a read access, the value of the loop counter is important;
  565. at the end of the loop the loop variable should contain the value it
  566. had in the last iteration.}
  567. if not_type=vn_onwrite then
  568. begin
  569. writeln('Loopvar does not matter on exit');
  570. end
  571. else
  572. begin
  573. exclude(loopflags,lnf_dont_mind_loopvar_on_exit);
  574. writeln('Loopvar does matter on exit');
  575. end;
  576. Tvarsym(symbol).unregister_notification(loopvar_notid);
  577. end;
  578. function tfornode.det_resulttype:tnode;
  579. var
  580. hp : tnode;
  581. begin
  582. result:=nil;
  583. resulttype:=voidtype;
  584. if left.nodetype<>assignn then
  585. begin
  586. CGMessage(cg_e_illegal_expression);
  587. exit;
  588. end;
  589. {Can we spare the first comparision?}
  590. if (right.nodetype=ordconstn) and (Tassignmentnode(left).right.nodetype=ordconstn) then
  591. if (
  592. (lnf_backward in loopflags) and
  593. (Tordconstnode(Tassignmentnode(left).right).value>=Tordconstnode(right).value)
  594. )
  595. or not(
  596. (lnf_backward in loopflags) and
  597. (Tordconstnode(Tassignmentnode(left).right).value<=Tordconstnode(right).value)
  598. ) then
  599. exclude(loopflags,lnf_testatbegin);
  600. { save counter var }
  601. t2:=tassignmentnode(left).left.getcopy;
  602. resulttypepass(left);
  603. set_varstate(left,false);
  604. if assigned(t1) then
  605. begin
  606. resulttypepass(t1);
  607. if codegenerror then
  608. exit;
  609. end;
  610. { process count var }
  611. resulttypepass(t2);
  612. set_varstate(t2,true);
  613. if codegenerror then
  614. exit;
  615. { Check count var, record fields are also allowed in tp7 }
  616. hp:=t2;
  617. while (hp.nodetype=subscriptn) or
  618. ((hp.nodetype=vecn) and
  619. is_constintnode(tvecnode(hp).right)) do
  620. hp:=tunarynode(hp).left;
  621. { we need a simple loadn, but the load must be in a global symtable or
  622. in the same level as the para of the current proc }
  623. if (
  624. (hp.nodetype=loadn) and
  625. (
  626. (tloadnode(hp).symtable.symtablelevel=main_program_level) or
  627. (tloadnode(hp).symtable.symtablelevel=current_procinfo.procdef.parast.symtablelevel)
  628. ) and
  629. not(
  630. (tloadnode(hp).symtableentry.typ=varsym) and
  631. ((tvarsym(tloadnode(hp).symtableentry).varspez in [vs_var,vs_out]) or
  632. (vo_is_thread_var in tvarsym(tloadnode(hp).symtableentry).varoptions))
  633. )
  634. ) then
  635. begin
  636. if (hp.nodetype=loadn) and
  637. (tloadnode(hp).symtableentry.typ=varsym) then
  638. tvarsym(tloadnode(hp).symtableentry).varstate:=vs_used;
  639. if not(is_ordinal(t2.resulttype.def))
  640. {$ifndef cpu64bit}
  641. or is_64bitint(t2.resulttype.def)
  642. {$endif cpu64bit}
  643. then
  644. CGMessagePos(hp.fileinfo,type_e_ordinal_expr_expected);
  645. end
  646. else
  647. CGMessagePos(hp.fileinfo,cg_e_illegal_count_var);
  648. resulttypepass(right);
  649. set_varstate(right,true);
  650. inserttypeconv(right,t2.resulttype);
  651. end;
  652. function tfornode.pass_1 : tnode;
  653. var
  654. old_t_times : longint;
  655. {$ifdef loopvar_dont_mind}
  656. hp : Tnode;
  657. {$endif loopvar_dont_mind}
  658. begin
  659. result:=nil;
  660. expectloc:=LOC_VOID;
  661. { Calc register weight }
  662. old_t_times:=rg.t_times;
  663. if not(cs_littlesize in aktglobalswitches) then
  664. rg.t_times:=rg.t_times*8;
  665. firstpass(left);
  666. if assigned(t1) then
  667. begin
  668. firstpass(t1);
  669. if codegenerror then
  670. exit;
  671. end;
  672. registers32:=t1.registers32;
  673. registersfpu:=t1.registersfpu;
  674. {$ifdef SUPPORT_MMX}
  675. registersmmx:=left.registersmmx;
  676. {$endif SUPPORT_MMX}
  677. if left.registers32>registers32 then
  678. registers32:=left.registers32;
  679. if left.registersfpu>registersfpu then
  680. registersfpu:=left.registersfpu;
  681. {$ifdef SUPPORT_MMX}
  682. if left.registersmmx>registersmmx then
  683. registersmmx:=left.registersmmx;
  684. {$endif SUPPORT_MMX}
  685. { process count var }
  686. firstpass(t2);
  687. if codegenerror then
  688. exit;
  689. if t2.registers32>registers32 then
  690. registers32:=t2.registers32;
  691. if t2.registersfpu>registersfpu then
  692. registersfpu:=t2.registersfpu;
  693. {$ifdef SUPPORT_MMX}
  694. if t2.registersmmx>registersmmx then
  695. registersmmx:=t2.registersmmx;
  696. {$endif SUPPORT_MMX}
  697. firstpass(right);
  698. {$ifdef loopvar_dont_mind}
  699. { Check count var, record fields are also allowed in tp7 }
  700. include(loopflags,lnf_dont_mind_loopvar_on_exit);
  701. hp:=t2;
  702. while (hp.nodetype=subscriptn) or
  703. ((hp.nodetype=vecn) and
  704. is_constintnode(tvecnode(hp).right)) do
  705. hp:=tunarynode(hp).left;
  706. if (hp.nodetype=loadn) and (Tloadnode(hp).symtableentry.typ=varsym) then
  707. loopvar_notid:=Tvarsym(Tloadnode(hp).symtableentry).
  708. register_notification([vn_onread,vn_onwrite],@loop_var_access);
  709. {$endif}
  710. if right.registers32>registers32 then
  711. registers32:=right.registers32;
  712. if right.registersfpu>registersfpu then
  713. registersfpu:=right.registersfpu;
  714. {$ifdef SUPPORT_MMX}
  715. if right.registersmmx>registersmmx then
  716. registersmmx:=right.registersmmx;
  717. {$endif SUPPORT_MMX}
  718. { we need at least one register for comparisons PM }
  719. if registers32=0 then
  720. inc(registers32);
  721. rg.t_times:=old_t_times;
  722. end;
  723. {*****************************************************************************
  724. TEXITNODE
  725. *****************************************************************************}
  726. constructor texitnode.create(l:tnode);
  727. begin
  728. inherited create(exitn,l);
  729. end;
  730. constructor texitnode.ppuload(t:tnodetype;ppufile:tcompilerppufile);
  731. begin
  732. inherited ppuload(t,ppufile);
  733. end;
  734. procedure texitnode.ppuwrite(ppufile:tcompilerppufile);
  735. begin
  736. inherited ppuwrite(ppufile);
  737. end;
  738. function texitnode.det_resulttype:tnode;
  739. begin
  740. result:=nil;
  741. if assigned(left) then
  742. begin
  743. { add assignment to funcretsym }
  744. inserttypeconv(left,current_procinfo.procdef.rettype);
  745. left:=cassignmentnode.create(
  746. cloadnode.create(current_procinfo.procdef.funcretsym,current_procinfo.procdef.funcretsym.owner),
  747. left);
  748. resulttypepass(left);
  749. set_varstate(left,true);
  750. end;
  751. resulttype:=voidtype;
  752. end;
  753. function texitnode.pass_1 : tnode;
  754. begin
  755. result:=nil;
  756. expectloc:=LOC_VOID;
  757. if assigned(left) then
  758. begin
  759. firstpass(left);
  760. if codegenerror then
  761. exit;
  762. registers32:=left.registers32;
  763. registersfpu:=left.registersfpu;
  764. {$ifdef SUPPORT_MMX}
  765. registersmmx:=left.registersmmx;
  766. {$endif SUPPORT_MMX}
  767. end;
  768. end;
  769. {*****************************************************************************
  770. TBREAKNODE
  771. *****************************************************************************}
  772. constructor tbreaknode.create;
  773. begin
  774. inherited create(breakn);
  775. end;
  776. function tbreaknode.det_resulttype:tnode;
  777. begin
  778. result:=nil;
  779. resulttype:=voidtype;
  780. end;
  781. function tbreaknode.pass_1 : tnode;
  782. begin
  783. result:=nil;
  784. expectloc:=LOC_VOID;
  785. end;
  786. {*****************************************************************************
  787. TCONTINUENODE
  788. *****************************************************************************}
  789. constructor tcontinuenode.create;
  790. begin
  791. inherited create(continuen);
  792. end;
  793. function tcontinuenode.det_resulttype:tnode;
  794. begin
  795. result:=nil;
  796. resulttype:=voidtype;
  797. end;
  798. function tcontinuenode.pass_1 : tnode;
  799. begin
  800. result:=nil;
  801. expectloc:=LOC_VOID;
  802. end;
  803. {*****************************************************************************
  804. TGOTONODE
  805. *****************************************************************************}
  806. constructor tgotonode.create(p : tlabelsym);
  807. begin
  808. inherited create(goton);
  809. exceptionblock:=aktexceptblock;
  810. labsym:=p;
  811. end;
  812. constructor tgotonode.ppuload(t:tnodetype;ppufile:tcompilerppufile);
  813. begin
  814. inherited ppuload(t,ppufile);
  815. ppufile.getderef(labsymderef);
  816. exceptionblock:=ppufile.getbyte;
  817. end;
  818. procedure tgotonode.ppuwrite(ppufile:tcompilerppufile);
  819. begin
  820. inherited ppuwrite(ppufile);
  821. ppufile.putderef(labsym,labsymderef);
  822. ppufile.putbyte(exceptionblock);
  823. end;
  824. procedure tgotonode.derefimpl;
  825. begin
  826. inherited derefimpl;
  827. labsym:=tlabelsym(labsymderef.resolve);
  828. end;
  829. function tgotonode.det_resulttype:tnode;
  830. begin
  831. result:=nil;
  832. resulttype:=voidtype;
  833. end;
  834. function tgotonode.pass_1 : tnode;
  835. begin
  836. result:=nil;
  837. expectloc:=LOC_VOID;
  838. { check if }
  839. if assigned(labsym) and
  840. assigned(labsym.code) and
  841. (exceptionblock<>tlabelnode(labsym.code).exceptionblock) then
  842. begin
  843. writeln('goto exceptblock: ',exceptionblock);
  844. writeln('label exceptblock: ',tlabelnode(labsym.code).exceptionblock);
  845. CGMessage(cg_e_goto_inout_of_exception_block);
  846. end;
  847. end;
  848. function tgotonode.getcopy : tnode;
  849. var
  850. p : tgotonode;
  851. begin
  852. p:=tgotonode(inherited getcopy);
  853. p.labsym:=labsym;
  854. p.exceptionblock:=exceptionblock;
  855. result:=p;
  856. end;
  857. function tgotonode.docompare(p: tnode): boolean;
  858. begin
  859. docompare := false;
  860. end;
  861. {*****************************************************************************
  862. TLABELNODE
  863. *****************************************************************************}
  864. constructor tlabelnode.createcase(p : tasmlabel;l:tnode);
  865. begin
  866. inherited create(labeln,l);
  867. { it shouldn't be possible to jump to case labels using goto }
  868. exceptionblock:=-1;
  869. labsym:=nil;
  870. labelnr:=p;
  871. end;
  872. constructor tlabelnode.create(p : tlabelsym;l:tnode);
  873. begin
  874. inherited create(labeln,l);
  875. exceptionblock:=aktexceptblock;
  876. labsym:=p;
  877. labelnr:=p.lab;
  878. { save the current labelnode in the labelsym }
  879. p.code:=self;
  880. end;
  881. constructor tlabelnode.ppuload(t:tnodetype;ppufile:tcompilerppufile);
  882. begin
  883. inherited ppuload(t,ppufile);
  884. ppufile.getderef(labsymderef);
  885. labelnr:=tasmlabel(ppufile.getasmsymbol);
  886. exceptionblock:=ppufile.getbyte;
  887. end;
  888. procedure tlabelnode.ppuwrite(ppufile:tcompilerppufile);
  889. begin
  890. inherited ppuwrite(ppufile);
  891. ppufile.putderef(labsym,labsymderef);
  892. ppufile.putasmsymbol(labelnr);
  893. ppufile.putbyte(exceptionblock);
  894. end;
  895. procedure tlabelnode.derefimpl;
  896. begin
  897. inherited derefimpl;
  898. labsym:=tlabelsym(labsymderef.resolve);
  899. objectlibrary.derefasmsymbol(tasmsymbol(labelnr));
  900. end;
  901. function tlabelnode.det_resulttype:tnode;
  902. begin
  903. result:=nil;
  904. { left could still be unassigned }
  905. if assigned(left) then
  906. resulttypepass(left);
  907. resulttype:=voidtype;
  908. end;
  909. function tlabelnode.pass_1 : tnode;
  910. begin
  911. result:=nil;
  912. expectloc:=LOC_VOID;
  913. if assigned(left) then
  914. begin
  915. firstpass(left);
  916. registers32:=left.registers32;
  917. registersfpu:=left.registersfpu;
  918. {$ifdef SUPPORT_MMX}
  919. registersmmx:=left.registersmmx;
  920. {$endif SUPPORT_MMX}
  921. end;
  922. end;
  923. function tlabelnode.getcopy : tnode;
  924. var
  925. p : tlabelnode;
  926. begin
  927. p:=tlabelnode(inherited getcopy);
  928. p.labelnr:=labelnr;
  929. p.exceptionblock:=exceptionblock;
  930. p.labsym:=labsym;
  931. result:=p;
  932. end;
  933. function tlabelnode.docompare(p: tnode): boolean;
  934. begin
  935. docompare := false;
  936. end;
  937. {*****************************************************************************
  938. TRAISENODE
  939. *****************************************************************************}
  940. constructor traisenode.create(l,taddr,tframe:tnode);
  941. begin
  942. inherited create(raisen,l,taddr);
  943. frametree:=tframe;
  944. end;
  945. constructor traisenode.ppuload(t:tnodetype;ppufile:tcompilerppufile);
  946. begin
  947. inherited ppuload(t,ppufile);
  948. frametree:=ppuloadnode(ppufile);
  949. end;
  950. procedure traisenode.ppuwrite(ppufile:tcompilerppufile);
  951. begin
  952. inherited ppuwrite(ppufile);
  953. ppuwritenode(ppufile,frametree);
  954. end;
  955. procedure traisenode.derefimpl;
  956. begin
  957. inherited derefimpl;
  958. if assigned(frametree) then
  959. frametree.derefimpl;
  960. end;
  961. function traisenode.getcopy : tnode;
  962. var
  963. n : traisenode;
  964. begin
  965. n:=traisenode(inherited getcopy);
  966. if assigned(frametree) then
  967. n.frametree:=frametree.getcopy
  968. else
  969. n.frametree:=nil;
  970. getcopy:=n;
  971. end;
  972. procedure traisenode.insertintolist(l : tnodelist);
  973. begin
  974. end;
  975. function traisenode.det_resulttype:tnode;
  976. begin
  977. result:=nil;
  978. resulttype:=voidtype;
  979. if assigned(left) then
  980. begin
  981. { first para must be a _class_ }
  982. resulttypepass(left);
  983. set_varstate(left,true);
  984. if codegenerror then
  985. exit;
  986. if not(is_class(left.resulttype.def)) then
  987. CGMessage(type_e_mismatch);
  988. { insert needed typeconvs for addr,frame }
  989. if assigned(right) then
  990. begin
  991. { addr }
  992. resulttypepass(right);
  993. inserttypeconv(right,voidpointertype);
  994. { frame }
  995. if assigned(frametree) then
  996. begin
  997. resulttypepass(frametree);
  998. inserttypeconv(frametree,voidpointertype);
  999. end;
  1000. end;
  1001. end;
  1002. end;
  1003. function traisenode.pass_1 : tnode;
  1004. begin
  1005. result:=nil;
  1006. include(current_procinfo.flags,pi_do_call);
  1007. expectloc:=LOC_VOID;
  1008. if assigned(left) then
  1009. begin
  1010. { first para must be a _class_ }
  1011. firstpass(left);
  1012. { insert needed typeconvs for addr,frame }
  1013. if assigned(right) then
  1014. begin
  1015. { addr }
  1016. firstpass(right);
  1017. { frame }
  1018. if assigned(frametree) then
  1019. firstpass(frametree);
  1020. end;
  1021. left_right_max;
  1022. end;
  1023. end;
  1024. function traisenode.docompare(p: tnode): boolean;
  1025. begin
  1026. docompare := false;
  1027. end;
  1028. {*****************************************************************************
  1029. TTRYEXCEPTNODE
  1030. *****************************************************************************}
  1031. constructor ttryexceptnode.create(l,r,_t1 : tnode);
  1032. begin
  1033. inherited create(tryexceptn,l,r,_t1,nil);
  1034. end;
  1035. function ttryexceptnode.det_resulttype:tnode;
  1036. begin
  1037. result:=nil;
  1038. resulttypepass(left);
  1039. { on statements }
  1040. if assigned(right) then
  1041. resulttypepass(right);
  1042. { else block }
  1043. if assigned(t1) then
  1044. resulttypepass(t1);
  1045. resulttype:=voidtype;
  1046. end;
  1047. function ttryexceptnode.pass_1 : tnode;
  1048. begin
  1049. result:=nil;
  1050. expectloc:=LOC_VOID;
  1051. firstpass(left);
  1052. { on statements }
  1053. if assigned(right) then
  1054. begin
  1055. firstpass(right);
  1056. registers32:=max(registers32,right.registers32);
  1057. registersfpu:=max(registersfpu,right.registersfpu);
  1058. {$ifdef SUPPORT_MMX}
  1059. registersmmx:=max(registersmmx,right.registersmmx);
  1060. {$endif SUPPORT_MMX}
  1061. end;
  1062. { else block }
  1063. if assigned(t1) then
  1064. begin
  1065. firstpass(t1);
  1066. registers32:=max(registers32,t1.registers32);
  1067. registersfpu:=max(registersfpu,t1.registersfpu);
  1068. {$ifdef SUPPORT_MMX}
  1069. registersmmx:=max(registersmmx,t1.registersmmx);
  1070. {$endif SUPPORT_MMX}
  1071. end;
  1072. end;
  1073. {*****************************************************************************
  1074. TTRYFINALLYNODE
  1075. *****************************************************************************}
  1076. constructor ttryfinallynode.create(l,r:tnode);
  1077. begin
  1078. inherited create(tryfinallyn,l,r,nil,nil);
  1079. implicitframe:=false;
  1080. end;
  1081. constructor ttryfinallynode.create_implicit(l,r,_t1:tnode);
  1082. begin
  1083. inherited create(tryfinallyn,l,r,_t1,nil);
  1084. implicitframe:=true;
  1085. end;
  1086. function ttryfinallynode.det_resulttype:tnode;
  1087. begin
  1088. result:=nil;
  1089. resulttype:=voidtype;
  1090. resulttypepass(left);
  1091. set_varstate(left,true);
  1092. resulttypepass(right);
  1093. set_varstate(right,true);
  1094. { special finally block only executed when there was an exception }
  1095. if assigned(t1) then
  1096. begin
  1097. resulttypepass(t1);
  1098. set_varstate(t1,true);
  1099. end;
  1100. end;
  1101. function ttryfinallynode.pass_1 : tnode;
  1102. begin
  1103. result:=nil;
  1104. expectloc:=LOC_VOID;
  1105. firstpass(left);
  1106. firstpass(right);
  1107. left_right_max;
  1108. if assigned(t1) then
  1109. begin
  1110. firstpass(t1);
  1111. registers32:=max(registers32,t1.registers32);
  1112. registersfpu:=max(registersfpu,t1.registersfpu);
  1113. {$ifdef SUPPORT_MMX}
  1114. registersmmx:=max(registersmmx,t1.registersmmx);
  1115. {$endif SUPPORT_MMX}
  1116. end;
  1117. end;
  1118. {*****************************************************************************
  1119. TONNODE
  1120. *****************************************************************************}
  1121. constructor tonnode.create(l,r:tnode);
  1122. begin
  1123. inherited create(onn,l,r);
  1124. exceptsymtable:=nil;
  1125. excepttype:=nil;
  1126. end;
  1127. destructor tonnode.destroy;
  1128. begin
  1129. if assigned(exceptsymtable) then
  1130. exceptsymtable.free;
  1131. inherited destroy;
  1132. end;
  1133. constructor tonnode.ppuload(t:tnodetype;ppufile:tcompilerppufile);
  1134. begin
  1135. inherited ppuload(t,ppufile);
  1136. exceptsymtable:=nil;
  1137. excepttype:=nil;
  1138. end;
  1139. function tonnode.getcopy : tnode;
  1140. var
  1141. n : tonnode;
  1142. begin
  1143. n:=tonnode(inherited getcopy);
  1144. n.exceptsymtable:=exceptsymtable;
  1145. n.excepttype:=excepttype;
  1146. result:=n;
  1147. end;
  1148. function tonnode.det_resulttype:tnode;
  1149. begin
  1150. result:=nil;
  1151. resulttype:=voidtype;
  1152. if not(is_class(excepttype)) then
  1153. CGMessage(type_e_mismatch);
  1154. if assigned(left) then
  1155. resulttypepass(left);
  1156. if assigned(right) then
  1157. resulttypepass(right);
  1158. end;
  1159. function tonnode.pass_1 : tnode;
  1160. begin
  1161. result:=nil;
  1162. expectloc:=LOC_VOID;
  1163. registers32:=0;
  1164. registersfpu:=0;
  1165. {$ifdef SUPPORT_MMX}
  1166. registersmmx:=0;
  1167. {$endif SUPPORT_MMX}
  1168. if assigned(left) then
  1169. begin
  1170. firstpass(left);
  1171. registers32:=left.registers32;
  1172. registersfpu:=left.registersfpu;
  1173. {$ifdef SUPPORT_MMX}
  1174. registersmmx:=left.registersmmx;
  1175. {$endif SUPPORT_MMX}
  1176. end;
  1177. if assigned(right) then
  1178. begin
  1179. firstpass(right);
  1180. registers32:=max(registers32,right.registers32);
  1181. registersfpu:=max(registersfpu,right.registersfpu);
  1182. {$ifdef SUPPORT_MMX}
  1183. registersmmx:=max(registersmmx,right.registersmmx);
  1184. {$endif SUPPORT_MMX}
  1185. end;
  1186. end;
  1187. function tonnode.docompare(p: tnode): boolean;
  1188. begin
  1189. docompare := false;
  1190. end;
  1191. begin
  1192. cwhilerepeatnode:=twhilerepeatnode;
  1193. cifnode:=tifnode;
  1194. cfornode:=tfornode;
  1195. cexitnode:=texitnode;
  1196. cgotonode:=tgotonode;
  1197. clabelnode:=tlabelnode;
  1198. craisenode:=traisenode;
  1199. ctryexceptnode:=ttryexceptnode;
  1200. ctryfinallynode:=ttryfinallynode;
  1201. connode:=tonnode;
  1202. end.
  1203. {
  1204. $Log$
  1205. Revision 1.80 2003-10-01 20:34:48 peter
  1206. * procinfo unit contains tprocinfo
  1207. * cginfo renamed to cgbase
  1208. * moved cgmessage to verbose
  1209. * fixed ppc and sparc compiles
  1210. Revision 1.79 2003/07/06 15:31:20 daniel
  1211. * Fixed register allocator. *Lots* of fixes.
  1212. Revision 1.78 2003/06/13 21:19:30 peter
  1213. * current_procdef removed, use current_procinfo.procdef instead
  1214. Revision 1.77 2003/06/07 20:26:32 peter
  1215. * re-resolving added instead of reloading from ppu
  1216. * tderef object added to store deref info for resolving
  1217. Revision 1.76 2003/06/07 18:57:04 jonas
  1218. + added freeintparaloc
  1219. * ppc get/freeintparaloc now check whether the parameter regs are
  1220. properly allocated/deallocated (and get an extra list para)
  1221. * ppc a_call_* now internalerrors if pi_do_call is not yet set
  1222. * fixed lot of missing pi_do_call's
  1223. Revision 1.75 2003/05/26 21:17:17 peter
  1224. * procinlinenode removed
  1225. * aktexit2label removed, fast exit removed
  1226. + tcallnode.inlined_pass_2 added
  1227. Revision 1.74 2003/05/13 19:14:41 peter
  1228. * failn removed
  1229. * inherited result code check moven to pexpr
  1230. Revision 1.73 2003/05/11 21:37:03 peter
  1231. * moved implicit exception frame from ncgutil to psub
  1232. * constructor/destructor helpers moved from cobj/ncgutil to psub
  1233. Revision 1.72 2003/05/01 07:59:42 florian
  1234. * introduced defaultordconsttype to decribe the default size of ordinal constants
  1235. on 64 bit CPUs it's equal to cs64bitdef while on 32 bit CPUs it's equal to s32bitdef
  1236. + added defines CPU32 and CPU64 for 32 bit and 64 bit CPUs
  1237. * int64s/qwords are allowed as for loop counter on 64 bit CPUs
  1238. Revision 1.71 2003/04/27 11:21:33 peter
  1239. * aktprocdef renamed to current_procinfo.procdef
  1240. * procinfo renamed to current_procinfo
  1241. * procinfo will now be stored in current_module so it can be
  1242. cleaned up properly
  1243. * gen_main_procsym changed to create_main_proc and release_main_proc
  1244. to also generate a tprocinfo structure
  1245. * fixed unit implicit initfinal
  1246. Revision 1.70 2003/04/27 07:29:50 peter
  1247. * current_procinfo.procdef cleanup, current_procdef is now always nil when parsing
  1248. a new procdef declaration
  1249. * aktprocsym removed
  1250. * lexlevel removed, use symtable.symtablelevel instead
  1251. * implicit init/final code uses the normal genentry/genexit
  1252. * funcret state checking updated for new funcret handling
  1253. Revision 1.69 2003/04/26 00:28:41 peter
  1254. * removed load_funcret
  1255. Revision 1.68 2003/04/25 20:59:33 peter
  1256. * removed funcretn,funcretsym, function result is now in varsym
  1257. and aliases for result and function name are added using absolutesym
  1258. * vs_hidden parameter for funcret passed in parameter
  1259. * vs_hidden fixes
  1260. * writenode changed to printnode and released from extdebug
  1261. * -vp option added to generate a tree.log with the nodetree
  1262. * nicer printnode for statements, callnode
  1263. Revision 1.67 2003/04/25 08:25:26 daniel
  1264. * Ifdefs around a lot of calls to cleartempgen
  1265. * Fixed registers that are allocated but not freed in several nodes
  1266. * Tweak to register allocator to cause less spills
  1267. * 8-bit registers now interfere with esi,edi and ebp
  1268. Compiler can now compile rtl successfully when using new register
  1269. allocator
  1270. Revision 1.66 2003/04/22 23:50:23 peter
  1271. * firstpass uses expectloc
  1272. * checks if there are differences between the expectloc and
  1273. location.loc from secondpass in EXTDEBUG
  1274. Revision 1.65 2003/03/20 15:54:46 peter
  1275. * don't allow var and out parameters as for loop counter
  1276. Revision 1.64 2003/01/09 21:52:37 peter
  1277. * merged some verbosity options.
  1278. * V_LineInfo is a verbosity flag to include line info
  1279. Revision 1.63 2003/01/04 08:08:47 daniel
  1280. * Readded missing variable
  1281. Revision 1.62 2003/01/03 17:16:57 peter
  1282. * fixed warning about unset funcret
  1283. Revision 1.61 2003/01/03 12:15:56 daniel
  1284. * Removed ifdefs around notifications
  1285. ifdefs around for loop optimizations remain
  1286. Revision 1.60 2002/12/31 09:55:58 daniel
  1287. + Notification implementation complete
  1288. + Add for loop code optimization using notifications
  1289. results in 1.5-1.9% speed improvement in nestloop benchmark
  1290. Optimization incomplete, compiler does not cycle yet with
  1291. notifications enabled.
  1292. Revision 1.59 2002/12/30 22:44:53 daniel
  1293. * Some work on notifications
  1294. Revision 1.58 2002/12/27 15:25:40 peter
  1295. * do not allow threadvar as loop counter
  1296. Revision 1.57 2002/11/28 11:17:02 florian
  1297. * loop node flags from node flags splitted
  1298. Revision 1.56 2002/11/25 17:43:18 peter
  1299. * splitted defbase in defutil,symutil,defcmp
  1300. * merged isconvertable and is_equal into compare_defs(_ext)
  1301. * made operator search faster by walking the list only once
  1302. Revision 1.55 2002/11/18 17:31:56 peter
  1303. * pass proccalloption to ret_in_xxx and push_xxx functions
  1304. Revision 1.54 2002/10/20 15:31:49 peter
  1305. * set funcret state for exit(0)
  1306. Revision 1.53 2002/10/05 12:43:25 carl
  1307. * fixes for Delphi 6 compilation
  1308. (warning : Some features do not work under Delphi)
  1309. Revision 1.52 2002/09/07 15:25:03 peter
  1310. * old logs removed and tabs fixed
  1311. Revision 1.51 2002/09/07 12:16:04 carl
  1312. * second part bug report 1996 fix, testrange in cordconstnode
  1313. only called if option is set (also make parsing a tiny faster)
  1314. Revision 1.50 2002/09/01 18:47:00 peter
  1315. * assignn check in exitnode changed to use a separate boolean as the
  1316. assignn can be changed to a calln
  1317. Revision 1.49 2002/09/01 08:01:16 daniel
  1318. * Removed sets from Tcallnode.det_resulttype
  1319. + Added read/write notifications of variables. These will be usefull
  1320. for providing information for several optimizations. For example
  1321. the value of the loop variable of a for loop does matter is the
  1322. variable is read after the for loop, but if it's no longer used
  1323. or written, it doesn't matter and this can be used to optimize
  1324. the loop code generation.
  1325. Revision 1.48 2002/08/22 15:15:20 daniel
  1326. * Fixed the detection wether the first check of a for loop can be skipped
  1327. Revision 1.47 2002/08/19 19:36:43 peter
  1328. * More fixes for cross unit inlining, all tnodes are now implemented
  1329. * Moved pocall_internconst to po_internconst because it is not a
  1330. calling type at all and it conflicted when inlining of these small
  1331. functions was requested
  1332. Revision 1.46 2002/08/17 22:09:46 florian
  1333. * result type handling in tcgcal.pass_2 overhauled
  1334. * better tnode.dowrite
  1335. * some ppc stuff fixed
  1336. Revision 1.45 2002/08/17 09:23:37 florian
  1337. * first part of current_procinfo rewrite
  1338. Revision 1.44 2002/07/21 06:58:49 daniel
  1339. * Changed booleans into flags
  1340. Revision 1.43 2002/07/20 11:57:54 florian
  1341. * types.pas renamed to defbase.pas because D6 contains a types
  1342. unit so this would conflicts if D6 programms are compiled
  1343. + Willamette/SSE2 instructions to assembler added
  1344. Revision 1.42 2002/07/20 11:18:18 daniel
  1345. * Small mistake fixed; the skip test was done before we know the for node
  1346. is correct.
  1347. Revision 1.40 2002/07/20 08:19:31 daniel
  1348. * State tracker automatically changes while loops into repeat loops
  1349. Revision 1.39 2002/07/19 12:55:27 daniel
  1350. * Further developed state tracking in whilerepeatn
  1351. Revision 1.38 2002/07/19 11:41:35 daniel
  1352. * State tracker work
  1353. * The whilen and repeatn are now completely unified into whilerepeatn. This
  1354. allows the state tracker to change while nodes automatically into
  1355. repeat nodes.
  1356. * Resulttypepass improvements to the notn. 'not not a' is optimized away and
  1357. 'not(a>b)' is optimized into 'a<=b'.
  1358. * Resulttypepass improvements to the whilerepeatn. 'while not a' is optimized
  1359. by removing the notn and later switchting the true and falselabels. The
  1360. same is done with 'repeat until not a'.
  1361. Revision 1.37 2002/07/16 13:57:02 florian
  1362. * raise takes now a void pointer as at and frame address
  1363. instead of a longint
  1364. Revision 1.36 2002/07/15 18:03:15 florian
  1365. * readded removed changes
  1366. Revision 1.35 2002/07/14 18:00:44 daniel
  1367. + Added the beginning of a state tracker. This will track the values of
  1368. variables through procedures and optimize things away.
  1369. Revision 1.34 2002/07/11 14:41:28 florian
  1370. * start of the new generic parameter handling
  1371. Revision 1.33 2002/07/01 18:46:23 peter
  1372. * internal linker
  1373. * reorganized aasm layer
  1374. Revision 1.32 2002/05/18 13:34:10 peter
  1375. * readded missing revisions
  1376. Revision 1.31 2002/05/16 19:46:38 carl
  1377. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  1378. + try to fix temp allocation (still in ifdef)
  1379. + generic constructor calls
  1380. + start of tassembler / tmodulebase class cleanup
  1381. }