196 lines
3.9 KiB
NASM
196 lines
3.9 KiB
NASM
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
|