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.

285 lines
6.0 KiB

  1. page ,132
  2. subttl emarith.asm - Arithmetic Operations
  3. ;***
  4. ;emarith.asm -
  5. ;
  6. ; Copyright (c) 1986-89, Microsoft Corporation
  7. ;
  8. ;Purpose:
  9. ; Arithmetic Operations
  10. ;
  11. ; This Module contains Proprietary Information of Microsoft
  12. ; Corporation and should be treated as Confidential.
  13. ;
  14. ;Revision History: (Also see emulator.hst)
  15. ;
  16. ; 12/19/89 WAJ XORSIGN was not masking the sign bit correctly.
  17. ;
  18. ;*******************************************************************************
  19. ;-----------------------------------------------;
  20. ; ;
  21. ; Double precision arithmetic ;
  22. ; ;
  23. ;-----------------------------------------------;
  24. ; Inputs:
  25. ; DI = (op1) NOS (Next on stack)
  26. ; SI = (op2) TOS (Top of stack)
  27. ;
  28. ; Functions:
  29. ; ADDRQQ - Addition RESULT <-- [DI] + [SI]
  30. ; SUDRQQ - Subtract RESULT <-- [DI] - [SI]
  31. ; MUDRQQ - Multiply RESULT <-- [DI] * [SI]
  32. ; DIDRQQ - Division RESULT <-- [DI] / [SI]
  33. ; SVDRQQ - Subtract Reversed RESULT <-- [SI] - [DI]
  34. ; DRDRQQ - Division Reversed RESULT <-- [SI] / [DI]
  35. ; Outputs:
  36. ; Destination of result is in RESULT
  37. ; Registers:
  38. ; All except BP destroyed.
  39. ; Understanding this code:
  40. ;
  41. ; Assign the symbol S to SI, assign the symbol D to DI.
  42. ;
  43. ; Upon entry: SI <-- S, DI <-- D , Performing D - S
  44. ProfBegin ARITH
  45. even
  46. lab SVDRQQ ; Reverse Subtract
  47. MOV DX,Sign*256 ; DH will be flag[SI], prepare to switch sign
  48. JMP short DOADD
  49. even
  50. lab SUDRQQ ; Normal Subtract
  51. MOV DX,Sign ; DL will be flag[DI], prepare to switch sign
  52. JMP short DOADD
  53. even
  54. lab MUDRQQ ; Multiplication
  55. xor idx,idx ; Do not change signs on entry
  56. MOV ibx,offset MULJMPTAB
  57. JMP short INITIL
  58. even
  59. lab DIDRQQ ; Normal Division
  60. xor idx,idx
  61. XCHG isi,idi ; Make SI - Numerator, DI - Denominator
  62. MOV ibx,offset DIVJMPTAB
  63. JMP short INITIL
  64. even
  65. lab DRDRQQ ; Reverse Division
  66. xor idx,idx
  67. MOV ibx,offset DIVJMPTAB
  68. JMP short INITIL
  69. even
  70. lab ADDRQQ ; Double Precision Add
  71. xor idx,idx ; No signs get switched
  72. lab DOADD
  73. MOV ibx,offset ADDJMPTAB
  74. lab INITIL
  75. MOV AL,Tag[idi] ; Get tags to determine special cases.
  76. SHL AL,1
  77. SHL AL,1
  78. OR AL,Tag[isi]
  79. CBI
  80. ifdef i386
  81. SHL iax,2
  82. else
  83. SHL iax,1
  84. endif
  85. ADD ibx,iax ; BX now points to address of proper routine.
  86. XOR DH,Flag[idi] ; Sign A
  87. XOR DL,Flag[isi] ; Sign B
  88. MOV CX,Expon[idi] ; Exponent of operand A
  89. MOV AX,Expon[isi] ; Exponent of operand B
  90. JMP cs:[ibx] ; Go to appropriate routine.
  91. page
  92. ;-----------------------------------------------------------;
  93. ; ;
  94. ; Special Case Routines for Arithmetic Functions ;
  95. ; ;
  96. ;-----------------------------------------------------------;
  97. lab DDD
  98. mov isi,idi ;return DI with sign from Add/Subtract
  99. mov dl,dh
  100. lab SSS ;Return SI with sign from Add/Subtract
  101. call MOVresult
  102. MOV Flag[idi],dl ;Overstore correct Sign from Add/Subtract
  103. ret
  104. lab D0SSINV ;Return SI, set both Invalid and Zerodivide
  105. OR [CURerr],ZeroDivide
  106. JMP short SSINV
  107. lab DDINV ;Return DI and set Invalid exception
  108. MOV isi,idi
  109. lab SSINV ;Return SI and set INVALID exception
  110. OR [CURerr],Invalid
  111. jmp short MOVresult
  112. lab ZEROS ;Return 0 with xor of signs
  113. MOV isi,offset IEEEzero
  114. lab XORSIGN
  115. XOR DH,DL
  116. AND DH,80h ; Mask to just the sign.
  117. CALL csMOVresult
  118. OR Flag[idi],DH
  119. RET
  120. lab DIV0 ;Set exception, Return Infinity signed
  121. OR [CURerr],ZeroDivide
  122. lab INFS ;Return signed infinity
  123. MOV isi,offset IEEEinfinity
  124. JMP XORSIGN
  125. lab D0INDINV ;Set div 0 exception, Return Indefinate and Invalid
  126. OR [CURerr],ZeroDivide
  127. lab INDINV
  128. MOV isi,offset IEEEindefinite
  129. OR [CURerr],Invalid
  130. lab csMOVresult
  131. mov idi,[RESULT]
  132. lab csMOVRQQ ; as above for constants in CS
  133. ifdef i386
  134. MOVS dword ptr es:[idi],dword ptr cs:[isi]
  135. MOVS dword ptr es:[idi],dword ptr cs:[isi]
  136. MOVS dword ptr es:[idi],dword ptr cs:[isi]
  137. else
  138. MOVS word ptr es:[idi],word ptr cs:[isi]
  139. MOVS word ptr es:[idi],word ptr cs:[isi]
  140. MOVS word ptr es:[idi],word ptr cs:[isi]
  141. MOVS word ptr es:[idi],word ptr cs:[isi]
  142. MOVS word ptr es:[idi],word ptr cs:[isi]
  143. MOVS word ptr es:[idi],word ptr cs:[isi]
  144. endif
  145. SUB idi,Reg87Len
  146. SUB isi,Reg87Len
  147. RET
  148. lab MOVresult
  149. mov idi,[RESULT] ; move to result
  150. cmp isi,idi
  151. je short MOVret ; unless the same
  152. lab MOVRQQ
  153. ifdef i386
  154. MOVS dword ptr es:[idi],dword ptr ds:[isi]
  155. MOVS dword ptr es:[idi],dword ptr ds:[isi]
  156. MOVS dword ptr es:[idi],dword ptr ds:[isi]
  157. else
  158. MOVS word ptr es:[idi],word ptr ds:[isi]
  159. MOVS word ptr es:[idi],word ptr ds:[isi]
  160. MOVS word ptr es:[idi],word ptr ds:[isi]
  161. MOVS word ptr es:[idi],word ptr ds:[isi]
  162. MOVS word ptr es:[idi],word ptr ds:[isi]
  163. MOVS word ptr es:[idi],word ptr ds:[isi]
  164. endif
  165. SUB idi,Reg87Len
  166. SUB isi,Reg87Len
  167. lab MOVret
  168. RET
  169. lab INFINF ; Addition of two infinities was attempted
  170. TEST [CWcntl],InfinityControl ; Invalid if projective closure
  171. JSZ INDINV
  172. XOR DL,DH ; Invalid if signs are different
  173. JSS INDINV
  174. JMP DDD ; Otherwise Inf is the answer, already at DI
  175. lab BIGNAN ; Return the NAN with the Bigger mantissa
  176. mov iax, isi
  177. mov ibx, idi
  178. add isi, MantissaByteCnt-2 ; UNDONE387: Convert SNAN to QNAN
  179. add idi, MantissaByteCnt-2
  180. mov icx, MantissaByteCnt/2
  181. std
  182. repe cmps word ptr ds:[isi], word ptr es:[idi]
  183. cld
  184. JSB DDNAN
  185. mov isi, iax ; Greater NAN was in si
  186. jmp SSINV
  187. lab DDNAN
  188. mov isi, ibx ; Greater NAN was in di
  189. jmp SSINV
  190. page
  191. if fastSP
  192. ifdef i386
  193. BUG ; fastsp and i386 do not work together
  194. endif
  195. ;Assumes DL = Flag[SI], DH = Flag[DI]. Will convert the mantissa on
  196. ;stack to double if necessary by appending zeros.
  197. ;Must not change AX, DX, SI, DI.
  198. lab CoerceToDouble
  199. MOV BX,DX ; get to work reg
  200. AND BX,Single + 256*Single ; mask to single flags only
  201. JSNZ CheckDI
  202. lab CoerceToDoubleReturn
  203. RET
  204. lab CheckDI
  205. XOR BX,BX ; Prepare to zero out mantissa
  206. XCHG AX,BX
  207. TEST DH,Single
  208. JSZ CheckSI
  209. STOSW ; Zero out lower five bytes
  210. STOSW
  211. STOSB
  212. SUB DI,5 ; Reset DI
  213. lab CheckSI
  214. TEST DL,Single
  215. JZ short ExitCoerceToDouble
  216. XCHG DI,SI
  217. STOSW ; Zero out lower five bytes
  218. STOSW
  219. STOSB
  220. SUB DI,5 ; Reset DI
  221. XCHG DI,SI
  222. lab ExitCoerceToDouble
  223. XCHG AX,BX ; Reset AX
  224. XOR BX,BX ; Set zero flag to indicate results now double
  225. RET
  226. endif ;fastSP
  227. ProfEnd ARITH