cgcpu.pas 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. {
  2. $Id$
  3. Copyright (c) 2002 by Florian Klaempfl
  4. This unit implements the code generator for the x86-64.
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************
  17. }
  18. { This unit implements the code generator for the x86-64.
  19. }
  20. unit cgcpu;
  21. {$i fpcdefs.inc}
  22. interface
  23. uses
  24. cginfo,cgbase,cgobj,cg64f64,cgx86,
  25. aasmbase,aasmtai,aasmcpu,
  26. cpubase,cpuinfo,cpupara,
  27. node,symconst;
  28. type
  29. tcgx86_64 = class(tcgx86)
  30. procedure g_concatcopy(list : taasmoutput;const source,dest : treference;len : aword; delsource,loadref : boolean);override;
  31. end;
  32. implementation
  33. uses
  34. globtype,globals,verbose,systems,cutils,
  35. symdef,symsym,defutil,paramgr,
  36. rgobj,tgobj,rgcpu;
  37. procedure tcgx86_64.g_concatcopy(list : taasmoutput;const source,dest : treference;len : aword; delsource,loadref : boolean);
  38. var
  39. ecxpushed : boolean;
  40. helpsize : longint;
  41. i : byte;
  42. reg8,reg32 : tregister;
  43. srcref,dstref : treference;
  44. swap : boolean;
  45. {!!!
  46. procedure maybepushecx;
  47. begin
  48. if not(R_ECX in rg.unusedregsint) then
  49. begin
  50. list.concat(Taicpu.Op_reg(A_PUSH,S_L,R_ECX));
  51. ecxpushed:=true;
  52. end
  53. else rg.getexplicitregisterint(list,R_ECX);
  54. end;
  55. }
  56. begin
  57. {!!!
  58. if (not loadref) and
  59. ((len<=8) or
  60. (not(cs_littlesize in aktglobalswitches ) and (len<=12))) then
  61. begin
  62. helpsize:=len shr 3;
  63. rg.getexplicitregisterint(list,R_RDI);
  64. dstref:=dest;
  65. srcref:=source;
  66. for i:=1 to helpsize do
  67. begin
  68. a_load_ref_reg(list,OS_64,srcref,R_RDI);
  69. If (len=8) and delsource then
  70. reference_release(list,source);
  71. a_load_reg_ref(list,OS_64,R_RDI,dstref);
  72. inc(srcref.offset,8);
  73. inc(dstref.offset,8);
  74. dec(len,8);
  75. end;
  76. if len>1 then
  77. begin
  78. a_load_ref_reg(list,OS_16,srcref,R_EDI);
  79. If (len =4) and delsource then
  80. reference_release(list,source);
  81. a_load_reg_ref(list,OS_16,R_EDI,dstref);
  82. inc(srcref.offset,4);
  83. inc(dstref.offset,4);
  84. dec(len,4);
  85. end;
  86. if len>1 then
  87. begin
  88. a_load_ref_reg(list,OS_16,srcref,R_DI);
  89. If (len = 2) and delsource then
  90. reference_release(list,source);
  91. a_load_reg_ref(list,OS_16,R_DI,dstref);
  92. inc(srcref.offset,2);
  93. inc(dstref.offset,2);
  94. dec(len,2);
  95. end;
  96. if len>0 then
  97. begin
  98. a_load_ref_reg(list,OS_16,srcref,R_DIL);
  99. a_load_reg_ref(list,OS_16,R_DIL,dstref);
  100. end;
  101. rg.ungetregisterint(list,R_RDI);
  102. end
  103. else
  104. begin
  105. rg.getexplicitregisterint(list,R_RDI);
  106. a_loadaddr_ref_reg(list,dest,R_RDI);
  107. list.concat(tai_regalloc.Alloc(R_RSI));
  108. if loadref then
  109. a_load_ref_reg(list,OS_ADDR,source,R_RSI)
  110. else
  111. begin
  112. a_loadaddr_ref_reg(list,source,R_RSI);
  113. if delsource then
  114. reference_release(list,source);
  115. end;
  116. list.concat(Taicpu.Op_none(A_CLD,S_NO));
  117. ecxpushed:=false;
  118. if cs_littlesize in aktglobalswitches then
  119. begin
  120. maybepushecx;
  121. a_load_const_reg(list,OS_INT,len,R_RCX);
  122. list.concat(Taicpu.Op_none(A_REP,S_NO));
  123. list.concat(Taicpu.Op_none(A_MOVSB,S_NO));
  124. end
  125. else
  126. begin
  127. helpsize:=len shr 2;
  128. len:=len and 3;
  129. if helpsize>1 then
  130. begin
  131. maybepushecx;
  132. a_load_const_reg(list,OS_INT,helpsize,R_RCX);
  133. list.concat(Taicpu.Op_none(A_REP,S_NO));
  134. end;
  135. if helpsize>0 then
  136. list.concat(Taicpu.Op_none(A_MOVSD,S_NO));
  137. if len>1 then
  138. begin
  139. dec(len,2);
  140. list.concat(Taicpu.Op_none(A_MOVSW,S_NO));
  141. end;
  142. if len=1 then
  143. list.concat(Taicpu.Op_none(A_MOVSB,S_NO));
  144. end;
  145. rg.ungetregisterint(list,R_RDI);
  146. list.concat(tai_regalloc.DeAlloc(R_RSI));
  147. if ecxpushed then
  148. list.concat(Taicpu.Op_reg(A_POP,S_L,R_RCX))
  149. else
  150. rg.ungetregisterint(list,R_RCX);
  151. { loading SELF-reference again }
  152. g_maybe_loadself(list);
  153. end;
  154. if delsource then
  155. tg.ungetiftemp(list,source);
  156. }
  157. end;
  158. begin
  159. cg:=tcgx86_64.create;
  160. cg64:=tcg64f64.create;
  161. end.
  162. {
  163. $Log$
  164. Revision 1.4 2003-04-30 15:45:35 florian
  165. * merged more x86-64/i386 code
  166. Revision 1.3 2003/01/05 13:36:54 florian
  167. * x86-64 compiles
  168. + very basic support for float128 type (x86-64 only)
  169. Revision 1.2 2002/07/25 22:55:33 florian
  170. * several fixes, small test units can be compiled
  171. Revision 1.1 2002/07/24 22:38:15 florian
  172. + initial release of x86-64 target code
  173. }