cpupi.pas 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  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,aasmdata,cgutils;
  25. type
  26. { TMIPSProcInfo }
  27. TMIPSProcInfo=class(tcgprocinfo)
  28. intregstart,
  29. floatregstart : aint;
  30. intregssave,
  31. floatregssave : byte;
  32. register_used : tparasupregsused;
  33. computed_local_size : longint;
  34. save_gp_ref: treference;
  35. //intparareg,
  36. //parasize : longint;
  37. constructor create(aparent:tprocinfo);override;
  38. function calc_stackframe_size:longint;override;
  39. procedure set_first_temp_offset;override;
  40. procedure allocate_got_register(list:tasmlist);override;
  41. end;
  42. { Used by Stabs debug info generator }
  43. function mips_extra_offset(procdef : tprocdef) : longint;
  44. implementation
  45. uses
  46. systems,globals,verbose,
  47. cpubase,cgbase,cgobj,
  48. tgobj,paramgr,symconst;
  49. constructor TMIPSProcInfo.create(aparent: tprocinfo);
  50. begin
  51. inherited create(aparent);
  52. if (cs_generate_stackframes in current_settings.localswitches) or
  53. not (cs_opt_stackframe in current_settings.optimizerswitches) then
  54. include(flags,pi_needs_stackframe);
  55. floatregssave:=12; { f20-f31 }
  56. intregssave:=10; { r16-r23,r30,r31 }
  57. computed_local_size:=-1;
  58. { pi_needs_got is not yet set correctly
  59. so include it always if creating PIC code }
  60. if (cs_create_pic in current_settings.moduleswitches) then
  61. begin
  62. include(flags, pi_needs_got);
  63. got:=NR_GP;
  64. end
  65. else
  66. got:=NR_NO;
  67. end;
  68. procedure TMIPSProcInfo.set_first_temp_offset;
  69. begin
  70. { MIPS stack frame is always "optimized" }
  71. framepointer:=NR_STACK_POINTER_REG;
  72. tg.direction:=1;
  73. { We allocate enough space to save all registers because we can't determine
  74. the necessary space because the used registers aren't known before
  75. secondpass is run. }
  76. { will call _mcount if profiling }
  77. if (cs_profile in current_settings.moduleswitches) and
  78. not (po_nostackframe in procdef.procoptions) then
  79. include(flags,pi_do_call);
  80. { Fixes the case when there are calls done by low-level means
  81. (cg.a_call_name) but no child callnode. !!For assembler procedure
  82. there is no clean way to determine what it calls, unless it is
  83. also declared as nostackframe and everything is managed manually. }
  84. if (pi_do_call in flags) or
  85. ((pi_is_assembler in flags) and not (po_nostackframe in procdef.procoptions)) then
  86. begin
  87. include(flags,pi_do_call); // for pi_is_assembler case
  88. allocate_push_parasize(mips_nb_used_registers*sizeof(aint));
  89. end;
  90. if not (po_nostackframe in procdef.procoptions) then
  91. tg.setfirsttemp(Align(maxpushedparasize+
  92. floatregssave*sizeof(aint)+intregssave*sizeof(aint)
  93. ,max(current_settings.alignment.localalignmin,8)))
  94. else
  95. tg.setfirsttemp(align(maxpushedparasize,max(current_settings.alignment.localalignmin,8)));
  96. end;
  97. procedure TMIPSProcInfo.allocate_got_register(list:tasmlist);
  98. begin
  99. if (cs_create_pic in current_settings.moduleswitches) then
  100. begin
  101. if (pi_do_call in flags) then
  102. include(flags,pi_needs_got);
  103. if (pi_needs_got in flags) and
  104. not (po_nostackframe in procdef.procoptions) then
  105. tg.gettemp(list,sizeof(aint),sizeof(aint),tt_noreuse,save_gp_ref);
  106. end;
  107. end;
  108. function TMIPSProcInfo.calc_stackframe_size:longint;
  109. begin
  110. result:=maxpushedparasize;
  111. floatregstart:=result;
  112. inc(result,floatregssave*4);
  113. intregstart:=result;
  114. //inc(result,intregssave*4);
  115. result:=Align(tg.lasttemp,max(current_settings.alignment.localalignmin,8));
  116. if computed_local_size=-1 then
  117. begin
  118. computed_local_size:=result;
  119. procdef.total_local_size:=result;
  120. end
  121. else if computed_local_size <> result then
  122. Comment(V_Error,'TMIPSProcInfo.calc_stackframe_size result changed');
  123. end;
  124. function mips_extra_offset(procdef : tprocdef) : longint;
  125. begin
  126. if procdef=nil then
  127. mips_extra_offset:=0
  128. else
  129. mips_extra_offset:=procdef.total_local_size;
  130. end;
  131. begin
  132. cprocinfo:=TMIPSProcInfo;
  133. end.