cgbase.pas 28 KB

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