paramgr.pas 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  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. {# Parameter passing manager. Used to manage how
  19. parameters are passed to routines.
  20. }
  21. unit paramgr;
  22. {$i fpcdefs.inc}
  23. interface
  24. uses
  25. cpubase,
  26. symtype,symdef;
  27. type
  28. {# This class defines some methods to take care of routine
  29. parameters. It should be overriden for each new processor
  30. }
  31. tparamanager = class
  32. {# Returns true if the return value can be put in accumulator }
  33. function ret_in_acc(def : tdef) : boolean;virtual;
  34. {# Returns true if the return value is actually a parameter
  35. pointer.
  36. }
  37. function ret_in_param(def : tdef) : boolean;virtual;
  38. function push_high_param(def : tdef) : boolean;virtual;
  39. {# Returns true if a parameter is too large to copy and only
  40. the address is pushed
  41. }
  42. function push_addr_param(def : tdef) : boolean;virtual;
  43. {# Returns a structure giving the information on
  44. the storage of the parameter (which must be
  45. an integer parameter)
  46. @param(nr Parameter number of routine, starting from 1)
  47. }
  48. function getintparaloc(nr : longint) : tparalocation;virtual;abstract;
  49. procedure create_param_loc_info(p : tabstractprocdef);virtual;abstract;
  50. {#
  51. Returns the location where the invisible parameter for structured
  52. function results will be passed.
  53. }
  54. function getfuncretloc(p : tabstractprocdef) : tparalocation;virtual;abstract;
  55. { Returns the self pointer location for the given tabstractprocdef,
  56. when the stack frame is already created. This is used by the code
  57. generating the wrappers for implemented interfaces.
  58. }
  59. function getselflocation(p : tabstractprocdef) : tparalocation;virtual;abstract;
  60. end;
  61. procedure setparalocs(p : tprocdef);
  62. var
  63. paralocdummy : tparalocation;
  64. paramanager : tparamanager;
  65. implementation
  66. uses
  67. cpuinfo,
  68. symconst,symbase,symsym,
  69. rgobj,
  70. defbase;
  71. { true if the return value is in accumulator (EAX for i386), D0 for 68k }
  72. function tparamanager.ret_in_acc(def : tdef) : boolean;
  73. begin
  74. ret_in_acc:=(def.deftype in [orddef,pointerdef,enumdef,classrefdef]) or
  75. ((def.deftype=stringdef) and (tstringdef(def).string_typ in [st_ansistring,st_widestring])) or
  76. ((def.deftype=procvardef) and not(po_methodpointer in tprocvardef(def).procoptions)) or
  77. ((def.deftype=objectdef) and not is_object(def)) or
  78. ((def.deftype=setdef) and (tsetdef(def).settype=smallset));
  79. end;
  80. { true if uses a parameter as return value }
  81. function tparamanager.ret_in_param(def : tdef) : boolean;
  82. begin
  83. ret_in_param:=(def.deftype in [arraydef,recorddef]) or
  84. ((def.deftype=stringdef) and (tstringdef(def).string_typ in [st_shortstring,st_longstring])) or
  85. ((def.deftype=procvardef) and (po_methodpointer in tprocvardef(def).procoptions)) or
  86. ((def.deftype=objectdef) and is_object(def)) or
  87. (def.deftype=variantdef) or
  88. ((def.deftype=setdef) and (tsetdef(def).settype<>smallset));
  89. end;
  90. function tparamanager.push_high_param(def : tdef) : boolean;
  91. begin
  92. push_high_param:=is_open_array(def) or
  93. is_open_string(def) or
  94. is_array_of_const(def);
  95. end;
  96. { true if a parameter is too large to copy and only the address is pushed }
  97. function tparamanager.push_addr_param(def : tdef) : boolean;
  98. begin
  99. push_addr_param:=false;
  100. if never_copy_const_param then
  101. push_addr_param:=true
  102. else
  103. begin
  104. case def.deftype of
  105. variantdef,
  106. formaldef :
  107. push_addr_param:=true;
  108. recorddef :
  109. push_addr_param:=(def.size>pointer_size);
  110. arraydef :
  111. push_addr_param:=((tarraydef(def).highrange>=tarraydef(def).lowrange) and (def.size>pointer_size)) or
  112. is_open_array(def) or
  113. is_array_of_const(def) or
  114. is_array_constructor(def);
  115. objectdef :
  116. push_addr_param:=is_object(def);
  117. stringdef :
  118. push_addr_param:=tstringdef(def).string_typ in [st_shortstring,st_longstring];
  119. procvardef :
  120. push_addr_param:=(po_methodpointer in tprocvardef(def).procoptions);
  121. setdef :
  122. push_addr_param:=(tsetdef(def).settype<>smallset);
  123. end;
  124. end;
  125. end;
  126. procedure setparalocs(p : tprocdef);
  127. var
  128. hp : tparaitem;
  129. begin
  130. hp:=tparaitem(p.para.first);
  131. while assigned(hp) do
  132. begin
  133. {$ifdef SUPPORT_MMX}
  134. if (hp.paraloc.loc in [LOC_REGISTER,LOC_FPUREGISTER,
  135. LOC_MMREGISTER]) and
  136. {$else}
  137. if (hp.paraloc.loc in [LOC_REGISTER,LOC_FPUREGISTER]) and
  138. {$endif}
  139. { if the parameter isn't regable, we've to work with the local copy }
  140. ((vo_regable in tvarsym(hp.parasym).varoptions) or
  141. (vo_fpuregable in tvarsym(hp.parasym).varoptions)) then
  142. begin
  143. case hp.paraloc.loc of
  144. LOC_REGISTER:
  145. hp.paraloc.loc := LOC_CREGISTER;
  146. LOC_FPUREGISTER:
  147. hp.paraloc.loc := LOC_CFPUREGISTER;
  148. {$ifdef SUPPORT_MMX}
  149. LOC_MMREGISTER:
  150. hp.paraloc.loc := LOC_CMMREGISTER;
  151. {$endif}
  152. end;
  153. tvarsym(hp.parasym).reg:=hp.paraloc.register;
  154. rg.regvar_loaded[hp.paraloc.register]:=true;
  155. end;
  156. hp:=tparaitem(hp.next);
  157. end;
  158. end;
  159. finalization
  160. paramanager.free;
  161. end.
  162. {
  163. $Log$
  164. Revision 1.11 2002-08-12 15:08:40 carl
  165. + stab register indexes for powerpc (moved from gdb to cpubase)
  166. + tprocessor enumeration moved to cpuinfo
  167. + linker in target_info is now a class
  168. * many many updates for m68k (will soon start to compile)
  169. - removed some ifdef or correct them for correct cpu
  170. Revision 1.10 2002/08/10 17:15:20 jonas
  171. * register parameters are now LOC_CREGISTER instead of LOC_REGISTER
  172. Revision 1.9 2002/08/09 07:33:02 florian
  173. * a couple of interface related fixes
  174. Revision 1.8 2002/08/06 20:55:21 florian
  175. * first part of ppc calling conventions fix
  176. Revision 1.7 2002/08/05 18:27:48 carl
  177. + more more more documentation
  178. + first version include/exclude (can't test though, not enough scratch for i386 :()...
  179. Revision 1.6 2002/07/30 20:50:43 florian
  180. * the code generator knows now if parameters are in registers
  181. Revision 1.5 2002/07/26 21:15:39 florian
  182. * rewrote the system handling
  183. Revision 1.4 2002/07/20 11:57:55 florian
  184. * types.pas renamed to defbase.pas because D6 contains a types
  185. unit so this would conflicts if D6 programms are compiled
  186. + Willamette/SSE2 instructions to assembler added
  187. Revision 1.3 2002/07/13 19:38:43 florian
  188. * some more generic calling stuff fixed
  189. Revision 1.2 2002/07/13 07:17:15 jonas
  190. * fixed memory leak reported by Sergey Korshunoff
  191. Revision 1.1 2002/07/11 14:41:28 florian
  192. * start of the new generic parameter handling
  193. }