windows-nt/Source/XPSP1/NT/base/mvdm/wow16/win87em/emlsdbl.asm

443 lines
8.6 KiB
NASM
Raw Permalink Normal View History

2020-09-26 03:20:57 -05:00
page ,132
subttl emlsdbl.asm - Load/Store Double Precision Numbers
;***
;emlsdbl.asm - Load/Store Double Precision Numbers
;
; Copyright (c) 1986-89, Microsoft Corporation
;
;Purpose:
; Load/Store Double Precision Numbers
;
; This Module contains Proprietary Information of Microsoft
; Corporation and should be treated as Confidential.
;
;Revision History:
; See emulator.hst
;
;*******************************************************************************
;*********************************************************************;
; ;
; Load Double Real ;
; ;
;*********************************************************************;
;
; Subroutine pushes double internal with double IEEE format at ES:SI
ProfBegin LSDBL
FLDSTOver:
xchg edi, esi ; di = TOS, es:si = double in memory
call OverStk
xchg edi, esi ; di = TOS, es:si = double in memory
jmp short FLDSTOk
even
pub eFLDdr
mov edi, [CURstk] ; Get current register
cmp edi, [LIMstk] ; Is current register the last register?
jae short FLDSTOver ; Then report overflow.
FLDSTOk:
add edi, Reg87Len ; Move to next free register.
mov [CURstk], edi ; Update current top of stack
LDUS2AX
mov bp, ax
LDUS2AX
mov dx, ax
LDUS2AX
mov cx, ax
LDUS2AX ; get final 2 bytes of source
mov esi, edi ; ds:si = TOS
mov bx, ax ; Double in bx:cx:dx:bp
; assume we have a valid non-zero number so normalize and store
SHL BP,1
RCL DX,1
RCL CX,1
RCL BX,1
SHL BP,1
RCL DX,1
RCL CX,1
RCL BX,1
SHL BP,1
RCL DX,1
RCL CX,1
RCL BX,1
OR BL,80H ; Set leading bit of mantissa
MOV MB7[esi],BL
MOV MB5[esi],CX
MOV MB3[esi],DX
MOV MB1[esi],BP
OR CX,BP ; Will need to determine if number is 0 later
OR CX,DX ; so mash all the bits together
MOV DH,AH
AND DH,Sign ; Mask everything but sign
MOV Flag[esi],DH ; and store
XOR DH,DH ; Clear for Tag
MOV MB0[esi],DH ; Also clear out least significant byte
AND AH,7FH ; Remove sign from exponent
SHR AX,1 ; Adjust
SHR AX,1
SHR AX,1
SHR AX,1
CMP AX,DexpMax ; See if number is NAN or Inf
JE short DNANorInf
CMP AX,DexpMin ; See if number is Zero or Denormal
JE short DZeroorDenorm
SUB AX,DexpBias ; Unbias exponent
pub DStoreExpnTag
MOV Expon[esi],AX
MOV Tag[esi],DH
RET
pub DNANorInf
MOV AX,IexpMax - IexpBias ; Set exponent to internal max
MOV DH,Special ; Set Tag to show NAN or Inf
CMP BL,80H ; If anything other than leading bit
JNE short DStoreExpnTag ; is set number is NAN (not Inf)
OR CX,CX
JNE DStoreExpnTag
OR DH,ZROorINF ; Set Tag to show Inf
JMP DStoreExpnTag
pub DZeroorDenorm
CMP BL,80H ; If anything other than leading bit
JNE short DDenormal ; is set number is Denormal
OR CX,CX
JNE short DDenormal
MOV AX,IexpMin - IexpBias ; Set exponent to internal min
MOV DH,ZROorINF ; Set Tag to show 0
JMP DStoreExpnTag
pub DDenormal
OR [CURerr],Denormal ; Set Denormal Exception
SUB AX,DexpBias ; unbias the Exponent
MOV BP,MB0[esi] ; must refetch mantissa and normalize
MOV DX,MB2[esi]
MOV CX,MB4[esi]
MOV BX,MB6[esi]
INC AX ; Shift once if exp = expmin
pub DNormalize
DEC AX ; Drop exponent
SHL BP,1 ; Shift mantissa
RCL DX,1
RCL CX,1
RCL BX,1
OR BX,BX
JNS DNormalize
MOV MB0[esi],BP ; Store mantissa
MOV MB2[esi],DX
MOV MB4[esi],CX
MOV MB6[esi],BX
XOR DH,DH ; Clear Tag
JMP DStoreExpnTag
page
;*********************************************************************;
; ;
; Store Double Real ;
; ;
;*********************************************************************;
;
pub DSpecial
TEST CL,Special ; NAN or INF?
JNE short DDNANorINF
XOR AX,AX ; Number is zero
STAX2US
STAX2US
STAX2US
STAX2US
JMP DCommonExit
pub DDNANorINF
TEST CL,ZROorINF
JNE short DInf
MOV DX,MB1[esi] ; Number is a NAN
MOV BX,MB3[esi] ; Fetch Mantissa
MOV AX,MB5[esi]
MOV CL,MB7[esi]
SHR CL,1 ; Shift into place
RCR AX,1
RCR BX,1
RCR DX,1
SHR CL,1
RCR AX,1
RCR BX,1
RCR DX,1
SHR CL,1
RCR AX,1
RCR BX,1
RCR DX,1
; Now store the Mantissa
XCHG DX,AX
STAX2US
MOV AX,BX
STAX2US
MOV AX,DX
STAX2US
MOV BH,Flag[esi] ; Pick up Sign
AND BH,Sign
MOV AX,DexpMax*16 ; Load shifted max exponent
OR AH,BH ; Merge in sign
OR AL,CL ; Merge in top bits of Mantissa
STAX2US
JMP DCommonExit
pub DInf
MOV BL,Flag[esi]
AND BL,Sign
JMP DSignedInfinity
pub JMPDOver
JMP DOver
pub JMPDUnder
JMP DUnder
pub JMPDSpecial
JMP DSpecial
even
pub eFSTdr
; internal TOS register at DS:SI to double IEEE in memory at ES:DI
MOV edi,esi ; 10 save target memory offset
MOV esi,[CURstk] ; 14 source offset is current TOS
MOV CL,Tag[esi] ; See if number is NAN, Inf, or 0
OR CL,CL
JNZ short JMPDSpecial
MOV CL,Flag[esi] ; Pick up sign
if fastSP
TEST CL,Single
JZ DD1
MOV word ptr MB0[esi],0
MOV word ptr MB2[esi],0
MOV byte ptr MB4[esi],0
DD1:
endif
MOV BP,Expon[esi] ; See if we blatently over or under flow
CMP BP,DexpMax - DexpBias
JGE JMPDOver
CMP BP,DexpMin - DexpBias
JLE JMPDUnder
;Since we won't have room to decide about rounding after we load
;the mantissa we will determine the rounding style first
MOV AL,MB0[esi] ; Low byte becomes sticky bit ...
MOV DX,MB1[esi] ; when combined with lo 2 bits of next byte
OR AL,AL
JZ short NOSTK
OR DL,1
pub NOSTK
TEST DL,7H ; See if anything will be chopped off in truncation
JZ short DTRUNC
OR [CURerr],Precision ; number is not exact so set flag and round
MOV AL,[CWcntl] ; Pick up rounding control
; Mantissa gets incremented for rounding only on these conditions:
; (UP and +) or (DOWN and -) or
; (NEAR and Roundbit and (Sticky or Oddlastbit))
SHR AL,1
SHR AL,1
SHR AL,1
JC short StDOWNorCHOP53
SHR AL,1
JC short StUP53
pub StNEAR53
TEST DL,4H ; 3rd bit over is round bit
JZ short DTRUNC
TEST DL,0BH ; 4th bit is last bit, 1st and 2nd are Sticky
JZ short DTRUNC
pub DINC ; Know we must increment mantissa so
MOV BX,MB3[esi] ; Fetch mantissa
MOV AX,MB5[esi]
MOV CL,MB7[esi]
AND CL,7FH ; Mask off leading bit
ADD DX,8H ; Add 1 to what will be last bit after the shift
ADC BX,0
ADC AX,0
ADC CL,0
JNS short DShift
AND CL,7FH ; Mask off leading bit
INC BP ; Increment exponent
CMP BP,DexpMax - DexpBias
JL short DShift ; And test for the rare chance we went over
JMP short DOverReset
even
pub StUP53
SHL CL,1 ; Test sign
JNC short DINC ; UP and + means inc
JMP SHORT DTRUNC
pub StDOWNorCHOP53
SHR AL,1
JC short StCHOP53
pub StDOWN53
SHL CL,1 ; Test sign
JC short DINC ; DOWN and - means inc
StCHOP53:
pub DTRUNC
MOV BX,MB3[esi] ; Fetch mantissa
MOV AX,MB5[esi]
MOV CL,MB7[esi]
AND CL,7FH ; Mask off leading bit
pub DShift
SHR CL,1
RCR AX,1
RCR BX,1
RCR DX,1
SHR CL,1
RCR AX,1
RCR BX,1
RCR DX,1
SHR CL,1
RCR AX,1
RCR BX,1
RCR DX,1
; Now store the Mantissa
XCHG DX,AX
STAX2US
MOV AX,BX
STAX2US
MOV AX,DX
STAX2US
MOV AX,BP ; Merge in the exponent
ADD AX,DexpBias ; Bias exponent
SHL AX,1 ; Shift into position
SHL AX,1
SHL AX,1
SHL AX,1
OR AL,CL ; Merge in top bits of Mantissa
MOV CL,Flag[esi] ; Pick up sign
AND CL,Sign
OR AH,CL ; Merge in the sign
STAX2US
pub DCommonExit
RET ; 8 return
pub DOverReset ; We come here if we stored 6 bytes of mantissa
; befor detecting overflow so must reset pointer
SUB edi,6 ; to double in memory
pub DOver ; Here on overflow
OR [CURerr],Overflow + Precision
MOV BL,Flag[esi]
AND BL,Sign ; Mask to sign
MOV CL,[CWcntl] ; Determine rounding style
SHR CL,1
SHR CL,1
SHR CL,1
JC short StMOVDNorCHP53
SHR CL,1
JC short StMOVUP53
StMOVNEAR53:
pub DSignedInfinity
MOV esi,offset IEEEinfinityD
pub DStore
csMVSI2US
csMVSI2US
csMVSI2US
LODS word ptr cs:[esi]
OR AH,BL ;Overstore correct sign
STAX2US
JMP DCommonExit
pub StMOVDNorCHP53
SHR CL,1
JC short StMOVCHOP53
pub StMOVDOWN53
OR BL,BL ; DOWN and + means biggest
JNZ short DSignedInfinity
StMOVCHOP53:
pub DSignedBiggest
MOV esi,offset IEEEbiggestD
JMP DStore
pub StMOVUP53
OR BL,BL ; UP and - means biggest
JZ DSignedInfinity
JMP DSignedBiggest
pub DUnder
OR [CURerr],Underflow+Precision ; Set flag
ADD BP,DexpBias ; Bias the exponent which was less than
NEG BP ; Min = 0 so convert to positive difference
ifdef i386
movzx ecx,BP ; Convert to shift count
else
MOV CX,BP ; Convert to shift count
endif
ADD ecx,4 ; 3 for Double format 1 to expose hidden bit
MOV DH,Flag[esi] ; Need and exp of 0 for denormal
AND DH,Sign
MOV DL,MB7[esi]
MOV BX,MB5[esi]
MOV BP,MB3[esi]
MOV AX,MB1[esi]
pub DshiftLoop
SHR DL,1
RCR BX,1
RCR BP,1
RCR AX,1
LOOP DshiftLoop
STAX2US
MOV AX,BP
STAX2US
MOV AX,BX
STAX2US
MOV AX,DX
STAX2US
JMP DCommonExit
ProfEnd LSDBL