cpupara.pas 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  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. 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. function getintparaloc(calloption : tproccalloption;nr : longint) : tparalocation;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. function tm68kparamanager.getintparaloc(calloption : tproccalloption;nr : longint) : tparalocation;
  48. begin
  49. fillchar(result,sizeof(tparalocation),0);
  50. if nr<1 then
  51. internalerror(2002070801)
  52. else
  53. begin
  54. { warning : THIS ONLY WORKS WITH INTERNAL ROUTINES,
  55. WHICH MUST ALWAYS PASS 4-BYTE PARAMETERS!!
  56. }
  57. result.loc:=LOC_REFERENCE;
  58. result.reference.index:=NR_STACK_POINTER_REG;
  59. result.reference.offset:=target_info.first_parm_offset+nr*4;
  60. end;
  61. end;
  62. function tm68kparamanager.create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;
  63. var
  64. param_offset : integer;
  65. hp : tparaitem;
  66. paraloc: tparalocation;
  67. l : longint;
  68. parasize : longint;
  69. begin
  70. { frame pointer for nested procedures? }
  71. { inc(nextintreg); }
  72. { constructor? }
  73. { destructor? }
  74. param_offset := target_info.first_parm_offset;
  75. hp:=tparaitem(p.para.last);
  76. while assigned(hp) do
  77. begin
  78. paraloc.size:=def_cgsize(hp.paratype.def);
  79. paraloc.loc:=LOC_REFERENCE;
  80. paraloc.alignment:=4;
  81. paraloc.reference.index:=NR_FRAME_POINTER_REG;
  82. l:=push_size(hp.paratyp,hp.paratype.def,p.proccalloption);
  83. paraloc.reference.offset:=parasize;
  84. parasize:=parasize+l;
  85. hp.paraloc[callerside]:=paraloc;
  86. hp:=tparaitem(hp.next);
  87. end;
  88. end;
  89. function tm68kparamanager.parseparaloc(p : tparaitem;const s : string) : boolean;
  90. begin
  91. result:=false;
  92. case target_info.system of
  93. system_m68k_amiga:
  94. begin
  95. p.paraloc[callerside].loc:=LOC_REGISTER;
  96. p.paraloc[callerside].lochigh:=LOC_INVALID;
  97. p.paraloc[callerside].size:=def_cgsize(p.paratype.def);
  98. p.paraloc[callerside].alignment:=4;
  99. { pattern is always uppercase'd }
  100. if s='D0' then
  101. p.paraloc[callerside].register:=NR_D0
  102. else if s='D1' then
  103. p.paraloc[callerside].register:=NR_D1
  104. else if s='D2' then
  105. p.paraloc[callerside].register:=NR_D2
  106. else if s='D3' then
  107. p.paraloc[callerside].register:=NR_D3
  108. else if s='D4' then
  109. p.paraloc[callerside].register:=NR_D4
  110. else if s='D5' then
  111. p.paraloc[callerside].register:=NR_D5
  112. else if s='D6' then
  113. p.paraloc[callerside].register:=NR_D6
  114. else if s='D7' then
  115. p.paraloc[callerside].register:=NR_D7
  116. else if s='A0' then
  117. p.paraloc[callerside].register:=NR_A0
  118. else if s='A1' then
  119. p.paraloc[callerside].register:=NR_A1
  120. else if s='A2' then
  121. p.paraloc[callerside].register:=NR_A2
  122. else if s='A3' then
  123. p.paraloc[callerside].register:=NR_A3
  124. else if s='A4' then
  125. p.paraloc[callerside].register:=NR_A4
  126. else if s='A5' then
  127. p.paraloc[callerside].register:=NR_A5
  128. { 'A6' is problematic, since it's the frame pointer in fpc,
  129. so it should be saved before a call! }
  130. else if s='A6' then
  131. p.paraloc[callerside].register:=NR_A6
  132. { 'A7' is the stack pointer on 68k, can't be overwritten by API calls }
  133. else
  134. exit;
  135. p.paraloc[calleeside]:=p.paraloc[callerside];
  136. end;
  137. else
  138. internalerror(200405092);
  139. end;
  140. result:=true;
  141. end;
  142. begin
  143. paramanager:=tm68kparamanager.create;
  144. end.
  145. {
  146. $Log$
  147. Revision 1.6 2004-05-12 13:28:01 karoly
  148. * added some basic code for later syscall support on M68k/Amiga
  149. Revision 1.5 2004/01/30 12:17:18 florian
  150. * fixed some m68k compilation problems
  151. Revision 1.4 2003/02/02 19:25:54 carl
  152. * Several bugfixes for m68k target (register alloc., opcode emission)
  153. + VIS target
  154. + Generic add more complete (still not verified)
  155. Revision 1.3 2003/01/08 18:43:57 daniel
  156. * Tregister changed into a record
  157. Revision 1.2 2002/12/14 15:02:03 carl
  158. * maxoperands -> max_operands (for portability in rautils.pas)
  159. * fix some range-check errors with loadconst
  160. + add ncgadd unit to m68k
  161. * some bugfix of a_param_reg with LOC_CREFERENCE
  162. Revision 1.1 2002/08/12 15:08:44 carl
  163. + stab register indexes for powerpc (moved from gdb to cpubase)
  164. + tprocessor enumeration moved to cpuinfo
  165. + linker in target_info is now a class
  166. * many many updates for m68k (will soon start to compile)
  167. - removed some ifdef or correct them for correct cpu
  168. }