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.

155 lines
3.9 KiB

  1. page ,132
  2. title 87fmod - fmod function
  3. ;***
  4. ;87fmod.asm - fmod function (8087/emulator version)
  5. ;
  6. ; Copyright (c) 1984-2001, Microsoft Corporation. All rights reserved.
  7. ;
  8. ;Purpose:
  9. ; Implements fmod() library function for computing floating-point
  10. ; remainder. Uses FPREM 8087 instruction or its emulated equivalent.
  11. ;
  12. ;Revision History:
  13. ; 12-09-84 GFW Added copyright message
  14. ; 05-12-85 GFW Changed fmod(x,0) = 0 for System V.2 compatibility
  15. ; 10-15-86 GFW In-line instructions rather than call _fpmath
  16. ; 05-08-87 BCM Added intrinsic version (_CIfmod)
  17. ; 10-12-87 BCM OS/2 support C library changes
  18. ; Including pascal naming and calling conv. & no _fac
  19. ; 01-18-88 BCM Eliminated IBMC20 switches; ifos2,noos2 ==> ifmt,nomt
  20. ; OS2_SUPPORT ==> MTHREAD
  21. ; 08-26-88 WAJ 386 version.
  22. ; 08-17-90 WAJ Now uses _stdcall.
  23. ; 05-17-91 WAJ Added _STDCALL ifdefs.
  24. ; 03-04-92 GDP Changed behavior for INF args
  25. ; 03-22-92 GDP Fixed bug: removed fxch out of the remloop
  26. ; 09-22-93 SKS Removed obsolete _FIamod (no longer needed by FORTRAN)
  27. ; 12-09-94 JWM Modified fFMOD to test for bogus Pentiums and call an FPREM workaround
  28. ; 12-13-94 SKS Correct spelling of _adjust_fdiv
  29. ; 10-15-95 BWT Don't do _adjust_fdiv test for NT.
  30. ;
  31. ;*******************************************************************************
  32. .xlist
  33. include cruntime.inc
  34. include mrt386.inc
  35. include elem87.inc
  36. .list
  37. .data
  38. ifndef NT_BUILD
  39. extrn _adjust_fdiv:dword
  40. endif
  41. jmptab OP_FMOD,4,<'fmod',0,0>,<0,0,0,0,0,0>,2
  42. DNCPTR codeoffset fFMOD ; 0000 NOS Valid non-0, TOS Valid non-0
  43. DNCPTR codeoffset _rtindfpop ; 0001 NOS Valid non-0, TOS 0
  44. DNCPTR codeoffset _tosnan2 ; 0010 NOS Valid non-0, TOS NAN
  45. DNCPTR codeoffset _rtindfpop ; 0011 NOS Valid non-0, TOS Inf
  46. DNCPTR codeoffset _rtzeropop ; 0100 NOS 0, TOS Valid non-0
  47. DNCPTR codeoffset _rtindfpop ; 0101 NOS 0, TOS 0
  48. DNCPTR codeoffset _tosnan2 ; 0110 NOS 0, TOS NAN
  49. DNCPTR codeoffset _rtindfpop ; 0111 NOS 0, TOS Inf
  50. DNCPTR codeoffset _nosnan2 ; 1000 NOS NAN, TOS Valid non-0
  51. DNCPTR codeoffset _nosnan2 ; 1001 NOS NAN, TOS 0
  52. DNCPTR codeoffset _nan2 ; 1010 NOS NAN, TOS NAN
  53. DNCPTR codeoffset _nosnan2 ; 1011 NOS NAN, TOS Inf
  54. DNCPTR codeoffset _rtindfpop ; 1100 NOS Inf, TOS Valid non-0
  55. DNCPTR codeoffset _rtindfpop ; 1101 NOS Inf, TOS 0
  56. DNCPTR codeoffset _tosnan2 ; 1110 NOS Inf, TOS NAN
  57. DNCPTR codeoffset _rtindfpop ; 1111 NOS Inf, TOS Inf
  58. page
  59. CODESEG
  60. extrn _ctrandisp2:near
  61. extrn _cintrindisp2:near
  62. extrn _rtindfpop:near
  63. extrn _rtnospop:near
  64. extrn _rtzeropop:near
  65. extrn _tosnan2:near
  66. extrn _nosnan2:near
  67. extrn _nan2:near
  68. ifndef NT_BUILD
  69. extrn _adj_fprem:near
  70. endif
  71. .386
  72. ;***
  73. ;fFMOD - floating-point remainder (8087/emulator intrinsic version)
  74. ;Purpose:
  75. ; fmod(x,y) computes floating-point remainder of x/y, i.e. the
  76. ; floating-point number f such that x = iy + f where f and x have
  77. ; the same sign, and |f| < |y|, and i is an integer.
  78. ;
  79. ; Uses the FPREM instruction to compute the remainder.
  80. ; (Formerly used FDIV.)
  81. ;
  82. ;Entry:
  83. ; floating-point numerator in ST(1)
  84. ; floating-point denominator in ST(0)
  85. ;
  86. ;Exit:
  87. ; floating-point result in ST(0);
  88. ; (pops one of the arguments, replaces the other with the result)
  89. ;
  90. ;Uses:
  91. ; AX, Flags.
  92. ;
  93. ;Exceptions:
  94. ; fmod(x, 0.0) currently returns 0.0 -- see System V specification
  95. ;*******************************************************************************
  96. public fmod
  97. fmod proc
  98. mov edx, OFFSET _OP_FMODjmptab
  99. jmp _ctrandisp2
  100. fmod endp
  101. public _CIfmod
  102. _CIfmod proc
  103. mov edx, OFFSET _OP_FMODjmptab
  104. jmp _cintrindisp2
  105. _CIfmod endp
  106. lab fFMOD
  107. fxch
  108. lab remloop
  109. ifdef NT_BUILD ; NT handles the P5 bug in the OS
  110. fprem ; do fprem's until reduction is done
  111. else
  112. cmp _adjust_fdiv, 1
  113. jz badP5_fprem
  114. fprem ; do fprem's until reduction is done
  115. jmp fprem_done
  116. lab badP5_fprem
  117. call _adj_fprem
  118. lab fprem_done
  119. endif
  120. fstsw ax
  121. fwait
  122. sahf ; load fprem flags into flags
  123. JSPE remloop ; not done with range reduction
  124. fstp st(1) ; get rid of divisor
  125. ret
  126. end