cpupara.pas 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  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. symconst,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. procedure freeintparaloc(list: taasmoutput; nr : longint); override;
  40. function getparaloc(p : tdef) : tcgloc;
  41. procedure create_paraloc_info(p : tabstractprocdef; side: tcallercallee);override;
  42. function getselflocation(p : tabstractprocdef) : tparalocation;override;
  43. end;
  44. implementation
  45. uses
  46. systems,verbose,
  47. symsym,
  48. cpuinfo,
  49. cgbase;
  50. function ti386paramanager.ret_in_param(def : tdef;calloption : tproccalloption) : boolean;
  51. begin
  52. case target_info.system of
  53. system_i386_win32 :
  54. begin
  55. { Win32 returns small records in the FUNCTION_RETURN_REG }
  56. case def.deftype of
  57. recorddef :
  58. begin
  59. if (calloption in [pocall_stdcall,pocall_cdecl,pocall_cppdecl]) and (def.size<=8) then
  60. begin
  61. result:=false;
  62. exit;
  63. end;
  64. end;
  65. end;
  66. end;
  67. end;
  68. result:=inherited ret_in_param(def,calloption);
  69. end;
  70. function ti386paramanager.push_addr_param(def : tdef;calloption : tproccalloption) : boolean;
  71. begin
  72. case target_info.system of
  73. system_i386_win32 :
  74. begin
  75. case def.deftype of
  76. recorddef :
  77. begin
  78. if (calloption=pocall_stdcall) and (def.size<=8) then
  79. begin
  80. result:=false;
  81. exit;
  82. end;
  83. end;
  84. arraydef :
  85. begin
  86. if (tarraydef(def).highrange>=tarraydef(def).lowrange) and
  87. (calloption in [pocall_cdecl,pocall_cppdecl]) then
  88. begin
  89. result:=true;
  90. exit;
  91. end;
  92. end;
  93. end;
  94. end;
  95. end;
  96. result:=inherited push_addr_param(def,calloption);
  97. end;
  98. function ti386paramanager.getintparaloc(list: taasmoutput; nr : longint) : tparalocation;
  99. begin
  100. getintparaloc.loc:=LOC_REFERENCE;
  101. getintparaloc.reference.index.enum:=R_EBP;
  102. getintparaloc.reference.offset:=4*nr;
  103. end;
  104. procedure ti386paramanager.freeintparaloc(list: taasmoutput; nr : longint);
  105. begin
  106. { nothing to release }
  107. end;
  108. function ti386paramanager.getparaloc(p : tdef) : tcgloc;
  109. begin
  110. result:=LOC_REFERENCE;
  111. end;
  112. procedure ti386paramanager.create_paraloc_info(p : tabstractprocdef; side: tcallercallee);
  113. var
  114. hp : tparaitem;
  115. paraloc : tparalocation;
  116. begin
  117. hp:=tparaitem(p.para.first);
  118. while assigned(hp) do
  119. begin
  120. if hp.paratyp in [vs_var,vs_out] then
  121. paraloc.size:=OS_ADDR
  122. else
  123. paraloc.size:=def_cgsize(hp.paratype.def);
  124. paraloc.loc:=LOC_REFERENCE;
  125. if assigned(current_procinfo) then
  126. paraloc.reference.index:=current_procinfo.framepointer
  127. else
  128. begin
  129. paraloc.reference.index.enum:=R_INTREGISTER;
  130. paraloc.reference.index.number:=NR_FRAME_POINTER_REG;
  131. end;
  132. paraloc.reference.offset:=tvarsym(hp.parasym).adjusted_address;
  133. hp.paraloc[side]:=paraloc;
  134. {$warning callerparaloc shall not be the same as calleeparaloc}
  135. hp:=tparaitem(hp.next);
  136. end;
  137. { Function return }
  138. fillchar(paraloc,sizeof(tparalocation),0);
  139. paraloc.size:=def_cgsize(p.rettype.def);
  140. { Return in FPU register? }
  141. if p.rettype.def.deftype=floatdef then
  142. begin
  143. paraloc.loc:=LOC_FPUREGISTER;
  144. paraloc.register.enum:=FPU_RESULT_REG;
  145. end
  146. else
  147. { Return in register? }
  148. if not ret_in_param(p.rettype.def,p.proccalloption) then
  149. begin
  150. paraloc.loc:=LOC_REGISTER;
  151. {$ifndef cpu64bit}
  152. if paraloc.size in [OS_64,OS_S64] then
  153. begin
  154. paraloc.register64.reglo.enum:=R_INTREGISTER;
  155. paraloc.register64.reglo.number:=NR_FUNCTION_RETURN64_LOW_REG;
  156. paraloc.register64.reghi.enum:=R_INTREGISTER;
  157. paraloc.register64.reghi.number:=NR_FUNCTION_RETURN64_HIGH_REG;
  158. end
  159. else
  160. {$endif cpu64bit}
  161. begin
  162. paraloc.register.enum:=R_INTREGISTER;
  163. paraloc.register.number:=NR_FUNCTION_RETURN_REG;
  164. end;
  165. end
  166. else
  167. begin
  168. paraloc.loc:=LOC_REFERENCE;
  169. end;
  170. p.funcret_paraloc[side]:=paraloc;
  171. end;
  172. function ti386paramanager.getselflocation(p : tabstractprocdef) : tparalocation;
  173. var
  174. hsym : tvarsym;
  175. begin
  176. hsym:=tvarsym(trecorddef(methodpointertype.def).symtable.search('self'));
  177. if not assigned(hsym) then
  178. internalerror(200305251);
  179. getselflocation.loc:=LOC_REFERENCE;
  180. getselflocation.sp_fixup:=POINTER_SIZE;
  181. getselflocation.reference.index.enum:=R_INTREGISTER;
  182. getselflocation.reference.index.number:=NR_STACK_POINTER_REG;
  183. getselflocation.reference.offset:=hsym.adjusted_address;
  184. end;
  185. begin
  186. paramanager:=ti386paramanager.create;
  187. end.
  188. {
  189. $Log$
  190. Revision 1.22 2003-08-11 21:18:20 peter
  191. * start of sparc support for newra
  192. Revision 1.21 2003/07/05 20:11:41 jonas
  193. * create_paraloc_info() is now called separately for the caller and
  194. callee info
  195. * fixed ppc cycle
  196. Revision 1.20 2003/07/02 22:18:04 peter
  197. * paraloc splitted in callerparaloc,calleeparaloc
  198. * sparc calling convention updates
  199. Revision 1.19 2003/06/17 16:34:19 peter
  200. * freeintparaloc added
  201. Revision 1.18 2003/06/07 18:57:04 jonas
  202. + added freeintparaloc
  203. * ppc get/freeintparaloc now check whether the parameter regs are
  204. properly allocated/deallocated (and get an extra list para)
  205. * ppc a_call_* now internalerrors if pi_do_call is not yet set
  206. * fixed lot of missing pi_do_call's
  207. Revision 1.17 2003/06/06 14:41:22 peter
  208. * needs cpuinfo
  209. Revision 1.16 2003/06/06 07:36:06 michael
  210. + Forgot a line in patch from peter
  211. Revision 1.15 2003/06/06 07:35:14 michael
  212. + Patch to Patch from peter
  213. Revision 1.14 2003/06/06 07:34:11 michael
  214. + Patch from peter
  215. Revision 1.13 2003/06/05 20:58:05 peter
  216. * updated
  217. Revision 1.12 2003/05/30 23:57:08 peter
  218. * more sparc cleanup
  219. * accumulator removed, splitted in function_return_reg (called) and
  220. function_result_reg (caller)
  221. Revision 1.11 2003/05/13 15:16:13 peter
  222. * removed ret_in_acc, it's the reverse of ret_in_param
  223. * fixed ret_in_param for win32 cdecl array
  224. Revision 1.10 2003/04/22 23:50:23 peter
  225. * firstpass uses expectloc
  226. * checks if there are differences between the expectloc and
  227. location.loc from secondpass in EXTDEBUG
  228. Revision 1.9 2003/04/22 14:33:38 peter
  229. * removed some notes/hints
  230. Revision 1.8 2003/01/08 18:43:57 daniel
  231. * Tregister changed into a record
  232. Revision 1.7 2002/12/24 15:56:50 peter
  233. * stackpointer_alloc added for adjusting ESP. Win32 needs
  234. this for the pageprotection
  235. Revision 1.6 2002/12/17 22:19:33 peter
  236. * fixed pushing of records>8 bytes with stdcall
  237. * simplified hightree loading
  238. Revision 1.5 2002/11/18 17:32:00 peter
  239. * pass proccalloption to ret_in_xxx and push_xxx functions
  240. Revision 1.4 2002/11/15 01:58:56 peter
  241. * merged changes from 1.0.7 up to 04-11
  242. - -V option for generating bug report tracing
  243. - more tracing for option parsing
  244. - errors for cdecl and high()
  245. - win32 import stabs
  246. - win32 records<=8 are returned in eax:edx (turned off by default)
  247. - heaptrc update
  248. - more info for temp management in .s file with EXTDEBUG
  249. Revision 1.3 2002/08/09 07:33:04 florian
  250. * a couple of interface related fixes
  251. Revision 1.2 2002/07/11 14:41:32 florian
  252. * start of the new generic parameter handling
  253. Revision 1.1 2002/07/07 09:52:33 florian
  254. * powerpc target fixed, very simple units can be compiled
  255. * some basic stuff for better callparanode handling, far from being finished
  256. }