| //===----------------------------------------------------------------------===// | |
| // | |
| // 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 | |
| // | |
| //===----------------------------------------------------------------------===// | |
| /// | |
| /// \file | |
| /// This file contains common utilities for AArch64 optimized mathvec functions. | |
| /// | |
| //===----------------------------------------------------------------------===// | |
| #include "src/__support/CPP/simd.h" | |
| // Type aliases for AdvSIMD vectors. | |
| using AdvSIMDFP32Vector = LIBC_NAMESPACE::cpp::simd<float, 4>; | |
| using AdvSIMDFP64Vector = LIBC_NAMESPACE::cpp::simd<double, 2>; | |
| // Returns the ptr, but hides its value from the compiler so accesses through it | |
| // cannot be optimized based on the contents. | |
| #define PTR_BARRIER(ptr) \ | |
| ({ \ | |
| decltype(ptr) __ptr = (ptr); \ | |
| asm("" : "+r"(__ptr)); \ | |
| __ptr; \ | |
| }) | |
| // Helpers for declaring vector constants containing all lanes the same, in a | |
| // way that varies between little- and big-endian AArch64. Use as follows: | |
| // | |
| // - define a type for the constant using V2_SPLAT_TYPE or V4_SPLAT_TYPE, with | |
| // a type-prefix parameter like `float64` or `int32` which the macro will | |
| // extend into a full scalar or vector type name. | |
| // | |
| // - define the constant using V2_SPLAT_INITIALIZER or V4_SPLAT_INITIALIZER | |
| // | |
| // - to get the actual vector, use MAKE_SPLAT_VECTOR(constant, suffix), where | |
| // 'suffix' is something like `f64` or `u32` which appears in the name of a | |
| // NEON intrinsic to specify its element type. | |
| #if __LITTLE_ENDIAN__ | |
| // Use the gcc language extension of defining a vector using an initializer | |
| // list, which allows the whole vector to be statically defined in const data. | |
| #define V2_SPLAT_TYPE(TYPE_PREFIX) TYPE_PREFIX##x2_t | |
| #define V2_SPLAT_INITIALIZER(LANE) {LANE, LANE} | |
| #define V4_SPLAT_TYPE(TYPE_PREFIX) TYPE_PREFIX##x4_t | |
| #define V4_SPLAT_INITIALIZER(LANE) {LANE, LANE, LANE, LANE} | |
| #define MAKE_SPLAT_VECTOR(VEC, FN_SUFFIX) VEC | |
| #else | |
| // Big-endian, that gcc language extension provokes a compiler diagnostic, so | |
| // instead we store just one copy of the data to be duplicated across lanes, | |
| // and perform the duplication using vdupq when loading it. | |
| #define V2_SPLAT_TYPE(TYPE_PREFIX) TYPE_PREFIX##_t | |
| #define V2_SPLAT_INITIALIZER(LANE) LANE | |
| #define V4_SPLAT_TYPE(TYPE_PREFIX) TYPE_PREFIX##_t | |
| #define V4_SPLAT_INITIALIZER(LANE) LANE | |
| #define MAKE_SPLAT_VECTOR(LANE, FN_SUFFIX) vdupq_n_##FN_SUFFIX(LANE) | |
| #endif |