// Copyright Naoki Shibata and contributors 2010 - 2021. // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #if (defined (__GNUC__) || defined (__clang__) || defined(__INTEL_COMPILER)) && !defined(_MSC_VER) #define CONST __attribute__((const)) #else #define CONST #endif #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__MINGW64__) static jmp_buf sigjmp; #define SETJMP(x) setjmp(x) #define LONGJMP longjmp #else static sigjmp_buf sigjmp; #define SETJMP(x) sigsetjmp(x, 1) #define LONGJMP siglongjmp #endif static void sighandler(int signum) { LONGJMP(sigjmp, 1); } static int cpuSupportsExt(void (*tryExt)()) { static int cache = -1; if (cache != -1) return cache; void (*org); org = signal(SIGILL, sighandler); if (SETJMP(sigjmp) == 0) { (*tryExt)(); cache = 1; } else { cache = 0; } signal(SIGILL, org); return cache; } #define DISPATCH_vq_vq(qtype, funcName, pfn, dfn, funcExt0, funcExt1) \ static CONST VECTOR_CC qtype (*pfn)(qtype arg0); \ static CONST VECTOR_CC qtype dfn(qtype arg0) { \ qtype CONST VECTOR_CC (*p)(qtype arg0) = funcExt0; \ SUBST_IF_EXT1(funcExt1); \ pfn = p; \ return (*pfn)(arg0); \ } \ static CONST VECTOR_CC qtype (*pfn)(qtype arg0) = dfn; \ EXPORT CONST VECTOR_CC qtype funcName(qtype arg0) { return (*pfn)(arg0); } #define DISPATCH_vq_vq_vq(qtype, funcName, pfn, dfn, funcExt0, funcExt1) \ static CONST VECTOR_CC qtype (*pfn)(qtype arg0, qtype arg1); \ static CONST VECTOR_CC qtype dfn(qtype arg0, qtype arg1) { \ qtype CONST VECTOR_CC (*p)(qtype arg0, qtype arg1) = funcExt0; \ SUBST_IF_EXT1(funcExt1); \ pfn = p; \ return (*pfn)(arg0, arg1); \ } \ static CONST VECTOR_CC qtype (*pfn)(qtype arg0, qtype arg1) = dfn; \ EXPORT CONST VECTOR_CC qtype funcName(qtype arg0, qtype arg1) { return (*pfn)(arg0, arg1); } #define DISPATCH_vq_vq_vq_vq(qtype, funcName, pfn, dfn, funcExt0, funcExt1) \ static CONST VECTOR_CC qtype (*pfn)(qtype arg0, qtype arg1, qtype arg2); \ static CONST VECTOR_CC qtype dfn(qtype arg0, qtype arg1, qtype arg2) { \ qtype CONST VECTOR_CC (*p)(qtype arg0, qtype arg1, qtype arg2) = funcExt0; \ SUBST_IF_EXT1(funcExt1); \ pfn = p; \ return (*pfn)(arg0, arg1, arg2); \ } \ static CONST VECTOR_CC qtype (*pfn)(qtype arg0, qtype arg1, qtype arg2) = dfn; \ EXPORT CONST VECTOR_CC qtype funcName(qtype arg0, qtype arg1, qtype arg2) { return (*pfn)(arg0, arg1, arg2); } #define DISPATCH_vq_vq_vx(qtype, xtype, funcName, pfn, dfn, funcExt0, funcExt1) \ static CONST VECTOR_CC qtype (*pfn)(qtype arg0, xtype arg1); \ static CONST VECTOR_CC qtype dfn(qtype arg0, xtype arg1) { \ qtype CONST VECTOR_CC (*p)(qtype arg0, xtype arg1) = funcExt0; \ SUBST_IF_EXT1(funcExt1); \ pfn = p; \ return (*pfn)(arg0, arg1); \ } \ static CONST VECTOR_CC qtype (*pfn)(qtype arg0, xtype arg1) = dfn; \ EXPORT CONST VECTOR_CC qtype funcName(qtype arg0, xtype arg1) { return (*pfn)(arg0, arg1); } #define DISPATCH_vq_vq_pvx(qtype, xtype, funcName, pfn, dfn, funcExt0, funcExt1) \ static VECTOR_CC qtype (*pfn)(qtype arg0, xtype *arg1); \ static VECTOR_CC qtype dfn(qtype arg0, xtype *arg1) { \ qtype VECTOR_CC (*p)(qtype arg0, xtype *arg1) = funcExt0; \ SUBST_IF_EXT1(funcExt1); \ pfn = p; \ return (*pfn)(arg0, arg1); \ } \ static VECTOR_CC qtype (*pfn)(qtype arg0, xtype *arg1) = dfn; \ EXPORT VECTOR_CC qtype funcName(qtype arg0, xtype *arg1) { return (*pfn)(arg0, arg1); } #define DISPATCH_vq_vx(qtype, xtype, funcName, pfn, dfn, funcExt0, funcExt1) \ static CONST VECTOR_CC qtype (*pfn)(xtype arg0); \ static CONST VECTOR_CC qtype dfn(xtype arg0) { \ qtype CONST VECTOR_CC (*p)(xtype arg0) = funcExt0; \ SUBST_IF_EXT1(funcExt1); \ pfn = p; \ return (*pfn)(arg0); \ } \ static CONST VECTOR_CC qtype (*pfn)(xtype arg0) = dfn; \ EXPORT CONST VECTOR_CC qtype funcName(xtype arg0) { return (*pfn)(arg0); } #define DISPATCH_vx_vq(qtype, xtype, funcName, pfn, dfn, funcExt0, funcExt1) \ static CONST VECTOR_CC xtype (*pfn)(qtype arg0); \ static CONST VECTOR_CC xtype dfn(qtype arg0) { \ xtype CONST VECTOR_CC (*p)(qtype arg0) = funcExt0; \ SUBST_IF_EXT1(funcExt1); \ pfn = p; \ return (*pfn)(arg0); \ } \ static CONST VECTOR_CC xtype (*pfn)(qtype arg0) = dfn; \ EXPORT CONST VECTOR_CC xtype funcName(qtype arg0) { return (*pfn)(arg0); } #define DISPATCH_vx_vq_vq(qtype, xtype, funcName, pfn, dfn, funcExt0, funcExt1) \ static CONST VECTOR_CC xtype (*pfn)(qtype arg0, qtype arg1); \ static CONST VECTOR_CC xtype dfn(qtype arg0, qtype arg1) { \ xtype CONST VECTOR_CC (*p)(qtype arg0, qtype arg1) = funcExt0; \ SUBST_IF_EXT1(funcExt1); \ pfn = p; \ return (*pfn)(arg0, arg1); \ } \ static CONST VECTOR_CC xtype (*pfn)(qtype arg0, qtype arg1) = dfn; \ EXPORT CONST VECTOR_CC xtype funcName(qtype arg0, qtype arg1) { return (*pfn)(arg0, arg1); } #define DISPATCH_q_vq_vx(qtype, xtype, funcName, pfn, dfn, funcExt0, funcExt1) \ static CONST VECTOR_CC Sleef_quad (*pfn)(qtype arg0, xtype arg1); \ static CONST VECTOR_CC Sleef_quad dfn(qtype arg0, xtype arg1) { \ Sleef_quad CONST VECTOR_CC (*p)(qtype arg0, xtype arg1) = funcExt0; \ SUBST_IF_EXT1(funcExt1); \ pfn = p; \ return (*pfn)(arg0, arg1); \ } \ static CONST VECTOR_CC Sleef_quad (*pfn)(qtype arg0, xtype arg1) = dfn; \ EXPORT CONST VECTOR_CC Sleef_quad funcName(qtype arg0, xtype arg1) { return (*pfn)(arg0, arg1); } #define DISPATCH_vq_vq_vi_q(qtype, xtype, funcName, pfn, dfn, funcExt0, funcExt1) \ static CONST VECTOR_CC qtype (*pfn)(qtype arg0, xtype arg1, Sleef_quad arg2); \ static CONST VECTOR_CC qtype dfn(qtype arg0, xtype arg1, Sleef_quad arg2) { \ qtype CONST VECTOR_CC (*p)(qtype arg0, xtype arg1, Sleef_quad arg2) = funcExt0; \ SUBST_IF_EXT1(funcExt1); \ pfn = p; \ return (*pfn)(arg0, arg1, arg2); \ } \ static CONST VECTOR_CC qtype (*pfn)(qtype arg0, xtype arg1, Sleef_quad arg2) = dfn; \ EXPORT CONST VECTOR_CC qtype funcName(qtype arg0, xtype arg1, Sleef_quad arg2) { return (*pfn)(arg0, arg1, arg2); } //