math.inc 6.0 KB

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