cpupara.pas 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729
  1. {
  2. $Id$
  3. Copyright (c) 2002 by Florian Klaempfl
  4. PowerPC specific calling conventions
  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. unit cpupara;
  19. {$i fpcdefs.inc}
  20. interface
  21. uses
  22. globtype,
  23. cclasses,
  24. aasmtai,
  25. cpubase,cpuinfo,
  26. symconst,symbase,symtype,symdef,symsym,
  27. paramgr,parabase,cgbase;
  28. type
  29. tppcparamanager = class(tparamanager)
  30. function get_volatile_registers_int(calloption : tproccalloption):tcpuregisterset;override;
  31. function get_volatile_registers_fpu(calloption : tproccalloption):tcpuregisterset;override;
  32. function push_addr_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;override;
  33. procedure getintparaloc(calloption : tproccalloption; nr : longint;var cgpara:TCGPara);override;
  34. function create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;override;
  35. function create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint;override;
  36. procedure create_funcretloc_info(p : tabstractprocdef; side: tcallercallee);
  37. private
  38. procedure init_values(var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset: aword);
  39. function create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee; paras:tparalist;
  40. var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset: aword):longint;
  41. function parseparaloc(p : tparavarsym;const s : string) : boolean;override;
  42. end;
  43. implementation
  44. uses
  45. verbose,systems,
  46. procinfo,
  47. rgobj,
  48. defutil,
  49. cgutils;
  50. function tppcparamanager.get_volatile_registers_int(calloption : tproccalloption):tcpuregisterset;
  51. begin
  52. result := [RS_R3..RS_R12];
  53. end;
  54. function tppcparamanager.get_volatile_registers_fpu(calloption : tproccalloption):tcpuregisterset;
  55. begin
  56. case target_info.abi of
  57. abi_powerpc_aix:
  58. result := [RS_F0..RS_F13];
  59. abi_powerpc_sysv:
  60. result := [RS_F0..RS_F13];
  61. else
  62. internalerror(2003091401);
  63. end;
  64. end;
  65. procedure tppcparamanager.getintparaloc(calloption : tproccalloption; nr : longint;var cgpara:TCGPara);
  66. var
  67. paraloc : pcgparalocation;
  68. begin
  69. cgpara.reset;
  70. cgpara.size:=OS_INT;
  71. cgpara.alignment:=get_para_align(calloption);
  72. paraloc:=cgpara.add_location;
  73. with paraloc^ do
  74. begin
  75. size:=OS_INT;
  76. if (nr<=8) then
  77. begin
  78. if nr=0 then
  79. internalerror(200309271);
  80. loc:=LOC_REGISTER;
  81. register:=newreg(R_INTREGISTER,RS_R2+nr,R_SUBWHOLE);
  82. end
  83. else
  84. begin
  85. loc:=LOC_REFERENCE;
  86. paraloc^.reference.index:=NR_STACK_POINTER_REG;
  87. reference.offset:=sizeof(aint)*(nr-8);
  88. end;
  89. end;
  90. end;
  91. function getparaloc(p : tdef) : tcgloc;
  92. begin
  93. { Later, the LOC_REFERENCE is in most cases changed into LOC_REGISTER
  94. if push_addr_param for the def is true
  95. }
  96. case p.deftype of
  97. orddef:
  98. result:=LOC_REGISTER;
  99. floatdef:
  100. result:=LOC_FPUREGISTER;
  101. enumdef:
  102. result:=LOC_REGISTER;
  103. pointerdef:
  104. result:=LOC_REGISTER;
  105. formaldef:
  106. result:=LOC_REGISTER;
  107. classrefdef:
  108. result:=LOC_REGISTER;
  109. recorddef:
  110. result:=LOC_REFERENCE;
  111. objectdef:
  112. if is_object(p) then
  113. result:=LOC_REFERENCE
  114. else
  115. result:=LOC_REGISTER;
  116. stringdef:
  117. if is_shortstring(p) or is_longstring(p) then
  118. result:=LOC_REFERENCE
  119. else
  120. result:=LOC_REGISTER;
  121. procvardef:
  122. if (po_methodpointer in tprocvardef(p).procoptions) then
  123. result:=LOC_REFERENCE
  124. else
  125. result:=LOC_REGISTER;
  126. filedef:
  127. result:=LOC_REGISTER;
  128. arraydef:
  129. result:=LOC_REFERENCE;
  130. setdef:
  131. if is_smallset(p) then
  132. result:=LOC_REGISTER
  133. else
  134. result:=LOC_REFERENCE;
  135. variantdef:
  136. result:=LOC_REFERENCE;
  137. { avoid problems with errornous definitions }
  138. errordef:
  139. result:=LOC_REGISTER;
  140. else
  141. internalerror(2002071001);
  142. end;
  143. end;
  144. function tppcparamanager.push_addr_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;
  145. var
  146. size, dummy: aint;
  147. begin
  148. { var,out always require address }
  149. if varspez in [vs_var,vs_out] then
  150. begin
  151. result:=true;
  152. exit;
  153. end;
  154. case def.deftype of
  155. recorddef:
  156. begin
  157. if (target_info.abi = abi_powerpc_aix) then
  158. begin
  159. // all records should be passed by value under the aix abi,
  160. // but we can only fake this for 1, 2 and 4 bytes for now
  161. size := def.size;
  162. result := (size > 4) or
  163. not(byte(size) in [1,2,4]);
  164. end
  165. else
  166. result := true;
  167. end;
  168. arraydef:
  169. result:=(tarraydef(def).highrange>=tarraydef(def).lowrange) or
  170. is_open_array(def) or
  171. is_array_of_const(def) or
  172. is_array_constructor(def);
  173. setdef :
  174. result:=(tsetdef(def).settype<>smallset);
  175. stringdef :
  176. result:=tstringdef(def).string_typ in [st_shortstring,st_longstring];
  177. procvardef :
  178. result:=po_methodpointer in tprocvardef(def).procoptions;
  179. else
  180. result:=inherited push_addr_param(varspez,def,calloption);
  181. end;
  182. end;
  183. procedure tppcparamanager.init_values(var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset: aword);
  184. begin
  185. case target_info.abi of
  186. abi_powerpc_aix:
  187. cur_stack_offset:=24;
  188. abi_powerpc_sysv:
  189. cur_stack_offset:=8;
  190. else
  191. internalerror(2003051901);
  192. end;
  193. curintreg:=RS_R3;
  194. curfloatreg:=RS_F1;
  195. curmmreg:=RS_M1;
  196. end;
  197. procedure tppcparamanager.create_funcretloc_info(p : tabstractprocdef; side: tcallercallee);
  198. var
  199. retcgsize : tcgsize;
  200. begin
  201. { Constructors return self instead of a boolean }
  202. if (p.proctypeoption=potype_constructor) then
  203. retcgsize:=OS_ADDR
  204. else
  205. retcgsize:=def_cgsize(p.rettype.def);
  206. location_reset(p.funcretloc[side],LOC_INVALID,OS_NO);
  207. p.funcretloc[side].size:=retcgsize;
  208. { void has no location }
  209. if is_void(p.rettype.def) then
  210. begin
  211. p.funcretloc[side].loc:=LOC_VOID;
  212. exit;
  213. end;
  214. { Return in FPU register? }
  215. if p.rettype.def.deftype=floatdef then
  216. begin
  217. p.funcretloc[side].loc:=LOC_FPUREGISTER;
  218. p.funcretloc[side].register:=NR_FPU_RESULT_REG;
  219. p.funcretloc[side].size:=retcgsize;
  220. end
  221. else
  222. { Return in register? }
  223. if not ret_in_param(p.rettype.def,p.proccalloption) then
  224. begin
  225. {$ifndef cpu64bit}
  226. if retcgsize in [OS_64,OS_S64] then
  227. begin
  228. { low 32bits }
  229. p.funcretloc[side].loc:=LOC_REGISTER;
  230. if side=callerside then
  231. p.funcretloc[side].register64.reghi:=NR_FUNCTION_RESULT64_HIGH_REG
  232. else
  233. p.funcretloc[side].register64.reghi:=NR_FUNCTION_RETURN64_HIGH_REG;
  234. { high 32bits }
  235. if side=callerside then
  236. p.funcretloc[side].register64.reglo:=NR_FUNCTION_RESULT64_LOW_REG
  237. else
  238. p.funcretloc[side].register64.reglo:=NR_FUNCTION_RETURN64_LOW_REG;
  239. end
  240. else
  241. {$endif cpu64bit}
  242. begin
  243. p.funcretloc[side].loc:=LOC_REGISTER;
  244. p.funcretloc[side].size:=retcgsize;
  245. if side=callerside then
  246. p.funcretloc[side].register:=newreg(R_INTREGISTER,RS_FUNCTION_RESULT_REG,cgsize2subreg(retcgsize))
  247. else
  248. p.funcretloc[side].register:=newreg(R_INTREGISTER,RS_FUNCTION_RETURN_REG,cgsize2subreg(retcgsize));
  249. end;
  250. end
  251. else
  252. begin
  253. p.funcretloc[side].loc:=LOC_REFERENCE;
  254. p.funcretloc[side].size:=retcgsize;
  255. end;
  256. end;
  257. function tppcparamanager.create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;
  258. var
  259. cur_stack_offset: aword;
  260. curintreg, curfloatreg, curmmreg: tsuperregister;
  261. begin
  262. init_values(curintreg,curfloatreg,curmmreg,cur_stack_offset);
  263. result := create_paraloc_info_intern(p,side,p.paras,curintreg,curfloatreg,curmmreg,cur_stack_offset);
  264. create_funcretloc_info(p,side);
  265. end;
  266. function tppcparamanager.create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee; paras:tparalist;
  267. var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset: aword):longint;
  268. var
  269. stack_offset: aword;
  270. nextintreg,nextfloatreg,nextmmreg, maxfpureg : tsuperregister;
  271. paradef : tdef;
  272. paraloc,paraloc2 : pcgparalocation;
  273. i : integer;
  274. hp : tparavarsym;
  275. loc : tcgloc;
  276. paracgsize: tcgsize;
  277. is_64bit: boolean;
  278. procedure assignintreg;
  279. begin
  280. if nextintreg<=RS_R10 then
  281. begin
  282. paraloc^.loc:=LOC_REGISTER;
  283. paraloc^.register:=newreg(R_INTREGISTER,nextintreg,R_SUBNONE);
  284. inc(nextintreg);
  285. if target_info.abi=abi_powerpc_aix then
  286. inc(stack_offset,4);
  287. end
  288. else
  289. begin
  290. paraloc^.loc:=LOC_REFERENCE;
  291. if (side = callerside) then
  292. paraloc^.reference.index:=NR_STACK_POINTER_REG
  293. else
  294. paraloc^.reference.index:=NR_R12;
  295. paraloc^.reference.offset:=stack_offset;
  296. inc(stack_offset,4);
  297. end;
  298. end;
  299. begin
  300. {$ifdef extdebug}
  301. if po_explicitparaloc in p.procoptions then
  302. internalerror(200411141);
  303. {$endif extdebug}
  304. result:=0;
  305. nextintreg := curintreg;
  306. nextfloatreg := curfloatreg;
  307. nextmmreg := curmmreg;
  308. stack_offset := cur_stack_offset;
  309. case target_info.abi of
  310. abi_powerpc_aix:
  311. maxfpureg := RS_F13;
  312. abi_powerpc_sysv:
  313. maxfpureg := RS_F8;
  314. else internalerror(2004070912);
  315. end;
  316. for i:=0 to paras.count-1 do
  317. begin
  318. hp:=tparavarsym(paras[i]);
  319. { Syscall for Morphos can have already a paraloc set }
  320. if (vo_has_explicit_paraloc in hp.varoptions) then
  321. begin
  322. if not(vo_is_syscall_lib in hp.varoptions) then
  323. internalerror(200412153);
  324. continue;
  325. end;
  326. hp.paraloc[side].reset;
  327. { currently only support C-style array of const }
  328. if (p.proccalloption in [pocall_cdecl,pocall_cppdecl]) and
  329. is_array_of_const(hp.vartype.def) then
  330. begin
  331. paraloc:=hp.paraloc[side].add_location;
  332. { hack: the paraloc must be valid, but is not actually used }
  333. paraloc^.loc := LOC_REGISTER;
  334. paraloc^.register := NR_R0;
  335. paraloc^.size := OS_ADDR;
  336. break;
  337. end;
  338. if (hp.varspez in [vs_var,vs_out]) then
  339. begin
  340. paradef:=voidpointertype.def;
  341. loc:=LOC_REGISTER;
  342. paracgsize := OS_ADDR;
  343. end
  344. else
  345. begin
  346. paradef := hp.vartype.def;
  347. loc:=getparaloc(paradef);
  348. if (hp.vartype.def.deftype = recorddef) and
  349. (target_info.abi = abi_powerpc_aix) and
  350. (hp.vartype.def.size <= 4) and
  351. (byte(hp.vartype.def.size) in [1,2,4]) then
  352. begin
  353. loc := LOC_REGISTER;
  354. paracgsize := def_cgsize(paradef);
  355. end
  356. else
  357. begin
  358. paracgsize:=def_cgsize(paradef);
  359. { for things like formaldef }
  360. if paracgsize=OS_NO then
  361. paracgsize:=OS_ADDR;
  362. end
  363. end;
  364. hp.paraloc[side].alignment:=std_param_align;
  365. hp.paraloc[side].size:=paracgsize;
  366. { First location }
  367. paraloc:=hp.paraloc[side].add_location;
  368. paraloc^.size:=paracgsize;
  369. case loc of
  370. LOC_REGISTER:
  371. begin
  372. is_64bit:=paraloc^.size in [OS_64,OS_S64];
  373. if nextintreg<=(RS_R10-ord(is_64bit)) then
  374. begin
  375. paraloc^.loc:=LOC_REGISTER;
  376. {$ifndef cpu64bit}
  377. if is_64bit then
  378. begin
  379. if odd(nextintreg-RS_R3) and (target_info.abi=abi_powerpc_sysv) Then
  380. inc(nextintreg);
  381. paraloc^.size:=OS_32;
  382. paraloc^.register:=newreg(R_INTREGISTER,nextintreg,R_SUBNONE);
  383. inc(nextintreg);
  384. paraloc2:=hp.paraloc[side].add_location;
  385. paraloc2^.loc:=LOC_REGISTER;
  386. paraloc2^.size:=OS_32;
  387. paraloc2^.register:=newreg(R_INTREGISTER,nextintreg,R_SUBNONE);
  388. inc(nextintreg);
  389. if target_info.abi=abi_powerpc_aix then
  390. inc(stack_offset,8);
  391. end
  392. else
  393. {$endif cpu64bit}
  394. begin
  395. paraloc^.register:=newreg(R_INTREGISTER,nextintreg,R_SUBNONE);
  396. inc(nextintreg);
  397. if target_info.abi=abi_powerpc_aix then
  398. inc(stack_offset,sizeof(aword));
  399. end;
  400. end
  401. else
  402. begin
  403. nextintreg:=RS_R11;
  404. paraloc^.loc:=LOC_REFERENCE;
  405. if (side = callerside) then
  406. paraloc^.reference.index:=NR_STACK_POINTER_REG
  407. else
  408. paraloc^.reference.index:=NR_R12;
  409. paraloc^.reference.offset:=stack_offset;
  410. if not is_64bit then
  411. inc(stack_offset,4)
  412. else
  413. inc(stack_offset,8);
  414. end;
  415. end;
  416. LOC_FPUREGISTER:
  417. begin
  418. if nextfloatreg<=maxfpureg then
  419. begin
  420. paraloc^.loc:=LOC_FPUREGISTER;
  421. paraloc^.register:=newreg(R_FPUREGISTER,nextfloatreg,R_SUBWHOLE);
  422. inc(nextfloatreg);
  423. end
  424. else
  425. begin
  426. paraloc^.loc:=LOC_REFERENCE;
  427. if (side = callerside) then
  428. paraloc^.reference.index:=NR_STACK_POINTER_REG
  429. else
  430. paraloc^.reference.index:=NR_R12;
  431. paraloc^.reference.offset:=stack_offset;
  432. end;
  433. if target_info.abi=abi_powerpc_aix then
  434. begin
  435. if paraloc^.size = OS_F32 then
  436. begin
  437. inc(stack_offset,4);
  438. if (nextintreg < RS_R11) then
  439. inc(nextintreg);
  440. end
  441. else
  442. begin
  443. inc(stack_offset,8);
  444. if (nextintreg < RS_R10) then
  445. inc(nextintreg,2)
  446. else
  447. nextintreg := RS_R11;
  448. end;
  449. end;
  450. end;
  451. LOC_REFERENCE:
  452. begin
  453. paraloc^.size:=OS_ADDR;
  454. if push_addr_param(hp.varspez,paradef,p.proccalloption) or
  455. is_open_array(paradef) or
  456. is_array_of_const(paradef) then
  457. assignintreg
  458. else
  459. begin
  460. paraloc^.loc:=LOC_REFERENCE;
  461. if (side = callerside) then
  462. paraloc^.reference.index:=NR_STACK_POINTER_REG
  463. else
  464. paraloc^.reference.index:=NR_R12;
  465. paraloc^.reference.offset:=stack_offset;
  466. inc(stack_offset,hp.vartype.def.size);
  467. end;
  468. end;
  469. else
  470. internalerror(2002071002);
  471. end;
  472. end;
  473. curintreg:=nextintreg;
  474. curfloatreg:=nextfloatreg;
  475. curmmreg:=nextmmreg;
  476. cur_stack_offset:=stack_offset;
  477. result:=cur_stack_offset;
  478. end;
  479. function tppcparamanager.create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint;
  480. var
  481. cur_stack_offset: aword;
  482. parasize, l: longint;
  483. curintreg, firstfloatreg, curfloatreg, curmmreg: tsuperregister;
  484. i : integer;
  485. hp: tparavarsym;
  486. paraloc: pcgparalocation;
  487. begin
  488. init_values(curintreg,curfloatreg,curmmreg,cur_stack_offset);
  489. firstfloatreg:=curfloatreg;
  490. result:=create_paraloc_info_intern(p,callerside,p.paras,curintreg,curfloatreg,curmmreg,cur_stack_offset);
  491. if (p.proccalloption in [pocall_cdecl,pocall_cppdecl]) then
  492. { just continue loading the parameters in the registers }
  493. result:=create_paraloc_info_intern(p,callerside,varargspara,curintreg,curfloatreg,curmmreg,cur_stack_offset)
  494. else
  495. begin
  496. parasize:=cur_stack_offset;
  497. for i:=0 to varargspara.count-1 do
  498. begin
  499. hp:=tparavarsym(varargspara[i]);
  500. hp.paraloc[callerside].alignment:=4;
  501. paraloc:=hp.paraloc[callerside].add_location;
  502. paraloc^.loc:=LOC_REFERENCE;
  503. paraloc^.size:=def_cgsize(hp.vartype.def);
  504. paraloc^.reference.index:=NR_STACK_POINTER_REG;
  505. l:=push_size(hp.varspez,hp.vartype.def,p.proccalloption);
  506. paraloc^.reference.offset:=parasize;
  507. parasize:=parasize+l;
  508. end;
  509. result:=parasize;
  510. end;
  511. if curfloatreg<>firstfloatreg then
  512. include(varargspara.varargsinfo,va_uses_float_reg);
  513. end;
  514. function tppcparamanager.parseparaloc(p : tparavarsym;const s : string) : boolean;
  515. var
  516. paraloc : pcgparalocation;
  517. begin
  518. result:=false;
  519. case target_info.system of
  520. system_powerpc_morphos:
  521. begin
  522. p.paraloc[callerside].alignment:=4;
  523. p.paraloc[callerside].size:=def_cgsize(p.vartype.def);
  524. paraloc:=p.paraloc[callerside].add_location;
  525. paraloc^.loc:=LOC_REFERENCE;
  526. paraloc^.size:=def_cgsize(p.vartype.def);
  527. paraloc^.reference.index:=newreg(R_INTREGISTER,RS_R2,R_SUBWHOLE);
  528. { pattern is always uppercase'd }
  529. if s='D0' then
  530. paraloc^.reference.offset:=0
  531. else if s='D1' then
  532. paraloc^.reference.offset:=4
  533. else if s='D2' then
  534. paraloc^.reference.offset:=8
  535. else if s='D3' then
  536. paraloc^.reference.offset:=12
  537. else if s='D4' then
  538. paraloc^.reference.offset:=16
  539. else if s='D5' then
  540. paraloc^.reference.offset:=20
  541. else if s='D6' then
  542. paraloc^.reference.offset:=24
  543. else if s='D7' then
  544. paraloc^.reference.offset:=28
  545. else if s='A0' then
  546. paraloc^.reference.offset:=32
  547. else if s='A1' then
  548. paraloc^.reference.offset:=36
  549. else if s='A2' then
  550. paraloc^.reference.offset:=40
  551. else if s='A3' then
  552. paraloc^.reference.offset:=44
  553. else if s='A4' then
  554. paraloc^.reference.offset:=48
  555. else if s='A5' then
  556. paraloc^.reference.offset:=52
  557. { 'A6' (offset 56) is used by mossyscall as libbase, so API
  558. never passes parameters in it,
  559. Indeed, but this allows to declare libbase either explicitly
  560. or let the compiler insert it }
  561. else if s='A6' then
  562. paraloc^.reference.offset:=56
  563. { 'A7' is the stack pointer on 68k, can't be overwritten
  564. by API calls, so it has no offset }
  565. { 'R12' is special, used internally to support r12base sysv
  566. calling convention }
  567. else if s='R12' then
  568. begin
  569. paraloc^.loc:=LOC_REGISTER;
  570. paraloc^.size:=OS_ADDR;
  571. paraloc^.register:=NR_R12;
  572. end
  573. else
  574. exit;
  575. { copy to callee side }
  576. p.paraloc[calleeside].add_location^:=paraloc^;
  577. end;
  578. else
  579. internalerror(200404182);
  580. end;
  581. result:=true;
  582. end;
  583. begin
  584. paramanager:=tppcparamanager.create;
  585. end.
  586. {
  587. $Log$
  588. Revision 1.80 2005-01-07 10:58:03 jonas
  589. * fixed stupid tregister/tsuperregister bug (type checking circumvented
  590. using explicit typecase), caused bug3523
  591. Revision 1.79 2005/01/06 02:13:03 karoly
  592. * more SysV call support stuff for MorphOS
  593. Revision 1.78 2005/01/05 19:01:53 karoly
  594. * sysv abi also uses F0-F13 as volatile registers
  595. Revision 1.77 2004/12/24 15:00:11 jonas
  596. * fixed call-by-value passing of records with size 1, 2 or 4 for AIX abi
  597. (using a hack, normally all records should by passed by value under the
  598. aix abi, but that's currently impossible)
  599. Revision 1.76 2004/12/15 19:30:32 peter
  600. * syscall with sysv abi for morphos
  601. Revision 1.75 2004/12/04 21:47:46 jonas
  602. * modifications to work with the generic code to copy LOC_REFERENCE
  603. parameters to local temps (fixes tests/test/cg/tmanypara)
  604. Revision 1.74 2004/11/22 22:01:19 peter
  605. * fixed varargs
  606. * replaced dynarray with tlist
  607. Revision 1.73 2004/11/21 17:54:59 peter
  608. * ttempcreatenode.create_reg merged into .create with parameter
  609. whether a register is allowed
  610. * funcret_paraloc renamed to funcretloc
  611. Revision 1.72 2004/11/21 17:17:04 florian
  612. * changed funcret location back to tlocation
  613. Revision 1.71 2004/11/15 23:35:31 peter
  614. * tparaitem removed, use tparavarsym instead
  615. * parameter order is now calculated from paranr value in tparavarsym
  616. Revision 1.70 2004/11/14 16:26:29 florian
  617. * fixed morphos syscall
  618. Revision 1.69 2004/09/25 20:28:20 florian
  619. * indention fixed
  620. Revision 1.68 2004/09/21 17:25:13 peter
  621. * paraloc branch merged
  622. Revision 1.67.4.3 2004/09/18 20:21:08 jonas
  623. * fixed ppc, but still needs fix in tgobj
  624. Revision 1.67.4.2 2004/09/10 11:10:08 florian
  625. * first part of ppc fixes
  626. Revision 1.67.4.1 2004/08/31 20:43:06 peter
  627. * paraloc patch
  628. Revision 1.67 2004/07/19 19:15:50 florian
  629. * fixed funcretloc writing in units
  630. Revision 1.66 2004/07/17 13:51:57 florian
  631. * function result location for syscalls on MOS hopefully correctly set now
  632. Revision 1.65 2004/07/09 21:45:24 jonas
  633. * fixed passing of fpu paras on the stack
  634. * fixed number of fpu parameters passed in registers
  635. * skip corresponding integer registers when using an fpu register for a
  636. parameter under the AIX abi
  637. Revision 1.64 2004/07/01 18:00:37 jonas
  638. * fix for broken TP-style constructor handling in the compiler
  639. Revision 1.63 2004/06/20 08:55:32 florian
  640. * logs truncated
  641. Revision 1.62 2004/05/01 22:05:02 florian
  642. + added lib support for Amiga/MorphOS syscalls
  643. Revision 1.61 2004/04/18 23:19:48 karoly
  644. * added correct offsets for PowerPC/MorphOS location support
  645. Revision 1.60 2004/04/18 15:22:24 florian
  646. + location support for arguments, currently PowerPC/MorphOS only
  647. Revision 1.59 2004/02/19 17:07:42 florian
  648. * fixed arg. area calculation
  649. Revision 1.58 2004/02/11 23:18:59 florian
  650. * fixed to compile the rtl again
  651. }