nppcinl.pas 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  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. private
  34. procedure load_fpu_location;
  35. end;
  36. implementation
  37. uses
  38. globtype,systems,
  39. cutils,verbose,globals,fmodule,
  40. symconst,symdef,defutil,
  41. aasmbase,aasmtai,aasmcpu,
  42. cginfo,cgbase,pass_1,pass_2,
  43. cpubase,paramgr,
  44. nbas,ncon,ncal,ncnv,nld,
  45. cga,tgobj,ncgutil,cgobj,cg64f32,rgobj,rgcpu;
  46. {*****************************************************************************
  47. TPPCINLINENODE
  48. *****************************************************************************}
  49. function tppcinlinenode.first_abs_real : tnode;
  50. begin
  51. expectloc:=LOC_FPUREGISTER;
  52. registers32:=left.registers32;
  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. registers32:=left.registers32;
  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. case left.location.loc of
  75. LOC_FPUREGISTER:
  76. location.register := left.location.register;
  77. LOC_CFPUREGISTER:
  78. begin
  79. location.register := rg.getregisterfpu(exprasmlist);
  80. end;
  81. LOC_REFERENCE,LOC_CREFERENCE:
  82. begin
  83. location.register := rg.getregisterfpu(exprasmlist);
  84. cg.a_loadfpu_ref_reg(exprasmlist,
  85. def_cgsize(left.resulttype.def),
  86. left.location.reference,location.register);
  87. location_release(exprasmlist,left.location);
  88. location_reset(left.location,LOC_FPUREGISTER,
  89. left.location.size);
  90. left.location.register := location.register;
  91. end
  92. else
  93. internalerror(309991);
  94. end;
  95. end;
  96. procedure tppcinlinenode.second_abs_real;
  97. begin
  98. location.loc:=LOC_FPUREGISTER;
  99. load_fpu_location;
  100. exprasmlist.concat(taicpu.op_reg_reg(A_FABS,location.register,
  101. left.location.register));
  102. end;
  103. procedure tppcinlinenode.second_sqr_real;
  104. begin
  105. location.loc:=LOC_FPUREGISTER;
  106. load_fpu_location;
  107. exprasmlist.concat(taicpu.op_reg_reg_reg(A_FMUL,location.register,
  108. left.location.register,left.location.register));
  109. end;
  110. begin
  111. cinlinenode:=tppcinlinenode;
  112. end.
  113. {
  114. $Log$
  115. Revision 1.6 2003-05-24 13:39:32 jonas
  116. * fsqrt is an optional instruction in the ppc architecture and isn't
  117. implemented by any current ppc afaik, so use the generic sqrt routine
  118. instead (adapted so it works with compilerproc)
  119. Revision 1.5 2003/04/23 12:35:35 florian
  120. * fixed several issues with powerpc
  121. + applied a patch from Jonas for nested function calls (PowerPC only)
  122. * ...
  123. Revision 1.4 2002/11/25 17:43:28 peter
  124. * splitted defbase in defutil,symutil,defcmp
  125. * merged isconvertable and is_equal into compare_defs(_ext)
  126. * made operator search faster by walking the list only once
  127. Revision 1.3 2002/09/18 09:19:37 jonas
  128. * fixed LOC_REFERENCE/LOC_CREFERENCE problems
  129. Revision 1.2 2002/08/19 17:35:42 jonas
  130. * fixes
  131. Revision 1.1 2002/08/10 17:15:00 jonas
  132. + abs, sqr, sqrt implementations
  133. }