mathu.inc 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 1999-2003 by Florian Klaempfl
  4. member of the Free Pascal development team
  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. {NOTE: the fpatan instruction on the 8087 and 80287 has the following restrictions:
  12. 0 <= ST(1) < ST(0) < +inf
  13. so the following code requires a 387+ and is therefore disabled, so that we use the
  14. generic implementation, until an asm optimized version, compatible with 8087/80287 is written }
  15. {//$define FPC_MATH_HAS_ARCTAN2}
  16. {function arctan2(y,x : float) : float;assembler;
  17. asm
  18. fld tbyte [y]
  19. fld tbyte [x]
  20. fpatan
  21. fwait
  22. end;}
  23. {//$define FPC_MATH_HAS_SINCOS}
  24. {procedure sincos(theta : extended;out sinus,cosinus : extended);assembler;
  25. asm
  26. fldt theta
  27. fsincos
  28. fstpt (%edx)
  29. fstpt (%eax)
  30. fwait
  31. end;
  32. procedure sincos(theta : double;out sinus,cosinus : double);assembler;
  33. asm
  34. fldl theta
  35. fsincos
  36. fstpl (%edx)
  37. fstpl (%eax)
  38. fwait
  39. end;
  40. procedure sincos(theta : single;out sinus,cosinus : single);assembler;
  41. asm
  42. flds theta
  43. fsincos
  44. fstps (%edx)
  45. fstps (%eax)
  46. fwait
  47. end;}
  48. {NOTE: the fpatan instruction on the 8087 and 80287 has the following restrictions:
  49. 0 <= ST(0) <= PI/4
  50. so the following code requires a 387+ and is therefore disabled, so that we use the
  51. generic implementation, until an asm optimized version, compatible with 8087/80287 is written }
  52. {//$define FPC_MATH_HAS_TAN}
  53. {function tan(x : float) : float;assembler;
  54. asm
  55. fldt X
  56. fptan
  57. fstp %st
  58. fwait
  59. end;}
  60. {//$define FPC_MATH_HAS_COTAN}
  61. {function cotan(x : float) : float;assembler;
  62. asm
  63. fldt X
  64. fptan
  65. fdivp %st,%st(1)
  66. fwait
  67. end;}
  68. {$define FPC_MATH_HAS_LOG2}
  69. function log2(x : float) : float;assembler;
  70. asm
  71. fld1
  72. fld tbyte [x]
  73. fyl2x
  74. fwait
  75. end;
  76. {//$define FPC_MATH_HAS_DIVMOD}
  77. {procedure DivMod(Dividend: Integer; Divisor: Word; var Result, Remainder: Word);assembler;
  78. asm
  79. pushl %edi
  80. movzwl %dx,%edi
  81. cltd
  82. idiv %edi
  83. movw %ax,(%ecx)
  84. movl Remainder,%ecx
  85. movw %dx,(%ecx)
  86. popl %edi
  87. end;
  88. procedure DivMod(Dividend: Integer; Divisor: Word; var Result, Remainder: SmallInt);assembler;
  89. asm
  90. pushl %edi
  91. movzwl %dx,%edi
  92. cltd
  93. idiv %edi
  94. movw %ax,(%ecx)
  95. movl Remainder,%ecx
  96. movw %dx,(%ecx)
  97. popl %edi
  98. end;
  99. procedure DivMod(Dividend: DWord; Divisor: DWord; var Result, Remainder: DWord);assembler;
  100. asm
  101. pushl %edi
  102. movl %edx,%edi
  103. xorl %edx,%edx
  104. div %edi
  105. movl %eax,(%ecx)
  106. movl Remainder,%ecx
  107. movl %edx,(%ecx)
  108. popl %edi
  109. end;
  110. procedure DivMod(Dividend: Integer; Divisor: Integer; var Result, Remainder: Integer);assembler;
  111. asm
  112. pushl %edi
  113. movl %edx,%edi
  114. cltd
  115. idiv %edi
  116. movl %eax,(%ecx)
  117. movl Remainder,%ecx
  118. movl %edx,(%ecx)
  119. popl %edi
  120. end;}
  121. function GetRoundMode: TFPURoundingMode;
  122. begin
  123. Result := TFPURoundingMode((Get8087CW shr 10) and 3);
  124. end;
  125. function SetRoundMode(const RoundMode: TFPURoundingMode): TFPURoundingMode;
  126. var
  127. CtlWord: Word;
  128. begin
  129. CtlWord := Get8087CW;
  130. Set8087CW((CtlWord and $F3FF) or (Ord(RoundMode) shl 10));
  131. { if has_sse_support then
  132. SetSSECSR((GetSSECSR and $ffff9fff) or (dword(RoundMode) shl 13));}
  133. Result := TFPURoundingMode((CtlWord shr 10) and 3);
  134. end;
  135. function GetPrecisionMode: TFPUPrecisionMode;
  136. begin
  137. Result := TFPUPrecisionMode((Get8087CW shr 8) and 3);
  138. end;
  139. function SetPrecisionMode(const Precision: TFPUPrecisionMode): TFPUPrecisionMode;
  140. var
  141. CtlWord: Word;
  142. begin
  143. CtlWord := Get8087CW;
  144. Set8087CW((CtlWord and $FCFF) or (Ord(Precision) shl 8));
  145. Result := TFPUPrecisionMode((CtlWord shr 8) and 3);
  146. end;
  147. function GetExceptionMask: TFPUExceptionMask;
  148. begin
  149. Result := TFPUExceptionMask(Byte(Get8087CW and $3F));
  150. end;
  151. function SetExceptionMask(const Mask: TFPUExceptionMask): TFPUExceptionMask;
  152. var
  153. CtlWord: Word;
  154. begin
  155. CtlWord := Get8087CW;
  156. Set8087CW( (CtlWord and $FFC0) or Byte(Mask) );
  157. { if has_sse_support then
  158. SetSSECSR((GetSSECSR and $ffffe07f) or (dword(Mask) shl 7));}
  159. Result := TFPUExceptionMask(Byte(CtlWord and $3F));
  160. end;
  161. procedure ClearExceptions(RaisePending: Boolean);assembler;
  162. asm
  163. cmp byte RaisePending, 0
  164. je @Lclear
  165. fwait
  166. @Lclear:
  167. fnclex
  168. end;