Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

217 lines
5.5 KiB

  1. page ,132
  2. title 87trigh - hyperbolic trigonometric functions - SINH, COSH, TANH
  3. ;***
  4. ;87trigh.asm - hyperbolic trigonometric functions - SINH, COSH, TANH
  5. ;
  6. ; Copyright (c) 1984-2001, Microsoft Corporation. All rights reserved.
  7. ;
  8. ;Purpose:
  9. ; Routines for SINH, COSH, TANH
  10. ;
  11. ;Revision History:
  12. ;
  13. ; 07/04/84 Greg Whitten
  14. ; initial version
  15. ;
  16. ; 10/31/85 Jamie Bariteau
  17. ; made _fFSINH and _fFCOSH public labels
  18. ;
  19. ; 10/30/87 Bill Johnston
  20. ; Minor changes for new cmacros.
  21. ;
  22. ; 08/25/88 Bill Johnston
  23. ; 386 version.
  24. ;
  25. ; 02/10/92 Georgios Papagiannakopoulos
  26. ; NT port --used CHECKOVER for detection of overflow
  27. ;
  28. ;*******************************************************************************
  29. .xlist
  30. include cruntime.inc
  31. include mrt386.inc
  32. include elem87.inc
  33. .list
  34. .data
  35. extrn _logemax:tbyte
  36. extrn _infinity:tbyte
  37. staticT _tanhmaxarg, 04003987E0C9996699000R
  38. jmptab OP_SINH,4,<'sinh',0,0>,<0,0,0,0,0,0>,1
  39. DNCPTR codeoffset fFSINH ; 0000 TOS Valid non-0
  40. DNCPTR codeoffset _rttosnpop ; 0001 TOS 0
  41. DNCPTR codeoffset _tosnan1 ; 0010 TOS NAN
  42. DNCPTR codeoffset _rtforsnhinf ; 0011 TOS Inf
  43. jmptab OP_COSH,4,<'cosh',0,0>,<0,0,0,0,0,0>,1
  44. DNCPTR codeoffset fFCOSH ; 0000 TOS Valid non-0
  45. DNCPTR codeoffset _rtonenpop ; 0001 TOS 0
  46. DNCPTR codeoffset _tosnan1 ; 0010 TOS NAN
  47. DNCPTR codeoffset _rtforcshinf ; 0011 TOS Inf
  48. jmptab OP_TANH,4,<'tanh',0,0>,<0,0,0,0,0,0>,1
  49. DNCPTR codeoffset fFTANH ; 0000 TOS Valid non-0
  50. DNCPTR codeoffset _rttosnpop ; 0001 TOS 0
  51. DNCPTR codeoffset _tosnan1 ; 0010 TOS NAN
  52. DNCPTR codeoffset _rtfortnhinf ; 0011 TOS Inf
  53. page
  54. CODESEG
  55. extrn _ffexpm1:near
  56. extrn _rtchsifneg:near
  57. extrn _rtindfnpop:near
  58. extrn _rtinfnpop:near
  59. extrn _rtonenpop:near
  60. extrn _rttospop:near
  61. extrn _rttosnpop:near
  62. extrn _rttosnpopde:near
  63. extrn _tosnan1:near
  64. ;----------------------------------------------------------
  65. ;
  66. ; HYPERBOLIC FUNCTIONS
  67. ;
  68. ;----------------------------------------------------------
  69. ;
  70. ; INPUTS - The argument is the stack top.
  71. ; The sign of the argument is bit 2 of CL.
  72. ;
  73. ; OUTPUT - The result is the stack top
  74. ;
  75. ;----------------------------------------------------------
  76. labelNP _fFSINH, PUBLIC
  77. lab fFSINH
  78. mov DSF.ErrorType, CHECKOVER ; indicate possible overflow on exit
  79. call fFEXPH ; compute e^x for hyperbolics
  80. or bl, bl ; if e^x is infinite
  81. JSZ _rtforsnhlarge ; return as if x = affine infinity
  82. call ExpHypCopyInv ; TOS = e^(-x), NOS = e^x
  83. fsubp st(1), st(0) ; compute e^x - e^(-x) for hyperbolics
  84. jmp short SinhCoshReturn
  85. lab fFTANH
  86. fld st(0) ; copy TOS
  87. fabs ; make TOS +ve
  88. fld [_tanhmaxarg] ; get largest arg, roughly ln(2)(55)/2
  89. fcompp
  90. fstsw DSF.StatusWord
  91. fwait
  92. test CondCode, 041h ; if abs(arg) > XBIG (see tanh.h)
  93. JSNZ _rtfortnhlarge ; return as if x = affine infinity
  94. call fFEXPH ; compute e^x for hyperbolics
  95. or bl, bl ; if e^x is infinite
  96. JSZ _rtfortnhlarge ; return as if x = affine infinity
  97. fld st(0) ; copy TOS
  98. call ExpHypSum ; compute e^x + e^(-x) for hyperbolics
  99. fxch ; get copy of e^x
  100. call ExpHypCopyInv ; TOS = e^(-x), NOS = e^x
  101. fsubp st(1), st(0) ; compute e^x - e^(-x) for hyperbolics
  102. fdivrp st(1), st(0) ; now TOS = tanh(x)
  103. ret
  104. labelNP _fFCOSH, PUBLIC
  105. lab fFCOSH
  106. mov DSF.ErrorType, CHECKOVER ; indicate possible overflow on exit
  107. call fFEXPH ; compute e^x for hyperbolics
  108. or bl, bl ; if e^x is infinite
  109. JSZ _rtforcnhlarge ; return as if x = affine infinity
  110. call ExpHypSum ; compute e^x + e^(-x) for hyperbolics
  111. lab SinhCoshReturn
  112. fld1
  113. fchs
  114. fxch
  115. fscale ; divide result by 2
  116. jmp _rttospop
  117. page
  118. lab _rtforsnhinf
  119. fstp st(0)
  120. fld [_infinity]
  121. jmp _rtchsifneg ; change sign if argument -ve
  122. lab _rtforcshinf
  123. fstp st(0)
  124. fld [_infinity]
  125. ret
  126. lab infpositive
  127. ret
  128. lab _rtforsnhlarge
  129. call _rtinfnpop ; TOS = infinity
  130. lab chsifneg
  131. jmp _rtchsifneg ; change sign if argument -ve
  132. lab _rtforcnhlarge
  133. jmp _rtinfnpop ; TOS = infinity
  134. lab _rtfortnhlarge
  135. mov DSF.ErrorType, INEXACT
  136. lab _rtfortnhinf
  137. call _rtonenpop ; TOS = one
  138. jmp chsifneg ; change sign if argument -ve
  139. page
  140. lab fFEXPH
  141. fldl2e
  142. fmul ; convert log base e to log base 2
  143. xor rbx, rbx ; clear e^x, finite result flags
  144. call _ffexpm1 ; TOS = e^|x|-1 unscaled, NOS = scale
  145. not bl ; set finite result flag
  146. test CondCode, 1 ; if fraction > 0 (TOS > 0)
  147. JSZ ExpHypNoInvert ; bypass e^x-1 invert
  148. call ExpHypCopyInv ; TOS = e^(-x)-1, NOS = e^x-1
  149. fxch
  150. fstp st(0) ; remove NOS
  151. lab ExpHypNoInvert
  152. test dl, 040h ; if integer part was zero
  153. JSNZ ExpHypScaled ; bypass scaling to avoid bug
  154. not bh ; set e^x flag
  155. fld1
  156. fadd ; TOS = e^x unscaled
  157. fscale ; now TOS = e^x
  158. lab ExpHypScaled
  159. jmp _rttospop ; TOS = e^x-1 or e^x scaled
  160. lab ExpHypSum
  161. call ExpHypCopyInv ; TOS = e^(-x), NOS = e^x
  162. fadd ; TOS = e^x + e^(-x)
  163. or bh, bh ; if e^x flag set
  164. JSNZ ExpHypSumReturn ; bypass e^x-1 adjust
  165. fld1
  166. fadd st(1),st
  167. fadd ; add 2 to result
  168. lab ExpHypSumReturn
  169. ret
  170. lab ExpHypCopyInv
  171. fld st(0) ; TOS = e^x (or e^x-1)
  172. fld1 ; TOS = 1, NOS = e^x (or e^x-1)
  173. or bh, bh ; if e^x flag set
  174. JSNZ ExpHypCopyInvReturn ; bypass e^x-1 adjust
  175. fadd st, st(1) ; TOS = e^x, NOS = e^x-1
  176. fchs ; TOS = -e^x, NOS = e^x-1
  177. fxch ; TOS = e^x-1, NOS = -e^x
  178. lab ExpHypCopyInvReturn
  179. fdivrp st(1), st(0) ; TOS = e^(-x) (or e^(-x)-1)
  180. ret
  181. end