4 MOV EAX,DWORD PTR [BP+4]
5 MOV EDX,DWORD PTR [BP+8]
6 MOV EBX,DWORD PTR [BP+12]
7 MOV ECX,DWORD PTR [BP+16]
9 MOV DWORD PTR _facc
,EAX
10 MOV DWORD PTR _facc
+4,EDX
15 XOR ECX,#
$80000000 ; complement sign bit, fall into add routine
20 MOV EDI,ECX ; free CL for shifts
21 MOV ESI,EDX ; this mainly for consistent naming
22 AND ESI,#
$7FFFFFFF ; discard sign so comparison is simple
35 AND ESI,#
$000FFFFF ; discard exponent
37 OR ESI,#
$00100000 ; normalize
42 MOV EBP,ECX ; prepare to compare signs (want high bits 0)
43 SUB CX,DX ; get difference of signs in CX
44 NEG CX ; D holds sign and exponent of both throughout
46 JAE TO_DONE1
; x dominates y
48 AND BP,#
$0800 ; see if signs are same
49 JNZ TO_SUBTRACT
; else roundoff reg EBP is 0
60 ; result DX(1+11):SI:AX:BP:BX but needs normalization
81 ; result DX(1):CX(11):SI:AX:BP:BX
85 ; top 11 bits of ESI known 0 and BSR is slooow
86 BSR EDI,EDI ; index of leading 1 bit in EDI is 11..31 in DI
87 JZ TO_NORMLITTLE
; ESI is zero (flag wrong in Intel Manual)
101 CMP EBP,#
$80000000 ; test roundoff register
103 JB DONE
; no rounding
106 TEST AL,#
1 ; ambiguous case, round to even
107 JZ DONE
; even, no rounding
114 JNZ LOVERFLOW
; rounding may cause overflow!
117 AND DX,#
$0800 ; extract sign of largest and result
118 OR DX,CX ; include exponent with sign
121 AND ESI,#
$000FFFFF ; discard normalization bit
128 UNDERFLOW: ; should have error message here
137 LOVERFLOW: ; carry bit must be right-shifted back in
146 OVERFLOW: ; should have error message here
147 MOV EDX,#
$FFE00000 ; + infinity
165 SHLD ESI,EAX,32-(1+11)
166 SHLD EAX,EBP,32-(1+11)
167 SHLD EBP,EBX,32-(1+11)
174 SUB EBP,EBP ; set up roundoff register
176 JAE SUBTRACT_BIGSHIFT
216 MOV ESI,EDX ; free DX for multiplications
217 MOV EDI,ECX ; this mainly for consistent naming
222 AND BP,#
$0800 ; extract sign
223 AND DX,#
$07FF ; exp(x)
225 AND CX,#
$07FF ; exp(y)
231 JA TO_OVERFLOW
; probably not quite right
233 AND ESI,#
$000FFFFF ; discard sign and exponent
235 OR ESI,#
$00100000 ; normalize
238 ; exponent is in CX, sign in BP, operands in ESI:EAX and EDI:EBX, DX is free
239 ; product to go in ESI:EAX:EBP:EBX
240 ; terminology: x * y = (x32:x0) * (y32:y0) = x32y32 + x32y0 + x0y32 +x0y0
246 MOV EBP,EDX ; x0y0.high in EBP
247 XCHG EBX,EAX ; x0y0.low in EBX (final), y0 in EAX
249 PUSH EAX ; x32y0.low on stack
250 PUSH EDX ; x32y0.high on stack
253 MOV ESI,EDX ; x32y32.high in ESI (final except carries)
254 XCHG ECX,EAX ; x32y32.low in ECX, x0 in EAX
257 ADD EBP,EAX ; x0y0.high + x0y32.low
259 ADC EAX,EDX ; x32y0.high + x0y32.high
262 ADD EBP,EDX ; (x0y0.high + x0y32.low) + x32y0.low
263 ADC EAX,ECX ; (x32y0.high + x0y32.high) + x32y32.low
267 ADD CX,#
13 ; temp fixup