rgcpu.pas 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. {
  2. Copyright (c) 1998-2002 by Florian Klaempfl
  3. This unit implements the powerpc specific class for the register
  4. allocator
  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 by
  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. unit rgcpu;
  19. {$i fpcdefs.inc}
  20. interface
  21. uses
  22. aasmbase,aasmtai,aasmdata,aasmcpu,
  23. cgbase,cgutils,
  24. cpubase,
  25. rgobj;
  26. type
  27. trgcpu = class(trgobj)
  28. procedure do_spill_read(list:TAsmList;pos:tai;const spilltemp:treference;tempreg:tregister);override;
  29. procedure do_spill_written(list:TAsmList;pos:tai;const spilltemp:treference;tempreg:tregister);override;
  30. end;
  31. trgintcpu = class(trgcpu)
  32. {$ifdef user0}
  33. procedure add_cpu_interferences(p : tai);override;
  34. {$endif user0}
  35. end;
  36. implementation
  37. uses
  38. verbose, cutils,
  39. cgobj,
  40. procinfo;
  41. procedure trgcpu.do_spill_read(list:TAsmList;pos:tai;const spilltemp:treference;tempreg:tregister);
  42. var
  43. tmpref : treference;
  44. helplist : TAsmList;
  45. l : tasmlabel;
  46. hreg : tregister;
  47. ins : Taicpu;
  48. begin
  49. if (spilltemp.offset<low(smallint)) or
  50. (spilltemp.offset>high(smallint)) then
  51. begin
  52. helplist:=TAsmList.create;
  53. if (spilltemp.index<>NR_NO) then
  54. internalerror(200704201);
  55. if getregtype(tempreg)=R_INTREGISTER then
  56. begin
  57. hreg:=getregisterinline(helplist,R_SUBWHOLE);
  58. {Done by add_cpu_interferences now.
  59. add_edge(getsupreg(hreg),RS_R0);}
  60. end
  61. else
  62. hreg:=cg.getintregister(helplist,OS_ADDR);
  63. reference_reset(tmpref);
  64. tmpref.offset:=spilltemp.offset;
  65. tmpref.refaddr:=addr_hi;
  66. ins:=taicpu.op_reg_reg_ref(A_ADDIS,hreg,spilltemp.base,tmpref);
  67. add_cpu_interferences(ins);
  68. helplist.concat(ins);
  69. tmpref:=spilltemp;
  70. tmpref.refaddr:=addr_lo;
  71. tmpref.base:=hreg;
  72. ins:=spilling_create_load(tmpref,tempreg);
  73. add_cpu_interferences(ins);
  74. helplist.concat(ins);
  75. if getregtype(tempreg)=R_INTREGISTER then
  76. ungetregisterinline(helplist,hreg);
  77. list.insertlistafter(pos,helplist);
  78. helplist.free;
  79. end
  80. else
  81. inherited do_spill_read(list,pos,spilltemp,tempreg);
  82. end;
  83. procedure trgcpu.do_spill_written(list:TAsmList;pos:tai;const spilltemp:treference;tempreg:tregister);
  84. var
  85. tmpref : treference;
  86. helplist : TAsmList;
  87. l : tasmlabel;
  88. hreg : tregister;
  89. ins : Taicpu;
  90. begin
  91. if (spilltemp.offset<low(smallint)) or
  92. (spilltemp.offset>high(smallint)) then
  93. begin
  94. helplist:=TAsmList.create;
  95. if (spilltemp.index<>NR_NO) then
  96. internalerror(200704201);
  97. if getregtype(tempreg)=R_INTREGISTER then
  98. begin
  99. hreg:=getregisterinline(helplist,R_SUBWHOLE);
  100. {Done by add_cpu_interferences now.
  101. add_edge(getsupreg(hreg),RS_R0);}
  102. end
  103. else
  104. hreg:=cg.getintregister(helplist,OS_ADDR);
  105. reference_reset(tmpref);
  106. tmpref.offset:=spilltemp.offset;
  107. tmpref.refaddr:=addr_hi;
  108. ins:=taicpu.op_reg_reg_ref(A_ADDIS,hreg,spilltemp.base,tmpref);
  109. add_cpu_interferences(ins);
  110. helplist.concat(ins);
  111. tmpref:=spilltemp;
  112. tmpref.refaddr:=addr_lo;
  113. tmpref.base:=hreg;
  114. ins:=spilling_create_store(tempreg,tmpref);
  115. add_cpu_interferences(ins);
  116. helplist.concat(ins);
  117. if getregtype(tempreg)=R_INTREGISTER then
  118. ungetregisterinline(helplist,hreg);
  119. list.insertlistafter(pos,helplist);
  120. helplist.free;
  121. end
  122. else
  123. inherited do_spill_written(list,pos,spilltemp,tempreg);
  124. end;
  125. {$ifdef user0}
  126. procedure trgintcpu.add_cpu_interferences(p : tai);
  127. var
  128. r : tregister;
  129. begin
  130. if p.typ=ait_instruction then
  131. begin
  132. case taicpu(p).opcode of
  133. A_ADDI, A_ADDIS,
  134. A_STB, A_LBZ, A_STBX, A_LBZX, A_STH, A_LHZ, A_STHX, A_LHZX, A_LHA, A_LHAX,
  135. A_STBU, A_LBZU, A_STBUX, A_LBZUX, A_STHU, A_LHZU, A_STHUX, A_LHZUX, A_LHAUX,
  136. A_STW, A_LWZ, A_STWX, A_LWZX,
  137. A_STWU, A_LWZU, A_STWUX, A_LWZUX,
  138. A_STFS, A_LFS, A_STFSX, A_LFSX, A_STFD, A_LFD, A_STFDX, A_LFDX, A_STFIWX,
  139. A_STFSU, A_LFSU, A_STFSUX, A_LFSUX, A_STFDU, A_LFDU, A_STFDUX, A_LFDUX,
  140. A_STHBRX, A_LHBRX, A_STWBRX, A_LWBRX, A_STWCX_, A_LWARX,
  141. A_ECIWX, A_ECOWX,
  142. A_LMW, A_STMW,A_LSWI,A_LSWX,A_STSWI,A_STSWX
  143. {$ifdef cpu64bit}
  144. , A_STDU, A_STDUX,
  145. A_LDU, A_LDUX,
  146. A_STD, A_STDX,
  147. A_LD, A_LDX,
  148. A_LWA, A_LWAX, A_LWAUX,
  149. A_STDCX_,A_LDARX
  150. {$endif cpu64bit}
  151. :
  152. begin
  153. case taicpu(p).oper[1]^.typ of
  154. top_reg:
  155. add_edge(getsupreg(taicpu(p).oper[1]^.reg),RS_R0);
  156. top_ref:
  157. if (taicpu(p).oper[1]^.ref^.base <> NR_NO) then
  158. add_edge(getsupreg(taicpu(p).oper[1]^.ref^.base),RS_R0);
  159. end;
  160. end;
  161. A_DCBA, A_DCBI, A_DCBST, A_DCBT, A_DCBTST, A_DCBZ, A_DCBF, A_ICBI:
  162. begin
  163. case taicpu(p).oper[0]^.typ of
  164. top_reg:
  165. add_edge(getsupreg(taicpu(p).oper[0]^.reg),RS_R0);
  166. top_ref:
  167. if (taicpu(p).oper[0]^.ref^.base <> NR_NO) then
  168. add_edge(getsupreg(taicpu(p).oper[1]^.ref^.base),RS_R0);
  169. end;
  170. end;
  171. end;
  172. end;
  173. end;
  174. {$endif user0}
  175. end.