Files
TheRock/compiler/amd-llvm/libclc/clc/lib/generic/math/clc_ep.inc
T
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

632 lines
22 KiB
PHP

//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#pragma OPENCL FP_CONTRACT OFF
#if __CLC_FPSIZE == 16
_CLC_DEF _CLC_OVERLOAD _CLC_CONST static __CLC_GENTYPE
ep_high_fp_bits(__CLC_GENTYPE x) {
return __CLC_AS_GENTYPE(__CLC_CONVERT_U_GENTYPE(
(__CLC_AS_U_GENTYPE(x) & (__CLC_U_GENTYPE)0xffc0U)));
}
#elif __CLC_FPSIZE == 32
_CLC_DEF _CLC_OVERLOAD _CLC_CONST static __CLC_GENTYPE
ep_high_fp_bits(__CLC_GENTYPE x) {
return __CLC_AS_GENTYPE(__CLC_AS_U_GENTYPE(x) & 0xfffff000U);
}
#elif __CLC_FPSIZE == 64
_CLC_DEF _CLC_OVERLOAD _CLC_CONST static __CLC_GENTYPE
ep_high_fp_bits(__CLC_GENTYPE x) {
return __CLC_AS_GENTYPE(__CLC_AS_U_GENTYPE(x) & 0xfffffffff8000000UL);
}
#endif
typedef struct __CLC_XCONCAT(__clc_ep_int_pair_, __CLC_GENTYPE) {
__CLC_INTN lo, hi;
} __CLC_XCONCAT(__clc_ep_int_pair_, __CLC_GENTYPE);
#define __CLC_EP_INT_PAIR __CLC_XCONCAT(__clc_ep_int_pair_, __CLC_GENTYPE)
_CLC_OVERLOAD
static __CLC_S_GENTYPE samesign(__CLC_GENTYPE x, __CLC_GENTYPE y) {
return __clc_signbit(x) == __clc_signbit(y);
}
_CLC_DEF
_CLC_OVERLOAD _CLC_CONST __CLC_EP_PAIR __clc_ep_absv(__CLC_EP_PAIR a) {
__CLC_EP_PAIR ret;
__CLC_EP_PAIR neg_a = __clc_ep_neg(a);
ret.lo = __clc_signbit(a.hi) ? neg_a.lo : a.lo;
ret.hi = __clc_signbit(a.hi) ? neg_a.hi : a.hi;
return ret;
}
_CLC_DEF
_CLC_OVERLOAD _CLC_CONST __CLC_EP_PAIR __clc_ep_neg(__CLC_EP_PAIR a) {
a.lo = -a.lo;
a.hi = -a.hi;
return a;
}
_CLC_DEF _CLC_OVERLOAD _CLC_CONST __CLC_EP_PAIR
__clc_ep_conditional_sign_match(__CLC_EP_PAIR a, __CLC_EP_PAIR b) {
__CLC_S_GENTYPE ss = samesign(a.hi, b.hi);
__CLC_EP_PAIR neg_a = __clc_ep_neg(a);
__CLC_EP_PAIR ret = {ss ? a.lo : neg_a.lo, ss ? a.hi : neg_a.hi};
return ret;
}
_CLC_DEF _CLC_OVERLOAD _CLC_CONST __CLC_EP_PAIR
__clc_ep_make_pair(__CLC_GENTYPE a, __CLC_GENTYPE b) {
__CLC_EP_PAIR ret = {b, a};
return ret;
}
_CLC_DEF _CLC_OVERLOAD _CLC_CONST __CLC_EP_PAIR
__clc_ep_fast_add(__CLC_GENTYPE a, __CLC_GENTYPE b) {
__CLC_GENTYPE s = a + b;
return __clc_ep_make_pair(s, b - (s - a));
}
_CLC_DEF _CLC_OVERLOAD _CLC_CONST __CLC_EP_PAIR
__clc_ep_normalize(__CLC_EP_PAIR a) {
return __clc_ep_fast_add(a.hi, a.lo);
}
_CLC_DEF _CLC_OVERLOAD _CLC_CONST __CLC_EP_PAIR
__clc_ep_normalize_overflow(__CLC_EP_PAIR a) {
__CLC_GENTYPE s = a.hi + a.lo;
__CLC_GENTYPE t = a.lo - (s - a.hi);
s = __clc_isinf(a.hi) ? a.hi : s;
return __clc_ep_make_pair(s, __clc_isinf(s) ? __CLC_FP_LIT(0.0) : t);
}
_CLC_DEF _CLC_OVERLOAD _CLC_CONST __CLC_EP_PAIR
__clc_ep_fast_sub(__CLC_GENTYPE a, __CLC_GENTYPE b) {
__CLC_GENTYPE d = a - b;
return __clc_ep_make_pair(d, (a - d) - b);
}
_CLC_DEF _CLC_OVERLOAD _CLC_CONST __CLC_EP_PAIR __clc_ep_add(__CLC_GENTYPE a,
__CLC_GENTYPE b) {
__CLC_GENTYPE s = a + b;
__CLC_GENTYPE d = s - a;
return __clc_ep_make_pair(s, (a - (s - d)) + (b - d));
}
_CLC_DEF _CLC_OVERLOAD _CLC_CONST __CLC_EP_PAIR __clc_ep_sub(__CLC_GENTYPE a,
__CLC_GENTYPE b) {
__CLC_GENTYPE d = a - b;
__CLC_GENTYPE e = d - a;
return __clc_ep_make_pair(d, (a - (d - e)) - (b + e));
}
_CLC_DEF _CLC_OVERLOAD _CLC_CONST __CLC_EP_PAIR __clc_ep_mul(__CLC_GENTYPE a,
__CLC_GENTYPE b) {
__CLC_GENTYPE p = a * b;
if (__CLC_GENTYPE_FAST_FMA) {
return __clc_ep_make_pair(p, __clc_fma(a, b, -p));
}
__CLC_GENTYPE ah = ep_high_fp_bits(a);
__CLC_GENTYPE al = a - ah;
__CLC_GENTYPE bh = ep_high_fp_bits(b);
__CLC_GENTYPE bl = b - bh;
return __clc_ep_make_pair(p, ((ah * bh - p) + ah * bl + al * bh) + al * bl);
}
_CLC_DEF _CLC_OVERLOAD _CLC_CONST __CLC_EP_PAIR __clc_ep_sqr(__CLC_GENTYPE a) {
__CLC_GENTYPE p = a * a;
if (__CLC_GENTYPE_FAST_FMA)
return __clc_ep_make_pair(p, __clc_fma(a, a, -p));
__CLC_GENTYPE ah = ep_high_fp_bits(a);
__CLC_GENTYPE al = a - ah;
return __clc_ep_make_pair(p, ((ah * ah - p) + __CLC_FP_LIT(2.0) * ah * al) +
al * al);
}
_CLC_DEF _CLC_OVERLOAD _CLC_CONST __CLC_EP_PAIR __clc_ep_add(__CLC_EP_PAIR a,
__CLC_GENTYPE b) {
__CLC_EP_PAIR s = __clc_ep_add(a.hi, b);
s.lo += a.lo;
return __clc_ep_normalize(s);
}
_CLC_DEF _CLC_OVERLOAD _CLC_CONST __CLC_EP_PAIR
__clc_ep_fast_add(__CLC_EP_PAIR a, __CLC_GENTYPE b) {
__CLC_EP_PAIR s = __clc_ep_fast_add(a.hi, b);
s.lo += a.lo;
return __clc_ep_normalize(s);
}
_CLC_DEF _CLC_OVERLOAD _CLC_CONST __CLC_EP_PAIR __clc_ep_add(__CLC_GENTYPE a,
__CLC_EP_PAIR b) {
__CLC_EP_PAIR s = __clc_ep_add(a, b.hi);
s.lo += b.lo;
return __clc_ep_normalize(s);
}
_CLC_DEF _CLC_OVERLOAD _CLC_CONST __CLC_EP_PAIR
__clc_ep_fast_add(__CLC_GENTYPE a, __CLC_EP_PAIR b) {
__CLC_EP_PAIR s = __clc_ep_fast_add(a, b.hi);
s.lo += b.lo;
return __clc_ep_normalize(s);
}
_CLC_DEF _CLC_OVERLOAD _CLC_CONST __CLC_EP_PAIR __clc_ep_add(__CLC_EP_PAIR a,
__CLC_EP_PAIR b) {
__CLC_EP_PAIR s = __clc_ep_add(a.hi, b.hi);
__CLC_EP_PAIR t = __clc_ep_add(a.lo, b.lo);
s.lo += t.hi;
s = __clc_ep_normalize(s);
s.lo += t.lo;
return __clc_ep_normalize(s);
}
_CLC_DEF _CLC_OVERLOAD _CLC_CONST __CLC_EP_PAIR
__clc_ep_fast_add(__CLC_EP_PAIR a, __CLC_EP_PAIR b) {
__CLC_EP_PAIR s = __clc_ep_fast_add(a.hi, b.hi);
s.lo += a.lo + b.lo;
return __clc_ep_normalize(s);
}
_CLC_DEF _CLC_OVERLOAD _CLC_CONST __CLC_EP_PAIR __clc_ep_sub(__CLC_EP_PAIR a,
__CLC_GENTYPE b) {
__CLC_EP_PAIR d = __clc_ep_sub(a.hi, b);
d.lo += a.lo;
return __clc_ep_normalize(d);
}
_CLC_DEF _CLC_OVERLOAD _CLC_CONST __CLC_EP_PAIR
__clc_ep_fast_sub(__CLC_EP_PAIR a, __CLC_GENTYPE b) {
__CLC_EP_PAIR d = __clc_ep_fast_sub(a.hi, b);
d.lo += a.lo;
return __clc_ep_normalize(d);
}
_CLC_DEF _CLC_OVERLOAD _CLC_CONST __CLC_EP_PAIR __clc_ep_sub(__CLC_GENTYPE a,
__CLC_EP_PAIR b) {
__CLC_EP_PAIR d = __clc_ep_sub(a, b.hi);
d.lo -= b.lo;
return __clc_ep_normalize(d);
}
_CLC_DEF _CLC_OVERLOAD _CLC_CONST __CLC_EP_PAIR
__clc_ep_fast_sub(__CLC_GENTYPE a, __CLC_EP_PAIR b) {
__CLC_EP_PAIR d = __clc_ep_fast_sub(a, b.hi);
d.lo -= b.lo;
return __clc_ep_normalize(d);
}
_CLC_DEF _CLC_OVERLOAD _CLC_CONST __CLC_EP_PAIR __clc_ep_sub(__CLC_EP_PAIR a,
__CLC_EP_PAIR b) {
__CLC_EP_PAIR d = __clc_ep_sub(a.hi, b.hi);
__CLC_EP_PAIR e = __clc_ep_sub(a.lo, b.lo);
d.lo += e.hi;
d = __clc_ep_normalize(d);
d.lo += e.lo;
return __clc_ep_normalize(d);
}
_CLC_DEF _CLC_OVERLOAD _CLC_CONST __CLC_EP_PAIR
__clc_ep_fast_sub(__CLC_EP_PAIR a, __CLC_EP_PAIR b) {
__CLC_EP_PAIR d = __clc_ep_fast_sub(a.hi, b.hi);
d.lo = d.lo + a.lo - b.lo;
return __clc_ep_normalize(d);
}
_CLC_DEF _CLC_OVERLOAD _CLC_CONST __CLC_EP_PAIR __clc_ep_ldexp(__CLC_EP_PAIR a,
__CLC_INTN e) {
return __clc_ep_make_pair(__clc_ldexp(a.hi, e), __clc_ldexp(a.lo, e));
}
_CLC_DEF _CLC_OVERLOAD _CLC_CONST __CLC_EP_PAIR __clc_ep_mul(__CLC_EP_PAIR a,
__CLC_GENTYPE b) {
__CLC_EP_PAIR p = __clc_ep_mul(a.hi, b);
if (__CLC_GENTYPE_FAST_FMA) {
p.lo = __clc_fma(a.lo, b, p.lo);
} else {
p.lo += a.lo * b;
}
return __clc_ep_normalize(p);
}
_CLC_DEF _CLC_OVERLOAD _CLC_CONST __CLC_EP_PAIR
__clc_ep_mul_overflow(__CLC_EP_PAIR a, __CLC_GENTYPE b) {
__CLC_EP_PAIR p = __clc_ep_mul(a.hi, b);
if (__CLC_GENTYPE_FAST_FMA) {
p.lo = __clc_fma(a.lo, b, p.lo);
} else {
p.lo += a.lo * b;
}
return __clc_ep_normalize_overflow(p);
}
_CLC_DEF _CLC_OVERLOAD _CLC_CONST __CLC_EP_PAIR __clc_ep_mul(__CLC_GENTYPE a,
__CLC_EP_PAIR b) {
__CLC_EP_PAIR p = __clc_ep_mul(a, b.hi);
if (__CLC_GENTYPE_FAST_FMA) {
p.lo = __clc_fma(a, b.lo, p.lo);
} else {
p.lo += a * b.lo;
}
return __clc_ep_normalize(p);
}
_CLC_DEF _CLC_OVERLOAD _CLC_CONST __CLC_EP_PAIR
__clc_ep_mul_overflow(__CLC_GENTYPE a, __CLC_EP_PAIR b) {
__CLC_EP_PAIR p = __clc_ep_mul(a, b.hi);
if (__CLC_GENTYPE_FAST_FMA) {
p.lo = __clc_fma(a, b.lo, p.lo);
} else {
p.lo += a * b.lo;
}
return __clc_ep_normalize_overflow(p);
}
_CLC_DEF _CLC_OVERLOAD _CLC_CONST __CLC_EP_PAIR __clc_ep_mul(__CLC_EP_PAIR a,
__CLC_EP_PAIR b) {
__CLC_EP_PAIR p = __clc_ep_mul(a.hi, b.hi);
if (__CLC_GENTYPE_FAST_FMA) {
p.lo = __clc_fma(a.lo, b.hi, __clc_fma(a.hi, b.lo, p.lo));
} else {
p.lo += a.hi * b.lo + a.lo * b.hi;
}
return __clc_ep_normalize(p);
}
_CLC_DEF _CLC_OVERLOAD _CLC_CONST __CLC_EP_PAIR
__clc_ep_mul_overflow(__CLC_EP_PAIR a, __CLC_EP_PAIR b) {
__CLC_EP_PAIR p = __clc_ep_mul(a.hi, b.hi);
if (__CLC_GENTYPE_FAST_FMA) {
p.lo += __clc_fma(a.hi, b.lo, a.lo * b.hi);
} else {
p.lo += a.hi * b.lo + a.lo * b.hi;
}
return __clc_ep_normalize_overflow(p);
}
_CLC_DEF _CLC_OVERLOAD _CLC_CONST __CLC_EP_PAIR __clc_ep_div(__CLC_GENTYPE a,
__CLC_GENTYPE b) {
__CLC_GENTYPE r = __clc_recip_fast(b);
__CLC_GENTYPE qhi = a * r;
__CLC_EP_PAIR p = __clc_ep_mul(qhi, b);
__CLC_EP_PAIR d = __clc_ep_fast_sub(a, p.hi);
d.lo -= p.lo;
__CLC_GENTYPE qlo = (d.hi + d.lo) * r;
return __clc_ep_fast_add(qhi, qlo);
}
_CLC_DEF _CLC_OVERLOAD _CLC_CONST __CLC_EP_PAIR __clc_ep_div(__CLC_EP_PAIR a,
__CLC_GENTYPE b) {
__CLC_GENTYPE r = __clc_recip_fast(b);
__CLC_GENTYPE qhi = a.hi * r;
__CLC_EP_PAIR p = __clc_ep_mul(qhi, b);
__CLC_EP_PAIR d = __clc_ep_fast_sub(a.hi, p.hi);
d.lo = d.lo + a.lo - p.lo;
__CLC_GENTYPE qlo = (d.hi + d.lo) * r;
return __clc_ep_fast_add(qhi, qlo);
}
_CLC_DEF _CLC_OVERLOAD _CLC_CONST __CLC_EP_PAIR __clc_ep_div(__CLC_GENTYPE a,
__CLC_EP_PAIR b) {
__CLC_GENTYPE r = __clc_recip_fast(b.hi);
__CLC_GENTYPE qhi = a * r;
__CLC_EP_PAIR p = __clc_ep_mul(qhi, b);
__CLC_EP_PAIR d = __clc_ep_fast_sub(a, p.hi);
d.lo -= p.lo;
__CLC_GENTYPE qlo = (d.hi + d.lo) * r;
return __clc_ep_fast_add(qhi, qlo);
}
_CLC_DEF _CLC_OVERLOAD _CLC_CONST __CLC_EP_PAIR
__clc_ep_fast_div(__CLC_EP_PAIR a, __CLC_EP_PAIR b) {
__CLC_GENTYPE r = __clc_recip_fast(b.hi);
__CLC_GENTYPE qhi = a.hi * r;
__CLC_EP_PAIR p = __clc_ep_mul(qhi, b);
__CLC_EP_PAIR d = __clc_ep_fast_sub(a.hi, p.hi);
d.lo = d.lo - p.lo + a.lo;
__CLC_GENTYPE qlo = (d.hi + d.lo) * r;
return __clc_ep_fast_add(qhi, qlo);
}
_CLC_DEF _CLC_OVERLOAD _CLC_CONST __CLC_EP_PAIR __clc_ep_div(__CLC_EP_PAIR a,
__CLC_EP_PAIR b) {
__CLC_GENTYPE y = __clc_recip_fast(b.hi);
__CLC_GENTYPE qhi = a.hi * y;
__CLC_EP_PAIR r = __clc_ep_fast_sub(a, __clc_ep_mul(qhi, b));
__CLC_GENTYPE qmi = r.hi * y;
r = __clc_ep_fast_sub(r, __clc_ep_mul(qmi, b));
__CLC_GENTYPE qlo = r.hi * y;
__CLC_EP_PAIR q = __clc_ep_fast_add(qhi, qmi);
q.lo += qlo;
return __clc_ep_normalize(q);
}
_CLC_DEF _CLC_OVERLOAD _CLC_CONST __CLC_EP_PAIR
__clc_ep_recip(__CLC_GENTYPE b) {
__CLC_GENTYPE qhi = __clc_recip_fast(b);
__CLC_EP_PAIR p = __clc_ep_mul(qhi, b);
__CLC_EP_PAIR d = __clc_ep_fast_sub(__CLC_FP_LIT(1.0), p.hi);
d.lo -= p.lo;
__CLC_GENTYPE qlo = (d.hi + d.lo) * qhi;
return __clc_ep_fast_add(qhi, qlo);
}
_CLC_DEF _CLC_OVERLOAD _CLC_CONST __CLC_EP_PAIR
__clc_ep_fast_recip(__CLC_EP_PAIR b) {
__CLC_GENTYPE qhi = __clc_recip_fast(b.hi);
__CLC_EP_PAIR p = __clc_ep_mul(qhi, b);
__CLC_EP_PAIR d = __clc_ep_fast_sub(__CLC_FP_LIT(1.0), p.hi);
d.lo -= p.lo;
__CLC_GENTYPE qlo = (d.hi + d.lo) * qhi;
return __clc_ep_fast_add(qhi, qlo);
}
_CLC_DEF _CLC_OVERLOAD _CLC_CONST __CLC_EP_PAIR
__clc_ep_recip(__CLC_EP_PAIR b) {
__CLC_GENTYPE qhi = __clc_recip_fast(b.hi);
__CLC_EP_PAIR r = __clc_ep_fast_sub(__CLC_FP_LIT(1.0), __clc_ep_mul(qhi, b));
__CLC_GENTYPE qmi = r.hi * qhi;
r = __clc_ep_fast_sub(r, __clc_ep_mul(qmi, b));
__CLC_GENTYPE qlo = r.hi * qhi;
__CLC_EP_PAIR q = __clc_ep_fast_add(qhi, qmi);
q.lo += qlo;
return __clc_ep_normalize(q);
}
_CLC_DEF _CLC_OVERLOAD _CLC_CONST __CLC_EP_PAIR __clc_ep_sqr(__CLC_EP_PAIR a) {
__CLC_EP_PAIR p = __clc_ep_sqr(a.hi);
if (__CLC_GENTYPE_FAST_FMA) {
p.lo = __clc_fma(a.hi, __CLC_FP_LIT(2.0) * a.lo, p.lo);
} else {
p.lo = p.lo + __CLC_FP_LIT(2.0) * a.lo * a.hi;
}
return __clc_ep_normalize(p);
}
_CLC_DEF _CLC_OVERLOAD _CLC_CONST __CLC_EP_PAIR __clc_ep_sqrt(__CLC_GENTYPE a) {
__CLC_GENTYPE shi = __clc_sqrt_fast(a);
__CLC_EP_PAIR e = __clc_ep_fast_sub(a, __clc_ep_sqr(shi));
__CLC_GENTYPE slo = __clc_div_fast(e.hi, __CLC_FP_LIT(2.0) * shi);
return __clc_ep_fast_add(shi,
a == __CLC_FP_LIT(0.0) ? __CLC_FP_LIT(0.0) : slo);
}
_CLC_DEF _CLC_OVERLOAD _CLC_CONST __CLC_EP_PAIR __clc_ep_sqrt(__CLC_EP_PAIR a) {
__CLC_GENTYPE shi = __clc_sqrt_fast(a.hi);
__CLC_EP_PAIR e = __clc_ep_fast_sub(a, __clc_ep_sqr(shi));
__CLC_GENTYPE slo = __clc_div_fast(e.hi, __CLC_FP_LIT(2.0) * shi);
return __clc_ep_fast_add(shi,
a.hi == __CLC_FP_LIT(0.0) ? __CLC_FP_LIT(0.0) : slo);
}
#if __CLC_FPSIZE == 32
_CLC_DEF _CLC_OVERLOAD _CLC_CONST __CLC_GENTYPE __clc_ep_exp(__CLC_EP_PAIR x) {
__CLC_GENTYPE d = x.hi == 0x1.62e430p+6f ? 0x1.0p-17f : 0.0f;
x.hi -= d;
x.lo += d;
__CLC_GENTYPE z = __clc_exp(x.hi);
__CLC_GENTYPE zz = __clc_fma(z, x.lo, z);
return __clc_isinf(z) ? z : zz;
}
_CLC_DEF _CLC_OVERLOAD _CLC_CONST __CLC_EP_PAIR
__clc_ep_exp_extended(__CLC_EP_PAIR x) {
const __CLC_FLOATN LOG2E = 0x1.715476p+0f;
const __CLC_FLOATN LN2_HI = 0x1.62e400p-1f;
const __CLC_FLOATN LN2_MED = 0x1.7f7800p-20f;
const __CLC_FLOATN LN2_LO = 0x1.473de6p-34f;
const __CLC_FLOATN POLY_C1 = 0x1.6850e4p-10f;
const __CLC_FLOATN POLY_C2 = 0x1.123bccp-7f;
const __CLC_FLOATN POLY_C3 = 0x1.555b98p-5f;
const __CLC_FLOATN POLY_C4 = 0x1.55548ep-3f;
const __CLC_FLOATN POLY_C5 = 0x1.fffff8p-2f;
__CLC_FLOATN fn = __clc_rint(x.hi * LOG2E);
__CLC_EP_PAIR term_hi = __clc_ep_fast_add(__clc_mad(fn, -LN2_HI, x.hi), x.lo);
__CLC_EP_PAIR term_med = __clc_ep_fast_sub(term_hi, fn * LN2_MED);
__CLC_EP_PAIR t = __clc_ep_fast_sub(term_med, fn * LN2_LO);
__CLC_FLOATN th = t.hi;
__CLC_FLOATN poly1 = __clc_mad(th, POLY_C1, POLY_C2);
__CLC_FLOATN poly2 = __clc_mad(th, poly1, POLY_C3);
__CLC_FLOATN poly3 = __clc_mad(th, poly2, POLY_C4);
__CLC_FLOATN p = __clc_mad(th, poly3, POLY_C5);
__CLC_EP_PAIR sqr_t = __clc_ep_sqr(t);
__CLC_EP_PAIR poly_term = __clc_ep_mul(sqr_t, p);
__CLC_EP_PAIR inner_sum = __clc_ep_fast_add(t, poly_term);
__CLC_EP_PAIR r = __clc_ep_fast_add(1.0f, inner_sum);
return __clc_ep_ldexp(r, __CLC_CONVERT_INTN(fn));
}
_CLC_DEF _CLC_OVERLOAD _CLC_CONST __CLC_EP_PAIR __clc_ep_ln(__CLC_GENTYPE a) {
__CLC_INTN a_exp;
__CLC_GENTYPE m = __clc_frexp(a, &a_exp);
__CLC_INTN b = m < (2.0f / 3.0f) ? 1 : 0;
m = __clc_ldexp(m, b);
__CLC_INTN e = a_exp - b;
__CLC_EP_PAIR x = __clc_ep_div(m - 1.0f, __clc_ep_fast_add(1.0f, m));
__CLC_EP_PAIR s = __clc_ep_sqr(x);
__CLC_GENTYPE t = s.hi;
__CLC_GENTYPE p = __clc_mad(t, __clc_mad(t, 0x1.ed89c2p-3f, 0x1.23e988p-2f),
0x1.999bdep-2f);
// ln(2)*e + 2*x + x^3(c3 + x^2*p)
__CLC_EP_PAIR r = __clc_ep_add(
__clc_ep_mul(__clc_ep_make_pair(__CLC_FP_LIT(0x1.62e430p-1),
__CLC_FP_LIT(-0x1.05c610p-29)),
__CLC_CONVERT_GENTYPE(e)),
__clc_ep_fast_add(
__clc_ep_ldexp(x, 1),
__clc_ep_mul(__clc_ep_mul(s, x),
__clc_ep_fast_add(
__clc_ep_make_pair(__CLC_FP_LIT(0x1.555554p-1),
__CLC_FP_LIT(0x1.e72020p-29)),
__clc_ep_mul(s, p)))));
return r;
}
_CLC_DEF _CLC_OVERLOAD _CLC_CONST __CLC_FLOATN __clc_ep_ln_hi(__CLC_EP_PAIR a,
__CLC_INTN ea) {
__CLC_INTN a_hi_exp;
__CLC_FLOATN a_hi_m = __clc_frexp(a.hi, &a_hi_exp);
__CLC_INTN b = a_hi_m < (2.0f / 3.0f) ? 1 : 0;
__CLC_INTN e = a_hi_exp - b;
__CLC_EP_PAIR m = __clc_ep_ldexp(a, -e);
__CLC_EP_PAIR x =
__clc_ep_div(__clc_ep_fast_add(-1.0f, m), __clc_ep_fast_add(1.0f, m));
__CLC_FLOATN s = x.hi * x.hi;
__CLC_FLOATN p = __clc_mad(s, __clc_mad(s, 0x1.36db58p-2f, 0x1.992b46p-2f),
0x1.5555b4p-1f);
const __CLC_EP_PAIR ln2 = __clc_ep_make_pair(__CLC_FP_LIT(0x1.62e430p-1),
__CLC_FP_LIT(-0x1.05c610p-29));
__CLC_EP_PAIR r =
__clc_ep_add(__clc_ep_mul(ln2, __CLC_CONVERT_FLOATN(e + ea)),
__clc_ep_fast_add(__clc_ep_ldexp(x, 1), s * x.hi * p));
return r.hi;
}
#elif __CLC_FPSIZE == 64
_CLC_DEF _CLC_OVERLOAD _CLC_CONST __CLC_GENTYPE __clc_ep_exp(__CLC_EP_PAIR x) {
__CLC_GENTYPE z = __clc_exp(x.hi);
__CLC_GENTYPE zz = __clc_mad(z, x.lo, z);
return __clc_isinf(z) ? z : zz;
}
_CLC_DEF _CLC_OVERLOAD _CLC_CONST __CLC_EP_PAIR
__clc_ep_exp_extended(__CLC_EP_PAIR x) {
const __CLC_DOUBLEN LOG2E = 0x1.71547652b82fep+0;
const __CLC_DOUBLEN LN2_HI = 0x1.62e42fefa3000p-1;
const __CLC_DOUBLEN LN2_MED = 0x1.3de6af278e000p-42;
const __CLC_DOUBLEN LN2_LO = 0x1.9cc01f97b57a0p-83;
const __CLC_DOUBLEN POLY_C1 = 0x1.ade156a5dcb37p-26;
const __CLC_DOUBLEN POLY_C2 = 0x1.28af3fca7ab0cp-22;
const __CLC_DOUBLEN POLY_C3 = 0x1.71dee623fde64p-19;
const __CLC_DOUBLEN POLY_C4 = 0x1.a01997c89e6b0p-16;
const __CLC_DOUBLEN POLY_C5 = 0x1.a01a014761f6ep-13;
const __CLC_DOUBLEN POLY_C6 = 0x1.6c16c1852b7b0p-10;
const __CLC_DOUBLEN POLY_C7 = 0x1.1111111122322p-7;
const __CLC_DOUBLEN POLY_C8 = 0x1.55555555502a1p-5;
const __CLC_DOUBLEN POLY_C9 = 0x1.5555555555511p-3;
const __CLC_DOUBLEN POLY_C10 = 0x1.000000000000bp-1;
__CLC_DOUBLEN dn = __clc_rint(x.hi * LOG2E);
__CLC_EP_PAIR term_hi = __clc_ep_fast_add(__clc_mad(dn, -LN2_HI, x.hi), x.lo);
__CLC_EP_PAIR term_med = __clc_ep_fast_sub(term_hi, dn * LN2_MED);
__CLC_EP_PAIR t = __clc_ep_fast_sub(term_med, dn * LN2_LO);
__CLC_DOUBLEN th = t.hi;
__CLC_DOUBLEN poly1 = __clc_mad(th, POLY_C1, POLY_C2);
__CLC_DOUBLEN poly2 = __clc_mad(th, poly1, POLY_C3);
__CLC_DOUBLEN poly3 = __clc_mad(th, poly2, POLY_C4);
__CLC_DOUBLEN poly4 = __clc_mad(th, poly3, POLY_C5);
__CLC_DOUBLEN poly5 = __clc_mad(th, poly4, POLY_C6);
__CLC_DOUBLEN poly6 = __clc_mad(th, poly5, POLY_C7);
__CLC_DOUBLEN poly7 = __clc_mad(th, poly6, POLY_C8);
__CLC_DOUBLEN poly8 = __clc_mad(th, poly7, POLY_C9);
__CLC_DOUBLEN p = __clc_mad(th, poly8, POLY_C10);
__CLC_EP_PAIR sqr_t = __clc_ep_sqr(t);
__CLC_EP_PAIR poly_term = __clc_ep_mul(sqr_t, p);
__CLC_EP_PAIR inner_sum = __clc_ep_fast_add(t, poly_term);
__CLC_EP_PAIR r = __clc_ep_fast_add(1.0, inner_sum);
return __clc_ep_ldexp(r, __CLC_CONVERT_INTN(dn));
}
_CLC_DEF _CLC_OVERLOAD _CLC_CONST __CLC_EP_PAIR __clc_ep_ln(__CLC_DOUBLEN a) {
__CLC_INTN a_exp;
__CLC_DOUBLEN m = __clc_frexp(a, &a_exp);
__CLC_INTN b = __CLC_CONVERT_INTN(m < __CLC_FP_LIT(2.0 / 3.0)) ? 1 : 0;
m = __clc_ldexp(m, b);
__CLC_INTN e = a_exp - b;
__CLC_EP_PAIR x = __clc_ep_div(m - 1.0, __clc_ep_fast_add(1.0, m));
__CLC_EP_PAIR s = __clc_ep_sqr(x);
__CLC_DOUBLEN t = s.hi;
__CLC_DOUBLEN p = __clc_mad(t, __clc_mad(t, __clc_mad(t, __clc_mad(t,
__clc_mad(t, __clc_mad(t, __clc_mad(t, __clc_mad(t,
0x1.dee674222de17p-4, 0x1.a6564968915a9p-4), 0x1.e25e43abe935ap-4), 0x1.110ef47e6c9c2p-3),
0x1.3b13bcfa74449p-3), 0x1.745d171bf3c30p-3), 0x1.c71c71c7792cep-3), 0x1.24924924920dap-2),
0x1.999999999999cp-2);
// ln(2)*e + 2*x + x^3(c3 + x^2*p)
__CLC_EP_PAIR r = __clc_ep_add(
__clc_ep_mul(__clc_ep_make_pair(__CLC_FP_LIT(0x1.62e42fefa39efp-1),
__CLC_FP_LIT(0x1.abc9e3b39803fp-56)),
__CLC_CONVERT_GENTYPE(e)),
__clc_ep_fast_add(
__clc_ep_ldexp(x, 1),
__clc_ep_mul(
__clc_ep_mul(s, x),
__clc_ep_fast_add(
__clc_ep_make_pair(__CLC_FP_LIT(0x1.5555555555555p-1),
__CLC_FP_LIT(0x1.543b0d5df274dp-55)),
__clc_ep_mul(s, p)))));
return r;
}
_CLC_DEF _CLC_OVERLOAD _CLC_CONST __CLC_DOUBLEN __clc_ep_ln_hi(__CLC_EP_PAIR a,
__CLC_INTN ea) {
__CLC_INTN a_hi_exp;
__CLC_DOUBLEN m_hi = __clc_frexp(a.hi, &a_hi_exp);
__CLC_INTN b = __CLC_CONVERT_INTN(m_hi < (2.0 / 3.0)) ? 1 : 0;
__CLC_INTN e = a_hi_exp - b;
__CLC_EP_PAIR m = __clc_ep_ldexp(a, -e);
__CLC_EP_PAIR x =
__clc_ep_div(__clc_ep_fast_add(-1.0, m), __clc_ep_fast_add(1.0, m));
__CLC_DOUBLEN s = x.hi * x.hi;
const __CLC_DOUBLEN ln_c1 = 0x1.3ab76bf559e2bp-3;
const __CLC_DOUBLEN ln_c2 = 0x1.385386b47b09ap-3;
const __CLC_DOUBLEN ln_c3 = 0x1.7474dd7f4df2ep-3;
const __CLC_DOUBLEN ln_c4 = 0x1.c71c016291751p-3;
const __CLC_DOUBLEN ln_c5 = 0x1.249249b27acf1p-2;
const __CLC_DOUBLEN ln_c6 = 0x1.99999998ef7b6p-2;
const __CLC_DOUBLEN ln_c7 = 0x1.5555555555780p-1;
__CLC_DOUBLEN q1 = __clc_mad(s, ln_c1, ln_c2);
__CLC_DOUBLEN q2 = __clc_mad(s, q1, ln_c3);
__CLC_DOUBLEN q3 = __clc_mad(s, q2, ln_c4);
__CLC_DOUBLEN q4 = __clc_mad(s, q3, ln_c5);
__CLC_DOUBLEN q5 = __clc_mad(s, q4, ln_c6);
__CLC_DOUBLEN p = __clc_mad(s, q5, ln_c7);
const __CLC_EP_PAIR ln2 = __clc_ep_make_pair(
__CLC_FP_LIT(0x1.62e42fefa39efp-1), __CLC_FP_LIT(0x1.abc9e3b39803fp-56));
__CLC_EP_PAIR r =
__clc_ep_add(__clc_ep_mul(ln2, __CLC_CONVERT_DOUBLEN(e + ea)),
__clc_ep_fast_add(__clc_ep_ldexp(x, 1), s * x.hi * p));
return r.hi;
}
#endif