cpupara.pas 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  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. { Generates the argument location information for i386.
  19. }
  20. unit cpupara;
  21. {$i fpcdefs.inc}
  22. interface
  23. uses
  24. aasmtai,
  25. cpubase,
  26. globtype,
  27. cginfo,
  28. symtype,symdef,paramgr;
  29. type
  30. { Returns the location for the nr-st 32 Bit int parameter
  31. if every parameter before is an 32 Bit int parameter as well
  32. and if the calling conventions for the helper routines of the
  33. rtl are used.
  34. }
  35. ti386paramanager = class(tparamanager)
  36. function ret_in_param(def : tdef;calloption : tproccalloption) : boolean;override;
  37. function push_addr_param(def : tdef;calloption : tproccalloption) : boolean;override;
  38. function getintparaloc(list: taasmoutput; nr : longint) : tparalocation;override;
  39. function getparaloc(p : tdef) : tcgloc;
  40. procedure create_param_loc_info(p : tabstractprocdef);override;
  41. function getselflocation(p : tabstractprocdef) : tparalocation;override;
  42. end;
  43. implementation
  44. uses
  45. systems,verbose,
  46. symconst,symsym,
  47. cpuinfo,
  48. cgbase;
  49. function ti386paramanager.ret_in_param(def : tdef;calloption : tproccalloption) : boolean;
  50. begin
  51. case target_info.system of
  52. system_i386_win32 :
  53. begin
  54. { Win32 returns small records in the FUNCTION_RETURN_REG }
  55. case def.deftype of
  56. recorddef :
  57. begin
  58. if (calloption in [pocall_stdcall,pocall_cdecl,pocall_cppdecl]) and (def.size<=8) then
  59. begin
  60. result:=false;
  61. exit;
  62. end;
  63. end;
  64. end;
  65. end;
  66. end;
  67. result:=inherited ret_in_param(def,calloption);
  68. end;
  69. function ti386paramanager.push_addr_param(def : tdef;calloption : tproccalloption) : boolean;
  70. begin
  71. case target_info.system of
  72. system_i386_win32 :
  73. begin
  74. case def.deftype of
  75. recorddef :
  76. begin
  77. if (calloption=pocall_stdcall) and (def.size<=8) then
  78. begin
  79. result:=false;
  80. exit;
  81. end;
  82. end;
  83. arraydef :
  84. begin
  85. if (tarraydef(def).highrange>=tarraydef(def).lowrange) and
  86. (calloption in [pocall_cdecl,pocall_cppdecl]) then
  87. begin
  88. result:=true;
  89. exit;
  90. end;
  91. end;
  92. end;
  93. end;
  94. end;
  95. result:=inherited push_addr_param(def,calloption);
  96. end;
  97. function ti386paramanager.getintparaloc(list: taasmoutput; nr : longint) : tparalocation;
  98. begin
  99. getintparaloc.loc:=LOC_REFERENCE;
  100. getintparaloc.reference.index.enum:=R_EBP;
  101. getintparaloc.reference.offset:=4*nr;
  102. end;
  103. function ti386paramanager.getparaloc(p : tdef) : tcgloc;
  104. begin
  105. result:=LOC_REFERENCE;
  106. end;
  107. procedure ti386paramanager.create_param_loc_info(p : tabstractprocdef);
  108. var
  109. hp : tparaitem;
  110. begin
  111. hp:=tparaitem(p.para.first);
  112. while assigned(hp) do
  113. begin
  114. if hp.paratyp in [vs_var,vs_out] then
  115. hp.paraloc.size:=OS_ADDR
  116. else
  117. hp.paraloc.size:=def_cgsize(hp.paratype.def);
  118. hp.paraloc.loc:=LOC_REFERENCE;
  119. if assigned(current_procinfo) then
  120. hp.paraloc.reference.index:=current_procinfo.framepointer
  121. else
  122. begin
  123. hp.paraloc.reference.index.enum:=R_INTREGISTER;
  124. hp.paraloc.reference.index.number:=NR_FRAME_POINTER_REG;
  125. end;
  126. hp.paraloc.reference.offset:=tvarsym(hp.parasym).adjusted_address;
  127. hp:=tparaitem(hp.next);
  128. end;
  129. end;
  130. function ti386paramanager.getselflocation(p : tabstractprocdef) : tparalocation;
  131. var
  132. hsym : tvarsym;
  133. begin
  134. hsym:=tvarsym(trecorddef(methodpointertype.def).symtable.search('self'));
  135. if not assigned(hsym) then
  136. internalerror(200305251);
  137. getselflocation.loc:=LOC_REFERENCE;
  138. getselflocation.sp_fixup:=POINTER_SIZE;
  139. getselflocation.reference.index.enum:=R_INTREGISTER;
  140. getselflocation.reference.index.number:=NR_STACK_POINTER_REG;
  141. getselflocation.reference.offset:=hsym.adjusted_address;
  142. end;
  143. begin
  144. paramanager:=ti386paramanager.create;
  145. end.
  146. {
  147. $Log$
  148. Revision 1.18 2003-06-07 18:57:04 jonas
  149. + added freeintparaloc
  150. * ppc get/freeintparaloc now check whether the parameter regs are
  151. properly allocated/deallocated (and get an extra list para)
  152. * ppc a_call_* now internalerrors if pi_do_call is not yet set
  153. * fixed lot of missing pi_do_call's
  154. Revision 1.17 2003/06/06 14:41:22 peter
  155. * needs cpuinfo
  156. Revision 1.16 2003/06/06 07:36:06 michael
  157. + Forgot a line in patch from peter
  158. Revision 1.15 2003/06/06 07:35:14 michael
  159. + Patch to Patch from peter
  160. Revision 1.14 2003/06/06 07:34:11 michael
  161. + Patch from peter
  162. Revision 1.13 2003/06/05 20:58:05 peter
  163. * updated
  164. Revision 1.12 2003/05/30 23:57:08 peter
  165. * more sparc cleanup
  166. * accumulator removed, splitted in function_return_reg (called) and
  167. function_result_reg (caller)
  168. Revision 1.11 2003/05/13 15:16:13 peter
  169. * removed ret_in_acc, it's the reverse of ret_in_param
  170. * fixed ret_in_param for win32 cdecl array
  171. Revision 1.10 2003/04/22 23:50:23 peter
  172. * firstpass uses expectloc
  173. * checks if there are differences between the expectloc and
  174. location.loc from secondpass in EXTDEBUG
  175. Revision 1.9 2003/04/22 14:33:38 peter
  176. * removed some notes/hints
  177. Revision 1.8 2003/01/08 18:43:57 daniel
  178. * Tregister changed into a record
  179. Revision 1.7 2002/12/24 15:56:50 peter
  180. * stackpointer_alloc added for adjusting ESP. Win32 needs
  181. this for the pageprotection
  182. Revision 1.6 2002/12/17 22:19:33 peter
  183. * fixed pushing of records>8 bytes with stdcall
  184. * simplified hightree loading
  185. Revision 1.5 2002/11/18 17:32:00 peter
  186. * pass proccalloption to ret_in_xxx and push_xxx functions
  187. Revision 1.4 2002/11/15 01:58:56 peter
  188. * merged changes from 1.0.7 up to 04-11
  189. - -V option for generating bug report tracing
  190. - more tracing for option parsing
  191. - errors for cdecl and high()
  192. - win32 import stabs
  193. - win32 records<=8 are returned in eax:edx (turned off by default)
  194. - heaptrc update
  195. - more info for temp management in .s file with EXTDEBUG
  196. Revision 1.3 2002/08/09 07:33:04 florian
  197. * a couple of interface related fixes
  198. Revision 1.2 2002/07/11 14:41:32 florian
  199. * start of the new generic parameter handling
  200. Revision 1.1 2002/07/07 09:52:33 florian
  201. * powerpc target fixed, very simple units can be compiled
  202. * some basic stuff for better callparanode handling, far from being finished
  203. }