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.

469 lines
12 KiB

  1. page ,132
  2. subttl emftran.asm - Transcendentals
  3. ;***
  4. ;emftran.asm - Transcendentals
  5. ;
  6. ; Copyright (c) 1986-89, Microsoft Corporation
  7. ;
  8. ;Purpose:
  9. ; Transcendentals
  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. ;-----------------------------------------;
  19. ; ;
  20. ; Transcendentals ;
  21. ; ;
  22. ;-----------------------------------------;
  23. ProfBegin FTRAN
  24. pub MoveCodeSItoDataSI
  25. PUSH edi
  26. MOV edi,offset COEFFICIENT
  27. ifdef i386
  28. rept Reg87Len/4
  29. MOVS dword ptr es:[edi],dword ptr cs:[esi]
  30. endm
  31. else
  32. rept Reg87Len/2
  33. MOVS word ptr es:[edi],word ptr cs:[esi]
  34. endm
  35. endif
  36. MOV esi,offset COEFFICIENT
  37. POP edi
  38. RET
  39. ;---------------------------------------------------
  40. ; !
  41. ; 8087 emulator transcendental utilities !
  42. ; !
  43. ;---------------------------------------------------
  44. ; COMPcsSIDI is analogous to the 8086 CMP instruction with operands
  45. ; cs:[SI],[DI]. All registers except CX and DX are left unaltered.
  46. ; Zero and negative zero are determined to be unequal. NAN's and
  47. ; infinities may not be compared with this routine.
  48. ;
  49. ; FRAT2X performs {TOS=[DI]} <-- {TOS=[SI]}*PNUM({TOS=[SI]}^2),
  50. ; and program created {temp=[SI]} <-- PDEN({TOS=[SI]}^2). On input,
  51. ; [BX] must contain the degree of PNUM, the coefficients of PNUM
  52. ; in descending order, the degree-1 of PDEN and the coefficients
  53. ; of PDEN in descending order. PDEN is evaluated assuming an implied
  54. ; highest coefficient of one. [BX] is left unaltered, ARG2 is loaded
  55. ; with {TOS}^2, DENORX is used, all registers are destroyed with
  56. ; DI returning the value input in SI.
  57. pub BOTHZERO
  58. CMP CH,CH ;set flags to equal
  59. JMP short COMPDONE ;compare finished
  60. pub COMPcsSIDI
  61. MOV CX,CS
  62. MOV DS,CX
  63. MOV CX,[esi+Flag] ;get sign byte of [SI]
  64. AND CL,Sign ;mask for sign
  65. MOV DX,ES:[edi+Flag] ;get sign byte of [DI]
  66. AND DL,Sign ;mask for sign
  67. CMP DL,CL ;compare signs
  68. JNE short SIGNDIFF
  69. PUSH ES
  70. PUSH esi
  71. PUSH edi ;save pointers
  72. OR CL,CL ;if signs are +
  73. JNS short BOTHPOS ; don't exchange pointers
  74. PUSH DS
  75. PUSH ES
  76. POP DS
  77. POP ES
  78. XCHG esi,edi ;exchange pointers
  79. XCHG CX,DX ;exchange flags
  80. pub BOTHPOS
  81. AND CH,ZROorINF ;mask for zero
  82. AND DH,ZROorINF ;mask for zero
  83. CMP DH,CH ;if exactly one zero
  84. JNE short COMPDONE ; then finished
  85. OR CH,CH ;if both zero
  86. JA BOTHZERO ; then done after flags set
  87. MOV CX,[esi+Expon] ;get exponent of [SI]
  88. ADD CX,IexpBias ;make it unbiased
  89. MOV DX,ES:[edi+Expon] ;get exponent of [DI]
  90. ADD DX,IexpBias ;make it unbiased
  91. CMP CX,DX
  92. JNE short COMPDONE ;compare exponents
  93. ADD esi,MB6
  94. ADD edi,MB6
  95. STD
  96. CMPS word ptr [edi],word ptr [esi]
  97. JNE short COMPDONE
  98. CMPS word ptr [edi],word ptr [esi]
  99. JNE short COMPDONE
  100. CMPS word ptr [edi],word ptr [esi]
  101. JNE short COMPDONE
  102. CMPS word ptr [edi],word ptr [esi] ;compare mantissas
  103. pub COMPDONE
  104. CLD
  105. POP edi
  106. POP esi
  107. POP ES
  108. pub SIGNDIFF
  109. MOV CX,ES
  110. MOV DS,CX
  111. RET
  112. pub FRAT2X
  113. MOV edi,offset DENORX ;[DI]=temp
  114. CALL MOVRQQ ;[DI]=x=temp
  115. PUSH edi ;save ptr to x=temp
  116. PUSH esi ;save ptr to TOS
  117. PUSH ebx ;save ptr to polynomials
  118. MOV edi,offset ARG2 ;get ptr to space for x^2
  119. CALL MOVRQQ ;copy x to space for x^2
  120. MOV [RESULT],edi ;result=[DI]
  121. CALL MUDRQQ ;ARG2 gets x^2
  122. POP esi ;get ptr to numerator poly
  123. ifdef i386
  124. xor ecx,ecx
  125. endif
  126. LODS word ptr CS:[esi]
  127. XCHG CX,AX ;CX=denominator degree-1
  128. POP edi ;[DI]=TOS
  129. CALL csMOVRQQ ;[DI]=first coeff=TOS
  130. MOV [RESULT],edi ;result=[DI]
  131. pub POLYLOOPA
  132. PUSH ecx ;save no. of terms left
  133. PUSH esi ;save ptr to next coeff
  134. MOV esi,offset ARG2 ;get ptr to x^2
  135. CALL MUDRQQ ;multiply TOS by x^2
  136. POP esi ;get pointer to coeff
  137. ADD esi,Reg87Len ;point to next coeff
  138. PUSH esi ;save pointer to coeff
  139. CALL MoveCodeSItoDataSI
  140. CALL ADDRQQ ;add coeff to TOS
  141. POP esi ;get ptr to coeff
  142. POP ecx ;get no. of terms remaining
  143. LOOP POLYLOOPA ;loop until no terms left
  144. MOV ebx,esi ;move poly ptr
  145. POP esi ;[SI]=x=temp
  146. PUSH esi ;save ptr to x
  147. PUSH ebx ;save poly ptr
  148. CALL MUDRQQ ;multiply poly by x
  149. POP esi ;get ptr to poly
  150. ADD esi,12 ;[SI]=denominator degree-1
  151. ifdef i386
  152. xor ecx,ecx
  153. endif
  154. LODS word ptr CS:[esi]
  155. XCHG CX,AX ;CX=denominator degree-1
  156. POP ebx ;[BX]=temp
  157. PUSH edi ;save denominator ptr
  158. MOV edi,ebx ;[DI]=temp
  159. CALL csMOVRQQ ;move second coeff to temp
  160. PUSH ecx ;save poly degree-1
  161. PUSH esi ;save ptr to denominator poly
  162. MOV esi,offset ARG2 ;get ptr to x^2
  163. MOV [RESULT],edi ;result=[DI]
  164. CALL ADDRQQ ;add x^2 to temp
  165. POP esi ;get ptr to second coeff
  166. POP ecx ;get poly degree-1
  167. pub POLYLOOPB
  168. PUSH ecx ;save no. of terms left
  169. ADD esi,Reg87Len ;point to next coeff
  170. PUSH esi ;save ptr to next coeff
  171. MOV esi,offset ARG2 ;get ptr to x^2
  172. CALL MUDRQQ ;multiply temp by x^2
  173. POP esi ;get pointer to coeff
  174. PUSH esi ;save pointer to coeff
  175. CALL MoveCodeSItoDataSI
  176. CALL ADDRQQ ;add coeff to temp
  177. POP esi ;get ptr to coeff
  178. POP ecx ;get no. of terms remaining
  179. LOOP POLYLOOPB ;loop until no terms left
  180. MOV esi,edi ;[SI]=denominator=temp
  181. POP edi ;[DI]=numerator=TOS
  182. RET
  183. ;-------------------------------------------------------------------------------
  184. pub eFPTAN
  185. MOV esi,[CURstk]
  186. CALL $FPTAN
  187. PUSH esi
  188. PUSHST
  189. MOV edi,[CURstk]
  190. POP esi
  191. CALL MOVRQQ
  192. RET
  193. ;---------------------------------------------------
  194. ; !
  195. ; 8087 emulator partial tangent !
  196. ; !
  197. ;---------------------------------------------------
  198. ; When 0<=x={TOS=[SI]}<=pi/4 then $FPTAN performs {TOS=[DI]} <--
  199. ; numerator tangent ({TOS=[SI]}), system created {temp=[SI]} <--
  200. ; denominator tangent ({TOS=[SI]). Every register except DI is
  201. ; destroyed.
  202. pub $FPTAN
  203. MOV ebx,offset TANRAT ;[BX]=rational function
  204. CALL FRAT2X ;[DI]=numerator=TOS,
  205. RET ; [SI]=denominator=temp
  206. ;-------------------------------------------------------------------------------
  207. pub eFPATAN
  208. MOV edi,[CURstk]
  209. MOV esi,edi
  210. MOV AX,Flag[esi]
  211. SUB edi,Reg87Len
  212. pub CALLFPATAN
  213. CALL $FPATAN
  214. MOV esi,[CURstk]
  215. POPST
  216. RET
  217. ;---------------------------------------------------
  218. ; !
  219. ; 8087 emulator arctangent !
  220. ; !
  221. ;---------------------------------------------------
  222. ; When 0<y={[DI]=NOS}<=x={[SI]=TOS}<infinity then $FPATAN performs
  223. ; {NOS=[DI]} <-- arctangent({NOS=[DI]}/{TOS=[SI]}), TOS is left
  224. ; unaltered. All registers except DI are destroyed.
  225. pub $FPATAN
  226. MOV [RESULT],edi ;result=[DI]
  227. CALL DIDRQQ ;NOS=[DI] <-- [DI]/[SI]=x
  228. MOV AL,0 ;flag reset
  229. MOV esi,offset TWOMRT3 ;[SI]=2-3^.5
  230. CALL COMPcsSIDI ;if 2-3^.5 >= x
  231. JNB short ATNREDUCED ; then bypass arg reduction
  232. MOV esi,edi ;[SI]=x=NOS
  233. MOV edi,offset TEMP1 ;[DI]=temp
  234. CALL MOVRQQ ;[DI]=x=temp
  235. PUSH esi ;save NOS
  236. MOV esi,offset RT3 ;[SI]=3^.5
  237. CALL MoveCodeSItoDataSI
  238. MOV [RESULT],edi ;result=[DI]
  239. CALL MUDRQQ ;[DI]=3^.5*x=temp
  240. MOV esi,offset cFLD1 ;[SI]=1
  241. CALL MoveCodeSItoDataSI
  242. CALL SUDRQQ ;[DI]=3^.5*x-1
  243. POP esi ;get NOS
  244. PUSH edi ;save ptr to 3^.5*x-1
  245. MOV edi,esi ;DI gets NOS
  246. MOV esi,offset RT3 ;[SI]=3^.5
  247. CALL MoveCodeSItoDataSI
  248. MOV [RESULT],edi ;result=[DI]
  249. CALL ADDRQQ ;[DI]=x+3^.5=NOS
  250. POP esi ;[SI]=3^.5*x-1
  251. CALL DRDRQQ ;[DI]=(3^.5*x-1)/(x+3^.5)=NOS
  252. MOV AL,1 ;flag set
  253. pub ATNREDUCED
  254. PUSH eax ;save flag
  255. MOV esi,edi ;[SI]=reduced x=NOS
  256. MOV ebx,offset ATNRAT ;[BX]=rational function
  257. CALL FRAT2X ;[DI]=numerator=NOS,
  258. ; [SI]=denominator=temp
  259. MOV [RESULT],edi ;result=[DI]
  260. CALL DIDRQQ ;[DI]=arctan(reduced x)=NOS
  261. POP eax ;get flag
  262. OR AL,AL ;if flag=0
  263. JZ short ATNCOMPLETE ; bypass adjust
  264. MOV esi,offset PIBY6 ;[SI]=pi/6
  265. CALL MoveCodeSItoDataSI
  266. CALL ADDRQQ ;[DI]=arctan(x)=NOS
  267. pub ATNCOMPLETE
  268. RET
  269. ;-------------------------------------------------------------------------------
  270. pub eF2XM1
  271. MOV esi,[CURstk]
  272. CALL $F2XM1
  273. RET
  274. ;---------------------------------------------------
  275. ; !
  276. ; 8087 emulator exponential !
  277. ; !
  278. ;---------------------------------------------------
  279. ; When 0<=x={TOS=[SI]}<=.5 then $F2XM1 performs {TOS=[SI]} <--
  280. ; 2^{TOS=[SI]}-1. All registers except SI are destroyed.
  281. pub $F2XM1
  282. MOV ebx,offset EXPRAT ;[BX]=rational function
  283. CALL FRAT2X ;[DI]=numerator=TOS
  284. PUSH edi ;save numerator=TOS
  285. XCHG esi,edi ;[SI]=numerator, [DI]=denominator
  286. MOV [RESULT],edi ;result=[DI]
  287. CALL SUDRQQ ;[DI]=denominator-numerator
  288. MOV esi,edi ;[SI]=denominator-numerator
  289. POP edi ;[DI]=numerator=TOS
  290. MOV [RESULT],edi ;result=[DI]
  291. CALL DIDRQQ ;[DI]=(2^x-1)/2
  292. INC word ptr [edi+Expon] ;[DI]=2^x-1
  293. MOV esi,edi ;[SI]=2^x-1
  294. RET
  295. ;-------------------------------------------------------------------------------
  296. pub eFYL2X
  297. MOV edi,[CURstk]
  298. MOV esi,edi
  299. MOV AX,Flag[esi]
  300. SUB edi,Reg87Len
  301. pub CALLFYL2X
  302. CALL $FYL2X
  303. MOV esi,[CURstk]
  304. POPST
  305. RET
  306. ;---------------------------------------------------
  307. ; !
  308. ; 8087 emulator multiple of logarithm !
  309. ; !
  310. ;---------------------------------------------------
  311. ; When -infinity<y={NOS=[DI]}<infinity and 0<x={TOS=[SI]}<infinity
  312. ; then $FYL2X performs {NOS=[DI]} <-- {NOS=[DI]}*log2({TOS=[SI]}).
  313. ; TOS is left unaltered, all registers except DI are destroyed.
  314. pub $FYL2X
  315. PUSH esi ;save ptr to x=TOS
  316. MOV esi,edi ;[SI]=y=NOS
  317. MOV edi,offset TEMP2 ;[DI]=temp2
  318. CALL MOVRQQ ;[DI]=y=temp2
  319. MOV edi,esi ;[DI]=y=NOS
  320. POP esi ;[SI]=x=TOS
  321. PUSH edi ;save ptr to y=NOS
  322. MOV edi,offset TEMP3 ;[DI]=temp3
  323. CALL MOVRQQ ;[DI]=x=temp3
  324. MOV BX,[edi+Expon] ;BX=exponent of x
  325. MOV word ptr [edi+Expon],0 ;set exponent of x to 0
  326. MOV esi,offset RT2 ;[SI]=2^.5
  327. CALL COMPcsSIDI ;if reduced x < 2^.5
  328. JA short LOGREDUCED ; then bypass normalization
  329. DEC word ptr [edi+Expon] ;otherwise make x < 2^.5
  330. INC BX ;adjust exponent
  331. pub LOGREDUCED
  332. PUSH ebx ;save exponent of x
  333. MOV esi,offset cFLD1 ;[SI]=1
  334. CALL MoveCodeSItoDataSI
  335. MOV [RESULT],edi ;result=[DI]
  336. CALL SUDRQQ ;[DI]=(reduced x)-1=temp3
  337. MOV esi,edi ;[SI]=(reduced x)-1=temp3
  338. POP ebx ;get exponent of x
  339. POP edi ;[DI]=y=NOS
  340. PUSH ebx ;save exponent of x
  341. CALL $FYL2XP1 ;[DI]=y*log2(reduced x)=NOS
  342. POP ebx ;get exponent of x
  343. XOR AX,AX ;zero AX
  344. OR BX,BX ;if exponent is zero
  345. JZ short LOGRETURN ; then done
  346. MOV DX,AX ;make sign +
  347. JNS short EXPPOSITIVE ;if + then bypass adjust
  348. MOV DL,Sign ;make sign -
  349. NEG BX ;negate exponent
  350. pub EXPPOSITIVE
  351. MOV CX,16 ;initialize bit count
  352. pub LOGLOOP
  353. DEC CX ;decrement shift count
  354. SHL BX,1 ;and shift exponent of x left
  355. JNC LOGLOOP ;until carry detected
  356. PUSH edi ;save ptr to y*log2(reduced x)=NOS
  357. RCR BX,1 ;normalize exponent of x
  358. MOV edi,offset TEMP3 ;[DI]=temp3
  359. STOS word ptr es:[edi]
  360. STOS word ptr es:[edi]
  361. STOS word ptr es:[edi]
  362. MOV AX,BX
  363. STOS word ptr es:[edi]
  364. MOV AX,CX
  365. STOS word ptr es:[edi]
  366. MOV AX,DX
  367. STOS word ptr es:[edi] ;store exponent of x in temp3
  368. MOV edi,offset TEMP2 ;[DI]=y=temp2
  369. MOV esi,offset TEMP3 ;[SI]=exponent of x=temp3
  370. MOV [RESULT],edi ;result=[DI]
  371. CALL MUDRQQ ;[DI]=y*exponent of x=temp2
  372. MOV esi,edi ;[SI]=y*exponent of x=temp2
  373. POP edi ;[DI]=y*log2(reduced x)=NOS
  374. MOV [RESULT],edi ;result=[DI]
  375. CALL ADDRQQ ;[DI]=y*log2(x)=NOS
  376. pub LOGRETURN
  377. RET
  378. ;-------------------------------------------------------------------------------
  379. pub eFYL2XP1
  380. MOV edi,[CURstk]
  381. MOV esi,edi
  382. MOV AX,Flag[esi]
  383. SUB edi,Reg87Len
  384. pub CALLFYL2XP1
  385. CALL $FYL2XP1
  386. MOV esi,[CURstk]
  387. POPST
  388. RET
  389. ;---------------------------------------------------
  390. ; !
  391. ; 8087 emulator add 1 multiple of logarithm !
  392. ; !
  393. ;---------------------------------------------------
  394. ; When -infinity<y={[DI]=NOS}<infinity and
  395. ; 2^-.5-1<=x={[SI]=TOS}<2^.5-1 then $FYL2XP1 performs {NOS=[DI]}
  396. ; <-- {NOS=[DI]}*log2({TOS=[SI]}+1). TOS is left unaltered, all
  397. ; registers except DI are destroyed.
  398. pub $FYL2XP1
  399. PUSH edi ;save ptr to y
  400. MOV edi,offset TEMP1 ;[DI]=temp
  401. CALL MOVRQQ ;[DI]=x=temp
  402. PUSH esi ;save ptr to x
  403. MOV esi,offset TWO ;[SI]=2
  404. CALL MoveCodeSItoDataSI
  405. MOV [RESULT],edi ;result=[DI]
  406. CALL ADDRQQ ;[DI]=x+2=temp
  407. POP esi ;[SI]=x=TOS
  408. CALL DRDRQQ ;[DI]=x/(x+2)=temp
  409. INC word ptr [edi+Expon] ;[DI]=2x/(x+2)=temp
  410. MOV esi,edi ;[SI]=2x/(x+2)=temp
  411. MOV ebx,offset LOGRAT ;[BX]=rational function
  412. CALL FRAT2X ;[DI]=numerator=temp,
  413. ; [SI]=denominator=temp
  414. MOV [RESULT],edi ;result=[DI]
  415. CALL DIDRQQ ;[DI]=log2(x+1)=temp
  416. MOV esi,edi ;[SI]=log2(x+1)=temp
  417. POP edi ;get ptr to y=NOS
  418. MOV [RESULT],edi ;result=[DI]
  419. CALL MUDRQQ ;[DI]=y*log2(x+1)=NOS
  420. RET
  421. ProfEnd FTRAN