|
|
page ,132 subttl emnormal.asm - Normalize and Round ;*** ;emnormal.asm - Normalize and Round ; ; Copyright (c) 1986-89, Microsoft Corporation ; ;Purpose: ; Normalize and Round. ; ; This Module contains Proprietary Information of Microsoft ; Corporation and should be treated as Confidential. ; ;Revision History: ; See emulator.hst ; ;*******************************************************************************
ProfBegin NORMAL
;------------------------------------------; ; ; ; Double Precision Normalize and Round ; ; ; ;------------------------------------------;
even
pub NODRQQ ; Normalize the double precision number ; All arithmetic operations exit through NODRQQ or RNDR7Q ; Mantissa in DI:BX:CX:DX:BP, Exponent in SI, sign on Stack, old BP on Stack
MOV AL,4 ; Maximum of 4 word shifts, sign in AH(6) pub DNOR OR DI,DI ; See if any bits on in high word JNZ short HIBYT ; If so, go check high byte for zero SUB SI,16 ; Drop exponent by shift count DEC AL ; Bump count JZ short NORZERO MOV DI,BX MOV BX,CX MOV CX,DX MOV DX,BP XOR BP,BP JMP DNOR
pub NORZERO ; Here if result after normalization is zero MOV esi,offset IEEEzero MOV edi,[RESULT] POP eax ; Throw out sign on stack POP ebp ; Restore Old BP JMP csMOVRQQ ; Move IEEE zero to TOS and return
even
pub HIBYT TEST DI,0FF00H ; See if high byte is zero JNZ short NORMSHF2 SUB SI,8 ; Drop exponent by shift amount
pub DN2 XCHG AX,DI MOV AH,AL MOV AL,BH MOV BH,BL MOV BL,CH MOV CH,CL MOV CL,DH MOV DH,DL XCHG AX,DI XCHG AX,BP MOV DL,AH MOV AH,AL XOR AL,AL XCHG AX,BP
even
pub NORMSHF2 TEST DI,8000H ; Normalization complete? JNZ ROUND ; Normalization complete
pub NORMLP ; Have to shift left DEC SI ; Account for shift in exponent SHL BP,1 RCL DX,1 RCL CX,1 RCL BX,1 RCL DI,1 TEST DI,8000H ; Check for normalized result JZ NORMLP ; Bit will be set when normalized JMP short ROUND
pub ROUND24 ; Round to 24 bits OR DX,BP ; See if result fits exactly in 24 bits OR CX,DX OR CL,CH MOV CH,BL OR CX,CX JZ short JEXACT OR [CURerr],Precision ; Set flag on inexact result SHR AL,1 JC short DOWNorCHOP24 SHR AL,1 JC short UP24
pub NEAR24 ; Round to nearest or Even CMP CX,8000H JA short INC24 ; Remainder Bigger then .5 so Bump up JB short MSK24 ; Remainder Less then .5 so Mask off TEST BH,1 ; Remainder = .5 so see if even JZ short MSK24 ; When even Mask JMP short INC24 ; When odd Bump up
pub UP24 POP eax ; Get the sign PUSH eax SHL AH,1 JC short MSK24 ; Trunc neg numbers to move toward + Inf JMP short INC24
pub DOWNorCHOP24 SHR AL,1 JC short CHOP24
pub DOWN24 POP eax ; Get the sign PUSH eax SHL AH,1 JC short INC24 JMP short MSK24 ; Trunc Pos numbers to move toward - Inf
pub INC24 ADD BH,1 ADC DI,0 JNC short MSK24 MOV DI,8000H ; Number overflowed from 1,111... to 10,000... INC SI ; Bump up Exponent
pub CHOP24 MSK24: ; Mask off insignificant bits XOR BP,BP MOV DX,BP MOV CX,DX MOV BL,CL pub JEXACT JMP EXACT
even
pub NORMSHF ; from multiply only TEST DI,8000H ; Normalization complete? JNZ ROUND ; Normalization complete
DEC SI ; Account for shift in exponent SHL BP,1 RCL DX,1 RCL CX,1 RCL BX,1 RCL DI,1
even ; mantissa in DI:BX:CX:DX:BP
pub ROUND ; Drop into ROUND when normalized MOV AL,[CWcntl] ; Pick up hi byte of control word SHR AL,1 ; Which has Rounding & Precision Control jnc short ROUND53
pub ROUND64 ; Round to 64 bits SHR AL,1 ; Remove other bit of Precision control OR BP,BP ; See if result fits exactly in 64 bits JZ short EXACT OR [CURerr],Precision ; Set flag on inexact result SHR AL,1 JC short DOWNorCHOP64 SHR AL,1 JC short UP64
pub NEAR64 ; Round to nearest or Even CMP BP,8000H JA short INC64 ; Remainder Bigger then .5 so Bump up JB short MSK64 ; Remainder Less then .5 so Mask off TEST DL,1 ; Remainder = .5 so see if even JZ short MSK64 ; When even Mask
pub INC64 XOR BP,BP ; Need a 0 ADD DX,1 ADC CX,BP ADC BX,BP ADC DI,BP JNC short EXACT
MOV DI,8000H ; Number overflowed from 1,111... to 10,000... INC SI ; Bump up Exponent
even
CHOP64: MSK64: ; Mask off insignificant bits
pub EXACT MOV eax,[RESULT] XCHG eax,edi MOV MB0[edi],DX ; Save Mantissa MOV MB2[edi],CX MOV MB4[edi],BX MOV MB6[edi],AX POP eax ; Fetch Sign POP ebp ; Fetch Old BP AND AH,Sign ; Mask off single precision MOV Flag[edi],AH
CMP SI,IexpMax - IexpBias ; Test for overflow JGE short jOVER CMP SI,IexpMin - IexpBias ; Test for Underflow JLE short UNDER
pub NORTAG MOV Expon[edi],SI MOV byte ptr Tag[edi],0 ; Number is in range and on TOS so ret RET
jOVER: jmp OVER
pub UP64 POP eax ; Get the sign PUSH eax SHL AH,1 JC short MSK64 ; Trunc neg numbers to move toward + Inf JMP short INC64
pub DOWNorCHOP64 SHR AL,1 JC short CHOP64
pub DOWN64 POP eax ; Get the sign PUSH eax SHL AH,1 JC short INC64 JMP short MSK64 ; Trunc Pos numbers to move toward - Inf
jROUND24: jmp ROUND24
pub ROUND53 ; Round to 53 bits (or 24) SHR AL,1 JNC short jROUND24
XCHG BP,AX ; See if result fits exactly in 53 bits OR AL,AH OR AL,DL MOV AH,DH AND AH,007H AND DH,0F8H XCHG BP,AX OR BP,BP JZ EXACT OR [CURerr],Precision ; Set flag on inexact result SHR AL,1 JC short DOWNorCHOP53 SHR AL,1 JC short UP53
pub NEAR53 ; Round to nearest or Even CMP BP,0400H JA short INC53 ; Remainder Bigger then .5 so Bump up JB short MSK53 ; Remainder Less then .5 so Mask off TEST DH,08H ; Remainder = .5 so see if even JZ short MSK53 ; When even Mask JMP short INC53 ; When odd Bump up
pub UNDER MUNDER: ; Masked Underflow MOV esi,offset IEEEzero CALL csMOVRQQ MOV Flag[edi],AH ; Overstore correct sign RET
pub UP53 POP eax ; Get the sign PUSH eax SHL AH,1 JC short MSK53 ; Trunc neg numbers to move toward + Inf JMP short INC53
pub DOWNorCHOP53 SHR AL,1 JC short CHOP53
pub DOWN53 POP eax ; Get the sign PUSH eax SHL AH,1 JC short INC53 JMP short MSK53 ; Trunc Pos numbers to move toward - Inf
pub INC53 XOR BP,BP ; Need a 0 ADD DH,08H ADC CX,BP ADC BX,BP ADC DI,BP JNC short MSK53
MOV DI,8000H ; Number overflowed from 1,111... to 10,000... INC SI ; Bump up Exponent
pub CHOP53 MSK53: ; Mask off insignificant bits XOR BP,BP XOR DL,DL ; Note: The garbage in DH was masked off at ROUND53 JMP EXACT
PAGE
pub OVER ; Here if number overflowed MOVER: ; The masked response to rounding depends on whether rounding ; is directed or not. If it is then Overflow flag is not set ; but precision is. Also the result is set to Inf or Biggest ; If rounding is not directed then Overflow is set and result ; is set to Inf.
OR [CURerr],Overflow MOV AL,[CWcntl] SHR AL,1 SHR AL,1 SHR AL,1 JC short MOvDNorCHP
SHR AL,1 JC short MOvUP
MOvNEAR: ; Masked Overflow Near Rounding
pub SignedInfinity ; Return signed infinity
MOV esi,offset IEEEinfinity CALL csMOVRQQ MOV Flag[edi],AH ; Overstore the proper sign RET
pub MOvDNorCHP SHR AL,1 JC short MOvCHOP
pub MOvDOWN ; Masked Overflow Down Rounding OR [CURerr],Precision TEST AH,Sign ; Positive goes to biggest JNZ short SignedInfinity
MOvCHOP: ; Masked Overflow Chop Rounding pub SignedBiggest MOV esi,offset IEEEbiggest CALL csMOVRQQ MOV Flag[edi],AH ; Overstore the proper sign RET
pub MOvUP ; Masked Overflow Up Rounding OR [CURerr],Precision TEST AH,Sign ; Negative goes to biggest JZ short SignedInfinity JMP SignedBiggest
ProfEnd NORMAL
|