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.

374 lines
7.4 KiB

  1. page ,132
  2. subttl emnormal.asm - Normalize and Round
  3. ;***
  4. ;emnormal.asm - Normalize and Round
  5. ;
  6. ; Copyright (c) 1986-89, Microsoft Corporation
  7. ;
  8. ;Purpose:
  9. ; Normalize and Round.
  10. ;
  11. ; This Module contains Proprietary Information of Microsoft
  12. ; Corporation and should be treated as Confidential.
  13. ;
  14. ;Revision History:
  15. ; See emulator.hst
  16. ;
  17. ;*******************************************************************************
  18. ProfBegin NORMAL
  19. ;------------------------------------------;
  20. ; ;
  21. ; Double Precision Normalize and Round ;
  22. ; ;
  23. ;------------------------------------------;
  24. even
  25. pub NODRQQ
  26. ; Normalize the double precision number
  27. ; All arithmetic operations exit through NODRQQ or RNDR7Q
  28. ; Mantissa in DI:BX:CX:DX:BP, Exponent in SI, sign on Stack, old BP on Stack
  29. MOV AL,4 ; Maximum of 4 word shifts, sign in AH(6)
  30. pub DNOR
  31. OR DI,DI ; See if any bits on in high word
  32. JNZ short HIBYT ; If so, go check high byte for zero
  33. SUB SI,16 ; Drop exponent by shift count
  34. DEC AL ; Bump count
  35. JZ short NORZERO
  36. MOV DI,BX
  37. MOV BX,CX
  38. MOV CX,DX
  39. MOV DX,BP
  40. XOR BP,BP
  41. JMP DNOR
  42. pub NORZERO ; Here if result after normalization is zero
  43. MOV esi,offset IEEEzero
  44. MOV edi,[RESULT]
  45. POP eax ; Throw out sign on stack
  46. POP ebp ; Restore Old BP
  47. JMP csMOVRQQ ; Move IEEE zero to TOS and return
  48. even
  49. pub HIBYT
  50. TEST DI,0FF00H ; See if high byte is zero
  51. JNZ short NORMSHF2
  52. SUB SI,8 ; Drop exponent by shift amount
  53. pub DN2
  54. XCHG AX,DI
  55. MOV AH,AL
  56. MOV AL,BH
  57. MOV BH,BL
  58. MOV BL,CH
  59. MOV CH,CL
  60. MOV CL,DH
  61. MOV DH,DL
  62. XCHG AX,DI
  63. XCHG AX,BP
  64. MOV DL,AH
  65. MOV AH,AL
  66. XOR AL,AL
  67. XCHG AX,BP
  68. even
  69. pub NORMSHF2
  70. TEST DI,8000H ; Normalization complete?
  71. JNZ ROUND ; Normalization complete
  72. pub NORMLP ; Have to shift left
  73. DEC SI ; Account for shift in exponent
  74. SHL BP,1
  75. RCL DX,1
  76. RCL CX,1
  77. RCL BX,1
  78. RCL DI,1
  79. TEST DI,8000H ; Check for normalized result
  80. JZ NORMLP ; Bit will be set when normalized
  81. JMP short ROUND
  82. pub ROUND24 ; Round to 24 bits
  83. OR DX,BP ; See if result fits exactly in 24 bits
  84. OR CX,DX
  85. OR CL,CH
  86. MOV CH,BL
  87. OR CX,CX
  88. JZ short JEXACT
  89. OR [CURerr],Precision ; Set flag on inexact result
  90. SHR AL,1
  91. JC short DOWNorCHOP24
  92. SHR AL,1
  93. JC short UP24
  94. pub NEAR24 ; Round to nearest or Even
  95. CMP CX,8000H
  96. JA short INC24 ; Remainder Bigger then .5 so Bump up
  97. JB short MSK24 ; Remainder Less then .5 so Mask off
  98. TEST BH,1 ; Remainder = .5 so see if even
  99. JZ short MSK24 ; When even Mask
  100. JMP short INC24 ; When odd Bump up
  101. pub UP24
  102. POP eax ; Get the sign
  103. PUSH eax
  104. SHL AH,1
  105. JC short MSK24 ; Trunc neg numbers to move toward + Inf
  106. JMP short INC24
  107. pub DOWNorCHOP24
  108. SHR AL,1
  109. JC short CHOP24
  110. pub DOWN24
  111. POP eax ; Get the sign
  112. PUSH eax
  113. SHL AH,1
  114. JC short INC24
  115. JMP short MSK24 ; Trunc Pos numbers to move toward - Inf
  116. pub INC24
  117. ADD BH,1
  118. ADC DI,0
  119. JNC short MSK24
  120. MOV DI,8000H ; Number overflowed from 1,111... to 10,000...
  121. INC SI ; Bump up Exponent
  122. pub CHOP24
  123. MSK24: ; Mask off insignificant bits
  124. XOR BP,BP
  125. MOV DX,BP
  126. MOV CX,DX
  127. MOV BL,CL
  128. pub JEXACT
  129. JMP EXACT
  130. even
  131. pub NORMSHF ; from multiply only
  132. TEST DI,8000H ; Normalization complete?
  133. JNZ ROUND ; Normalization complete
  134. DEC SI ; Account for shift in exponent
  135. SHL BP,1
  136. RCL DX,1
  137. RCL CX,1
  138. RCL BX,1
  139. RCL DI,1
  140. even
  141. ; mantissa in DI:BX:CX:DX:BP
  142. pub ROUND ; Drop into ROUND when normalized
  143. MOV AL,[CWcntl] ; Pick up hi byte of control word
  144. SHR AL,1 ; Which has Rounding & Precision Control
  145. jnc short ROUND53
  146. pub ROUND64 ; Round to 64 bits
  147. SHR AL,1 ; Remove other bit of Precision control
  148. OR BP,BP ; See if result fits exactly in 64 bits
  149. JZ short EXACT
  150. OR [CURerr],Precision ; Set flag on inexact result
  151. SHR AL,1
  152. JC short DOWNorCHOP64
  153. SHR AL,1
  154. JC short UP64
  155. pub NEAR64 ; Round to nearest or Even
  156. CMP BP,8000H
  157. JA short INC64 ; Remainder Bigger then .5 so Bump up
  158. JB short MSK64 ; Remainder Less then .5 so Mask off
  159. TEST DL,1 ; Remainder = .5 so see if even
  160. JZ short MSK64 ; When even Mask
  161. pub INC64
  162. XOR BP,BP ; Need a 0
  163. ADD DX,1
  164. ADC CX,BP
  165. ADC BX,BP
  166. ADC DI,BP
  167. JNC short EXACT
  168. MOV DI,8000H ; Number overflowed from 1,111... to 10,000...
  169. INC SI ; Bump up Exponent
  170. even
  171. CHOP64:
  172. MSK64: ; Mask off insignificant bits
  173. pub EXACT
  174. MOV eax,[RESULT]
  175. XCHG eax,edi
  176. MOV MB0[edi],DX ; Save Mantissa
  177. MOV MB2[edi],CX
  178. MOV MB4[edi],BX
  179. MOV MB6[edi],AX
  180. POP eax ; Fetch Sign
  181. POP ebp ; Fetch Old BP
  182. AND AH,Sign ; Mask off single precision
  183. MOV Flag[edi],AH
  184. CMP SI,IexpMax - IexpBias ; Test for overflow
  185. JGE short jOVER
  186. CMP SI,IexpMin - IexpBias ; Test for Underflow
  187. JLE short UNDER
  188. pub NORTAG
  189. MOV Expon[edi],SI
  190. MOV byte ptr Tag[edi],0 ; Number is in range and on TOS so ret
  191. RET
  192. jOVER: jmp OVER
  193. pub UP64
  194. POP eax ; Get the sign
  195. PUSH eax
  196. SHL AH,1
  197. JC short MSK64 ; Trunc neg numbers to move toward + Inf
  198. JMP short INC64
  199. pub DOWNorCHOP64
  200. SHR AL,1
  201. JC short CHOP64
  202. pub DOWN64
  203. POP eax ; Get the sign
  204. PUSH eax
  205. SHL AH,1
  206. JC short INC64
  207. JMP short MSK64 ; Trunc Pos numbers to move toward - Inf
  208. jROUND24:
  209. jmp ROUND24
  210. pub ROUND53 ; Round to 53 bits (or 24)
  211. SHR AL,1
  212. JNC short jROUND24
  213. XCHG BP,AX ; See if result fits exactly in 53 bits
  214. OR AL,AH
  215. OR AL,DL
  216. MOV AH,DH
  217. AND AH,007H
  218. AND DH,0F8H
  219. XCHG BP,AX
  220. OR BP,BP
  221. JZ EXACT
  222. OR [CURerr],Precision ; Set flag on inexact result
  223. SHR AL,1
  224. JC short DOWNorCHOP53
  225. SHR AL,1
  226. JC short UP53
  227. pub NEAR53 ; Round to nearest or Even
  228. CMP BP,0400H
  229. JA short INC53 ; Remainder Bigger then .5 so Bump up
  230. JB short MSK53 ; Remainder Less then .5 so Mask off
  231. TEST DH,08H ; Remainder = .5 so see if even
  232. JZ short MSK53 ; When even Mask
  233. JMP short INC53 ; When odd Bump up
  234. pub UNDER
  235. MUNDER: ; Masked Underflow
  236. MOV esi,offset IEEEzero
  237. CALL csMOVRQQ
  238. MOV Flag[edi],AH ; Overstore correct sign
  239. RET
  240. pub UP53
  241. POP eax ; Get the sign
  242. PUSH eax
  243. SHL AH,1
  244. JC short MSK53 ; Trunc neg numbers to move toward + Inf
  245. JMP short INC53
  246. pub DOWNorCHOP53
  247. SHR AL,1
  248. JC short CHOP53
  249. pub DOWN53
  250. POP eax ; Get the sign
  251. PUSH eax
  252. SHL AH,1
  253. JC short INC53
  254. JMP short MSK53 ; Trunc Pos numbers to move toward - Inf
  255. pub INC53
  256. XOR BP,BP ; Need a 0
  257. ADD DH,08H
  258. ADC CX,BP
  259. ADC BX,BP
  260. ADC DI,BP
  261. JNC short MSK53
  262. MOV DI,8000H ; Number overflowed from 1,111... to 10,000...
  263. INC SI ; Bump up Exponent
  264. pub CHOP53
  265. MSK53: ; Mask off insignificant bits
  266. XOR BP,BP
  267. XOR DL,DL ; Note: The garbage in DH was masked off at ROUND53
  268. JMP EXACT
  269. PAGE
  270. pub OVER ; Here if number overflowed
  271. MOVER: ; The masked response to rounding depends on whether rounding
  272. ; is directed or not. If it is then Overflow flag is not set
  273. ; but precision is. Also the result is set to Inf or Biggest
  274. ; If rounding is not directed then Overflow is set and result
  275. ; is set to Inf.
  276. OR [CURerr],Overflow
  277. MOV AL,[CWcntl]
  278. SHR AL,1
  279. SHR AL,1
  280. SHR AL,1
  281. JC short MOvDNorCHP
  282. SHR AL,1
  283. JC short MOvUP
  284. MOvNEAR: ; Masked Overflow Near Rounding
  285. pub SignedInfinity ; Return signed infinity
  286. MOV esi,offset IEEEinfinity
  287. CALL csMOVRQQ
  288. MOV Flag[edi],AH ; Overstore the proper sign
  289. RET
  290. pub MOvDNorCHP
  291. SHR AL,1
  292. JC short MOvCHOP
  293. pub MOvDOWN ; Masked Overflow Down Rounding
  294. OR [CURerr],Precision
  295. TEST AH,Sign ; Positive goes to biggest
  296. JNZ short SignedInfinity
  297. MOvCHOP: ; Masked Overflow Chop Rounding
  298. pub SignedBiggest
  299. MOV esi,offset IEEEbiggest
  300. CALL csMOVRQQ
  301. MOV Flag[edi],AH ; Overstore the proper sign
  302. RET
  303. pub MOvUP ; Masked Overflow Up Rounding
  304. OR [CURerr],Precision
  305. TEST AH,Sign ; Negative goes to biggest
  306. JZ short SignedInfinity
  307. JMP SignedBiggest
  308. ProfEnd NORMAL