cpupi.pas 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. {
  2. Copyright (c) 2002-2009 by Florian Klaempfl and David Zhang
  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. unit cpupi;
  18. {$i fpcdefs.inc}
  19. interface
  20. uses
  21. cutils,
  22. globtype,symdef,
  23. procinfo,cpuinfo,cpupara,
  24. psub;
  25. type
  26. { TMIPSProcInfo }
  27. TMIPSProcInfo=class(tcgprocinfo)
  28. intregstart,
  29. floatregstart : aint;
  30. intregssave,
  31. floatregssave : byte;
  32. needs_frame_pointer: boolean;
  33. register_used : tparasupregsused;
  34. register_size : tparasupregsize;
  35. register_name : tparasuprename;
  36. register_offset : tparasupregsoffset;
  37. computed_local_size : longint;
  38. //intparareg,
  39. //parasize : longint;
  40. constructor create(aparent:tprocinfo);override;
  41. function calc_stackframe_size:longint;override;
  42. procedure set_first_temp_offset;override;
  43. end;
  44. { Used by Stabs debug info generator }
  45. function mips_extra_offset(procdef : tprocdef) : longint;
  46. implementation
  47. uses
  48. systems,globals,verbose,
  49. cpubase,cgbase,cgutils,cgobj,
  50. tgobj,paramgr,symconst;
  51. constructor TMIPSProcInfo.create(aparent: tprocinfo);
  52. var
  53. i : longint;
  54. begin
  55. inherited create(aparent);
  56. { will call _mcount if profiling }
  57. if cs_profile in current_settings.moduleswitches then
  58. include(flags,pi_do_call);
  59. for i:=low(tparasupregs) to high(tparasupregs) do
  60. begin
  61. register_used[i]:=false;
  62. register_size[i]:=OS_NO;
  63. register_name[i]:='invalid';
  64. register_offset[i]:=-1;
  65. end;
  66. floatregssave:=12; { f20-f31 }
  67. intregssave:=12; { r16-r23,r28-r31 }
  68. { for testing }
  69. needs_frame_pointer := true;//false;
  70. computed_local_size:=-1;
  71. { pi_needs_got is not yet set correctly
  72. so include it always if creating PIC code }
  73. if (cs_create_pic in current_settings.moduleswitches) then
  74. begin
  75. include(flags, pi_needs_got);
  76. got:=NR_GP;
  77. end
  78. else
  79. got:=NR_NO;
  80. end;
  81. procedure TMIPSProcInfo.set_first_temp_offset;
  82. begin
  83. { We allocate enough space to save all registers because we can't determine
  84. the necessary space because the used registers aren't known before
  85. secondpass is run. }
  86. if tg.direction = -1 then
  87. tg.setfirsttemp(0)
  88. else
  89. begin
  90. { Fixes the case when there are calls done by low-level means
  91. (cg.a_call_name) but no child callnode. !!For assembler procedure
  92. there is no clean way to determine what it calls, unless it is
  93. also declared as nostackframe and everything is managed manually. }
  94. if (pi_do_call in flags) or
  95. ((pi_is_assembler in flags) and not (po_nostackframe in procdef.procoptions)) then
  96. allocate_push_parasize(mips_nb_used_registers*sizeof(aint));
  97. if not (po_nostackframe in procdef.procoptions) then
  98. tg.setfirsttemp(Align(maxpushedparasize+
  99. floatregssave*sizeof(aint)+intregssave*sizeof(aint)
  100. ,max(current_settings.alignment.localalignmin,8)))
  101. else
  102. tg.setfirsttemp(align(maxpushedparasize,max(current_settings.alignment.localalignmin,8)));
  103. end;
  104. end;
  105. function TMIPSProcInfo.calc_stackframe_size:longint;
  106. begin
  107. result:=maxpushedparasize;
  108. floatregstart:=result;
  109. inc(result,floatregssave*4);
  110. intregstart:=result;
  111. //inc(result,intregssave*4);
  112. result:=Align(tg.lasttemp,max(current_settings.alignment.localalignmin,8));
  113. if computed_local_size=-1 then
  114. begin
  115. computed_local_size:=result;
  116. procdef.total_local_size:=result;
  117. end
  118. else if computed_local_size <> result then
  119. Comment(V_Error,'TMIPSProcInfo.calc_stackframe_size result changed');
  120. end;
  121. function mips_extra_offset(procdef : tprocdef) : longint;
  122. begin
  123. if procdef=nil then
  124. mips_extra_offset:=0
  125. else
  126. mips_extra_offset:=procdef.total_local_size;
  127. end;
  128. begin
  129. cprocinfo:=TMIPSProcInfo;
  130. end.