|
|
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
|