mathu.inc 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 2014 by Jonas Maebe
  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. {$ifdef FPUFD}
  12. function GetRoundMode: TFPURoundingMode;
  13. const
  14. bits2rm: array[0..3] of TFPURoundingMode = (rmNearest,rmTruncate,rmDown,rmUp);
  15. begin
  16. result:=TFPURoundingMode(bits2rm[GetNativeFPUControlWord.rndmode])
  17. end;
  18. function SetRoundMode(const RoundMode: TFPURoundingMode): TFPURoundingMode;
  19. const
  20. rm2bits : array[TFPURoundingMode] of byte = (0,2,3,1);
  21. var
  22. cw: TNativeFPUControlWord;
  23. begin
  24. softfloat_rounding_mode:=RoundMode;
  25. SetRoundMode:=GetRoundMode;
  26. cw:=GetNativeFPUControlWord;
  27. cw.rndmode:=rm2bits[RoundMode];
  28. SetNativeFPUControlWord(cw);
  29. end;
  30. function GetPrecisionMode: TFPUPrecisionMode;
  31. begin
  32. result:=pmDouble;
  33. end;
  34. function SetPrecisionMode(const Precision: TFPUPrecisionMode): TFPUPrecisionMode;
  35. begin
  36. result:=pmDouble;
  37. end;
  38. const
  39. fpu_nx = 1 shl 0;
  40. fpu_uf = 1 shl 1;
  41. fpu_of = 1 shl 2;
  42. fpu_dz = 1 shl 3;
  43. fpu_nv = 1 shl 4;
  44. function GetExceptionMask: TFPUExceptionMask;
  45. begin
  46. Result:=softfloat_exception_mask;
  47. end;
  48. function SetExceptionMask(const Mask: TFPUExceptionMask): TFPUExceptionMask;
  49. begin
  50. Result:=softfloat_exception_mask;
  51. { clear "exception happened" flags }
  52. ClearExceptions(false);
  53. softfloat_exception_mask:=Mask;
  54. end;
  55. procedure RaisePendingExceptions;
  56. var
  57. fflags : dword;
  58. f: TFPUException;
  59. begin
  60. fflags:=GetNativeFPUControlWord.cw;
  61. if (fflags and fpu_dz) <> 0 then
  62. float_raise(exZeroDivide);
  63. if (fflags and fpu_of) <> 0 then
  64. float_raise(exOverflow);
  65. if (fflags and fpu_uf) <> 0 then
  66. float_raise(exUnderflow);
  67. if (fflags and fpu_nv) <> 0 then
  68. float_raise(exInvalidOp);
  69. if (fflags and fpu_nx) <> 0 then
  70. float_raise(exPrecision);
  71. { now the soft float exceptions }
  72. for f in softfloat_exception_flags do
  73. float_raise(f);
  74. end;
  75. procedure ClearExceptions(RaisePending: Boolean);
  76. var
  77. cw: TNativeFPUControlWord;
  78. begin
  79. if raisepending then
  80. RaisePendingExceptions;
  81. softfloat_exception_flags:=[];
  82. cw:=GetNativeFPUControlWord;
  83. cw.cw:=0;
  84. SetNativeFPUControlWord(cw);
  85. end;
  86. {$else}
  87. function GetRoundMode: TFPURoundingMode;
  88. begin
  89. GetRoundMode:=softfloat_rounding_mode;
  90. end;
  91. function SetRoundMode(const RoundMode: TFPURoundingMode): TFPURoundingMode;
  92. begin
  93. result:=softfloat_rounding_mode;
  94. softfloat_rounding_mode:=RoundMode;
  95. end;
  96. function GetPrecisionMode: TFPUPrecisionMode;
  97. begin
  98. result := pmDouble;
  99. end;
  100. function SetPrecisionMode(const Precision: TFPUPrecisionMode): TFPUPrecisionMode;
  101. begin
  102. { does not apply }
  103. result := pmDouble;
  104. end;
  105. function GetExceptionMask: TFPUExceptionMask;
  106. begin
  107. Result:=softfloat_exception_mask;
  108. end;
  109. function SetExceptionMask(const Mask: TFPUExceptionMask): TFPUExceptionMask;
  110. begin
  111. Result:=softfloat_exception_mask;
  112. softfloat_exception_mask:=Mask;
  113. end;
  114. procedure ClearExceptions(RaisePending: Boolean =true);
  115. begin
  116. softfloat_exception_flags:=[];
  117. end;
  118. {$endif}