/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ART_RUNTIME_ARCH_INSTRUCTION_SET_FEATURES_H_
#define ART_RUNTIME_ARCH_INSTRUCTION_SET_FEATURES_H_

#include <iosfwd>
#include <memory>
#include <vector>

#include "arch/instruction_set.h"
#include "base/macros.h"

namespace art HIDDEN {

class ArmInstructionSetFeatures;
class Arm64InstructionSetFeatures;
class Riscv64InstructionSetFeatures;
class X86InstructionSetFeatures;
class X86_64InstructionSetFeatures;

// Abstraction used to describe features of a different instruction sets.
class InstructionSetFeatures {
 public:
  // Process a CPU variant string for the given ISA and create an InstructionSetFeatures.
  EXPORT static std::unique_ptr<const InstructionSetFeatures> FromVariant(
      InstructionSet isa, const std::string& variant, std::string* error_msg);

  // Process a CPU variant string for the given ISA and make sure the features advertised
  // are supported by the hardware. This is needed for Pixel3a which wrongly
  // reports itself as cortex-a75.
  EXPORT static std::unique_ptr<const InstructionSetFeatures> FromVariantAndHwcap(
      InstructionSet isa, const std::string& variant, std::string* error_msg);

  // Parse a bitmap for the given isa and create an InstructionSetFeatures.
  EXPORT static std::unique_ptr<const InstructionSetFeatures> FromBitmap(InstructionSet isa,
                                                                         uint32_t bitmap);

  // Turn C pre-processor #defines into the equivalent instruction set features for kRuntimeISA.
  EXPORT static std::unique_ptr<const InstructionSetFeatures> FromCppDefines();

  // Check if run-time detection of instruction set features is supported.
  //
  // Return: true - if run-time detection is supported on a target device.
  //         false - otherwise
  static bool IsRuntimeDetectionSupported() {
    return FromRuntimeDetection() != nullptr;
  }

  // Use run-time detection to get instruction set features.
  //
  // Return: a set of detected features or nullptr if runtime detection is not
  //         supported on a target.
  static std::unique_ptr<const InstructionSetFeatures> FromRuntimeDetection();

  // Process /proc/cpuinfo and use kRuntimeISA to produce InstructionSetFeatures.
  static std::unique_ptr<const InstructionSetFeatures> FromCpuInfo();

  // Process the auxiliary vector AT_HWCAP entry and use kRuntimeISA to produce
  // InstructionSetFeatures.
  static std::unique_ptr<const InstructionSetFeatures> FromHwcap();

  // Use assembly tests of the current runtime (ie kRuntimeISA) to determine the
  // InstructionSetFeatures. This works around kernel bugs in AT_HWCAP and /proc/cpuinfo.
  static std::unique_ptr<const InstructionSetFeatures> FromAssembly();

  // Use external cpu_features library.
  static std::unique_ptr<const InstructionSetFeatures> FromCpuFeatures();

  // Parse a string of the form "div,-atomic_ldrd_strd" adding and removing these features to
  // create a new InstructionSetFeatures.
  EXPORT std::unique_ptr<const InstructionSetFeatures> AddFeaturesFromString(
      const std::string& feature_list, std::string* error_msg) const WARN_UNUSED;

  // Are these features the same as the other given features?
  virtual bool Equals(const InstructionSetFeatures* other) const = 0;

  // For testing purposes we want to make sure that the system we run on has at
  // least the options we claim it has. In this cases Equals() does not
  // suffice and will cause the test to fail, since the runtime cpu feature
  // detection claims more capabilities then statically specified from the
  // build system.
  //
  // A good example of this is the armv8 ART test target that declares
  // "CPU_VARIANT=generic". If the generic target is specified and the code
  // is run on a platform with enhanced capabilities, the
  // instruction_set_features test will fail if we resort to using Equals()
  // between statically defined cpu features and runtime cpu features.
  //
  // For now we default this to Equals() in case the architecture does not
  // provide it.
  virtual bool HasAtLeast(const InstructionSetFeatures* other) const {
    return Equals(other);
  }

  // Return the ISA these features relate to.
  virtual InstructionSet GetInstructionSet() const = 0;

  // Return a bitmap that represents the features. ISA specific.
  virtual uint32_t AsBitmap() const = 0;

  // Return a string of the form "div,lpae" or "none".
  virtual std::string GetFeatureString() const = 0;

  // Down cast this ArmInstructionFeatures.
  const ArmInstructionSetFeatures* AsArmInstructionSetFeatures() const;

  // Down cast this Arm64InstructionFeatures.
  EXPORT const Arm64InstructionSetFeatures* AsArm64InstructionSetFeatures() const;

  // Down cast this Riscv64InstructionFeatures.
  EXPORT const Riscv64InstructionSetFeatures* AsRiscv64InstructionSetFeatures() const;

  // Down cast this X86InstructionFeatures.
  const X86InstructionSetFeatures* AsX86InstructionSetFeatures() const;

  // Down cast this X86_64InstructionFeatures.
  const X86_64InstructionSetFeatures* AsX86_64InstructionSetFeatures() const;

  virtual ~InstructionSetFeatures() {}

 protected:
  InstructionSetFeatures() {}

  // Returns true if variant appears in the array variants.
  static bool FindVariantInArray(const char* const variants[], size_t num_variants,
                                 const std::string& variant);

  // Add architecture specific features in sub-classes.
  virtual std::unique_ptr<const InstructionSetFeatures>
      AddFeaturesFromSplitString(const std::vector<std::string>& features,
                                 std::string* error_msg) const = 0;

  // Add run-time detected architecture specific features in sub-classes.
  virtual std::unique_ptr<const InstructionSetFeatures> AddRuntimeDetectedFeatures(
      [[maybe_unused]] const InstructionSetFeatures* features) const;

 private:
  DISALLOW_COPY_AND_ASSIGN(InstructionSetFeatures);
};
EXPORT std::ostream& operator<<(std::ostream& os, const InstructionSetFeatures& rhs);

}  // namespace art

#endif  // ART_RUNTIME_ARCH_INSTRUCTION_SET_FEATURES_H_
