math.inc 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. {
  2. Implementation of mathematical routines for x86_64
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1999-2005 by the Free Pascal development team
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. {$push}
  12. {$codealign constmin=16}
  13. const
  14. FPC_ABSMASK_SINGLE: array[0..1] of qword=($7fffffff7fffffff,$7fffffff7fffffff); cvar; public;
  15. FPC_ABSMASK_DOUBLE: array[0..1] of qword=($7fffffffffffffff,$7fffffffffffffff); cvar; public;
  16. {$pop}
  17. {****************************************************************************
  18. FPU Control word
  19. ****************************************************************************}
  20. procedure Set8087CW(cw:word);
  21. begin
  22. default8087cw:=cw;
  23. asm
  24. fnclex
  25. fldcw cw
  26. end;
  27. end;
  28. function Get8087CW:word;assembler;
  29. var
  30. tmp: word;
  31. asm
  32. fnstcw tmp
  33. movw tmp,%ax
  34. andl $0xffff,%eax { clears bits 32-63 }
  35. end;
  36. procedure SetMXCSR(w : dword);
  37. begin
  38. defaultmxcsr:=w;
  39. asm
  40. ldmxcsr w
  41. end;
  42. end;
  43. function GetMXCSR : dword;assembler;
  44. var
  45. _w : dword;
  46. asm
  47. stmxcsr _w
  48. movl _w,%eax
  49. end;
  50. procedure SetSSECSR(w : dword);
  51. begin
  52. SetMXCSR(w);
  53. end;
  54. function GetSSECSR: dword;
  55. begin
  56. result:=GetMXCSR;
  57. end;
  58. {****************************************************************************
  59. EXTENDED data type routines
  60. ****************************************************************************}
  61. {$ifndef FPC_SYSTEM_HAS_ABS}
  62. {$define FPC_SYSTEM_HAS_ABS}
  63. function fpc_abs_real(d : ValReal) : ValReal;compilerproc;
  64. begin
  65. { Function is handled internal in the compiler }
  66. runerror(207);
  67. result:=0;
  68. end;
  69. {$endif FPC_SYSTEM_HAS_ABS}
  70. {$ifndef FPC_SYSTEM_HAS_SQR}
  71. {$define FPC_SYSTEM_HAS_SQR}
  72. function fpc_sqr_real(d : ValReal) : ValReal;compilerproc;
  73. begin
  74. { Function is handled internal in the compiler }
  75. runerror(207);
  76. result:=0;
  77. end;
  78. {$endif FPC_SYSTEM_HAS_SQR}
  79. {$ifndef FPC_SYSTEM_HAS_SQRT}
  80. {$define FPC_SYSTEM_HAS_SQRT}
  81. function fpc_sqrt_real(d : ValReal) : ValReal;compilerproc;
  82. begin
  83. { Function is handled internal in the compiler }
  84. runerror(207);
  85. result:=0;
  86. end;
  87. {$endif FPC_SYSTEM_HAS_SQRT}
  88. {$ifdef FPC_HAS_TYPE_EXTENDED}
  89. {$ifndef FPC_SYSTEM_HAS_ARCTAN}
  90. {$define FPC_SYSTEM_HAS_ARCTAN}
  91. function fpc_arctan_real(d : ValReal) : ValReal;compilerproc;
  92. begin
  93. { Function is handled internal in the compiler }
  94. runerror(207);
  95. result:=0;
  96. end;
  97. {$endif FPC_SYSTEM_HAS_ARCTAN}
  98. {$ifndef FPC_SYSTEM_HAS_LN}
  99. {$define FPC_SYSTEM_HAS_LN}
  100. function fpc_ln_real(d : ValReal) : ValReal;compilerproc;
  101. begin
  102. { Function is handled internal in the compiler }
  103. runerror(207);
  104. result:=0;
  105. end;
  106. {$endif FPC_SYSTEM_HAS_LN}
  107. {$ifndef FPC_SYSTEM_HAS_SIN}
  108. {$define FPC_SYSTEM_HAS_SIN}
  109. function fpc_sin_real(d : ValReal) : ValReal;compilerproc;
  110. begin
  111. { Function is handled internal in the compiler }
  112. runerror(207);
  113. result:=0;
  114. end;
  115. {$endif FPC_SYSTEM_HAS_SIN}
  116. {$ifndef FPC_SYSTEM_HAS_COS}
  117. {$define FPC_SYSTEM_HAS_COS}
  118. function fpc_cos_real(d : ValReal) : ValReal;compilerproc;
  119. begin
  120. { Function is handled internal in the compiler }
  121. runerror(207);
  122. result:=0;
  123. end;
  124. {$endif FPC_SYSTEM_HAS_COS}
  125. {$ifndef FPC_SYSTEM_HAS_EXP}
  126. {$define FPC_SYSTEM_HAS_EXP}
  127. function fpc_exp_real(d : ValReal) : ValReal;assembler;compilerproc;
  128. var
  129. oldcw,newcw: word;
  130. asm
  131. // comes from DJ GPP
  132. fldt d
  133. fldl2e
  134. fmulp %st,%st(1)
  135. fstcw oldcw
  136. fstcw newcw
  137. andw $0xf3ff,newcw
  138. orw $0x0400,newcw
  139. fldcw newcw
  140. fld %st(0)
  141. frndint
  142. fldcw oldcw
  143. fxch %st(1)
  144. fsub %st(1),%st
  145. f2xm1
  146. fld1
  147. faddp %st,%st(1)
  148. fscale
  149. fstp %st(1)
  150. end;
  151. {$endif FPC_SYSTEM_HAS_EXP}
  152. {$ifndef FPC_SYSTEM_HAS_FRAC}
  153. {$define FPC_SYSTEM_HAS_FRAC}
  154. function fpc_frac_real(d : ValReal) : ValReal;assembler;compilerproc;
  155. var
  156. oldcw,newcw: word;
  157. asm
  158. fnstcw oldcw
  159. fwait
  160. movw oldcw,%cx
  161. orw $0x0c3f,%cx
  162. movw %cx,newcw
  163. fldcw newcw
  164. fwait
  165. fldt d
  166. frndint
  167. fldt d
  168. fsub %st(1),%st
  169. fstp %st(1)
  170. fnclex
  171. fldcw oldcw
  172. end;
  173. {$endif FPC_SYSTEM_HAS_FRAC}
  174. {$ifndef FPC_SYSTEM_HAS_INT}
  175. {$define FPC_SYSTEM_HAS_INT}
  176. function fpc_int_real(d : ValReal) : ValReal;assembler;compilerproc;
  177. var
  178. oldcw,newcw: word;
  179. asm
  180. fnstcw oldcw
  181. fwait
  182. movw oldcw,%cx
  183. orw $0x0c3f,%cx
  184. movw %cx,newcw
  185. fldcw newcw
  186. fwait
  187. fldt d
  188. frndint
  189. fwait
  190. fldcw oldcw
  191. end;
  192. {$endif FPC_SYSTEM_HAS_INT}
  193. {$ifndef FPC_SYSTEM_HAS_TRUNC}
  194. {$define FPC_SYSTEM_HAS_TRUNC}
  195. function fpc_trunc_real(d : ValReal) : int64;assembler;compilerproc;
  196. var
  197. oldcw,
  198. newcw : word;
  199. res : int64;
  200. asm
  201. fnstcw oldcw
  202. fwait
  203. movw oldcw,%cx
  204. orw $0x0c3f,%cx
  205. movw %cx,newcw
  206. fldcw newcw
  207. fldt d
  208. fistpq res
  209. fwait
  210. movq res,%rax
  211. fldcw oldcw
  212. end;
  213. {$endif FPC_SYSTEM_HAS_TRUNC}
  214. {$ifndef FPC_SYSTEM_HAS_ROUND}
  215. {$define FPC_SYSTEM_HAS_ROUND}
  216. function fpc_round_real(d : ValReal) : int64;assembler;compilerproc;
  217. var
  218. res : int64;
  219. asm
  220. fldt d
  221. fistpq res
  222. fwait
  223. movq res,%rax
  224. end;
  225. {$endif FPC_SYSTEM_HAS_ROUND}
  226. {$else FPC_HAS_TYPE_EXTENDED}
  227. {$define FPC_SYSTEM_HAS_TRUNC}
  228. function fpc_trunc_real(d : ValReal) : int64;compilerproc; assembler; nostackframe;
  229. asm
  230. cvttsd2si %xmm0,%rax;
  231. end;
  232. {$define FPC_SYSTEM_HAS_ROUND}
  233. function fpc_round_real(d : ValReal) : int64;compilerproc; assembler; nostackframe;
  234. asm
  235. cvtsd2si %xmm0,%rax;
  236. end;
  237. {$endif FPC_HAS_TYPE_EXTENDED}