njvminl.pas 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. {
  2. Copyright (c) 1998-2011 by Florian Klaempfl and Jonas Maebe
  3. Generate JVM inline nodes
  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 njvminl;
  18. {$i fpcdefs.inc}
  19. interface
  20. uses
  21. cpubase,
  22. node,ninl,ncginl;
  23. type
  24. tjvminlinenode = class(tcginlinenode)
  25. { first pass override
  26. so that the code generator will actually generate
  27. these nodes.
  28. }
  29. (*
  30. function first_sqrt_real: tnode; override;
  31. *)
  32. function first_sqr_real: tnode; override;
  33. function first_trunc_real: tnode; override;
  34. (*
  35. function first_round_real: tnode; override;
  36. procedure second_sqrt_real; override;
  37. procedure second_abs_real; override;
  38. *)
  39. procedure second_sqr_real; override;
  40. procedure second_trunc_real; override;
  41. (*
  42. procedure second_round_real; override;
  43. *)
  44. protected
  45. procedure load_fpu_location;
  46. end;
  47. implementation
  48. uses
  49. cutils,globals,verbose,globtype,
  50. aasmtai,aasmdata,aasmcpu,
  51. symconst,symdef,
  52. defutil,
  53. cgbase,pass_2,
  54. cpuinfo,ncgutil,
  55. cgutils,hlcgobj,hlcgcpu;
  56. {*****************************************************************************
  57. tjvminlinenode
  58. *****************************************************************************}
  59. (*
  60. function tjvminlinenode.first_sqrt_real : tnode;
  61. begin
  62. if (current_settings.cputype >= cpu_PPC970) then
  63. begin
  64. expectloc:=LOC_FPUREGISTER;
  65. first_sqrt_real := nil;
  66. end
  67. else
  68. result:=inherited first_sqrt_real;
  69. end;
  70. *)
  71. function tjvminlinenode.first_sqr_real : tnode;
  72. begin
  73. expectloc:=LOC_FPUREGISTER;
  74. first_sqr_real:=nil;
  75. end;
  76. function tjvminlinenode.first_trunc_real : tnode;
  77. begin
  78. expectloc:=LOC_REGISTER;
  79. first_trunc_real:=nil;
  80. end;
  81. (*
  82. function tjvminlinenode.first_round_real : tnode;
  83. begin
  84. if (current_settings.cputype >= cpu_PPC970) then
  85. begin
  86. expectloc:=LOC_REFERENCE;
  87. first_round_real := nil;
  88. end
  89. else
  90. result:=inherited first_round_real;
  91. end;
  92. *)
  93. { load the FPU value on the evaluation stack }
  94. procedure tjvminlinenode.load_fpu_location;
  95. begin
  96. secondpass(left);
  97. thlcgjvm(hlcg).a_load_loc_stack(current_asmdata.CurrAsmList,left.resultdef,left.location);
  98. end;
  99. (*
  100. procedure tjvminlinenode.second_sqrt_real;
  101. begin
  102. if (current_settings.cputype < cpu_PPC970) then
  103. internalerror(2007020910);
  104. location.loc:=LOC_FPUREGISTER;
  105. load_fpu_location;
  106. case left.location.size of
  107. OS_F32:
  108. current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_FSQRTS,location.register,
  109. left.location.register));
  110. OS_F64:
  111. current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_FSQRT,location.register,
  112. left.location.register));
  113. else
  114. inherited;
  115. end;
  116. end;
  117. *)
  118. procedure tjvminlinenode.second_sqr_real;
  119. begin
  120. load_fpu_location;
  121. location_reset(location,LOC_FPUREGISTER,location.size);
  122. location.register:=hlcg.getfpuregister(current_asmdata.CurrAsmList,resultdef);
  123. case left.location.size of
  124. OS_F32:
  125. begin
  126. current_asmdata.CurrAsmList.concat(taicpu.op_none(a_dup));
  127. thlcgjvm(hlcg).incstack(current_asmdata.CurrAsmList,1);
  128. current_asmdata.CurrAsmList.concat(taicpu.op_none(a_fmul));
  129. thlcgjvm(hlcg).decstack(current_asmdata.CurrAsmList,1);
  130. end;
  131. OS_F64:
  132. begin
  133. current_asmdata.CurrAsmList.concat(taicpu.op_none(a_dup2));
  134. thlcgjvm(hlcg).incstack(current_asmdata.CurrAsmList,2);
  135. current_asmdata.CurrAsmList.concat(taicpu.op_none(a_dmul));
  136. thlcgjvm(hlcg).decstack(current_asmdata.CurrAsmList,2);
  137. end;
  138. else
  139. internalerror(2011010804);
  140. end;
  141. thlcgjvm(hlcg).a_load_stack_reg(current_asmdata.CurrAsmList,resultdef,location.register);
  142. end;
  143. procedure tjvminlinenode.second_trunc_real;
  144. begin
  145. load_fpu_location;
  146. location_reset(location,LOC_REGISTER,left.location.size);
  147. location.register:=hlcg.getintregister(current_asmdata.CurrAsmList,resultdef);
  148. case left.location.size of
  149. OS_F32:
  150. begin
  151. current_asmdata.CurrAsmList.concat(taicpu.op_none(a_f2l));
  152. { 32 bit float -> 64 bit int: +1 stack slot }
  153. thlcgjvm(hlcg).incstack(current_asmdata.CurrAsmList,1);
  154. end;
  155. OS_F64:
  156. begin
  157. { 64 bit float -> 64 bit int: same number of stack slots }
  158. current_asmdata.CurrAsmList.concat(taicpu.op_none(a_d2l));
  159. end;
  160. else
  161. internalerror(2011010805);
  162. end;
  163. thlcgjvm(hlcg).a_load_stack_reg(current_asmdata.CurrAsmList,resultdef,location.register);
  164. end;
  165. begin
  166. cinlinenode:=tjvminlinenode;
  167. end.