nflw.pas 43 KB

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