regvars.pas 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741
  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, 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. {$ifdef i386}
  34. procedure sync_regvars_other(list1, list2: taasmoutput; const regvarsloaded1,
  35. regvarsloaded2: regvarother_booleanarray);
  36. procedure sync_regvars_int(list1, list2: taasmoutput; const regvarsloaded1,
  37. regvarsloaded2: Tsupregset);
  38. {$endif i386}
  39. implementation
  40. uses
  41. globtype,systems,comphook,
  42. cutils,cclasses,verbose,globals,
  43. symconst,symbase,symtype,symdef,paramgr,defutil,
  44. cgbase,cgobj,rgcpu;
  45. procedure searchregvars(p : tnamedindexitem;arg:pointer);
  46. var
  47. i,j,k : longint;
  48. parasym : boolean;
  49. begin
  50. parasym:=pboolean(arg)^;
  51. if (tsym(p).typ=varsym) and (vo_regable in tvarsym(p).varoptions) then
  52. begin
  53. j:=tvarsym(p).refs;
  54. { parameter get a less value }
  55. if parasym then
  56. begin
  57. if cs_littlesize in aktglobalswitches then
  58. dec(j,1)
  59. else
  60. dec(j,100);
  61. end;
  62. { walk through all momentary register variables }
  63. for i:=1 to maxvarregs do
  64. begin
  65. with pregvarinfo(current_procdef.regvarinfo)^ do
  66. if ((regvars[i]=nil) or (j>regvars_refs[i])) and (j>0) then
  67. begin
  68. for k:=maxvarregs-1 downto i do
  69. begin
  70. regvars[k+1]:=regvars[k];
  71. regvars_para[k+1]:=regvars_para[k];
  72. regvars_refs[k+1]:=regvars_refs[k];
  73. end;
  74. { calc the new refs
  75. tvarsym(p).refs:=j; }
  76. regvars[i]:=tvarsym(p);
  77. regvars_para[i]:=parasym;
  78. regvars_refs[i]:=j;
  79. break;
  80. end;
  81. end;
  82. end;
  83. end;
  84. procedure searchfpuregvars(p : tnamedindexitem;arg:pointer);
  85. var
  86. i,j,k : longint;
  87. parasym : boolean;
  88. begin
  89. parasym:=pboolean(arg)^;
  90. if (tsym(p).typ=varsym) and (vo_fpuregable in tvarsym(p).varoptions) then
  91. begin
  92. j:=tvarsym(p).refs;
  93. { parameter get a less value }
  94. if parasym then
  95. begin
  96. if cs_littlesize in aktglobalswitches then
  97. dec(j,1)
  98. else
  99. dec(j,100);
  100. end;
  101. { walk through all momentary register variables }
  102. for i:=1 to maxfpuvarregs do
  103. begin
  104. with pregvarinfo(current_procdef.regvarinfo)^ do
  105. if ((fpuregvars[i]=nil) or (j>fpuregvars_refs[i])) and (j>0) then
  106. begin
  107. for k:=maxfpuvarregs-1 downto i do
  108. begin
  109. fpuregvars[k+1]:=fpuregvars[k];
  110. fpuregvars_para[k+1]:=fpuregvars_para[k];
  111. fpuregvars_refs[k+1]:=fpuregvars_refs[k];
  112. end;
  113. { calc the new refs
  114. tvarsym(p).refs:=j; }
  115. fpuregvars[i]:=tvarsym(p);
  116. fpuregvars_para[i]:=parasym;
  117. fpuregvars_refs[i]:=j;
  118. break;
  119. end;
  120. end;
  121. end;
  122. end;
  123. procedure assign_regvars(p: tnode);
  124. { register variables }
  125. var
  126. regvarinfo: pregvarinfo;
  127. i: longint;
  128. parasym : boolean;
  129. r : Tregister;
  130. siz : tcgsize;
  131. begin
  132. { max. optimizations }
  133. { only if no asm is used }
  134. { and no try statement }
  135. if (cs_regalloc in aktglobalswitches) and
  136. not(pi_uses_asm 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_procdef.regvarinfo := regvarinfo;
  142. if (p.registers32<maxvarregs) then
  143. begin
  144. parasym:=false;
  145. symtablestack.foreach_static({$ifdef FPCPROCVAR}@{$endif}searchregvars,@parasym);
  146. { copy parameter into a register ? }
  147. parasym:=true;
  148. symtablestack.next.foreach_static({$ifdef FPCPROCVAR}@{$endif}searchregvars,@parasym);
  149. { hold needed registers free }
  150. for i:=maxvarregs downto maxvarregs-p.registers32+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.registers32 do
  157. begin
  158. if assigned(regvarinfo^.regvars[i]) and
  159. (rg.reg_pushes_int[varregs[i]] < regvarinfo^.regvars[i].refs) then
  160. begin
  161. { register is no longer available for }
  162. { expressions }
  163. { search the register which is the most }
  164. { unused }
  165. rg.makeregvarint(varregs[i]);
  166. { call by reference/const ? }
  167. if (regvarinfo^.regvars[i].varspez in [vs_var,vs_out]) or
  168. ((regvarinfo^.regvars[i].varspez=vs_const) and
  169. paramanager.push_addr_param(regvarinfo^.regvars[i].vartype.def,current_procdef.proccalloption)) then
  170. siz:=OS_32
  171. else
  172. if (regvarinfo^.regvars[i].vartype.def.deftype in [orddef,enumdef]) and
  173. (regvarinfo^.regvars[i].vartype.def.size=1) then
  174. siz:=OS_8
  175. else
  176. if (regvarinfo^.regvars[i].vartype.def.deftype in [orddef,enumdef]) and
  177. (regvarinfo^.regvars[i].vartype.def.size=2) then
  178. siz:=OS_16
  179. else
  180. siz:=OS_32;
  181. regvarinfo^.regvars[i].reg.enum:=R_INTREGISTER;
  182. regvarinfo^.regvars[i].reg.number:=(varregs[i] shl 8) or cgsize2subreg(siz);
  183. {$ifdef i386}
  184. { procedure uses this register }
  185. include(rg.usedintinproc,varregs[i]);
  186. {$endif i386}
  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({$ifdef FPCPROCVAR}@{$endif}searchfpuregvars,@parasym);
  199. {$ifdef dummy}
  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({$ifdef FPCPROCVAR}@{$endif}searchregvars);
  208. {$endif dummy}
  209. { hold needed registers free }
  210. { in non leaf procedures we must be very careful }
  211. { with assigning registers }
  212. if aktmaxfpuregisters=-1 then
  213. begin
  214. if (pi_do_call in current_procinfo.flags) then
  215. begin
  216. for i:=maxfpuvarregs downto 2 do
  217. regvarinfo^.fpuregvars[i]:=nil;
  218. end
  219. else
  220. begin
  221. for i:=maxfpuvarregs downto maxfpuvarregs-p.registersfpu do
  222. regvarinfo^.fpuregvars[i]:=nil;
  223. end;
  224. end
  225. else
  226. begin
  227. for i:=aktmaxfpuregisters+1 to maxfpuvarregs do
  228. regvarinfo^.fpuregvars[i]:=nil;
  229. end;
  230. { now assign register }
  231. for i:=1 to maxfpuvarregs do
  232. begin
  233. if assigned(regvarinfo^.fpuregvars[i]) then
  234. begin
  235. {$ifdef i386}
  236. { reserve place on the FPU stack }
  237. r.enum:=R_ST0;
  238. regvarinfo^.fpuregvars[i].reg:=trgcpu(rg).correct_fpuregister(r,i);
  239. {$else i386}
  240. regvarinfo^.fpuregvars[i].reg.enum:=fpuvarregs[i];
  241. rg.makeregvarother(regvarinfo^.fpuregvars[i].reg);
  242. {$endif i386}
  243. end;
  244. end;
  245. end;
  246. end;
  247. end;
  248. procedure store_regvar(asml: TAAsmoutput; reg: tregister);
  249. var
  250. i: longint;
  251. r : tregister;
  252. hr: treference;
  253. regvarinfo: pregvarinfo;
  254. vsym: tvarsym;
  255. begin
  256. {$ifdef i386}
  257. regvarinfo := pregvarinfo(current_procdef.regvarinfo);
  258. if not assigned(regvarinfo) then
  259. exit;
  260. if reg.enum=R_INTREGISTER then
  261. begin
  262. for i := 1 to maxvarregs do
  263. if assigned(regvarinfo^.regvars[i]) and
  264. (regvarinfo^.regvars[i].reg.number shr 8 = reg.number shr 8) then
  265. begin
  266. if (reg.number shr 8) in rg.regvar_loaded_int then
  267. begin
  268. vsym := tvarsym(regvarinfo^.regvars[i]);
  269. { we only have to store the regvar back to memory if it's }
  270. { possible that it's been modified (JM) }
  271. if not(vsym.varspez in [vs_const,vs_var,vs_out]) then
  272. begin
  273. reference_reset_base(hr,current_procinfo.framepointer,vsym.adjusted_address);
  274. cg.a_load_reg_ref(asml,def_cgsize(vsym.vartype.def),vsym.reg,hr);
  275. end;
  276. asml.concat(tai_regalloc.dealloc(vsym.reg));
  277. exclude(rg.regvar_loaded_int,reg.number shr 8);
  278. end;
  279. break;
  280. end;
  281. end
  282. else
  283. begin
  284. for i := 1 to maxvarregs do
  285. if assigned(regvarinfo^.regvars[i]) then
  286. begin
  287. r:=rg.makeregsize(regvarinfo^.regvars[i].reg,OS_INT);
  288. if (r.enum = reg.enum) then
  289. begin
  290. if rg.regvar_loaded_other[r.enum] then
  291. begin
  292. vsym := tvarsym(regvarinfo^.regvars[i]);
  293. { we only have to store the regvar back to memory if it's }
  294. { possible that it's been modified (JM) }
  295. if not(vsym.varspez in [vs_const,vs_var,vs_out]) then
  296. begin
  297. reference_reset_base(hr,current_procinfo.framepointer,vsym.adjusted_address);
  298. cg.a_load_reg_ref(asml,def_cgsize(vsym.vartype.def),vsym.reg,hr);
  299. end;
  300. asml.concat(tai_regalloc.dealloc(vsym.reg));
  301. rg.regvar_loaded_other[r.enum] := false;
  302. end;
  303. break;
  304. end;
  305. end;
  306. end;
  307. {$endif i386}
  308. end;
  309. procedure load_regvar(asml: TAAsmoutput; vsym: tvarsym);
  310. var
  311. hr: treference;
  312. opsize: tcgsize;
  313. r,
  314. reg : tregister;
  315. begin
  316. {$ifndef i386}
  317. exit;
  318. {$endif i386}
  319. reg:=vsym.reg;
  320. if reg.enum=R_INTREGISTER then
  321. begin
  322. if not((reg.number shr 8) in rg.regvar_loaded_int) then
  323. begin
  324. asml.concat(tai_regalloc.alloc(reg));
  325. reference_reset_base(hr,current_procinfo.framepointer,vsym.adjusted_address);
  326. if (vsym.varspez in [vs_var,vs_out]) or
  327. ((vsym.varspez=vs_const) and
  328. paramanager.push_addr_param(vsym.vartype.def,current_procdef.proccalloption)) then
  329. opsize := OS_ADDR
  330. else
  331. opsize := def_cgsize(vsym.vartype.def);
  332. cg.a_load_ref_reg(asml,opsize,hr,reg);
  333. include(rg.regvar_loaded_int,reg.number shr 8);
  334. end;
  335. end
  336. else
  337. begin
  338. r:=rg.makeregsize(reg,OS_INT);
  339. if not rg.regvar_loaded_other[r.enum] then
  340. begin
  341. asml.concat(tai_regalloc.alloc(reg));
  342. reference_reset_base(hr,current_procinfo.framepointer,vsym.adjusted_address);
  343. if (vsym.varspez in [vs_var,vs_out]) or
  344. ((vsym.varspez=vs_const) and
  345. paramanager.push_addr_param(vsym.vartype.def,current_procdef.proccalloption)) then
  346. opsize := OS_ADDR
  347. else
  348. opsize := def_cgsize(vsym.vartype.def);
  349. cg.a_load_ref_reg(asml,opsize,hr,reg);
  350. rg.regvar_loaded_other[r.enum] := true;
  351. end;
  352. end;
  353. end;
  354. procedure load_regvar_reg(asml: TAAsmoutput; reg: tregister);
  355. var
  356. i: longint;
  357. regvarinfo: pregvarinfo;
  358. reg_spare : tregister;
  359. begin
  360. regvarinfo := pregvarinfo(current_procdef.regvarinfo);
  361. if not assigned(regvarinfo) then
  362. exit;
  363. if reg.enum=R_INTREGISTER then
  364. begin
  365. for i := 1 to maxvarregs do
  366. if assigned(regvarinfo^.regvars[i]) and
  367. (regvarinfo^.regvars[i].reg.number shr 8 = reg.number shr 8) then
  368. load_regvar(asml,tvarsym(regvarinfo^.regvars[i]))
  369. end
  370. else
  371. begin
  372. reg_spare := rg.makeregsize(reg,OS_INT);
  373. if reg_spare.enum>lastreg then
  374. internalerror(2003010801);
  375. for i := 1 to maxvarregs do
  376. if assigned(regvarinfo^.regvars[i]) and
  377. (rg.makeregsize(regvarinfo^.regvars[i].reg,OS_INT).enum = reg_spare.enum) then
  378. load_regvar(asml,tvarsym(regvarinfo^.regvars[i]))
  379. end;
  380. end;
  381. procedure load_all_regvars(asml: TAAsmoutput);
  382. var
  383. i: longint;
  384. regvarinfo: pregvarinfo;
  385. begin
  386. regvarinfo := pregvarinfo(current_procdef.regvarinfo);
  387. if not assigned(regvarinfo) then
  388. exit;
  389. for i := 1 to maxvarregs do
  390. if assigned(regvarinfo^.regvars[i]) then
  391. load_regvar(asml,tvarsym(regvarinfo^.regvars[i]))
  392. end;
  393. procedure load_regvars(asml: TAAsmoutput; p: tnode);
  394. var
  395. i: longint;
  396. regvarinfo: pregvarinfo;
  397. r:Tregister;
  398. begin
  399. if (cs_regalloc in aktglobalswitches) and
  400. not(pi_uses_asm in current_procinfo.flags) and
  401. not(pi_uses_exceptions in current_procinfo.flags) then
  402. begin
  403. regvarinfo := pregvarinfo(current_procdef.regvarinfo);
  404. { can happen when inlining assembler procedures (JM) }
  405. if not assigned(regvarinfo) then
  406. exit;
  407. for i:=1 to maxvarregs do
  408. begin
  409. if assigned(regvarinfo^.regvars[i]) then
  410. begin
  411. r:=regvarinfo^.regvars[i].reg;
  412. convert_register_to_enum(r);
  413. if cs_asm_source in aktglobalswitches then
  414. asml.insert(tai_comment.Create(strpnew(regvarinfo^.regvars[i].name+
  415. ' with weight '+tostr(regvarinfo^.regvars[i].refs)+' assigned to register '+
  416. std_reg2str[r.enum])));
  417. Message3(cg_d_register_weight,std_reg2str[r.enum],
  418. tostr(regvarinfo^.regvars[i].refs),regvarinfo^.regvars[i].name);
  419. end;
  420. end;
  421. for i:=1 to maxfpuvarregs do
  422. begin
  423. if assigned(regvarinfo^.fpuregvars[i]) then
  424. begin
  425. {$ifdef i386}
  426. r.enum:=R_ST0;
  427. { reserve place on the FPU stack }
  428. regvarinfo^.fpuregvars[i].reg:=trgcpu(rg).correct_fpuregister(r,i-1);
  429. asml.concat(Taicpu.op_none(A_FLDZ,S_NO));
  430. {$endif i386}
  431. end;
  432. end;
  433. {$ifdef i386}
  434. if assigned(p) then
  435. if cs_asm_source in aktglobalswitches then
  436. asml.insert(tai_comment.Create(strpnew(tostr(p.registersfpu)+
  437. ' registers on FPU stack used by temp. expressions')));
  438. {$endif i386}
  439. for i:=1 to maxfpuvarregs do
  440. begin
  441. if assigned(regvarinfo^.fpuregvars[i]) then
  442. begin
  443. if cs_asm_source in aktglobalswitches then
  444. asml.insert(tai_comment.Create(strpnew(regvarinfo^.fpuregvars[i].name+
  445. ' with weight '+tostr(regvarinfo^.fpuregvars[i].refs)+' assigned to register '+
  446. std_reg2str[regvarinfo^.fpuregvars[i].reg.enum])));
  447. if (status.verbosity and v_debug)=v_debug then
  448. Message3(cg_d_register_weight,std_reg2str[regvarinfo^.fpuregvars[i].reg.enum],
  449. tostr(regvarinfo^.fpuregvars[i].refs),regvarinfo^.fpuregvars[i].name);
  450. end;
  451. end;
  452. if cs_asm_source in aktglobalswitches then
  453. asml.insert(tai_comment.Create(strpnew('Register variable assignment:')));
  454. end;
  455. end;
  456. {$ifdef i386}
  457. procedure sync_regvars_other(list1, list2: taasmoutput; const regvarsloaded1,
  458. regvarsloaded2: regvarother_booleanarray);
  459. var
  460. counter: tregister;
  461. begin
  462. for counter.enum := low(rg.regvar_loaded_other) to high(rg.regvar_loaded_other) do
  463. begin
  464. rg.regvar_loaded_other[counter.enum] := regvarsloaded1[counter.enum] and
  465. regvarsloaded2[counter.enum];
  466. if regvarsloaded1[counter.enum] xor regvarsloaded2[counter.enum] then
  467. if regvarsloaded1[counter.enum] then
  468. load_regvar_reg(list2,counter)
  469. else
  470. load_regvar_reg(list1,counter);
  471. end;
  472. end;
  473. procedure sync_regvars_int(list1, list2: taasmoutput; const regvarsloaded1,
  474. regvarsloaded2: Tsupregset);
  475. var
  476. i : longint;
  477. r : tregister;
  478. begin
  479. for i:=1 to maxvarregs do
  480. begin
  481. r.enum:=R_INTREGISTER;
  482. r.number:=varregs[i] shl 8;
  483. if (varregs[i] in regvarsloaded1) and
  484. not(varregs[i] in regvarsloaded2) then
  485. load_regvar_reg(list2,r)
  486. else
  487. if (varregs[i] in regvarsloaded2) and
  488. not(varregs[i] in regvarsloaded1) then
  489. load_regvar_reg(list1,r);
  490. end;
  491. end;
  492. {$endif i386}
  493. procedure cleanup_regvars(asml: TAAsmoutput);
  494. var
  495. i: longint;
  496. r,reg : tregister;
  497. begin
  498. { can happen when inlining assembler procedures (JM) }
  499. if not assigned(current_procdef.regvarinfo) then
  500. exit;
  501. if (cs_regalloc in aktglobalswitches) and
  502. not(pi_uses_asm in current_procinfo.flags) and
  503. not(pi_uses_exceptions in current_procinfo.flags) then
  504. with pregvarinfo(current_procdef.regvarinfo)^ do
  505. begin
  506. {$ifdef i386}
  507. r.enum:=R_ST0;
  508. for i:=1 to maxfpuvarregs do
  509. if assigned(fpuregvars[i]) then
  510. { ... and clean it up }
  511. asml.concat(Taicpu.op_reg(A_FSTP,S_NO,r));
  512. {$endif i386}
  513. for i := 1 to maxvarregs do
  514. begin
  515. if assigned(regvars[i]) then
  516. begin
  517. reg:=regvars[i].reg;
  518. if reg.enum=R_INTREGISTER then
  519. begin
  520. if (reg.number shr 8 in rg.regvar_loaded_int) then
  521. asml.concat(tai_regalloc.dealloc(reg));
  522. end
  523. else
  524. begin
  525. reg.number:=(reg.number and not $ff) or cgsize2subreg(OS_INT);
  526. r:=reg;
  527. convert_register_to_enum(r);
  528. if r.enum>lastreg then
  529. internalerror(200201081);
  530. if (rg.regvar_loaded_other[r.enum]) then
  531. asml.concat(tai_regalloc.dealloc(reg));
  532. end;
  533. end;
  534. end;
  535. end;
  536. end;
  537. end.
  538. {
  539. $Log$
  540. Revision 1.52 2003-05-30 18:55:21 jonas
  541. * fixed several regvar related bugs for non-i386. make cycle with -Or now
  542. works for ppc
  543. Revision 1.51 2003/05/23 14:27:35 peter
  544. * remove some unit dependencies
  545. * current_procinfo changes to store more info
  546. Revision 1.50 2003/05/16 14:33:31 peter
  547. * regvar fixes
  548. Revision 1.49 2003/05/15 18:58:53 peter
  549. * removed selfpointer_offset, vmtpointer_offset
  550. * tvarsym.adjusted_address
  551. * address in localsymtable is now in the real direction
  552. * removed some obsolete globals
  553. Revision 1.48 2003/05/12 17:22:00 jonas
  554. * fixed (last?) remaining -tvarsym(X).address to
  555. tg.direction*tvarsym(X).address...
  556. Revision 1.47 2003/04/27 11:21:34 peter
  557. * aktprocdef renamed to current_procdef
  558. * procinfo renamed to current_procinfo
  559. * procinfo will now be stored in current_module so it can be
  560. cleaned up properly
  561. * gen_main_procsym changed to create_main_proc and release_main_proc
  562. to also generate a tprocinfo structure
  563. * fixed unit implicit initfinal
  564. Revision 1.46 2003/03/28 19:16:57 peter
  565. * generic constructor working for i386
  566. * remove fixed self register
  567. * esi added as address register for i386
  568. Revision 1.45 2003/02/19 22:00:14 daniel
  569. * Code generator converted to new register notation
  570. - Horribily outdated todo.txt removed
  571. Revision 1.44 2003/01/08 18:43:57 daniel
  572. * Tregister changed into a record
  573. Revision 1.43 2002/11/25 17:43:24 peter
  574. * splitted defbase in defutil,symutil,defcmp
  575. * merged isconvertable and is_equal into compare_defs(_ext)
  576. * made operator search faster by walking the list only once
  577. Revision 1.42 2002/11/18 17:31:59 peter
  578. * pass proccalloption to ret_in_xxx and push_xxx functions
  579. Revision 1.41 2002/08/25 19:25:20 peter
  580. * sym.insert_in_data removed
  581. * symtable.insertvardata/insertconstdata added
  582. * removed insert_in_data call from symtable.insert, it needs to be
  583. called separatly. This allows to deref the address calculation
  584. * procedures now calculate the parast addresses after the procedure
  585. directives are parsed. This fixes the cdecl parast problem
  586. * push_addr_param has an extra argument that specifies if cdecl is used
  587. or not
  588. Revision 1.40 2002/08/18 20:06:25 peter
  589. * inlining is now also allowed in interface
  590. * renamed write/load to ppuwrite/ppuload
  591. * tnode storing in ppu
  592. * nld,ncon,nbas are already updated for storing in ppu
  593. Revision 1.39 2002/08/17 09:23:41 florian
  594. * first part of procinfo rewrite
  595. Revision 1.38 2002/08/06 20:55:22 florian
  596. * first part of ppc calling conventions fix
  597. Revision 1.37 2002/07/20 11:57:57 florian
  598. * types.pas renamed to defbase.pas because D6 contains a types
  599. unit so this would conflicts if D6 programms are compiled
  600. + Willamette/SSE2 instructions to assembler added
  601. Revision 1.36 2002/07/11 14:41:30 florian
  602. * start of the new generic parameter handling
  603. Revision 1.35 2002/07/01 18:46:25 peter
  604. * internal linker
  605. * reorganized aasm layer
  606. Revision 1.34 2002/06/24 12:43:00 jonas
  607. * fixed errors found with new -CR code from Peter when cycling with -O2p3r
  608. Revision 1.33 2002/05/18 13:34:17 peter
  609. * readded missing revisions
  610. Revision 1.32 2002/05/16 19:46:44 carl
  611. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  612. + try to fix temp allocation (still in ifdef)
  613. + generic constructor calls
  614. + start of tassembler / tmodulebase class cleanup
  615. Revision 1.30 2002/05/12 16:53:10 peter
  616. * moved entry and exitcode to ncgutil and cgobj
  617. * foreach gets extra argument for passing local data to the
  618. iterator function
  619. * -CR checks also class typecasts at runtime by changing them
  620. into as
  621. * fixed compiler to cycle with the -CR option
  622. * fixed stabs with elf writer, finally the global variables can
  623. be watched
  624. * removed a lot of routines from cga unit and replaced them by
  625. calls to cgobj
  626. * u32bit-s32bit updates for and,or,xor nodes. When one element is
  627. u32bit then the other is typecasted also to u32bit without giving
  628. a rangecheck warning/error.
  629. * fixed pascal calling method with reversing also the high tree in
  630. the parast, detected by tcalcst3 test
  631. Revision 1.29 2002/04/21 15:23:34 carl
  632. + changeregsize -> makeregsize
  633. Revision 1.28 2002/04/19 15:46:03 peter
  634. * mangledname rewrite, tprocdef.mangledname is now created dynamicly
  635. in most cases and not written to the ppu
  636. * add mangeledname_prefix() routine to generate the prefix of
  637. manglednames depending on the current procedure, object and module
  638. * removed static procprefix since the mangledname is now build only
  639. on demand from tprocdef.mangledname
  640. Revision 1.27 2002/04/15 19:44:19 peter
  641. * fixed stackcheck that would be called recursively when a stack
  642. error was found
  643. * generic changeregsize(reg,size) for i386 register resizing
  644. * removed some more routines from cga unit
  645. * fixed returnvalue handling
  646. * fixed default stacksize of linux and go32v2, 8kb was a bit small :-)
  647. Revision 1.26 2002/04/15 19:04:04 carl
  648. + reg2str -> std_reg2str()
  649. Revision 1.25 2002/04/06 18:13:01 jonas
  650. * several powerpc-related additions and fixes
  651. Revision 1.24 2002/04/02 17:11:29 peter
  652. * tlocation,treference update
  653. * LOC_CONSTANT added for better constant handling
  654. * secondadd splitted in multiple routines
  655. * location_force_reg added for loading a location to a register
  656. of a specified size
  657. * secondassignment parses now first the right and then the left node
  658. (this is compatible with Kylix). This saves a lot of push/pop especially
  659. with string operations
  660. * adapted some routines to use the new cg methods
  661. Revision 1.23 2002/03/31 20:26:36 jonas
  662. + a_loadfpu_* and a_loadmm_* methods in tcg
  663. * register allocation is now handled by a class and is mostly processor
  664. independent (+rgobj.pas and i386/rgcpu.pas)
  665. * temp allocation is now handled by a class (+tgobj.pas, -i386\tgcpu.pas)
  666. * some small improvements and fixes to the optimizer
  667. * some register allocation fixes
  668. * some fpuvaroffset fixes in the unary minus node
  669. * push/popusedregisters is now called rg.save/restoreusedregisters and
  670. (for i386) uses temps instead of push/pop's when using -Op3 (that code is
  671. also better optimizable)
  672. * fixed and optimized register saving/restoring for new/dispose nodes
  673. * LOC_FPU locations now also require their "register" field to be set to
  674. R_ST, not R_ST0 (the latter is used for LOC_CFPUREGISTER locations only)
  675. - list field removed of the tnode class because it's not used currently
  676. and can cause hard-to-find bugs
  677. }