1// Copyright 2018 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef V8_CODEGEN_CPU_FEATURES_H_
6#define V8_CODEGEN_CPU_FEATURES_H_
7
8#include "src/common/globals.h"
9
10namespace v8 {
11
12namespace internal {
13
14// CPU feature flags.
15enum CpuFeature {
16#if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X64
17  SSE4_2,
18  SSE4_1,
19  SSSE3,
20  SSE3,
21  SAHF,
22  AVX,
23  AVX2,
24  FMA3,
25  BMI1,
26  BMI2,
27  LZCNT,
28  POPCNT,
29  INTEL_ATOM,
30  CETSS,
31
32#elif V8_TARGET_ARCH_ARM
33  // - Standard configurations. The baseline is ARMv6+VFPv2.
34  ARMv7,        // ARMv7-A + VFPv3-D32 + NEON
35  ARMv7_SUDIV,  // ARMv7-A + VFPv4-D32 + NEON + SUDIV
36  ARMv8,        // ARMv8-A (+ all of the above)
37
38  // ARM feature aliases (based on the standard configurations above).
39  VFPv3 = ARMv7,
40  NEON = ARMv7,
41  VFP32DREGS = ARMv7,
42  SUDIV = ARMv7_SUDIV,
43
44#elif V8_TARGET_ARCH_ARM64
45  JSCVT,
46
47#elif V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64
48  FPU,
49  FP64FPU,
50  MIPSr1,
51  MIPSr2,
52  MIPSr6,
53  MIPS_SIMD,  // MSA instructions
54
55#elif V8_TARGET_ARCH_LOONG64
56  FPU,
57
58#elif V8_TARGET_ARCH_PPC || V8_TARGET_ARCH_PPC64
59  PPC_6_PLUS,
60  PPC_7_PLUS,
61  PPC_8_PLUS,
62  PPC_9_PLUS,
63  PPC_10_PLUS,
64
65#elif V8_TARGET_ARCH_S390X
66  FPU,
67  DISTINCT_OPS,
68  GENERAL_INSTR_EXT,
69  FLOATING_POINT_EXT,
70  VECTOR_FACILITY,
71  VECTOR_ENHANCE_FACILITY_1,
72  VECTOR_ENHANCE_FACILITY_2,
73  MISC_INSTR_EXT2,
74
75#elif V8_TARGET_ARCH_RISCV64
76  FPU,
77  FP64FPU,
78  RISCV_SIMD,
79#endif
80
81  NUMBER_OF_CPU_FEATURES
82};
83
84// CpuFeatures keeps track of which features are supported by the target CPU.
85// Supported features must be enabled by a CpuFeatureScope before use.
86// Example:
87//   if (assembler->IsSupported(SSE3)) {
88//     CpuFeatureScope fscope(assembler, SSE3);
89//     // Generate code containing SSE3 instructions.
90//   } else {
91//     // Generate alternative code.
92//   }
93class V8_EXPORT_PRIVATE CpuFeatures : public AllStatic {
94 public:
95  CpuFeatures(const CpuFeatures&) = delete;
96  CpuFeatures& operator=(const CpuFeatures&) = delete;
97
98  static void Probe(bool cross_compile) {
99    STATIC_ASSERT(NUMBER_OF_CPU_FEATURES <= kBitsPerInt);
100    if (initialized_) return;
101    initialized_ = true;
102    ProbeImpl(cross_compile);
103  }
104
105  static unsigned SupportedFeatures() {
106    Probe(false);
107    return supported_;
108  }
109
110  static bool IsSupported(CpuFeature f) {
111    return (supported_ & (1u << f)) != 0;
112  }
113
114  static void SetSupported(CpuFeature f) { supported_ |= 1u << f; }
115  static void SetUnsupported(CpuFeature f) { supported_ &= ~(1u << f); }
116
117  static bool SupportsWasmSimd128();
118
119  static inline bool SupportsOptimizer();
120
121  static inline unsigned icache_line_size() {
122    DCHECK_NE(icache_line_size_, 0);
123    return icache_line_size_;
124  }
125
126  static inline unsigned dcache_line_size() {
127    DCHECK_NE(dcache_line_size_, 0);
128    return dcache_line_size_;
129  }
130
131  static void PrintTarget();
132  static void PrintFeatures();
133
134 private:
135  friend void V8_EXPORT_PRIVATE FlushInstructionCache(void*, size_t);
136  friend class ExternalReference;
137  // Flush instruction cache.
138  static void FlushICache(void* start, size_t size);
139
140  // Platform-dependent implementation.
141  static void ProbeImpl(bool cross_compile);
142
143  static unsigned supported_;
144  static unsigned icache_line_size_;
145  static unsigned dcache_line_size_;
146  static bool initialized_;
147  // This variable is only used for certain archs to query SupportWasmSimd128()
148  // at runtime in builtins using an extern ref. Other callers should use
149  // CpuFeatures::SupportWasmSimd128().
150  static bool supports_wasm_simd_128_;
151  static bool supports_cetss_;
152};
153
154}  // namespace internal
155}  // namespace v8
156#endif  // V8_CODEGEN_CPU_FEATURES_H_
157