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.

192 lines
4.6 KiB

  1. page ,132
  2. subttl emspec.asm - Special emulator functions for speed
  3. ;***
  4. ;emspec.asm - Special emulator functions for speed
  5. ;
  6. ; Copyright (c) 1987-89, Microsoft Corporation
  7. ;
  8. ;Purpose:
  9. ; Special emulator functions for speed
  10. ;
  11. ; This Module contains Proprietary Information of Microsoft
  12. ; Corporation and should be treated as Confidential.
  13. ;
  14. ;Revision History:
  15. ; See emulator.hst
  16. ;
  17. ;*******************************************************************************
  18. ProfBegin SPEC
  19. pub loadcontrolword
  20. ifdef QB3
  21. or al,2 ; mask denormal exceptions
  22. endif ;QB3
  23. mov [UserControlWord],ax ; save user's version
  24. and ax,0FF3CH ; Turn off reserved, IEM, Denormal
  25. ; & invalid exception mask bits
  26. ifndef frontend
  27. ifndef only87
  28. cmp [Have8087],0 ; Non-0 if 8087 present
  29. je EmulateFLDCW
  30. endif ;only87
  31. mov [REMLSW],ax ; use this cell (not busy)
  32. fnop ; fix for intel erratum #8
  33. fldcw [REMLSW] ; 8087 gets new control word
  34. endif ;frontend
  35. pub EmulateFLDCW
  36. mov [ControlWord],ax ; save internal control word
  37. ret
  38. ;-----------------------------------------------------------------------------
  39. ifndef QB3 ; rest not needed if QB 3
  40. pub storecontrolword
  41. mov ax,[UserControlWord] ; get user's version
  42. ret
  43. pub storestatusword
  44. xor ax,ax
  45. ifndef frontend
  46. cmp al,[Have8087]
  47. je no87status
  48. fstsw [NewStatusWord]
  49. fwait
  50. mov al,byte ptr [NewStatusWord] ; get exception summary
  51. and al,03Fh ; only low 6 bits are wanted
  52. endif ;frontend
  53. pub no87status
  54. or ax,[UserStatusWord] ; or with full status
  55. and ax,UStatMask ; mask down to actual status bits
  56. mov [UserStatusWord],ax ; update full status word
  57. ret
  58. page
  59. ; Procedure to truncate TOS to integer TOS
  60. ; ax = new rounding control
  61. pub truncateTOS
  62. and ax,RoundControl shl 8 ; mask to new rounding control
  63. ifndef frontend
  64. ifndef only87
  65. cmp [Have8087],0
  66. je Emulatetruncate
  67. endif ;only87
  68. FSTCW [ControlWord] ; get control word
  69. FWAIT ; synchronize
  70. MOV CX,[ControlWord] ; round mode saved
  71. and ch,not RoundControl ; clear rounding control bits
  72. OR ax,cx ; set new rounding
  73. MOV [REMLSW],AX ; back to memory
  74. FLDCW [REMLSW] ; reset rounding
  75. FRNDINT ; "round" top of stack
  76. FLDCW [ControlWord] ; restore rounding
  77. RET ; simple return
  78. endif ;frontend
  79. ifndef only87
  80. pub Emulatetruncate
  81. mov cx,[ControlWord]
  82. push cx ; remember what control word was
  83. and ch,not RoundControl ; clear rounding control bits
  84. OR ah,ch ; set new rounding
  85. MOV [CWcntl],ah ; flag new rounding mode
  86. PUSH BP ; save BP
  87. CALL eFRNDINT
  88. POP BP ; restore BP
  89. POP [ControlWord] ; set back to the way it was
  90. call checktrunc ; check for truncation error
  91. RET ; finished
  92. endif ;only87
  93. page
  94. ; Procedure to truncate TOS to integer in DX:AX
  95. ; ax = new rounding control
  96. pub truncateTOSto32int
  97. and ax,RoundControl shl 8
  98. ifndef frontend
  99. ifndef only87
  100. cmp [Have8087],0
  101. je Emulatetruncateto32int
  102. endif ;only87
  103. FSTCW [ControlWord] ; get control word
  104. FWAIT ; synchronize
  105. MOV CX,[ControlWord] ; round mode saved
  106. and ch,not RoundControl ; clear rounding control bits
  107. OR ax,cx ; set new rounding
  108. MOV [REMLSW],AX ; back to memory
  109. FLDCW [REMLSW] ; reset rounding
  110. FISTP dword ptr [REMLSW] ; "round" top of stack
  111. FLDCW [ControlWord] ; restore rounding
  112. mov ax,[REMLSW]
  113. mov dx,[REMLSW+2]
  114. RET ; simple return
  115. endif ;frontend
  116. ifndef only87
  117. pub Emulatetruncateto32int
  118. mov cx,[ControlWord]
  119. push cx ; remember what control word was
  120. and ch,not RoundControl ; clear rounding control bits
  121. OR ah,ch ; set new rounding
  122. MOV [CWcntl],ah ; flag new rounding mode
  123. PUSH BP ; save BP
  124. CALL TOSto32int ; convert to 32-bit int in BX:DX
  125. POP BP ; restore BP
  126. mov ax,dx
  127. mov dx,bx
  128. call checktrunc ; check for truncation error
  129. POPST ; pop of current stack entry
  130. POP [ControlWord] ; set back to the way it was
  131. pub truncerrOK ; (reuse RET for routine below)
  132. RET ; finished
  133. ; check for errors
  134. pub checktrunc ; !!! check emmain for same code
  135. MOV cx,[CURerr] ; fetch errors
  136. or [UserStatusWord],cx ; OR into user status word
  137. OR [SWerr],cl ; set errors in sticky error flag
  138. NOT cl ; make a zero mean an error
  139. MOV ch,byte ptr [UserControlWord] ; get user's IEEE control word
  140. OR ch,0C2H ; mask reserved, IEM and denormal bits
  141. AND ch,03FH ; unmask invalid instruction,
  142. ; stack overflow.
  143. OR cl,ch ; mask for IEEE exceptions
  144. NOT cl ; make a one mean an error
  145. MOV ch,byte ptr (CURerr+1) ; get stack over/underflow flags
  146. TEST cx,0FFFFh-MemoryOperand ; test for errors to report
  147. jz truncerrOK ; error is masked
  148. xchg ax,cx ; ax = exception
  149. jmp CommonExceptions ; handle error (??? unclean stack)
  150. endif ;only87
  151. endif ;QB3
  152. ProfEnd SPEC