Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

238 lines
6.0 KiB

  1. subttl emfmul.asm - Multiplication
  2. page
  3. ;*******************************************************************************
  4. ; Copyright (c) Microsoft Corporation 1991
  5. ; All Rights Reserved
  6. ;
  7. ;emfmul.asm - long double multiply
  8. ; by Tim Paterson
  9. ;
  10. ;Purpose:
  11. ; Long double multiplication.
  12. ;Inputs:
  13. ; ebx:esi = op1 mantissa
  14. ; ecx = op1 sign in bit 15, exponent in high half
  15. ; edi = pointer to op2 and result location
  16. ; [Result] = edi
  17. ;
  18. ; Exponents are unbiased. Denormals have been normalized using
  19. ; this expanded exponent range. Neither operand is allowed to be zero.
  20. ;Outputs:
  21. ; Jumps to [RoundMode] to round and store result.
  22. ;
  23. ;Revision History:
  24. ;
  25. ; [] 09/05/91 TP Initial 32-bit version.
  26. ;
  27. ;*******************************************************************************
  28. ;Dispatch table for multiply
  29. ;
  30. ;One operand has been loaded into ecx:ebx:esi ("source"), the other is
  31. ;pointed to by edi ("dest").
  32. ;
  33. ;Tag of source is shifted. Tag values are as follows:
  34. .erre TAG_SNGL eq 0 ;SINGLE: low 32 bits are zero
  35. .erre TAG_VALID eq 1
  36. .erre TAG_ZERO eq 2
  37. .erre TAG_SPCL eq 3 ;NAN, Infinity, Denormal, Empty
  38. ;Any special case routines not found in this file are in emarith.asm
  39. tFmulDisp label dword ;Source (reg) Dest (*[di])
  40. dd MulSingle ;single single
  41. dd MulDouble ;single double
  42. dd XorDestSign ;single zero
  43. dd MulSpclDest ;single special
  44. dd MulDouble ;double single
  45. dd MulDouble ;double double
  46. dd XorDestSign ;double zero
  47. dd MulSpclDest ;double special
  48. dd XorSourceSign ;zero single
  49. dd XorSourceSign ;zero double
  50. dd XorDestSign ;zero zero
  51. dd MulSpclDest ;zero special
  52. dd MulSpclSource ;special single
  53. dd MulSpclSource ;special double
  54. dd MulSpclSource ;special zero
  55. dd TwoOpBothSpcl ;special special
  56. dd XorDestSign ;Two infinities
  57. EM_ENTRY eFIMUL16
  58. eFIMUL16:
  59. push offset MulSetResult
  60. jmp Load16Int ;Returns to MulSetResult
  61. EM_ENTRY eFIMUL32
  62. eFIMUL32:
  63. push offset MulSetResult
  64. jmp Load32Int ;Returns to MulSetResult
  65. EM_ENTRY eFMUL32
  66. eFMUL32:
  67. push offset MulSetResult
  68. jmp Load32Real ;Returns to MulSetResult
  69. EM_ENTRY eFMUL64
  70. eFMUL64:
  71. push offset MulSetResult
  72. jmp Load64Real ;Returns to MulSetResult
  73. EM_ENTRY eFMULPreg
  74. eFMULPreg:
  75. push offset PopWhenDone
  76. EM_ENTRY eFMULreg
  77. eFMULreg:
  78. xchg esi,edi
  79. EM_ENTRY eFMULtop
  80. eFMULtop:
  81. mov ecx,EMSEG:[esi].ExpSgn
  82. mov ebx,EMSEG:[esi].lManHi
  83. mov esi,EMSEG:[esi].lManLo
  84. MulSetResult:
  85. mov ebp,offset tFmulDisp
  86. mov EMSEG:[Result],edi ;Save result pointer
  87. mov al,cl
  88. or al,EMSEG:[edi].bTag
  89. cmp al,bTAG_VALID
  90. .erre bTAG_VALID eq 1
  91. .erre bTAG_SNGL eq 0
  92. jz MulDouble
  93. ja TwoOpResultSet
  94. ;.erre MulSingle eq $ ;Fall into MulSingle
  95. ;*********
  96. MulSingle:
  97. ;*********
  98. mov edx,EMSEG:[edi].ExpSgn
  99. mov eax,EMSEG:[edi].lManHi
  100. ;op1 mantissa in ebx:esi, exponent in high ecx, sign in ch bit 7
  101. ;op2 high mantissa in eax, exponent in high edx, sign in dh bit 7
  102. xor ch,dh ;Compute result sign
  103. xor dx,dx ;Clear out sign and tag
  104. add ecx,edx ;Result exponent
  105. .erre TexpBias eq 0 ;Exponents not biased
  106. jo SMulBigUnderflow ;Multiplying two denormals
  107. ContSmul:
  108. ;Value in ecx is correct exponent if result is not normalized.
  109. ;If result comes out normalized, 1 will be added.
  110. mul ebx ;Compute product
  111. mov ebx,edx
  112. mov esi,eax
  113. xor eax,eax ;Extend with zero
  114. ;Result in ebx:esi:eax
  115. ;ecx = exponent minus one in high half, sign in ch
  116. or ebx,ebx ;Check for normalization
  117. jns ShiftOneBit ;In emfadd.asm
  118. add ecx,1 shl 16 ;Adjust exponent
  119. jmp EMSEG:[RoundMode]
  120. SMulBigUnderflow:
  121. or EMSEG:[CURerr],Underflow
  122. add ecx,Underbias shl 16 ;Fix up exponent
  123. test EMSEG:[CWmask],Underflow ;Is exception masked?
  124. jz ContSmul ;No, continue with multiply
  125. UnderflowZero:
  126. or EMSEG:[CURerr],Precision
  127. SignedZero:
  128. and ecx,bSign shl 8 ;Preserve sign bit
  129. xor ebx,ebx
  130. mov esi,ebx
  131. mov cl,bTAG_ZERO
  132. jmp EMSEG:[ZeroVector]
  133. ;*******************************************************************************
  134. DMulBigUnderflow:
  135. ;Overflow flag set could only occur with denormals (true exp < -32768)
  136. or EMSEG:[CURerr],Underflow
  137. test EMSEG:[CWmask],Underflow ;Is exception masked?
  138. jnz UnderflowZero ;Yes, return zero
  139. add ecx,Underbias shl 16 ;Fix up exponent
  140. jmp ContDmul ;Continue with multiply
  141. PolyMulToZero:
  142. ret ;Return the zero in registers
  143. PolyMulDouble:
  144. ;This entry point is used by polynomial evaluator.
  145. ;It checks the operand in registers for zero.
  146. cmp cl,bTAG_ZERO ;Adding to zero?
  147. jz PolyMulToZero
  148. ;*********
  149. MulDouble:
  150. ;*********
  151. mov eax,EMSEG:[edi].ExpSgn
  152. mov edx,EMSEG:[edi].lManHi
  153. mov edi,EMSEG:[edi].lManLo
  154. MulDoubleReg: ;Entry point used by transcendentals
  155. ;op1 mantissa in ebx:esi, exponent in high ecx, sign in ch bit 7
  156. ;op2 mantissa in edx:edi, exponent in high eax, sign in ah bit 7
  157. xor ch,ah ;Compute result sign
  158. xor ax,ax ;Clear out sign and tag
  159. add ecx,eax ;Result exponent
  160. .erre TexpBias eq 0 ;Exponents not biased
  161. jo DMulBigUnderflow ;Multiplying two denormals
  162. ContDmul:
  163. ;Value in ecx is correct exponent if result is not normalized.
  164. ;If result comes out normalized, 1 will be added.
  165. mov ebp,edx ;edx is used by MUL instruction
  166. ;Generate and sum partial products, from least to most significant
  167. mov eax,edi
  168. mul esi ;Lowest partial product
  169. add eax,-1 ;CY set IFF eax<>0
  170. sbb cl,cl ;Sticky bit: 0 if zero, -1 if nz
  171. xchg edi,edx ;Save high result
  172. ;First product: cl reflects low dword non-zero (sticky bit), edi has high dword
  173. mov eax,ebx
  174. mul edx
  175. add edi,eax
  176. adc edx,0 ;Sum first results
  177. xchg edx,esi ;High result to esi
  178. ;Second product: accumulated in esi:edi:cl
  179. mov eax,ebp ;Next mult. to eax
  180. mul edx
  181. add edi,eax ;Sum low results
  182. adc esi,edx ;Sum high results
  183. mov eax,ebx
  184. mov ebx,0 ;Preserve CY flag
  185. adc ebx,ebx ;Keep carry out of high sum
  186. ;Third product: accumulated in ebx:esi:edi:cl
  187. mul ebp
  188. add esi,eax
  189. adc ebx,edx
  190. mov eax,edi
  191. or al,cl ;Collapse sticky bits into eax
  192. ;Result in ebx:esi:eax
  193. ;ecx = exponent minus one in high half, sign in ch
  194. MulDivNorm:
  195. or ebx,ebx ;Check for normalization
  196. jns ShiftOneBit ;In emfadd.asm
  197. add ecx,1 shl 16 ;Adjust exponent
  198. jmp EMSEG:[RoundMode]