Source code of Windows XP (NT5)
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.

157 lines
4.1 KiB

  1. ;***
  2. ;
  3. ; Copyright (c) 1984-2001, Microsoft Corporation. All rights reserved.
  4. ;
  5. ;Purpose:
  6. ; support for asin() and acos() functions
  7. ;
  8. ;Revision History:
  9. ;
  10. ;*******************************************************************************
  11. .xlist
  12. include cruntime.inc
  13. include elem87.inc
  14. .list
  15. .data
  16. ifdef _ACOS_
  17. _NAME_ db 'acos',0,0,0,0
  18. _FUNC_ equ <acos>
  19. _IFUNC_ equ <_CIacos>
  20. elseifdef _ASIN_
  21. _SIN_ equ 1
  22. _NAME_ db 'asin',0,0,0,0
  23. _FUNC_ equ <asin>
  24. _IFUNC_ equ <_CIasin>
  25. endif
  26. extrn _indefinite:tbyte
  27. extrn __fastflag:dword
  28. extrn _piby2:tbyte
  29. CODESEG
  30. extrn _startOneArgErrorHandling:near
  31. extrn _fload_withFB:near
  32. extrn _convertTOStoQNaN:near
  33. extrn _checkTOS_withFB:near
  34. extrn _math_exit:near
  35. extrn _fast_exit:near
  36. extrn _load_CW:near
  37. ; arg ErrorType result
  38. ;------------------------------------------------
  39. ; |x| >1 DOMAIN indefinite
  40. ;+/-infinity DOMAIN indefinite | ? Do we really need
  41. ;QNaN DOMAIN_QNAN QNaN | ? to distinguish them???
  42. ;SNaN DOMAIN indefinite | ? it costs 14 bytes per function
  43. ;indefinite is like QNaN
  44. ;denormal fld converts it to normal (80 bits)
  45. public _FUNC_,_IFUNC_
  46. _IFUNC_ proc
  47. sub esp,DBLSIZE+4 ; for argument
  48. fst qword ptr [esp]
  49. call _checkTOS_withFB
  50. call start
  51. add esp, DBLSIZE+4
  52. ret
  53. _FUNC_ label proc
  54. lea edx, [esp+4]
  55. call _fload_withFB
  56. start:
  57. push edx ; allocate space for Control Word
  58. fstcw [esp] ; store Control Word
  59. ; at this point we have on stack: cw(4), ret_addr(4), arg1(8bytes)
  60. jz inf_or_nan
  61. cmp word ptr[esp], default_CW
  62. je CW_is_set_to_default
  63. call _load_CW ; use user's precision bits
  64. CW_is_set_to_default:
  65. cmp eax,3ff00000H ; check if |x|>=1
  66. jae x_huge
  67. fld1 ; load 1.0
  68. fadd st, st(1) ; 1+x
  69. fld1 ; load 1.0
  70. fsub st, st(2) ; 1-x
  71. fmul ; (1+x)(1-x)
  72. fsqrt ; sqrt((1+x)(1-x))
  73. ifdef _ACOS_
  74. fxch
  75. endif
  76. fpatan ; fpatan(x,sqrt((1+x)(1-x)))
  77. exit:
  78. cmp __fastflag, 0
  79. jnz _fast_exit
  80. ; prepare in registers arguments for math_exit
  81. ifdef _ACOS_
  82. mov edx,OP_ACOS
  83. elseifdef _ASIN_
  84. mov edx,OP_ASIN
  85. endif
  86. lea ecx,[_NAME_]
  87. jmp _math_exit
  88. x_huge: ja not_in_range
  89. mov eax,[esp+0cH]
  90. mov ecx,eax
  91. and eax,000fffffH
  92. or eax,[esp+8]
  93. jnz not_in_range
  94. and ecx,80000000H
  95. fstp st(0) ; remove TOS
  96. ifdef _ASIN_
  97. fld _piby2 ; asin(1) = pi/2
  98. jz exit
  99. fchs ; asin(-1) = -pi/2
  100. jmp exit
  101. elseifdef _ACOS_
  102. jz ret_zero
  103. fldpi
  104. jmp exit
  105. ret_zero:
  106. fldz
  107. jmp exit
  108. endif
  109. not_infinity:
  110. call _convertTOStoQNaN ; eax MUST contain high dword
  111. jmp _Error_handling ; eax=error number
  112. inf_or_nan:
  113. test eax, 000fffffh
  114. jnz not_infinity
  115. cmp dword ptr[esp+8], 0
  116. jne not_infinity
  117. not_in_range:
  118. fstp st(0)
  119. fld [_indefinite]
  120. mov eax,DOMAIN
  121. _Error_handling:
  122. cmp __fastflag, 0
  123. jnz _fast_exit
  124. ifdef _ACOS_
  125. mov edx,OP_ACOS
  126. elseifdef _ASIN_
  127. mov edx,OP_ASIN
  128. endif
  129. lea ecx,[_NAME_]
  130. call _startOneArgErrorHandling
  131. pop edx ; remove saved CW from stack
  132. ret
  133. _IFUNC_ endp
  134. end