stanh.s
上传用户:nvosite88
上传日期:2007-01-17
资源大小:4983k
文件大小:5k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* stanh.s - Motorola 68040 FP hyperbolic tangent routines (EXC) */
  2. /* Copyright 1991-1993 Wind River Systems, Inc. */
  3. .data
  4. .globl _copyright_wind_river
  5. .long _copyright_wind_river
  6. /*
  7. modification history
  8. --------------------
  9. 01e,21jul93,kdl  added .text (SPR #2372).
  10. 01d,23aug92,jcf  changed bxxx to jxx.
  11. 01c,26may92,rrr  the tree shuffle
  12. 01b,10jan92,kdl  added modification history; general cleanup.
  13. 01a,15aug91,kdl  original version, from Motorola FPSP v2.0.
  14. */
  15. /*
  16. DESCRIPTION
  17. stanhsa 3.1 12/10/90
  18. The entry point sTanh computes the hyperbolic tangent of
  19. an input argument|  sTanhd does the same except for denormalized
  20. input.
  21. Input: Double-extended number X in location pointed to
  22. by address register a0.
  23. Output: The value tanh(X) returned in floating-point register Fp0.
  24. Accuracy and Monotonicity: The returned result is within 3 ulps in
  25. 64 significant bit, i.e. within 0.5001 ulp to 53 bits if the
  26. result is subsequently rounded to double precision. The
  27. result is provably monotonic in double precision.
  28. Speed: The program __x_stanh takes approximately 270 cycles.
  29. Algorithm:
  30. TANH
  31. 1. If |X| >= (5/2) log2 or |X| <= 2**(-40), go to 3.
  32. 2. (2**(-40) < |X| < (5/2) log2) Calculate tanh(X) by
  33. sgn := sign(X), y := 2|X|, z := expm1(Y), and
  34. tanh(X) = sgn*( z/(2+z) ).
  35. Exit.
  36. 3. (|X| <= 2**(-40) or |X| >= (5/2) log2). If |X| < 1,
  37. go to 7.
  38. 4. (|X| >= (5/2) log2) If |X| >= 50 log2, go to 6.
  39. 5. ((5/2) log2 <= |X| < 50 log2) Calculate tanh(X) by
  40. sgn := sign(X), y := 2|X|, z := exp(Y),
  41. tanh(X) = sgn - [ sgn*2/(1+z) ].
  42. Exit.
  43. 6. (|X| >= 50 log2) Tanh(X) = +-1 (round to nearest). Thus, we
  44. calculate Tanh(X) by
  45. sgn := sign(X), Tiny := 2**(-126),
  46. tanh(X) := sgn - sgn*Tiny.
  47. Exit.
  48. 7. (|X| < 2**(-40)). Tanh(X) = X. Exit.
  49. Copyright (C) Motorola, Inc. 1990
  50. All Rights Reserved
  51. THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MOTOROLA
  52. The copyright notice above does not evidence any
  53. actual or intended publication of such source code.
  54. STANH idnt 2,1 Motorola 040 Floating Point Software Package
  55. section 8
  56. NOMANUAL
  57. */
  58. #include "fpsp040E.h"
  59. #define X FP_SCR5
  60. #define XDCARE X+2
  61. #define XFRAC X+4
  62. #define SGN L_SCR3
  63. #define V FP_SCR6
  64. BOUNDS1: .long 0x3FD78000,0x3FFFDDCE |... 2^(-40), (5/2)LOG2
  65. | xref __x_t_frcinx
  66. | xref __x_t_extdnrm
  67. | xref __x_setox
  68. | xref __x_setoxm1
  69. .text
  70. .globl __x_stanhd
  71. __x_stanhd:
  72. |--TANH(X) = X FOR DENORMALIZED X
  73. jra  __x_t_extdnrm
  74. .globl __x_stanh
  75. __x_stanh:
  76. fmovex a0@,fp0 |...lOAD INPUT
  77. fmovex fp0,a6@(X)
  78. movel a0@,d0
  79. movew a0@(4),d0
  80. movel d0,a6@(X)
  81. andl #0x7FFFFFFF,d0
  82. cmp2l pc@(BOUNDS1),d0 |...2**(-40) < |X| < (5/2)LOG2 ?
  83. jcs  TANHBORS
  84. |--THIS IS THE USUAL CASE
  85. |--Y = 2|X|, Z = EXPM1(Y), TANH(X) = SIGN(X) * Z / (Z+2).
  86. movel a6@(X),d0
  87. movel d0,a6@(SGN)
  88. andl #0x7FFF0000,d0
  89. addl #0x00010000,d0 |...EXPONENT OF 2|X|
  90. movel d0,a6@(X)
  91. andl #0x80000000,a6@(SGN)
  92. fmovex a6@(X),fp0 |...FP0 IS Y = 2|X|
  93. movel d1,a7@-
  94. clrl d1
  95. fmovemx fp0-fp0,a0@
  96. bsrl __x_setoxm1  |...FP0 IS Z = EXPM1(Y)
  97. movel a7@+,d1
  98. fmovex fp0,fp1
  99. .long 0xf23c44a2,0x40000000 /*  fadds  &0x40000000,fp1 */
  100. movel a6@(SGN),d0
  101. fmovex fp1,a6@(V)
  102. eorl d0,a6@(V)
  103. fmovel d1,fpcr | restore users exceptions
  104. fdivx a6@(V),fp0
  105. jra  __x_t_frcinx
  106. TANHBORS:
  107. cmpl #0x3FFF8000,d0
  108. jlt  TANHSM
  109. cmpl #0x40048AA1,d0
  110. jgt  TANHHUGE
  111. |-- (5/2) LOG2 < |X| < 50 LOG2,
  112. |--TANH(X) = 1 - (2/[EXP(2X)+1]). LET Y = 2|X|, SGN = SIGN(X),
  113. |--TANH(X) = SGN - SGN*2/[EXP(Y)+1].
  114. movel a6@(X),d0
  115. movel d0,a6@(SGN)
  116. andl #0x7FFF0000,d0
  117. addl #0x00010000,d0 |...EXPO OF 2|X|
  118. movel d0,a6@(X) |...Y = 2|X|
  119. andl #0x80000000,a6@(SGN)
  120. movel a6@(SGN),d0
  121. fmovex a6@(X),fp0 |...Y = 2|X|
  122. movel d1,a7@-
  123. clrl d1
  124. fmovemx fp0-fp0,a0@
  125. bsrl __x_setox |...FP0 IS EXP(Y)
  126. movel a7@+,d1
  127. movel a6@(SGN),d0
  128. .long 0xf23c4422,0x3f800000 /*  fadds  &0x3F800000,fp0 */
  129. eorl #0xC0000000,d0 |...-SIGN(X)*2
  130. fmoves d0,fp1 |...-SIGN(X)*2 IN SGL FMT
  131. fdivx fp0,fp1   |...-SIGN(X)2 / [EXP(Y)+1 ]
  132. movel a6@(SGN),d0
  133. orl #0x3F800000,d0 |...SGN
  134. fmoves d0,fp0 |...SGN IN SGL FMT
  135. fmovel d1,fpcr | restore users exceptions
  136. faddx fp1,fp0
  137. jra  __x_t_frcinx
  138. TANHSM:
  139. movew #0x0000,a6@(XDCARE)
  140. fmovel d1,fpcr | restore users exceptions
  141. fmovex a6@(X),fp0 | last inst - possible exception set
  142. jra  __x_t_frcinx
  143. TANHHUGE:
  144. |---RETURN SGN(X) - SGN(X)EPS
  145. movel a6@(X),d0
  146. andl #0x80000000,d0
  147. orl #0x3F800000,d0
  148. fmoves d0,fp0
  149. andl #0x80000000,d0
  150. eorl #0x80800000,d0 |...-SIGN(X)*EPS
  151. fmovel d1,fpcr | restore users exceptions
  152. fadds d0,fp0
  153. jra  __x_t_frcinx
  154. | end