rgcpu.pas 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  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; orgsupreg: tsuperregister); override;
  29. procedure do_spill_written(list: TAsmList; pos: tai; const spilltemp: treference; tempreg: tregister; orgsupreg: tsuperregister); 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,globtype,
  39. cgobj,
  40. procinfo;
  41. procedure trgcpu.do_spill_read(list: TAsmList; pos: tai; const spilltemp: treference; tempreg: tregister; orgsupreg: tsuperregister);
  42. var
  43. tmpref : treference;
  44. helplist : TAsmList;
  45. hreg : tregister;
  46. ins : Taicpu;
  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. {Done by add_cpu_interferences now.
  58. add_edge(getsupreg(hreg),RS_R0);}
  59. end
  60. else
  61. hreg:=cg.getintregister(helplist,OS_ADDR);
  62. reference_reset(tmpref,sizeof(aint),[]);
  63. tmpref.offset:=spilltemp.offset;
  64. tmpref.refaddr := addr_higha;
  65. ins:=taicpu.op_reg_reg_ref(A_ADDIS,hreg,spilltemp.base,tmpref);
  66. add_cpu_interferences(ins);
  67. helplist.concat(ins);
  68. tmpref:=spilltemp;
  69. tmpref.refaddr := addr_low;
  70. tmpref.base:=hreg;
  71. ins:=spilling_create_load(tmpref,tempreg);
  72. add_cpu_interferences(ins);
  73. helplist.concat(ins);
  74. if getregtype(tempreg)=R_INTREGISTER then
  75. ungetregisterinline(helplist,hreg);
  76. list.insertlistafter(pos,helplist);
  77. helplist.free;
  78. end
  79. else
  80. inherited;
  81. end;
  82. procedure trgcpu.do_spill_written(list: TAsmList; pos: tai; const spilltemp: treference; tempreg: tregister; orgsupreg: tsuperregister);
  83. var
  84. tmpref : treference;
  85. helplist : TAsmList;
  86. hreg : tregister;
  87. ins : Taicpu;
  88. begin
  89. if (spilltemp.offset<low(smallint)) or
  90. (spilltemp.offset>high(smallint)) then
  91. begin
  92. helplist:=TAsmList.create;
  93. if (spilltemp.index<>NR_NO) then
  94. internalerror(200704201);
  95. if getregtype(tempreg)=R_INTREGISTER then
  96. begin
  97. hreg:=getregisterinline(helplist,[R_SUBWHOLE]);
  98. {Done by add_cpu_interferences now.
  99. add_edge(getsupreg(hreg),RS_R0);}
  100. end
  101. else
  102. hreg:=cg.getintregister(helplist,OS_ADDR);
  103. reference_reset(tmpref,sizeof(aint),[]);
  104. tmpref.offset:=spilltemp.offset;
  105. tmpref.refaddr := addr_higha;
  106. ins:=taicpu.op_reg_reg_ref(A_ADDIS,hreg,spilltemp.base,tmpref);
  107. add_cpu_interferences(ins);
  108. helplist.concat(ins);
  109. tmpref:=spilltemp;
  110. tmpref.refaddr := addr_low;
  111. tmpref.base:=hreg;
  112. ins:=spilling_create_store(tempreg,tmpref);
  113. add_cpu_interferences(ins);
  114. helplist.concat(ins);
  115. if getregtype(tempreg)=R_INTREGISTER then
  116. ungetregisterinline(helplist,hreg);
  117. list.insertlistafter(pos,helplist);
  118. helplist.free;
  119. end
  120. else
  121. inherited;
  122. end;
  123. {$ifdef user0}
  124. procedure trgintcpu.add_cpu_interferences(p : tai);
  125. var
  126. r : tregister;
  127. begin
  128. if p.typ=ait_instruction then
  129. begin
  130. case taicpu(p).opcode of
  131. A_ADDI, A_ADDIS,
  132. A_STB, A_LBZ, A_STBX, A_LBZX, A_STH, A_LHZ, A_STHX, A_LHZX, A_LHA, A_LHAX,
  133. A_STW, A_LWZ, A_STWX, A_LWZX,
  134. A_STFS, A_LFS, A_STFSX, A_LFSX, A_STFD, A_LFD, A_STFDX, A_LFDX, A_STFIWX,
  135. A_STHBRX, A_LHBRX, A_STWBRX, A_LWBRX, A_STWCX_, A_LWARX,
  136. A_ECIWX, A_ECOWX,
  137. A_LMW, A_STMW,A_LSWI,A_LSWX,A_STSWI,A_STSWX
  138. {$ifdef cpu64bitalu}
  139. , A_STD, A_STDX,
  140. A_LD, A_LDX,
  141. A_LWA, A_LWAX,
  142. A_STDCX_,A_LDARX
  143. {$endif cpu64bitalu}
  144. :
  145. begin
  146. case taicpu(p).oper[1]^.typ of
  147. top_reg:
  148. add_edge(getsupreg(taicpu(p).oper[1]^.reg),RS_R0);
  149. top_ref:
  150. if (taicpu(p).oper[1]^.ref^.base <> NR_NO) then
  151. add_edge(getsupreg(taicpu(p).oper[1]^.ref^.base),RS_R0);
  152. end;
  153. end;
  154. A_DCBA, A_DCBI, A_DCBST, A_DCBT, A_DCBTST, A_DCBZ, A_DCBF, A_ICBI:
  155. begin
  156. case taicpu(p).oper[0]^.typ of
  157. top_reg:
  158. add_edge(getsupreg(taicpu(p).oper[0]^.reg),RS_R0);
  159. top_ref:
  160. if (taicpu(p).oper[0]^.ref^.base <> NR_NO) then
  161. add_edge(getsupreg(taicpu(p).oper[1]^.ref^.base),RS_R0);
  162. end;
  163. end;
  164. end;
  165. end;
  166. end;
  167. {$endif user0}
  168. end.