nbas.pas 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835
  1. {
  2. $Id$
  3. Copyright (c) 2000-2002 by Florian Klaempfl
  4. This unit implements some basic nodes
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************
  17. }
  18. unit nbas;
  19. {$i fpcdefs.inc}
  20. interface
  21. uses
  22. cpubase,
  23. aasmbase,aasmtai,aasmcpu,
  24. node,
  25. symtype,symppu;
  26. type
  27. tnothingnode = class(tnode)
  28. constructor create;virtual;
  29. function pass_1 : tnode;override;
  30. function det_resulttype:tnode;override;
  31. end;
  32. tnothingnodeclass = class of tnothingnode;
  33. terrornode = class(tnode)
  34. constructor create;virtual;
  35. function pass_1 : tnode;override;
  36. function det_resulttype:tnode;override;
  37. end;
  38. terrornodeclass = class of terrornode;
  39. tasmnode = class(tnode)
  40. p_asm : taasmoutput;
  41. constructor create(p : taasmoutput);virtual;
  42. destructor destroy;override;
  43. constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override;
  44. procedure ppuwrite(ppufile:tcompilerppufile);override;
  45. procedure derefimpl;override;
  46. function getcopy : tnode;override;
  47. function pass_1 : tnode;override;
  48. function det_resulttype:tnode;override;
  49. function docompare(p: tnode): boolean; override;
  50. end;
  51. tasmnodeclass = class of tasmnode;
  52. tstatementnode = class(tbinarynode)
  53. constructor create(l,r : tnode);virtual;
  54. function pass_1 : tnode;override;
  55. function det_resulttype:tnode;override;
  56. {$ifdef extdebug}
  57. procedure _dowrite;override;
  58. {$endif extdebug}
  59. end;
  60. tstatementnodeclass = class of tstatementnode;
  61. tblocknode = class(tunarynode)
  62. constructor create(l : tnode);virtual;
  63. function pass_1 : tnode;override;
  64. function det_resulttype:tnode;override;
  65. {$ifdef state_tracking}
  66. function track_state_pass(exec_known:boolean):boolean;override;
  67. {$endif state_tracking}
  68. end;
  69. tblocknodeclass = class of tblocknode;
  70. { to allow access to the location by temp references even after the temp has }
  71. { already been disposed and to make sure the coherency between temps and }
  72. { temp references is kept after a getcopy }
  73. ptempinfo = ^ttempinfo;
  74. ttempinfo = record
  75. { set to the copy of a tempcreate pnode (if it gets copied) so that the }
  76. { refs and deletenode can hook to this copy once they get copied too }
  77. hookoncopy : ptempinfo;
  78. ref : treference;
  79. restype : ttype;
  80. valid : boolean;
  81. end;
  82. { a node which will create a (non)persistent temp of a given type with a given }
  83. { size (the size is separate to allow creating "void" temps with a custom size) }
  84. ttempcreatenode = class(tnode)
  85. size: longint;
  86. tempinfo: ptempinfo;
  87. persistent: boolean;
  88. { * persistent temps are used in manually written code where the temp }
  89. { be usable among different statements and where you can manually say }
  90. { when the temp has to be freed (using a ttempdeletenode) }
  91. { * non-persistent temps are mostly used in typeconversion helpers, }
  92. { where the node that receives the temp becomes responsible for }
  93. { freeing it. In this last case, you should use only one reference }
  94. { to it and *not* generate a ttempdeletenode }
  95. constructor create(const _restype: ttype; _size: longint; _persistent: boolean); virtual;
  96. function getcopy: tnode; override;
  97. function pass_1 : tnode; override;
  98. function det_resulttype: tnode; override;
  99. function docompare(p: tnode): boolean; override;
  100. end;
  101. ttempcreatenodeclass = class of ttempcreatenode;
  102. { a node which is a reference to a certain temp }
  103. ttemprefnode = class(tnode)
  104. constructor create(const temp: ttempcreatenode); virtual;
  105. constructor create_offset(const temp: ttempcreatenode;aoffset:longint);
  106. function getcopy: tnode; override;
  107. function pass_1 : tnode; override;
  108. function det_resulttype : tnode; override;
  109. function docompare(p: tnode): boolean; override;
  110. protected
  111. tempinfo: ptempinfo;
  112. offset : longint;
  113. end;
  114. ttemprefnodeclass = class of ttemprefnode;
  115. { a node which removes a temp }
  116. ttempdeletenode = class(tnode)
  117. constructor create(const temp: ttempcreatenode);
  118. { this will convert the persistant temp to a normal temp
  119. for returning to the other nodes }
  120. constructor create_normal_temp(const temp: ttempcreatenode);
  121. function getcopy: tnode; override;
  122. function pass_1: tnode; override;
  123. function det_resulttype: tnode; override;
  124. function docompare(p: tnode): boolean; override;
  125. destructor destroy; override;
  126. protected
  127. tempinfo: ptempinfo;
  128. release_to_normal : boolean;
  129. end;
  130. ttempdeletenodeclass = class of ttempdeletenode;
  131. var
  132. cnothingnode : tnothingnodeclass;
  133. cerrornode : terrornodeclass;
  134. casmnode : tasmnodeclass;
  135. cstatementnode : tstatementnodeclass;
  136. cblocknode : tblocknodeclass;
  137. ctempcreatenode : ttempcreatenodeclass;
  138. ctemprefnode : ttemprefnodeclass;
  139. ctempdeletenode : ttempdeletenodeclass;
  140. { Create a blocknode and statement node for multiple statements
  141. generated internally by the parser }
  142. function internalstatements(var laststatement:tstatementnode):tblocknode;
  143. procedure addstatement(var laststatement:tstatementnode;n:tnode);
  144. implementation
  145. uses
  146. cutils,
  147. verbose,globals,globtype,systems,
  148. symconst,symdef,symsym,defbase,
  149. pass_1,
  150. nld,ncal,nflw,rgobj,cgbase
  151. ;
  152. {*****************************************************************************
  153. Helpers
  154. *****************************************************************************}
  155. function internalstatements(var laststatement:tstatementnode):tblocknode;
  156. begin
  157. { create dummy initial statement }
  158. laststatement := cstatementnode.create(nil,cnothingnode.create);
  159. internalstatements := cblocknode.create(laststatement);
  160. end;
  161. procedure addstatement(var laststatement:tstatementnode;n:tnode);
  162. begin
  163. if assigned(laststatement.left) then
  164. internalerror(200204201);
  165. laststatement.left:=cstatementnode.create(nil,n);
  166. laststatement:=tstatementnode(laststatement.left);
  167. end;
  168. {*****************************************************************************
  169. TFIRSTNOTHING
  170. *****************************************************************************}
  171. constructor tnothingnode.create;
  172. begin
  173. inherited create(nothingn);
  174. end;
  175. function tnothingnode.det_resulttype:tnode;
  176. begin
  177. result:=nil;
  178. resulttype:=voidtype;
  179. end;
  180. function tnothingnode.pass_1 : tnode;
  181. begin
  182. result:=nil;
  183. end;
  184. {*****************************************************************************
  185. TFIRSTERROR
  186. *****************************************************************************}
  187. constructor terrornode.create;
  188. begin
  189. inherited create(errorn);
  190. end;
  191. function terrornode.det_resulttype:tnode;
  192. begin
  193. result:=nil;
  194. include(flags,nf_error);
  195. codegenerror:=true;
  196. resulttype:=generrortype;
  197. end;
  198. function terrornode.pass_1 : tnode;
  199. begin
  200. result:=nil;
  201. codegenerror:=true;
  202. end;
  203. {*****************************************************************************
  204. TSTATEMENTNODE
  205. *****************************************************************************}
  206. constructor tstatementnode.create(l,r : tnode);
  207. begin
  208. inherited create(statementn,l,r);
  209. end;
  210. function tstatementnode.det_resulttype:tnode;
  211. begin
  212. result:=nil;
  213. resulttype:=voidtype;
  214. { right is the statement itself calln assignn or a complex one }
  215. resulttypepass(right);
  216. if (not (cs_extsyntax in aktmoduleswitches)) and
  217. assigned(right.resulttype.def) and
  218. not((right.nodetype=calln) and
  219. (tcallnode(right).procdefinition.proctypeoption=potype_constructor)) and
  220. not(is_void(right.resulttype.def)) then
  221. CGMessage(cg_e_illegal_expression);
  222. if codegenerror then
  223. exit;
  224. { left is the next in the list }
  225. resulttypepass(left);
  226. if codegenerror then
  227. exit;
  228. end;
  229. function tstatementnode.pass_1 : tnode;
  230. begin
  231. result:=nil;
  232. { no temps over several statements }
  233. rg.cleartempgen;
  234. { right is the statement itself calln assignn or a complex one }
  235. firstpass(right);
  236. if codegenerror then
  237. exit;
  238. location.loc:=right.location.loc;
  239. registers32:=right.registers32;
  240. registersfpu:=right.registersfpu;
  241. {$ifdef SUPPORT_MMX}
  242. registersmmx:=right.registersmmx;
  243. {$endif SUPPORT_MMX}
  244. { left is the next in the list }
  245. firstpass(left);
  246. if codegenerror then
  247. exit;
  248. if right.registers32>registers32 then
  249. registers32:=right.registers32;
  250. if right.registersfpu>registersfpu then
  251. registersfpu:=right.registersfpu;
  252. {$ifdef SUPPORT_MMX}
  253. if right.registersmmx>registersmmx then
  254. registersmmx:=right.registersmmx;
  255. {$endif}
  256. end;
  257. {$ifdef extdebug}
  258. procedure tstatementnode._dowrite;
  259. begin
  260. { can't use inherited dowrite, because that will use the
  261. binary which we don't want for statements }
  262. dowritenodetype;
  263. writeln(',');
  264. { write the statement }
  265. writenodeindention:=writenodeindention+' ';
  266. writenode(right);
  267. writeln(')');
  268. delete(writenodeindention,1,4);
  269. { go on with the next statement }
  270. writenode(left);
  271. end;
  272. {$endif}
  273. {*****************************************************************************
  274. TBLOCKNODE
  275. *****************************************************************************}
  276. constructor tblocknode.create(l : tnode);
  277. begin
  278. inherited create(blockn,l);
  279. end;
  280. function tblocknode.det_resulttype:tnode;
  281. var
  282. hp : tstatementnode;
  283. begin
  284. result:=nil;
  285. resulttype:=voidtype;
  286. hp:=tstatementnode(left);
  287. while assigned(hp) do
  288. begin
  289. if assigned(hp.right) then
  290. begin
  291. codegenerror:=false;
  292. resulttypepass(hp.right);
  293. if (not (cs_extsyntax in aktmoduleswitches)) and
  294. assigned(hp.right.resulttype.def) and
  295. not((hp.right.nodetype=calln) and
  296. (tcallnode(hp.right).procdefinition.proctypeoption=potype_constructor)) and
  297. not(is_void(hp.right.resulttype.def)) then
  298. CGMessage(cg_e_illegal_expression);
  299. { the resulttype of the block is the last type that is
  300. returned. Normally this is a voidtype. But when the
  301. compiler inserts a block of multiple statements then the
  302. last entry can return a value }
  303. resulttype:=hp.right.resulttype;
  304. end;
  305. hp:=tstatementnode(hp.left);
  306. end;
  307. end;
  308. function tblocknode.pass_1 : tnode;
  309. var
  310. hp : tstatementnode;
  311. count : longint;
  312. begin
  313. result:=nil;
  314. count:=0;
  315. hp:=tstatementnode(left);
  316. while assigned(hp) do
  317. begin
  318. if cs_regalloc in aktglobalswitches then
  319. begin
  320. { node transformations }
  321. { concat function result to exit }
  322. { this is wrong for string or other complex
  323. result types !!! }
  324. if {ret_in_acc(aktprocdef.rettype.def) and }
  325. (is_ordinal(aktprocdef.rettype.def) or
  326. is_smallset(aktprocdef.rettype.def)) and
  327. assigned(hp.left) and
  328. assigned(tstatementnode(hp.left).right) and
  329. (tstatementnode(hp.left).right.nodetype=exitn) and
  330. (hp.right.nodetype=assignn) and
  331. { !!!! this tbinarynode should be tassignmentnode }
  332. (tbinarynode(hp.right).left.nodetype=funcretn) then
  333. begin
  334. if assigned(texitnode(tstatementnode(hp.left).right).left) then
  335. CGMessage(cg_n_inefficient_code)
  336. else
  337. begin
  338. texitnode(tstatementnode(hp.left).right).left:=tassignmentnode(hp.right).right;
  339. tassignmentnode(hp.right).right:=nil;
  340. hp.right.free;
  341. hp.right:=nil;
  342. end;
  343. end
  344. { warning if unreachable code occurs and elimate this }
  345. else if (hp.right.nodetype in
  346. [exitn,breakn,continuen,goton]) and
  347. { statement node (JM) }
  348. assigned(hp.left) and
  349. { kind of statement! (JM) }
  350. assigned(tstatementnode(hp.left).right) and
  351. (tstatementnode(hp.left).right.nodetype<>labeln) then
  352. begin
  353. { use correct line number }
  354. aktfilepos:=hp.left.fileinfo;
  355. hp.left.free;
  356. hp.left:=nil;
  357. CGMessage(cg_w_unreachable_code);
  358. { old lines }
  359. aktfilepos:=hp.right.fileinfo;
  360. end;
  361. end;
  362. if assigned(hp.right) then
  363. begin
  364. rg.cleartempgen;
  365. codegenerror:=false;
  366. firstpass(hp.right);
  367. hp.registers32:=hp.right.registers32;
  368. hp.registersfpu:=hp.right.registersfpu;
  369. {$ifdef SUPPORT_MMX}
  370. hp.registersmmx:=hp.right.registersmmx;
  371. {$endif SUPPORT_MMX}
  372. end
  373. else
  374. hp.registers32:=0;
  375. if hp.registers32>registers32 then
  376. registers32:=hp.registers32;
  377. if hp.registersfpu>registersfpu then
  378. registersfpu:=hp.registersfpu;
  379. {$ifdef SUPPORT_MMX}
  380. if hp.registersmmx>registersmmx then
  381. registersmmx:=hp.registersmmx;
  382. {$endif}
  383. location.loc:=hp.location.loc;
  384. inc(count);
  385. hp:=tstatementnode(hp.left);
  386. end;
  387. end;
  388. {$ifdef state_tracking}
  389. function Tblocknode.track_state_pass(exec_known:boolean):boolean;
  390. var hp:Tstatementnode;
  391. begin
  392. track_state_pass:=false;
  393. hp:=Tstatementnode(left);
  394. while assigned(hp) do
  395. begin
  396. if hp.right.track_state_pass(exec_known) then
  397. track_state_pass:=true;
  398. hp:=Tstatementnode(hp.left);
  399. end;
  400. end;
  401. {$endif state_tracking}
  402. {*****************************************************************************
  403. TASMNODE
  404. *****************************************************************************}
  405. constructor tasmnode.create(p : taasmoutput);
  406. begin
  407. inherited create(asmn);
  408. p_asm:=p;
  409. end;
  410. destructor tasmnode.destroy;
  411. begin
  412. if assigned(p_asm) then
  413. p_asm.free;
  414. inherited destroy;
  415. end;
  416. constructor tasmnode.ppuload(t:tnodetype;ppufile:tcompilerppufile);
  417. var
  418. hp : tai;
  419. begin
  420. inherited ppuload(t,ppufile);
  421. p_asm:=taasmoutput.create;
  422. repeat
  423. hp:=ppuloadai(ppufile);
  424. if hp=nil then
  425. break;
  426. p_asm.concat(hp);
  427. until false;
  428. end;
  429. procedure tasmnode.ppuwrite(ppufile:tcompilerppufile);
  430. var
  431. hp : tai;
  432. begin
  433. inherited ppuwrite(ppufile);
  434. hp:=tai(p_asm.first);
  435. while assigned(hp) do
  436. begin
  437. ppuwriteai(ppufile,hp);
  438. hp:=tai(hp.next);
  439. end;
  440. { end is marked by a nil }
  441. ppuwriteai(ppufile,nil);
  442. end;
  443. procedure tasmnode.derefimpl;
  444. var
  445. hp : tai;
  446. begin
  447. inherited derefimpl;
  448. hp:=tai(p_asm.first);
  449. while assigned(hp) do
  450. begin
  451. hp.derefimpl;
  452. hp:=tai(hp.next);
  453. end;
  454. end;
  455. function tasmnode.getcopy: tnode;
  456. var
  457. n: tasmnode;
  458. begin
  459. n := tasmnode(inherited getcopy);
  460. if assigned(p_asm) then
  461. begin
  462. n.p_asm:=taasmoutput.create;
  463. n.p_asm.concatlistcopy(p_asm);
  464. end
  465. else n.p_asm := nil;
  466. getcopy := n;
  467. end;
  468. function tasmnode.det_resulttype:tnode;
  469. begin
  470. result:=nil;
  471. resulttype:=voidtype;
  472. end;
  473. function tasmnode.pass_1 : tnode;
  474. begin
  475. result:=nil;
  476. procinfo.flags:=procinfo.flags or pi_uses_asm;
  477. end;
  478. function tasmnode.docompare(p: tnode): boolean;
  479. begin
  480. { comparing of asmlists is not implemented (JM) }
  481. docompare := false;
  482. end;
  483. {*****************************************************************************
  484. TEMPCREATENODE
  485. *****************************************************************************}
  486. constructor ttempcreatenode.create(const _restype: ttype; _size: longint; _persistent: boolean);
  487. begin
  488. inherited create(tempcreaten);
  489. size := _size;
  490. new(tempinfo);
  491. fillchar(tempinfo^,sizeof(tempinfo^),0);
  492. tempinfo^.restype := _restype;
  493. persistent := _persistent;
  494. end;
  495. function ttempcreatenode.getcopy: tnode;
  496. var
  497. n: ttempcreatenode;
  498. begin
  499. n := ttempcreatenode(inherited getcopy);
  500. n.size := size;
  501. new(n.tempinfo);
  502. fillchar(n.tempinfo^,sizeof(n.tempinfo^),0);
  503. n.tempinfo^.restype := tempinfo^.restype;
  504. { signal the temprefs that the temp they point to has been copied, }
  505. { so that if the refs get copied as well, they can hook themselves }
  506. { to the copy of the temp }
  507. tempinfo^.hookoncopy := n.tempinfo;
  508. result := n;
  509. end;
  510. function ttempcreatenode.pass_1 : tnode;
  511. begin
  512. result := nil;
  513. end;
  514. function ttempcreatenode.det_resulttype: tnode;
  515. begin
  516. result := nil;
  517. { a tempcreatenode doesn't have a resulttype, only temprefnodes do }
  518. resulttype := voidtype;
  519. end;
  520. function ttempcreatenode.docompare(p: tnode): boolean;
  521. begin
  522. result :=
  523. inherited docompare(p) and
  524. (ttempcreatenode(p).size = size) and
  525. is_equal(ttempcreatenode(p).tempinfo^.restype.def,tempinfo^.restype.def);
  526. end;
  527. {*****************************************************************************
  528. TEMPREFNODE
  529. *****************************************************************************}
  530. constructor ttemprefnode.create(const temp: ttempcreatenode);
  531. begin
  532. inherited create(temprefn);
  533. tempinfo := temp.tempinfo;
  534. offset:=0;
  535. end;
  536. constructor ttemprefnode.create_offset(const temp: ttempcreatenode;aoffset:longint);
  537. begin
  538. self.create(temp);
  539. offset := aoffset;
  540. end;
  541. function ttemprefnode.getcopy: tnode;
  542. var
  543. n: ttemprefnode;
  544. begin
  545. n := ttemprefnode(inherited getcopy);
  546. if assigned(tempinfo^.hookoncopy) then
  547. { if the temp has been copied, assume it becomes a new }
  548. { temp which has to be hooked by the copied reference }
  549. begin
  550. { hook the ref to the copied temp }
  551. n.tempinfo := tempinfo^.hookoncopy;
  552. end
  553. else
  554. { if the temp we refer to hasn't been copied, assume }
  555. { we're just a new reference to that temp }
  556. begin
  557. n.tempinfo := tempinfo;
  558. end;
  559. result := n;
  560. end;
  561. function ttemprefnode.pass_1 : tnode;
  562. begin
  563. location.loc:=LOC_REFERENCE;
  564. result := nil;
  565. end;
  566. function ttemprefnode.det_resulttype: tnode;
  567. begin
  568. { check if the temp is already resulttype passed }
  569. if not assigned(tempinfo^.restype.def) then
  570. internalerror(200108233);
  571. result := nil;
  572. resulttype := tempinfo^.restype;
  573. end;
  574. function ttemprefnode.docompare(p: tnode): boolean;
  575. begin
  576. result :=
  577. inherited docompare(p) and
  578. (ttemprefnode(p).tempinfo = tempinfo);
  579. end;
  580. {*****************************************************************************
  581. TEMPDELETENODE
  582. *****************************************************************************}
  583. constructor ttempdeletenode.create(const temp: ttempcreatenode);
  584. begin
  585. inherited create(temprefn);
  586. tempinfo := temp.tempinfo;
  587. release_to_normal := false;
  588. if not temp.persistent then
  589. internalerror(200204211);
  590. end;
  591. constructor ttempdeletenode.create_normal_temp(const temp: ttempcreatenode);
  592. begin
  593. inherited create(tempdeleten);
  594. tempinfo := temp.tempinfo;
  595. release_to_normal := true;
  596. end;
  597. function ttempdeletenode.getcopy: tnode;
  598. var
  599. n: ttempdeletenode;
  600. begin
  601. n := ttempdeletenode(inherited getcopy);
  602. if assigned(tempinfo^.hookoncopy) then
  603. { if the temp has been copied, assume it becomes a new }
  604. { temp which has to be hooked by the copied deletenode }
  605. begin
  606. { hook the tempdeletenode to the copied temp }
  607. n.tempinfo := tempinfo^.hookoncopy;
  608. end
  609. else
  610. { if the temp we refer to hasn't been copied, we have a }
  611. { problem since that means we now have two delete nodes }
  612. { for one temp }
  613. internalerror(200108234);
  614. result := n;
  615. end;
  616. function ttempdeletenode.pass_1 : tnode;
  617. begin
  618. result := nil;
  619. end;
  620. function ttempdeletenode.det_resulttype: tnode;
  621. begin
  622. result := nil;
  623. resulttype := voidtype;
  624. end;
  625. function ttempdeletenode.docompare(p: tnode): boolean;
  626. begin
  627. result :=
  628. inherited docompare(p) and
  629. (ttemprefnode(p).tempinfo = tempinfo);
  630. end;
  631. destructor ttempdeletenode.destroy;
  632. begin
  633. dispose(tempinfo);
  634. end;
  635. begin
  636. cnothingnode:=tnothingnode;
  637. cerrornode:=terrornode;
  638. casmnode:=tasmnode;
  639. cstatementnode:=tstatementnode;
  640. cblocknode:=tblocknode;
  641. ctempcreatenode:=ttempcreatenode;
  642. ctemprefnode:=ttemprefnode;
  643. ctempdeletenode:=ttempdeletenode;
  644. end.
  645. {
  646. $Log$
  647. Revision 1.34 2002-08-18 20:06:23 peter
  648. * inlining is now also allowed in interface
  649. * renamed write/load to ppuwrite/ppuload
  650. * tnode storing in ppu
  651. * nld,ncon,nbas are already updated for storing in ppu
  652. Revision 1.33 2002/08/17 22:09:44 florian
  653. * result type handling in tcgcal.pass_2 overhauled
  654. * better tnode.dowrite
  655. * some ppc stuff fixed
  656. Revision 1.32 2002/08/17 09:23:34 florian
  657. * first part of procinfo rewrite
  658. Revision 1.31 2002/08/15 19:10:35 peter
  659. * first things tai,tnode storing in ppu
  660. Revision 1.30 2002/07/20 11:57:53 florian
  661. * types.pas renamed to defbase.pas because D6 contains a types
  662. unit so this would conflicts if D6 programms are compiled
  663. + Willamette/SSE2 instructions to assembler added
  664. Revision 1.29 2002/07/19 11:41:35 daniel
  665. * State tracker work
  666. * The whilen and repeatn are now completely unified into whilerepeatn. This
  667. allows the state tracker to change while nodes automatically into
  668. repeat nodes.
  669. * Resulttypepass improvements to the notn. 'not not a' is optimized away and
  670. 'not(a>b)' is optimized into 'a<=b'.
  671. * Resulttypepass improvements to the whilerepeatn. 'while not a' is optimized
  672. by removing the notn and later switchting the true and falselabels. The
  673. same is done with 'repeat until not a'.
  674. Revision 1.28 2002/07/14 18:00:43 daniel
  675. + Added the beginning of a state tracker. This will track the values of
  676. variables through procedures and optimize things away.
  677. Revision 1.27 2002/07/01 18:46:22 peter
  678. * internal linker
  679. * reorganized aasm layer
  680. Revision 1.26 2002/06/24 12:43:00 jonas
  681. * fixed errors found with new -CR code from Peter when cycling with -O2p3r
  682. Revision 1.25 2002/05/18 13:34:09 peter
  683. * readded missing revisions
  684. Revision 1.24 2002/05/16 19:46:37 carl
  685. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  686. + try to fix temp allocation (still in ifdef)
  687. + generic constructor calls
  688. + start of tassembler / tmodulebase class cleanup
  689. Revision 1.22 2002/04/23 19:16:34 peter
  690. * add pinline unit that inserts compiler supported functions using
  691. one or more statements
  692. * moved finalize and setlength from ninl to pinline
  693. Revision 1.21 2002/04/21 19:02:03 peter
  694. * removed newn and disposen nodes, the code is now directly
  695. inlined from pexpr
  696. * -an option that will write the secondpass nodes to the .s file, this
  697. requires EXTDEBUG define to actually write the info
  698. * fixed various internal errors and crashes due recent code changes
  699. Revision 1.20 2002/04/04 19:05:57 peter
  700. * removed unused units
  701. * use tlocation.size in cg.a_*loc*() routines
  702. Revision 1.19 2002/03/31 20:26:33 jonas
  703. + a_loadfpu_* and a_loadmm_* methods in tcg
  704. * register allocation is now handled by a class and is mostly processor
  705. independent (+rgobj.pas and i386/rgcpu.pas)
  706. * temp allocation is now handled by a class (+tgobj.pas, -i386\tgcpu.pas)
  707. * some small improvements and fixes to the optimizer
  708. * some register allocation fixes
  709. * some fpuvaroffset fixes in the unary minus node
  710. * push/popusedregisters is now called rg.save/restoreusedregisters and
  711. (for i386) uses temps instead of push/pop's when using -Op3 (that code is
  712. also better optimizable)
  713. * fixed and optimized register saving/restoring for new/dispose nodes
  714. * LOC_FPU locations now also require their "register" field to be set to
  715. R_ST, not R_ST0 (the latter is used for LOC_CFPUREGISTER locations only)
  716. - list field removed of the tnode class because it's not used currently
  717. and can cause hard-to-find bugs
  718. }