cpupara.pas 7.1 KB

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