regvars.pas 25 KB

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