math.inc 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1999-2001 by the Free Pascal development team
  5. Implementation of mathematical routines (for extended type)
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. {****************************************************************************
  13. FPU Control word
  14. ****************************************************************************}
  15. procedure Set8087CW(cw:word);assembler;
  16. asm
  17. {$ifndef REGCALL}
  18. movw cw,%ax
  19. {$endif}
  20. movw %ax,default8087cw
  21. fnclex
  22. fldcw default8087cw
  23. end;
  24. function Get8087CW:word;assembler;
  25. asm
  26. pushl $0
  27. fnstcw (%esp)
  28. popl %eax
  29. end;
  30. {****************************************************************************
  31. EXTENDED data type routines
  32. ****************************************************************************}
  33. {$define FPC_SYSTEM_HAS_PI}
  34. function pi : extended;[internproc:in_pi];
  35. {$define FPC_SYSTEM_HAS_ABS}
  36. function abs(d : extended) : extended;[internproc:in_abs_extended];
  37. {$define FPC_SYSTEM_HAS_SQR}
  38. function sqr(d : extended) : extended;[internproc:in_sqr_extended];
  39. {$define FPC_SYSTEM_HAS_SQRT}
  40. function sqrt(d : extended) : extended;[internproc:in_sqrt_extended];
  41. {$define FPC_SYSTEM_HAS_ARCTAN}
  42. function arctan(d : extended) : extended;[internproc:in_arctan_extended];
  43. {$define FPC_SYSTEM_HAS_LN}
  44. function ln(d : extended) : extended;[internproc:in_ln_extended];
  45. {$define FPC_SYSTEM_HAS_SIN}
  46. function sin(d : extended) : extended;[internproc:in_sin_extended];
  47. {$define FPC_SYSTEM_HAS_COS}
  48. function cos(d : extended) : extended;[internproc:in_cos_extended];
  49. {$define FPC_SYSTEM_HAS_EXP}
  50. function exp(d : extended) : extended;assembler;[internconst:in_const_exp];
  51. asm
  52. // comes from DJ GPP
  53. fldt d
  54. fldl2e
  55. fmulp %st,%st(1)
  56. fstcw .LCW1
  57. fstcw .LCW2
  58. andw $0xf3ff,.LCW2
  59. orw $0x0400,.LCW2
  60. fldcw .LCW2
  61. fld %st(0)
  62. frndint
  63. fldcw .LCW1
  64. fxch %st(1)
  65. fsub %st(1),%st
  66. f2xm1
  67. fld1
  68. faddp %st,%st(1)
  69. fscale
  70. fstp %st(1)
  71. jmp .LCW3
  72. // store some help data in the data segment
  73. .data
  74. .LCW1:
  75. .word 0
  76. .LCW2:
  77. .word 0
  78. .text
  79. .LCW3:
  80. end;
  81. {$define FPC_SYSTEM_HAS_FRAC}
  82. function frac(d : extended) : extended;assembler;[internconst:in_const_frac];
  83. asm
  84. subl $16,%esp
  85. fnstcw -4(%ebp)
  86. fwait
  87. movw -4(%ebp),%cx
  88. orw $0x0c3f,%cx
  89. movw %cx,-8(%ebp)
  90. fldcw -8(%ebp)
  91. fwait
  92. fldt d
  93. frndint
  94. fldt d
  95. fsub %st(1),%st
  96. fstp %st(1)
  97. fclex
  98. fldcw -4(%ebp)
  99. end;
  100. {$define FPC_SYSTEM_HAS_INT}
  101. function int(d : extended) : extended;assembler;[internconst:in_const_int];
  102. asm
  103. subl $16,%esp
  104. fnstcw -4(%ebp)
  105. fwait
  106. movw -4(%ebp),%cx
  107. orw $0x0c3f,%cx
  108. movw %cx,-8(%ebp)
  109. fldcw -8(%ebp)
  110. fwait
  111. fldt d
  112. frndint
  113. fclex
  114. fldcw -4(%ebp)
  115. end;
  116. {$define FPC_SYSTEM_HAS_TRUNC}
  117. function trunc(d : extended) : int64;assembler;[internconst:in_const_trunc];
  118. var
  119. oldcw,
  120. newcw : word;
  121. res : int64;
  122. asm
  123. fnstcw oldcw
  124. fwait
  125. movw oldcw,%cx
  126. orw $0x0c3f,%cx
  127. movw %cx,newcw
  128. fldcw newcw
  129. fwait
  130. fldt d
  131. fistpq res
  132. movl res,%eax
  133. movl res+4,%edx
  134. fldcw oldcw
  135. end;
  136. {$define FPC_SYSTEM_HAS_ROUND}
  137. {$ifdef hascompilerproc}
  138. function round(d : extended) : int64;[internconst:in_const_round, external name 'FPC_ROUND'];
  139. function fpc_round(d : extended) : int64;assembler;[public, alias:'FPC_ROUND'];{$ifdef hascompilerproc}compilerproc;{$endif hascompilerproc}
  140. {$else}
  141. function round(d : extended) : int64;assembler;[internconst:in_const_round];
  142. {$endif hascompilerproc}
  143. var
  144. oldcw,
  145. newcw : word;
  146. res : int64;
  147. asm
  148. fnstcw oldcw
  149. fwait
  150. movw $0x1372,newcw
  151. fldcw newcw
  152. fwait
  153. fldt d
  154. fistpq res
  155. movl res,%eax
  156. movl res+4,%edx
  157. fldcw oldcw
  158. end;
  159. {$define FPC_SYSTEM_HAS_POWER}
  160. function power(bas,expo : extended) : extended;
  161. begin
  162. if bas=0 then
  163. begin
  164. if expo<>0 then
  165. power:=0.0
  166. else
  167. HandleError(207);
  168. end
  169. else if expo=0 then
  170. power:=1
  171. else
  172. { bas < 0 is not allowed when doing roots }
  173. if (bas<0) and (frac(expo) <> 0) then
  174. handleerror(207)
  175. else
  176. begin
  177. power:=exp(ln(abs(bas))*expo);
  178. if (bas < 0) and
  179. odd(trunc(expo)) then
  180. begin
  181. power := -power;
  182. end;
  183. end;
  184. end;
  185. {
  186. $Log$
  187. Revision 1.18 2003-11-29 16:40:12 jonas
  188. * fix power() for negative base
  189. Revision 1.17 2003/11/24 21:57:43 michael
  190. + Patch from Johannes Berg for bug 2759
  191. Revision 1.16 2003/11/11 21:08:17 peter
  192. * REGCALL define added
  193. Revision 1.15 2003/09/08 18:21:37 peter
  194. * save edi,esi,ebx
  195. Revision 1.14 2003/04/23 21:28:21 peter
  196. * fpc_round added, needed for int64 currency
  197. Revision 1.13 2003/02/05 19:53:17 carl
  198. * round bugfix with -Or switch
  199. Revision 1.12 2003/01/15 00:45:17 peter
  200. * use generic int64 power
  201. Revision 1.11 2003/01/15 00:40:18 peter
  202. * power returns int64
  203. Revision 1.10 2003/01/03 20:34:02 peter
  204. * i386 fpu controlword functions added
  205. Revision 1.9 2002/10/06 21:26:17 peter
  206. * round returns int64
  207. Revision 1.8 2002/09/07 16:01:19 peter
  208. * old logs removed and tabs fixed
  209. }