1//===-- Compile time cpu feature detection ----------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8// This file lists target cpu features by introspecting compiler enabled
9// preprocessor definitions.
10//===----------------------------------------------------------------------===//
11
12#ifndef LLVM_LIBC_SRC___SUPPORT_MACROS_PROPERTIES_CPU_FEATURES_H
13#define LLVM_LIBC_SRC___SUPPORT_MACROS_PROPERTIES_CPU_FEATURES_H
14
15#include "architectures.h"
16
17#if defined(__ARM_FEATURE_FP16_SCALAR_ARITHMETIC)
18#define LIBC_TARGET_CPU_HAS_FULLFP16
19#endif
20
21#if defined(__ARM_FEATURE_SVE)
22#define LIBC_TARGET_CPU_HAS_SVE
23#endif
24
25#if defined(__ARM_FEATURE_SVE2)
26#define LIBC_TARGET_CPU_HAS_SVE2
27#endif
28
29// __ARM_FEATURE_MVE is a bitfield
30#if defined(__ARM_FEATURE_MVE)
31#if (__ARM_FEATURE_MVE & 0x1)
32#define LIBC_TARGET_CPU_HAS_MVE
33#endif // LIBC_TARGET_CPU_HAS_MVE
34#if (__ARM_FEATURE_MVE & 0x2)
35#define LIBC_TARGET_CPU_HAS_MVE_FP
36#endif // LIBC_TARGET_CPU_HAS_MVE_FP
37#endif // __ARM_FEATURE_MVE
38
39#if defined(__ARM_FEATURE_MOPS)
40#define LIBC_TARGET_CPU_HAS_MOPS
41#endif
42
43#if defined(__SSE2__)
44#define LIBC_TARGET_CPU_HAS_SSE2
45#define LIBC_TARGET_CPU_HAS_FPU_FLOAT
46#define LIBC_TARGET_CPU_HAS_FPU_DOUBLE
47#define LIBC_TARGET_CPU_GENERIC_VECTOR_SIZE_MAX 128
48#endif
49
50#if defined(__SSE4_2__)
51#define LIBC_TARGET_CPU_HAS_SSE4_2
52#endif
53
54#if defined(__AVX__)
55#define LIBC_TARGET_CPU_HAS_AVX
56#undef LIBC_TARGET_CPU_GENERIC_VECTOR_SIZE_MAX
57#define LIBC_TARGET_CPU_GENERIC_VECTOR_SIZE_MAX 256
58#endif
59
60#if defined(__AVX2__)
61#define LIBC_TARGET_CPU_HAS_AVX2
62#endif
63
64#if defined(__AVX512F__)
65#define LIBC_TARGET_CPU_HAS_AVX512F
66#undef LIBC_TARGET_CPU_GENERIC_VECTOR_SIZE_MAX
67#define LIBC_TARGET_CPU_GENERIC_VECTOR_SIZE_MAX 512
68#endif
69
70#if defined(__AVX512BW__)
71#define LIBC_TARGET_CPU_HAS_AVX512BW
72#endif
73
74#if defined(__AVX512F__) || defined(__AVX2__)
75#define LIBC_TARGET_CPU_HAS_GATHER
76#endif
77
78#if defined(__ARM_FP)
79#if (__ARM_FP & 0x2)
80#define LIBC_TARGET_CPU_HAS_ARM_FPU_HALF
81#define LIBC_TARGET_CPU_HAS_FPU_HALF
82#endif // LIBC_TARGET_CPU_HAS_ARM_FPU_HALF
83#if (__ARM_FP & 0x4)
84#define LIBC_TARGET_CPU_HAS_ARM_FPU_FLOAT
85#define LIBC_TARGET_CPU_HAS_FPU_FLOAT
86#endif // LIBC_TARGET_CPU_HAS_ARM_FPU_FLOAT
87#if (__ARM_FP & 0x8)
88#define LIBC_TARGET_CPU_HAS_ARM_FPU_DOUBLE
89#define LIBC_TARGET_CPU_HAS_FPU_DOUBLE
90#endif // LIBC_TARGET_CPU_HAS_ARM_FPU_DOUBLE
91#endif // __ARM_FP
92
93#if defined(__ARM_NEON)
94#define LIBC_TARGET_CPU_HAS_ARM_NEON
95#define LIBC_TARGET_CPU_GENERIC_VECTOR_SIZE_MAX 512
96#endif
97
98#if defined(__riscv_flen)
99// https://github.com/riscv-non-isa/riscv-c-api-doc/blob/main/src/c-api.adoc
100#if defined(__riscv_zfhmin)
101#define LIBC_TARGET_CPU_HAS_RISCV_FPU_HALF
102#define LIBC_TARGET_CPU_HAS_FPU_HALF
103#endif // LIBC_TARGET_CPU_HAS_RISCV_FPU_HALF
104#if (__riscv_flen >= 32)
105#define LIBC_TARGET_CPU_HAS_RISCV_FPU_FLOAT
106#define LIBC_TARGET_CPU_HAS_FPU_FLOAT
107#endif // LIBC_TARGET_CPU_HAS_RISCV_FPU_FLOAT
108#if (__riscv_flen >= 64)
109#define LIBC_TARGET_CPU_HAS_RISCV_FPU_DOUBLE
110#define LIBC_TARGET_CPU_HAS_FPU_DOUBLE
111#endif // LIBC_TARGET_CPU_HAS_RISCV_FPU_DOUBLE
112#endif // __riscv_flen
113
114#if defined(__riscv_v_min_vlen)
115#define LIBC_TARGET_CPU_GENERIC_VECTOR_SIZE_MAX __riscv_v_min_vlen
116#endif // __riscv_v_min_vlen
117
118#if defined(__NVPTX__) || defined(__AMDGPU__) || defined(__SPIRV__)
119#define LIBC_TARGET_CPU_HAS_FPU_FLOAT
120#define LIBC_TARGET_CPU_HAS_FPU_DOUBLE
121#endif
122
123#if defined(__ARM_FEATURE_FMA) || (defined(__AVX2__) && defined(__FMA__)) || \
124 defined(__NVPTX__) || defined(__AMDGPU__) || defined(__riscv_flen) || \
125 defined(__SPIRV__)
126#define LIBC_TARGET_CPU_HAS_FMA
127// Provide a more fine-grained control of FMA instruction for ARM targets.
128#if defined(LIBC_TARGET_CPU_HAS_FPU_HALF)
129#define LIBC_TARGET_CPU_HAS_FMA_HALF
130#endif // LIBC_TARGET_CPU_HAS_FMA_HALF
131#if defined(LIBC_TARGET_CPU_HAS_FPU_FLOAT)
132#define LIBC_TARGET_CPU_HAS_FMA_FLOAT
133#endif // LIBC_TARGET_CPU_HAS_FMA_FLOAT
134#if defined(LIBC_TARGET_CPU_HAS_FPU_DOUBLE)
135#define LIBC_TARGET_CPU_HAS_FMA_DOUBLE
136#endif // LIBC_TARGET_CPU_HAS_FMA_DOUBLE
137#endif
138
139#if defined(LIBC_TARGET_ARCH_IS_AARCH64) || \
140 (defined(LIBC_TARGET_ARCH_IS_X86_64) && \
141 defined(LIBC_TARGET_CPU_HAS_SSE4_2))
142#define LIBC_TARGET_CPU_HAS_NEAREST_INT
143#endif
144
145#if defined(LIBC_TARGET_ARCH_IS_AARCH64) || defined(LIBC_TARGET_ARCH_IS_GPU)
146#define LIBC_TARGET_CPU_HAS_FAST_FLOAT16_OPS
147#endif
148
149#endif // LLVM_LIBC_SRC___SUPPORT_MACROS_PROPERTIES_CPU_FEATURES_H
150