rgcpu.pas 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. {
  2. $Id$
  3. Copyright (c) 1998-2003 by Florian Klaempfl
  4. This unit implements the arm specific class for the register
  5. allocator
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2 of the License, or
  9. (at your option) any later version.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with this program; if not, write to the Free Software
  16. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. ****************************************************************************
  18. }
  19. unit rgcpu;
  20. {$i fpcdefs.inc}
  21. interface
  22. uses
  23. aasmbase,aasmtai,aasmcpu,
  24. cgbase,
  25. cpubase,
  26. rgobj;
  27. type
  28. trgcpu = class(trgobj)
  29. procedure do_spill_read(list : taasmoutput;instr : taicpu;pos: tai; regidx: word;
  30. const spilltemplist:Tspill_temp_list;const regs : tspillregsinfo);override;
  31. procedure do_spill_written(list : taasmoutput;instr : taicpu;pos: tai; regidx: word;
  32. const spilltemplist:Tspill_temp_list;const regs : tspillregsinfo);override;
  33. procedure do_spill_readwritten(list : taasmoutput;instr : taicpu;pos: tai; regidx: word;
  34. const spilltemplist:Tspill_temp_list;const regs : tspillregsinfo);override;
  35. end;
  36. trgintcpu = class(trgcpu)
  37. procedure add_cpu_interferences(p : tai);override;
  38. end;
  39. implementation
  40. uses
  41. verbose, cutils,
  42. cgutils,cgobj,
  43. procinfo;
  44. procedure trgcpu.do_spill_read(list : taasmoutput;instr : taicpu;pos: tai; regidx: word;
  45. const spilltemplist:Tspill_temp_list;const regs : tspillregsinfo);
  46. var
  47. helpins: tai;
  48. tmpref,ref : treference;
  49. helplist : taasmoutput;
  50. l : tasmlabel;
  51. tmpreg : tregister;
  52. begin
  53. ref:=spilltemplist[regs[regidx].orgreg];
  54. if abs(ref.offset)>4095 then
  55. begin
  56. helplist:=taasmoutput.create;
  57. reference_reset(tmpref);
  58. { create consts entry }
  59. objectlibrary.getlabel(l);
  60. cg.a_label(current_procinfo.aktlocaldata,l);
  61. tmpref.symboldata:=current_procinfo.aktlocaldata.last;
  62. current_procinfo.aktlocaldata.concat(tai_const.Create_32bit(ref.offset));
  63. { load consts entry }
  64. if getregtype(regs[regidx].tempreg)=R_INTREGISTER then
  65. getregisterinline(helplist,pos,defaultsub,tmpreg)
  66. else
  67. tmpreg:=cg.getintregister(helplist,OS_ADDR);
  68. tmpref.symbol:=l;
  69. tmpref.base:=NR_R15;
  70. helplist.concat(taicpu.op_reg_ref(A_LDR,tmpreg,tmpref));
  71. if ref.index<>NR_NO then
  72. internalerror(200401263);
  73. ref.index:=tmpreg;
  74. ref.offset:=0;
  75. helpins:=spilling_create_load(ref,regs[regidx].tempreg);
  76. helplist.concat(helpins);
  77. if pos=nil then
  78. list.insertlistafter(list.first,helplist)
  79. else
  80. list.insertlistafter(pos.next,helplist);
  81. ungetregisterinline(list,helpins,regs[regidx].tempreg);
  82. if getregtype(regs[regidx].tempreg)=R_INTREGISTER then
  83. ungetregisterinline(list,helpins,tmpreg);
  84. forward_allocation(tai(helpins.next),instr);
  85. helplist.free;
  86. end
  87. else
  88. inherited do_spill_read(list,instr,pos,regidx,spilltemplist,regs);
  89. end;
  90. procedure trgcpu.do_spill_written(list : taasmoutput;instr : taicpu;pos: tai; regidx: word;
  91. const spilltemplist:Tspill_temp_list;const regs : tspillregsinfo);
  92. var
  93. helpins: tai;
  94. ref,tmpref : treference;
  95. helplist : taasmoutput;
  96. l : tasmlabel;
  97. tmpreg : tregister;
  98. begin
  99. ref:=spilltemplist[regs[regidx].orgreg];
  100. if abs(ref.offset)>4095 then
  101. begin
  102. helplist:=taasmoutput.create;
  103. reference_reset(tmpref);
  104. { create consts entry }
  105. objectlibrary.getlabel(l);
  106. cg.a_label(current_procinfo.aktlocaldata,l);
  107. tmpref.symboldata:=current_procinfo.aktlocaldata.last;
  108. current_procinfo.aktlocaldata.concat(tai_const.Create_32bit(ref.offset));
  109. { load consts entry }
  110. if getregtype(regs[regidx].tempreg)=R_INTREGISTER then
  111. getregisterinline(helplist,pos,defaultsub,tmpreg)
  112. else
  113. tmpreg:=cg.getintregister(helplist,OS_ADDR);
  114. tmpref.symbol:=l;
  115. tmpref.base:=NR_R15;
  116. helplist.concat(taicpu.op_reg_ref(A_LDR,tmpreg,tmpref));
  117. if ref.index<>NR_NO then
  118. internalerror(200401263);
  119. ref.index:=tmpreg;
  120. ref.offset:=0;
  121. helplist.concat(spilling_create_store(regs[regidx].tempreg,ref));
  122. ungetregisterinline(helplist,tai(helplist.last),regs[regidx].tempreg);
  123. if getregtype(regs[regidx].tempreg)=R_INTREGISTER then
  124. ungetregisterinline(helplist,tai(helplist.last),tmpreg);
  125. list.insertlistafter(instr,helplist);
  126. helplist.free;
  127. end
  128. else
  129. inherited do_spill_written(list,instr,pos,regidx,spilltemplist,regs);
  130. end;
  131. procedure trgcpu.do_spill_readwritten(list : taasmoutput;instr : taicpu;pos: tai; regidx: word;
  132. const spilltemplist:Tspill_temp_list;const regs : tspillregsinfo);
  133. var
  134. helpins1, helpins2: tai;
  135. tmpref,ref : treference;
  136. helplist : taasmoutput;
  137. l : tasmlabel;
  138. tmpreg : tregister;
  139. begin
  140. ref:=spilltemplist[regs[regidx].orgreg];
  141. if abs(ref.offset)>4095 then
  142. begin
  143. helplist:=taasmoutput.create;
  144. reference_reset(tmpref);
  145. { create consts entry }
  146. objectlibrary.getlabel(l);
  147. cg.a_label(current_procinfo.aktlocaldata,l);
  148. tmpref.symboldata:=current_procinfo.aktlocaldata.last;
  149. current_procinfo.aktlocaldata.concat(tai_const.Create_32bit(ref.offset));
  150. { load consts entry }
  151. if getregtype(regs[regidx].tempreg)=R_INTREGISTER then
  152. getregisterinline(helplist,pos,defaultsub,tmpreg)
  153. else
  154. tmpreg:=cg.getintregister(helplist,OS_ADDR);
  155. tmpref.symbol:=l;
  156. tmpref.base:=NR_R15;
  157. helplist.concat(taicpu.op_reg_ref(A_LDR,tmpreg,tmpref));
  158. if ref.index<>NR_NO then
  159. internalerror(200401263);
  160. ref.index:=tmpreg;
  161. ref.offset:=0;
  162. helpins1:=spilling_create_load(ref,regs[regidx].tempreg);
  163. helplist.concat(helpins1);
  164. if pos=nil then
  165. list.insertlistafter(list.first,helplist)
  166. else
  167. list.insertlistafter(pos.next,helplist);
  168. helpins2:=spilling_create_store(regs[regidx].tempreg,ref);
  169. list.insertafter(helpins2,instr);
  170. ungetregisterinline(list,helpins2,regs[regidx].tempreg);
  171. if getregtype(regs[regidx].tempreg)=R_INTREGISTER then
  172. ungetregisterinline(list,helpins2,tmpreg);
  173. forward_allocation(tai(helpins1.next),instr);
  174. end
  175. else
  176. inherited do_spill_readwritten(list,instr,pos,regidx,spilltemplist,regs);
  177. end;
  178. procedure trgintcpu.add_cpu_interferences(p : tai);
  179. begin
  180. if p.typ=ait_instruction then
  181. begin
  182. if (taicpu(p).opcode=A_MUL) then
  183. add_edge(getsupreg(taicpu(p).oper[0]^.reg),getsupreg(taicpu(p).oper[1]^.reg));
  184. end;
  185. end;
  186. end.
  187. {
  188. $Log$
  189. Revision 1.13 2004-07-03 19:29:14 florian
  190. * fixed problem with cpu interferences
  191. Revision 1.12 2004/06/20 08:55:31 florian
  192. * logs truncated
  193. Revision 1.11 2004/06/16 20:07:10 florian
  194. * dwarf branch merged
  195. Revision 1.10.2.4 2004/06/13 20:38:38 florian
  196. * fixed floating point register spilling on sparc
  197. Revision 1.10.2.3 2004/06/13 16:02:39 florian
  198. * fixed floating point register spilling problems with offsets > 4095
  199. Revision 1.10.2.2 2004/06/13 10:51:17 florian
  200. * fixed several register allocator problems (sparc/arm)
  201. Revision 1.10.2.1 2004/06/12 17:01:01 florian
  202. * fixed compilation of arm compiler
  203. }