(CFLAGS-tst-align.c): Add -mpreferred-stack-boundary=4.
[glibc.git] / sysdeps / ia64 / fpu / e_acosl.S
blobab1bbf41a70cc13f27c26edf80beaaf9fe7c03e8
1 .file "acosl.s"
3 // Copyright (C) 2000, 2001, Intel Corporation
4 // All rights reserved.
5 // 
6 // Contributed 2/2/2000 by John Harrison, Ted Kubaska, Bob Norin, Shane Story,
7 // and Ping Tak Peter Tang of the Computational Software Lab, Intel Corporation.
8 //
9 // Redistribution and use in source and binary forms, with or without
10 // modification, are permitted provided that the following conditions are
11 // met:
13 // * Redistributions of source code must retain the above copyright
14 // notice, this list of conditions and the following disclaimer.
16 // * Redistributions in binary form must reproduce the above copyright
17 // notice, this list of conditions and the following disclaimer in the
18 // documentation and/or other materials provided with the distribution.
20 // * The name of Intel Corporation may not be used to endorse or promote
21 // products derived from this software without specific prior written
22 // permission.
24 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
25 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
26 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS 
28 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
29 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
30 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
31 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
32 // OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY OR TORT (INCLUDING
33 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
34 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
35 // 
36 // Intel Corporation is the author of this code, and requests that all
37 // problem reports or change requests be submitted to it directly at 
38 // http://developer.intel.com/opensource.
40 // History
41 //==============================================================
42 // 2/02/00  Initial version 
43 // 2/07/00  Modified calculation of acos_corr to correct acosl
44 // 4/04/00  Unwind support added
45 // 8/15/00  Bundle added after call to __libm_error_support to properly
46 //          set [the previously overwritten] GR_Parameter_RESULT.
47 // 12/20/00 Set denormal flag properly.
49 // API
50 //==============================================================
51 // double-extended = acosl (double-extended)
52 // input  floating point f8
53 // output floating point f8
55 // Registers used
56 //==============================================================
58 // predicate registers used:
59 // p6 -> p12
61 // floating-point registers used:
62 // f8 has input, then output
63 // f8 -> f15, f32 ->f99
65 // general registers used:
66 // r32 -> r48
68 // Overview of operation
69 //==============================================================
70 // There are three paths
71 // 1. |x| < 2^-25                 ACOS_TINY
72 // 2. 2^-25 <= |x| < 1/4          ACOS_POLY
73 // 3. 1/4 <= |x| < 1              ACOS_ATAN
75 #include "libm_support.h"
77 // Assembly macros
78 //==============================================================
80 // f8 is input, but acos_V must be put in f8
81 //    when __libm_atan2_reg is called, f8 must get V
82 // f9 gets U when __libm_atan2_reg is called
85 // __libm_atan2_reg returns 
86 // f8  = Z_hi
87 // f10 = Z_lo
88 // f11 = s_lo
90 acos_Z_hi = f8
91 acos_Z_lo = f10
92 acos_S_lo = f11
94 // When we call __libm_atan2_reg, we must save 
95 // the following:
97 acos_corr  = f12
98 acos_X     = f13
99 acos_pi_hi = f14
100 acos_pi_lo = f15
102 // The rest of the assembly macros
104 acos_P79                   = f32
105 acos_P59                   = f33
106 acos_P39                   = f34
107 acos_P19                   = f35
109 acos_P810                  = f36
110 acos_P610                  = f37
111 acos_P410                  = f38
112 acos_P210                  = f39
114 acos_A1                    = f41
115 acos_A2                    = f42
116 acos_A3                    = f43
117 acos_A4                    = f44
118 acos_A5                    = f45
119 acos_A6                    = f46
120 acos_A7                    = f47
121 acos_A8                    = f48
122 acos_A9                    = f49
123 acos_A10                   = f50
125 acos_X2                    = f51
126 acos_X4                    = f52
128 acos_B                     = f53
129 acos_Bb                    = f54
130 acos_A                     = f55
131 acos_Aa                    = f56
133 acos_1mA                   = f57
135 acos_W                     = f58
136 acos_Ww                    = f59
138 acos_y0                    = f60
139 acos_y1                    = f61
140 acos_y2                    = f62
142 acos_H                     = f63
143 acos_Hh                    = f64
145 acos_t1                    = f65
146 acos_t2                    = f66
147 acos_t3                    = f67
148 acos_t4                    = f68
149 acos_t5                    = f69
151 acos_Pseries               = f70
152 acos_NORM_f8               = f71
153 acos_ABS_NORM_f8           = f72
155 acos_2                     = f73
156 acos_P1P2                  = f74
157 acos_HALF                  = f75
158 acos_U                     = f76
160 acos_1mB                   = f77
161 acos_V                     = f78 
162 acos_S                     = f79
164 acos_BmUU                  = f80 
165 acos_BmUUpb                = f81 
166 acos_2U                    = f82
167 acos_1d2U                  = f83
169 acos_Dd                    = f84
171 acos_pi_by_2_hi            = f85
172 acos_pi_by_2_lo            = f86
173 acos_xmpi_by_2_lo          = f87
174 acos_xPmw                  = f88
176 acos_Uu                    = f89
177 acos_AmVV                  = f90 
178 acos_AmVVpa                = f91 
180 acos_2V                    = f92 
181 acos_1d2V                  = f93
182 acos_Vv                    = f94
184 acos_Vu                    = f95 
185 acos_Uv                    = f96 
187 acos_2_Z_hi                = f97
188 acos_s_lo_Z_lo             = f98
189 acos_result_lo             = f99
191 acos_Z_hi                  = f8
192 acos_Z_lo                  = f10
193 acos_s_lo                  = f11
195 acos_GR_17_ones            = r33
196 acos_GR_16_ones            = r34
197 acos_GR_signexp_f8         = r35
198 acos_GR_exp                = r36
199 acos_GR_true_exp           = r37
200 acos_GR_fffe               = r38
202 GR_SAVE_PFS                = r43
203 GR_SAVE_B0                 = r39
204 GR_SAVE_GP                 = r41
206 // r40 is address of table of coefficients
207 // r42 
209 GR_Parameter_X             = r44 
210 GR_Parameter_Y             = r45 
211 GR_Parameter_RESULT        = r46 
212 GR_Parameter_TAG                = r47 
215 // 2^-40:
216 // A true exponent of -40 is
217 //                    : -40 + register_bias
218 //                    : -28 + ffff = ffd7
220 // A true exponent of 1 is 
221 //                    : 1 + register_bias
222 //                    : 1 + ffff = 10000
224 // Data tables
225 //==============================================================
227 #ifdef _LIBC
228 .rodata
229 #else
230 .data
231 #endif
233 .align 16
235 acos_coefficients:
236 ASM_TYPE_DIRECTIVE(acos_coefficients,@object)
237 data8  0xc90fdaa22168c234, 0x00003FFF            // pi_by_2_hi
238 data8  0xc4c6628b80dc1cd1, 0x00003FBF            // pi_by_2_lo
239 data8  0xc90fdaa22168c234, 0x00004000            // pi_hi
240 data8  0xc4c6628b80dc1cd1, 0x00003FC0            // pi_lo
242 data8  0xBB08911F2013961E, 0x00003FF8            // A10
243 data8  0x981F1095A23A87D3, 0x00003FF8            // A9 
244 data8  0xBDF09C6C4177BCC6, 0x00003FF8            // A8 
245 data8  0xE4C3A60B049ACCEA, 0x00003FF8            // A7 
246 data8  0x8E2789F4E8A8F1AD, 0x00003FF9            // A6 
247 data8  0xB745D09B2B0E850B, 0x00003FF9            // A5 
248 data8  0xF8E38E3BC4C50920, 0x00003FF9            // A4 
249 data8  0xB6DB6DB6D89FCD81, 0x00003FFA            // A3 
250 data8  0x99999999999AF376, 0x00003FFB            // A2 
251 data8  0xAAAAAAAAAAAAAA71, 0x00003FFC            // A1
252 ASM_SIZE_DIRECTIVE(acos_coefficients)
255 .align 32
256 .global acosl#
257 ASM_TYPE_DIRECTIVE(acosl#,@function)
259 .section .text
260 .proc  acosl#
261 .align 32
264 acosl: 
266 // After normalizing f8, get its true exponent
267 { .mfi
268       alloc r32 = ar.pfs,1,11,4,0                                             
269 (p0)  fnorm.s1    acos_NORM_f8 = f8                                            
270 (p0)  mov         acos_GR_17_ones = 0x1ffff                                    
273 { .mmi
274 (p0)  mov        acos_GR_16_ones = 0xffff                                     
275 (p0)  addl                 r40   = @ltoff(acos_coefficients), gp
276       nop.i 999
280 // Set denormal flag on denormal input with fcmp
281 { .mfi
282       ld8 r40 = [r40]
283       fcmp.eq  p6,p0 = f8,f0
284       nop.i 999
289 // Load the constants pi_by_2 and pi.
290 // Each is stored as hi and lo values
291 // Also load the coefficients for ACOS_POLY
293 { .mmi
294 (p0) ldfe       acos_pi_by_2_hi = [r40],16 ;;      
295 (p0) ldfe       acos_pi_by_2_lo = [r40],16      
296      nop.i 999 ;;
299 { .mmi
300 (p0) ldfe       acos_pi_hi      = [r40],16 ;;      
301 (p0) ldfe       acos_pi_lo      = [r40],16      
302      nop.i 999 ;;
305 { .mmi
306 (p0) ldfe       acos_A10        = [r40],16 ;;      
307 (p0) ldfe       acos_A9         = [r40],16      
308      nop.i 999 ;;
311 // Take the absolute value of f8
312 { .mmf
313       nop.m 999
314 (p0)  getf.exp   acos_GR_signexp_f8  = acos_NORM_f8                           
315 (p0)  fmerge.s  acos_ABS_NORM_f8 = f0, acos_NORM_f8 
318 { .mii
319 (p0) ldfe       acos_A8         = [r40],16      
320      nop.i 999 ;;
321 (p0) and        acos_GR_exp         = acos_GR_signexp_f8, acos_GR_17_ones ;;    
324 // case 1: |x| < 2^-25         ==> p6   ACOS_TINY
325 // case 2: 2^-25 <= |x| < 2^-2 ==> p8   ACOS_POLY
326 // case 3: 2^-2  <= |x| < 1    ==> p9   ACOS_ATAN
327 // case 4: 1     <= |x|        ==> p11  ACOS_ERROR_RETURN
328 //  Admittedly |x| = 1 is not an error but this is where that case is
329 //  handled.
331 { .mii
332 (p0) ldfe       acos_A7         = [r40],16      
333 (p0) sub        acos_GR_true_exp    = acos_GR_exp, acos_GR_16_ones ;;           
334 (p0) cmp.ge.unc p6, p7    = -26, acos_GR_true_exp ;;                            
337 { .mii
338 (p0) ldfe       acos_A6         = [r40],16      
339 (p7) cmp.ge.unc p8, p9    = -3,  acos_GR_true_exp ;;                            
340 (p9) cmp.ge.unc p10, p11  =  -1, acos_GR_true_exp                            
343 { .mmi
344 (p0) ldfe       acos_A5         = [r40],16 ;;      
345 (p0) ldfe       acos_A4         = [r40],16      
346       nop.i 999 ;;
349 { .mmi
350 (p0) ldfe       acos_A3         = [r40],16 ;;      
351 (p0) ldfe       acos_A2         = [r40],16      
352       nop.i 999 ;;
355 // ACOS_ERROR_RETURN ==> p11 is true
356 // case 4: |x| >= 1
357 { .mib
358 (p0)  ldfe       acos_A1         = [r40],16      
359       nop.i 999
360 (p11) br.spnt         L(ACOS_ERROR_RETURN) ;; 
363 // ACOS_TINY ==> p6 is true
364 // case 1: |x| < 2^-25
365 { .mfi
366       nop.m 999
367 (p6)  fms.s1        acos_xmpi_by_2_lo = acos_NORM_f8,f1, acos_pi_by_2_lo 
368       nop.i 999 ;;
371 { .mfb
372            nop.m 999
373 (p6)  fms.s0         f8 = acos_pi_by_2_hi,f1, acos_xmpi_by_2_lo                
374 (p6)  br.ret.spnt   b0 ;;                                                   
379 // ACOS_POLY ==> p8 is true
380 // case 2: 2^-25 <= |x| < 2^-2                   
381 { .mfi
382       nop.m 999
383 (p8)  fms.s1        acos_W       = acos_pi_by_2_hi, f1, acos_NORM_f8     
384       nop.i 999 ;;
387 { .mfi
388       nop.m 999
389 (p8)  fma.s1        acos_X2   = f8,f8, f0                                
390       nop.i 999 ;;
393 { .mfi
394       nop.m 999
395 (p8)  fms.s1        acos_Ww      = acos_pi_by_2_hi, f1, acos_W           
396       nop.i 999 ;;
399 { .mfi
400       nop.m 999
401 (p8)  fma.s1        acos_X4   = acos_X2,acos_X2, f0                      
402       nop.i 999 ;;
405 { .mfi
406       nop.m 999
407 (p8)  fms.s1        acos_Ww      = acos_Ww, f1, acos_NORM_f8             
408       nop.i 999 ;;
411 { .mfi
412       nop.m 999
413 (p8)  fma.s1        acos_P810 = acos_X4, acos_A10, acos_A8               
414       nop.i 999
417 // acos_P79  = X4*A9   + A7
418 // acos_P810 = X4*A10  + A8
419 { .mfi
420       nop.m 999
421 (p8)  fma.s1        acos_P79  = acos_X4, acos_A9, acos_A7                
422       nop.i 999 ;;
425 { .mfi
426       nop.m 999
427 (p8)  fma.s1        acos_Ww      = acos_Ww, f1, acos_pi_by_2_lo          
428       nop.i 999 ;;
431 { .mfi
432       nop.m 999
433 (p8)  fma.s1        acos_P610 = acos_X4, acos_P810, acos_A6              
434       nop.i 999
438 // acos_P59   = X4*(X4*A9   + A7)  + A5
439 // acos_P610  = X4*(X4*A10  + A8)  + A6
440 { .mfi
441       nop.m 999
442 (p8)  fma.s1        acos_P59  = acos_X4, acos_P79, acos_A5               
443       nop.i 999 ;;
446 { .mfi
447       nop.m 999
448 (p8)  fma.s1        acos_P410 = acos_X4, acos_P610, acos_A4              
449       nop.i 999
452 // acos_P39   = X4*(X4*(X4*A9   + A7)  + A5) + A3
453 // acos_P410  = X4*(X4*(X4*A10  + A8)  + A6) + A4
454 { .mfi
455       nop.m 999
456 (p8)  fma.s1        acos_P39  = acos_X4, acos_P59, acos_A3               
457       nop.i 999 ;;
460 { .mfi
461       nop.m 999
462 (p8)  fma.s1        acos_P210 = acos_X4, acos_P410, acos_A2              
463       nop.i 999
466 // acos_P19   = X4*(X4*(X4*(X4*A9   + A7)  + A5) + A3) + A1 = P1
467 // acos_P210  = X4*(X4*(X4*(X4*A10  + A8)  + A6) + A4) + A2 = P2
468 { .mfi
469       nop.m 999
470 (p8)  fma.s1        acos_P19  = acos_X4, acos_P39, acos_A1               
471       nop.i 999 ;;
474 // acos_P1P2 = Xsq*P2 + P1
475 // acos_P1P2 = Xsq*(Xsq*P2 + P1)
476 { .mfi
477       nop.m 999
478 (p8)  fma.s1        acos_P1P2    = acos_X2, acos_P210, acos_P19          
479       nop.i 999 ;;
482 { .mfi
483       nop.m 999
484 (p8)  fma.s1        acos_P1P2    = acos_X2, acos_P1P2, f0                
485       nop.i 999 ;;
488 { .mfi
489       nop.m 999
490 (p8)  fms.s1        acos_xPmw    = acos_NORM_f8, acos_P1P2, acos_Ww       
491       nop.i 999 ;;
494 { .mfb
495       nop.m 999
496 (p8)  fms.s0         f8           = acos_W, f1, acos_xPmw                 
497 (p8)  br.ret.spnt   b0 ;;                                                   
501 // ACOS_ATAN
502 // case 3: 2^-2  <= |x| < 1                      
503 // case 3: 2^-2  <= |x| < 1    ==> p9   ACOS_ATAN
505 // Step 1.1:     Get A,B and a,b
506 // A + a = 1- |X|
507 // B + b = 1+ |X|
508 // Note also that we will use  acos_corr (f13)
509 // and                         acos_W
511 // Step 2
512 // Call __libm_atan2_reg
515 { .mfi
516 (p0)  mov    acos_GR_fffe = 0xfffe                      
517 (p0)  fma.s1 acos_B          = f1,f1,  acos_ABS_NORM_f8                            
518 (p0)  mov   GR_SAVE_B0 = b0 ;;                                
521 { .mmf
522 (p0)  mov   GR_SAVE_GP = gp                                
523       nop.m 999
524 (p0)  fms.s1 acos_A   = f1,f1,  acos_ABS_NORM_f8                            
527 { .mfi
528 (p0)  setf.exp       acos_HALF = acos_GR_fffe                   
529       nop.f 999
530       nop.i 999 ;;
533 { .mfi
534       nop.m 999
535 (p0)  fms.s1 acos_1mB = f1,f1, acos_B                                       
536       nop.i 999 ;;
539 // We want atan2(V,U)
540 //   so put V in f8 and U in f9
541 //   but save X in acos_X
543 { .mfi
544       nop.m 999
545 (p0)  fmerge.se acos_X = f8, f8                               
546       nop.i 999 ;;
549 // Step 1.2:
550 /////////////////////////
551 // Get U = sqrt(B)
552 /////////////////////////
554 { .mfi
555       nop.m 999
556 (p0)  frsqrta.s1     acos_y0,p8  = acos_B                                
557       nop.i 999
560 { .mfi
561       nop.m 999
562 (p0)  fms.s1 acos_1mA = f1,f1, acos_A                                       
563       nop.i 999 ;;
566 { .mfi
567       nop.m 999
568 (p0)  fma.s1 acos_Bb  = acos_1mB,f1, acos_ABS_NORM_f8                       
569       nop.i 999 ;;
572 { .mfi
573       nop.m 999
574 (p0)  fma.s1         acos_Hh     = acos_HALF, acos_B, f0                 
575       nop.i 999 ;;
578 { .mfi
579       nop.m 999
580 (p0)  fma.s1         acos_t1     = acos_y0, acos_y0, f0                  
581       nop.i 999
584 { .mfi
585       nop.m 999
586 (p0)  fms.s1 acos_Aa  = acos_1mA,f1, acos_ABS_NORM_f8                       
587       nop.i 999 ;;
590 { .mfi
591       nop.m 999
592 (p0)  fnma.s1        acos_t2     = acos_t1, acos_Hh, acos_HALF           
593       nop.i 999 ;;
596 { .mfi
597       nop.m 999
598 (p0)  fma.s1         acos_y1     = acos_t2, acos_y0, acos_y0             
599       nop.i 999
603 // Step 1.2:
604 /////////////////////////
605 // Get V = sqrt(A)
606 /////////////////////////
607 { .mfi
608       nop.m 999
609 (p0)  frsqrta.s1     acos_y0,p8  = acos_A                                
610       nop.i 999 ;;
613 { .mfi
614       nop.m 999
615 (p0)  fma.s1         acos_t3     = acos_y1, acos_Hh, f0                  
616       nop.i 999 ;;
619 { .mfi
620       nop.m 999
621 (p0)  fma.s1         acos_t1     = acos_y0, acos_y0, f0                  
622       nop.i 999 ;;
625 { .mfi
626       nop.m 999
627 (p0)  fnma.s1        acos_t4     = acos_t3, acos_y1, acos_HALF           
628       nop.i 999 ;;
631 { .mfi
632       nop.m 999
633 (p0)  fma.s1         acos_y2     = acos_t4, acos_y1, acos_y1             
634       nop.i 999 ;;
637 { .mfi
638       nop.m 999
639 (p0)  fma.s1         acos_S      = acos_B, acos_y2, f0                   
640       nop.i 999
643 { .mfi
644       nop.m 999
645 (p0)  fma.s1         acos_H      = acos_y2, acos_HALF, f0                
646       nop.i 999 ;;
649 { .mfi
650       nop.m 999
651 (p0)  fma.s1         acos_t5     = acos_Hh, acos_y2, f0                  
652       nop.i 999
655 { .mfi
656       nop.m 999
657 (p0)  fma.s1         acos_Hh     = acos_HALF, acos_A, f0                 
658       nop.i 999 ;;
661 { .mfi
662       nop.m 999
663 (p0)  fnma.s1        acos_Dd     = acos_S, acos_S, acos_B                
664       nop.i 999 ;;
667 { .mfi
668       nop.m 999
669 (p0)  fnma.s1        acos_t2     = acos_t1, acos_Hh, acos_HALF           
670       nop.i 999 ;;
673 { .mfi
674       nop.m 999
675 (p0)  fma.s1         acos_U      = acos_Dd, acos_H, acos_S               
676       nop.i 999 ;;
679 { .mfi
680       nop.m 999
681 (p0)  fma.s1         acos_y1     = acos_t2, acos_y0, acos_y0             
682       nop.i 999 ;;
685 { .mfi
686       nop.m 999
687 (p0)  fma.s1         acos_2U       = acos_U, f1, acos_U                  
688       nop.i 999 ;;
691 { .mfi
692       nop.m 999
693 (p0)  fma.s1         acos_t3     = acos_y1, acos_Hh, f0                  
694       nop.i 999
698 // Step 1.3: 
699 // sqrt(A + a) = V + v
700 // sqrt(B + b) = U + u
702 /////////////////////////
703 // Get u
704 /////////////////////////
706 // acos_BmUU   = B - UU
707 // acos_BmUUpb = (B - UU) + b
709 { .mfi
710       nop.m 999
711 (p0)  fnma.s1        acos_BmUU     = acos_U, acos_U, acos_B              
712       nop.i 999 ;;
715 { .mfi
716       nop.m 999
717 (p0)   fmerge.se f9 = acos_U, acos_U                           
718       nop.i 999 ;;
721 { .mfi
722       nop.m 999
723 (p0)  fnma.s1        acos_t4     = acos_t3, acos_y1, acos_HALF           
724       nop.i 999 ;;
727 // acos_1d2U = frcpa(2U)
728 { .mfi
729       nop.m 999
730 (p0)  frcpa.s1       acos_1d2U,p9  = f1, acos_2U                         
731       nop.i 999
734 { .mfi
735       nop.m 999
736 (p0)  fma.s1         acos_BmUUpb   = acos_BmUU, f1, acos_Bb              
737       nop.i 999 ;;
740 { .mfi
741       nop.m 999
742 (p0)  fma.s1         acos_y2     = acos_t4, acos_y1, acos_y1             
743       nop.i 999 ;;
746 { .mfi
747       nop.m 999
748 // acos_Uu = ((B - UU) + b) * frcpa(2U)
749 (p0)  fma.s1         acos_Uu       = acos_BmUUpb, acos_1d2U, f0          
750       nop.i 999 ;;
753 { .mfi
754       nop.m 999
755 (p0)  fma.s1         acos_S      = acos_A, acos_y2, f0                   
756       nop.i 999
759 { .mfi
760       nop.m 999
761 (p0)  fma.s1         acos_H      = acos_y2, acos_HALF, f0                
762       nop.i 999 ;;
765 { .mfi
766       nop.m 999
767 (p0)  fma.s1         acos_t5     = acos_Hh, acos_y2, f0                  
768       nop.i 999 ;;
771 { .mfi
772       nop.m 999
773 (p0)  fnma.s1        acos_Dd     = acos_S, acos_S, acos_A                
774       nop.i 999 ;;
777 { .mfi
778       nop.m 999
779 (p0)  fma.s1         acos_V      = acos_Dd, acos_H, acos_S               
780       nop.i 999 ;;
783 { .mfi
784       nop.m 999
785 (p0)  fma.s1         acos_2V       = acos_V, f1, acos_V                  
786       nop.i 999
789 // Step 3
790 /////////////////////////
791 // Calculate the correction, acos_corr
792 /////////////////////////
793 // acos_corr = U*v - (V*u)
795 { .mfi
796       nop.m 999
797 (p0)  fma.s1  acos_Vu   = acos_V,acos_Uu, f0                  
798       nop.i 999 ;;
801 /////////////////////////
802 // Get v
803 /////////////////////////
804 // acos_AmVV   = A - VV
805 // acos_AmVVpa = (A - VV) + a
807 { .mfi
808       nop.m 999
809 (p0)  fnma.s1        acos_AmVV     = acos_V, acos_V, acos_A              
810       nop.i 999 ;;
813 { .mfi
814       nop.m 999
815 (p0)   fmerge.se f8 = acos_V, acos_V                           
816       nop.i 999 ;;
819 { .mfi
820       nop.m 999
821 (p0)  fma.s1         acos_AmVVpa   = acos_AmVV, f1, acos_Aa              
822       nop.i 999 ;;
825 // acos_1d2V = frcpa(2V)
826 { .mfi
827       nop.m 999
828 (p0)  frcpa.s1       acos_1d2V,p9  = f1, acos_2V                         
829       nop.i 999 ;;
832 // acos_Vv = ((A - VV) + a) * frcpa(2V)
833 { .mfi
834       nop.m 999
835 (p0)  fma.s1         acos_Vv       = acos_AmVVpa, acos_1d2V, f0          
836       nop.i 999 ;;
839 { .mfi
840       nop.m 999
841 (p0)   fma.s1  acos_Uv   = acos_U,acos_Vv, f0                  
842       nop.i 999 ;;
846 .endp acosl#
847 ASM_SIZE_DIRECTIVE(acosl#)
850 .proc __libm_callout
851 __libm_callout:
852 .prologue
853 { .mfi
854         nop.m 0
855         nop.f 0
856 .save   ar.pfs,GR_SAVE_PFS
857         mov  GR_SAVE_PFS=ar.pfs
861 { .mfi
862         mov GR_SAVE_GP=gp
863         nop.f 0
864 .save   b0, GR_SAVE_B0
865         mov GR_SAVE_B0=b0
868 .body
869 { .mfb
870       nop.m 999
871 (p0)   fms.s1  acos_corr = acos_Uv,f1, acos_Vu                 
872 (p0)   br.call.sptk.many  b0=__libm_atan2_reg# ;;                        
876 // p6 ==> X is negative
877 // p7 ==> x is positive
878 // We know that |X| >= 1/4
880 { .mfi
881 (p0)   mov gp              = GR_SAVE_GP                           
882 (p0)   fcmp.lt.unc   p6,p7 = acos_X , f0                       
883 (p0)   mov b0              = GR_SAVE_B0 ;;                           
886 // acos_2_Z_hi    = 2 * acos_Z_hi
887 // acos_s_lo_Z_lo = s_lo * Z_lo
889 { .mfi
890        nop.m 999
891 (p0)   fma.s1  acos_2_Z_hi      = acos_Z_hi, f1, acos_Z_hi               
892 (p0)   mov ar.pfs               = GR_SAVE_PFS                                     
895 { .mfi
896       nop.m 999
897 (p0)   fma.s1  acos_s_lo_Z_lo   = acos_s_lo, acos_Z_lo, f0               
898       nop.i 999 ;;
901 // 2 is a constant needed later
902 { .mfi
903       nop.m 999
904 (p0)  fma.s1     acos_2 = f1,f1,f1                             
905       nop.i 999 ;;
908 // X >= 1/4
909 // acos_result_lo = 2(s_lo * Z_lo) - corr
910 // f8             = (2*Z_hi) + (2(s_lo * Z_lo) - corr)
912 { .mfi
913       nop.m 999
914 (p7)   fma.s1  acos_result_lo     = acos_s_lo_Z_lo, acos_2, acos_corr      
915       nop.i 999 ;;
918 { .mfi
919       nop.m 999
920 (p7)  fma.s0   f8                 = acos_2_Z_hi, f1, acos_result_lo        
921       nop.i 999
924 // acos_result_lo = (pi_lo - corr)
925 // acos_result_lo = (pi_lo - corr) + acos_Ww 
926 { .mfi
927       nop.m 999
928 (p6)  fms.s1  acos_result_lo     = acos_pi_lo, f1, acos_corr              
929       nop.i 999 ;;
932 // X <= -1/4
933 // acos_W = pi_hi - 2 * Z_hi
934 { .mfi
935       nop.m 999
936 (p6)  fnma.s1 acos_W             = acos_2, acos_Z_hi, acos_pi_hi          
937       nop.i 999 ;;
940 // acos_Ww = pi_hi - W
941 // acos_Ww = (pi_hi - W) + (2 * Z_hi)
942 { .mfi
943       nop.m 999
944 (p6)  fms.s1  acos_Ww            = acos_pi_hi, f1, acos_W                 
945       nop.i 999 ;;
948 { .mfi
949       nop.m 999
950 (p6)   fms.s1  acos_Ww            = acos_Ww, f1, acos_2_Z_hi               
951       nop.i 999 ;;
954 { .mfi
955       nop.m 999
956 (p6)   fma.s1  acos_result_lo     = acos_result_lo, f1, acos_Ww            
957       nop.i 999 ;;
960 // acos_Z_lo = ((pi_lo - corr) + acos_Ww) - 2 * (s_lo * Z_lo)
961 { .mfi
962       nop.m 999
963 (p6)  fnma.s1  acos_Z_lo          = acos_s_lo_Z_lo, acos_2, acos_result_lo 
964       nop.i 999 ;;
967 { .mfb
968       nop.m 999
969 (p6)  fma.s0   f8                  = acos_W, f1, acos_Z_lo                
970 (p0)  br.ret.sptk   b0 ;;                          
972 .endp __libm_callout
973 ASM_SIZE_DIRECTIVE(__libm_callout)
975 .proc SPECIAL
976 SPECIAL:
977 L(ACOS_NAN): 
978 { .mfb
979       nop.m 999
980 (p0)  fma.s0 f8 = f8,f1,f0                       
981 (p0)  br.ret.sptk   b0 ;;                          
984 L(ACOS_ERROR_RETURN): 
985 // Save ar.pfs, b0, and gp; restore on exit
987 // qnan snan inf norm     unorm 0 -+
988 // 1    1    0   0        0     0 11 = 0xc3
990 // Coming in as X = +- 1
991 // What should we return?
993 // If X is 1, return (sign of X)pi/2
996 { .mfi
997       nop.m 999
998 (p0)  fcmp.eq.unc p6,p7 = acos_ABS_NORM_f8,f1              
999       nop.i 999 ;;
1002 { .mfi
1003       nop.m 999
1004 (p6)  fcmp.lt.unc p8,p9 = f8,f0                            
1005       nop.i 999 ;;
1008 { .mfi
1009       nop.m 999
1010 (p8)  fma.s0 f8          = acos_pi_hi, f1, acos_pi_lo       
1011       nop.i 999
1014 { .mfb
1015       nop.m 999
1016 (p9)  fmerge.s    f8 = f8,f0                               
1017 (p6)  br.ret.spnt   b0 ;;                                     
1020 // If X is a NAN, leave
1021 { .mfi
1022       nop.m 999
1023 (p0)  fclass.m.unc p12,p0 = f8, 0xc3            
1024       nop.i 999 ;;
1027 { .mfb
1028       nop.m 999
1029 (p12) fma.s0 f8 = f8,f1,f0                       
1030 (p12) br.ret.spnt   b0 ;;                          
1033 { .mfi
1034 (p0)   mov   GR_Parameter_TAG = 57 
1035 (p0)   frcpa f10, p6 = f0, f0
1036 nop.i 999
1039 .endp SPECIAL
1040 ASM_SIZE_DIRECTIVE(SPECIAL)
1042 .proc __libm_error_region
1043 __libm_error_region:
1044 .prologue
1045 // (1)
1046 { .mfi
1047         add   GR_Parameter_Y=-32,sp             // Parameter 2 value
1048         nop.f 0
1049 .save   ar.pfs,GR_SAVE_PFS
1050         mov  GR_SAVE_PFS=ar.pfs                 // Save ar.pfs
1052 { .mfi
1053 .fframe 64
1054         add sp=-64,sp                          // Create new stack
1055         nop.f 0
1056         mov GR_SAVE_GP=gp                      // Save gp
1060 // (2)
1061 { .mmi
1062         stfe [GR_Parameter_Y] = f1,16         // Store Parameter 2 on stack
1063         add GR_Parameter_X = 16,sp            // Parameter 1 address
1064 .save   b0, GR_SAVE_B0
1065         mov GR_SAVE_B0=b0                     // Save b0
1068 .body
1069 // (3)
1070 { .mib
1071         stfe [GR_Parameter_X] = f8              // Store Parameter 1 on stack
1072         add   GR_Parameter_RESULT = 0,GR_Parameter_Y
1073         nop.b 0                                 // Parameter 3 address
1075 { .mib
1076         stfe [GR_Parameter_Y] = f10             // Store Parameter 3 on stack
1077         add   GR_Parameter_Y = -16,GR_Parameter_Y
1078         br.call.sptk b0=__libm_error_support#   // Call error handling function
1080 { .mmi
1081         nop.m 0
1082         nop.m 0
1083         add   GR_Parameter_RESULT = 48,sp
1086 // (4)
1087 { .mmi
1088         ldfe  f8 = [GR_Parameter_RESULT]       // Get return result off stack
1089 .restore sp
1090         add   sp = 64,sp                       // Restore stack pointer
1091         mov   b0 = GR_SAVE_B0                  // Restore return address
1094 { .mib
1095         mov   gp = GR_SAVE_GP                  // Restore gp
1096         mov   ar.pfs = GR_SAVE_PFS             // Restore ar.pfs
1097         br.ret.sptk     b0                     // Return
1100 .endp __libm_error_region
1101 ASM_SIZE_DIRECTIVE(__libm_error_region)
1103 .type   __libm_error_support#,@function
1104 .global __libm_error_support#
1106 .type   __libm_atan2_reg#,@function
1107 .global __libm_atan2_reg#