2
0

rgcpu.pas 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. {
  2. Copyright (c) 1998-2002 by Florian Klaempfl
  3. This unit implements the SPARC 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. unit rgcpu;
  18. {$i fpcdefs.inc}
  19. interface
  20. uses
  21. aasmbase,aasmcpu,aasmtai,aasmdata,
  22. cgbase,cgutils,
  23. cpubase,
  24. globtype,
  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. protected
  31. procedure do_spill_op(list: tasmlist; op: tasmop; pos: tai; const spilltemp: treference; tempreg: tregister; orgsupreg: tsuperregister);
  32. end;
  33. trgintcpu=class(trgcpu)
  34. procedure add_cpu_interferences(p: tai); override;
  35. end;
  36. implementation
  37. uses
  38. verbose,cutils,
  39. cgobj;
  40. procedure trgcpu.do_spill_read(list: TAsmList; pos: tai; const spilltemp: treference; tempreg: tregister; orgsupreg: tsuperregister);
  41. begin
  42. do_spill_op(list,A_LDR,pos,spilltemp,tempreg,orgsupreg);
  43. end;
  44. procedure trgcpu.do_spill_written(list: TAsmList; pos: tai; const spilltemp: treference; tempreg: tregister; orgsupreg: tsuperregister);
  45. begin
  46. do_spill_op(list,A_STR,pos,spilltemp,tempreg,orgsupreg);
  47. end;
  48. procedure trgcpu.do_spill_op(list: tasmlist; op: tasmop; pos: tai; const spilltemp: treference; tempreg: tregister; orgsupreg: tsuperregister);
  49. var
  50. helpins : tai;
  51. tmpref : treference;
  52. helplist : TAsmList;
  53. hreg : tregister;
  54. isload : boolean;
  55. begin
  56. isload:=op=A_LDR;
  57. { offset out of range for regular load/store? }
  58. if simple_ref_type(op,reg_cgsize(tempreg),PF_None,spilltemp)<>sr_simple then
  59. begin
  60. helplist:=TAsmList.create;
  61. if getregtype(tempreg)=R_INTREGISTER then
  62. hreg:=tempreg
  63. else
  64. hreg:=cg.getaddressregister(helplist);
  65. cg.a_load_const_reg(helplist,OS_ADDR,spilltemp.offset,hreg);
  66. reference_reset_base(tmpref,spilltemp.base,0,spilltemp.temppos,sizeof(pint),[]);
  67. tmpref.index:=hreg;
  68. if isload then
  69. helpins:=spilling_create_load(tmpref,tempreg)
  70. else
  71. helpins:=spilling_create_store(tempreg,tmpref);
  72. helplist.concat(helpins);
  73. add_cpu_interferences(helpins);
  74. list.insertlistafter(pos,helplist);
  75. helplist.free;
  76. end
  77. else if isload then
  78. inherited do_spill_read(list,pos,spilltemp,tempreg,orgsupreg)
  79. else
  80. inherited do_spill_written(list,pos,spilltemp,tempreg,orgsupreg)
  81. end;
  82. procedure trgintcpu.add_cpu_interferences(p: tai);
  83. var
  84. i, j: longint;
  85. begin
  86. if p.typ=ait_instruction then
  87. begin
  88. { add interferences for instructions that can have SP as a register
  89. operand }
  90. case taicpu(p).opcode of
  91. A_MOV:
  92. { all operands can be SP }
  93. exit;
  94. A_ADD,
  95. A_SUB,
  96. A_CMP,
  97. A_CMN:
  98. { ok as destination or first source in immediate or extended
  99. register form }
  100. if (taicpu(p).oper[taicpu(p).ops-1]^.typ<>top_shifterop) or
  101. valid_shifter_operand(taicpu(p).opcode,false,true,
  102. reg_cgsize(taicpu(p).oper[0]^.reg) in [OS_64,OS_S64],
  103. taicpu(p).oper[taicpu(p).ops-1]^.shifterop^.shiftmode,
  104. taicpu(p).oper[taicpu(p).ops-1]^.shifterop^.shiftimm) then
  105. begin
  106. if taicpu(p).oper[taicpu(p).ops-1]^.typ=top_shifterop then
  107. i:=taicpu(p).ops-2
  108. else
  109. i:=taicpu(p).ops-1;
  110. if (taicpu(p).oper[i]^.typ=top_reg) then
  111. add_edge(getsupreg(taicpu(p).oper[i]^.reg),RS_SP);
  112. exit;
  113. end;
  114. A_AND,
  115. A_EOR,
  116. A_ORR,
  117. A_TST:
  118. { ok in immediate form }
  119. if taicpu(p).oper[taicpu(p).ops-1]^.typ=top_const then
  120. exit;
  121. end;
  122. { add interferences for other registers }
  123. for i:=0 to taicpu(p).ops-1 do
  124. begin
  125. case taicpu(p).oper[i]^.typ of
  126. top_reg:
  127. if getregtype(taicpu(p).oper[i]^.reg)=R_INTREGISTER then
  128. add_edge(getsupreg(taicpu(p).oper[i]^.reg),RS_SP);
  129. top_ref:
  130. begin
  131. { sp can always be base, never be index }
  132. if taicpu(p).oper[i]^.ref^.index<>NR_NO then
  133. add_edge(getsupreg(taicpu(p).oper[i]^.ref^.index),RS_SP);
  134. { in case of write back, the base register must be
  135. different from the loaded/stored register }
  136. if (taicpu(p).oper[i]^.ref^.addressmode in [AM_PREINDEXED,AM_POSTINDEXED]) and
  137. (taicpu(p).oper[i]^.ref^.base<>NR_NO) then
  138. begin
  139. for j:=pred(i) downto 0 do
  140. if taicpu(p).oper[j]^.typ=TOP_REG then
  141. add_edge(getsupreg(taicpu(p).oper[j]^.reg),getsupreg(taicpu(p).oper[i]^.ref^.base));
  142. end;
  143. end;
  144. end;
  145. end;
  146. end;
  147. end;
  148. end.