cgbase.pas 27 KB

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