math.inc 7.4 KB

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