page ,132
subttl emspec.asm - Special emulator functions for speed
;***
;emspec.asm - Special emulator functions for speed
;
; Copyright (c) 1987-89, Microsoft Corporation
;
;Purpose:
; Special emulator functions for speed
;
; This Module contains Proprietary Information of Microsoft
; Corporation and should be treated as Confidential.
;
;Revision History:
; See emulator.hst
;
;*******************************************************************************
ProfBegin SPEC
pub loadcontrolword
ifdef QB3
or al,2 ; mask denormal exceptions
endif ;QB3
mov [UserControlWord],ax ; save user's version
and ax,0FF3CH ; Turn off reserved, IEM, Denormal
; & invalid exception mask bits
ifndef frontend
ifndef only87
cmp [Have8087],0 ; Non-0 if 8087 present
je EmulateFLDCW
endif ;only87
mov [REMLSW],ax ; use this cell (not busy)
fnop ; fix for intel erratum #8
fldcw [REMLSW] ; 8087 gets new control word
endif ;frontend
pub EmulateFLDCW
mov [ControlWord],ax ; save internal control word
ret
;-----------------------------------------------------------------------------
ifndef QB3 ; rest not needed if QB 3
pub storecontrolword
mov ax,[UserControlWord] ; get user's version
ret
pub storestatusword
xor ax,ax
ifndef frontend
cmp al,[Have8087]
je no87status
fstsw [NewStatusWord]
fwait
mov al,byte ptr [NewStatusWord] ; get exception summary
and al,03Fh ; only low 6 bits are wanted
endif ;frontend
pub no87status
or ax,[UserStatusWord] ; or with full status
and ax,UStatMask ; mask down to actual status bits
mov [UserStatusWord],ax ; update full status word
ret
page
; Procedure to truncate TOS to integer TOS
; ax = new rounding control
pub truncateTOS
and ax,RoundControl shl 8 ; mask to new rounding control
ifndef frontend
ifndef only87
cmp [Have8087],0
je Emulatetruncate
endif ;only87
FSTCW [ControlWord] ; get control word
FWAIT ; synchronize
MOV CX,[ControlWord] ; round mode saved
and ch,not RoundControl ; clear rounding control bits
OR ax,cx ; set new rounding
MOV [REMLSW],AX ; back to memory
FLDCW [REMLSW] ; reset rounding
FRNDINT ; "round" top of stack
FLDCW [ControlWord] ; restore rounding
RET ; simple return
endif ;frontend
ifndef only87
pub Emulatetruncate
mov cx,[ControlWord]
push cx ; remember what control word was
and ch,not RoundControl ; clear rounding control bits
OR ah,ch ; set new rounding
MOV [CWcntl],ah ; flag new rounding mode
PUSH BP ; save BP
CALL eFRNDINT
POP BP ; restore BP
POP [ControlWord] ; set back to the way it was
call checktrunc ; check for truncation error
RET ; finished
endif ;only87
page
; Procedure to truncate TOS to integer in DX:AX
; ax = new rounding control
pub truncateTOSto32int
and ax,RoundControl shl 8
ifndef frontend
ifndef only87
cmp [Have8087],0
je Emulatetruncateto32int
endif ;only87
FSTCW [ControlWord] ; get control word
FWAIT ; synchronize
MOV CX,[ControlWord] ; round mode saved
and ch,not RoundControl ; clear rounding control bits
OR ax,cx ; set new rounding
MOV [REMLSW],AX ; back to memory
FLDCW [REMLSW] ; reset rounding
FISTP dword ptr [REMLSW] ; "round" top of stack
FLDCW [ControlWord] ; restore rounding
mov ax,[REMLSW]
mov dx,[REMLSW+2]
RET ; simple return
endif ;frontend
ifndef only87
pub Emulatetruncateto32int
mov cx,[ControlWord]
push cx ; remember what control word was
and ch,not RoundControl ; clear rounding control bits
OR ah,ch ; set new rounding
MOV [CWcntl],ah ; flag new rounding mode
PUSH BP ; save BP
CALL TOSto32int ; convert to 32-bit int in BX:DX
POP BP ; restore BP
mov ax,dx
mov dx,bx
call checktrunc ; check for truncation error
POPST ; pop of current stack entry
POP [ControlWord] ; set back to the way it was
pub truncerrOK ; (reuse RET for routine below)
RET ; finished
; check for errors
pub checktrunc ; !!! check emmain for same code
MOV cx,[CURerr] ; fetch errors
or [UserStatusWord],cx ; OR into user status word
OR [SWerr],cl ; set errors in sticky error flag
NOT cl ; make a zero mean an error
MOV ch,byte ptr [UserControlWord] ; get user's IEEE control word
OR ch,0C2H ; mask reserved, IEM and denormal bits
AND ch,03FH ; unmask invalid instruction,
; stack overflow.
OR cl,ch ; mask for IEEE exceptions
NOT cl ; make a one mean an error
MOV ch,byte ptr (CURerr+1) ; get stack over/underflow flags
TEST cx,0FFFFh-MemoryOperand ; test for errors to report
jz truncerrOK ; error is masked
xchg ax,cx ; ax = exception
jmp CommonExceptions ; handle error (??? unclean stack)
endif ;only87
endif ;QB3
ProfEnd SPEC