cpupara.pas 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  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,
  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 : tparaitem;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 : tparaitem;
  71. paracgsize : tcgsize;
  72. paralen : longint;
  73. parasize : longint;
  74. begin
  75. parasize:=0;
  76. hp:=tparaitem(p.para.first);
  77. while assigned(hp) do
  78. begin
  79. if push_addr_param(hp.paratyp,hp.paratype.def,p.proccalloption) then
  80. paracgsize:=OS_ADDR
  81. else
  82. begin
  83. paracgsize:=def_cgSize(hp.paratype.def);
  84. if paracgsize=OS_NO then
  85. paracgsize:=OS_ADDR;
  86. end;
  87. hp.paraloc[side].reset;
  88. hp.paraloc[side].size:=paracgsize;
  89. hp.paraloc[side].Alignment:=std_param_align;
  90. paraloc:=hp.paraloc[side].add_location;
  91. paraloc^.size:=paracgsize;
  92. paraloc^.loc:=LOC_REFERENCE;
  93. if side=callerside then
  94. paraloc^.reference.index:=NR_STACK_POINTER_REG
  95. else
  96. paraloc^.reference.index:=NR_FRAME_POINTER_REG;
  97. paraloc^.reference.offset:=target_info.first_parm_offset+parasize;
  98. hp:=TParaItem(hp.Next);
  99. end;
  100. result:=parasize;
  101. end;
  102. function tm68kparamanager.parseparaloc(p : tparaitem;const s : string) : boolean;
  103. var
  104. paraloc : pcgparalocation;
  105. begin
  106. result:=false;
  107. case target_info.system of
  108. system_m68k_amiga:
  109. begin
  110. p.paraloc[callerside].alignment:=4;
  111. paraloc:=p.paraloc[callerside].add_location;
  112. paraloc^.loc:=LOC_REGISTER;
  113. paraloc^.size:=def_cgsize(p.paratype.def);
  114. { pattern is always uppercase'd }
  115. if s='D0' then
  116. paraloc^.register:=NR_D0
  117. else if s='D1' then
  118. paraloc^.register:=NR_D1
  119. else if s='D2' then
  120. paraloc^.register:=NR_D2
  121. else if s='D3' then
  122. paraloc^.register:=NR_D3
  123. else if s='D4' then
  124. paraloc^.register:=NR_D4
  125. else if s='D5' then
  126. paraloc^.register:=NR_D5
  127. else if s='D6' then
  128. paraloc^.register:=NR_D6
  129. else if s='D7' then
  130. paraloc^.register:=NR_D7
  131. else if s='A0' then
  132. paraloc^.register:=NR_A0
  133. else if s='A1' then
  134. paraloc^.register:=NR_A1
  135. else if s='A2' then
  136. paraloc^.register:=NR_A2
  137. else if s='A3' then
  138. paraloc^.register:=NR_A3
  139. else if s='A4' then
  140. paraloc^.register:=NR_A4
  141. else if s='A5' then
  142. paraloc^.register:=NR_A5
  143. { 'A6' is problematic, since it's the frame pointer in fpc,
  144. so it should be saved before a call! }
  145. else if s='A6' then
  146. paraloc^.register:=NR_A6
  147. { 'A7' is the stack pointer on 68k, can't be overwritten by API calls }
  148. else
  149. exit;
  150. { copy to callee side }
  151. p.paraloc[calleeside].add_location^:=paraloc^;
  152. end;
  153. else
  154. internalerror(200405092);
  155. end;
  156. result:=true;
  157. end;
  158. begin
  159. paramanager:=tm68kparamanager.create;
  160. end.
  161. {
  162. $Log$
  163. Revision 1.8 2004-11-09 22:32:59 peter
  164. * small m68k updates to bring it up2date
  165. * give better error for external local variable
  166. Revision 1.7 2004/06/20 08:55:31 florian
  167. * logs truncated
  168. Revision 1.6 2004/05/12 13:28:01 karoly
  169. * added some basic code for later syscall support on M68k/Amiga
  170. Revision 1.5 2004/01/30 12:17:18 florian
  171. * fixed some m68k compilation problems
  172. }