cgbase.pas 26 KB

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