nppcinl.pas 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 by Florian Klaempfl
  4. Generate i386 inline nodes
  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. unit nppcinl;
  19. {$i fpcdefs.inc}
  20. interface
  21. uses
  22. node,ninl,ncginl;
  23. type
  24. tppcinlinenode = class(tcginlinenode)
  25. { first pass override
  26. so that the code generator will actually generate
  27. these nodes.
  28. }
  29. function first_abs_real: tnode; override;
  30. function first_sqr_real: tnode; override;
  31. procedure second_abs_real; override;
  32. procedure second_sqr_real; override;
  33. procedure second_prefetch;override;
  34. private
  35. procedure load_fpu_location;
  36. end;
  37. implementation
  38. uses
  39. cutils,globals,verbose,
  40. aasmtai,aasmcpu,
  41. symconst,symdef,
  42. defutil,
  43. cgbase,pass_2,
  44. cpubase,ncgutil,
  45. cgobj,rgobj;
  46. {*****************************************************************************
  47. TPPCINLINENODE
  48. *****************************************************************************}
  49. function tppcinlinenode.first_abs_real : tnode;
  50. begin
  51. expectloc:=LOC_FPUREGISTER;
  52. registersint:=left.registersint;
  53. registersfpu:=max(left.registersfpu,1);
  54. {$ifdef SUPPORT_MMX}
  55. registersmmx:=left.registersmmx;
  56. {$endif SUPPORT_MMX}
  57. first_abs_real := nil;
  58. end;
  59. function tppcinlinenode.first_sqr_real : tnode;
  60. begin
  61. expectloc:=LOC_FPUREGISTER;
  62. registersint:=left.registersint;
  63. registersfpu:=max(left.registersfpu,1);
  64. {$ifdef SUPPORT_MMX}
  65. registersmmx:=left.registersmmx;
  66. {$endif SUPPORT_MMX}
  67. first_sqr_real := nil;
  68. end;
  69. { load the FPU into the an fpu register }
  70. procedure tppcinlinenode.load_fpu_location;
  71. begin
  72. location_reset(location,LOC_FPUREGISTER,def_cgsize(resulttype.def));
  73. secondpass(left);
  74. location_force_fpureg(exprasmlist,left.location,true);
  75. location_copy(location,left.location);
  76. if (location.loc = LOC_CFPUREGISTER) then
  77. begin
  78. location.loc := LOC_FPUREGISTER;
  79. location.register := cg.getfpuregister(exprasmlist,OS_F64);
  80. end;
  81. end;
  82. procedure tppcinlinenode.second_abs_real;
  83. begin
  84. location.loc:=LOC_FPUREGISTER;
  85. load_fpu_location;
  86. exprasmlist.concat(taicpu.op_reg_reg(A_FABS,location.register,
  87. left.location.register));
  88. end;
  89. procedure tppcinlinenode.second_sqr_real;
  90. begin
  91. location.loc:=LOC_FPUREGISTER;
  92. load_fpu_location;
  93. exprasmlist.concat(taicpu.op_reg_reg_reg(A_FMUL,location.register,
  94. location.register,left.location.register));
  95. end;
  96. procedure tppcinlinenode.second_prefetch;
  97. var
  98. r: tregister;
  99. begin
  100. secondpass(left);
  101. case left.location.loc of
  102. LOC_CREFERENCE,
  103. LOC_REFERENCE:
  104. begin
  105. r:=cg.getintregister(exprasmlist,OS_ADDR);
  106. if (left.location.reference.offset = 0) and
  107. not assigned(left.location.reference.symbol) then
  108. begin
  109. if (left.location.reference.index = NR_NO) then
  110. exprasmlist.concat(taicpu.op_const_reg(A_DCBT,0,left.location.reference.base))
  111. else
  112. exprasmlist.concat(taicpu.op_reg_reg(A_DCBT,left.location.reference.base,left.location.reference.index));
  113. location_release(exprasmlist,left.location);
  114. end
  115. else
  116. begin
  117. cg.a_loadaddr_ref_reg(exprasmlist,left.location.reference,r);
  118. location_release(exprasmlist,left.location);
  119. exprasmlist.concat(taicpu.op_const_reg(A_DCBT,0,r));
  120. cg.ungetregister(exprasmlist,r);
  121. end;
  122. end;
  123. else
  124. internalerror(200402021);
  125. end;
  126. end;
  127. begin
  128. cinlinenode:=tppcinlinenode;
  129. end.
  130. {
  131. $Log$
  132. Revision 1.13 2004-02-03 22:32:54 peter
  133. * renamed xNNbittype to xNNinttype
  134. * renamed registers32 to registersint
  135. * replace some s32bit,u32bit with torddef([su]inttype).def.typ
  136. Revision 1.12 2004/02/02 21:22:19 jonas
  137. + implemented second_prefetch
  138. Revision 1.11 2003/10/17 01:22:08 florian
  139. * compilation of the powerpc compiler fixed
  140. Revision 1.10 2003/10/01 20:34:49 peter
  141. * procinfo unit contains tprocinfo
  142. * cginfo renamed to cgbase
  143. * moved cgmessage to verbose
  144. * fixed ppc and sparc compiles
  145. Revision 1.9 2003/08/08 19:01:02 jonas
  146. * fixed bug in load_fpu_location found by Olle
  147. Revision 1.8 2003/06/13 17:03:38 jonas
  148. * fixed bugs in case the left node was a LOC_(C)REFERENCE
  149. Revision 1.7 2003/06/01 21:38:06 peter
  150. * getregisterfpu size parameter added
  151. * op_const_reg size parameter added
  152. * sparc updates
  153. Revision 1.6 2003/05/24 13:39:32 jonas
  154. * fsqrt is an optional instruction in the ppc architecture and isn't
  155. implemented by any current ppc afaik, so use the generic sqrt routine
  156. instead (adapted so it works with compilerproc)
  157. Revision 1.5 2003/04/23 12:35:35 florian
  158. * fixed several issues with powerpc
  159. + applied a patch from Jonas for nested function calls (PowerPC only)
  160. * ...
  161. Revision 1.4 2002/11/25 17:43:28 peter
  162. * splitted defbase in defutil,symutil,defcmp
  163. * merged isconvertable and is_equal into compare_defs(_ext)
  164. * made operator search faster by walking the list only once
  165. Revision 1.3 2002/09/18 09:19:37 jonas
  166. * fixed LOC_REFERENCE/LOC_CREFERENCE problems
  167. Revision 1.2 2002/08/19 17:35:42 jonas
  168. * fixes
  169. Revision 1.1 2002/08/10 17:15:00 jonas
  170. + abs, sqr, sqrt implementations
  171. }