xref: /freebsd/contrib/llvm-project/llvm/include/llvm/TextAPI/ArchitectureSet.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //===- llvm/TextAPI/ArchitectureSet.h - ArchitectureSet ---------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Defines the architecture set.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef LLVM_TEXTAPI_ARCHITECTURESET_H
14 #define LLVM_TEXTAPI_ARCHITECTURESET_H
15 
16 #include "llvm/Support/Compiler.h"
17 #include "llvm/TextAPI/Architecture.h"
18 #include <cstddef>
19 #include <iterator>
20 #include <limits>
21 #include <string>
22 #include <tuple>
23 #include <vector>
24 
25 namespace llvm {
26 class raw_ostream;
27 
28 namespace MachO {
29 
30 class ArchitectureSet {
31 private:
32   using ArchSetType = uint32_t;
33 
34   const static ArchSetType EndIndexVal =
35       std::numeric_limits<ArchSetType>::max();
36   ArchSetType ArchSet{0};
37 
38 public:
39   constexpr ArchitectureSet() = default;
ArchitectureSet(ArchSetType Raw)40   constexpr ArchitectureSet(ArchSetType Raw) : ArchSet(Raw) {}
ArchitectureSet(Architecture Arch)41   ArchitectureSet(Architecture Arch) : ArchitectureSet() { set(Arch); }
42   LLVM_ABI ArchitectureSet(const std::vector<Architecture> &Archs);
43 
All()44   static ArchitectureSet All() { return ArchitectureSet(EndIndexVal); }
45 
set(Architecture Arch)46   void set(Architecture Arch) {
47     if (Arch == AK_unknown)
48       return;
49     ArchSet |= 1U << static_cast<int>(Arch);
50   }
51 
clear(Architecture Arch)52   ArchitectureSet clear(Architecture Arch) {
53     ArchSet &= ~(1U << static_cast<int>(Arch));
54     return ArchSet;
55   }
56 
has(Architecture Arch)57   bool has(Architecture Arch) const {
58     return ArchSet & (1U << static_cast<int>(Arch));
59   }
60 
contains(ArchitectureSet Archs)61   bool contains(ArchitectureSet Archs) const {
62     return (ArchSet & Archs.ArchSet) == Archs.ArchSet;
63   }
64 
65   LLVM_ABI size_t count() const;
66 
empty()67   bool empty() const { return ArchSet == 0; }
68 
rawValue()69   ArchSetType rawValue() const { return ArchSet; }
70 
hasX86()71   bool hasX86() const {
72     return has(AK_i386) || has(AK_x86_64) || has(AK_x86_64h);
73   }
74 
75   template <typename Ty> class arch_iterator {
76   public:
77     using iterator_category = std::forward_iterator_tag;
78     using value_type = Architecture;
79     using difference_type = std::size_t;
80     using pointer = value_type *;
81     using reference = value_type &;
82 
83   private:
84     ArchSetType Index;
85     Ty *ArchSet;
86 
findNextSetBit()87     void findNextSetBit() {
88       if (Index == EndIndexVal)
89         return;
90       while (++Index < sizeof(Ty) * 8) {
91         if (*ArchSet & (1UL << Index))
92           return;
93       }
94 
95       Index = EndIndexVal;
96     }
97 
98   public:
99     arch_iterator(Ty *ArchSet, ArchSetType Index = 0)
Index(Index)100         : Index(Index), ArchSet(ArchSet) {
101       if (Index != EndIndexVal && !(*ArchSet & (1UL << Index)))
102         findNextSetBit();
103     }
104 
105     Architecture operator*() const { return static_cast<Architecture>(Index); }
106 
107     arch_iterator &operator++() {
108       findNextSetBit();
109       return *this;
110     }
111 
112     arch_iterator operator++(int) {
113       auto tmp = *this;
114       findNextSetBit();
115       return tmp;
116     }
117 
118     bool operator==(const arch_iterator &o) const {
119       return std::tie(Index, ArchSet) == std::tie(o.Index, o.ArchSet);
120     }
121 
122     bool operator!=(const arch_iterator &o) const { return !(*this == o); }
123   };
124 
125   ArchitectureSet operator&(const ArchitectureSet &o) {
126     return {ArchSet & o.ArchSet};
127   }
128 
129   ArchitectureSet operator|(const ArchitectureSet &o) {
130     return {ArchSet | o.ArchSet};
131   }
132 
133   ArchitectureSet &operator|=(const ArchitectureSet &o) {
134     ArchSet |= o.ArchSet;
135     return *this;
136   }
137 
138   ArchitectureSet &operator|=(const Architecture &Arch) {
139     set(Arch);
140     return *this;
141   }
142 
143   bool operator==(const ArchitectureSet &o) const {
144     return ArchSet == o.ArchSet;
145   }
146 
147   bool operator!=(const ArchitectureSet &o) const {
148     return ArchSet != o.ArchSet;
149   }
150 
151   bool operator<(const ArchitectureSet &o) const { return ArchSet < o.ArchSet; }
152 
153   using iterator = arch_iterator<ArchSetType>;
154   using const_iterator = arch_iterator<const ArchSetType>;
155 
begin()156   iterator begin() { return {&ArchSet}; }
end()157   iterator end() { return {&ArchSet, EndIndexVal}; }
158 
begin()159   const_iterator begin() const { return {&ArchSet}; }
end()160   const_iterator end() const { return {&ArchSet, EndIndexVal}; }
161 
162   LLVM_ABI operator std::string() const;
163   LLVM_ABI operator std::vector<Architecture>() const;
164   LLVM_ABI void print(raw_ostream &OS) const;
165 };
166 
167 inline ArchitectureSet operator|(const Architecture &lhs,
168                                  const Architecture &rhs) {
169   return ArchitectureSet(lhs) | ArchitectureSet(rhs);
170 }
171 
172 LLVM_ABI raw_ostream &operator<<(raw_ostream &OS, ArchitectureSet Set);
173 
174 } // end namespace MachO.
175 } // end namespace llvm.
176 
177 #endif // LLVM_TEXTAPI_ARCHITECTURESET_H
178