tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

Cpu-Features-vixl.cpp (5575B)


      1 // Copyright 2018, VIXL authors
      2 // All rights reserved.
      3 //
      4 // Redistribution and use in source and binary forms, with or without
      5 // modification, are permitted provided that the following conditions are met:
      6 //
      7 //   * Redistributions of source code must retain the above copyright notice,
      8 //     this list of conditions and the following disclaimer.
      9 //   * Redistributions in binary form must reproduce the above copyright notice,
     10 //     this list of conditions and the following disclaimer in the documentation
     11 //     and/or other materials provided with the distribution.
     12 //   * Neither the name of ARM Limited nor the names of its contributors may be
     13 //     used to endorse or promote products derived from this software without
     14 //     specific prior written permission.
     15 //
     16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
     17 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     18 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     19 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
     20 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     21 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     22 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
     23 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     24 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26 
     27 
     28 #include "jit/arm64/vixl/Cpu-Features-vixl.h"
     29 
     30 #include <ostream>
     31 
     32 #include "jit/arm64/vixl/Cpu-vixl.h"
     33 #include "jit/arm64/vixl/Globals-vixl.h"
     34 #include "jit/arm64/vixl/Utils-vixl.h"
     35 
     36 // Mozilla change: Don't use VIXL_USE_AARCH64_CPU_HELPERS for the simulator, so
     37 // that we get consistent simulator behavior across architectures.
     38 #if defined(__aarch64__) && !defined(JS_SIMULATOR_ARM64)
     39  #define VIXL_USE_AARCH64_CPU_HELPERS
     40 #endif
     41 
     42 namespace vixl {
     43 
     44 CPUFeatures CPUFeatures::All() {
     45  CPUFeatures all;
     46  all.features_.set();
     47  return all;
     48 }
     49 
     50 CPUFeatures CPUFeatures::InferFromIDRegisters() {
     51  // This function assumes that kIDRegisterEmulation is available.
     52  CPUFeatures features(CPUFeatures::kIDRegisterEmulation);
     53 #ifdef VIXL_USE_AARCH64_CPU_HELPERS
     54  // Note that the Linux kernel filters these values during emulation, so the
     55  // results may not exactly match the expected hardware support.
     56  features.Combine(CPU::InferCPUFeaturesFromIDRegisters());
     57 #endif
     58  return features;
     59 }
     60 
     61 CPUFeatures CPUFeatures::InferFromOS(QueryIDRegistersOption option) {
     62 #ifdef VIXL_USE_AARCH64_CPU_HELPERS
     63  return CPU::InferCPUFeaturesFromOS(option);
     64 #else
     65  USE(option);
     66  return CPUFeatures();
     67 #endif
     68 }
     69 
     70 void CPUFeatures::Combine(const CPUFeatures& other) {
     71  features_ |= other.features_;
     72 }
     73 
     74 void CPUFeatures::Combine(Feature feature) {
     75  if (feature != CPUFeatures::kNone) features_.set(feature);
     76 }
     77 
     78 void CPUFeatures::Remove(const CPUFeatures& other) {
     79  features_ &= ~other.features_;
     80 }
     81 
     82 void CPUFeatures::Remove(Feature feature) {
     83  if (feature != CPUFeatures::kNone) features_.reset(feature);
     84 }
     85 
     86 bool CPUFeatures::Has(const CPUFeatures& other) const {
     87  return (features_ & other.features_) == other.features_;
     88 }
     89 
     90 bool CPUFeatures::Has(Feature feature) const {
     91  return (feature == CPUFeatures::kNone) || features_[feature];
     92 }
     93 
     94 size_t CPUFeatures::Count() const { return features_.count(); }
     95 
     96 std::ostream& operator<<(std::ostream& os, CPUFeatures::Feature feature) {
     97  // clang-format off
     98  switch (feature) {
     99 #define VIXL_FORMAT_FEATURE(SYMBOL, NAME, CPUINFO) \
    100    case CPUFeatures::SYMBOL:                      \
    101      return os << NAME;
    102 VIXL_CPU_FEATURE_LIST(VIXL_FORMAT_FEATURE)
    103 #undef VIXL_FORMAT_FEATURE
    104    case CPUFeatures::kNone:
    105      return os << "none";
    106    case CPUFeatures::kNumberOfFeatures:
    107      VIXL_UNREACHABLE();
    108  }
    109  // clang-format on
    110  VIXL_UNREACHABLE();
    111  return os;
    112 }
    113 
    114 CPUFeatures::const_iterator CPUFeatures::begin() const {
    115  // For iterators in general, it's undefined to increment `end()`, but here we
    116  // control the implementation and it is safe to do this.
    117  return ++end();
    118 }
    119 
    120 CPUFeatures::const_iterator CPUFeatures::end() const {
    121  return const_iterator(this, kNone);
    122 }
    123 
    124 std::ostream& operator<<(std::ostream& os, const CPUFeatures& features) {
    125  bool need_separator = false;
    126  for (CPUFeatures::Feature feature : features) {
    127    if (need_separator) os << ", ";
    128    need_separator = true;
    129    os << feature;
    130  }
    131  return os;
    132 }
    133 
    134 bool CPUFeaturesConstIterator::operator==(
    135    const CPUFeaturesConstIterator& other) const {
    136  VIXL_ASSERT(IsValid());
    137  return (cpu_features_ == other.cpu_features_) && (feature_ == other.feature_);
    138 }
    139 
    140 CPUFeaturesConstIterator& CPUFeaturesConstIterator::operator++() {  // Prefix
    141  VIXL_ASSERT(IsValid());
    142  do {
    143    // Find the next feature. The order is unspecified.
    144    feature_ = static_cast<CPUFeatures::Feature>(feature_ + 1);
    145    if (feature_ == CPUFeatures::kNumberOfFeatures) {
    146      feature_ = CPUFeatures::kNone;
    147      VIXL_STATIC_ASSERT(CPUFeatures::kNone == -1);
    148    }
    149    VIXL_ASSERT(CPUFeatures::kNone <= feature_);
    150    VIXL_ASSERT(feature_ < CPUFeatures::kNumberOfFeatures);
    151    // cpu_features_->Has(kNone) is always true, so this will terminate even if
    152    // the features list is empty.
    153  } while (!cpu_features_->Has(feature_));
    154  return *this;
    155 }
    156 
    157 CPUFeaturesConstIterator CPUFeaturesConstIterator::operator++(int) {  // Postfix
    158  CPUFeaturesConstIterator result = *this;
    159  ++(*this);
    160  return result;
    161 }
    162 
    163 }  // namespace vixl