cpupara.pas 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. {
  2. $Id$
  3. Copyright (c) 2002 by Florian Klaempfl
  4. Generates the argument location information for 680x0
  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 680x0.
  19. }
  20. unit cpupara;
  21. {$i fpcdefs.inc}
  22. interface
  23. uses
  24. globtype,
  25. cpubase,
  26. symconst,symdef,symsym,
  27. parabase,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. tm68kparamanager = class(tparamanager)
  35. procedure getintparaloc(calloption : tproccalloption; nr : longint;var cgpara : TCGPara);override;
  36. function create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;override;
  37. private
  38. function parseparaloc(p : tparavarsym;const s : string) : boolean;override;
  39. end;
  40. implementation
  41. uses
  42. verbose,
  43. globals,
  44. systems,
  45. cpuinfo,cgbase,
  46. defutil;
  47. procedure tm68kparamanager.getintparaloc(calloption : tproccalloption; nr : longint;var cgpara : TCGPara);
  48. var
  49. paraloc : pcgparalocation;
  50. begin
  51. if nr<1 then
  52. internalerror(2002070801);
  53. cgpara.reset;
  54. cgpara.size:=OS_INT;
  55. cgpara.alignment:=std_param_align;
  56. paraloc:=cgpara.add_location;
  57. with paraloc^ do
  58. begin
  59. { warning : THIS ONLY WORKS WITH INTERNAL ROUTINES,
  60. WHICH MUST ALWAYS PASS 4-BYTE PARAMETERS!!
  61. }
  62. loc:=LOC_REFERENCE;
  63. reference.index:=NR_STACK_POINTER_REG;
  64. reference.offset:=target_info.first_parm_offset+nr*4;
  65. end;
  66. end;
  67. function tm68kparamanager.create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;
  68. var
  69. paraloc : pcgparalocation;
  70. hp : tparavarsym;
  71. paracgsize : tcgsize;
  72. paralen : longint;
  73. parasize : longint;
  74. i : longint;
  75. begin
  76. parasize:=0;
  77. for i:=0 to p.paras.count-1 do
  78. begin
  79. hp:=tparavarsym(p.paras[i]);
  80. hp.paraloc[side].reset;
  81. { currently only support C-style array of const }
  82. if (p.proccalloption in [pocall_cdecl,pocall_cppdecl]) and
  83. is_array_of_const(hp.vartype.def) then
  84. begin
  85. paraloc:=hp.paraloc[side].add_location;
  86. { hack: the paraloc must be valid, but is not actually used }
  87. paraloc^.loc:=LOC_REFERENCE;
  88. if side=callerside then
  89. paraloc^.reference.index:=NR_STACK_POINTER_REG
  90. else
  91. paraloc^.reference.index:=NR_FRAME_POINTER_REG;
  92. paraloc^.size:=OS_ADDR;
  93. paraloc^.reference.offset:=0;
  94. break;
  95. end;
  96. if push_addr_param(hp.varspez,hp.vartype.def,p.proccalloption) then
  97. paracgsize:=OS_ADDR
  98. else
  99. begin
  100. paracgsize:=def_cgsize(hp.vartype.def);
  101. if paracgsize=OS_NO then
  102. paracgsize:=OS_ADDR;
  103. end;
  104. hp.paraloc[side].size:=paracgsize;
  105. hp.paraloc[side].Alignment:=std_param_align;
  106. paraloc:=hp.paraloc[side].add_location;
  107. paraloc^.size:=paracgsize;
  108. paraloc^.loc:=LOC_REFERENCE;
  109. if side=callerside then
  110. paraloc^.reference.index:=NR_STACK_POINTER_REG
  111. else
  112. paraloc^.reference.index:=NR_FRAME_POINTER_REG;
  113. paraloc^.reference.offset:=target_info.first_parm_offset+parasize;
  114. end;
  115. result:=parasize;
  116. end;
  117. function tm68kparamanager.parseparaloc(p : tparavarsym;const s : string) : boolean;
  118. var
  119. paraloc : pcgparalocation;
  120. begin
  121. result:=false;
  122. case target_info.system of
  123. system_m68k_amiga:
  124. begin
  125. p.paraloc[callerside].alignment:=4;
  126. paraloc:=p.paraloc[callerside].add_location;
  127. paraloc^.loc:=LOC_REGISTER;
  128. paraloc^.size:=def_cgsize(p.vartype.def);
  129. { pattern is always uppercase'd }
  130. if s='D0' then
  131. paraloc^.register:=NR_D0
  132. else if s='D1' then
  133. paraloc^.register:=NR_D1
  134. else if s='D2' then
  135. paraloc^.register:=NR_D2
  136. else if s='D3' then
  137. paraloc^.register:=NR_D3
  138. else if s='D4' then
  139. paraloc^.register:=NR_D4
  140. else if s='D5' then
  141. paraloc^.register:=NR_D5
  142. else if s='D6' then
  143. paraloc^.register:=NR_D6
  144. else if s='D7' then
  145. paraloc^.register:=NR_D7
  146. else if s='A0' then
  147. paraloc^.register:=NR_A0
  148. else if s='A1' then
  149. paraloc^.register:=NR_A1
  150. else if s='A2' then
  151. paraloc^.register:=NR_A2
  152. else if s='A3' then
  153. paraloc^.register:=NR_A3
  154. else if s='A4' then
  155. paraloc^.register:=NR_A4
  156. else if s='A5' then
  157. paraloc^.register:=NR_A5
  158. { 'A6' is problematic, since it's the frame pointer in fpc,
  159. so it should be saved before a call! }
  160. else if s='A6' then
  161. paraloc^.register:=NR_A6
  162. { 'A7' is the stack pointer on 68k, can't be overwritten by API calls }
  163. else
  164. exit;
  165. { copy to callee side }
  166. p.paraloc[calleeside].add_location^:=paraloc^;
  167. end;
  168. else
  169. internalerror(200405092);
  170. end;
  171. result:=true;
  172. end;
  173. begin
  174. paramanager:=tm68kparamanager.create;
  175. end.
  176. {
  177. $Log$
  178. Revision 1.9 2004-11-27 16:16:02 florian
  179. * some m68k stuff updated
  180. Revision 1.8 2004/11/09 22:32:59 peter
  181. * small m68k updates to bring it up2date
  182. * give better error for external local variable
  183. Revision 1.7 2004/06/20 08:55:31 florian
  184. * logs truncated
  185. Revision 1.6 2004/05/12 13:28:01 karoly
  186. * added some basic code for later syscall support on M68k/Amiga
  187. Revision 1.5 2004/01/30 12:17:18 florian
  188. * fixed some m68k compilation problems
  189. }