math.inc 6.0 KB

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