cpupara.pas 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641
  1. {
  2. Copyright (c) 2002 by Florian Klaempfl
  3. Generates the argument location information for 680x0
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. ****************************************************************************
  16. }
  17. unit cpupara;
  18. {$i fpcdefs.inc}
  19. interface
  20. uses
  21. globtype,
  22. cpubase,
  23. aasmdata,
  24. symconst,symtype,symdef,symsym,
  25. parabase,paramgr,cgbase,cgutils;
  26. type
  27. { Returns the location for the nr-st 32 Bit int parameter
  28. if every parameter before is an 32 Bit int parameter as well
  29. and if the calling conventions for the helper routines of the
  30. rtl are used.
  31. }
  32. tcpuparamanager = class(tparamanager)
  33. function ret_in_param(def:tdef;pd:tabstractprocdef):boolean;override;
  34. function param_use_paraloc(const cgpara:tcgpara):boolean;override;
  35. function create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;override;
  36. function push_addr_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;override;
  37. function get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;override;
  38. procedure createtempparaloc(list: TAsmList;calloption : tproccalloption;parasym : tparavarsym;can_use_final_stack_loc : boolean;var cgpara:TCGPara);override;
  39. function create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint;override;
  40. function parsefuncretloc(p : tabstractprocdef; const s : string) : boolean;override;
  41. function get_volatile_registers_int(calloption:tproccalloption):tcpuregisterset;override;
  42. function get_volatile_registers_address(calloption:tproccalloption):tcpuregisterset;override;
  43. function get_volatile_registers_fpu(calloption:tproccalloption):tcpuregisterset;override;
  44. private
  45. function parse_loc_string_to_register(var locreg: tregister; const s : string): boolean;
  46. function create_stdcall_paraloc_info(p : tabstractprocdef; side: tcallercallee; paras: tparalist;
  47. var cur_stack_offset: aword):longint;
  48. function create_register_paraloc_info(p : tabstractprocdef; side: tcallercallee; paras: tparalist;
  49. var cur_stack_offset: aword):longint;
  50. end;
  51. implementation
  52. uses
  53. verbose,
  54. globals,
  55. systems,
  56. cpuinfo,
  57. defutil,
  58. cutils,
  59. hlcgobj;
  60. const
  61. intparasupregs : array[0..1] of tsuperregister = (RS_D0,RS_D1);
  62. addrparasupregs : array[0..1] of tsuperregister = (RS_A0,RS_A1);
  63. floatparasupregs : array[0..1] of tsuperregister = (RS_FP0,RS_FP1);
  64. function tcpuparamanager.get_volatile_registers_int(calloption:tproccalloption):tcpuregisterset;
  65. begin
  66. { d0 and d1 are considered volatile }
  67. Result:=VOLATILE_INTREGISTERS;
  68. end;
  69. function tcpuparamanager.get_volatile_registers_address(calloption:tproccalloption):tcpuregisterset;
  70. begin
  71. { a0 and a1 are considered volatile }
  72. Result:=VOLATILE_ADDRESSREGISTERS;
  73. end;
  74. function tcpuparamanager.get_volatile_registers_fpu(calloption:tproccalloption):tcpuregisterset;
  75. begin
  76. { fp0 and fp1 are considered volatile }
  77. Result:=VOLATILE_FPUREGISTERS;
  78. end;
  79. function tcpuparamanager.param_use_paraloc(const cgpara:tcgpara):boolean;
  80. var
  81. paraloc : pcgparalocation;
  82. begin
  83. if not assigned(cgpara.location) then
  84. internalerror(200410102);
  85. result:=true;
  86. { All locations are LOC_REFERENCE }
  87. paraloc:=cgpara.location;
  88. while assigned(paraloc) do
  89. begin
  90. if (paraloc^.loc<>LOC_REFERENCE) then
  91. begin
  92. result:=false;
  93. exit;
  94. end;
  95. paraloc:=paraloc^.next;
  96. end;
  97. end;
  98. { TODO: copied from ppc cg, needs work}
  99. function tcpuparamanager.push_addr_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;
  100. begin
  101. result:=false;
  102. { var,out,constref always require address }
  103. if varspez in [vs_var,vs_out,vs_constref] then
  104. begin
  105. result:=true;
  106. exit;
  107. end;
  108. case def.typ of
  109. variantdef,
  110. formaldef :
  111. result:=true;
  112. recorddef:
  113. result:=(calloption in [pocall_register]) and
  114. (varspez in [vs_const]);
  115. arraydef:
  116. result:=(tarraydef(def).highrange>=tarraydef(def).lowrange) or
  117. is_open_array(def) or
  118. is_array_of_const(def) or
  119. is_array_constructor(def);
  120. objectdef :
  121. result:=is_object(def);
  122. setdef :
  123. result:=not is_smallset(def);
  124. stringdef :
  125. result:=tstringdef(def).stringtype in [st_shortstring,st_longstring];
  126. procvardef :
  127. { Handling of methods must match that of records }
  128. result:=false;
  129. end;
  130. end;
  131. function tcpuparamanager.ret_in_param(def:tdef;pd:tabstractprocdef):boolean;
  132. begin
  133. if handle_common_ret_in_param(def,pd,result) then
  134. exit;
  135. case def.typ of
  136. recorddef:
  137. if def.size in [1,2,4] then
  138. begin
  139. result:=false;
  140. exit;
  141. end;
  142. end;
  143. result:=inherited ret_in_param(def,pd);
  144. end;
  145. function tcpuparamanager.get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;
  146. var
  147. paraloc : pcgparalocation;
  148. retcgsize : tcgsize;
  149. retregtype : tregistertype;
  150. begin
  151. if set_common_funcretloc_info(p,forcetempdef,retcgsize,result) then
  152. exit;
  153. { always use the whole 32 bit register when returning values }
  154. if (side=calleeside) and
  155. (result.intsize>0) and
  156. (result.intsize<sizeof(aint)) then
  157. begin
  158. result.def:=sinttype;
  159. result.intsize:=sizeof(aint);
  160. retcgsize:=OS_SINT;
  161. result.size:=retcgsize;
  162. end;
  163. paraloc:=result.add_location;
  164. { Return in FPU register? }
  165. if not (cs_fp_emulation in current_settings.moduleswitches) and
  166. not (current_settings.fputype=fpu_soft) and (result.def.typ=floatdef) then
  167. begin
  168. paraloc^.loc:=LOC_FPUREGISTER;
  169. paraloc^.register:=NR_FPU_RESULT_REG;
  170. paraloc^.size:=retcgsize;
  171. paraloc^.def:=result.def;
  172. end
  173. else
  174. { Return in register }
  175. begin
  176. if retcgsize in [OS_64,OS_S64] then
  177. begin
  178. { low 32bits }
  179. paraloc^.loc:=LOC_REGISTER;
  180. paraloc^.size:=OS_32;
  181. paraloc^.def:=u32inttype;
  182. if side=callerside then
  183. paraloc^.register:=NR_FUNCTION_RESULT64_LOW_REG
  184. else
  185. paraloc^.register:=NR_FUNCTION_RETURN64_LOW_REG;
  186. { high 32bits }
  187. paraloc:=result.add_location;
  188. paraloc^.loc:=LOC_REGISTER;
  189. paraloc^.size:=OS_32;
  190. paraloc^.def:=u32inttype;
  191. if side=calleeside then
  192. paraloc^.register:=NR_FUNCTION_RESULT64_HIGH_REG
  193. else
  194. paraloc^.register:=NR_FUNCTION_RETURN64_HIGH_REG;
  195. end
  196. else
  197. begin
  198. paraloc^.loc:=LOC_REGISTER;
  199. paraloc^.size:=retcgsize;
  200. paraloc^.def:=result.def;
  201. { GCC (and SVR4 in general maybe?) requires a pointer result on the A0
  202. register, as well as D0. So we init the result to be A0, then copy
  203. it also to D0 in hlcg.gen_load_loc_function_result. This is not pretty,
  204. but we don't really have an architecture for funcretlocs in two
  205. separate locations.
  206. We also have to figure out a better switch for this, because this is
  207. now compiler and platform specific... (KB) }
  208. if (tprocdef(p).proccalloption in [pocall_cdecl,pocall_cppdecl]) and
  209. (target_info.system in [system_m68k_linux]) and
  210. assigned(result.def) and
  211. (result.def.typ in [stringdef,pointerdef,classrefdef,objectdef,
  212. procvardef,procdef,arraydef,formaldef]) then
  213. retregtype:=R_ADDRESSREGISTER
  214. else
  215. retregtype:=R_INTREGISTER;
  216. if retregtype = R_ADDRESSREGISTER then
  217. begin
  218. if side=callerside then
  219. paraloc^.register:=newreg(R_ADDRESSREGISTER,RS_RETURN_ADDRESS_REG,cgsize2subreg(R_ADDRESSREGISTER,retcgsize))
  220. else
  221. paraloc^.register:=newreg(R_ADDRESSREGISTER,RS_RETURN_ADDRESS_REG,cgsize2subreg(R_ADDRESSREGISTER,retcgsize));
  222. end
  223. else
  224. begin
  225. if side=callerside then
  226. paraloc^.register:=newreg(R_INTREGISTER,RS_FUNCTION_RESULT_REG,cgsize2subreg(R_INTREGISTER,retcgsize))
  227. else
  228. paraloc^.register:=newreg(R_INTREGISTER,RS_FUNCTION_RETURN_REG,cgsize2subreg(R_INTREGISTER,retcgsize));
  229. end;
  230. end;
  231. end;
  232. end;
  233. function tcpuparamanager.create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;
  234. var
  235. cur_stack_offset: aword;
  236. begin
  237. cur_stack_offset:=0;
  238. case p.proccalloption of
  239. pocall_register :
  240. result:=create_register_paraloc_info(p,side,p.paras,cur_stack_offset);
  241. else
  242. result:=create_stdcall_paraloc_info(p,side,p.paras,cur_stack_offset);
  243. end;
  244. create_funcretloc_info(p,side);
  245. end;
  246. function tcpuparamanager.create_stdcall_paraloc_info(p : tabstractprocdef; side: tcallercallee; paras: tparalist;
  247. var cur_stack_offset: aword):longint;
  248. var
  249. paraloc : pcgparalocation;
  250. hp : tparavarsym;
  251. paracgsize : tcgsize;
  252. paralen : aint;
  253. paradef : tdef;
  254. i : longint;
  255. firstparaloc : boolean;
  256. begin
  257. result:=0;
  258. for i:=0 to paras.count-1 do
  259. begin
  260. hp:=tparavarsym(paras[i]);
  261. paradef:=hp.vardef;
  262. { syscall for AmigaOS can have already a paraloc set }
  263. if (vo_has_explicit_paraloc in hp.varoptions) then
  264. begin
  265. if not(vo_is_syscall_lib in hp.varoptions) then
  266. internalerror(200506051);
  267. continue;
  268. end;
  269. hp.paraloc[side].reset;
  270. { currently only support C-style array of const }
  271. if (p.proccalloption in cstylearrayofconst) and
  272. is_array_of_const(paradef) then
  273. begin
  274. paraloc:=hp.paraloc[side].add_location;
  275. { hack: the paraloc must be valid, but is not actually used }
  276. paraloc^.loc:=LOC_REGISTER;
  277. paraloc^.register:=NR_D0;
  278. paraloc^.size:=OS_ADDR;
  279. paraloc^.def:=voidpointertype;
  280. break;
  281. end;
  282. if push_addr_param(hp.varspez,paradef,p.proccalloption) then
  283. begin
  284. paradef:=cpointerdef.getreusable_no_free(paradef);
  285. paracgsize := OS_ADDR;
  286. paralen := tcgsize2size[OS_ADDR];
  287. end
  288. else
  289. begin
  290. if not is_special_array(paradef) then
  291. paralen:=paradef.size
  292. else
  293. paralen:=tcgsize2size[def_cgsize(paradef)];
  294. paracgsize:=def_cgsize(paradef);
  295. { for things like formaldef }
  296. if (paracgsize=OS_NO) and (paradef.typ<>recorddef) then
  297. begin
  298. paracgsize:=OS_ADDR;
  299. paralen := tcgsize2size[OS_ADDR];
  300. end;
  301. end;
  302. hp.paraloc[side].alignment:=target_info.stackalign; //std_param_align;
  303. hp.paraloc[side].size:=paracgsize;
  304. hp.paraloc[side].intsize:=paralen;
  305. hp.paraloc[side].def:=paradef;
  306. if (paralen = 0) then
  307. if (paradef.typ = recorddef) then
  308. begin
  309. paraloc:=hp.paraloc[side].add_location;
  310. paraloc^.loc := LOC_VOID;
  311. end
  312. else
  313. internalerror(200506052);
  314. firstparaloc:=true;
  315. { can become < 0 for e.g. 3-byte records }
  316. while (paralen > 0) do
  317. begin
  318. paraloc:=hp.paraloc[side].add_location;
  319. paraloc^.loc:=LOC_REFERENCE;
  320. paraloc^.def:=get_paraloc_def(paradef,paralen,firstparaloc);
  321. if (not (cs_fp_emulation in current_settings.moduleswitches)) and
  322. (paradef.typ=floatdef) then
  323. paraloc^.size:=int_float_cgsize(paralen)
  324. else
  325. paraloc^.size:=int_cgsize(paralen);
  326. paraloc^.reference.offset:=cur_stack_offset;
  327. if (side = callerside) then
  328. paraloc^.reference.index:=NR_STACK_POINTER_REG
  329. else
  330. begin
  331. paraloc^.reference.index:=NR_FRAME_POINTER_REG;
  332. inc(paraloc^.reference.offset,target_info.first_parm_offset);
  333. end;
  334. { M68K is a big-endian target }
  335. if (paralen<target_info.stackalign{tcgsize2size[OS_INT]}) then
  336. inc(paraloc^.reference.offset,target_info.stackalign-paralen);
  337. inc(cur_stack_offset,align(paralen,target_info.stackalign));
  338. paralen := 0;
  339. firstparaloc:=false;
  340. end;
  341. end;
  342. result:=cur_stack_offset;
  343. end;
  344. function tcpuparamanager.create_register_paraloc_info(p : tabstractprocdef; side: tcallercallee;paras:tparalist;
  345. var cur_stack_offset: aword): longint;
  346. var
  347. hp : tparavarsym;
  348. paradef : tdef;
  349. paraloc : pcgparalocation;
  350. paracgsize : tcgsize;
  351. i : integer;
  352. l,
  353. paralen,
  354. parareg: longint;
  355. addrparareg: longint;
  356. floatparareg: longint;
  357. varalign : longint;
  358. paraalign : shortint;
  359. pass : byte;
  360. firstparaloc,
  361. pushaddr : boolean;
  362. rt: tregistertype;
  363. begin
  364. result:=0;
  365. parareg:=0;
  366. addrparareg:=0;
  367. floatparareg:=0;
  368. if paras.count=0 then
  369. exit;
  370. paraalign:=get_para_align(p.proccalloption);
  371. { clean up here so we can later detect properly if a parameter has been
  372. assigned or not
  373. }
  374. for i:=0 to paras.count-1 do
  375. tparavarsym(paras[i]).paraloc[side].reset;
  376. { Register parameters are assigned from left to right,
  377. stack parameters from right to left so assign first the
  378. register parameters in a first pass, in the second
  379. pass all unhandled parameters are done }
  380. for pass:=1 to 2 do
  381. begin
  382. if pass=1 then
  383. i:=0
  384. else
  385. i:=paras.count-1;
  386. while true do
  387. begin
  388. hp:=tparavarsym(paras[i]);
  389. paradef:=hp.vardef;
  390. if not(assigned(hp.paraloc[side].location)) then
  391. begin
  392. pushaddr:=push_addr_param(hp.varspez,hp.vardef,p.proccalloption);
  393. if pushaddr then
  394. begin
  395. paralen:=sizeof(aint);
  396. paracgsize:=OS_ADDR;
  397. paradef:=cpointerdef.getreusable_no_free(paradef);
  398. end
  399. else
  400. begin
  401. paralen:=push_size(hp.varspez,hp.vardef,p.proccalloption);
  402. paracgsize:=def_cgsize(hp.vardef);
  403. end;
  404. hp.paraloc[side].size:=paracgsize;
  405. hp.paraloc[side].intsize:=paralen;
  406. hp.paraloc[side].Alignment:=paraalign;
  407. hp.paraloc[side].def:=paradef;
  408. {
  409. In case of po_delphi_nested_cc, the parent frame pointer
  410. is also always passed on the stack.
  411. }
  412. rt:=chlcgobj.def2regtyp(paradef);
  413. if (rt=R_FPUREGISTER) and
  414. (floatparareg<=high(floatparasupregs)) and
  415. (not pushaddr) then
  416. begin
  417. if pass=1 then
  418. begin
  419. paraloc:=hp.paraloc[side].add_location;
  420. paraloc^.size:=paracgsize;
  421. paraloc^.def:=paradef;
  422. paraloc^.loc:=LOC_FPUREGISTER;
  423. paraloc^.register:=newreg(R_FPUREGISTER,floatparasupregs[floatparareg],R_SUBWHOLE);
  424. inc(floatparareg);
  425. end;
  426. end
  427. else
  428. if (((rt=R_INTREGISTER) and (parareg<=high(intparasupregs))) or
  429. ((rt=R_ADDRESSREGISTER) and (addrparareg<=high(addrparasupregs)))) and
  430. (paralen<=sizeof(aint)) and
  431. (not(hp.vardef.typ in [floatdef,recorddef,arraydef]) or
  432. pushaddr or
  433. is_dynamic_array(hp.vardef)) and
  434. (not(vo_is_parentfp in hp.varoptions) or
  435. not(po_delphi_nested_cc in p.procoptions)) then
  436. begin
  437. if pass=1 then
  438. begin
  439. paraloc:=hp.paraloc[side].add_location;
  440. paraloc^.size:=paracgsize;
  441. paraloc^.def:=paradef;
  442. paraloc^.loc:=LOC_REGISTER;
  443. if (rt=R_ADDRESSREGISTER) and (addrparareg<=high(addrparasupregs)) then
  444. begin
  445. paraloc^.register:=newreg(R_ADDRESSREGISTER,addrparasupregs[addrparareg],R_SUBWHOLE);
  446. inc(addrparareg);
  447. end
  448. else
  449. if (rt=R_INTREGISTER) and (parareg<=high(intparasupregs)) then
  450. begin
  451. paraloc^.register:=newreg(R_INTREGISTER,intparasupregs[parareg],cgsize2subreg(R_INTREGISTER,paracgsize));
  452. inc(parareg);
  453. end
  454. else
  455. internalerror(2016051801);
  456. end;
  457. end
  458. else
  459. if pass=2 then
  460. begin
  461. { Copy to stack? }
  462. if (use_fixed_stack) or
  463. (paracgsize=OS_NO) then
  464. begin
  465. paraloc:=hp.paraloc[side].add_location;
  466. paraloc^.loc:=LOC_REFERENCE;
  467. paraloc^.size:=paracgsize;
  468. paraloc^.def:=paradef;
  469. if side=callerside then
  470. paraloc^.reference.index:=NR_STACK_POINTER_REG
  471. else
  472. paraloc^.reference.index:=NR_FRAME_POINTER_REG;
  473. varalign:=used_align(size_2_align(paralen),paraalign,paraalign);
  474. paraloc^.reference.offset:=cur_stack_offset;
  475. if side=calleeside then
  476. inc(paraloc^.reference.offset,target_info.first_parm_offset);
  477. if (paralen<target_info.stackalign{tcgsize2size[OS_INT]}) then
  478. inc(paraloc^.reference.offset,target_info.stackalign-paralen);
  479. cur_stack_offset:=align(cur_stack_offset+paralen,varalign);
  480. end
  481. else
  482. begin
  483. if paralen=0 then
  484. internalerror(200501163);
  485. firstparaloc:=true;
  486. while (paralen>0) do
  487. begin
  488. paraloc:=hp.paraloc[side].add_location;
  489. paraloc^.loc:=LOC_REFERENCE;
  490. { Extended and double need a single location }
  491. if (paracgsize in [OS_F64,OS_F32]) then
  492. begin
  493. paraloc^.size:=paracgsize;
  494. paraloc^.def:=paradef;
  495. l:=paralen;
  496. end
  497. else
  498. begin
  499. { We can allocate at maximum 32 bits per location }
  500. if paralen>sizeof(aint) then
  501. begin
  502. l:=sizeof(aint);
  503. paraloc^.def:=uinttype;
  504. end
  505. else
  506. begin
  507. l:=paralen;
  508. paraloc^.def:=get_paraloc_def(paradef,l,firstparaloc);
  509. end;
  510. paraloc^.size:=int_cgsize(l);
  511. end;
  512. if side=callerside then
  513. paraloc^.reference.index:=NR_STACK_POINTER_REG
  514. else
  515. paraloc^.reference.index:=NR_FRAME_POINTER_REG;
  516. varalign:=used_align(size_2_align(l),paraalign,paraalign);
  517. paraloc^.reference.offset:=cur_stack_offset;
  518. { M68K is a big-endian target }
  519. if (paralen<target_info.stackalign{tcgsize2size[OS_INT]}) then
  520. inc(paraloc^.reference.offset,target_info.stackalign-paralen);
  521. if side=calleeside then
  522. inc(paraloc^.reference.offset,target_info.first_parm_offset);
  523. cur_stack_offset:=align(cur_stack_offset+l,varalign);
  524. dec(paralen,l);
  525. firstparaloc:=false;
  526. end;
  527. end;
  528. end;
  529. end;
  530. case pass of
  531. 1:
  532. begin
  533. if i=paras.count-1 then
  534. break;
  535. inc(i);
  536. end;
  537. 2:
  538. begin
  539. if i=0 then
  540. break;
  541. dec(i);
  542. end;
  543. end;
  544. end;
  545. end;
  546. result:=cur_stack_offset;
  547. end;
  548. function tcpuparamanager.parse_loc_string_to_register(var locreg: tregister; const s : string): boolean;
  549. begin
  550. locreg:=std_regnum_search(lower(s));
  551. result:=(locreg <> NR_NO) and (locreg <> NR_SP);
  552. end;
  553. function tcpuparamanager.parsefuncretloc(p : tabstractprocdef; const s : string) : boolean;
  554. begin
  555. case target_info.system of
  556. system_m68k_amiga:
  557. result:=parse_loc_string_to_register(p.exp_funcretloc, s);
  558. else
  559. internalerror(2005121801);
  560. end;
  561. end;
  562. procedure tcpuparamanager.createtempparaloc(list: TAsmList;calloption : tproccalloption;parasym : tparavarsym;can_use_final_stack_loc : boolean;var cgpara:TCGPara);
  563. begin
  564. { Never a need for temps when value is pushed (calls inside parameters
  565. will simply allocate even more stack space for their parameters) }
  566. if not(use_fixed_stack) then
  567. can_use_final_stack_loc:=true;
  568. inherited createtempparaloc(list,calloption,parasym,can_use_final_stack_loc,cgpara);
  569. end;
  570. function tcpuparamanager.create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint;
  571. var
  572. cur_stack_offset: aword;
  573. begin
  574. cur_stack_offset:=0;
  575. result:=create_stdcall_paraloc_info(p,callerside,p.paras,cur_stack_offset);
  576. if (p.proccalloption in cstylearrayofconst) then
  577. { just continue loading the parameters in the registers }
  578. result:=create_stdcall_paraloc_info(p,callerside,varargspara,cur_stack_offset)
  579. else
  580. internalerror(200410231);
  581. end;
  582. begin
  583. paramanager:=tcpuparamanager.create;
  584. end.