emuFncALib.s
上传用户:nvosite88
上传日期:2007-01-17
资源大小:4983k
文件大小:25k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* Copyright 1991-2001 Wind River Systems, Inc. */
  2. /*
  3. modification history
  4. --------------------
  5. 01e,28aug01,hdn  added FUNC/FUNC_LABEL, replaced .align with .balign
  6. 01d,16apr98,hdn  fixed comments which cause assembler error.
  7. 01c,03feb98,hdn  fixed sin/cos problem (SPR7764) w USSW v.311
  8. 01b,24oct96,yp   stuck in a # in USSC mailing addr so cpp will work
  9. 01a,24jan95,hdn  original US Software version.
  10. */
  11. #
  12. #       Filename:   EMUFNC.ASM
  13. #
  14. #       Copyright (C) 1990,1991 By
  15. #       # United States Software Corporation
  16. #       # 14215 N.W. Science Park Drive
  17. #       # Portland, Oregon 97229
  18. #
  19. #       This software is furnished under a license and may be used
  20. #       and copied only in accordance with the terms of such license
  21. #       and with the inclusion of the above copyright notice.
  22. #       This software or any other copies thereof may not be provided
  23. #       or otherwise made available to any other person.  No title to
  24. #       and ownership of the software is hereby transferred.
  25. #
  26. #       The information in this software is subject to change without
  27. #       notice and should not be construed as a commitment by United
  28. #       States Software Corporation.
  29. #
  30. #       Version:        V3.09  01/19/95 GOFAST  WRS GNU version of GF-PROT
  31. #       Released:       1 March 1991
  32. #
  33. #
  34. #define _ASMLANGUAGE
  35. #include "vxWorks.h"
  36. #include "asm.h"
  37. .data
  38. .globl FUNC(copyright_wind_river)
  39. .long FUNC(copyright_wind_river)
  40. .include "emuIncALib.s"
  41. .text
  42. #        extrn   wiep:near
  43. #        extrn   tnormal:near,shiftr:near,exproc:near,exprop:near
  44. #        extrn   epmul:near
  45. #        extrn   epadd1:near,epmul1:near,epdiv1:near
  46. #        extrn   retnan:near,getqn:near,chkarg:near,exret:near
  47. #DGROUP  GROUP   hwseg
  48. #CGROUP  GROUP   emuseg
  49. #hwseg   segment RW para public 'DATA'
  50. #        assume  ds:DGROUP, es:DGROUP, ss:DGROUP
  51. #        extrn   h_ctrl:word,h_stat:word
  52. #hwseg   ends
  53. #emuseg  segment public USE32 'CODE'
  54. #        assume  cs:CGROUP
  55. __lib:
  56. #        subttl  (2 to power x) - 1
  57. #        page
  58. # raise 2 to power x and subtract 1 (x between -1 and 1)
  59. # input:        EP in cx:edx:eax
  60. # output:       result in cx:edx:eax
  61. .globl epf2xm1
  62. .balign 16
  63. expcon: .word 0,0xf717,0x0001,0x0000,0x0000,0x0000 # ln2^18/18!
  64. .word 0,0x0889,0x0033,0x0000,0x0000,0x0000 # ln2^17/17!
  65. .word 0,0xa26b,0x04e3,0x0000,0x0000,0x0000 # ln2^16/16!
  66. .word 0,0xa10e,0x70db,0x0000,0x0000,0x0000 # ln2^15/15!
  67. .word 0,0x26ac,0x8a4b,0x0009,0x0000,0x0000 # ln2^14/14!
  68. .word 0,0x8b36,0xb0c9,0x00c0,0x0000,0x0000 # ln2^13/13!
  69. .word 0,0x7e14,0xeb28,0x0e1d,0x0000,0x0000 # ln2^12/12!
  70. .word 0,0x8dd9,0x639a,0xf465,0x0000,0x0000 # ln2^11/11!
  71. .word 0,0xc764,0x8ac5,0x267a,0x000f,0x0000 # ln2^10/10!
  72. .word 0,0x3e1e,0x9caf,0x929e,0x00da,0x0000 # ln2^9/9!
  73. .word 0,0x11fe,0xd2e4,0x0111,0x0b16,0x0000 # ln2^8/8!
  74. .word 0,0x1a1b,0x22c3,0xff16,0x7ff2,0x0000 # ln2^7/7!
  75. .word 0,0xdbd2,0xb1e1,0x4be1,0x0c24,0x0005 # ln2^6/6!
  76. .word 0,0x20e2,0xce62,0xcf14,0xb0ff,0x002b # ln2^5/5!
  77. .word 0,0x9ccb,0xe772,0xfba4,0x2ab6,0x013b # ln2^4/4!
  78. .word 0,0xcce9,0x2fe2,0xc128,0xc235,0x071a # ln2^3/3!
  79. .word 0,0x6f16,0x8ea8,0x82c5,0xbdff,0x1ebf # ln2^2/2!
  80. .word 0,0xe4f1,0xbcd5,0xe8e7,0x0bfb,0x58b9 # ln2^1/1!
  81. .word -1
  82. exp87: orl %ecx,%ecx #argument + or - 1
  83. jns exp89 #   +1 returns +1
  84. decl %ecx #   -1 returns -1/2
  85. exp89: ret
  86. expw: btl $16,%ecx #zero returns as such
  87. jc exp89
  88. call chkarg #weed out illegals
  89. jc exp89
  90. cmpw $0x7fff,%cx #-INF returns -1, +INF as such
  91. jnz exp2
  92. orl %ecx,%ecx
  93. jns exp89
  94. movl $0x80003fff,%ecx
  95. ret
  96. epf2xm1:
  97. testl $0x00030000,%ecx #jump if special value
  98. jnz expw
  99. exp2: #PREEXS  precis          #set precision exception
  100. orb $precis,h_stat
  101. testb $precis,h_ctrl
  102. jnz LL1
  103. orw $0x8080,h_stat
  104. movl $exret,-4(%ebp)
  105. LL1:
  106. cmpw $0x3fff,%cx #handle limit cases +1 and -1
  107. jz exp87
  108. movl $expcon,%ebx #call the polynomial routine
  109. call sigmax
  110. addw $0x3ffe,%cx
  111. call epmul #then multiply with x
  112. ret
  113. # sin: trigonometric sine of x
  114. # cos: trigonometric cosine of x
  115. # tan: trigonometric tangent of x
  116. # input:        x in ecx:edx:eax and ST
  117. # return:       answer in ecx:edx:eax
  118. .globl epsin,epcos,eptan
  119. .balign 16
  120. sincon: #coefficients for sin(x)
  121. .word 0,0x1dc0,0x654b,0x0000,0x0000,0x0000
  122. .word 0,0x6332,0x6030,0xff94,0xffff,0xffff
  123. .word 0,0xa1b4,0x184e,0x5849,0x0000,0x0000
  124. .word 0,0x763a,0x3015,0x3375,0xffca,0xffff
  125. .word 0,0x338e,0x56c7,0xe3a5,0x171d,0x0000
  126. .word 0,0x7f98,0x97f9,0xf97f,0x7f97,0xfff9
  127. .word 0,0x1111,0x1111,0x1111,0x1111,0x0111
  128. .word 0,0xaaab,0xaaaa,0xaaaa,0xaaaa,0xeaaa
  129. .word 0,0x0000,0x0000,0x0000,0x0000,0x8000
  130. .word -1
  131. .balign 16
  132. coscon: #coefficients for cos(x)
  133. .word 0,0x61b8,0xfa5f,0xffff,0xffff,0xffff
  134. .word 0,0xf9cc,0xb9fc,0x0006,0x0000,0x0000
  135. .word 0,0xcfe2,0xa2d5,0xf9b1,0xffff,0xffff
  136. .word 0,0x3624,0x3bfe,0x7bb6,0x0004,0x0000
  137. .word 0,0x1472,0x10ec,0x3609,0xfdb0,0xffff
  138. .word 0,0xd00d,0x0d00,0x00d0,0xd00d,0x0000
  139. .word 0,0x7d28,0x27d2,0xd27d,0x7d27,0xffd2
  140. .word 0,0x5555,0x5555,0x5555,0x5555,0x0555
  141. .word 0,0x0000,0x0000,0x0000,0x0000,0xc000
  142. .word 0,0x0000,0x0000,0x0000,0x0000,0x8000
  143. .word -1
  144. .balign 16
  145. tancon: #coefficients for tan(x)
  146. .word 0,0x49fa,0xa843,0xffff,0xffff,0xffff
  147. .word 0,0xd55c,0x9e11,0xfffc,0xffff,0xffff
  148. .word 0,0x5074,0x9d9a,0xffde,0xffff,0xffff
  149. .word 0,0xcc5e,0x827f,0xfeb6,0xffff,0xffff
  150. .word 0,0xb1e6,0x0f07,0xf34c,0xffff,0xffff
  151. .word 0,0xd54e,0x9a5c,0x82a0,0xffff,0xffff
  152. .word 0,0xb45a,0x38a6,0x2a9e,0xfffb,0xffff
  153. .word 0,0xd548,0xc10c,0x4b63,0xffd0,0xffff
  154. .word 0,0xe9e2,0xb1f6,0x24d3,0xfe29,0xffff
  155. .word 0,0x810a,0xbbda,0xfa29,0xedd7,0xffff
  156. .word 0,0x12ec,0x478a,0x86a0,0x4cab,0xffff
  157. .word 0,0x54e8,0xc43d,0x1b32,0x10a2,0xfff9
  158. .word 0,0x5100,0xaa65,0x0ffb,0xa655,0xffba
  159. .word 0,0xd27d,0x7d27,0x27d2,0xd27d,0xfd27
  160. .word 0,0x5555,0x5555,0x5555,0x5555,0xd555
  161. .word 0,0x0000,0x0000,0x0000,0x0000,0x8000
  162. .word -1
  163. epsin:
  164. #PREEXS  precis          #not precise
  165. orb $precis,h_stat
  166. testb $precis,h_ctrl
  167. jnz LL2
  168. orw $0x8080,h_stat
  169. movl $exret,-4(%ebp)
  170. LL2:
  171. cmpb $4,%bl #sin(x+pi) = -sinx
  172. jc sin2 #   so if octant > 3 we flip the sign
  173. xorb $0x80,11(%edi) #   and subtract 4 from octant number
  174. andb $-5,%bl
  175. sin2: jpo cos3 #if octant is 1 or 2 we take cosx
  176. sin3: movl %eax,(%edi) #store reduced value, leave sign
  177. movl %edx,4(%edi)
  178. movw %cx,8(%edi)
  179. call square #we use x^2 in the polynomial
  180. lea sincon,%ebx #do the polynomial
  181. call sigmax
  182. addw $0x3ffe,%cx
  183. call epmul1 #multiply with x
  184. ret
  185. epcos:
  186. #PREEXS  precis          #not precise
  187. orb $precis,h_stat
  188. testb $precis,h_ctrl
  189. jnz LL3
  190. orw $0x8080,h_stat
  191. movl $exret,-4(%ebp)
  192. LL3:
  193. andl $0xffff,%ecx #store for possible use, sign cleared
  194. movl %ecx,8(%edi)
  195. testb $2,%bl #we flip the sign in octants 2 and 3
  196. jz cos2
  197. xorb $0x80,11(%edi)
  198. cos2: cmpb $4,%bl #cos(x+pi) = -cosx
  199. jc cos2b #   so if octant > 3 we flip the sign
  200. xorb $0x80,11(%edi) #   and subtract 4 from octant number
  201. andb $-5,%bl
  202. cos2b: jpo sin3 #if octant is 1 or 2 we take sinx
  203. cos3: call square #we use x^2 in the polynomial
  204. lea coscon,%ebx #do the polynomial
  205. call sigmax
  206. addw $0x3ffe,%cx
  207. movw $0,8(%edi) #put in the sign
  208. orl 8(%edi),%ecx
  209. ret
  210. eptan:
  211. #PREEXS  precis          #not precise
  212. orb $precis,h_stat
  213. testb $precis,h_ctrl
  214. jnz LL4
  215. orw $0x8080,h_stat
  216. movl $exret,-4(%ebp)
  217. LL4:
  218. movl %eax,(%edi)
  219. movl %edx,4(%edi)
  220. movw %cx,8(%edi)
  221. andb $-5,%bl #tan(x+pi) = tan(x) 
  222. testb $2,%bl #if octant is 2 or 3 flip sign
  223. jz tan3
  224. xorb $0x80,11(%edi)
  225. tan3: call square #we use x^2 in the polynomial
  226. pushl %ebx #save the octant
  227. lea tancon,%ebx #do the polynomial
  228. call sigmax
  229. addw $0x3ffe,%cx
  230. popl %ebx #tan(x) = x/SUM
  231. orb %bl,%bl #   if octant is 1 or 2 we take 1/tan(x)
  232. jpo tan7
  233. xchgw 8(%edi),%cx
  234. xchgl 4(%edi),%edx
  235. xchgl 0(%edi),%eax
  236. tan7: call epdiv1
  237. ret #return
  238. #        subttl   base 2 logarithm of x
  239. #        page
  240. # take base 2 logarithm of x
  241. # input:        x in cx:edx:eax and ST
  242. # output:       log2(x) in cx:edx:eax
  243. .globl eplog,eplog1
  244. .balign 16
  245. logcon: .word 0,0x26b2,0xff99,0xd343,0x0f07,0x04dc #log2(e)/19
  246. .word 0,0xd0e5,0xc350,0xdd0f,0x6b26,0x056e #log2(e)/17
  247. .word 0,0xb98d,0xff7d,0xa533,0xcec5,0x0627 #log2(e)/15
  248. .word 0,0x388f,0xd807,0x34c5,0x3d5a,0x071a #log2(e)/13
  249. .word 0,0x2b91,0x1694,0xca01,0xd424,0x0864 #log2(e)/11
  250. .word 0,0x3540,0x54c7,0xbe01,0x589e,0x0a42 #log2(e)/9
  251. .word 0,0xb22e,0x6c9f,0x3d6f,0xbb15,0x0d30 #log2(e)/7
  252. .word 0,0x2ca7,0xfe79,0xef9b,0x6c50,0x1277 #log2(e)/5
  253. .word 0,0x9fc1,0xfd74,0x3a03,0x09dc,0x1ec7 #log2(e)/3
  254. .word 0,0xdf44,0xf85d,0xae0b,0x1d94,0x5c55 #log2(e)
  255. .word -1
  256. .balign 16
  257. flnlog: .word 0x0000,0x0000,0x0000,0x8000,0x3fff,0x8000 #log2(0.5) 
  258. .word 0xf0c1,0x0852,0xcb8c,0xd47f,0x3ffe,0x8000 #log2(0.5625)
  259. .word 0xd407,0xcb91,0x1ed0,0xad96,0x3ffe,0x8000 #log2(0.625)
  260. .word 0xc407,0x3457,0xb07f,0x8a62,0x3ffe,0x8000 #log2(0.6875)
  261. .word 0xf0c1,0x0852,0xcb8c,0xd47f,0x3ffd,0x8000 #log2(0.75)
  262. .word 0x432d,0x8773,0xf71b,0x995f,0x3ffd,0x8000 #log2(0.8125)
  263. .word 0x9333,0xfde9,0xc055,0xc544,0x3ffc,0x8000 #log2(0.875)
  264. .word 0x633a,0x7dda,0x24b6,0xbeb0,0x3ffb,0x8000 #log2(0.9375)
  265. .word 0x0000,0x0000,0x0000,0x0000,0x0000,1 #log2(1)
  266. .word 0x3cfd,0xdeb4,0xd1cf,0xae00,0x3ffc,0 #log2(1.125)
  267. .word 0x57f2,0x68dc,0xc25e,0xa4d3,0x3ffd,0 #log2(1.25)
  268. .word 0x77f2,0x9750,0x9f01,0xeb3a,0x3ffd,0 #log2(1.375)
  269. .word 0x87a0,0xfbd6,0x1a39,0x95c0,0x3ffe,0 #log2(1.5)
  270. .word 0x5e69,0x3c46,0x0472,0xb350,0x3ffe,0 #log2(1.625)
  271. .word 0x9b33,0x8085,0xcfea,0xceae,0x3ffe,0 #log2(1.75)
  272. .word 0xb399,0x3044,0xfb69,0xe829,0x3ffe,0 #log2(1.875)
  273. logzer: orb $zerod,h_stat #return -INF
  274. call exproc
  275. btsl $31,%edx
  276. jmp log88
  277. lognan: orb $invop,h_stat #return NaN
  278. call exproc
  279. movl $0xc0000000,%edx
  280. log88: movl $0x80027fff,%ecx
  281. xorl %eax,%eax
  282. log89: ret
  283. logw: btl $16,%ecx #zero returns -INF
  284. jc logzer
  285. call chkarg #weed out illegals
  286. jc log89
  287. orl %ecx,%ecx #negative illegal
  288. js lognan
  289. cmpw $0x7fff,%cx #+INF returns as such
  290. jz log89
  291. call tnormal #handle denormal
  292. #PUTEP   
  293. movl %eax,(%edi)
  294. movl %edx,4(%edi)
  295. movl %ecx,8(%edi)
  296. eplog:
  297. testl $0x80030000,%ecx #jump if special value
  298. jnz logw
  299. log2: movl %edx,%ebx #precision exception unless power of 2
  300. addl %ebx,%ebx
  301. orl %eax,%ebx
  302. jz log3
  303. #PREEXS  precis
  304. orb $precis,h_stat
  305. testb $precis,h_ctrl
  306. jnz LL5
  307. orw $0x8080,h_stat
  308. movl $exret,-4(%ebp)
  309. LL5:
  310. log3: movl %ecx,%ebx #we make the exponent 0 or -1
  311. cmpw $0x3fff,%cx #   depending on if x > 1 or < 1
  312. movw $0x3fff,%cx #   push the needed adjustment
  313. jge log31
  314. decl %ecx
  315. log31: movw %cx,8(%edi)
  316. subl %ecx,%ebx
  317. movswl %bx,%ebx
  318. pushl %ebx
  319. xorl %ebx,%ebx #calculate area number (0-15) 
  320. shldl $4,%edx,%ebx
  321. testb $1,%cl
  322. jnz log5
  323. andb $7,%bl
  324. log5: cmpb $7,%bl #handle 0.9375 < x < specially
  325. jnz log21
  326. incl %ebx
  327. pushl %ebx
  328. stc
  329. rcrl $1,%edx
  330. rcrl $1,%eax
  331. incw %cx
  332. xchgl (%edi),%eax
  333. xchgl 4(%edi),%edx
  334. xchgw 8(%edi),%cx
  335. notl %edx
  336. negl %eax
  337. sbbl $-1,%edx
  338. xorl $0x80000000,%ecx
  339. jmp log51
  340. log21: pushl %ebx #interpolation area number
  341. movl %edx,%ebx #registers = x+C
  342. andl $0xf0000000,%ebx
  343. addl %ebx,%edx
  344. rcrl $1,%edx
  345. rcrl $1,%eax
  346. incw %cx
  347. xchgl (%edi),%eax #swap arguments
  348. xchgl 4(%edi),%edx
  349. xchgw 8(%edi),%cx
  350. andl $0x0fffffff,%edx #registers = x-C
  351. log54: jnz log51
  352. orl %eax,%eax
  353. jnz log51
  354. xorl %ecx,%ecx
  355. jmp log57
  356. log51: decw %cx
  357. addl %eax,%eax
  358. adcl %edx,%edx
  359. jns log51
  360. log52: call epdiv1 #calculate d = (M-C)/(M+C)
  361. addb %bl,%bl
  362. adcl $0,%eax
  363. adcl $0,%edx
  364. #PUTEP   
  365. movl %eax,(%edi)
  366. movl %edx,4(%edi)
  367. movl %ecx,8(%edi)
  368. call square #square that
  369. lea logcon,%ebx #calculate polynomial for d^2
  370. call sigmax
  371. addb $0x40,%ch
  372. call epmul1 #then multiply by d
  373. addb %bl,%bl
  374. adcl $0,%eax
  375. adcl $0,%edx
  376. log57: popl %ebx #add base log2(C)
  377. shll $2,%ebx
  378. lea flnlog(%ebx,%ebx,2),%ebx
  379. movl %cs:(%ebx),%esi
  380. movl %esi,(%edi)
  381. movl %cs:4(%ebx),%esi
  382. movl %esi,4(%edi)
  383. movl %cs:8(%ebx),%esi
  384. movl %esi,8(%edi)
  385. call epadd1
  386. addb %bl,%bl
  387. adcl $0,%eax
  388. adcl $0,%edx
  389. #PUTEP   
  390. movl %eax,(%edi)
  391. movl %edx,4(%edi)
  392. movl %ecx,8(%edi)
  393. popl %edx #get exponent adjustment
  394. call wiep #   convert to EP, add to log2(d)
  395. call epadd1
  396. addb %bl,%bl
  397. adcl $0,%eax
  398. adcl $0,%edx
  399. log9: ret
  400. lgpw61: orl %ecx,%ecx #-INF returns NaN
  401. js lognan
  402. ret
  403. lgpw: btl $16,%ecx #zero returns 0
  404. jc log9
  405. call chkarg #weed out illegals
  406. jc log9
  407. cmpw $0x7fff,%cx #INF jumps
  408. jz lgpw61
  409. lgpw8: #PREEXS  precis          #very small multiplied by log2(e)
  410. orb $precis,h_stat
  411. testb $precis,h_ctrl
  412. jnz LL6
  413. orw $0x8080,h_stat
  414. movl $exret,-4(%ebp)
  415. LL6:
  416. movl $0x5C17F0BC,0(%edi)
  417. movl $0xB8AA3B29,4(%edi)
  418. movl $0x3fff,8(%edi)
  419. call epmul
  420. ret
  421. eplog1:
  422. testl $0x00030000,%ecx #jump if special value
  423. jnz lgpw
  424. cmpb $0x10,%ch #very small skip some code
  425. jc lgpw8
  426. #PREEXS  precis
  427. orb $precis,h_stat
  428. testb $precis,h_ctrl
  429. jnz LL7
  430. orw $0x8080,h_stat
  431. movl $exret,-4(%ebp)
  432. LL7:
  433. xorl %ebx,%ebx #push zero exponent adjustment
  434. pushl %ebx
  435. orl %ecx,%ecx #go handle x < 0 separately
  436. js lgp30
  437. subw $tBIAS-4,%cx #calculate area number (8-15) 
  438. cmpw $9,%cx
  439. jnc lgp3
  440. shldl %cl,%edx,%ebx
  441. lgp3: addb $8,%bl
  442. pushl %ebx
  443. movw $0x4000,%cx #calculate x+1+C
  444. subw 8(%edi),%cx
  445. call shiftr
  446. btsl $30,%edx
  447. movl %edx,%ebx
  448. andl $0x78000000,%ebx
  449. addl %ebx,%edx
  450. movl $0x4000,%ecx
  451. xchgl (%edi),%eax #swap arguments
  452. xchgl 4(%edi),%edx
  453. xchgl 8(%edi),%ecx
  454. movl %ecx,%ebx #registers = x-C
  455. addw $4-tBIAS,%bx
  456. jle log52
  457. xchgl %ecx,%ebx
  458. shll %cl,%edx
  459. shrl %cl,%edx
  460. xchgl %ecx,%ebx
  461. jmp log54
  462. lgp30: subw $tBIAS-5,%cx #calculate area number (0-7) 
  463. cmpw $9,%cx
  464. jnc lgp33
  465. shldl %cl,%edx,%ebx
  466. negl %ebx
  467. lgp33: addl $8,%ebx
  468. pushl %ebx
  469. movw $0x3fff,%cx #calculate x+1+C
  470. subw 8(%edi),%cx
  471. call shiftr
  472. movl %edx,%esi
  473. andl $0x38000000,%esi
  474. addl %esi,%edx
  475. addb %bl,%bl
  476. cmc
  477. notl %eax
  478. adcl $0,%eax
  479. notl %edx
  480. adcl $0,%edx
  481. movl $0x3fff,%ecx
  482. adcl $0,%ecx
  483. orl $0x80000000,%edx
  484. xchgl (%edi),%eax #swap arguments
  485. xchgl 4(%edi),%edx
  486. xchgl 8(%edi),%ecx
  487. movl %ecx,%ebx #registers = x-C
  488. addw $0xc006,%bx
  489. jle log52
  490. xchgl %ecx,%ebx
  491. shll %cl,%edx
  492. shrl %cl,%edx
  493. xchgl %ecx,%ebx
  494. jmp log54
  495. #        subttl   arctangent of x
  496. #        page
  497. # take arctangent of x
  498. # input:        x in cx:edx:eax and ST
  499. # output:       atan(x) in cx:edx:eax
  500. .globl epatan
  501. .balign 16
  502. atncon: #coefficients for polynomial
  503. .word 0,0x45d1,0x5d17,0xd174,0x1745,0xf45d
  504. .word 0,0xe38e,0x8e38,0x38e3,0xe38e,0x0e38
  505. .word 0,0xdb6e,0x6db6,0xb6db,0xdb6d,0xedb6
  506. .word 0,0x999a,0x9999,0x9999,0x9999,0x1999
  507. .word 0,0x5555,0x5555,0x5555,0x5555,0xd555
  508. .word 0,0x0000,0x0000,0x0000,0x0000,0x8000
  509. .word -1
  510. .balign 16
  511. attab: #interpolation table for n/32
  512. .word 0x0000,0x0000,0x0000,0x0000,0x0000,1 # atan(0.000000)
  513. .word 0x2542,0x4bb1,0xaddd,0xffea,0x3ff9,0 # atan(0.031250)
  514. .word 0x4e37,0x67ef,0xddb9,0xffaa,0x3ffa,0 # atan(0.062500)
  515. .word 0x7460,0x1788,0xc130,0xbf70,0x3ffb,0 # atan(0.093750)
  516. .word 0x6e33,0x617b,0xd4d5,0xfead,0x3ffb,0 # atan(0.125000)
  517. .word 0x62c4,0x3313,0x7746,0x9eb7,0x3ffc,0 # atan(0.156250)
  518. .word 0x1135,0x72d8,0xda5e,0xbdcb,0x3ffc,0 # atan(0.187500)
  519. .word 0x1023,0x9305,0xba94,0xdc86,0x3ffc,0 # atan(0.218750)
  520. .word 0xeb16,0x6406,0xafc9,0xfadb,0x3ffc,0 # atan(0.250000)
  521. .word 0xc130,0x5f8b,0xad18,0x8c5f,0x3ffd,0 # atan(0.281250)
  522. .word 0x5e6a,0x3f5e,0xb9b8,0x9b13,0x3ffd,0 # atan(0.312500)
  523. .word 0x4eda,0x8e6a,0x6cca,0xa985,0x3ffd,0 # atan(0.343750)
  524. .word 0x8473,0x26f7,0xca0f,0xb7b0,0x3ffd,0 # atan(0.375000)
  525. .word 0x2b6d,0x50d9,0x69ca,0xc592,0x3ffd,0 # atan(0.406250)
  526. .word 0xe5b6,0x611f,0x761e,0xd327,0x3ffd,0 # atan(0.437500)
  527. .word 0x7c68,0x764f,0xa64a,0xe06d,0x3ffd,0 # atan(0.468750)
  528. .word 0x7b46,0x0dda,0x382b,0xed63,0x3ffd,0 # atan(0.500000)
  529. .word 0xbe5c,0xa0a0,0xe85a,0xfa06,0x3ffd,0 # atan(0.531250)
  530. .word 0x7e2a,0xd986,0xf4a6,0x832b,0x3ffe,0 # atan(0.562500)
  531. .word 0x47b5,0xde95,0xecdf,0x892a,0x3ffe,0 # atan(0.593750)
  532. .word 0x9f9c,0xf7f5,0x5d5e,0x8f00,0x3ffe,0 # atan(0.625000)
  533. .word 0x86f6,0x8471,0x72c9,0x94ac,0x3ffe,0 # atan(0.656250)
  534. .word 0xda20,0x71bd,0x80e6,0x9a2f,0x3ffe,0 # atan(0.687500)
  535. .word 0xa1ed,0xf4b7,0xfdc4,0x9f89,0x3ffe,0 # atan(0.718750)
  536. .word 0x0924,0x34f7,0x7d19,0xa4bc,0x3ffe,0 # atan(0.750000)
  537. .word 0xf5c8,0x4830,0xabdc,0xa9c7,0x3ffe,0 # atan(0.781250)
  538. .word 0xc080,0xb4d8,0x4c38,0xaeac,0x3ffe,0 # atan(0.812500)
  539. .word 0x3691,0x1f04,0x31c9,0xb36b,0x3ffe,0 # atan(0.843750)
  540. .word 0x9e74,0xc231,0x3e2b,0xb805,0x3ffe,0 # atan(0.875000)
  541. .word 0xf281,0xe98a,0x5dea,0xbc7b,0x3ffe,0 # atan(0.906250)
  542. .word 0x6640,0xac52,0x85b8,0xc0ce,0x3ffe,0 # atan(0.937500)
  543. .word 0xbd54,0xbf8f,0xaffa,0xc4ff,0x3ffe,0 # atan(0.968750)
  544. atnw8: movl 8(%edi),%ecx #return 3pi/4
  545. andl $0x80000000,%ecx
  546. movw $0x4000,%cx
  547. movl $0x96cbe3f9,%edx
  548. movl $0x990e91a7,%eax
  549. orb $precis,h_stat
  550. call exprop
  551. ret
  552. atnzer: movb 11(%edi),%ch #return signed zero
  553. movb $1,%cl
  554. shll $16,%ecx
  555. xorl %edx,%edx
  556. xorl %eax,%eax
  557. ret
  558. atnw11: orl %ecx,%ecx # INF / INF
  559. js atnw8
  560. orb $precis,h_stat
  561. call exprop
  562. jmp atn90
  563. atnw3: cmpw $0x7fff,%cx # INF / y
  564. jz atnw11
  565. atnw9: orb $precis,h_stat
  566. call exprop
  567. atn82: movl $0x3fff,%ecx #INF returns +- pi/2
  568. jmp atn91
  569. atnw5: orl %ecx,%ecx # y / INF or 0 / x
  570. jns atnzer
  571. orb $precis,h_stat
  572. call exprop
  573. atn84: movl $0x4000,%ecx #here return +-pi
  574. jmp atn91
  575. atnw:
  576. call retnan #proper return for illegal arguments
  577. testb $1,10(%edi) #weed out x = 0
  578. jnz atnw5
  579. btl $16,%ecx #weed out y = 0
  580. jc atnw9
  581. cmpw $0x7fff,8(%edi) #weed out x = INF
  582. jz atnw3
  583. cmpw $0x7fff,%cx #weed out y = INF
  584. jz atnw5
  585. call tnormal #normalize arguments
  586. xchgl (%edi),%eax
  587. xchgl 4(%edi),%edx
  588. xchgl 8(%edi),%ecx
  589. call tnormal
  590. xchgl (%edi),%eax
  591. xchgl 4(%edi),%edx
  592. xchgl 8(%edi),%ecx
  593. jmp atn2
  594. atn90: orl %ecx,%ecx
  595. js atnw8
  596. movl $0x3ffe,%ecx #atan(1) return +-pi/4
  597. atn91: movl $0xc90fdaa2,%edx
  598. movl $0x2168c235,%eax
  599. jmp atn23
  600. atn89: movb s_X+5(%ebp),%bl
  601. testb $1,%bl
  602. jz atn82
  603. orb %bl,%bl
  604. js atn84
  605. call epdiv1
  606. jmp atn23
  607. epatan:
  608. shldl $16,%ecx,%ebx #save sign bits
  609. movb 11(%edi),%bl
  610. movw %bx,s_X+4(%ebp)
  611. shldl $16,%ecx,%ebx #weed out special arguments
  612. orb 10(%edi),%bl
  613. jnz atnw
  614. atn2: #PREEXS  precis          #set precision exception
  615. orb $precis,h_stat
  616. testb $precis,h_ctrl
  617. jnz LL8
  618. orw $0x8080,h_stat
  619. movl $exret,-4(%ebp)
  620. LL8:
  621. cmpw 8(%edi),%cx #compare x and y
  622. jl atn5
  623. jnz atn7
  624. cmpl 4(%edi),%edx
  625. jc atn5
  626. jnz atn7
  627. cmpl (%edi),%eax
  628. jz atn90
  629. jc atn5
  630. atn7: xchgl (%edi),%eax #switch arguments, set flag
  631. xchgl 4(%edi),%edx
  632. xchgl 8(%edi),%ecx
  633. incb s_X+5(%ebp)
  634. atn5: movl %ecx,%ebx #underflow here means either
  635. addw $tBIAS,%bx #   atn(INF) = +-pi/2 or
  636. subw 8(%edi),%bx #   atn(0) = 0 or pi
  637. cmpw $0x3f40,%bx
  638. jl atn89
  639. atn6: call epdiv1 #divide x / y
  640. andl $0x7fffffff,%ecx
  641. #PUTEP   
  642. movl %eax,(%edi)
  643. movl %edx,4(%edi)
  644. movl %ecx,8(%edi)
  645. xorl %ebx,%ebx #get interpolation interval, 0-31
  646. subw $tBIAS-6,%cx
  647. cmpw $9,%cx
  648. jc atn4
  649. movw $0,%cx
  650. atn4: shldl %cl,%edx,%ebx
  651. pushl %ebx
  652. shll %cl,%edx #calculate x - C = d
  653. shrl %cl,%edx
  654. movw 8(%edi),%cx
  655. js atn55
  656. jnz atn51
  657. orl %eax,%eax
  658. jnz atn51
  659. xorl %ecx,%ecx
  660. jmp atn54
  661. atn51: decw %cx
  662. addl %eax,%eax
  663. adcl %edx,%edx
  664. jns atn51
  665. atn55: pushl %eax #push d
  666. pushl %edx
  667. pushl %ecx
  668. rorl $5,%ebx #calculate x * C
  669. movl 4(%edi),%eax
  670. mull %ebx
  671. movl %eax,%ecx
  672. xchgl %ebx,%edx
  673. movl (%edi),%eax
  674. mull %edx
  675. addl %edx,%ecx
  676. adcl $0,%ebx
  677. movl %ebx,%edx #get x * C into right registers
  678. xchgl %ecx,%eax
  679. xorl %ebx,%ebx
  680. movl $0x3fff,%ecx
  681. subw 8(%edi),%cx
  682. atn11: shrl $1,%edx #normalize x * C to exponent 3fff
  683. rcrl $1,%eax
  684. loop atn11
  685. orl $0x80000000,%edx #calculate 1 + x*C
  686. movw $0x3fff,%cx
  687. #PUTEP   
  688. movl %eax,(%edi)
  689. movl %edx,4(%edi)
  690. movl %ecx,8(%edi)
  691. popl %ecx #calculate d/(1 + x*C)
  692. popl %edx
  693. popl %eax
  694. call epdiv1
  695. addb %bl,%bl
  696. adcl $0,%eax
  697. adcl $0,%edx
  698. #PUTEP   
  699. movl %eax,(%edi)
  700. movl %edx,4(%edi)
  701. movl %ecx,8(%edi)
  702. call square #polynomial uses x^2
  703. movl $atncon,%ebx #do the polynomial
  704. call sigmax
  705. addw $0x3ffe,%cx
  706. call epmul1 #multiply with x
  707. atn54: popl %ebx #then add atan(C)       
  708. shll $2,%ebx
  709. lea attab(%ebx,%ebx,2),%ebx
  710. movl %cs:(%ebx),%esi
  711. movl %esi,(%edi)
  712. movl %cs:4(%ebx),%esi
  713. movl %esi,4(%edi)
  714. movl %cs:8(%ebx),%esi
  715. movl %esi,8(%edi)
  716. call epadd1
  717. movb s_X+5(%ebp),%bl #adjust for actual quadrant
  718. cmpb $0x01,%bl
  719. jz atn23
  720. cmpb $0x80,%bl
  721. jz atn25
  722. orl $0x80000000,%ecx
  723. atn25: movw $0x4000,8(%edi)
  724. cmpb $0x81,%bl
  725. jz atn26
  726. movw $0x3fff,8(%edi)
  727. atn26: movl $0xc90fdaa2,4(%edi)
  728. movl $0x2168c235,0(%edi)
  729. call epadd1
  730. atn23: roll $8,%ecx #put in sign
  731. movb s_X+4(%ebp),%cl
  732. rorl $8,%ecx
  733. ret
  734. # routine to compute a Taylor polynomial
  735. # for speed and accuracy, we perform fixed-point scaled calculations
  736. # in    ebx = pointer to coefficient table
  737. #       ecx:edx:eax = EP argument
  738. # out   ecx:edx:eax = EP result
  739. shf22: movl %edx,%eax #big shift here
  740. xorl %edx,%edx
  741. subw $32,%cx
  742. cmpw $32,%cx
  743. jc shf9
  744. xorl %eax,%eax
  745. jmp shf19
  746. sigmax:
  747. pushl %edi #save registers
  748. movl %ecx,%esi
  749. subw $0x3ffe,%cx #get the scaling factor
  750. negl %ecx
  751. cmpw $32,%cx
  752. jnc shf22
  753. shf9: shrdl %cl,%edx,%eax #shift x right to scale
  754. shrl %cl,%edx
  755. shf19: movl %eax,s_A(%ebp) #store x 
  756. movl %edx,s_A+4(%ebp)
  757. movw %cs:2(%ebx),%ax #initial value of sum = first coefficient
  758. movl %cs:4(%ebx),%ecx
  759. movl %cs:8(%ebx),%edx
  760. addl $12,%ebx
  761. sig5: pushl %ebx #keep constant pointer on the stack
  762. movl %edx,%edi
  763. mulw s_A+6(%ebp) #multiply with x01
  764. movw %dx,%si #   put result in ebx:ecx:si
  765. movl %edi,%eax
  766. mull s_A+4(%ebp)
  767. movl %edx,%ebx
  768. xchgl %ecx,%eax
  769. orl %edi,%edi
  770. jns sig42
  771. subl s_A(%ebp),%ecx
  772. sbbl s_A+4(%ebp),%ebx
  773. sig42: pushl %eax
  774. mull s_A+4(%ebp)
  775. shrl $16,%eax
  776. addw %ax,%si
  777. adcl %edx,%ecx
  778. adcl $0,%ebx
  779. popl %eax #multiply with x23
  780. shrl $16,%eax
  781. mulw s_A+2(%ebp)
  782. addw %dx,%si
  783. adcl $0,%ecx
  784. adcl $0,%ebx
  785. movl %edi,%eax
  786. mull s_A(%ebp)
  787. shrl $16,%eax
  788. addw %si,%ax
  789. adcl %edx,%ecx
  790. adcl $0,%ebx
  791. movl %ebx,%edx #sum now in edx:ecx:ax
  792. popl %ebx #address of constant table in bx
  793. orl %esi,%esi #we may have to complement the sum
  794. jns sig31
  795. notl %edx
  796. notl %ecx
  797. negw %ax
  798. sbbl $-1,%ecx
  799. sbbl $-1,%edx
  800. sig31: addw %cs:2(%ebx),%ax #add next coefficient to sum
  801. adcl %cs:4(%ebx),%ecx
  802. adcl %cs:8(%ebx),%edx
  803. addl $12,%ebx #proceed to next element
  804. cmpb $-1,(%ebx)
  805. jnz sig5
  806. movb %ah,%bl #restore registers
  807. movl %ecx,%eax
  808. popl %edi
  809. movl $1,%ecx #normalize number
  810. orl %edx,%edx
  811. js sig18
  812. decl %ecx
  813. addb %bl,%bl
  814. adcl %eax,%eax
  815. adcl %edx,%edx
  816. sig18: ret
  817. #routine to raise number to second power
  818. # in    x in ecx:edx:eax
  819. # out   x^2 in same
  820. squ80: ret #return unchanged
  821. square:
  822. orw %cx,%cx #may be called with zero
  823. jz squ80
  824. pushl %edi #preserve registers
  825. pushl %ebx
  826. pushl %ebp
  827. pushl %ecx
  828. movl %edx,%esi #move mantissa
  829. movl %eax,%edi
  830. shrl $16,%eax #x23 * x23
  831. mulw %ax
  832. movb %dh,%bl
  833. movl %esi,%eax #x01 * x01 -> bp:cx:bl
  834. mull %eax
  835. movl %eax,%ecx
  836. movl %edx,%ebp
  837. movl %esi,%eax #double x01 * x23
  838. mull %edi
  839. shrl $16,%eax
  840. addb %al,%bl
  841. adcl %edx,%ecx
  842. adcl $0,%ebp
  843. addb %al,%bl
  844. adcl %edx,%ecx
  845. adcl $0,%ebp
  846. movl %ecx,%eax #move mantissa to proper place
  847. movl %ebp,%edx
  848. popl %ecx #double exponent
  849. addl %ecx,%ecx
  850. subw $tBIAS-1,%cx
  851. addb %bl,%bl #round
  852. adcl $0,%eax
  853. adcl $0,%edx
  854. popl %ebp #restore registers
  855. popl %ebx
  856. popl %edi
  857. ret
  858. # routine to reduce the trigonometric argument to between 0 and pi/4
  859. # returns octant number (0-7) in cl
  860. .globl reduct
  861. red80: orb $4,h_stat+1 #argument too big
  862. addl $4,%esp
  863. ret
  864. red85: call getqn #here INF
  865. orb $invop,h_stat
  866. call exproc
  867. red99: xorb %bl,%bl
  868. ret
  869. red96: andl $0x8000ffff,%ecx
  870. jmp red99
  871. redw: call chkarg #weed out illegals
  872. jc red99
  873. btl $16,%ecx #weed out INF, zero
  874. jc red99
  875. cmpw $1,%cx
  876. jz red96
  877. orw %cx,%cx
  878. jnz red85
  879. btsl $18,%ecx
  880. cmpb $7,rmcode(%ebp)
  881. jz red99
  882. orb $underf,h_stat
  883. call exproc
  884. jmp red99
  885. reduct:
  886. andb $0x0fb,h_stat+1 #clear reduction bit
  887. testl $0x00030000,%ecx #jump if special value
  888. jnz redw
  889. cmpw $tBIAS-1,%cx #small x, do nothing
  890. jc red99
  891. subw $tBIAS-2,%cx #get shift count -> cx
  892. cmpw $64,%cx #   reduce only up to 63
  893. jg red80
  894. pushl %edi #preserve register
  895. movl $0x2168c234,%edi
  896. movl $0xc90fdaa2,%esi
  897. xorl %ebx,%ebx #divide by subtraction
  898. red61: subb $0x0c0,%bh #   remainder -> edx:eax:bh
  899. sbbl %edi,%eax
  900. sbbl %esi,%edx
  901. sbbb $0,%ch
  902. jnc red63
  903. xorb %ch,%ch
  904. addb $0x0c0,%bh
  905. adcl %edi,%eax
  906. adcl %esi,%edx
  907. red63: cmc
  908. adcb %bl,%bl
  909. decb %cl
  910. jle red65
  911. addb %bh,%bh
  912. adcl %eax,%eax
  913. adcl %edx,%edx
  914. adcb $0,%ch
  915. jmp red61
  916. red65: andb $7,%bl #octant number -> bh
  917. testb $1,%bl #if octant 1 or 3 return pi/4 - x
  918. jz red41
  919. negb %bh
  920. addb $0x0c0,%bh
  921. notl %eax
  922. adcl %edi,%eax
  923. notl %edx
  924. adcl %esi,%edx
  925. red41: movl $0x3ffe,%ecx #exponent of pi/4
  926. popl %edi
  927. red37: orl %edx,%edx #normalize so bit 31 = 1
  928. js red19
  929. jnz red25
  930. xchgl %eax,%edx
  931. xchgb %bh,%al
  932. shll $16,%eax #fix 10/28/97
  933. # shll $16,%ebx
  934. subl $32,%ecx
  935. jmp red37
  936. red25: decl %ecx
  937. addb %bh,%bh
  938. adcl %eax,%eax
  939. adcl %edx,%edx
  940. jns red25
  941. red19: ret
  942. #__lib   endp
  943. #emuseg  ends
  944. #        end