cpupara.pas 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. {
  2. Copyright (c) 2002 by Florian Klaempfl
  3. Risc-V32 specific calling conventions
  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 cpupara;
  18. {$i fpcdefs.inc}
  19. interface
  20. uses
  21. globtype,
  22. aasmtai,aasmdata,
  23. cpubase,
  24. symconst,symtype,symdef,symsym,
  25. paramgr,parabase,cgbase,cgutils,
  26. pararv;
  27. type
  28. tcpuparamanager = class(trvparamanager)
  29. function push_addr_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;override;
  30. function create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;override;
  31. end;
  32. implementation
  33. uses
  34. cpuinfo,globals,
  35. verbose,systems,
  36. defutil,symtable,
  37. procinfo,cpupi;
  38. function tcpuparamanager.push_addr_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;
  39. begin
  40. result:=false;
  41. { var,out,constref always require address }
  42. if varspez in [vs_var,vs_out,vs_constref] then
  43. begin
  44. result:=true;
  45. exit;
  46. end;
  47. case def.typ of
  48. variantdef,
  49. formaldef :
  50. result:=true;
  51. { regular procvars must be passed by value, because you cannot pass
  52. the address of a local stack location when calling e.g.
  53. pthread_create with the address of a function (first of all it
  54. expects the address of the function to execute and not the address
  55. of a memory location containing that address, and secondly if you
  56. first store the address on the stack and then pass the address of
  57. this stack location, then this stack location may no longer be
  58. valid when the newly started thread accesses it.
  59. However, for "procedure of object" we must use the same calling
  60. convention as for "8 byte record" due to the need for
  61. interchangeability with the TMethod record type.
  62. }
  63. procvardef,
  64. recorddef:
  65. result := not(def.size in [0..sizeof(aint)*2]) or (varspez = vs_const);
  66. arraydef:
  67. result:=(tarraydef(def).highrange>=tarraydef(def).lowrange) or
  68. is_open_array(def) or
  69. is_array_of_const(def) or
  70. is_array_constructor(def);
  71. objectdef :
  72. result:=is_object(def);
  73. setdef :
  74. result:=not is_smallset(def);
  75. stringdef :
  76. result:=tstringdef(def).stringtype in [st_shortstring,st_longstring];
  77. else
  78. ;
  79. end;
  80. end;
  81. function tcpuparamanager.create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;
  82. var
  83. cur_stack_offset: aword;
  84. curintreg, curfloatreg, curmmreg: tsuperregister;
  85. begin
  86. init_values(curintreg,curfloatreg,curmmreg,cur_stack_offset);
  87. result := create_paraloc_info_intern(p,side,p.paras,curintreg,curfloatreg,curmmreg,cur_stack_offset,false);
  88. create_funcretloc_info(p,side);
  89. end;
  90. begin
  91. paramanager:=tcpuparamanager.create;
  92. end.