llvm.org GIT mirror llvm / 23dd089
Use std::bitset for SubtargetFeatures Previously, subtarget features were a bitfield with the underlying type being uint64_t. Since several targets (X86 and ARM, in particular) have hit or were very close to hitting this bound, switching the features to use a bitset. No functional change. Differential Revision: http://reviews.llvm.org/D7065 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@229831 91177308-0d34-0410-b5e6-96231b3b80d8 Michael Kuperstein 5 years ago
33 changed file(s) with 374 addition(s) and 346 deletion(s). Raw diff Collapse all Expand all
99 #ifndef LLVM_MC_MCINSTPRINTER_H
1010 #define LLVM_MC_MCINSTPRINTER_H
1111
12 #include "llvm/MC/SubtargetFeature.h"
1213 #include "llvm/Support/DataTypes.h"
1314 #include "llvm/Support/Format.h"
1415
4041 const MCRegisterInfo &MRI;
4142
4243 /// The current set of available features.
43 uint64_t AvailableFeatures;
44 FeatureBitset AvailableFeatures;
4445
4546 /// True if we are printing marked up assembly.
4647 bool UseMarkup;
5758 MCInstPrinter(const MCAsmInfo &mai, const MCInstrInfo &mii,
5859 const MCRegisterInfo &mri)
5960 : CommentStream(nullptr), MAI(mai), MII(mii), MRI(mri),
60 AvailableFeatures(0), UseMarkup(0), PrintImmHex(0),
61 AvailableFeatures(), UseMarkup(0), PrintImmHex(0),
6162 PrintHexStyle(HexStyle::C) {}
6263
6364 virtual ~MCInstPrinter();
7778 /// printRegName - Print the assembler register name.
7879 virtual void printRegName(raw_ostream &OS, unsigned RegNo) const;
7980
80 uint64_t getAvailableFeatures() const { return AvailableFeatures; }
81 void setAvailableFeatures(uint64_t Value) { AvailableFeatures = Value; }
81 const FeatureBitset& getAvailableFeatures() const { return AvailableFeatures; }
82 void setAvailableFeatures(const FeatureBitset& Value) { AvailableFeatures = Value; }
8283
8384 bool getUseMarkup() const { return UseMarkup; }
8485 void setUseMarkup(bool Value) { UseMarkup = Value; }
149149 const uint16_t *ImplicitUses; // Registers implicitly read by this instr
150150 const uint16_t *ImplicitDefs; // Registers implicitly defined by this instr
151151 const MCOperandInfo *OpInfo; // 'NumOperands' entries about operands
152 uint64_t DeprecatedFeatureMask;// Feature bits that this is deprecated on, if any
152 FeatureBitset DeprecatedFeatureMask; // Feature bits that this is deprecated on, if any
153153 // A complex method to determine is a certain is deprecated or not, and return
154154 // the reason for deprecation.
155155 bool (*ComplexDeprecationInfo)(MCInst &, MCSubtargetInfo &, std::string &);
172172 std::string &Info) const {
173173 if (ComplexDeprecationInfo)
174174 return ComplexDeprecationInfo(MI, STI, Info);
175 if ((DeprecatedFeatureMask & STI.getFeatureBits()) != 0) {
175 if ((STI.getFeatureBits() & DeprecatedFeatureMask).any()) {
176176 // FIXME: it would be nice to include the subtarget feature here.
177177 Info = "deprecated";
178178 return true;
4141 const InstrStage *Stages; // Instruction itinerary stages
4242 const unsigned *OperandCycles; // Itinerary operand cycles
4343 const unsigned *ForwardingPaths; // Forwarding paths
44 uint64_t FeatureBits; // Feature bits for current CPU + FS
44 FeatureBitset FeatureBits; // Feature bits for current CPU + FS
4545
4646 public:
4747 void InitMCSubtargetInfo(StringRef TT, StringRef CPU, StringRef FS,
6666
6767 /// getFeatureBits - Return the feature bits.
6868 ///
69 uint64_t getFeatureBits() const {
69 const FeatureBitset& getFeatureBits() const {
7070 return FeatureBits;
7171 }
7272
7373 /// setFeatureBits - Set the feature bits.
7474 ///
75 void setFeatureBits(uint64_t FeatureBits_) { FeatureBits = FeatureBits_; }
75 void setFeatureBits(FeatureBitset& FeatureBits_) { FeatureBits = FeatureBits_; }
7676
7777 /// InitMCProcessorInfo - Set or change the CPU (optionally supplemented with
7878 /// feature string). Recompute feature bits and scheduling model.
8383
8484 /// ToggleFeature - Toggle a feature and returns the re-computed feature
8585 /// bits. This version does not change the implied bits.
86 uint64_t ToggleFeature(uint64_t FB);
86 FeatureBitset ToggleFeature(uint64_t FB);
8787
8888 /// ToggleFeature - Toggle a feature and returns the re-computed feature
89 /// bits. This version will also change all implied bits.
90 uint64_t ToggleFeature(StringRef FS);
89 /// bits. This version does not change the implied bits.
90 FeatureBitset ToggleFeature(const FeatureBitset& FB);
91
92 /// ToggleFeature - Toggle a set of features and returns the re-computed
93 /// feature bits. This version will also change all implied bits.
94 FeatureBitset ToggleFeature(StringRef FS);
9195
9296 /// getSchedModelForCPU - Get the machine model of a CPU.
9397 ///
2020 #include "llvm/ADT/ArrayRef.h"
2121 #include "llvm/ADT/Triple.h"
2222 #include "llvm/Support/DataTypes.h"
23 #include
2324
2425 namespace llvm {
2526 class raw_ostream;
2627 class StringRef;
28
29 // A container class for subtarget features.
30 // This is convenient because std::bitset does not have a constructor
31 // with an initializer list of set bits.
32 const unsigned MAX_SUBTARGET_FEATURES = 64;
33 class FeatureBitset : public std::bitset {
34 public:
35 // Cannot inherit constructors because it's not supported by VC++..
36 FeatureBitset() : bitset() {}
37
38 FeatureBitset(const bitset& B) : bitset(B) {}
39
40 FeatureBitset(std::initializer_list Init) : bitset() {
41 for (auto I = Init.begin() , E = Init.end(); I != E; ++I)
42 set(*I);
43 }
44 };
2745
2846 //===----------------------------------------------------------------------===//
2947 ///
3351 struct SubtargetFeatureKV {
3452 const char *Key; // K-V key string
3553 const char *Desc; // Help descriptor
36 uint64_t Value; // K-V integer value
37 uint64_t Implies; // K-V bit mask
54 FeatureBitset Value; // K-V integer value
55 FeatureBitset Implies; // K-V bit mask
3856
3957 // Compare routine for std::lower_bound
4058 bool operator<(StringRef S) const {
8199
82100 /// ToggleFeature - Toggle a feature and returns the newly updated feature
83101 /// bits.
84 uint64_t ToggleFeature(uint64_t Bits, StringRef String,
102 FeatureBitset ToggleFeature(FeatureBitset Bits, StringRef String,
85103 ArrayRef FeatureTable);
86104
87105 /// Get feature bits of a CPU.
88 uint64_t getFeatureBits(StringRef CPU,
106 FeatureBitset getFeatureBits(StringRef CPU,
89107 ArrayRef CPUTable,
90108 ArrayRef FeatureTable);
91109
6262
6363 /// ToggleFeature - Toggle a feature and returns the re-computed feature
6464 /// bits. This version does not change the implied bits.
65 uint64_t MCSubtargetInfo::ToggleFeature(uint64_t FB) {
65 FeatureBitset MCSubtargetInfo::ToggleFeature(uint64_t FB) {
66 FeatureBits.flip(FB);
67 return FeatureBits;
68 }
69
70 FeatureBitset MCSubtargetInfo::ToggleFeature(const FeatureBitset &FB) {
6671 FeatureBits ^= FB;
6772 return FeatureBits;
6873 }
6974
7075 /// ToggleFeature - Toggle a feature and returns the re-computed feature
7176 /// bits. This version will also change all implied bits.
72 uint64_t MCSubtargetInfo::ToggleFeature(StringRef FS) {
77 FeatureBitset MCSubtargetInfo::ToggleFeature(StringRef FS) {
7378 SubtargetFeatures Features;
7479 FeatureBits = Features.ToggleFeature(FeatureBits, FS, ProcFeatures);
7580 return FeatureBits;
149149 /// feature, set it.
150150 ///
151151 static
152 void SetImpliedBits(uint64_t &Bits, const SubtargetFeatureKV *FeatureEntry,
152 void SetImpliedBits(FeatureBitset &Bits, const SubtargetFeatureKV *FeatureEntry,
153153 ArrayRef FeatureTable) {
154154 for (auto &FE : FeatureTable) {
155155 if (FeatureEntry->Value == FE.Value) continue;
156156
157 if (FeatureEntry->Implies & FE.Value) {
157 if ((FeatureEntry->Implies & FE.Value).any()) {
158158 Bits |= FE.Value;
159159 SetImpliedBits(Bits, &FE, FeatureTable);
160160 }
165165 /// feature, clear it.
166166 ///
167167 static
168 void ClearImpliedBits(uint64_t &Bits, const SubtargetFeatureKV *FeatureEntry,
168 void ClearImpliedBits(FeatureBitset &Bits,
169 const SubtargetFeatureKV *FeatureEntry,
169170 ArrayRef FeatureTable) {
170171 for (auto &FE : FeatureTable) {
171172 if (FeatureEntry->Value == FE.Value) continue;
172173
173 if (FE.Implies & FeatureEntry->Value) {
174 if ((FE.Implies & FeatureEntry->Value).any()) {
174175 Bits &= ~FE.Value;
175176 ClearImpliedBits(Bits, &FE, FeatureTable);
176177 }
179180
180181 /// ToggleFeature - Toggle a feature and returns the newly updated feature
181182 /// bits.
182 uint64_t
183 SubtargetFeatures::ToggleFeature(uint64_t Bits, StringRef Feature,
183 FeatureBitset
184 SubtargetFeatures::ToggleFeature(FeatureBitset Bits, StringRef Feature,
184185 ArrayRef FeatureTable) {
185186
186187 // Find feature in table.
190191 if (FeatureEntry) {
191192 if ((Bits & FeatureEntry->Value) == FeatureEntry->Value) {
192193 Bits &= ~FeatureEntry->Value;
193
194194 // For each feature that implies this, clear it.
195195 ClearImpliedBits(Bits, FeatureEntry, FeatureTable);
196196 } else {
211211
212212 /// getFeatureBits - Get feature bits a CPU.
213213 ///
214 uint64_t
214 FeatureBitset
215215 SubtargetFeatures::getFeatureBits(StringRef CPU,
216216 ArrayRef CPUTable,
217217 ArrayRef FeatureTable) {
218218
219219 if (CPUTable.empty() || FeatureTable.empty())
220 return 0;
220 return FeatureBitset();
221221
222222 #ifndef NDEBUG
223223 for (size_t i = 1, e = CPUTable.size(); i != e; ++i) {
229229 "CPU features table is not sorted");
230230 }
231231 #endif
232 uint64_t Bits = 0; // Resulting bits
232 // Resulting bits
233 FeatureBitset Bits;
233234
234235 // Check if help is needed
235236 if (CPU == "help")
246247
247248 // Set the feature implied by this CPU feature, if any.
248249 for (auto &FE : FeatureTable) {
249 if (CPUEntry->Value & FE.Value)
250 if ((CPUEntry->Value & FE.Value).any())
250251 SetImpliedBits(Bits, &FE, FeatureTable);
251252 }
252253 } else {
1313 #include "llvm/ADT/APFloat.h"
1414 #include "llvm/ADT/SmallVector.h"
1515 #include "llvm/ADT/StringExtras.h"
16 #include "llvm/MC/SubtargetFeature.h"
1617 #include "llvm/Support/Regex.h"
1718
1819 using namespace llvm;
244245 {"ich_elsr_el2", ICH_ELSR_EL2}
245246 };
246247
247 AArch64SysReg::MRSMapper::MRSMapper(uint64_t FeatureBits)
248 AArch64SysReg::MRSMapper::MRSMapper(const FeatureBitset &FeatureBits)
248249 : SysRegMapper(FeatureBits) {
249250 InstPairs = &MRSPairs[0];
250251 NumInstPairs = llvm::array_lengthof(MRSPairs);
268269 {"icc_sgi0r_el1", ICC_SGI0R_EL1}
269270 };
270271
271 AArch64SysReg::MSRMapper::MSRMapper(uint64_t FeatureBits)
272 AArch64SysReg::MSRMapper::MSRMapper(const FeatureBitset &FeatureBits)
272273 : SysRegMapper(FeatureBits) {
273274 InstPairs = &MSRPairs[0];
274275 NumInstPairs = llvm::array_lengthof(MSRPairs);
772773 }
773774
774775 // Next search for target specific registers
775 if (FeatureBits & AArch64::ProcCyclone) {
776 if (FeatureBits[AArch64::ProcCyclone]) {
776777 for (unsigned i = 0; i < array_lengthof(CycloneSysRegPairs); ++i) {
777778 if (CycloneSysRegPairs[i].Name == NameLower) {
778779 Valid = true;
822823 }
823824
824825 // Next search for target specific registers
825 if (FeatureBits & AArch64::ProcCyclone) {
826 if (FeatureBits[AArch64::ProcCyclone]) {
826827 for (unsigned i = 0; i < array_lengthof(CycloneSysRegPairs); ++i) {
827828 if (CycloneSysRegPairs[i].Value == Bits) {
828829 return CycloneSysRegPairs[i].Name;
2424 #include "llvm/Support/ErrorHandling.h"
2525
2626 namespace llvm {
27
28 class FeatureBitset;
2729
2830 inline static unsigned getWRegFromXReg(unsigned Reg) {
2931 switch (Reg) {
11381140
11391141 const AArch64NamedImmMapper::Mapping *InstPairs;
11401142 size_t NumInstPairs;
1141 uint64_t FeatureBits;
1142
1143 SysRegMapper(uint64_t FeatureBits) : FeatureBits(FeatureBits) { }
1143 const FeatureBitset &FeatureBits;
1144
1145 SysRegMapper(const FeatureBitset &FeatureBits) : FeatureBits(FeatureBits) { }
11441146 uint32_t fromString(StringRef Name, bool &Valid) const;
11451147 std::string toString(uint32_t Bits) const;
11461148 };
11471149
11481150 struct MSRMapper : SysRegMapper {
11491151 static const AArch64NamedImmMapper::Mapping MSRPairs[];
1150 MSRMapper(uint64_t FeatureBits);
1152 MSRMapper(const FeatureBitset &FeatureBits);
11511153 };
11521154
11531155 struct MRSMapper : SysRegMapper {
11541156 static const AArch64NamedImmMapper::Mapping MRSPairs[];
1155 MRSMapper(uint64_t FeatureBits);
1157 MRSMapper(const FeatureBitset &FeatureBits);
11561158 };
11571159
11581160 uint32_t ParseGenericRegister(StringRef Name, bool &Valid);
421421 }
422422
423423 static bool isThumb(const MCSubtargetInfo& STI) {
424 return (STI.getFeatureBits() & ARM::ModeThumb) != 0;
424 return STI.getFeatureBits()[ARM::ModeThumb];
425425 }
426426
427427 void ARMAsmPrinter::emitInlineAsmEnd(const MCSubtargetInfo &StartInfo,
45064506 }
45074507
45084508 bool ARMBaseInstrInfo::hasNOP() const {
4509 return (Subtarget.getFeatureBits() & ARM::HasV6T2Ops) != 0;
4509 return Subtarget.getFeatureBits()[ARM::HasV6T2Ops];
45104510 }
45114511
45124512 bool ARMBaseInstrInfo::isSwiftFastImmShift(const MachineInstr *MI) const {
261261 }
262262
263263 // NEON f32 ops are non-IEEE 754 compliant. Darwin is ok with it by default.
264 uint64_t Bits = getFeatureBits();
265 if ((Bits & ARM::ProcA5 || Bits & ARM::ProcA8) && // Where this matters
264 const FeatureBitset &Bits = getFeatureBits();
265 if ((Bits[ARM::ProcA5] || Bits[ARM::ProcA8]) && // Where this matters
266266 (Options.UnsafeFPMath || isTargetDarwin()))
267267 UseNEONForSinglePrecisionFP = true;
268268 }
243243
244244 bool isThumb() const {
245245 // FIXME: Can tablegen auto-generate this?
246 return (STI.getFeatureBits() & ARM::ModeThumb) != 0;
246 return STI.getFeatureBits()[ARM::ModeThumb];
247247 }
248248 bool isThumbOne() const {
249 return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2) == 0;
249 return isThumb() && !STI.getFeatureBits()[ARM::FeatureThumb2];
250250 }
251251 bool isThumbTwo() const {
252 return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2);
252 return isThumb() && STI.getFeatureBits()[ARM::FeatureThumb2];
253253 }
254254 bool hasThumb() const {
255 return STI.getFeatureBits() & ARM::HasV4TOps;
255 return STI.getFeatureBits()[ARM::HasV4TOps];
256256 }
257257 bool hasV6Ops() const {
258 return STI.getFeatureBits() & ARM::HasV6Ops;
258 return STI.getFeatureBits()[ARM::HasV6Ops];
259259 }
260260 bool hasV6MOps() const {
261 return STI.getFeatureBits() & ARM::HasV6MOps;
261 return STI.getFeatureBits()[ARM::HasV6MOps];
262262 }
263263 bool hasV7Ops() const {
264 return STI.getFeatureBits() & ARM::HasV7Ops;
264 return STI.getFeatureBits()[ARM::HasV7Ops];
265265 }
266266 bool hasV8Ops() const {
267 return STI.getFeatureBits() & ARM::HasV8Ops;
267 return STI.getFeatureBits()[ARM::HasV8Ops];
268268 }
269269 bool hasARM() const {
270 return !(STI.getFeatureBits() & ARM::FeatureNoARM);
270 return !STI.getFeatureBits()[ARM::FeatureNoARM];
271271 }
272272 bool hasThumb2DSP() const {
273 return STI.getFeatureBits() & ARM::FeatureDSPThumb2;
273 return STI.getFeatureBits()[ARM::FeatureDSPThumb2];
274274 }
275275 bool hasD16() const {
276 return STI.getFeatureBits() & ARM::FeatureD16;
276 return STI.getFeatureBits()[ARM::FeatureD16];
277277 }
278278
279279 void SwitchMode() {
281281 setAvailableFeatures(FB);
282282 }
283283 bool isMClass() const {
284 return STI.getFeatureBits() & ARM::FeatureMClass;
284 return STI.getFeatureBits()[ARM::FeatureMClass];
285285 }
286286
287287 /// @name Auto-generated Match Functions
91859185 // tools/clang/lib/Driver/Tools.cpp
91869186 static const struct {
91879187 const unsigned ID;
9188 const uint64_t Enabled;
9189 const uint64_t Disabled;
9188 const FeatureBitset Enabled;
9189 const FeatureBitset Disabled;
91909190 } FPUs[] = {
9191 {/* ID */ ARM::VFP,
9192 /* Enabled */ ARM::FeatureVFP2,
9193 /* Disabled */ ARM::FeatureNEON},
9194 {/* ID */ ARM::VFPV2,
9195 /* Enabled */ ARM::FeatureVFP2,
9196 /* Disabled */ ARM::FeatureNEON},
9197 {/* ID */ ARM::VFPV3,
9198 /* Enabled */ ARM::FeatureVFP2 | ARM::FeatureVFP3,
9199 /* Disabled */ ARM::FeatureNEON | ARM::FeatureD16},
9200 {/* ID */ ARM::VFPV3_D16,
9201 /* Enable */ ARM::FeatureVFP2 | ARM::FeatureVFP3 | ARM::FeatureD16,
9202 /* Disabled */ ARM::FeatureNEON},
9203 {/* ID */ ARM::VFPV4,
9204 /* Enabled */ ARM::FeatureVFP2 | ARM::FeatureVFP3 | ARM::FeatureVFP4,
9205 /* Disabled */ ARM::FeatureNEON | ARM::FeatureD16},
9206 {/* ID */ ARM::VFPV4_D16,
9207 /* Enabled */ ARM::FeatureVFP2 | ARM::FeatureVFP3 | ARM::FeatureVFP4 |
9208 ARM::FeatureD16,
9209 /* Disabled */ ARM::FeatureNEON},
9210 {/* ID */ ARM::FPV5_D16,
9211 /* Enabled */ ARM::FeatureVFP2 | ARM::FeatureVFP3 | ARM::FeatureVFP4 |
9212 ARM::FeatureFPARMv8 | ARM::FeatureD16,
9213 /* Disabled */ ARM::FeatureNEON | ARM::FeatureCrypto},
9214 {/* ID */ ARM::FP_ARMV8,
9215 /* Enabled */ ARM::FeatureVFP2 | ARM::FeatureVFP3 | ARM::FeatureVFP4 |
9216 ARM::FeatureFPARMv8,
9217 /* Disabled */ ARM::FeatureNEON | ARM::FeatureCrypto | ARM::FeatureD16},
9218 {/* ID */ ARM::NEON,
9219 /* Enabled */ ARM::FeatureVFP2 | ARM::FeatureVFP3 | ARM::FeatureNEON,
9220 /* Disabled */ ARM::FeatureD16},
9221 {/* ID */ ARM::NEON_VFPV4,
9222 /* Enabled */ ARM::FeatureVFP2 | ARM::FeatureVFP3 | ARM::FeatureVFP4 |
9223 ARM::FeatureNEON,
9224 /* Disabled */ ARM::FeatureD16},
9225 {/* ID */ ARM::NEON_FP_ARMV8,
9226 /* Enabled */ ARM::FeatureVFP2 | ARM::FeatureVFP3 | ARM::FeatureVFP4 |
9227 ARM::FeatureFPARMv8 | ARM::FeatureNEON,
9228 /* Disabled */ ARM::FeatureCrypto | ARM::FeatureD16},
9229 {/* ID */ ARM::CRYPTO_NEON_FP_ARMV8,
9230 /* Enabled */ ARM::FeatureVFP2 | ARM::FeatureVFP3 | ARM::FeatureVFP4 |
9231 ARM::FeatureFPARMv8 | ARM::FeatureNEON | ARM::FeatureCrypto,
9232 /* Disabled */ ARM::FeatureD16},
9233 {ARM::SOFTVFP, 0, 0},
9191 {/* ID */ ARM::VFP,
9192 /* Enabled */ {ARM::FeatureVFP2},
9193 /* Disabled */ {ARM::FeatureNEON}},
9194 {/* ID */ ARM::VFPV2,
9195 /* Enabled */ {ARM::FeatureVFP2},
9196 /* Disabled */ {ARM::FeatureNEON}},
9197 {/* ID */ ARM::VFPV3,
9198 /* Enabled */ {ARM::FeatureVFP2, ARM::FeatureVFP3},
9199 /* Disabled */ {ARM::FeatureNEON, ARM::FeatureD16}},
9200 {/* ID */ ARM::VFPV3_D16,
9201 /* Enabled */ {ARM::FeatureVFP2, ARM::FeatureVFP3, ARM::FeatureD16},
9202 /* Disabled */ {ARM::FeatureNEON}},
9203 {/* ID */ ARM::VFPV4,
9204 /* Enabled */ {ARM::FeatureVFP2, ARM::FeatureVFP3, ARM::FeatureVFP4},
9205 /* Disabled */ {ARM::FeatureNEON, ARM::FeatureD16}},
9206 {/* ID */ ARM::VFPV4_D16,
9207 /* Enabled */ {ARM::FeatureVFP2, ARM::FeatureVFP3, ARM::FeatureVFP4,
9208 ARM::FeatureD16},
9209 /* Disabled */ {ARM::FeatureNEON}},
9210 {/* ID */ ARM::FPV5_D16,
9211 /* Enabled */ {ARM::FeatureVFP2, ARM::FeatureVFP3, ARM::FeatureVFP4,
9212 ARM::FeatureFPARMv8, ARM::FeatureD16},
9213 /* Disabled */ {ARM::FeatureNEON, ARM::FeatureCrypto}},
9214 {/* ID */ ARM::FP_ARMV8,
9215 /* Enabled */ {ARM::FeatureVFP2, ARM::FeatureVFP3, ARM::FeatureVFP4,
9216 ARM::FeatureFPARMv8},
9217 /* Disabled */ {ARM::FeatureNEON, ARM::FeatureCrypto, ARM::FeatureD16}},
9218 {/* ID */ ARM::NEON,
9219 /* Enabled */ {ARM::FeatureVFP2, ARM::FeatureVFP3, ARM::FeatureNEON},
9220 /* Disabled */ {ARM::FeatureD16}},
9221 {/* ID */ ARM::NEON_VFPV4,
9222 /* Enabled */ {ARM::FeatureVFP2, ARM::FeatureVFP3, ARM::FeatureVFP4,
9223 ARM::FeatureNEON},
9224 /* Disabled */ {ARM::FeatureD16}},
9225 {/* ID */ ARM::NEON_FP_ARMV8,
9226 /* Enabled */ {ARM::FeatureVFP2, ARM::FeatureVFP3, ARM::FeatureVFP4,
9227 ARM::FeatureFPARMv8, ARM::FeatureNEON},
9228 /* Disabled */ {ARM::FeatureCrypto, ARM::FeatureD16}},
9229 {/* ID */ ARM::CRYPTO_NEON_FP_ARMV8,
9230 /* Enabled */ {ARM::FeatureVFP2, ARM::FeatureVFP3, ARM::FeatureVFP4,
9231 ARM::FeatureFPARMv8, ARM::FeatureNEON,
9232 ARM::FeatureCrypto},
9233 /* Disabled */ {ARM::FeatureD16}},
9234 {ARM::SOFTVFP, {}, {}},
92349235 };
92359236
92369237 /// parseDirectiveFPU
92559256
92569257 // Need to toggle features that should be on but are off and that
92579258 // should off but are on.
9258 uint64_t Toggle = (Entry.Enabled & ~STI.getFeatureBits()) |
9259 (Entry.Disabled & STI.getFeatureBits());
9259 FeatureBitset Toggle = (Entry.Enabled & ~STI.getFeatureBits()) |
9260 (Entry.Disabled & STI.getFeatureBits());
92609261 setAvailableFeatures(ComputeAvailableFeatures(STI.ToggleFeature(Toggle)));
92619262 break;
92629263 }
99939994 static const struct {
99949995 const char *Name;
99959996 const unsigned ArchCheck;
9996 const uint64_t Features;
9997 const FeatureBitset Features;
99979998 } Extensions[] = {
9998 { "crc", Feature_HasV8, ARM::FeatureCRC },
9999 { "crc", Feature_HasV8, {ARM::FeatureCRC} },
999910000 { "crypto", Feature_HasV8,
10000 ARM::FeatureCrypto | ARM::FeatureNEON | ARM::FeatureFPARMv8 },
10001 { "fp", Feature_HasV8, ARM::FeatureFPARMv8 },
10001 {ARM::FeatureCrypto, ARM::FeatureNEON, ARM::FeatureFPARMv8} },
10002 { "fp", Feature_HasV8, {ARM::FeatureFPARMv8} },
1000210003 { "idiv", Feature_HasV7 | Feature_IsNotMClass,
10003 ARM::FeatureHWDiv | ARM::FeatureHWDivARM },
10004 {ARM::FeatureHWDiv, ARM::FeatureHWDivARM} },
1000410005 // FIXME: iWMMXT not supported
10005 { "iwmmxt", Feature_None, 0 },
10006 { "iwmmxt", Feature_None, {} },
1000610007 // FIXME: iWMMXT2 not supported
10007 { "iwmmxt2", Feature_None, 0 },
10008 { "iwmmxt2", Feature_None, {} },
1000810009 // FIXME: Maverick not supported
10009 { "maverick", Feature_None, 0 },
10010 { "mp", Feature_HasV7 | Feature_IsNotMClass, ARM::FeatureMP },
10010 { "maverick", Feature_None, {} },
10011 { "mp", Feature_HasV7 | Feature_IsNotMClass, {ARM::FeatureMP} },
1001110012 // FIXME: ARMv6-m OS Extensions feature not checked
10012 { "os", Feature_None, 0 },
10013 { "os", Feature_None, {} },
1001310014 // FIXME: Also available in ARMv6-K
10014 { "sec", Feature_HasV7, ARM::FeatureTrustZone },
10015 { "simd", Feature_HasV8, ARM::FeatureNEON | ARM::FeatureFPARMv8 },
10015 { "sec", Feature_HasV7, {ARM::FeatureTrustZone} },
10016 { "simd", Feature_HasV8, {ARM::FeatureNEON, ARM::FeatureFPARMv8} },
1001610017 // FIXME: Only available in A-class, isel not predicated
10017 { "virt", Feature_HasV7, ARM::FeatureVirtualization },
10018 { "virt", Feature_HasV7, {ARM::FeatureVirtualization} },
1001810019 // FIXME: xscale not supported
10019 { "xscale", Feature_None, 0 },
10020 { "xscale", Feature_None, {} },
1002010021 };
1002110022
1002210023 /// parseDirectiveArchExtension
1004410045 if (Extension.Name != Name)
1004510046 continue;
1004610047
10047 if (!Extension.Features)
10048 if (Extension.Features.none())
1004810049 report_fatal_error("unsupported architectural extension: " + Name);
1004910050
1005010051 if ((getAvailableFeatures() & Extension.ArchCheck) != Extension.ArchCheck) {
1005310054 return false;
1005410055 }
1005510056
10056 uint64_t ToggleFeatures = EnableFeature
10057 ? (~STI.getFeatureBits() & Extension.Features)
10058 : ( STI.getFeatureBits() & Extension.Features);
10057 FeatureBitset ToggleFeatures = EnableFeature
10058 ? (~STI.getFeatureBits() & Extension.Features)
10059 : ( STI.getFeatureBits() & Extension.Features);
10060
1005910061 uint64_t Features =
1006010062 ComputeAvailableFeatures(STI.ToggleFeature(ToggleFeatures));
1006110063 setAvailableFeatures(Features);
430430 raw_ostream &CS) const {
431431 CommentStream = &CS;
432432
433 assert(!(STI.getFeatureBits() & ARM::ModeThumb) &&
433 assert(!STI.getFeatureBits()[ARM::ModeThumb] &&
434434 "Asked to disassemble an ARM instruction but Subtarget is in Thumb "
435435 "mode!");
436436
695695 raw_ostream &CS) const {
696696 CommentStream = &CS;
697697
698 assert((STI.getFeatureBits() & ARM::ModeThumb) &&
698 assert(STI.getFeatureBits()[ARM::ModeThumb] &&
699699 "Asked to disassemble in Thumb mode but Subtarget is in ARM mode!");
700700
701701 // We want to read exactly 2 bytes of data.
10211021
10221022 static DecodeStatus DecodeDPRRegisterClass(MCInst &Inst, unsigned RegNo,
10231023 uint64_t Address, const void *Decoder) {
1024 uint64_t featureBits = ((const MCDisassembler*)Decoder)->getSubtargetInfo()
1025 .getFeatureBits();
1026 bool hasD16 = featureBits & ARM::FeatureD16;
1024 const FeatureBitset &featureBits =
1025 ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
1026
1027 bool hasD16 = featureBits[ARM::FeatureD16];
10271028
10281029 if (RegNo > 31 || (hasD16 && RegNo > 15))
10291030 return MCDisassembler::Fail;
13681369 break;
13691370 }
13701371
1371 uint64_t featureBits = ((const MCDisassembler*)Decoder)->getSubtargetInfo()
1372 .getFeatureBits();
1373 if ((featureBits & ARM::HasV8Ops) && (coproc != 14))
1372 const FeatureBitset &featureBits =
1373 ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
1374 if (featureBits[ARM::HasV8Ops] && (coproc != 14))
13741375 return MCDisassembler::Fail;
13751376
13761377 Inst.addOperand(MCOperand::CreateImm(coproc));
32663267 unsigned Rt = fieldFromInstruction(Insn, 12, 4);
32673268 unsigned Rn = fieldFromInstruction(Insn, 16, 4);
32683269
3269 uint64_t featureBits = ((const MCDisassembler*)Decoder)->getSubtargetInfo()
3270 .getFeatureBits();
3271 bool hasMP = featureBits & ARM::FeatureMP;
3272 bool hasV7Ops = featureBits & ARM::HasV7Ops;
3270 const FeatureBitset &featureBits =
3271 ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
3272
3273 bool hasMP = featureBits[ARM::FeatureMP];
3274 bool hasV7Ops = featureBits[ARM::HasV7Ops];
32733275
32743276 if (Rn == 15) {
32753277 switch (Inst.getOpcode()) {
33523354 imm |= (Rn << 9);
33533355 unsigned add = fieldFromInstruction(Insn, 9, 1);
33543356
3355 uint64_t featureBits = ((const MCDisassembler*)Decoder)->getSubtargetInfo()
3356 .getFeatureBits();
3357 bool hasMP = featureBits & ARM::FeatureMP;
3358 bool hasV7Ops = featureBits & ARM::HasV7Ops;
3357 const FeatureBitset &featureBits =
3358 ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
3359
3360 bool hasMP = featureBits[ARM::FeatureMP];
3361 bool hasV7Ops = featureBits[ARM::HasV7Ops];
33593362
33603363 if (Rn == 15) {
33613364 switch (Inst.getOpcode()) {
34323435 unsigned imm = fieldFromInstruction(Insn, 0, 12);
34333436 imm |= (Rn << 13);
34343437
3435 uint64_t featureBits = ((const MCDisassembler*)Decoder)->getSubtargetInfo()
3436 .getFeatureBits();
3437 bool hasMP = (featureBits & ARM::FeatureMP);
3438 bool hasV7Ops = (featureBits & ARM::HasV7Ops);
3438 const FeatureBitset &featureBits =
3439 ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
3440
3441 bool hasMP = featureBits[ARM::FeatureMP];
3442 bool hasV7Ops = featureBits[ARM::HasV7Ops];
34393443
34403444 if (Rn == 15) {
34413445 switch (Inst.getOpcode()) {
35493553 unsigned U = fieldFromInstruction(Insn, 23, 1);
35503554 int imm = fieldFromInstruction(Insn, 0, 12);
35513555
3552 uint64_t featureBits = ((const MCDisassembler*)Decoder)->getSubtargetInfo()
3553 .getFeatureBits();
3554 bool hasV7Ops = (featureBits & ARM::HasV7Ops);
3556 const FeatureBitset &featureBits =
3557 ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
3558
3559 bool hasV7Ops = featureBits[ARM::HasV7Ops];
35553560
35563561 if (Rt == 15) {
35573562 switch (Inst.getOpcode()) {
38723877 if (Val == 0xA || Val == 0xB)
38733878 return MCDisassembler::Fail;
38743879
3875 uint64_t featureBits = ((const MCDisassembler*)Decoder)->getSubtargetInfo()
3876 .getFeatureBits();
3877 if ((featureBits & ARM::HasV8Ops) && !(Val == 14 || Val == 15))
3880 const FeatureBitset &featureBits =
3881 ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
3882
3883 if (featureBits[ARM::HasV8Ops] && !(Val == 14 || Val == 15))
38783884 return MCDisassembler::Fail;
38793885
38803886 Inst.addOperand(MCOperand::CreateImm(Val));
40244030 static DecodeStatus DecodeMSRMask(MCInst &Inst, unsigned Val,
40254031 uint64_t Address, const void *Decoder) {
40264032 DecodeStatus S = MCDisassembler::Success;
4027 uint64_t FeatureBits = ((const MCDisassembler*)Decoder)->getSubtargetInfo()
4028 .getFeatureBits();
4029 if (FeatureBits & ARM::FeatureMClass) {
4033 const FeatureBitset &FeatureBits =
4034 ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
4035
4036 if (FeatureBits[ARM::FeatureMClass]) {
40304037 unsigned ValLow = Val & 0xff;
40314038
40324039 // Validate the SYSm value first.
40464053 case 17: // basepri
40474054 case 18: // basepri_max
40484055 case 19: // faultmask
4049 if (!(FeatureBits & ARM::HasV7Ops))
4056 if (!(FeatureBits[ARM::HasV7Ops]))
40504057 // Values basepri, basepri_max and faultmask are only valid for v7m.
40514058 return MCDisassembler::Fail;
40524059 break;
40564063
40574064 if (Inst.getOpcode() == ARM::t2MSR_M) {
40584065 unsigned Mask = fieldFromInstruction(Val, 10, 2);
4059 if (!(FeatureBits & ARM::HasV7Ops)) {
4066 if (!(FeatureBits[ARM::HasV7Ops])) {
40604067 // The ARMv6-M MSR bits {11-10} can be only 0b10, other values are
40614068 // unpredictable.
40624069 if (Mask != 2)
40704077 // indicates the move for the GE{3:0} bits, the mask{0} bit can be set
40714078 // only if the processor includes the DSP extension.
40724079 if (Mask == 0 || (Mask != 2 && ValLow > 3) ||
4073 (!(FeatureBits & ARM::FeatureDSPThumb2) && (Mask & 1)))
4080 (!(FeatureBits[ARM::FeatureDSPThumb2]) && (Mask & 1)))
40744081 S = MCDisassembler::SoftFail;
40754082 }
40764083 }
8989 case 3: O << "\twfi"; break;
9090 case 4: O << "\tsev"; break;
9191 case 5:
92 if ((getAvailableFeatures() & ARM::HasV8Ops)) {
92 if (getAvailableFeatures()[ARM::HasV8Ops]) {
9393 O << "\tsevl";
9494 break;
9595 } // Fallthrough for non-v8
298298 if (MI->getNumOperands() == 3 &&
299299 MI->getOperand(0).isImm() &&
300300 MI->getOperand(0).getImm() == 0 &&
301 (getAvailableFeatures() & ARM::FeatureVirtualization)) {
301 getAvailableFeatures()[ARM::FeatureVirtualization]) {
302302 O << "\teret";
303303 printPredicateOperand(MI, 1, O);
304304 printAnnotation(O, Annot);
697697 void ARMInstPrinter::printMemBOption(const MCInst *MI, unsigned OpNum,
698698 raw_ostream &O) {
699699 unsigned val = MI->getOperand(OpNum).getImm();
700 O << ARM_MB::MemBOptToString(val, (getAvailableFeatures() & ARM::HasV8Ops));
700 O << ARM_MB::MemBOptToString(val, getAvailableFeatures()[ARM::HasV8Ops]);
701701 }
702702
703703 void ARMInstPrinter::printInstSyncBOption(const MCInst *MI, unsigned OpNum,
795795 const MCOperand &Op = MI->getOperand(OpNum);
796796 unsigned SpecRegRBit = Op.getImm() >> 4;
797797 unsigned Mask = Op.getImm() & 0xf;
798 uint64_t FeatureBits = getAvailableFeatures();
799
800 if (FeatureBits & ARM::FeatureMClass) {
798 const FeatureBitset &FeatureBits = getAvailableFeatures();
799
800 if (FeatureBits[ARM::FeatureMClass]) {
801801 unsigned SYSm = Op.getImm();
802802 unsigned Opcode = MI->getOpcode();
803803
804804 // For writes, handle extended mask bits if the DSP extension is present.
805 if (Opcode == ARM::t2MSR_M && (FeatureBits & ARM::FeatureDSPThumb2)) {
805 if (Opcode == ARM::t2MSR_M && FeatureBits[ARM::FeatureDSPThumb2]) {
806806 switch (SYSm) {
807807 case 0x400: O << "apsr_g"; return;
808808 case 0xc00: O << "apsr_nzcvqg"; return;
818818 // Handle the basic 8-bit mask.
819819 SYSm &= 0xff;
820820
821 if (Opcode == ARM::t2MSR_M && (FeatureBits & ARM::HasV7Ops)) {
821 if (Opcode == ARM::t2MSR_M && FeatureBits [ARM::HasV7Ops]) {
822822 // ARMv7-M deprecates using MSR APSR without a _ qualifier as an
823823 // alias for MSR APSR_nzcvq.
824824 switch (SYSm) {
3232 return ARM::NumTargetFixupKinds;
3333 }
3434
35 bool hasNOP() const { return (STI->getFeatureBits() & ARM::HasV6T2Ops) != 0; }
35 bool hasNOP() const { return STI->getFeatureBits()[ARM::HasV6T2Ops]; }
3636
3737 const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override;
3838
5050 ~ARMMCCodeEmitter() {}
5151
5252 bool isThumb(const MCSubtargetInfo &STI) const {
53 return (STI.getFeatureBits() & ARM::ModeThumb) != 0;
53 return STI.getFeatureBits()[ARM::ModeThumb];
5454 }
5555 bool isThumb2(const MCSubtargetInfo &STI) const {
56 return isThumb(STI) && (STI.getFeatureBits() & ARM::FeatureThumb2) != 0;
56 return isThumb(STI) && STI.getFeatureBits()[ARM::FeatureThumb2];
5757 }
5858 bool isTargetMachO(const MCSubtargetInfo &STI) const {
5959 Triple TT(STI.getTargetTriple());
3232
3333 static bool getMCRDeprecationInfo(MCInst &MI, MCSubtargetInfo &STI,
3434 std::string &Info) {
35 if (STI.getFeatureBits() & llvm::ARM::HasV7Ops &&
35 if (STI.getFeatureBits()[llvm::ARM::HasV7Ops] &&
3636 (MI.getOperand(0).isImm() && MI.getOperand(0).getImm() == 15) &&
3737 (MI.getOperand(1).isImm() && MI.getOperand(1).getImm() == 0) &&
3838 // Checks for the deprecated CP15ISB encoding:
6464
6565 static bool getITDeprecationInfo(MCInst &MI, MCSubtargetInfo &STI,
6666 std::string &Info) {
67 if (STI.getFeatureBits() & llvm::ARM::HasV8Ops && MI.getOperand(1).isImm() &&
67 if (STI.getFeatureBits()[llvm::ARM::HasV8Ops] && MI.getOperand(1).isImm() &&
6868 MI.getOperand(1).getImm() != 8) {
6969 Info = "applying IT instruction to more than one subsequent instruction is "
7070 "deprecated";
7676
7777 static bool getARMStoreDeprecationInfo(MCInst &MI, MCSubtargetInfo &STI,
7878 std::string &Info) {
79 assert((~STI.getFeatureBits() & llvm::ARM::ModeThumb) &&
79 assert(!STI.getFeatureBits()[llvm::ARM::ModeThumb] &&
8080 "cannot predicate thumb instructions");
8181
8282 assert(MI.getNumOperands() >= 4 && "expected >= 4 arguments");
9393
9494 static bool getARMLoadDeprecationInfo(MCInst &MI, MCSubtargetInfo &STI,
9595 std::string &Info) {
96 assert((~STI.getFeatureBits() & llvm::ARM::ModeThumb) &&
96 assert(!STI.getFeatureBits()[llvm::ARM::ModeThumb] &&
9797 "cannot predicate thumb instructions");
9898
9999 assert(MI.getNumOperands() >= 4 && "expected >= 4 arguments");
7070 // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
7171 // The reason we need this mask is explained in the selectArch function.
7272 // FIXME: Ideally we would like TableGen to generate this information.
73 static const uint64_t AllArchRelatedMask =
74 Mips::FeatureMips1 | Mips::FeatureMips2 | Mips::FeatureMips3 |
75 Mips::FeatureMips3_32 | Mips::FeatureMips3_32r2 | Mips::FeatureMips4 |
76 Mips::FeatureMips4_32 | Mips::FeatureMips4_32r2 | Mips::FeatureMips5 |
77 Mips::FeatureMips5_32r2 | Mips::FeatureMips32 | Mips::FeatureMips32r2 |
78 Mips::FeatureMips32r3 | Mips::FeatureMips32r5 | Mips::FeatureMips32r6 |
79 Mips::FeatureMips64 | Mips::FeatureMips64r2 | Mips::FeatureMips64r3 |
80 Mips::FeatureMips64r5 | Mips::FeatureMips64r6 | Mips::FeatureCnMips |
81 Mips::FeatureFP64Bit | Mips::FeatureGP64Bit | Mips::FeatureNaN2008;
73 static const FeatureBitset AllArchRelatedMask;
8274
8375 private:
8476 unsigned ATReg;
8779 uint64_t Features;
8880 };
8981 }
82
83 const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = {
84 Mips::FeatureMips1, Mips::FeatureMips2, Mips::FeatureMips3,
85 Mips::FeatureMips3_32, Mips::FeatureMips3_32r2, Mips::FeatureMips4,
86 Mips::FeatureMips4_32, Mips::FeatureMips4_32r2, Mips::FeatureMips5,
87 Mips::FeatureMips5_32r2, Mips::FeatureMips32, Mips::FeatureMips32r2,
88 Mips::FeatureMips32r3, Mips::FeatureMips32r5, Mips::FeatureMips32r6,
89 Mips::FeatureMips64, Mips::FeatureMips64r2, Mips::FeatureMips64r3,
90 Mips::FeatureMips64r5, Mips::FeatureMips64r6, Mips::FeatureCnMips,
91 Mips::FeatureFP64Bit, Mips::FeatureGP64Bit, Mips::FeatureNaN2008
92 };
9093
9194 namespace {
9295 class MipsAsmParser : public MCTargetAsmParser {
292295 // FeatureMipsGP64 | FeatureMips1)
293296 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
294297 void selectArch(StringRef ArchFeature) {
295 uint64_t FeatureBits = STI.getFeatureBits();
298 FeatureBitset FeatureBits = STI.getFeatureBits();
296299 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
297300 STI.setFeatureBits(FeatureBits);
298301 setAvailableFeatures(
301304 }
302305
303306 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
304 if (!(STI.getFeatureBits() & Feature)) {
307 if (!(STI.getFeatureBits()[Feature])) {
305308 setAvailableFeatures(
306309 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
307310 }
309312 }
310313
311314 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
312 if (STI.getFeatureBits() & Feature) {
315 if (STI.getFeatureBits()[Feature]) {
313316 setAvailableFeatures(
314317 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
315318 }
354357 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
355358 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
356359
357 bool isGP64bit() const { return STI.getFeatureBits() & Mips::FeatureGP64Bit; }
358 bool isFP64bit() const { return STI.getFeatureBits() & Mips::FeatureFP64Bit; }
360 bool isGP64bit() const { return STI.getFeatureBits()[Mips::FeatureGP64Bit]; }
361 bool isFP64bit() const { return STI.getFeatureBits()[Mips::FeatureFP64Bit]; }
359362 const MipsABIInfo &getABI() const { return ABI; }
360363 bool isABI_N32() const { return ABI.IsN32(); }
361364 bool isABI_N64() const { return ABI.IsN64(); }
362365 bool isABI_O32() const { return ABI.IsO32(); }
363 bool isABI_FPXX() const { return STI.getFeatureBits() & Mips::FeatureFPXX; }
366 bool isABI_FPXX() const { return STI.getFeatureBits()[Mips::FeatureFPXX]; }
364367
365368 bool useOddSPReg() const {
366 return !(STI.getFeatureBits() & Mips::FeatureNoOddSPReg);
369 return !(STI.getFeatureBits()[Mips::FeatureNoOddSPReg]);
367370 }
368371
369372 bool inMicroMipsMode() const {
370 return STI.getFeatureBits() & Mips::FeatureMicroMips;
371 }
372 bool hasMips1() const { return STI.getFeatureBits() & Mips::FeatureMips1; }
373 bool hasMips2() const { return STI.getFeatureBits() & Mips::FeatureMips2; }
374 bool hasMips3() const { return STI.getFeatureBits() & Mips::FeatureMips3; }
375 bool hasMips4() const { return STI.getFeatureBits() & Mips::FeatureMips4; }
376 bool hasMips5() const { return STI.getFeatureBits() & Mips::FeatureMips5; }
373 return STI.getFeatureBits()[Mips::FeatureMicroMips];
374 }
375 bool hasMips1() const { return STI.getFeatureBits()[Mips::FeatureMips1]; }
376 bool hasMips2() const { return STI.getFeatureBits()[Mips::FeatureMips2]; }
377 bool hasMips3() const { return STI.getFeatureBits()[Mips::FeatureMips3]; }
378 bool hasMips4() const { return STI.getFeatureBits()[Mips::FeatureMips4]; }
379 bool hasMips5() const { return STI.getFeatureBits()[Mips::FeatureMips5]; }
377380 bool hasMips32() const {
378 return (STI.getFeatureBits() & Mips::FeatureMips32);
381 return STI.getFeatureBits()[Mips::FeatureMips32];
379382 }
380383 bool hasMips64() const {
381 return (STI.getFeatureBits() & Mips::FeatureMips64);
384 return STI.getFeatureBits()[Mips::FeatureMips64];
382385 }
383386 bool hasMips32r2() const {
384 return (STI.getFeatureBits() & Mips::FeatureMips32r2);
387 return STI.getFeatureBits()[Mips::FeatureMips32r2];
385388 }
386389 bool hasMips64r2() const {
387 return (STI.getFeatureBits() & Mips::FeatureMips64r2);
390 return STI.getFeatureBits()[Mips::FeatureMips64r2];
388391 }
389392 bool hasMips32r3() const {
390 return (STI.getFeatureBits() & Mips::FeatureMips32r3);
393 return (STI.getFeatureBits()[Mips::FeatureMips32r3]);
391394 }
392395 bool hasMips64r3() const {
393 return (STI.getFeatureBits() & Mips::FeatureMips64r3);
396 return (STI.getFeatureBits()[Mips::FeatureMips64r3]);
394397 }
395398 bool hasMips32r5() const {
396 return (STI.getFeatureBits() & Mips::FeatureMips32r5);
399 return (STI.getFeatureBits()[Mips::FeatureMips32r5]);
397400 }
398401 bool hasMips64r5() const {
399 return (STI.getFeatureBits() & Mips::FeatureMips64r5);
402 return (STI.getFeatureBits()[Mips::FeatureMips64r5]);
400403 }
401404 bool hasMips32r6() const {
402 return (STI.getFeatureBits() & Mips::FeatureMips32r6);
405 return STI.getFeatureBits()[Mips::FeatureMips32r6];
403406 }
404407 bool hasMips64r6() const {
405 return (STI.getFeatureBits() & Mips::FeatureMips64r6);
406 }
408 return STI.getFeatureBits()[Mips::FeatureMips64r6];
409 }
410
411 bool hasDSP() const { return STI.getFeatureBits()[Mips::FeatureDSP]; }
412 bool hasDSPR2() const { return STI.getFeatureBits()[Mips::FeatureDSPR2]; }
413 bool hasMSA() const { return STI.getFeatureBits()[Mips::FeatureMSA]; }
407414 bool hasCnMips() const {
408 return (STI.getFeatureBits() & Mips::FeatureCnMips);
409 }
410 bool hasDSP() const { return (STI.getFeatureBits() & Mips::FeatureDSP); }
411 bool hasDSPR2() const { return (STI.getFeatureBits() & Mips::FeatureDSPR2); }
412 bool hasMSA() const { return (STI.getFeatureBits() & Mips::FeatureMSA); }
415 return (STI.getFeatureBits()[Mips::FeatureCnMips]);
416 }
413417
414418 bool inMips16Mode() const {
415 return STI.getFeatureBits() & Mips::FeatureMips16;
419 return STI.getFeatureBits()[Mips::FeatureMips16];
416420 }
417421 // TODO: see how can we get this info.
418422 bool abiUsesSoftFloat() const { return false; }
3535 public:
3636 MipsDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx, bool IsBigEndian)
3737 : MCDisassembler(STI, Ctx),
38 IsMicroMips(STI.getFeatureBits() & Mips::FeatureMicroMips),
38 IsMicroMips(STI.getFeatureBits()[Mips::FeatureMicroMips]),
3939 IsBigEndian(IsBigEndian) {}
4040
41 bool hasMips3() const { return STI.getFeatureBits() & Mips::FeatureMips3; }
42 bool hasMips32() const { return STI.getFeatureBits() & Mips::FeatureMips32; }
41 bool hasMips3() const { return STI.getFeatureBits()[Mips::FeatureMips3]; }
42 bool hasMips32() const { return STI.getFeatureBits()[Mips::FeatureMips32]; }
4343 bool hasMips32r6() const {
44 return STI.getFeatureBits() & Mips::FeatureMips32r6;
45 }
46
47 bool isGP64() const { return STI.getFeatureBits() & Mips::FeatureGP64Bit; }
44 return STI.getFeatureBits()[Mips::FeatureMips32r6];
45 }
46
47 bool isGP64() const { return STI.getFeatureBits()[Mips::FeatureGP64Bit]; }
4848
4949 bool hasCOP3() const {
5050 // Only present in MIPS-I and MIPS-II
113113 }
114114
115115 bool MipsMCCodeEmitter::isMicroMips(const MCSubtargetInfo &STI) const {
116 return STI.getFeatureBits() & Mips::FeatureMicroMips;
116 return STI.getFeatureBits()[Mips::FeatureMicroMips];
117117 }
118118
119119 void MipsMCCodeEmitter::EmitByte(unsigned char C, raw_ostream &OS) const {
176176 (Opcode != Mips::SLL_MM) && !Binary)
177177 llvm_unreachable("unimplemented opcode in EncodeInstruction()");
178178
179 if (STI.getFeatureBits() & Mips::FeatureMicroMips) {
179 if (STI.getFeatureBits()[Mips::FeatureMicroMips]) {
180180 int NewOpcode = Mips::Std2MicroMips (Opcode, Mips::Arch_micromips);
181181 if (NewOpcode != -1) {
182182 if (Fixups.size() > N)
366366 const MCSubtargetInfo &STI)
367367 : MipsTargetStreamer(S), MicroMipsEnabled(false), STI(STI) {
368368 MCAssembler &MCA = getStreamer().getAssembler();
369
369370 Triple T(STI.getTargetTriple());
370371 Pic = (MCA.getContext().getObjectFileInfo()->getRelocM() == Reloc::PIC_)
371372 ? true
372373 : false;
373374
374 uint64_t Features = STI.getFeatureBits();
375 const FeatureBitset &Features = STI.getFeatureBits();
375376
376377 // Set the header flags that we can in the constructor.
377378 // FIXME: This is a fairly terrible hack. We set the rest
387388 unsigned EFlags = MCA.getELFHeaderEFlags();
388389
389390 // Architecture
390 if (Features & Mips::FeatureMips64r6)
391 if (Features[Mips::FeatureMips64r6])
391392 EFlags |= ELF::EF_MIPS_ARCH_64R6;
392 else if (Features & Mips::FeatureMips64r2 ||
393 Features & Mips::FeatureMips64r3 ||
394 Features & Mips::FeatureMips64r5)
393 else if (Features[Mips::FeatureMips64r2] ||
394 Features[Mips::FeatureMips64r3] ||
395 Features[Mips::FeatureMips64r5])
395396 EFlags |= ELF::EF_MIPS_ARCH_64R2;
396 else if (Features & Mips::FeatureMips64)
397 else if (Features[Mips::FeatureMips64])
397398 EFlags |= ELF::EF_MIPS_ARCH_64;
398 else if (Features & Mips::FeatureMips5)
399 else if (Features[Mips::FeatureMips5])
399400 EFlags |= ELF::EF_MIPS_ARCH_5;
400 else if (Features & Mips::FeatureMips4)
401 else if (Features[Mips::FeatureMips4])
401402 EFlags |= ELF::EF_MIPS_ARCH_4;
402 else if (Features & Mips::FeatureMips3)
403 else if (Features[Mips::FeatureMips3])
403404 EFlags |= ELF::EF_MIPS_ARCH_3;
404 else if (Features & Mips::FeatureMips32r6)
405 else if (Features[Mips::FeatureMips32r6])
405406 EFlags |= ELF::EF_MIPS_ARCH_32R6;
406 else if (Features & Mips::FeatureMips32r2 ||
407 Features & Mips::FeatureMips32r3 ||
408 Features & Mips::FeatureMips32r5)
407 else if (Features[Mips::FeatureMips32r2] ||
408 Features[Mips::FeatureMips32r3] ||
409 Features[Mips::FeatureMips32r5])
409410 EFlags |= ELF::EF_MIPS_ARCH_32R2;
410 else if (Features & Mips::FeatureMips32)
411 else if (Features[Mips::FeatureMips32])
411412 EFlags |= ELF::EF_MIPS_ARCH_32;
412 else if (Features & Mips::FeatureMips2)
413 else if (Features[Mips::FeatureMips2])
413414 EFlags |= ELF::EF_MIPS_ARCH_2;
414415 else
415416 EFlags |= ELF::EF_MIPS_ARCH_1;
416417
417418 // Other options.
418 if (Features & Mips::FeatureNaN2008)
419 if (Features[Mips::FeatureNaN2008])
419420 EFlags |= ELF::EF_MIPS_NAN2008;
420421
421422 // -mabicalls and -mplt are not implemented but we should act as if they were
455456 DataSectionData.setAlignment(std::max(16u, DataSectionData.getAlignment()));
456457 BSSSectionData.setAlignment(std::max(16u, BSSSectionData.getAlignment()));
457458
458 uint64_t Features = STI.getFeatureBits();
459 const FeatureBitset &Features = STI.getFeatureBits();
459460
460461 // Update e_header flags. See the FIXME and comment above in
461462 // the constructor for a full rundown on this.
468469 else if (getABI().IsN32())
469470 EFlags |= ELF::EF_MIPS_ABI2;
470471
471 if (Features & Mips::FeatureGP64Bit) {
472 if (Features[Mips::FeatureGP64Bit]) {
472473 if (getABI().IsO32())
473474 EFlags |= ELF::EF_MIPS_32BITMODE; /* Compatibility Mode */
474 } else if (Features & Mips::FeatureMips64r2 || Features & Mips::FeatureMips64)
475 } else if (Features[Mips::FeatureMips64r2] || Features[Mips::FeatureMips64])
475476 EFlags |= ELF::EF_MIPS_32BITMODE;
476477
477478 // If we've set the cpic eflag and we're n64, go ahead and set the pic
7575 const MCRegisterInfo &MRI,
7676 const MCSubtargetInfo &STI,
7777 MCContext &Ctx) {
78 if (STI.getFeatureBits() & AMDGPU::Feature64BitPtr) {
78 if (STI.getFeatureBits()[AMDGPU::Feature64BitPtr]) {
7979 return createSIMCCodeEmitter(MCII, MRI, STI, Ctx);
8080 } else {
8181 return createR600MCCodeEmitter(MCII, MRI, STI);
9898 } else if (IS_VTX(Desc)) {
9999 uint64_t InstWord01 = getBinaryCodeForInstr(MI, Fixups, STI);
100100 uint32_t InstWord2 = MI.getOperand(2).getImm(); // Offset
101 if (!(STI.getFeatureBits() & AMDGPU::FeatureCaymanISA)) {
101 if (!(STI.getFeatureBits()[AMDGPU::FeatureCaymanISA])) {
102102 InstWord2 |= 1 << 19; // Mega-Fetch bit
103103 }
104104
131131 Emit((uint32_t) 0, OS);
132132 } else {
133133 uint64_t Inst = getBinaryCodeForInstr(MI, Fixups, STI);
134 if ((STI.getFeatureBits() & AMDGPU::FeatureR600ALUInst) &&
134 if ((STI.getFeatureBits()[AMDGPU::FeatureR600ALUInst]) &&
135135 ((Desc.TSFlags & R600_InstFlag::OP1) ||
136136 Desc.TSFlags & R600_InstFlag::OP2)) {
137137 uint64_t ISAOpCode = Inst & (0x3FFULL << 39);
3434 #include "SparcGenAsmWriter.inc"
3535
3636 bool SparcInstPrinter::isV9() const {
37 return (STI.getFeatureBits() & Sparc::FeatureV9) != 0;
37 return (STI.getFeatureBits()[Sparc::FeatureV9]) != 0;
3838 }
3939
4040 void SparcInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const
261261 MCContext &Ctx, int64_t *Residue);
262262
263263 bool is64BitMode() const {
264 return (STI.getFeatureBits() & X86::Mode64Bit) != 0;
264 return STI.getFeatureBits()[X86::Mode64Bit];
265265 }
266266 bool is32BitMode() const {
267 return (STI.getFeatureBits() & X86::Mode32Bit) != 0;
267 return STI.getFeatureBits()[X86::Mode32Bit];
268268 }
269269 bool is16BitMode() const {
270 return (STI.getFeatureBits() & X86::Mode16Bit) != 0;
270 return STI.getFeatureBits()[X86::Mode16Bit];
271271 }
272272
273273 unsigned getPointerWidth() {
10721072 const bool hasCompilerRTSupport = T.isOSLinux();
10731073 if (ClAsanInstrumentAssembly && hasCompilerRTSupport &&
10741074 MCOptions.SanitizeAddress) {
1075 if ((STI.getFeatureBits() & X86::Mode32Bit) != 0)
1075 if (STI.getFeatureBits()[X86::Mode32Bit] != 0)
10761076 return new X86AddressSanitizer32(STI);
1077 if ((STI.getFeatureBits() & X86::Mode64Bit) != 0)
1077 if (STI.getFeatureBits()[X86::Mode64Bit] != 0)
10781078 return new X86AddressSanitizer64(STI);
10791079 }
10801080 return new X86AsmInstrumentation(STI);
726726
727727 bool is64BitMode() const {
728728 // FIXME: Can tablegen auto-generate this?
729 return (STI.getFeatureBits() & X86::Mode64Bit) != 0;
729 return STI.getFeatureBits()[X86::Mode64Bit];
730730 }
731731 bool is32BitMode() const {
732732 // FIXME: Can tablegen auto-generate this?
733 return (STI.getFeatureBits() & X86::Mode32Bit) != 0;
733 return STI.getFeatureBits()[X86::Mode32Bit];
734734 }
735735 bool is16BitMode() const {
736736 // FIXME: Can tablegen auto-generate this?
737 return (STI.getFeatureBits() & X86::Mode16Bit) != 0;
738 }
739 void SwitchMode(uint64_t mode) {
740 uint64_t oldMode = STI.getFeatureBits() &
741 (X86::Mode64Bit | X86::Mode32Bit | X86::Mode16Bit);
742 unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(oldMode | mode));
737 return STI.getFeatureBits()[X86::Mode16Bit];
738 }
739 void SwitchMode(unsigned mode) {
740 FeatureBitset AllModes({X86::Mode64Bit, X86::Mode32Bit, X86::Mode16Bit});
741 FeatureBitset OldMode = STI.getFeatureBits() & AllModes;
742 unsigned FB = ComputeAvailableFeatures(
743 STI.ToggleFeature(OldMode.flip(mode)));
743744 setAvailableFeatures(FB);
744 assert(mode == (STI.getFeatureBits() &
745 (X86::Mode64Bit | X86::Mode32Bit | X86::Mode16Bit)));
745
746 assert(FeatureBitset({mode}) == (STI.getFeatureBits() & AllModes));
746747 }
747748
748749 unsigned getPointerWidth() {
17131714 bool X86AsmParser::HandleAVX512Operand(OperandVector &Operands,
17141715 const MCParsedAsmOperand &Op) {
17151716 MCAsmParser &Parser = getParser();
1716 if(STI.getFeatureBits() & X86::FeatureAVX512) {
1717 if(STI.getFeatureBits()[X86::FeatureAVX512]) {
17171718 if (getLexer().is(AsmToken::LCurly)) {
17181719 // Eat "{" and mark the current place.
17191720 const SMLoc consumedToken = consumeToken();
7979 MCContext &Ctx,
8080 std::unique_ptr MII)
8181 : MCDisassembler(STI, Ctx), MII(std::move(MII)) {
82 switch (STI.getFeatureBits() &
83 (X86::Mode16Bit | X86::Mode32Bit | X86::Mode64Bit)) {
84 case X86::Mode16Bit:
82 const FeatureBitset &FB = STI.getFeatureBits();
83 if (FB[X86::Mode16Bit]) {
8584 fMode = MODE_16BIT;
86 break;
87 case X86::Mode32Bit:
85 return;
86 } else if (FB[X86::Mode32Bit]) {
8887 fMode = MODE_32BIT;
89 break;
90 case X86::Mode64Bit:
88 return;
89 } else if (FB[X86::Mode64Bit]) {
9190 fMode = MODE_64BIT;
92 break;
93 default:
94 llvm_unreachable("Invalid CPU mode");
95 }
91 return;
92 }
93
94 llvm_unreachable("Invalid CPU mode");
9695 }
9796
9897 struct Region {
5959 // InstrInfo.td as soon as Requires clause is supported properly
6060 // for InstAlias.
6161 if (MI->getOpcode() == X86::CALLpcrel32 &&
62 (getAvailableFeatures() & X86::Mode64Bit) != 0) {
62 getAvailableFeatures()[X86::Mode64Bit]) {
6363 OS << "\tcallq\t";
6464 printPCRelImm(MI, 0, OS);
6565 }
4141 ~X86MCCodeEmitter() {}
4242
4343 bool is64BitMode(const MCSubtargetInfo &STI) const {
44 return (STI.getFeatureBits() & X86::Mode64Bit) != 0;
44 return STI.getFeatureBits()[X86::Mode64Bit];
4545 }
4646
4747 bool is32BitMode(const MCSubtargetInfo &STI) const {
48 return (STI.getFeatureBits() & X86::Mode32Bit) != 0;
48 return STI.getFeatureBits()[X86::Mode32Bit];
4949 }
5050
5151 bool is16BitMode(const MCSubtargetInfo &STI) const {
52 return (STI.getFeatureBits() & X86::Mode16Bit) != 0;
52 return STI.getFeatureBits()[X86::Mode16Bit];
5353 }
5454
5555 /// Is16BitMemOperand - Return true if the specified instruction has
22412241 Info.AsmParser->getValueAsString("AsmParserClassName");
22422242
22432243 OS << "uint64_t " << Info.Target.getName() << ClassName << "::\n"
2244 << "ComputeAvailableFeatures(uint64_t FB) const {\n";
2244 << "ComputeAvailableFeatures(const FeatureBitset& FB) const {\n";
22452245 OS << " uint64_t Features = 0;\n";
22462246 for (const auto &SF : Info.SubtargetFeatures) {
22472247 const SubtargetFeatureInfo &SFI = SF.second;
22632263 Cond = Cond.substr(1);
22642264 }
22652265
2266 OS << "((FB & " << Info.Target.getName() << "::" << Cond << ")";
2266 OS << "(";
22672267 if (Neg)
2268 OS << " == 0";
2269 else
2270 OS << " != 0";
2271 OS << ")";
2268 OS << "!";
2269 OS << "FB[" << Info.Target.getName() << "::" << Cond << "])";
22722270
22732271 if (Comma.second.empty())
22742272 break;
26382636 OS << "#undef GET_ASSEMBLER_HEADER\n";
26392637 OS << " // This should be included into the middle of the declaration of\n";
26402638 OS << " // your subclasses implementation of MCTargetAsmParser.\n";
2641 OS << " uint64_t ComputeAvailableFeatures(uint64_t FeatureBits) const;\n";
2639 OS << " uint64_t ComputeAvailableFeatures(const FeatureBitset& FB) const;\n";
26422640 OS << " void convertToMCInst(unsigned Kind, MCInst &Inst, "
26432641 << "unsigned Opcode,\n"
26442642 << " const OperandVector "
847847 // The predicate function is just a big switch statement based on the
848848 // input predicate index.
849849 OS.indent(Indentation) << "static bool checkDecoderPredicate(unsigned Idx, "
850 << "uint64_t Bits) {\n";
850 << "const FeatureBitset& Bits) {\n";
851851 Indentation += 2;
852852 if (!Predicates.empty()) {
853853 OS.indent(Indentation) << "switch (Idx) {\n";
11011101 static void emitSinglePredicateMatch(raw_ostream &o, StringRef str,
11021102 const std::string &PredicateNamespace) {
11031103 if (str[0] == '!')
1104 o << "!(Bits & " << PredicateNamespace << "::"
1105 << str.slice(1,str.size()) << ")";
1104 o << "!Bits[" << PredicateNamespace << "::"
1105 << str.slice(1,str.size()) << "]";
11061106 else
1107 o << "(Bits & " << PredicateNamespace << "::" << str << ")";
1107 o << "Bits[" << PredicateNamespace << "::" << str << "]";
11081108 }
11091109
11101110 bool FilterChooser::emitPredicateMatch(raw_ostream &o, unsigned &Indentation,
20092009 << " InsnType insn, uint64_t Address,\n"
20102010 << " const void *DisAsm,\n"
20112011 << " const MCSubtargetInfo &STI) {\n"
2012 << " uint64_t Bits = STI.getFeatureBits();\n"
2012 << " const FeatureBitset& Bits = STI.getFeatureBits();\n"
20132013 << "\n"
20142014 << " const uint8_t *Ptr = DecodeTable;\n"
20152015 << " uint32_t CurFieldValue = 0;\n"
546546 CodeGenTarget &Target = CDP.getTargetInfo();
547547 if (Inst.HasComplexDeprecationPredicate)
548548 // Emit a function pointer to the complex predicate method.
549 OS << ",0"
549 OS << ", { } "
550550 << ",&get" << Inst.DeprecatedReason << "DeprecationInfo";
551551 else if (!Inst.DeprecatedReason.empty())
552552 // Emit the Subtarget feature.
553 OS << "," << Target.getInstNamespace() << "::" << Inst.DeprecatedReason
554 << ",nullptr";
553 OS << ", { " << Target.getInstNamespace() << "::" << Inst.DeprecatedReason
554 << "} ,nullptr";
555555 else
556556 // Instruction isn't deprecated.
557 OS << ",0,nullptr";
557 OS << ", { } ,nullptr";
558558
559559 OS << " }, // Inst #" << Num << " = " << Inst.TheDef->getName() << "\n";
560560 }
1515 #include "llvm/ADT/STLExtras.h"
1616 #include "llvm/ADT/StringExtras.h"
1717 #include "llvm/MC/MCInstrItineraries.h"
18 #include "llvm/MC/SubtargetFeature.h"
1819 #include "llvm/Support/Debug.h"
1920 #include "llvm/Support/Format.h"
2021 #include "llvm/TableGen/Error.h"
6162 CodeGenSchedModels &SchedModels;
6263 std::string Target;
6364
64 void Enumeration(raw_ostream &OS, const char *ClassName, bool isBits);
65 void Enumeration(raw_ostream &OS, const char *ClassName);
6566 unsigned FeatureKeyValues(raw_ostream &OS);
6667 unsigned CPUKeyValues(raw_ostream &OS);
6768 void FormItineraryStageString(const std::string &Names,
111112 // Enumeration - Emit the specified class as an enumeration.
112113 //
113114 void SubtargetEmitter::Enumeration(raw_ostream &OS,
114 const char *ClassName,
115 bool isBits) {
115 const char *ClassName) {
116116 // Get all records of class and sort
117117 std::vector DefList = Records.getAllDerivedDefinitions(ClassName);
118118 std::sort(DefList.begin(), DefList.end(), LessRecord());
120120 unsigned N = DefList.size();
121121 if (N == 0)
122122 return;
123 if (N > 64) {
124 errs() << "Too many (> 64) subtarget features!\n";
123 if (N > MAX_SUBTARGET_FEATURES) {
124 errs() << "Too many subtarget features! Bump MAX_SUBTARGET_FEATURES.";
125125 exit(1);
126126 }
127127
128128 OS << "namespace " << Target << " {\n";
129129
130 // For bit flag enumerations with more than 32 items, emit constants.
131 // Emit an enum for everything else.
132 if (isBits && N > 32) {
133 // For each record
134 for (unsigned i = 0; i < N; i++) {
135 // Next record
136 Record *Def = DefList[i];
137
138 // Get and emit name and expression (1 << i)
139 OS << " const uint64_t " << Def->getName() << " = 1ULL << " << i << ";\n";
140 }
141 } else {
142 // Open enumeration
143 OS << "enum {\n";
144
145 // For each record
146 for (unsigned i = 0; i < N;) {
147 // Next record
148 Record *Def = DefList[i];
149
150 // Get and emit name
151 OS << " " << Def->getName();
152
153 // If bit flags then emit expression (1 << i)
154 if (isBits) OS << " = " << " 1ULL << " << i;
155
156 // Depending on 'if more in the list' emit comma
157 if (++i < N) OS << ",";
158
159 OS << "\n";
160 }
161
162 // Close enumeration
163 OS << "};\n";
164 }
165
166 OS << "}\n";
130 // Open enumeration
131 OS << "enum {\n";
132
133 // For each record
134 for (unsigned i = 0; i < N;) {
135 // Next record
136 Record *Def = DefList[i];
137
138 // Get and emit name
139 OS << " " << Def->getName() << " = " << i;
140 if (++i < N) OS << ",";
141
142 OS << "\n";
143 }
144
145 // Close enumeration and namespace
146 OS << "};\n}\n";
167147 }
168148
169149 //
197177
198178 if (CommandLineName.empty()) continue;
199179
200 // Emit as { "feature", "description", featureEnum, i1 | i2 | ... | in }
180 // Emit as { "feature", "description", { featureEnum }, { i1 , i2 , ... , in } }
201181 OS << " { "
202182 << "\"" << CommandLineName << "\", "
203183 << "\"" << Desc << "\", "
204 << Target << "::" << Name << ", ";
184 << "{ " << Target << "::" << Name << " }, ";
205185
206186 const std::vector &ImpliesList =
207187 Feature->getValueAsListOfDefs("Implies");
208188
209189 if (ImpliesList.empty()) {
210 OS << "0ULL";
190 OS << "{ }";
211191 } else {
192 OS << "{ ";
212193 for (unsigned j = 0, M = ImpliesList.size(); j < M;) {
213194 OS << Target << "::" << ImpliesList[j]->getName();
214 if (++j < M) OS << " | ";
215 }
195 if (++j < M) OS << ", ";
196 }
197 OS << " }";
216198 }
217199
218200 OS << " }";
254236 const std::vector &FeatureList =
255237 Processor->getValueAsListOfDefs("Features");
256238
257 // Emit as { "cpu", "description", f1 | f2 | ... fn },
239 // Emit as { "cpu", "description", { f1 , f2 , ... fn } },
258240 OS << " { "
259241 << "\"" << Name << "\", "
260242 << "\"Select the " << Name << " processor\", ";
261243
262244 if (FeatureList.empty()) {
263 OS << "0ULL";
245 OS << "{ }";
264246 } else {
247 OS << "{ ";
265248 for (unsigned j = 0, M = FeatureList.size(); j < M;) {
266249 OS << Target << "::" << FeatureList[j]->getName();
267 if (++j < M) OS << " | ";
268 }
269 }
270
271 // The "0" is for the "implies" section of this data structure.
272 OS << ", 0ULL }";
250 if (++j < M) OS << ", ";
251 }
252 OS << " }";
253 }
254
255 // The { } is for the "implies" section of this data structure.
256 OS << ", { } }";
273257
274258 // Depending on 'if more in the list' emit comma
275259 if (++i < N) OS << ",";
13971381 }
13981382
13991383 OS << " InitMCProcessorInfo(CPU, FS);\n"
1400 << " uint64_t Bits = getFeatureBits();\n";
1384 << " const FeatureBitset& Bits = getFeatureBits();\n";
14011385
14021386 for (unsigned i = 0; i < Features.size(); i++) {
14031387 // Next record
14071391 const std::string &Attribute = R->getValueAsString("Attribute");
14081392
14091393 if (Value=="true" || Value=="false")
1410 OS << " if ((Bits & " << Target << "::"
1411 << Instance << ") != 0) "
1394 OS << " if (Bits[" << Target << "::"
1395 << Instance << "]) "
14121396 << Attribute << " = " << Value << ";\n";
14131397 else
1414 OS << " if ((Bits & " << Target << "::"
1415 << Instance << ") != 0 && "
1398 OS << " if (Bits[" << Target << "::"
1399 << Instance << "] && "
14161400 << Attribute << " < " << Value << ") "
14171401 << Attribute << " = " << Value << ";\n";
14181402 }
14301414 OS << "#undef GET_SUBTARGETINFO_ENUM\n";
14311415
14321416 OS << "namespace llvm {\n";
1433 Enumeration(OS, "SubtargetFeature", true);
1417 Enumeration(OS, "SubtargetFeature");
14341418 OS << "} // End llvm namespace \n";
14351419 OS << "#endif // GET_SUBTARGETINFO_ENUM\n\n";
14361420