11cb0ef41Sopenharmony_ci// Copyright 2018 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#ifndef V8_CODEGEN_CPU_FEATURES_H_
61cb0ef41Sopenharmony_ci#define V8_CODEGEN_CPU_FEATURES_H_
71cb0ef41Sopenharmony_ci
81cb0ef41Sopenharmony_ci#include "src/common/globals.h"
91cb0ef41Sopenharmony_ci
101cb0ef41Sopenharmony_cinamespace v8 {
111cb0ef41Sopenharmony_ci
121cb0ef41Sopenharmony_cinamespace internal {
131cb0ef41Sopenharmony_ci
141cb0ef41Sopenharmony_ci// CPU feature flags.
151cb0ef41Sopenharmony_cienum CpuFeature {
161cb0ef41Sopenharmony_ci#if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X64
171cb0ef41Sopenharmony_ci  SSE4_2,
181cb0ef41Sopenharmony_ci  SSE4_1,
191cb0ef41Sopenharmony_ci  SSSE3,
201cb0ef41Sopenharmony_ci  SSE3,
211cb0ef41Sopenharmony_ci  SAHF,
221cb0ef41Sopenharmony_ci  AVX,
231cb0ef41Sopenharmony_ci  AVX2,
241cb0ef41Sopenharmony_ci  FMA3,
251cb0ef41Sopenharmony_ci  BMI1,
261cb0ef41Sopenharmony_ci  BMI2,
271cb0ef41Sopenharmony_ci  LZCNT,
281cb0ef41Sopenharmony_ci  POPCNT,
291cb0ef41Sopenharmony_ci  INTEL_ATOM,
301cb0ef41Sopenharmony_ci  CETSS,
311cb0ef41Sopenharmony_ci
321cb0ef41Sopenharmony_ci#elif V8_TARGET_ARCH_ARM
331cb0ef41Sopenharmony_ci  // - Standard configurations. The baseline is ARMv6+VFPv2.
341cb0ef41Sopenharmony_ci  ARMv7,        // ARMv7-A + VFPv3-D32 + NEON
351cb0ef41Sopenharmony_ci  ARMv7_SUDIV,  // ARMv7-A + VFPv4-D32 + NEON + SUDIV
361cb0ef41Sopenharmony_ci  ARMv8,        // ARMv8-A (+ all of the above)
371cb0ef41Sopenharmony_ci
381cb0ef41Sopenharmony_ci  // ARM feature aliases (based on the standard configurations above).
391cb0ef41Sopenharmony_ci  VFPv3 = ARMv7,
401cb0ef41Sopenharmony_ci  NEON = ARMv7,
411cb0ef41Sopenharmony_ci  VFP32DREGS = ARMv7,
421cb0ef41Sopenharmony_ci  SUDIV = ARMv7_SUDIV,
431cb0ef41Sopenharmony_ci
441cb0ef41Sopenharmony_ci#elif V8_TARGET_ARCH_ARM64
451cb0ef41Sopenharmony_ci  JSCVT,
461cb0ef41Sopenharmony_ci
471cb0ef41Sopenharmony_ci#elif V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64
481cb0ef41Sopenharmony_ci  FPU,
491cb0ef41Sopenharmony_ci  FP64FPU,
501cb0ef41Sopenharmony_ci  MIPSr1,
511cb0ef41Sopenharmony_ci  MIPSr2,
521cb0ef41Sopenharmony_ci  MIPSr6,
531cb0ef41Sopenharmony_ci  MIPS_SIMD,  // MSA instructions
541cb0ef41Sopenharmony_ci
551cb0ef41Sopenharmony_ci#elif V8_TARGET_ARCH_LOONG64
561cb0ef41Sopenharmony_ci  FPU,
571cb0ef41Sopenharmony_ci
581cb0ef41Sopenharmony_ci#elif V8_TARGET_ARCH_PPC || V8_TARGET_ARCH_PPC64
591cb0ef41Sopenharmony_ci  PPC_6_PLUS,
601cb0ef41Sopenharmony_ci  PPC_7_PLUS,
611cb0ef41Sopenharmony_ci  PPC_8_PLUS,
621cb0ef41Sopenharmony_ci  PPC_9_PLUS,
631cb0ef41Sopenharmony_ci  PPC_10_PLUS,
641cb0ef41Sopenharmony_ci
651cb0ef41Sopenharmony_ci#elif V8_TARGET_ARCH_S390X
661cb0ef41Sopenharmony_ci  FPU,
671cb0ef41Sopenharmony_ci  DISTINCT_OPS,
681cb0ef41Sopenharmony_ci  GENERAL_INSTR_EXT,
691cb0ef41Sopenharmony_ci  FLOATING_POINT_EXT,
701cb0ef41Sopenharmony_ci  VECTOR_FACILITY,
711cb0ef41Sopenharmony_ci  VECTOR_ENHANCE_FACILITY_1,
721cb0ef41Sopenharmony_ci  VECTOR_ENHANCE_FACILITY_2,
731cb0ef41Sopenharmony_ci  MISC_INSTR_EXT2,
741cb0ef41Sopenharmony_ci
751cb0ef41Sopenharmony_ci#elif V8_TARGET_ARCH_RISCV64
761cb0ef41Sopenharmony_ci  FPU,
771cb0ef41Sopenharmony_ci  FP64FPU,
781cb0ef41Sopenharmony_ci  RISCV_SIMD,
791cb0ef41Sopenharmony_ci#endif
801cb0ef41Sopenharmony_ci
811cb0ef41Sopenharmony_ci  NUMBER_OF_CPU_FEATURES
821cb0ef41Sopenharmony_ci};
831cb0ef41Sopenharmony_ci
841cb0ef41Sopenharmony_ci// CpuFeatures keeps track of which features are supported by the target CPU.
851cb0ef41Sopenharmony_ci// Supported features must be enabled by a CpuFeatureScope before use.
861cb0ef41Sopenharmony_ci// Example:
871cb0ef41Sopenharmony_ci//   if (assembler->IsSupported(SSE3)) {
881cb0ef41Sopenharmony_ci//     CpuFeatureScope fscope(assembler, SSE3);
891cb0ef41Sopenharmony_ci//     // Generate code containing SSE3 instructions.
901cb0ef41Sopenharmony_ci//   } else {
911cb0ef41Sopenharmony_ci//     // Generate alternative code.
921cb0ef41Sopenharmony_ci//   }
931cb0ef41Sopenharmony_ciclass V8_EXPORT_PRIVATE CpuFeatures : public AllStatic {
941cb0ef41Sopenharmony_ci public:
951cb0ef41Sopenharmony_ci  CpuFeatures(const CpuFeatures&) = delete;
961cb0ef41Sopenharmony_ci  CpuFeatures& operator=(const CpuFeatures&) = delete;
971cb0ef41Sopenharmony_ci
981cb0ef41Sopenharmony_ci  static void Probe(bool cross_compile) {
991cb0ef41Sopenharmony_ci    STATIC_ASSERT(NUMBER_OF_CPU_FEATURES <= kBitsPerInt);
1001cb0ef41Sopenharmony_ci    if (initialized_) return;
1011cb0ef41Sopenharmony_ci    initialized_ = true;
1021cb0ef41Sopenharmony_ci    ProbeImpl(cross_compile);
1031cb0ef41Sopenharmony_ci  }
1041cb0ef41Sopenharmony_ci
1051cb0ef41Sopenharmony_ci  static unsigned SupportedFeatures() {
1061cb0ef41Sopenharmony_ci    Probe(false);
1071cb0ef41Sopenharmony_ci    return supported_;
1081cb0ef41Sopenharmony_ci  }
1091cb0ef41Sopenharmony_ci
1101cb0ef41Sopenharmony_ci  static bool IsSupported(CpuFeature f) {
1111cb0ef41Sopenharmony_ci    return (supported_ & (1u << f)) != 0;
1121cb0ef41Sopenharmony_ci  }
1131cb0ef41Sopenharmony_ci
1141cb0ef41Sopenharmony_ci  static void SetSupported(CpuFeature f) { supported_ |= 1u << f; }
1151cb0ef41Sopenharmony_ci  static void SetUnsupported(CpuFeature f) { supported_ &= ~(1u << f); }
1161cb0ef41Sopenharmony_ci
1171cb0ef41Sopenharmony_ci  static bool SupportsWasmSimd128();
1181cb0ef41Sopenharmony_ci
1191cb0ef41Sopenharmony_ci  static inline bool SupportsOptimizer();
1201cb0ef41Sopenharmony_ci
1211cb0ef41Sopenharmony_ci  static inline unsigned icache_line_size() {
1221cb0ef41Sopenharmony_ci    DCHECK_NE(icache_line_size_, 0);
1231cb0ef41Sopenharmony_ci    return icache_line_size_;
1241cb0ef41Sopenharmony_ci  }
1251cb0ef41Sopenharmony_ci
1261cb0ef41Sopenharmony_ci  static inline unsigned dcache_line_size() {
1271cb0ef41Sopenharmony_ci    DCHECK_NE(dcache_line_size_, 0);
1281cb0ef41Sopenharmony_ci    return dcache_line_size_;
1291cb0ef41Sopenharmony_ci  }
1301cb0ef41Sopenharmony_ci
1311cb0ef41Sopenharmony_ci  static void PrintTarget();
1321cb0ef41Sopenharmony_ci  static void PrintFeatures();
1331cb0ef41Sopenharmony_ci
1341cb0ef41Sopenharmony_ci private:
1351cb0ef41Sopenharmony_ci  friend void V8_EXPORT_PRIVATE FlushInstructionCache(void*, size_t);
1361cb0ef41Sopenharmony_ci  friend class ExternalReference;
1371cb0ef41Sopenharmony_ci  // Flush instruction cache.
1381cb0ef41Sopenharmony_ci  static void FlushICache(void* start, size_t size);
1391cb0ef41Sopenharmony_ci
1401cb0ef41Sopenharmony_ci  // Platform-dependent implementation.
1411cb0ef41Sopenharmony_ci  static void ProbeImpl(bool cross_compile);
1421cb0ef41Sopenharmony_ci
1431cb0ef41Sopenharmony_ci  static unsigned supported_;
1441cb0ef41Sopenharmony_ci  static unsigned icache_line_size_;
1451cb0ef41Sopenharmony_ci  static unsigned dcache_line_size_;
1461cb0ef41Sopenharmony_ci  static bool initialized_;
1471cb0ef41Sopenharmony_ci  // This variable is only used for certain archs to query SupportWasmSimd128()
1481cb0ef41Sopenharmony_ci  // at runtime in builtins using an extern ref. Other callers should use
1491cb0ef41Sopenharmony_ci  // CpuFeatures::SupportWasmSimd128().
1501cb0ef41Sopenharmony_ci  static bool supports_wasm_simd_128_;
1511cb0ef41Sopenharmony_ci  static bool supports_cetss_;
1521cb0ef41Sopenharmony_ci};
1531cb0ef41Sopenharmony_ci
1541cb0ef41Sopenharmony_ci}  // namespace internal
1551cb0ef41Sopenharmony_ci}  // namespace v8
1561cb0ef41Sopenharmony_ci#endif  // V8_CODEGEN_CPU_FEATURES_H_
157