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.

333 lines
7.4 KiB

  1. page ,132
  2. subttl emlssng.asm - Load/Store Single Precision Numbers
  3. ;***
  4. ;emlssng.asm - Load/Store Single Precision Numbers
  5. ;
  6. ; Copyright (c) 1984-89, Microsoft Corporation
  7. ;
  8. ;Purpose:
  9. ; Load/Store Single Precision Numbers
  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 LSSNG
  19. ;*********************************************************************;
  20. ; ;
  21. ; Load Single Real ;
  22. ; ;
  23. ;*********************************************************************;
  24. ;
  25. ; Subroutine converts single in regs to internal at ES:SI
  26. pub eFLDsr
  27. LDUS2AX ; get lower mantissa part
  28. MOV DI,AX ; 2 keep lower mantissa in DX
  29. LDUS2AX ; get upper exponent/sign part
  30. MOV DL,AL ; 2 copy most sig. mantissa byte
  31. ROL AX,1 ; 2 sign to AL, exponent to AH
  32. AND AL,1 ; 4 clear all flags except sign
  33. ROR AL,1 ; 2 get sign in right position
  34. XCHG AL,AH
  35. ; AX, DI, DL: operand one
  36. PUSHST ; 64 allocate another register
  37. pub SingleToInternal
  38. OR DL,80H ; Set leading bit of mantissa
  39. XOR DH,DH ; Set Tag to valid non-zero
  40. CMP AL,SexpMax ; Is Number NAN or Inf?
  41. JE short SNANorInf
  42. if fastSP
  43. OR AH,Single ; Set single Precision flag
  44. endif
  45. CMP AL,SexpMin ; Is Number Zero or Denormal
  46. JE short SZeroOrDenorm
  47. ; Otherwise number is valid non-zero
  48. MOV Flag[esi],AH ; Store sign
  49. SUB AL,SexpBias ; Unbias the exponent
  50. CBW
  51. pub SStoreExpnTag
  52. MOV Expon[esi],AX ; Store Exponent
  53. MOV Tag[esi],DH ; Store Tag
  54. MOV MB7[esi],DL ; Store Mantissa
  55. MOV MB5[esi],DI
  56. ife fastSP
  57. XOR AX,AX ; Clear low order bytes of Mantissa
  58. MOV MB4[esi],AL
  59. MOV MB2[esi],AX
  60. MOV MB0[esi],AX
  61. endif
  62. RET
  63. pub SNANorInf
  64. MOV Flag[esi],AH ; Store sign
  65. MOV AX,IexpMax - IexpBias ; Set exponent to internal max
  66. MOV DH,Special ; Set Tag to show NAN or Inf
  67. CMP DL,80H ; If anything other than leading bit
  68. JNE short SStoreExpnTag ; is set number is NAN (not Inf)
  69. OR DI,DI
  70. JNE short SStoreExpnTag
  71. OR DH,ZROorINF ; Set Tag to show Inf
  72. JMP SStoreExpnTag
  73. pub SZeroorDenorm
  74. MOV Flag[esi],AH ; Store sign
  75. CMP DL,80H ; If anything other than leading bit
  76. JNE short SDenormal ; is set number is Denormal
  77. OR DI,DI
  78. JNE short SDenormal
  79. MOV AX,IexpMin - IexpBias ; Set exponent to internal min
  80. OR DH,ZROorINF ; Set Tag to show 0
  81. JMP SStoreExpnTag
  82. pub SDenormal
  83. OR [CURerr],Denormal ; Set Denormal Exception
  84. SUB AL,SexpBias ; unbias the Exponent
  85. CBW
  86. INC AX
  87. pub SNormalize
  88. DEC AX
  89. SHL DI,1
  90. RCL DL,1
  91. OR DL,DL
  92. JNS SNormalize
  93. JMP SStoreExpnTag
  94. page
  95. ;************************************************************;
  96. ; ;
  97. ; Store Single Real ;
  98. ; ;
  99. ;************************************************************;
  100. pub SSpecial ; number is NAN or INF or Zero
  101. TEST CL,Special ; NAN or INF?
  102. JNE short SSNANorINF
  103. XOR AX,AX ; Number is Zero
  104. MOV BX,AX
  105. JMP STRUNC
  106. pub SSNANorINF
  107. TEST CL,ZROorINF
  108. JNE short SInf
  109. MOV BX,MB5[esi] ; Number is a NAN
  110. MOV AL,MB7[esi]
  111. MOV AH,Flag[esi] ; Pick up Sign
  112. SHL AX,1 ; Destroy leading bit, Sign to CF
  113. MOV AH,SexpMax
  114. RCR AX,1
  115. JMP STRUNC
  116. pub SInf
  117. MOV AH,Flag[esi]
  118. JMP SSignedInfinity
  119. pub JMPSOver
  120. JMP SOver
  121. pub JMPSUnder
  122. JMP SUnder
  123. ; ES:SI: memory address of single
  124. ; stores and misc. operations; first setup register values as follows:
  125. ; AX: TOS flags (for DOUB and SIGN flags)
  126. ; SI: TOS address (offset)
  127. pub eFSTsr
  128. mov edi,esi ; ES:DI = store address
  129. MOV esi,[CURstk] ; 14 load TOS address
  130. MOV AX,Flag[esi] ; 21 get TOS flags (sign, double)
  131. ; convert internal at DS:SI to single
  132. ; DS:SI = TOS, ES:DI = memory, CH = operation (POP), BP = old ES value
  133. MOV CL,Tag[esi] ; See if number is NAN or Inf or Zero
  134. OR CL,CL
  135. JNZ short SSpecial
  136. MOV CL,Flag[esi] ; Pick up sign & single precision flag
  137. MOV AX,Expon[esi]
  138. CMP AX,SexpMax - SexpBias
  139. JGE short JMPSOver
  140. CMP AX,SexpMin - SexpBias
  141. JLE short JMPSUnder
  142. ADD AL,SexpBias ; Bias the Exponent
  143. MOV AH,MB7[esi] ; Pick up MSB of Mantissa
  144. XCHG AH,AL
  145. SHL AL,1 ; Shift mantissa to destroy leading integer bit
  146. SHL CL,1 ; Get sign into CF
  147. RCR AX,1 ; Pack sign, exp, & MSB
  148. if fastSP
  149. TEST CL,Single*2 ; if number was single rounding is not needed
  150. JZ SS1
  151. MOV BX,MB5[esi]
  152. JMP SHORT STRUNC
  153. SS1:
  154. endif
  155. MOV DX,MB0[esi] ; DL Will be the sticky bit
  156. OR DX,MB2[esi] ; DH will be round and the rest of sticky
  157. OR DL,DH
  158. XOR DH,DH
  159. MOV BX,MB5[esi]
  160. OR DX,MB3[esi]
  161. JZ short STRUNC ; If no Round or Sticky result is exact
  162. OR [CURerr],Precision
  163. pub SRound ; single in AX:BX:DX
  164. MOV CL,[CWcntl] ; Need to know Rounding Control
  165. SHR CL,1
  166. SHR CL,1
  167. SHR CL,1
  168. JC short StDOWNorCHOP24
  169. SHR CL,1
  170. JC short StUP24
  171. pub StNEAR24
  172. CMP DX,8000H ; How are round and sticky bits?
  173. JB short STRUNC ; No round, so truncate
  174. JA short SINC ; Round and sticky so round up
  175. TEST BL,1 ; Round and no sticky, is last bit even?
  176. JZ short STRUNC ; Yes, so truncate.
  177. pub SINC
  178. MOV DL,AL ; Increment mantissa
  179. ADD BX,1
  180. ADC AX,0
  181. XOR DL,AL ; See if we overflowed a bit into the exponent
  182. JNS short STRUNC ; If not number is now correct so go store
  183. MOV DX,AX ; Exponent was incremented, see if it overflowed
  184. SHL DX,1
  185. CMP DH,SexpMax
  186. JE short SOver
  187. pub StCHOP24
  188. STRUNC:
  189. XCHG AX,BX
  190. STAX2US
  191. MOV AX,BX
  192. STAX2US
  193. pub SStoreExit
  194. RET
  195. pub StDOWNorCHOP24
  196. SHR CL,1
  197. JC short StCHOP24
  198. pub StDOWN24
  199. OR AH,AH ; Test the sign
  200. JS short SINC
  201. JMP short STRUNC
  202. pub StUP24
  203. OR AH,AH ; Test the sign
  204. JS short STRUNC
  205. JMP short SINC
  206. pub SOver ; Number overflowed Single Precision range.
  207. ; Result returned depends upon rounding control
  208. OR [CURerr],Overflow + Precision
  209. MOV CL,[CWcntl]
  210. SHR CL,1
  211. SHR CL,1
  212. SHR CL,1
  213. JC short StMOvDNorCHP24
  214. SHR CL,1
  215. JC short StMOvUP24
  216. StMOvNEAR24: ; Masked Overflow Near Rounding
  217. pub SSignedInfinity ; Return signed infinity
  218. MOV BX,[IEEEinfinityS + 2]
  219. AND AH,Sign ; Overstore the proper sign
  220. OR BH,AH
  221. MOV AX,[IEEEinfinityS]
  222. STAX2US
  223. MOV AX,BX
  224. STAX2US
  225. JMP SStoreExit
  226. pub StMOvDNorCHP24
  227. SHR CL,1
  228. JC short StMOvCHOP24
  229. pub StMOvDOWN24 ; Masked Overflow Down Rounding
  230. TEST AH,Sign ; Positive goes to biggest
  231. JNZ short SSignedInfinity
  232. StMOvCHOP24: ; Masked Overflow Chop Rounding
  233. pub SSignedBiggest
  234. MOV BX,[IEEEbiggestS + 2]
  235. AND AH,Sign ; Overstore the proper sign
  236. OR AH,BH
  237. MOV AL,BL
  238. STAX2US
  239. MOV AX,[IEEEbiggestS]
  240. STAX2US
  241. JMP SStoreExit
  242. pub StMOvUP24 ; Masked Overflow Up Rounding
  243. TEST AH,Sign ; Negative goes to biggest
  244. JZ short SSignedInfinity
  245. JMP SSignedBiggest
  246. pub SUnder ; Masked Underflow - Try to denormalize
  247. OR [CURerr],Underflow+Precision
  248. NEG AX ; Convert exponent (which is too small)
  249. ADD AX,SexpMin-SexpBias+1 ; To a positive shift count
  250. CMP AX,24 ; Is shift more than mantissa precision
  251. JGE short Szero
  252. XCHG CX,AX
  253. ifdef i386
  254. movzx ecx,cx ; (ecx) = zero-extended loop count
  255. endif
  256. MOV DX,MB0[esi] ; Pick up Insignif bytes for sticky bit
  257. OR DX,MB2[esi]
  258. MOV AL,DL
  259. OR AL,DH
  260. MOV DX,MB4[esi]
  261. MOV BX,MB6[esi]
  262. OR AL,AL
  263. JZ short SSHIFTR
  264. OR DL,1 ; Set the sticky bit
  265. pub SSHIFTR
  266. SHR BX,1
  267. RCR DX,1
  268. JNC short SSLOOP
  269. OR DL,1
  270. pub SSLOOP
  271. LOOP SSHIFTR
  272. XCHG AH,CH ; Restore operation to CH
  273. MOV AH,Flag[esi] ; Pick up sign
  274. AND AH,Sign ; Mask to sign only
  275. MOV AL,BH ; Biased exponent for a denormal is 0
  276. MOV BH,BL
  277. MOV BL,DH
  278. MOV DH,DL
  279. XOR DL,DL
  280. JMP SRound
  281. pub Szero
  282. XOR AX,AX
  283. MOV BX,AX
  284. JMP STRUNC ; Go store single and exit
  285. ProfEnd LSSNG