mathu.inc 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  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. function getrm: dword; nostackframe; assembler;
  12. asm
  13. frrm a0
  14. end;
  15. procedure setrm(val: dword); nostackframe; assembler;
  16. asm
  17. fsrm a0
  18. end;
  19. function getfflags: dword; nostackframe; assembler;
  20. asm
  21. frflags a0
  22. end;
  23. procedure setfflags(flags : dword); nostackframe; assembler;
  24. asm
  25. fsflags a0
  26. end;
  27. function GetRoundMode: TFPURoundingMode;
  28. const
  29. bits2rm: array[0..3] of TFPURoundingMode = (rmNearest,rmTruncate,rmDown,rmUp);
  30. begin
  31. result:=TFPURoundingMode(bits2rm[getrm])
  32. end;
  33. function SetRoundMode(const RoundMode: TFPURoundingMode): TFPURoundingMode;
  34. const
  35. rm2bits : array[TFPURoundingMode] of byte = (0,2,3,1);
  36. begin
  37. softfloat_rounding_mode:=RoundMode;
  38. SetRoundMode:=RoundMode;
  39. setrm(rm2bits[RoundMode]);
  40. end;
  41. function GetPrecisionMode: TFPUPrecisionMode;
  42. begin
  43. result:=pmDouble;
  44. end;
  45. function SetPrecisionMode(const Precision: TFPUPrecisionMode): TFPUPrecisionMode;
  46. begin
  47. result:=pmDouble;
  48. end;
  49. const
  50. fpu_nx = 1 shl 0;
  51. fpu_uf = 1 shl 1;
  52. fpu_of = 1 shl 2;
  53. fpu_dz = 1 shl 3;
  54. fpu_nv = 1 shl 4;
  55. function GetExceptionMask: TFPUExceptionMask;
  56. begin
  57. Result:=softfloat_exception_mask;
  58. end;
  59. function SetExceptionMask(const Mask: TFPUExceptionMask): TFPUExceptionMask;
  60. begin
  61. Result:=softfloat_exception_mask;
  62. { clear "exception happened" flags }
  63. ClearExceptions(false);
  64. softfloat_exception_mask:=Mask;
  65. end;
  66. procedure RaisePendingExceptions;
  67. var
  68. fflags : dword;
  69. f: TFPUException;
  70. begin
  71. fflags:=getfflags;
  72. if (fflags and fpu_dz) <> 0 then
  73. float_raise(exZeroDivide);
  74. if (fflags and fpu_of) <> 0 then
  75. float_raise(exOverflow);
  76. if (fflags and fpu_uf) <> 0 then
  77. float_raise(exUnderflow);
  78. if (fflags and fpu_nv) <> 0 then
  79. float_raise(exInvalidOp);
  80. if (fflags and fpu_nx) <> 0 then
  81. float_raise(exPrecision);
  82. { now the soft float exceptions }
  83. for f in softfloat_exception_flags do
  84. float_raise(f);
  85. end;
  86. procedure ClearExceptions(RaisePending: Boolean);
  87. begin
  88. if raisepending then
  89. RaisePendingExceptions;
  90. softfloat_exception_flags:=[];
  91. setfflags(0);
  92. end;