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

VxWorks

开发平台:

C/C++

  1. /* l_ssin.s - Motorola 68040 FP sine/cosine routines (LIB) */
  2. /* Copyright 1991-1993 Wind River Systems, Inc. */
  3. .data
  4. .globl _copyright_wind_river
  5. .long _copyright_wind_river
  6. /*
  7. modification history
  8. --------------------
  9. 01f,21jul93,kdl  added .text (SPR #2372).
  10. 01e,23aug92,jcf  changed bxxx to jxx.
  11. 01d,26may92,rrr  the tree shuffle
  12. 01c,10jan92,kdl  general cleanup.
  13. 01b,17dec91,kdl  put in changes from Motorola v3.3 (from FPSP 2.1):
  14.  reduce argument by one step before general reduction
  15.  loop.
  16. 01a,15aug91,kdl  original version, from Motorola FPSP v2.0.
  17. */
  18. /*
  19. DESCRIPTION
  20. ssinsa 3.2 12/18/90
  21. The entry point sSIN computes the sine of an input argument
  22. sCOS computes the cosine, and sSINCOS computes both. The
  23. corresponding entry points with a "d" computes the same
  24. corresponding function values for denormalized inputs.
  25. Input: Double-extended number X in location pointed to
  26. by address register a0.
  27. Output: The funtion value sin(X) or cos(X) returned in Fp0 if SIN or
  28. COS is requested. Otherwise, for SINCOS, sin(X) is returned
  29. in Fp0, and cos(X) is returned in Fp1.
  30. Modifies: Fp0 for SIN or COS|  both Fp0 and Fp1 for SINCOS.
  31. Accuracy and Monotonicity: The returned result is within 1 ulp in
  32. 64 significant bit, i.e. within 0.5001 ulp to 53 bits if the
  33. result is subsequently rounded to double precision. The
  34. result is provably monotonic in double precision.
  35. Speed: The programs sSIN and sCOS take approximately 150 cycles for
  36. input argument X such that |X| < 15Pi, which is the the usual
  37. situation. The speed for sSINCOS is approximately 190 cycles.
  38. Algorithm:
  39. SIN and COS:
  40. 1. If SIN is invoked, set AdjN := 0|  otherwise, set AdjN := 1.
  41. 2. If |X| >= 15Pi or |X| < 2**(-40), go to 7.
  42. 3. Decompose X as X = N(Pi/2) + r where |r| <= Pi/4. Let
  43. k = N mod 4, so in particular, k = 0,1,2,or 3. Overwirte
  44. k by k := k + AdjN.
  45. 4. If k is even, go to 6.
  46. 5. (k is odd) Set j := (k-1)/2, sgn := (-1)**j. Return sgn*cos(r)
  47. where cos(r) is approximated by an even polynomial in r,
  48. 1 + r*r*(B1+s*(B2+ |... + s*B8)), s = r*r.
  49. Exit.
  50. 6. (k is even) Set j := k/2, sgn := (-1)**j. Return sgn*sin(r)
  51. where sin(r) is approximated by an odd polynomial in r
  52. r + r*s*(A1+s*(A2+ |... + s*A7)), s = r*r.
  53. Exit.
  54. 7. If |X| > 1, go to 9.
  55. 8. (|X|<2**(-40)) If SIN is invoked, return X|  otherwise return 1.
  56. 9. Overwrite X by X := X rem 2Pi. Now that |X| <= Pi, go back to 3.
  57. SINCOS:
  58. 1. If |X| >= 15Pi or |X| < 2**(-40), go to 6.
  59. 2. Decompose X as X = N(Pi/2) + r where |r| <= Pi/4. Let
  60. k = N mod 4, so in particular, k = 0,1,2,or 3.
  61. 3. If k is even, go to 5.
  62. 4. (k is odd) Set j1 := (k-1)/2, j2 := j1 (EOR) (k mod 2), i.e.
  63. j1 exclusive or with the ls.b. of k.
  64. sgn1 := (-1)**j1, sgn2 := (-1)**j2.
  65. SIN(X) = sgn1 * cos(r) and COS(X) = sgn2*sin(r) where
  66. sin(r) and cos(r) are computed as odd and even polynomials
  67. in r, respectively. Exit
  68. 5. (k is even) Set j1 := k/2, sgn1 := (-1)**j1.
  69. SIN(X) = sgn1 * sin(r) and COS(X) = sgn1*cos(r) where
  70. sin(r) and cos(r) are computed as odd and even polynomials
  71. in r, respectively. Exit
  72. 6. If |X| > 1, go to 8.
  73. 7. (|X|<2**(-40)) SIN(X) = X and COS(X) = 1. Exit.
  74. 8. Overwrite X by X := X rem 2Pi. Now that |X| <= Pi, go back to 2.
  75. Copyright (C) Motorola, Inc. 1990
  76. All Rights Reserved
  77. THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MOTOROLA
  78. The copyright notice above does not evidence any
  79. actual or intended publication of such source code.
  80. SSIN idnt 2,1 Motorola 040 Floating Point Software Package
  81. section 8
  82. NOMANUAL
  83. */
  84. #include "fpsp040L.h"
  85. BOUNDS1: .long 0x3FD78000,0x4004BC7E
  86. TWOBYPI: .long 0x3FE45F30,0x6DC9C883
  87. SINA7: .long 0xBD6AAA77,0xCCC994F5
  88. SINA6: .long 0x3DE61209,0x7AAE8DA1
  89. SINA5: .long 0xBE5AE645,0x2A118AE4
  90. SINA4: .long 0x3EC71DE3,0xA5341531
  91. SINA3: .long 0xBF2A01A0,0x1A018B59,0x00000000,0x00000000
  92. SINA2: .long 0x3FF80000,0x88888888,0x888859AF,0x00000000
  93. SINA1: .long 0xBFFC0000,0xAAAAAAAA,0xAAAAAA99,0x00000000
  94. COSB8: .long 0x3D2AC4D0,0xD6011EE3
  95. COSB7: .long 0xBDA9396F,0x9F45AC19
  96. COSB6: .long 0x3E21EED9,0x0612C972
  97. COSB5: .long 0xBE927E4F,0xB79D9FCF
  98. COSB4: .long 0x3EFA01A0,0x1A01D423,0x00000000,0x00000000
  99. COSB3: .long 0xBFF50000,0xB60B60B6,0x0B61D438,0x00000000
  100. COSB2: .long 0x3FFA0000,0xAAAAAAAA,0xAAAAAB5E
  101. COSB1: .long 0xBF000000
  102. INVTWOPI: .long 0x3FFC0000,0xA2F9836E,0x4E44152A
  103. TWOPI1: .long 0x40010000,0xC90FDAA2,0x00000000,0x00000000
  104. TWOPI2: .long 0x3FDF0000,0x85A308D4,0x00000000,0x00000000
  105. | xref __l_PITBL
  106. #define INARG FP_SCR4
  107. #define X FP_SCR5
  108. #define XDCARE X+2
  109. #define XFRAC X+4
  110. #define RPRIME FP_SCR1
  111. #define SPRIME FP_SCR2
  112. #define POSNEG1 L_SCR1
  113. #define TWOTO63 L_SCR1
  114. #define ENDFLAG L_SCR2
  115. #define N L_SCR2
  116. #define ADJN L_SCR3
  117. | xref __l_t_frcinx
  118. | xref __l_t_extdnrm
  119. | xref __l_sto_cos
  120. .text
  121. .globl __l_ssind
  122. __l_ssind:
  123. |--SIN(X) = X FOR DENORMALIZED X
  124. jra  __l_t_extdnrm
  125. .globl __l_scosd
  126. __l_scosd:
  127. |--COS(X) = 1 FOR DENORMALIZED X
  128. .long 0xf23c4400,0x3f800000 /* fmoves &0x3F800000,fp0 */
  129. |
  130. | 9D25B Fix: Sometimes the previous fmoves sets fpsr bits
  131. |
  132. fmovel #0,fpsr
  133. |
  134. jra  __l_t_frcinx
  135. .globl __l_ssin
  136. __l_ssin:
  137. |--SET ADJN TO 0
  138. movel #0,a6@(ADJN)
  139. jra  SINBGN
  140. .globl __l_scos
  141. __l_scos:
  142. |--SET ADJN TO 1
  143. movel #1,a6@(ADJN)
  144. SINBGN:
  145. |--SAVE fpcr, FP1. CHECK IF |X| IS TOO SMALL OR LARGE
  146. fmovex a0@,fp0 |...lOAD INPUT
  147. movel A0@,d0
  148. movew A0@(4),d0
  149. fmovex fp0,a6@(X)
  150. andil #0x7FFFFFFF,d0 |...COMPACTIFY X
  151. cmpil #0x3FD78000,d0 |...|X| >= 2**(-40)?
  152. jge  SOK1
  153. jra  SINSM
  154. SOK1:
  155. cmpil #0x4004BC7E,d0 |...|X| < 15 PI?
  156. jlt  SINMAIN
  157. jra  REDUCEX
  158. SINMAIN:
  159. |--THIS IS THE USUAL CASE, |X| <= 15 PI.
  160. |--THE ARGUMENT REDUCTION IS DONE BY TABLE LOOK UP.
  161. fmovex fp0,fp1
  162. fmuld TWOBYPI,fp1 |...X*2/PI
  163. |--HIDE THE NEXT THREE INSTRUCTIONS
  164. lea __l_PITBL+0x200,a1 |...TABLE OF N*PI/2, N = -32,...,32
  165. |--FP1 IS NOW READY
  166. fmovel fp1,a6@(N) |...CONVERT TO INTEGER
  167. movel a6@(N),d0
  168. asll #4,d0
  169. addal d0,a1 |...A1 IS THE ADDRESS OF N*PIBY2
  170. | |...wHICH IS IN TWO PIECES Y1 # Y2
  171. fsubx A1@+,fp0 |...X-Y1
  172. |--HIDE THE NEXT ONE
  173. fsubs A1@,fp0 |...FP0 IS R = (X-Y1)-Y2
  174. SINCONT:
  175. |--continuation from REDUCEX
  176. |--GET N+ADJN AND SEE IF SIN(R) OR COS(R) IS NEEDED
  177. movel a6@(N),d0
  178. addl a6@(ADJN),d0 |...SEE IF d0 IS ODD OR EVEN
  179. rorl #1,d0 |...D0 WAS ODD IFF d0 IS NEGATIVE
  180. cmpil #0,d0
  181. jlt  COSPOLY
  182. SINPOLY:
  183. |--LET J BE THE LEAST SIG. BIT OF D0, LET SGN := (-1)**J.
  184. |--THEN WE RETURN SGN*SIN(R). SGN*SIN(R) IS COMPUTED BY
  185. /* |--R' + R'*S*(A1 + S(A2 + S(A3 + S(A4 + |... + SA7)))), WHERE */
  186. /* |--R' = SGN*R, S=R*R. THIS CAN BE REWRITTEN AS */
  187. /* |--R' + R'*S*( [A1+T(A3+T(A5+TA7))] + [S(A2+T(A4+TA6))]) */
  188. |--WHERE T=S*S.
  189. |--NOTE THAT A3 THROUGH A7 ARE STORED IN DOUBLE PRECISION
  190. |--WHILE A1 AND A2 ARE IN DOUBLE-EXTENDED FORMAT.
  191. fmovex fp0,a6@(X) |...X IS R
  192. fmulx fp0,fp0 |...FP0 IS S
  193. |---HIDE THE NEXT TWO WHILE WAITING FOR FP0
  194. fmoved SINA7,fp3
  195. fmoved SINA6,fp2
  196. |--FP0 IS NOW READY
  197. fmovex fp0,fp1
  198. fmulx fp1,fp1 |...FP1 IS T
  199. |--HIDE THE NEXT TWO WHILE WAITING FOR FP1
  200. rorl #1,d0
  201. andil #0x80000000,d0
  202. | |...lEAST SIG. BIT OF D0 IN SIGN POSITION
  203. eorl d0,a6@(X) /* |...X IS NOW R'= SGN*R */
  204. fmulx fp1,fp3 |...TA7
  205. fmulx fp1,fp2 |...TA6
  206. faddd SINA5,fp3 |...A5+TA7
  207. faddd SINA4,fp2 |...A4+TA6
  208. fmulx fp1,fp3 |...T(A5+TA7)
  209. fmulx fp1,fp2 |...T(A4+TA6)
  210. faddd SINA3,fp3 |...A3+T(A5+TA7)
  211. faddx SINA2,fp2 |...A2+T(A4+TA6)
  212. fmulx fp3,fp1 |...T(A3+T(A5+TA7))
  213. fmulx fp0,fp2 |...S(A2+T(A4+TA6))
  214. faddx SINA1,fp1 |...A1+T(A3+T(A5+TA7))
  215. fmulx a6@(X),fp0 /* |...R'*S */
  216. faddx fp2,fp1 |...[A1+T(A3+T(A5+TA7))]+[S(A2+T(A4+TA6))]
  217. |--FP3 RELEASED, RESTORE NOW AND TAKE SOME ADVANTAGE OF HIDING
  218. |--FP2 RELEASED, RESTORE NOW AND TAKE FULL ADVANTAGE OF HIDING
  219. fmulx fp1,fp0 /* |...SIN(R')-R' */
  220. |--FP1 RELEASED.
  221. fmovel d1,fpcr | restore users exceptions
  222. faddx a6@(X),fp0 | last inst - possible exception set
  223. jra  __l_t_frcinx
  224. COSPOLY:
  225. |--LET J BE THE LEAST SIG. BIT OF D0, LET SGN := (-1)**J.
  226. |--THEN WE RETURN SGN*COS(R). SGN*COS(R) IS COMPUTED BY
  227. /* |--SGN + S'*(B1 + S(B2 + S(B3 + S(B4 + |... + SB8)))), WHERE */
  228. /* |--S=R*R AND S'=SGN*S. THIS CAN BE REWRITTEN AS */
  229. /* |--SGN + S'*([B1+T(B3+T(B5+TB7))] + [S(B2+T(B4+T(B6+TB8)))]) */
  230. |--WHERE T=S*S.
  231. |--NOTE THAT B4 THROUGH B8 ARE STORED IN DOUBLE PRECISION
  232. |--WHILE B2 AND B3 ARE IN DOUBLE-EXTENDED FORMAT, B1 IS -1/2
  233. |--AND IS THEREFORE STORED AS SINGLE PRECISION.
  234. fmulx fp0,fp0 |...FP0 IS S
  235. |---HIDE THE NEXT TWO WHILE WAITING FOR FP0
  236. fmoved COSB8,fp2
  237. fmoved COSB7,fp3
  238. |--FP0 IS NOW READY
  239. fmovex fp0,fp1
  240. fmulx fp1,fp1 |...FP1 IS T
  241. |--HIDE THE NEXT TWO WHILE WAITING FOR FP1
  242. fmovex fp0,a6@(X) |...X IS S
  243. rorl #1,d0
  244. andil #0x80000000,d0
  245. | |...lEAST SIG. BIT OF D0 IN SIGN POSITION
  246. fmulx fp1,fp2 |...TB8
  247. |--HIDE THE NEXT TWO WHILE WAITING FOR THE XU
  248. eorl d0,a6@(X) /* |...X IS NOW S'= SGN*S */
  249. andil #0x80000000,d0
  250. fmulx fp1,fp3 |...TB7
  251. |--HIDE THE NEXT TWO WHILE WAITING FOR THE XU
  252. oril #0x3F800000,d0 |...D0 IS SGN IN SINGLE
  253. movel d0,a6@(POSNEG1)
  254. faddd COSB6,fp2 |...B6+TB8
  255. faddd COSB5,fp3 |...B5+TB7
  256. fmulx fp1,fp2 |...T(B6+TB8)
  257. fmulx fp1,fp3 |...T(B5+TB7)
  258. faddd COSB4,fp2 |...B4+T(B6+TB8)
  259. faddx COSB3,fp3 |...B3+T(B5+TB7)
  260. fmulx fp1,fp2 |...T(B4+T(B6+TB8))
  261. fmulx fp3,fp1 |...T(B3+T(B5+TB7))
  262. faddx COSB2,fp2 |...B2+T(B4+T(B6+TB8))
  263. fadds COSB1,fp1 |...B1+T(B3+T(B5+TB7))
  264. fmulx fp2,fp0 |...S(B2+T(B4+T(B6+TB8)))
  265. |--FP3 RELEASED, RESTORE NOW AND TAKE SOME ADVANTAGE OF HIDING
  266. |--FP2 RELEASED.
  267. faddx fp1,fp0
  268. |--FP1 RELEASED
  269. fmulx a6@(X),fp0
  270. fmovel d1,fpcr | restore users exceptions
  271. fadds a6@(POSNEG1),fp0 | last inst - possible exception set
  272. jra  __l_t_frcinx
  273. SINBORS:
  274. |--IF |X| > 15PI, WE USE THE GENERAL ARGUMENT REDUCTION.
  275. |--IF |X| < 2**(-40), RETURN X OR 1.
  276. cmpil #0x3FFF8000,d0
  277. jgt  REDUCEX
  278. SINSM:
  279. movel a6@(ADJN),d0
  280. cmpil #0,d0
  281. jgt  COSTINY
  282. SINTINY:
  283. movew #0x0000,a6@(XDCARE) |...JUST IN CASE
  284. fmovel d1,fpcr | restore users exceptions
  285. fmovex a6@(X),fp0 | last inst - possible exception set
  286. jra  __l_t_frcinx
  287. COSTINY:
  288. .long 0xf23c4400,0x3f800000  /* fmoves &0x3F800000,fp0 */
  289. fmovel d1,fpcr | restore users exceptions
  290. .long 0xf23c4428,0x00800000  /* fsubs &0x00800000,fp0 */
  291. jra  __l_t_frcinx
  292. REDUCEX:
  293. |--WHEN REDUCEX IS USED, THE CODE WILL INEVITABLY BE SLOW.
  294. |--THIS REDUCTION METHOD, HOWEVER, IS MUCH FASTER THAN USING
  295. |--THE REMAINDER INSTRUCTION WHICH IS NOW IN SOFTWARE.
  296. fmovemx fp2-fp5,A7@- |...save fp2 through fp5
  297. movel d2,A7@-
  298. .long 0xf23c4480,0x00000000 /* fmoves &0x00000000,fp1 */
  299. |--If compact form of abs(arg) in d0=0x7ffeffff, argument is so large that
  300. |--there is a danger of unwanted overflow in first LOOP iteration.  In this
  301. |--case, reduce argument by one remainder step to make subsequent reduction
  302. |--safe.
  303. cmpil #0x7ffeffff,d0 | is argument dangerously large?
  304. jne  LOOP
  305. movel #0x7ffe0000,a6@(FP_SCR2) | yes
  306. | | create 2**16383*PI/2
  307. movel #0xc90fdaa2,a6@(FP_SCR2+4)
  308. clrl a6@(FP_SCR2+8)
  309. ftstx fp0 | test sign of argument
  310. movel #0x7fdc0000,a6@(FP_SCR3) | create low half of 2**16383*
  311. | | PI/2 at FP_SCR3
  312. movel #0x85a308d3,a6@(FP_SCR3+4)
  313. clrl   a6@(FP_SCR3+8)
  314. fblt red_neg
  315. orw #0x8000,a6@(FP_SCR2) | positive arg
  316. orw #0x8000,a6@(FP_SCR3)
  317. red_neg:
  318. faddx  a6@(FP_SCR2),fp0 | high part of reduction is exact
  319. fmovex  fp0,fp1 | save high result in fp1
  320. faddx  a6@(FP_SCR3),fp0 | low part of reduction
  321. fsubx   fp0,fp1 | determine low component of result
  322. faddx  a6@(FP_SCR3),fp1 | fp0/fp1 are reduced argument.
  323. |--ON ENTRY, FP0 IS X, ON RETURN, FP0 IS X REM PI/2, |X| <= PI/4.
  324. |--integer quotient will be stored in N
  325. |--Intermeditate remainder is 66-bit long|  (R,r) in (FP0,FP1)
  326. LOOP:
  327. fmovex fp0,a6@(INARG) |...+-2**K * F, 1 <= F < 2
  328. movew a6@(INARG),d0
  329.         movel          d0,a1 |...save a copy of d0
  330. andil #0x00007FFF,d0
  331. subil #0x00003FFF,d0 |...D0 IS K
  332. cmpil #28,d0
  333. jle  LASTLOOP
  334. CONTLOOP:
  335. subil #27,d0  |...D0 IS L := K-27
  336. movel #0,a6@(ENDFLAG)
  337. jra  WORK
  338. LASTLOOP:
  339. clrl d0 |...D0 IS L := 0
  340. movel #1,a6@(ENDFLAG)
  341. WORK:
  342. |--FIND THE REMAINDER OF (R,r) W.R.T. 2**L * (PI/2). L IS SO CHOSEN
  343. |--THAT INT( X * (2/PI) / 2**(L) ) < 2**29.
  344. |--CREATE 2**(-L) * (2/PI), SIGN(INARG)*2**(63),
  345. |--2**L * (PIby2_1), 2**L * (PIby2_2)
  346. movel #0x00003FFE,d2 |...BIASED EXPO OF 2/PI
  347. subl d0,d2 |...BIASED EXPO OF 2**(-L)*(2/PI)
  348. movel #0xA2F9836E,a6@(FP_SCR1+4)
  349. movel #0x4E44152A,a6@(FP_SCR1+8)
  350. movew d2,a6@(FP_SCR1) |...FP_SCR1 is 2**(-L)*(2/PI)
  351. fmovex fp0,fp2
  352. fmulx a6@(FP_SCR1),fp2
  353. |--WE MUST NOW FIND INT(FP2). SINCE WE NEED THIS VALUE IN
  354. /* |--FLOATING POINT FORMAT, THE TWO FMOVE'S FMOVE.l FP <--> N */
  355. |--WILL BE TOO INEFFICIENT. THE WAY AROUND IT IS THAT
  356. |--(SIGN(INARG)*2**63 + FP2) - SIGN(INARG)*2**63 WILL GIVE
  357. |--US THE DESIRED VALUE IN FLOATING POINT.
  358. |--HIDE SIX CYCLES OF INSTRUCTION
  359.         movel a1,d2
  360.         swap d2
  361. andil #0x80000000,d2
  362. oril #0x5F000000,d2 |...D2 IS SIGN(INARG)*2**63 IN SGL
  363. movel d2,a6@(TWOTO63)
  364. movel d0,d2
  365. addil #0x00003FFF,d2 |...BIASED EXPO OF 2**L * (PI/2)
  366. |--FP2 IS READY
  367. fadds a6@(TWOTO63),fp2 |...THE FRACTIONAL PART OF fp1 IS ROUNDED
  368. |--HIDE 4 CYCLES OF INSTRUCTION|  creating 2**(L)*Piby2_1  and  2**(L)*Piby2_2
  369.         movew d2,a6@(FP_SCR2)
  370. clrw           a6@(FP_SCR2+2)
  371. movel #0xC90FDAA2,a6@(FP_SCR2+4)
  372. clrl a6@(FP_SCR2+8) |...FP_SCR2 is  2**(L) * Piby2_1
  373. |--FP2 IS READY
  374. fsubs a6@(TWOTO63),fp2 |...FP2 is N
  375. addil #0x00003FDD,d0
  376.         movew d0,a6@(FP_SCR3)
  377. clrw           a6@(FP_SCR3+2)
  378. movel #0x85A308D3,a6@(FP_SCR3+4)
  379. clrl a6@(FP_SCR3+8) |...FP_SCR3 is 2**(L) * Piby2_2
  380. movel a6@(ENDFLAG),d0
  381. |--We are now ready to perform (R+r) - N*P1 - N*P2, P1 = 2**(L) * Piby2_1 and
  382. |--P2 = 2**(L) * Piby2_2
  383. fmovex fp2,fp4
  384. fmulx a6@(FP_SCR2),fp4 |...w = N*P1
  385. fmovex fp2,fp5
  386. fmulx a6@(FP_SCR3),fp5 |...w = N*P2
  387. fmovex fp4,fp3
  388. |--we want P+p = W+w  but  |p| <= half ulp of P
  389. |--Then, we need to compute  A := R-P   and  a := r-p
  390. faddx fp5,fp3 |...FP3 is P
  391. fsubx fp3,fp4 |...w-P
  392. fsubx fp3,fp0 |...FP0 is A := R - P
  393.         faddx fp5,fp4 |...FP4 is p = (W-P)+w
  394. fmovex fp0,fp3 |...FP3 A
  395. fsubx fp4,fp1 |...FP1 is a := r - p
  396. |--Now we need to normalize (A,a) to  "new (R,r)" where R+r = A+a but
  397. |--|r| <= half ulp of R.
  398. faddx fp1,fp0 |...FP0 is R := A+a
  399. |--No need to calculate r if this is the last loop
  400. cmpil #0,d0
  401. jgt  RESTORE
  402. |--Need to calculate r
  403. fsubx fp0,fp3 |...A-R
  404. faddx fp3,fp1 |...FP1 is r := (A-R)+a
  405. jra  LOOP
  406. RESTORE:
  407.         fmovel fp2,a6@(N)
  408. movel A7@+,d2
  409. fmovemx A7@+,fp2-fp5
  410. movel a6@(ADJN),d0
  411. cmpil #4,d0
  412. jlt  SINCONT
  413. jra  SCCONT
  414. .globl __l_ssincosd
  415. __l_ssincosd:
  416. |--SIN AND COS OF X FOR DENORMALIZED X
  417. .long 0xf23c4480,0x3f800000 /* fmoves &0x3F800000,fp1 */
  418. bsrl __l_sto_cos | store cosine result
  419. jra  __l_t_extdnrm
  420. .globl __l_ssincos
  421. __l_ssincos:
  422. |--SET ADJN TO 4
  423. movel #4,a6@(ADJN)
  424. fmovex a0@,fp0 |...lOAD INPUT
  425. movel A0@,d0
  426. movew A0@(4),d0
  427. fmovex fp0,a6@(X)
  428. andil #0x7FFFFFFF,d0 |...COMPACTIFY X
  429. cmpil #0x3FD78000,d0 |...|X| >= 2**(-40)?
  430. jge  SCOK1
  431. jra  SCSM
  432. SCOK1:
  433. cmpil #0x4004BC7E,d0 |...|X| < 15 PI?
  434. jlt  SCMAIN
  435. jra  REDUCEX
  436. SCMAIN:
  437. |--THIS IS THE USUAL CASE, |X| <= 15 PI.
  438. |--THE ARGUMENT REDUCTION IS DONE BY TABLE LOOK UP.
  439. fmovex fp0,fp1
  440. fmuld TWOBYPI,fp1 |...X*2/PI
  441. |--HIDE THE NEXT THREE INSTRUCTIONS
  442. lea __l_PITBL+0x200,a1 |...TABLE OF N*PI/2, N = -32,...,32
  443. |--FP1 IS NOW READY
  444. fmovel fp1,a6@(N) |...CONVERT TO INTEGER
  445. movel a6@(N),d0
  446. asll #4,d0
  447. addal d0,a1 |...ADDRESS OF N*PIBY2, IN Y1, Y2
  448. fsubx A1@+,fp0 |...X-Y1
  449.         fsubs A1@,fp0 |...FP0 IS R = (X-Y1)-Y2
  450. SCCONT:
  451. |--continuation point from REDUCEX
  452. |--HIDE THE NEXT TWO
  453. movel a6@(N),d0
  454. rorl #1,d0
  455. cmpil #0,d0 |...D0 < 0 IFF N IS ODD
  456. jge  NEVEN
  457. NODD:
  458. |--REGISTERS SAVED SO FAR: D0, A0, FP2.
  459. fmovex fp0,a6@(RPRIME)
  460. fmulx fp0,fp0   |...FP0 IS S = R*R
  461. fmoved SINA7,fp1 |...A7
  462. fmoved COSB8,fp2 |...B8
  463. fmulx fp0,fp1   |...SA7
  464. movel d2,A7@-
  465. movel d0,d2
  466. fmulx fp0,fp2   |...SB8
  467. rorl #1,d2
  468. andil #0x80000000,d2
  469. faddd SINA6,fp1 |...A6+SA7
  470. eorl d0,d2
  471. andil #0x80000000,d2
  472. faddd COSB7,fp2 |...B7+SB8
  473. fmulx fp0,fp1   |...S(A6+SA7)
  474. eorl d2,a6@(RPRIME)
  475. movel A7@+,d2
  476. fmulx fp0,fp2   |...S(B7+SB8)
  477. rorl #1,d0
  478. andil #0x80000000,d0
  479. faddd SINA5,fp1 |...A5+S(A6+SA7)
  480. movel #0x3F800000,a6@(POSNEG1)
  481. eorl d0,a6@(POSNEG1)
  482. faddd COSB6,fp2 |...B6+S(B7+SB8)
  483. fmulx fp0,fp1   |...S(A5+S(A6+SA7))
  484. fmulx fp0,fp2   |...S(B6+S(B7+SB8))
  485. fmovex fp0,a6@(SPRIME)
  486. faddd SINA4,fp1 |...A4+S(A5+S(A6+SA7))
  487. eorl d0,a6@(SPRIME)
  488. faddd COSB5,fp2 |...B5+S(B6+S(B7+SB8))
  489. fmulx fp0,fp1   |...S(A4+...)
  490. fmulx fp0,fp2   |...S(B5+...)
  491. faddd SINA3,fp1 |...A3+S(A4+...)
  492. faddd COSB4,fp2 |...B4+S(B5+...)
  493. fmulx fp0,fp1   |...S(A3+...)
  494. fmulx fp0,fp2   |...S(B4+...)
  495. faddx SINA2,fp1 |...A2+S(A3+...)
  496. faddx COSB3,fp2 |...B3+S(B4+...)
  497. fmulx fp0,fp1   |...S(A2+...)
  498. fmulx fp0,fp2   |...S(B3+...)
  499. faddx SINA1,fp1 |...A1+S(A2+...)
  500. faddx COSB2,fp2 |...B2+S(B3+...)
  501. fmulx fp0,fp1   |...S(A1+...)
  502. fmulx fp2,fp0   |...S(B2+...)
  503. fmulx a6@(RPRIME),fp1 /* |...R'S(A1+...) */
  504. fadds COSB1,fp0 |...B1+S(B2...)
  505. fmulx a6@(SPRIME),fp0 /* |...S'(B1+S(B2+...)) */
  506. movel d1,a7@- | restore users mode # precision
  507. andil #0xff,d1 | mask off all exceptions
  508. fmovel d1,fpcr
  509. faddx a6@(RPRIME),fp1 |...COS(X)
  510. bsrl __l_sto_cos | store cosine result
  511. fmovel a7@+,fpcr | restore users exceptions
  512. fadds a6@(POSNEG1),fp0 |...SIN(X)
  513. jra  __l_t_frcinx
  514. NEVEN:
  515. |--REGISTERS SAVED SO FAR: FP2.
  516. fmovex fp0,a6@(RPRIME)
  517. fmulx fp0,fp0   |...FP0 IS S = R*R
  518. fmoved COSB8,fp1 |...B8
  519. fmoved SINA7,fp2 |...A7
  520. fmulx fp0,fp1   |...SB8
  521. fmovex fp0,a6@(SPRIME)
  522. fmulx fp0,fp2   |...SA7
  523. rorl #1,d0
  524. andil #0x80000000,d0
  525. faddd COSB7,fp1 |...B7+SB8
  526. faddd SINA6,fp2 |...A6+SA7
  527. eorl d0,a6@(RPRIME)
  528. eorl d0,a6@(SPRIME)
  529. fmulx fp0,fp1   |...S(B7+SB8)
  530. oril #0x3F800000,d0
  531. movel d0,a6@(POSNEG1)
  532. fmulx fp0,fp2   |...S(A6+SA7)
  533. faddd COSB6,fp1 |...B6+S(B7+SB8)
  534. faddd SINA5,fp2 |...A5+S(A6+SA7)
  535. fmulx fp0,fp1   |...S(B6+S(B7+SB8))
  536. fmulx fp0,fp2   |...S(A5+S(A6+SA7))
  537. faddd COSB5,fp1 |...B5+S(B6+S(B7+SB8))
  538. faddd SINA4,fp2 |...A4+S(A5+S(A6+SA7))
  539. fmulx fp0,fp1   |...S(B5+...)
  540. fmulx fp0,fp2   |...S(A4+...)
  541. faddd COSB4,fp1 |...B4+S(B5+...)
  542. faddd SINA3,fp2 |...A3+S(A4+...)
  543. fmulx fp0,fp1   |...S(B4+...)
  544. fmulx fp0,fp2   |...S(A3+...)
  545. faddx COSB3,fp1 |...B3+S(B4+...)
  546. faddx SINA2,fp2 |...A2+S(A3+...)
  547. fmulx fp0,fp1   |...S(B3+...)
  548. fmulx fp0,fp2   |...S(A2+...)
  549. faddx COSB2,fp1 |...B2+S(B3+...)
  550. faddx SINA1,fp2 |...A1+S(A2+...)
  551. fmulx fp0,fp1   |...S(B2+...)
  552. fmulx fp2,fp0   |...s(a1+...)
  553. fadds COSB1,fp1 |...B1+S(B2...)
  554. fmulx a6@(RPRIME),fp0 /*  |...R'S(A1+...) */
  555. fmulx a6@(SPRIME),fp1 /*  |...S'(B1+S(B2+...)) */
  556. movel d1,a7@- | save users mode # precision
  557. andil #0xff,d1 | mask off all exceptions
  558. fmovel d1,fpcr
  559. fadds a6@(POSNEG1),fp1 |...COS(X)
  560. bsrl __l_sto_cos | store cosine result
  561. fmovel a7@+,fpcr | restore users exceptions
  562. faddx a6@(RPRIME),fp0 |...SIN(X)
  563. jra  __l_t_frcinx
  564. SCBORS:
  565. cmpil #0x3FFF8000,d0
  566. jgt  REDUCEX
  567. SCSM:
  568. movew #0x0000,a6@(XDCARE)
  569. .long 0xf23c4480,0x3f800000 /* fmoves &0x3F800000,fp1 */
  570. movel d1,a7@- | save users mode # precision
  571. andil #0xff,d1 | mask off all exceptions
  572. fmovel d1,fpcr
  573. .long 0xf23c44a8,0x00800000 /* fsubs &0x00800000,fp1 */
  574. bsrl __l_sto_cos | store cosine result
  575. fmovel a7@+,fpcr | restore users exceptions
  576. fmovex a6@(X),fp0
  577. jra  __l_t_frcinx
  578. | end