cgbase.pas 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 by Florian Klaempfl
  4. This unit exports some help routines for the code generation
  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. {# Some helpers for the code generator.
  19. }
  20. unit cgbase;
  21. {$i fpcdefs.inc}
  22. interface
  23. uses
  24. { common }
  25. cclasses,
  26. { global }
  27. globals,verbose,
  28. { symtable }
  29. symconst,symtype,symdef,symsym,
  30. { aasm }
  31. cpubase,cpuinfo,cginfo,aasmbase,aasmtai
  32. ;
  33. const
  34. {# bitmask indicating if the procedure uses asm }
  35. pi_uses_asm = $1;
  36. {# bitmask indicating if the procedure is exported by an unit }
  37. pi_is_global = $2;
  38. {# bitmask indicating if the procedure does a call }
  39. pi_do_call = $4;
  40. {# bitmask indicating if the procedure is an operator }
  41. pi_operator = $8;
  42. {# bitmask indicating if the procedure is an external C function }
  43. pi_c_import = $10;
  44. {# bitmask indicating if the procedure has a try statement = no register optimization }
  45. pi_uses_exceptions = $20;
  46. {# bitmask indicating if the procedure is declared as @var(assembler), don't optimize}
  47. pi_is_assembler = $40;
  48. {# bitmask indicating if the procedure contains data which needs to be finalized }
  49. pi_needs_implicit_finally = $80;
  50. type
  51. {# This object gives information on the current routine being
  52. compiled.
  53. }
  54. tprocinfo = class
  55. { pointer to parent in nested procedures }
  56. parent : tprocinfo;
  57. {# current class, if we are in a method }
  58. _class : tobjectdef;
  59. {# the definition of the routine itself }
  60. procdef : tprocdef;
  61. {# offset from frame pointer to get parent frame pointer reference
  62. (used in nested routines only)
  63. }
  64. framepointer_offset : longint;
  65. {# offset from frame pointer to get self reference }
  66. selfpointer_offset : longint;
  67. {# result value offset in stack (functions only) }
  68. return_offset : longint;
  69. {# firsttemp position }
  70. firsttemp_offset : longint;
  71. {# offset from frame pointer to parameters }
  72. para_offset : longint;
  73. {# some collected informations about the procedure
  74. see pi_xxxx constants above
  75. }
  76. flags : longint;
  77. {# register used as frame pointer }
  78. framepointer : tregister;
  79. {# true, if the procedure is exported by a unit }
  80. globalsymbol : boolean;
  81. {# true, if the procedure should be exported (only OS/2) }
  82. exported : boolean;
  83. {# true, if we can not use fast exit code }
  84. no_fast_exit : boolean;
  85. {# Holds the environment reference for default exceptions
  86. The exception reference is created when ansistrings
  87. or classes are used. It holds buffer for exception
  88. frames. It is allocted by g_new_exception.
  89. }
  90. exception_env_ref : treference;
  91. {# Holds the environment reference for default exceptions
  92. The exception reference is created when ansistrings
  93. or classes are used. It holds buffer for setjmp
  94. It is allocted by g_new_exception.
  95. }
  96. exception_jmp_ref :treference;
  97. {# Holds the environment reference for default exceptions
  98. The exception reference is created when ansistrings
  99. or classes are used. It holds the location where
  100. temporary storage of the setjmp result is stored.
  101. This reference can be unused, if the result is instead
  102. saved on the stack.
  103. }
  104. exception_result_ref :treference;
  105. {# Holds the reference used to store alll saved registers.
  106. This is used on systems which do not have direct stack
  107. operations (such as the PowerPC), it is unused on other
  108. systems
  109. }
  110. save_regs_ref : treference;
  111. {# The code for the routine itself, excluding entry and
  112. exit code. This is a linked list of tai classes.
  113. }
  114. aktproccode : taasmoutput;
  115. {# The code for the routine entry code.
  116. }
  117. aktentrycode: taasmoutput;
  118. {# The code for the routine exit code.
  119. }
  120. aktexitcode: taasmoutput;
  121. aktlocaldata : taasmoutput;
  122. constructor create;virtual;
  123. destructor destroy;override;
  124. procedure allocate_interrupt_stackframe;virtual;
  125. { Updates usedinproc depending on the resulttype }
  126. procedure update_usedinproc_result;virtual;
  127. { Does the necessary stuff before a procedure body is compiled }
  128. procedure handle_body_start;virtual;
  129. { This is called by parser, after the header of a subroutine is parsed.
  130. If the local symtable offset depends on the para symtable size, the
  131. necessary stuff must be done here.
  132. }
  133. procedure after_header;virtual;
  134. { This procedure is called after the pass 1 of the subroutine body is done.
  135. Here the address fix ups to generate code for the body must be done.
  136. }
  137. procedure after_pass1;virtual;
  138. { sets the offset for a temp used by the result }
  139. procedure set_result_offset;virtual;
  140. end;
  141. pregvarinfo = ^tregvarinfo;
  142. tregvarinfo = record
  143. regvars : array[1..maxvarregs] of tvarsym;
  144. regvars_para : array[1..maxvarregs] of boolean;
  145. regvars_refs : array[1..maxvarregs] of longint;
  146. fpuregvars : array[1..maxfpuvarregs] of tvarsym;
  147. fpuregvars_para : array[1..maxfpuvarregs] of boolean;
  148. fpuregvars_refs : array[1..maxfpuvarregs] of longint;
  149. end;
  150. var
  151. {# information about the current sub routine being parsed (@var(pprocinfo))}
  152. procinfo : tprocinfo;
  153. cprocinfo : class of tprocinfo;
  154. { labels for BREAK and CONTINUE }
  155. aktbreaklabel,aktcontinuelabel : tasmlabel;
  156. { label when the result is true or false }
  157. truelabel,falselabel : tasmlabel;
  158. { label to leave the sub routine }
  159. aktexitlabel : tasmlabel;
  160. { also an exit label, only used we need to clear only the stack }
  161. aktexit2label : tasmlabel;
  162. {# only used in constructor for fail keyword or if getmem fails }
  163. faillabel : tasmlabel;
  164. quickexitlabel : tasmlabel;
  165. {# true, if there was an error while code generation occurs }
  166. codegenerror : boolean;
  167. { save the size of pushed parameter, needed for aligning }
  168. pushedparasize : longint;
  169. { message calls with codegenerror support }
  170. procedure cgmessage(t : longint);
  171. procedure cgmessage1(t : longint;const s : string);
  172. procedure cgmessage2(t : longint;const s1,s2 : string);
  173. procedure cgmessage3(t : longint;const s1,s2,s3 : string);
  174. procedure CGMessagePos(const pos:tfileposinfo;t:longint);
  175. procedure CGMessagePos1(const pos:tfileposinfo;t:longint;const s1:string);
  176. procedure CGMessagePos2(const pos:tfileposinfo;t:longint;const s1,s2:string);
  177. procedure CGMessagePos3(const pos:tfileposinfo;t:longint;const s1,s2,s3:string);
  178. { initialize respectively terminates the code generator }
  179. { for a new module or procedure }
  180. procedure codegen_doneprocedure;
  181. procedure codegen_donemodule;
  182. procedure codegen_newmodule;
  183. procedure codegen_newprocedure;
  184. {# From a definition return the abstract code generator size enum. It is
  185. to note that the value returned can be @var(OS_NO) }
  186. function def_cgsize(def: tdef): tcgsize;
  187. {# From a constant numeric value, return the abstract code generator
  188. size.
  189. }
  190. function int_cgsize(const l: byte): tcgsize;
  191. {# return the inverse condition of opcmp }
  192. function inverse_opcmp(opcmp: topcmp): topcmp;
  193. {# return whether op is commutative }
  194. function commutativeop(op: topcg): boolean;
  195. implementation
  196. uses
  197. systems,
  198. cresstr,
  199. tgobj,rgobj,
  200. defbase,
  201. fmodule
  202. {$ifdef fixLeaksOnError}
  203. ,comphook
  204. {$endif fixLeaksOnError}
  205. ,symbase,paramgr
  206. ;
  207. {$ifdef fixLeaksOnError}
  208. var procinfoStack: TStack;
  209. hcodegen_old_do_stop: tstopprocedure;
  210. {$endif fixLeaksOnError}
  211. {*****************************************************************************
  212. override the message calls to set codegenerror
  213. *****************************************************************************}
  214. procedure cgmessage(t : longint);
  215. var
  216. olderrorcount : longint;
  217. begin
  218. if not(codegenerror) then
  219. begin
  220. olderrorcount:=Errorcount;
  221. verbose.Message(t);
  222. codegenerror:=olderrorcount<>Errorcount;
  223. end;
  224. end;
  225. procedure cgmessage1(t : longint;const s : string);
  226. var
  227. olderrorcount : longint;
  228. begin
  229. if not(codegenerror) then
  230. begin
  231. olderrorcount:=Errorcount;
  232. verbose.Message1(t,s);
  233. codegenerror:=olderrorcount<>Errorcount;
  234. end;
  235. end;
  236. procedure cgmessage2(t : longint;const s1,s2 : string);
  237. var
  238. olderrorcount : longint;
  239. begin
  240. if not(codegenerror) then
  241. begin
  242. olderrorcount:=Errorcount;
  243. verbose.Message2(t,s1,s2);
  244. codegenerror:=olderrorcount<>Errorcount;
  245. end;
  246. end;
  247. procedure cgmessage3(t : longint;const s1,s2,s3 : string);
  248. var
  249. olderrorcount : longint;
  250. begin
  251. if not(codegenerror) then
  252. begin
  253. olderrorcount:=Errorcount;
  254. verbose.Message3(t,s1,s2,s3);
  255. codegenerror:=olderrorcount<>Errorcount;
  256. end;
  257. end;
  258. procedure cgmessagepos(const pos:tfileposinfo;t : longint);
  259. var
  260. olderrorcount : longint;
  261. begin
  262. if not(codegenerror) then
  263. begin
  264. olderrorcount:=Errorcount;
  265. verbose.MessagePos(pos,t);
  266. codegenerror:=olderrorcount<>Errorcount;
  267. end;
  268. end;
  269. procedure cgmessagepos1(const pos:tfileposinfo;t : longint;const s1 : string);
  270. var
  271. olderrorcount : longint;
  272. begin
  273. if not(codegenerror) then
  274. begin
  275. olderrorcount:=Errorcount;
  276. verbose.MessagePos1(pos,t,s1);
  277. codegenerror:=olderrorcount<>Errorcount;
  278. end;
  279. end;
  280. procedure cgmessagepos2(const pos:tfileposinfo;t : longint;const s1,s2 : string);
  281. var
  282. olderrorcount : longint;
  283. begin
  284. if not(codegenerror) then
  285. begin
  286. olderrorcount:=Errorcount;
  287. verbose.MessagePos2(pos,t,s1,s2);
  288. codegenerror:=olderrorcount<>Errorcount;
  289. end;
  290. end;
  291. procedure cgmessagepos3(const pos:tfileposinfo;t : longint;const s1,s2,s3 : string);
  292. var
  293. olderrorcount : longint;
  294. begin
  295. if not(codegenerror) then
  296. begin
  297. olderrorcount:=Errorcount;
  298. verbose.MessagePos3(pos,t,s1,s2,s3);
  299. codegenerror:=olderrorcount<>Errorcount;
  300. end;
  301. end;
  302. {****************************************************************************
  303. TProcInfo
  304. ****************************************************************************}
  305. constructor tprocinfo.create;
  306. begin
  307. parent:=nil;
  308. _class:=nil;
  309. procdef:=nil;
  310. framepointer_offset:=0;
  311. selfpointer_offset:=0;
  312. return_offset:=0;
  313. firsttemp_offset:=0;
  314. para_offset:=0;
  315. flags:=0;
  316. framepointer:=R_NO;
  317. globalsymbol:=false;
  318. exported:=false;
  319. no_fast_exit:=false;
  320. aktentrycode:=Taasmoutput.Create;
  321. aktexitcode:=Taasmoutput.Create;
  322. aktproccode:=Taasmoutput.Create;
  323. aktlocaldata:=Taasmoutput.Create;
  324. reference_reset(exception_env_ref);
  325. reference_reset(exception_jmp_ref);
  326. reference_reset(exception_result_ref);
  327. end;
  328. destructor tprocinfo.destroy;
  329. begin
  330. aktentrycode.free;
  331. aktexitcode.free;
  332. aktproccode.free;
  333. aktlocaldata.free;
  334. end;
  335. procedure tprocinfo.allocate_interrupt_stackframe;
  336. begin
  337. end;
  338. procedure tprocinfo.handle_body_start;
  339. begin
  340. { temporary space is set, while the BEGIN of the procedure }
  341. if (symtablestack.symtabletype=localsymtable) then
  342. procinfo.firsttemp_offset := tg.direction*symtablestack.datasize
  343. else
  344. procinfo.firsttemp_offset := 0;
  345. { space for the return value }
  346. { !!!!! this means that we can not set the return value
  347. in a subfunction !!!!! }
  348. { because we don't know yet where the address is }
  349. if not is_void(aktprocdef.rettype.def) then
  350. begin
  351. if paramanager.ret_in_reg(aktprocdef.rettype.def) then
  352. begin
  353. { the space has been set in the local symtable }
  354. procinfo.return_offset:=tg.direction*tfuncretsym(aktprocdef.funcretsym).address;
  355. if ((procinfo.flags and pi_operator)<>0) and
  356. assigned(otsym) then
  357. otsym.address:=tfuncretsym(aktprocdef.funcretsym).address;
  358. rg.usedinproc := rg.usedinproc +
  359. getfuncretusedregisters(aktprocdef.rettype.def);
  360. end;
  361. end;
  362. end;
  363. { updates usedinproc depending on the resulttype }
  364. procedure tprocinfo.update_usedinproc_result;
  365. begin
  366. if paramanager.ret_in_reg(procdef.rettype.def) then
  367. begin
  368. rg.usedinproc := rg.usedinproc +
  369. getfuncretusedregisters(procdef.rettype.def);
  370. end;
  371. end;
  372. procedure tprocinfo.set_result_offset;
  373. begin
  374. if paramanager.ret_in_reg(aktprocdef) then
  375. procinfo.return_offset:=-tfuncretsym(procdef.funcretsym).address;
  376. end;
  377. procedure tprocinfo.after_header;
  378. begin
  379. end;
  380. procedure tprocinfo.after_pass1;
  381. begin
  382. end;
  383. {*****************************************************************************
  384. initialize/terminate the codegen for procedure and modules
  385. *****************************************************************************}
  386. procedure codegen_newprocedure;
  387. begin
  388. aktbreaklabel:=nil;
  389. aktcontinuelabel:=nil;
  390. { aktexitlabel:=0; is store in oldaktexitlabel
  391. so it must not be reset to zero before this storage !}
  392. { new procinfo }
  393. procinfo:=cprocinfo.create;
  394. {$ifdef fixLeaksOnError}
  395. procinfoStack.push(procinfo);
  396. {$endif fixLeaksOnError}
  397. end;
  398. procedure codegen_doneprocedure;
  399. begin
  400. {$ifdef fixLeaksOnError}
  401. if procinfo <> procinfoStack.pop then
  402. writeln('problem with procinfoStack!');
  403. {$endif fixLeaksOnError}
  404. procinfo.free;
  405. procinfo:=nil;
  406. end;
  407. procedure codegen_newmodule;
  408. begin
  409. exprasmlist:=taasmoutput.create;
  410. datasegment:=taasmoutput.create;
  411. codesegment:=taasmoutput.create;
  412. bsssegment:=taasmoutput.create;
  413. debuglist:=taasmoutput.create;
  414. withdebuglist:=taasmoutput.create;
  415. consts:=taasmoutput.create;
  416. rttilist:=taasmoutput.create;
  417. ResourceStringList:=Nil;
  418. importssection:=nil;
  419. exportssection:=nil;
  420. resourcesection:=nil;
  421. { resourcestrings }
  422. ResourceStrings:=TResourceStrings.Create;
  423. { use the librarydata from current_module }
  424. objectlibrary:=current_module.librarydata;
  425. end;
  426. procedure codegen_donemodule;
  427. {$ifdef MEMDEBUG}
  428. var
  429. d : tmemdebug;
  430. {$endif}
  431. begin
  432. {$ifdef MEMDEBUG}
  433. d:=tmemdebug.create(current_module.modulename^+' - asmlists');
  434. {$endif}
  435. exprasmlist.free;
  436. codesegment.free;
  437. bsssegment.free;
  438. datasegment.free;
  439. debuglist.free;
  440. withdebuglist.free;
  441. consts.free;
  442. rttilist.free;
  443. if assigned(ResourceStringList) then
  444. ResourceStringList.free;
  445. if assigned(importssection) then
  446. importssection.free;
  447. if assigned(exportssection) then
  448. exportssection.free;
  449. if assigned(resourcesection) then
  450. resourcesection.free;
  451. {$ifdef MEMDEBUG}
  452. d.free;
  453. {$endif}
  454. { resource strings }
  455. ResourceStrings.free;
  456. objectlibrary:=nil;
  457. end;
  458. function def_cgsize(def: tdef): tcgsize;
  459. begin
  460. case def.deftype of
  461. orddef,
  462. enumdef,
  463. setdef:
  464. begin
  465. result := int_cgsize(def.size);
  466. if is_signed(def) then
  467. result := tcgsize(ord(result)+(ord(OS_S8)-ord(OS_8)));
  468. end;
  469. classrefdef,
  470. pointerdef,
  471. procvardef:
  472. result := OS_ADDR;
  473. stringdef :
  474. begin
  475. if is_ansistring(def) or is_widestring(def) then
  476. result := OS_ADDR
  477. else
  478. result := OS_NO;
  479. end;
  480. objectdef :
  481. begin
  482. if is_class_or_interface(def) then
  483. result := OS_ADDR
  484. else
  485. result := OS_NO;
  486. end;
  487. floatdef:
  488. result := tfloat2tcgsize[tfloatdef(def).typ];
  489. recorddef :
  490. result:=int_cgsize(def.size);
  491. arraydef :
  492. begin
  493. if not is_special_array(def) then
  494. result := int_cgsize(def.size)
  495. else
  496. result := OS_NO;
  497. end;
  498. else
  499. begin
  500. { undefined size }
  501. result:=OS_NO;
  502. end;
  503. end;
  504. end;
  505. function int_cgsize(const l: byte): tcgsize;
  506. begin
  507. case l of
  508. 1 :
  509. result := OS_8;
  510. 2 :
  511. result := OS_16;
  512. 3,4 :
  513. result := OS_32;
  514. 5..8 :
  515. result := OS_64;
  516. else
  517. result:=OS_NO;
  518. end;
  519. end;
  520. function inverse_opcmp(opcmp: topcmp): topcmp;
  521. const
  522. list: array[TOpCmp] of TOpCmp =
  523. (OC_NONE,OC_NE,OC_LTE,OC_GTE,OC_LT,OC_GT,OC_EQ,OC_A,OC_AE,
  524. OC_B,OC_BE);
  525. begin
  526. inverse_opcmp := list[opcmp];
  527. end;
  528. function commutativeop(op: topcg): boolean;
  529. const
  530. list: array[topcg] of boolean =
  531. (true,true,true,false,false,true,true,false,false,
  532. true,false,false,false,false,true);
  533. begin
  534. commutativeop := list[op];
  535. end;
  536. {$ifdef fixLeaksOnError}
  537. procedure hcodegen_do_stop;
  538. var p: pprocinfo;
  539. begin
  540. p := pprocinfo(procinfoStack.pop);
  541. while p <> nil Do
  542. begin
  543. dispose(p,done);
  544. p := pprocinfo(procinfoStack.pop);
  545. end;
  546. procinfoStack.done;
  547. do_stop := hcodegen_old_do_stop;
  548. do_stop{$ifdef FPCPROCVAR}(){$endif};
  549. end;
  550. begin
  551. hcodegen_old_do_stop := do_stop;
  552. do_stop := {$ifdef FPCPROCVAR}@{$endif}hcodegen_do_stop;
  553. procinfoStack.init;
  554. {$endif fixLeaksOnError}
  555. end.
  556. {
  557. $Log$
  558. Revision 1.30 2002-09-30 07:00:44 florian
  559. * fixes to common code to get the alpha compiler compiled applied
  560. Revision 1.29 2002/09/07 19:35:45 florian
  561. + tcg.direction is used now
  562. Revision 1.28 2002/09/07 15:25:01 peter
  563. * old logs removed and tabs fixed
  564. Revision 1.27 2002/09/05 19:29:42 peter
  565. * memdebug enhancements
  566. Revision 1.26 2002/08/18 20:06:23 peter
  567. * inlining is now also allowed in interface
  568. * renamed write/load to ppuwrite/ppuload
  569. * tnode storing in ppu
  570. * nld,ncon,nbas are already updated for storing in ppu
  571. Revision 1.25 2002/08/17 09:23:33 florian
  572. * first part of procinfo rewrite
  573. Revision 1.24 2002/08/11 14:32:26 peter
  574. * renamed current_library to objectlibrary
  575. Revision 1.23 2002/08/11 13:24:11 peter
  576. * saving of asmsymbols in ppu supported
  577. * asmsymbollist global is removed and moved into a new class
  578. tasmlibrarydata that will hold the info of a .a file which
  579. corresponds with a single module. Added librarydata to tmodule
  580. to keep the library info stored for the module. In the future the
  581. objectfiles will also be stored to the tasmlibrarydata class
  582. * all getlabel/newasmsymbol and friends are moved to the new class
  583. Revision 1.22 2002/08/06 20:55:20 florian
  584. * first part of ppc calling conventions fix
  585. Revision 1.21 2002/08/05 18:27:48 carl
  586. + more more more documentation
  587. + first version include/exclude (can't test though, not enough scratch for i386 :()...
  588. Revision 1.20 2002/08/04 19:06:41 carl
  589. + added generic exception support (still does not work!)
  590. + more documentation
  591. Revision 1.19 2002/07/20 11:57:53 florian
  592. * types.pas renamed to defbase.pas because D6 contains a types
  593. unit so this would conflicts if D6 programms are compiled
  594. + Willamette/SSE2 instructions to assembler added
  595. Revision 1.18 2002/07/01 18:46:22 peter
  596. * internal linker
  597. * reorganized aasm layer
  598. Revision 1.17 2002/05/20 13:30:40 carl
  599. * bugfix of hdisponen (base must be set, not index)
  600. * more portability fixes
  601. Revision 1.16 2002/05/18 13:34:05 peter
  602. * readded missing revisions
  603. Revision 1.15 2002/05/16 19:46:35 carl
  604. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  605. + try to fix temp allocation (still in ifdef)
  606. + generic constructor calls
  607. + start of tassembler / tmodulebase class cleanup
  608. Revision 1.13 2002/04/25 20:16:38 peter
  609. * moved more routines from cga/n386util
  610. Revision 1.12 2002/04/21 15:28:06 carl
  611. - remove duplicate constants
  612. - move some constants to cginfo
  613. Revision 1.11 2002/04/20 21:32:23 carl
  614. + generic FPC_CHECKPOINTER
  615. + first parameter offset in stack now portable
  616. * rename some constants
  617. + move some cpu stuff to other units
  618. - remove unused constents
  619. * fix stacksize for some targets
  620. * fix generic size problems which depend now on EXTEND_SIZE constant
  621. Revision 1.10 2002/04/07 09:13:39 carl
  622. + documentation
  623. - remove unused variables
  624. Revision 1.9 2002/04/04 19:05:54 peter
  625. * removed unused units
  626. * use tlocation.size in cg.a_*loc*() routines
  627. Revision 1.8 2002/04/02 17:11:27 peter
  628. * tlocation,treference update
  629. * LOC_CONSTANT added for better constant handling
  630. * secondadd splitted in multiple routines
  631. * location_force_reg added for loading a location to a register
  632. of a specified size
  633. * secondassignment parses now first the right and then the left node
  634. (this is compatible with Kylix). This saves a lot of push/pop especially
  635. with string operations
  636. * adapted some routines to use the new cg methods
  637. Revision 1.7 2002/03/31 20:26:33 jonas
  638. + a_loadfpu_* and a_loadmm_* methods in tcg
  639. * register allocation is now handled by a class and is mostly processor
  640. independent (+rgobj.pas and i386/rgcpu.pas)
  641. * temp allocation is now handled by a class (+tgobj.pas, -i386\tgcpu.pas)
  642. * some small improvements and fixes to the optimizer
  643. * some register allocation fixes
  644. * some fpuvaroffset fixes in the unary minus node
  645. * push/popusedregisters is now called rg.save/restoreusedregisters and
  646. (for i386) uses temps instead of push/pop's when using -Op3 (that code is
  647. also better optimizable)
  648. * fixed and optimized register saving/restoring for new/dispose nodes
  649. * LOC_FPU locations now also require their "register" field to be set to
  650. R_ST, not R_ST0 (the latter is used for LOC_CFPUREGISTER locations only)
  651. - list field removed of the tnode class because it's not used currently
  652. and can cause hard-to-find bugs
  653. }