nflw.pas 44 KB

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