mathu.inc 3.5 KB

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