tgobj.pas 25 KB

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