math.inc 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  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 SetSSECSR(w : dword);
  37. begin
  38. mxcsr:=w;
  39. asm
  40. ldmxcsr w
  41. end;
  42. end;
  43. function GetSSECSR : dword;assembler;
  44. var
  45. _w : dword;
  46. asm
  47. stmxcsr _w
  48. movl _w,%eax
  49. end;
  50. {****************************************************************************
  51. EXTENDED data type routines
  52. ****************************************************************************}
  53. {$ifndef FPC_SYSTEM_HAS_PI}
  54. {$define FPC_SYSTEM_HAS_PI}
  55. function fpc_pi_real : ValReal;compilerproc;
  56. begin
  57. { Function is handled internal in the compiler }
  58. runerror(207);
  59. result:=0;
  60. end;
  61. {$endif FPC_SYSTEM_HAS_PI}
  62. {$ifndef FPC_SYSTEM_HAS_ABS}
  63. {$define FPC_SYSTEM_HAS_ABS}
  64. function fpc_abs_real(d : ValReal) : ValReal;compilerproc;
  65. begin
  66. { Function is handled internal in the compiler }
  67. runerror(207);
  68. result:=0;
  69. end;
  70. {$endif FPC_SYSTEM_HAS_ABS}
  71. {$ifndef FPC_SYSTEM_HAS_SQR}
  72. {$define FPC_SYSTEM_HAS_SQR}
  73. function fpc_sqr_real(d : ValReal) : ValReal;compilerproc;
  74. begin
  75. { Function is handled internal in the compiler }
  76. runerror(207);
  77. result:=0;
  78. end;
  79. {$endif FPC_SYSTEM_HAS_SQR}
  80. {$ifndef FPC_SYSTEM_HAS_SQRT}
  81. {$define FPC_SYSTEM_HAS_SQRT}
  82. function fpc_sqrt_real(d : ValReal) : ValReal;compilerproc;
  83. begin
  84. { Function is handled internal in the compiler }
  85. runerror(207);
  86. result:=0;
  87. end;
  88. {$endif FPC_SYSTEM_HAS_SQRT}
  89. {$ifdef FPC_HAS_TYPE_EXTENDED}
  90. {$ifndef FPC_SYSTEM_HAS_ARCTAN}
  91. {$define FPC_SYSTEM_HAS_ARCTAN}
  92. function fpc_arctan_real(d : ValReal) : ValReal;compilerproc;
  93. begin
  94. { Function is handled internal in the compiler }
  95. runerror(207);
  96. result:=0;
  97. end;
  98. {$endif FPC_SYSTEM_HAS_ARCTAN}
  99. {$ifndef FPC_SYSTEM_HAS_LN}
  100. {$define FPC_SYSTEM_HAS_LN}
  101. function fpc_ln_real(d : ValReal) : ValReal;compilerproc;
  102. begin
  103. { Function is handled internal in the compiler }
  104. runerror(207);
  105. result:=0;
  106. end;
  107. {$endif FPC_SYSTEM_HAS_LN}
  108. {$ifndef FPC_SYSTEM_HAS_SIN}
  109. {$define FPC_SYSTEM_HAS_SIN}
  110. function fpc_sin_real(d : ValReal) : ValReal;compilerproc;
  111. begin
  112. { Function is handled internal in the compiler }
  113. runerror(207);
  114. result:=0;
  115. end;
  116. {$endif FPC_SYSTEM_HAS_SIN}
  117. {$ifndef FPC_SYSTEM_HAS_COS}
  118. {$define FPC_SYSTEM_HAS_COS}
  119. function fpc_cos_real(d : ValReal) : ValReal;compilerproc;
  120. begin
  121. { Function is handled internal in the compiler }
  122. runerror(207);
  123. result:=0;
  124. end;
  125. {$endif FPC_SYSTEM_HAS_COS}
  126. {$ifndef FPC_SYSTEM_HAS_EXP}
  127. {$define FPC_SYSTEM_HAS_EXP}
  128. function fpc_exp_real(d : ValReal) : ValReal;assembler;compilerproc;
  129. var
  130. oldcw,newcw: word;
  131. asm
  132. // comes from DJ GPP
  133. fldt d
  134. fldl2e
  135. fmulp %st,%st(1)
  136. fstcw oldcw
  137. fstcw newcw
  138. andw $0xf3ff,newcw
  139. orw $0x0400,newcw
  140. fldcw newcw
  141. fld %st(0)
  142. frndint
  143. fldcw oldcw
  144. fxch %st(1)
  145. fsub %st(1),%st
  146. f2xm1
  147. fld1
  148. faddp %st,%st(1)
  149. fscale
  150. fstp %st(1)
  151. end;
  152. {$endif FPC_SYSTEM_HAS_EXP}
  153. {$ifndef FPC_SYSTEM_HAS_FRAC}
  154. {$define FPC_SYSTEM_HAS_FRAC}
  155. function fpc_frac_real(d : ValReal) : ValReal;assembler;compilerproc;
  156. var
  157. oldcw,newcw: word;
  158. asm
  159. fnstcw oldcw
  160. fwait
  161. movw oldcw,%cx
  162. orw $0x0c3f,%cx
  163. movw %cx,newcw
  164. fldcw newcw
  165. fwait
  166. fldt d
  167. frndint
  168. fldt d
  169. fsub %st(1),%st
  170. fstp %st(1)
  171. fnclex
  172. fldcw oldcw
  173. end;
  174. {$endif FPC_SYSTEM_HAS_FRAC}
  175. {$ifndef FPC_SYSTEM_HAS_INT}
  176. {$define FPC_SYSTEM_HAS_INT}
  177. function fpc_int_real(d : ValReal) : ValReal;assembler;compilerproc;
  178. var
  179. oldcw,newcw: word;
  180. asm
  181. fnstcw oldcw
  182. fwait
  183. movw oldcw,%cx
  184. orw $0x0c3f,%cx
  185. movw %cx,newcw
  186. fldcw newcw
  187. fwait
  188. fldt d
  189. frndint
  190. fwait
  191. fldcw oldcw
  192. end;
  193. {$endif FPC_SYSTEM_HAS_INT}
  194. {$ifndef FPC_SYSTEM_HAS_TRUNC}
  195. {$define FPC_SYSTEM_HAS_TRUNC}
  196. function fpc_trunc_real(d : ValReal) : int64;assembler;compilerproc;
  197. var
  198. oldcw,
  199. newcw : word;
  200. res : int64;
  201. asm
  202. fnstcw oldcw
  203. fwait
  204. movw oldcw,%cx
  205. orw $0x0c3f,%cx
  206. movw %cx,newcw
  207. fldcw newcw
  208. fldt d
  209. fistpq res
  210. fwait
  211. movq res,%rax
  212. fldcw oldcw
  213. end;
  214. {$endif FPC_SYSTEM_HAS_TRUNC}
  215. {$ifndef FPC_SYSTEM_HAS_ROUND}
  216. {$define FPC_SYSTEM_HAS_ROUND}
  217. function fpc_round_real(d : ValReal) : int64;assembler;compilerproc;
  218. var
  219. res : int64;
  220. asm
  221. fldt d
  222. fistpq res
  223. fwait
  224. movq res,%rax
  225. end;
  226. {$endif FPC_SYSTEM_HAS_ROUND}
  227. {$ifndef FPC_SYSTEM_HAS_POWER}
  228. {$define FPC_SYSTEM_HAS_POWER}
  229. function power(bas,expo : extended) : extended;
  230. begin
  231. if bas=0 then
  232. begin
  233. if expo<>0 then
  234. power:=0.0
  235. else
  236. HandleError(207);
  237. end
  238. else if expo=0 then
  239. power:=1
  240. else
  241. { bas < 0 is not allowed }
  242. if bas<0 then
  243. handleerror(207)
  244. else
  245. power:=exp(ln(bas)*expo);
  246. end;
  247. {$endif FPC_SYSTEM_HAS_POWER}
  248. {$else FPC_HAS_TYPE_EXTENDED}
  249. {$define FPC_SYSTEM_HAS_TRUNC}
  250. function fpc_trunc_real(d : ValReal) : int64;compilerproc; assembler; nostackframe;
  251. asm
  252. cvttsd2si %xmm0,%rax;
  253. end;
  254. {$define FPC_SYSTEM_HAS_ROUND}
  255. function fpc_round_real(d : ValReal) : int64;compilerproc; assembler; nostackframe;
  256. asm
  257. cvtsd2si %xmm0,%rax;
  258. end;
  259. {$endif FPC_HAS_TYPE_EXTENDED}