rgcpu.pas 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  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. begin
  48. if (spilltemp.offset<low(smallint)) or
  49. (spilltemp.offset>high(smallint)) then
  50. begin
  51. helplist:=TAsmList.create;
  52. if (spilltemp.index<>NR_NO) then
  53. internalerror(200704201);
  54. if getregtype(tempreg)=R_INTREGISTER then
  55. begin
  56. hreg:=getregisterinline(helplist,R_SUBWHOLE);
  57. add_edge(getsupreg(hreg),RS_R0);
  58. end
  59. else
  60. hreg:=cg.getintregister(helplist,OS_ADDR);
  61. reference_reset(tmpref);
  62. tmpref.offset:=spilltemp.offset;
  63. tmpref.refaddr:=addr_hi;
  64. helplist.concat(taicpu.op_reg_reg_ref(A_ADDIS,hreg,spilltemp.base,tmpref));
  65. tmpref:=spilltemp;
  66. tmpref.refaddr:=addr_lo;
  67. tmpref.base:=hreg;
  68. helplist.concat(spilling_create_load(tmpref,tempreg));
  69. if getregtype(tempreg)=R_INTREGISTER then
  70. ungetregisterinline(helplist,hreg);
  71. list.insertlistafter(pos,helplist);
  72. helplist.free;
  73. end
  74. else
  75. inherited do_spill_read(list,pos,spilltemp,tempreg);
  76. end;
  77. procedure trgcpu.do_spill_written(list:TAsmList;pos:tai;const spilltemp:treference;tempreg:tregister);
  78. var
  79. tmpref : treference;
  80. helplist : TAsmList;
  81. l : tasmlabel;
  82. hreg : tregister;
  83. begin
  84. if (spilltemp.offset<low(smallint)) or
  85. (spilltemp.offset>high(smallint)) then
  86. begin
  87. helplist:=TAsmList.create;
  88. if (spilltemp.index<>NR_NO) then
  89. internalerror(200704201);
  90. if getregtype(tempreg)=R_INTREGISTER then
  91. begin
  92. hreg:=getregisterinline(helplist,R_SUBWHOLE);
  93. add_edge(getsupreg(hreg),RS_R0);
  94. end
  95. else
  96. hreg:=cg.getintregister(helplist,OS_ADDR);
  97. reference_reset(tmpref);
  98. tmpref.offset:=spilltemp.offset;
  99. tmpref.refaddr:=addr_hi;
  100. helplist.concat(taicpu.op_reg_reg_ref(A_ADDIS,hreg,spilltemp.base,tmpref));
  101. tmpref:=spilltemp;
  102. tmpref.refaddr:=addr_lo;
  103. tmpref.base:=hreg;
  104. helplist.concat(spilling_create_store(tempreg,tmpref));
  105. if getregtype(tempreg)=R_INTREGISTER then
  106. ungetregisterinline(helplist,hreg);
  107. list.insertlistafter(pos,helplist);
  108. helplist.free;
  109. end
  110. else
  111. inherited do_spill_written(list,pos,spilltemp,tempreg);
  112. end;
  113. {$ifdef user0}
  114. procedure trgintcpu.add_cpu_interferences(p : tai);
  115. var
  116. r : tregister;
  117. begin
  118. if p.typ=ait_instruction then
  119. begin
  120. case taicpu(p).opcode of
  121. A_ADDI, A_ADDIS,
  122. A_STB, A_LBZ, A_STBX, A_LBZX, A_STH, A_LHZ, A_STHX, A_LHZX, A_LHA, A_LHAX,
  123. A_STBU, A_LBZU, A_STBUX, A_LBZUX, A_STHU, A_LHZU, A_STHUX, A_LHZUX, A_LHAUX,
  124. A_STW, A_LWZ, A_STWX, A_LWZX,
  125. A_STWU, A_LWZU, A_STWUX, A_LWZUX,
  126. A_STFS, A_LFS, A_STFSX, A_LFSX, A_STFD, A_LFD, A_STFDX, A_LFDX, A_STFIWX,
  127. A_STFSU, A_LFSU, A_STFSUX, A_LFSUX, A_STFDU, A_LFDU, A_STFDUX, A_LFDUX,
  128. A_STHBRX, A_LHBRX, A_STWBRX, A_LWBRX, A_STWCX_, A_LWARX,
  129. A_ECIWX, A_ECOWX,
  130. A_LMW, A_STMW,A_LSWI,A_LSWX,A_STSWI,A_STSWX
  131. {$ifdef cpu64bit}
  132. , A_STDU, A_STDUX,
  133. A_LDU, A_LDUX,
  134. A_STD, A_STDX,
  135. A_LD, A_LDX,
  136. A_LWA, A_LWAX, A_LWAUX,
  137. A_STDCX_,A_LDARX
  138. {$endif cpu64bit}
  139. :
  140. begin
  141. case taicpu(p).oper[1]^.typ of
  142. top_reg:
  143. add_edge(getsupreg(taicpu(p).oper[1]^.reg),RS_R0);
  144. top_ref:
  145. if (taicpu(p).oper[1]^.ref^.base <> NR_NO) then
  146. add_edge(getsupreg(taicpu(p).oper[1]^.ref^.base),RS_R0);
  147. end;
  148. end;
  149. A_DCBA, A_DCBI, A_DCBST, A_DCBT, A_DCBTST, A_DCBZ, A_DCBF, A_ICBI:
  150. begin
  151. case taicpu(p).oper[0]^.typ of
  152. top_reg:
  153. add_edge(getsupreg(taicpu(p).oper[0]^.reg),RS_R0);
  154. top_ref:
  155. if (taicpu(p).oper[0]^.ref^.base <> NR_NO) then
  156. add_edge(getsupreg(taicpu(p).oper[1]^.ref^.base),RS_R0);
  157. end;
  158. end;
  159. end;
  160. end;
  161. end;
  162. {$endif user0}
  163. end.