Blame sysdeps/ia64/fpu/s_expm1l.S

Packit Service 82fcde
.file "expl_m1.s"
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
// Copyright (c) 2000 - 2003, Intel Corporation
Packit Service 82fcde
// All rights reserved.
Packit Service 82fcde
//
Packit Service 82fcde
// Contributed 2000 by the Intel Numerics Group, Intel Corporation
Packit Service 82fcde
//
Packit Service 82fcde
// Redistribution and use in source and binary forms, with or without
Packit Service 82fcde
// modification, are permitted provided that the following conditions are
Packit Service 82fcde
// met:
Packit Service 82fcde
//
Packit Service 82fcde
// * Redistributions of source code must retain the above copyright
Packit Service 82fcde
// notice, this list of conditions and the following disclaimer.
Packit Service 82fcde
//
Packit Service 82fcde
// * Redistributions in binary form must reproduce the above copyright
Packit Service 82fcde
// notice, this list of conditions and the following disclaimer in the
Packit Service 82fcde
// documentation and/or other materials provided with the distribution.
Packit Service 82fcde
//
Packit Service 82fcde
// * The name of Intel Corporation may not be used to endorse or promote
Packit Service 82fcde
// products derived from this software without specific prior written
Packit Service 82fcde
// permission.
Packit Service 82fcde
Packit Service 82fcde
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
Packit Service 82fcde
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
Packit Service 82fcde
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
Packit Service 82fcde
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
Packit Service 82fcde
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
Packit Service 82fcde
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
Packit Service 82fcde
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
Packit Service 82fcde
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
Packit Service 82fcde
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY OR TORT (INCLUDING
Packit Service 82fcde
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
Packit Service 82fcde
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Packit Service 82fcde
//
Packit Service 82fcde
// Intel Corporation is the author of this code, and requests that all
Packit Service 82fcde
// problem reports or change requests be submitted to it directly at
Packit Service 82fcde
// http://www.intel.com/software/products/opensource/libraries/num.htm.
Packit Service 82fcde
//
Packit Service 82fcde
// History
Packit Service 82fcde
//==============================================================
Packit Service 82fcde
// 02/02/00 Initial Version
Packit Service 82fcde
// 04/04/00 Unwind support added
Packit Service 82fcde
// 08/15/00 Bundle added after call to __libm_error_support to properly
Packit Service 82fcde
//          set [the previously overwritten] GR_Parameter_RESULT.
Packit Service 82fcde
// 07/07/01 Improved speed of all paths
Packit Service 82fcde
// 05/20/02 Cleaned up namespace and sf0 syntax
Packit Service 82fcde
// 02/10/03 Reordered header: .section, .global, .proc, .align;
Packit Service 82fcde
//          used data8 for long double table values
Packit Service 82fcde
// 03/11/03 Improved accuracy and performance, corrected missing inexact flags
Packit Service 82fcde
// 04/17/03 Eliminated misplaced and unused data label
Packit Service 82fcde
// 12/15/03 Eliminated call to error support on expm1l underflow
Packit Service 82fcde
//
Packit Service 82fcde
//*********************************************************************
Packit Service 82fcde
//
Packit Service 82fcde
// Function:   Combined expl(x) and expm1l(x), where
Packit Service 82fcde
//                        x
Packit Service 82fcde
//             expl(x) = e , for double-extended precision x values
Packit Service 82fcde
//                          x
Packit Service 82fcde
//             expm1l(x) = e  - 1  for double-extended precision x values
Packit Service 82fcde
//
Packit Service 82fcde
//*********************************************************************
Packit Service 82fcde
//
Packit Service 82fcde
// Resources Used:
Packit Service 82fcde
//
Packit Service 82fcde
//    Floating-Point Registers: f8  (Input and Return Value)
Packit Service 82fcde
//                              f9-f15,f32-f77
Packit Service 82fcde
//
Packit Service 82fcde
//    General Purpose Registers:
Packit Service 82fcde
//      r14-r38
Packit Service 82fcde
//      r35-r38 (Used to pass arguments to error handling routine)
Packit Service 82fcde
//
Packit Service 82fcde
//    Predicate Registers:      p6-p15
Packit Service 82fcde
//
Packit Service 82fcde
//*********************************************************************
Packit Service 82fcde
//
Packit Service 82fcde
// IEEE Special Conditions:
Packit Service 82fcde
//
Packit Service 82fcde
//    Denormal  fault raised on denormal inputs
Packit Service 82fcde
//    Overflow exceptions raised when appropriate for exp and expm1
Packit Service 82fcde
//    Underflow exceptions raised when appropriate for exp and expm1
Packit Service 82fcde
//    (Error Handling Routine called for overflow and Underflow)
Packit Service 82fcde
//    Inexact raised when appropriate by algorithm
Packit Service 82fcde
//
Packit Service 82fcde
//    exp(inf) = inf
Packit Service 82fcde
//    exp(-inf) = +0
Packit Service 82fcde
//    exp(SNaN) = QNaN
Packit Service 82fcde
//    exp(QNaN) = QNaN
Packit Service 82fcde
//    exp(0) = 1
Packit Service 82fcde
//    exp(EM_special Values) = QNaN
Packit Service 82fcde
//    exp(inf) = inf
Packit Service 82fcde
//    expm1(-inf) = -1
Packit Service 82fcde
//    expm1(SNaN) = QNaN
Packit Service 82fcde
//    expm1(QNaN) = QNaN
Packit Service 82fcde
//    expm1(0) = 0
Packit Service 82fcde
//    expm1(EM_special Values) = QNaN
Packit Service 82fcde
//
Packit Service 82fcde
//*********************************************************************
Packit Service 82fcde
//
Packit Service 82fcde
// Implementation and Algorithm Notes:
Packit Service 82fcde
//
Packit Service 82fcde
//  ker_exp_64( in_FR  : X,
Packit Service 82fcde
//            out_FR : Y_hi,
Packit Service 82fcde
//            out_FR : Y_lo,
Packit Service 82fcde
//            out_FR : scale,
Packit Service 82fcde
//            out_PR : Safe )
Packit Service 82fcde
//
Packit Service 82fcde
// On input, X is in register format
Packit Service 82fcde
// p6 for exp,
Packit Service 82fcde
// p7 for expm1,
Packit Service 82fcde
//
Packit Service 82fcde
// On output,
Packit Service 82fcde
//
Packit Service 82fcde
//   scale*(Y_hi + Y_lo)  approximates  exp(X)       if exp
Packit Service 82fcde
//   scale*(Y_hi + Y_lo)  approximates  exp(X)-1     if expm1
Packit Service 82fcde
//
Packit Service 82fcde
// The accuracy is sufficient for a highly accurate 64 sig.
Packit Service 82fcde
// bit implementation.  Safe is set if there is no danger of
Packit Service 82fcde
// overflow/underflow when the result is composed from scale,
Packit Service 82fcde
// Y_hi and Y_lo. Thus, we can have a fast return if Safe is set.
Packit Service 82fcde
// Otherwise, one must prepare to handle the possible exception
Packit Service 82fcde
// appropriately.  Note that SAFE not set (false) does not mean
Packit Service 82fcde
// that overflow/underflow will occur; only the setting of SAFE
Packit Service 82fcde
// guarantees the opposite.
Packit Service 82fcde
//
Packit Service 82fcde
// **** High Level Overview ****
Packit Service 82fcde
//
Packit Service 82fcde
// The method consists of three cases.
Packit Service 82fcde
//
Packit Service 82fcde
// If           |X| < Tiny	use case exp_tiny;
Packit Service 82fcde
// else if	|X| < 2^(-m)	use case exp_small; m=12 for exp, m=7 for expm1
Packit Service 82fcde
// else		use case exp_regular;
Packit Service 82fcde
//
Packit Service 82fcde
// Case exp_tiny:
Packit Service 82fcde
//
Packit Service 82fcde
//   1 + X     can be used to approximate exp(X)
Packit Service 82fcde
//   X + X^2/2 can be used to approximate exp(X) - 1
Packit Service 82fcde
//
Packit Service 82fcde
// Case exp_small:
Packit Service 82fcde
//
Packit Service 82fcde
//   Here, exp(X) and exp(X) - 1 can all be
Packit Service 82fcde
//   approximated by a relatively simple polynomial.
Packit Service 82fcde
//
Packit Service 82fcde
//   This polynomial resembles the truncated Taylor series
Packit Service 82fcde
//
Packit Service 82fcde
//	exp(w) = 1 + w + w^2/2! + w^3/3! + ... + w^n/n!
Packit Service 82fcde
//
Packit Service 82fcde
// Case exp_regular:
Packit Service 82fcde
//
Packit Service 82fcde
//   Here we use a table lookup method. The basic idea is that in
Packit Service 82fcde
//   order to compute exp(X), we accurately decompose X into
Packit Service 82fcde
//
Packit Service 82fcde
//   X = N * log(2)/(2^12)  + r,	|r| <= log(2)/2^13.
Packit Service 82fcde
//
Packit Service 82fcde
//   Hence
Packit Service 82fcde
//
Packit Service 82fcde
//   exp(X) = 2^( N / 2^12 ) * exp(r).
Packit Service 82fcde
//
Packit Service 82fcde
//   The value 2^( N / 2^12 ) is obtained by simple combinations
Packit Service 82fcde
//   of values calculated beforehand and stored in table; exp(r)
Packit Service 82fcde
//   is approximated by a short polynomial because |r| is small.
Packit Service 82fcde
//
Packit Service 82fcde
//   We elaborate this method in 4 steps.
Packit Service 82fcde
//
Packit Service 82fcde
//   Step 1: Reduction
Packit Service 82fcde
//
Packit Service 82fcde
//   The value 2^12/log(2) is stored as a double-extended number
Packit Service 82fcde
//   L_Inv.
Packit Service 82fcde
//
Packit Service 82fcde
//   N := round_to_nearest_integer( X * L_Inv )
Packit Service 82fcde
//
Packit Service 82fcde
//   The value log(2)/2^12 is stored as two numbers L_hi and L_lo so
Packit Service 82fcde
//   that r can be computed accurately via
Packit Service 82fcde
//
Packit Service 82fcde
//   r := (X - N*L_hi) - N*L_lo
Packit Service 82fcde
//
Packit Service 82fcde
//   We pick L_hi such that N*L_hi is representable in 64 sig. bits
Packit Service 82fcde
//   and thus the FMA   X - N*L_hi   is error free. So r is the
Packit Service 82fcde
//   1 rounding error from an exact reduction with respect to
Packit Service 82fcde
//
Packit Service 82fcde
//   L_hi + L_lo.
Packit Service 82fcde
//
Packit Service 82fcde
//   In particular, L_hi has 30 significant bit and can be stored
Packit Service 82fcde
//   as a double-precision number; L_lo has 64 significant bits and
Packit Service 82fcde
//   stored as a double-extended number.
Packit Service 82fcde
//
Packit Service 82fcde
//   Step 2: Approximation
Packit Service 82fcde
//
Packit Service 82fcde
//   exp(r) - 1 is approximated by a short polynomial of the form
Packit Service 82fcde
//
Packit Service 82fcde
//   r + A_1 r^2 + A_2 r^3 + A_3 r^4 .
Packit Service 82fcde
//
Packit Service 82fcde
//   Step 3: Composition from Table Values
Packit Service 82fcde
//
Packit Service 82fcde
//   The value 2^( N / 2^12 ) can be composed from a couple of tables
Packit Service 82fcde
//   of precalculated values. First, express N as three integers
Packit Service 82fcde
//   K, M_1, and M_2 as
Packit Service 82fcde
//
Packit Service 82fcde
//     N  =  K * 2^12  + M_1 * 2^6 + M_2
Packit Service 82fcde
//
Packit Service 82fcde
//   Where 0 <= M_1, M_2 < 2^6; and K can be positive or negative.
Packit Service 82fcde
//   When N is represented in 2's complement, M_2 is simply the 6
Packit Service 82fcde
//   lsb's, M_1 is the next 6, and K is simply N shifted right
Packit Service 82fcde
//   arithmetically (sign extended) by 12 bits.
Packit Service 82fcde
//
Packit Service 82fcde
//   Now, 2^( N / 2^12 ) is simply
Packit Service 82fcde
//
Packit Service 82fcde
//      2^K * 2^( M_1 / 2^6 ) * 2^( M_2 / 2^12 )
Packit Service 82fcde
//
Packit Service 82fcde
//   Clearly, 2^K needs no tabulation. The other two values are less
Packit Service 82fcde
//   trivial because if we store each accurately to more than working
Packit Service 82fcde
//   precision, than its product is too expensive to calculate. We
Packit Service 82fcde
//   use the following method.
Packit Service 82fcde
//
Packit Service 82fcde
//   Define two mathematical values, delta_1 and delta_2, implicitly
Packit Service 82fcde
//   such that
Packit Service 82fcde
//
Packit Service 82fcde
//     T_1 = exp( [M_1 log(2)/2^6]  -  delta_1 )
Packit Service 82fcde
//     T_2 = exp( [M_2 log(2)/2^12] -  delta_2 )
Packit Service 82fcde
//
Packit Service 82fcde
//   are representable as 24 significant bits. To illustrate the idea,
Packit Service 82fcde
//   we show how we define delta_1:
Packit Service 82fcde
//
Packit Service 82fcde
//     T_1     := round_to_24_bits( exp( M_1 log(2)/2^6 ) )
Packit Service 82fcde
//     delta_1  = (M_1 log(2)/2^6) - log( T_1 )
Packit Service 82fcde
//
Packit Service 82fcde
//   The last equality means mathematical equality. We then tabulate
Packit Service 82fcde
//
Packit Service 82fcde
//     W_1 := exp(delta_1) - 1
Packit Service 82fcde
//     W_2 := exp(delta_2) - 1
Packit Service 82fcde
//
Packit Service 82fcde
//   Both in double precision.
Packit Service 82fcde
//
Packit Service 82fcde
//   From the tabulated values T_1, T_2, W_1, W_2, we compose the values
Packit Service 82fcde
//   T and W via
Packit Service 82fcde
//
Packit Service 82fcde
//     T := T_1 * T_2			...exactly
Packit Service 82fcde
//     W := W_1 + (1 + W_1)*W_2
Packit Service 82fcde
//
Packit Service 82fcde
//   W approximates exp( delta ) - 1  where delta = delta_1 + delta_2.
Packit Service 82fcde
//   The mathematical product of T and (W+1) is an accurate representation
Packit Service 82fcde
//   of 2^(M_1/2^6) * 2^(M_2/2^12).
Packit Service 82fcde
//
Packit Service 82fcde
//   Step 4. Reconstruction
Packit Service 82fcde
//
Packit Service 82fcde
//   Finally, we can reconstruct exp(X), exp(X) - 1.
Packit Service 82fcde
//   Because
Packit Service 82fcde
//
Packit Service 82fcde
//	X = K * log(2) + (M_1*log(2)/2^6  - delta_1)
Packit Service 82fcde
//		       + (M_2*log(2)/2^12 - delta_2)
Packit Service 82fcde
//		       + delta_1 + delta_2 + r 		...accurately
Packit Service 82fcde
//   We have
Packit Service 82fcde
//
Packit Service 82fcde
//	exp(X) ~=~ 2^K * ( T + T*[exp(delta_1+delta_2+r) - 1] )
Packit Service 82fcde
//	       ~=~ 2^K * ( T + T*[exp(delta + r) - 1]         )
Packit Service 82fcde
//	       ~=~ 2^K * ( T + T*[(exp(delta)-1)
Packit Service 82fcde
//				 + exp(delta)*(exp(r)-1)]   )
Packit Service 82fcde
//             ~=~ 2^K * ( T + T*( W + (1+W)*poly(r) ) )
Packit Service 82fcde
//             ~=~ 2^K * ( Y_hi  +  Y_lo )
Packit Service 82fcde
//
Packit Service 82fcde
//   where Y_hi = T  and Y_lo = T*(W + (1+W)*poly(r))
Packit Service 82fcde
//
Packit Service 82fcde
//   For exp(X)-1, we have
Packit Service 82fcde
//
Packit Service 82fcde
//	exp(X)-1 ~=~ 2^K * ( Y_hi + Y_lo ) - 1
Packit Service 82fcde
//		 ~=~ 2^K * ( Y_hi + Y_lo - 2^(-K) )
Packit Service 82fcde
//
Packit Service 82fcde
//   and we combine Y_hi + Y_lo - 2^(-N)  into the form of two
Packit Service 82fcde
//   numbers  Y_hi + Y_lo carefully.
Packit Service 82fcde
//
Packit Service 82fcde
//   **** Algorithm Details ****
Packit Service 82fcde
//
Packit Service 82fcde
//   A careful algorithm must be used to realize the mathematical ideas
Packit Service 82fcde
//   accurately. We describe each of the three cases. We assume SAFE
Packit Service 82fcde
//   is preset to be TRUE.
Packit Service 82fcde
//
Packit Service 82fcde
//   Case exp_tiny:
Packit Service 82fcde
//
Packit Service 82fcde
//   The important points are to ensure an accurate result under
Packit Service 82fcde
//   different rounding directions and a correct setting of the SAFE
Packit Service 82fcde
//   flag.
Packit Service 82fcde
//
Packit Service 82fcde
//   If expm1 is 1, then
Packit Service 82fcde
//      SAFE  := False	...possibility of underflow
Packit Service 82fcde
//      Scale := 1.0
Packit Service 82fcde
//      Y_hi  := X
Packit Service 82fcde
//      Y_lo  := 2^(-17000)
Packit Service 82fcde
//   Else
Packit Service 82fcde
//      Scale := 1.0
Packit Service 82fcde
//      Y_hi  := 1.0
Packit Service 82fcde
//      Y_lo  := X	...for different rounding modes
Packit Service 82fcde
//   Endif
Packit Service 82fcde
//
Packit Service 82fcde
//   Case exp_small:
Packit Service 82fcde
//
Packit Service 82fcde
//   Here we compute a simple polynomial. To exploit parallelism, we split
Packit Service 82fcde
//   the polynomial into several portions.
Packit Service 82fcde
//
Packit Service 82fcde
//   Let r = X
Packit Service 82fcde
//
Packit Service 82fcde
//   If exp 	...i.e. exp( argument )
Packit Service 82fcde
//
Packit Service 82fcde
//      rsq := r * r;
Packit Service 82fcde
//      r4  := rsq*rsq
Packit Service 82fcde
//      poly_lo := P_3 + r*(P_4 + r*(P_5 + r*P_6))
Packit Service 82fcde
//      poly_hi := r + rsq*(P_1 + r*P_2)
Packit Service 82fcde
//      Y_lo    := poly_hi + r4 * poly_lo
Packit Service 82fcde
//      Y_hi    := 1.0
Packit Service 82fcde
//      Scale   := 1.0
Packit Service 82fcde
//
Packit Service 82fcde
//   Else			...i.e. exp( argument ) - 1
Packit Service 82fcde
//
Packit Service 82fcde
//      rsq := r * r
Packit Service 82fcde
//      r4  := rsq * rsq
Packit Service 82fcde
//      poly_lo := Q_7 + r*(Q_8 + r*Q_9))
Packit Service 82fcde
//      poly_med:= Q_3 + r*Q_4 + rsq*(Q_5 + r*Q_6)
Packit Service 82fcde
//      poly_med:= poly_med + r4*poly_lo
Packit Service 82fcde
//      poly_hi := Q_1 + r*Q_2
Packit Service 82fcde
//      Y_lo    := rsq*(poly_hi +  rsq*poly_lo)
Packit Service 82fcde
//      Y_hi    := X
Packit Service 82fcde
//      Scale   := 1.0
Packit Service 82fcde
//
Packit Service 82fcde
//   Endif
Packit Service 82fcde
//
Packit Service 82fcde
//  Case exp_regular:
Packit Service 82fcde
//
Packit Service 82fcde
//  The previous description contain enough information except the
Packit Service 82fcde
//  computation of poly and the final Y_hi and Y_lo in the case for
Packit Service 82fcde
//  exp(X)-1.
Packit Service 82fcde
//
Packit Service 82fcde
//  The computation of poly for Step 2:
Packit Service 82fcde
//
Packit Service 82fcde
//   rsq := r*r
Packit Service 82fcde
//   poly := r + rsq*(A_1 + r*(A_2 + r*A_3))
Packit Service 82fcde
//
Packit Service 82fcde
//  For the case exp(X) - 1, we need to incorporate 2^(-K) into
Packit Service 82fcde
//  Y_hi and Y_lo at the end of Step 4.
Packit Service 82fcde
//
Packit Service 82fcde
//   If K > 10 then
Packit Service 82fcde
//      Y_lo := Y_lo - 2^(-K)
Packit Service 82fcde
//   Else
Packit Service 82fcde
//      If K < -10 then
Packit Service 82fcde
//	 Y_lo := Y_hi + Y_lo
Packit Service 82fcde
//	 Y_hi := -2^(-K)
Packit Service 82fcde
//      Else
Packit Service 82fcde
//	 Y_hi := Y_hi - 2^(-K)
Packit Service 82fcde
//      End If
Packit Service 82fcde
//   End If
Packit Service 82fcde
//
Packit Service 82fcde
//=======================================================
Packit Service 82fcde
// General Purpose Registers
Packit Service 82fcde
//
Packit Service 82fcde
GR_ad_Arg           = r14
Packit Service 82fcde
GR_ad_A             = r15
Packit Service 82fcde
GR_sig_inv_ln2      = r15
Packit Service 82fcde
GR_rshf_2to51       = r16
Packit Service 82fcde
GR_ad_PQ            = r16
Packit Service 82fcde
GR_ad_Q             = r16
Packit Service 82fcde
GR_signexp_x        = r17
Packit Service 82fcde
GR_exp_x            = r17
Packit Service 82fcde
GR_small_exp        = r18
Packit Service 82fcde
GR_rshf             = r18
Packit Service 82fcde
GR_exp_mask         = r19
Packit Service 82fcde
GR_ad_W1            = r20
Packit Service 82fcde
GR_exp_2tom51       = r20
Packit Service 82fcde
GR_ad_W2            = r21
Packit Service 82fcde
GR_exp_underflow    = r21
Packit Service 82fcde
GR_M2               = r22
Packit Service 82fcde
GR_huge_exp         = r22
Packit Service 82fcde
GR_M1               = r23
Packit Service 82fcde
GR_huge_signif      = r23
Packit Service 82fcde
GR_K                = r24
Packit Service 82fcde
GR_one              = r24
Packit Service 82fcde
GR_minus_one        = r24
Packit Service 82fcde
GR_exp_bias         = r25
Packit Service 82fcde
GR_ad_Limits        = r26
Packit Service 82fcde
GR_N_fix            = r26
Packit Service 82fcde
GR_exp_2_mk         = r26
Packit Service 82fcde
GR_ad_P             = r27
Packit Service 82fcde
GR_exp_2_k          = r27
Packit Service 82fcde
GR_big_expo_neg     = r28
Packit Service 82fcde
GR_very_small_exp   = r29
Packit Service 82fcde
GR_exp_half         = r29
Packit Service 82fcde
GR_ad_T1            = r30
Packit Service 82fcde
GR_ad_T2            = r31
Packit Service 82fcde
Packit Service 82fcde
GR_SAVE_PFS         = r32
Packit Service 82fcde
GR_SAVE_B0          = r33
Packit Service 82fcde
GR_SAVE_GP          = r34
Packit Service 82fcde
GR_Parameter_X      = r35
Packit Service 82fcde
GR_Parameter_Y      = r36
Packit Service 82fcde
GR_Parameter_RESULT = r37
Packit Service 82fcde
GR_Parameter_TAG    = r38
Packit Service 82fcde
Packit Service 82fcde
// Floating Point Registers
Packit Service 82fcde
//
Packit Service 82fcde
FR_norm_x           = f9
Packit Service 82fcde
FR_RSHF_2TO51       = f10
Packit Service 82fcde
FR_INV_LN2_2TO63    = f11
Packit Service 82fcde
FR_W_2TO51_RSH      = f12
Packit Service 82fcde
FR_2TOM51           = f13
Packit Service 82fcde
FR_RSHF             = f14
Packit Service 82fcde
FR_Y_hi             = f34
Packit Service 82fcde
FR_Y_lo             = f35
Packit Service 82fcde
FR_scale            = f36
Packit Service 82fcde
FR_tmp              = f37
Packit Service 82fcde
FR_float_N          = f38
Packit Service 82fcde
FR_N_signif         = f39
Packit Service 82fcde
FR_L_hi             = f40
Packit Service 82fcde
FR_L_lo             = f41
Packit Service 82fcde
FR_r                = f42
Packit Service 82fcde
FR_W1               = f43
Packit Service 82fcde
FR_T1               = f44
Packit Service 82fcde
FR_W2               = f45
Packit Service 82fcde
FR_T2               = f46
Packit Service 82fcde
FR_W1_p1            = f47
Packit Service 82fcde
FR_rsq              = f48
Packit Service 82fcde
FR_A2               = f49
Packit Service 82fcde
FR_r4               = f50
Packit Service 82fcde
FR_A3               = f51
Packit Service 82fcde
FR_poly             = f52
Packit Service 82fcde
FR_T                = f53
Packit Service 82fcde
FR_W                = f54
Packit Service 82fcde
FR_Wp1              = f55
Packit Service 82fcde
FR_p21              = f59
Packit Service 82fcde
FR_p210             = f59
Packit Service 82fcde
FR_p65              = f60
Packit Service 82fcde
FR_p654             = f60
Packit Service 82fcde
FR_p6543            = f60
Packit Service 82fcde
FR_2_mk             = f61
Packit Service 82fcde
FR_P4Q7             = f61
Packit Service 82fcde
FR_P4               = f61
Packit Service 82fcde
FR_Q7               = f61
Packit Service 82fcde
FR_P3Q6             = f62
Packit Service 82fcde
FR_P3               = f62
Packit Service 82fcde
FR_Q6               = f62
Packit Service 82fcde
FR_q65              = f62
Packit Service 82fcde
FR_q6543            = f62
Packit Service 82fcde
FR_P2Q5             = f63
Packit Service 82fcde
FR_P2               = f63
Packit Service 82fcde
FR_Q5               = f63
Packit Service 82fcde
FR_P1Q4             = f64
Packit Service 82fcde
FR_P1               = f64
Packit Service 82fcde
FR_Q4               = f64
Packit Service 82fcde
FR_q43              = f64
Packit Service 82fcde
FR_Q3               = f65
Packit Service 82fcde
FR_Q2               = f66
Packit Service 82fcde
FR_q21              = f66
Packit Service 82fcde
FR_Q1               = f67
Packit Service 82fcde
FR_A1               = f68
Packit Service 82fcde
FR_P6Q9             = f68
Packit Service 82fcde
FR_P6               = f68
Packit Service 82fcde
FR_Q9               = f68
Packit Service 82fcde
FR_P5Q8             = f69
Packit Service 82fcde
FR_P5               = f69
Packit Service 82fcde
FR_Q8               = f69
Packit Service 82fcde
FR_q987             = f69
Packit Service 82fcde
FR_q98              = f69
Packit Service 82fcde
FR_q9876543         = f69
Packit Service 82fcde
FR_min_oflow_x      = f70
Packit Service 82fcde
FR_huge_exp         = f70
Packit Service 82fcde
FR_zero_uflow_x     = f71
Packit Service 82fcde
FR_huge_signif      = f71
Packit Service 82fcde
FR_huge             = f72
Packit Service 82fcde
FR_small            = f72
Packit Service 82fcde
FR_half             = f73
Packit Service 82fcde
FR_T_scale          = f74
Packit Service 82fcde
FR_result_lo        = f75
Packit Service 82fcde
FR_W_T_scale        = f76
Packit Service 82fcde
FR_Wp1_T_scale      = f77
Packit Service 82fcde
FR_ftz              = f77
Packit Service 82fcde
FR_half_x           = f77
Packit Service 82fcde
//
Packit Service 82fcde
Packit Service 82fcde
FR_X                = f9
Packit Service 82fcde
FR_Y                = f0
Packit Service 82fcde
FR_RESULT           = f15
Packit Service 82fcde
Packit Service 82fcde
// ************* DO NOT CHANGE ORDER OF THESE TABLES ********************
Packit Service 82fcde
Packit Service 82fcde
// double-extended 1/ln(2)
Packit Service 82fcde
// 3fff b8aa 3b29 5c17 f0bb be87fed0691d3e88
Packit Service 82fcde
// 3fff b8aa 3b29 5c17 f0bc
Packit Service 82fcde
// For speed the significand will be loaded directly with a movl and setf.sig
Packit Service 82fcde
//   and the exponent will be bias+63 instead of bias+0.  Thus subsequent
Packit Service 82fcde
//   computations need to scale appropriately.
Packit Service 82fcde
// The constant 2^12/ln(2) is needed for the computation of N.  This is also
Packit Service 82fcde
//   obtained by scaling the computations.
Packit Service 82fcde
//
Packit Service 82fcde
// Two shifting constants are loaded directly with movl and setf.d.
Packit Service 82fcde
//   1. RSHF_2TO51 = 1.1000..00 * 2^(63-12)
Packit Service 82fcde
//        This constant is added to x*1/ln2 to shift the integer part of
Packit Service 82fcde
//        x*2^12/ln2 into the rightmost bits of the significand.
Packit Service 82fcde
//        The result of this fma is N_signif.
Packit Service 82fcde
//   2. RSHF       = 1.1000..00 * 2^(63)
Packit Service 82fcde
//        This constant is subtracted from N_signif * 2^(-51) to give
Packit Service 82fcde
//        the integer part of N, N_fix, as a floating-point number.
Packit Service 82fcde
//        The result of this fms is float_N.
Packit Service 82fcde
Packit Service 82fcde
RODATA
Packit Service 82fcde
.align 64
Packit Service 82fcde
LOCAL_OBJECT_START(Constants_exp_64_Arg)
Packit Service 82fcde
//data8 0xB8AA3B295C17F0BC,0x0000400B // Inv_L = 2^12/log(2)
Packit Service 82fcde
data8 0xB17217F400000000,0x00003FF2 // L_hi = hi part log(2)/2^12
Packit Service 82fcde
data8 0xF473DE6AF278ECE6,0x00003FD4 // L_lo = lo part log(2)/2^12
Packit Service 82fcde
LOCAL_OBJECT_END(Constants_exp_64_Arg)
Packit Service 82fcde
Packit Service 82fcde
LOCAL_OBJECT_START(Constants_exp_64_Limits)
Packit Service 82fcde
data8 0xb17217f7d1cf79ac,0x0000400c // Smallest long dbl oflow x
Packit Service 82fcde
data8 0xb220000000000000,0x0000c00c // Small long dbl uflow zero x
Packit Service 82fcde
LOCAL_OBJECT_END(Constants_exp_64_Limits)
Packit Service 82fcde
Packit Service 82fcde
LOCAL_OBJECT_START(Constants_exp_64_A)
Packit Service 82fcde
data8 0xAAAAAAABB1B736A0,0x00003FFA // A3
Packit Service 82fcde
data8 0xAAAAAAAB90CD6327,0x00003FFC // A2
Packit Service 82fcde
data8 0xFFFFFFFFFFFFFFFF,0x00003FFD // A1
Packit Service 82fcde
LOCAL_OBJECT_END(Constants_exp_64_A)
Packit Service 82fcde
Packit Service 82fcde
LOCAL_OBJECT_START(Constants_exp_64_P)
Packit Service 82fcde
data8 0xD00D6C8143914A8A,0x00003FF2 // P6
Packit Service 82fcde
data8 0xB60BC4AC30304B30,0x00003FF5 // P5
Packit Service 82fcde
data8 0x888888887474C518,0x00003FF8 // P4
Packit Service 82fcde
data8 0xAAAAAAAA8DAE729D,0x00003FFA // P3
Packit Service 82fcde
data8 0xAAAAAAAAAAAAAF61,0x00003FFC // P2
Packit Service 82fcde
data8 0x80000000000004C7,0x00003FFE // P1
Packit Service 82fcde
LOCAL_OBJECT_END(Constants_exp_64_P)
Packit Service 82fcde
Packit Service 82fcde
LOCAL_OBJECT_START(Constants_exp_64_Q)
Packit Service 82fcde
data8 0x93F2AC5F7471F32E, 0x00003FE9 // Q9
Packit Service 82fcde
data8 0xB8DA0F3550B3E764, 0x00003FEC // Q8
Packit Service 82fcde
data8 0xD00D00D0028E89C4, 0x00003FEF // Q7
Packit Service 82fcde
data8 0xD00D00DAEB8C4E91, 0x00003FF2 // Q6
Packit Service 82fcde
data8 0xB60B60B60B60B6F5, 0x00003FF5 // Q5
Packit Service 82fcde
data8 0x888888888886CC23, 0x00003FF8 // Q4
Packit Service 82fcde
data8 0xAAAAAAAAAAAAAAAB, 0x00003FFA // Q3
Packit Service 82fcde
data8 0xAAAAAAAAAAAAAAAB, 0x00003FFC // Q2
Packit Service 82fcde
data8 0x8000000000000000, 0x00003FFE // Q1
Packit Service 82fcde
LOCAL_OBJECT_END(Constants_exp_64_Q)
Packit Service 82fcde
Packit Service 82fcde
LOCAL_OBJECT_START(Constants_exp_64_T1)
Packit Service 82fcde
data4 0x3F800000,0x3F8164D2,0x3F82CD87,0x3F843A29
Packit Service 82fcde
data4 0x3F85AAC3,0x3F871F62,0x3F88980F,0x3F8A14D5
Packit Service 82fcde
data4 0x3F8B95C2,0x3F8D1ADF,0x3F8EA43A,0x3F9031DC
Packit Service 82fcde
data4 0x3F91C3D3,0x3F935A2B,0x3F94F4F0,0x3F96942D
Packit Service 82fcde
data4 0x3F9837F0,0x3F99E046,0x3F9B8D3A,0x3F9D3EDA
Packit Service 82fcde
data4 0x3F9EF532,0x3FA0B051,0x3FA27043,0x3FA43516
Packit Service 82fcde
data4 0x3FA5FED7,0x3FA7CD94,0x3FA9A15B,0x3FAB7A3A
Packit Service 82fcde
data4 0x3FAD583F,0x3FAF3B79,0x3FB123F6,0x3FB311C4
Packit Service 82fcde
data4 0x3FB504F3,0x3FB6FD92,0x3FB8FBAF,0x3FBAFF5B
Packit Service 82fcde
data4 0x3FBD08A4,0x3FBF179A,0x3FC12C4D,0x3FC346CD
Packit Service 82fcde
data4 0x3FC5672A,0x3FC78D75,0x3FC9B9BE,0x3FCBEC15
Packit Service 82fcde
data4 0x3FCE248C,0x3FD06334,0x3FD2A81E,0x3FD4F35B
Packit Service 82fcde
data4 0x3FD744FD,0x3FD99D16,0x3FDBFBB8,0x3FDE60F5
Packit Service 82fcde
data4 0x3FE0CCDF,0x3FE33F89,0x3FE5B907,0x3FE8396A
Packit Service 82fcde
data4 0x3FEAC0C7,0x3FED4F30,0x3FEFE4BA,0x3FF28177
Packit Service 82fcde
data4 0x3FF5257D,0x3FF7D0DF,0x3FFA83B3,0x3FFD3E0C
Packit Service 82fcde
LOCAL_OBJECT_END(Constants_exp_64_T1)
Packit Service 82fcde
Packit Service 82fcde
LOCAL_OBJECT_START(Constants_exp_64_T2)
Packit Service 82fcde
data4 0x3F800000,0x3F80058C,0x3F800B18,0x3F8010A4
Packit Service 82fcde
data4 0x3F801630,0x3F801BBD,0x3F80214A,0x3F8026D7
Packit Service 82fcde
data4 0x3F802C64,0x3F8031F2,0x3F803780,0x3F803D0E
Packit Service 82fcde
data4 0x3F80429C,0x3F80482B,0x3F804DB9,0x3F805349
Packit Service 82fcde
data4 0x3F8058D8,0x3F805E67,0x3F8063F7,0x3F806987
Packit Service 82fcde
data4 0x3F806F17,0x3F8074A8,0x3F807A39,0x3F807FCA
Packit Service 82fcde
data4 0x3F80855B,0x3F808AEC,0x3F80907E,0x3F809610
Packit Service 82fcde
data4 0x3F809BA2,0x3F80A135,0x3F80A6C7,0x3F80AC5A
Packit Service 82fcde
data4 0x3F80B1ED,0x3F80B781,0x3F80BD14,0x3F80C2A8
Packit Service 82fcde
data4 0x3F80C83C,0x3F80CDD1,0x3F80D365,0x3F80D8FA
Packit Service 82fcde
data4 0x3F80DE8F,0x3F80E425,0x3F80E9BA,0x3F80EF50
Packit Service 82fcde
data4 0x3F80F4E6,0x3F80FA7C,0x3F810013,0x3F8105AA
Packit Service 82fcde
data4 0x3F810B41,0x3F8110D8,0x3F81166F,0x3F811C07
Packit Service 82fcde
data4 0x3F81219F,0x3F812737,0x3F812CD0,0x3F813269
Packit Service 82fcde
data4 0x3F813802,0x3F813D9B,0x3F814334,0x3F8148CE
Packit Service 82fcde
data4 0x3F814E68,0x3F815402,0x3F81599C,0x3F815F37
Packit Service 82fcde
LOCAL_OBJECT_END(Constants_exp_64_T2)
Packit Service 82fcde
Packit Service 82fcde
LOCAL_OBJECT_START(Constants_exp_64_W1)
Packit Service 82fcde
data8 0x0000000000000000, 0xBE384454171EC4B4
Packit Service 82fcde
data8 0xBE6947414AA72766, 0xBE5D32B6D42518F8
Packit Service 82fcde
data8 0x3E68D96D3A319149, 0xBE68F4DA62415F36
Packit Service 82fcde
data8 0xBE6DDA2FC9C86A3B, 0x3E6B2E50F49228FE
Packit Service 82fcde
data8 0xBE49C0C21188B886, 0x3E64BFC21A4C2F1F
Packit Service 82fcde
data8 0xBE6A2FBB2CB98B54, 0x3E5DC5DE9A55D329
Packit Service 82fcde
data8 0x3E69649039A7AACE, 0x3E54728B5C66DBA5
Packit Service 82fcde
data8 0xBE62B0DBBA1C7D7D, 0x3E576E0409F1AF5F
Packit Service 82fcde
data8 0x3E6125001A0DD6A1, 0xBE66A419795FBDEF
Packit Service 82fcde
data8 0xBE5CDE8CE1BD41FC, 0xBE621376EA54964F
Packit Service 82fcde
data8 0x3E6370BE476E76EE, 0x3E390D1A3427EB92
Packit Service 82fcde
data8 0x3E1336DE2BF82BF8, 0xBE5FF1CBD0F7BD9E
Packit Service 82fcde
data8 0xBE60A3550CEB09DD, 0xBE5CA37E0980F30D
Packit Service 82fcde
data8 0xBE5C541B4C082D25, 0xBE5BBECA3B467D29
Packit Service 82fcde
data8 0xBE400D8AB9D946C5, 0xBE5E2A0807ED374A
Packit Service 82fcde
data8 0xBE66CB28365C8B0A, 0x3E3AAD5BD3403BCA
Packit Service 82fcde
data8 0x3E526055C7EA21E0, 0xBE442C75E72880D6
Packit Service 82fcde
data8 0x3E58B2BB85222A43, 0xBE5AAB79522C42BF
Packit Service 82fcde
data8 0xBE605CB4469DC2BC, 0xBE589FA7A48C40DC
Packit Service 82fcde
data8 0xBE51C2141AA42614, 0xBE48D087C37293F4
Packit Service 82fcde
data8 0x3E367A1CA2D673E0, 0xBE51BEBB114F7A38
Packit Service 82fcde
data8 0xBE6348E5661A4B48, 0xBDF526431D3B9962
Packit Service 82fcde
data8 0x3E3A3B5E35A78A53, 0xBE46C46C1CECD788
Packit Service 82fcde
data8 0xBE60B7EC7857D689, 0xBE594D3DD14F1AD7
Packit Service 82fcde
data8 0xBE4F9C304C9A8F60, 0xBE52187302DFF9D2
Packit Service 82fcde
data8 0xBE5E4C8855E6D68F, 0xBE62140F667F3DC4
Packit Service 82fcde
data8 0xBE36961B3BF88747, 0x3E602861C96EC6AA
Packit Service 82fcde
data8 0xBE3B5151D57FD718, 0x3E561CD0FC4A627B
Packit Service 82fcde
data8 0xBE3A5217CA913FEA, 0x3E40A3CC9A5D193A
Packit Service 82fcde
data8 0xBE5AB71310A9C312, 0x3E4FDADBC5F57719
Packit Service 82fcde
data8 0x3E361428DBDF59D5, 0x3E5DB5DB61B4180D
Packit Service 82fcde
data8 0xBE42AD5F7408D856, 0x3E2A314831B2B707
Packit Service 82fcde
LOCAL_OBJECT_END(Constants_exp_64_W1)
Packit Service 82fcde
Packit Service 82fcde
LOCAL_OBJECT_START(Constants_exp_64_W2)
Packit Service 82fcde
data8 0x0000000000000000, 0xBE641F2537A3D7A2
Packit Service 82fcde
data8 0xBE68DD57AD028C40, 0xBE5C77D8F212B1B6
Packit Service 82fcde
data8 0x3E57878F1BA5B070, 0xBE55A36A2ECAE6FE
Packit Service 82fcde
data8 0xBE620608569DFA3B, 0xBE53B50EA6D300A3
Packit Service 82fcde
data8 0x3E5B5EF2223F8F2C, 0xBE56A0D9D6DE0DF4
Packit Service 82fcde
data8 0xBE64EEF3EAE28F51, 0xBE5E5AE2367EA80B
Packit Service 82fcde
data8 0x3E47CB1A5FCBC02D, 0xBE656BA09BDAFEB7
Packit Service 82fcde
data8 0x3E6E70C6805AFEE7, 0xBE6E0509A3415EBA
Packit Service 82fcde
data8 0xBE56856B49BFF529, 0x3E66DD3300508651
Packit Service 82fcde
data8 0x3E51165FC114BC13, 0x3E53333DC453290F
Packit Service 82fcde
data8 0x3E6A072B05539FDA, 0xBE47CD877C0A7696
Packit Service 82fcde
data8 0xBE668BF4EB05C6D9, 0xBE67C3E36AE86C93
Packit Service 82fcde
data8 0xBE533904D0B3E84B, 0x3E63E8D9556B53CE
Packit Service 82fcde
data8 0x3E212C8963A98DC8, 0xBE33138F032A7A22
Packit Service 82fcde
data8 0x3E530FA9BC584008, 0xBE6ADF82CCB93C97
Packit Service 82fcde
data8 0x3E5F91138370EA39, 0x3E5443A4FB6A05D8
Packit Service 82fcde
data8 0x3E63DACD181FEE7A, 0xBE62B29DF0F67DEC
Packit Service 82fcde
data8 0x3E65C4833DDE6307, 0x3E5BF030D40A24C1
Packit Service 82fcde
data8 0x3E658B8F14E437BE, 0xBE631C29ED98B6C7
Packit Service 82fcde
data8 0x3E6335D204CF7C71, 0x3E529EEDE954A79D
Packit Service 82fcde
data8 0x3E5D9257F64A2FB8, 0xBE6BED1B854ED06C
Packit Service 82fcde
data8 0x3E5096F6D71405CB, 0xBE3D4893ACB9FDF5
Packit Service 82fcde
data8 0xBDFEB15801B68349, 0x3E628D35C6A463B9
Packit Service 82fcde
data8 0xBE559725ADE45917, 0xBE68C29C042FC476
Packit Service 82fcde
data8 0xBE67593B01E511FA, 0xBE4A4313398801ED
Packit Service 82fcde
data8 0x3E699571DA7C3300, 0x3E5349BE08062A9E
Packit Service 82fcde
data8 0x3E5229C4755BB28E, 0x3E67E42677A1F80D
Packit Service 82fcde
data8 0xBE52B33F6B69C352, 0xBE6B3550084DA57F
Packit Service 82fcde
data8 0xBE6DB03FD1D09A20, 0xBE60CBC42161B2C1
Packit Service 82fcde
data8 0x3E56ED9C78A2B771, 0xBE508E319D0FA795
Packit Service 82fcde
data8 0xBE59482AFD1A54E9, 0xBE2A17CEB07FD23E
Packit Service 82fcde
data8 0x3E68BF5C17365712, 0x3E3956F9B3785569
Packit Service 82fcde
LOCAL_OBJECT_END(Constants_exp_64_W2)
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
.section .text
Packit Service 82fcde
Packit Service 82fcde
GLOBAL_IEEE754_ENTRY(expm1l)
Packit Service 82fcde
Packit Service 82fcde
//
Packit Service 82fcde
//    Set p7 true for expm1, p6 false
Packit Service 82fcde
//
Packit Service 82fcde
Packit Service 82fcde
{ .mlx
Packit Service 82fcde
      getf.exp GR_signexp_x = f8  // Get sign and exponent of x, redo if unorm
Packit Service 82fcde
      movl GR_sig_inv_ln2 = 0xb8aa3b295c17f0bc  // significand of 1/ln2
Packit Service 82fcde
}
Packit Service 82fcde
{ .mlx
Packit Service 82fcde
      addl GR_ad_Arg = @ltoff(Constants_exp_64_Arg#),gp
Packit Service 82fcde
      movl GR_rshf_2to51 = 0x4718000000000000 // 1.10000 2^(63+51)
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
      ld8  GR_ad_Arg = [GR_ad_Arg]       // Point to Arg table
Packit Service 82fcde
      fclass.m p8, p0 =  f8, 0x1E7       // Test x for natval, nan, inf, zero
Packit Service 82fcde
      cmp.eq  p7, p6 =  r0, r0
Packit Service 82fcde
}
Packit Service 82fcde
{ .mfb
Packit Service 82fcde
      mov GR_exp_half = 0x0FFFE          // Exponent of 0.5, for very small path
Packit Service 82fcde
      fnorm.s1 FR_norm_x = f8            // Normalize x
Packit Service 82fcde
      br.cond.sptk exp_continue
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
GLOBAL_IEEE754_END(expm1l)
Packit Service 82fcde
libm_alias_ldouble_other (__expm1, expm1)
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
GLOBAL_IEEE754_ENTRY(expl)
Packit Service 82fcde
//
Packit Service 82fcde
//    Set p7 false for exp, p6 true
Packit Service 82fcde
//
Packit Service 82fcde
{ .mlx
Packit Service 82fcde
      getf.exp GR_signexp_x = f8  // Get sign and exponent of x, redo if unorm
Packit Service 82fcde
      movl GR_sig_inv_ln2 = 0xb8aa3b295c17f0bc  // significand of 1/ln2
Packit Service 82fcde
}
Packit Service 82fcde
{ .mlx
Packit Service 82fcde
      addl GR_ad_Arg = @ltoff(Constants_exp_64_Arg#),gp
Packit Service 82fcde
      movl GR_rshf_2to51 = 0x4718000000000000 // 1.10000 2^(63+51)
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
      ld8  GR_ad_Arg = [GR_ad_Arg]       // Point to Arg table
Packit Service 82fcde
      fclass.m p8, p0 =  f8, 0x1E7       // Test x for natval, nan, inf, zero
Packit Service 82fcde
      cmp.eq  p6, p7 =  r0, r0
Packit Service 82fcde
}
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
      mov GR_exp_half = 0x0FFFE          // Exponent of 0.5, for very small path
Packit Service 82fcde
      fnorm.s1 FR_norm_x = f8            // Normalize x
Packit Service 82fcde
      nop.i 999
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
exp_continue:
Packit Service 82fcde
// Form two constants we need
Packit Service 82fcde
//  1/ln2 * 2^63  to compute  w = x * 1/ln2 * 128
Packit Service 82fcde
//  1.1000..000 * 2^(63+63-12) to right shift int(N) into the significand
Packit Service 82fcde
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
      setf.sig  FR_INV_LN2_2TO63 = GR_sig_inv_ln2 // form 1/ln2 * 2^63
Packit Service 82fcde
      fclass.nm.unc p9, p0 =  f8, 0x1FF  // Test x for unsupported
Packit Service 82fcde
      mov GR_exp_2tom51 = 0xffff-51
Packit Service 82fcde
}
Packit Service 82fcde
{ .mlx
Packit Service 82fcde
      setf.d  FR_RSHF_2TO51 = GR_rshf_2to51 // Form const 1.1000 * 2^(63+51)
Packit Service 82fcde
      movl GR_rshf = 0x43e8000000000000  // 1.10000 2^63 for right shift
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
      setf.exp FR_half = GR_exp_half     // Form 0.5 for very small path
Packit Service 82fcde
      fma.s1 FR_scale = f1,f1,f0         // Scale = 1.0
Packit Service 82fcde
      mov GR_exp_bias = 0x0FFFF          // Set exponent bias
Packit Service 82fcde
}
Packit Service 82fcde
{ .mib
Packit Service 82fcde
      add GR_ad_Limits = 0x20, GR_ad_Arg // Point to Limits table
Packit Service 82fcde
      mov GR_exp_mask = 0x1FFFF          // Form exponent mask
Packit Service 82fcde
(p8)  br.cond.spnt EXP_64_SPECIAL        // Branch if natval, nan, inf, zero
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
      setf.exp FR_2TOM51 = GR_exp_2tom51 // Form 2^-51 for scaling float_N
Packit Service 82fcde
      nop.f 999
Packit Service 82fcde
      add GR_ad_A = 0x40, GR_ad_Arg      // Point to A table
Packit Service 82fcde
}
Packit Service 82fcde
{ .mib
Packit Service 82fcde
      setf.d  FR_RSHF = GR_rshf          // Form right shift const 1.1000 * 2^63
Packit Service 82fcde
      add GR_ad_T1 = 0x160, GR_ad_Arg    // Point to T1 table
Packit Service 82fcde
(p9)  br.cond.spnt EXP_64_UNSUPPORTED    // Branch if unsupported
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
.pred.rel "mutex",p6,p7
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
      ldfe FR_L_hi = [GR_ad_Arg],16      // Get L_hi
Packit Service 82fcde
      fcmp.eq.s0 p9,p0 =  f8, f0         // Dummy op to flag denormals
Packit Service 82fcde
(p6)  add GR_ad_PQ = 0x30, GR_ad_A       // Point to P table for exp
Packit Service 82fcde
}
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
      ldfe FR_min_oflow_x = [GR_ad_Limits],16 // Get min x to cause overflow
Packit Service 82fcde
      fmpy.s1 FR_rsq = f8, f8            // rsq = x * x for small path
Packit Service 82fcde
(p7)  add GR_ad_PQ = 0x90, GR_ad_A       // Point to Q table for expm1
Packit Service 82fcde
};;
Packit Service 82fcde
Packit Service 82fcde
{ .mmi
Packit Service 82fcde
      ldfe FR_L_lo = [GR_ad_Arg],16      // Get L_lo
Packit Service 82fcde
      ldfe FR_zero_uflow_x = [GR_ad_Limits],16 // Get x for zero uflow result
Packit Service 82fcde
      add GR_ad_W1 = 0x200, GR_ad_T1     // Point to W1 table
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
      ldfe FR_P6Q9 = [GR_ad_PQ],16       // P6(exp) or Q9(expm1) for small path
Packit Service 82fcde
      mov FR_r = FR_norm_x               // r = X for small path
Packit Service 82fcde
      mov GR_very_small_exp = -60        // Exponent of x for very small path
Packit Service 82fcde
}
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
      add GR_ad_W2 = 0x400, GR_ad_T1     // Point to W2 table
Packit Service 82fcde
      nop.f 999
Packit Service 82fcde
(p7)  mov GR_small_exp = -7              // Exponent of x for small path expm1
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
{ .mmi
Packit Service 82fcde
      ldfe FR_P5Q8 = [GR_ad_PQ],16       // P5(exp) or Q8(expm1) for small path
Packit Service 82fcde
      and  GR_exp_x = GR_signexp_x, GR_exp_mask
Packit Service 82fcde
(p6)  mov GR_small_exp = -12             // Exponent of x for small path exp
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
// N_signif = X * Inv_log2_by_2^12
Packit Service 82fcde
// By adding 1.10...0*2^63 we shift and get round_int(N_signif) in significand.
Packit Service 82fcde
// We actually add 1.10...0*2^51 to X * Inv_log2 to do the same thing.
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
      ldfe FR_P4Q7 = [GR_ad_PQ],16       // P4(exp) or Q7(expm1) for small path
Packit Service 82fcde
      fma.s1 FR_N_signif = FR_norm_x, FR_INV_LN2_2TO63, FR_RSHF_2TO51
Packit Service 82fcde
      nop.i 999
Packit Service 82fcde
}
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
      sub GR_exp_x = GR_exp_x, GR_exp_bias // Get exponent
Packit Service 82fcde
      fmpy.s1 FR_r4 = FR_rsq, FR_rsq     // Form r4 for small path
Packit Service 82fcde
      cmp.eq.unc  p15, p0 =  r0, r0      // Set Safe as default
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
{ .mmi
Packit Service 82fcde
      ldfe FR_P3Q6 = [GR_ad_PQ],16       // P3(exp) or Q6(expm1) for small path
Packit Service 82fcde
      cmp.lt  p14, p0 =  GR_exp_x, GR_very_small_exp // Is |x| < 2^-60?
Packit Service 82fcde
      nop.i 999
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
      ldfe FR_P2Q5 = [GR_ad_PQ],16       // P2(exp) or Q5(expm1) for small path
Packit Service 82fcde
      fmpy.s1 FR_half_x = FR_half, FR_norm_x // 0.5 * x for very small path
Packit Service 82fcde
      cmp.lt  p13, p0 =  GR_exp_x, GR_small_exp // Is |x| < 2^-m?
Packit Service 82fcde
}
Packit Service 82fcde
{ .mib
Packit Service 82fcde
      nop.m 999
Packit Service 82fcde
      nop.i 999
Packit Service 82fcde
(p14) br.cond.spnt EXP_VERY_SMALL        // Branch if |x| < 2^-60
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
      ldfe FR_A3 = [GR_ad_A],16          // Get A3 for normal path
Packit Service 82fcde
      fcmp.ge.s1 p10,p0 = FR_norm_x, FR_min_oflow_x // Will result overflow?
Packit Service 82fcde
      mov GR_big_expo_neg = -16381       // -0x3ffd
Packit Service 82fcde
}
Packit Service 82fcde
{ .mfb
Packit Service 82fcde
      ldfe FR_P1Q4 = [GR_ad_PQ],16       // P1(exp) or Q4(expm1) for small path
Packit Service 82fcde
      nop.f 999
Packit Service 82fcde
(p13) br.cond.spnt EXP_SMALL             // Branch if |x| < 2^-m
Packit Service 82fcde
                                         // m=12 for exp, m=7 for expm1
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
// Now we are on the main path for |x| >= 2^-m, m=12 for exp, m=7 for expm1
Packit Service 82fcde
//
Packit Service 82fcde
// float_N = round_int(N_signif)
Packit Service 82fcde
// The signficand of N_signif contains the rounded integer part of X * 2^12/ln2,
Packit Service 82fcde
// as a twos complement number in the lower bits (that is, it may be negative).
Packit Service 82fcde
// That twos complement number (called N) is put into GR_N.
Packit Service 82fcde
Packit Service 82fcde
// Since N_signif is scaled by 2^51, it must be multiplied by 2^-51
Packit Service 82fcde
// before the shift constant 1.10000 * 2^63 is subtracted to yield float_N.
Packit Service 82fcde
// Thus, float_N contains the floating point version of N
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
      ldfe FR_A2 = [GR_ad_A],16          // Get A2 for main path
Packit Service 82fcde
      fcmp.lt.s1 p11,p0 = FR_norm_x, FR_zero_uflow_x // Certain zero, uflow?
Packit Service 82fcde
      add GR_ad_T2 = 0x100, GR_ad_T1     // Point to T2 table
Packit Service 82fcde
}
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
      nop.m 999
Packit Service 82fcde
      fms.s1 FR_float_N = FR_N_signif, FR_2TOM51, FR_RSHF // Form float_N
Packit Service 82fcde
      nop.i 999
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
{ .mbb
Packit Service 82fcde
      getf.sig GR_N_fix = FR_N_signif    // Get N from significand
Packit Service 82fcde
(p10) br.cond.spnt  EXP_OVERFLOW         // Branch if result will overflow
Packit Service 82fcde
(p11) br.cond.spnt  EXP_CERTAIN_UNDERFLOW_ZERO // Branch if certain zero, uflow
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
      ldfe FR_A1 = [GR_ad_A],16          // Get A1 for main path
Packit Service 82fcde
      fnma.s1 FR_r = FR_L_hi, FR_float_N, FR_norm_x  // r = -L_hi * float_N + x
Packit Service 82fcde
      extr.u GR_M1 = GR_N_fix, 6, 6      // Extract index M_1
Packit Service 82fcde
}
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
      and GR_M2 = 0x3f, GR_N_fix         // Extract index M_2
Packit Service 82fcde
      nop.f 999
Packit Service 82fcde
      nop.i 999
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
// N_fix is only correct up to 50 bits because of our right shift technique.
Packit Service 82fcde
// Actually in the normal path we will have restricted K to about 14 bits.
Packit Service 82fcde
// Somewhat arbitrarily we extract 32 bits.
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
      shladd GR_ad_W1 = GR_M1,3,GR_ad_W1 // Point to W1
Packit Service 82fcde
      nop.f 999
Packit Service 82fcde
      extr GR_K = GR_N_fix, 12, 32       // Extract limited range K
Packit Service 82fcde
}
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
      shladd GR_ad_T1 = GR_M1,2,GR_ad_T1 // Point to T1
Packit Service 82fcde
      nop.f 999
Packit Service 82fcde
      shladd GR_ad_T2 = GR_M2,2,GR_ad_T2 // Point to T2
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
{ .mmi
Packit Service 82fcde
      ldfs  FR_T1 = [GR_ad_T1],0         // Get T1
Packit Service 82fcde
      ldfd  FR_W1 = [GR_ad_W1],0         // Get W1
Packit Service 82fcde
      add GR_exp_2_k = GR_exp_bias, GR_K // Form exponent of 2^k
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
{ .mmi
Packit Service 82fcde
      ldfs  FR_T2 = [GR_ad_T2],0         // Get T2
Packit Service 82fcde
      shladd GR_ad_W2 = GR_M2,3,GR_ad_W2 // Point to W2
Packit Service 82fcde
      sub GR_exp_2_mk = GR_exp_bias, GR_K // Form exponent of 2^-k
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
{ .mmf
Packit Service 82fcde
      ldfd  FR_W2 = [GR_ad_W2],0         // Get W2
Packit Service 82fcde
      setf.exp FR_scale = GR_exp_2_k     // Set scale = 2^k
Packit Service 82fcde
      fnma.s1 FR_r = FR_L_lo, FR_float_N, FR_r // r = -L_lo * float_N + r
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
      setf.exp FR_2_mk = GR_exp_2_mk     // Form 2^-k
Packit Service 82fcde
      fma.s1 FR_poly = FR_r, FR_A3, FR_A2 // poly = r * A3 + A2
Packit Service 82fcde
      cmp.lt p8,p15 = GR_K,GR_big_expo_neg // Set Safe if K > big_expo_neg
Packit Service 82fcde
}
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
      nop.m 999
Packit Service 82fcde
      fmpy.s1 FR_rsq = FR_r, FR_r         // rsq = r * r
Packit Service 82fcde
      nop.i 999
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
      nop.m 999
Packit Service 82fcde
      fmpy.s1 FR_T = FR_T1, FR_T2         // T = T1 * T2
Packit Service 82fcde
      nop.i 999
Packit Service 82fcde
}
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
      nop.m 999
Packit Service 82fcde
      fadd.s1 FR_W1_p1 = FR_W1, f1        // W1_p1 = W1 + 1.0
Packit Service 82fcde
      nop.i 999
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
(p7)  cmp.lt.unc  p8, p9 =  10, GR_K       // If expm1, set p8 if K > 10
Packit Service 82fcde
      fma.s1 FR_poly = FR_r, FR_poly, FR_A1 // poly = r * poly + A1
Packit Service 82fcde
      nop.i 999
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
(p7)  cmp.eq  p15, p0 =  r0, r0            // If expm1, set Safe flag
Packit Service 82fcde
      fma.s1 FR_T_scale = FR_T, FR_scale, f0 // T_scale = T * scale
Packit Service 82fcde
(p9)  cmp.gt.unc  p9, p10 =  -10, GR_K     // If expm1, set p9 if K < -10
Packit Service 82fcde
                                           // If expm1, set p10 if -10<=K<=10
Packit Service 82fcde
}
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
      nop.m 999
Packit Service 82fcde
      fma.s1 FR_W = FR_W2, FR_W1_p1, FR_W1 // W = W2 * (W1+1.0) + W1
Packit Service 82fcde
      nop.i 999
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
      nop.m 999
Packit Service 82fcde
      mov FR_Y_hi = FR_T                   // Assume Y_hi = T
Packit Service 82fcde
      nop.i 999
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
      nop.m 999
Packit Service 82fcde
      fma.s1 FR_poly = FR_rsq, FR_poly, FR_r // poly = rsq * poly + r
Packit Service 82fcde
      nop.i 999
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
      nop.m 999
Packit Service 82fcde
      fma.s1 FR_Wp1_T_scale = FR_W, FR_T_scale, FR_T_scale // (W+1)*T*scale
Packit Service 82fcde
      nop.i 999
Packit Service 82fcde
}
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
      nop.m 999
Packit Service 82fcde
      fma.s1 FR_W_T_scale = FR_W, FR_T_scale, f0 // W*T*scale
Packit Service 82fcde
      nop.i 999
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
      nop.m 999
Packit Service 82fcde
(p9)  fsub.s1 FR_Y_hi = f0, FR_2_mk      // If expm1, if K < -10 set Y_hi
Packit Service 82fcde
      nop.i 999
Packit Service 82fcde
}
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
      nop.m 999
Packit Service 82fcde
(p10) fsub.s1 FR_Y_hi = FR_T, FR_2_mk    // If expm1, if |K|<=10 set Y_hi
Packit Service 82fcde
      nop.i 999
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
      nop.m 999
Packit Service 82fcde
      fma.s1 FR_result_lo = FR_Wp1_T_scale, FR_poly, FR_W_T_scale
Packit Service 82fcde
      nop.i 999
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
.pred.rel "mutex",p8,p9
Packit Service 82fcde
// If K > 10 adjust result_lo = result_lo - scale * 2^-k
Packit Service 82fcde
// If |K| <= 10 adjust result_lo = result_lo + scale * T
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
      nop.m 999
Packit Service 82fcde
(p8)  fnma.s1 FR_result_lo = FR_scale, FR_2_mk, FR_result_lo // If K > 10
Packit Service 82fcde
      nop.i 999
Packit Service 82fcde
}
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
      nop.m 999
Packit Service 82fcde
(p9)  fma.s1 FR_result_lo = FR_T_scale, f1, FR_result_lo // If |K| <= 10
Packit Service 82fcde
      nop.i 999
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
      nop.m 999
Packit Service 82fcde
      fmpy.s0 FR_tmp = FR_A1, FR_A1         // Dummy op to set inexact
Packit Service 82fcde
      nop.i 999
Packit Service 82fcde
}
Packit Service 82fcde
{ .mfb
Packit Service 82fcde
      nop.m 999
Packit Service 82fcde
(p15) fma.s0 f8 = FR_Y_hi, FR_scale, FR_result_lo  // Safe result
Packit Service 82fcde
(p15) br.ret.sptk b0                        // Safe exit for normal path
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
// Here if unsafe, will only be here for exp with K < big_expo_neg
Packit Service 82fcde
{ .mfb
Packit Service 82fcde
      nop.m 999
Packit Service 82fcde
      fma.s0 FR_RESULT = FR_Y_hi, FR_scale, FR_result_lo  // Prelim result
Packit Service 82fcde
      br.cond.sptk EXP_POSSIBLE_UNDERFLOW  // Branch to unsafe code
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
EXP_SMALL:
Packit Service 82fcde
// Here if 2^-60 < |x| < 2^-m, m=12 for exp, m=7 for expm1
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
(p7)  ldfe FR_Q3 = [GR_ad_Q],16          // Get Q3 for small path, if expm1
Packit Service 82fcde
(p6)  fma.s1 FR_p65 = FR_P6, FR_r, FR_P5  // If exp, p65 = P6 * r + P5
Packit Service 82fcde
      nop.i 999
Packit Service 82fcde
}
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
      mov GR_minus_one = -1
Packit Service 82fcde
(p7)  fma.s1 FR_q98 = FR_Q9, FR_r, FR_Q8  // If expm1, q98 = Q9 * r + Q8
Packit Service 82fcde
      nop.i 999
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
(p7)  ldfe FR_Q2 = [GR_ad_Q],16           // Get Q2 for small path, if expm1
Packit Service 82fcde
(p7)  fma.s1 FR_q65 = FR_Q6, FR_r, FR_Q5  // If expm1, q65 = Q6 * r + Q5
Packit Service 82fcde
      nop.i 999
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
      setf.sig FR_tmp = GR_minus_one      // Create value to force inexact
Packit Service 82fcde
(p6)  fma.s1 FR_p21 = FR_P2, FR_r, FR_P1  // If exp, p21 = P2 * r + P1
Packit Service 82fcde
      nop.i 999
Packit Service 82fcde
}
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
(p7)  ldfe FR_Q1 = [GR_ad_Q],16           // Get Q1 for small path, if expm1
Packit Service 82fcde
(p7)  fma.s1 FR_q43 = FR_Q4, FR_r, FR_Q3  // If expm1, q43 = Q4 * r + Q3
Packit Service 82fcde
      nop.i 999
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
      nop.m 999
Packit Service 82fcde
(p6)  fma.s1 FR_p654 = FR_p65, FR_r, FR_P4 // If exp, p654 = p65 * r + P4
Packit Service 82fcde
      nop.i 999
Packit Service 82fcde
}
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
      nop.m 999
Packit Service 82fcde
(p7)  fma.s1 FR_q987 = FR_q98, FR_r, FR_Q7 // If expm1, q987 = q98 * r + Q7
Packit Service 82fcde
      nop.i 999
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
      nop.m 999
Packit Service 82fcde
(p7)  fma.s1 FR_q21 = FR_Q2, FR_r, FR_Q1  // If expm1, q21 = Q2 * r + Q1
Packit Service 82fcde
      nop.i 999
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
      nop.m 999
Packit Service 82fcde
(p6)  fma.s1 FR_p210 = FR_p21, FR_rsq, FR_r // If exp, p210 = p21 * r + P0
Packit Service 82fcde
      nop.i 999
Packit Service 82fcde
}
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
      nop.m 999
Packit Service 82fcde
(p7)  fma.s1 FR_q6543 = FR_q65, FR_rsq, FR_q43 // If expm1, q6543 = q65*r2+q43
Packit Service 82fcde
      nop.i 999
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
      nop.m 999
Packit Service 82fcde
(p6)  fma.s1 FR_p6543 = FR_p654, FR_r, FR_P3 // If exp, p6543 = p654 * r + P3
Packit Service 82fcde
      nop.i 999
Packit Service 82fcde
}
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
      nop.m 999
Packit Service 82fcde
(p7)  fma.s1 FR_q9876543 = FR_q987, FR_r4, FR_q6543 // If expm1, q9876543 = ...
Packit Service 82fcde
      nop.i 999
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
      nop.m 999
Packit Service 82fcde
(p6)  fma.s1 FR_Y_lo = FR_p6543, FR_r4, FR_p210 // If exp, form Y_lo
Packit Service 82fcde
      nop.i 999
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
      nop.m 999
Packit Service 82fcde
(p7)  fma.s1 FR_Y_lo = FR_q9876543, FR_rsq, FR_q21 // If expm1, form Y_lo
Packit Service 82fcde
      nop.i 999
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
      nop.m 999
Packit Service 82fcde
      fmpy.s0  FR_tmp = FR_tmp, FR_tmp   // Dummy op to set inexact
Packit Service 82fcde
      nop.i 999
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
.pred.rel "mutex",p6,p7
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
      nop.m 999
Packit Service 82fcde
(p6)  fma.s0 f8 = FR_Y_lo, f1, f1          // If exp, result = 1 + Y_lo
Packit Service 82fcde
      nop.i 999
Packit Service 82fcde
}
Packit Service 82fcde
{ .mfb
Packit Service 82fcde
      nop.m 999
Packit Service 82fcde
(p7)  fma.s0 f8 = FR_Y_lo, FR_rsq, FR_norm_x // If expm1, result = Y_lo*r2+x
Packit Service 82fcde
      br.ret.sptk  b0                      // Exit for 2^-60 <= |x| < 2^-m
Packit Service 82fcde
                                           // m=12 for exp, m=7 for expm1
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
EXP_VERY_SMALL:
Packit Service 82fcde
//
Packit Service 82fcde
// Here if 0 < |x| < 2^-60
Packit Service 82fcde
// If exp, result = 1.0 + x
Packit Service 82fcde
// If expm1, result = x +x*x/2, but have to check for possible underflow
Packit Service 82fcde
//
Packit Service 82fcde
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
(p7)  mov GR_exp_underflow = -16381        // Exponent for possible underflow
Packit Service 82fcde
(p6)  fadd.s0 f8 = f1, FR_norm_x           // If exp, result = 1+x
Packit Service 82fcde
      nop.i 999
Packit Service 82fcde
}
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
      nop.m 999
Packit Service 82fcde
(p7)  fmpy.s1 FR_result_lo = FR_half_x, FR_norm_x  // If expm1 result_lo = x*x/2
Packit Service 82fcde
      nop.i 999
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
(p7)  cmp.lt.unc p0, p8 = GR_exp_x, GR_exp_underflow // Unsafe if expm1 x small
Packit Service 82fcde
(p7)  mov FR_Y_hi = FR_norm_x              // If expm1, Y_hi = x
Packit Service 82fcde
(p7)  cmp.lt p0, p15 = GR_exp_x, GR_exp_underflow // Unsafe if expm1 x small
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
{ .mfb
Packit Service 82fcde
      nop.m 999
Packit Service 82fcde
(p8)  fma.s0 f8 = FR_norm_x, f1, FR_result_lo // If expm1, result=x+x*x/2
Packit Service 82fcde
(p15) br.ret.sptk b0                       // If Safe, exit
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
// Here if expm1 and 0 < |x| < 2^-16381;  may be possible underflow
Packit Service 82fcde
{ .mfb
Packit Service 82fcde
      nop.m 999
Packit Service 82fcde
      fma.s0 FR_RESULT = FR_Y_hi, FR_scale, FR_result_lo // Prelim result
Packit Service 82fcde
      br.cond.sptk EXP_POSSIBLE_UNDERFLOW  // Branch to unsafe code
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
EXP_CERTAIN_UNDERFLOW_ZERO:
Packit Service 82fcde
// Here if x < zero_uflow_x
Packit Service 82fcde
// For exp, set result to tiny+0.0 and set I, U, and branch to error handling
Packit Service 82fcde
// For expm1, set result to tiny-1.0 and set I, and exit
Packit Service 82fcde
{ .mmi
Packit Service 82fcde
      alloc GR_SAVE_PFS = ar.pfs,0,3,4,0
Packit Service 82fcde
      nop.m 999
Packit Service 82fcde
      mov GR_one = 1
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
{ .mmi
Packit Service 82fcde
      setf.exp FR_small = GR_one               // Form small value
Packit Service 82fcde
      nop.m 999
Packit Service 82fcde
(p6)  mov GR_Parameter_TAG = 13                // Error tag for exp underflow
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
      nop.m 999
Packit Service 82fcde
      fmerge.s FR_X = f8,f8                    // Save x for error call
Packit Service 82fcde
      nop.i 999
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
.pred.rel "mutex",p6,p7
Packit Service 82fcde
{ .mfb
Packit Service 82fcde
      nop.m 999
Packit Service 82fcde
(p6)  fma.s0 FR_RESULT = FR_small, FR_small, f0 // If exp, set I,U, tiny result
Packit Service 82fcde
(p6)  br.cond.sptk __libm_error_region          // If exp, go to error handling
Packit Service 82fcde
}
Packit Service 82fcde
{ .mfb
Packit Service 82fcde
      nop.m 999
Packit Service 82fcde
(p7)  fms.s0 f8 = FR_small, FR_small, f1        // If expm1, set I, result -1.0
Packit Service 82fcde
(p7)  br.ret.sptk  b0                           // If expm1, exit
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
EXP_OVERFLOW:
Packit Service 82fcde
// Here if x >= min_oflow_x
Packit Service 82fcde
{ .mmi
Packit Service 82fcde
      alloc GR_SAVE_PFS = ar.pfs,0,3,4,0
Packit Service 82fcde
      mov GR_huge_exp = 0x1fffe
Packit Service 82fcde
      nop.i 999
Packit Service 82fcde
}
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
      mov GR_huge_signif = -0x1
Packit Service 82fcde
      nop.f 999
Packit Service 82fcde
(p6)  mov GR_Parameter_TAG = 12                // Error tag for exp overflow
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
{ .mmf
Packit Service 82fcde
      setf.exp FR_huge_exp = GR_huge_exp       // Create huge value
Packit Service 82fcde
      setf.sig FR_huge_signif = GR_huge_signif // Create huge value
Packit Service 82fcde
      fmerge.s FR_X = f8,f8                    // Save x for error call
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
      nop.m 999
Packit Service 82fcde
      fmerge.se FR_huge = FR_huge_exp, FR_huge_signif
Packit Service 82fcde
(p7)  mov GR_Parameter_TAG = 39                // Error tag for expm1 overflow
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
{ .mfb
Packit Service 82fcde
      nop.m 999
Packit Service 82fcde
      fma.s0 FR_RESULT = FR_huge, FR_huge, FR_huge // Force I, O, and Inf
Packit Service 82fcde
      br.cond.sptk __libm_error_region         // Branch to error handling
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
EXP_POSSIBLE_UNDERFLOW:
Packit Service 82fcde
// Here if exp and zero_uflow_x < x < about -11356 [where k < -16381]
Packit Service 82fcde
// Here if expm1 and |x| < 2^-16381
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
      alloc GR_SAVE_PFS = ar.pfs,0,3,4,0
Packit Service 82fcde
      fsetc.s2 0x7F,0x41                   // Set FTZ and disable traps
Packit Service 82fcde
      nop.i 999
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
      nop.m 999
Packit Service 82fcde
      fma.s2 FR_ftz = FR_Y_hi, FR_scale, FR_result_lo   // Result with FTZ
Packit Service 82fcde
      nop.i 999
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
      nop.m 999
Packit Service 82fcde
      fsetc.s2 0x7F,0x40                   // Disable traps (set s2 default)
Packit Service 82fcde
      nop.i 999
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
      nop.m 999
Packit Service 82fcde
(p6)  fclass.m.unc p11, p0 = FR_ftz, 0x00F // If exp, FTZ result denorm or zero?
Packit Service 82fcde
      nop.i 999
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
{ .mfb
Packit Service 82fcde
(p11) mov   GR_Parameter_TAG = 13             // exp underflow
Packit Service 82fcde
      fmerge.s FR_X = f8,f8                   // Save x for error call
Packit Service 82fcde
(p11) br.cond.spnt __libm_error_region        // Branch on exp underflow
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
{ .mfb
Packit Service 82fcde
      nop.m 999
Packit Service 82fcde
      mov   f8     = FR_RESULT                // Was safe after all
Packit Service 82fcde
      br.ret.sptk   b0
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
EXP_64_SPECIAL:
Packit Service 82fcde
// Here if x natval, nan, inf, zero
Packit Service 82fcde
// If x natval, +inf, or if expm1 and x zero, just return x.
Packit Service 82fcde
// The other cases must be tested for, and results set.
Packit Service 82fcde
// These cases do not generate exceptions.
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
      nop.m 999
Packit Service 82fcde
      fclass.m p8, p0 =  f8, 0x0c3            // Is x nan?
Packit Service 82fcde
      nop.i 999
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
      nop.m 999
Packit Service 82fcde
(p6)  fclass.m.unc p13, p0 =  f8, 0x007       // If exp, is x zero?
Packit Service 82fcde
      nop.i 999
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
      nop.m 999
Packit Service 82fcde
(p6)  fclass.m.unc p11, p0 =  f8, 0x022       // If exp, is x -inf?
Packit Service 82fcde
      nop.i 999
Packit Service 82fcde
}
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
      nop.m 999
Packit Service 82fcde
(p8)  fadd.s0 f8 = f8, f1                     // If x nan, result quietized x
Packit Service 82fcde
      nop.i 999
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
      nop.m 999
Packit Service 82fcde
(p7)  fclass.m.unc p10, p0 =  f8, 0x022       // If expm1, is x -inf?
Packit Service 82fcde
      nop.i 999
Packit Service 82fcde
}
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
      nop.m 999
Packit Service 82fcde
(p13) fadd.s0 f8 = f0, f1                     // If exp and x zero, result 1.0
Packit Service 82fcde
      nop.i 999
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
      nop.m 999
Packit Service 82fcde
(p11) mov f8 = f0                             // If exp and x -inf, result 0
Packit Service 82fcde
      nop.i 999
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
{ .mfb
Packit Service 82fcde
      nop.m 999
Packit Service 82fcde
(p10) fsub.s1 f8 = f0, f1                     // If expm1, x -inf, result -1.0
Packit Service 82fcde
      br.ret.sptk b0                          // Exit special cases
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
EXP_64_UNSUPPORTED:
Packit Service 82fcde
// Here if x unsupported type
Packit Service 82fcde
{ .mfb
Packit Service 82fcde
      nop.m 999
Packit Service 82fcde
      fmpy.s0 f8 = f8, f0                     // Return nan
Packit Service 82fcde
      br.ret.sptk   b0
Packit Service 82fcde
}
Packit Service 82fcde
;;
Packit Service 82fcde
Packit Service 82fcde
GLOBAL_IEEE754_END(expl)
Packit Service 82fcde
libm_alias_ldouble_other (__exp, exp)
Packit Service 82fcde
Packit Service 82fcde
LOCAL_LIBM_ENTRY(__libm_error_region)
Packit Service 82fcde
.prologue
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
        add   GR_Parameter_Y=-32,sp             // Parameter 2 value
Packit Service 82fcde
        nop.f 0
Packit Service 82fcde
.save   ar.pfs,GR_SAVE_PFS
Packit Service 82fcde
        mov  GR_SAVE_PFS=ar.pfs                 // Save ar.pfs
Packit Service 82fcde
}
Packit Service 82fcde
{ .mfi
Packit Service 82fcde
.fframe 64
Packit Service 82fcde
        add sp=-64,sp                           // Create new stack
Packit Service 82fcde
        nop.f 0
Packit Service 82fcde
        mov GR_SAVE_GP=gp                       // Save gp
Packit Service 82fcde
};;
Packit Service 82fcde
{ .mmi
Packit Service 82fcde
        stfe [GR_Parameter_Y] = FR_Y,16         // Save Parameter 2 on stack
Packit Service 82fcde
        add GR_Parameter_X = 16,sp              // Parameter 1 address
Packit Service 82fcde
.save   b0, GR_SAVE_B0
Packit Service 82fcde
        mov GR_SAVE_B0=b0                       // Save b0
Packit Service 82fcde
};;
Packit Service 82fcde
.body
Packit Service 82fcde
{ .mib
Packit Service 82fcde
        stfe [GR_Parameter_X] = FR_X            // Store Parameter 1 on stack
Packit Service 82fcde
        add   GR_Parameter_RESULT = 0,GR_Parameter_Y
Packit Service 82fcde
        nop.b 0                                 // Parameter 3 address
Packit Service 82fcde
}
Packit Service 82fcde
{ .mib
Packit Service 82fcde
        stfe [GR_Parameter_Y] = FR_RESULT      // Store Parameter 3 on stack
Packit Service 82fcde
        add   GR_Parameter_Y = -16,GR_Parameter_Y
Packit Service 82fcde
        br.call.sptk b0=__libm_error_support#  // Call error handling function
Packit Service 82fcde
};;
Packit Service 82fcde
{ .mmi
Packit Service 82fcde
        add   GR_Parameter_RESULT = 48,sp
Packit Service 82fcde
        nop.m 0
Packit Service 82fcde
        nop.i 0
Packit Service 82fcde
};;
Packit Service 82fcde
{ .mmi
Packit Service 82fcde
        ldfe  f8 = [GR_Parameter_RESULT]       // Get return result off stack
Packit Service 82fcde
.restore sp
Packit Service 82fcde
        add   sp = 64,sp                       // Restore stack pointer
Packit Service 82fcde
        mov   b0 = GR_SAVE_B0                  // Restore return address
Packit Service 82fcde
};;
Packit Service 82fcde
{ .mib
Packit Service 82fcde
        mov   gp = GR_SAVE_GP                  // Restore gp
Packit Service 82fcde
        mov   ar.pfs = GR_SAVE_PFS             // Restore ar.pfs
Packit Service 82fcde
        br.ret.sptk     b0                     // Return
Packit Service 82fcde
};;
Packit Service 82fcde
LOCAL_LIBM_END(__libm_error_region#)
Packit Service 82fcde
Packit Service 82fcde
.type   __libm_error_support#,@function
Packit Service 82fcde
.global __libm_error_support#