math.inc 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 1999-2001 by the Free Pascal development team
  4. Implementation of mathematical routines (for extended type)
  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. {****************************************************************************
  12. FPU Control word
  13. ****************************************************************************}
  14. procedure Set8087CW(cw:word);assembler;
  15. asm
  16. {$ifndef REGCALL}
  17. movw cw,%ax
  18. {$endif}
  19. movw %ax,default8087cw
  20. fnclex
  21. fldcw default8087cw
  22. end;
  23. function Get8087CW:word;assembler;
  24. asm
  25. pushl $0
  26. fnstcw (%esp)
  27. popl %eax
  28. end;
  29. procedure SetSSECSR(w : dword);
  30. var
  31. _w : dword;
  32. begin
  33. _w:=w;
  34. asm
  35. ldmxcsr _w
  36. end;
  37. end;
  38. function GetSSECSR : dword;
  39. var
  40. _w : dword;
  41. begin
  42. asm
  43. stmxcsr _w
  44. end;
  45. result:=_w;
  46. end;
  47. {****************************************************************************
  48. EXTENDED data type routines
  49. ****************************************************************************}
  50. {$define FPC_SYSTEM_HAS_PI}
  51. function fpc_pi_real : ValReal;compilerproc;
  52. begin
  53. { Function is handled internal in the compiler }
  54. runerror(207);
  55. result:=0;
  56. end;
  57. {$define FPC_SYSTEM_HAS_ABS}
  58. function fpc_abs_real(d : ValReal) : ValReal;compilerproc;
  59. begin
  60. { Function is handled internal in the compiler }
  61. runerror(207);
  62. result:=0;
  63. end;
  64. {$define FPC_SYSTEM_HAS_SQR}
  65. function fpc_sqr_real(d : ValReal) : ValReal;compilerproc;
  66. begin
  67. { Function is handled internal in the compiler }
  68. runerror(207);
  69. result:=0;
  70. end;
  71. {$define FPC_SYSTEM_HAS_SQRT}
  72. function fpc_sqrt_real(d : ValReal) : ValReal;compilerproc;
  73. begin
  74. { Function is handled internal in the compiler }
  75. runerror(207);
  76. result:=0;
  77. end;
  78. {$define FPC_SYSTEM_HAS_ARCTAN}
  79. function fpc_arctan_real(d : ValReal) : ValReal;compilerproc;
  80. begin
  81. { Function is handled internal in the compiler }
  82. runerror(207);
  83. result:=0;
  84. end;
  85. {$define FPC_SYSTEM_HAS_LN}
  86. function fpc_ln_real(d : ValReal) : ValReal;compilerproc;
  87. begin
  88. { Function is handled internal in the compiler }
  89. runerror(207);
  90. result:=0;
  91. end;
  92. {$define FPC_SYSTEM_HAS_SIN}
  93. function fpc_sin_real(d : ValReal) : ValReal;compilerproc;
  94. begin
  95. { Function is handled internal in the compiler }
  96. runerror(207);
  97. result:=0;
  98. end;
  99. {$define FPC_SYSTEM_HAS_COS}
  100. function fpc_cos_real(d : ValReal) : ValReal;compilerproc;
  101. begin
  102. { Function is handled internal in the compiler }
  103. runerror(207);
  104. result:=0;
  105. end;
  106. {$define FPC_SYSTEM_HAS_EXP}
  107. function fpc_exp_real(d : ValReal) : ValReal;assembler;compilerproc;
  108. asm
  109. // comes from DJ GPP
  110. fldt d
  111. fldl2e
  112. fmulp %st,%st(1)
  113. fstcw .LCW1
  114. fstcw .LCW2
  115. fwait
  116. andw $0xf3ff,.LCW2
  117. orw $0x0400,.LCW2
  118. fldcw .LCW2
  119. fld %st(0)
  120. frndint
  121. fldcw .LCW1
  122. fxch %st(1)
  123. fsub %st(1),%st
  124. f2xm1
  125. fld1
  126. faddp %st,%st(1)
  127. fscale
  128. fstp %st(1)
  129. fclex
  130. jmp .LCW3
  131. // store some help data in the data segment
  132. .data
  133. .LCW1:
  134. .word 0
  135. .LCW2:
  136. .word 0
  137. .text
  138. .LCW3:
  139. end;
  140. {$define FPC_SYSTEM_HAS_FRAC}
  141. function fpc_frac_real(d : ValReal) : ValReal;assembler;compilerproc;
  142. asm
  143. subl $16,%esp
  144. fnstcw -4(%ebp)
  145. fwait
  146. movw -4(%ebp),%cx
  147. orw $0x0f00,%cx
  148. movw %cx,-8(%ebp)
  149. fldcw -8(%ebp)
  150. fldt d
  151. frndint
  152. fldt d
  153. fsub %st(1),%st
  154. fstp %st(1)
  155. fldcw -4(%ebp)
  156. end;
  157. {$define FPC_SYSTEM_HAS_INT}
  158. function fpc_int_real(d : ValReal) : ValReal;assembler;compilerproc;
  159. asm
  160. subl $16,%esp
  161. fnstcw -4(%ebp)
  162. fwait
  163. movw -4(%ebp),%cx
  164. orw $0x0f00,%cx
  165. movw %cx,-8(%ebp)
  166. fldcw -8(%ebp)
  167. fwait
  168. fldt d
  169. frndint
  170. fwait
  171. fldcw -4(%ebp)
  172. end;
  173. {$define FPC_SYSTEM_HAS_TRUNC}
  174. function fpc_trunc_real(d : ValReal) : int64;assembler;compilerproc;
  175. asm
  176. subl $12,%esp
  177. fldt d
  178. fnstcw (%esp)
  179. movw (%esp),%cx
  180. orw $0x0f00,(%esp)
  181. fldcw (%esp)
  182. movw %cx,(%esp)
  183. fistpq 4(%esp)
  184. fldcw (%esp)
  185. fwait
  186. movl 4(%esp),%eax
  187. movl 8(%esp),%edx
  188. end;
  189. {$define FPC_SYSTEM_HAS_ROUND}
  190. { keep for bootstrapping with 2.0.x }
  191. function fpc_round_real(d : ValReal) : int64;compilerproc;assembler;
  192. var
  193. res : int64;
  194. asm
  195. fldt d
  196. fistpq res
  197. fwait
  198. movl res,%eax
  199. movl res+4,%edx
  200. end;
  201. {$define FPC_SYSTEM_HAS_POWER}
  202. function power(bas,expo : ValReal) : ValReal;
  203. begin
  204. if bas=0 then
  205. begin
  206. if expo<>0 then
  207. power:=0.0
  208. else
  209. HandleError(207);
  210. end
  211. else if expo=0 then
  212. power:=1
  213. else
  214. { bas < 0 is not allowed when doing roots }
  215. if (bas<0) and (frac(expo) <> 0) then
  216. handleerror(207)
  217. else
  218. begin
  219. power:=exp(ln(abs(bas))*expo);
  220. if (bas < 0) and
  221. odd(trunc(expo)) then
  222. begin
  223. power := -power;
  224. end;
  225. end;
  226. end;