regvars.pas 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 by Florian Klaempfl and Jonas Maebe
  4. This unit handles register variable allocation
  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 regvars;
  19. {$i defines.inc}
  20. interface
  21. uses
  22. aasm,
  23. node,
  24. symsym,
  25. cpubase, cginfo, tgobj, rgobj;
  26. procedure assign_regvars(p: tnode);
  27. procedure load_regvars(asml: TAAsmoutput; p: tnode);
  28. procedure cleanup_regvars(asml: TAAsmoutput);
  29. procedure store_regvar(asml: TAAsmoutput; reg: tregister);
  30. procedure load_regvar(asml: TAAsmoutput; vsym: tvarsym);
  31. procedure load_regvar_reg(asml: TAAsmoutput; reg: tregister);
  32. procedure load_all_regvars(asml: TAAsmoutput);
  33. procedure sync_regvars(list1, list2: taasmoutput; const regvarsloaded1,
  34. regvarsloaded2: regvar_booleanarray);
  35. implementation
  36. uses
  37. globtype,systems,comphook,
  38. cutils,cclasses,verbose,globals,
  39. symconst,symbase,symtype,symdef,types,
  40. tainst,cgbase,cpuasm,cgobj, cgcpu,cga,rgcpu;
  41. var
  42. parasym : boolean;
  43. procedure searchregvars(p : tnamedindexitem);
  44. var
  45. i,j,k : longint;
  46. begin
  47. if (tsym(p).typ=varsym) and (vo_regable in tvarsym(p).varoptions) then
  48. begin
  49. j:=tvarsym(p).refs;
  50. { parameter get a less value }
  51. if parasym then
  52. begin
  53. if cs_littlesize in aktglobalswitches then
  54. dec(j,1)
  55. else
  56. dec(j,100);
  57. end;
  58. { walk through all momentary register variables }
  59. for i:=1 to maxvarregs do
  60. begin
  61. with pregvarinfo(aktprocdef.regvarinfo)^ do
  62. if ((regvars[i]=nil) or (j>regvars_refs[i])) and (j>0) then
  63. begin
  64. for k:=maxvarregs-1 downto i do
  65. begin
  66. regvars[k+1]:=regvars[k];
  67. regvars_para[k+1]:=regvars_para[k];
  68. regvars_refs[k+1]:=regvars_refs[k];
  69. end;
  70. { calc the new refs
  71. tvarsym(p).refs:=j; }
  72. regvars[i]:=tvarsym(p);
  73. regvars_para[i]:=parasym;
  74. regvars_refs[i]:=j;
  75. break;
  76. end;
  77. end;
  78. end;
  79. end;
  80. procedure searchfpuregvars(p : tnamedindexitem);
  81. var
  82. i,j,k : longint;
  83. begin
  84. if (tsym(p).typ=varsym) and (vo_fpuregable in tvarsym(p).varoptions) then
  85. begin
  86. j:=tvarsym(p).refs;
  87. { parameter get a less value }
  88. if parasym then
  89. begin
  90. if cs_littlesize in aktglobalswitches then
  91. dec(j,1)
  92. else
  93. dec(j,100);
  94. end;
  95. { walk through all momentary register variables }
  96. for i:=1 to maxfpuvarregs do
  97. begin
  98. with pregvarinfo(aktprocdef.regvarinfo)^ do
  99. if ((fpuregvars[i]=nil) or (j>fpuregvars_refs[i])) and (j>0) then
  100. begin
  101. for k:=maxfpuvarregs-1 downto i do
  102. begin
  103. fpuregvars[k+1]:=fpuregvars[k];
  104. fpuregvars_para[k+1]:=fpuregvars_para[k];
  105. fpuregvars_refs[k+1]:=fpuregvars_refs[k];
  106. end;
  107. { calc the new refs
  108. tvarsym(p).refs:=j; }
  109. fpuregvars[i]:=tvarsym(p);
  110. fpuregvars_para[i]:=parasym;
  111. fpuregvars_refs[i]:=j;
  112. break;
  113. end;
  114. end;
  115. end;
  116. end;
  117. procedure assign_regvars(p: tnode);
  118. { register variables }
  119. var
  120. regvarinfo: pregvarinfo;
  121. i: longint;
  122. begin
  123. { max. optimizations }
  124. { only if no asm is used }
  125. { and no try statement }
  126. if (cs_regalloc in aktglobalswitches) and
  127. ((procinfo^.flags and (pi_uses_asm or pi_uses_exceptions))=0) then
  128. begin
  129. new(regvarinfo);
  130. fillchar(regvarinfo^,sizeof(regvarinfo^),0);
  131. aktprocdef.regvarinfo := regvarinfo;
  132. if (p.registers32<4) then
  133. begin
  134. parasym:=false;
  135. symtablestack.foreach_static({$ifdef FPCPROCVAR}@{$endif}searchregvars);
  136. { copy parameter into a register ? }
  137. parasym:=true;
  138. symtablestack.next.foreach_static({$ifdef FPCPROCVAR}@{$endif}searchregvars);
  139. { hold needed registers free }
  140. for i:=maxvarregs downto maxvarregs-p.registers32+1 do
  141. begin
  142. regvarinfo^.regvars[i]:=nil;
  143. regvarinfo^.regvars_para[i] := false;
  144. end;
  145. { now assign register }
  146. for i:=1 to maxvarregs-p.registers32 do
  147. begin
  148. if assigned(regvarinfo^.regvars[i]) and
  149. (rg.reg_pushes[varregs[i]] < regvarinfo^.regvars[i].refs) then
  150. begin
  151. { register is no longer available for }
  152. { expressions }
  153. { search the register which is the most }
  154. { unused }
  155. rg.makeregvar(varregs[i]);
  156. { possibly no 32 bit register are needed }
  157. { call by reference/const ? }
  158. if (regvarinfo^.regvars[i].varspez in [vs_var,vs_out]) or
  159. ((regvarinfo^.regvars[i].varspez=vs_const) and
  160. push_addr_param(regvarinfo^.regvars[i].vartype.def)) then
  161. begin
  162. regvarinfo^.regvars[i].reg:=varregs[i];
  163. end
  164. else
  165. if (regvarinfo^.regvars[i].vartype.def.deftype in [orddef,enumdef]) and
  166. (torddef(regvarinfo^.regvars[i].vartype.def).size=1) then
  167. begin
  168. regvarinfo^.regvars[i].reg:=rg.makeregsize(varregs[i],OS_8);
  169. end
  170. else
  171. if (regvarinfo^.regvars[i].vartype.def.deftype in [orddef,enumdef]) and
  172. (torddef(regvarinfo^.regvars[i].vartype.def).size=2) then
  173. begin
  174. regvarinfo^.regvars[i].reg:=rg.makeregsize(varregs[i],OS_16);
  175. end
  176. else
  177. begin
  178. regvarinfo^.regvars[i].reg:=varregs[i];
  179. end;
  180. { procedure uses this register }
  181. include(rg.usedinproc,varregs[i]);
  182. end
  183. else
  184. begin
  185. regvarinfo^.regvars[i] := nil;
  186. regvarinfo^.regvars_para[i] := false;
  187. end;
  188. end;
  189. end;
  190. if ((p.registersfpu+1)<maxfpuvarregs) then
  191. begin
  192. parasym:=false;
  193. symtablestack.foreach_static({$ifdef FPCPROCVAR}@{$endif}searchfpuregvars);
  194. {$ifdef dummy}
  195. { copy parameter into a register ? }
  196. parasym:=true;
  197. symtablestack.next.foreach_static({$ifdef FPCPROCVAR}@{$endif}searchregvars);
  198. {$endif dummy}
  199. { hold needed registers free }
  200. { in non leaf procedures we must be very careful }
  201. { with assigning registers }
  202. if aktmaxfpuregisters=-1 then
  203. begin
  204. if (procinfo^.flags and pi_do_call)<>0 then
  205. begin
  206. for i:=maxfpuvarregs downto 2 do
  207. regvarinfo^.fpuregvars[i]:=nil;
  208. end
  209. else
  210. begin
  211. for i:=maxfpuvarregs downto maxfpuvarregs-p.registersfpu do
  212. regvarinfo^.fpuregvars[i]:=nil;
  213. end;
  214. end
  215. else
  216. begin
  217. for i:=aktmaxfpuregisters+1 to maxfpuvarregs do
  218. regvarinfo^.fpuregvars[i]:=nil;
  219. end;
  220. { now assign register }
  221. for i:=1 to maxfpuvarregs do
  222. begin
  223. if assigned(regvarinfo^.fpuregvars[i]) then
  224. begin
  225. {$ifdef i386}
  226. { reserve place on the FPU stack }
  227. regvarinfo^.fpuregvars[i].reg:=trgcpu(rg).correct_fpuregister(R_ST0,i);
  228. {$else i386}
  229. rg.makeregvar(regvarinfo^.fpuregvars[i].reg);
  230. {$endif i386}
  231. end;
  232. end;
  233. end;
  234. end;
  235. end;
  236. procedure store_regvar(asml: TAAsmoutput; reg: tregister);
  237. var
  238. i: longint;
  239. hr: treference;
  240. regvarinfo: pregvarinfo;
  241. vsym: tvarsym;
  242. begin
  243. regvarinfo := pregvarinfo(aktprocdef.regvarinfo);
  244. if not assigned(regvarinfo) then
  245. exit;
  246. for i := 1 to maxvarregs do
  247. if assigned(regvarinfo^.regvars[i]) and
  248. (rg.makeregsize(regvarinfo^.regvars[i].reg,OS_INT) = reg) then
  249. begin
  250. if rg.regvar_loaded[rg.makeregsize(reg,OS_INT)] then
  251. begin
  252. vsym := tvarsym(regvarinfo^.regvars[i]);
  253. { we only have to store the regvar back to memory if it's }
  254. { possible that it's been modified (JM) }
  255. if not(vsym.varspez in [vs_const,vs_var,vs_out]) then
  256. begin
  257. reference_reset(hr);
  258. if vsym.owner.symtabletype in [inlinelocalsymtable,localsymtable] then
  259. hr.offset:=-vsym.address+vsym.owner.address_fixup
  260. else
  261. hr.offset:=vsym.address+vsym.owner.address_fixup;
  262. hr.base:=procinfo^.framepointer;
  263. cg.a_load_reg_ref(asml,def_cgsize(vsym.vartype.def),vsym.reg,hr);
  264. end;
  265. asml.concat(Tairegalloc.dealloc(rg.makeregsize(reg,OS_INT)));
  266. rg.regvar_loaded[rg.makeregsize(reg,OS_INT)] := false;
  267. end;
  268. break;
  269. end;
  270. end;
  271. procedure load_regvar(asml: TAAsmoutput; vsym: tvarsym);
  272. var
  273. hr: treference;
  274. opsize: tcgsize;
  275. reg : tregister;
  276. begin
  277. reg:=rg.makeregsize(vsym.reg,OS_INT);
  278. if not rg.regvar_loaded[reg] then
  279. begin
  280. asml.concat(Tairegalloc.alloc(reg));
  281. reference_reset(hr);
  282. if vsym.owner.symtabletype in [inlinelocalsymtable,localsymtable] then
  283. hr.offset:=-vsym.address+vsym.owner.address_fixup
  284. else
  285. hr.offset:=vsym.address+vsym.owner.address_fixup;
  286. hr.base:=procinfo^.framepointer;
  287. if (vsym.varspez in [vs_var,vs_out]) or
  288. ((vsym.varspez=vs_const) and
  289. push_addr_param(vsym.vartype.def)) then
  290. opsize := OS_ADDR
  291. else
  292. opsize := def_cgsize(vsym.vartype.def);
  293. cg.a_load_ref_reg(asml,opsize,hr,reg);
  294. rg.regvar_loaded[reg] := true;
  295. end;
  296. end;
  297. procedure load_regvar_reg(asml: TAAsmoutput; reg: tregister);
  298. var
  299. i: longint;
  300. regvarinfo: pregvarinfo;
  301. reg_spare : tregister;
  302. begin
  303. regvarinfo := pregvarinfo(aktprocdef.regvarinfo);
  304. if not assigned(regvarinfo) then
  305. exit;
  306. reg_spare := rg.makeregsize(reg,OS_INT);
  307. for i := 1 to maxvarregs do
  308. if assigned(regvarinfo^.regvars[i]) and
  309. (rg.makeregsize(regvarinfo^.regvars[i].reg,OS_INT) = reg_spare) then
  310. load_regvar(asml,tvarsym(regvarinfo^.regvars[i]))
  311. end;
  312. procedure load_all_regvars(asml: TAAsmoutput);
  313. var
  314. i: longint;
  315. regvarinfo: pregvarinfo;
  316. begin
  317. regvarinfo := pregvarinfo(aktprocdef.regvarinfo);
  318. if not assigned(regvarinfo) then
  319. exit;
  320. for i := 1 to maxvarregs do
  321. if assigned(regvarinfo^.regvars[i]) {and
  322. (makereg32(regvarinfo^.regvars[i].reg) in [R_EAX,R_EBX,R_ECX,R_EDX])} then
  323. load_regvar(asml,tvarsym(regvarinfo^.regvars[i]))
  324. end;
  325. procedure load_regvars(asml: TAAsmoutput; p: tnode);
  326. var
  327. i: longint;
  328. regvarinfo: pregvarinfo;
  329. begin
  330. if (cs_regalloc in aktglobalswitches) and
  331. ((procinfo^.flags and (pi_uses_asm or pi_uses_exceptions))=0) then
  332. begin
  333. regvarinfo := pregvarinfo(aktprocdef.regvarinfo);
  334. { can happen when inlining assembler procedures (JM) }
  335. if not assigned(regvarinfo) then
  336. exit;
  337. for i:=1 to maxvarregs do
  338. begin
  339. if assigned(regvarinfo^.regvars[i]) then
  340. begin
  341. if cs_asm_source in aktglobalswitches then
  342. asml.insert(Tai_asm_comment.Create(strpnew(regvarinfo^.regvars[i].name+
  343. ' with weight '+tostr(regvarinfo^.regvars[i].refs)+' assigned to register '+
  344. std_reg2str[regvarinfo^.regvars[i].reg])));
  345. if (status.verbosity and v_debug)=v_debug then
  346. Message3(cg_d_register_weight,std_reg2str[regvarinfo^.regvars[i].reg],
  347. tostr(regvarinfo^.regvars[i].refs),regvarinfo^.regvars[i].name);
  348. end;
  349. end;
  350. for i:=1 to maxfpuvarregs do
  351. begin
  352. if assigned(regvarinfo^.fpuregvars[i]) then
  353. begin
  354. {$ifdef i386}
  355. { reserve place on the FPU stack }
  356. regvarinfo^.fpuregvars[i].reg:=trgcpu(rg).correct_fpuregister(R_ST0,i-1);
  357. asml.concat(Taicpu.op_none(A_FLDZ,S_NO));
  358. {$endif i386}
  359. end;
  360. end;
  361. {$ifdef i386}
  362. if assigned(p) then
  363. if cs_asm_source in aktglobalswitches then
  364. asml.insert(Tai_asm_comment.Create(strpnew(tostr(p.registersfpu)+
  365. ' registers on FPU stack used by temp. expressions')));
  366. {$endif i386}
  367. for i:=1 to maxfpuvarregs do
  368. begin
  369. if assigned(regvarinfo^.fpuregvars[i]) then
  370. begin
  371. if cs_asm_source in aktglobalswitches then
  372. asml.insert(Tai_asm_comment.Create(strpnew(regvarinfo^.fpuregvars[i].name+
  373. ' with weight '+tostr(regvarinfo^.fpuregvars[i].refs)+' assigned to register '+
  374. std_reg2str[regvarinfo^.fpuregvars[i].reg])));
  375. if (status.verbosity and v_debug)=v_debug then
  376. Message3(cg_d_register_weight,std_reg2str[regvarinfo^.fpuregvars[i].reg],
  377. tostr(regvarinfo^.fpuregvars[i].refs),regvarinfo^.fpuregvars[i].name);
  378. end;
  379. end;
  380. if cs_asm_source in aktglobalswitches then
  381. asml.insert(Tai_asm_comment.Create(strpnew('Register variable assignment:')));
  382. end;
  383. end;
  384. procedure sync_regvars(list1, list2: taasmoutput; const regvarsloaded1,
  385. regvarsloaded2: regvar_booleanarray);
  386. var
  387. counter: tregister;
  388. begin
  389. for counter := low(rg.regvar_loaded) to high(rg.regvar_loaded) do
  390. begin
  391. rg.regvar_loaded[counter] := regvarsloaded1[counter] and
  392. regvarsloaded2[counter];
  393. if regvarsloaded1[counter] xor regvarsloaded2[counter] then
  394. if regvarsloaded1[counter] then
  395. load_regvar_reg(list2,counter)
  396. else
  397. load_regvar_reg(list1,counter);
  398. end;
  399. end;
  400. procedure cleanup_regvars(asml: TAAsmoutput);
  401. var
  402. i: longint;
  403. reg : tregister;
  404. begin
  405. { can happen when inlining assembler procedures (JM) }
  406. if not assigned(aktprocdef.regvarinfo) then
  407. exit;
  408. if (cs_regalloc in aktglobalswitches) and
  409. ((procinfo^.flags and (pi_uses_asm or pi_uses_exceptions))=0) then
  410. with pregvarinfo(aktprocdef.regvarinfo)^ do
  411. begin
  412. {$ifdef i386}
  413. for i:=1 to maxfpuvarregs do
  414. if assigned(fpuregvars[i]) then
  415. { ... and clean it up }
  416. asml.concat(Taicpu.op_reg(A_FSTP,S_NO,R_ST0));
  417. {$endif i386}
  418. for i := 1 to maxvarregs do
  419. begin
  420. if assigned(regvars[i]) then
  421. begin
  422. reg:=rg.makeregsize(regvars[i].reg,OS_INT);
  423. if (rg.regvar_loaded[reg]) then
  424. asml.concat(Tairegalloc.dealloc(reg));
  425. end;
  426. end;
  427. end;
  428. end;
  429. end.
  430. {
  431. $Log$
  432. Revision 1.29 2002-04-21 15:23:34 carl
  433. + changeregsize -> makeregsize
  434. Revision 1.28 2002/04/19 15:46:03 peter
  435. * mangledname rewrite, tprocdef.mangledname is now created dynamicly
  436. in most cases and not written to the ppu
  437. * add mangeledname_prefix() routine to generate the prefix of
  438. manglednames depending on the current procedure, object and module
  439. * removed static procprefix since the mangledname is now build only
  440. on demand from tprocdef.mangledname
  441. Revision 1.27 2002/04/15 19:44:19 peter
  442. * fixed stackcheck that would be called recursively when a stack
  443. error was found
  444. * generic changeregsize(reg,size) for i386 register resizing
  445. * removed some more routines from cga unit
  446. * fixed returnvalue handling
  447. * fixed default stacksize of linux and go32v2, 8kb was a bit small :-)
  448. Revision 1.26 2002/04/15 19:04:04 carl
  449. + reg2str -> std_reg2str()
  450. Revision 1.25 2002/04/06 18:13:01 jonas
  451. * several powerpc-related additions and fixes
  452. Revision 1.24 2002/04/02 17:11:29 peter
  453. * tlocation,treference update
  454. * LOC_CONSTANT added for better constant handling
  455. * secondadd splitted in multiple routines
  456. * location_force_reg added for loading a location to a register
  457. of a specified size
  458. * secondassignment parses now first the right and then the left node
  459. (this is compatible with Kylix). This saves a lot of push/pop especially
  460. with string operations
  461. * adapted some routines to use the new cg methods
  462. Revision 1.23 2002/03/31 20:26:36 jonas
  463. + a_loadfpu_* and a_loadmm_* methods in tcg
  464. * register allocation is now handled by a class and is mostly processor
  465. independent (+rgobj.pas and i386/rgcpu.pas)
  466. * temp allocation is now handled by a class (+tgobj.pas, -i386\tgcpu.pas)
  467. * some small improvements and fixes to the optimizer
  468. * some register allocation fixes
  469. * some fpuvaroffset fixes in the unary minus node
  470. * push/popusedregisters is now called rg.save/restoreusedregisters and
  471. (for i386) uses temps instead of push/pop's when using -Op3 (that code is
  472. also better optimizable)
  473. * fixed and optimized register saving/restoring for new/dispose nodes
  474. * LOC_FPU locations now also require their "register" field to be set to
  475. R_ST, not R_ST0 (the latter is used for LOC_CFPUREGISTER locations only)
  476. - list field removed of the tnode class because it's not used currently
  477. and can cause hard-to-find bugs
  478. Revision 1.22 2001/12/29 15:32:13 jonas
  479. * powerpc/cgcpu.pas compiles :)
  480. * several powerpc-related fixes
  481. * cpuasm unit is now based on common tainst unit
  482. + nppcmat unit for powerpc (almost complete)
  483. Revision 1.21 2001/12/03 12:17:02 jonas
  484. * forgot to commit yesterday :( (less unnecessary loading of regvars with
  485. if-statements)
  486. Revision 1.20 2001/11/05 16:49:32 jonas
  487. * constant regvars (addresses of var/out para's and const para's) aren't
  488. saved to memory anymore when their register will be destroyed
  489. * unit has been made mostly processor independent
  490. Revision 1.19 2001/11/02 22:58:06 peter
  491. * procsym definition rewrite
  492. Revision 1.18 2001/08/26 13:36:49 florian
  493. * some cg reorganisation
  494. * some PPC updates
  495. Revision 1.17 2001/04/21 12:03:12 peter
  496. * m68k updates merged from fixes branch
  497. Revision 1.16 2001/04/13 01:22:13 peter
  498. * symtable change to classes
  499. * range check generation and errors fixed, make cycle DEBUG=1 works
  500. * memory leaks fixed
  501. Revision 1.15 2000/12/25 00:07:28 peter
  502. + new tlinkedlist class (merge of old tstringqueue,tcontainer and
  503. tlinkedlist objects)
  504. Revision 1.14 2000/12/05 11:44:32 jonas
  505. + new integer regvar handling, should be much more efficient
  506. Revision 1.13 2000/11/29 00:30:39 florian
  507. * unused units removed from uses clause
  508. * some changes for widestrings
  509. Revision 1.12 2000/11/04 14:25:21 florian
  510. + merged Attila's changes for interfaces, not tested yet
  511. Revision 1.11 2000/10/31 22:02:51 peter
  512. * symtable splitted, no real code changes
  513. Revision 1.10 2000/10/14 10:14:52 peter
  514. * moehrendorf oct 2000 rewrite
  515. Revision 1.9 2000/10/01 19:48:25 peter
  516. * lot of compile updates for cg11
  517. Revision 1.8 2000/09/30 16:08:45 peter
  518. * more cg11 updates
  519. Revision 1.7 2000/09/30 13:08:16 jonas
  520. * regvars are now zeroed at the start of their life if they contain an 8
  521. or 16bit var/parameter, because the full 32bits are used if they are
  522. necessary for a btrl instruction
  523. Revision 1.6 2000/09/24 15:06:27 peter
  524. * use defines.inc
  525. Revision 1.5 2000/08/27 16:11:52 peter
  526. * moved some util functions from globals,cobjects to cutils
  527. * splitted files into finput,fmodule
  528. Revision 1.4 2000/08/17 11:07:51 jonas
  529. * fixed crash when inlining assembler procedures with -Or
  530. Revision 1.3 2000/08/04 05:52:00 jonas
  531. * correct version (I also had a regvars.pp locally, which was used
  532. instead of the regvars.pas on CVS, so I didn't notice the errors :( )
  533. Revision 1.2 2000/08/03 14:36:47 jonas
  534. * fixed inserting of allocated register for regvars (only those for
  535. parameters were done, and sometimes even the wrong ones)
  536. Revision 1.1 2000/08/03 13:17:25 jonas
  537. + allow regvars to be used inside inlined procs, which required the
  538. following changes:
  539. + load regvars in genentrycode/free them in genexitcode (cgai386)
  540. * moved all regvar related code to new regvars unit
  541. + added pregvarinfo type to hcodegen
  542. + added regvarinfo field to tprocinfo (symdef/symdefh)
  543. * deallocate the regvars of the caller in secondprocinline before
  544. inlining the called procedure and reallocate them afterwards
  545. }