1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #pragma once 18 19 #include <stdlib.h> 20 21 #include <array> 22 #include <initializer_list> 23 #include <set> 24 #include <string> 25 26 enum class Arch : size_t { 27 arm = 0, 28 arm64, 29 mips, 30 mips64, 31 x86, 32 x86_64, 33 }; 34 35 std::string to_string(const Arch& arch); 36 Arch arch_from_string(const std::string& name); 37 38 template <typename T> 39 class ArchMapIterator; 40 41 template <typename T> 42 class ArchMap { 43 public: ArchMap()44 ArchMap() { 45 } 46 ArchMap(std::initializer_list<std::pair<Arch,T>> initializer)47 ArchMap(std::initializer_list<std::pair<Arch, T>> initializer) { 48 for (auto& pair : initializer) { 49 this->operator[](pair.first) = pair.second; 50 } 51 } 52 53 T& operator[](Arch arch) { 54 return data_[size_t(arch)]; 55 } 56 57 const T& operator[](Arch arch) const { 58 return data_[size_t(arch)]; 59 } 60 61 bool operator==(const ArchMap& other) const { 62 for (size_t i = 0; i < data_.size(); ++i) { 63 if (data_[i] != other.data_[i]) { 64 return false; 65 } 66 } 67 return true; 68 } 69 begin()70 ArchMapIterator<T> begin() const { 71 return ArchMapIterator<T>(*this, Arch::arm); 72 } 73 end()74 ArchMapIterator<T> end() const { 75 return ArchMapIterator<T>(*this, Arch(size_t(Arch::x86_64) + 1)); 76 } 77 78 private: 79 std::array<T, size_t(Arch::x86_64) + 1> data_ = {}; 80 }; 81 82 template <typename T> 83 class ArchMapIterator { 84 const ArchMap<T>& map_; 85 Arch arch_ = Arch::arm; 86 87 public: 88 ArchMapIterator() = delete; 89 ArchMapIterator(const ArchMap<T> & map,Arch arch)90 ArchMapIterator(const ArchMap<T>& map, Arch arch) : map_(map), arch_(arch) { 91 } 92 93 bool operator==(const ArchMapIterator<T>& rhs) const { 94 return map_ == rhs.map_ && arch_ == rhs.arch_; 95 } 96 97 bool operator!=(const ArchMapIterator<T>& rhs) const { 98 return !(*this == rhs); 99 } 100 101 ArchMapIterator& operator++() { 102 arch_ = Arch(size_t(arch_) + 1); 103 return *this; 104 } 105 106 ArchMapIterator operator++(int) { 107 ArchMapIterator result = *this; 108 ++*this; 109 return result; 110 } 111 112 std::pair<const Arch&, const T&> operator*() const { 113 return std::tie(arch_, map_[arch_]); 114 } 115 116 std::pair<const Arch&, const T&> operator->() const { 117 return std::tie(arch_, map_[arch_]); 118 } 119 }; 120 121 static const std::set<Arch> supported_archs = { 122 Arch::arm, 123 Arch::arm64, 124 Arch::mips, 125 Arch::mips64, 126 Arch::x86, 127 Arch::x86_64, 128 }; 129 130 static ArchMap<std::string> arch_targets = { 131 { Arch::arm, "arm-linux-androideabi" }, 132 { Arch::arm64, "aarch64-linux-android" }, 133 { Arch::mips, "mipsel-linux-android" }, 134 { Arch::mips64, "mips64el-linux-android" }, 135 { Arch::x86, "i686-linux-android" }, 136 { Arch::x86_64, "x86_64-linux-android" }, 137 }; 138 139 static const std::set<int> supported_levels = { 9, 12, 13, 14, 15, 16, 17, 18, 19, 21, 23, 24 }; 140 141 static const ArchMap<int> arch_min_api = { 142 { Arch::arm, 9 }, 143 { Arch::arm64, 21 }, 144 { Arch::mips, 9 }, 145 { Arch::mips64, 21 }, 146 { Arch::x86, 9 }, 147 { Arch::x86_64, 21 }, 148 }; 149