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.

139 lines
4.7 KiB

  1. ; file: floor_wmt.asm
  2. ; Copyright (C) 1985-2000 Intel Corporation.
  3. ;
  4. ; The information and source code contained herein is the exclusive property
  5. ; of Intel Corporation and may not be disclosed, examined, or reproduced in
  6. ; whole or in part without explicit written authorization from the Company.
  7. ;
  8. ; Implemented in VNIIEF-STL, july 2000
  9. ; double floor (double x)
  10. ;
  11. ; Willamette specific version (MASM 6.15 required)
  12. ;
  13. ; Description:
  14. ; The floor functions return the largest integer value not greater than x,
  15. ; expressed as a (double-precision) floating-point number.
  16. ;
  17. ; Special cases:
  18. ; floor(NaN) = that NaN
  19. ; floor(INF) = that INF
  20. ; floor(0) = that 0
  21. ;
  22. ; Accuracy:
  23. ; The result is always exact.
  24. .xlist
  25. include cruntime.inc
  26. .list
  27. EXTRN C __libm_error_support : NEAR
  28. _FUNC_ equ <floor>
  29. _FUNC_DEF_ equ <_floor_default>
  30. _FUNC_P4_ equ <_floor_pentium4>
  31. _FUNC_DEF_EXTERN_ equ 1
  32. include disp_pentium4.inc
  33. .const
  34. ALIGN 16
  35. ;-- 16x-aligned data --------------------------------------------------------
  36. _One DQ 03ff0000000000000H,03ff0000000000000H
  37. _Bns DQ 00000000000000433H,00000000000000433H
  38. _NegOne DQ 0bff0000000000000H,04330000000000000H
  39. _NegZero DQ 08000000000000000H,08000000000000000H
  40. _S DQ 000000000000007ffH,00000000000000000H
  41. codeseg
  42. ALIGN 16
  43. ; double floor (double x);
  44. ; Stack frame locations
  45. floor_x TEXTEQU <esp+4>
  46. XMMWORD TEXTEQU <OWORD>
  47. PUBLIC _floor_pentium4
  48. _floor_pentium4 PROC NEAR
  49. movq xmm0, QWORD PTR [floor_x] ; X
  50. movapd xmm2, XMMWORD PTR _Bns ;
  51. movapd xmm1, xmm0 ;
  52. movapd xmm7, xmm0 ;
  53. psrlq xmm0, 52 ; exp(x) ; sign(X) | exp(X) in XMM reg
  54. movd eax, xmm0 ; sign(X) | exp(X) in eax reg
  55. andpd xmm0, XMMWORD PTR _S ; exp(X) (+3ff)
  56. psubd xmm2, xmm0 ; exp(X)
  57. psrlq xmm1, xmm2 ; truncate the fraction (shift right)
  58. test eax, 0800h ;
  59. jne SHORT negat ; if (X<0.0) goto negat
  60. cmp eax, 03ffh ;**** POSITIVE X *****
  61. jl SHORT ret_zero ; if (X<1.0) return zero
  62. psllq xmm1, xmm2 ; truncate the fraction (integer part)
  63. cmp eax, 0432h ; if X is integer, return X
  64. jg SHORT return_x
  65. movq QWORD PTR [floor_x], xmm1 ; save integer part
  66. fld QWORD PTR [floor_x] ; return integer part
  67. ret ;
  68. return_x:
  69. ucomisd xmm7, xmm7
  70. jnp not_nan
  71. mov edx, 1005
  72. ;call libm_error_support(void *arg1,void *arg2,void *retval,error_types input_tag)
  73. sub esp, 16
  74. mov DWORD PTR [esp+12],edx
  75. mov edx, esp
  76. add edx, 16+4
  77. mov DWORD PTR [esp+8],edx
  78. mov DWORD PTR [esp+4],edx
  79. mov DWORD PTR [esp],edx
  80. call NEAR PTR __libm_error_support
  81. add esp, 16
  82. not_nan:
  83. fld QWORD PTR [floor_x] ; return integer part
  84. ret ;
  85. negat: ; **** NEGATIVE X ****
  86. movq xmm0, QWORD PTR [floor_x] ;
  87. psllq xmm1, xmm2 ;
  88. movapd xmm3, xmm0 ;
  89. cmppd xmm0, xmm1, 1 ; if X<integer part, form Mask
  90. cmp eax, 0bffh ; if X > -1.0 return -1.0
  91. jl SHORT ret_neg_one ;
  92. cmp eax, 0c32h ; if X is integer, return X
  93. jg SHORT return_x ;
  94. andpd xmm0, XMMWORD PTR _One ; Mask & One
  95. subsd xmm1, xmm0 ; if X<integer part,
  96. movq QWORD PTR [floor_x], xmm1 ; return (int.part-1.0)
  97. fld QWORD PTR [floor_x] ;
  98. ret ;
  99. ret_zero:
  100. fldz ;
  101. ret ;
  102. ret_neg_one:
  103. cmppd xmm3, XMMWORD PTR _NegZero, 1 ; case for X = Negative Zero
  104. orpd xmm3, XMMWORD PTR _NegZero ; return X, if X == Negative Zero
  105. andpd xmm3, XMMWORD PTR _NegOne ; if X==NegZero, xmm3=0.0
  106. movq QWORD PTR [floor_x], xmm3 ;
  107. fld QWORD PTR [floor_x] ;
  108. ret ;
  109. _floor_pentium4 ENDP
  110. END