cpupi.pas 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  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. allocate_push_parasize(mips_nb_used_registers*sizeof(aint));
  87. if not (po_nostackframe in procdef.procoptions) then
  88. tg.setfirsttemp(Align(maxpushedparasize+
  89. floatregssave*sizeof(aint)+intregssave*sizeof(aint)
  90. ,max(current_settings.alignment.localalignmin,8)))
  91. else
  92. tg.setfirsttemp(align(maxpushedparasize,max(current_settings.alignment.localalignmin,8)));
  93. end;
  94. procedure TMIPSProcInfo.allocate_got_register(list:tasmlist);
  95. begin
  96. if (cs_create_pic in current_settings.moduleswitches) then
  97. begin
  98. if (pi_do_call in flags) then
  99. include(flags,pi_needs_got);
  100. if (pi_needs_got in flags) and
  101. not (po_nostackframe in procdef.procoptions) then
  102. tg.gettemp(list,sizeof(aint),sizeof(aint),tt_noreuse,save_gp_ref);
  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.