math.inc 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  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. movw cw,%ax
  18. movw %ax,default8087cw
  19. fnclex
  20. fldcw default8087cw
  21. end;
  22. function Get8087CW:word;assembler;
  23. asm
  24. pushq $0
  25. fnstcw (%rsp)
  26. popq %rax
  27. end;
  28. {****************************************************************************
  29. EXTENDED data type routines
  30. ****************************************************************************}
  31. {$define FPC_SYSTEM_HAS_PI}
  32. function pi : extended;[internproc:in_pi];
  33. {$define FPC_SYSTEM_HAS_ABS}
  34. function abs(d : extended) : extended;[internproc:in_abs_extended];
  35. {$define FPC_SYSTEM_HAS_SQR}
  36. function sqr(d : extended) : extended;[internproc:in_sqr_extended];
  37. {$define FPC_SYSTEM_HAS_SQRT}
  38. function sqrt(d : extended) : extended;[internproc:in_sqrt_extended];
  39. {$define FPC_SYSTEM_HAS_ARCTAN}
  40. function arctan(d : extended) : extended;[internproc:in_arctan_extended];
  41. {$define FPC_SYSTEM_HAS_LN}
  42. function ln(d : extended) : extended;[internproc:in_ln_extended];
  43. {$define FPC_SYSTEM_HAS_SIN}
  44. function sin(d : extended) : extended;[internproc:in_sin_extended];
  45. {$define FPC_SYSTEM_HAS_COS}
  46. function cos(d : extended) : extended;[internproc:in_cos_extended];
  47. {$define FPC_SYSTEM_HAS_EXP}
  48. function exp(d : extended) : extended;assembler;[internconst:in_const_exp];
  49. asm
  50. // comes from DJ GPP
  51. fldt d
  52. fldl2e
  53. fmulp %st,%st(1)
  54. fstcw .LCW1
  55. fstcw .LCW2
  56. andw $0xf3ff,.LCW2
  57. orw $0x0400,.LCW2
  58. fldcw .LCW2
  59. fld %st(0)
  60. frndint
  61. fldcw .LCW1
  62. fxch %st(1)
  63. fsub %st(1),%st
  64. f2xm1
  65. fld1
  66. faddp %st,%st(1)
  67. fscale
  68. fstp %st(1)
  69. jmp .LCW3
  70. // store some help data in the data segment
  71. .data
  72. .LCW1:
  73. .word 0
  74. .LCW2:
  75. .word 0
  76. .text
  77. .LCW3:
  78. end;
  79. {$define FPC_SYSTEM_HAS_FRAC}
  80. function frac(d : extended) : extended;assembler;[internconst:in_const_frac];
  81. asm
  82. subq $16,%rsp
  83. fnstcw -4(%rbp)
  84. fwait
  85. movw -4(%rbp),%cx
  86. orw $0x0c3f,%cx
  87. movw %cx,-8(%rbp)
  88. fldcw -8(%rbp)
  89. fwait
  90. fldt d
  91. frndint
  92. fldt d
  93. fsub %st(1),%st
  94. fstp %st(1)
  95. fclex
  96. fldcw -4(%rbp)
  97. end ['ECX'];
  98. {$define FPC_SYSTEM_HAS_INT}
  99. function int(d : extended) : extended;assembler;[internconst:in_const_int];
  100. asm
  101. subq $16,%rsp
  102. fnstcw -4(%rbp)
  103. fwait
  104. movw -4(%rbp),%cx
  105. orw $0x0c3f,%cx
  106. movw %cx,-8(%rbp)
  107. fldcw -8(%rbp)
  108. fwait
  109. fldt d
  110. frndint
  111. fclex
  112. fldcw -4(%rbp)
  113. end ['ECX'];
  114. {$define FPC_SYSTEM_HAS_TRUNC}
  115. function trunc(d : extended) : int64;assembler;[internconst:in_const_trunc];
  116. var
  117. oldcw,
  118. newcw : word;
  119. res : int64;
  120. asm
  121. fnstcw oldcw
  122. fwait
  123. movw oldcw,%cx
  124. orw $0x0c3f,%cx
  125. movw %cx,newcw
  126. fldcw newcw
  127. fwait
  128. fldt d
  129. fistpq res
  130. movq res,%rax
  131. fldcw oldcw
  132. end ['RAX','RCX'];
  133. {$define FPC_SYSTEM_HAS_ROUND}
  134. {$ifdef hascompilerproc}
  135. function round(d : extended) : int64;[internconst:in_const_round, external name 'FPC_ROUND'];
  136. function fpc_round(d : extended) : int64;assembler;[public, alias:'FPC_ROUND'];{$ifdef hascompilerproc}compilerproc;{$endif hascompilerproc}
  137. {$else}
  138. function round(d : extended) : int64;assembler;[internconst:in_const_round];
  139. {$endif hascompilerproc}
  140. var
  141. oldcw,
  142. newcw : word;
  143. res : int64;
  144. asm
  145. fnstcw oldcw
  146. fwait
  147. movw $0x1372,newcw
  148. fldcw newcw
  149. fwait
  150. fldt d
  151. fistpq res
  152. movq res,%rax
  153. fldcw oldcw
  154. end ['RAX'];
  155. {$define FPC_SYSTEM_HAS_POWER}
  156. function power(bas,expo : extended) : extended;
  157. begin
  158. if bas=0 then
  159. begin
  160. if expo<>0 then
  161. power:=0.0
  162. else
  163. HandleError(207);
  164. end
  165. else if expo=0 then
  166. power:=1
  167. else
  168. { bas < 0 is not allowed }
  169. if bas<0 then
  170. handleerror(207)
  171. else
  172. power:=exp(ln(bas)*expo);
  173. end;
  174. {
  175. $Log$
  176. Revision 1.4 2004-04-24 18:31:25 florian
  177. * trunc and round for x86-64 fixed
  178. Revision 1.3 2004/02/06 15:58:21 florian
  179. * fixed x86-64 assembler problems
  180. Revision 1.2 2004/02/05 01:16:12 florian
  181. + completed x86-64/linux system unit
  182. Revision 1.1 2003/04/30 22:11:06 florian
  183. + for a lot of x86-64 dependend files mostly dummies added
  184. }