1//===-- TargetParser - Parser for target features ---------------*- 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// This file implements a target parser to recognise hardware features such as
10// FPU/CPU/ARCH names as well as specific support such as HDIV, etc.
11//
12//===----------------------------------------------------------------------===//
13
14#include "llvm/TargetParser/TargetParser.h"
15#include "llvm/ADT/ArrayRef.h"
16
17using namespace llvm;
18
19/// Find KV in array using binary search.
20static const BasicSubtargetSubTypeKV *
21find(StringRef S, ArrayRef<BasicSubtargetSubTypeKV> A) {
22 // Binary search the array
23 const BasicSubtargetSubTypeKV *F = llvm::lower_bound(Range&: A, Value&: S);
24 // If not found then return NULL
25 if (F == A.end() || StringRef(F->Key) != S)
26 return nullptr;
27 // Return the found array item
28 return F;
29}
30
31/// For each feature that is (transitively) implied by this feature, set it.
32static void setImpliedBits(FeatureBitset &Bits, const FeatureBitset &Implies,
33 ArrayRef<BasicSubtargetFeatureKV> FeatureTable) {
34 // OR the Implies bits in outside the loop. This allows the Implies for CPUs
35 // which might imply features not in FeatureTable to use this.
36 Bits |= Implies;
37 for (const auto &FE : FeatureTable)
38 if (Implies.test(I: FE.Value))
39 setImpliedBits(Bits, Implies: FE.Implies.getAsBitset(), FeatureTable);
40}
41
42std::optional<llvm::StringMap<bool>> llvm::getCPUDefaultTargetFeatures(
43 StringRef CPU, ArrayRef<BasicSubtargetSubTypeKV> ProcDesc,
44 ArrayRef<BasicSubtargetFeatureKV> ProcFeatures) {
45 if (CPU.empty())
46 return std::nullopt;
47
48 const BasicSubtargetSubTypeKV *CPUEntry = ::find(S: CPU, A: ProcDesc);
49 if (!CPUEntry)
50 return std::nullopt;
51
52 // Set the features implied by this CPU feature if there is a match.
53 FeatureBitset Bits;
54 llvm::StringMap<bool> DefaultFeatures;
55 setImpliedBits(Bits, Implies: CPUEntry->Implies.getAsBitset(), FeatureTable: ProcFeatures);
56
57 [[maybe_unused]] unsigned BitSize = Bits.size();
58 for (const BasicSubtargetFeatureKV &FE : ProcFeatures) {
59 assert(FE.Value < BitSize && "Target Feature is out of range");
60 if (Bits[FE.Value])
61 DefaultFeatures[FE.Key] = true;
62 }
63 return DefaultFeatures;
64}
65