mathu.inc 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  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. {//$define FPC_MATH_HAS_TAN}
  49. {function tan(x : float) : float;assembler;
  50. asm
  51. fldt X
  52. fptan
  53. fstp %st
  54. fwait
  55. end;}
  56. {//$define FPC_MATH_HAS_COTAN}
  57. {function cotan(x : float) : float;assembler;
  58. asm
  59. fldt X
  60. fptan
  61. fdivp %st,%st(1)
  62. fwait
  63. end;}
  64. {$define FPC_MATH_HAS_LOG2}
  65. function log2(x : float) : float;assembler;
  66. asm
  67. fld1
  68. fld tbyte [x]
  69. fyl2x
  70. fwait
  71. end;
  72. {//$define FPC_MATH_HAS_DIVMOD}
  73. {procedure DivMod(Dividend: Integer; Divisor: Word; var Result, Remainder: Word);assembler;
  74. asm
  75. pushl %edi
  76. movzwl %dx,%edi
  77. cltd
  78. idiv %edi
  79. movw %ax,(%ecx)
  80. movl Remainder,%ecx
  81. movw %dx,(%ecx)
  82. popl %edi
  83. end;
  84. procedure DivMod(Dividend: Integer; Divisor: Word; var Result, Remainder: SmallInt);assembler;
  85. asm
  86. pushl %edi
  87. movzwl %dx,%edi
  88. cltd
  89. idiv %edi
  90. movw %ax,(%ecx)
  91. movl Remainder,%ecx
  92. movw %dx,(%ecx)
  93. popl %edi
  94. end;
  95. procedure DivMod(Dividend: DWord; Divisor: DWord; var Result, Remainder: DWord);assembler;
  96. asm
  97. pushl %edi
  98. movl %edx,%edi
  99. xorl %edx,%edx
  100. div %edi
  101. movl %eax,(%ecx)
  102. movl Remainder,%ecx
  103. movl %edx,(%ecx)
  104. popl %edi
  105. end;
  106. procedure DivMod(Dividend: Integer; Divisor: Integer; var Result, Remainder: Integer);assembler;
  107. asm
  108. pushl %edi
  109. movl %edx,%edi
  110. cltd
  111. idiv %edi
  112. movl %eax,(%ecx)
  113. movl Remainder,%ecx
  114. movl %edx,(%ecx)
  115. popl %edi
  116. end;}
  117. function GetRoundMode: TFPURoundingMode;
  118. begin
  119. Result := TFPURoundingMode((Get8087CW shr 10) and 3);
  120. end;
  121. function SetRoundMode(const RoundMode: TFPURoundingMode): TFPURoundingMode;
  122. var
  123. CtlWord: Word;
  124. begin
  125. CtlWord := Get8087CW;
  126. Set8087CW((CtlWord and $F3FF) or (Ord(RoundMode) shl 10));
  127. { if has_sse_support then
  128. SetSSECSR((GetSSECSR and $ffff9fff) or (dword(RoundMode) shl 13));}
  129. Result := TFPURoundingMode((CtlWord shr 10) and 3);
  130. end;
  131. function GetPrecisionMode: TFPUPrecisionMode;
  132. begin
  133. Result := TFPUPrecisionMode((Get8087CW shr 8) and 3);
  134. end;
  135. function SetPrecisionMode(const Precision: TFPUPrecisionMode): TFPUPrecisionMode;
  136. var
  137. CtlWord: Word;
  138. begin
  139. CtlWord := Get8087CW;
  140. Set8087CW((CtlWord and $FCFF) or (Ord(Precision) shl 8));
  141. Result := TFPUPrecisionMode((CtlWord shr 8) and 3);
  142. end;
  143. function GetExceptionMask: TFPUExceptionMask;
  144. begin
  145. Result := TFPUExceptionMask(Byte(Get8087CW and $3F));
  146. end;
  147. function SetExceptionMask(const Mask: TFPUExceptionMask): TFPUExceptionMask;
  148. var
  149. CtlWord: Word;
  150. begin
  151. CtlWord := Get8087CW;
  152. Set8087CW( (CtlWord and $FFC0) or Byte(Mask) );
  153. { if has_sse_support then
  154. SetSSECSR((GetSSECSR and $ffffe07f) or (dword(Mask) shl 7));}
  155. Result := TFPUExceptionMask(Byte(CtlWord and $3F));
  156. end;
  157. procedure ClearExceptions(RaisePending: Boolean);assembler;
  158. asm
  159. cmp byte RaisePending, 0
  160. je @Lclear
  161. fwait
  162. @Lclear:
  163. fnclex
  164. end;