nptl: Add more coverage in tst-cancel4
[glibc.git] / sysdeps / ia64 / fpu / s_logb.S
blob7ee898712b024049745154ecb68a31bfd2481046
1 .file "logb.s"
4 // Copyright (c) 2000 - 2003, 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.
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 // 02/16/00 Modified to conform to C9X
44 // 03/16/00 Improved speed
45 // 04/04/00 Unwind support added
46 // 05/30/00 Fixed bug when x double-extended denormal
47 // 08/15/00 Bundle added after call to __libm_error_support to properly
48 //          set [the previously overwritten] GR_Parameter_RESULT.
49 // 05/20/02 Cleaned up namespace and sf0 syntax
50 // 01/20/03 Improved performance
52 // API
53 //==============================================================
54 // double logb( double x );
56 // Overview of operation
57 //==============================================================
58 // The logb function extracts the exponent of x as an integer in
59 // floating-point format.
60 // logb computes log2 of x as a double
62 // logb is similar to ilogb but differs in the  following ways:
63 //         +-inf
64 //            ilogb: returns INT_MAX
65 //             logb: returns +inf
66 //         Nan  returns FP_LOGBNAN (which is either INT_MAX or INT_MIN)
67 //            ilogb: returns INT_MAX (7fffffff)
68 //             logb: returns QNAN (quietized SNAN)
69 //         0    returns FP_ILOGB0 (which is either INT_MIN or -INT_MAX)
70 //            ilogb: returns -INT_MAX (80000001)
71 //             logb: returns -inf, raises the divide-by-zero exception,
72 //                   and calls libm_error_support to set domain error
74 // Registers used
75 //==============================================================
76 // general registers used:
77 // r26 -> r38
78 // r35 -> r38 used as parameters to error path
80 // predicate registers used:
81 // p6, p7, p8
82 // floating-point registers used:
83 // f9, f10, f11
84 // f8, input
86 rExpBias            = r26
87 rExpMask            = r27
88 rSignexp_x          = r28
89 rExp_x              = r29
90 rTrueExp_x          = r30
91 rExp_2to64          = r31
93 GR_SAVE_PFS         = r32
94 GR_SAVE_B0          = r33
95 GR_SAVE_GP          = r34
97 GR_Parameter_X      = r35
98 GR_Parameter_Y      = r36
99 GR_Parameter_RESULT = r37
100 GR_Parameter_TAG    = r38
102 fExp_in_signif      = f9
103 fNorm_x             = f10
104 fFloat_Exp          = f10
105 f2to64              = f11
107 .section .text
108 GLOBAL_LIBM_ENTRY(logb)
110 // X NORMAL
111 // TrueExp_x = exp(f8) - 0xffff
112 // sig = TrueExp_x
113 // f8 = convert_to_fp (sig))
114 { .mfi
115       getf.exp        rSignexp_x = f8
116       fclass.m        p8,p0 = f8, 0x0b   // Test for x unorm
117       mov             rExpBias = 0xffff  // Exponent bias
119 { .mfi
120       nop.m           0
121       fnorm.s1        fNorm_x = f8
122       mov             rExpMask = 0x1ffff // Exponent mask
126 // Form signexp of 2^64 in case need to scale denormal
127 { .mfb
128       mov             rExp_2to64 = 0x1003f
129       fclass.m        p6,p0 = f8, 0x1e3  // Test x natval, nan, inf
130 (p8)  br.cond.spnt    LOGB_DENORM        // Branch if x unorm
134 LOGB_COMMON:
135 // Return here from LOGB_DENORM
136 { .mfi
137       and             rExp_x = rSignexp_x, rExpMask // Get biased exponent
138       fclass.m        p7,p0 = f8, 0x07   // Test x zero
139       nop.i           0
143 // X NAN or INFINITY, return f8 * f8
144 { .mfb
145       sub             rTrueExp_x = rExp_x, rExpBias // Get true exponent
146 (p6)  fma.d.s0        f8= f8,f8,f0       // Result if x natval, nan, inf
147 (p6)  br.ret.spnt     b0                 // Exit if x natval, nan, inf
151 { .mib
152       setf.sig        fExp_in_signif = rTrueExp_x // Exponent as integer in fp
153       nop.i 999
154 (p7)  br.cond.spnt    LOGB_ZERO
158 // Result can be represented in less than 24 bits, so no precision completer
159 // is needed.
160 { .mfb
161       nop.m           0
162       fcvt.xf         f8 = fExp_in_signif
163       br.ret.sptk     b0                 // Exit main path, 0 < |x| < inf
167 LOGB_DENORM:
168 // Form 2^64 in case need to scale denormal
169 // Check to see if double-extended denormal
170 { .mfi
171       setf.exp        f2to64 = rExp_2to64
172       fclass.m        p8,p0 = fNorm_x, 0x0b
173       nop.i           0
177 { .mfi
178       nop.m           0
179       fcmp.eq.s0      p7,p0 = f8, f0           // Dummy op to set denormal flag
180       nop.i           0
184 // If double-extended denormal add 64 to exponent bias for scaling
185 // If double-extended denormal form x * 2^64 which is normal
186 { .mfi
187 (p8)  add             rExpBias = 64, rExpBias
188 (p8)  fmpy.s1         fNorm_x = fNorm_x, f2to64
189       nop.i           0
193 // Logic is the same as normal path but use normalized input
194 { .mib
195       getf.exp        rSignexp_x = fNorm_x
196       nop.i           0
197       br.cond.sptk    LOGB_COMMON              // Return to main path
201 LOGB_ZERO:
202 // Here if x zero
203 // f10  = -|f8|
204 // f9  = 1.0/f10 = -1.0/|f8| = -inf
206 { .mmf
207       alloc           r32=ar.pfs,1,2,4,0
208       mov             GR_Parameter_TAG = 151  // Error code
209       fmerge.ns       f10 = f0,f8
213 { .mfb
214       nop.m           0
215       frcpa.s0        f9,p6 = f1,f10          // Produce -inf, Z flag
216       br.cond.sptk    __libm_error_region     // Call error support
220 GLOBAL_LIBM_END(logb)
223 LOCAL_LIBM_ENTRY(__libm_error_region)
224 .prologue
226 { .mfi
227         add   GR_Parameter_Y=-32,sp           // Parameter 2 value
228         nop.f 0
229 .save   ar.pfs,GR_SAVE_PFS
230         mov  GR_SAVE_PFS=ar.pfs               // Save ar.pfs
232 { .mfi
233 .fframe 64
234         add sp=-64,sp                         // Create new stack
235         nop.f 0
236         mov GR_SAVE_GP=gp                     // Save gp
239 { .mmi
240         stfd [GR_Parameter_Y] = f0,16         // STORE Parameter 2 on stack
241         add GR_Parameter_X    = 16,sp         // Parameter 1 address
242 .save   b0, GR_SAVE_B0
243         mov GR_SAVE_B0=b0                     // Save b0
246 .body
247 { .mib
248         stfd [GR_Parameter_X] = f8            // STORE Parameter 1 on stack
249         add   GR_Parameter_RESULT = 0,GR_Parameter_Y    // Parameter 3 address
250         nop.b 0
252 { .mib
253         stfd [GR_Parameter_Y] = f9            // Store Parameter 3 on stack
254         add   GR_Parameter_Y = -16,GR_Parameter_Y
255         br.call.sptk b0=__libm_error_support# // Call error handling function
258 { .mmi
259         add   GR_Parameter_RESULT = 48,sp
260         nop.m 0
261         nop.i 0
264 { .mmi
265         ldfd  f8 = [GR_Parameter_RESULT]       // Get return result off stack
266 .restore sp
267         add   sp = 64,sp                       // Restore stack pointer
268         mov   b0 = GR_SAVE_B0                  // Restore return address
271 { .mib
272         mov   gp = GR_SAVE_GP                  // Restore gp
273         mov   ar.pfs = GR_SAVE_PFS             // Restore ar.pfs
274         br.ret.sptk   b0
277 LOCAL_LIBM_END(__libm_error_region)
280 .type   __libm_error_support#,@function
281 .global __libm_error_support#