Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Android/art/art/runtime/arch/   (Android Betriebssystem Version 17©)  Datei vom 26.5.2026 mit Größe 11 kB image not shown  

Quelle  instruction_set_features.cc

  Sprache: C
 

/*
 * 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 charconst variants[], size_t num_variants,
                                                const std::string& variant) {
  const charconst * begin = variants;
  const charconst * 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

Messung V0.5 in Prozent
C=90 H=92 G=90

¤ Dauer der Verarbeitung: 0.11 Sekunden  (vorverarbeitet am  2026-06-29) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.