paramgr.pas 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648
  1. {
  2. $Id$
  3. Copyright (c) 2002 by Florian Klaempfl
  4. Generic calling convention handling
  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. {# Parameter passing manager. Used to manage how
  19. parameters are passed to routines.
  20. }
  21. unit paramgr;
  22. {$i fpcdefs.inc}
  23. interface
  24. uses
  25. cpubase,
  26. aasmtai,
  27. globtype,
  28. symconst,symtype,symdef;
  29. type
  30. tcallercallee = (callerside,calleeside);
  31. {# This class defines some methods to take care of routine
  32. parameters. It should be overriden for each new processor
  33. }
  34. tparamanager = class
  35. {# Returns true if the return value is actually a parameter
  36. pointer.
  37. }
  38. function ret_in_param(def : tdef;calloption : tproccalloption) : boolean;virtual;
  39. function push_high_param(def : tdef;calloption : tproccalloption) : boolean;virtual;
  40. { Returns true if a parameter is too large to copy and only
  41. the address is pushed
  42. }
  43. function push_addr_param(def : tdef;calloption : tproccalloption) : boolean;virtual;
  44. { return the size of a push }
  45. function push_size(varspez:tvarspez;def : tdef;calloption : tproccalloption) : longint;
  46. { Returns true if a parameter needs to be copied on the stack, this
  47. is required for cdecl procedures
  48. }
  49. function copy_value_on_stack(def : tdef;calloption : tproccalloption) : boolean;
  50. {# Returns a structure giving the information on
  51. the storage of the parameter (which must be
  52. an integer parameter). This is only used when calling
  53. internal routines directly, where all parameters must
  54. be 4-byte values.
  55. In case the location is a register, this register is allocated.
  56. Call freeintparaloc() after the call to free the locations again.
  57. Default implementation: don't do anything at all (in case you don't
  58. use register parameter passing)
  59. @param(list Current assembler list)
  60. @param(nr Parameter number of routine, starting from 1)
  61. }
  62. function getintparaloc(list: taasmoutput; nr : longint) : tparalocation;virtual;abstract;
  63. {# frees a parameter location allocated with getintparaloc
  64. @param(list Current assembler list)
  65. @param(nr Parameter number of routine, starting from 1)
  66. }
  67. procedure freeintparaloc(list: taasmoutput; nr : longint); virtual; abstract;
  68. {# allocate a parameter location created with create_paraloc_info
  69. @param(list Current assembler list)
  70. @param(loc Parameter location)
  71. }
  72. procedure allocparaloc(list: taasmoutput; const loc: tparalocation); virtual;
  73. {# free a parameter location allocated with allocparaloc
  74. @param(list Current assembler list)
  75. @param(loc Parameter location)
  76. }
  77. procedure freeparaloc(list: taasmoutput; const loc: tparalocation); virtual;
  78. {# This is used to populate the location information on all parameters
  79. for the routine as seen in either the caller or the callee. This is used for normal call resolution.
  80. }
  81. procedure create_paraloc_info(p : tabstractprocdef; side: tcallercallee);virtual;abstract;
  82. {
  83. Returns the location where the invisible parameter for structured
  84. function results will be passed.
  85. }
  86. function getfuncretparaloc(p : tabstractprocdef) : tparalocation;virtual;
  87. {
  88. Returns the location where the invisible parameter for nested
  89. subroutines is passed.
  90. }
  91. function getframepointerloc(p : tabstractprocdef) : tparalocation;virtual;
  92. { Returns the self pointer location for the given tabstractprocdef,
  93. when the stack frame is already created. This is used by the code
  94. generating the wrappers for implemented interfaces.
  95. }
  96. function getselflocation(p : tabstractprocdef) : tparalocation;virtual;abstract;
  97. {
  98. Returns the location of the result if the result is in
  99. a register, the register(s) return depend on the type of
  100. the result.
  101. @param(def The definition of the result type of the function)
  102. }
  103. function getfuncresultloc(def : tdef;calloption:tproccalloption): tparalocation;virtual;
  104. procedure splitparaloc64(const locpara:tparalocation;var loclopara,lochipara:tparalocation);virtual;
  105. end;
  106. var
  107. paralocdummy : tparalocation;
  108. paramanager : tparamanager;
  109. implementation
  110. uses
  111. cpuinfo,globals,systems,
  112. symbase,symsym,
  113. rgobj,
  114. defutil,cgbase,cginfo,verbose;
  115. { true if uses a parameter as return value }
  116. function tparamanager.ret_in_param(def : tdef;calloption : tproccalloption) : boolean;
  117. begin
  118. ret_in_param:=(def.deftype in [arraydef,recorddef]) or
  119. ((def.deftype=stringdef) and (tstringdef(def).string_typ in [st_shortstring,st_longstring])) or
  120. ((def.deftype=procvardef) and (po_methodpointer in tprocvardef(def).procoptions)) or
  121. ((def.deftype=objectdef) and is_object(def)) or
  122. (def.deftype=variantdef) or
  123. ((def.deftype=setdef) and (tsetdef(def).settype<>smallset));
  124. end;
  125. function tparamanager.push_high_param(def : tdef;calloption : tproccalloption) : boolean;
  126. begin
  127. push_high_param:=not(calloption in [pocall_cdecl,pocall_cppdecl]) and
  128. (
  129. is_open_array(def) or
  130. is_open_string(def) or
  131. is_array_of_const(def)
  132. );
  133. end;
  134. { true if a parameter is too large to copy and only the address is pushed }
  135. function tparamanager.push_addr_param(def : tdef;calloption : tproccalloption) : boolean;
  136. begin
  137. push_addr_param:=false;
  138. case def.deftype of
  139. variantdef,
  140. formaldef :
  141. push_addr_param:=true;
  142. recorddef :
  143. push_addr_param:=not(calloption in [pocall_cdecl,pocall_cppdecl]) and (def.size>pointer_size);
  144. arraydef :
  145. begin
  146. if (calloption in [pocall_cdecl,pocall_cppdecl]) then
  147. begin
  148. { array of const values are pushed on the stack }
  149. push_addr_param:=not is_array_of_const(def);
  150. end
  151. else
  152. begin
  153. push_addr_param:=(
  154. (tarraydef(def).highrange>=tarraydef(def).lowrange) and
  155. (def.size>pointer_size)
  156. ) or
  157. is_open_array(def) or
  158. is_array_of_const(def) or
  159. is_array_constructor(def);
  160. end;
  161. end;
  162. objectdef :
  163. push_addr_param:=is_object(def);
  164. stringdef :
  165. push_addr_param:=not(calloption in [pocall_cdecl,pocall_cppdecl]) and (tstringdef(def).string_typ in [st_shortstring,st_longstring]);
  166. procvardef :
  167. push_addr_param:=not(calloption in [pocall_cdecl,pocall_cppdecl]) and (po_methodpointer in tprocvardef(def).procoptions);
  168. setdef :
  169. push_addr_param:=not(calloption in [pocall_cdecl,pocall_cppdecl]) and (tsetdef(def).settype<>smallset);
  170. end;
  171. end;
  172. { true if a parameter is too large to push and needs a concatcopy to get the value on the stack }
  173. function tparamanager.copy_value_on_stack(def : tdef;calloption : tproccalloption) : boolean;
  174. begin
  175. copy_value_on_stack:=false;
  176. { this is only for cdecl procedures }
  177. if not(calloption in [pocall_cdecl,pocall_cppdecl]) then
  178. exit;
  179. case def.deftype of
  180. variantdef,
  181. formaldef :
  182. copy_value_on_stack:=true;
  183. recorddef :
  184. copy_value_on_stack:=(def.size>pointer_size);
  185. arraydef :
  186. copy_value_on_stack:=(tarraydef(def).highrange>=tarraydef(def).lowrange) and
  187. (def.size>pointer_size);
  188. objectdef :
  189. copy_value_on_stack:=is_object(def);
  190. stringdef :
  191. copy_value_on_stack:=tstringdef(def).string_typ in [st_shortstring,st_longstring];
  192. procvardef :
  193. copy_value_on_stack:=(po_methodpointer in tprocvardef(def).procoptions);
  194. setdef :
  195. copy_value_on_stack:=(tsetdef(def).settype<>smallset);
  196. end;
  197. end;
  198. { return the size of a push }
  199. function tparamanager.push_size(varspez:tvarspez;def : tdef;calloption : tproccalloption) : longint;
  200. begin
  201. push_size:=-1;
  202. case varspez of
  203. vs_out,
  204. vs_var :
  205. push_size:=pointer_size;
  206. vs_value,
  207. vs_const :
  208. begin
  209. if push_addr_param(def,calloption) then
  210. push_size:=pointer_size
  211. else
  212. begin
  213. { special array are normally pushed by addr, only for
  214. cdecl array of const it comes here and the pushsize
  215. is unknown }
  216. if is_array_of_const(def) then
  217. push_size:=0
  218. else
  219. push_size:=def.size;
  220. end;
  221. end;
  222. end;
  223. end;
  224. procedure tparamanager.allocparaloc(list: taasmoutput; const loc: tparalocation);
  225. begin
  226. case loc.loc of
  227. LOC_REGISTER, LOC_CREGISTER:
  228. begin
  229. {$ifndef cpu64bit}
  230. if (loc.size in [OS_64,OS_S64,OS_F64]) then
  231. begin
  232. rg.getexplicitregisterint(list,loc.registerhigh.number);
  233. rg.getexplicitregisterint(list,loc.registerlow.number);
  234. end
  235. else
  236. {$endif cpu64bit}
  237. rg.getexplicitregisterint(list,loc.register.number);
  238. end;
  239. LOC_FPUREGISTER, LOC_CFPUREGISTER:
  240. rg.getexplicitregisterfpu(list,loc.register.enum);
  241. LOC_REFERENCE,LOC_CREFERENCE:
  242. { do nothing by default, most of the time it's the framepointer }
  243. else
  244. internalerror(200306091);
  245. end;
  246. end;
  247. procedure tparamanager.freeparaloc(list: taasmoutput; const loc: tparalocation);
  248. begin
  249. case loc.loc of
  250. LOC_REGISTER, LOC_CREGISTER:
  251. begin
  252. {$ifndef cpu64bit}
  253. if (loc.size in [OS_64,OS_S64,OS_F64]) then
  254. begin
  255. rg.ungetregisterint(list,loc.registerhigh);
  256. rg.ungetregisterint(list,loc.registerlow);
  257. end
  258. else
  259. {$endif cpu64bit}
  260. rg.ungetregisterint(list,loc.register);
  261. end;
  262. LOC_FPUREGISTER, LOC_CFPUREGISTER:
  263. rg.ungetregisterfpu(list,loc.register,loc.size);
  264. LOC_REFERENCE,LOC_CREFERENCE:
  265. { do nothing by default, most of the time it's the framepointer }
  266. else
  267. internalerror(200306091);
  268. end;
  269. end;
  270. function tparamanager.getfuncretparaloc(p : tabstractprocdef) : tparalocation;
  271. begin
  272. result.loc:=LOC_REFERENCE;
  273. result.size:=OS_ADDR;
  274. result.sp_fixup:=pointer_size;
  275. result.reference.index.enum:=R_INTREGISTER;
  276. result.reference.index.number:=NR_STACK_POINTER_REG;
  277. result.reference.offset:=0;
  278. end;
  279. function tparamanager.getframepointerloc(p : tabstractprocdef) : tparalocation;
  280. begin
  281. result.loc:=LOC_REFERENCE;
  282. result.size:=OS_ADDR;
  283. result.sp_fixup:=pointer_size;
  284. result.reference.index.enum:=R_INTREGISTER;
  285. result.reference.index.number:=NR_STACK_POINTER_REG;
  286. result.reference.offset:=0;
  287. end;
  288. function tparamanager.getfuncresultloc(def : tdef;calloption:tproccalloption): tparalocation;
  289. begin
  290. fillchar(result,sizeof(tparalocation),0);
  291. if is_void(def) then exit;
  292. result.size := def_cgsize(def);
  293. case def.deftype of
  294. orddef,
  295. enumdef :
  296. begin
  297. result.loc := LOC_REGISTER;
  298. {$ifndef cpu64bit}
  299. if result.size in [OS_64,OS_S64] then
  300. begin
  301. result.register64.reglo.enum:=R_INTREGISTER;
  302. result.register64.reglo.number:=NR_FUNCTION_RETURN64_LOW_REG;
  303. result.register64.reghi.enum:=R_INTREGISTER;
  304. result.register64.reghi.number:=NR_FUNCTION_RETURN64_HIGH_REG;
  305. end
  306. else
  307. {$endif cpu64bit}
  308. begin
  309. result.register.enum:=R_INTREGISTER;
  310. result.register.number:=NR_FUNCTION_RETURN_REG;
  311. end;
  312. end;
  313. floatdef :
  314. begin
  315. result.loc := LOC_FPUREGISTER;
  316. {$ifdef cpufpemu}
  317. if cs_fp_emulation in aktmoduleswitches then
  318. begin
  319. result.register.enum:=R_INTREGISTER;
  320. result.register.number:=FUNCTION_RETURN_REG;
  321. end
  322. else
  323. {$endif cpufpemu}
  324. result.register.enum := FPU_RESULT_REG;
  325. end;
  326. else
  327. begin
  328. if not ret_in_param(def,calloption) then
  329. begin
  330. result.loc := LOC_REGISTER;
  331. result.register.enum:=R_INTREGISTER;
  332. result.register.number:=NR_FUNCTION_RETURN_REG;
  333. end
  334. else
  335. begin
  336. result.loc := LOC_REFERENCE;
  337. internalerror(2002081602);
  338. (*
  339. {$ifdef EXTDEBUG}
  340. { it is impossible to have the
  341. return value with an index register
  342. and a symbol!
  343. }
  344. if (ref.index <> R_NO) or (assigned(ref.symbol)) then
  345. internalerror(2002081602);
  346. {$endif}
  347. result.reference.index := ref.base;
  348. result.reference.offset := ref.offset;
  349. *)
  350. end;
  351. end;
  352. end;
  353. end;
  354. procedure tparamanager.splitparaloc64(const locpara:tparalocation;var loclopara,lochipara:tparalocation);
  355. begin
  356. if not(locpara.size in [OS_64,OS_S64]) then
  357. internalerror(200307023);
  358. lochipara:=locpara;
  359. loclopara:=locpara;
  360. if locpara.size=OS_S64 then
  361. lochipara.size:=OS_S32
  362. else
  363. lochipara.size:=OS_32;
  364. loclopara.size:=OS_32;
  365. case locpara.loc of
  366. LOC_REGISTER,LOC_CREGISTER:
  367. begin
  368. loclopara.register:=locpara.registerlow;
  369. lochipara.register:=locpara.registerhigh;
  370. end;
  371. LOC_REFERENCE:
  372. begin
  373. if target_info.endian=endian_big then
  374. inc(loclopara.reference.offset,4)
  375. else
  376. inc(lochipara.reference.offset,4);
  377. end;
  378. else
  379. internalerror(200307024);
  380. end;
  381. end;
  382. initialization
  383. ;
  384. finalization
  385. paramanager.free;
  386. end.
  387. {
  388. $Log$
  389. Revision 1.48 2003-07-05 20:11:41 jonas
  390. * create_paraloc_info() is now called separately for the caller and
  391. callee info
  392. * fixed ppc cycle
  393. Revision 1.47 2003/07/02 22:18:04 peter
  394. * paraloc splitted in callerparaloc,calleeparaloc
  395. * sparc calling convention updates
  396. Revision 1.46 2003/06/17 16:32:03 peter
  397. * allocpara/freepara 64bit support
  398. Revision 1.45 2003/06/13 21:19:30 peter
  399. * current_procdef removed, use current_procinfo.procdef instead
  400. Revision 1.44 2003/06/12 21:11:10 peter
  401. * ungetregisterfpu gets size parameter
  402. Revision 1.43 2003/06/09 14:54:26 jonas
  403. * (de)allocation of registers for parameters is now performed properly
  404. (and checked on the ppc)
  405. - removed obsolete allocation of all parameter registers at the start
  406. of a procedure (and deallocation at the end)
  407. Revision 1.42 2003/06/08 10:54:41 jonas
  408. - disabled changing of LOC_*REGISTER to LOC_C*REGISTER in setparalocs,
  409. this is not necessary anymore (doesn't do anything anymore actually,
  410. except making sure the interface crc changes)
  411. Revision 1.41 2003/06/07 18:57:04 jonas
  412. + added freeintparaloc
  413. * ppc get/freeintparaloc now check whether the parameter regs are
  414. properly allocated/deallocated (and get an extra list para)
  415. * ppc a_call_* now internalerrors if pi_do_call is not yet set
  416. * fixed lot of missing pi_do_call's
  417. Revision 1.40 2003/05/31 15:05:28 peter
  418. * FUNCTION_RESULT64_LOW/HIGH_REG added for int64 results
  419. Revision 1.39 2003/05/30 23:57:08 peter
  420. * more sparc cleanup
  421. * accumulator removed, splitted in function_return_reg (called) and
  422. function_result_reg (caller)
  423. Revision 1.38 2003/05/13 15:16:13 peter
  424. * removed ret_in_acc, it's the reverse of ret_in_param
  425. * fixed ret_in_param for win32 cdecl array
  426. Revision 1.37 2003/04/30 22:15:59 florian
  427. * some 64 bit adaptions in ncgadd
  428. * x86-64 now uses ncgadd
  429. * tparamanager.ret_in_acc doesn't return true anymore for a void-def
  430. Revision 1.36 2003/04/27 11:21:33 peter
  431. * aktprocdef renamed to current_procinfo.procdef
  432. * procinfo renamed to current_procinfo
  433. * procinfo will now be stored in current_module so it can be
  434. cleaned up properly
  435. * gen_main_procsym changed to create_main_proc and release_main_proc
  436. to also generate a tprocinfo structure
  437. * fixed unit implicit initfinal
  438. Revision 1.35 2003/04/27 07:29:50 peter
  439. * current_procinfo.procdef cleanup, current_procdef is now always nil when parsing
  440. a new procdef declaration
  441. * aktprocsym removed
  442. * lexlevel removed, use symtable.symtablelevel instead
  443. * implicit init/final code uses the normal genentry/genexit
  444. * funcret state checking updated for new funcret handling
  445. Revision 1.34 2003/04/23 13:15:04 peter
  446. * fix push_high_param for cdecl
  447. Revision 1.33 2003/04/23 10:14:30 peter
  448. * cdecl array of const has no addr push
  449. Revision 1.32 2003/04/22 13:47:08 peter
  450. * fixed C style array of const
  451. * fixed C array passing
  452. * fixed left to right with high parameters
  453. Revision 1.31 2003/02/02 19:25:54 carl
  454. * Several bugfixes for m68k target (register alloc., opcode emission)
  455. + VIS target
  456. + Generic add more complete (still not verified)
  457. Revision 1.30 2003/01/08 18:43:56 daniel
  458. * Tregister changed into a record
  459. Revision 1.29 2002/12/23 20:58:03 peter
  460. * remove unused global var
  461. Revision 1.28 2002/12/17 22:19:33 peter
  462. * fixed pushing of records>8 bytes with stdcall
  463. * simplified hightree loading
  464. Revision 1.27 2002/12/06 16:56:58 peter
  465. * only compile cs_fp_emulation support when cpufpuemu is defined
  466. * define cpufpuemu for m68k only
  467. Revision 1.26 2002/11/27 20:04:09 peter
  468. * tvarsym.get_push_size replaced by paramanager.push_size
  469. Revision 1.25 2002/11/27 02:33:19 peter
  470. * copy_value_on_stack method added for cdecl record passing
  471. Revision 1.24 2002/11/25 17:43:21 peter
  472. * splitted defbase in defutil,symutil,defcmp
  473. * merged isconvertable and is_equal into compare_defs(_ext)
  474. * made operator search faster by walking the list only once
  475. Revision 1.23 2002/11/18 17:31:58 peter
  476. * pass proccalloption to ret_in_xxx and push_xxx functions
  477. Revision 1.22 2002/11/16 18:00:04 peter
  478. * only push small arrays on the stack for win32
  479. Revision 1.21 2002/10/05 12:43:25 carl
  480. * fixes for Delphi 6 compilation
  481. (warning : Some features do not work under Delphi)
  482. Revision 1.20 2002/09/30 07:07:25 florian
  483. * fixes to common code to get the alpha compiler compiled applied
  484. Revision 1.19 2002/09/30 07:00:47 florian
  485. * fixes to common code to get the alpha compiler compiled applied
  486. Revision 1.18 2002/09/09 09:10:51 florian
  487. + added generic tparamanager.getframepointerloc
  488. Revision 1.17 2002/09/07 19:40:39 florian
  489. * tvarsym.paraitem is set now
  490. Revision 1.16 2002/09/01 21:04:48 florian
  491. * several powerpc related stuff fixed
  492. Revision 1.15 2002/08/25 19:25:19 peter
  493. * sym.insert_in_data removed
  494. * symtable.insertvardata/insertconstdata added
  495. * removed insert_in_data call from symtable.insert, it needs to be
  496. called separatly. This allows to deref the address calculation
  497. * procedures now calculate the parast addresses after the procedure
  498. directives are parsed. This fixes the cdecl parast problem
  499. * push_addr_param has an extra argument that specifies if cdecl is used
  500. or not
  501. Revision 1.14 2002/08/17 22:09:47 florian
  502. * result type handling in tcgcal.pass_2 overhauled
  503. * better tnode.dowrite
  504. * some ppc stuff fixed
  505. Revision 1.13 2002/08/17 09:23:38 florian
  506. * first part of procinfo rewrite
  507. Revision 1.12 2002/08/16 14:24:58 carl
  508. * issameref() to test if two references are the same (then emit no opcodes)
  509. + ret_in_reg to replace ret_in_acc
  510. (fix some register allocation bugs at the same time)
  511. + save_std_register now has an extra parameter which is the
  512. usedinproc registers
  513. Revision 1.11 2002/08/12 15:08:40 carl
  514. + stab register indexes for powerpc (moved from gdb to cpubase)
  515. + tprocessor enumeration moved to cpuinfo
  516. + linker in target_info is now a class
  517. * many many updates for m68k (will soon start to compile)
  518. - removed some ifdef or correct them for correct cpu
  519. Revision 1.10 2002/08/10 17:15:20 jonas
  520. * register parameters are now LOC_CREGISTER instead of LOC_REGISTER
  521. Revision 1.9 2002/08/09 07:33:02 florian
  522. * a couple of interface related fixes
  523. Revision 1.8 2002/08/06 20:55:21 florian
  524. * first part of ppc calling conventions fix
  525. Revision 1.7 2002/08/05 18:27:48 carl
  526. + more more more documentation
  527. + first version include/exclude (can't test though, not enough scratch for i386 :()...
  528. Revision 1.6 2002/07/30 20:50:43 florian
  529. * the code generator knows now if parameters are in registers
  530. Revision 1.5 2002/07/26 21:15:39 florian
  531. * rewrote the system handling
  532. Revision 1.4 2002/07/20 11:57:55 florian
  533. * types.pas renamed to defbase.pas because D6 contains a types
  534. unit so this would conflicts if D6 programms are compiled
  535. + Willamette/SSE2 instructions to assembler added
  536. Revision 1.3 2002/07/13 19:38:43 florian
  537. * some more generic calling stuff fixed
  538. Revision 1.2 2002/07/13 07:17:15 jonas
  539. * fixed memory leak reported by Sergey Korshunoff
  540. Revision 1.1 2002/07/11 14:41:28 florian
  541. * start of the new generic parameter handling
  542. }