hlcgcpu.pas 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. {
  2. Copyright (c) 1998-2010 by Florian Klaempfl and Jonas Maebe
  3. Member of the Free Pascal development team
  4. This unit contains routines to create a pass-through high-level code
  5. generator. This is used by most regular code generators.
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2 of the License, or
  9. (at your option) any later version.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with this program; if not, write to the Free Software
  16. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. ****************************************************************************
  18. }
  19. unit hlcgcpu;
  20. {$i fpcdefs.inc}
  21. interface
  22. uses
  23. aasmdata,
  24. symtype,parabase,
  25. cgutils,
  26. hlcgobj, hlcgx86;
  27. type
  28. thlcgcpu = class(thlcgx86)
  29. protected
  30. procedure gen_loadfpu_loc_cgpara(list: TAsmList; size: tdef; const l: tlocation; const cgpara: tcgpara; locintsize: longint); override;
  31. end;
  32. procedure create_hlcodegen;
  33. implementation
  34. uses
  35. globtype,verbose,
  36. paramgr,
  37. cgbase,
  38. cpubase,tgobj,cgobj,cgcpu;
  39. { thlcgcpu }
  40. procedure thlcgcpu.gen_loadfpu_loc_cgpara(list: TAsmList; size: tdef; const l: tlocation; const cgpara: tcgpara; locintsize: longint);
  41. var
  42. locsize : tcgsize;
  43. locdef : tdef;
  44. tmploc : tlocation;
  45. href : treference;
  46. stacksize : longint;
  47. begin
  48. if not(l.size in [OS_32,OS_S32,OS_64,OS_S64,OS_128,OS_S128]) then
  49. locsize:=l.size
  50. else
  51. locsize:=int_float_cgsize(tcgsize2size[l.size]);
  52. case l.loc of
  53. LOC_FPUREGISTER,
  54. LOC_CFPUREGISTER:
  55. begin
  56. case cgpara.location^.loc of
  57. LOC_REFERENCE:
  58. begin
  59. stacksize:=align(locintsize,cgpara.alignment);
  60. if (not paramanager.use_fixed_stack) and
  61. (cgpara.location^.reference.index=NR_STACK_POINTER_REG) then
  62. begin
  63. cg.g_stackpointer_alloc(list,stacksize);
  64. reference_reset_base(href,NR_STACK_POINTER_REG,0,sizeof(pint));
  65. end
  66. else
  67. reference_reset_base(href,cgpara.location^.reference.index,cgpara.location^.reference.offset,cgpara.alignment);
  68. cg.a_loadfpu_reg_ref(list,locsize,locsize,l.register,href);
  69. end;
  70. LOC_FPUREGISTER:
  71. begin
  72. cg.a_loadfpu_reg_reg(list,locsize,cgpara.location^.size,l.register,cgpara.location^.register);
  73. end;
  74. { can happen if a record with only 1 "single field" is
  75. returned in a floating point register and then is directly
  76. passed to a regcall parameter }
  77. LOC_REGISTER:
  78. begin
  79. tmploc:=l;
  80. location_force_mem(list,tmploc,size);
  81. case locsize of
  82. OS_F32:
  83. tmploc.size:=OS_32;
  84. OS_F64:
  85. tmploc.size:=OS_64;
  86. else
  87. internalerror(2010053116);
  88. end;
  89. cg.a_load_loc_cgpara(list,tmploc,cgpara);
  90. location_freetemp(list,tmploc);
  91. end
  92. else
  93. internalerror(2010053003);
  94. end;
  95. end;
  96. LOC_MMREGISTER,
  97. LOC_CMMREGISTER:
  98. begin
  99. case cgpara.location^.loc of
  100. LOC_REFERENCE:
  101. begin
  102. { can't use TCGSize2Size[l.size], because the size of an
  103. 80 bit extended parameter can be either 10 or 12 bytes }
  104. stacksize:=align(locintsize,cgpara.alignment);
  105. if (not paramanager.use_fixed_stack) and
  106. (cgpara.location^.reference.index=NR_STACK_POINTER_REG) then
  107. begin
  108. cg.g_stackpointer_alloc(list,stacksize);
  109. reference_reset_base(href,NR_STACK_POINTER_REG,0,sizeof(pint));
  110. end
  111. else
  112. reference_reset_base(href,cgpara.location^.reference.index,cgpara.location^.reference.offset,cgpara.alignment);
  113. cg.a_loadmm_reg_ref(list,locsize,locsize,l.register,href,mms_movescalar);
  114. end;
  115. LOC_FPUREGISTER:
  116. begin
  117. tmploc:=l;
  118. location_force_mem(list,tmploc,size);
  119. cg.a_loadfpu_ref_cgpara(list,tmploc.size,tmploc.reference,cgpara);
  120. location_freetemp(list,tmploc);
  121. end;
  122. else
  123. internalerror(2010053004);
  124. end;
  125. end;
  126. LOC_REFERENCE,
  127. LOC_CREFERENCE :
  128. begin
  129. case cgpara.location^.loc of
  130. LOC_REFERENCE:
  131. begin
  132. stacksize:=align(locintsize,cgpara.alignment);
  133. if (not paramanager.use_fixed_stack) and
  134. (cgpara.location^.reference.index=NR_STACK_POINTER_REG) then
  135. cg.a_load_ref_cgpara(list,locsize,l.reference,cgpara)
  136. else
  137. begin
  138. reference_reset_base(href,cgpara.location^.reference.index,cgpara.location^.reference.offset,cgpara.alignment);
  139. cg.g_concatcopy(list,l.reference,href,stacksize);
  140. end;
  141. end;
  142. LOC_FPUREGISTER:
  143. begin
  144. cg.a_loadfpu_ref_cgpara(list,locsize,l.reference,cgpara);
  145. end;
  146. else
  147. internalerror(2010053005);
  148. end;
  149. end;
  150. else
  151. internalerror(2002042430);
  152. end;
  153. end;
  154. procedure create_hlcodegen;
  155. begin
  156. hlcg:=thlcgcpu.create;
  157. create_codegen;
  158. end;
  159. end.