Remove support in configure for unsupported architectures
[glibc.git] / sysdeps / ia64 / fpu / e_sinhl.S
blob5b4a4addc22ab0b8e173a3e224c10a4452db2427
1 .file "sinhl.s"
4 // Copyright (c) 2000 - 2002, Intel Corporation
5 // All rights reserved.
6 //
7 // Contributed 2000 by the Intel Numerics Group, 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://www.intel.com/software/products/opensource/libraries/num.htm.
40 // History
41 //==============================================================
42 // 02/02/00 Initial version
43 // 04/04/00 Unwind support added
44 // 08/15/00 Bundle added after call to __libm_error_support to properly
45 //          set [the previously overwritten] GR_Parameter_RESULT.
46 // 10/12/00 Update to set denormal operand and underflow flags
47 // 01/22/01 Fixed to set inexact flag for small args.  Fixed incorrect 
48 //          call to __libm_error_support for 710.476 < x < 11357.2166.
49 // 05/02/01 Reworked to improve speed of all paths
50 // 05/20/02 Cleaned up namespace and sf0 syntax
51 // 12/04/02 Improved performance
53 // API
54 //==============================================================
55 // long double = sinhl(long double)
56 // input  floating point f8
57 // output floating point f8
59 // Registers used
60 //==============================================================
61 // general registers: 
62 // r14 -> r40
63 // predicate registers used:
64 // p6 -> p11
65 // floating-point registers used:
66 // f9 -> f15; f32 -> f90; 
67 // f8 has input, then output
69 // Overview of operation
70 //==============================================================
71 // There are seven paths
72 // 1. 0 < |x| < 0.25          SINH_BY_POLY
73 // 2. 0.25 <=|x| < 32         SINH_BY_TBL
74 // 3. 32 <= |x| < 11357.21655 SINH_BY_EXP (merged path with SINH_BY_TBL)
75 // 4. |x| >= 11357.21655      SINH_HUGE
76 // 5. x=0                     Done with early exit
77 // 6. x=inf,nan               Done with early exit
78 // 7. x=denormal              SINH_DENORM
80 // For double extended we get overflow for x >= 400c b174 ddc0 31ae c0ea
81 //                                           >= 11357.21655
84 // 1. SINH_BY_POLY   0 < |x| < 0.25
85 // ===============
86 // Evaluate sinh(x) by a 13th order polynomial
87 // Care is take for the order of multiplication; and P_1 is not exactly 1/3!, 
88 // P_2 is not exactly 1/5!, etc.
89 // sinh(x) = sign * (series(e^x) - series(e^-x))/2
90 //         = sign * (ax + ax^3/3! + ax^5/5! + ax^7/7! + ax^9/9! + ax^11/11!
91 //                        + ax^13/13!)
92 //         = sign * (ax   + ax * ( ax^2 * (1/3! + ax^4 * (1/7! + ax^4*1/11!)) )
93 //                        + ax * ( ax^4 * (1/5! + ax^4 * (1/9! + ax^4*1/13!)) ))
94 //         = sign * (ax   + ax*p_odd + (ax*p_even))
95 //         = sign * (ax   + Y_lo)
96 // sinh(x) = sign * (Y_hi + Y_lo)
97 // Note that ax = |x|
99 // 2. SINH_BY_TBL   0.25 <= |x| < 32.0
100 // =============
101 // sinh(x) = sinh(B+R)
102 //         = sinh(B)cosh(R) + cosh(B)sinh(R)
103 // 
104 // ax = |x| = M*log2/64 + R
105 // B = M*log2/64
106 // M = 64*N + j 
107 //   We will calculate M and get N as (M-j)/64
108 //   The division is a shift.
109 // exp(B)  = exp(N*log2 + j*log2/64)
110 //         = 2^N * 2^(j*log2/64)
111 // sinh(B) = 1/2(e^B -e^-B)
112 //         = 1/2(2^N * 2^(j*log2/64) - 2^-N * 2^(-j*log2/64)) 
113 // sinh(B) = (2^(N-1) * 2^(j*log2/64) - 2^(-N-1) * 2^(-j*log2/64)) 
114 // cosh(B) = (2^(N-1) * 2^(j*log2/64) + 2^(-N-1) * 2^(-j*log2/64)) 
115 // 2^(j*log2/64) is stored as Tjhi + Tjlo , j= -32,....,32
116 // Tjhi is double-extended (80-bit) and Tjlo is single(32-bit)
118 // R = ax - M*log2/64
119 // R = ax - M*log2_by_64_hi - M*log2_by_64_lo
120 // exp(R) = 1 + R +R^2(1/2! + R(1/3! + R(1/4! + ... + R(1/n!)...)
121 //        = 1 + p_odd + p_even
122 //        where the p_even uses the A coefficients and the p_even uses 
123 //        the B coefficients
125 // So sinh(R) = 1 + p_odd + p_even -(1 -p_odd -p_even)/2 = p_odd
126 //    cosh(R) = 1 + p_even
127 //    sinh(B) = S_hi + S_lo
128 //    cosh(B) = C_hi
129 // sinh(x) = sinh(B)cosh(R) + cosh(B)sinh(R)
131 // 3. SINH_BY_EXP   32.0 <= |x| < 11357.21655  ( 400c b174 ddc0 31ae c0ea )
132 // ==============
133 // Can approximate result by exp(x)/2 in this region.
134 // Y_hi = Tjhi
135 // Y_lo = Tjhi * (p_odd + p_even) + Tjlo
136 // sinh(x) = Y_hi + Y_lo
138 // 4. SINH_HUGE     |x| >= 11357.21655  ( 400c b174 ddc0 31ae c0ea )
139 // ============
140 // Set error tag and call error support
143 // Assembly macros
144 //==============================================================
145 r_ad5                 = r14
146 r_rshf_2to57          = r15
147 r_exp_denorm          = r15
148 r_ad_mJ_lo            = r15
149 r_ad_J_lo             = r16
150 r_2Nm1                = r17
151 r_2mNm1               = r18
152 r_exp_x               = r18
153 r_ad_J_hi             = r19
154 r_ad2o                = r19
155 r_ad_mJ_hi            = r20
156 r_mj                  = r21
157 r_ad2e                = r22
158 r_ad3                 = r23
159 r_ad1                 = r24
160 r_Mmj                 = r24
161 r_rshf                = r25
162 r_M                   = r25
163 r_N                   = r25
164 r_jshf                = r26
165 r_exp_2tom57          = r26
166 r_j                   = r26
167 r_exp_mask            = r27
168 r_signexp_x           = r28
169 r_signexp_sgnx_0_5    = r28
170 r_exp_0_25            = r29
171 r_sig_inv_ln2         = r30
172 r_exp_32              = r30
173 r_exp_huge            = r30
174 r_ad4                 = r31
176 GR_SAVE_PFS           = r34
177 GR_SAVE_B0            = r35
178 GR_SAVE_GP            = r36
180 GR_Parameter_X        = r37
181 GR_Parameter_Y        = r38
182 GR_Parameter_RESULT   = r39
183 GR_Parameter_TAG      = r40
186 f_ABS_X               = f9 
187 f_X2                  = f10
188 f_X4                  = f11
189 f_tmp                 = f14
190 f_RSHF                = f15
192 f_Inv_log2by64        = f32
193 f_log2by64_lo         = f33
194 f_log2by64_hi         = f34
195 f_A1                  = f35
197 f_A2                  = f36
198 f_A3                  = f37
199 f_Rcub                = f38
200 f_M_temp              = f39
201 f_R_temp              = f40
203 f_Rsq                 = f41
204 f_R                   = f42
205 f_M                   = f43
206 f_B1                  = f44
207 f_B2                  = f45
209 f_B3                  = f46
210 f_peven_temp1         = f47
211 f_peven_temp2         = f48
212 f_peven               = f49
213 f_podd_temp1          = f50
215 f_podd_temp2          = f51
216 f_podd                = f52
217 f_poly65              = f53
218 f_poly6543            = f53
219 f_poly6to1            = f53
220 f_poly43              = f54
221 f_poly21              = f55
223 f_X3                  = f56
224 f_INV_LN2_2TO63       = f57
225 f_RSHF_2TO57          = f58
226 f_2TOM57              = f59
227 f_smlst_oflow_input   = f60
229 f_pre_result          = f61
230 f_huge                = f62
231 f_spos                = f63
232 f_sneg                = f64
233 f_Tjhi                = f65
235 f_Tjlo                = f66
236 f_Tmjhi               = f67
237 f_Tmjlo               = f68
238 f_S_hi                = f69
239 f_SC_hi_temp          = f70
241 f_S_lo_temp1          = f71 
242 f_S_lo_temp2          = f72 
243 f_S_lo_temp3          = f73 
244 f_S_lo_temp4          = f73 
245 f_S_lo                = f74
246 f_C_hi                = f75
248 f_Y_hi                = f77 
249 f_Y_lo_temp           = f78 
250 f_Y_lo                = f79 
251 f_NORM_X              = f80
253 f_P1                  = f81
254 f_P2                  = f82
255 f_P3                  = f83
256 f_P4                  = f84
257 f_P5                  = f85
259 f_P6                  = f86
260 f_Tjhi_spos           = f87
261 f_Tjlo_spos           = f88
262 f_huge                = f89
263 f_signed_hi_lo        = f90
266 // Data tables
267 //==============================================================
269 // DO NOT CHANGE ORDER OF THESE TABLES
270 RODATA
272 .align 16
273 LOCAL_OBJECT_START(sinh_arg_reduction)
274 //   data8 0xB8AA3B295C17F0BC, 0x00004005  // 64/log2 -- signif loaded with setf
275    data8 0xB17217F7D1000000, 0x00003FF8  // log2/64 high part
276    data8 0xCF79ABC9E3B39804, 0x00003FD0  // log2/64 low part
277    data8 0xb174ddc031aec0ea, 0x0000400c  // Smallest x to overflow (11357.21655)
278 LOCAL_OBJECT_END(sinh_arg_reduction)
280 LOCAL_OBJECT_START(sinh_p_table)
281    data8 0xB08AF9AE78C1239F, 0x00003FDE  // P6
282    data8 0xB8EF1D28926D8891, 0x00003FEC  // P4
283    data8 0x8888888888888412, 0x00003FF8  // P2
284    data8 0xD732377688025BE9, 0x00003FE5  // P5
285    data8 0xD00D00D00D4D39F2, 0x00003FF2  // P3
286    data8 0xAAAAAAAAAAAAAAAB, 0x00003FFC  // P1
287 LOCAL_OBJECT_END(sinh_p_table)
289 LOCAL_OBJECT_START(sinh_ab_table)
290    data8 0xAAAAAAAAAAAAAAAC, 0x00003FFC  // A1
291    data8 0x88888888884ECDD5, 0x00003FF8  // A2
292    data8 0xD00D0C6DCC26A86B, 0x00003FF2  // A3
293    data8 0x8000000000000002, 0x00003FFE  // B1
294    data8 0xAAAAAAAAAA402C77, 0x00003FFA  // B2
295    data8 0xB60B6CC96BDB144D, 0x00003FF5  // B3
296 LOCAL_OBJECT_END(sinh_ab_table)
298 LOCAL_OBJECT_START(sinh_j_hi_table)
299    data8 0xB504F333F9DE6484, 0x00003FFE
300    data8 0xB6FD91E328D17791, 0x00003FFE
301    data8 0xB8FBAF4762FB9EE9, 0x00003FFE
302    data8 0xBAFF5AB2133E45FB, 0x00003FFE
303    data8 0xBD08A39F580C36BF, 0x00003FFE
304    data8 0xBF1799B67A731083, 0x00003FFE
305    data8 0xC12C4CCA66709456, 0x00003FFE
306    data8 0xC346CCDA24976407, 0x00003FFE
307    data8 0xC5672A115506DADD, 0x00003FFE
308    data8 0xC78D74C8ABB9B15D, 0x00003FFE
309    data8 0xC9B9BD866E2F27A3, 0x00003FFE
310    data8 0xCBEC14FEF2727C5D, 0x00003FFE
311    data8 0xCE248C151F8480E4, 0x00003FFE
312    data8 0xD06333DAEF2B2595, 0x00003FFE
313    data8 0xD2A81D91F12AE45A, 0x00003FFE
314    data8 0xD4F35AABCFEDFA1F, 0x00003FFE
315    data8 0xD744FCCAD69D6AF4, 0x00003FFE
316    data8 0xD99D15C278AFD7B6, 0x00003FFE
317    data8 0xDBFBB797DAF23755, 0x00003FFE
318    data8 0xDE60F4825E0E9124, 0x00003FFE
319    data8 0xE0CCDEEC2A94E111, 0x00003FFE
320    data8 0xE33F8972BE8A5A51, 0x00003FFE
321    data8 0xE5B906E77C8348A8, 0x00003FFE
322    data8 0xE8396A503C4BDC68, 0x00003FFE
323    data8 0xEAC0C6E7DD24392F, 0x00003FFE
324    data8 0xED4F301ED9942B84, 0x00003FFE
325    data8 0xEFE4B99BDCDAF5CB, 0x00003FFE
326    data8 0xF281773C59FFB13A, 0x00003FFE
327    data8 0xF5257D152486CC2C, 0x00003FFE
328    data8 0xF7D0DF730AD13BB9, 0x00003FFE
329    data8 0xFA83B2DB722A033A, 0x00003FFE
330    data8 0xFD3E0C0CF486C175, 0x00003FFE
331    data8 0x8000000000000000, 0x00003FFF // Center of table
332    data8 0x8164D1F3BC030773, 0x00003FFF
333    data8 0x82CD8698AC2BA1D7, 0x00003FFF
334    data8 0x843A28C3ACDE4046, 0x00003FFF
335    data8 0x85AAC367CC487B15, 0x00003FFF
336    data8 0x871F61969E8D1010, 0x00003FFF
337    data8 0x88980E8092DA8527, 0x00003FFF
338    data8 0x8A14D575496EFD9A, 0x00003FFF
339    data8 0x8B95C1E3EA8BD6E7, 0x00003FFF
340    data8 0x8D1ADF5B7E5BA9E6, 0x00003FFF
341    data8 0x8EA4398B45CD53C0, 0x00003FFF
342    data8 0x9031DC431466B1DC, 0x00003FFF
343    data8 0x91C3D373AB11C336, 0x00003FFF
344    data8 0x935A2B2F13E6E92C, 0x00003FFF
345    data8 0x94F4EFA8FEF70961, 0x00003FFF
346    data8 0x96942D3720185A00, 0x00003FFF
347    data8 0x9837F0518DB8A96F, 0x00003FFF
348    data8 0x99E0459320B7FA65, 0x00003FFF
349    data8 0x9B8D39B9D54E5539, 0x00003FFF
350    data8 0x9D3ED9A72CFFB751, 0x00003FFF
351    data8 0x9EF5326091A111AE, 0x00003FFF
352    data8 0xA0B0510FB9714FC2, 0x00003FFF
353    data8 0xA27043030C496819, 0x00003FFF
354    data8 0xA43515AE09E6809E, 0x00003FFF
355    data8 0xA5FED6A9B15138EA, 0x00003FFF
356    data8 0xA7CD93B4E965356A, 0x00003FFF
357    data8 0xA9A15AB4EA7C0EF8, 0x00003FFF
358    data8 0xAB7A39B5A93ED337, 0x00003FFF
359    data8 0xAD583EEA42A14AC6, 0x00003FFF
360    data8 0xAF3B78AD690A4375, 0x00003FFF
361    data8 0xB123F581D2AC2590, 0x00003FFF
362    data8 0xB311C412A9112489, 0x00003FFF
363    data8 0xB504F333F9DE6484, 0x00003FFF
364 LOCAL_OBJECT_END(sinh_j_hi_table)
366 LOCAL_OBJECT_START(sinh_j_lo_table)
367    data4 0x1EB2FB13
368    data4 0x1CE2CBE2
369    data4 0x1DDC3CBC
370    data4 0x1EE9AA34
371    data4 0x9EAEFDC1
372    data4 0x9DBF517B
373    data4 0x1EF88AFB
374    data4 0x1E03B216
375    data4 0x1E78AB43
376    data4 0x9E7B1747
377    data4 0x9EFE3C0E
378    data4 0x9D36F837
379    data4 0x9DEE53E4
380    data4 0x9E24AE8E
381    data4 0x1D912473
382    data4 0x1EB243BE
383    data4 0x1E669A2F
384    data4 0x9BBC610A
385    data4 0x1E761035
386    data4 0x9E0BE175
387    data4 0x1CCB12A1
388    data4 0x1D1BFE90
389    data4 0x1DF2F47A
390    data4 0x1EF22F22
391    data4 0x9E3F4A29
392    data4 0x1EC01A5B
393    data4 0x1E8CAC3A
394    data4 0x9DBB3FAB
395    data4 0x1EF73A19
396    data4 0x9BB795B5
397    data4 0x1EF84B76
398    data4 0x9EF5818B
399    data4 0x00000000 // Center of table
400    data4 0x1F77CACA
401    data4 0x1EF8A91D
402    data4 0x1E57C976
403    data4 0x9EE8DA92
404    data4 0x1EE85C9F
405    data4 0x1F3BF1AF
406    data4 0x1D80CA1E
407    data4 0x9D0373AF
408    data4 0x9F167097
409    data4 0x1EB70051
410    data4 0x1F6EB029
411    data4 0x1DFD6D8E
412    data4 0x9EB319B0
413    data4 0x1EBA2BEB
414    data4 0x1F11D537
415    data4 0x1F0D5A46
416    data4 0x9E5E7BCA
417    data4 0x9F3AAFD1
418    data4 0x9E86DACC
419    data4 0x9F3EDDC2
420    data4 0x1E496E3D
421    data4 0x9F490BF6
422    data4 0x1DD1DB48
423    data4 0x1E65EBFB
424    data4 0x9F427496
425    data4 0x1F283C4A
426    data4 0x1F4B0047
427    data4 0x1F130152
428    data4 0x9E8367C0
429    data4 0x9F705F90
430    data4 0x1EFB3C53
431    data4 0x1F32FB13
432 LOCAL_OBJECT_END(sinh_j_lo_table)
435 .section .text
436 GLOBAL_IEEE754_ENTRY(sinhl)
438 { .mlx
439       getf.exp        r_signexp_x = f8   // Get signexp of x, must redo if unorm
440       movl            r_sig_inv_ln2 = 0xb8aa3b295c17f0bc // significand of 1/ln2
442 { .mlx
443       addl            r_ad1 = @ltoff(sinh_arg_reduction), gp
444       movl            r_rshf_2to57 = 0x4778000000000000 // 1.10000 2^(63+57)
448 { .mfi
449       ld8             r_ad1 = [r_ad1]
450       fmerge.s        f_ABS_X    = f0,f8
451       mov             r_exp_0_25 = 0x0fffd    // Form exponent for 0.25
453 { .mfi
454       nop.m           0
455       fnorm.s1        f_NORM_X = f8      
456       mov             r_exp_2tom57 = 0xffff-57
460 { .mfi
461       setf.d          f_RSHF_2TO57 = r_rshf_2to57 // Form const 1.100 * 2^120
462       fclass.m        p10,p0 = f8, 0x0b           // Test for denorm
463       mov             r_exp_mask = 0x1ffff 
465 { .mlx
466       setf.sig        f_INV_LN2_2TO63 = r_sig_inv_ln2 // Form 1/ln2 * 2^63
467       movl            r_rshf = 0x43e8000000000000 // 1.1000 2^63 for right shift
471 { .mfi
472       nop.m           0
473       fclass.m        p7,p0 = f8, 0x07  // Test if x=0
474       nop.i           0
476 { .mfi
477       setf.exp        f_2TOM57 = r_exp_2tom57 // Form 2^-57 for scaling
478       nop.f           0
479       add             r_ad3 = 0x90, r_ad1  // Point to ab_table
483 { .mfi
484       setf.d          f_RSHF = r_rshf     // Form right shift const 1.100 * 2^63
485       fclass.m        p6,p0 = f8, 0xe3     // Test if x nan, inf
486       add             r_ad4 = 0x2f0, r_ad1 // Point to j_hi_table midpoint
488 { .mib
489       add             r_ad2e = 0x20, r_ad1 // Point to p_table
490       nop.i           0
491 (p10) br.cond.spnt    SINH_DENORM          // Branch if x denorm
495 // Common path -- return here from SINH_DENORM if x is unnorm
496 SINH_COMMON:
497 { .mfi
498       ldfe            f_smlst_oflow_input = [r_ad2e],16
499       nop.f           0
500       add             r_ad5 = 0x580, r_ad1 // Point to j_lo_table midpoint
502 { .mib
503       ldfe            f_log2by64_hi  = [r_ad1],16       
504       and             r_exp_x = r_exp_mask, r_signexp_x
505 (p7)  br.ret.spnt     b0                  // Exit if x=0
509 // Get the A coefficients for SINH_BY_TBL
510 { .mfi
511       ldfe            f_A1 = [r_ad3],16            
512       fcmp.lt.s1      p8,p9 = f8,f0           // Test for x<0
513       cmp.lt          p7,p0 = r_exp_x, r_exp_0_25  // Test x < 0.25
515 { .mfb
516       add             r_ad2o = 0x30, r_ad2e  // Point to p_table odd coeffs
517 (p6)  fma.s0          f8 = f8,f1,f0          // Result for x nan, inf          
518 (p6)  br.ret.spnt     b0                     // Exit for x nan, inf
522 // Calculate X2 = ax*ax for SINH_BY_POLY
523 { .mfi
524       ldfe            f_log2by64_lo  = [r_ad1],16       
525       nop.f           0
526       nop.i           0
528 { .mfb
529       ldfe            f_A2 = [r_ad3],16            
530       fma.s1          f_X2 = f_NORM_X, f_NORM_X, f0
531 (p7)  br.cond.spnt    SINH_BY_POLY
535 // Here if |x| >= 0.25
536 SINH_BY_TBL: 
537 // ******************************************************
538 // STEP 1 (TBL and EXP) - Argument reduction
539 // ******************************************************
540 // Get the following constants. 
541 // Inv_log2by64
542 // log2by64_hi
543 // log2by64_lo
546 // We want 2^(N-1) and 2^(-N-1). So bias N-1 and -N-1 and
547 // put them in an exponent.
548 // f_spos = 2^(N-1) and f_sneg = 2^(-N-1)
549 // 0xffff + (N-1)  = 0xffff +N -1
550 // 0xffff - (N +1) = 0xffff -N -1
553 // Calculate M and keep it as integer and floating point.
554 // M = round-to-integer(x*Inv_log2by64)
555 // f_M = M = truncate(ax/(log2/64))
556 // Put the integer representation of M in r_M
557 //    and the floating point representation of M in f_M
559 // Get the remaining A,B coefficients
560 { .mmi
561       ldfe            f_A3 = [r_ad3],16
562       nop.m           0
563       nop.i           0
567 .pred.rel "mutex",p8,p9
568 // Use constant (1.100*2^(63-6)) to get rounded M into rightmost significand
569 // |x| * 64 * 1/ln2 * 2^(63-6) + 1.1000 * 2^(63+(63-6))
570 { .mfi
571 (p8)  mov             r_signexp_sgnx_0_5 = 0x2fffe // signexp of -0.5
572       fma.s1          f_M_temp = f_ABS_X, f_INV_LN2_2TO63, f_RSHF_2TO57
573 (p9)  mov             r_signexp_sgnx_0_5 = 0x0fffe // signexp of +0.5
577 // Test for |x| >= overflow limit
578 { .mfi
579       ldfe            f_B1 = [r_ad3],16
580       fcmp.ge.s1      p6,p0 = f_ABS_X, f_smlst_oflow_input
581       nop.i           0
585 { .mfi
586       ldfe            f_B2 = [r_ad3],16
587       nop.f           0
588       mov             r_exp_32 = 0x10004
592 // Subtract RSHF constant to get rounded M as a floating point value
593 // M_temp * 2^(63-6) - 2^63
594 { .mfb
595       ldfe            f_B3 = [r_ad3],16            
596       fms.s1          f_M = f_M_temp, f_2TOM57, f_RSHF
597 (p6)  br.cond.spnt    SINH_HUGE  // Branch if result will overflow
601 { .mfi
602       getf.sig        r_M = f_M_temp                 
603       nop.f           0
604       cmp.ge          p7,p6 = r_exp_x, r_exp_32 // Test if x >= 32
608 // Calculate j. j is the signed extension of the six lsb of M. It 
609 // has a range of -32 thru 31.
611 // Calculate R
612 // ax - M*log2by64_hi
613 // R = (ax - M*log2by64_hi) - M*log2by64_lo
615 { .mfi
616       nop.m           0
617       fnma.s1         f_R_temp = f_M, f_log2by64_hi, f_ABS_X
618       and             r_j = 0x3f, r_M
622 { .mii
623       nop.m           0
624       shl             r_jshf = r_j, 0x2 // Shift j so can sign extend it
626       sxt1            r_jshf = r_jshf
630 { .mii
631       nop.m           0
632       shr             r_j = r_jshf, 0x2    // Now j has range -32 to 31
633       nop.i           0
637 { .mmi
638       shladd          r_ad_J_hi = r_j, 4, r_ad4 // pointer to Tjhi
639       sub             r_Mmj = r_M, r_j          // M-j
640       sub             r_mj = r0, r_j            // Form -j
644 // The TBL and EXP branches are merged and predicated
645 // If TBL, p6 true, 0.25 <= |x| < 32
646 // If EXP, p7 true, 32 <= |x| < overflow_limit
648 // N = (M-j)/64
649 { .mfi
650       ldfe            f_Tjhi = [r_ad_J_hi]
651       fnma.s1         f_R = f_M, f_log2by64_lo, f_R_temp 
652       shr             r_N = r_Mmj, 0x6            // N = (M-j)/64 
654 { .mfi
655       shladd          r_ad_mJ_hi = r_mj, 4, r_ad4 // pointer to Tmjhi
656       nop.f           0
657       shladd          r_ad_mJ_lo = r_mj, 2, r_ad5 // pointer to Tmjlo
661 { .mfi
662       sub             r_2mNm1 = r_signexp_sgnx_0_5, r_N // signexp sgnx*2^(-N-1)
663       nop.f           0
664       shladd          r_ad_J_lo = r_j, 2, r_ad5   // pointer to Tjlo
666 { .mfi
667       ldfe            f_Tmjhi = [r_ad_mJ_hi]
668       nop.f           0
669       add             r_2Nm1 = r_signexp_sgnx_0_5, r_N // signexp sgnx*2^(N-1)
673 { .mmf
674       ldfs            f_Tmjlo = [r_ad_mJ_lo]
675       setf.exp        f_sneg = r_2mNm1            // Form sgnx * 2^(-N-1)
676       nop.f           0
680 { .mmf
681       ldfs            f_Tjlo  = [r_ad_J_lo]
682       setf.exp        f_spos = r_2Nm1             // Form sgnx * 2^(N-1)
683       nop.f           0
687 // ******************************************************
688 // STEP 2 (TBL and EXP)
689 // ******************************************************
690 // Calculate Rsquared and Rcubed in preparation for p_even and p_odd
692 { .mmf
693       nop.m           0
694       nop.m           0
695       fma.s1          f_Rsq  = f_R, f_R, f0
700 // Calculate p_even
701 // B_2 + Rsq *B_3
702 // B_1 + Rsq * (B_2 + Rsq *B_3)
703 // p_even = Rsq * (B_1 + Rsq * (B_2 + Rsq *B_3))
704 { .mfi
705       nop.m           0
706       fma.s1          f_peven_temp1 = f_Rsq, f_B3, f_B2
707       nop.i           0
709 // Calculate p_odd
710 // A_2 + Rsq *A_3
711 // A_1 + Rsq * (A_2 + Rsq *A_3)
712 // podd = R + Rcub * (A_1 + Rsq * (A_2 + Rsq *A_3))
713 { .mfi
714       nop.m           0
715       fma.s1          f_podd_temp1 = f_Rsq, f_A3, f_A2
716       nop.i           0
720 { .mfi
721       nop.m           0
722       fma.s1          f_Rcub = f_Rsq, f_R, f0
723       nop.i           0
727 // 
728 // If TBL, 
729 // Calculate S_hi and S_lo, and C_hi
730 // SC_hi_temp = sneg * Tmjhi
731 // S_hi = spos * Tjhi - SC_hi_temp
732 // S_hi = spos * Tjhi - (sneg * Tmjhi)
733 // C_hi = spos * Tjhi + SC_hi_temp
734 // C_hi = spos * Tjhi + (sneg * Tmjhi)
736 { .mfi
737       nop.m           0
738 (p6)  fma.s1          f_SC_hi_temp = f_sneg, f_Tmjhi, f0   
739       nop.i           0
743 // If TBL, 
744 // S_lo_temp3 = sneg * Tmjlo
745 // S_lo_temp4 = spos * Tjlo - S_lo_temp3
746 // S_lo_temp4 = spos * Tjlo -(sneg * Tmjlo)
747 { .mfi
748       nop.m           0
749 (p6)  fma.s1          f_S_lo_temp3 =  f_sneg, f_Tmjlo, f0
750       nop.i           0
754 { .mfi
755       nop.m           0
756       fma.s1          f_peven_temp2 = f_Rsq, f_peven_temp1, f_B1
757       nop.i           0
759 { .mfi
760       nop.m           0
761       fma.s1          f_podd_temp2 = f_Rsq, f_podd_temp1, f_A1
762       nop.i           0
766 // If EXP, 
767 // Compute sgnx * 2^(N-1) * Tjhi and sgnx * 2^(N-1) * Tjlo
768 { .mfi
769       nop.m           0
770 (p7)  fma.s1          f_Tjhi_spos = f_Tjhi, f_spos, f0
771       nop.i           0
773 { .mfi
774       nop.m           0
775 (p7)  fma.s1          f_Tjlo_spos = f_Tjlo, f_spos, f0
776       nop.i           0
780 { .mfi
781       nop.m           0
782 (p6)  fms.s1          f_S_hi = f_spos, f_Tjhi, f_SC_hi_temp
783       nop.i           0
787 { .mfi
788       nop.m           0
789 (p6)  fma.s1          f_C_hi = f_spos, f_Tjhi, f_SC_hi_temp
790       nop.i           0
792 { .mfi
793       nop.m           0
794 (p6)  fms.s1          f_S_lo_temp4 = f_spos, f_Tjlo, f_S_lo_temp3
795       nop.i           0
799 { .mfi
800       nop.m           0
801       fma.s1          f_peven = f_Rsq, f_peven_temp2, f0
802       nop.i           0
804 { .mfi
805       nop.m           0
806       fma.s1          f_podd = f_podd_temp2, f_Rcub, f_R
807       nop.i           0
811 // If TBL,
812 // S_lo_temp1 =  spos * Tjhi - S_hi
813 // S_lo_temp2 = -sneg * Tmjlo + S_lo_temp1
814 // S_lo_temp2 = -sneg * Tmjlo + (spos * Tjhi - S_hi)
816 { .mfi
817       nop.m           0
818 (p6)  fms.s1          f_S_lo_temp1 =  f_spos, f_Tjhi,  f_S_hi
819       nop.i           0
823 { .mfi
824       nop.m           0
825 (p6)  fnma.s1         f_S_lo_temp2 = f_sneg, f_Tmjhi, f_S_lo_temp1       
826       nop.i           0
830 // If EXP,
831 // Y_hi = sgnx * 2^(N-1) * Tjhi
832 // Y_lo = sgnx * 2^(N-1) * Tjhi * (p_odd + p_even) + sgnx * 2^(N-1) * Tjlo
833 { .mfi
834       nop.m           0
835 (p7)  fma.s1          f_Y_lo_temp =  f_peven, f1, f_podd
836       nop.i           0
840 // If TBL,
841 // S_lo = S_lo_temp4 + S_lo_temp2
842 { .mfi
843       nop.m           0
844 (p6)  fma.s1          f_S_lo = f_S_lo_temp4, f1, f_S_lo_temp2
845       nop.i           0
849 // If TBL,
850 // Y_hi = S_hi 
851 // Y_lo = C_hi*p_odd + (S_hi*p_even + S_lo)
852 { .mfi
853       nop.m           0
854 (p6)  fma.s1          f_Y_lo_temp = f_S_hi, f_peven, f_S_lo
855       nop.i           0
859 { .mfi
860       nop.m           0
861 (p7)  fma.s1          f_Y_lo = f_Tjhi_spos, f_Y_lo_temp, f_Tjlo_spos
862       nop.i           0
866 // Dummy multiply to generate inexact
867 { .mfi
868       nop.m           0
869       fmpy.s0         f_tmp = f_B2, f_B2
870       nop.i           0
872 { .mfi
873       nop.m           0
874 (p6)  fma.s1          f_Y_lo = f_C_hi, f_podd, f_Y_lo_temp
875       nop.i           0
879 // f8 = answer = Y_hi + Y_lo
880 { .mfi
881       nop.m           0
882 (p7)  fma.s0          f8 = f_Y_lo,  f1, f_Tjhi_spos
883       nop.i           0
887 // f8 = answer = Y_hi + Y_lo
888 { .mfb
889       nop.m           0
890 (p6)  fma.s0          f8 = f_Y_lo, f1, f_S_hi
891       br.ret.sptk     b0      // Exit for SINH_BY_TBL and SINH_BY_EXP
896 // Here if 0 < |x| < 0.25
897 SINH_BY_POLY: 
898 { .mmf
899       ldfe            f_P6 = [r_ad2e],16
900       ldfe            f_P5 = [r_ad2o],16
901       nop.f           0
905 { .mmi
906       ldfe            f_P4 = [r_ad2e],16
907       ldfe            f_P3 = [r_ad2o],16
908       nop.i           0
912 { .mmi
913       ldfe            f_P2 = [r_ad2e],16
914       ldfe            f_P1 = [r_ad2o],16                 
915       nop.i           0
919 { .mfi
920       nop.m           0
921       fma.s1          f_X3 = f_NORM_X, f_X2, f0
922       nop.i           0
924 { .mfi
925       nop.m           0
926       fma.s1          f_X4 = f_X2, f_X2, f0
927       nop.i           0
931 { .mfi
932       nop.m           0
933       fma.s1          f_poly65 = f_X2, f_P6, f_P5
934       nop.i           0
936 { .mfi
937       nop.m           0
938       fma.s1          f_poly43 = f_X2, f_P4, f_P3
939       nop.i           0
943 { .mfi
944       nop.m           0
945       fma.s1          f_poly21 = f_X2, f_P2, f_P1
946       nop.i           0
950 { .mfi
951       nop.m           0
952       fma.s1          f_poly6543 = f_X4, f_poly65, f_poly43
953       nop.i           0
957 { .mfi
958       nop.m           0
959       fma.s1          f_poly6to1 = f_X4, f_poly6543, f_poly21
960       nop.i           0
964 // Dummy multiply to generate inexact
965 { .mfi
966       nop.m           0
967       fmpy.s0         f_tmp = f_P6, f_P6
968       nop.i           0
970 { .mfb
971       nop.m           0
972       fma.s0          f8 = f_poly6to1, f_X3, f_NORM_X
973       br.ret.sptk     b0                // Exit SINH_BY_POLY
978 // Here if x denorm or unorm
979 SINH_DENORM:
980 // Determine if x really a denorm and not a unorm
981 { .mmf
982       getf.exp        r_signexp_x = f_NORM_X
983       mov             r_exp_denorm = 0x0c001   // Real denorms have exp < this
984       fmerge.s        f_ABS_X = f0, f_NORM_X
988 { .mfi
989       nop.m           0
990       fcmp.eq.s0      p10,p0 = f8, f0  // Set denorm flag
991       nop.i           0
995 // Set p8 if really a denorm
996 { .mmi
997       and             r_exp_x = r_exp_mask, r_signexp_x
999       cmp.lt          p8,p9 = r_exp_x, r_exp_denorm
1000       nop.i           0
1004 // Identify denormal operands.
1005 { .mfb
1006       nop.m           0
1007 (p8)  fcmp.ge.unc.s1  p6,p7 = f8, f0   // Test sign of denorm
1008 (p9)  br.cond.sptk    SINH_COMMON    // Return to main path if x unorm
1012 { .mfi
1013       nop.m           0
1014 (p6)  fma.s0          f8 =  f8,f8,f8  // If x +denorm, result=x+x^2
1015       nop.i           0 
1017 { .mfb
1018       nop.m           0
1019 (p7)  fnma.s0         f8 =  f8,f8,f8  // If x -denorm, result=x-x^2
1020       br.ret.sptk     b0            // Exit if x denorm
1025 // Here if |x| >= overflow limit
1026 SINH_HUGE: 
1027 // for SINH_HUGE, put 24000 in exponent; take sign from input
1028 { .mmi
1029       mov             r_exp_huge = 0x15dbf
1031       setf.exp        f_huge  = r_exp_huge
1032       nop.i           0
1036 .pred.rel "mutex",p8,p9
1037 { .mfi
1038       alloc           r32 = ar.pfs,0,5,4,0                  
1039 (p8)  fnma.s1         f_signed_hi_lo = f_huge, f1, f1
1040       nop.i           0
1042 { .mfi
1043       nop.m           0
1044 (p9)  fma.s1          f_signed_hi_lo = f_huge, f1, f1
1045       nop.i           0
1049 { .mfi
1050       nop.m           0
1051       fma.s0          f_pre_result = f_signed_hi_lo, f_huge, f0
1052       mov             GR_Parameter_TAG = 126
1056 GLOBAL_IEEE754_END(sinhl)
1059 LOCAL_LIBM_ENTRY(__libm_error_region)
1060 .prologue
1062 { .mfi
1063         add   GR_Parameter_Y=-32,sp              // Parameter 2 value
1064         nop.f 0
1065 .save   ar.pfs,GR_SAVE_PFS
1066         mov  GR_SAVE_PFS=ar.pfs                  // Save ar.pfs
1068 { .mfi
1069 .fframe 64
1070         add sp=-64,sp                            // Create new stack
1071         nop.f 0
1072         mov GR_SAVE_GP=gp                        // Save gp
1075 { .mmi
1076         stfe [GR_Parameter_Y] = f0,16            // STORE Parameter 2 on stack
1077         add GR_Parameter_X = 16,sp               // Parameter 1 address
1078 .save   b0, GR_SAVE_B0
1079         mov GR_SAVE_B0=b0                        // Save b0
1082 .body
1083 { .mib
1084         stfe [GR_Parameter_X] = f8               // STORE Parameter 1 on stack
1085         add   GR_Parameter_RESULT = 0,GR_Parameter_Y   // Parameter 3 address
1086         nop.b 0                            
1088 { .mib
1089         stfe [GR_Parameter_Y] = f_pre_result     // STORE Parameter 3 on stack
1090         add   GR_Parameter_Y = -16,GR_Parameter_Y
1091         br.call.sptk b0=__libm_error_support#    // Call error handling function
1094 { .mmi
1095         add   GR_Parameter_RESULT = 48,sp
1096         nop.m 0
1097         nop.i 0
1100 { .mmi
1101         ldfe  f8 = [GR_Parameter_RESULT]         // Get return result off stack
1102 .restore sp
1103         add   sp = 64,sp                         // Restore stack pointer
1104         mov   b0 = GR_SAVE_B0                    // Restore return address
1107 { .mib
1108         mov   gp = GR_SAVE_GP                    // Restore gp
1109         mov   ar.pfs = GR_SAVE_PFS               // Restore ar.pfs
1110         br.ret.sptk     b0                       // Return
1113 LOCAL_LIBM_END(__libm_error_region)
1116 .type   __libm_error_support#,@function
1117 .global __libm_error_support#