tgobj.pas 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 by Florian Klaempfl
  4. This unit implements the base object for temp. generator
  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. {#@abstract(Temporary reference allocator unit)
  19. Temporary reference allocator unit. This unit contains
  20. all which is related to allocating temporary memory
  21. space on the stack, as required, by the code generator.
  22. }
  23. unit tgobj;
  24. {$i fpcdefs.inc}
  25. interface
  26. uses
  27. globals,
  28. cpubase,
  29. cpuinfo,
  30. cpuasm,
  31. tainst,
  32. cclasses,globtype,cgbase,aasm;
  33. type
  34. ttemptype = (tt_none,tt_free,tt_normal,tt_persistant,
  35. tt_ansistring,tt_freeansistring,tt_widestring,tt_freewidestring,
  36. tt_interfacecom,tt_freeinterfacecom);
  37. ttemptypeset = set of ttemptype;
  38. ptemprecord = ^ttemprecord;
  39. ttemprecord = record
  40. temptype : ttemptype;
  41. pos : longint;
  42. size : longint;
  43. next : ptemprecord;
  44. nextfree : ptemprecord; { for faster freeblock checking }
  45. {$ifdef EXTDEBUG}
  46. posinfo,
  47. releaseposinfo : tfileposinfo;
  48. {$endif}
  49. end;
  50. {# Generates temporary variables }
  51. ttgobj = class
  52. { contains all temps }
  53. templist : ptemprecord;
  54. { contains all free temps using nextfree links }
  55. tempfreelist : ptemprecord;
  56. { Offsets of the first/last temp }
  57. firsttemp,
  58. lasttemp : longint;
  59. lasttempofsize : ptemprecord;
  60. { tries to hold the amount of times which the current tree is processed }
  61. t_times: longint;
  62. constructor create;
  63. {# Clear and free the complete linked list of temporary memory
  64. locations. The list is set to nil.}
  65. procedure resettempgen;
  66. {# Sets the first offset from the frame pointer or stack pointer where
  67. the temporary references will be allocated. It is to note that this
  68. value should always be negative.
  69. @param(l start offset where temps will start in stack)
  70. }
  71. procedure setfirsttemp(l : longint);
  72. function gettempsize : longint;
  73. { special call for inlined procedures }
  74. function gettempofsizepersistant(list: taasmoutput; size : longint) : longint;
  75. procedure gettempofsizereferencepersistant(list: taasmoutput; l : longint;var ref : treference);
  76. procedure gettemppointerreferencefortype(list: taasmoutput; var ref : treference; const usedtype, freetype: ttemptype);
  77. function ungettemppointeriftype(list: taasmoutput; const ref : treference; const usedtype, freetype: ttemptype) : boolean;
  78. { for parameter func returns }
  79. procedure normaltemptopersistant(pos : longint);
  80. {# Searches the list of currently allocated persistent memory space
  81. as the specified address @var(pos) , and if found, converts this memory
  82. space to normal volatile memory space which can be freed and reused.
  83. @param(pos offset from current frame pointer to memory area to convert)
  84. }
  85. procedure persistanttemptonormal(pos : longint);
  86. {procedure ungettemp(pos : longint;size : longint);}
  87. procedure ungetpersistanttemp(list: taasmoutput; pos : longint);
  88. procedure ungetpersistanttempreference(list: taasmoutput; const ref : treference);
  89. {# This routine is used to assign and allocate extra temporary volatile memory space
  90. on the stack from a reference. @var(l) is the size of the persistent memory space to
  91. allocate, while @var(ref) is a reference entry which will be set to the correct offset
  92. and correct base register (which is the current @var(procinfo^.framepointer)) register.
  93. The offset and base fields of ref will be set appropriately in this routine, and can be
  94. considered valid on exit of this routine.
  95. @param(l size of the area to allocate)
  96. @param(ref allocated reference)
  97. }
  98. procedure gettempofsizereference(list: taasmoutput; l : longint;var ref : treference);
  99. {# Returns TRUE if the reference ref is allocated in temporary volatile memory space,
  100. otherwise returns FALSE.
  101. @param(ref reference to verify)
  102. }
  103. function istemp(const ref : treference) : boolean;
  104. {# Frees a reference @var(ref) which was allocated in the volatile temporary memory space.
  105. The freed space can later be reallocated and reused. If this reference
  106. is not in the temporary memory, it is simply not freed.
  107. }
  108. procedure ungetiftemp(list: taasmoutput; const ref : treference);
  109. function getsizeoftemp(const ref: treference): longint;
  110. function ungetiftempansi(list: taasmoutput; const ref : treference) : boolean;
  111. procedure gettempansistringreference(list: taasmoutput; var ref : treference);
  112. function ungetiftempwidestr(list: taasmoutput; const ref : treference) : boolean;
  113. procedure gettempwidestringreference(list: taasmoutput; var ref : treference);
  114. function ungetiftempintfcom(list: taasmoutput; const ref : treference) : boolean;
  115. procedure gettempintfcomreference(list: taasmoutput; var ref : treference);
  116. private
  117. function ungettemp(list: taasmoutput; pos:longint;allowtype:ttemptype):ttemptype;
  118. function newtempofsize(size : longint) : longint;
  119. function gettempofsize(list: taasmoutput; size : longint) : longint;
  120. end;
  121. var
  122. tg: ttgobj;
  123. implementation
  124. uses
  125. systems,
  126. verbose,cutils;
  127. constructor ttgobj.create;
  128. begin
  129. tempfreelist:=nil;
  130. templist:=nil;
  131. lasttempofsize := nil;
  132. end;
  133. procedure ttgobj.resettempgen;
  134. var
  135. hp : ptemprecord;
  136. begin
  137. { Clear the old templist }
  138. while assigned(templist) do
  139. begin
  140. {$ifdef EXTDEBUG}
  141. case templist^.temptype of
  142. tt_normal,
  143. tt_persistant :
  144. Comment(V_Warning,'temporary assignment of size '+
  145. tostr(templist^.size)+' from pos '+tostr(templist^.posinfo.line)+
  146. ':'+tostr(templist^.posinfo.column)+
  147. ' at pos '+tostr(templist^.pos)+
  148. ' not freed at the end of the procedure');
  149. tt_ansistring :
  150. Comment(V_Warning,'temporary ANSI assignment of size '+
  151. tostr(templist^.size)+' from pos '+tostr(templist^.posinfo.line)+
  152. ':'+tostr(templist^.posinfo.column)+
  153. ' at pos '+tostr(templist^.pos)+
  154. ' not freed at the end of the procedure');
  155. tt_widestring :
  156. Comment(V_Warning,'temporary WIDE assignment of size '+
  157. tostr(templist^.size)+' from pos '+tostr(templist^.posinfo.line)+
  158. ':'+tostr(templist^.posinfo.column)+
  159. ' at pos '+tostr(templist^.pos)+
  160. ' not freed at the end of the procedure');
  161. end;
  162. {$endif}
  163. hp:=templist;
  164. templist:=hp^.next;
  165. dispose(hp);
  166. end;
  167. templist:=nil;
  168. tempfreelist:=nil;
  169. firsttemp:=0;
  170. lasttemp:=0;
  171. end;
  172. procedure ttgobj.setfirsttemp(l : longint);
  173. begin
  174. { this is a negative value normally }
  175. if l <= 0 then
  176. Begin
  177. if odd(l) then
  178. Dec(l);
  179. end
  180. else
  181. internalerror(20020422);
  182. firsttemp:=l;
  183. lasttemp:=l;
  184. end;
  185. function ttgobj.newtempofsize(size : longint) : longint;
  186. var
  187. tl : ptemprecord;
  188. begin
  189. { we need to allocate at least a minimum of 4 bytes, else
  190. we get two temps at the same position resulting in problems
  191. when finding the corresponding temprecord }
  192. if size=0 then
  193. size:=4;
  194. { Just extend the temp, everything below has been use
  195. already }
  196. dec(lasttemp,size);
  197. { now we can create the templist entry }
  198. new(tl);
  199. tl^.temptype:=tt_normal;
  200. tl^.pos:=lasttemp;
  201. tl^.size:=size;
  202. tl^.next:=templist;
  203. tl^.nextfree:=nil;
  204. templist:=tl;
  205. newtempofsize:=tl^.pos;
  206. end;
  207. function ttgobj.gettempofsize(list: taasmoutput; size : longint) : longint;
  208. var
  209. tl,
  210. bestslot,bestprev,
  211. hprev,hp : ptemprecord;
  212. bestsize,ofs : longint;
  213. begin
  214. bestprev:=nil;
  215. bestslot:=nil;
  216. tl:=nil;
  217. bestsize:=0;
  218. {$ifdef EXTDEBUG}
  219. if size=0 then
  220. Comment(V_Warning,'Temp of size 0 requested');
  221. {$endif}
  222. { Align needed size on 4 bytes }
  223. if (size mod 4)<>0 then
  224. size:=size+(4-(size mod 4));
  225. { First check the tmpfreelist }
  226. if assigned(tempfreelist) then
  227. begin
  228. { Check for a slot with the same size first }
  229. hprev:=nil;
  230. hp:=tempfreelist;
  231. while assigned(hp) do
  232. begin
  233. {$ifdef EXTDEBUG}
  234. if hp^.temptype<>tt_free then
  235. Comment(V_Warning,'Temp in freelist is not set to tt_free');
  236. {$endif}
  237. if hp^.size>=size then
  238. begin
  239. { Slot is the same size, then leave immediatly }
  240. if hp^.size=size then
  241. begin
  242. bestprev:=hprev;
  243. bestslot:=hp;
  244. bestsize:=size;
  245. break;
  246. end
  247. else
  248. begin
  249. if (bestsize=0) or (hp^.size<bestsize) then
  250. begin
  251. bestprev:=hprev;
  252. bestslot:=hp;
  253. bestsize:=hp^.size;
  254. end;
  255. end;
  256. end;
  257. hprev:=hp;
  258. hp:=hp^.nextfree;
  259. end;
  260. end;
  261. { Reuse an old temp ? }
  262. if assigned(bestslot) then
  263. begin
  264. if bestsize=size then
  265. begin
  266. bestslot^.temptype:=tt_normal;
  267. ofs:=bestslot^.pos;
  268. tl:=bestslot;
  269. { Remove from the tempfreelist }
  270. if assigned(bestprev) then
  271. bestprev^.nextfree:=bestslot^.nextfree
  272. else
  273. tempfreelist:=bestslot^.nextfree;
  274. end
  275. else
  276. begin
  277. { Resize the old block }
  278. dec(bestslot^.size,size);
  279. { Create new block and link after bestslot }
  280. new(tl);
  281. tl^.temptype:=tt_normal;
  282. tl^.pos:=bestslot^.pos+bestslot^.size;
  283. ofs:=tl^.pos;
  284. tl^.size:=size;
  285. tl^.nextfree:=nil;
  286. { link the new block }
  287. tl^.next:=bestslot^.next;
  288. bestslot^.next:=tl;
  289. end;
  290. end
  291. else
  292. begin
  293. ofs:=newtempofsize(size);
  294. tl:=templist;
  295. end;
  296. lasttempofsize:=tl;
  297. {$ifdef EXTDEBUG}
  298. tl^.posinfo:=aktfilepos;
  299. {$endif}
  300. list.concat(Taitempalloc.alloc(ofs,size));
  301. gettempofsize:=ofs;
  302. end;
  303. function ttgobj.gettempofsizepersistant(list: taasmoutput; size : longint) : longint;
  304. var
  305. l : longint;
  306. begin
  307. l:=gettempofsize(list, size);
  308. lasttempofsize^.temptype:=tt_persistant;
  309. {$ifdef EXTDEBUG}
  310. Comment(V_Debug,'temp managment : call to gettempofsizepersistant()'+
  311. ' with size '+tostr(size)+' returned '+tostr(l));
  312. {$endif}
  313. gettempofsizepersistant:=l;
  314. end;
  315. function ttgobj.gettempsize : longint;
  316. var
  317. _align : longint;
  318. begin
  319. { align to 4 bytes at least
  320. otherwise all those subl $2,%esp are meaningless PM }
  321. _align:=target_info.alignment.localalignmin;
  322. if _align<4 then
  323. _align:=4;
  324. {$ifdef testtemp}
  325. if firsttemp <> lasttemp then
  326. gettempsize:=Align(-(lasttemp-firsttemp),_align)
  327. else
  328. gettempsize := 0;
  329. {$else}
  330. gettempsize:=Align(-lasttemp,_align);
  331. {$endif}
  332. end;
  333. procedure ttgobj.gettempofsizereference(list: taasmoutput; l : longint;var ref : treference);
  334. begin
  335. { do a reset, because the reference isn't used }
  336. FillChar(ref,sizeof(treference),0);
  337. ref.offset:=gettempofsize(list,l);
  338. ref.base:=procinfo^.framepointer;
  339. end;
  340. procedure ttgobj.gettempofsizereferencepersistant(list: taasmoutput; l : longint;var ref : treference);
  341. begin
  342. { do a reset, because the reference isn't used }
  343. FillChar(ref,sizeof(treference),0);
  344. ref.offset:=gettempofsizepersistant(list,l);
  345. ref.base:=procinfo^.framepointer;
  346. end;
  347. procedure ttgobj.gettemppointerreferencefortype(list: taasmoutput; var ref : treference; const usedtype, freetype: ttemptype);
  348. var
  349. foundslot,tl : ptemprecord;
  350. begin
  351. { do a reset, because the reference isn't used }
  352. FillChar(ref,sizeof(treference),0);
  353. ref.base:=procinfo^.framepointer;
  354. { Reuse old slot ? }
  355. foundslot:=nil;
  356. tl:=templist;
  357. while assigned(tl) do
  358. begin
  359. if tl^.temptype=freetype then
  360. begin
  361. foundslot:=tl;
  362. {$ifdef EXTDEBUG}
  363. tl^.posinfo:=aktfilepos;
  364. {$endif}
  365. break;
  366. end;
  367. tl:=tl^.next;
  368. end;
  369. if assigned(foundslot) then
  370. begin
  371. foundslot^.temptype:=usedtype;
  372. ref.offset:=foundslot^.pos;
  373. end
  374. else
  375. begin
  376. ref.offset:=newtempofsize(pointer_size);
  377. {$ifdef EXTDEBUG}
  378. templist^.posinfo:=aktfilepos;
  379. {$endif}
  380. templist^.temptype:=usedtype;
  381. end;
  382. list.concat(Taitempalloc.alloc(ref.offset,pointer_size));
  383. end;
  384. function ttgobj.ungettemppointeriftype(list: taasmoutput; const ref : treference; const usedtype, freetype: ttemptype) : boolean;
  385. var
  386. tl : ptemprecord;
  387. begin
  388. ungettemppointeriftype:=false;
  389. tl:=templist;
  390. while assigned(tl) do
  391. begin
  392. if tl^.pos=ref.offset then
  393. begin
  394. if tl^.temptype=usedtype then
  395. begin
  396. tl^.temptype:=freetype;
  397. ungettemppointeriftype:=true;
  398. list.concat(Taitempalloc.dealloc(tl^.pos,tl^.size));
  399. exit;
  400. {$ifdef EXTDEBUG}
  401. end
  402. else if (tl^.temptype=freetype) then
  403. begin
  404. Comment(V_Debug,'temp managment problem : ungettemppointeriftype()'+
  405. ' at pos '+tostr(ref.offset)+ ' already free !');
  406. {$endif}
  407. end;
  408. end;
  409. tl:=tl^.next;
  410. end;
  411. end;
  412. procedure ttgobj.gettempansistringreference(list: taasmoutput; var ref : treference);
  413. begin
  414. gettemppointerreferencefortype(list,ref,tt_ansistring,tt_freeansistring);
  415. end;
  416. procedure ttgobj.gettempwidestringreference(list: taasmoutput; var ref : treference);
  417. begin
  418. gettemppointerreferencefortype(list,ref,tt_widestring,tt_freewidestring);
  419. end;
  420. function ttgobj.ungetiftempansi(list: taasmoutput; const ref : treference) : boolean;
  421. begin
  422. ungetiftempansi:=ungettemppointeriftype(list,ref,tt_ansistring,tt_freeansistring);
  423. end;
  424. function ttgobj.ungetiftempwidestr(list: taasmoutput; const ref : treference) : boolean;
  425. begin
  426. ungetiftempwidestr:=ungettemppointeriftype(list,ref,tt_widestring,tt_freewidestring);
  427. end;
  428. procedure ttgobj.gettempintfcomreference(list: taasmoutput; var ref : treference);
  429. begin
  430. gettemppointerreferencefortype(list,ref,tt_interfacecom,tt_freeinterfacecom);
  431. end;
  432. function ttgobj.ungetiftempintfcom(list: taasmoutput; const ref : treference) : boolean;
  433. begin
  434. ungetiftempintfcom:=ungettemppointeriftype(list,ref,tt_ansistring,tt_freeansistring);
  435. end;
  436. function ttgobj.istemp(const ref : treference) : boolean;
  437. begin
  438. { ref.index = R_NO was missing
  439. led to problems with local arrays
  440. with lower bound > 0 (PM) }
  441. istemp:=((ref.base=procinfo^.framepointer) and
  442. (ref.index=R_NO) and
  443. (ref.offset<firsttemp));
  444. end;
  445. procedure ttgobj.persistanttemptonormal(pos : longint);
  446. var
  447. hp : ptemprecord;
  448. begin
  449. hp:=templist;
  450. while assigned(hp) do
  451. if (hp^.pos=pos) and (hp^.temptype=tt_persistant) then
  452. begin
  453. {$ifdef EXTDEBUG}
  454. Comment(V_Debug,'temp managment : persistanttemptonormal()'+
  455. ' at pos '+tostr(pos)+ ' found !');
  456. {$endif}
  457. hp^.temptype:=tt_normal;
  458. exit;
  459. end
  460. else
  461. hp:=hp^.next;
  462. {$ifdef EXTDEBUG}
  463. Comment(V_Debug,'temp managment problem : persistanttemptonormal()'+
  464. ' at pos '+tostr(pos)+ ' not found !');
  465. {$endif}
  466. end;
  467. procedure ttgobj.normaltemptopersistant(pos : longint);
  468. var
  469. hp : ptemprecord;
  470. begin
  471. hp:=templist;
  472. while assigned(hp) do
  473. if (hp^.pos=pos) and (hp^.temptype=tt_normal) then
  474. begin
  475. {$ifdef EXTDEBUG}
  476. Comment(V_Debug,'temp managment : normaltemptopersistant()'+
  477. ' at pos '+tostr(pos)+ ' found !');
  478. {$endif}
  479. hp^.temptype:=tt_persistant;
  480. exit;
  481. end
  482. else
  483. hp:=hp^.next;
  484. {$ifdef EXTDEBUG}
  485. Comment(V_Debug,'temp managment problem : normaltemptopersistant()'+
  486. ' at pos '+tostr(pos)+ ' not found !');
  487. {$endif}
  488. end;
  489. function ttgobj.ungettemp(list: taasmoutput; pos:longint;allowtype:ttemptype):ttemptype;
  490. var
  491. hp,hnext,hprev,hprevfree : ptemprecord;
  492. begin
  493. ungettemp:=tt_none;
  494. hp:=templist;
  495. hprev:=nil;
  496. hprevfree:=nil;
  497. while assigned(hp) do
  498. begin
  499. if (hp^.pos=pos) then
  500. begin
  501. { check type }
  502. ungettemp:=hp^.temptype;
  503. if hp^.temptype<>allowtype then
  504. begin
  505. exit;
  506. end;
  507. list.concat(Taitempalloc.dealloc(hp^.pos,hp^.size));
  508. { set this block to free }
  509. hp^.temptype:=tt_free;
  510. { Update tempfreelist }
  511. if assigned(hprevfree) then
  512. begin
  513. { Connect with previous? }
  514. if assigned(hprev) and (hprev^.temptype=tt_free) then
  515. begin
  516. inc(hprev^.size,hp^.size);
  517. hprev^.next:=hp^.next;
  518. dispose(hp);
  519. hp:=hprev;
  520. end
  521. else
  522. hprevfree^.nextfree:=hp;
  523. end
  524. else
  525. begin
  526. hp^.nextfree:=tempfreelist;
  527. tempfreelist:=hp;
  528. end;
  529. { Next block free ? Yes, then concat }
  530. hnext:=hp^.next;
  531. if assigned(hnext) and (hnext^.temptype=tt_free) then
  532. begin
  533. inc(hp^.size,hnext^.size);
  534. hp^.nextfree:=hnext^.nextfree;
  535. hp^.next:=hnext^.next;
  536. dispose(hnext);
  537. end;
  538. exit;
  539. end;
  540. if (hp^.temptype=tt_free) then
  541. hprevfree:=hp;
  542. hprev:=hp;
  543. hp:=hp^.next;
  544. end;
  545. ungettemp:=tt_none;
  546. end;
  547. function ttgobj.getsizeoftemp(const ref: treference): longint;
  548. var
  549. hp : ptemprecord;
  550. begin
  551. hp:=templist;
  552. while assigned(hp) do
  553. begin
  554. if (hp^.pos=ref.offset) then
  555. begin
  556. getsizeoftemp := hp^.size;
  557. exit;
  558. end;
  559. hp := hp^.next;
  560. end;
  561. getsizeoftemp := -1;
  562. end;
  563. procedure ttgobj.ungetpersistanttemp(list: taasmoutput; pos : longint);
  564. begin
  565. {$ifdef EXTDEBUG}
  566. if ungettemp(list,pos,tt_persistant)<>tt_persistant then
  567. Comment(V_Warning,'temp managment problem : ungetpersistanttemp()'+
  568. ' at pos '+tostr(pos)+ ' not found !');
  569. {$else}
  570. ungettemp(list,pos,tt_persistant);
  571. {$endif}
  572. end;
  573. procedure ttgobj.ungetpersistanttempreference(list: taasmoutput; const ref : treference);
  574. begin
  575. ungetpersistanttemp(list, ref.offset);
  576. end;
  577. procedure ttgobj.ungetiftemp(list: taasmoutput; const ref : treference);
  578. {$ifdef EXTDEBUG}
  579. var
  580. tt : ttemptype;
  581. {$endif}
  582. begin
  583. if istemp(ref) then
  584. begin
  585. { first check if ansistring }
  586. if ungetiftempansi(list,ref) or
  587. ungetiftempwidestr(list,ref) or
  588. ungetiftempintfcom(list,ref) then
  589. exit;
  590. {$ifndef EXTDEBUG}
  591. ungettemp(list,ref.offset,tt_normal);
  592. {$else}
  593. tt:=ungettemp(list,ref.offset,tt_normal);
  594. if tt=tt_persistant then
  595. Comment(V_Debug,'temp at pos '+tostr(ref.offset)+ ' not released because persistant!');
  596. if tt=tt_none then
  597. Comment(V_Warning,'temp not found for release at offset '+tostr(ref.offset));
  598. {$endif}
  599. end;
  600. end;
  601. initialization
  602. tg := ttgobj.create;
  603. finalization
  604. tg.free;
  605. end.
  606. {
  607. $Log$
  608. Revision 1.8 2002-05-16 19:46:45 carl
  609. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  610. + try to fix temp allocation (still in ifdef)
  611. + generic constructor calls
  612. + start of tassembler / tmodulebase class cleanup
  613. Revision 1.7 2002/05/14 19:34:52 peter
  614. * removed old logs and updated copyright year
  615. Revision 1.6 2002/04/15 19:08:22 carl
  616. + target_info.size_of_pointer -> pointer_size
  617. + some cleanup of unused types/variables
  618. Revision 1.5 2002/04/07 13:38:48 carl
  619. + update documentation
  620. Revision 1.4 2002/04/07 09:17:17 carl
  621. + documentation
  622. - clean-up
  623. Revision 1.3 2002/04/04 19:06:06 peter
  624. * removed unused units
  625. * use tlocation.size in cg.a_*loc*() routines
  626. Revision 1.2 2002/04/02 17:11:32 peter
  627. * tlocation,treference update
  628. * LOC_CONSTANT added for better constant handling
  629. * secondadd splitted in multiple routines
  630. * location_force_reg added for loading a location to a register
  631. of a specified size
  632. * secondassignment parses now first the right and then the left node
  633. (this is compatible with Kylix). This saves a lot of push/pop especially
  634. with string operations
  635. * adapted some routines to use the new cg methods
  636. Revision 1.1 2002/03/31 20:26:37 jonas
  637. + a_loadfpu_* and a_loadmm_* methods in tcg
  638. * register allocation is now handled by a class and is mostly processor
  639. independent (+rgobj.pas and i386/rgcpu.pas)
  640. * temp allocation is now handled by a class (+tgobj.pas, -i386\tgcpu.pas)
  641. * some small improvements and fixes to the optimizer
  642. * some register allocation fixes
  643. * some fpuvaroffset fixes in the unary minus node
  644. * push/popusedregisters is now called rg.save/restoreusedregisters and
  645. (for i386) uses temps instead of push/pop's when using -Op3 (that code is
  646. also better optimizable)
  647. * fixed and optimized register saving/restoring for new/dispose nodes
  648. * LOC_FPU locations now also require their "register" field to be set to
  649. R_ST, not R_ST0 (the latter is used for LOC_CFPUREGISTER locations only)
  650. - list field removed of the tnode class because it's not used currently
  651. and can cause hard-to-find bugs
  652. }