/*
 * 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.
 */

#include "instruction_set_features.h"

#include <algorithm>
#include <ostream>

#include "android-base/strings.h"
#include "arm/instruction_set_features_arm.h"
#include "arm64/instruction_set_features_arm64.h"
#include "base/casts.h"
#include "base/utils.h"
#include "riscv64/instruction_set_features_riscv64.h"
#include "x86/instruction_set_features_x86.h"
#include "x86_64/instruction_set_features_x86_64.h"

namespace art HIDDEN {

std::unique_ptr<const InstructionSetFeatures> InstructionSetFeatures::FromVariant(
    InstructionSet isa, const std::string& variant, std::string* error_msg) {
  switch (isa) {
    case InstructionSet::kArm:
    case InstructionSet::kThumb2:
      return ArmInstructionSetFeatures::FromVariant(variant, error_msg);
    case InstructionSet::kArm64:
      return Arm64InstructionSetFeatures::FromVariant(variant, error_msg);
    case InstructionSet::kRiscv64:
      return Riscv64InstructionSetFeatures::FromVariant(variant, error_msg);
    case InstructionSet::kX86:
      return X86InstructionSetFeatures::FromVariant(variant, error_msg);
    case InstructionSet::kX86_64:
      return X86_64InstructionSetFeatures::FromVariant(variant, error_msg);

    default:
      break;
  }
  UNIMPLEMENTED(FATAL) << isa;
  UNREACHABLE();
}

std::unique_ptr<const InstructionSetFeatures> InstructionSetFeatures::FromVariantAndHwcap(
    InstructionSet isa, const std::string& variant, std::string* error_msg) {
  auto variant_features = FromVariant(isa, variant, error_msg);
  if (variant_features == nullptr) {
    return nullptr;
  }
  // Pixel3a is wrongly reporting itself as cortex-a75, so validate the features
  // with hwcaps.
  // Note that when cross-compiling on device (using dex2oat32 for compiling
  // arm64), the hwcaps will report that no feature is supported. This is
  // currently our best approach to be safe/correct. Maybe using the
  // cpu_features library could fix this issue.
  if (isa == InstructionSet::kArm64) {
    auto new_features = down_cast<const Arm64InstructionSetFeatures*>(variant_features.get())
        ->IntersectWithHwcap();
    if (!variant_features->Equals(new_features.get())) {
      LOG(WARNING) << "Mismatch between instruction set variant of device ("
            << *variant_features
            << ") and features returned by the hardware (" << *new_features << ")";
    }
    return new_features;
  } else {
    // TODO: Implement this validation on all architectures.
    return variant_features;
  }
}

std::unique_ptr<const InstructionSetFeatures> InstructionSetFeatures::FromBitmap(InstructionSet isa,
                                                                                 uint32_t bitmap) {
  std::unique_ptr<const InstructionSetFeatures> result;
  switch (isa) {
    case InstructionSet::kArm:
    case InstructionSet::kThumb2:
      result = ArmInstructionSetFeatures::FromBitmap(bitmap);
      break;
    case InstructionSet::kArm64:
      result = Arm64InstructionSetFeatures::FromBitmap(bitmap);
      break;
    case InstructionSet::kRiscv64:
      result = Riscv64InstructionSetFeatures::FromBitmap(bitmap);
      break;
    case InstructionSet::kX86:
      result = X86InstructionSetFeatures::FromBitmap(bitmap);
      break;
    case InstructionSet::kX86_64:
      result = X86_64InstructionSetFeatures::FromBitmap(bitmap);
      break;

    default:
      UNIMPLEMENTED(FATAL) << isa;
      UNREACHABLE();
  }
  CHECK_EQ(bitmap, result->AsBitmap());
  return result;
}

std::unique_ptr<const InstructionSetFeatures> InstructionSetFeatures::FromCppDefines() {
  switch (kRuntimeISA) {
    case InstructionSet::kArm:
    case InstructionSet::kThumb2:
      return ArmInstructionSetFeatures::FromCppDefines();
    case InstructionSet::kArm64:
      return Arm64InstructionSetFeatures::FromCppDefines();
    case InstructionSet::kRiscv64:
      return Riscv64InstructionSetFeatures::FromCppDefines();
    case InstructionSet::kX86:
      return X86InstructionSetFeatures::FromCppDefines();
    case InstructionSet::kX86_64:
      return X86_64InstructionSetFeatures::FromCppDefines();

    default:
      break;
  }
  UNIMPLEMENTED(FATAL) << kRuntimeISA;
  UNREACHABLE();
}

std::unique_ptr<const InstructionSetFeatures> InstructionSetFeatures::FromRuntimeDetection() {
  switch (kRuntimeISA) {
#ifdef ART_TARGET_ANDROID
    case InstructionSet::kArm64:
      return Arm64InstructionSetFeatures::FromHwcap();
#endif
    default:
      return nullptr;
  }
}

std::unique_ptr<const InstructionSetFeatures> InstructionSetFeatures::FromCpuInfo() {
  switch (kRuntimeISA) {
    case InstructionSet::kArm:
    case InstructionSet::kThumb2:
      return ArmInstructionSetFeatures::FromCpuInfo();
    case InstructionSet::kArm64:
      return Arm64InstructionSetFeatures::FromCpuInfo();
    case InstructionSet::kRiscv64:
      return Riscv64InstructionSetFeatures::FromCpuInfo();
    case InstructionSet::kX86:
      return X86InstructionSetFeatures::FromCpuInfo();
    case InstructionSet::kX86_64:
      return X86_64InstructionSetFeatures::FromCpuInfo();

    default:
      break;
  }
  UNIMPLEMENTED(FATAL) << kRuntimeISA;
  UNREACHABLE();
}

std::unique_ptr<const InstructionSetFeatures> InstructionSetFeatures::FromHwcap() {
  switch (kRuntimeISA) {
    case InstructionSet::kArm:
    case InstructionSet::kThumb2:
      return ArmInstructionSetFeatures::FromHwcap();
    case InstructionSet::kArm64:
      return Arm64InstructionSetFeatures::FromHwcap();
    case InstructionSet::kRiscv64:
      return Riscv64InstructionSetFeatures::FromHwcap();
    case InstructionSet::kX86:
      return X86InstructionSetFeatures::FromHwcap();
    case InstructionSet::kX86_64:
      return X86_64InstructionSetFeatures::FromHwcap();

    default:
      break;
  }
  UNIMPLEMENTED(FATAL) << kRuntimeISA;
  UNREACHABLE();
}

std::unique_ptr<const InstructionSetFeatures> InstructionSetFeatures::FromAssembly() {
  switch (kRuntimeISA) {
    case InstructionSet::kArm:
    case InstructionSet::kThumb2:
      return ArmInstructionSetFeatures::FromAssembly();
    case InstructionSet::kArm64:
      return Arm64InstructionSetFeatures::FromAssembly();
    case InstructionSet::kRiscv64:
      return Riscv64InstructionSetFeatures::FromAssembly();
    case InstructionSet::kX86:
      return X86InstructionSetFeatures::FromAssembly();
    case InstructionSet::kX86_64:
      return X86_64InstructionSetFeatures::FromAssembly();

    default:
      break;
  }
  UNIMPLEMENTED(FATAL) << kRuntimeISA;
  UNREACHABLE();
}

std::unique_ptr<const InstructionSetFeatures> InstructionSetFeatures::FromCpuFeatures() {
  switch (kRuntimeISA) {
    case InstructionSet::kArm:
    case InstructionSet::kThumb2:
      return ArmInstructionSetFeatures::FromCpuFeatures();
    case InstructionSet::kArm64:
      return Arm64InstructionSetFeatures::FromCpuFeatures();
    case InstructionSet::kRiscv64:
      return Riscv64InstructionSetFeatures::FromCpuFeatures();
    case InstructionSet::kX86:
      return X86InstructionSetFeatures::FromCpuFeatures();
    case InstructionSet::kX86_64:
      return X86_64InstructionSetFeatures::FromCpuFeatures();

    default:
      break;
  }
  UNIMPLEMENTED(FATAL) << kRuntimeISA;
  UNREACHABLE();
}

std::unique_ptr<const InstructionSetFeatures> InstructionSetFeatures::AddFeaturesFromString(
    const std::string& feature_list, /* out */ std::string* error_msg) const {
  std::vector<std::string> features;
  Split(feature_list, ',', &features);
  std::transform(std::begin(features), std::end(features), std::begin(features),
                 [](const std::string &s) { return android::base::Trim(s); });
  auto empty_strings_begin = std::copy_if(std::begin(features), std::end(features),
                                          std::begin(features),
                                          [](const std::string& s) { return !s.empty(); });
  features.erase(empty_strings_begin, std::end(features));
  if (features.empty()) {
    *error_msg = "No instruction set features specified";
    return nullptr;
  }

  bool use_default = false;
  bool use_runtime_detection = false;
  for (const std::string& feature : features) {
    if (feature == "default") {
      if (features.size() > 1) {
        *error_msg = "Specific instruction set feature(s) cannot be used when 'default' is used.";
        return nullptr;
      }
      use_default = true;
      features.pop_back();
      break;
    } else if (feature == "runtime") {
      if (features.size() > 1) {
        *error_msg = "Specific instruction set feature(s) cannot be used when 'runtime' is used.";
        return nullptr;
      }
      use_runtime_detection = true;
      features.pop_back();
      break;
    }
  }
  // Expectation: "default" and "runtime" are standalone, no other feature names.
  // But an empty features vector after processing can also come along if the
  // handled feature names  are the only ones in the list. So
  // logically, we check "default or runtime => features.empty."
  DCHECK((!use_default && !use_runtime_detection) || features.empty());

  std::unique_ptr<const InstructionSetFeatures> runtime_detected_features;
  if (use_runtime_detection) {
    runtime_detected_features = FromRuntimeDetection();
  }

  if (runtime_detected_features != nullptr) {
    return AddRuntimeDetectedFeatures(runtime_detected_features.get());
  } else {
    return AddFeaturesFromSplitString(features, error_msg);
  }
}

const ArmInstructionSetFeatures* InstructionSetFeatures::AsArmInstructionSetFeatures() const {
  DCHECK_EQ(InstructionSet::kArm, GetInstructionSet());
  return down_cast<const ArmInstructionSetFeatures*>(this);
}

const Arm64InstructionSetFeatures* InstructionSetFeatures::AsArm64InstructionSetFeatures() const {
  DCHECK_EQ(InstructionSet::kArm64, GetInstructionSet());
  return down_cast<const Arm64InstructionSetFeatures*>(this);
}

const Riscv64InstructionSetFeatures* InstructionSetFeatures::AsRiscv64InstructionSetFeatures()
    const {
  DCHECK_EQ(InstructionSet::kRiscv64, GetInstructionSet());
  return down_cast<const Riscv64InstructionSetFeatures*>(this);
}

const X86InstructionSetFeatures* InstructionSetFeatures::AsX86InstructionSetFeatures() const {
  DCHECK(InstructionSet::kX86 == GetInstructionSet() ||
         InstructionSet::kX86_64 == GetInstructionSet());
  return down_cast<const X86InstructionSetFeatures*>(this);
}

const X86_64InstructionSetFeatures* InstructionSetFeatures::AsX86_64InstructionSetFeatures() const {
  DCHECK_EQ(InstructionSet::kX86_64, GetInstructionSet());
  return down_cast<const X86_64InstructionSetFeatures*>(this);
}

bool InstructionSetFeatures::FindVariantInArray(const char* const variants[], size_t num_variants,
                                                const std::string& variant) {
  const char* const * begin = variants;
  const char* const * end = begin + num_variants;
  return std::find(begin, end, variant) != end;
}

std::unique_ptr<const InstructionSetFeatures> InstructionSetFeatures::AddRuntimeDetectedFeatures(
    [[maybe_unused]] const InstructionSetFeatures* features) const {
  UNIMPLEMENTED(FATAL) << kRuntimeISA;
  UNREACHABLE();
}

std::ostream& operator<<(std::ostream& os, const InstructionSetFeatures& rhs) {
  os << "ISA: " << rhs.GetInstructionSet() << " Feature string: " << rhs.GetFeatureString();
  return os;
}

}  // namespace art
