cpupi.pas 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. {
  2. Copyright (c) 2002 by Florian Klaempfl
  3. This unit contains the CPU specific part of tprocinfo
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. ****************************************************************************
  16. }
  17. { This unit contains the CPU specific part of tprocinfo. }
  18. unit cpupi;
  19. {$i fpcdefs.inc}
  20. interface
  21. uses
  22. cutils,globtype,
  23. cgbase,
  24. procinfo,cpuinfo,psub;
  25. type
  26. tppcprocinfo = class(tcgprocinfo)
  27. { offset where the frame pointer from the outer procedure is stored. }
  28. parent_framepointer_offset : longint;
  29. constructor create(aparent:tprocinfo);override;
  30. procedure set_first_temp_offset;override;
  31. procedure allocate_push_parasize(size: longint);override;
  32. function calc_stackframe_size:longint;override;
  33. function uses_stack_temps: boolean;
  34. private
  35. start_temp_offset: aint;
  36. first_save_int_reg, first_save_fpu_reg: tsuperregister;
  37. public
  38. property get_first_save_int_reg: tsuperregister read first_save_int_reg;
  39. property get_first_save_fpu_reg: tsuperregister read first_save_fpu_reg;
  40. end;
  41. implementation
  42. uses
  43. globals,systems,
  44. cpubase,
  45. aasmtai,
  46. tgobj,cgobj,
  47. symconst,symsym,paramgr,symutil,
  48. verbose;
  49. constructor tppcprocinfo.create(aparent:tprocinfo);
  50. begin
  51. inherited create(aparent);
  52. maxpushedparasize:=0;
  53. start_temp_offset:=-1;
  54. first_save_int_reg:=-1;
  55. first_save_fpu_reg:=-1;
  56. end;
  57. procedure tppcprocinfo.set_first_temp_offset;
  58. var
  59. ofs : aword;
  60. locals: longint;
  61. begin
  62. if not(po_assembler in procdef.procoptions) then
  63. begin
  64. case target_info.abi of
  65. abi_powerpc_aix:
  66. ofs:=maxpushedparasize+LinkageAreaSizeAIX;
  67. abi_powerpc_sysv:
  68. ofs:=maxpushedparasize+LinkageAreaSizeSYSV;
  69. else
  70. internalerror(200402191);
  71. end;
  72. tg.setfirsttemp(ofs);
  73. start_temp_offset := ofs;
  74. end
  75. else
  76. begin
  77. locals := 0;
  78. start_temp_offset := 0;
  79. current_procinfo.procdef.localst.foreach_static(@count_locals,@locals);
  80. if locals <> 0 then
  81. begin
  82. { at 0(r1), the previous value of r1 will be stored }
  83. tg.setfirsttemp(4);
  84. start_temp_offset := 4;
  85. end;
  86. end;
  87. end;
  88. (*
  89. procedure tppcprocinfo.after_pass1;
  90. begin
  91. if not(po_assembler in procdef.procoptions) then
  92. begin
  93. if cs_asm_source in aktglobalswitches then
  94. aktproccode.insert(Tai_comment.Create(strpnew('Parameter copies start at: r1+'+tostr(procdef.parast.address_fixup))));
  95. if cs_asm_source in aktglobalswitches then
  96. aktproccode.insert(Tai_comment.Create(strpnew('Locals start at: r1+'+tostr(procdef.localst.address_fixup))));
  97. firsttemp_offset:=align(procdef.localst.address_fixup+procdef.localst.datasize,16);
  98. if cs_asm_source in aktglobalswitches then
  99. aktproccode.insert(Tai_comment.Create(strpnew('Temp. space start: r1+'+tostr(firsttemp_offset))));
  100. //!!!! tg.setfirsttemp(firsttemp_offset);
  101. tg.firsttemp:=firsttemp_offset;
  102. tg.lasttemp:=firsttemp_offset;
  103. inherited after_pass1;
  104. end;
  105. end;
  106. *)
  107. procedure tppcprocinfo.allocate_push_parasize(size:longint);
  108. begin
  109. if size>maxpushedparasize then
  110. maxpushedparasize:=size;
  111. end;
  112. function tppcprocinfo.uses_stack_temps: boolean;
  113. begin
  114. if (start_temp_offset = -1) then
  115. internalerror(200512301);
  116. result := start_temp_offset <> tg.lasttemp;
  117. end;
  118. function tppcprocinfo.calc_stackframe_size:longint;
  119. var
  120. low_nonvol_fpu_reg, regcounter: tsuperregister;
  121. begin
  122. if not (po_assembler in procdef.procoptions) then
  123. begin
  124. first_save_fpu_reg := 32;
  125. first_save_int_reg := 32;
  126. { FIXME: has to be R_F14 instead of R_F8 for SYSV-64bit }
  127. case target_info.abi of
  128. abi_powerpc_aix:
  129. low_nonvol_fpu_reg := RS_F14;
  130. abi_powerpc_sysv:
  131. low_nonvol_fpu_reg := RS_F14;
  132. else
  133. internalerror(2003122903);
  134. end;
  135. for regcounter := low_nonvol_fpu_reg to RS_F31 do
  136. begin
  137. if regcounter in cg.rg[R_FPUREGISTER].used_in_proc then
  138. begin
  139. first_save_fpu_reg := ord(regcounter) - ord(RS_F0);
  140. break;
  141. end;
  142. end;
  143. for regcounter := RS_R13 to RS_R31 do
  144. begin
  145. if regcounter in cg.rg[R_INTREGISTER].used_in_proc then
  146. begin
  147. first_save_int_reg := ord(regcounter) - ord(RS_R0);
  148. break;
  149. end;
  150. end;
  151. if not(pi_do_call in flags) and
  152. (not uses_stack_temps) and
  153. (((target_info.abi = abi_powerpc_aix) and
  154. ((32-first_save_int_reg)*4+(32-first_save_fpu_reg)*8 <= 220)) or
  155. ((target_info.abi = abi_powerpc_sysv) and
  156. (first_save_int_reg + first_save_fpu_reg = 64))) then
  157. { don't allocate a stack frame }
  158. result := (32-first_save_int_reg)*4+(32-first_save_fpu_reg)*8
  159. else
  160. result := (32-first_save_int_reg)*4+(32-first_save_fpu_reg)*8+tg.lasttemp;
  161. result := align(result,16);
  162. end
  163. else
  164. result := align(tg.lasttemp,16);
  165. end;
  166. begin
  167. cprocinfo:=tppcprocinfo;
  168. end.