|
|
page ,132 subttl emarith.asm - Arithmetic Operations ;*** ;emarith.asm - ; ; Copyright (c) 1986-89, Microsoft Corporation ; ;Purpose: ; Arithmetic Operations ; ; This Module contains Proprietary Information of Microsoft ; Corporation and should be treated as Confidential. ; ;Revision History: (Also see emulator.hst) ; ; 12/19/89 WAJ XORSIGN was not masking the sign bit correctly. ; ;*******************************************************************************
;-----------------------------------------------; ; ; ; Double precision arithmetic ; ; ; ;-----------------------------------------------;
; Inputs: ; DI = (op1) NOS (Next on stack) ; SI = (op2) TOS (Top of stack) ; ; Functions: ; ADDRQQ - Addition RESULT <-- [DI] + [SI] ; SUDRQQ - Subtract RESULT <-- [DI] - [SI] ; MUDRQQ - Multiply RESULT <-- [DI] * [SI] ; DIDRQQ - Division RESULT <-- [DI] / [SI] ; SVDRQQ - Subtract Reversed RESULT <-- [SI] - [DI] ; DRDRQQ - Division Reversed RESULT <-- [SI] / [DI] ; Outputs: ; Destination of result is in RESULT ; Registers: ; All except BP destroyed.
; Understanding this code: ; ; Assign the symbol S to SI, assign the symbol D to DI. ; ; Upon entry: SI <-- S, DI <-- D , Performing D - S
ProfBegin ARITH
even
lab SVDRQQ ; Reverse Subtract MOV DX,Sign*256 ; DH will be flag[SI], prepare to switch sign JMP short DOADD
even
lab SUDRQQ ; Normal Subtract MOV DX,Sign ; DL will be flag[DI], prepare to switch sign JMP short DOADD
even
lab MUDRQQ ; Multiplication xor idx,idx ; Do not change signs on entry MOV ibx,offset MULJMPTAB JMP short INITIL
even
lab DIDRQQ ; Normal Division xor idx,idx XCHG isi,idi ; Make SI - Numerator, DI - Denominator MOV ibx,offset DIVJMPTAB JMP short INITIL
even
lab DRDRQQ ; Reverse Division xor idx,idx MOV ibx,offset DIVJMPTAB JMP short INITIL
even
lab ADDRQQ ; Double Precision Add xor idx,idx ; No signs get switched lab DOADD MOV ibx,offset ADDJMPTAB
lab INITIL MOV AL,Tag[idi] ; Get tags to determine special cases. SHL AL,1 SHL AL,1 OR AL,Tag[isi] CBI ifdef i386 SHL iax,2 else SHL iax,1 endif ADD ibx,iax ; BX now points to address of proper routine.
XOR DH,Flag[idi] ; Sign A XOR DL,Flag[isi] ; Sign B MOV CX,Expon[idi] ; Exponent of operand A MOV AX,Expon[isi] ; Exponent of operand B
JMP cs:[ibx] ; Go to appropriate routine.
page ;-----------------------------------------------------------; ; ; ; Special Case Routines for Arithmetic Functions ; ; ; ;-----------------------------------------------------------;
lab DDD mov isi,idi ;return DI with sign from Add/Subtract mov dl,dh
lab SSS ;Return SI with sign from Add/Subtract call MOVresult MOV Flag[idi],dl ;Overstore correct Sign from Add/Subtract ret
lab D0SSINV ;Return SI, set both Invalid and Zerodivide OR [CURerr],ZeroDivide JMP short SSINV
lab DDINV ;Return DI and set Invalid exception MOV isi,idi
lab SSINV ;Return SI and set INVALID exception OR [CURerr],Invalid jmp short MOVresult
lab ZEROS ;Return 0 with xor of signs MOV isi,offset IEEEzero
lab XORSIGN XOR DH,DL AND DH,80h ; Mask to just the sign. CALL csMOVresult OR Flag[idi],DH RET
lab DIV0 ;Set exception, Return Infinity signed OR [CURerr],ZeroDivide
lab INFS ;Return signed infinity MOV isi,offset IEEEinfinity JMP XORSIGN
lab D0INDINV ;Set div 0 exception, Return Indefinate and Invalid OR [CURerr],ZeroDivide
lab INDINV MOV isi,offset IEEEindefinite OR [CURerr],Invalid
lab csMOVresult mov idi,[RESULT]
lab csMOVRQQ ; as above for constants in CS ifdef i386 MOVS dword ptr es:[idi],dword ptr cs:[isi] MOVS dword ptr es:[idi],dword ptr cs:[isi] MOVS dword ptr es:[idi],dword ptr cs:[isi] else MOVS word ptr es:[idi],word ptr cs:[isi] MOVS word ptr es:[idi],word ptr cs:[isi] MOVS word ptr es:[idi],word ptr cs:[isi] MOVS word ptr es:[idi],word ptr cs:[isi] MOVS word ptr es:[idi],word ptr cs:[isi] MOVS word ptr es:[idi],word ptr cs:[isi] endif SUB idi,Reg87Len SUB isi,Reg87Len RET
lab MOVresult mov idi,[RESULT] ; move to result cmp isi,idi je short MOVret ; unless the same
lab MOVRQQ ifdef i386 MOVS dword ptr es:[idi],dword ptr ds:[isi] MOVS dword ptr es:[idi],dword ptr ds:[isi] MOVS dword ptr es:[idi],dword ptr ds:[isi] else MOVS word ptr es:[idi],word ptr ds:[isi] MOVS word ptr es:[idi],word ptr ds:[isi] MOVS word ptr es:[idi],word ptr ds:[isi] MOVS word ptr es:[idi],word ptr ds:[isi] MOVS word ptr es:[idi],word ptr ds:[isi] MOVS word ptr es:[idi],word ptr ds:[isi] endif SUB idi,Reg87Len SUB isi,Reg87Len
lab MOVret RET
lab INFINF ; Addition of two infinities was attempted TEST [CWcntl],InfinityControl ; Invalid if projective closure JSZ INDINV XOR DL,DH ; Invalid if signs are different JSS INDINV JMP DDD ; Otherwise Inf is the answer, already at DI
lab BIGNAN ; Return the NAN with the Bigger mantissa mov iax, isi mov ibx, idi
add isi, MantissaByteCnt-2 ; UNDONE387: Convert SNAN to QNAN add idi, MantissaByteCnt-2 mov icx, MantissaByteCnt/2 std repe cmps word ptr ds:[isi], word ptr es:[idi] cld JSB DDNAN
mov isi, iax ; Greater NAN was in si jmp SSINV
lab DDNAN mov isi, ibx ; Greater NAN was in di jmp SSINV
page
if fastSP
ifdef i386 BUG ; fastsp and i386 do not work together endif
;Assumes DL = Flag[SI], DH = Flag[DI]. Will convert the mantissa on ;stack to double if necessary by appending zeros. ;Must not change AX, DX, SI, DI.
lab CoerceToDouble MOV BX,DX ; get to work reg AND BX,Single + 256*Single ; mask to single flags only JSNZ CheckDI
lab CoerceToDoubleReturn RET
lab CheckDI XOR BX,BX ; Prepare to zero out mantissa XCHG AX,BX TEST DH,Single JSZ CheckSI STOSW ; Zero out lower five bytes STOSW STOSB SUB DI,5 ; Reset DI
lab CheckSI TEST DL,Single JZ short ExitCoerceToDouble XCHG DI,SI STOSW ; Zero out lower five bytes STOSW STOSB SUB DI,5 ; Reset DI XCHG DI,SI
lab ExitCoerceToDouble XCHG AX,BX ; Reset AX XOR BX,BX ; Set zero flag to indicate results now double RET
endif ;fastSP
ProfEnd ARITH
|