1779d98e1SKrzysztof Parzyszek //===--- CodeGenHwModes.cpp -----------------------------------------------===//
2779d98e1SKrzysztof Parzyszek //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6779d98e1SKrzysztof Parzyszek //
7779d98e1SKrzysztof Parzyszek //===----------------------------------------------------------------------===//
8779d98e1SKrzysztof Parzyszek // Classes to parse and store HW mode information for instruction selection
9779d98e1SKrzysztof Parzyszek //===----------------------------------------------------------------------===//
10779d98e1SKrzysztof Parzyszek
11779d98e1SKrzysztof Parzyszek #include "CodeGenHwModes.h"
12779d98e1SKrzysztof Parzyszek #include "llvm/Support/Debug.h"
13779d98e1SKrzysztof Parzyszek #include "llvm/Support/raw_ostream.h"
14779d98e1SKrzysztof Parzyszek #include "llvm/TableGen/Error.h"
15779d98e1SKrzysztof Parzyszek #include "llvm/TableGen/Record.h"
16779d98e1SKrzysztof Parzyszek
17779d98e1SKrzysztof Parzyszek using namespace llvm;
18779d98e1SKrzysztof Parzyszek
19779d98e1SKrzysztof Parzyszek StringRef CodeGenHwModes::DefaultModeName = "DefaultMode";
20779d98e1SKrzysztof Parzyszek
HwMode(Record * R)21779d98e1SKrzysztof Parzyszek HwMode::HwMode(Record *R) {
22779d98e1SKrzysztof Parzyszek Name = R->getName();
23*adcd0268SBenjamin Kramer Features = std::string(R->getValueAsString("Features"));
24779d98e1SKrzysztof Parzyszek }
25779d98e1SKrzysztof Parzyszek
26779d98e1SKrzysztof Parzyszek LLVM_DUMP_METHOD
dump() const27779d98e1SKrzysztof Parzyszek void HwMode::dump() const {
28779d98e1SKrzysztof Parzyszek dbgs() << Name << ": " << Features << '\n';
29779d98e1SKrzysztof Parzyszek }
30779d98e1SKrzysztof Parzyszek
HwModeSelect(Record * R,CodeGenHwModes & CGH)31779d98e1SKrzysztof Parzyszek HwModeSelect::HwModeSelect(Record *R, CodeGenHwModes &CGH) {
32779d98e1SKrzysztof Parzyszek std::vector<Record*> Modes = R->getValueAsListOfDefs("Modes");
33779d98e1SKrzysztof Parzyszek std::vector<Record*> Objects = R->getValueAsListOfDefs("Objects");
34779d98e1SKrzysztof Parzyszek if (Modes.size() != Objects.size()) {
35779d98e1SKrzysztof Parzyszek PrintError(R->getLoc(), "in record " + R->getName() +
36779d98e1SKrzysztof Parzyszek " derived from HwModeSelect: the lists Modes and Objects should "
37779d98e1SKrzysztof Parzyszek "have the same size");
38779d98e1SKrzysztof Parzyszek report_fatal_error("error in target description.");
39779d98e1SKrzysztof Parzyszek }
40779d98e1SKrzysztof Parzyszek for (unsigned i = 0, e = Modes.size(); i != e; ++i) {
41779d98e1SKrzysztof Parzyszek unsigned ModeId = CGH.getHwModeId(Modes[i]->getName());
42779d98e1SKrzysztof Parzyszek Items.push_back(std::make_pair(ModeId, Objects[i]));
43779d98e1SKrzysztof Parzyszek }
44779d98e1SKrzysztof Parzyszek }
45779d98e1SKrzysztof Parzyszek
46779d98e1SKrzysztof Parzyszek LLVM_DUMP_METHOD
dump() const47779d98e1SKrzysztof Parzyszek void HwModeSelect::dump() const {
48779d98e1SKrzysztof Parzyszek dbgs() << '{';
49779d98e1SKrzysztof Parzyszek for (const PairType &P : Items)
50779d98e1SKrzysztof Parzyszek dbgs() << " (" << P.first << ',' << P.second->getName() << ')';
51779d98e1SKrzysztof Parzyszek dbgs() << " }\n";
52779d98e1SKrzysztof Parzyszek }
53779d98e1SKrzysztof Parzyszek
CodeGenHwModes(RecordKeeper & RK)54779d98e1SKrzysztof Parzyszek CodeGenHwModes::CodeGenHwModes(RecordKeeper &RK) : Records(RK) {
55779d98e1SKrzysztof Parzyszek std::vector<Record*> MRs = Records.getAllDerivedDefinitions("HwMode");
56779d98e1SKrzysztof Parzyszek // The default mode needs a definition in the .td sources for TableGen
57779d98e1SKrzysztof Parzyszek // to accept references to it. We need to ignore the definition here.
58779d98e1SKrzysztof Parzyszek for (auto I = MRs.begin(), E = MRs.end(); I != E; ++I) {
59779d98e1SKrzysztof Parzyszek if ((*I)->getName() != DefaultModeName)
60779d98e1SKrzysztof Parzyszek continue;
61779d98e1SKrzysztof Parzyszek MRs.erase(I);
62779d98e1SKrzysztof Parzyszek break;
63779d98e1SKrzysztof Parzyszek }
64779d98e1SKrzysztof Parzyszek
65779d98e1SKrzysztof Parzyszek for (Record *R : MRs) {
66779d98e1SKrzysztof Parzyszek Modes.emplace_back(R);
67779d98e1SKrzysztof Parzyszek unsigned NewId = Modes.size();
68779d98e1SKrzysztof Parzyszek ModeIds.insert(std::make_pair(Modes[NewId-1].Name, NewId));
69779d98e1SKrzysztof Parzyszek }
70779d98e1SKrzysztof Parzyszek
71779d98e1SKrzysztof Parzyszek std::vector<Record*> MSs = Records.getAllDerivedDefinitions("HwModeSelect");
72779d98e1SKrzysztof Parzyszek for (Record *R : MSs) {
73779d98e1SKrzysztof Parzyszek auto P = ModeSelects.emplace(std::make_pair(R, HwModeSelect(R, *this)));
74779d98e1SKrzysztof Parzyszek assert(P.second);
75779d98e1SKrzysztof Parzyszek (void)P;
76779d98e1SKrzysztof Parzyszek }
77779d98e1SKrzysztof Parzyszek }
78779d98e1SKrzysztof Parzyszek
getHwModeId(StringRef Name) const79779d98e1SKrzysztof Parzyszek unsigned CodeGenHwModes::getHwModeId(StringRef Name) const {
80779d98e1SKrzysztof Parzyszek if (Name == DefaultModeName)
81779d98e1SKrzysztof Parzyszek return DefaultMode;
82779d98e1SKrzysztof Parzyszek auto F = ModeIds.find(Name);
83779d98e1SKrzysztof Parzyszek assert(F != ModeIds.end() && "Unknown mode name");
84779d98e1SKrzysztof Parzyszek return F->second;
85779d98e1SKrzysztof Parzyszek }
86779d98e1SKrzysztof Parzyszek
getHwModeSelect(Record * R) const87779d98e1SKrzysztof Parzyszek const HwModeSelect &CodeGenHwModes::getHwModeSelect(Record *R) const {
88779d98e1SKrzysztof Parzyszek auto F = ModeSelects.find(R);
89779d98e1SKrzysztof Parzyszek assert(F != ModeSelects.end() && "Record is not a \"mode select\"");
90779d98e1SKrzysztof Parzyszek return F->second;
91779d98e1SKrzysztof Parzyszek }
92779d98e1SKrzysztof Parzyszek
93779d98e1SKrzysztof Parzyszek LLVM_DUMP_METHOD
dump() const94779d98e1SKrzysztof Parzyszek void CodeGenHwModes::dump() const {
95779d98e1SKrzysztof Parzyszek dbgs() << "Modes: {\n";
96779d98e1SKrzysztof Parzyszek for (const HwMode &M : Modes) {
97779d98e1SKrzysztof Parzyszek dbgs() << " ";
98779d98e1SKrzysztof Parzyszek M.dump();
99779d98e1SKrzysztof Parzyszek }
100779d98e1SKrzysztof Parzyszek dbgs() << "}\n";
101779d98e1SKrzysztof Parzyszek
102779d98e1SKrzysztof Parzyszek dbgs() << "ModeIds: {\n";
103779d98e1SKrzysztof Parzyszek for (const auto &P : ModeIds)
104779d98e1SKrzysztof Parzyszek dbgs() << " " << P.first() << " -> " << P.second << '\n';
105779d98e1SKrzysztof Parzyszek dbgs() << "}\n";
106779d98e1SKrzysztof Parzyszek
107779d98e1SKrzysztof Parzyszek dbgs() << "ModeSelects: {\n";
108779d98e1SKrzysztof Parzyszek for (const auto &P : ModeSelects) {
109779d98e1SKrzysztof Parzyszek dbgs() << " " << P.first->getName() << " -> ";
110779d98e1SKrzysztof Parzyszek P.second.dump();
111779d98e1SKrzysztof Parzyszek }
112779d98e1SKrzysztof Parzyszek dbgs() << "}\n";
113779d98e1SKrzysztof Parzyszek }
114