1044eb2f6SDimitry Andric //===--- CodeGenHwModes.cpp -----------------------------------------------===//
2044eb2f6SDimitry Andric //
3e6d15924SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e6d15924SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e6d15924SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6044eb2f6SDimitry Andric //
7044eb2f6SDimitry Andric //===----------------------------------------------------------------------===//
8044eb2f6SDimitry Andric // Classes to parse and store HW mode information for instruction selection
9044eb2f6SDimitry Andric //===----------------------------------------------------------------------===//
10044eb2f6SDimitry Andric
11044eb2f6SDimitry Andric #include "CodeGenHwModes.h"
12044eb2f6SDimitry Andric #include "llvm/Support/Debug.h"
13044eb2f6SDimitry Andric #include "llvm/Support/raw_ostream.h"
14044eb2f6SDimitry Andric #include "llvm/TableGen/Error.h"
15044eb2f6SDimitry Andric #include "llvm/TableGen/Record.h"
16044eb2f6SDimitry Andric
17044eb2f6SDimitry Andric using namespace llvm;
18044eb2f6SDimitry Andric
19044eb2f6SDimitry Andric StringRef CodeGenHwModes::DefaultModeName = "DefaultMode";
20044eb2f6SDimitry Andric
HwMode(Record * R)21044eb2f6SDimitry Andric HwMode::HwMode(Record *R) {
22044eb2f6SDimitry Andric Name = R->getName();
23cfca06d7SDimitry Andric Features = std::string(R->getValueAsString("Features"));
247fa27ce4SDimitry Andric
257fa27ce4SDimitry Andric std::vector<Record *> PredicateRecs = R->getValueAsListOfDefs("Predicates");
267fa27ce4SDimitry Andric SmallString<128> PredicateCheck;
277fa27ce4SDimitry Andric raw_svector_ostream OS(PredicateCheck);
287fa27ce4SDimitry Andric ListSeparator LS(" && ");
297fa27ce4SDimitry Andric for (Record *Pred : PredicateRecs) {
307fa27ce4SDimitry Andric StringRef CondString = Pred->getValueAsString("CondString");
317fa27ce4SDimitry Andric if (CondString.empty())
327fa27ce4SDimitry Andric continue;
337fa27ce4SDimitry Andric OS << LS << '(' << CondString << ')';
347fa27ce4SDimitry Andric }
357fa27ce4SDimitry Andric
367fa27ce4SDimitry Andric Predicates = std::string(PredicateCheck);
37044eb2f6SDimitry Andric }
38044eb2f6SDimitry Andric
39044eb2f6SDimitry Andric LLVM_DUMP_METHOD
dump() const40ac9a064cSDimitry Andric void HwMode::dump() const { dbgs() << Name << ": " << Features << '\n'; }
41044eb2f6SDimitry Andric
HwModeSelect(Record * R,CodeGenHwModes & CGH)42044eb2f6SDimitry Andric HwModeSelect::HwModeSelect(Record *R, CodeGenHwModes &CGH) {
43044eb2f6SDimitry Andric std::vector<Record *> Modes = R->getValueAsListOfDefs("Modes");
44044eb2f6SDimitry Andric std::vector<Record *> Objects = R->getValueAsListOfDefs("Objects");
45044eb2f6SDimitry Andric if (Modes.size() != Objects.size()) {
46ac9a064cSDimitry Andric PrintError(
47ac9a064cSDimitry Andric R->getLoc(),
48ac9a064cSDimitry Andric "in record " + R->getName() +
49044eb2f6SDimitry Andric " derived from HwModeSelect: the lists Modes and Objects should "
50044eb2f6SDimitry Andric "have the same size");
51044eb2f6SDimitry Andric report_fatal_error("error in target description.");
52044eb2f6SDimitry Andric }
53044eb2f6SDimitry Andric for (unsigned i = 0, e = Modes.size(); i != e; ++i) {
547fa27ce4SDimitry Andric unsigned ModeId = CGH.getHwModeId(Modes[i]);
55ac9a064cSDimitry Andric Items.push_back(std::pair(ModeId, Objects[i]));
56044eb2f6SDimitry Andric }
57044eb2f6SDimitry Andric }
58044eb2f6SDimitry Andric
59044eb2f6SDimitry Andric LLVM_DUMP_METHOD
dump() const60044eb2f6SDimitry Andric void HwModeSelect::dump() const {
61044eb2f6SDimitry Andric dbgs() << '{';
62044eb2f6SDimitry Andric for (const PairType &P : Items)
63044eb2f6SDimitry Andric dbgs() << " (" << P.first << ',' << P.second->getName() << ')';
64044eb2f6SDimitry Andric dbgs() << " }\n";
65044eb2f6SDimitry Andric }
66044eb2f6SDimitry Andric
CodeGenHwModes(RecordKeeper & RK)67044eb2f6SDimitry Andric CodeGenHwModes::CodeGenHwModes(RecordKeeper &RK) : Records(RK) {
687fa27ce4SDimitry Andric for (Record *R : Records.getAllDerivedDefinitions("HwMode")) {
69044eb2f6SDimitry Andric // The default mode needs a definition in the .td sources for TableGen
70044eb2f6SDimitry Andric // to accept references to it. We need to ignore the definition here.
717fa27ce4SDimitry Andric if (R->getName() == DefaultModeName)
72044eb2f6SDimitry Andric continue;
73044eb2f6SDimitry Andric Modes.emplace_back(R);
74ac9a064cSDimitry Andric ModeIds.insert(std::pair(R, Modes.size()));
75044eb2f6SDimitry Andric }
76044eb2f6SDimitry Andric
77ac9a064cSDimitry Andric assert(Modes.size() <= 32 && "number of HwModes exceeds maximum of 32");
78ac9a064cSDimitry Andric
797fa27ce4SDimitry Andric for (Record *R : Records.getAllDerivedDefinitions("HwModeSelect")) {
80ac9a064cSDimitry Andric auto P = ModeSelects.emplace(std::pair(R, HwModeSelect(R, *this)));
81044eb2f6SDimitry Andric assert(P.second);
82044eb2f6SDimitry Andric (void)P;
83044eb2f6SDimitry Andric }
84044eb2f6SDimitry Andric }
85044eb2f6SDimitry Andric
getHwModeId(Record * R) const867fa27ce4SDimitry Andric unsigned CodeGenHwModes::getHwModeId(Record *R) const {
877fa27ce4SDimitry Andric if (R->getName() == DefaultModeName)
88044eb2f6SDimitry Andric return DefaultMode;
897fa27ce4SDimitry Andric auto F = ModeIds.find(R);
90044eb2f6SDimitry Andric assert(F != ModeIds.end() && "Unknown mode name");
91044eb2f6SDimitry Andric return F->second;
92044eb2f6SDimitry Andric }
93044eb2f6SDimitry Andric
getHwModeSelect(Record * R) const94044eb2f6SDimitry Andric const HwModeSelect &CodeGenHwModes::getHwModeSelect(Record *R) const {
95044eb2f6SDimitry Andric auto F = ModeSelects.find(R);
96044eb2f6SDimitry Andric assert(F != ModeSelects.end() && "Record is not a \"mode select\"");
97044eb2f6SDimitry Andric return F->second;
98044eb2f6SDimitry Andric }
99044eb2f6SDimitry Andric
100044eb2f6SDimitry Andric LLVM_DUMP_METHOD
dump() const101044eb2f6SDimitry Andric void CodeGenHwModes::dump() const {
102044eb2f6SDimitry Andric dbgs() << "Modes: {\n";
103044eb2f6SDimitry Andric for (const HwMode &M : Modes) {
104044eb2f6SDimitry Andric dbgs() << " ";
105044eb2f6SDimitry Andric M.dump();
106044eb2f6SDimitry Andric }
107044eb2f6SDimitry Andric dbgs() << "}\n";
108044eb2f6SDimitry Andric
109044eb2f6SDimitry Andric dbgs() << "ModeIds: {\n";
110044eb2f6SDimitry Andric for (const auto &P : ModeIds)
1117fa27ce4SDimitry Andric dbgs() << " " << P.first->getName() << " -> " << P.second << '\n';
112044eb2f6SDimitry Andric dbgs() << "}\n";
113044eb2f6SDimitry Andric
114044eb2f6SDimitry Andric dbgs() << "ModeSelects: {\n";
115044eb2f6SDimitry Andric for (const auto &P : ModeSelects) {
116044eb2f6SDimitry Andric dbgs() << " " << P.first->getName() << " -> ";
117044eb2f6SDimitry Andric P.second.dump();
118044eb2f6SDimitry Andric }
119044eb2f6SDimitry Andric dbgs() << "}\n";
120044eb2f6SDimitry Andric }
121