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.

416 lines
10 KiB

  1. subttl emload.asm - FLD and FILD instructions
  2. page
  3. ;*******************************************************************************
  4. ;emload.asm - FLD and FILD instructions
  5. ;
  6. ; Microsoft Confidential
  7. ;
  8. ; Copyright (c) Microsoft Corporation 1991
  9. ; All Rights Reserved
  10. ;
  11. ;Purpose:
  12. ; FLD and FILD instructions
  13. ;Inputs:
  14. ; edi = [CURstk]
  15. ; dseg:esi = pointer to memory operand
  16. ;
  17. ;Revision History:
  18. ;
  19. ; [] 09/05/91 TP Initial 32-bit version.
  20. ;
  21. ;*******************************************************************************
  22. PrevStackWrap edi,LdStk ;Tied to PrevStackElem below
  23. ;*******
  24. EM_ENTRY eFLDreg
  25. eFLDreg:
  26. ;*******
  27. ; edi = [CURstk]
  28. ; esi = pointer to st(i) from instruction field
  29. PrevStackElem edi,LdStk ;Point to receiving location
  30. cmp EMSEG:[edi].bTag,bTAG_EMPTY ;Is it empty?
  31. jnz FldErr
  32. mov ecx,EMSEG:[esi].ExpSgn
  33. cmp cl,bTAG_EMPTY
  34. jz FldErr
  35. mov ebx,EMSEG:[esi].lManHi
  36. mov esi,EMSEG:[esi].lManLo
  37. mov EMSEG:[CURstk],edi
  38. mov EMSEG:[edi].lManLo,esi
  39. mov EMSEG:[edi].lManHi,ebx
  40. mov EMSEG:[edi].ExpSgn,ecx
  41. ret
  42. ;This is common code that stores a value into the stack after being loaded
  43. ;into registers by the appropriate routine.
  44. PrevStackWrap edi,Load ;Tied to PrevStackElem below
  45. FldCont:
  46. ;mantissa in ebx:esi, exp/sign in ecx
  47. ;edi = [CURstk]
  48. PrevStackElem edi,Load ;Point to receiving location
  49. cmp EMSEG:[edi].bTag,bTAG_EMPTY ;Is it empty?
  50. jnz FldErr
  51. cmp cl,bTAG_NAN ;Returning a NAN?
  52. jz FldNAN
  53. SaveStack:
  54. mov EMSEG:[CURstk],edi
  55. mov EMSEG:[edi].lManLo,esi
  56. mov EMSEG:[edi].lManHi,ebx
  57. mov EMSEG:[edi].ExpSgn,ecx
  58. ret
  59. FldErr:
  60. or EMSEG:[SWcc],C1 ;Signal overflow
  61. mov EMSEG:[CURerr],StackFlag;Kills possible denormal exception
  62. Unsupported:
  63. call ReturnIndefinite ;in emarith.asm
  64. jz FldExit ;Unmasked, do nothing
  65. mov EMSEG:[CURstk],edi ;Update top of stack
  66. FldExit:
  67. ret
  68. FldNAN:
  69. ;Is it a signaling NAN?
  70. test ebx,1 shl 30 ;Check for SNAN
  71. jnz SaveStack ;If QNAN, just use it as result
  72. or EMSEG:[CURerr],Invalid ;Flag the error
  73. or ebx,1 shl 30 ;Make it into a QNAN
  74. test EMSEG:[CWmask],Invalid ;Is it masked?
  75. jnz SaveStack ;If so, update with masked response
  76. ret
  77. ;****************
  78. ;Load Single Real
  79. ;****************
  80. EM_ENTRY eFLD32
  81. eFLD32:
  82. push offset FldCont ;Return address
  83. ;Fall into Load32Real
  84. Load32Real:
  85. ;dseg:esi points to IEEE 32-bit real number
  86. ;On exit:
  87. ; mantissa in ebx:esi, exponent in high ecx, sign in ch bit 7, tag in cl
  88. ;preserves edi.
  89. mov EMSEG:[PrevDataOff],esi ;Save operand pointer
  90. mov ecx,dseg:[esi] ;Get number
  91. mov ebx,ecx ;Save copy of mantissa
  92. shl ebx,8 ;Normalize
  93. shr ecx,7 ;Bring exponent down
  94. and ecx,0FFH shl 16 ;Look at just exponent
  95. mov ch,dseg:[esi+3] ;Get sign again
  96. jz short ZeroOrDenorm32 ;Exponent is zero
  97. xor esi,esi ;Zero out the low bits
  98. or ebx,1 shl 31 ;Set implied bit
  99. cmp ecx,SexpMax shl 16
  100. jge NANorInf ;Max exp., must be NAN or Infinity
  101. add ecx,(TexpBias-SexpBias) shl 16 ;Change to extended format bias
  102. mov cl,bTAG_SNGL
  103. ret
  104. ZeroOrDenorm32:
  105. ;Exponent is zero. Number is either zero or denormalized
  106. xor esi,esi ;Zero out the low bits
  107. and ebx,not (1 shl 31) ;Keep just mantissa
  108. jnz Norm32
  109. mov cl,bTAG_ZERO
  110. ret
  111. Norm32:
  112. add ecx,(TexpBias-SexpBias+1-31) shl 16 ;Fix up bias
  113. jmp FixDenorm
  114. NANorInf:
  115. ;Shared by single and double real
  116. and ecx,bSign shl 8 ;Save only sign in ch
  117. or ecx,TexpMax shl 16 + bTAG_NAN ;Max exp.
  118. cmp ebx,1 shl 31 ;Only 1 bit set means infinity
  119. jnz @F
  120. or esi,esi
  121. jnz @F
  122. mov cl,bTAG_INF
  123. @@:
  124. ret
  125. ;****************
  126. ;Load Double Real
  127. ;****************
  128. EM_ENTRY eFLD64
  129. eFLD64:
  130. push offset FldCont ;Return address
  131. ;Fall into Load64Real
  132. Load64Real:
  133. ;dseg:esi points to IEEE 64-bit real number
  134. ;On exit:
  135. ; mantissa in ebx:esi, exponent in high ecx, sign in ch bit 7, tag in cl
  136. ;preserves edi.
  137. mov EMSEG:[PrevDataOff],esi ;Save operand pointer
  138. mov ecx,dseg:[esi+4] ;Get sign, exp., and high mantissa
  139. mov ebx,ecx ;Save copy of mantissa
  140. shr ecx,4 ;Bring exponent down
  141. and ecx,7FFH shl 16 ;Look at just exponent
  142. mov ch,dseg:[esi+7] ;Get sign again
  143. mov esi,dseg:[esi] ;Get low 32 bits of op
  144. jz short ZeroOrDenorm64 ;Exponent is zero
  145. shld ebx,esi,31-20
  146. shl esi,31-20 ;Normalize
  147. or ebx,1 shl 31 ;Set implied bit
  148. cmp ecx,DexpMax shl 16
  149. jge NANorInf ;Max exp., must be NAN or Infinity
  150. add ecx,(TexpBias-DexpBias) shl 16 ;Change to extended format bias
  151. SetNormTag:
  152. or esi,esi ;Any bits in low half?
  153. .erre bTAG_VALID eq 1
  154. .erre bTAG_SNGL eq 0
  155. setnz cl ;if low half==0 then cl=0 else cl=1
  156. ret
  157. ZeroOrDenorm64:
  158. ;Exponent is zero. Number is either zero or denormalized
  159. and ebx,0FFFFFH ;Keep just mantissa
  160. jnz ShortNorm64 ;Are top 20 bits zero?
  161. or esi,esi ;Are low 32 bits zero too?
  162. jnz LongNorm64
  163. mov cl,bTAG_ZERO
  164. ret
  165. LongNorm64:
  166. xchg ebx,esi ;Shift up 32 bits
  167. sub ecx,32 shl 16 ;Correct exponent
  168. ShortNorm64:
  169. add ecx,(TexpBias-DexpBias+12-31) shl 16 ;Fix up bias
  170. FixDenorm:
  171. or EMSEG:[CURerr],Denormal ;Set Denormal Exception
  172. bsr edx,ebx ;Scan for MSB
  173. ;Bit number in edx ranges from 0 to 31
  174. mov cl,dl
  175. not cl ;Convert bit number to shift count
  176. shld ebx,esi,cl
  177. shl esi,cl
  178. shl edx,16 ;Move exp. adjustment to high end
  179. add ecx,edx ;Adjust exponent
  180. jmp SetNormTag
  181. ;******************
  182. ;Load Short Integer
  183. ;******************
  184. EM_ENTRY eFILD16
  185. eFILD16:
  186. push offset FldCont ;Return address
  187. ;Fall into Load16Int
  188. Load16Int:
  189. ;dseg:esi points to 16-bit integer
  190. ;On exit:
  191. ; mantissa in ebx:esi, exponent in high ecx, sign in ch bit 7, tag in cl
  192. ;preserves edi.
  193. mov EMSEG:[PrevDataOff],esi ;Save operand pointer
  194. mov ax,dseg:[esi]
  195. NormInt16:
  196. xor esi,esi ;Extend with zero
  197. cwd ;extend sign through dx
  198. xor ax,dx
  199. sub ax,dx ;Take ABS() of integer
  200. bsr cx,ax ;Find MSB
  201. jz ZeroInt
  202. ;Bit number in cx ranges from 0 to 15
  203. not ecx ;Convert to shift count
  204. shl eax,cl ;Normalize
  205. not ecx
  206. .erre TexpBias eq 0
  207. shl ecx,16 ;Move exponent to high half
  208. mov ch,dh ;Set sign
  209. mov ebx,eax ;Mantissa to ebx
  210. mov cl,bTAG_SNGL
  211. ret
  212. ZeroInt:
  213. xor ebx,ebx
  214. mov ecx,ebx
  215. mov cl,bTAG_ZERO
  216. ret
  217. ;******************
  218. ;Load Long Integer
  219. ;******************
  220. EM_ENTRY eFILD32
  221. eFILD32:
  222. push offset FldCont ;Return address
  223. ;Fall into Load32Int
  224. Load32Int:
  225. ;dseg:esi points to 32-bit integer
  226. ;On exit:
  227. ; mantissa in ebx:esi, exponent in high ecx, sign in ch bit 7, tag in cl
  228. ;preserves edi.
  229. mov EMSEG:[PrevDataOff],esi ;Save operand pointer
  230. mov eax,dseg:[esi]
  231. xor esi,esi ;Extend with zero
  232. or eax,eax ;It it zero?
  233. jz ZeroInt
  234. cdq ;extend sign through edx
  235. xor eax,edx
  236. sub eax,edx ;Take ABS() of integer
  237. mov ebx,eax ;Mantissa to ebx
  238. ;BSR uses 3 clocks/bit, so speed it up by checking the top half
  239. ;This saves 36 clocks on 386 (42 on 486sx)
  240. ;Cost is 13 clocks on 386 if high word isn't zero (5 on 486sx)
  241. .erre TexpBias eq 0
  242. xor eax,eax ;Initialize exponent
  243. cmp ebx,0FFFFH ;Upper bits zero?
  244. ja @F
  245. shl ebx,16
  246. sub eax,16
  247. @@:
  248. bsr ecx,ebx ;Find MSB
  249. add eax,ecx ;Compute expoment
  250. not cl ;Convert bit number to shift count
  251. shl ebx,cl ;Normalize
  252. shrd ecx,eax,16 ;Move exponent to high half of ecx
  253. mov ch,dh ;Set sign
  254. mov cl,bTAG_SNGL
  255. ret
  256. ;*****************
  257. ;Load Quad Integer
  258. ;*****************
  259. EM_ENTRY eFILD64
  260. eFILD64:
  261. mov EMSEG:[PrevDataOff],esi ;Save operand pointer
  262. mov ebx,dseg:[esi+4] ;Get high 32 bits
  263. mov eax,ebx ;Make copy of sign
  264. mov esi,dseg:[esi] ;Get low 32 bits
  265. mov ecx,ebx
  266. or ecx,esi ;Is it zero?
  267. jz ZeroQuad
  268. NormQuadInt:
  269. ;Entry point from eFBLD
  270. ;eax bit 31 = sign
  271. ;ebx:esi = integer
  272. ;edi = [CURstk]
  273. .erre TexpBias eq 0
  274. mov ax,32 ;Initialize exponent
  275. or ebx,ebx ;Check sign
  276. jz LongNormInt
  277. jns FindBit
  278. not ebx
  279. neg esi ;CY set if non-zero
  280. sbb ebx,-1 ;Add one if esi == 0
  281. jnz FindBit ;Check for high bits zero
  282. LongNormInt:
  283. xchg ebx,esi ;Normalize 32 bits
  284. xor ax,ax ;Reduce exponent by 32
  285. FindBit:
  286. ;BSR uses 3 clocks/bit, so speed it up by checking the top half
  287. ;This saves 35 clocks on 386 (41 on 486sx)
  288. ;Cost is 11 clocks on 386 if high word isn't zero (4 on 486sx)
  289. cmp ebx,0FFFFH ;Upper bits zero?
  290. ja @F
  291. shld ebx,esi,16
  292. shl esi,16
  293. sub eax,16
  294. @@:
  295. bsr ecx,ebx ;Find MSB
  296. add eax,ecx ;Compute expoment
  297. not cl ;Convert bit number to shift count
  298. shld ebx,esi,cl ;Normalize
  299. shl esi,cl
  300. mov ecx,eax ;Move sign and exponent to ecx
  301. rol ecx,16 ;Swap sign and exponent halves
  302. or esi,esi ;Any bits in low half?
  303. .erre bTAG_VALID eq 1
  304. .erre bTAG_SNGL eq 0
  305. setnz cl ;if low half==0 then cl=0 else cl=1
  306. jmp FldCont
  307. ZeroQuad:
  308. mov cl,bTAG_ZERO
  309. jmp FldCont
  310. ;****************
  311. ;Load Temp Real
  312. ;****************
  313. PrevStackWrap edi,Ld80 ;Tied to PrevStackElem below
  314. EM_ENTRY eFLD80
  315. eFLD80:
  316. ;This is not considered an "arithmetic" operation (like all the others are),
  317. ;so SNANs do NOT cause an exception. However, unsupported formats do.
  318. mov EMSEG:[PrevDataOff],esi ;Save operand pointer
  319. PrevStackElem edi,Ld80 ;Point to receiving location
  320. cmp EMSEG:[edi].bTag,bTAG_EMPTY ;Is it empty?
  321. jnz FldErr
  322. LoadTempReal:
  323. mov ebx,dseg:[esi+4] ;Get high half of mantissa
  324. mov cx,dseg:[esi+8] ;Get exponent and sign
  325. mov esi,dseg:[esi] ;Get low half of mantissa
  326. mov eax,ecx
  327. and ch,7FH ;Mask off sign bit
  328. shl ecx,16 ;Move exponent to high end
  329. mov ch,ah ;Restore sign
  330. jz ZeroOrDenorm80
  331. ;Check for unsupported format: unnormals (MSB not set)
  332. or ebx,ebx
  333. jns Unsupported
  334. sub ecx,(IexpBias-TexpBias) shl 16 ;Correct the bias
  335. cmp ecx,TexpMax shl 16
  336. jge NANorInf80
  337. SetupTag:
  338. or esi,esi ;Any bits in low half?
  339. .erre bTAG_VALID eq 1
  340. .erre bTAG_SNGL eq 0
  341. setnz cl ;if low half==0 then cl=0 else cl=1
  342. jmp SaveStack
  343. NANorInf80:
  344. mov cl,bTAG_NAN
  345. cmp ebx,1 shl 31 ;Only 1 bit set means infinity
  346. jnz SaveStack
  347. or esi,esi
  348. jnz SaveStack
  349. mov cl,bTAG_INF
  350. jmp SaveStack
  351. ZeroOrDenorm80:
  352. ;Exponent is zero. Number is either zero or denormalized
  353. or ebx,ebx
  354. jnz ShortNorm80 ;Are top 32 bits zero?
  355. or esi,esi ;Are low 32 bits zero too?
  356. jnz LongNorm80
  357. mov cl,bTAG_ZERO
  358. jmp SaveStack
  359. ;This code accepts and works correctly with pseudo-denormals (MSB already set)
  360. LongNorm80:
  361. xchg ebx,esi ;Shift up 32 bits
  362. sub ecx,32 shl 16 ;Correct exponent
  363. ShortNorm80:
  364. add ecx,(TexpBias-IexpBias+1-31) shl 16 ;Fix up bias
  365. bsr edx,ebx ;Scan for MSB
  366. ;Bit number in edx ranges from 0 to 31
  367. mov cl,dl
  368. not cl ;Convert bit number to shift count
  369. shld ebx,esi,cl
  370. shl esi,cl
  371. shl edx,16 ;Move exp. adjustment to high end
  372. add ecx,edx ;Adjust exponent
  373. jmp SetUpTag