cgbase.pas 27 KB

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