cgbase.pas 26 KB

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