mathh.inc 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 1999-2000 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. { i386 FPU Controlword }
  12. {$if defined(cpui8086) or defined(cpui386) or defined(cpux86_64)}
  13. {$define FPC_SYSTEM_FPU_CUSTOM_CONTROL_WORD}
  14. const
  15. Default8087CW : word = $1332;
  16. procedure Set8087CW(cw:word);
  17. function Get8087CW:word;
  18. {$endif}
  19. {$if defined (cpui386) or defined(cpux86_64)}
  20. {$define FPC_SYSTEM_FPU_CUSTOM_CONTROL_WORD}
  21. const
  22. DefaultMXCSR: dword = $1900;
  23. procedure SetMXCSR(w: dword);
  24. function GetMXCSR: dword;
  25. procedure SetSSECSR(w : dword); deprecated 'Renamed to SetMXCSR';
  26. function GetSSECSR : dword; deprecated 'Renamed to GetMXCSR';
  27. {$endif}
  28. {$if defined(cpum68k)}
  29. {$define FPC_SYSTEM_FPU_CUSTOM_CONTROL_WORD}
  30. {$if defined(fpu68881) or defined(fpucoldfire)}
  31. const
  32. {$ifdef FPC_68K_SYSTEM_HAS_FPU_EXCEPTIONS}
  33. Default68KFPCR: DWord = $3400; { Enable OVFL, OPERR and DZ, round to nearest, default precision }
  34. {$else}
  35. Default68KFPCR: DWord = 0;
  36. {$endif}
  37. procedure SetFPCR(x: DWord);
  38. procedure SetFPSR(x: DWord);
  39. function GetFPCR: DWord;
  40. function GetFPSR: DWord;
  41. {$else}
  42. {$define FPC_SYSTEM_FPUCW_IMMUTABLE}
  43. {$endif}
  44. {$endif}
  45. {$if (defined(FPC_SYSTEM_FPUCW_IMMUTABLE) or defined(FPU_NONE)) and not declared(TNativeFPUControlWord)}
  46. type
  47. TNativeFPUControlWord = record
  48. end;
  49. {$endif}
  50. function GetNativeFPUControlWord: TNativeFPUControlWord; {$if (defined(FPC_SYSTEM_FPUCW_IMMUTABLE) or defined(FPUNONE)) and defined(SYSTEMINLINE)}inline;{$endif}
  51. procedure SetNativeFPUControlWord(const cw: TNativeFPUControlWord); {$if (defined(FPC_SYSTEM_FPUCW_IMMUTABLE) or defined(FPUNONE)) and defined(SYSTEMINLINE)}inline;{$endif}
  52. type
  53. TFPURoundingMode = (rmNearest, rmDown, rmUp, rmTruncate);
  54. TFPUPrecisionMode = (pmSingle, pmReserved, pmDouble, pmExtended);
  55. TFPUException = (exInvalidOp, exDenormalized, exZeroDivide,
  56. exOverflow, exUnderflow, exPrecision);
  57. TFPUExceptionMask = set of TFPUException;
  58. const
  59. {*
  60. -------------------------------------------------------------------------------
  61. Software IEC/IEEE floating-point exception flags.
  62. -------------------------------------------------------------------------------
  63. *}
  64. float_flag_invalid = exInvalidOp;
  65. float_flag_denormal = exDenormalized;
  66. float_flag_divbyzero = exZeroDivide;
  67. float_flag_overflow = exOverflow;
  68. float_flag_underflow = exUnderflow;
  69. float_flag_inexact = exPrecision;
  70. {*
  71. -------------------------------------------------------------------------------
  72. Software IEC/IEEE floating-point rounding mode.
  73. -------------------------------------------------------------------------------
  74. *}
  75. float_round_nearest_even = rmNearest;
  76. float_round_down = rmDown;
  77. float_round_up = rmUp;
  78. float_round_to_zero = rmTruncate;
  79. {$ifdef FPC_HAS_FEATURE_THREADING}
  80. ThreadVar
  81. {$else FPC_HAS_FEATURE_THREADING}
  82. Var
  83. {$endif FPC_HAS_FEATURE_THREADING}
  84. softfloat_exception_flags : TFPUExceptionMask;
  85. softfloat_exception_mask : TFPUExceptionMask;
  86. softfloat_rounding_mode : TFPURoundingMode;
  87. procedure float_raise(i: TFPUException);
  88. procedure float_raise(i: TFPUExceptionMask);
  89. {$ifdef cpui386}
  90. {$define INTERNMATH}
  91. {$endif}
  92. {$ifndef INTERNMATH}
  93. {$ifdef FPC_USE_LIBC}
  94. {$ifdef SYSTEMINLINE}
  95. {$define MATHINLINE}
  96. {$endif}
  97. {$endif}
  98. {$endif}
  99. function Pi : ValReal;[internproc:fpc_in_pi_real];
  100. function Abs(d : ValReal) : ValReal;[internproc:fpc_in_abs_real];
  101. function Sqr(d : ValReal) : ValReal;[internproc:fpc_in_sqr_real];
  102. function Sqrt(d : ValReal) : ValReal;[internproc:fpc_in_sqrt_real];
  103. function ArcTan(d : ValReal) : ValReal;[internproc:fpc_in_arctan_real];
  104. function Ln(d : ValReal) : ValReal;[internproc:fpc_in_ln_real];
  105. function Sin(d : ValReal) : ValReal;[internproc:fpc_in_sin_real];
  106. function Cos(d : ValReal) : ValReal;[internproc:fpc_in_cos_real];
  107. function Exp(d : ValReal) : ValReal;[internproc:fpc_in_exp_real];
  108. function Round(d : ValReal) : int64;[internproc:fpc_in_round_real];
  109. function Frac(d : ValReal) : ValReal;[internproc:fpc_in_frac_real];
  110. function Int(d : ValReal) : ValReal;[internproc:fpc_in_int_real];
  111. function Trunc(d : ValReal) : int64;[internproc:fpc_in_trunc_real];
  112. {$ifdef SUPPORT_EXTENDED}
  113. function FPower10(val: Extended; Power: Longint): Extended;
  114. {$endif SUPPORT_EXTENDED}
  115. type
  116. Real48 = array[0..5] of byte;
  117. {$ifdef SUPPORT_DOUBLE}
  118. function Real2Double(r : real48) : double;
  119. operator := (b:real48) d:double; {$ifdef SYSTEMINLINE}inline;{$endif}
  120. {$endif}
  121. {$ifdef SUPPORT_EXTENDED}
  122. operator := (b:real48) e:extended; {$ifdef SYSTEMINLINE}inline;{$endif}
  123. {$endif SUPPORT_EXTENDED}
  124. type
  125. TFloatSpecial = (fsZero,fsNZero,fsDenormal,fsNDenormal,fsPositive,fsNegative,
  126. fsInf,fsNInf,fsNaN,fsInvalidOp);
  127. {$if defined(SUPPORT_EXTENDED) or defined(FPC_SOFT_FPUX80)}
  128. TExtended80Rec = packed record
  129. private
  130. const
  131. Bias = $3FFF;
  132. function GetExp : QWord;
  133. procedure SetExp(e : QWord);
  134. function GetSign : Boolean;
  135. procedure SetSign(s : Boolean);
  136. public
  137. function Mantissa(IncludeHiddenBit: Boolean = False) : QWord; // unused parameter inserted to have consistent function signature
  138. function Fraction : Extended;
  139. function Exponent : Longint;
  140. property Sign : Boolean read GetSign write SetSign;
  141. property Exp : QWord read GetExp write SetExp;
  142. function SpecialType : TFloatSpecial;
  143. procedure BuildUp(const _Sign : Boolean; const _Mantissa : QWord; const _Exponent : Longint);
  144. case byte of
  145. 0: (Bytes : array[0..9] of Byte);
  146. 1: (Words : array[0..4] of Word);
  147. {$ifdef ENDIAN_LITTLE}
  148. 2: (Frac : QWord; _Exp: Word);
  149. {$else ENDIAN_LITTLE}
  150. 2: (_Exp: Word; Frac : QWord);
  151. {$endif ENDIAN_LITTLE}
  152. {$ifdef SUPPORT_EXTENDED}
  153. 3: (Value: Extended);
  154. {$else}
  155. 3: (Value: array[0..9] of Byte);
  156. {$endif}
  157. end;
  158. {$endif SUPPORT_EXTENDED or FPC_SOFT_FPUX80}
  159. {$ifdef SUPPORT_DOUBLE}
  160. TDoubleRec = packed record
  161. private
  162. const
  163. Bias = $3FF;
  164. function GetExp : QWord;
  165. procedure SetExp(e : QWord);
  166. function GetSign : Boolean;
  167. procedure SetSign(s : Boolean);
  168. function GetFrac : QWord;
  169. procedure SetFrac(e : QWord);
  170. public
  171. function Mantissa(IncludeHiddenBit: Boolean = False) : QWord;
  172. function Fraction : ValReal;
  173. function Exponent : Longint;
  174. property Sign : Boolean read GetSign write SetSign;
  175. property Exp : QWord read GetExp write SetExp;
  176. property Frac : QWord read Getfrac write SetFrac;
  177. function SpecialType : TFloatSpecial;
  178. procedure BuildUp(const _Sign : Boolean; const _Mantissa : QWord; const _Exponent : Longint);
  179. case byte of
  180. 0: (Bytes : array[0..7] of Byte);
  181. 1: (Words : array[0..3] of Word);
  182. 2: (Data : QWord);
  183. 3: (Value: Double);
  184. end;
  185. {$endif SUPPORT_DOUBLE}
  186. {$ifdef SUPPORT_SINGLE}
  187. TSingleRec = packed record
  188. private
  189. const
  190. Bias = $7F;
  191. function GetExp : QWord;
  192. procedure SetExp(e : QWord);
  193. function GetSign : Boolean;
  194. procedure SetSign(s : Boolean);
  195. function GetFrac : QWord;
  196. procedure SetFrac(e : QWord);
  197. public
  198. function Mantissa(IncludeHiddenBit: Boolean = False) : QWord;
  199. function Fraction : ValReal;
  200. function Exponent : Longint;
  201. property Sign : Boolean read GetSign write SetSign;
  202. property Exp : QWord read GetExp write SetExp;
  203. property Frac : QWord read Getfrac write SetFrac;
  204. function SpecialType : TFloatSpecial;
  205. procedure BuildUp(const _Sign : Boolean; const _Mantissa : QWord; const _Exponent : Longint);
  206. case byte of
  207. 0: (Bytes : array[0..3] of Byte);
  208. 1: (Words : array[0..1] of Word);
  209. 2: (Data : DWord);
  210. 3: (Value: Single);
  211. end;
  212. {$endif SUPPORT_SINGLE}
  213. function FMASingle(s1,s2,s3 : single) : single;[internproc:fpc_in_fma_single];
  214. {$ifdef SUPPORT_DOUBLE}
  215. function FMADouble(d1,d2,d3 : double) : double;[internproc:fpc_in_fma_double];
  216. {$endif SUPPORT_DOUBLE}
  217. {$ifdef SUPPORT_EXTENDED}
  218. function FMAExtended(e1,e2,e3 : extended) : extended;[internproc:fpc_in_fma_extended];
  219. {$endif SUPPORT_EXTENDED}
  220. {$ifdef SUPPORT_FLOAT128}
  221. function FMAFloat128(f1,f2,f3 : float128) : float128;[internproc:fpc_in_fma_float128];
  222. {$endif SUPPORT_FLOAT128}