.file "tgammal.s"
// Copyright (c) 2002 - 2005, Intel Corporation
// All rights reserved.
//
// Contributed 2002 by the Intel Numerics Group, Intel Corporation
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote
// products derived from this software without specific prior written
// permission.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Intel Corporation is the author of this code, and requests that all
// problem reports or change requests be submitted to it directly at
// http://www.intel.com/software/products/opensource/libraries/num.htm.
//
// History
//==============================================================
// 01/16/02 Initial version
// 05/20/02 Cleaned up namespace and sf0 syntax
// 02/10/03 Reordered header: .section, .global, .proc, .align;
// used data8 for long double table values
// 03/17/03 Moved tgammal_libm_err label into .proc region
// 04/10/03 Changed error codes for overflow and negative integers
// 03/31/05 Reformatted delimiters between data tables
//
// API
//==============================================================
// long double tgammal(long double)
//
// Resources Used:
//
// Floating-Point Registers: f8-f15
// f32-f127
//
// General Purpose Registers: r32-r67
//
// Predicate Registers: p6-p15
//
//*********************************************************************
//
// IEEE Special Conditions:
//
// tgammal(+inf) = +inf
// tgammal(-inf) = QNaN
// tgammal(+/-0) = +/-inf
// tgammal(x<0, x - integer) = QNaN
// tgammal(SNaN) = QNaN
// tgammal(QNaN) = QNaN
//
//*********************************************************************
// Overview of operation
//==============================================================
//
// Algorithm description
// ---------------------
//
// There are 3 main paths in the implementation
// (and additional special values branches)
//
// 1) |X| >= 13 - Stirling formula computation
// a) Positive arguments:
// TGAMMAL(X) = exp((X-0.5)*ln(X) - X + C + S(Z)),
// where C = 0.5*ln(2*Pi) , Z = 1/Z, S(Z) - Bernulli polynomial
// (up to 'B18' term).
// Some of these calculation done in multiprecision.
// Ln returns multiprecision result too
// and exp also accepts and returns pair of values.
//
// b) Negative arguments
// TGAMMAL(-X) = PI/(X*TGAMMAL(X)*sin(PI*X)).
// (X*sin(PI*X))/PI calculated in parallel with TGAMMAL.
// Here we use polynomial of 9th degree with 2 multiprecision steps.
// Argument range reduction is:
// N = [x] with round to nearest, r = x - N, -0.5 <= r < 0.5
// After ((X-0.5)*ln(X) - X + C + S(Z)) completed we just invert
// its result and compute exp with negative argument (1/exp(x)=exp(-x))
// Then we multiply exp result to PI/(X*sin(PI*X)).
//
// 2) 1 <= |X| < 13 - Polynomial part
// a) Positive arguments:
// All values are splitted to such intervals as:
// #0->[2;3], #1->[3,4], #2->[5,6]...
// For even intervals we just use polynomial computation with degree 20
// and first 6 multiprecision computations.
// Range reduction looks like
// N = [x] with truncate, r = x - N - 0.5, -0.5 <= r < 0.5
// For odd intervals we use reccurent formula:
// TGAMMAL(X) = TGAMMA(X-1)*(X-1)
// [1;2] interval is splitted to 3 subranges:
// [1;1.25], [1.25;1.75], [1.75;2] with the same polynomial forms
//
// b) Negative arguments
// TGAMMAL(-X) = PI/(X*TGAMMAL(X)*sin(PI*X)).
// (X*sin(PI*X))/PI calculated in parallel with TGAMMAL.
// After multiplication by TGAMMAL(X) result we calculate reciprocal
// and get final result.
//
// 3) 0 < |X| < 1 - Near 0 part
// a) Here we use reccurent formula TGAMMAL(X) = TGAMMAL(X+1)/X
// TGAMMAL(X+1) calculated as shown above,
// 1/X result obtained in parallel. Then we just multiply these values.
// There is only additional separated subrange: [0;0.125] with specific
// polynomial constants set.
//
// b) Negative arguments
// TGAMMAL(-X) = PI/(TGAMMAL(X+1)*sin(PI*X)).
// There is no need to compute 1/X.
RODATA
.align 16
LOCAL_OBJECT_START(Constants_Tgammal_log_80_Q)
// log2_hi, log2_lo, Q_6, Q_5, Q_4, Q_3, Q_2, Q_1
data4 0x00000000,0xB1721800,0x00003FFE,0x00000000
data4 0x4361C4C6,0x82E30865,0x0000BFE2,0x00000000
data4 0xA51BE0AF,0x92492453,0x00003FFC,0x00000000
data4 0xA0CFD29F,0xAAAAAB73,0x0000BFFC,0x00000000
data4 0xCCCE3872,0xCCCCCCCC,0x00003FFC,0x00000000
data4 0xFFFFB4FB,0xFFFFFFFF,0x0000BFFC,0x00000000
data4 0xAAAAAAAB,0xAAAAAAAA,0x00003FFD,0x00000000
data4 0x00000000,0x80000000,0x0000BFFE,0x00000000
LOCAL_OBJECT_END(Constants_Tgammal_log_80_Q)
.align 64
LOCAL_OBJECT_START(Constants_Tgammal_log_80_Z_G_H_h1)
// Z1 - 16 bit fixed, G1 and H1 IEEE single, h1 IEEE double
data4 0x00008000,0x3F800000,0x00000000,0x00000000
data4 0x00000000,0x00000000,0x00000000,0x00000000
data4 0x00007879,0x3F70F0F0,0x3D785196,0x00000000
data4 0xEBA0E0D1,0x8B1D330B,0x00003FDA,0x00000000
data4 0x000071C8,0x3F638E38,0x3DF13843,0x00000000
data4 0x9EADD553,0xE2AF365E,0x00003FE2,0x00000000
data4 0x00006BCB,0x3F579430,0x3E2FF9A0,0x00000000
data4 0x752F34A2,0xF585FEC3,0x0000BFE3,0x00000000
data4 0x00006667,0x3F4CCCC8,0x3E647FD6,0x00000000
data4 0x893B03F3,0xF3546435,0x00003FE2,0x00000000
data4 0x00006187,0x3F430C30,0x3E8B3AE7,0x00000000
data4 0x39CDD2AC,0xBABA62E0,0x00003FE4,0x00000000
data4 0x00005D18,0x3F3A2E88,0x3EA30C68,0x00000000
data4 0x457978A1,0x8718789F,0x00003FE2,0x00000000
data4 0x0000590C,0x3F321640,0x3EB9CEC8,0x00000000
data4 0x3185E56A,0x9442DF96,0x0000BFE4,0x00000000
data4 0x00005556,0x3F2AAAA8,0x3ECF9927,0x00000000
data4 0x2BBE2CBD,0xCBF9A4BF,0x00003FE4,0x00000000
data4 0x000051EC,0x3F23D708,0x3EE47FC5,0x00000000
data4 0x852D5935,0xF3537535,0x00003FE3,0x00000000
data4 0x00004EC5,0x3F1D89D8,0x3EF8947D,0x00000000
data4 0x46CDF32F,0xA1F1E699,0x0000BFDF,0x00000000
data4 0x00004BDB,0x3F17B420,0x3F05F3A1,0x00000000
data4 0xD8484CE3,0x84A61856,0x00003FE4,0x00000000
data4 0x00004925,0x3F124920,0x3F0F4303,0x00000000
data4 0xFF28821B,0xC7DD97E0,0x0000BFE2,0x00000000
data4 0x0000469F,0x3F0D3DC8,0x3F183EBF,0x00000000
data4 0xEF1FD32F,0xD3C4A887,0x00003FE3,0x00000000
data4 0x00004445,0x3F088888,0x3F20EC80,0x00000000
data4 0x464C76DA,0x84672BE6,0x00003FE5,0x00000000
data4 0x00004211,0x3F042108,0x3F29516A,0x00000000
data4 0x18835FB9,0x9A43A511,0x0000BFE5,0x00000000
LOCAL_OBJECT_END(Constants_Tgammal_log_80_Z_G_H_h1)
.align 64
LOCAL_OBJECT_START(Constants_Tgammal_log_80_Z_G_H_h2)
// Z2 - 16 bit fixed, G2 and H2 IEEE single, h2 IEEE double
data4 0x00008000,0x3F800000,0x00000000,0x00000000
data4 0x00000000,0x00000000,0x00000000,0x00000000
data4 0x00007F81,0x3F7F00F8,0x3B7F875D,0x00000000
data4 0x211398BF,0xAD08B116,0x00003FDB,0x00000000
data4 0x00007F02,0x3F7E03F8,0x3BFF015B,0x00000000
data4 0xC376958E,0xB106790F,0x00003FDE,0x00000000
data4 0x00007E85,0x3F7D08E0,0x3C3EE393,0x00000000
data4 0x79A7679A,0xFD03F242,0x0000BFDA,0x00000000
data4 0x00007E08,0x3F7C0FC0,0x3C7E0586,0x00000000
data4 0x05E7AE08,0xF03F81C3,0x0000BFDF,0x00000000
data4 0x00007D8D,0x3F7B1880,0x3C9E75D2,0x00000000
data4 0x049EB22F,0xD1B87D3C,0x00003FDE,0x00000000
data4 0x00007D12,0x3F7A2328,0x3CBDC97A,0x00000000
data4 0x3A9E81E0,0xFABC8B95,0x00003FDF,0x00000000
data4 0x00007C98,0x3F792FB0,0x3CDCFE47,0x00000000
data4 0x7C4B5443,0xF5F3653F,0x00003FDF,0x00000000
data4 0x00007C20,0x3F783E08,0x3CFC15D0,0x00000000
data4 0xF65A1773,0xE78AB204,0x00003FE0,0x00000000
data4 0x00007BA8,0x3F774E38,0x3D0D874D,0x00000000
data4 0x7B8EF695,0xDB7CBFFF,0x0000BFE0,0x00000000
data4 0x00007B31,0x3F766038,0x3D1CF49B,0x00000000
data4 0xCF773FB3,0xC0241AEA,0x0000BFE0,0x00000000
data4 0x00007ABB,0x3F757400,0x3D2C531D,0x00000000
data4 0xC9539FDF,0xFC8F4D48,0x00003FE1,0x00000000
data4 0x00007A45,0x3F748988,0x3D3BA322,0x00000000
data4 0x954665C2,0x9CD035FB,0x0000BFE1,0x00000000
data4 0x000079D1,0x3F73A0D0,0x3D4AE46F,0x00000000
data4 0xDD367A30,0xEC9017C7,0x00003FE1,0x00000000
data4 0x0000795D,0x3F72B9D0,0x3D5A1756,0x00000000
data4 0xCB11189C,0xEE6625D3,0x0000BFE1,0x00000000
data4 0x000078EB,0x3F71D488,0x3D693B9D,0x00000000
data4 0xBE11C424,0xA49C8DB5,0x0000BFE0,0x00000000
LOCAL_OBJECT_END(Constants_Tgammal_log_80_Z_G_H_h2)
.align 64
LOCAL_OBJECT_START(Constants_Tgammal_log_80_h3_G_H)
// h3 IEEE double extended, H3 and G3 IEEE single
data4 0x112666B0,0xAAACAAB1,0x00003FD3,0x3F7FFC00
data4 0x9B7FAD21,0x90051030,0x00003FD8,0x3F7FF400
data4 0xF4D783C4,0xA6B46F46,0x00003FDA,0x3F7FEC00
data4 0x11C6DDCA,0xDA148D88,0x0000BFD8,0x3F7FE400
data4 0xCA964D95,0xCE65C1D8,0x0000BFD8,0x3F7FDC00
data4 0x23412D13,0x883838EE,0x0000BFDB,0x3F7FD400
data4 0x983ED687,0xB7E5CFA1,0x00003FDB,0x3F7FCC08
data4 0xE3C3930B,0xDBE23B16,0x0000BFD9,0x3F7FC408
data4 0x48AA4DFC,0x9B92F1FC,0x0000BFDC,0x3F7FBC10
data4 0xCE9C8F7E,0x9A8CEB15,0x0000BFD9,0x3F7FB410
data4 0x0DECE74A,0x8C220879,0x00003FDC,0x3F7FAC18
data4 0x2F053150,0xB25CA912,0x0000BFDA,0x3F7FA420
data4 0xD9A5BE20,0xA5876555,0x00003FDB,0x3F7F9C20
data4 0x2053F087,0xC919BB6E,0x00003FD9,0x3F7F9428
data4 0x041E9A77,0xB70BDA79,0x00003FDC,0x3F7F8C30
data4 0xEA1C9C30,0xF18A5C08,0x00003FDA,0x3F7F8438
data4 0x796D89E5,0xA3790D84,0x0000BFDD,0x3F7F7C40
data4 0xA2915A3A,0xE1852369,0x0000BFDD,0x3F7F7448
data4 0xA39ED868,0xD803858F,0x00003FDC,0x3F7F6C50
data4 0x9417EBB7,0xB2EEE356,0x0000BFDD,0x3F7F6458
data4 0x9BB0D07F,0xED5C1F8A,0x0000BFDC,0x3F7F5C68
data4 0xE87C740A,0xD6D201A0,0x0000BFDD,0x3F7F5470
data4 0x1CA74025,0xE8DEBF5E,0x00003FDC,0x3F7F4C78
data4 0x1F34A7EB,0x9A995A97,0x0000BFDC,0x3F7F4488
data4 0x359EED97,0x9CB0F742,0x0000BFDA,0x3F7F3C90
data4 0xBBC6A1C8,0xD6F833C2,0x0000BFDD,0x3F7F34A0
data4 0xE71090EC,0xE1F68F2A,0x00003FDC,0x3F7F2CA8
data4 0xC160A74F,0xD1881CF1,0x0000BFDB,0x3F7F24B8
data4 0xD78CB5A4,0x9AD05AE2,0x00003FD6,0x3F7F1CC8
data4 0x9A77DC4B,0xE658CB8E,0x0000BFDD,0x3F7F14D8
data4 0x6BD6D312,0xBA281296,0x00003FDC,0x3F7F0CE0
data4 0xF95210D0,0xB478BBEB,0x0000BFDB,0x3F7F04F0
data4 0x38800100,0x39400480,0x39A00640,0x39E00C41 // H's start here
data4 0x3A100A21,0x3A300F22,0x3A4FF51C,0x3A6FFC1D
data4 0x3A87F20B,0x3A97F68B,0x3AA7EB86,0x3AB7E101
data4 0x3AC7E701,0x3AD7DD7B,0x3AE7D474,0x3AF7CBED
data4 0x3B03E1F3,0x3B0BDE2F,0x3B13DAAA,0x3B1BD766
data4 0x3B23CC5C,0x3B2BC997,0x3B33C711,0x3B3BBCC6
data4 0x3B43BAC0,0x3B4BB0F4,0x3B53AF6D,0x3B5BA620
data4 0x3B639D12,0x3B6B9444,0x3B7393BC,0x3B7B8B6D
LOCAL_OBJECT_END(Constants_Tgammal_log_80_h3_G_H)
.align 64
LOCAL_OBJECT_START(Constants_Tgammal_stirling)
//0.5*ln(2*Pi)=9.1893853320467266954096885e-01 + 7.2239360881843238220057778e-17
data8 0x3FED67F1C864BEB4, 0x3C94D252F2400510
// Bernulli numbers
data8 0xAAAAAAAAAAAAAAAB, 0x00003FFB //B2 = 8.3333333333333333333333333333e-02
data8 0xBF66C16C16C16C17 //B4 = -2.7777777777777777777777777778e-03
data8 0x3F4A01A01A01A01A //B6 = 7.9365079365079365079365079365e-04
data8 0xBF43813813813814 //B8 = -5.9523809523809523809523809524e-04
data8 0x3F4B951E2B18FF23 //B10 = 8.4175084175084175084175084175e-04
data8 0xBF5F6AB0D9993C7D //B12 = -1.9175269175269175269175269175e-03
data8 0x3F7A41A41A41A41A //B14 = 6.4102564102564102564102564103e-03
data8 0xBF9E4286CB0F5398 //B16 = -2.9550653594771241830065359477e-02
data8 0x3FC6FE96381E0680 //B18 = 1.7964437236883057316493849002e-01
data8 0x3FE0000000000000 // 0.5
LOCAL_OBJECT_END(Constants_Tgammal_stirling)
.align 64
LOCAL_OBJECT_START(Constants_Tgammal_sin)
// Polynomial coefficients for the sin(Pi*x)/Pi, 0 <= |x| < 0.5
//A2 = 8.1174242528335360802316245099e-01 + 5.1302254650266899774269946201e-18
data8 0x3FE9F9CB402BC46C, 0x3C57A8B3819B7CEC
//A1 = -1.6449340668482264060656916627e+00 + -3.0210280454695477893051351574e-17
data8 0xBFFA51A6625307D3, 0xBC816A402079D0EF
data8 0xF3AEF1FFCCE6C813, 0x0000BFE3 //A9 = -7.0921197799923779127089910470e-09
data8 0x87D54408E6D4BB9D, 0x00003FE9 //A8 = 2.5300880778252693946712766029e-07
data8 0xEA12033DCE7B8ED9, 0x0000BFED //A7 = -6.9758403885461690048189307819e-06
data8 0x9BA38C952A59D1A8, 0x00003FF2 //A6 = 1.4842878710882320255092707181e-04
data8 0x99C0B55178FF0E38, 0x0000BFF6 //A5 = -2.3460810348048124421268761990e-03
data8 0xD63402E798FEC896, 0x00003FF9 //A4 = 2.6147847817611456327417812320e-02
data8 0xC354723906D95E92, 0x0000BFFC //A3 = -1.9075182412208257558294507774e-01
LOCAL_OBJECT_END(Constants_Tgammal_sin)
.align 64
LOCAL_OBJECT_START(Constants_Tgammal_exp_64_Arg)
data4 0x00000000,0xB17217F4,0x00003FF2,0x00000000 // L_hi = hi part log(2)/2^12
data4 0xF278ECE6,0xF473DE6A,0x00003FD4,0x00000000 // L_lo = lo part log(2)/2^12
LOCAL_OBJECT_END(Constants_Tgammal_exp_64_Arg)
LOCAL_OBJECT_START(Constants_Tgammal_exp_64_A)
data4 0xB1B736A0,0xAAAAAAAB,0x00003FFA,0x00000000 // A3
data4 0x90CD6327,0xAAAAAAAB,0x00003FFC,0x00000000 // A2
data4 0xFFFFFFFF,0xFFFFFFFF,0x00003FFD,0x00000000 // A1
LOCAL_OBJECT_END(Constants_Tgammal_exp_64_A)
LOCAL_OBJECT_START(Constants_Tgammal_exp_64_T1)
data4 0x3F800000,0x3F8164D2,0x3F82CD87,0x3F843A29
data4 0x3F85AAC3,0x3F871F62,0x3F88980F,0x3F8A14D5
data4 0x3F8B95C2,0x3F8D1ADF,0x3F8EA43A,0x3F9031DC
data4 0x3F91C3D3,0x3F935A2B,0x3F94F4F0,0x3F96942D
data4 0x3F9837F0,0x3F99E046,0x3F9B8D3A,0x3F9D3EDA
data4 0x3F9EF532,0x3FA0B051,0x3FA27043,0x3FA43516
data4 0x3FA5FED7,0x3FA7CD94,0x3FA9A15B,0x3FAB7A3A
data4 0x3FAD583F,0x3FAF3B79,0x3FB123F6,0x3FB311C4
data4 0x3FB504F3,0x3FB6FD92,0x3FB8FBAF,0x3FBAFF5B
data4 0x3FBD08A4,0x3FBF179A,0x3FC12C4D,0x3FC346CD
data4 0x3FC5672A,0x3FC78D75,0x3FC9B9BE,0x3FCBEC15
data4 0x3FCE248C,0x3FD06334,0x3FD2A81E,0x3FD4F35B
data4 0x3FD744FD,0x3FD99D16,0x3FDBFBB8,0x3FDE60F5
data4 0x3FE0CCDF,0x3FE33F89,0x3FE5B907,0x3FE8396A
data4 0x3FEAC0C7,0x3FED4F30,0x3FEFE4BA,0x3FF28177
data4 0x3FF5257D,0x3FF7D0DF,0x3FFA83B3,0x3FFD3E0C
LOCAL_OBJECT_END(Constants_Tgammal_exp_64_T1)
LOCAL_OBJECT_START(Constants_Tgammal_exp_64_T2)
data4 0x3F800000,0x3F80058C,0x3F800B18,0x3F8010A4
data4 0x3F801630,0x3F801BBD,0x3F80214A,0x3F8026D7
data4 0x3F802C64,0x3F8031F2,0x3F803780,0x3F803D0E
data4 0x3F80429C,0x3F80482B,0x3F804DB9,0x3F805349
data4 0x3F8058D8,0x3F805E67,0x3F8063F7,0x3F806987
data4 0x3F806F17,0x3F8074A8,0x3F807A39,0x3F807FCA
data4 0x3F80855B,0x3F808AEC,0x3F80907E,0x3F809610
data4 0x3F809BA2,0x3F80A135,0x3F80A6C7,0x3F80AC5A
data4 0x3F80B1ED,0x3F80B781,0x3F80BD14,0x3F80C2A8
data4 0x3F80C83C,0x3F80CDD1,0x3F80D365,0x3F80D8FA
data4 0x3F80DE8F,0x3F80E425,0x3F80E9BA,0x3F80EF50
data4 0x3F80F4E6,0x3F80FA7C,0x3F810013,0x3F8105AA
data4 0x3F810B41,0x3F8110D8,0x3F81166F,0x3F811C07
data4 0x3F81219F,0x3F812737,0x3F812CD0,0x3F813269
data4 0x3F813802,0x3F813D9B,0x3F814334,0x3F8148CE
data4 0x3F814E68,0x3F815402,0x3F81599C,0x3F815F37
LOCAL_OBJECT_END(Constants_Tgammal_exp_64_T2)
LOCAL_OBJECT_START(Constants_Tgammal_exp_64_W1)
data8 0x0000000000000000, 0xBE384454171EC4B4
data8 0xBE6947414AA72766, 0xBE5D32B6D42518F8
data8 0x3E68D96D3A319149, 0xBE68F4DA62415F36
data8 0xBE6DDA2FC9C86A3B, 0x3E6B2E50F49228FE
data8 0xBE49C0C21188B886, 0x3E64BFC21A4C2F1F
data8 0xBE6A2FBB2CB98B54, 0x3E5DC5DE9A55D329
data8 0x3E69649039A7AACE, 0x3E54728B5C66DBA5
data8 0xBE62B0DBBA1C7D7D, 0x3E576E0409F1AF5F
data8 0x3E6125001A0DD6A1, 0xBE66A419795FBDEF
data8 0xBE5CDE8CE1BD41FC, 0xBE621376EA54964F
data8 0x3E6370BE476E76EE, 0x3E390D1A3427EB92
data8 0x3E1336DE2BF82BF8, 0xBE5FF1CBD0F7BD9E
data8 0xBE60A3550CEB09DD, 0xBE5CA37E0980F30D
data8 0xBE5C541B4C082D25, 0xBE5BBECA3B467D29
data8 0xBE400D8AB9D946C5, 0xBE5E2A0807ED374A
data8 0xBE66CB28365C8B0A, 0x3E3AAD5BD3403BCA
data8 0x3E526055C7EA21E0, 0xBE442C75E72880D6
data8 0x3E58B2BB85222A43, 0xBE5AAB79522C42BF
data8 0xBE605CB4469DC2BC, 0xBE589FA7A48C40DC
data8 0xBE51C2141AA42614, 0xBE48D087C37293F4
data8 0x3E367A1CA2D673E0, 0xBE51BEBB114F7A38
data8 0xBE6348E5661A4B48, 0xBDF526431D3B9962
data8 0x3E3A3B5E35A78A53, 0xBE46C46C1CECD788
data8 0xBE60B7EC7857D689, 0xBE594D3DD14F1AD7
data8 0xBE4F9C304C9A8F60, 0xBE52187302DFF9D2
data8 0xBE5E4C8855E6D68F, 0xBE62140F667F3DC4
data8 0xBE36961B3BF88747, 0x3E602861C96EC6AA
data8 0xBE3B5151D57FD718, 0x3E561CD0FC4A627B
data8 0xBE3A5217CA913FEA, 0x3E40A3CC9A5D193A
data8 0xBE5AB71310A9C312, 0x3E4FDADBC5F57719
data8 0x3E361428DBDF59D5, 0x3E5DB5DB61B4180D
data8 0xBE42AD5F7408D856, 0x3E2A314831B2B707
LOCAL_OBJECT_END(Constants_Tgammal_exp_64_W1)
LOCAL_OBJECT_START(Constants_Tgammal_exp_64_W2)
data8 0x0000000000000000, 0xBE641F2537A3D7A2
data8 0xBE68DD57AD028C40, 0xBE5C77D8F212B1B6
data8 0x3E57878F1BA5B070, 0xBE55A36A2ECAE6FE
data8 0xBE620608569DFA3B, 0xBE53B50EA6D300A3
data8 0x3E5B5EF2223F8F2C, 0xBE56A0D9D6DE0DF4
data8 0xBE64EEF3EAE28F51, 0xBE5E5AE2367EA80B
data8 0x3E47CB1A5FCBC02D, 0xBE656BA09BDAFEB7
data8 0x3E6E70C6805AFEE7, 0xBE6E0509A3415EBA
data8 0xBE56856B49BFF529, 0x3E66DD3300508651
data8 0x3E51165FC114BC13, 0x3E53333DC453290F
data8 0x3E6A072B05539FDA, 0xBE47CD877C0A7696
data8 0xBE668BF4EB05C6D9, 0xBE67C3E36AE86C93
data8 0xBE533904D0B3E84B, 0x3E63E8D9556B53CE
data8 0x3E212C8963A98DC8, 0xBE33138F032A7A22
data8 0x3E530FA9BC584008, 0xBE6ADF82CCB93C97
data8 0x3E5F91138370EA39, 0x3E5443A4FB6A05D8
data8 0x3E63DACD181FEE7A, 0xBE62B29DF0F67DEC
data8 0x3E65C4833DDE6307, 0x3E5BF030D40A24C1
data8 0x3E658B8F14E437BE, 0xBE631C29ED98B6C7
data8 0x3E6335D204CF7C71, 0x3E529EEDE954A79D
data8 0x3E5D9257F64A2FB8, 0xBE6BED1B854ED06C
data8 0x3E5096F6D71405CB, 0xBE3D4893ACB9FDF5
data8 0xBDFEB15801B68349, 0x3E628D35C6A463B9
data8 0xBE559725ADE45917, 0xBE68C29C042FC476
data8 0xBE67593B01E511FA, 0xBE4A4313398801ED
data8 0x3E699571DA7C3300, 0x3E5349BE08062A9E
data8 0x3E5229C4755BB28E, 0x3E67E42677A1F80D
data8 0xBE52B33F6B69C352, 0xBE6B3550084DA57F
data8 0xBE6DB03FD1D09A20, 0xBE60CBC42161B2C1
data8 0x3E56ED9C78A2B771, 0xBE508E319D0FA795
data8 0xBE59482AFD1A54E9, 0xBE2A17CEB07FD23E
data8 0x3E68BF5C17365712, 0x3E3956F9B3785569
LOCAL_OBJECT_END(Constants_Tgammal_exp_64_W2)
LOCAL_OBJECT_START(Constants_Tgammal_poly)
// Polynomial coefficients for the tgammal(x), 2 <= |x| < 3
//A5 = 2.8360780594841213109180699803e-02 + 2.2504152891014320704380000000e-19
data8 0x3F9D0A9BC49353D2, 0x3C109AEA0F23CE2D
//A4 = 1.0967323400216015538699565468e-01 + 9.9225166000430644587276000000e-18
data8 0x3FBC138B89492C5B, 0x3C66E138506D5652
//A3 = 2.5387124684114281691904579930e-01 + 2.2667777637607113205546600000e-17
data8 0x3FD03F6D2FA4F4F8, 0x3C7A2258DA8CD8B1
data8 0xC5866457328BC39B, 0x00003FE3 //A20 = 5.7487331964156762795056629138e-09
data8 0xE93D9F1ACD59C929, 0x0000BFE4 //A19= -1.3576396100397317396956445658e-08
data8 0xE33389C8F6CBA813, 0x00003FE5 //A18 = 2.6449714924964597501721434271e-08
data8 0x8FE7B25B9CD26D2A, 0x0000BFE7 //A17= -6.7011017946055513660266853311e-08
data8 0xB89F4721BFBC15B0, 0x00003FE8 //A16 = 1.7194280320370423615174419192e-07
data8 0xE49CBDC1874EBABA, 0x0000BFE9 //A15= -4.2582353660153782928729466776e-07
data8 0x913AF50A336129CA, 0x00003FEB //A14 = 1.0820500665257088283172211622e-06
data8 0xABCF0F7313B3B332, 0x0000BFEC //A13= -2.5601510627710417669568115706e-06
//A2 = 6.5455857798133676439533701341e-01 + 1.3292075193155190798867000000e-18
data8 0x3FE4F224D4B7E01C, 0x3C3885014A2B8319
//A1 = 9.3473452162608550164435428087e-01 + 3.2785154201417136611642400000e-17
data8 0x3FEDE9585F1A7093, 0x3C82E63C1B5028BF
//A0 = 1.3293403881791368004172682049e+00 + 2.2005689328949279282607500000e-16
data8 0x3FF544FA6D47B38F, 0x3CAFB6AA9829E81F
data8 0xF3668F799997C76D, 0x00003FED //A12 = 7.2539039479124273660331538367e-06
data8 0xD6C6BBD54CDEAEB1, 0x0000BFEE //A11= -1.2801665282681088568639378920e-05
data8 0x809E4763B06F6883, 0x00003FF1 //A10 = 6.1329973609906572700697893187e-05
data8 0x8443B000F8F9A71A, 0x00003FED //A9 = 3.9417864189995544394564413428e-06
data8 0xC5C7E6D62A6991D8, 0x00003FF4 //A8 = 7.5447412886334708803357581519e-04
data8 0xD2AF690725C62D88, 0x00003FF5 //A7 = 1.6074004848394703022110823298e-03
data8 0xAA44E635D4B7B682, 0x00003FF8 //A6 = 1.0392403425906843901680697839e-02
//
// Polynomial coefficients for the tgammal(x), 4 <= |x| < 5
//A5 = 1.1600674810589555185913468449e+00 + 3.0229979112715124660731000000e-17
data8 0x3FF28FA2EB44D22E, 0x3C816D285234C815
//A4 = 3.1374268565470946334983182169e+00 + 1.3694868953995008497659600000e-16
data8 0x400919734073B1E1, 0x3CA3BC83CD7E9565
//A3 = 7.0834593993741057360580271052e+00 + 3.3899702569039156457249800000e-16
data8 0x401C5576617B6C1F, 0x3CB86D6431213296
data8 0xA4A5FB49C094966B, 0x00003FDA //A20 = 9.3591760106637809309720130828e-12
data8 0xA9260DA0F51D7ED8, 0x00003FDD //A19 = 7.6919898428091669411809372180e-11
data8 0xA16441DFB14BD6E1, 0x00003FE0 //A18 = 5.8713933014370867331213494535e-10
data8 0x95F098D9C2234849, 0x00003FE3 //A17 = 4.3638234584169302324461091035e-09
data8 0x8581817400E5AD2B, 0x00003FE6 //A16 = 3.1084260332429955234755367839e-08
data8 0xE272940E373EBE15, 0x00003FE8 //A15 = 2.1089573544273993580820317236e-07
data8 0xB6B3391145D226FB, 0x00003FEB //A14 = 1.3612217421122787182942706259e-06
data8 0x8B9428C4DF95FCD5, 0x00003FEE //A13 = 8.3195416382628990683949003789e-06
//A2 = 1.2665135075272345943631080445e+01 + 9.8721896915973874255877000000e-16
data8 0x4029548C95A76F38, 0x3CD1C8BE715B8E13
//A1 = 1.6154969393303069580269948347e+01 + 9.6850518810678379641029000000e-16
data8 0x403027AC12FC1E1E, 0x3CD172711C15501B
//A0 = 1.1631728396567448058362970187e+01 + 8.7078125362814179268673000000e-16
data8 0x40274371E7866C65, 0x3CCF5F8A1A5FACA0
data8 0xC94A903114272C03, 0x00003FF0 //A12 = 4.7991576836334427243159066630e-05
data8 0x8844262960E04BE6, 0x00003FF3 //A11 = 2.5990716419283017929486175141e-04
data8 0xAC5418A76767678D, 0x00003FF5 //A10 = 1.3147621245497801180184809726e-03
data8 0xCA231B6EFE959132, 0x00003FF7 //A9 = 6.1687358811367989146517222415e-03
data8 0xDA38E39C13819D2A, 0x00003FF9 //A8 = 2.6638454961912040754759086920e-02
data8 0xD696DF8D8389FE53, 0x00003FFB //A7 = 1.0477995539298934056097943975e-01
data8 0xBDD5C153048BC435, 0x00003FFD //A6 = 3.7077144754791605130056406006e-01
//
// Polynomial coefficients for the tgammal(x), 6 <= |x| < 7
//A5 = 6.7169398121054200601065531373e+01 + 2.9481001527213915901489600000e-15
data8 0x4050CAD76B377BA0, 0x3CEA8DDB2B2DE93E
//A4 = 1.6115104376855398982115730178e+02 + 1.3422421925418824418257300000e-14
data8 0x406424D559BDC687, 0x3D0E397FDB5B33DC
//A3 = 3.1812194028053562533386866562e+02 + 3.9881709875858650942409600000e-14
data8 0x4073E1F377A6CF73, 0x3D26738F63FE9C4C
data8 0xD6E1B5FF90CAABD3, 0x00003FE1 //A20 = 1.5634700199277480081025480635e-09
data8 0xD451987B925DD37E, 0x00003FE4 //A19 = 1.2358576813211397717382327174e-08
data8 0xBFC151B67FA58E6B, 0x00003FE7 //A18 = 8.9292951435632759686382657901e-08
data8 0xA9034C5E1D67572E, 0x00003FEA //A17 = 6.2962205718327848327368724720e-07
data8 0x8E40F6EAA30A71EC, 0x00003FED //A16 = 4.2394926442967995119170095258e-06
data8 0xE3C3541B03A1C350, 0x00003FEF //A15 = 2.7151465666109594512258841637e-05
data8 0xACE2E58436B2DDCE, 0x00003FF2 //A14 = 1.6487723793339152877117376243e-04
data8 0xF7EAF8D8D1CAA3D1, 0x00003FF4 //A13 = 9.4573158112768812533636022369e-04
//A2 = 4.8664351544258869353143381886e+02 + 4.7424047995944376868895400000e-14
data8 0x407E6A4BD6D9463B, 0x3D2AB2868D79E192
//A1 = 5.1615277644992545447166776285e+02 + 3.0901956935588717379242200000e-14
data8 0x40802138E2DC003B, 0x3D216570FB601AEA
//A0 = 2.8788527781504433278314536437e+02 + 2.8213174117085164944959600000e-14
data8 0x4071FE2A1911F7D6, 0x3D1FC3E4CF4DB5AF
data8 0xA72B88E48D3D1BAB, 0x00003FF7 //A12 = 5.1016252919939028020562237471e-03
data8 0xD2EFB1067DB4FFB2, 0x00003FF9 //A11 = 2.5749059441230515023024615917e-02
data8 0xF788AF9522205C24, 0x00003FFB //A10 = 1.2086617635601742290221382521e-01
data8 0x861A6CE06CB29EAF, 0x00003FFE //A9 = 5.2384071807018493367136112163e-01
data8 0x84FBDE0947718B58, 0x00004000 //A8 = 2.0778727617851237754568261869e+00
data8 0xEEC1371E265A2C3A, 0x00004001 //A7 = 7.4610858525146049022238037342e+00
data8 0xBF514B9BE68ED59D, 0x00004003 //A6 = 2.3914694993947572859629197920e+01
//
// Polynomial coefficients for the tgammal(x), 8 <= |x| < 9
//A5 = 5.8487447114416836484451778233e+03 + 4.7365465221455983144182900000e-13
data8 0x40B6D8BEA568B6FD, 0x3D60AA4D44C2589B
//A4 = 1.2796464063087094473303295672e+04 + 1.2373341702514898266244200000e-12
data8 0x40C8FE3B666B532D, 0x3D75C4752C5B4783
//A3 = 2.2837606581322281272150576115e+04 + 2.6598064610627891398831000000e-13
data8 0x40D64D66D23A7764, 0x3D52B77B3A10EA5C
data8 0xB23418F75B0BE22A, 0x00003FE9 //A20 = 3.3192989594206801808678663868e-07
data8 0xA984A7BC8B856ED2, 0x00003FEC //A19 = 2.5260177918662350066375115788e-06
data8 0x921A49729416372C, 0x00003FEF //A18 = 1.7416797068239475136398213598e-05
data8 0xF5BB9415CC399CA4, 0x00003FF1 //A17 = 1.1717449586392814601938207599e-04
data8 0xC50B91A40B81F9DF, 0x00003FF4 //A16 = 7.5166775151159345732094429036e-04
data8 0x96002572326DB203, 0x00003FF7 //A15 = 4.5776541559407384162139204300e-03
data8 0xD81A1A595E4157BA, 0x00003FF9 //A14 = 2.6379634345126284099420760736e-02
data8 0x92B700D0CFECADD8, 0x00003FFC //A13 = 1.4327622675407940907282658100e-01
//A2 = 3.1237895525940199149772524834e+04 + 3.1280450505163186432331700000e-12
data8 0x40DE8179504C0878, 0x3D8B83BB33FBB766
//A1 = 2.9192841741344487672904506326e+04 + 7.9300780509779689630767000000e-13
data8 0x40DC8235DF171691, 0x3D6BE6C780EE54DF
//A0 = 1.4034407293483411194756627083e+04 + 1.4038139346291543309253700000e-12
data8 0x40CB693422315F90, 0x3D78B23746113FCE
data8 0xBAE50807548BC711, 0x00003FFE //A12 = 7.3005724123917935346868107005e-01
data8 0xDE28B1F57E68CFB6, 0x00004000 //A11 = 3.4712338349724065462763671443e+00
data8 0xF4DCA5A5FF901118, 0x00004002 //A10 = 1.5303868912154033908205911714e+01
data8 0xF85AAA1AD5E84E5E, 0x00004004 //A9 = 6.2088539523416399361048051373e+01
data8 0xE5AA8BB1BF02934D, 0x00004006 //A8 = 2.2966619406617480799195651466e+02
data8 0xBF6CFEFD67F59845, 0x00004008 //A7 = 7.6570306334640770654588802417e+02
data8 0x8DB5D2F001635C29, 0x0000400A //A6 = 2.2673639984182571062068713002e+03
//
// Polynomial coefficients for the tgammal(x), 10 <= |x| < 11
//A5 = 7.2546009516580589115619659424e+05 + 1.0343348865365065212891728822e-10
data8 0x412623A830B99290, 0x3DDC6E7C157611C4
//A4 = 1.4756292870840241666883230209e+06 + 8.1516565365333844166705674775e-11
data8 0x4136842D497E56AF, 0x3DD66837E4C3F9EE
//A3 = 2.4356116926500420086085796356e+06 + 3.5508860076560925641351069404e-10
data8 0x4142950DD8A8C1AF, 0x3DF866C8E3DD0980
data8 0xB7FD0D1EEAC38EB4, 0x00003FF1 //A20 = 8.7732544640091602721643775932e-05
data8 0xA9345C64AC750AE9, 0x00003FF4 //A19 = 6.4546407626804942279126469603e-04
data8 0x8BEABC81BE1E93C9, 0x00003FF7 //A18 = 4.2699261134524096128048819443e-03
data8 0xE1CD281EDD7315F8, 0x00003FF9 //A17 = 2.7563646660310313164706189622e-02
data8 0xAD8A5BA6D0FD9758, 0x00003FFC //A16 = 1.6947310643831556048460963841e-01
data8 0xFCDDA464AD3F182E, 0x00003FFE //A15 = 9.8775699098518676937088606052e-01
data8 0xAE0DCE2F7B60D1AE, 0x00004001 //A14 = 5.4391852309591064073782104822e+00
data8 0xE1745D9ABEB8D1A7, 0x00004003 //A13 = 2.8181819161363002758615770457e+01
//A2 = 3.0619656223573554307222366333e+06 + 1.0819940302945474471259520006e-10
data8 0x41475C66CFA967E4, 0x3DDDBDDB2A27334B
//A1 = 2.6099413018962685018777847290e+06 + 3.6851882860056025385268615240e-10
data8 0x4143E98AA6A48974, 0x3DF9530D42589AB6
//A0 = 1.1332783889487853739410638809e+06 + 1.9339350553312096248591829758e-10
data8 0x41314ADE639225C9, 0x3DEA946DD6C2C8D3
data8 0x88BCFAAE71812A1C, 0x00004006 //A12 = 1.3673820009490115307300592012e+02
data8 0x9A770F5AB540A326, 0x00004008 //A11 = 6.1786031215382040427126476507e+02
data8 0xA170C1D2C6B413FC, 0x0000400A //A10 = 2.5830473201524594051391525170e+03
data8 0x9AE56061CB02EB55, 0x0000400C //A9 = 9.9133441230507404119297200255e+03
data8 0x872390769650FBE2, 0x0000400E //A8 = 3.4595564309496661629764193479e+04
data8 0xD3E5E8D6923910C1, 0x0000400F //A7 = 1.0849181904819284819615140521e+05
data8 0x930D70602F50B754, 0x00004011 //A6 = 3.0116351174131169193070583741e+05
//
// Polynomial coefficients for the tgammal(x), 12 <= |x| < 13
//A5 = 1.2249876249976964294910430908e+08 + 6.0051348061679753770848000000e-09
data8 0x419D34BB29FFC39D, 0x3E39CAB72E01818D
//A4 = 2.3482765927605420351028442383e+08 + 1.1874729051592862323641700000e-08
data8 0x41ABFE5F168D56FA, 0x3E4980338AA7B04B
//A3 = 3.6407329688125067949295043945e+08 + 2.6657200942150363994658700000e-08
data8 0x41B5B35150E199A5, 0x3E5C9F79C0EB5300
data8 0xE89AE0F8D726329D, 0x00003FF9 //A20 = 2.8394164465429105626588451540e-02
data8 0xCF90981F86E38013, 0x00003FFC //A19 = 2.0270002071785908652476845915e-01
data8 0xA56C658079CA8C4A, 0x00003FFF //A18 = 1.2923704984019263122675412350e+00
data8 0x80AEF96A67C5615A, 0x00004002 //A17 = 8.0427183300456238315262463506e+00
data8 0xBE886D7529678931, 0x00004004 //A16 = 4.7633230047847868242503413461e+01
data8 0x858EDBA4CE2F7508, 0x00004007 //A15 = 2.6711607799594541057655957154e+02
data8 0xB0B0A3AF388274F0, 0x00004009 //A14 = 1.4135199810126975119809102782e+03
data8 0xDBA87137988751EF, 0x0000400B //A13 = 7.0290552818218513870879313985e+03
//A2 = 4.2828433593031734228134155273e+08 + 3.9760422293645854535247300000e-08
data8 0x41B98719AFEE2947, 0x3E6558A17E0D3007
//A1 = 3.4008253676084774732589721680e+08 + 1.2558352335001093116071000000e-09
data8 0x41B4453F68C2C6EB, 0x3E159338C5BC7EC3
//A0 = 1.3684336546556583046913146973e+08 + 2.6786516700381562934240300000e-08
data8 0x41A05020CAEE5EA5, 0x3E5CC3058A858579
data8 0xFF5E3940FB4BA576, 0x0000400D //A12 = 3.2687111823895439312116108631e+04
data8 0x8A08C124C7F74B6C, 0x00004010 //A11 = 1.4134701786994123329786229006e+05
data8 0x89D701953540BFFB, 0x00004012 //A10 = 5.6459209892773907605385652281e+05
data8 0xFC46344B3116C3AD, 0x00004013 //A9 = 2.0666305367147234406757715163e+06
data8 0xD183EBD7A400151F, 0x00004015 //A8 = 6.8653979211730981618367536737e+06
data8 0x9C083A40742112F4, 0x00004017 //A7 = 2.0451444503543981795037456447e+07
data8 0xCD3C475B1A8B6662, 0x00004018 //A6 = 5.3801245423495149598177886823e+07
LOCAL_OBJECT_END(Constants_Tgammal_poly)
LOCAL_OBJECT_START(Constants_Tgammal_poly_splitted)
// Polynomial coefficients for the tgammal(x), 1 <= |x| < 1.25
//A5 = -9.8199506890310417350775651357e-01+ -3.2546247786122976510752200000e-17
data8 0xBFEF6C80EC38B509, 0xBC82C2FA7A3DE3BD
//A4 = 9.8172808683439960475425323239e-01 + 4.4847611775298520359811400000e-17
data8 0x3FEF6A51055096B0, 0x3C89DA56DE95EFE4
//A3 = -9.0747907608088618225394839101e-01 +-1.0244057366544064435443970000e-16
data8 0xBFED0A118F324B62, 0xBC9D86C7B9EBCFFF
data8 0xB8E3FDAA66CC738E, 0x00003FFB //A20 = 9.0278608095877488976217714815e-02
data8 0xA76067AE1738699C, 0x0000BFFD //A19 =-3.2690738678103132837070881737e-01
data8 0x9D66B13718408C44, 0x00003FFE //A18 = 6.1484820933424283818320582920e-01
data8 0xD4AC67BBB4AE5599, 0x0000BFFE //A17 =-8.3075569470082063491389474937e-01
data8 0xF1426ED1C1488DB3, 0x00003FFE //A16 = 9.4241993542644505594957058785e-01
data8 0xFC12EB07AA6F4B6B, 0x0000BFFE //A15 =-9.8466366707947121954333549690e-01
data8 0xFF2B32CFE5B0DDC8, 0x00003FFE //A14 = 9.9675290656677214804168895915e-01
data8 0xFFD8E7E6FF3662EA, 0x0000BFFE //A13 =-9.9940347089360552383472582319e-01
//A2 = 9.8905599532797250361682017683e-01 + 5.1760162410376024240867300000e-17
data8 0x3FEFA658C23B1578, 0x3C8DD673A61F6FE7
//A1 = -5.7721566490153275452712478000e-01+ -1.0607935612223465065923310000e-16
data8 0xBFE2788CFC6FB618, 0xBC9E9346622D53B7
//A0 = 9.9999999999999988897769753748e-01 + 1.1102230245372554544790880000e-16
data8 0x3FEFFFFFFFFFFFFF, 0x3C9FFFFFFFF51E4E
data8 0xFFF360DF628F0BC9, 0x00003FFE //A12 = 9.9980740979895815468216470840e-01
data8 0xFFEF8F9A72B40480, 0x0000BFFE //A11 = -9.9974916001038145045939523470e-01
data8 0xFFE037B8C7E39952, 0x00003FFE //A10 = 9.9951504002809911822597567307e-01
data8 0xFFC01E08F348BED2, 0x0000BFFE //A9 = -9.9902522772325406705059517941e-01
data8 0xFF83DAC83119B52C, 0x00003FFE //A8 = 9.9810569179053383842734164901e-01
data8 0xFEF9F8AB891ABB24, 0x0000BFFE //A7 = -9.9600176036720260345608796766e-01
data8 0xFE3F0537573C8235, 0x00003FFE //A6 = 9.9314911461918778676646301341e-01
//
// Polynomial coefficients for the tgammal(x), 1.25 <= |x| < 1.75
//A5 = -7.7523052299853054125655660300e-02+ -1.2693512521686721504433600000e-17
data8 0xBFB3D88CFE50601B, 0xBC6D44ED60EE2170
//A4 = 1.4464535904462152982041800442e-01 + 2.5426820829345729856648800000e-17
data8 0x3FC283BD374EB2A9, 0x3C7D50AC436187C3
//A3 = -1.0729480456477220873257039102e-01+ -6.2429894945456418196551000000e-18
data8 0xBFBB77AC1CA2EBA5, 0xBC5CCA6BCC422D41
data8 0xF732D2689F323283, 0x00003FF2 //A20 = 2.3574688251652899567587145422e-04
data8 0xB6B00E23DE89D13A, 0x0000BFF3 //A19 =-3.4844916488842618776630058875e-04
data8 0xE98396FE4A1B2799, 0x00003FF3 //A18 =4.4539265198744452020440735977e-04
data8 0xAF8D235A640DB1A2, 0x0000BFF4 //A17 =-6.6967514303333563295261178346e-04
data8 0x8513B736C918B261, 0x00003FF5 //A16 = 1.0152970456990865810615917715e-03
data8 0xC790A1A2C78D8E17, 0x0000BFF5 //A15 =-1.5225598630329403515321688394e-03
data8 0x959706CFA638CDE2, 0x00003FF6 //A14 = 2.2825614575133879623648932383e-03
data8 0xE050A6021E129860, 0x0000BFF6 //A13 =-3.4227757733947066666295285936e-03
//A2 = 4.1481345368830113695679528973e-01 + 3.1252439808354284892632100000e-17
data8 0x3FDA8C4DBA620D56, 0x3C82040BCB483C76
//A1 = 3.2338397448885010387886751460e-02 + 3.4437825798552300531443100000e-18
data8 0x3FA08EA88EE561B1, 0x3C4FC366D6C64806
//A0 = 8.8622692545275794095971377828e-01 + 7.2689375867553992399219000000e-17
data8 0x3FEC5BF891B4EF6A, 0x3C94F3877D311C0C
data8 0xA8275AADC09D16FC, 0x00003FF7 //A12 = 5.1316445128621071486146117136e-03
data8 0xFBFE2CE9215267A2, 0x0000BFF7 //A11= -7.6902121820788373000579382408e-03
data8 0xBCC8EEAB67ECD91D, 0x00003FF8 //A10 = 1.1522515369164312742737727262e-02
data8 0x8D1614BB97E5E8C2, 0x0000BFF9 //A9 = -1.7222443097804730395560633583e-02
data8 0xD3A963578BE291E3, 0x00003FF9 //A8 = 2.5837606456090186343624210891e-02
data8 0x9BA7EAE64C42FDF7, 0x0000BFFA //A7 = -3.8001935555045161419575037512e-02
data8 0xF0115BA1A77607E7, 0x00003FFA //A6 = 5.8610303817173477119764956736e-02
//
// Polynomial coefficients for the tgammal(x), 1.75 <= |x| < 2.0
//A5 = 2.6698206874501426502654943818e-04 + 3.4033756836921062797887300000e-20
data8 0x3F317F3740FE2A68, 0x3BE417093234B06E
//A4 = 7.4249010753513894345090307070e-02 + 3.9810018444482764697014200000e-18
data8 0x3FB301FBB0F25A92, 0x3C525BEFFABB622F
//A3 = -8.1576919247086265851720554565e-02+ -5.2716624487804746360745000000e-19
data8 0xBFB4E239984650AC, 0xBC2372F1C4F276FF
data8 0xFEF3AEE71038E9A3, 0x00003FEB //A20 = 1.8995395865421509009969188571e-06
data8 0xA11CFA2672BF876A, 0x0000BFEB //A19 =-1.2003868221414015771269244270e-06
data8 0xF8E107215DAE2164, 0x00003FEC //A18 = 3.7085863210303833432006027217e-06
data8 0xBCDDD3FC011EF7D6, 0x00003FEC //A17 = 2.8143303971756051015245433043e-06
data8 0x8683C4687FA22E68, 0x00003FEE //A16 = 8.0177018464360416764308252462e-06
data8 0xFDA09E5D33E32968, 0x00003FEE //A15 = 1.5117372062443781157389064848e-05
data8 0xFFB00D0CFF4089B4, 0x00003FEF //A14 = 3.0480348961227424242198174995e-05
data8 0xFEF6C39566785085, 0x00003FF0 //A13 = 6.0788135974125244644334004947e-05
//A2 = 4.1184033042643969357854416558e-01 + 1.2103396182129232634761000000e-18
data8 0x3FDA5B978B96BEBF, 0x3C3653AAD0A139E4
//A1 = -4.2278433509846713445057275749e-01+ -4.9429151528135657430413000000e-18
data8 0xBFDB0EE6072093CE, 0xBC56CB907027554F
//A0 = 1.0000000000000000000000000000e+00 + 1.0969171200000000000000000000e-31
data8 0x3FF0000000000000, 0x3981CC6A5B20B4D5
data8 0xFF2B7BA9A8D68C37, 0x00003FF1 //A12 = 1.2167446884801403650547161615e-04
data8 0xFCA53468E3692EF1, 0x00003FF2 //A11 = 2.4094136329542400976250900707e-04
data8 0x808D698A9C993615, 0x00003FF4 //A10 = 4.9038845704938303659791698883e-04
data8 0xF10F8E3FB8BB4AFB, 0x00003FF4 //A9 = 9.1957383840999861214472423976e-04
data8 0x89E224E42F93F005, 0x00003FF6 //A8 = 2.1039333407187324139473634747e-03
data8 0xBAF374824937A323, 0x00003FF6 //A7 = 2.8526458211545152218493600470e-03
data8 0xB6BF7564F52140C6, 0x00003FF8 //A6 = 1.1154045718131014476684982178e-02
//
// Polynomial coefficients for the tgammal(x), 0.0 <= |x| < 0.125
//A5 = -9.8199506890314514073736518185e-01+ -5.9363811993837985890950900000e-17
data8 0xBFEF6C80EC38B67A, 0xBC911C46B447C81F
//A4 = 9.8172808683440015986576554496e-01 + 2.7457414262802803699834200000e-17
data8 0x3FEF6A51055096B5, 0x3C7FA7FF90ACAD1F
//A3 = -9.0747907608088618225394839101e-01 + -1.0676255850934306734701780000e-16
data8 0xBFED0A118F324B62, 0xBC9EC5AFB633438D
data8 0x9217E83FA207CB80, 0x00003FFD //A20 = 2.8533864762086088781083621561e-01
data8 0xA8DABFA52FDF03EC, 0x0000BFFE //A19= -6.5958783896337186303285832783e-01
data8 0xE331ED293AF39F9B, 0x00003FFE //A18 = 8.8748056656454687449654731184e-01
data8 0xF9163C5DDB52419D, 0x0000BFFE //A17= -9.7299554149078295602977718525e-01
data8 0xFEC0A1C672CB9265, 0x00003FFE //A16 = 9.9512683005268190987854104489e-01
data8 0xFFD2D65B8EA7B5F4, 0x0000BFFE //A15= -9.9931087241443958201592847861e-01
data8 0xFFF93AA39EE53445, 0x00003FFE //A14 = 9.9989668364186884793382816496e-01
data8 0xFFFB99A9A3F5F480, 0x0000BFFE //A13= -9.9993286506283835663204999212e-01
//A2 = 9.8905599532797250361682017683e-01 + 5.1778575360788420716540100000e-17
data8 0x3FEFA658C23B1578, 0x3C8DD92B45408D07
//A1 = -5.7721566490153275452712478000e-01+ -1.0607938730998824663273110000e-16
data8 0xBFE2788CFC6FB618, 0xBC9E9346F8FDE55B
//A0 = 9.9999999999999988897769753748e-01 + 1.1102230246251564036631420000e-16
data8 0x3FEFFFFFFFFFFFFF, 0x3C9FFFFFFFFFFFFF
data8 0xFFF7FEBB545812C1, 0x00003FFE //A12 = 9.9987785409425126648628395084e-01
data8 0xFFF00C02E943A3F2, 0x0000BFFE //A11= -9.9975657530855116454438747397e-01
data8 0xFFE0420AADC53820, 0x00003FFE //A10 = 9.9951565514290485919027183699e-01
data8 0xFFC01EB42EF27EEB, 0x0000BFFE //A9 = -9.9902526759155739377365522320e-01
data8 0xFF83DAD0BF23FF12, 0x00003FFE //A8 = 9.9810569378236378800364235948e-01
data8 0xFEF9F8ABDBCDB2F3, 0x0000BFFE //A7 = -9.9600176044241699109053158187e-01
data8 0xFE3F05375988491D, 0x00003FFE //A6 = 9.9314911462127599008937257662e-01
LOCAL_OBJECT_END(Constants_Tgammal_poly_splitted)
.align 64
LOCAL_OBJECT_START(Constants_Tgammal_common)
// Positive overflow value
data8 0x3FE0000000000000 // 0.5
data8 0x3FF8000000000000 // 1.5
data8 0x3FD0000000000000 // 0.25
data8 0x0000000000000000 // 0
data8 0xDB718C066B352E21, 0x00004009 // Positive overflow value
LOCAL_OBJECT_END(Constants_Tgammal_common)
//=======================================================
// Lgamma registers
// General Purpose Registers
GR_l_Log_Table = r33
GR_l_Log_Table1 = r34
GR_l_BIAS = r34
GR_l_Index1 = r35
GR_l_Index2 = r36
GR_l_signif_Z = r37
GR_l_X_0 = r38
GR_l_X_1 = r39
GR_l_X_2 = r40
GR_l_Z_1 = r41
GR_l_Z_2 = r42
GR_l_N = r43
GR_l_Index3 = r44
GR_l_Stirling_Table = r45
GR_l_N_Unbiased = r46
// Floating Point Registers
FR_l_logl_X = f8
FR_l_h_3 = f10
FR_l_poly_hi = f10
FR_l_W = f11
FR_l_S = f12
FR_l_GS_hi = f13
FR_l_Y_lo = f13
FR_l_r_cor = f14
FR_l_G_1 = f15
FR_l_G = f15
FR_l_H_1 = f32
FR_l_H = f32
FR_l_h = f33
FR_l_h_1 = f33
FR_l_N = f33
FR_l_G_2 = f34
FR_l_H_2 = f35
FR_l_h_2 = f36
FR_l_G_3 = f37
FR_l_log2_hi = f38
FR_l_GS_lo = f39
FR_l_H_3 = f40
FR_l_float_N = f41
FR_l_Q_4 = f42
FR_l_Q_3 = f43
FR_l_Q_2 = f44
FR_l_Q_1 = f45
FR_l_Q_5 = f46
FR_l_Q_6 = f47
FR_l_log2_lo = f48
FR_l_r = f49
FR_l_poly_lo = f50
FR_l_poly = f51
FR_l_rsq = f52
FR_l_Y_lo_res = f53
FR_l_Y0 = f55
FR_l_Q0 = f56
FR_l_E0 = f57
FR_l_E2 = f58
FR_l_E1 = f59
FR_l_Y1 = f60
FR_l_E3 = f61
FR_l_Y2 = f62
FR_l_Z = f63
FR_l_Z2 = f64
FR_l_Z4 = f65
FR_l_Z8 = f66
FR_l_CH = f67
FR_l_CL = f68
FR_l_B2 = f69
FR_l_B4 = f70
FR_l_B6 = f71
FR_l_B8 = f72
FR_l_B10 = f73
FR_l_B12 = f74
FR_l_B14 = f75
FR_l_B16 = f76
FR_l_B18 = f77
FR_l_Half = f78
FR_l_SS = f79
FR_l_AbsX_m_Half = f80
FR_l_CXH = f81
FR_l_CXL = f82
FR_l_SSCXH = f83
FR_l_SSCXL = f84
FR_l_XYH = f85
FR_l_XYL = f86
FR_l_Temp = f87
FR_l_logl_YHi = f88
FR_l_logl_YLo = f89
FR_l_SignedXYH = f123
FR_l_AbsX = f127
//=======================================================
// Negative part registers
// General Purpose Registers
GR_n_sin_Table = r47
GR_n_XN = r48
// Float point registers
FR_n_IXNS = f125
FR_n_IXN = f126
FR_n_XNS = f90
FR_n_XS = f91
FR_n_XS2 = f92
FR_n_XS2L = f93
FR_n_XS4 = f94
FR_n_XS7 = f95
FR_n_XS8 = f96
FR_n_TT = f97
FR_n_TH = f98
FR_n_TL = f99
FR_n_A2H = f100
FR_n_A2L = f101
FR_n_A1H = f102
FR_n_A1L = f103
FR_n_A9 = f104
FR_n_A8 = f105
FR_n_A7 = f106
FR_n_A6 = f107
FR_n_A5 = f108
FR_n_A4 = f109
FR_n_A3 = f110
FR_n_PolyH = f111
FR_n_PolyL = f112
FR_n_Poly1H = f113
FR_n_SinxH = f113 // the same as FR_n_Poly1H
FR_n_Poly1L = f114
FR_n_SinxL = f114 // the same as FR_n_Poly1L
FR_n_Tail = f115
FR_n_NegOne = f116
FR_n_Y0 = f117
FR_n_Q0 = f118
FR_n_E0 = f119
FR_n_E2 = f120
FR_n_E1 = f121
FR_n_Y1 = f55
FR_n_E3 = f56
FR_n_Y2 = f57
FR_n_R0 = f58
FR_n_E4 = f59
FR_n_RcpResH = f60
FR_n_Y3 = f61
FR_n_R1 = f62
FR_n_Temp = f63
FR_n_RcpResL = f64
FR_n_ResH = f65
FR_n_ResL = f66
//=======================================================
// Exp registers
// General Purpose Registers
GR_e_ad_Arg = r33
GR_e_ad_A = r34
GR_e_signexp_x = r35
GR_e_exp_x = r35
GR_e_exp_mask = r36
GR_e_ad_W1 = r37
GR_e_ad_W2 = r38
GR_e_M2 = r39
GR_e_M1 = r40
GR_e_K = r41
GR_e_exp_2_mk = r42
GR_e_exp_2_k = r43
GR_e_ad_T1 = r44
GR_e_ad_T2 = r45
GR_e_N_fix = r46
GR_e_one = r47
GR_e_exp_bias = r48
GR_e_sig_inv_ln2 = r49
GR_e_rshf_2to51 = r50
GR_e_exp_2tom51 = r51
GR_e_rshf = r52
// Floating Point Registers
FR_e_RSHF_2TO51 = f10
FR_e_INV_LN2_2TO63 = f11
FR_e_W_2TO51_RSH = f12
FR_e_2TOM51 = f13
FR_e_RSHF = f14
FR_e_Y_hi = f15
FR_e_Y_lo = f32
FR_e_scale = f33
FR_e_float_N = f34
FR_e_N_signif = f35
FR_e_L_hi = f36
FR_e_L_lo = f37
FR_e_r = f38
FR_e_W1 = f39
FR_e_T1 = f40
FR_e_W2 = f41
FR_e_T2 = f42
FR_e_W1_p1 = f43
FR_e_rsq = f44
FR_e_A2 = f45
FR_e_r4 = f46
FR_e_A3 = f47
FR_e_poly = f48
FR_e_T = f49
FR_e_W = f50
FR_e_Wp1 = f51
FR_e_r6 = f52
FR_e_2_mk = f53
FR_e_A1 = f54
FR_e_T_scale = f55
FR_e_result_lo = f56
FR_e_W_T_scale = f57
FR_e_Wp1_T_scale = f58
FR_e_expl_Input_X = f123
FR_e_expl_Input_Y = f124
FR_e_expl_Output_X = f123
FR_e_expl_Output_Y = f124
FR_e_expl_Input_AbsX = f122
//=======================================================
// Common registers
// General Purpose Registers
GR_c_Table = r53
GR_c_NegUnderflow = r54
GR_c_NegSingularity = r55
GR_c_X = r56
GR_c_SignBit = r57
GR_c_13 = r58
// Floating Point Registers
FR_c_PosOverflow = f123
FR_c_XN = f124
//=======================================================
// Polynomial part registers
// General Purpose Registers
GR_p_Table = r59
GR_p_XN = r33
GR_p_Table2 = r34
GR_p_Int = r35
GR_p_Offset = r36
GR_p_Offset2 = r38
GR_p_X_Sgnd = GR_l_signif_Z // = r37
GR_p_Exp = r61
GR_p_Bias = r62
GR_p_0p75 = r63
// Floating Point Registers
FR_p_AbsX = FR_l_AbsX // = f127
FR_p_IXN = FR_n_IXN // = f126
FR_p_XN = f32
FR_p_0p5 = f33
FR_p_1p5 = f34
FR_p_AbsXM1 = f35
FR_p_2 = f36
FR_p_A20 = f37
FR_p_A19 = f38
FR_p_A18 = f39
FR_p_A17 = f40
FR_p_A16 = f41
FR_p_A15 = f42
FR_p_A14 = f43
FR_p_A13 = f44
FR_p_A12 = f45
FR_p_A11 = f46
FR_p_A10 = f47
FR_p_A9 = f48
FR_p_A8 = f49
FR_p_A7 = f50
FR_p_A6 = f51
FR_p_A5H = f52
FR_p_A5L = f53
FR_p_A4H = f54
FR_p_A4L = f55
FR_p_A3H = f56
FR_p_A3L = f57
FR_p_A2H = f58
FR_p_A2L = f59
FR_p_A1H = f60
FR_p_A1L = f61
FR_p_A0H = f62
FR_p_A0L = f63
FR_p_XR = f64
FR_p_XR2 = f65
FR_p_XR2L = f52
FR_p_XR3 = f58
FR_p_XR3L = f38
FR_p_XR4 = f42
FR_p_XR6 = f40
FR_p_XR8 = f37
FR_p_Poly5H = f66
FR_p_Poly5L = f67
FR_p_Poly4H = f53
FR_p_Poly4L = f44
FR_p_Poly3H = f41
FR_p_Poly3L = f47
FR_p_Poly2H = f68
FR_p_Poly2L = f54
FR_p_Poly1H = f55
FR_p_Poly1L = f46
FR_p_Poly0H = f39
FR_p_Poly0L = f43
FR_p_Temp5H = f69
FR_p_Temp5L = f70
FR_p_Temp4H = f71
FR_p_Temp4L = f60
FR_p_Temp2H = f72
FR_p_Temp2L = f73
FR_p_Temp1H = f59
FR_p_Temp1L = f61
FR_p_Temp0H = f49
FR_p_Temp0L = f48
FR_p_PolyTail = f45
FR_p_OddPoly0H = f56
FR_p_OddPoly0L = f51
FR_p_0p25 = f73
//=======================================================
// Negative polynomial part registers
// General Purpose Registers
GR_r_sin_Table = r47
GR_r_sin_Table2 = r60
// Floating Point Registers
FR_r_IXNS = FR_n_IXNS
FR_r_IXN = FR_n_IXN
FR_r_AbsX = FR_l_AbsX
FR_r_A9 = f74
FR_r_A8 = f75
FR_r_A7 = f76
FR_r_A6 = f77
FR_r_A5 = f78
FR_r_A4 = f79
FR_r_A3 = f80
FR_r_A2H = f81
FR_r_A2L = f82
FR_r_A1H = f83
FR_r_A1L = f84
FR_r_XNS = f85
FR_r_XS = f86
FR_r_XS2 = f87
FR_r_XS2L = f88
FR_r_XS4 = f89
FR_r_XS7 = f90
FR_r_XS8 = f91
FR_r_Tail = f92
FR_r_TT = f93
FR_r_TH = f94
FR_r_TL = f95
FR_r_ResH = f96
FR_r_ResL = f97
FR_r_Res3H = f98
FR_r_Res3L = f99
FR_r_Res1H = f100
FR_r_Res1L = f101
FR_r_Y0 = f102
FR_r_Q0 = f103
FR_r_E0 = f104
FR_r_E2 = f105
FR_r_E1 = f106
FR_r_Y1 = f107
FR_r_E3 = f108
FR_r_Y2 = f109
FR_r_R0 = f110
FR_r_E4 = f111
FR_r_ZH = f112
FR_r_Y3 = f113
FR_r_R1 = f114
FR_r_ZHN = f115
FR_r_ZL = f115
FR_r_NegOne = f116
FR_z_Y0 = f102
FR_z_Q0 = f103
FR_z_E0 = f104
FR_z_E2 = f105
FR_z_E1 = f106
FR_z_Y1 = f107
FR_z_E3 = f108
FR_z_Y2 = f109
FR_z_R0 = f110
FR_z_E4 = f111
FR_z_ZH = f112
FR_z_Y3 = f113
FR_z_R1 = f114
FR_z_ZL = f115
// General Purpose Registers
GR_SAVE_PFS = r32
GR_DenOverflow = r33
GR_u_XN = r34
GR_SAVE_B0 = r35
GR_SAVE_GP = r36
GR_SAVE_SP = r37
// Floating Point Registers
FR_u_IXN = f34
// ERROR HANDLER REGISTERS
GR_Parameter_X = r64
GR_Parameter_Y = r65
GR_Parameter_RESULT = r66
GR_Parameter_TAG = r67
FR_RESULT = f8
FR_X = f32
FR_Y = f1
.section .text
GLOBAL_LIBM_ENTRY(tgammal)
{ .mfi
alloc r32 = ar.pfs,0,32,4,0
fabs FR_l_AbsX = f8 // Get absolute value of X
addl GR_n_sin_Table = @ltoff(Constants_Tgammal_sin), gp
}
{ .mfi
addl GR_l_Log_Table=@ltoff(Constants_Tgammal_log_80_Z_G_H_h1#),gp
nop.f 0
addl GR_l_Stirling_Table = @ltoff(Constants_Tgammal_stirling), gp
};;
{ .mfi
getf.sig GR_l_signif_Z = f8 // Significand of X
fcvt.fx.s1 FR_n_IXNS = f8 // Convert to fixed point
addl GR_c_Table = @ltoff(Constants_Tgammal_common), gp
}
{ .mfi
ld8 GR_l_Log_Table = [GR_l_Log_Table]
nop.f 0
addl GR_p_Table = @ltoff(Constants_Tgammal_poly), gp
};;
{ .mfi
ld8 GR_n_sin_Table = [GR_n_sin_Table]
fclass.m p6,p0 = f8,0x1EF // Check x for NaN, 0, INF, denorm
// NatVal.
addl GR_c_NegSingularity = 0x1003E, r0
}
{ .mlx
ld8 GR_l_Stirling_Table = [GR_l_Stirling_Table]
movl GR_c_13 = 0x402A000000000000 // 13.0
};;
{ .mfi
getf.d GR_c_X = f8 // Double prec. X to general register
frcpa.s1 FR_z_Y0,p0 = f1,f8 // y = frcpa(x) (for negatives)
extr.u GR_l_Index1 = GR_l_signif_Z, 59, 4 // = High 4 bits of Z
}
{ .mlx
ld8 GR_c_Table = [GR_c_Table]
movl GR_c_SignBit = 0x8000000000000000 // High bit (sign)
};;
{ .mfi
ld8 GR_p_Table = [GR_p_Table]
fcmp.lt.s1 p15, p14 = f8,f0 // p14 - positive arg, p15 - negative
shl GR_l_Index1 = GR_l_Index1,5 // Adjust Index1 ptr (x32)
}
{ .mfb
adds GR_c_NegUnderflow = 1765, r0
nop.f 0
(p6) br.cond.spnt tgammal_spec // Spec. values processing branch ////////////
// (0s, INFs, NANs, NatVals, denormals) //////
};;
{ .mfi
ldfpd FR_l_CH,FR_l_CL= [GR_l_Stirling_Table], 16 // Load CH, CL
fcvt.fx.trunc.s1 FR_n_IXN = FR_l_AbsX // Abs arg to int by trunc
extr.u GR_l_X_0 = GR_l_signif_Z, 49, 15 // High 15 bit of Z
}
{ .mfi
add GR_l_Index1 = GR_l_Index1,GR_l_Log_Table // Add offset
fma.s1 FR_p_2 = f1, f1, f1 // 2.0
andcm GR_c_X = GR_c_X, GR_c_SignBit // Remove sign
};;
{ .mfi
addl GR_l_Log_Table = @ltoff(Constants_Tgammal_log_80_Z_G_H_h2#), gp
fcmp.lt.s1 p10, p0 = FR_l_AbsX, f1 // If |X|<1 then p10 = 1
nop.i 0
}
{ .mlx
ld2 GR_l_Z_1 = [GR_l_Index1],4 // load Z_1 from Index1
movl GR_l_BIAS = 0x000000000000FFFF // Bias for exponent
};;
{ .mfi
ld8 GR_l_Log_Table = [GR_l_Log_Table]
frcpa.s1 FR_l_Y0, p0 = f1, FR_l_AbsX // y = frcpa(x)
nop.i 0
}
{ .mfi
ldfs FR_l_G_1 = [GR_l_Index1],4 // Load G_1
fsub.s1 FR_l_W = FR_l_AbsX, f1 // W = |X|-1
nop.i 0
};;
{ .mfi
getf.exp GR_l_N_Unbiased= FR_l_AbsX // exponent of |X|
fmerge.se FR_l_S = f1, FR_l_AbsX // S = merging of X and 1.0
cmp.gtu p11, p0 = GR_c_13, GR_c_X // If 1 <= |X| < 13
// then p11 = 1
}
{ .mfb
ldfs FR_l_H_1 = [GR_l_Index1],8 // Load H_1
fcvt.xf FR_n_XNS = FR_n_IXNS // Convert to FP repr. of int X
(p10) br.cond.spnt tgamma_lt_1 // Branch to |X| < 1 path ///////////////////
};;
{ .mfi
ldfpd FR_n_A2H, FR_n_A2L = [GR_n_sin_Table], 16
nop.f 0
pmpyshr2.u GR_l_X_1 = GR_l_X_0,GR_l_Z_1,15 // Adjust Index2 (x32)
}
{ .mfb
ldfe FR_l_B2 = [GR_l_Stirling_Table], 16
nop.f 0
(p11) br.cond.spnt tgamma_lt_13 // Branch to 1 <= |X| < 13 path ///////////////
};;
{ .mfi
ldfe FR_l_h_1 = [GR_l_Index1],0
nop.f 0
sub GR_l_N = GR_l_N_Unbiased, GR_l_BIAS // N - BIAS
}
{ .mib
ldfpd FR_l_B4,FR_l_B6= [GR_l_Stirling_Table], 16 // Load C
(p15) cmp.geu.unc p8,p0 = GR_l_N_Unbiased, GR_c_NegSingularity
(p8) br.cond.spnt tgammal_singularity // Singularity for arg < to -2^63 //////
};;
{ .mmi
(p15) ldfpd FR_n_A1H, FR_n_A1L = [GR_n_sin_Table], 16
ldfpd FR_l_B8, FR_l_B10 = [GR_l_Stirling_Table], 16
add GR_c_Table = 0x20, GR_c_Table
};;
{ .mfi
(p15) ldfe FR_n_A9 = [GR_n_sin_Table], 16
fma.s1 FR_l_Q0 = f1,FR_l_Y0,f0 // Q0 = Y0
nop.i 0
}
{ .mfi
ldfpd FR_l_B12, FR_l_B14 = [GR_l_Stirling_Table], 16
fnma.s1 FR_l_E0 = FR_l_Y0,FR_l_AbsX,f1 // e = 1-b*y
nop.i 0
};;
{ .mfi
(p15) ldfe FR_n_A8 = [GR_n_sin_Table], 16
fcvt.xf FR_c_XN = FR_n_IXN // Convert to FP repr. of int X
extr.u GR_l_Index2 = GR_l_X_1, 6, 4 // Extract Index2
}
{ .mfi
ldfpd FR_l_B16, FR_l_B18 = [GR_l_Stirling_Table], 16
nop.f 0
nop.i 0
};;
{ .mfi
(p15) ldfe FR_n_A7 = [GR_n_sin_Table], 16
fms.s1 FR_l_CXH = FR_l_CH, f1, FR_l_AbsX // CXH = CH+|X|
shl GR_l_Index2 = GR_l_Index2,5
}
{ .mfi
ldfd FR_l_Half = [GR_l_Stirling_Table] // Load 0.5
nop.f 0
nop.i 0
};;
{ .mfi
add GR_l_Index2 = GR_l_Index2, GR_l_Log_Table // Add offset
nop.f 0
nop.i 0
}
{ .mfi
(p15) ldfe FR_n_A6 = [GR_n_sin_Table], 16
(p15) fma.s1 FR_n_XS = FR_l_AbsX , f1, FR_n_XNS // xs = x - int(x)
nop.i 0
};;
{ .mmi
ld2 GR_l_Z_2 = [GR_l_Index2],4
addl GR_l_Log_Table = @ltoff(Constants_Tgammal_log_80_h3_G_H#),gp
nop.i 0
};;
{ .mfi
ld8 GR_l_Log_Table = [GR_l_Log_Table]
fma.s1 FR_l_E2 = FR_l_E0,FR_l_E0,FR_l_E0 // e2 = e+e^2
nop.i 0
}
{ .mfi
ldfs FR_l_G_2 = [GR_l_Index2],4
fma.s1 FR_l_E1 = FR_l_E0,FR_l_E0,f0 // e1 = e^2
nop.i 0
};;
{ .mmi
ldfs FR_l_H_2 = [GR_l_Index2],8
(p15) ldfe FR_n_A5 = [GR_n_sin_Table], 16
nop.i 0
};;
{ .mfi
setf.sig FR_l_float_N = GR_l_N // float_N = Make N a fp number
nop.f 0
pmpyshr2.u GR_l_X_2 = GR_l_X_1,GR_l_Z_2,15 // X_2 = X_1 * Z_2
}
{ .mfi
ldfe FR_l_h_2 = [GR_l_Index2],0
fma.s1 FR_l_CXL = FR_l_AbsX, f1, FR_l_CXH // CXL = |X|+CXH
add GR_l_Log_Table1= 0x200, GR_l_Log_Table
};;
{ .mfi
(p15) ldfe FR_n_A4 = [GR_n_sin_Table], 16
(p15) fcmp.eq.unc.s1 p9,p0 = FR_l_AbsX, FR_c_XN //if argument is integer
// and negative
nop.i 0
}
{ .mfi
ldfe FR_c_PosOverflow = [GR_c_Table],16 //Load pos overflow value
(p15) fma.s1 FR_n_XS2 = FR_n_XS, FR_n_XS, f0 // xs^2 = xs*xs
nop.i 0
};;
{ .mfi
(p15) ldfe FR_n_A3 = [GR_n_sin_Table], 16
nop.f 0
nop.i 0
};;
{ .mfi
(p15) getf.sig GR_n_XN = FR_n_IXN // int(x) to general reg
fma.s1 FR_l_Y1 = FR_l_Y0,FR_l_E2,FR_l_Y0 // y1 = y+y*e2
nop.i 0
}
{ .mfb
nop.m 0
fma.s1 FR_l_E3 = FR_l_E1,FR_l_E1,FR_l_E0 // e3 = e+e1^2
(p9) br.cond.spnt tgammal_singularity // Singularity for integer /////////////
// and negative arguments //////////////
};;
{ .mfi
nop.m 0
fms.s1 FR_l_AbsX_m_Half = FR_l_AbsX, f1, FR_l_Half // |x|-0.5
extr.u GR_l_Index2 = GR_l_X_2, 1, 5 // Get Index3
};;
{ .mfi
shladd GR_l_Log_Table1= GR_l_Index2, 2, GR_l_Log_Table1
nop.f 0
shladd GR_l_Index3 = GR_l_Index2,4, GR_l_Log_Table // Index3
}
{ .mfb
(p15) cmp.gtu.unc p11, p0 = GR_n_XN, GR_c_NegUnderflow // X < -1765
fms.s1 FR_l_CXL = FR_l_CH, f1, FR_l_CXL // CXL = CH - CXL
(p11) br.cond.spnt tgammal_underflow // Singularity for negative argument //////
// at underflow domain (X < -1765) //////
};;
{ .mfi
addl GR_l_Log_Table = @ltoff(Constants_Tgammal_log_80_Q#), gp
(p15) fma.s1 FR_n_TT = FR_n_A2L, FR_n_XS2, f0 // T=A2L*x^2
tbit.nz.unc p13, p12 = GR_n_XN, 0x0 // whether [X] odd or even
}
{ .mfi
nop.m 0
(p15) fms.s1 FR_n_XS2L = FR_n_XS, FR_n_XS, FR_n_XS2 // xs^2 Low part
nop.i 0
};;
{ .mfi
ld8 GR_l_Log_Table = [GR_l_Log_Table]
(p15) fma.s1 FR_n_A7 = FR_n_A8, FR_n_XS2, FR_n_A7 // poly tail
nop.i 0
}
{ .mfi
ldfe FR_l_h_3 = [GR_l_Index3],12
(p15) fma.s1 FR_n_XS4 = FR_n_XS2, FR_n_XS2, f0 // xs^4 = xs^2*xs^2
nop.i 0
};;
{ .mfi
ldfs FR_l_H_3 = [GR_l_Log_Table1], 0
fma.s1 FR_l_Y2 = FR_l_Y1, FR_l_E3, FR_l_Y0 // y2 = y+y1*e3
nop.i 0
}
{ .mfi
ldfs FR_l_G_3 = [GR_l_Index3], 0
fnma.s1 FR_l_Z = FR_l_AbsX,FR_l_Q0,f1 // r = a-b*q
nop.i 0
};;
{ .mfi
nop.m 0
fmpy.s1 FR_l_G = FR_l_G_1, FR_l_G_2 // G = G1 * G_2
nop.i 0
}
{ .mfi
nop.m 0
fadd.s1 FR_l_H = FR_l_H_1, FR_l_H_2 // H = H_1 + H_2
nop.i 0
};;
{ .mfi
ldfe FR_l_log2_hi = [GR_l_Log_Table],16 // load log2_hi part
fadd.s1 FR_l_h = FR_l_h_1, FR_l_h_2 // h = h_1 + h_2
nop.i 0
}
{ .mfi
nop.m 0
fcvt.xf FR_l_float_N = FR_l_float_N // int(N)
nop.i 0
};;
{ .mfi
ldfe FR_l_log2_lo = [GR_l_Log_Table],16 // Load log2_lo part
fma.s1 FR_l_CXL = FR_l_CXL, f1, FR_l_CL
nop.i 0
}
{ .mfi
nop.m 0
(p15) fma.s1 FR_n_TT = FR_n_A2H, FR_n_XS2L, FR_n_TT // T=A2H*x2L+T
nop.i 0
};;
{ .mfi
ldfe FR_l_Q_6 = [GR_l_Log_Table],16
(p15) fma.s1 FR_n_A3 = FR_n_A4, FR_n_XS2, FR_n_A3 // poly tail
nop.i 0
}
{ .mfi
nop.m 0
(p15) fma.s1 FR_n_A5 = FR_n_A6, FR_n_XS2, FR_n_A5 // poly tail
nop.i 0
};;
{ .mfi
ldfe FR_l_Q_5 = [GR_l_Log_Table],16
(p15) fabs FR_n_XS = FR_n_XS // abs(xs)
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_l_Z = FR_l_Z,FR_l_Y2,FR_l_Q0 // x_hi = q+r*y2
nop.i 0
};;
{ .mfi
ldfe FR_l_Q_4 = [GR_l_Log_Table],16
(p15) fma.s1 FR_n_A7 = FR_n_A9, FR_n_XS4, FR_n_A7 // poly tail
nop.i 0
}
{ .mfi
nop.m 0
(p15) fma.s1 FR_n_XS7 = FR_n_XS4, FR_n_XS2, f0 // = x^4*x^2
nop.i 0
};;
{ .mfi
ldfe FR_l_Q_3 = [GR_l_Log_Table],16
fneg FR_n_NegOne = f1 // -1.0
nop.i 0
}
{ .mfi
nop.m 0
(p15) fma.s1 FR_n_XS8 = FR_n_XS4, FR_n_XS4, f0 // xs^8 = xs^4*xs^4
nop.i 0
};;
{ .mfi
ldfe FR_l_Q_2 = [GR_l_Log_Table],16
fadd.s1 FR_l_h = FR_l_h, FR_l_h_3 // h = h_1 + h_2 + h_3
nop.i 0
}
{ .mfi
nop.m 0
(p15) fma.s1 FR_n_TH = FR_n_A2H, FR_n_XS2, FR_n_TT // A2H*xs2+T
nop.i 0
};;
{ .mfi
ldfe FR_l_Q_1 = [GR_l_Log_Table],16
fmpy.s1 FR_l_G = FR_l_G, FR_l_G_3 // G = G_1 * G_2 * G_3
nop.i 0
}
{ .mfi
nop.m 0
fadd.s1 FR_l_H = FR_l_H, FR_l_H_3 // H = H_1 + H_2 + H_3
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_l_Z2 = FR_l_Z, FR_l_Z, f0 // Z^2
nop.i 0
}
{ .mfi
nop.m 0
(p15) fma.s1 FR_n_A3 = FR_n_A5, FR_n_XS4, FR_n_A3 // poly tail
nop.i 0
};;
{ .mfi
nop.m 0
(p14) fcmp.gt.unc.s1 p7,p0 = FR_l_AbsX, FR_c_PosOverflow //X > 1755.5483
// (overflow domain, result cannot be represented by normal value)
nop.i 0
}
{ .mfi
nop.m 0
(p15) fma.s1 FR_n_XS7 = FR_n_XS7, FR_n_XS, f0 // x^7 construction
nop.i 0
};;
{ .mfi
nop.m 0
(p15) fms.s1 FR_n_TL = FR_n_A2H, FR_n_XS2, FR_n_TH // A2H*xs2+TH
nop.i 0
}
{ .mfi
nop.m 0
(p15) fma.s1 FR_n_PolyH = FR_n_TH, f1, FR_n_A1H // PolyH=TH+A1H
nop.i 0
};;
{ .mfi
nop.m 0
fmpy.s1 FR_l_GS_hi = FR_l_G, FR_l_S // GS_hi = G*S
nop.i 0
}
{ .mfb
nop.m 0
fms.s1 FR_l_r = FR_l_G, FR_l_S, f1 // r = G*S -1
(p7) br.cond.spnt tgammal_overflow // Overflow path for arg > 1755.5483 //////
};;
{ .mfi
nop.m 0
fma.s1 FR_l_B14 = FR_l_B16, FR_l_Z2, FR_l_B14// Bernoulli tail
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_l_Z4 = FR_l_Z2, FR_l_Z2, f0 // Z^4 = Z^2*Z^2
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_l_B2 = FR_l_B4, FR_l_Z2, FR_l_B2 // Bernoulli tail
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_l_B6 = FR_l_B8, FR_l_Z2, FR_l_B6 // Bernoulli tail
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_l_B10 = FR_l_B12, FR_l_Z2, FR_l_B10// Bernoulli tail
nop.i 0
}
{ .mfi
nop.m 0
(p15) fma.s1 FR_n_Tail = FR_n_A7, FR_n_XS8, FR_n_A3 // poly tail
nop.i 0
};;
{ .mfi
nop.m 0
(p15) fma.s1 FR_n_TL = FR_n_TL, f1, FR_n_TT // TL = TL+T
nop.i 0
}
{ .mfi
nop.m 0
(p15) fms.s1 FR_n_PolyL = FR_n_A1H, f1, FR_n_PolyH // polyH+A1H
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_l_poly_lo = FR_l_r, FR_l_Q_6, FR_l_Q_5 // Q_5+r*Q_6
nop.i 0
}
{ .mfi
nop.m 0
fsub.s1 FR_l_r_cor = FR_l_GS_hi, f1 // r_cor = GS_hi -1
nop.i 0
};;
{ .mfi
nop.m 0
fms.s1 FR_l_GS_lo = FR_l_G, FR_l_S, FR_l_GS_hi // G*S-GS_hi
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_l_poly = FR_l_r, FR_l_Q_2, FR_l_Q_1 //poly=r*Q2+Q1
nop.i 0
};;
{ .mfi
nop.m 0
fmpy.s1 FR_l_rsq = FR_l_r, FR_l_r // rsq = r * r
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_l_G = FR_l_float_N, FR_l_log2_hi, FR_l_H // Tbl =
// float_N*log2_hi + H
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_l_Y_lo = FR_l_float_N, FR_l_log2_lo, FR_l_h // Y_lo=
// float_N*log2_lo + h
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_l_B14 = FR_l_B18, FR_l_Z4, FR_l_B14 //bernulli tail
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_l_B2 = FR_l_B6, FR_l_Z4, FR_l_B2 //bernulli tail
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_l_Z8 = FR_l_Z4, FR_l_Z4, f0 //bernulli tail
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_l_poly_lo = FR_l_r, FR_l_poly_lo, FR_l_Q_4 // poly_lo =
// Q_4 + r * poly_lo
nop.i 0
}
{ .mfi
nop.m 0
fsub.s1 FR_l_r_cor = FR_l_r_cor, FR_l_r // r_cor = r_cor - r
nop.i 0
};;
{ .mfi
nop.m 0
(p15) fma.s1 FR_n_PolyL = FR_n_PolyL, f1, FR_n_TH // polyL+TH
nop.i 0
}
{ .mfi
nop.m 0
(p15) fma.s1 FR_n_TT = FR_n_TL, f1, FR_n_A1L // TL+A1L
nop.i 0
};;
{ .mfi
nop.m 0
fadd.s1 FR_l_logl_YHi = FR_l_G, FR_l_r // Y_hi = Tbl + r
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_l_B10 = FR_l_B14, FR_l_Z4, FR_l_B10 //bernulli tail
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_l_poly_lo = FR_l_r, FR_l_poly_lo, FR_l_Q_3 // poly_lo =
// Q_3 + r * poly_lo
nop.i 0
}
{ .mfi
nop.m 0
fadd.s1 FR_l_r_cor = FR_l_r_cor, FR_l_GS_lo // r_cor=r_cor+GS_lo
nop.i 0
};;
{ .mfi
nop.m 0
(p15) fma.s1 FR_n_PolyL = FR_n_PolyL, f1, FR_n_TT // polyL+TT
nop.i 0
};;
{ .mfi
nop.m 0
fsub.s1 FR_l_Y_lo_res = FR_l_G, FR_l_logl_YHi // Y_lo = Tbl - Y_hi
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_l_XYH = FR_l_logl_YHi, FR_l_AbsX_m_Half, f0 // XYH=
// YHi*|x-0.5|
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_l_SS = FR_l_B10, FR_l_Z8, FR_l_B2 // Bernoulli tail
nop.i 0
};;
{ .mfi
nop.m 0
fadd.s1 FR_l_r_cor = FR_l_r_cor, FR_l_Y_lo // r_cor = r_cor+Y_lo
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_l_poly = FR_l_rsq, FR_l_poly_lo, FR_l_poly //poly=
// r^2*polyLo+poly
nop.i 0
};;
{ .mfi
nop.m 0
(p15) fma.s1 FR_n_TT = FR_n_PolyL, FR_n_XS2, f0 // T=polyL*xs^2
nop.i 0
};;
{ .mfi
nop.m 0
fadd.s1 FR_l_Y_lo = FR_l_Y_lo_res, FR_l_r // Y_lo = Y_lo + r
nop.i 0
}
{ .mfi
nop.m 0
fms.s1 FR_l_XYL = FR_l_logl_YHi, FR_l_AbsX_m_Half, FR_l_XYH
// XYL = YHi*|x-0.5|-XYH
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_l_SSCXH = FR_l_SS, FR_l_Z, FR_l_CXH // SS*Z+CXH
nop.i 0
}
{ .mfi
mov GR_e_exp_2tom51= 0xffff-51 // 2^-51
(p15) fma.s1 FR_l_SignedXYH = FR_l_XYH, FR_n_NegOne, f0 // XYH = -XYH
// for negatives
nop.i 0
};;
{ .mlx
nop.m 0
movl GR_e_rshf_2to51 = 0x4718000000000000 // 1.10000 2^(63+51)
}
{ .mlx
nop.m 0
movl GR_e_sig_inv_ln2 = 0xb8aa3b295c17f0bc //significand of 1/ln2
};;
{ .mfi
nop.m 0
fma.s1 FR_l_poly = FR_l_rsq, FR_l_poly, FR_l_r_cor // poly =
// rsq * poly + r_cor
nop.i 0
};;
{ .mfi
addl GR_e_ad_Arg = @ltoff(Constants_Tgammal_exp_64_Arg#),gp
(p15) fma.s1 FR_n_TT = FR_n_PolyH, FR_n_XS2L, FR_n_TT
mov GR_e_exp_mask = 0x1FFFF // Form exponent mask
}
{ .mlx
nop.m 0
movl GR_e_rshf = 0x43e8000000000000 // 1.10000 2^63 rshift
};;
{ .mmi
setf.sig FR_e_INV_LN2_2TO63 = GR_e_sig_inv_ln2 // form 1/ln2 * 2^63
setf.d FR_e_RSHF_2TO51 = GR_e_rshf_2to51 // 1.1000 * 2^(63+51)
nop.i 0
};;
{ .mfi
nop.m 0
fms.s1 FR_l_SSCXL = FR_l_CXH, f1, FR_l_SSCXH // CXH+SS*CXH
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_e_expl_Input_AbsX = FR_l_XYH, f1, FR_l_SSCXH // HI EXP
nop.i 0
};;
.pred.rel "mutex",p14,p15
{ .mfi
nop.m 0
(p14) fma.s1 FR_e_expl_Input_X = FR_l_XYH, f1, FR_l_SSCXH // HI EXP
mov GR_e_exp_bias = 0x0FFFF // Set exponent bias
}
{ .mfi
ld8 GR_e_ad_Arg = [GR_e_ad_Arg] // Point to Arg table
(p15) fms.s1 FR_e_expl_Input_X = FR_l_SignedXYH, f1, FR_l_SSCXH // HI EXP
nop.i 0
};;
{ .mfi
nop.m 0
fadd.s1 FR_l_logl_YLo = FR_l_Y_lo, FR_l_poly // YLo = YLo+poly
nop.i 0
};;
{ .mfi
setf.exp FR_e_2TOM51 = GR_e_exp_2tom51 //2^-51 for scaling float_N
(p15) fma.s1 FR_n_TH = FR_n_PolyH, FR_n_XS2, FR_n_TT // TH=
// polyH*xs^2+T
nop.i 0
}
{ .mib
setf.d FR_e_RSHF = GR_e_rshf // Right shift const 1.1000*2^63
nop.i 0
nop.b 0
};;
{ .mfi
add GR_e_ad_A = 0x20, GR_e_ad_Arg // Point to A table
nop.f 0
add GR_e_ad_T1 = 0x50, GR_e_ad_Arg // Point to T1 table
}
{ .mfi
add GR_e_ad_T2 = 0x150, GR_e_ad_Arg // Point to T2 table
nop.f 0
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_l_SSCXL = FR_l_SS, FR_l_Z, FR_l_SSCXL
nop.i 0
}
{ .mfi
nop.m 0
fms.s1 FR_e_expl_Input_Y = FR_l_XYH, f1, FR_e_expl_Input_AbsX
nop.i 0
};;
{ .mfi
ldfe FR_e_L_hi = [GR_e_ad_Arg],16 // Get L_hi
nop.f 0
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_l_XYL = FR_l_logl_YLo, FR_l_AbsX_m_Half, FR_l_XYL
// XYL = YLo*|x-0.5|+XYL
nop.i 0
};;
{ .mfi
ldfe FR_e_L_lo = [GR_e_ad_Arg],16 // Get L_lo
(p15) fms.s1 FR_n_TL = FR_n_PolyH, FR_n_XS2, FR_n_TH // TL =
// = polyH*xs^2-TH
add GR_e_ad_W1 = 0x100, GR_e_ad_T2 // Point to W1 table
}
{ .mfi
nop.m 0
(p15) fma.s1 FR_n_Poly1H = FR_n_TH, f1, f1 // poly1H = TH+1
add GR_e_ad_W2 = 0x300, GR_e_ad_T2 // Point to W2 table
};;
{ .mmi
getf.exp GR_e_signexp_x = FR_e_expl_Input_X // Extract sign and exp
ldfe FR_e_A3 = [GR_e_ad_A],16 // Get A3
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_l_SSCXL = FR_l_SSCXL, f1, FR_l_CXL
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_e_expl_Input_Y = FR_e_expl_Input_Y, f1, FR_l_SSCXH
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_e_N_signif=FR_e_expl_Input_X,FR_e_INV_LN2_2TO63,FR_e_RSHF_2TO51
and GR_e_exp_x = GR_e_signexp_x, GR_e_exp_mask
};;
{ .mmi
sub GR_e_exp_x = GR_e_exp_x, GR_e_exp_bias // Get exponent
ldfe FR_e_A2 = [GR_e_ad_A],16 // Get A2 for main path
nop.i 0
};;
{ .mfi
nop.m 0
(p15) fma.s1 FR_n_PolyH = FR_n_Poly1H, FR_n_XS, f0//sin(Pi*x) poly
nop.i 0
}
{ .mfi
nop.m 0
(p15) fms.s1 FR_n_Poly1L = f1, f1, FR_n_Poly1H//sin(Pi*x) poly
nop.i 0
};;
{ .mfi
nop.m 0
(p15) fma.s1 FR_n_TL = FR_n_TL, f1, FR_n_TT//sin(Pi*x) poly
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_l_Temp = FR_l_XYL, f1, FR_l_SSCXL // XYL+SS*CXL
nop.i 0
}
{ .mfi
nop.m 0
(p15) fma.s1 FR_e_expl_Input_Y = FR_e_expl_Input_Y, FR_n_NegOne, f0
// Negate lo part of exp argument for negative input values
nop.i 0
};;
{ .mfi
ldfe FR_e_A1 = [GR_e_ad_A],16 // Get A1
nop.f 0
nop.i 0
}
{ .mfi
nop.m 0
fms.s1 FR_e_float_N = FR_e_N_signif, FR_e_2TOM51, FR_e_RSHF
// Get float N = signd*2^51-RSHIFTER
nop.i 0
};;
{ .mfi
nop.m 0
(p15) fma.s1 FR_n_Poly1L = FR_n_Poly1L, f1, FR_n_TH //sin(Pi*x) poly
nop.i 0
}
{ .mfi
nop.m 0
(p15) fms.s1 FR_n_PolyL = FR_n_Poly1H, FR_n_XS, FR_n_PolyH//sin(Pi*x)
nop.i 0
};;
{ .mfi
getf.sig GR_e_N_fix = FR_e_N_signif // Get N from significand
nop.f 0
nop.i 0
};;
.pred.rel "mutex",p14,p15
{ .mfi
nop.m 0
(p14) fma.s1 FR_e_expl_Input_Y = FR_e_expl_Input_Y, f1, FR_l_Temp
nop.i 0
}
{ .mfi
nop.m 0
(p15) fms.s1 FR_e_expl_Input_Y = FR_e_expl_Input_Y, f1, FR_l_Temp
// arguments for exp computation
nop.i 0
};;
{ .mfi
nop.m 0
fnma.s1 FR_e_r = FR_e_L_hi, FR_e_float_N, FR_e_expl_Input_X
// r = -L_hi * float_N + x
extr.u GR_e_M1 = GR_e_N_fix, 6, 6 // Extract index M_1
};;
{ .mfi
nop.m 0
(p15) fma.s1 FR_n_Poly1L = FR_n_Poly1L, f1, FR_n_TL //sin(Pi*x) poly
nop.i 0
};;
{ .mmf
nop.m 0
nop.m 0
fma.s1 FR_e_r = FR_e_r, f1, FR_e_expl_Input_Y
// r = r + FR_e_expl_Input_Y
};;
{ .mmi
shladd GR_e_ad_W1 = GR_e_M1,3,GR_e_ad_W1 // Point to W1
shladd GR_e_ad_T1 = GR_e_M1,2,GR_e_ad_T1 // Point to T1
extr.u GR_e_M2 = GR_e_N_fix, 0, 6 // Extract index M_2
};;
{ .mfi
ldfs FR_e_T1 = [GR_e_ad_T1],0 // Get T1
nop.f 0
extr GR_e_K = GR_e_N_fix, 12, 32 //Extract limit range K
}
{ .mfi
shladd GR_e_ad_T2 = GR_e_M2,2,GR_e_ad_T2 // Point to T2
(p15) fma.s1 FR_n_PolyL = FR_n_Poly1L, FR_n_XS, FR_n_PolyL
//sin(Pi*x) poly
shladd GR_e_ad_W2 = GR_e_M2,3,GR_e_ad_W2 // Point to W2
};;
{ .mfi
ldfs FR_e_T2 = [GR_e_ad_T2],0 // Get T2
nop.f 0
add GR_e_exp_2_k = GR_e_exp_bias, GR_e_K // exp of 2^k
}
{ .mfi
ldfd FR_e_W1 = [GR_e_ad_W1],0 // Get W1
nop.f 0
sub GR_e_exp_2_mk = GR_e_exp_bias, GR_e_K // exp of 2^-k
};;
{ .mmi
ldfd FR_e_W2 = [GR_e_ad_W2],0 // Get W2
nop.m 0
nop.i 0
};;
{ .mmf
setf.exp FR_e_scale = GR_e_exp_2_k // Set scale = 2^k
setf.exp FR_e_2_mk = GR_e_exp_2_mk // Form 2^-k
fnma.s1 FR_e_r = FR_e_L_lo, FR_e_float_N, FR_e_r
// r = -L_lo * float_N + r
};;
{ .mfi
nop.m 0
(p15) fma.s1 FR_n_PolyL = FR_n_Tail, FR_n_XS7, FR_n_PolyL
//sin(Pi*x) poly
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_e_poly = FR_e_r, FR_e_A3, FR_e_A2 // poly=r*A3+A2
nop.i 0
}
{ .mfi
nop.m 0
fmpy.s1 FR_e_rsq = FR_e_r, FR_e_r // rsq = r * r
nop.i 0
};;
{ .mfi
nop.m 0
fmpy.s1 FR_e_T = FR_e_T1, FR_e_T2 // T = T1 * T2
nop.i 0
}
{ .mfi
nop.m 0
fadd.s1 FR_e_W1_p1 = FR_e_W1, f1 // W1_p1 = W1 + 1.0
nop.i 0
};;
{ .mfi
nop.m 0
(p15) fma.s1 FR_n_TT = FR_n_PolyL, FR_l_AbsX, f0 //sin(Pi*x) poly
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_e_poly = FR_e_r, FR_e_poly, FR_e_A1
// poly = r * poly + A1
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_e_T_scale = FR_e_T, FR_e_scale, f0 // T_scale=T*scale
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_e_W = FR_e_W2, FR_e_W1_p1, FR_e_W1
// W = W2 * (W1+1.0) + W1
nop.i 0
};;
{ .mfi
nop.m 0
(p15) fma.s1 FR_n_SinxH = FR_n_PolyH, FR_l_AbsX, FR_n_TT
// sin(Pi*x) poly
nop.i 0
};;
{ .mfi
nop.m 0
mov FR_e_Y_hi = FR_e_T // Assume Y_hi = T
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_e_poly = FR_e_rsq, FR_e_poly, FR_e_r
// poly = rsq * poly + r
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_e_Wp1_T_scale = FR_e_W, FR_e_T_scale, FR_e_T_scale
// (W+1)*T*scale
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_e_W_T_scale = FR_e_W, FR_e_T_scale, f0 // W*T*scale
nop.i 0
};;
{ .mfi
nop.m 0
(p15) fms.s1 FR_n_SinxL = FR_n_PolyH, FR_l_AbsX, FR_n_SinxH
// Low part of sin
nop.i 0
};;
{ .mfi
nop.m 0
(p15) frcpa.s1 FR_n_Y0, p0 = f1, FR_n_SinxH // y = frcpa(b)
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_e_result_lo = FR_e_Wp1_T_scale, FR_e_poly, FR_e_W_T_scale
// Low part of exp result
nop.i 0
};;
{ .mfi
nop.m 0
(p15) fma.s1 FR_n_SinxL = FR_n_SinxL, f1, FR_n_TT // sin low result
nop.i 0
};;
{ .mfi
nop.m 0
(p15) fma.s1 FR_n_Q0 = f1,FR_n_Y0,f0 // q = y
nop.i 0
}
{ .mfi
nop.m 0
(p15) fnma.s1 FR_n_E0 = FR_n_Y0, FR_n_SinxH, f1 // e = 1-b*y
nop.i 0
};;
{ .mfb
nop.m 0
(p14) fma.s0 f8 = FR_e_Y_hi, FR_e_scale, FR_e_result_lo
(p14) br.ret.spnt b0 // Exit for positive Stirling path //////////////////////
};;
{ .mfi
nop.m 0
fma.s1 FR_e_expl_Output_X = FR_e_Y_hi, FR_e_scale, f0 // exp result
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_e_expl_Output_Y = FR_e_result_lo, f1, f0// exp lo result
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_n_E2 = FR_n_E0,FR_n_E0,FR_n_E0 // e2 = e+e^2
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_n_E1 = FR_n_E0,FR_n_E0,f0 // e1 = e^2
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_n_Y1 = FR_n_Y0,FR_n_E2,FR_n_Y0 // y1 = y+y*e2
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_n_E3 = FR_n_E1,FR_n_E1,FR_n_E0 // e3 = e+e1^2
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_n_Y2 = FR_n_Y1,FR_n_E3,FR_n_Y0 // y2 = y+y1*e3
nop.i 0
}
{ .mfi
nop.m 0
fnma.s1 FR_n_R0 = FR_n_SinxH,FR_n_Q0,f1 // r = a-b*q
nop.i 0
};;
{ .mfi
nop.m 0
fnma.s1 FR_n_E4 = FR_n_SinxH,FR_n_Y2,f1 // e4 = 1-b*y2
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_n_RcpResH = FR_n_R0,FR_n_Y2,FR_n_Q0 // x = q+r*y2
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_n_Y3 = FR_n_Y2,FR_n_E4,FR_n_Y2 // y3 = y2+y2*e4
nop.i 0
}
{ .mfi
nop.m 0
fnma.s1 FR_n_R1 = FR_n_SinxH,FR_n_RcpResH,f1 // r1 = a-b*x
nop.i 0
};;
{ .mfi
nop.m 0
fnma.s1 FR_n_R1 = FR_n_SinxL,FR_n_RcpResH,FR_n_R1
// r1 = r1 - b_lo*X
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_n_RcpResL = FR_n_R1,FR_n_Y3,f0 // x_lo = r1*y3
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_n_Temp = FR_n_RcpResH, FR_e_expl_Output_Y, f0
// Multiplying exp and sin result
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_n_Temp = FR_n_RcpResL, FR_e_expl_Output_X, FR_n_Temp
// Multiplying exp and sin result
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_n_ResH = FR_n_RcpResH, FR_e_expl_Output_X, FR_n_Temp
// Multiplying exp and sin result
nop.i 0
};;
{ .mfi
nop.m 0
fms.s1 FR_n_ResL = FR_n_RcpResH, FR_e_expl_Output_X, FR_n_ResH
// Multiplying exp and sin result
nop.i 0
}
{ .mfi
nop.m 0
(p12) fma.s1 FR_n_ResH = FR_n_ResH, FR_n_NegOne, f0 // Negate
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_n_ResL = FR_n_ResL, f1, FR_n_Temp
// Multiplying exp and sin result - low result obtained
nop.i 0
};;
.pred.rel "mutex",p12,p13
{ .mfi
nop.m 0
(p13) fma.s0 f8 = FR_n_ResH, f1, FR_n_ResL // For odd
nop.i 0
}
{ .mfb
nop.m 0
(p12) fms.s0 f8 = FR_n_ResH, f1, FR_n_ResL // For even
br.ret.sptk b0 // Exit for negative Stirling path //////////////////////
};;
//////////// 1 <= |X| < 13 path ////////////////////////////////////////////////
//------------------------------------------------------------------------------
.align 64
tgamma_lt_13:
{ .mfi
getf.sig GR_p_XN = FR_p_IXN // Get significand
fcvt.xf FR_p_XN = FR_p_IXN // xn = [x]
add GR_r_sin_Table2= 0x40, GR_r_sin_Table // Shifted table addr.
}
{ .mfi
ldfpd FR_p_0p5, FR_p_1p5 = [GR_c_Table], 16 // 0.5 & 1.5
fms.s1 FR_p_AbsXM1 = FR_p_AbsX, f1, f1 // X-1
add GR_p_Table2 = 0xB0, GR_p_Table
};;
{ .mfi
add GR_r_sin_Table = -16, GR_r_sin_Table // For compensation
fcvt.xf FR_r_XNS = FR_r_IXNS // Convert int repr to float
shr.u GR_p_X_Sgnd = GR_p_X_Sgnd, 59 // Get only 5 bit of signd
};;
{ .mfi
ldfpd FR_r_A2H,FR_r_A2L = [GR_r_sin_Table], 16 // Load A2
nop.f 0
add GR_p_Int = -2, GR_p_XN // int = int - 2
}
{ .mfi
ldfe FR_r_A6 = [GR_r_sin_Table2], 16
nop.f 0
cmp.gtu p11, p12 = 0x2, GR_p_XN // p11: x < 2 (splitted intervals),
// p12: x > 2 (base intervals)
};;
{ .mfi
ldfpd FR_r_A1H, FR_r_A1L = [GR_r_sin_Table], 16
nop.f 0
shr GR_p_Int = GR_p_Int, 1 // int/2
}
{ .mfi
ldfe FR_r_A5 = [GR_r_sin_Table2], 16
nop.f 0
(p11) cmp.gtu.unc p10, p11 = 0x1C, GR_p_X_Sgnd // sgnd(x) < 0.75
};;
{ .mfi
ldfe FR_r_A9 = [GR_r_sin_Table], 16
nop.f 0
shl GR_p_Offset = GR_p_Int, 4 // offset = int*16
}
{ .mfi
ldfe FR_r_A4 = [GR_r_sin_Table2], 16
nop.f 0
(p10) cmp.gtu.unc p9, p10 = 0x14, GR_p_X_Sgnd // sgnd(x) < 0.25
};;
{ .mfi
ldfe FR_r_A8 = [GR_r_sin_Table], 16
nop.f 0
(p12) tbit.nz.unc p13, p12 = GR_p_XN, 0x0 // p13: reccurent computations
// X is at [3;4], [5;6], [7;8]... interval
}
{ .mfi
ldfe FR_r_A3 = [GR_r_sin_Table2], 16
nop.f 0
shladd GR_p_Offset = GR_p_Int, 2, GR_p_Offset // +int*4
};;
.pred.rel "mutex",p9,p11
{ .mfi
add GR_p_Offset = GR_p_Int, GR_p_Offset
// +int, so offset = int*21
(p9) fms.s1 FR_p_XR = FR_p_AbsX, f1, f1 // r = x-1
nop.i 0
}
{ .mfi
ldfe FR_r_A7 = [GR_r_sin_Table], 16
(p11) fms.s1 FR_p_XR = FR_p_2, f1, FR_p_AbsX
// r = 2-x for 1.75 < x < 2
nop.i 0
};;
.pred.rel "mutex",p9,p10
.pred.rel "mutex",p10,p11
.pred.rel "mutex",p9,p11
{ .mfi
(p9) add GR_p_Offset = 126, r0 // 1.0 < x < 1.25 table
(p15) fcmp.eq.unc.s1 p7,p0 = FR_p_AbsX, FR_p_XN
// If arg is integer and negative - singularity branch
nop.i 0
}
{ .mfi
(p10) add GR_p_Offset = 147, r0 // 1.25 < x < 1.75 table
nop.f 0
(p11) add GR_p_Offset = 168, r0 // 1.75 < x < 2.0 table
};;
{ .mmf
shladd GR_p_Table = GR_p_Offset, 4, GR_p_Table
shladd GR_p_Table2 = GR_p_Offset, 4, GR_p_Table2
fma.s1 FR_r_XS = FR_r_AbsX , f1, FR_r_XNS // xs = x - [x]
};;
{ .mmb
ldfpd FR_p_A5H, FR_p_A5L = [GR_p_Table], 16
ldfpd FR_p_A2H, FR_p_A2L = [GR_p_Table2], 16
(p7) br.cond.spnt tgammal_singularity // Singularity for integer /////////////
// and negative argument ///////////////
};;
{ .mfi
ldfpd FR_p_A4H, FR_p_A4L = [GR_p_Table], 16
fma.s1 FR_p_XN = FR_p_XN, f1, FR_p_0p5 // xn = xn+0.5
nop.i 0
}
{ .mfi
ldfpd FR_p_A1H, FR_p_A1L = [GR_p_Table2], 16
(p10) fms.s1 FR_p_XR = FR_p_AbsX, f1, FR_p_1p5 // r = x - 1.5
nop.i 0
};;
{ .mmi
ldfpd FR_p_A3H, FR_p_A3L = [GR_p_Table], 16
ldfpd FR_p_A0H, FR_p_A0L = [GR_p_Table2], 16
nop.i 0
};;
{ .mmi
ldfe FR_p_A20 = [GR_p_Table], 16
ldfe FR_p_A12 = [GR_p_Table2], 16
nop.i 0
};;
{ .mmf
ldfe FR_p_A19 = [GR_p_Table], 16
ldfe FR_p_A11 = [GR_p_Table2], 16
fma.s1 FR_r_XS2 = FR_r_XS, FR_r_XS, f0 // xs2 = xs*xs
};;
{ .mmi
ldfe FR_p_A18 = [GR_p_Table], 16
ldfe FR_p_A10 = [GR_p_Table2], 16
nop.i 0
};;
.pred.rel "mutex",p12,p13
{ .mfi
ldfe FR_p_A17 = [GR_p_Table], 16
(p12) fms.s1 FR_p_XR = FR_p_AbsX, f1, FR_p_XN // r = x - xn
nop.i 0
}
{ .mfi
ldfe FR_p_A9 = [GR_p_Table2], 16
(p13) fms.s1 FR_p_XR = FR_p_AbsX, f1, FR_p_XN
nop.i 0
};;
{ .mmi
ldfe FR_p_A16 = [GR_p_Table], 16
ldfe FR_p_A8 = [GR_p_Table2], 16
(p9) cmp.eq p12, p0 = r0, r0 // clear p12
};;
{ .mmi
ldfe FR_p_A15 = [GR_p_Table], 16
ldfe FR_p_A7 = [GR_p_Table2], 16
(p10) cmp.eq p12, p0 = r0, r0 // clear p12
};;
{ .mfi
ldfe FR_p_A14 = [GR_p_Table], 16
fma.s1 FR_r_TH = FR_r_A2H, FR_r_XS2, f0 // sin for neg
(p11) cmp.eq p12, p0 = r0, r0 // clear p12
}
{ .mfi
ldfe FR_p_A6 = [GR_p_Table2], 16
fma.s1 FR_r_TL = FR_r_A2L, FR_r_XS2, f0 // sin for neg
nop.i 0
};;
{ .mfi
ldfe FR_p_A13 = [GR_p_Table], 16
fms.s1 FR_r_XS2L = FR_r_XS, FR_r_XS, FR_r_XS2 // x2Lo part
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_p_Temp5H = FR_p_A5H, FR_p_XR, f0 // A5H*r
// 'Low poly'
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_p_XR2 = FR_p_XR, FR_p_XR, f0 // r^2 = r*r
nop.i 0
};;
{ .mfi
nop.m 0
fabs FR_r_XS = FR_r_XS // abs(xs)
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_p_Temp2H = FR_p_A2H, FR_p_XR, f0 // A2H*r
// 'High poly'
nop.i 0
};;
{ .mfi
nop.m 0
fms.s1 FR_r_TT = FR_r_A2H, FR_r_XS2, FR_r_TH // sin for neg
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_r_ResH = FR_r_TH, f1, FR_r_A1H // sin for neg
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_r_TL = FR_r_A2H, FR_r_XS2L, FR_r_TL // sin for neg
nop.i 0
};;
{ .mfi
nop.m 0
fms.s1 FR_p_Temp5L = FR_p_A5H,FR_p_XR,FR_p_Temp5H //A5H*r delta
// 'Low poly'
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_p_Poly5H = FR_p_Temp5H, f1, FR_p_A4H // A5H*r+A4H
// 'Low poly'
nop.i 0
};;
{ .mfi
nop.m 0
fms.s1 FR_p_Temp2L = FR_p_A2H, FR_p_XR, FR_p_Temp2H//A2H*r delta
//'High poly'
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_p_Poly2H = FR_p_Temp2H, f1, FR_p_A1H // A2H*r+A1H
//'High poly'
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_p_XR3 = FR_p_XR2, FR_p_XR, f0 // r^3 = r^2*r
nop.i 0
}
{ .mfi
nop.m 0
fms.s1 FR_p_XR2L = FR_p_XR, FR_p_XR, FR_p_XR2 // r^2 delta
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_p_A18 = FR_p_A19, FR_p_XR, FR_p_A18 // Poly tail
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_p_A14 = FR_p_A15, FR_p_XR, FR_p_A14 // Poly tail
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_p_XR4 = FR_p_XR2, FR_p_XR2, f0 // r^4 = r^2*r^2
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_p_Temp5L = FR_p_A5L, FR_p_XR, FR_p_Temp5L// Low part
// of A5*r+A4
nop.i 0
}
{ .mfi
nop.m 0
fms.s1 FR_p_Poly5L = FR_p_A4H, f1, FR_p_Poly5H // Low part
// of A5*r+A4
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_p_Temp4H = FR_p_Poly5H, FR_p_XR, f0 // (A5H*r+A4H)*r
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_p_Temp2L = FR_p_A2L, FR_p_XR, FR_p_Temp2L // A2*r low
nop.i 0
};;
{ .mfi
nop.m 0
fms.s1 FR_p_Poly2L = FR_p_A1H, f1, FR_p_Poly2H // High poly
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_p_Temp1H = FR_p_Poly2H, FR_p_XR, f0 // High poly
nop.i 0
};;
{ .mfi
nop.m 0
fms.s1 FR_p_XR3L = FR_p_XR2, FR_p_XR, FR_p_XR3 // x^3 delta
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_p_A16 = FR_p_A17, FR_p_XR, FR_p_A16 // Poly tail
nop.i 0
};;
{ .mfi
nop.m 0
fms.s1 FR_r_ResL = FR_r_A1H, f1, FR_r_ResH // sin for neg
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_r_TL = FR_r_TL, f1, FR_r_TT // sin for neg
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_p_Temp5L = FR_p_Temp5L, f1, FR_p_A4L // Low poly
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_p_Poly5L = FR_p_Poly5L, f1, FR_p_Temp5H // Low poly
nop.i 0
};;
{ .mfi
nop.m 0
fms.s1 FR_p_Temp4L = FR_p_Poly5H,FR_p_XR,FR_p_Temp4H //Low poly
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_p_Poly4H = FR_p_Temp4H, f1, FR_p_A3H // Low poly
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_p_Temp2L = FR_p_Temp2L, f1, FR_p_A1L // High poly
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_p_Poly2L = FR_p_Poly2L, f1, FR_p_Temp2H // High poly
nop.i 0
};;
{ .mfi
nop.m 0
fms.s1 FR_p_Temp1L = FR_p_Poly2H,FR_p_XR,FR_p_Temp1H //High poly
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_p_Poly1H = FR_p_Temp1H, f1, FR_p_A0H // High poly
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_p_A12 = FR_p_A13, FR_p_XR, FR_p_A12 // Poly tail
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_p_XR3L = FR_p_XR2L, FR_p_XR, FR_p_XR3L // x^3 low
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_p_Poly5L = FR_p_Poly5L, f1, FR_p_Temp5L // Low poly
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_p_A10 = FR_p_A11, FR_p_XR, FR_p_A10 // Poly tail
nop.i 0
};;
{ .mfi
nop.m 0
fms.s1 FR_p_Poly4L = FR_p_A3H, f1, FR_p_Poly4H // Low poly
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_p_A6 = FR_p_A7, FR_p_XR, FR_p_A6 // Poly tail
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_p_A8 = FR_p_A9, FR_p_XR, FR_p_A8 // Poly tail
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_p_XR6 = FR_p_XR4, FR_p_XR2, f0 // Poly tail
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_p_Poly2L = FR_p_Poly2L, f1, FR_p_Temp2L // High poly
nop.i 0
}
{ .mfi
nop.m 0
fms.s1 FR_p_Poly1L = FR_p_A0H, f1, FR_p_Poly1H // High poly
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_r_ResL = FR_r_ResL, f1, FR_r_TH // sin for neg
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_r_TT = FR_r_TL, f1, FR_r_A1L // sin for neg
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_p_Temp4L = FR_p_Poly5L,FR_p_XR,FR_p_Temp4L // Low poly
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_p_A18 = FR_p_A20, FR_p_XR2, FR_p_A18 // Poly tail
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_p_Poly4L = FR_p_Poly4L, f1, FR_p_Temp4H // Low poly
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_p_A14 = FR_p_A16, FR_p_XR2, FR_p_A14 // Poly tail
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_p_A6 = FR_p_A8, FR_p_XR2, FR_p_A6 // Poly tail
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_p_A10 = FR_p_A12, FR_p_XR2, FR_p_A10 // Poly tail
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_p_Temp1L = FR_p_Poly2L,FR_p_XR,FR_p_Temp1L //High poly
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_p_Poly1L = FR_p_Poly1L, f1, FR_p_Temp1H // High poly
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_r_ResL = FR_r_ResL, f1, FR_r_TT // sin for neg
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_r_TH = FR_r_ResH, FR_r_XS2, f0 // sin for neg
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_p_Temp4L = FR_p_Temp4L, f1, FR_p_A3L // Low poly
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_p_Poly3H = FR_p_Poly4H, FR_p_XR3, f0 // Low poly
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_p_A14 = FR_p_A18, FR_p_XR4, FR_p_A14 // Poly tail
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_p_XR8 = FR_p_XR4, FR_p_XR4, f0 // Poly tail
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_r_TL = FR_r_ResH, FR_r_XS2L, f0 // sin for neg
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_p_Temp1L = FR_p_Temp1L, f1, FR_p_A0L // High poly
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_p_A6 = FR_p_A10, FR_p_XR4, FR_p_A6 // Poly tail
nop.i 0
};;
{ .mfi
nop.m 0
fms.s1 FR_r_TT = FR_r_ResH, FR_r_XS2, FR_r_TH // sin for neg
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_r_Res3H = FR_r_TH, f1, f1 // sin for neg
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_p_Poly4L = FR_p_Poly4L, f1, FR_p_Temp4L // Low poly
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_p_Poly3L = FR_p_Poly4H, FR_p_XR3L, f0 // Low poly
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_p_Poly0H = FR_p_Poly3H,f1,FR_p_Poly1H //Low & High add
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_r_A7 = FR_r_A8, FR_r_XS2, FR_r_A7 // sin for neg
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_r_TL = FR_r_ResL, FR_r_XS2, FR_r_TL // sin for neg
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_r_XS4 = FR_r_XS2, FR_r_XS2, f0 // sin for neg
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_p_Poly1L = FR_p_Poly1L, f1, FR_p_Temp1L // High poly
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_p_PolyTail = FR_p_A14, FR_p_XR8, FR_p_A6 // Poly tail
nop.i 0
};;
{ .mfi
nop.m 0
fms.s1 FR_r_Res3L = f1, f1, FR_r_Res3H // sin for neg
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_r_ResH = FR_r_Res3H, FR_r_XS, f0 // sin for neg
nop.i 0
};;
{ .mfi
nop.m 0
fms.s1 FR_p_Temp0L = FR_p_Poly4H,FR_p_XR3,FR_p_Poly3H //Low poly
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_p_Poly3L = FR_p_Poly4L,FR_p_XR3,FR_p_Poly3L //Low poly
nop.i 0
};;
{ .mfi
nop.m 0
fms.s1 FR_p_Poly0L = FR_p_Poly1H,f1,FR_p_Poly0H //Low & High add
nop.i 0
}
{ .mfi
nop.m 0
(p13) fma.s1 FR_p_OddPoly0H = FR_p_Poly0H, FR_p_AbsXM1, f0
// Reccurent computations - multiplying by X-1
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_r_TL = FR_r_TL, f1, FR_r_TT // sin for neg
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_r_A3 = FR_r_A4, FR_r_XS2, FR_r_A3 // sin for neg
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_p_Poly1L = FR_p_PolyTail,FR_p_XR6,FR_p_Poly1L//High
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_r_A5 = FR_r_A6, FR_r_XS2, FR_r_A5 // sin for neg
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_r_Res3L = FR_r_Res3L, f1, FR_r_TH // sin for neg
nop.i 0
}
{ .mfi
nop.m 0
fms.s1 FR_r_ResL = FR_r_Res3H, FR_r_XS, FR_r_ResH//sin for neg
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_p_Poly3L = FR_p_Poly3L, f1, FR_p_Temp0L // Low poly
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_r_A7 = FR_r_A9, FR_r_XS4, FR_r_A7 // sin for neg
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_p_Poly0L = FR_p_Poly0L,f1,FR_p_Poly3H //Low & High add
nop.i 0
}
{ .mfi
nop.m 0
(p13) fms.s1 FR_p_OddPoly0L = FR_p_Poly0H, FR_p_AbsXM1, FR_p_OddPoly0H
// Reccurent computations - multiplying by X-1 (low part)
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_r_A3 = FR_r_A5, FR_r_XS4, FR_r_A3 // sin for neg
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_r_XS7 = FR_r_XS4, FR_r_XS2, f0 // xs^6
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_r_Res3L = FR_r_Res3L, f1, FR_r_TL // sin for neg
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_r_XS8 = FR_r_XS4, FR_r_XS4, f0 // sin for neg
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_p_Temp0H = FR_p_Poly3L,f1,FR_p_Poly1L //Low & High add
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_r_XS7 = FR_r_XS7, FR_r_XS, f0 // xs^7
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_r_ResL = FR_r_Res3L, FR_r_XS, FR_r_ResL//sin for neg
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_r_Tail = FR_r_A7, FR_r_XS8, FR_r_A3 // sin tail res
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_p_Poly0L = FR_p_Poly0L,f1,FR_p_Temp0H //Low & High add
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_r_ResL = FR_r_Tail,FR_r_XS7,FR_r_ResL //sin for neg
nop.i 0
};;
{ .mfi
nop.m 0
(p13) fma.s1 FR_p_OddPoly0L = FR_p_Poly0L, FR_p_AbsXM1, FR_p_OddPoly0L
// Reccurent computations - multiplying by X-1 (low part)
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_r_TT = FR_r_ResL, FR_r_AbsX, f0 // X*sin
nop.i 0
};;
.pred.rel "mutex",p12,p13
{ .mfi
nop.m 0
(p12) fma.s0 f8 = FR_p_Poly0H, f1, FR_p_Poly0L // Even
nop.i 0
}
{ .mfb
nop.m 0
(p13) fma.s0 f8 = FR_p_OddPoly0H, f1, FR_p_OddPoly0L // Odd
(p14) br.ret.spnt b0 // Exit for 1 <= |X| < 13 path (positive arguments)/////
};;
{ .mfi
nop.m 0
(p13) fma.s1 FR_p_Poly0H = FR_p_OddPoly0H, f1, f0
// Reccurent computations
nop.i 0
}
{ .mfi
nop.m 0
(p13) fma.s1 FR_p_Poly0L = FR_p_OddPoly0L, f1, f0
// Reccurent computations
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_r_Res1H = FR_r_ResH, FR_r_AbsX, FR_r_TT // X*sin
(p11) cmp.eq p13, p12 = r0, r0
};;
{ .mfi
nop.m 0
fms.s1 FR_r_Res1L = FR_r_ResH,FR_r_AbsX,FR_r_Res1H// X*sin
(p9) cmp.eq p13, p12 = r0, r0
};;
{ .mfi
nop.m 0
fma.s1 FR_r_Res1L = FR_r_Res1L, f1, FR_r_TT // sin for neg
(p10) cmp.eq p13, p12 = r0, r0
}
{ .mfi
nop.m 0
fma.s1 FR_r_TL = FR_p_Poly0L, FR_r_Res1H, f0 // mult by sin
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_r_TL = FR_p_Poly0H,FR_r_Res1L,FR_r_TL//mult by sin
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_r_ResH = FR_p_Poly0H,FR_r_Res1H,FR_r_TL//mult by sin
nop.i 0
};;
{ .mfi
nop.m 0
fms.s1 FR_r_ResL = FR_p_Poly0H,FR_r_Res1H,FR_r_ResH//sin mult
nop.i 0
};;
{ .mfi
nop.m 0
frcpa.s1 FR_r_Y0,p0 = f1,FR_r_ResH // y = frcpa(b)
nop.i 0
};;
{ .mfi
nop.m 0
fneg FR_r_NegOne = f1 // Form -1.0
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_r_ResL = FR_r_ResL, f1, FR_r_TL //Low result of mult
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_r_Q0 = f1,FR_r_Y0,f0 // q = a*y
nop.i 0
}
{ .mfi
nop.m 0
fnma.s1 FR_r_E0 = FR_r_Y0,FR_r_ResH,f1 // e = 1-b*y
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_r_E2 = FR_r_E0,FR_r_E0,FR_r_E0 // e2 = e+e^2
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_r_E1 = FR_r_E0,FR_r_E0,f0 // e1 = e^2
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_r_Y1 = FR_r_Y0,FR_r_E2,FR_r_Y0 // y1 = y+y*e2
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_r_E3 = FR_r_E1,FR_r_E1,FR_r_E0 // e3 = e+e1^2
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_r_Y2 = FR_r_Y1,FR_r_E3,FR_r_Y0 // y2 = y+y1*e3
nop.i 0
}
{ .mfi
nop.m 0
fnma.s1 FR_r_R0 = FR_r_ResH,FR_r_Q0,f1 // r = a-b*q
nop.i 0
};;
{ .mfi
nop.m 0
fnma.s1 FR_r_E4 = FR_r_ResH,FR_r_Y2,f1 // e4 = 1-b*y2
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_r_ZH = FR_r_R0,FR_r_Y2,FR_r_Q0 // x = q+r*y2
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_r_Y3 = FR_r_Y2,FR_r_E4,FR_r_Y2 // y3 = y2+y2*e4
nop.i 0
}
{ .mfi
nop.m 0
fnma.s1 FR_r_R1 = FR_r_ResH,FR_r_ZH,f1 // r1 = a-b*x
nop.i 0
};;
{ .mfi
nop.m 0
fnma.s1 FR_r_R1 = FR_r_ResL,FR_r_ZH,FR_r_R1 // r1=r1-b_lo*X
nop.i 0
}
{ .mfi
nop.m 0
(p12) fma.s1 FR_r_ZHN = FR_r_ZH,FR_r_NegOne, f0 // Negate for evens
nop.i 0
};;
.pred.rel "mutex",p13,p12
{ .mfi
nop.m 0
(p13) fma.s0 f8 = FR_r_R1,FR_r_Y3,FR_r_ZH // Final result
nop.i 0
}
{ .mfb
nop.m 0
(p12) fnma.s0 f8 = FR_r_R1,FR_r_Y3,FR_r_ZHN // Final result
br.ret.sptk b0 // Exit for 1 <= |X| < 13 path (negative arguments)//////
};;
//////////// |X| < 1 path /////////////////////////////////////////////////////
//------------------------------------------------------------------------------
.align 64
tgamma_lt_1:
{ .mfi
getf.exp GR_p_Exp = FR_p_AbsX // exp of abs X
fma.s1 FR_z_Q0 = f1,FR_z_Y0,f0 // q = a*y
add GR_r_sin_Table2= 0x50, GR_r_sin_Table
}
{ .mfi
ldfpd FR_p_0p5, FR_p_1p5 = [GR_c_Table], 16
fnma.s1 FR_z_E0 = FR_z_Y0,f8,f1 // e = 1-b*y
add GR_p_Table2 = 0xB0, GR_p_Table
};;
{ .mfi
ldfd FR_p_0p25 = [GR_c_Table]
fcvt.xf FR_r_XNS = FR_r_IXNS // Convert int repr to float
shr.u GR_p_X_Sgnd = GR_p_X_Sgnd, 60
// Obtain only 4 bits of significand
}
{ .mfi
nop.m 0
nop.f 0
add GR_p_Bias = 0xffff, r0 // Set bias
};;
{ .mfi
ldfpd FR_r_A2H, FR_r_A2L = [GR_r_sin_Table], 16
nop.f 0
shl GR_p_XN = GR_p_Exp, 4
// Shift exp to 4 bits left to set place for significand
}
{ .mlx
ldfe FR_r_A6 = [GR_r_sin_Table2], 16
movl GR_p_0p75 = 0xfffec // 0.75
};;
{ .mfi
ldfpd FR_r_A1H, FR_r_A1L = [GR_r_sin_Table], 16
nop.f 0
or GR_p_XN = GR_p_XN, GR_p_X_Sgnd
// Combine exp with 4 high bits of significand
}
{ .mfi
ldfe FR_r_A5 = [GR_r_sin_Table2], 16
nop.f 0
sub GR_p_Exp = GR_p_Exp, GR_p_Bias // Unbiased exp
};;
{ .mmi
ldfe FR_r_A9 = [GR_r_sin_Table], 16
ldfe FR_r_A4 = [GR_r_sin_Table2], 16
cmp.gtu.unc p10, p11 = GR_p_0p75, GR_p_XN // sgnd(x) < 0.75
};;
{ .mfi
ldfe FR_r_A8 = [GR_r_sin_Table], 16
fma.s1 FR_z_E2 = FR_z_E0,FR_z_E0,FR_z_E0 // e2 = e+e^2
(p10) cmp.gt.unc p9, p10 = -2, GR_p_Exp // x < 0.25
}
{ .mfi
ldfe FR_r_A3 = [GR_r_sin_Table2], 16
fma.s1 FR_z_E1 = FR_z_E0,FR_z_E0,f0 // e1 = e^2
(p11) add GR_p_Offset = 168, r0 // [0.75;1] interval
};;
{ .mmi
(p10) add GR_p_Offset = 147, r0 // [0.25;0.75] interval
ldfe FR_r_A7 = [GR_r_sin_Table], 16
(p9) cmp.gt.unc p8, p9 = -3, GR_p_Exp // x < 0.125
};;
.pred.rel "mutex",p9,p8
{ .mmi
(p9) add GR_p_Offset = 126, r0 // [0.125;0.25] interval
(p8) add GR_p_Offset = 189, r0 // [0.;0.125] interval
nop.i 0
};;
{ .mmf
shladd GR_p_Table = GR_p_Offset, 4, GR_p_Table //Make addresses
shladd GR_p_Table2 = GR_p_Offset, 4, GR_p_Table2
fma.s1 FR_r_XS = FR_r_AbsX , f1, FR_r_XNS // xs = |x|-[x]
};;
.pred.rel "mutex",p8,p11
{ .mfi
ldfpd FR_p_A5H, FR_p_A5L = [GR_p_Table], 16
(p11) fms.s1 FR_p_XR = f1, f1, FR_p_AbsX // r = 1 - |x|
// for [0.75;1] interval
nop.i 0
}
{ .mfi
ldfpd FR_p_A2H, FR_p_A2L = [GR_p_Table2], 16
(p8) fms.s1 FR_p_XR = FR_p_AbsX, f1, f0 // r = |x|
// for [0.;0.125] interval
nop.i 0
};;
{ .mfi
ldfpd FR_p_A4H, FR_p_A4L = [GR_p_Table], 16
fma.s1 FR_z_Y1 = FR_z_Y0,FR_z_E2,FR_z_Y0 // y1 = y+y*e2
nop.i 0
}
{ .mfi
ldfpd FR_p_A1H, FR_p_A1L = [GR_p_Table2], 16
fma.s1 FR_z_E3 = FR_z_E1,FR_z_E1,FR_z_E0 // e3 = e+e1^2
nop.i 0
};;
.pred.rel "mutex",p9,p10
{ .mfi
ldfpd FR_p_A3H, FR_p_A3L = [GR_p_Table], 16
(p9) fms.s1 FR_p_XR = FR_p_AbsX, f1, f0 // r = |x|
// for [0.125;0.25] interval
nop.i 0
}
{ .mfi
ldfpd FR_p_A0H, FR_p_A0L = [GR_p_Table2], 16
(p10) fms.s1 FR_p_XR = FR_p_AbsX, f1, FR_p_0p5 // r = |x| - 0.5
// for [0.25;0.75] interval
nop.i 0
};;
{ .mmi
ldfe FR_p_A20 = [GR_p_Table], 16
ldfe FR_p_A12 = [GR_p_Table2], 16
nop.i 0
};;
{ .mfi
ldfe FR_p_A19 = [GR_p_Table], 16
fma.s1 FR_r_XS2 = FR_r_XS, FR_r_XS, f0 // xs^2
nop.i 0
}
{ .mfi
ldfe FR_p_A11 = [GR_p_Table2], 16
nop.f 0
nop.i 0
};;
{ .mmi
ldfe FR_p_A18 = [GR_p_Table], 16
ldfe FR_p_A10 = [GR_p_Table2], 16
nop.i 0
};;
.pred.rel "mutex",p12,p13
{ .mfi
ldfe FR_p_A17 = [GR_p_Table], 16
fma.s1 FR_z_Y2 = FR_z_Y1,FR_z_E3,FR_z_Y0 // y2 = y+y1*e3
nop.i 0
}
{ .mfi
ldfe FR_p_A9 = [GR_p_Table2], 16
fnma.s1 FR_z_R0 = f8,FR_z_Q0,f1 // r = a-b*q
nop.i 0
};;
{ .mmi
ldfe FR_p_A16 = [GR_p_Table], 16
ldfe FR_p_A8 = [GR_p_Table2], 16
nop.i 0
};;
{ .mmi
ldfe FR_p_A15 = [GR_p_Table], 16
ldfe FR_p_A7 = [GR_p_Table2], 16
nop.i 0
};;
{ .mfi
ldfe FR_p_A14 = [GR_p_Table], 16
fma.s1 FR_r_TH = FR_r_A2H, FR_r_XS2, f0 // neg sin
nop.i 0
}
{ .mfi
ldfe FR_p_A6 = [GR_p_Table2], 16
fma.s1 FR_r_TL = FR_r_A2L, FR_r_XS2, f0 // neg sin
nop.i 0
};;
{ .mfi
ldfe FR_p_A13 = [GR_p_Table], 16
fms.s1 FR_r_XS2L = FR_r_XS, FR_r_XS, FR_r_XS2 // xs^2 delta
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_p_Temp5H = FR_p_A5H, FR_p_XR, f0 // Low poly
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_p_XR2 = FR_p_XR, FR_p_XR, f0 // poly tail
nop.i 0
};;
{ .mfi
nop.m 0
fabs FR_r_XS = FR_r_XS // Absolute value of xs
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_p_Temp2H = FR_p_A2H, FR_p_XR, f0 // High poly
nop.i 0
};;
{ .mfi
nop.m 0
fnma.s1 FR_z_E4 = f8,FR_z_Y2,f1 // e4 = 1-b*y2
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_z_ZH = FR_z_R0,FR_z_Y2,FR_z_Q0 // 1/x = q+r*y2
nop.i 0
};;
{ .mfi
nop.m 0
fms.s1 FR_r_TT = FR_r_A2H, FR_r_XS2, FR_r_TH // neg sin
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_r_ResH = FR_r_TH, f1, FR_r_A1H // neg sin
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_r_TL = FR_r_A2H, FR_r_XS2L, FR_r_TL // neg sin
nop.i 0
};;
{ .mfi
nop.m 0
fms.s1 FR_p_Temp5L = FR_p_A5H, FR_p_XR, FR_p_Temp5H // Low poly
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_p_Poly5H = FR_p_Temp5H, f1, FR_p_A4H // Low poly
nop.i 0
};;
{ .mfi
nop.m 0
fms.s1 FR_p_Temp2L = FR_p_A2H, FR_p_XR, FR_p_Temp2H // High poly
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_p_Poly2H = FR_p_Temp2H, f1, FR_p_A1H // High poly
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_p_XR3 = FR_p_XR2, FR_p_XR, f0 // r^3
nop.i 0
}
{ .mfi
nop.m 0
fms.s1 FR_p_XR2L = FR_p_XR, FR_p_XR, FR_p_XR2 // r^2 delta
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_p_A18 = FR_p_A19, FR_p_XR, FR_p_A18 // poly tail
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_p_A14 = FR_p_A15, FR_p_XR, FR_p_A14 // poly tail
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_p_XR4 = FR_p_XR2, FR_p_XR2, f0 // poly tail
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_z_Y3 = FR_z_Y2,FR_z_E4,FR_z_Y2 // y3 = y2+y2*e4
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_p_Temp5L = FR_p_A5L, FR_p_XR, FR_p_Temp5L // Low poly
nop.i 0
}
{ .mfi
nop.m 0
fms.s1 FR_p_Poly5L = FR_p_A4H, f1, FR_p_Poly5H // Low poly
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_p_Temp4H = FR_p_Poly5H, FR_p_XR, f0 // Low poly
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_p_Temp2L = FR_p_A2L, FR_p_XR, FR_p_Temp2L // High poly
nop.i 0
};;
{ .mfi
nop.m 0
fms.s1 FR_p_Poly2L = FR_p_A1H, f1, FR_p_Poly2H // High poly
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_p_Temp1H = FR_p_Poly2H, FR_p_XR, f0 // High poly
nop.i 0
};;
{ .mfi
nop.m 0
fms.s1 FR_p_XR3L = FR_p_XR2, FR_p_XR, FR_p_XR3 // x^3 delta
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_p_A16 = FR_p_A17, FR_p_XR, FR_p_A16 //poly tail
nop.i 0
};;
{ .mfi
nop.m 0
fms.s1 FR_r_ResL = FR_r_A1H, f1, FR_r_ResH // neg sin
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_r_TL = FR_r_TL, f1, FR_r_TT // neg sin
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_p_Temp5L = FR_p_Temp5L, f1, FR_p_A4L // Low poly
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_p_Poly5L = FR_p_Poly5L, f1, FR_p_Temp5H //Low poly
nop.i 0
};;
{ .mfi
nop.m 0
fms.s1 FR_p_Temp4L = FR_p_Poly5H, FR_p_XR, FR_p_Temp4H//Low poly
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_p_Poly4H = FR_p_Temp4H, f1, FR_p_A3H // Low poly
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_p_Temp2L = FR_p_Temp2L, f1, FR_p_A1L // High poly
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_p_Poly2L = FR_p_Poly2L, f1, FR_p_Temp2H // High poly
nop.i 0
};;
{ .mfi
nop.m 0
fms.s1 FR_p_Temp1L = FR_p_Poly2H,FR_p_XR,FR_p_Temp1H //High poly
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_p_Poly1H = FR_p_Temp1H, f1, FR_p_A0H // High poly
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_p_A12 = FR_p_A13, FR_p_XR, FR_p_A12 // poly tail
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_p_XR3L = FR_p_XR2L, FR_p_XR, FR_p_XR3L // x^3 low
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_p_Poly5L = FR_p_Poly5L, f1, FR_p_Temp5L //Low poly
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_p_A10 = FR_p_A11, FR_p_XR, FR_p_A10 //poly tail
nop.i 0
};;
{ .mfi
nop.m 0
fms.s1 FR_p_Poly4L = FR_p_A3H, f1, FR_p_Poly4H /// Low poly
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_p_A6 = FR_p_A7, FR_p_XR, FR_p_A6 // poly tail
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_p_A8 = FR_p_A9, FR_p_XR, FR_p_A8 // poly tail
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_p_XR6 = FR_p_XR4, FR_p_XR2, f0 // r^6
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_p_Poly2L = FR_p_Poly2L, f1, FR_p_Temp2L // High poly
nop.i 0
}
{ .mfi
nop.m 0
fms.s1 FR_p_Poly1L = FR_p_A0H, f1, FR_p_Poly1H // High poly
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_r_ResL = FR_r_ResL, f1, FR_r_TH // neg sin
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_r_TT = FR_r_TL, f1, FR_r_A1L // neg sin
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_p_Temp4L = FR_p_Poly5L,FR_p_XR,FR_p_Temp4L //Low poly
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_p_A18 = FR_p_A20, FR_p_XR2, FR_p_A18 // poly tail
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_p_Poly4L = FR_p_Poly4L, f1, FR_p_Temp4H // Low poly
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_p_A14 = FR_p_A16, FR_p_XR2, FR_p_A14 // poly tail
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_p_A6 = FR_p_A8, FR_p_XR2, FR_p_A6 // poly tail
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_p_A10 = FR_p_A12, FR_p_XR2, FR_p_A10 // poly tail
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_p_Temp1L = FR_p_Poly2L,FR_p_XR,FR_p_Temp1L //High poly
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_p_Poly1L = FR_p_Poly1L, f1, FR_p_Temp1H // High poly
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_r_ResL = FR_r_ResL, f1, FR_r_TT // neg sin
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_r_TH = FR_r_ResH, FR_r_XS2, f0 // neg sin
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_p_Temp4L = FR_p_Temp4L, f1, FR_p_A3L // Low poly
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_p_Poly3H = FR_p_Poly4H, FR_p_XR3, f0 // Low poly
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_p_A14 = FR_p_A18, FR_p_XR4, FR_p_A14 // poly tail
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_p_XR8 = FR_p_XR4, FR_p_XR4, f0 // r^8
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_r_TL = FR_r_ResH, FR_r_XS2L, f0 // neg sin
nop.i 0
}
{ .mfi
nop.m 0
fnma.s1 FR_z_R1 = f8,FR_z_ZH,f1 // r1 = a-b*x
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_p_Temp1L = FR_p_Temp1L, f1, FR_p_A0L // High poly
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_p_A6 = FR_p_A10, FR_p_XR4, FR_p_A6 // poly tail
nop.i 0
};;
{ .mfi
nop.m 0
fms.s1 FR_r_TT = FR_r_ResH, FR_r_XS2, FR_r_TH // neg sin
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_r_Res3H = FR_r_TH, f1, f1 // neg sin
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_p_Poly4L = FR_p_Poly4L, f1, FR_p_Temp4L // Low poly
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_p_Poly3L = FR_p_Poly4H, FR_p_XR3L, f0 // Low poly
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_p_Poly0H = FR_p_Poly3H, f1, FR_p_Poly1H // Result
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_r_A7 = FR_r_A8, FR_r_XS2, FR_r_A7 // neg sin
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_r_TL = FR_r_ResL, FR_r_XS2, FR_r_TL // neg sin
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_r_XS4 = FR_r_XS2, FR_r_XS2, f0 // xs^4
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_p_Poly1L = FR_p_Poly1L, f1, FR_p_Temp1L // High poly
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_p_PolyTail = FR_p_A14, FR_p_XR8, FR_p_A6 // poly tail
nop.i 0
};;
{ .mfi
nop.m 0
fms.s1 FR_r_Res3L = f1, f1, FR_r_Res3H // neg sin
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_r_ResH = FR_r_Res3H, FR_r_XS, f0 // neg sin
nop.i 0
};;
{ .mfi
nop.m 0
fms.s1 FR_p_Temp0L = FR_p_Poly4H,FR_p_XR3,FR_p_Poly3H //Low poly
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_p_Poly3L = FR_p_Poly4L,FR_p_XR3,FR_p_Poly3L //Low poly
nop.i 0
};;
{ .mfi
nop.m 0
fms.s1 FR_p_Poly0L = FR_p_Poly1H, f1, FR_p_Poly0H // Result
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_z_ZL = FR_z_R1,FR_z_Y3, f0 // x_lo = r1*y3
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_r_TL = FR_r_TL, f1, FR_r_TT // neg sin
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_r_A3 = FR_r_A4, FR_r_XS2, FR_r_A3 /// neg sin
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_p_Poly1L = FR_p_PolyTail,FR_p_XR6,FR_p_Poly1L // High
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_r_A5 = FR_r_A6, FR_r_XS2, FR_r_A5 // neg sin
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_r_Res3L = FR_r_Res3L, f1, FR_r_TH // neg sin
nop.i 0
}
{ .mfi
nop.m 0
fms.s1 FR_r_ResL = FR_r_Res3H, FR_r_XS, FR_r_ResH // neg sin
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_p_Poly3L = FR_p_Poly3L, f1, FR_p_Temp0L // Low poly
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_r_A7 = FR_r_A9, FR_r_XS4, FR_r_A7 // neg sin
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_p_Poly0L = FR_p_Poly0L, f1, FR_p_Poly3H // result
nop.i 0
};;
{ .mfi
nop.m 0
(p14) fma.s1 f8 = FR_p_Poly0H, FR_z_ZH, f0 // z*poly
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_p_Temp1L = FR_p_Poly0H, FR_z_ZL, f0 // z*poly low
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_r_A3 = FR_r_A5, FR_r_XS4, FR_r_A3 // sin tail
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_r_XS7 = FR_r_XS4, FR_r_XS2, f0 // xs^6
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_r_Res3L = FR_r_Res3L, f1, FR_r_TL // sin low
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_r_XS8 = FR_r_XS4, FR_r_XS4, f0 // xs^8
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_p_Temp0H = FR_p_Poly3L, f1, FR_p_Poly1L // result
nop.i 0
};;
{ .mfi
nop.m 0
(p14) fms.s1 FR_p_Temp1H = FR_p_Poly0H, FR_z_ZH, f8 // hi result
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_r_XS7 = FR_r_XS7, FR_r_XS, f0 // xs^7
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_r_ResL = FR_r_Res3L, FR_r_XS, FR_r_ResL // lo result
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_r_Tail = FR_r_A7, FR_r_XS8, FR_r_A3 // tail result
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_p_Poly0L = FR_p_Poly0L, f1, FR_p_Temp0H // lo result
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_r_ResL = FR_r_Tail, FR_r_XS7, FR_r_ResL // lo result
nop.i 0
};;
{ .mfi
nop.m 0
(p14) fma.s1 FR_p_Temp1L = FR_p_Poly0L,FR_z_ZH,FR_p_Temp1L //hi result
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_r_TT = FR_r_ResL, f1, f0 // for low result
nop.i 0
};;
.pred.rel "mutex",p12,p13
{ .mfi
nop.m 0
(p14) fma.s1 FR_p_Temp1L = FR_p_Temp1L, f1, FR_p_Temp1H // for lo res
nop.i 0
};;
{ .mfi
(p10) cmp.eq p13, p12 = r0, r0 // set p13, clear p12
fma.s1 FR_r_Res1H = FR_r_ResH, f1, FR_r_TT // hi res
nop.i 0
};;
{ .mfb
(p9) cmp.eq p13, p12 = r0, r0 // set p13, clear p12
(p14) fma.s0 f8 = f8, f1, FR_p_Temp1L // Final result
(p14) br.ret.spnt b0 // Exit for 0 < |X| < 1 path (positive arguments)///////
};;
{ .mfi
(p11) cmp.eq p13, p12 = r0, r0 // set p13, clear p12
fms.s1 FR_r_Res1L = FR_r_ResH, f1, FR_r_Res1H // Low sin result
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_r_Res1L = FR_r_Res1L, f1, FR_r_TT // Low sin result
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_r_TL = FR_p_Poly0L,FR_r_Res1H,f0 //Low sin result
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_r_TL = FR_p_Poly0H, FR_r_Res1L, FR_r_TL //Low sin
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_r_ResH = FR_p_Poly0H, FR_r_Res1H, FR_r_TL //High sin
nop.i 0
};;
{ .mfi
nop.m 0
fms.s1 FR_r_ResL = FR_p_Poly0H,FR_r_Res1H,FR_r_ResH //Low res
nop.i 0
};;
{ .mfi
nop.m 0
frcpa.s1 FR_r_Y0,p0 = f1,FR_r_ResH // y = frcpa(b)
nop.i 0
};;
{ .mfi
nop.m 0
fneg FR_r_NegOne = f1 // Construct -1.0
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_r_ResL = FR_r_ResL, f1, FR_r_TL // low sin
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_r_Q0 = f1,FR_r_Y0,f0 // q = a*y
nop.i 0
}
{ .mfi
nop.m 0
fnma.s1 FR_r_E0 = FR_r_Y0,FR_r_ResH,f1 // e = 1-b*y
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_r_E2 = FR_r_E0,FR_r_E0,FR_r_E0 // e2 = e+e^2
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_r_E1 = FR_r_E0,FR_r_E0,f0 // e1 = e^2
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_r_Y1 = FR_r_Y0,FR_r_E2,FR_r_Y0 // y1 = y+y*e2
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_r_E3 = FR_r_E1,FR_r_E1,FR_r_E0 // e3 = e+e1^2
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_r_Y2 = FR_r_Y1,FR_r_E3,FR_r_Y0 // y2 = y+y1*e3
nop.i 0
}
{ .mfi
nop.m 0
fnma.s1 FR_r_R0 = FR_r_ResH,FR_r_Q0,f1 // r = a-b*q
nop.i 0
};;
{ .mfi
nop.m 0
fnma.s1 FR_r_E4 = FR_r_ResH,FR_r_Y2,f1 // e4 = 1-b*y2
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_r_ZH = FR_r_R0,FR_r_Y2,FR_r_Q0 // x = q+r*y2
nop.i 0
};;
{ .mfi
nop.m 0
fma.s1 FR_r_Y3 = FR_r_Y2,FR_r_E4,FR_r_Y2 // y3 = y2+y2*e4
nop.i 0
}
{ .mfi
nop.m 0
fnma.s1 FR_r_R1 = FR_r_ResH,FR_r_ZH,f1 // r1 = a-b*x
nop.i 0
};;
{ .mfi
nop.m 0
fnma.s1 FR_r_R1 = FR_r_ResL,FR_r_ZH,FR_r_R1 // r1=r1 - b_lo*X
nop.i 0
}
{ .mfi
nop.m 0
fma.s1 FR_r_ZHN = FR_r_ZH,FR_r_NegOne, f0 // Negate
nop.i 0
};;
.pred.rel "mutex",p13,p12
{ .mfb
nop.m 0
fnma.s0 f8 = FR_r_R1,FR_r_Y3,FR_r_ZHN // Result for neg
br.ret.sptk b0 // Exit for 0 < |X| < 1 path (negative arguments)//////
};;
// SPECIALS (x for natval, nan, +/-inf or +/-0) ///////////////////////////////
//------------------------------------------------------------------------------
.align 32
tgammal_spec:
{ .mlx
nop.m 0
movl GR_DenOverflow = 0x2000000000000001
}
{ .mfi
nop.m 0
fclass.m p9,p0 = f8,0xB // +/-denormals
nop.i 0
};;
{ .mfi
nop.m 0
fclass.m p6,p0 = f8,0x1E1 // Test x for natval, nan, +inf
nop.i 0
};;
{ .mfi
nop.m 0
fclass.m p7,p8 = f8,0x7 // +/-0
nop.i 0
}
{ .mfi
(p9) cmp.ltu.unc p10,p11 = GR_l_signif_Z, GR_DenOverflow
(p9) fnorm.s0 f8 = f8
nop.i 0
};;
{ .mfb
nop.m 0
(p9) fcvt.fx.trunc.s1 FR_n_IXN = FR_l_AbsX // Round by truncate
(p11) br.cond.sptk tgamma_lt_1 // Return to gamma ('good' denormal)////////////
};;
{ .mfb
nop.m 0
nop.f 0
(p10) br.cond.spnt tgammal_overflow // "Bad" denormal - overflow! /////////////
};;
{ .mfi
nop.m 0
mov FR_X = f8 // for error handler
nop.i 0
}
{ .mfb
nop.m 0
(p6) fma.s0 f8 = f8,f1,f8 // res = x + x
(p6) br.ret.spnt b0 // Exit for NAN, INF and NatVals ////////////////////////
};;
.pred.rel "mutex",p7,p8
{ .mfi
(p7) mov GR_Parameter_TAG = 256 // negative
(p7) frcpa.s0 f8,p0 = f1,f8 // Raise V flag
nop.i 0
}
{ .mfb
nop.m 0
nop.f 0
(p8) br.cond.spnt tgammal_singularity // Branch for +ZERO ////////////////////
};;
{ .mfb
nop.m 0
nop.f 0
br.cond.spnt tgammal_libm_err // Branch for -ZERO ///////////////////////
};;
// SINGULARITY (x is negative integer or 0) ////////////////////////////////////
//------------------------------------------------------------------------------
.align 32
tgammal_singularity:
{ .mfi
nop.m 0
mov FR_X = f8 // For error handler
mov GR_Parameter_TAG = 256 // negative
}
{ .mfb
nop.m 0
frcpa.s0 f8,p0 = f0,f0 // Raise V flag
br.cond.sptk tgammal_libm_err // Call error handler /////////////////////
// with singularity error /////////////////
};;
// OVERFLOW (result is too big and cannot be represented by normal value) //////
// ( X > 1755.54 and for denormals with abs value less than 0x2000000000000001 )
//------------------------------------------------------------------------------
.align 32
tgammal_overflow:
{ .mfi
addl r8 = 0x1FFFE, r0 // Exp of INF
fcmp.lt.s1 p15,p14 = f8,f0 // p14 - pos arg, p15 - neg arg
nop.i 0
};;
{ .mfi
setf.exp f9 = r8
mov FR_X = f8 // For error handler
mov GR_Parameter_TAG = 255 // overflow
};;
.pred.rel "mutex",p14,p15
{ .mfi
nop.m 0
(p14) fma.s0 f8 = f9,f9,f0 // Set I,O and +INF result
nop.i 0
}
{ .mfb
nop.m 0
(p15) fnma.s0 f8 = f9,f9,f0 // Set I,O and -INF result
br.cond.sptk tgammal_libm_err // Call error handler /////////////////////
// with overflow error ////////////////////
};;
// UNDERFLOW (x is negative noninteger with big absolute value) ////////////////
//------------------------------------------------------------------------------
.align 32
tgammal_underflow:
{ .mfi
nop.m 0
fcvt.fx.trunc.s1 FR_u_IXN = f8 // Convert arg to int repres. in FR
nop.i 0
};;
{ .mmi
getf.sig GR_u_XN = FR_u_IXN
mov r11 = 0x00001
nop.i 0
};;
{ .mfi
setf.exp f9 = r11
nop.f 0
nop.i 0
};;
{ .mfi
nop.m 0
nop.f 0
tbit.z p6,p7 = GR_u_XN,0 // even or odd
};;
.pred.rel "mutex",p6,p7
{ .mfi
nop.m 0
(p6) fms.s0 f8 = f9,f9,f9 // for negatives
nop.i 0
}
{ .mfb
nop.m 0
(p7) fma.s0 f8 = f9,f9,f9 // for positives
br.ret.sptk b0 // Exit for underflow path //////////////////////////////
};;
GLOBAL_LIBM_END(tgammal)
libm_alias_ldouble_other (tgamma, tgamma)
////////////////// Tgammal error handler ///////////////////////////////////////
//------------------------------------------------------------------------------
LOCAL_LIBM_ENTRY(__libm_error_region)
tgammal_libm_err:
.prologue
{ .mfi
add GR_Parameter_Y=-32,sp // Parameter 2 value
nop.f 0
.save ar.pfs,GR_SAVE_PFS
mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
}
{ .mfi
.fframe 64
add sp=-64,sp // Create new stack
nop.f 0
mov GR_SAVE_GP=gp // Save gp
};;
{ .mmi
stfe [GR_Parameter_Y] = FR_Y,16 // Save Parameter 2 on stack
add GR_Parameter_X = 16,sp // Parameter 1 address
.save b0, GR_SAVE_B0
mov GR_SAVE_B0=b0 // Save b0
};;
.body
{ .mib
stfe [GR_Parameter_X] = FR_X // Store Parameter 1 on stack
add GR_Parameter_RESULT = 0,GR_Parameter_Y
nop.b 0 // Parameter 3 address
}
{ .mib
stfe [GR_Parameter_Y] = FR_RESULT // Store Parameter 3 on stack
add GR_Parameter_Y = -16,GR_Parameter_Y
br.call.sptk b0=__libm_error_support# // Call error handling function
};;
{ .mmi
nop.m 999
nop.m 999
add GR_Parameter_RESULT = 48,sp
};;
{ .mmi
ldfe f8 = [GR_Parameter_RESULT] // Get return result off stack
.restore sp
add sp = 64,sp // Restore stack pointer
mov b0 = GR_SAVE_B0 // Restore return address
};;
{ .mib
mov gp = GR_SAVE_GP // Restore gp
mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
br.ret.sptk b0 // Return
};;
LOCAL_LIBM_END(__libm_error_region#)
.type __libm_error_support#,@function
.global __libm_error_support#