satanh.S 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. |
  2. | satanh.sa 3.3 12/19/90
  3. |
  4. | The entry point satanh computes the inverse
  5. | hyperbolic tangent of
  6. | an input argument; satanhd does the same except for denormalized
  7. | input.
  8. |
  9. | Input: Double-extended number X in location pointed to
  10. | by address register a0.
  11. |
  12. | Output: The value arctanh(X) returned in floating-point register Fp0.
  13. |
  14. | Accuracy and Monotonicity: The returned result is within 3 ulps in
  15. | 64 significant bit, i.e. within 0.5001 ulp to 53 bits if the
  16. | result is subsequently rounded to double precision. The
  17. | result is provably monotonic in double precision.
  18. |
  19. | Speed: The program satanh takes approximately 270 cycles.
  20. |
  21. | Algorithm:
  22. |
  23. | ATANH
  24. | 1. If |X| >= 1, go to 3.
  25. |
  26. | 2. (|X| < 1) Calculate atanh(X) by
  27. | sgn := sign(X)
  28. | y := |X|
  29. | z := 2y/(1-y)
  30. | atanh(X) := sgn * (1/2) * logp1(z)
  31. | Exit.
  32. |
  33. | 3. If |X| > 1, go to 5.
  34. |
  35. | 4. (|X| = 1) Generate infinity with an appropriate sign and
  36. | divide-by-zero by
  37. | sgn := sign(X)
  38. | atan(X) := sgn / (+0).
  39. | Exit.
  40. |
  41. | 5. (|X| > 1) Generate an invalid operation by 0 * infinity.
  42. | Exit.
  43. |
  44. | Copyright (C) Motorola, Inc. 1990
  45. | All Rights Reserved
  46. |
  47. | For details on the license for this file, please see the
  48. | file, README, in this same directory.
  49. |satanh idnt 2,1 | Motorola 040 Floating Point Software Package
  50. |section 8
  51. |xref t_dz
  52. |xref t_operr
  53. |xref t_frcinx
  54. |xref t_extdnrm
  55. |xref slognp1
  56. .global satanhd
  57. satanhd:
  58. |--ATANH(X) = X FOR DENORMALIZED X
  59. bra t_extdnrm
  60. .global satanh
  61. satanh:
  62. movel (%a0),%d0
  63. movew 4(%a0),%d0
  64. andil #0x7FFFFFFF,%d0
  65. cmpil #0x3FFF8000,%d0
  66. bges ATANHBIG
  67. |--THIS IS THE USUAL CASE, |X| < 1
  68. |--Y = |X|, Z = 2Y/(1-Y), ATANH(X) = SIGN(X) * (1/2) * LOG1P(Z).
  69. fabsx (%a0),%fp0 | ...Y = |X|
  70. fmovex %fp0,%fp1
  71. fnegx %fp1 | ...-Y
  72. faddx %fp0,%fp0 | ...2Y
  73. fadds #0x3F800000,%fp1 | ...1-Y
  74. fdivx %fp1,%fp0 | ...2Y/(1-Y)
  75. movel (%a0),%d0
  76. andil #0x80000000,%d0
  77. oril #0x3F000000,%d0 | ...SIGN(X)*HALF
  78. movel %d0,-(%sp)
  79. fmovemx %fp0-%fp0,(%a0) | ...overwrite input
  80. movel %d1,-(%sp)
  81. clrl %d1
  82. bsr slognp1 | ...LOG1P(Z)
  83. fmovel (%sp)+,%fpcr
  84. fmuls (%sp)+,%fp0
  85. bra t_frcinx
  86. ATANHBIG:
  87. fabsx (%a0),%fp0 | ...|X|
  88. fcmps #0x3F800000,%fp0
  89. fbgt t_operr
  90. bra t_dz
  91. |end