tgcpu.pas 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712
  1. {
  2. $Id$
  3. Copyright (C) 1998-2000 by Florian Klaempfl
  4. This unit handles the temporary variables stuff for i386
  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 tgcpu;
  19. {$i defines.inc}
  20. interface
  21. uses
  22. cobjects,globals,
  23. hcodegen,verbose,aasm,
  24. node,
  25. cpubase,cpuasm
  26. ;
  27. type
  28. tregisterset = set of tregister;
  29. tpushed = array[R_EAX..R_MM6] of boolean;
  30. tsaved = array[R_EAX..R_MM6] of longint;
  31. const
  32. usablereg32 : byte = 4;
  33. { this value is used in tsaved, if the register isn't saved }
  34. reg_not_saved = $7fffffff;
  35. {$ifdef SUPPORT_MMX}
  36. usableregmmx : byte = 8;
  37. {$endif SUPPORT_MMX}
  38. var
  39. { tries to hold the amount of times which the current tree is processed }
  40. t_times : longint;
  41. {$ifdef TEMPREGDEBUG}
  42. procedure testregisters32;
  43. {$endif TEMPREGDEBUG}
  44. function getregister32 : tregister;
  45. procedure ungetregister32(r : tregister);
  46. { tries to allocate the passed register, if possible }
  47. function getexplicitregister32(r : tregister) : tregister;
  48. {$ifdef SUPPORT_MMX}
  49. function getregistermmx : tregister;
  50. procedure ungetregistermmx(r : tregister);
  51. {$endif SUPPORT_MMX}
  52. procedure ungetregister(r : tregister);
  53. procedure cleartempgen;
  54. procedure del_reference(const ref : treference);
  55. procedure del_locref(const location : tlocation);
  56. procedure del_location(const l : tlocation);
  57. { pushs and restores registers }
  58. procedure pushusedregisters(var pushed : tpushed;b : byte);
  59. procedure popusedregisters(const pushed : tpushed);
  60. { saves register variables (restoring happens automatically (JM) }
  61. procedure saveregvars(b: byte);
  62. { saves and restores used registers to temp. values }
  63. procedure saveusedregisters(var saved : tsaved;b : byte);
  64. procedure restoreusedregisters(const saved : tsaved);
  65. { increments the push count of all registers in b}
  66. procedure incrementregisterpushed(b : byte);
  67. procedure clearregistercount;
  68. procedure resetusableregisters;
  69. { corrects the fpu stack register by ofs }
  70. function correct_fpuregister(r : tregister;ofs : byte) : tregister;
  71. type
  72. {$ifdef SUPPORT_MMX}
  73. regvar_longintarray = array[R_EAX..R_MM6] of longint;
  74. regvar_booleanarray = array[R_EAX..R_MM6] of boolean;
  75. regvar_ptreearray = array[R_EAX..R_MM6] of tnode;
  76. {$else SUPPORT_MMX}
  77. regvar_longintarray = array[R_EAX..R_EDI] of longint;
  78. regvar_booleanarray = array[R_EAX..R_EDI] of boolean;
  79. regvar_ptreearray = array[R_EAX..R_EDI] of tnode;
  80. {$endif SUPPORT_MMX}
  81. var
  82. unused,usableregs : tregisterset;
  83. c_usableregs : longint;
  84. { uses only 1 byte while a set uses in FPC 32 bytes }
  85. usedinproc : byte;
  86. fpuvaroffset : byte;
  87. { count, how much a register must be pushed if it is used as register }
  88. { variable }
  89. reg_pushes : regvar_longintarray;
  90. is_reg_var : regvar_booleanarray;
  91. regvar_loaded: regvar_booleanarray;
  92. {$ifdef TEMPREGDEBUG}
  93. reg_user : regvar_ptreearray;
  94. reg_releaser : regvar_ptreearray;
  95. {$endif TEMPREGDEBUG}
  96. implementation
  97. uses
  98. globtype,temp_gen,regvars;
  99. procedure incrementregisterpushed(b : byte);
  100. var
  101. regi : tregister;
  102. begin
  103. for regi:=R_EAX to R_EDI do
  104. begin
  105. if (b and ($80 shr word(regi)))<>0 then
  106. inc(reg_pushes[regi],t_times*2);
  107. end;
  108. end;
  109. procedure pushusedregisters(var pushed : tpushed;b : byte);
  110. var
  111. r : tregister;
  112. {$ifdef SUPPORT_MMX}
  113. hr : preference;
  114. {$endif}
  115. begin
  116. usedinproc:=usedinproc or b;
  117. for r:=R_EAX to R_EBX do
  118. begin
  119. pushed[r]:=false;
  120. { if the register is used by the calling subroutine }
  121. if ((b and ($80 shr byte(r)))<>0) then
  122. begin
  123. { and is present in use }
  124. if not is_reg_var[r] then
  125. if not(r in unused) then
  126. begin
  127. { then save it }
  128. exprasmlist.concat(Taicpu.Op_reg(A_PUSH,S_L,r));
  129. { here was a big problem !!!!!}
  130. { you cannot do that for a register that is
  131. globally assigned to a var
  132. this also means that you must push it much more
  133. often, but there must be a better way
  134. maybe by putting the value back to the stack !! }
  135. if not(is_reg_var[r]) then
  136. begin
  137. unused:=unused+[r];
  138. {$ifdef TEMPREGDEBUG}
  139. inc(usablereg32);
  140. {$endif TEMPREGDEBUG}
  141. end;
  142. pushed[r]:=true;
  143. end;
  144. end;
  145. end;
  146. {$ifdef SUPPORT_MMX}
  147. for r:=R_MM0 to R_MM6 do
  148. begin
  149. pushed[r]:=false;
  150. { if the mmx register is in use, save it }
  151. if not(r in unused) then
  152. begin
  153. exprasmList.concat(Taicpu.Op_const_reg(A_SUB,S_L,8,R_ESP));
  154. new(hr);
  155. reset_reference(hr^);
  156. hr^.base:=R_ESP;
  157. exprasmList.concat(Taicpu.Op_reg_ref(A_MOVQ,S_NO,r,hr));
  158. if not(is_reg_var[r]) then
  159. begin
  160. unused:=unused+[r];
  161. {$ifdef TEMPREGDEBUG}
  162. inc(usableregmmx);
  163. {$endif TEMPREGDEBUG}
  164. end;
  165. pushed[r]:=true;
  166. end;
  167. end;
  168. {$endif SUPPORT_MMX}
  169. {$ifdef TEMPREGDEBUG}
  170. testregisters32;
  171. {$endif TEMPREGDEBUG}
  172. end;
  173. procedure saveregvars(b: byte);
  174. var
  175. r : tregister;
  176. begin
  177. if not(cs_regalloc in aktglobalswitches) then
  178. exit;
  179. for r:=R_EAX to R_EBX do
  180. { if the register is used by the calling subroutine }
  181. if ((b and ($80 shr byte(r)))<>0) and is_reg_var[r] then
  182. store_regvar(exprasmlist,r)
  183. end;
  184. procedure saveusedregisters(var saved : tsaved;b : byte);
  185. var
  186. r : tregister;
  187. hr : treference;
  188. begin
  189. usedinproc:=usedinproc or b;
  190. for r:=R_EAX to R_EBX do
  191. begin
  192. saved[r]:=reg_not_saved;
  193. { if the register is used by the calling subroutine }
  194. if ((b and ($80 shr byte(r)))<>0) then
  195. begin
  196. { and is present in use }
  197. if not(r in unused) then
  198. begin
  199. { then save it }
  200. gettempofsizereference(4,hr);
  201. saved[r]:=hr.offset;
  202. exprasmList.concat(Taicpu.Op_reg_ref(A_MOV,S_L,r,newreference(hr)));
  203. { here was a big problem !!!!!}
  204. { you cannot do that for a register that is
  205. globally assigned to a var
  206. this also means that you must push it much more
  207. often, but there must be a better way
  208. maybe by putting the value back to the stack !! }
  209. if not(is_reg_var[r]) then
  210. begin
  211. unused:=unused+[r];
  212. {$ifdef TEMPREGDEBUG}
  213. inc(usablereg32);
  214. {$endif TEMPREGDEBUG}
  215. end;
  216. end;
  217. end;
  218. end;
  219. {$ifdef SUPPORT_MMX}
  220. for r:=R_MM0 to R_MM6 do
  221. begin
  222. saved[r]:=reg_not_saved;
  223. { if the mmx register is in use, save it }
  224. if not(r in unused) then
  225. begin
  226. gettempofsizereference(8,hr);
  227. exprasmList.concat(Taicpu.Op_reg_ref(A_MOVQ,S_NO,r,newreference(hr)));
  228. if not(is_reg_var[r]) then
  229. begin
  230. unused:=unused+[r];
  231. {$ifdef TEMPREGDEBUG}
  232. inc(usableregmmx);
  233. {$endif TEMPREGDEBUG}
  234. end;
  235. saved[r]:=hr.offset;
  236. end;
  237. end;
  238. {$endif SUPPORT_MMX}
  239. {$ifdef TEMPREGDEBUG}
  240. testregisters32;
  241. {$endif TEMPREGDEBUG}
  242. end;
  243. procedure popusedregisters(const pushed : tpushed);
  244. var
  245. r : tregister;
  246. {$ifdef SUPPORT_MMX}
  247. hr : preference;
  248. {$endif SUPPORT_MMX}
  249. begin
  250. { restore in reverse order: }
  251. {$ifdef SUPPORT_MMX}
  252. for r:=R_MM6 downto R_MM0 do
  253. begin
  254. if pushed[r] then
  255. begin
  256. new(hr);
  257. reset_reference(hr^);
  258. hr^.base:=R_ESP;
  259. exprasmList.concat(Taicpu.Op_ref_reg(
  260. A_MOVQ,S_NO,hr,r));
  261. exprasmList.concat(Taicpu.Op_const_reg(
  262. A_ADD,S_L,8,R_ESP));
  263. unused:=unused-[r];
  264. {$ifdef TEMPREGDEBUG}
  265. dec(usableregmmx);
  266. {$endif TEMPREGDEBUG}
  267. end;
  268. end;
  269. {$endif SUPPORT_MMX}
  270. for r:=R_EBX downto R_EAX do
  271. if pushed[r] then
  272. begin
  273. exprasmList.concat(Taicpu.Op_reg(A_POP,S_L,r));
  274. {$ifdef TEMPREGDEBUG}
  275. if not (r in unused) then
  276. { internalerror(10)
  277. in cg386cal we always restore regs
  278. that appear as used
  279. due to a unused tmep storage PM }
  280. else
  281. dec(usablereg32);
  282. {$endif TEMPREGDEBUG}
  283. unused:=unused-[r];
  284. end;
  285. {$ifdef TEMPREGDEBUG}
  286. testregisters32;
  287. {$endif TEMPREGDEBUG}
  288. end;
  289. procedure restoreusedregisters(const saved : tsaved);
  290. var
  291. r : tregister;
  292. hr : treference;
  293. begin
  294. { restore in reverse order: }
  295. {$ifdef SUPPORT_MMX}
  296. for r:=R_MM6 downto R_MM0 do
  297. begin
  298. if saved[r]<>reg_not_saved then
  299. begin
  300. reset_reference(hr);
  301. hr.base:=frame_pointer;
  302. hr.offset:=saved[r];
  303. exprasmList.concat(Taicpu.Op_ref_reg(
  304. A_MOVQ,S_NO,newreference(hr),r));
  305. unused:=unused-[r];
  306. {$ifdef TEMPREGDEBUG}
  307. dec(usableregmmx);
  308. {$endif TEMPREGDEBUG}
  309. ungetiftemp(hr);
  310. end;
  311. end;
  312. {$endif SUPPORT_MMX}
  313. for r:=R_EBX downto R_EAX do
  314. if saved[r]<>reg_not_saved then
  315. begin
  316. reset_reference(hr);
  317. hr.base:=frame_pointer;
  318. hr.offset:=saved[r];
  319. exprasmList.concat(Taicpu.Op_ref_reg(A_MOV,S_L,newreference(hr),r));
  320. {$ifdef TEMPREGDEBUG}
  321. if not (r in unused) then
  322. internalerror(10)
  323. else
  324. dec(usablereg32);
  325. {$endif TEMPREGDEBUG}
  326. unused:=unused-[r];
  327. ungetiftemp(hr);
  328. end;
  329. {$ifdef TEMPREGDEBUG}
  330. testregisters32;
  331. {$endif TEMPREGDEBUG}
  332. end;
  333. procedure ungetregister(r : tregister);
  334. begin
  335. if r in [R_EAX,R_ECX,R_EDX,R_EBX,R_ESP,R_EBP,R_ESI,R_EDI] then
  336. ungetregister32(r)
  337. else if r in [R_AX,R_CX,R_DX,R_BX,R_SP,R_BP,R_SI,R_DI] then
  338. ungetregister32(reg16toreg32(r))
  339. else if r in [R_AL,R_BL,R_CL,R_DL] then
  340. ungetregister32(reg8toreg32(r))
  341. {$ifdef SUPPORT_MMX}
  342. else if r in [R_MM0..R_MM6] then
  343. ungetregistermmx(r)
  344. {$endif SUPPORT_MMX}
  345. else internalerror(18);
  346. end;
  347. procedure ungetregister32(r : tregister);
  348. begin
  349. if (r = R_EDI) or
  350. ((not assigned(procinfo^._class)) and (r = R_ESI)) then
  351. begin
  352. exprasmList.concat(Tairegalloc.DeAlloc(r));
  353. exit;
  354. end;
  355. if cs_regalloc in aktglobalswitches then
  356. begin
  357. { takes much time }
  358. if not(r in usableregs) then
  359. exit;
  360. unused:=unused+[r];
  361. inc(usablereg32);
  362. end
  363. else
  364. begin
  365. if not(r in [R_EAX,R_EBX,R_ECX,R_EDX]) then
  366. exit;
  367. {$ifdef TEMPREGDEBUG}
  368. if (r in unused) then
  369. {$ifdef EXTTEMPREGDEBUG}
  370. begin
  371. Comment(V_Debug,'register freed twice '+reg2str(r));
  372. testregisters32;
  373. exit;
  374. end
  375. {$else EXTTEMPREGDEBUG}
  376. exit
  377. {$endif EXTTEMPREGDEBUG}
  378. else
  379. {$endif TEMPREGDEBUG}
  380. inc(usablereg32);
  381. unused:=unused+[r];
  382. {$ifdef TEMPREGDEBUG}
  383. reg_releaser[r]:=curptree^;
  384. {$endif TEMPREGDEBUG}
  385. end;
  386. exprasmList.concat(Tairegalloc.DeAlloc(r));
  387. {$ifdef TEMPREGDEBUG}
  388. testregisters32;
  389. {$endif TEMPREGDEBUG}
  390. end;
  391. {$ifdef SUPPORT_MMX}
  392. function getregistermmx : tregister;
  393. var
  394. r : tregister;
  395. begin
  396. dec(usableregmmx);
  397. for r:=R_MM0 to R_MM6 do
  398. if r in unused then
  399. begin
  400. unused:=unused-[r];
  401. usedinproc:=usedinproc or ($80 shr byte(R_EAX));
  402. getregistermmx:=r;
  403. exit;
  404. end;
  405. internalerror(10);
  406. end;
  407. procedure ungetregistermmx(r : tregister);
  408. begin
  409. if cs_regalloc in aktglobalswitches then
  410. begin
  411. { takes much time }
  412. if not(r in usableregs) then
  413. exit;
  414. unused:=unused+[r];
  415. inc(usableregmmx);
  416. end
  417. else
  418. begin
  419. unused:=unused+[r];
  420. inc(usableregmmx);
  421. end;
  422. end;
  423. {$endif SUPPORT_MMX}
  424. procedure del_reference(const ref : treference);
  425. begin
  426. if ref.is_immediate then
  427. exit;
  428. ungetregister32(ref.base);
  429. ungetregister32(ref.index);
  430. end;
  431. procedure del_locref(const location : tlocation);
  432. begin
  433. if (location.loc<>loc_mem) and (location.loc<>loc_reference) then
  434. exit;
  435. if location.reference.is_immediate then
  436. exit;
  437. ungetregister32(location.reference.base);
  438. ungetregister32(location.reference.index);
  439. end;
  440. procedure del_location(const l : tlocation);
  441. begin
  442. case l.loc of
  443. LOC_REGISTER :
  444. ungetregister(l.register);
  445. LOC_MEM,LOC_REFERENCE :
  446. del_reference(l.reference);
  447. end;
  448. end;
  449. {$ifdef TEMPREGDEBUG}
  450. procedure testregisters32;
  451. var test : byte;
  452. begin
  453. test:=0;
  454. if R_EAX in unused then
  455. inc(test);
  456. if R_EBX in unused then
  457. inc(test);
  458. if R_ECX in unused then
  459. inc(test);
  460. if R_EDX in unused then
  461. inc(test);
  462. if test<>usablereg32 then
  463. internalerror(10);
  464. end;
  465. {$endif TEMPREGDEBUG}
  466. function getregister32 : tregister;
  467. begin
  468. if usablereg32=0 then
  469. internalerror(10);
  470. {$ifdef TEMPREGDEBUG}
  471. if curptree^^.usableregs-usablereg32>curptree^^.registers32 then
  472. internalerror(10);
  473. {$endif TEMPREGDEBUG}
  474. {$ifdef EXTTEMPREGDEBUG}
  475. if curptree^^.usableregs-usablereg32>curptree^^.reallyusedregs then
  476. curptree^^.reallyusedregs:=curptree^^.usableregs-usablereg32;
  477. {$endif EXTTEMPREGDEBUG}
  478. dec(usablereg32);
  479. if R_EAX in unused then
  480. begin
  481. unused:=unused-[R_EAX];
  482. usedinproc:=usedinproc or ($80 shr byte(R_EAX));
  483. getregister32:=R_EAX;
  484. {$ifdef TEMPREGDEBUG}
  485. reg_user[R_EAX]:=curptree^;
  486. {$endif TEMPREGDEBUG}
  487. exprasmList.concat(Tairegalloc.Alloc(R_EAX));
  488. end
  489. else if R_EDX in unused then
  490. begin
  491. unused:=unused-[R_EDX];
  492. usedinproc:=usedinproc or ($80 shr byte(R_EDX));
  493. getregister32:=R_EDX;
  494. {$ifdef TEMPREGDEBUG}
  495. reg_user[R_EDX]:=curptree^;
  496. {$endif TEMPREGDEBUG}
  497. exprasmList.concat(Tairegalloc.Alloc(R_EDX));
  498. end
  499. else if R_EBX in unused then
  500. begin
  501. unused:=unused-[R_EBX];
  502. usedinproc:=usedinproc or ($80 shr byte(R_EBX));
  503. getregister32:=R_EBX;
  504. {$ifdef TEMPREGDEBUG}
  505. reg_user[R_EBX]:=curptree^;
  506. {$endif TEMPREGDEBUG}
  507. exprasmList.concat(Tairegalloc.Alloc(R_EBX));
  508. end
  509. else if R_ECX in unused then
  510. begin
  511. unused:=unused-[R_ECX];
  512. usedinproc:=usedinproc or ($80 shr byte(R_ECX));
  513. getregister32:=R_ECX;
  514. {$ifdef TEMPREGDEBUG}
  515. reg_user[R_ECX]:=curptree^;
  516. {$endif TEMPREGDEBUG}
  517. exprasmList.concat(Tairegalloc.Alloc(R_ECX));
  518. end
  519. else internalerror(10);
  520. {$ifdef TEMPREGDEBUG}
  521. testregisters32;
  522. {$endif TEMPREGDEBUG}
  523. end;
  524. function getexplicitregister32(r : tregister) : tregister;
  525. begin
  526. if r in [R_ESI,R_EDI] then
  527. begin
  528. exprasmList.concat(Tairegalloc.Alloc(r));
  529. getexplicitregister32 := r;
  530. exit;
  531. end;
  532. if r in unused then
  533. begin
  534. dec(usablereg32);
  535. {$ifdef TEMPREGDEBUG}
  536. if curptree^^.usableregs-usablereg32>curptree^^.registers32 then
  537. internalerror(10);
  538. reg_user[r]:=curptree^;
  539. {$endif TEMPREGDEBUG}
  540. unused:=unused-[r];
  541. usedinproc:=usedinproc or ($80 shr byte(r));
  542. exprasmList.concat(Tairegalloc.Alloc(r));
  543. getexplicitregister32:=r;
  544. {$ifdef TEMPREGDEBUG}
  545. testregisters32;
  546. {$endif TEMPREGDEBUG}
  547. end
  548. else
  549. getexplicitregister32:=getregister32;
  550. end;
  551. procedure cleartempgen;
  552. begin
  553. unused:=usableregs;
  554. usablereg32:=c_usableregs;
  555. {fpuvaroffset:=0;
  556. this must only be resetted at each procedure
  557. compilation start PM }
  558. end;
  559. procedure clearregistercount;
  560. var
  561. regi : tregister;
  562. begin
  563. {$ifdef SUPPORT_MMX}
  564. for regi:=R_EAX to R_MM6 do
  565. begin
  566. reg_pushes[regi]:=0;
  567. is_reg_var[regi]:=false;
  568. end;
  569. {$else SUPPORT_MMX}
  570. for regi:=R_EAX to R_EDI do
  571. begin
  572. reg_pushes[regi]:=0;
  573. is_reg_var[regi]:=false;
  574. end;
  575. {$endif SUPPORT_MMX}
  576. end;
  577. function correct_fpuregister(r : tregister;ofs : byte) : tregister;
  578. begin
  579. correct_fpuregister:=tregister(longint(r)+ofs);
  580. end;
  581. procedure resetusableregisters;
  582. begin
  583. {$ifdef SUPPORT_MMX}
  584. usableregs:=[R_EAX,R_EBX,R_ECX,R_EDX,R_MM0..R_MM6];
  585. c_usableregs:=4;
  586. usableregmmx:=8;
  587. {$else}
  588. usableregs:=[R_EAX,R_EBX,R_ECX,R_EDX];
  589. c_usableregs:=4;
  590. {$endif SUPPORT_MMX}
  591. fillchar(regvar_loaded,sizeof(regvar_loaded),false);
  592. fillchar(is_reg_var,sizeof(is_reg_var),false);
  593. fpuvaroffset:=0;
  594. end;
  595. begin
  596. resetusableregisters;
  597. end.
  598. {
  599. $Log$
  600. Revision 1.3 2000-12-25 00:07:34 peter
  601. + new tlinkedlist class (merge of old tstringqueue,tcontainer and
  602. tlinkedlist objects)
  603. Revision 1.2 2000/12/05 11:44:34 jonas
  604. + new integer regvar handling, should be much more efficient
  605. Revision 1.1 2000/11/29 00:30:51 florian
  606. * unused units removed from uses clause
  607. * some changes for widestrings
  608. Revision 1.9 2000/10/31 22:30:13 peter
  609. * merged asm result patch part 2
  610. Revision 1.8 2000/10/14 10:14:56 peter
  611. * moehrendorf oct 2000 rewrite
  612. Revision 1.7 2000/09/30 16:08:46 peter
  613. * more cg11 updates
  614. Revision 1.6 2000/09/24 15:06:32 peter
  615. * use defines.inc
  616. Revision 1.5 2000/08/27 16:11:55 peter
  617. * moved some util functions from globals,cobjects to cutils
  618. * splitted files into finput,fmodule
  619. Revision 1.4 2000/08/05 13:32:39 peter
  620. * fixed build prob without support_mmx
  621. Revision 1.3 2000/08/04 05:09:49 jonas
  622. * forgot to commit :( (part of regvar changes)
  623. Revision 1.2 2000/07/13 11:32:52 michael
  624. + removed logs
  625. }