blob: 15afa1b7d2b2e4ae77437cf2ce6861d708ceaf36 [file] [log] [blame]
// Copyright 2019 Google LLC
//
// This source code is licensed under the BSD-style license found in the
// LICENSE file in the root directory of this source tree.
#include <assert.h>
#include <immintrin.h>
#include <xnnpack/math-stubs.h>
void xnn_math_f32_exp__avx512f_p5_scalef(
size_t n,
const float* input,
float* output)
{
assert(n % (16 * sizeof(float)) == 0);
const __m512 log2e = _mm512_set1_ps(0x1.715476p+0f);
const __m512 minus_ln2_hi = _mm512_set1_ps(-0x1.62E43p-1f);
const __m512 minus_ln2_lo = _mm512_set1_ps(0x1.05C61p-29f);
const __m512 one = _mm512_set1_ps(1.0f);
const __m512 c2 = _mm512_set1_ps(0x1.FFFDFCp-2f);
const __m512 c3 = _mm512_set1_ps(0x1.5557ACp-3f);
const __m512 c4 = _mm512_set1_ps(0x1.572A12p-5f);
const __m512 c5 = _mm512_set1_ps(0x1.1063E2p-7f);
for (; n != 0; n -= 16 * sizeof(float)) {
const __m512 x = _mm512_loadu_ps(input);
const __m512 s = _mm512_roundscale_ps(_mm512_mul_ps(x, log2e), 0);
__m512 rx = _mm512_fmadd_ps(s, minus_ln2_hi, x);
rx = _mm512_fmadd_ps(s, minus_ln2_lo, rx);
__m512 rf = _mm512_fmadd_ps(c5, rx, c4);
rf = _mm512_fmadd_ps(rf, rx, c3);
rf = _mm512_fmadd_ps(rf, rx, c2);
rf = _mm512_fmadd_ps(rf, rx, one);
rf = _mm512_fmadd_ps(rf, rx, one);
__m512 f = _mm512_scalef_ps(rf, s);
_mm512_storeu_ps(output, f);
input += 16;
output += 16;
}
}