cpupara.pas 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703
  1. {
  2. $Id$
  3. Copyright (c) 2002 by Florian Klaempfl
  4. Generates the argument location information for i386
  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 bymethodpointer
  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. unit cpupara;
  19. {$i fpcdefs.inc}
  20. interface
  21. uses
  22. globtype,
  23. aasmtai,cpubase,cgbase,
  24. symconst,symtype,symsym,symdef,
  25. parabase,paramgr;
  26. type
  27. ti386paramanager = class(tparamanager)
  28. function param_use_paraloc(const cgpara:tcgpara):boolean;override;
  29. function ret_in_param(def : tdef;calloption : tproccalloption) : boolean;override;
  30. function push_addr_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;override;
  31. function get_para_align(calloption : tproccalloption):byte;override;
  32. function get_volatile_registers_int(calloption : tproccalloption):tcpuregisterset;override;
  33. function get_volatile_registers_fpu(calloption : tproccalloption):tcpuregisterset;override;
  34. function get_volatile_registers_mm(calloption : tproccalloption):tcpuregisterset;override;
  35. { Returns the location for the nr-st 32 Bit int parameter
  36. if every parameter before is an 32 Bit int parameter as well
  37. and if the calling conventions for the helper routines of the
  38. rtl are used.
  39. }
  40. procedure getintparaloc(calloption : tproccalloption; nr : longint;var cgpara:TCGPara);override;
  41. function create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;override;
  42. function create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint;override;
  43. procedure createtempparaloc(list: taasmoutput;calloption : tproccalloption;parasym : tparavarsym;var cgpara:TCGPara);override;
  44. private
  45. procedure create_funcretloc_info(p : tabstractprocdef; side: tcallercallee);
  46. procedure create_stdcall_paraloc_info(p : tabstractprocdef; side: tcallercallee;paras:tparalist;var parasize:longint);
  47. procedure create_register_paraloc_info(p : tabstractprocdef; side: tcallercallee;paras:tparalist;var parareg,parasize:longint);
  48. end;
  49. implementation
  50. uses
  51. cutils,
  52. systems,verbose,
  53. defutil,
  54. cgutils;
  55. const
  56. parasupregs : array[0..2] of tsuperregister = (RS_EAX,RS_EDX,RS_ECX);
  57. {****************************************************************************
  58. TI386PARAMANAGER
  59. ****************************************************************************}
  60. function ti386paramanager.param_use_paraloc(const cgpara:tcgpara):boolean;
  61. var
  62. paraloc : pcgparalocation;
  63. begin
  64. if not assigned(cgpara.location) then
  65. internalerror(200410102);
  66. result:=true;
  67. { All locations are LOC_REFERENCE }
  68. paraloc:=cgpara.location;
  69. while assigned(paraloc) do
  70. begin
  71. if (paraloc^.loc<>LOC_REFERENCE) then
  72. begin
  73. result:=false;
  74. exit;
  75. end;
  76. paraloc:=paraloc^.next;
  77. end;
  78. end;
  79. function ti386paramanager.ret_in_param(def : tdef;calloption : tproccalloption) : boolean;
  80. begin
  81. case target_info.system of
  82. system_i386_win32 :
  83. begin
  84. case def.deftype of
  85. recorddef :
  86. begin
  87. { Win32 GCC returns small records in the FUNCTION_RETURN_REG.
  88. For stdcall we follow delphi instead of GCC }
  89. if (calloption in [pocall_cdecl,pocall_cppdecl]) and
  90. (def.size<=8) then
  91. begin
  92. result:=false;
  93. exit;
  94. end;
  95. end;
  96. end;
  97. end;
  98. end;
  99. result:=inherited ret_in_param(def,calloption);
  100. end;
  101. function ti386paramanager.push_addr_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;
  102. begin
  103. result:=false;
  104. { var,out always require address }
  105. if varspez in [vs_var,vs_out] then
  106. begin
  107. result:=true;
  108. exit;
  109. end;
  110. { Only vs_const, vs_value here }
  111. case def.deftype of
  112. variantdef,
  113. formaldef :
  114. result:=true;
  115. recorddef :
  116. begin
  117. { Win32 passes small records on the stack for call by
  118. value }
  119. if (target_info.system=system_i386_win32) and
  120. (calloption in [pocall_stdcall,pocall_cdecl,pocall_cppdecl]) and
  121. (varspez=vs_value) and
  122. (def.size<=8) then
  123. result:=false
  124. else
  125. result:=not(calloption in [pocall_cdecl,pocall_cppdecl]) and (def.size>sizeof(aint));
  126. end;
  127. arraydef :
  128. begin
  129. { Win32 passes arrays on the stack for call by
  130. value }
  131. if (target_info.system=system_i386_win32) and
  132. (calloption in [pocall_stdcall,pocall_cdecl,pocall_cppdecl]) and
  133. (varspez=vs_value) and
  134. (tarraydef(def).highrange>=tarraydef(def).lowrange) then
  135. result:=false
  136. else
  137. { array of const values are pushed on the stack }
  138. if (calloption in [pocall_cdecl,pocall_cppdecl]) then
  139. result:=not is_array_of_const(def)
  140. else
  141. begin
  142. result:=(
  143. (tarraydef(def).highrange>=tarraydef(def).lowrange) and
  144. (def.size>sizeof(aint))
  145. ) or
  146. is_open_array(def) or
  147. is_array_of_const(def) or
  148. is_array_constructor(def);
  149. end;
  150. end;
  151. objectdef :
  152. result:=is_object(def);
  153. stringdef :
  154. result:=not(calloption in [pocall_cdecl,pocall_cppdecl]) and (tstringdef(def).string_typ in [st_shortstring,st_longstring]);
  155. procvardef :
  156. result:=not(calloption in [pocall_cdecl,pocall_cppdecl]) and (po_methodpointer in tprocvardef(def).procoptions);
  157. setdef :
  158. result:=not(calloption in [pocall_cdecl,pocall_cppdecl]) and (tsetdef(def).settype<>smallset);
  159. end;
  160. end;
  161. function ti386paramanager.get_para_align(calloption : tproccalloption):byte;
  162. begin
  163. if calloption=pocall_oldfpccall then
  164. begin
  165. if target_info.system in [system_i386_go32v2,system_i386_watcom] then
  166. result:=2
  167. else
  168. result:=4;
  169. end
  170. else
  171. result:=std_param_align;
  172. end;
  173. function ti386paramanager.get_volatile_registers_int(calloption : tproccalloption):tcpuregisterset;
  174. begin
  175. case calloption of
  176. pocall_internproc :
  177. result:=[];
  178. pocall_compilerproc :
  179. begin
  180. if pocall_default=pocall_oldfpccall then
  181. result:=[RS_EAX,RS_EDX,RS_ECX,RS_ESI,RS_EDI,RS_EBX]
  182. else
  183. result:=[RS_EAX,RS_EDX,RS_ECX];
  184. end;
  185. pocall_inline,
  186. pocall_register,
  187. pocall_safecall,
  188. pocall_stdcall,
  189. pocall_cdecl,
  190. pocall_cppdecl :
  191. result:=[RS_EAX,RS_EDX,RS_ECX];
  192. pocall_far16,
  193. pocall_pascal,
  194. pocall_oldfpccall :
  195. result:=[RS_EAX,RS_EDX,RS_ECX,RS_ESI,RS_EDI,RS_EBX];
  196. else
  197. internalerror(200309071);
  198. end;
  199. end;
  200. function ti386paramanager.get_volatile_registers_fpu(calloption : tproccalloption):tcpuregisterset;
  201. begin
  202. result:=[0..first_fpu_imreg-1];
  203. end;
  204. function ti386paramanager.get_volatile_registers_mm(calloption : tproccalloption):tcpuregisterset;
  205. begin
  206. result:=[0..first_mm_imreg-1];
  207. end;
  208. procedure ti386paramanager.getintparaloc(calloption : tproccalloption; nr : longint;var cgpara:TCGPara);
  209. var
  210. paraloc : pcgparalocation;
  211. begin
  212. cgpara.reset;
  213. cgpara.size:=OS_INT;
  214. cgpara.intsize:=tcgsize2size[OS_INT];
  215. cgpara.alignment:=get_para_align(calloption);
  216. paraloc:=cgpara.add_location;
  217. with paraloc^ do
  218. begin
  219. size:=OS_INT;
  220. if calloption=pocall_register then
  221. begin
  222. if (nr<=high(parasupregs)+1) then
  223. begin
  224. if nr=0 then
  225. internalerror(200309271);
  226. loc:=LOC_REGISTER;
  227. register:=newreg(R_INTREGISTER,parasupregs[nr-1],R_SUBWHOLE);
  228. end
  229. else
  230. begin
  231. loc:=LOC_REFERENCE;
  232. reference.index:=NR_STACK_POINTER_REG;
  233. reference.offset:=sizeof(aint)*nr;
  234. end;
  235. end
  236. else
  237. begin
  238. loc:=LOC_REFERENCE;
  239. reference.index:=NR_STACK_POINTER_REG;
  240. reference.offset:=sizeof(aint)*nr;
  241. end;
  242. end;
  243. end;
  244. procedure ti386paramanager.create_funcretloc_info(p : tabstractprocdef; side: tcallercallee);
  245. var
  246. retcgsize : tcgsize;
  247. begin
  248. { Constructors return self instead of a boolean }
  249. if (p.proctypeoption=potype_constructor) then
  250. retcgsize:=OS_ADDR
  251. else
  252. retcgsize:=def_cgsize(p.rettype.def);
  253. location_reset(p.funcretloc[side],LOC_INVALID,OS_NO);
  254. { void has no location }
  255. if is_void(p.rettype.def) then
  256. begin
  257. location_reset(p.funcretloc[side],LOC_VOID,OS_NO);
  258. exit;
  259. end;
  260. { Return in FPU register? }
  261. if p.rettype.def.deftype=floatdef then
  262. begin
  263. p.funcretloc[side].loc:=LOC_FPUREGISTER;
  264. p.funcretloc[side].register:=NR_FPU_RESULT_REG;
  265. p.funcretloc[side].size:=retcgsize;
  266. end
  267. else
  268. { Return in register? }
  269. if not ret_in_param(p.rettype.def,p.proccalloption) then
  270. begin
  271. if retcgsize in [OS_64,OS_S64] then
  272. begin
  273. { low 32bits }
  274. p.funcretloc[side].loc:=LOC_REGISTER;
  275. p.funcretloc[side].size:=OS_64;
  276. if side=callerside then
  277. p.funcretloc[side].register64.reglo:=NR_FUNCTION_RESULT64_LOW_REG
  278. else
  279. p.funcretloc[side].register64.reglo:=NR_FUNCTION_RETURN64_LOW_REG;
  280. { high 32bits }
  281. if side=callerside then
  282. p.funcretloc[side].register64.reghi:=NR_FUNCTION_RESULT64_HIGH_REG
  283. else
  284. p.funcretloc[side].register64.reghi:=NR_FUNCTION_RETURN64_HIGH_REG;
  285. end
  286. else
  287. begin
  288. p.funcretloc[side].loc:=LOC_REGISTER;
  289. p.funcretloc[side].size:=retcgsize;
  290. if side=callerside then
  291. p.funcretloc[side].register:=newreg(R_INTREGISTER,RS_FUNCTION_RESULT_REG,cgsize2subreg(retcgsize))
  292. else
  293. p.funcretloc[side].register:=newreg(R_INTREGISTER,RS_FUNCTION_RETURN_REG,cgsize2subreg(retcgsize));
  294. end;
  295. end
  296. else
  297. begin
  298. p.funcretloc[side].loc:=LOC_REFERENCE;
  299. p.funcretloc[side].size:=retcgsize;
  300. end;
  301. end;
  302. procedure ti386paramanager.create_stdcall_paraloc_info(p : tabstractprocdef; side: tcallercallee;paras:tparalist;var parasize:longint);
  303. var
  304. i : integer;
  305. hp : tparavarsym;
  306. paraloc : pcgparalocation;
  307. l,
  308. paralen,
  309. varalign : longint;
  310. paraalign : shortint;
  311. pushaddr : boolean;
  312. paracgsize : tcgsize;
  313. begin
  314. paraalign:=get_para_align(p.proccalloption);
  315. { we push Flags and CS as long
  316. to cope with the IRETD
  317. and we save 6 register + 4 selectors }
  318. if po_interrupt in p.procoptions then
  319. inc(parasize,8+6*4+4*2);
  320. { Offset is calculated like:
  321. sub esp,12
  322. mov [esp+8],para3
  323. mov [esp+4],para2
  324. mov [esp],para1
  325. call function
  326. That means for pushes the para with the
  327. highest offset (see para3) needs to be pushed first
  328. }
  329. for i:=0 to paras.count-1 do
  330. begin
  331. hp:=tparavarsym(paras[i]);
  332. pushaddr:=push_addr_param(hp.varspez,hp.vartype.def,p.proccalloption);
  333. if pushaddr then
  334. begin
  335. paralen:=sizeof(aint);
  336. paracgsize:=OS_ADDR;
  337. end
  338. else
  339. begin
  340. paralen:=push_size(hp.varspez,hp.vartype.def,p.proccalloption);
  341. paracgsize:=def_cgsize(hp.vartype.def);
  342. end;
  343. hp.paraloc[side].reset;
  344. hp.paraloc[side].size:=paracgsize;
  345. hp.paraloc[side].intsize:=paralen;
  346. hp.paraloc[side].Alignment:=paraalign;
  347. { Copy to stack? }
  348. if paracgsize=OS_NO then
  349. begin
  350. paraloc:=hp.paraloc[side].add_location;
  351. paraloc^.loc:=LOC_REFERENCE;
  352. paraloc^.size:=paracgsize;
  353. if side=callerside then
  354. paraloc^.reference.index:=NR_STACK_POINTER_REG
  355. else
  356. paraloc^.reference.index:=NR_FRAME_POINTER_REG;
  357. varalign:=used_align(size_2_align(paralen),paraalign,paraalign);
  358. paraloc^.reference.offset:=parasize;
  359. parasize:=align(parasize+paralen,varalign);
  360. end
  361. else
  362. begin
  363. if paralen=0 then
  364. internalerror(200501163);
  365. while (paralen>0) do
  366. begin
  367. { We can allocate at maximum 32 bits per location }
  368. if paralen>sizeof(aint) then
  369. l:=sizeof(aint)
  370. else
  371. l:=paralen;
  372. paraloc:=hp.paraloc[side].add_location;
  373. paraloc^.loc:=LOC_REFERENCE;
  374. paraloc^.size:=int_cgsize(l);
  375. if side=callerside then
  376. paraloc^.reference.index:=NR_STACK_POINTER_REG
  377. else
  378. paraloc^.reference.index:=NR_FRAME_POINTER_REG;
  379. varalign:=used_align(size_2_align(l),paraalign,paraalign);
  380. paraloc^.reference.offset:=parasize;
  381. parasize:=align(parasize+l,varalign);
  382. dec(paralen,l);
  383. end;
  384. end;
  385. end;
  386. { Adapt offsets for left-to-right calling }
  387. if p.proccalloption in pushleftright_pocalls then
  388. begin
  389. for i:=0 to paras.count-1 do
  390. begin
  391. hp:=tparavarsym(paras[i]);
  392. l:=push_size(hp.varspez,hp.vartype.def,p.proccalloption);
  393. varalign:=used_align(size_2_align(l),paraalign,paraalign);
  394. l:=align(l,varalign);
  395. with hp.paraloc[side].location^ do
  396. begin
  397. reference.offset:=parasize-reference.offset-l;
  398. if side=calleeside then
  399. inc(reference.offset,target_info.first_parm_offset);
  400. end;
  401. end;
  402. end
  403. else
  404. begin
  405. { Only need to adapt the callee side to include the
  406. standard stackframe size }
  407. if side=calleeside then
  408. begin
  409. for i:=0 to paras.count-1 do
  410. begin
  411. hp:=tparavarsym(paras[i]);
  412. inc(hp.paraloc[side].location^.reference.offset,target_info.first_parm_offset);
  413. end;
  414. end;
  415. end;
  416. end;
  417. procedure ti386paramanager.create_register_paraloc_info(p : tabstractprocdef; side: tcallercallee;paras:tparalist;
  418. var parareg,parasize:longint);
  419. var
  420. hp : tparavarsym;
  421. paraloc : pcgparalocation;
  422. paracgsize : tcgsize;
  423. i : integer;
  424. l,
  425. paralen,
  426. varalign : longint;
  427. pushaddr : boolean;
  428. paraalign : shortint;
  429. begin
  430. paraalign:=get_para_align(p.proccalloption);
  431. { Register parameters are assigned from left to right }
  432. for i:=0 to paras.count-1 do
  433. begin
  434. hp:=tparavarsym(paras[i]);
  435. pushaddr:=push_addr_param(hp.varspez,hp.vartype.def,p.proccalloption);
  436. if pushaddr then
  437. begin
  438. paralen:=sizeof(aint);
  439. paracgsize:=OS_ADDR;
  440. end
  441. else
  442. begin
  443. paralen:=push_size(hp.varspez,hp.vartype.def,p.proccalloption);
  444. paracgsize:=def_cgsize(hp.vartype.def);
  445. end;
  446. hp.paraloc[side].reset;
  447. hp.paraloc[side].size:=paracgsize;
  448. hp.paraloc[side].intsize:=paralen;
  449. hp.paraloc[side].Alignment:=paraalign;
  450. {
  451. EAX
  452. EDX
  453. ECX
  454. Stack
  455. Stack
  456. 64bit values,floats,arrays and records are always
  457. on the stack.
  458. }
  459. if (parareg<=high(parasupregs)) and
  460. (paralen<=sizeof(aint)) and
  461. (
  462. not(hp.vartype.def.deftype in [floatdef,recorddef,arraydef]) or
  463. pushaddr
  464. ) then
  465. begin
  466. paraloc:=hp.paraloc[side].add_location;
  467. paraloc^.size:=paracgsize;
  468. paraloc^.loc:=LOC_REGISTER;
  469. paraloc^.register:=newreg(R_INTREGISTER,parasupregs[parareg],cgsize2subreg(paracgsize));
  470. inc(parareg);
  471. end
  472. else
  473. begin
  474. { Copy to stack? }
  475. if paracgsize=OS_NO then
  476. begin
  477. paraloc:=hp.paraloc[side].add_location;
  478. paraloc^.loc:=LOC_REFERENCE;
  479. paraloc^.size:=paracgsize;
  480. if side=callerside then
  481. paraloc^.reference.index:=NR_STACK_POINTER_REG
  482. else
  483. paraloc^.reference.index:=NR_FRAME_POINTER_REG;
  484. varalign:=used_align(size_2_align(paralen),paraalign,paraalign);
  485. paraloc^.reference.offset:=parasize;
  486. parasize:=align(parasize+paralen,varalign);
  487. end
  488. else
  489. begin
  490. if paralen=0 then
  491. internalerror(200501163);
  492. while (paralen>0) do
  493. begin
  494. { We can allocate at maximum 32 bits per location }
  495. if paralen>sizeof(aint) then
  496. l:=sizeof(aint)
  497. else
  498. l:=paralen;
  499. paraloc:=hp.paraloc[side].add_location;
  500. paraloc^.loc:=LOC_REFERENCE;
  501. paraloc^.size:=int_cgsize(l);
  502. if side=callerside then
  503. paraloc^.reference.index:=NR_STACK_POINTER_REG
  504. else
  505. paraloc^.reference.index:=NR_FRAME_POINTER_REG;
  506. varalign:=used_align(size_2_align(l),paraalign,paraalign);
  507. paraloc^.reference.offset:=parasize;
  508. parasize:=align(parasize+l,varalign);
  509. dec(paralen,l);
  510. end;
  511. end;
  512. end;
  513. end;
  514. { Register parameters are assigned from left-to-right, adapt offset
  515. for calleeside to be reversed }
  516. for i:=0 to paras.count-1 do
  517. begin
  518. hp:=tparavarsym(paras[i]);
  519. with hp.paraloc[side].location^ do
  520. begin
  521. if (loc=LOC_REFERENCE) then
  522. begin
  523. l:=push_size(hp.varspez,hp.vartype.def,p.proccalloption);
  524. varalign:=used_align(size_2_align(l),paraalign,paraalign);
  525. l:=align(l,varalign);
  526. reference.offset:=parasize-reference.offset-l;
  527. if side=calleeside then
  528. inc(reference.offset,target_info.first_parm_offset);
  529. end;
  530. end;
  531. end;
  532. end;
  533. function ti386paramanager.create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;
  534. var
  535. parasize,
  536. parareg : longint;
  537. begin
  538. parasize:=0;
  539. parareg:=0;
  540. case p.proccalloption of
  541. pocall_register :
  542. create_register_paraloc_info(p,side,p.paras,parareg,parasize);
  543. pocall_inline,
  544. pocall_compilerproc,
  545. pocall_internproc :
  546. begin
  547. { Use default calling }
  548. if (pocall_default=pocall_register) then
  549. create_register_paraloc_info(p,side,p.paras,parareg,parasize)
  550. else
  551. create_stdcall_paraloc_info(p,side,p.paras,parasize);
  552. end;
  553. else
  554. create_stdcall_paraloc_info(p,side,p.paras,parasize);
  555. end;
  556. create_funcretloc_info(p,side);
  557. result:=parasize;
  558. end;
  559. function ti386paramanager.create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint;
  560. var
  561. parasize : longint;
  562. begin
  563. parasize:=0;
  564. { calculate the registers for the normal parameters }
  565. create_stdcall_paraloc_info(p,callerside,p.paras,parasize);
  566. { append the varargs }
  567. create_stdcall_paraloc_info(p,callerside,varargspara,parasize);
  568. result:=parasize;
  569. end;
  570. procedure ti386paramanager.createtempparaloc(list: taasmoutput;calloption : tproccalloption;parasym : tparavarsym;var cgpara:TCGPara);
  571. var
  572. paraloc : pcgparalocation;
  573. begin
  574. paraloc:=parasym.paraloc[callerside].location;
  575. { No need for temps when value is pushed }
  576. if assigned(paraloc) and
  577. (paraloc^.loc=LOC_REFERENCE) and
  578. (paraloc^.reference.index=NR_STACK_POINTER_REG) then
  579. duplicateparaloc(list,calloption,parasym,cgpara)
  580. else
  581. inherited createtempparaloc(list,calloption,parasym,cgpara);
  582. end;
  583. begin
  584. paramanager:=ti386paramanager.create;
  585. end.
  586. {
  587. $Log$
  588. Revision 1.65 2005-02-03 20:04:49 peter
  589. * push_addr_param must be defined per target
  590. Revision 1.64 2005/01/30 11:03:22 peter
  591. * revert last commit
  592. Revision 1.62 2005/01/18 22:19:20 peter
  593. * multiple location support for i386 a_param_ref
  594. * remove a_param_copy_ref for i386
  595. Revision 1.61 2005/01/10 21:50:05 jonas
  596. + support for passing records in registers under darwin
  597. * tcgpara now also has an intsize field, which contains the size in
  598. bytes of the whole parameter
  599. Revision 1.60 2004/11/22 22:01:19 peter
  600. * fixed varargs
  601. * replaced dynarray with tlist
  602. Revision 1.59 2004/11/21 17:54:59 peter
  603. * ttempcreatenode.create_reg merged into .create with parameter
  604. whether a register is allowed
  605. * funcret_paraloc renamed to funcretloc
  606. Revision 1.58 2004/11/21 17:17:04 florian
  607. * changed funcret location back to tlocation
  608. Revision 1.57 2004/11/15 23:35:31 peter
  609. * tparaitem removed, use tparavarsym instead
  610. * parameter order is now calculated from paranr value in tparavarsym
  611. Revision 1.56 2004/10/31 21:45:03 peter
  612. * generic tlocation
  613. * move tlocation to cgutils
  614. Revision 1.55 2004/09/21 17:25:12 peter
  615. * paraloc branch merged
  616. Revision 1.54.4.1 2004/08/31 20:43:06 peter
  617. * paraloc patch
  618. Revision 1.54 2004/07/09 23:30:13 jonas
  619. * changed first_sse_imreg to first_mm_imreg
  620. Revision 1.53 2004/07/09 23:09:02 peter
  621. * varargs calculation fixed, it's now the same as the other
  622. targets
  623. Revision 1.52 2004/06/20 08:55:31 florian
  624. * logs truncated
  625. Revision 1.51 2004/06/16 20:07:10 florian
  626. * dwarf branch merged
  627. Revision 1.50.2.3 2004/05/02 21:37:35 florian
  628. * setting of func. ret. for i386 fixed
  629. Revision 1.50.2.2 2004/05/02 12:45:32 peter
  630. * enabled cpuhasfixedstack for x86-64 again
  631. * fixed size of temp allocation for parameters
  632. Revision 1.50.2.1 2004/05/01 16:02:10 peter
  633. * POINTER_SIZE replaced with sizeof(aint)
  634. * aint,aword,tconst*int moved to globtype
  635. Revision 1.50 2004/02/09 22:14:17 peter
  636. * more x86_64 parameter fixes
  637. * tparalocation.lochigh is now used to indicate if register64.reghi
  638. is used and what the type is
  639. }