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.

571 lines
10 KiB

  1. ; SCCSID = @(#)emsincos.asm 13.5 90/03/27
  2. page ,132
  3. subttl emsincos - fsin, fcos and fsincos
  4. ;***
  5. ;emulator.asm - 80387 emulator
  6. ;
  7. ; IBM/Microsoft Confidential
  8. ;
  9. ; Copyright (c) IBM Corporation 1987, 1989
  10. ; Copyright (c) Microsoft Corporation 1987, 1989
  11. ;
  12. ; All Rights Reserved
  13. ;
  14. ;Purpose:
  15. ; Code for fsin, fcos and fsincos
  16. ;
  17. ;Revision History:
  18. ; See emulator.hst
  19. ;
  20. ;*******************************************************************************
  21. lab eFsincosStackOver
  22. or SEL[CURerr], StackFlag or Invalid
  23. test SEL[CWmask], Invalid
  24. JSZ eFsincosStackOverRet
  25. mov SEL[rsi.lMan0], 0 ; st(0) = Ind
  26. mov SEL[rsi.lMan1], 0c0000000h
  27. mov SEL[rsi.wExp], 7fffh - IexpBias
  28. mov SEL[rsi.bTag], bTAG_NAN
  29. mov SEL[rsi.bFlags], bSign
  30. mov SEL[rdi.lMan0], 0 ; st(-1) = Ind
  31. mov SEL[rdi.lMan1], 0c0000000h
  32. mov SEL[rdi.wExp], 7fffh - IexpBias
  33. mov SEL[rdi.bTag], bTAG_NAN
  34. mov SEL[rdi.bFlags], bSign
  35. mov SEL[CURstk], rdi ; push stack
  36. lab eFsincosStackOverRet
  37. ret
  38. lab eFSINCOS
  39. mov esi, SEL[CURStk] ; esi = st(0)
  40. mov edi, esi
  41. PrevStackElem edi ; edi = st(-1)
  42. cmp SEL[edi.bTag], bTAG_EMPTY
  43. JSNE eFsincosStackOver
  44. cmp SEL[esi.bTag], bTAG_NAN
  45. JSNE eFsincosNotSNaN
  46. test SEL[esi.bMan7], 40h
  47. JSNZ eFsincosNotSNaN
  48. test SEL[CWmask], Invalid
  49. JSNZ eFsincosNotSNaN
  50. or SEL[CURerr], Invalid
  51. ret
  52. lab eFsincosNotSNaN
  53. ifdef NT386
  54. push eax
  55. mov eax, dword ptr SEL[rsi]
  56. mov dword ptr SEL[rdi], eax
  57. mov eax, dword ptr SEL[rsi+4]
  58. mov dword ptr SEL[rdi+4], eax
  59. mov eax, dword ptr SEL[rsi+8]
  60. mov dword ptr SEL[rdi+8], eax
  61. add rsi, Reg87Len
  62. add rdi, Reg87Len
  63. pop eax
  64. else
  65. push ds ; Copy current stack into st(-1)
  66. pop es
  67. movsd
  68. movsd
  69. movsd
  70. endif
  71. call eFSIN
  72. PUSHST
  73. call eFCOS
  74. ret
  75. lab eFcosSpecial
  76. mov esp, ebp
  77. pop ebp
  78. mov SEL[RESULT], esi
  79. mov al, SEL[esi.bTag]
  80. cmp al, bTAG_ZERO
  81. JSNE eFcosInf
  82. lab eFcosRetOne
  83. mov SEL[esi.lMan0], 0
  84. mov SEL[esi.lMan1], 080000000h
  85. mov SEL[esi.wExp], 3fffh - IexpBias
  86. mov SEL[esi.bFlags], 0
  87. mov SEL[esi.bTag], bTAG_VALID
  88. ret
  89. lab eFcosInf
  90. cmp al, bTAG_INF
  91. JE RetIndInv
  92. lab eFcosNaN
  93. jmp OneArgOpNaNRet
  94. cProc eFCOS,<PLM,PUBLIC>,<>
  95. localT temp
  96. localB SignFlag
  97. cBegin
  98. mov esi, SEL[CURstk]
  99. cmp SEL[esi.bTag], bTAG_VALID
  100. jne eFcosSpecial
  101. or SEL[CURerr], Precision
  102. and SEL[esi].bFlags, not bSign ; st(0) = fabs( st(0) );
  103. call SinCosReduce ; Set ah to condition code.
  104. add SEL[esi].wExp, IExpBias
  105. push SEL[esi].wExp
  106. push SEL[esi].lMan1
  107. push SEL[esi].lMan0
  108. lea ecx, [temp]
  109. push ecx
  110. mov bl, ah ; if octant 2, 3, 4, or 5 then final
  111. and bl, bOCT2 or bOCT4 ; result must be negative
  112. mov [SignFlag], bl
  113. test ah, bOCT1 or bOCT2 ; if octant is 1, 2, 5, 6 then must
  114. jpo CosCallSin ; do sin()
  115. call __FASTLDCOS
  116. jmp short CosCopyRes
  117. CosCallSin:
  118. call __FASTLDSIN
  119. CosCopyRes:
  120. mov eax, dword ptr [temp]
  121. mov SEL[esi].lMan0, eax
  122. mov eax, dword ptr [temp+4]
  123. mov SEL[esi].lMan1, eax
  124. mov ax, word ptr [temp+8]
  125. sub ax, IExpBias
  126. mov SEL[esi].wExp, ax
  127. cmp [SignFlag], 0
  128. jpe CosDone
  129. or SEL[esi].bFlags, bSign ; Make result negative.
  130. CosDone:
  131. cEnd
  132. lab eFsinSpecial
  133. mov esp, ebp
  134. pop ebp
  135. mov al, SEL[esi.bTag]
  136. cmp al, bTAG_ZERO
  137. JSNE eFsinInf
  138. lab eFsinZero
  139. ret
  140. lab eFsinInf
  141. cmp al, bTAG_INF
  142. JE RetIndInv
  143. lab eFsinNaN
  144. jmp OneArgOpNaNRet
  145. cProc eFSIN,<PLM,PUBLIC>,<>
  146. localT temp
  147. localB SignFlag
  148. cBegin
  149. mov esi, SEL[CURstk]
  150. cmp SEL[esi.bTag], bTAG_VALID
  151. jne eFsinSpecial
  152. or SEL[CURerr], Precision
  153. mov al, SEL[esi].bFlags
  154. and SEL[esi].bFlags, not bSign
  155. shl al, 1 ; shift sign into carry.
  156. sbb cl, cl ; set cl to -1 if argument is negative.
  157. push ecx
  158. call SinCosReduce ; Set ah to condition code.
  159. pop ecx
  160. cmp SEL[esi].bTag, bTAG_ZERO
  161. je SinDone
  162. add SEL[esi].wExp, IExpBias
  163. push SEL[esi].wExp
  164. push SEL[esi].lMan1
  165. push SEL[esi].lMan0
  166. lea ebx, [temp]
  167. push ebx
  168. mov bl, ah ; if octant 4, 5, 6 or 7 then final
  169. and bl, bOCT4 ; result must be negative
  170. neg cl ; set cl to odd parity if arg was < 0.0
  171. xor bl, cl ; set bl to odd parity if result must be negative
  172. mov [SignFlag], bl
  173. test ah, bOCT1 or bOCT2 ; if octant is 1, 2, 5, 6 then must
  174. jpo SinCallCos ; do cos()
  175. call __FASTLDSIN
  176. jmp short SinCopyResult
  177. SinCallCos:
  178. call __FASTLDCOS
  179. SinCopyResult:
  180. mov eax, dword ptr [temp]
  181. mov SEL[esi].lMan0, eax
  182. mov eax, dword ptr [temp+4]
  183. mov SEL[esi].lMan1, eax
  184. mov ax, word ptr [temp+8]
  185. sub ax, IExpBias
  186. mov SEL[esi].wExp, ax
  187. cmp [SignFlag], 0
  188. jpe SinDone
  189. or SEL[esi].bFlags, bSign ; Make result negative.
  190. SinDone:
  191. cEnd
  192. lab SinCosReduce
  193. mov SEL[TEMP1.bFlags], 0 ; TEMP1 = pi/4
  194. mov SEL[TEMP1.bTag], bTAG_VALID
  195. mov SEL[TEMP1.wExp], 3ffeh-IExpBias
  196. mov SEL[TEMP1.wMan3], 0c90fh
  197. mov SEL[TEMP1.wMan2], 0daa2h
  198. mov SEL[TEMP1.wMan1], 2168h
  199. mov SEL[TEMP1.wMan0], 0c235h
  200. ifdef NT386
  201. mov edi, TEMP1
  202. else
  203. mov edi, edataOFFSET TEMP1
  204. endif
  205. push esi
  206. call InternFPREM ; rsi = st(0), rdi = st(0)
  207. pop esi
  208. mov ah, SEL[SWcc]
  209. test ah, bOCT1 ; check for even octant
  210. jz EvenOct ; yes
  211. add SEL[esi.wExp], IExpBias ; convert to true long double
  212. push ds
  213. push esi
  214. push cs
  215. push ecodeOFFSET PIBY4
  216. push ds
  217. push esi
  218. push -1
  219. call __FASTLDADD ; st(0) = pi/4 - st(0)
  220. mov ah, SEL[SWcc]
  221. sub SEL[esi.wExp], IExpBias ; convert to squirly emulator long double
  222. EvenOct:
  223. retn
  224. labelW PIBY4
  225. dw 0c235h, 02168h, 0daa2h, 0c90fh, 3ffeh
  226. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  227. ; NOTE tedm: NT masm can't handle floating-point constants ;
  228. ; because strtod and _strtold C-runtimes aren't ;
  229. ; there. So the constants below must be pre- ;
  230. ; assembled and defined as a byte stream. ;
  231. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  232. ifdef NOTDEF
  233. staticT FourByPI, +0.1273239544735162686151e+01
  234. staticT SinP0, +0.7853981633974483096141845e+00
  235. staticT SinP1, -0.8074551218828078152025820e-01
  236. staticT SinP2, +0.2490394570192716275251900e-02
  237. staticT SinP3, -0.3657620418214640005290000e-04
  238. staticT SinP4, +0.3133616889173253480000000e-06
  239. staticT SinP5, -0.1757247417617080600000000e-08
  240. staticT SinP6, +0.6948152035052200000000000e-11
  241. staticT SinP7, -0.2022531292930000000000000e-13
  242. staticT CosP0, +0.99999999999999999996415e+00
  243. staticT CosP1, -0.30842513753404245242414e+00
  244. staticT CosP2, +0.15854344243815410897540e-01
  245. staticT CosP3, -0.32599188692668755044000e-03
  246. staticT CosP4, +0.35908604458858195300000e-05
  247. staticT CosP5, -0.24611363826370050000000e-07
  248. staticT CosP6, +0.11500497024263000000000e-09
  249. staticT CosP7, -0.38577620372000000000000e-12
  250. else
  251. staticB FourByPI, <02Ah,015h,044h,04Eh,06Eh,083h,0F9h,0A2h,0FFh,03Fh>
  252. staticB SinP0 , <035h,0C2h,068h,021h,0A2h,0DAh,00Fh,0C9h,0FEh,03Fh>
  253. staticB SinP1 , <0DAh,095h,0F2h,02Dh,031h,0E7h,05Dh,0A5h,0FBh,0BFh>
  254. staticB SinP2 , <0E9h,0C6h,056h,0ADh,03Bh,0E3h,035h,0A3h,0F6h,03Fh>
  255. staticB SinP3 , <0D5h,0E7h,05Dh,015h,073h,066h,069h,099h,0F0h,0BFh>
  256. staticB SinP4 , <0BCh,032h,069h,0E1h,042h,01Ah,03Ch,0A8h,0E9h,03Fh>
  257. staticB SinP5 , <021h,077h,004h,05Fh,0A1h,0A5h,083h,0F1h,0E1h,0BFh>
  258. staticB SinP6 , <0FCh,01Ah,0D1h,006h,0CCh,063h,077h,0F4h,0D9h,03Fh>
  259. staticB SinP7 , <04Ah,003h,086h,040h,07Ch,065h,02Ch,0B6h,0D1h,0BFh>
  260. staticB CosP0 , <0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FEh,03Fh>
  261. staticB CosP1 , <02Fh,0F2h,02Eh,0F2h,04Dh,0E6h,0E9h,09Dh,0FDh,0BFh>
  262. staticB CosP2 , <02Fh,04Eh,0D5h,0DAh,040h,0F8h,0E0h,081h,0F9h,03Fh>
  263. staticB CosP3 , <09Dh,0DEh,06Ah,0E4h,0F1h,0E3h,0E9h,0AAh,0F3h,0BFh>
  264. staticB CosP4 , <031h,01Eh,0F9h,081h,041h,083h,0FAh,0F0h,0ECh,03Fh>
  265. staticB CosP5 , <076h,0B1h,000h,0A4h,01Eh,0F6h,068h,0D3h,0E5h,0BFh>
  266. staticB CosP6 , <0D8h,005h,06Fh,08Ah,0EAh,00Ah,0E6h,0FCh,0DDh,03Fh>
  267. staticB CosP7 , <003h,0D5h,00Ah,0ACh,0CCh,035h,02Ch,0D9h,0D5h,0BFh>
  268. endif
  269. cProc __FASTLDSIN,<PLM,PUBLIC>,<isi,idi>
  270. parmT x
  271. parmI RetOff
  272. localT x2
  273. localT poly
  274. localI count
  275. cBegin
  276. lea isi, [x] ; x = x * (4/PI)
  277. push ss
  278. push isi
  279. push ss
  280. push isi
  281. mov iax, codeOFFSET FourByPI
  282. push cs
  283. push iax
  284. call __FASTLDMULT
  285. lea idi, [x2] ; x2 = x * x
  286. push ss
  287. push idi
  288. push ss
  289. push isi
  290. push ss
  291. push isi
  292. call __FASTLDMULT
  293. if 0
  294. push ss
  295. pop es
  296. lea idi, [poly]
  297. mov isi, codeOFFSET SinP7
  298. movsw
  299. movsw
  300. movsw
  301. movsw
  302. movsw
  303. endif
  304. mov eax, dword ptr [SinP7] ; poly = SinP7
  305. mov dword ptr [poly], eax
  306. mov eax, dword ptr [SinP7+4]
  307. mov dword ptr [poly+4], eax
  308. mov ax, word ptr [SinP7+8]
  309. mov word ptr [poly+8], ax
  310. lea isi, [poly]
  311. mov idi, codeOFFSET SinP6
  312. mov [count], 7
  313. SinPolyLoop:
  314. push ss
  315. push isi ; poly = poly * x2
  316. push ss
  317. push isi
  318. lea iax, [x2]
  319. push ss
  320. push iax
  321. call __FASTLDMULT
  322. push ss
  323. push isi ; poly = poly + SinP[n]
  324. push ss
  325. push isi
  326. push cs
  327. push idi
  328. xor iax, iax
  329. push iax
  330. call __FASTLDADD
  331. sub idi, 10
  332. dec [count]
  333. jnz SinPolyLoop
  334. push ss
  335. push [RetOff] ; return x * poly
  336. lea iax, [x]
  337. push ss
  338. push iax
  339. push ss
  340. push isi
  341. call __FASTLDMULT
  342. mov iax, [RetOff]
  343. mov idx, ss
  344. cEnd
  345. cProc __FASTLDCOS,<PLM,PUBLIC>,<isi,idi>
  346. parmT x
  347. parmI RetOff
  348. localT x2
  349. localI count
  350. cBegin
  351. lea isi, [x] ; x = x * (4/PI)
  352. push ss
  353. push isi
  354. push ss
  355. push isi
  356. mov iax, codeOFFSET FourByPI
  357. push cs
  358. push iax
  359. call __FASTLDMULT
  360. lea idi, [x2] ; x2 = x * x
  361. push ss
  362. push idi
  363. push ss
  364. push isi
  365. push ss
  366. push isi
  367. call __FASTLDMULT
  368. if 0
  369. push ss ; (return) = CosP7
  370. pop es
  371. mov idi, [RetOff]
  372. mov isi, codeOFFSET CosP7
  373. movsw
  374. movsw
  375. movsw
  376. movsw
  377. movsw
  378. endif
  379. mov isi, [RetOff]
  380. mov eax, dword ptr [CosP7]
  381. mov dword ptr ss:[isi], eax
  382. mov eax, dword ptr [CosP7+4]
  383. mov dword ptr ss:[isi+4], eax
  384. mov ax, word ptr [CosP7+8]
  385. mov word ptr ss:[isi+8], ax
  386. mov idi, codeOFFSET CosP6
  387. mov [count], 7
  388. CosPolyLoop:
  389. push ss
  390. push isi ; (return) = (return) * x2
  391. push ss
  392. push isi
  393. lea iax, [x2]
  394. push ss
  395. push iax
  396. call __FASTLDMULT
  397. push ss
  398. push isi ; (return) = (return) + SinP[n]
  399. push ss
  400. push isi
  401. push cs
  402. push idi
  403. xor iax, iax
  404. push iax
  405. call __FASTLDADD
  406. sub idi, 10
  407. dec [count]
  408. jnz CosPolyLoop
  409. mov iax, isi
  410. mov idx, ss
  411. cEnd