nflw.pas 51 KB

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