4 // Copyright (c) 2000 - 2002, Intel Corporation
5 // All rights reserved.
8 // Redistribution and use in source and binary forms, with or without
9 // modification, are permitted provided that the following conditions are
12 // * Redistributions of source code must retain the above copyright
13 // notice, this list of conditions and the following disclaimer.
15 // * Redistributions in binary form must reproduce the above copyright
16 // notice, this list of conditions and the following disclaimer in the
17 // documentation and/or other materials provided with the distribution.
19 // * The name of Intel Corporation may not be used to endorse or promote
20 // products derived from this software without specific prior written
23 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
27 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
31 // OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY OR TORT (INCLUDING
32 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 // Intel Corporation is the author of this code, and requests that all
36 // problem reports or change requests be submitted to it directly at
37 // http://www.intel.com/software/products/opensource/libraries/num.htm.
40 //==============================================================
41 // 02/02/00 Initial version
42 // 04/04/00 Unwind support added
43 // 08/15/00 Bundle added after call to __libm_error_support to properly
44 // set [the previously overwritten] GR_Parameter_RESULT.
45 // 01/23/01 Set inexact flag for large args.
46 // 05/07/01 Reworked to improve speed of all paths
47 // 05/20/02 Cleaned up namespace and sf0 syntax
48 // 12/06/02 Improved performance
51 //==============================================================
52 // long double = coshl(long double)
53 // input floating point f8
54 // output floating point f8
57 //==============================================================
60 // predicate registers used:
62 // floating-point registers used:
63 // f9 -> f15; f32 -> f90;
64 // f8 has input, then output
66 // Overview of operation
67 //==============================================================
68 // There are seven paths
69 // 1. 0 < |x| < 0.25 COSH_BY_POLY
70 // 2. 0.25 <=|x| < 32 COSH_BY_TBL
71 // 3. 32 <= |x| < 11357.21655 COSH_BY_EXP (merged path with COSH_BY_TBL)
72 // 4. |x| >= 11357.21655 COSH_HUGE
73 // 5. x=0 Done with early exit
74 // 6. x=inf,nan Done with early exit
75 // 7. x=denormal COSH_DENORM
77 // For double extended we get overflow for x >= 400c b174 ddc0 31ae c0ea
81 // 1. COSH_BY_POLY 0 < |x| < 0.25
83 // Evaluate cosh(x) by a 12th order polynomial
84 // Care is take for the order of multiplication; and P2 is not exactly 1/4!,
85 // P3 is not exactly 1/6!, etc.
86 // cosh(x) = 1 + (P1*x^2 + P2*x^4 + P3*x^6 + P4*x^8 + P5*x^10 + P6*x^12)
88 // 2. COSH_BY_TBL 0.25 <= |x| < 32.0
90 // cosh(x) = cosh(B+R)
91 // = cosh(B)cosh(R) + sinh(B)sinh(R)
93 // ax = |x| = M*log2/64 + R
96 // We will calculate M and get N as (M-j)/64
97 // The division is a shift.
98 // exp(B) = exp(N*log2 + j*log2/64)
99 // = 2^N * 2^(j*log2/64)
100 // cosh(B) = 1/2(e^B + e^-B)
101 // = 1/2(2^N * 2^(j*log2/64) + 2^-N * 2^(-j*log2/64))
102 // cosh(B) = (2^(N-1) * 2^(j*log2/64) + 2^(-N-1) * 2^(-j*log2/64))
103 // sinh(B) = (2^(N-1) * 2^(j*log2/64) - 2^(-N-1) * 2^(-j*log2/64))
104 // 2^(j*log2/64) is stored as Tjhi + Tjlo , j= -32,....,32
105 // Tjhi is double-extended (80-bit) and Tjlo is single(32-bit)
107 // R = ax - M*log2/64
108 // R = ax - M*log2_by_64_hi - M*log2_by_64_lo
109 // exp(R) = 1 + R +R^2(1/2! + R(1/3! + R(1/4! + ... + R(1/n!)...)
110 // = 1 + p_odd + p_even
111 // where the p_even uses the A coefficients and the p_even uses
112 // the B coefficients
114 // So sinh(R) = 1 + p_odd + p_even -(1 -p_odd -p_even)/2 = p_odd
115 // cosh(R) = 1 + p_even
116 // cosh(B) = C_hi + C_lo
118 // cosh(x) = cosh(B)cosh(R) + sinh(B)sinh(R)
120 // 3. COSH_BY_EXP 32.0 <= |x| < 11357.21655 ( 400c b174 ddc0 31ae c0ea )
122 // Can approximate result by exp(x)/2 in this region.
124 // Y_lo = Tjhi * (p_odd + p_even) + Tjlo
125 // cosh(x) = Y_hi + Y_lo
127 // 4. COSH_HUGE |x| >= 11357.21655 ( 400c b174 ddc0 31ae c0ea )
129 // Set error tag and call error support
133 //==============================================================
171 GR_Parameter_RESULT = r39
172 GR_Parameter_TAG = r40
213 f_INV_LN2_2TO63 = f57
216 f_smlst_oflow_input = f60
256 //==============================================================
258 // DO NOT CHANGE ORDER OF THESE TABLES
262 LOCAL_OBJECT_START(cosh_arg_reduction)
263 // data8 0xB8AA3B295C17F0BC, 0x00004005 // 64/log2 -- signif loaded with setf
264 data8 0xB17217F7D1000000, 0x00003FF8 // log2/64 high part
265 data8 0xCF79ABC9E3B39804, 0x00003FD0 // log2/64 low part
266 data8 0xb174ddc031aec0ea, 0x0000400c // Smallest x to overflow (11357.21655)
267 LOCAL_OBJECT_END(cosh_arg_reduction)
269 LOCAL_OBJECT_START(cosh_p_table)
270 data8 0x8FA02AC65BCBD5BC, 0x00003FE2 // P6
271 data8 0xD00D00D1021D7370, 0x00003FEF // P4
272 data8 0xAAAAAAAAAAAAAB80, 0x00003FFA // P2
273 data8 0x93F27740C0C2F1CC, 0x00003FE9 // P5
274 data8 0xB60B60B60B4FE884, 0x00003FF5 // P3
275 data8 0x8000000000000000, 0x00003FFE // P1
276 LOCAL_OBJECT_END(cosh_p_table)
278 LOCAL_OBJECT_START(cosh_ab_table)
279 data8 0xAAAAAAAAAAAAAAAC, 0x00003FFC // A1
280 data8 0x88888888884ECDD5, 0x00003FF8 // A2
281 data8 0xD00D0C6DCC26A86B, 0x00003FF2 // A3
282 data8 0x8000000000000002, 0x00003FFE // B1
283 data8 0xAAAAAAAAAA402C77, 0x00003FFA // B2
284 data8 0xB60B6CC96BDB144D, 0x00003FF5 // B3
285 LOCAL_OBJECT_END(cosh_ab_table)
287 LOCAL_OBJECT_START(cosh_j_hi_table)
288 data8 0xB504F333F9DE6484, 0x00003FFE
289 data8 0xB6FD91E328D17791, 0x00003FFE
290 data8 0xB8FBAF4762FB9EE9, 0x00003FFE
291 data8 0xBAFF5AB2133E45FB, 0x00003FFE
292 data8 0xBD08A39F580C36BF, 0x00003FFE
293 data8 0xBF1799B67A731083, 0x00003FFE
294 data8 0xC12C4CCA66709456, 0x00003FFE
295 data8 0xC346CCDA24976407, 0x00003FFE
296 data8 0xC5672A115506DADD, 0x00003FFE
297 data8 0xC78D74C8ABB9B15D, 0x00003FFE
298 data8 0xC9B9BD866E2F27A3, 0x00003FFE
299 data8 0xCBEC14FEF2727C5D, 0x00003FFE
300 data8 0xCE248C151F8480E4, 0x00003FFE
301 data8 0xD06333DAEF2B2595, 0x00003FFE
302 data8 0xD2A81D91F12AE45A, 0x00003FFE
303 data8 0xD4F35AABCFEDFA1F, 0x00003FFE
304 data8 0xD744FCCAD69D6AF4, 0x00003FFE
305 data8 0xD99D15C278AFD7B6, 0x00003FFE
306 data8 0xDBFBB797DAF23755, 0x00003FFE
307 data8 0xDE60F4825E0E9124, 0x00003FFE
308 data8 0xE0CCDEEC2A94E111, 0x00003FFE
309 data8 0xE33F8972BE8A5A51, 0x00003FFE
310 data8 0xE5B906E77C8348A8, 0x00003FFE
311 data8 0xE8396A503C4BDC68, 0x00003FFE
312 data8 0xEAC0C6E7DD24392F, 0x00003FFE
313 data8 0xED4F301ED9942B84, 0x00003FFE
314 data8 0xEFE4B99BDCDAF5CB, 0x00003FFE
315 data8 0xF281773C59FFB13A, 0x00003FFE
316 data8 0xF5257D152486CC2C, 0x00003FFE
317 data8 0xF7D0DF730AD13BB9, 0x00003FFE
318 data8 0xFA83B2DB722A033A, 0x00003FFE
319 data8 0xFD3E0C0CF486C175, 0x00003FFE
320 data8 0x8000000000000000, 0x00003FFF // Center of table
321 data8 0x8164D1F3BC030773, 0x00003FFF
322 data8 0x82CD8698AC2BA1D7, 0x00003FFF
323 data8 0x843A28C3ACDE4046, 0x00003FFF
324 data8 0x85AAC367CC487B15, 0x00003FFF
325 data8 0x871F61969E8D1010, 0x00003FFF
326 data8 0x88980E8092DA8527, 0x00003FFF
327 data8 0x8A14D575496EFD9A, 0x00003FFF
328 data8 0x8B95C1E3EA8BD6E7, 0x00003FFF
329 data8 0x8D1ADF5B7E5BA9E6, 0x00003FFF
330 data8 0x8EA4398B45CD53C0, 0x00003FFF
331 data8 0x9031DC431466B1DC, 0x00003FFF
332 data8 0x91C3D373AB11C336, 0x00003FFF
333 data8 0x935A2B2F13E6E92C, 0x00003FFF
334 data8 0x94F4EFA8FEF70961, 0x00003FFF
335 data8 0x96942D3720185A00, 0x00003FFF
336 data8 0x9837F0518DB8A96F, 0x00003FFF
337 data8 0x99E0459320B7FA65, 0x00003FFF
338 data8 0x9B8D39B9D54E5539, 0x00003FFF
339 data8 0x9D3ED9A72CFFB751, 0x00003FFF
340 data8 0x9EF5326091A111AE, 0x00003FFF
341 data8 0xA0B0510FB9714FC2, 0x00003FFF
342 data8 0xA27043030C496819, 0x00003FFF
343 data8 0xA43515AE09E6809E, 0x00003FFF
344 data8 0xA5FED6A9B15138EA, 0x00003FFF
345 data8 0xA7CD93B4E965356A, 0x00003FFF
346 data8 0xA9A15AB4EA7C0EF8, 0x00003FFF
347 data8 0xAB7A39B5A93ED337, 0x00003FFF
348 data8 0xAD583EEA42A14AC6, 0x00003FFF
349 data8 0xAF3B78AD690A4375, 0x00003FFF
350 data8 0xB123F581D2AC2590, 0x00003FFF
351 data8 0xB311C412A9112489, 0x00003FFF
352 data8 0xB504F333F9DE6484, 0x00003FFF
353 LOCAL_OBJECT_END(cosh_j_hi_table)
355 LOCAL_OBJECT_START(cosh_j_lo_table)
388 data4 0x00000000 // Center of table
421 LOCAL_OBJECT_END(cosh_j_lo_table)
425 GLOBAL_IEEE754_ENTRY(coshl)
428 getf.exp r_signexp_x = f8 // Get signexp of x, must redo if unorm
429 movl r_sig_inv_ln2 = 0xb8aa3b295c17f0bc // significand of 1/ln2
432 addl r_ad1 = @ltoff(cosh_arg_reduction), gp
433 movl r_rshf_2to57 = 0x4778000000000000 // 1.10000 2^(63+57)
439 fmerge.s f_ABS_X = f0,f8
440 mov r_exp_0_25 = 0x0fffd // Form exponent for 0.25
444 fnorm.s1 f_NORM_X = f8
445 mov r_exp_2tom57 = 0xffff-57
450 setf.d f_RSHF_2TO57 = r_rshf_2to57 // Form const 1.100 * 2^120
451 fclass.m p10,p0 = f8, 0x0b // Test for denorm
452 mov r_exp_mask = 0x1ffff
455 setf.sig f_INV_LN2_2TO63 = r_sig_inv_ln2 // Form 1/ln2 * 2^63
456 movl r_rshf = 0x43e8000000000000 // 1.1000 2^63 for right shift
462 fclass.m p7,p0 = f8, 0x07 // Test if x=0
466 setf.exp f_2TOM57 = r_exp_2tom57 // Form 2^-57 for scaling
468 add r_ad3 = 0x90, r_ad1 // Point to ab_table
473 setf.d f_RSHF = r_rshf // Form right shift const 1.100 * 2^63
474 fclass.m p6,p0 = f8, 0xe3 // Test if x nan, inf
475 add r_ad4 = 0x2f0, r_ad1 // Point to j_hi_table midpoint
478 add r_ad2e = 0x20, r_ad1 // Point to p_table
480 (p10) br.cond.spnt COSH_DENORM // Branch if x denorm
484 // Common path -- return here from COSH_DENORM if x is unnorm
487 ldfe f_smlst_oflow_input = [r_ad2e],16
488 (p7) fma.s0 f8 = f1, f1, f0 // Result = 1.0 if x=0
489 add r_ad5 = 0x580, r_ad1 // Point to j_lo_table midpoint
492 ldfe f_log2by64_hi = [r_ad1],16
493 and r_exp_x = r_exp_mask, r_signexp_x
494 (p7) br.ret.spnt b0 // Exit if x=0
498 // Get the A coefficients for COSH_BY_TBL
500 ldfe f_A1 = [r_ad3],16
501 fcmp.lt.s1 p8,p9 = f8,f0 // Test for x<0
502 cmp.lt p7,p0 = r_exp_x, r_exp_0_25 // Test x < 0.25
505 add r_ad2o = 0x30, r_ad2e // Point to p_table odd coeffs
506 (p6) fma.s0 f8 = f8,f8,f0 // Result for x nan, inf
507 (p6) br.ret.spnt b0 // Exit for x nan, inf
511 // Calculate X2 = ax*ax for COSH_BY_POLY
513 ldfe f_log2by64_lo = [r_ad1],16
518 ldfe f_A2 = [r_ad3],16
519 fma.s1 f_X2 = f_NORM_X, f_NORM_X, f0
520 (p7) br.cond.spnt COSH_BY_POLY
524 // Here if |x| >= 0.25
526 // ******************************************************
527 // STEP 1 (TBL and EXP) - Argument reduction
528 // ******************************************************
529 // Get the following constants.
535 // We want 2^(N-1) and 2^(-N-1). So bias N-1 and -N-1 and
536 // put them in an exponent.
537 // f_spos = 2^(N-1) and f_sneg = 2^(-N-1)
538 // 0xffff + (N-1) = 0xffff +N -1
539 // 0xffff - (N +1) = 0xffff -N -1
542 // Calculate M and keep it as integer and floating point.
543 // M = round-to-integer(x*Inv_log2by64)
544 // f_M = M = truncate(ax/(log2/64))
545 // Put the integer representation of M in r_M
546 // and the floating point representation of M in f_M
548 // Get the remaining A,B coefficients
550 ldfe f_A3 = [r_ad3],16
556 // Use constant (1.100*2^(63-6)) to get rounded M into rightmost significand
557 // |x| * 64 * 1/ln2 * 2^(63-6) + 1.1000 * 2^(63+(63-6))
560 fma.s1 f_M_temp = f_ABS_X, f_INV_LN2_2TO63, f_RSHF_2TO57
561 mov r_signexp_0_5 = 0x0fffe // signexp of +0.5
565 // Test for |x| >= overflow limit
567 ldfe f_B1 = [r_ad3],16
568 fcmp.ge.s1 p6,p0 = f_ABS_X, f_smlst_oflow_input
574 ldfe f_B2 = [r_ad3],16
576 mov r_exp_32 = 0x10004
580 // Subtract RSHF constant to get rounded M as a floating point value
581 // M_temp * 2^(63-6) - 2^63
583 ldfe f_B3 = [r_ad3],16
584 fms.s1 f_M = f_M_temp, f_2TOM57, f_RSHF
585 (p6) br.cond.spnt COSH_HUGE // Branch if result will overflow
590 getf.sig r_M = f_M_temp
592 cmp.ge p7,p6 = r_exp_x, r_exp_32 // Test if x >= 32
596 // Calculate j. j is the signed extension of the six lsb of M. It
597 // has a range of -32 thru 31.
600 // ax - M*log2by64_hi
601 // R = (ax - M*log2by64_hi) - M*log2by64_lo
605 fnma.s1 f_R_temp = f_M, f_log2by64_hi, f_ABS_X
612 shl r_jshf = r_j, 0x2 // Shift j so can sign extend it
620 shr r_j = r_jshf, 0x2 // Now j has range -32 to 31
626 shladd r_ad_J_hi = r_j, 4, r_ad4 // pointer to Tjhi
627 sub r_Mmj = r_M, r_j // M-j
628 sub r_mj = r0, r_j // Form -j
632 // The TBL and EXP branches are merged and predicated
633 // If TBL, p6 true, 0.25 <= |x| < 32
634 // If EXP, p7 true, 32 <= |x| < overflow_limit
638 ldfe f_Tjhi = [r_ad_J_hi]
639 fnma.s1 f_R = f_M, f_log2by64_lo, f_R_temp
640 shr r_N = r_Mmj, 0x6 // N = (M-j)/64
643 shladd r_ad_mJ_hi = r_mj, 4, r_ad4 // pointer to Tmjhi
645 shladd r_ad_mJ_lo = r_mj, 2, r_ad5 // pointer to Tmjlo
650 sub r_2mNm1 = r_signexp_0_5, r_N // signexp 2^(-N-1)
652 shladd r_ad_J_lo = r_j, 2, r_ad5 // pointer to Tjlo
655 ldfe f_Tmjhi = [r_ad_mJ_hi]
657 add r_2Nm1 = r_signexp_0_5, r_N // signexp 2^(N-1)
662 ldfs f_Tmjlo = [r_ad_mJ_lo]
663 setf.exp f_sneg = r_2mNm1 // Form 2^(-N-1)
669 ldfs f_Tjlo = [r_ad_J_lo]
670 setf.exp f_spos = r_2Nm1 // Form 2^(N-1)
675 // ******************************************************
676 // STEP 2 (TBL and EXP)
677 // ******************************************************
678 // Calculate Rsquared and Rcubed in preparation for p_even and p_odd
683 fma.s1 f_Rsq = f_R, f_R, f0
690 // B_1 + Rsq * (B_2 + Rsq *B_3)
691 // p_even = Rsq * (B_1 + Rsq * (B_2 + Rsq *B_3))
694 fma.s1 f_peven_temp1 = f_Rsq, f_B3, f_B2
699 // A_1 + Rsq * (A_2 + Rsq *A_3)
700 // podd = R + Rcub * (A_1 + Rsq * (A_2 + Rsq *A_3))
703 fma.s1 f_podd_temp1 = f_Rsq, f_A3, f_A2
710 fma.s1 f_Rcub = f_Rsq, f_R, f0
717 // Calculate S_hi and S_lo, and C_hi
718 // SC_hi_temp = sneg * Tmjhi
719 // S_hi = spos * Tjhi - SC_hi_temp
720 // S_hi = spos * Tjhi - (sneg * Tmjhi)
721 // C_hi = spos * Tjhi + SC_hi_temp
722 // C_hi = spos * Tjhi + (sneg * Tmjhi)
726 (p6) fma.s1 f_SC_hi_temp = f_sneg, f_Tmjhi, f0
732 // C_lo_temp3 = sneg * Tmjlo
733 // C_lo_temp4 = spos * Tjlo + C_lo_temp3
734 // C_lo_temp4 = spos * Tjlo + (sneg * Tmjlo)
737 (p6) fma.s1 f_C_lo_temp3 = f_sneg, f_Tmjlo, f0
744 fma.s1 f_peven_temp2 = f_Rsq, f_peven_temp1, f_B1
749 fma.s1 f_podd_temp2 = f_Rsq, f_podd_temp1, f_A1
755 // Compute 2^(N-1) * Tjhi and 2^(N-1) * Tjlo
758 (p7) fma.s1 f_Tjhi_spos = f_Tjhi, f_spos, f0
763 (p7) fma.s1 f_Tjlo_spos = f_Tjlo, f_spos, f0
770 (p6) fma.s1 f_C_hi = f_spos, f_Tjhi, f_SC_hi_temp
777 (p6) fms.s1 f_S_hi = f_spos, f_Tjhi, f_SC_hi_temp
782 (p6) fma.s1 f_C_lo_temp4 = f_spos, f_Tjlo, f_C_lo_temp3
789 fma.s1 f_peven = f_Rsq, f_peven_temp2, f0
794 fma.s1 f_podd = f_podd_temp2, f_Rcub, f_R
800 // C_lo_temp1 = spos * Tjhi - C_hi
801 // C_lo_temp2 = sneg * Tmjlo + C_lo_temp1
802 // C_lo_temp2 = sneg * Tmjlo + (spos * Tjhi - C_hi)
806 (p6) fms.s1 f_C_lo_temp1 = f_spos, f_Tjhi, f_C_hi
813 (p6) fma.s1 f_C_lo_temp2 = f_sneg, f_Tmjhi, f_C_lo_temp1
819 // Y_hi = 2^(N-1) * Tjhi
820 // Y_lo = 2^(N-1) * Tjhi * (p_odd + p_even) + 2^(N-1) * Tjlo
823 (p7) fma.s1 f_Y_lo_temp = f_peven, f1, f_podd
829 // C_lo = C_lo_temp4 + C_lo_temp2
832 (p6) fma.s1 f_C_lo = f_C_lo_temp4, f1, f_C_lo_temp2
839 // Y_lo = S_hi*p_odd + (C_hi*p_even + C_lo)
842 (p6) fma.s1 f_Y_lo_temp = f_C_hi, f_peven, f_C_lo
849 (p7) fma.s1 f_Y_lo = f_Tjhi_spos, f_Y_lo_temp, f_Tjlo_spos
854 // Dummy multiply to generate inexact
857 fmpy.s0 f_tmp = f_B2, f_B2
862 (p6) fma.s1 f_Y_lo = f_S_hi, f_podd, f_Y_lo_temp
867 // f8 = answer = Y_hi + Y_lo
870 (p7) fma.s0 f8 = f_Y_lo, f1, f_Tjhi_spos
875 // f8 = answer = Y_hi + Y_lo
878 (p6) fma.s0 f8 = f_Y_lo, f1, f_C_hi
879 br.ret.sptk b0 // Exit for COSH_BY_TBL and COSH_BY_EXP
884 // Here if 0 < |x| < 0.25
887 ldfe f_P6 = [r_ad2e],16
888 ldfe f_P5 = [r_ad2o],16
894 ldfe f_P4 = [r_ad2e],16
895 ldfe f_P3 = [r_ad2o],16
901 ldfe f_P2 = [r_ad2e],16
902 ldfe f_P1 = [r_ad2o],16
909 fma.s1 f_X3 = f_NORM_X, f_X2, f0
914 fma.s1 f_X4 = f_X2, f_X2, f0
921 fma.s1 f_poly65 = f_X2, f_P6, f_P5
926 fma.s1 f_poly43 = f_X2, f_P4, f_P3
933 fma.s1 f_poly21 = f_X2, f_P2, f_P1
940 fma.s1 f_poly6543 = f_X4, f_poly65, f_poly43
947 fma.s1 f_poly6to1 = f_X4, f_poly6543, f_poly21
952 // Dummy multiply to generate inexact
955 fmpy.s0 f_tmp = f_P6, f_P6
960 fma.s0 f8 = f_poly6to1, f_X2, f1
961 br.ret.sptk b0 // Exit COSH_BY_POLY
966 // Here if x denorm or unorm
968 // Determine if x really a denorm and not a unorm
970 getf.exp r_signexp_x = f_NORM_X
971 mov r_exp_denorm = 0x0c001 // Real denorms have exp < this
972 fmerge.s f_ABS_X = f0, f_NORM_X
978 fcmp.eq.s0 p10,p0 = f8, f0 // Set denorm flag
983 // Set p8 if really a denorm
985 and r_exp_x = r_exp_mask, r_signexp_x
987 cmp.lt p8,p9 = r_exp_x, r_exp_denorm
992 // Identify denormal operands.
995 (p8) fma.s0 f8 = f8,f8,f1 // If x denorm, result=1+x^2
996 (p9) br.cond.sptk COSH_COMMON // Return to main path if x unorm
1003 br.ret.sptk b0 // Exit if x denorm
1008 // Here if |x| >= overflow limit
1010 // for COSH_HUGE, put 24000 in exponent; take sign from input
1012 mov r_exp_huge = 0x15dbf
1014 setf.exp f_huge = r_exp_huge
1020 alloc r32 = ar.pfs,0,5,4,0
1021 fma.s1 f_signed_hi_lo = f_huge, f1, f1
1028 fma.s0 f_pre_result = f_signed_hi_lo, f_huge, f0
1029 mov GR_Parameter_TAG = 63
1033 GLOBAL_IEEE754_END(coshl)
1034 libm_alias_ldouble_other (__cosh, cosh)
1037 LOCAL_LIBM_ENTRY(__libm_error_region)
1041 add GR_Parameter_Y=-32,sp // Parameter 2 value
1043 .save ar.pfs,GR_SAVE_PFS
1044 mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
1048 add sp=-64,sp // Create new stack
1050 mov GR_SAVE_GP=gp // Save gp
1054 stfe [GR_Parameter_Y] = f0,16 // STORE Parameter 2 on stack
1055 add GR_Parameter_X = 16,sp // Parameter 1 address
1056 .save b0, GR_SAVE_B0
1057 mov GR_SAVE_B0=b0 // Save b0
1062 stfe [GR_Parameter_X] = f8 // STORE Parameter 1 on stack
1063 add GR_Parameter_RESULT = 0,GR_Parameter_Y // Parameter 3 address
1067 stfe [GR_Parameter_Y] = f_pre_result // STORE Parameter 3 on stack
1068 add GR_Parameter_Y = -16,GR_Parameter_Y
1069 br.call.sptk b0=__libm_error_support# // Call error handling function
1073 add GR_Parameter_RESULT = 48,sp
1079 ldfe f8 = [GR_Parameter_RESULT] // Get return result off stack
1081 add sp = 64,sp // Restore stack pointer
1082 mov b0 = GR_SAVE_B0 // Restore return address
1086 mov gp = GR_SAVE_GP // Restore gp
1087 mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
1088 br.ret.sptk b0 // Return
1091 LOCAL_LIBM_END(__libm_error_region)
1094 .type __libm_error_support#,@function
1095 .global __libm_error_support#