/*

(C) 2008-2024 Advanced Micro Devices, Inc. All Rights Reserved.

Advanced Micro Devices, Inc.
Software License Agreement

IMPORTANT-READ CAREFULLY:  Do not load or use the Software until you have
carefully read and agreed to the following terms and conditions.  This is a
legal agreement ("Agreement") between you (either an individual or an entity)
("Licensee") and Advanced Micro Devices, Inc. ("AMD"). If Licensee does not
agree to the terms of this Agreement, do not install or use this software or
any portion thereof.  By loading or using the object code version only of the
software obtained herewith, which may include associated install scripts and
online or electronic documentation or any portion thereof, that is made
available by AMD to download from any media ("Software"), Licensee agrees to
all of the terms of this Agreement.

1.  LICENSE:

    a.  Subject to the terms and conditions of this Agreement, AMD grants
    Licensee the following non-exclusive, non-transferable, royalty-free,
    limited copyright license to download, copy, use, distribute and sublicense
    the foregoing rights through multiple tiers of sublicenses the object code
    version of the Software and materials associated with this Agreement,
    including without limitation printed documentation, (collectively,
    "Materials"), provided that Licensee agrees to include all copyright
    legends and other legal notices that may appear in the Materials.  The
    foregoing license is conditioned upon Licensee distributing the object code
    version of the Software only and under this software license agreement.
    Except for the limited license granted herein, Licensee shall have no other
    rights in the Materials, whether express, implied, arising by estoppel or
    otherwise.

    b.  Except as expressly set forth in Section 1(a), Licensee does not have
    the right to (i) distribute, rent, lease, sell, sublicense, assign, or
    otherwise transfer the Materials, in whole or in part, to third parties for
    commercial or for non-commercial use; or (ii) modify, disassemble, reverse
    engineer, or decompile the Software, or otherwise reduce any part of the
    Software to any human readable form.  All rights in and to the Materials
    not expressly granted to Licensee in this Agreement are reserved to AMD.

2.  FEEDBACK:  Licensee may provide AMD feedback, suggestions or opinions as to
the Software, its features, and desired enhancements or changes.  If Licensee
provides feedback, suggestions or opinions to AMD regarding any new features,
use, functionality, or change to the Software or any materials related to the
Software, Licensee hereby agrees to grant, and does grant, AMD all rights
needed for AMD to incorporate, modify, distribute, use and commercialize any
new feature, use, functionality, or change at no charge or encumbrance to AMD.
Licensee agrees that AMD may disclose such feedback, suggestions or opinions to
any third party in any manner, and Licensee agrees that AMD has the ability to
sublicense any of the foregoing rights in any feedback, suggestions or opinions
or AMD products or services in any form to any third party without restriction.

3.  OWNERSHIP AND COPYRIGHT OF MATERIALS: Licensee agrees that the Materials
are owned by AMD and are protected by United States and foreign intellectual
property laws (e.g. patent and copyright laws) and international treaty
provisions.  Licensee will not remove the copyright notice from the Materials.
Licensee agrees to prevent any unauthorized copying of the Materials.  All
title and copyrights in and to the Materials, all copies thereof (in whole or
in part, and in any form), and all rights therein shall remain vested in AMD.
Except as expressly provided herein, AMD does not grant any express or implied
right to Licensee under AMD patents, copyrights, trademarks, or trade secret
information.

4.  WARRANTY DISCLAIMER: THE MATERIALS ARE PROVIDED "AS IS" WITHOUT ANY EXPRESS
OR IMPLIED WARRANTY OF ANY KIND INCLUDING WARRANTIES OF MERCHANTABILITY,
NONINFRINGEMENT OF THIRD-PARTY INTELLECTUAL PROPERTY, TITLE, OR FITNESS FOR ANY
PARTICULAR PURPOSE, OR THOSE ARISING FROM CUSTOM OF TRADE OR COURSE OF USAGE.
THE ENTIRE RISK ARISING OUT OF USE OR PERFORMANCE OF THE MATERIALS REMAINS WITH
LICENSEE.  AMD DOES NOT WARRANT, GUARANTEE, OR MAKE ANY REPRESENTATIONS AS TO
THE CORRECTNESS, ACCURACY, COMPLETENESS, QUALITY, OR RELIABILITY OF THE
MATERIALS.

AMD DOES NOT WARRANT THAT OPERATION OF THE MATERIALS WILL BE UNINTERRUPTED OR
ERROR-FREE.  YOU ARE RESPONSIBLE FOR DETERMINING THE APPROPRIATENESS OF USING
THE SOFTWARE AND ASSUME ALL RISKS ASSOCIATED WITH THE USE OF THE MATERIALS,
INCLUDING BUT NOT LIMITED TO THE RISKS OF PROGRAM ERRORS, DAMAGE TO OR LOSS OF
DATA, PROGRAMS OR EQUIPMENT, AND UNAVAILABILITY OR INTERRUPTION OF OPERATIONS.
SOME JURISDICTIONS DO NOT ALLOW FOR THE EXCLUSION OR LIMITATION OF IMPLIED
WARRANTIES, SO THE ABOVE LIMITATIONS OR EXCLUSIONS MAY NOT APPLY TO LICENSEE.

5.  LIMITATION OF LIABILITY:  IN NO EVENT SHALL AMD OR ITS DIRECTORS, OFFICERS,
EMPLOYEES AND AGENTS, ITS SUPPLIERS OR ITS LICENSORS BE LIABLE TO LICENSEE OR
ANY THIRD PARTIES IN RECEIPT OF THE MATERIALS FOR CONSEQUENTIAL, INCIDENTAL,
PUNITIVE OR SPECIAL DAMAGES, INCLUDING, BUT NOT LIMITED TO LOSS OF PROFITS,
BUSINESS INTERRUPTION, OR LOSS OF INFORMATION ARISING OUT OF THE USE OF OR
INABILITY TO USE THE MATERIALS, EVEN IF AMD HAS BEEN ADVISED OF THE POSSIBILITY
OF SUCH DAMAGES.  AMD DOES NOT ASSUME ANY RESPONSIBILITY TO SUPPORT OR UPDATE
THE MATERIALS.  BY USING THE MATERIALS WITHOUT CHARGE, YOU ACCEPT THIS
ALLOCATION OF RISK.  BECAUSE SOME JURSIDICTIONS PROHIBIT THE EXCLUSION OR
LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES, THE ABOVE
LIMITATION MAY NOT APPLY TO LICENSEE.

6.  U.S. GOVERNMENT RESTRICTED RIGHTS: The Materials are provided with
"RESTRICTED RIGHTS."  Use, duplication or disclosure by the Government is
subject to restrictions as set forth in FAR52.227-14 and DFAR252.227-7013, et
seq., or its successor.  Use of the Materials by the Government constitutes
acknowledgment of AMD's proprietary rights in them.

7.  TERMINATION OF LICENSE: This Agreement will terminate immediately without
notice from AMD or judicial resolution if Licensee fails to comply with any
provisions of this Agreement.  Upon termination of this Agreement, Licensee
must delete or destroy all copies of the Materials.

8.  SUPPORT.  Under this Agreement, AMD is under no obligation to assist in the
use of the Materials, to provide support to licensees of the Materials, or to
provide maintenance, correction, modification, enhancement, or upgrades to the
Materials.  If AMD determines, in its sole discretion, to support, maintain,
correct, modify, enhance, or upgrade the Software, such support, maintenance,
correction, modification, enhancement or upgrade shall be considered part of
the Materials, and shall be subject to this Agreement.

9.  SURVIVAL:  Sections 1(b), 2, 3, 4, 5, 6, and 8 through 14 shall survive any
expiration or termination of this Agreement.

10. APPLICABLE LAWS:  Any claim arising under or relating to this Agreement
shall be governed by and construed in accordance with the substantive laws of
the State of California, without regard to principles of conflict of laws.
Each party hereto submits to the jurisdiction of the state and federal courts
of Santa Clara County and the Northern District of California for the purposes
of all legal proceedings arising out of or relating to this Agreement or the
subject matter hereof.  Each party waives any objection which it may have to
contest such forum.

11. IMPORT/EXPORT/RE-EXPORT/USE/RELEASE/TRANSFER RESTRICTIONS AND COMPLIANCE
WITH LAWS:  Licensee is hereby provided notice, and agrees and acknowledges,
that the Software, its source code, any accompanying media, material or
information, and any product of the foregoing, may be subject to restrictions
on use, release, transfer, importation, exportation and/or re- exportation
under the laws and regulations of the United States or other countries
("Applicable Laws"), which include but are not limited to U.S. export control
laws such as the Export Administration Regulations and national security
controls as defined thereunder, as well as State Department controls under the
U.S. Munitions List.  Licensee further agrees that the Software, its source
code, any accompanying media, material or information, and any product of the
foregoing, will not be used, released, transferred, imported, exported and/or
re-exported in any manner prohibited under Applicable Laws, including U.S.
export control laws regarding specifically designated persons, countries and
nationals of countries subject to national security controls as provided in
License Exception TSR of the Export Administration Regulations and any
successor regulations.

12. SEVERABILITY:  Should any term of this Agreement be declared void or
unenforceable by any court of competent jurisdiction, such declaration shall
have no effect on the remaining terms hereof.

13. NO WAIVER:  The failure of either party to enforce any rights granted
hereunder or to take action against the other party in the event of any breach
hereunder shall not be deemed a waiver by that party as to subsequent
enforcement of rights or subsequent actions in the event of future breaches.

14. ENTIRE AGREEMENT:  This Agreement constitutes the entire agreement between
the parties and supersedes any prior or contemporaneous oral or written
agreements with respect to the subject matter of this Agreement.

*/


#include <emmintrin.h>
#include <immintrin.h>
#if defined(_WIN64) || defined(_WIN32)
    #include <avx512fintrin.h>
#endif
#ifndef AMD_LIBM_VEC_EXTERNAL_H
#define AMD_LIBM_VEC_EXTERNAL_H

/*
 * We don’t expect anyone to include this file directly.
* but rely on AOCC to generate appropriate calls to vector functions
*/

#ifndef AMD_LIBM_VEC_EXPERIMENTAL
#error "The functionality in this header is experimental, please define AMD_LIBM_VEC_EXPERIMENTAL"
#endif /* EXPERIMENTAL */

#ifdef __cplusplus
extern "C" {
#endif

 /* Arithmetic */

    __m128d amd_vrd2_fabs   (__m128d x);
    __m256d amd_vrd4_fabs   (__m256d x);
    __m128  amd_vrs4_fabsf  (__m128  x);
    __m256  amd_vrs8_fabsf  (__m256  x);

    /* array vector variants */
    void amd_vrsa_addf      (int len, float *lhs, float *rhs, float *dst);
    void amd_vrda_add       (int len, double *lhs, double *rhs, double *dst);
    void amd_vrsa_subf      (int len, float *lhs, float *rhs, float *dst);
    void amd_vrda_sub       (int len, double *lhs, double *rhs, double *dst);
    void amd_vrsa_mulf      (int len, float *lhs, float *rhs, float *dst);
    void amd_vrda_mul       (int len, double *lhs, double *rhs, double *dst);
    void amd_vrsa_divf      (int len, float *lhs, float *rhs, float *dst);
    void amd_vrda_div       (int len, double *lhs, double *rhs, double *dst);
    void amd_vrsa_fmaxf     (int len, float *lhs, float *rhs, float *dst);
    void amd_vrda_fmax      (int len, double *lhs, double *rhs, double *dst);
    void amd_vrsa_fminf     (int len, float *lhs, float *rhs, float *dst);
    void amd_vrda_fmin      (int len, double *lhs, double *rhs, double *dst);
    void amd_vrsa_fabsf     (int len, float  *src, float  *dst);
    void amd_vrda_fabs      (int len, double *src, double *dst);

    /* array vector variants with increment */
    void amd_vrsa_addfi     (int len, float *lhs, int inc_a, float *rhs, int inc_b, float *dst, int inc_res);
    void amd_vrda_addi      (int len, double *lhs, int inc_a, double *rhs, int inc_b, double *dst, int inc_res);
    void amd_vrsa_subfi     (int len, float *lhs, int inc_a, float *rhs, int inc_b, float *dst, int inc_res);
    void amd_vrda_subi      (int len, double *lhs, int inc_a, double *rhs, int inc_b, double *dst, int inc_res);
    void amd_vrsa_mulfi     (int len, float *lhs, int inc_a, float *rhs, int inc_b, float *dst, int inc_res);
    void amd_vrda_muli      (int len, double *lhs, int inc_a, double *rhs, int inc_b, double *dst, int inc_res);
    void amd_vrsa_divfi     (int len, float *lhs, int inc_a, float *rhs, int inc_b, float *dst, int inc_res);
    void amd_vrda_divi      (int len, double *lhs, int inc_a, double *rhs, int inc_b, double *dst, int inc_res);
    void amd_vrsa_fmaxfi    (int len, float *lhs, int inc_a, float *rhs, int inc_b, float *dst, int inc_res);
    void amd_vrda_fmaxi     (int len, double *lhs, int inc_a, double *rhs, int inc_b, double *dst, int inc_res);
    void amd_vrsa_fminfi    (int len, float *lhs, int inc_a, float *rhs, int inc_b, float *dst, int inc_res);
    void amd_vrda_fmini     (int len, double *lhs, int inc_a, double *rhs, int inc_b, double *dst, int inc_res);

 /* Exponential */

    __m128d amd_vrd2_exp    (__m128d x);
    __m128d amd_vrd2_exp2   (__m128d x);
    __m128d amd_vrd2_exp10  (__m128d x);
    __m128d amd_vrd2_expm1  (__m128d x);

    __m128  amd_vrs4_expf   (__m128  x);
    __m128  amd_vrs4_exp2f  (__m128  x);
    __m128  amd_vrs4_exp10f (__m128  x);

    __m256d amd_vrd4_exp    (__m256d x);
    __m256d amd_vrd4_exp2   (__m256d x);
    __m128  amd_vrs4_expm1f (__m128  x);

    __m256  amd_vrs8_expf   (__m256 x);
    __m256  amd_vrs8_exp2f  (__m256 x);

    /* array vector variants */
    void amd_vrda_exp       (int len, double *src, double *dst);
    void amd_vrsa_expf      (int len, float  *src, float  *dst);
    void amd_vrda_exp2      (int len, double *src, double *dst);
    void amd_vrsa_exp2f     (int len, float  *src, float  *dst);
    void amd_vrda_exp10     (int len, double *src, double *dst);
    void amd_vrsa_exp10f    (int len, float  *src, float  *dst);
    void amd_vrda_expm1     (int len, double *src, double *dst);
    void amd_vrsa_expm1f    (int len, float  *src, float  *dst);

 /* Logarithmic */

    __m128d amd_vrd2_log     (__m128d x);
    __m128d amd_vrd2_log2    (__m128d x);
    __m128d amd_vrd2_log1p   (__m128d x);
    __m128d amd_vrd2_log10   (__m128d x);

    __m128  amd_vrs4_logf    (__m128  x);
    __m128  amd_vrs4_log2f   (__m128  x);
    __m128  amd_vrs4_log10f  (__m128  x);

    __m256d amd_vrd4_log     (__m256d x);
    __m256d amd_vrd4_log2    (__m256d x);
    __m128  amd_vrs4_log1pf  (__m128  x);

    __m256  amd_vrs8_logf    (__m256 x);
    __m256  amd_vrs8_log2f   (__m256 x);
    __m256  amd_vrs8_log10f  (__m256 x);

    /* array vector variants */
    void amd_vrda_log       (int len, double *src, double *dst);
    void amd_vrsa_logf      (int len, float  *src, float  *dst);
    void amd_vrda_log2      (int len, double *src, double *dst);
    void amd_vrsa_log2f     (int len, float  *src, float  *dst);
    void amd_vrda_log10     (int len, double *src, double *dst);
    void amd_vrsa_log10f    (int len, float  *src, float  *dst);
    void amd_vrda_log1p     (int len, double *src, double *dst);
    void amd_vrsa_log1pf    (int len, float  *src, float  *dst);

/* Trigonometric */
    __m128d amd_vrd2_cos    (__m128d x);
    __m128d amd_vrd2_sin    (__m128d x);
    __m128d amd_vrd2_tan    (__m128d x);

    __m128  amd_vrs4_sinf   (__m128  x);
    __m128  amd_vrs4_cosf   (__m128  x);
    __m128  amd_vrs4_tanf   (__m128  x);
    void    amd_vrs4_sincosf(__m128 x, __m128 *sin, __m128 *cos);

    __m256  amd_vrs8_tanf   (__m256  x);
    __m256  amd_vrs8_sinf   (__m256  x);
    __m256  amd_vrs8_cosf   (__m256  x);
    void    amd_vrs8_sincosf(__m256 x, __m256 *sin, __m256 *cos);

    __m256d amd_vrd4_sin    (__m256d x);
    __m256d amd_vrd4_cos    (__m256d x);
    __m256d amd_vrd4_tan    (__m256d x);
    void amd_vrd4_sincos    (__m256d x, __m256d *sin, __m256d *cos);

    /* array vector variants */
    void amd_vrda_cos       (int len, double *src, double *dst);
    void amd_vrsa_cosf      (int len, float  *src, float  *dst);
    void amd_vrda_sin       (int len, double *src, double *dst);
    void amd_vrsa_sinf      (int len, float  *src, float  *dst);

/* Inverse Trigonometric */
    __m128  amd_vrs4_asinf  (__m128  x);
    __m128  amd_vrs4_acosf  (__m128  x);
    __m128  amd_vrs4_atanf  (__m128  x);

   __m256  amd_vrs8_acosf  (__m256  x);
   __m256  amd_vrs8_atanf  (__m256  x);
   __m256  amd_vrs8_asinf  (__m256  x);

    __m128d amd_vrd2_atan   (__m128d x);
    __m256d amd_vrd4_atan   (__m256d x);

/*Hyperbolic*/
   __m128  amd_vrs4_coshf   (__m128  x);
   __m128  amd_vrs4_tanhf   (__m128  x);

   __m256  amd_vrs8_coshf   (__m256  x);
   __m256  amd_vrs8_tanhf   (__m256  x);

   __m128d amd_vrd2_cosh    (__m128d x);

 /* Power */
    __m128d amd_vrd2_pow    (__m128d x, __m128d y);
    __m128  amd_vrs4_powf   (__m128 x, __m128 y);
    __m256d amd_vrd4_pow    (__m256d, __m256d);
    __m256  amd_vrs8_powf   (__m256, __m256);

    __m128d amd_vrd2_powx   (__m128d x, double y);
    __m256d amd_vrd4_powx   (__m256d, double);


    __m128  amd_vrs4_powxf   (__m128 x, float y);
    __m256  amd_vrs8_powxf   (__m256 x, float y);

    __m128d amd_vrd2_cbrt   (__m128d x);
    __m128  amd_vrs4_cbrtf  (__m128  x);

    /* array vector variants */
    void amd_vrda_pow       (int len, double *src1, double *src2, double *dst);
    void amd_vrsa_powf      (int len, float  *src1, float  *src2, float  *dst);

    void amd_vrda_cbrt      (int len, double *src, double *dst);
    void amd_vrsa_cbrtf     (int len, float  *src, float  *dst);

/* erf */
    __m128d amd_vrd2_erf    (__m128d x);
    __m128  amd_vrs4_erff   (__m128 x);
    __m256d amd_vrd4_erf    (__m256d x);
    __m256  amd_vrs8_erff   (__m256 x);

/* sqrt */
    __m128d amd_vrd2_sqrt   (__m128d x);
    __m256d amd_vrd4_sqrt   (__m256d x);

    __m128  amd_vrs4_sqrtf   (__m128 x);
    __m256  amd_vrs8_sqrtf   (__m256 x);

    void amd_vrda_sqrt       (int len, double *src, double *dst);
    void amd_vrsa_sqrtf      (int len, float  *src, float  *dst);

/* linearfrac */
    __m128d amd_vrd2_linearfrac   (__m128d x, __m128d y, double, double, double, double);
    __m256d amd_vrd4_linearfrac   (__m256d x, __m256d y, double, double, double, double);

    __m128 amd_vrs4_linearfracf   (__m128 x, __m128 y, float, float, float, float);
    __m256 amd_vrs8_linearfracf   (__m256 x, __m256 y, float, float, float, float);

    void amd_vrda_linearfrac      (int len, double *x, double *y, double scx, double shx, double scy, double shy, double *dst);
    void amd_vrsa_linearfracf     (int len, float *x, float *y, float scx, float shx, float scy, float shy, float *dst);

/* AVX512 variants */
#if defined(__AVX512F__)

    /* Exp */
    __m512d amd_vrd8_exp    (__m512d x);
    __m512  amd_vrs16_expf  (__m512  x);

    __m512d amd_vrd8_exp2   (__m512d x);
    __m512  amd_vrs16_exp2f (__m512  x);

    /* Log */
    __m512d amd_vrd8_log     (__m512d x);
    __m512d amd_vrd8_log2    (__m512d x);

    __m512  amd_vrs16_logf   (__m512  x);
    __m512  amd_vrs16_log2f  (__m512 x);
    __m512  amd_vrs16_log10f (__m512 x);

    /* Cos */
    __m512  amd_vrs16_cosf   (__m512 x);
    __m512d amd_vrd8_cos     (__m512d x);

    /* Sin */
    __m512  amd_vrs16_sinf   (__m512 x);
    __m512d amd_vrd8_sin     (__m512d x);

    /* Tan */
    __m512d amd_vrd8_tan     (__m512d x);
    __m512  amd_vrs16_tanf   (__m512 x);

    /* Sincos */
    void    amd_vrd8_sincos  (__m512d x, __m512d *sin, __m512d *cos);
    void    amd_vrs16_sincosf(__m512 x, __m512 *sin, __m512 *cos);

    /* Atan */
    __m512 amd_vrs16_atanf  (__m512 x);
    __m512d amd_vrd8_atan   (__m512d x);

    /* Asin */
    __m512 amd_vrs16_asinf  (__m512 x);
    __m512d amd_vrd8_asin   (__m512d x);

    /* Acos */
    __m512 amd_vrs16_acosf  (__m512 x);

    /* Tanh */
    __m512 amd_vrs16_tanhf  (__m512 x);

    /* Pow */
    __m512d amd_vrd8_pow    (__m512d x, __m512d y);
    __m512  amd_vrs16_powf  (__m512  x, __m512  y);

    __m512d amd_vrd8_powx   (__m512d x, double y);
    __m512  amd_vrs16_powxf  (__m512  x, float  y);

    /* Erf */
    __m512d amd_vrd8_erf    (__m512d x);
    __m512  amd_vrs16_erff  (__m512 x);

    /* Sqrt */
    __m512d amd_vrd8_sqrt   (__m512d x);
    __m512  amd_vrs16_sqrtf  (__m512 x);

    /* Linearfrac */
     __m512d amd_vrd8_linearfrac   (__m512d x, __m512d y, double, double, double, double);
     __m512  amd_vrs16_linearfracf (__m512 x, __m512 y, float, float, float, float);

#endif

#ifdef __cplusplus
}
#endif

#endif /* AMD_\LIBM_VEC_EXTERNAL */
