qp_util.c 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. /* Software floating-point emulation.
  2. Helper routine for _Qp_* routines.
  3. Simulate exceptions using double arithmetics.
  4. Copyright (C) 1999-2017 Free Software Foundation, Inc.
  5. This file is part of the GNU C Library.
  6. Contributed by Jakub Jelinek (jj@ultra.linux.cz).
  7. The GNU C Library is free software; you can redistribute it and/or
  8. modify it under the terms of the GNU Lesser General Public
  9. License as published by the Free Software Foundation; either
  10. version 2.1 of the License, or (at your option) any later version.
  11. The GNU C Library is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. Lesser General Public License for more details.
  15. You should have received a copy of the GNU Lesser General Public
  16. License along with the GNU C Library; if not, see
  17. <http://www.gnu.org/licenses/>. */
  18. #include <float.h>
  19. #include <math.h>
  20. #include <assert.h>
  21. #include "soft-fp.h"
  22. void __Qp_handle_exceptions(int exceptions)
  23. {
  24. if (exceptions & FP_EX_INVALID)
  25. {
  26. float f = 0.0;
  27. __asm__ __volatile__ ("fdivs %0, %0, %0" : "+f" (f));
  28. }
  29. if (exceptions & FP_EX_DIVZERO)
  30. {
  31. float f = 1.0, g = 0.0;
  32. __asm__ __volatile__ ("fdivs %0, %1, %0"
  33. : "+f" (f)
  34. : "f" (g));
  35. }
  36. if (exceptions & FP_EX_OVERFLOW)
  37. {
  38. float f = FLT_MAX;
  39. __asm__ __volatile__("fmuls %0, %0, %0" : "+f" (f));
  40. exceptions &= ~FP_EX_INEXACT;
  41. }
  42. if (exceptions & FP_EX_UNDERFLOW)
  43. {
  44. float f = FLT_MIN;
  45. __asm__ __volatile__("fmuls %0, %0, %0" : "+f" (f));
  46. exceptions &= ~FP_EX_INEXACT;
  47. }
  48. if (exceptions & FP_EX_INEXACT)
  49. {
  50. double d = 1.0, e = M_PI;
  51. __asm__ __volatile__ ("fdivd %0, %1, %0"
  52. : "+f" (d)
  53. : "f" (e));
  54. }
  55. }