/sysdeps/m68k/m680x0/fpu/s_cexp.c

https://gitlab.com/Namal/glibc · C · 136 lines · 102 code · 13 blank · 21 comment · 17 complexity · 8d0f2fc4a1cdbc44c22b5070de9dd191 MD5 · raw file

  1. /* Complex exponential function. m68k fpu version
  2. Copyright (C) 1997-2016 Free Software Foundation, Inc.
  3. This file is part of the GNU C Library.
  4. Contributed by Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
  5. The GNU C Library is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU Lesser General Public
  7. License as published by the Free Software Foundation; either
  8. version 2.1 of the License, or (at your option) any later version.
  9. The GNU C Library is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. Lesser General Public License for more details.
  13. You should have received a copy of the GNU Lesser General Public
  14. License along with the GNU C Library. If not, see
  15. <http://www.gnu.org/licenses/>. */
  16. #include <float.h>
  17. #include <complex.h>
  18. #include <math.h>
  19. #include "mathimpl.h"
  20. #ifndef SUFF
  21. #define SUFF
  22. #endif
  23. #ifndef float_type
  24. #define float_type double
  25. #endif
  26. #define CONCATX(a,b) __CONCAT(a,b)
  27. #define s(name) CONCATX(name,SUFF)
  28. #define m81(func) __m81_u(s(func))
  29. __complex__ float_type
  30. s(__cexp) (__complex__ float_type x)
  31. {
  32. __complex__ float_type retval;
  33. unsigned long ix_cond;
  34. ix_cond = __m81_test (__imag__ x);
  35. if ((ix_cond & (__M81_COND_NAN|__M81_COND_INF)) == 0)
  36. {
  37. /* Imaginary part is finite. */
  38. unsigned long rx_cond = __m81_test (__real__ x);
  39. if ((rx_cond & (__M81_COND_NAN|__M81_COND_INF)) == 0)
  40. {
  41. const int t = (int) ((LDBL_MAX_EXP - 1) * M_LN2l);
  42. long double sin_ix, cos_ix, exp_val;
  43. __m81_u (__sincosl) (__imag__ x, &sin_ix, &cos_ix);
  44. if (__real__ x > t)
  45. {
  46. long double exp_t = __m81_u(__ieee754_expl) (t);
  47. __real__ x -= t;
  48. sin_ix *= exp_t;
  49. cos_ix *= exp_t;
  50. if (__real__ x > t)
  51. {
  52. __real__ x -= t;
  53. sin_ix *= exp_t;
  54. cos_ix *= exp_t;
  55. }
  56. }
  57. exp_val = __m81_u(__ieee754_expl) (__real__ x);
  58. __real__ retval = exp_val * cos_ix;
  59. if (ix_cond & __M81_COND_ZERO)
  60. __imag__ retval = __imag__ x;
  61. else
  62. __imag__ retval = exp_val * sin_ix;
  63. }
  64. else
  65. {
  66. /* Compute the sign of the result. */
  67. long double remainder, pi_2;
  68. int quadrant;
  69. if ((rx_cond & (__M81_COND_NAN|__M81_COND_NEG)) == __M81_COND_NEG)
  70. __real__ retval = __imag__ retval = 0.0;
  71. else
  72. __real__ retval = __imag__ retval = __real__ x;
  73. __asm ("fmovecr %#0,%0\n\tfscale%.w %#-1,%0" : "=f" (pi_2));
  74. __asm ("fmod%.x %2,%0\n\tfmove%.l %/fpsr,%1"
  75. : "=f" (remainder), "=dm" (quadrant)
  76. : "f" (pi_2), "0" (__imag__ x));
  77. quadrant = (quadrant >> 16) & 0x83;
  78. if (quadrant & 0x80)
  79. quadrant ^= 0x83;
  80. switch (quadrant)
  81. {
  82. default:
  83. break;
  84. case 1:
  85. __real__ retval = -__real__ retval;
  86. break;
  87. case 2:
  88. __real__ retval = -__real__ retval;
  89. case 3:
  90. __imag__ retval = -__imag__ retval;
  91. break;
  92. }
  93. if (ix_cond & __M81_COND_ZERO && (rx_cond & __M81_COND_NAN) == 0)
  94. __imag__ retval = __imag__ x;
  95. }
  96. }
  97. else
  98. {
  99. unsigned long rx_cond = __m81_test (__real__ x);
  100. if (rx_cond & __M81_COND_INF)
  101. {
  102. /* Real part is infinite. */
  103. if (rx_cond & __M81_COND_NEG)
  104. {
  105. __real__ retval = __imag__ retval = 0.0;
  106. if (ix_cond & __M81_COND_NEG)
  107. __imag__ retval = -__imag__ retval;
  108. }
  109. else
  110. {
  111. __real__ retval = __real__ x;
  112. __imag__ retval = __imag__ x - __imag__ x;
  113. }
  114. }
  115. else
  116. __real__ retval = __imag__ retval = __imag__ x - __imag__ x;
  117. }
  118. return retval;
  119. }
  120. weak_alias (s(__cexp), s(cexp))