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.

309 lines
9.2 KiB

  1. subttl emxtract - FXTRACT and FSCALE instructions
  2. page
  3. ;*******************************************************************************
  4. ;emxtract - FXTRACT and FSCALE instructions
  5. ;
  6. ; Microsoft Confidential
  7. ;
  8. ; Copyright (c) Microsoft Corporation 1991
  9. ; All Rights Reserved
  10. ;
  11. ;Inputs:
  12. ; edi = [CURstk]
  13. ;
  14. ;Revision History:
  15. ;
  16. ; [] 09/05/91 TP Initial 32-bit version.
  17. ;
  18. ;*******************************************************************************
  19. XtractStackOver:
  20. mov EMSEG:[SWcc],C1 ;Flag stack overflow
  21. XtractEmpty:
  22. ;Result is two Indefinites (if exception masked)
  23. call StackError ;Put first indefinite at [edi] = ST(0)
  24. jz XtractExit ;Error was unmasked--just exit
  25. mov EMSEG:[CURstk],edi
  26. mov eax,EMSEG:[edi].ExpSgn
  27. mov EMSEG:[esi].ExpSgn,eax
  28. mov eax,EMSEG:[edi].lManHi
  29. mov EMSEG:[esi].lManHi,eax
  30. mov eax,EMSEG:[edi].lManLo
  31. mov EMSEG:[esi].lManLo,eax
  32. ret
  33. PrevStackWrap edi,Xtract
  34. EM_ENTRY eFXTRACT
  35. eFXTRACT:
  36. ;edi = [CURstk]
  37. mov esi,edi ;Save current ST
  38. PrevStackElem edi,Xtract
  39. ;edi = ST(0)
  40. ;esi = ST(1) (operand)
  41. mov eax,EMSEG:[esi].ExpSgn
  42. ;Exception priority requires reporting stack underflow (i.e., using an EMPTY)
  43. ;before stack overflow (i.e., no place for result). Yes, both can happen
  44. ;together if they've messed with the stack! (ST empty when ST(-1) isn't).
  45. cmp al,bTAG_EMPTY ;Is operand empty?
  46. jz XtractEmpty
  47. cmp EMSEG:[edi].bTag,bTAG_EMPTY ;Is there an empty spot?
  48. jnz XtractStackOver
  49. cmp al,bTAG_ZERO ;Is it special?
  50. jae XtractSpclOrZero
  51. XtractNormal:
  52. mov EMSEG:[CURstk],edi
  53. .erre TexpBias eq 0
  54. movzx ebx,ax ;Zero exponent
  55. ;Save mantissa in ST(0)
  56. mov EMSEG:[edi].ExpSgn,ebx
  57. mov ebx,EMSEG:[esi].lManHi
  58. mov EMSEG:[edi].lManHi,ebx
  59. mov ebx,EMSEG:[esi].lManLo
  60. mov EMSEG:[edi].lManLo,ebx
  61. mov edi,esi ;Save ST(1) pointer in edi
  62. shr eax,16 ;Move exponent down
  63. call NormInt16 ;in emload.asm
  64. ;mantissa in ebx:esi, exponent in high ecx, sign in ch bit 7, tag in cl
  65. mov EMSEG:[edi].lManLo,esi
  66. mov EMSEG:[edi].lManHi,ebx
  67. mov EMSEG:[edi].ExpSgn,ecx
  68. XtractExit:
  69. ret
  70. XtractSpcl:
  71. cmp al,bTAG_INF
  72. jz XtractInf
  73. cmp al,bTAG_NAN
  74. jz XtractNAN
  75. ;Must be denormal. Change tag to VALID or SNGL.
  76. cmp EMSEG:[esi].lManLo,0 ;Any bits in low half?
  77. .erre bTAG_VALID eq 1
  78. .erre bTAG_SNGL eq 0
  79. setnz al ;if low half==0 then al=0 else al=1
  80. mov EMSEG:[CURerr],Denormal
  81. test EMSEG:[CWmask],Denormal ;Is it masked?
  82. jnz XtractNormal ;If so, ignore denormalization
  83. ret
  84. XtractSpclOrZero:
  85. ja XtractSpcl
  86. ;Operand is zero. Result is ST(0) = 0 (same sign), ST(1) = -infinity
  87. mov EMSEG:[CURerr],ZeroDivide
  88. test EMSEG:[CWmask],ZeroDivide ;Exception masked?
  89. jz XtractExit
  90. mov EMSEG:[CURstk],edi
  91. mov EMSEG:[edi].ExpSgn,eax
  92. mov eax,EMSEG:[esi].lManHi
  93. mov EMSEG:[edi].lManHi,eax
  94. mov eax,EMSEG:[esi].lManLo
  95. mov EMSEG:[edi].lManLo,eax
  96. mov EMSEG:[esi].ExpSgn,(IexpMax-IexpBias+TexpBias) shl 16 + bSign shl 8 + bTAG_INF
  97. mov EMSEG:[esi].bMan7,80H ;Change zero to infinity
  98. ret
  99. XtractInf:
  100. ;Result is ST(0) = infinity (same sign), ST(1) = +infinity
  101. mov EMSEG:[esi].bSgn,0 ;Ensure ST(1) is positive
  102. XtractQNAN:
  103. mov EMSEG:[CURstk],edi
  104. mov EMSEG:[edi].ExpSgn,eax
  105. mov eax,EMSEG:[esi].lManHi
  106. mov EMSEG:[edi].lManHi,eax
  107. mov eax,EMSEG:[esi].lManLo
  108. mov EMSEG:[edi].lManLo,eax
  109. ret
  110. XtractNAN:
  111. ;Result is two QNANs, signal Invalid Operation if SNAN
  112. test EMSEG:[esi].bMan7,40H ;Is it SNAN?
  113. jnz XtractQNAN
  114. mov EMSEG:[CURerr],Invalid
  115. test EMSEG:[CWmask],Invalid
  116. jz XtractExit
  117. or EMSEG:[esi].bMan7,40H ;Change to QNAN
  118. jmp XtractQNAN
  119. ;*******************************************************************************
  120. ;
  121. ;FSCALE instruction
  122. ;Actual instruction entry point is in emarith.asm
  123. ;Dispatch table for scale
  124. ;
  125. ;One operand has been loaded into ecx:ebx:esi ("source"), the other is
  126. ;pointed to by edi ("dest").
  127. ;
  128. ;Tag of source is shifted. Tag values are as follows:
  129. .erre TAG_SNGL eq 0 ;SINGLE: low 32 bits are zero
  130. .erre TAG_VALID eq 1
  131. .erre TAG_ZERO eq 2
  132. .erre TAG_SPCL eq 3 ;NAN, Infinity, Denormal, Empty
  133. ;Any special case routines not found in this file are in emarith.asm
  134. tFscaleDisp label dword ;Source (reg) Dest (*[di] = ST)
  135. dd ScaleDouble ;single single
  136. dd ScaleDouble ;single double
  137. dd ScaleX ;single zero
  138. dd ScaleSpclDest ;single special
  139. dd ScaleDouble ;double single
  140. dd ScaleDouble ;double double
  141. dd ScaleX ;double zero
  142. dd ScaleSpclDest ;double special
  143. dd ScaleX ;zero single
  144. dd ScaleX ;zero double
  145. dd ScaleX ;zero zero
  146. dd ScaleSpclDest ;zero special
  147. dd ScaleSpclSource ;special single
  148. dd ScaleSpclSource ;special double
  149. dd ScaleSpclSource ;special zero
  150. dd TwoOpBothSpcl ;special special
  151. dd ScaleTwoInf ;Two infinites
  152. ;The unmasked response to overflow and underflow with FSCALE is complicated
  153. ;by the extreme range it can generate. Normally, the exponent is biased
  154. ;by 24,576 in the appropriate direction to bring it back into range.
  155. ;This may not be enough, however. If it isn't, a result of infinity
  156. ;(with the correct sign) is returned for overflow, regardless of the
  157. ;rounding mode. For underflow, zero (with the correct sign) is returned,
  158. ;even if it could be represented as a denormal. This may be the only
  159. ;operation in which the unmasked response destroys the operands beyond
  160. ;recovery.
  161. BigScale:
  162. ;Scale factor is much too big. Just shift mantissa right two bits to get
  163. ;MSB out of sign bit and ensure no overflow when we add.
  164. mov cl,2 ;Always shift 2 bits if it's big
  165. jmp ScaleCont
  166. ScaleDouble:
  167. ;ebx:esi = ST(1) mantissa
  168. ;ecx = ST(1) sign in bit 15, exponent in high half
  169. ;edi = pointer to ST(0)
  170. rol ecx,16 ;Bring exponent down, sign to top
  171. or ch,ch ;Check sign of exponent
  172. js ScaleX ;No work if less than zero
  173. cmp cx,30 ;Scale factor exceed 30 bits?
  174. jge BigScale
  175. not cl ;cl = amount to shift right (mod 32)
  176. ScaleCont:
  177. shr ebx,cl ;ebx = exponent adjustment for ST(0)
  178. ;Use two's complement if negative (complement and increment)
  179. mov eax,ecx
  180. cdq ;Extend sign through edx
  181. xor ebx,edx ;Complement if negative
  182. sub ebx,edx ;Increment if negative
  183. ;Scale exponent
  184. movsx eax,EMSEG:[edi].wExp ;Get exponent to adjust
  185. add eax,ebx ;Can't overflow
  186. cmp eax,IexpMax-IexpBias ;Within normal range?
  187. jge ScaleOverflow
  188. cmp eax,IexpMin-IexpBias
  189. jle ScaleUnderflow
  190. SaveScaledExp:
  191. ;Result fit withing normal range
  192. mov EMSEG:[edi].wExp,ax ;Update exponent of ST(0)
  193. ScaleX:
  194. ret
  195. ScaleOverflow:
  196. ;eax = exponent that's too big
  197. mov EMSEG:[CURerr],Overflow
  198. test EMSEG:[CWmask],Overflow ;Is exception unmasked?
  199. jz UnmaskedScaleOvfl
  200. ;Produce masked overflow response
  201. mov al,EMSEG:[CWcntl] ;Get rounding control
  202. mov ah,al
  203. ;Return max value if RCup bit = 1 and -, or RCdown bit = 1 and +
  204. ;i.e., RCup & sign OR RCdown & not sign
  205. .erre RCchop eq RCup + RCdown ;Always return max value
  206. .erre RCnear eq 0 ;Never return max value
  207. sar ch,7 ;Expand sign through whole byte
  208. .erre (RCdown and bSign) eq 0 ;Don't want to change real sign
  209. xor ch,RCdown ;Flip sign for RCdown bit
  210. and ah,ch ;RCup & sign OR RCdown & not sign
  211. jz ScaleToInfinity ;Save Infinity
  212. ;Get max value
  213. sub ecx,1 shl 16 ;Drop exponent by 1
  214. xor esi,esi
  215. dec esi ;esi == -1
  216. mov ebx,esi
  217. SaveScaleMax:
  218. mov EMSEG:[edi].lManLo,esi
  219. mov EMSEG:[edi].lManHi,ebx
  220. mov EMSEG:[edi].ExpSgn,ecx
  221. ret
  222. UnmaskedScaleOvfl:
  223. sub eax,UnderBias ;Unmasked response
  224. cmp eax,IexpMax-IexpBias ;Within normal range now?
  225. jl SaveScaledExp ;Use exponent biased by 24K
  226. ScaleToInfinity:
  227. mov ebx,1 shl 31
  228. xor esi,esi
  229. mov ecx,(IexpMax-IexpBias+TexpBias) shl 16 + bTAG_INF
  230. mov ch,EMSEG:[edi].bSgn ;Give it same sign
  231. jmp SaveScaleMax ;Use infinity
  232. ScaleUnderflow:
  233. ;eax = exponent that's too big
  234. test EMSEG:[CWmask],Underflow ;Is exception unmasked?
  235. jz ScaleSetUnder
  236. cmp eax,-32768 ;Does exponent fit in 16 bits?
  237. jg @F
  238. mov ax,-32768 ;Max value
  239. @@:
  240. ;Set up for denormalizer
  241. mov ebx,EMSEG:[edi].lManHi
  242. mov esi,EMSEG:[edi].lManLo
  243. shrd ecx,eax,16 ;Move exponent to high end of ecx
  244. mov ch,EMSEG:[edi].bSgn ;Keep sign
  245. xor eax,eax ;No sticky bits
  246. mov EMSEG:[Result],edi
  247. jmp Denormalize ;In emround.asm
  248. ScaleSetUnder:
  249. ;Underflow exception not masked. Adjust exponent and try again.
  250. mov EMSEG:[CURerr],Underflow
  251. add eax,UnderBias ;Unmasked response
  252. cmp eax,IexpMin-IexpBias ;Within normal range now?
  253. jg SaveScaledExp ;Use exponent biased by 24K
  254. mov EMSEG:[CURerr],Underflow
  255. ScaleToZero:
  256. mov ecx,bTAG_ZERO
  257. mov ch,EMSEG:[edi].bSgn ;Give it same sign
  258. xor ebx,ebx
  259. mov esi,ebx
  260. jmp SaveScaleMax ;Set to zero
  261. ;***
  262. ScaleSpclDest:
  263. mov al,EMSEG:[edi].bTag ;Pick up tag
  264. cmp al,bTAG_INF ;Scaling infinity?
  265. jz ScaleRet ;No change if so
  266. jmp SpclDest ;In emarith.asm
  267. ScaleRet:
  268. ret
  269. ;***
  270. ScaleSpclSource:
  271. cmp cl,bTAG_INF ;Scaling by infinity?
  272. jnz SpclSource ;in emarith.asm
  273. or ch,ch ;Scaling by -infinity?
  274. js ScaleToZero
  275. cmp EMSEG:[edi].bTag,bTAG_ZERO ;Zero scaled by +infinity?
  276. jnz ScaleToInfinity
  277. jmp ReturnIndefinite ;Invalid operation
  278. ;***
  279. ScaleTwoInf:
  280. or ch,ch ;Scaling by +infinity?
  281. jns ScaleRet ;All done then
  282. ;Scaling infinity by -infinity
  283. jmp ReturnIndefinite ;Invalid operation