math.inc 5.7 KB

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