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.

179 lines
5.2 KiB

  1. ;***
  2. ;
  3. ; Copyright (c) 1984-2001, Microsoft Corporation. All rights reserved.
  4. ;
  5. ;Revision History:
  6. ; 01-26-01 PML Pentium4 merge.
  7. ; 02-28-01 PML Check for negative denormal.
  8. ;
  9. ;*******************************************************************************
  10. .xlist
  11. include cruntime.inc
  12. include elem87.inc
  13. .list
  14. ifdef _LOG10_
  15. _FUNC_ equ <log10>
  16. _FUNC_DEF_ equ <_log10_default>
  17. _FUNC_P4_ equ <_log10_pentium4>
  18. else
  19. _FUNC_ equ <log>
  20. _FUNC_DEF_ equ <_log_default>
  21. _FUNC_P4_ equ <_log_pentium4>
  22. endif
  23. _FUNC_P4_EXTERN_ equ 1
  24. include disp_pentium4.inc
  25. ifdef _LOG10_
  26. _FUNC_ equ <_CIlog10>
  27. _FUNC_DEF_ equ <_CIlog10_default>
  28. _FUNC_P4_ equ <_CIlog10_pentium4>
  29. else
  30. _FUNC_ equ <_CIlog>
  31. _FUNC_DEF_ equ <_CIlog_default>
  32. _FUNC_P4_ equ <_CIlog_pentium4>
  33. endif
  34. include disp_pentium4.inc
  35. .data
  36. extrn _infinity:tbyte
  37. extrn _minfinity:tbyte
  38. extrn _indefinite:tbyte
  39. extrn __fastflag:dword
  40. extrn _DEFAULT_CW_in_mem:word
  41. ifdef _LOG10_
  42. LOG_name db 'log10',0,0,0
  43. _FUNC_ equ <_log10_default>
  44. _IFUNC_ equ <_CIlog10_default>
  45. else
  46. LOG_name db 'log',0
  47. _FUNC_ equ <_log_default>
  48. _IFUNC_ equ <_CIlog_default>
  49. endif
  50. ;page
  51. CODESEG
  52. extrn _startOneArgErrorHandling:near
  53. extrn _fload_withFB:near
  54. extrn _convertTOStoQNaN:near
  55. extrn _checkTOS_withFB:near
  56. extrn _math_exit:near
  57. extrn _fast_exit:near
  58. ; arg ErrorType result
  59. ;-------------------------------------------
  60. ;0.0 or -0.0 SING minfinity
  61. ;negative DOMAIN indefinite
  62. ;-infinity DOMAIN indefinite
  63. ;+infinity ?? +infinity
  64. ;QNaN DOMAIN_QNAN QNaN
  65. ;SNaN DOMAIN QNaN=indefinite
  66. ;indefinite is like QNaN
  67. ;denormal(53) fld converts it to normal (64 bits)
  68. ;denormal(64) like normal number (64 bits)
  69. public _IFUNC_,_FUNC_
  70. _IFUNC_ proc
  71. sub esp,DBLSIZE+4 ; for argument
  72. fst qword ptr [esp]
  73. call _checkTOS_withFB
  74. call start
  75. add esp,DBLSIZE+4
  76. ret
  77. _FUNC_ label proc
  78. lea edx,[esp+4]
  79. call _fload_withFB
  80. start:
  81. push edx ; allocate space for Control Word
  82. fstcw [esp] ; store Control Word
  83. ; at this point we have on stack: cw(4), ret_addr(4), arg1(8bytes)
  84. jz inf_or_nan
  85. mov eax,[esp+0ch] ; eax contains high dword
  86. cmp word ptr[esp],default_CW
  87. je CW_is_set_to_default
  88. ; fyl2x is not affected by precision bits. So we may ignore user's CW
  89. fldcw _DEFAULT_CW_in_mem
  90. CW_is_set_to_default:
  91. test eax,7ff00000h
  92. jz test_if_x_zero
  93. test eax,80000000h ; obtain sign
  94. jnz negative_x
  95. normal:
  96. ifdef _LOG10_
  97. fldlg2
  98. else
  99. fldln2 ; y=load loge(2)
  100. endif
  101. fxch
  102. fyl2x ; y*log2(x)
  103. exit:
  104. cmp __fastflag,0
  105. jnz _fast_exit
  106. ; prepare in registers arguments for math_exit
  107. lea ecx,[LOG_name]
  108. ifdef _LOG10_
  109. mov edx,OP_LOG10
  110. else
  111. mov edx,OP_LOG
  112. endif
  113. jmp _math_exit
  114. x_is_denormal: ; denormal is like normal
  115. test eax,80000000h ; obtain sign
  116. jnz negative_x
  117. jmp normal
  118. inf_or_nan: ; we differ inf and NaN
  119. test eax,000fffffH ; eax=high
  120. jnz not_infinity
  121. cmp dword ptr[esp+8],0 ; test if low dword is zero
  122. jnz not_infinity
  123. and eax,80000000H ; test sign of infinity
  124. jz exit ; infinity is already in ST(0)
  125. negative_x: ; -inf and neg is the same
  126. fstp ST(0)
  127. fld [_indefinite] ; log(infinity)=indefinite
  128. mov eax,DOMAIN
  129. jmp _ErrorHandling
  130. not_infinity: ; argument is QNaN or SNaN
  131. call _convertTOStoQNaN ; eax MUST contain high dword
  132. jmp _ErrorHandling
  133. test_if_x_zero: ; test if TOS is zero
  134. test eax,000fffffH
  135. jnz x_is_denormal ; denormal operand
  136. cmp dword ptr[esp+8],0 ; test if low dword is zero
  137. jnz x_is_denormal ; denormal operand
  138. fstp ST(0) ; log(0)=-infinity
  139. fld tbyte ptr[_minfinity]
  140. mov eax,SING
  141. ; jmp _ErrorHandling
  142. _ErrorHandling:
  143. cmp __fastflag,0
  144. jnz _fast_exit
  145. lea ecx,[LOG_name]
  146. ifdef _LOG10_
  147. mov edx,OP_LOG10
  148. else
  149. mov edx,OP_LOG
  150. endif
  151. call _startOneArgErrorHandling
  152. pop edx ; remove saved CW from stack
  153. ret
  154. _IFUNC_ endp
  155. end