cpupara.pas 26 KB

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