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