|
|
page ,132 subttl emfmul.asm - Multiplication ;*** ;emfmisc.asm - Multiplication ; ; Copyright (c) 1986-89, Microsoft Corporation ; ;Purpose: ; Multiplication ; ; ; This Module contains Proprietary Information of Microsoft ; Corporation and should be treated as Confidential. ; ;Revision History: ; See emulator.hst ; ;*******************************************************************************
;-----------------------------------------; ; ; ; Multiplication ; ; ; ;-----------------------------------------;
; Perform multiply by summing partial products of 16x16 hardware multiply. ; Before each multiply, the operands are checked for zero to see if it can be ; skipped, since it's a slow operation on the 8086. The sum is kept in ; registers as much as possible. Any insignificant bits lost are ORed together ; and kept in a word on the top of the stack. This can be used for sticky bit ; rounding. First we will need some macros.
ProfBegin FMUL
MULP MACRO SIOFFSET,DIOFFSET,NEXTLOC ;Will multiply the words found at the given offsets if those words ;are non-0. since we assume the numbers are normalized and the ;most significant word has offset 6 we know that words with offset ;6 are non-0 hence the conditional code in this macro.
MOV AX,SIOFFSET[esi]
IF SIOFFSET - 6 ;When SI offset is 6 it is most sig word hence not 0 OR AX,AX JZ short NEXTLOC ENDIF
IF DIOFFSET - 6 MOV DX,DIOFFSET[edi] OR DX,DX JZ short NEXTLOC MUL DX ELSE MUL WORD PTR DIOFFSET[edi] ENDIF
ENDM
ADDP MACRO HI,MID,LO ;Will add the double word result of a multiply to the triple word ; at HI:MID:LO using HI to record overflow
ADD LO,AX ADC MID,DX ADC HI,0 ENDM
STICKY MACRO R ;R is the register containing the least significant word which ;should be ORed to the sticky bit (kept on the stack) and then ;cleared so the register can be reused
POP eax OR AX,R PUSH eax XOR R,R ENDM
page
RMBRQQ: ; Routine MUL Both must see if we have two singles.
if fastSP MOV BX,DX XOR BX,Single + 256*Single TEST BX,Single + 256*Single JNZ RMDRQQ MOV BX,OFFSET TMSRQQ JMP [BX] endif ;fastSP
pub RMDRQQ ;RoutineMulDouble SI & DI point to valid non-0 reals ; AX CX are the exponents ; DL DH are the signs if fastSP CALL CoerceToDouble ; insure that both args are double endif ;fastSP
PUSH ebp ; Must save BP MOV BH,DH ; Save Single double flag XOR DH,DL ; Get sign onto stack PUSH edx ADD AX,CX ; New exponent is sum of old plus 1 INC AX ; because of the normalize step PUSH eax ; Save it while we Multiply AND BH,DL
pub PROD1 XOR BX,BX MOV BP,BX MOV CX,BX MULP 0,0,PROD2 MOV BP,AX ; Save insignificant bits MOV CX,DX pub PROD2 PUSH ebp ; Save Sticky bit on stack xor ebp, ebp ; bp is now the working high word of bp:bx:cx MULP 0,2,PROD3 ADDP BP,BX,CX pub PROD3 MULP 2,0,PROD4 ADDP BP,BX,CX
pub PROD4 STICKY CX MULP 0,4,PROD5 ADDP CX,BP,BX pub PROD5 MULP 2,2,PROD6 ADDP CX,BP,BX pub PROD6 MULP 4,0,PROD7 ADDP CX,BP,BX
pub PROD7 STICKY BX MULP 0,6,PROD8 ADDP BX,CX,BP pub PROD8 MULP 2,4,PROD9 ADDP BX,CX,BP pub PROD9 MULP 4,2,PROD10 ADDP BX,CX,BP pub PROD10 MULP 6,0,PROD11 ADDP BX,CX,BP
pub PROD11 MOV DX,BP ; Everything but guard and round go to sticky AND BP,03FFFH STICKY BP PUSH edx ; Save guard and round on stack MULP 2,6,PROD12 ADDP BP,BX,CX pub PROD12 MULP 4,4,PROD13 ADDP BP,BX,CX pub PROD13 MULP 6,2,PROD14 ADDP BP,BX,CX
pub PROD14 PUSH ecx ; Save LSW on stack (not enough registers) XOR CX,CX MULP 4,6,PROD15 ADDP CX,BP,BX pub PROD15 MULP 6,4,PROD16 ADDP CX,BP,BX
pub PROD16 MULP 6,6,PROD17 ADD AX,BP ADC DX,CX POP ecx POP ebp ; Result in DX:AX:BX:CX:BP Sticky on stack
MOV DI,DX MOV DX,CX MOV CX,BX MOV BX,AX ; Result in DI:BX:CX:DX:BP POP eax ; Merge Sticky bit into BP OR AX,AX JZ short STBITOK OR BP,1 pub STBITOK POP esi ; Exponent in SI, Sign on Stack, Old BP on Stack JMP NORMSHF ; Result must be normalized at most 1 bit
ProfEnd FMUL
|