blob: 0fbeb74fa01e8fd52e9fa0a312e3c0f4db139cb9 [file] [edit]
//===----------------------------------------------------------------------===//
//
// 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