cpupi.pas 5.5 KB

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