2
0

regvars.pas 25 KB

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