regvars.pas 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 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 fpcdefs.inc}
  20. interface
  21. uses
  22. aasmbase,aasmtai,aasmcpu,
  23. node,
  24. symsym,
  25. cpubase, cgbase, tgobj;
  26. {$ifdef OLDREGVARS}
  27. procedure assign_regvars(p: tnode);
  28. procedure load_regvars(asml: TAAsmoutput; p: tnode);
  29. procedure cleanup_regvars(asml: TAAsmoutput);
  30. procedure store_regvar(asml: TAAsmoutput; reg: tregister);
  31. procedure load_regvar(asml: TAAsmoutput; vsym: tvarsym);
  32. procedure load_regvar_reg(asml: TAAsmoutput; reg: tregister);
  33. procedure load_all_regvars(asml: TAAsmoutput);
  34. procedure free_regvars(list: taasmoutput);
  35. { procedure translate_regvars(list: taasmoutput); }
  36. {$endif OLDREGVARS}
  37. {$ifdef i386}
  38. (*
  39. procedure sync_regvars_other(list1, list2: taasmoutput; const regvarsloaded1,
  40. regvarsloaded2: regvarother_booleanarray);
  41. procedure sync_regvars_int(list1, list2: taasmoutput; const regvarsloaded1,
  42. regvarsloaded2: Tsuperregisterset);
  43. *)
  44. {$endif i386}
  45. implementation
  46. uses
  47. globtype,systems,comphook,
  48. cutils,cclasses,verbose,globals,
  49. psub,
  50. symconst,symbase,symtype,symdef,paramgr,defutil,
  51. cpuinfo,cgobj,procinfo;
  52. {$ifdef OLDREGVARS}
  53. procedure searchregvars(p : tnamedindexitem;arg:pointer);
  54. var
  55. i,j,k : longint;
  56. parasym : boolean;
  57. begin
  58. parasym:=pboolean(arg)^;
  59. if (tsym(p).typ=varsym) and
  60. ((vo_regable in tvarsym(p).varoptions) or
  61. ((tvarsym(p).varspez in [vs_var,vs_const,vs_out]) and
  62. paramanager.push_addr_param(tvarsym(p).varspez,tvarsym(p).vartype.def,current_procinfo.procdef.proccalloption))) and
  63. not tvarsym(p).vartype.def.needs_inittable then
  64. begin
  65. j:=tvarsym(p).refs;
  66. { walk through all momentary register variables }
  67. for i:=1 to maxvarregs do
  68. begin
  69. with pregvarinfo(current_procinfo.procdef.regvarinfo)^ do
  70. if ((regvars[i]=nil) or (j>regvars_refs[i])) and (j>0) then
  71. begin
  72. for k:=maxvarregs-1 downto i do
  73. begin
  74. regvars[k+1]:=regvars[k];
  75. regvars_para[k+1]:=regvars_para[k];
  76. regvars_refs[k+1]:=regvars_refs[k];
  77. end;
  78. { calc the new refs
  79. tvarsym(p).refs:=j; }
  80. regvars[i]:=tsym(p);
  81. regvars_para[i]:=parasym;
  82. regvars_refs[i]:=j;
  83. break;
  84. end;
  85. end;
  86. end;
  87. end;
  88. procedure searchfpuregvars(p : tnamedindexitem;arg:pointer);
  89. var
  90. i,j,k : longint;
  91. parasym : boolean;
  92. begin
  93. parasym:=pboolean(arg)^;
  94. if (tsym(p).typ=varsym) and (vo_fpuregable in tvarsym(p).varoptions) then
  95. begin
  96. j:=tvarsym(p).refs;
  97. { parameter get a less value }
  98. { walk through all momentary register variables }
  99. for i:=1 to maxfpuvarregs do
  100. begin
  101. with pregvarinfo(current_procinfo.procdef.regvarinfo)^ do
  102. if ((fpuregvars[i]=nil) or (j>fpuregvars_refs[i])) and (j>0) then
  103. begin
  104. for k:=maxfpuvarregs-1 downto i do
  105. begin
  106. fpuregvars[k+1]:=fpuregvars[k];
  107. fpuregvars_para[k+1]:=fpuregvars_para[k];
  108. fpuregvars_refs[k+1]:=fpuregvars_refs[k];
  109. end;
  110. { calc the new refs
  111. tvarsym(p).refs:=j; }
  112. fpuregvars[i]:=tsym(p);
  113. fpuregvars_para[i]:=parasym;
  114. fpuregvars_refs[i]:=j;
  115. break;
  116. end;
  117. end;
  118. end;
  119. end;
  120. procedure assign_regvars(p: tnode);
  121. { register variables }
  122. var
  123. {$ifndef i386}
  124. hp: tparaitem;
  125. {$endif i386}
  126. regvarinfo: pregvarinfo;
  127. i: longint;
  128. parasym : boolean;
  129. siz : tcgsize;
  130. begin
  131. { max. optimizations }
  132. { only if no asm is used }
  133. { and no try statement }
  134. if (cs_regvars in aktglobalswitches) and
  135. { we have to store regvars back to memory in this case (the nested }
  136. { procedures can access the variables of the parent) }
  137. (tcgprocinfo(current_procinfo).nestedprocs.count = 0) and
  138. not(pi_has_assembler_block in current_procinfo.flags) and
  139. not(pi_uses_exceptions in current_procinfo.flags) then
  140. begin
  141. new(regvarinfo);
  142. fillchar(regvarinfo^,sizeof(regvarinfo^),0);
  143. current_procinfo.procdef.regvarinfo := regvarinfo;
  144. if (p.registersint<maxvarregs) then
  145. begin
  146. parasym:=false;
  147. symtablestack.foreach_static({$ifdef FPCPROCVAR}@{$endif}searchregvars,@parasym);
  148. { copy parameter into a register ? }
  149. parasym:=true;
  150. symtablestack.next.foreach_static({$ifdef FPCPROCVAR}@{$endif}searchregvars,@parasym);
  151. { hold needed registers free }
  152. for i:=maxvarregs downto maxvarregs-p.registersint+1 do
  153. begin
  154. regvarinfo^.regvars[i]:=nil;
  155. regvarinfo^.regvars_para[i] := false;
  156. end;
  157. { now assign register }
  158. for i:=1 to maxvarregs-p.registersint do
  159. begin
  160. if assigned(regvarinfo^.regvars[i]) and
  161. { currently we assume we can use registers for all }
  162. { regvars if procedure does no call }
  163. (not(pi_do_call in current_procinfo.flags) or
  164. { otherwise, demand some (arbitrary) minimum usage }
  165. (tvarsym(regvarinfo^.regvars[i]).refs > 100)) then
  166. begin
  167. { register is no longer available for }
  168. { expressions }
  169. { search the register which is the most }
  170. { unused }
  171. { call by reference/const ? }
  172. if paramanager.push_addr_param(tvarsym(regvarinfo^.regvars[i]).varspez,tvarsym(regvarinfo^.regvars[i]).vartype.def,current_procinfo.procdef.proccalloption) then
  173. siz:=OS_32
  174. else
  175. if (tvarsym(regvarinfo^.regvars[i]).vartype.def.deftype in [orddef,enumdef]) and
  176. (tvarsym(regvarinfo^.regvars[i]).vartype.def.size=1) then
  177. siz:=OS_8
  178. else
  179. if (tvarsym(regvarinfo^.regvars[i]).vartype.def.deftype in [orddef,enumdef]) and
  180. (tvarsym(regvarinfo^.regvars[i]).vartype.def.size=2) then
  181. siz:=OS_16
  182. else
  183. siz:=OS_32;
  184. { allocate a register for this regvar }
  185. tvarsym(regvarinfo^.regvars[i]).localloc.register:=cg.getintregister(exprasmlist,siz);
  186. tvarsym(regvarinfo^.regvars[i]).localloc.loc:=LOC_REGISTER;
  187. { and make sure it can't be freed }
  188. { rg.makeregvarint(getsupreg(regvarinfo^.regvars[i].localloc.register));}
  189. end
  190. else
  191. begin
  192. regvarinfo^.regvars[i] := nil;
  193. regvarinfo^.regvars_para[i] := false;
  194. end;
  195. end;
  196. end;
  197. if ((p.registersfpu+1)<maxfpuvarregs) then
  198. begin
  199. parasym:=false;
  200. symtablestack.foreach_static({$ifdef FPCPROCVAR}@{$endif}searchfpuregvars,@parasym);
  201. {$ifndef i386}
  202. { this code should be never enabled because }
  203. { 1. the caller loads parameters into registers }
  204. { 2. (later) the CSE loads a parameter into a }
  205. { register, if necessary }
  206. { (FK) }
  207. { copy parameter into a register ? }
  208. parasym:=true;
  209. symtablestack.next.foreach_static({$ifdef FPCPROCVAR}@{$endif}searchregvars,@parasym);
  210. {$endif i386}
  211. { hold needed registers free }
  212. { in non leaf procedures we must be very careful }
  213. { with assigning registers }
  214. {$ifdef i386}
  215. if aktmaxfpuregisters=-1 then
  216. begin
  217. if (pi_do_call in current_procinfo.flags) then
  218. begin
  219. for i:=maxfpuvarregs downto 2 do
  220. regvarinfo^.fpuregvars[i]:=nil;
  221. end
  222. else
  223. {$endif i386}
  224. begin
  225. for i:=maxfpuvarregs downto maxfpuvarregs-p.registersfpu do
  226. regvarinfo^.fpuregvars[i]:=nil;
  227. end;
  228. {$ifdef i386}
  229. end
  230. else
  231. begin
  232. for i:=aktmaxfpuregisters+1 to maxfpuvarregs do
  233. regvarinfo^.fpuregvars[i]:=nil;
  234. end;
  235. {$endif i386}
  236. { now assign register }
  237. for i:=1 to maxfpuvarregs do
  238. begin
  239. if assigned(regvarinfo^.fpuregvars[i]) then
  240. begin
  241. {$ifdef i386}
  242. { reserve place on the FPU stack }
  243. {$error fixme x86 fpuregvars}
  244. { regvarinfo^.fpuregvars[i].localloc.register:=trgcpu(rg).correct_fpuregister(NR_ST0,i);}
  245. {$else i386}
  246. {$ifdef x86_64}
  247. {$endif x86_64}
  248. begin
  249. tvarsym(regvarinfo^.fpuregvars[i]).localloc.register:=cg.getfpuregister(exprasmlist,OS_F64);
  250. tvarsym(regvarinfo^.fpuregvars[i]).localloc.loc:=LOC_FPUREGISTER;
  251. { rg.makeregvarother(regvarinfo^.fpuregvars[i].localloc.register);}
  252. end;
  253. {$endif i386}
  254. end;
  255. end;
  256. end;
  257. end;
  258. end;
  259. procedure store_regvar(asml: TAAsmoutput; reg: tregister);
  260. var
  261. i: longint;
  262. cgsize : tcgsize;
  263. r : tregister;
  264. hr: treference;
  265. regvarinfo: pregvarinfo;
  266. vsym: tvarsym;
  267. regidx : tregisterindex;
  268. supreg : tsuperregister;
  269. begin
  270. {$ifdef i386}
  271. regvarinfo := pregvarinfo(current_procinfo.procdef.regvarinfo);
  272. if not assigned(regvarinfo) then
  273. exit;
  274. if getregtype(reg)=R_INTREGISTER then
  275. begin
  276. supreg:=getsupreg(reg);
  277. for i := 1 to maxvarregs do
  278. if assigned(regvarinfo^.regvars[i]) and
  279. (getsupreg(tvarsym(regvarinfo^.regvars[i]).localloc.register)=supreg) then
  280. begin
  281. {$warning fixme regvar_loaded_int}
  282. (* if supreg in rg.regvar_loaded_int then
  283. begin
  284. vsym := tvarsym(regvarinfo^.regvars[i]);
  285. { we only have to store the regvar back to memory if it's }
  286. { possible that it's been modified (JM) }
  287. if not(vsym.varspez in [vs_const,vs_var,vs_out]) then
  288. begin
  289. {$warning FIXME Check vsym.localloc for regvars}
  290. // reference_reset_base(hr,current_procinfo.framepointer,vsym.adjusted_address);
  291. cgsize:=def_cgsize(vsym.vartype.def);
  292. cg.a_load_reg_ref(asml,cgsize,cgsize,vsym.localloc.register,hr);
  293. end;
  294. asml.concat(tai_regalloc.dealloc(vsym.localloc.register));
  295. exclude(rg.regvar_loaded_int,supreg);
  296. end;
  297. *)
  298. break;
  299. end;
  300. end
  301. else
  302. begin
  303. for i := 1 to maxvarregs do
  304. if assigned(regvarinfo^.regvars[i]) then
  305. begin
  306. {$warning fixme regvars}
  307. (*
  308. r:=rg.makeregsize(regvarinfo^.regvars[i].localloc.register,OS_INT);
  309. if (r = reg) then
  310. begin
  311. regidx:=findreg_by_number(r);
  312. if rg.regvar_loaded_other[regidx] then
  313. begin
  314. vsym := tvarsym(regvarinfo^.regvars[i]);
  315. { we only have to store the regvar back to memory if it's }
  316. { possible that it's been modified (JM) }
  317. if not(vsym.varspez in [vs_const,vs_var,vs_out]) then
  318. begin
  319. {$warning FIXME Check vsym.localloc for regvars}
  320. // reference_reset_base(hr,current_procinfo.framepointer,vsym.adjusted_address);
  321. cgsize:=def_cgsize(vsym.vartype.def);
  322. cg.a_load_reg_ref(asml,cgsize,cgsize,vsym.localloc.register,hr);
  323. end;
  324. asml.concat(tai_regalloc.dealloc(vsym.localloc.register));
  325. rg.regvar_loaded_other[regidx] := false;
  326. end;
  327. break;
  328. end;
  329. *)
  330. end;
  331. end;
  332. {$endif i386}
  333. end;
  334. procedure load_regvar(asml: TAAsmoutput; vsym: tvarsym);
  335. var
  336. hr: treference;
  337. opsize: tcgsize;
  338. r,
  339. reg : tregister;
  340. regidx : tregisterindex;
  341. begin
  342. {$ifndef i386}
  343. exit;
  344. {$endif i386}
  345. reg:=vsym.localloc.register;
  346. {$warning fixme regvars}
  347. (*
  348. if getregtype(reg)=R_INTREGISTER then
  349. begin
  350. if not(getsupreg(reg) in rg.regvar_loaded_int) then
  351. begin
  352. asml.concat(tai_regalloc.alloc(reg));
  353. {$warning FIXME Check vsym.localloc for regvars}
  354. // reference_reset_base(hr,current_procinfo.framepointer,vsym.adjusted_address);
  355. if paramanager.push_addr_param(vsym.varspez,vsym.vartype.def,current_procinfo.procdef.proccalloption) then
  356. opsize := OS_ADDR
  357. else
  358. opsize := def_cgsize(vsym.vartype.def);
  359. cg.a_load_ref_reg(asml,opsize,opsize,hr,reg);
  360. include(rg.regvar_loaded_int,getsupreg(reg));
  361. end;
  362. end
  363. else
  364. begin
  365. r:=rg.makeregsize(reg,OS_INT);
  366. regidx:=findreg_by_number(r);
  367. if not rg.regvar_loaded_other[regidx] then
  368. begin
  369. asml.concat(tai_regalloc.alloc(reg));
  370. {$warning FIXME Check vsym.localloc for regvars}
  371. // reference_reset_base(hr,current_procinfo.framepointer,vsym.adjusted_address);
  372. if paramanager.push_addr_param(vsym.varspez,vsym.vartype.def,current_procinfo.procdef.proccalloption) then
  373. opsize := OS_ADDR
  374. else
  375. opsize := def_cgsize(vsym.vartype.def);
  376. cg.a_load_ref_reg(asml,opsize,opsize,hr,reg);
  377. rg.regvar_loaded_other[regidx] := true;
  378. end;
  379. end;
  380. *)
  381. end;
  382. procedure load_regvar_reg(asml: TAAsmoutput; reg: tregister);
  383. var
  384. i: longint;
  385. regvarinfo: pregvarinfo;
  386. reg_spare : tregister;
  387. supreg : tsuperregister;
  388. begin
  389. {
  390. regvarinfo := pregvarinfo(current_procinfo.procdef.regvarinfo);
  391. if not assigned(regvarinfo) then
  392. exit;
  393. if getregtype(reg)=R_INTREGISTER then
  394. begin
  395. supreg:=getsupreg(reg);
  396. for i := 1 to maxvarregs do
  397. if assigned(regvarinfo^.regvars[i]) and
  398. (getsupreg(regvarinfo^.regvars[i].localloc.register) = supreg) then
  399. load_regvar(asml,tvarsym(regvarinfo^.regvars[i]))
  400. end
  401. else
  402. begin
  403. reg_spare := cg.makeregsize(reg,OS_INT);
  404. for i := 1 to maxvarregs do
  405. if assigned(regvarinfo^.regvars[i]) and
  406. (cg.makeregsize(regvarinfo^.regvars[i].localloc.register,OS_INT) = reg_spare) then
  407. load_regvar(asml,tvarsym(regvarinfo^.regvars[i]))
  408. end;
  409. }
  410. end;
  411. procedure load_all_regvars(asml: TAAsmoutput);
  412. {
  413. var
  414. i: longint;
  415. regvarinfo: pregvarinfo;
  416. }
  417. begin
  418. {
  419. regvarinfo := pregvarinfo(current_procinfo.procdef.regvarinfo);
  420. if not assigned(regvarinfo) then
  421. exit;
  422. for i := 1 to maxvarregs do
  423. if assigned(regvarinfo^.regvars[i]) then
  424. load_regvar(asml,tvarsym(regvarinfo^.regvars[i]))
  425. }
  426. end;
  427. procedure load_regvars(asml: TAAsmoutput; p: tnode);
  428. var
  429. i: longint;
  430. regvarinfo: pregvarinfo;
  431. begin
  432. if (cs_regvars in aktglobalswitches) and
  433. not(pi_has_assembler_block in current_procinfo.flags) and
  434. not(pi_uses_exceptions in current_procinfo.flags) then
  435. begin
  436. regvarinfo := pregvarinfo(current_procinfo.procdef.regvarinfo);
  437. { can happen when inlining assembler procedures (JM) }
  438. if not assigned(regvarinfo) then
  439. exit;
  440. for i:=1 to maxfpuvarregs do
  441. begin
  442. if assigned(regvarinfo^.fpuregvars[i]) then
  443. begin
  444. {$ifdef i386}
  445. { reserve place on the FPU stack }
  446. {$warning fixme fpustack}
  447. (*
  448. regvarinfo^.fpuregvars[i].localloc.register:=trgcpu(rg).correct_fpuregister(NR_ST0,i-1);
  449. *)
  450. asml.concat(Taicpu.op_none(A_FLDZ,S_NO));
  451. {$endif i386}
  452. end;
  453. end;
  454. {$ifdef i386}
  455. if assigned(p) then
  456. if cs_asm_source in aktglobalswitches then
  457. asml.insert(tai_comment.Create(strpnew(tostr(p.registersfpu)+
  458. ' registers on FPU stack used by temp. expressions')));
  459. {$endif i386}
  460. {
  461. for i:=1 to maxfpuvarregs do
  462. begin
  463. if assigned(regvarinfo^.fpuregvars[i]) then
  464. begin
  465. if cs_asm_source in aktglobalswitches then
  466. asml.insert(tai_comment.Create(strpnew(regvarinfo^.fpuregvars[i].name+
  467. ' with weight '+tostr(regvarinfo^.fpuregvars[i].refs)+' assigned to register '+
  468. std_regname(regvarinfo^.fpuregvars[i].localloc.register))));
  469. if (status.verbosity and v_debug)=v_debug then
  470. Message3(cg_d_register_weight,std_regname(regvarinfo^.fpuregvars[i].localloc.register),
  471. tostr(regvarinfo^.fpuregvars[i].refs),regvarinfo^.fpuregvars[i].name);
  472. end;
  473. end;
  474. if cs_asm_source in aktglobalswitches then
  475. asml.insert(tai_comment.Create(strpnew('Register variable assignment:')));
  476. }
  477. end;
  478. end;
  479. {$ifdef i386}
  480. (*
  481. procedure sync_regvars_other(list1, list2: taasmoutput; const regvarsloaded1,
  482. regvarsloaded2: regvarother_booleanarray);
  483. var
  484. counter: tregisterindex;
  485. begin
  486. for counter := low(rg.regvar_loaded_other) to high(rg.regvar_loaded_other) do
  487. begin
  488. rg.regvar_loaded_other[counter] := regvarsloaded1[counter] and
  489. regvarsloaded2[counter];
  490. if regvarsloaded1[counter] xor regvarsloaded2[counter] then
  491. if regvarsloaded1[counter] then
  492. load_regvar_reg(list2,counter)
  493. else
  494. load_regvar_reg(list1,counter);
  495. end;
  496. end;
  497. procedure sync_regvars_int(list1, list2: taasmoutput; const regvarsloaded1,
  498. regvarsloaded2: Tsuperregisterset);
  499. var
  500. i : longint;
  501. r : tregister;
  502. begin
  503. for i:=1 to maxvarregs do
  504. begin
  505. r:=newreg(R_INTREGISTER,varregs[i],R_SUBWHOLE);
  506. if (varregs[i] in regvarsloaded1) and
  507. not(varregs[i] in regvarsloaded2) then
  508. load_regvar_reg(list2,r)
  509. else
  510. if (varregs[i] in regvarsloaded2) and
  511. not(varregs[i] in regvarsloaded1) then
  512. load_regvar_reg(list1,r);
  513. end;
  514. end;
  515. *)
  516. {$endif i386}
  517. procedure cleanup_regvars(asml: TAAsmoutput);
  518. var
  519. i: longint;
  520. reg : tregister;
  521. regidx : tregisterindex;
  522. begin
  523. { can happen when inlining assembler procedures (JM) }
  524. if not assigned(current_procinfo.procdef.regvarinfo) then
  525. exit;
  526. if (cs_regvars in aktglobalswitches) and
  527. not(pi_has_assembler_block in current_procinfo.flags) and
  528. not(pi_uses_exceptions in current_procinfo.flags) then
  529. with pregvarinfo(current_procinfo.procdef.regvarinfo)^ do
  530. begin
  531. {$ifdef i386}
  532. for i:=1 to maxfpuvarregs do
  533. if assigned(fpuregvars[i]) then
  534. { ... and clean it up }
  535. asml.concat(Taicpu.op_reg(A_FSTP,S_NO,NR_ST0));
  536. {$endif i386}
  537. (*
  538. for i := 1 to maxvarregs do
  539. begin
  540. if assigned(regvars[i]) then
  541. begin
  542. reg:=regvars[i].localloc.register;
  543. if getregtype(reg)=R_INTREGISTER then
  544. begin
  545. end
  546. else
  547. begin
  548. reg:=cg.makeregsize(reg,OS_INT);
  549. regidx:=findreg_by_number(reg);
  550. {$warning fixme regvar dealloc}
  551. {
  552. if (rg.regvar_loaded_other[regidx]) then
  553. asml.concat(tai_regalloc.dealloc(reg));
  554. }
  555. end;
  556. end;
  557. end;
  558. *)
  559. end;
  560. end;
  561. {
  562. Note: this one can't really be "fixed": register colouring happens after
  563. stabs generation. It could still be useful to generate the "var X is
  564. assigned to register Y with weight ZZZ" messages though
  565. procedure translate_regvars(list: taasmoutput);
  566. var
  567. i: longint;
  568. r: tregister;
  569. begin
  570. if not assigned(current_procinfo.procdef.regvarinfo) then
  571. exit;
  572. with pregvarinfo(current_procinfo.procdef.regvarinfo)^ do
  573. begin
  574. for i := 1 to maxvarregs do
  575. if assigned(regvars[i]) then
  576. begin
  577. cg.rg[R_INTREGISTER].translate_register(tvarsym(regvars[i]).localloc.register);
  578. r:=tvarsym(regvars[i]).localloc.register;
  579. if cs_asm_source in aktglobalswitches then
  580. list.insert(tai_comment.Create(strpnew(tvarsym(regvars[i]).name+
  581. ' with weight '+tostr(tvarsym(regvars[i]).refs)+' assigned to register '+
  582. std_regname(r))));
  583. Message3(cg_d_register_weight,std_regname(r),
  584. tostr(tvarsym(regvars[i]).refs),tvarsym(regvars[i]).name);
  585. end;
  586. for i := 1 to maxfpuvarregs do
  587. if assigned(fpuregvars[i]) then
  588. begin
  589. cg.rg[R_FPUREGISTER].translate_register(tvarsym(regvars[i]).localloc.register);
  590. r:=tvarsym(fpuregvars[i]).localloc.register;
  591. if cs_asm_source in aktglobalswitches then
  592. list.insert(tai_comment.Create(strpnew(tvarsym(fpuregvars[i]).name+
  593. ' with weight '+tostr(tvarsym(fpuregvars[i]).refs)+' assigned to register '+
  594. std_regname(r))));
  595. Message3(cg_d_register_weight,std_regname(r),
  596. tostr(tvarsym(fpuregvars[i]).refs),tvarsym(fpuregvars[i]).name);
  597. end;
  598. end;
  599. end;
  600. }
  601. procedure free_regvars(list: taasmoutput);
  602. var
  603. i: longint;
  604. reg: tregister;
  605. size: tcgsize;
  606. begin
  607. if not assigned(current_procinfo.procdef.regvarinfo) then
  608. exit;
  609. with pregvarinfo(current_procinfo.procdef.regvarinfo)^ do
  610. begin
  611. for i := 1 to maxvarregs do
  612. if assigned(regvars[i]) then
  613. begin
  614. reg:=cg.makeregsize(list,tvarsym(regvars[i]).localloc.register,OS_INT);
  615. cg.a_load_reg_reg(list,OS_INT,OS_INT,reg,reg);
  616. end;
  617. for i := 1 to maxfpuvarregs do
  618. if assigned(fpuregvars[i]) then
  619. begin
  620. reg:=tvarsym(fpuregvars[i]).localloc.register;
  621. size:=reg_cgsize(reg);
  622. cg.a_loadfpu_reg_reg(list,size,reg,reg);
  623. end;
  624. end;
  625. end;
  626. {$endif OLDREGVARS}
  627. end.
  628. {
  629. $Log$
  630. Revision 1.80 2004-09-26 17:45:30 peter
  631. * simple regvar support, not yet finished
  632. Revision 1.79 2004/09/25 14:23:54 peter
  633. * ungetregister is now only used for cpuregisters, renamed to
  634. ungetcpuregister
  635. * renamed (get|unget)explicitregister(s) to ..cpuregister
  636. * removed location-release/reference_release
  637. Revision 1.78 2004/09/10 19:59:38 jonas
  638. * clarified comment
  639. Revision 1.77 2004/06/20 08:55:30 florian
  640. * logs truncated
  641. Revision 1.76 2004/06/17 16:55:46 peter
  642. * powerpc compiles again
  643. Revision 1.75 2004/05/30 15:36:55 jonas
  644. * fixed regvars compilation
  645. Revision 1.74 2004/02/08 20:15:42 jonas
  646. - removed taicpu.is_reg_move because it's not used anymore
  647. + support tracking fpu register moves by rgobj for the ppc
  648. Revision 1.73 2004/02/08 18:08:59 jonas
  649. * fixed regvars support. Needs -doldregvars to activate. Only tested with
  650. ppc, other processors should however only require maxregvars and
  651. maxfpuregvars constants in cpubase.pas. Remember to take scratch-
  652. registers into account when defining that value.
  653. Revision 1.72 2004/02/03 22:32:54 peter
  654. * renamed xNNbittype to xNNinttype
  655. * renamed registers32 to registersint
  656. * replace some s32bit,u32bit with torddef([su]inttype).def.typ
  657. }