tgobj.pas 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667
  1. {
  2. Copyright (c) 1998-2002 by Florian Klaempfl
  3. This unit implements the base object for temp. generator
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. ****************************************************************************
  16. }
  17. {#@abstract(Temporary reference allocator unit)
  18. Temporary reference allocator unit. This unit contains
  19. all which is related to allocating temporary memory
  20. space on the stack, as required, by the code generator.
  21. }
  22. unit tgobj;
  23. {$i fpcdefs.inc}
  24. interface
  25. uses
  26. cclasses,
  27. globals,globtype,
  28. symtype,
  29. cpubase,cpuinfo,cgbase,cgutils,
  30. aasmbase,aasmtai,aasmdata;
  31. type
  32. ptemprecord = ^ttemprecord;
  33. ttemprecord = record
  34. temptype : ttemptype;
  35. pos : longint;
  36. size : longint;
  37. def : tdef;
  38. next : ptemprecord;
  39. nextfree : ptemprecord; { for faster freeblock checking }
  40. {$ifdef EXTDEBUG}
  41. posinfo,
  42. releaseposinfo : tfileposinfo;
  43. {$endif}
  44. end;
  45. {# Generates temporary variables }
  46. ttgobj = class
  47. protected
  48. { contains all free temps using nextfree links }
  49. tempfreelist : ptemprecord;
  50. function alloctemp(list: TAsmList; size,alignment : longint; temptype : ttemptype; def:tdef) : longint; virtual;
  51. procedure freetemp(list: TAsmList; pos:longint;temptypes:ttemptypeset);
  52. public
  53. { contains all temps }
  54. templist : ptemprecord;
  55. { Offsets of the first/last temp }
  56. firsttemp,
  57. lasttemp : longint;
  58. direction : shortint;
  59. constructor create;virtual;reintroduce;
  60. {# Clear and free the complete linked list of temporary memory
  61. locations. The list is set to nil.}
  62. procedure resettempgen;
  63. {# Sets the first offset from the frame pointer or stack pointer where
  64. the temporary references will be allocated. It is to note that this
  65. value should always be negative.
  66. @param(l start offset where temps will start in stack)
  67. }
  68. procedure setfirsttemp(l : longint); virtual;
  69. procedure gettemp(list: TAsmList; size, alignment : longint;temptype:ttemptype;out ref : treference);
  70. procedure gettemptyped(list: TAsmList; def:tdef;temptype:ttemptype;out ref : treference);
  71. procedure ungettemp(list: TAsmList; const ref : treference);
  72. function sizeoftemp(list: TAsmList; const ref: treference): longint;
  73. function changetemptype(list: TAsmList; const ref:treference;temptype:ttemptype):boolean;
  74. function gettypeoftemp(const ref:treference): ttemptype;
  75. {# Returns TRUE if the reference ref is allocated in temporary volatile memory space,
  76. otherwise returns FALSE.
  77. @param(ref reference to verify)
  78. }
  79. function istemp(const ref : treference) : boolean;
  80. {# Frees a reference @var(ref) which was allocated in the volatile temporary memory space.
  81. The freed space can later be reallocated and reused. If this reference
  82. is not in the temporary memory, it is simply not freed.
  83. }
  84. procedure ungetiftemp(list: TAsmList; const ref : treference);
  85. { Allocate space for a local }
  86. procedure getlocal(list: TAsmList; size : longint;def:tdef;var ref : treference);
  87. procedure getlocal(list: TAsmList; size : longint; alignment : shortint; def:tdef;var ref : treference);
  88. procedure UnGetLocal(list: TAsmList; const ref : treference);
  89. end;
  90. ttgobjclass = class of ttgobj;
  91. var
  92. tg: ttgobj;
  93. tgobjclass: ttgobjclass = ttgobj;
  94. procedure location_freetemp(list:TAsmList; const l : tlocation);
  95. implementation
  96. uses
  97. cutils,
  98. systems,verbose,
  99. procinfo,
  100. symconst
  101. ;
  102. const
  103. FreeTempTypes = [tt_free,tt_freenoreuse,tt_freeregallocator];
  104. {$ifdef EXTDEBUG}
  105. TempTypeStr : array[ttemptype] of string[18] = (
  106. '<none>',
  107. 'free','normal','persistant',
  108. 'noreuse','freenoreuse',
  109. 'regallocator','freeregallocator'
  110. );
  111. {$endif EXTDEBUG}
  112. Used2Free : array[ttemptype] of ttemptype = (
  113. tt_none,
  114. tt_none,tt_free,tt_free,
  115. tt_freenoreuse,tt_none,
  116. tt_freeregallocator,tt_none
  117. );
  118. {*****************************************************************************
  119. Helpers
  120. *****************************************************************************}
  121. procedure location_freetemp(list:TAsmList; const l : tlocation);
  122. begin
  123. if (l.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
  124. tg.ungetiftemp(list,l.reference);
  125. end;
  126. {*****************************************************************************
  127. TTGOBJ
  128. *****************************************************************************}
  129. constructor ttgobj.create;
  130. begin
  131. tempfreelist:=nil;
  132. templist:=nil;
  133. { we could create a new child class for this but I don't if it is worth the effort (FK) }
  134. {$if defined(powerpc) or defined(powerpc64) or defined(avr) or defined(jvm)}
  135. direction:=1;
  136. {$else}
  137. direction:=-1;
  138. {$endif}
  139. end;
  140. procedure ttgobj.resettempgen;
  141. var
  142. hp : ptemprecord;
  143. begin
  144. { Clear the old templist }
  145. while assigned(templist) do
  146. begin
  147. {$ifdef EXTDEBUG}
  148. if not(templist^.temptype in FreeTempTypes) then
  149. begin
  150. Comment(V_Warning,'tgobj: (ResetTempgen) temp at pos '+tostr(templist^.pos)+
  151. ' with size '+tostr(templist^.size)+' and type '+TempTypeStr[templist^.temptype]+
  152. ' from pos '+tostr(templist^.posinfo.line)+':'+tostr(templist^.posinfo.column)+
  153. ' not freed at the end of the procedure');
  154. end;
  155. {$endif EXTDEBUG}
  156. hp:=templist;
  157. templist:=hp^.next;
  158. dispose(hp);
  159. end;
  160. templist:=nil;
  161. tempfreelist:=nil;
  162. firsttemp:=0;
  163. lasttemp:=0;
  164. end;
  165. procedure ttgobj.setfirsttemp(l : longint);
  166. begin
  167. { this is a negative value normally }
  168. if l*direction>=0 then
  169. begin
  170. if odd(l) then
  171. inc(l,direction);
  172. end
  173. else
  174. internalerror(200204221);
  175. firsttemp:=l;
  176. lasttemp:=l;
  177. end;
  178. function ttgobj.AllocTemp(list: TAsmList; size,alignment : longint; temptype : ttemptype;def : tdef) : longint;
  179. var
  180. tl,htl,
  181. bestslot,bestprev,
  182. hprev,hp : ptemprecord;
  183. freetype : ttemptype;
  184. bestatend,
  185. fitatbegin,
  186. fitatend : boolean;
  187. begin
  188. AllocTemp:=0;
  189. bestprev:=nil;
  190. bestslot:=nil;
  191. tl:=nil;
  192. bestatend:=false;
  193. if size=0 then
  194. begin
  195. {$ifdef EXTDEBUG}
  196. Comment(V_Warning,'tgobj: (AllocTemp) temp of size 0 requested, allocating 4 bytes');
  197. {$endif}
  198. size:=4;
  199. end;
  200. freetype:=Used2Free[temptype];
  201. if freetype=tt_none then
  202. internalerror(200208201);
  203. size:=align(size,alignment);
  204. { First check the tmpfreelist, but not when
  205. we don't want to reuse an already allocated block }
  206. if assigned(tempfreelist) and
  207. (temptype<>tt_noreuse) then
  208. begin
  209. hprev:=nil;
  210. hp:=tempfreelist;
  211. while assigned(hp) do
  212. begin
  213. {$ifdef EXTDEBUG}
  214. if not(hp^.temptype in FreeTempTypes) then
  215. Comment(V_Warning,'tgobj: (AllocTemp) temp at pos '+tostr(hp^.pos)+ ' in freelist is not set to tt_free !');
  216. {$endif}
  217. { Check only slots that are
  218. - free
  219. - share the same type
  220. - contain enough space
  221. - has a correct alignment }
  222. if (hp^.temptype=freetype) and
  223. (hp^.def=def) and
  224. (hp^.size>=size) and
  225. ((hp^.pos=align(hp^.pos,alignment)) or
  226. (hp^.pos+hp^.size-size = align(hp^.pos+hp^.size-size,alignment))) then
  227. begin
  228. { Slot is the same size then leave immediatly }
  229. if (hp^.size=size) then
  230. begin
  231. bestprev:=hprev;
  232. bestslot:=hp;
  233. break;
  234. end
  235. else
  236. begin
  237. { we can fit a smaller block either at the begin or at }
  238. { the end of a block. For direction=-1 we prefer the }
  239. { end, for direction=1 we prefer the begin (i.e., }
  240. { always closest to the source). We also try to use }
  241. { the block with the worst possible alignment that }
  242. { still suffices. And we pick the block which will }
  243. { have the best alignmenment after this new block is }
  244. { substracted from it. }
  245. fitatend:=(hp^.pos+hp^.size-size)=align(hp^.pos+hp^.size-size,alignment);
  246. fitatbegin:=hp^.pos=align(hp^.pos,alignment);
  247. if assigned(bestslot) then
  248. begin
  249. fitatend:=fitatend and
  250. ((not bestatend and
  251. (direction=-1)) or
  252. (bestatend and
  253. isbetteralignedthan(abs(bestslot^.pos+hp^.size-size),abs(hp^.pos+hp^.size-size),current_settings.alignment.localalignmax)));
  254. fitatbegin:=fitatbegin and
  255. (not bestatend or
  256. (direction=1)) and
  257. isbetteralignedthan(abs(hp^.pos+size),abs(bestslot^.pos+size),current_settings.alignment.localalignmax);
  258. end;
  259. if fitatend and
  260. fitatbegin then
  261. if isbetteralignedthan(abs(hp^.pos+hp^.size-size),abs(hp^.pos+size),current_settings.alignment.localalignmax) then
  262. fitatbegin:=false
  263. else if isbetteralignedthan(abs(hp^.pos+size),abs(hp^.pos+hp^.size-size),current_settings.alignment.localalignmax) then
  264. fitatend:=false
  265. else if (direction=1) then
  266. fitatend:=false
  267. else
  268. fitatbegin:=false;
  269. if fitatend or
  270. fitatbegin then
  271. begin
  272. bestprev:=hprev;
  273. bestslot:=hp;
  274. bestatend:=fitatend;
  275. end;
  276. end;
  277. end;
  278. hprev:=hp;
  279. hp:=hp^.nextfree;
  280. end;
  281. end;
  282. { Reuse an old temp ? }
  283. if assigned(bestslot) then
  284. begin
  285. if bestslot^.size=size then
  286. begin
  287. tl:=bestslot;
  288. { Remove from the tempfreelist }
  289. if assigned(bestprev) then
  290. bestprev^.nextfree:=tl^.nextfree
  291. else
  292. tempfreelist:=tl^.nextfree;
  293. end
  294. else
  295. begin
  296. { Duplicate bestlost and the block in the list }
  297. new(tl);
  298. move(bestslot^,tl^,sizeof(ttemprecord));
  299. tl^.next:=bestslot^.next;
  300. bestslot^.next:=tl;
  301. { Now we split the block in 2 parts. Depending on the direction
  302. we need to resize the newly inserted block or the old reused block.
  303. For direction=1 we can use tl for the new block. For direction=-1 we
  304. will be reusing bestslot and resize the new block, that means we need
  305. to swap the pointers }
  306. if (direction=-1) xor
  307. bestatend then
  308. begin
  309. htl:=tl;
  310. tl:=bestslot;
  311. bestslot:=htl;
  312. { Update the tempfreelist to point to the new block }
  313. if assigned(bestprev) then
  314. bestprev^.nextfree:=bestslot
  315. else
  316. tempfreelist:=bestslot;
  317. end;
  318. if not bestatend then
  319. inc(bestslot^.pos,size)
  320. else
  321. inc(tl^.pos,tl^.size-size);
  322. { Create new block and resize the old block }
  323. tl^.size:=size;
  324. tl^.nextfree:=nil;
  325. { Resize the old block }
  326. dec(bestslot^.size,size);
  327. end;
  328. tl^.temptype:=temptype;
  329. tl^.def:=def;
  330. tl^.nextfree:=nil;
  331. end
  332. else
  333. begin
  334. { now we can create the templist entry }
  335. new(tl);
  336. tl^.temptype:=temptype;
  337. tl^.def:=def;
  338. { Extend the temp }
  339. if direction=-1 then
  340. begin
  341. lasttemp:=(-align(-lasttemp,alignment))-size;
  342. tl^.pos:=lasttemp;
  343. end
  344. else
  345. begin
  346. tl^.pos:=align(lasttemp,alignment);
  347. lasttemp:=tl^.pos+size;
  348. end;
  349. tl^.size:=size;
  350. tl^.next:=templist;
  351. tl^.nextfree:=nil;
  352. templist:=tl;
  353. end;
  354. {$ifdef EXTDEBUG}
  355. tl^.posinfo:=current_filepos;
  356. if assigned(tl^.def) then
  357. list.concat(tai_tempalloc.allocinfo(tl^.pos,tl^.size,'allocated with type '+TempTypeStr[tl^.temptype]+' for def '+tl^.def.typename))
  358. else
  359. list.concat(tai_tempalloc.allocinfo(tl^.pos,tl^.size,'allocated with type '+TempTypeStr[tl^.temptype]));
  360. {$else}
  361. list.concat(tai_tempalloc.alloc(tl^.pos,tl^.size));
  362. {$endif}
  363. AllocTemp:=tl^.pos;
  364. end;
  365. procedure ttgobj.FreeTemp(list: TAsmList; pos:longint;temptypes:ttemptypeset);
  366. var
  367. hp,hnext,hprev,hprevfree : ptemprecord;
  368. begin
  369. hp:=templist;
  370. hprev:=nil;
  371. hprevfree:=nil;
  372. while assigned(hp) do
  373. begin
  374. if (hp^.pos=pos) then
  375. begin
  376. { check if already freed }
  377. if hp^.temptype in FreeTempTypes then
  378. begin
  379. {$ifdef EXTDEBUG}
  380. Comment(V_Warning,'tgobj: (FreeTemp) temp at pos '+tostr(pos)+ ' is already free !');
  381. list.concat(tai_tempalloc.allocinfo(hp^.pos,hp^.size,'temp is already freed'));
  382. {$endif}
  383. exit;
  384. end;
  385. { check type that are allowed to be released }
  386. if not(hp^.temptype in temptypes) then
  387. begin
  388. {$ifdef EXTDEBUG}
  389. Comment(V_Debug,'tgobj: (Freetemp) temp at pos '+tostr(pos)+ ' has different type ('+TempTypeStr[hp^.temptype]+'), not releasing');
  390. list.concat(tai_tempalloc.allocinfo(hp^.pos,hp^.size,'temp has wrong type ('+TempTypeStr[hp^.temptype]+') not releasing'));
  391. {$endif}
  392. exit;
  393. end;
  394. list.concat(tai_tempalloc.dealloc(hp^.pos,hp^.size));
  395. { set this block to free }
  396. hp^.temptype:=Used2Free[hp^.temptype];
  397. { Update tempfreelist }
  398. if assigned(hprevfree) then
  399. begin
  400. { Concat blocks when the previous block is free and
  401. there is no block assigned for a tdef }
  402. if assigned(hprev) and
  403. (hp^.temptype=tt_free) and
  404. not assigned(hp^.def) and
  405. (hprev^.temptype=tt_free) and
  406. not assigned(hprev^.def) then
  407. begin
  408. inc(hprev^.size,hp^.size);
  409. if direction=1 then
  410. hprev^.pos:=hp^.pos;
  411. hprev^.next:=hp^.next;
  412. dispose(hp);
  413. hp:=hprev;
  414. end
  415. else
  416. hprevfree^.nextfree:=hp;
  417. end
  418. else
  419. begin
  420. hp^.nextfree:=tempfreelist;
  421. tempfreelist:=hp;
  422. end;
  423. { Concat blocks when the next block is free and
  424. there is no block assigned for a tdef }
  425. hnext:=hp^.next;
  426. if assigned(hnext) and
  427. (hp^.temptype=tt_free) and
  428. not assigned(hp^.def) and
  429. (hnext^.temptype=tt_free) and
  430. not assigned(hnext^.def) then
  431. begin
  432. inc(hp^.size,hnext^.size);
  433. if direction=1 then
  434. hp^.pos:=hnext^.pos;
  435. hp^.nextfree:=hnext^.nextfree;
  436. hp^.next:=hnext^.next;
  437. dispose(hnext);
  438. end;
  439. { Stop }
  440. exit;
  441. end;
  442. if (hp^.temptype=tt_free) then
  443. hprevfree:=hp;
  444. hprev:=hp;
  445. hp:=hp^.next;
  446. end;
  447. end;
  448. procedure ttgobj.gettemp(list: TAsmList; size, alignment : longint;temptype:ttemptype;out ref : treference);
  449. var
  450. varalign : shortint;
  451. begin
  452. varalign:=used_align(alignment,current_settings.alignment.localalignmin,current_settings.alignment.localalignmax);
  453. { can't use reference_reset_base, because that will let tgobj depend
  454. on cgobj (PFV) }
  455. fillchar(ref,sizeof(ref),0);
  456. ref.base:=current_procinfo.framepointer;
  457. ref.offset:=alloctemp(list,size,varalign,temptype,nil);
  458. ref.alignment:=varalign;
  459. end;
  460. procedure ttgobj.gettemptyped(list: TAsmList; def:tdef;temptype:ttemptype;out ref : treference);
  461. var
  462. varalign : shortint;
  463. begin
  464. varalign:=def.alignment;
  465. varalign:=used_align(varalign,current_settings.alignment.localalignmin,current_settings.alignment.localalignmax);
  466. { can't use reference_reset_base, because that will let tgobj depend
  467. on cgobj (PFV) }
  468. fillchar(ref,sizeof(ref),0);
  469. ref.base:=current_procinfo.framepointer;
  470. ref.offset:=alloctemp(list,def.size,varalign,temptype,def);
  471. ref.alignment:=varalign;
  472. end;
  473. function ttgobj.istemp(const ref : treference) : boolean;
  474. begin
  475. { ref.index = R_NO was missing
  476. led to problems with local arrays
  477. with lower bound > 0 (PM) }
  478. if direction = 1 then
  479. begin
  480. istemp:=(ref.base=current_procinfo.framepointer) and
  481. (ref.index=NR_NO) and
  482. (ref.offset>=firsttemp);
  483. end
  484. else
  485. begin
  486. istemp:=(ref.base=current_procinfo.framepointer) and
  487. (ref.index=NR_NO) and
  488. (ref.offset<firsttemp);
  489. end;
  490. end;
  491. function ttgobj.sizeoftemp(list: TAsmList; const ref: treference): longint;
  492. var
  493. hp : ptemprecord;
  494. begin
  495. SizeOfTemp := -1;
  496. hp:=templist;
  497. while assigned(hp) do
  498. begin
  499. if (hp^.pos=ref.offset) then
  500. begin
  501. sizeoftemp := hp^.size;
  502. exit;
  503. end;
  504. hp := hp^.next;
  505. end;
  506. {$ifdef EXTDEBUG}
  507. comment(v_debug,'tgobj: (SizeOfTemp) temp at pos '+tostr(ref.offset)+' not found !');
  508. list.concat(tai_tempalloc.allocinfo(ref.offset,0,'temp not found'));
  509. {$endif}
  510. end;
  511. function ttgobj.changetemptype(list: tasmList; const ref:treference; temptype:ttemptype):boolean;
  512. var
  513. hp : ptemprecord;
  514. begin
  515. ChangeTempType:=false;
  516. hp:=templist;
  517. while assigned(hp) do
  518. begin
  519. if (hp^.pos=ref.offset) then
  520. begin
  521. if hp^.temptype<>tt_free then
  522. begin
  523. {$ifdef EXTDEBUG}
  524. if hp^.temptype=temptype then
  525. Comment(V_Warning,'tgobj: (ChangeTempType) temp'+
  526. ' at pos '+tostr(ref.offset)+ ' is already of the correct type !');
  527. list.concat(tai_tempalloc.allocinfo(hp^.pos,hp^.size,'type changed to '+TempTypeStr[temptype]));
  528. {$endif}
  529. ChangeTempType:=true;
  530. hp^.temptype:=temptype;
  531. end
  532. else
  533. begin
  534. {$ifdef EXTDEBUG}
  535. Comment(V_Warning,'tgobj: (ChangeTempType) temp'+
  536. ' at pos '+tostr(ref.offset)+ ' is already freed !');
  537. list.concat(tai_tempalloc.allocinfo(hp^.pos,hp^.size,'temp is already freed'));
  538. {$endif}
  539. end;
  540. exit;
  541. end;
  542. hp:=hp^.next;
  543. end;
  544. {$ifdef EXTDEBUG}
  545. Comment(V_Warning,'tgobj: (ChangeTempType) temp'+
  546. ' at pos '+tostr(ref.offset)+ ' not found !');
  547. list.concat(tai_tempalloc.allocinfo(ref.offset,0,'temp not found'));
  548. {$endif}
  549. end;
  550. function ttgobj.gettypeoftemp(const ref:treference): ttemptype;
  551. var
  552. hp : ptemprecord;
  553. begin
  554. hp:=templist;
  555. while assigned(hp) do
  556. begin
  557. if (hp^.pos=ref.offset) then
  558. begin
  559. if hp^.temptype<>tt_free then
  560. result:=hp^.temptype
  561. else
  562. internalerror(2007020810);
  563. exit;
  564. end;
  565. hp:=hp^.next;
  566. end;
  567. result:=tt_none;
  568. end;
  569. procedure ttgobj.UnGetTemp(list: TAsmList; const ref : treference);
  570. begin
  571. FreeTemp(list,ref.offset,[tt_normal,tt_noreuse,tt_persistent,tt_regallocator]);
  572. end;
  573. procedure ttgobj.UnGetIfTemp(list: TAsmList; const ref : treference);
  574. begin
  575. if istemp(ref) then
  576. FreeTemp(list,ref.offset,[tt_normal]);
  577. end;
  578. procedure ttgobj.getlocal(list: TAsmList; size : longint;def:tdef;var ref : treference);
  579. begin
  580. getlocal(list, size, def.alignment, def, ref);
  581. end;
  582. procedure ttgobj.getlocal(list: TAsmList; size : longint; alignment : shortint; def:tdef;var ref : treference);
  583. begin
  584. alignment:=used_align(alignment,current_settings.alignment.localalignmin,current_settings.alignment.localalignmax);
  585. { can't use reference_reset_base, because that will let tgobj depend
  586. on cgobj (PFV) }
  587. fillchar(ref,sizeof(ref),0);
  588. ref.base:=current_procinfo.framepointer;
  589. ref.offset:=alloctemp(list,size,alignment,tt_persistent,nil);
  590. ref.alignment:=alignment;
  591. end;
  592. procedure ttgobj.UnGetLocal(list: TAsmList; const ref : treference);
  593. begin
  594. FreeTemp(list,ref.offset,[tt_persistent]);
  595. end;
  596. end.