Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/utils/TableGen/Common/CodeGenInstAlias.cpp
35290 views
1
//===- CodeGenInstAlias.cpp - CodeGen InstAlias Class Wrapper -------------===//
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 the CodeGenInstAlias class.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "CodeGenInstAlias.h"
14
#include "CodeGenInstruction.h"
15
#include "CodeGenRegisters.h"
16
#include "CodeGenTarget.h"
17
#include "llvm/ADT/StringMap.h"
18
#include "llvm/TableGen/Error.h"
19
#include "llvm/TableGen/Record.h"
20
21
using namespace llvm;
22
23
/// tryAliasOpMatch - This is a helper function for the CodeGenInstAlias
24
/// constructor. It checks if an argument in an InstAlias pattern matches
25
/// the corresponding operand of the instruction. It returns true on a
26
/// successful match, with ResOp set to the result operand to be used.
27
bool CodeGenInstAlias::tryAliasOpMatch(DagInit *Result, unsigned AliasOpNo,
28
Record *InstOpRec, bool hasSubOps,
29
ArrayRef<SMLoc> Loc, CodeGenTarget &T,
30
ResultOperand &ResOp) {
31
Init *Arg = Result->getArg(AliasOpNo);
32
DefInit *ADI = dyn_cast<DefInit>(Arg);
33
Record *ResultRecord = ADI ? ADI->getDef() : nullptr;
34
35
if (ADI && ADI->getDef() == InstOpRec) {
36
// If the operand is a record, it must have a name, and the record type
37
// must match up with the instruction's argument type.
38
if (!Result->getArgName(AliasOpNo))
39
PrintFatalError(Loc, "result argument #" + Twine(AliasOpNo) +
40
" must have a name!");
41
ResOp = ResultOperand(std::string(Result->getArgNameStr(AliasOpNo)),
42
ResultRecord);
43
return true;
44
}
45
46
// For register operands, the source register class can be a subclass
47
// of the instruction register class, not just an exact match.
48
if (InstOpRec->isSubClassOf("RegisterOperand"))
49
InstOpRec = InstOpRec->getValueAsDef("RegClass");
50
51
if (ADI && ADI->getDef()->isSubClassOf("RegisterOperand"))
52
ADI = ADI->getDef()->getValueAsDef("RegClass")->getDefInit();
53
54
if (ADI && ADI->getDef()->isSubClassOf("RegisterClass")) {
55
if (!InstOpRec->isSubClassOf("RegisterClass"))
56
return false;
57
if (!T.getRegisterClass(InstOpRec).hasSubClass(
58
&T.getRegisterClass(ADI->getDef())))
59
return false;
60
ResOp = ResultOperand(std::string(Result->getArgNameStr(AliasOpNo)),
61
ResultRecord);
62
return true;
63
}
64
65
// Handle explicit registers.
66
if (ADI && ADI->getDef()->isSubClassOf("Register")) {
67
if (InstOpRec->isSubClassOf("OptionalDefOperand")) {
68
DagInit *DI = InstOpRec->getValueAsDag("MIOperandInfo");
69
// The operand info should only have a single (register) entry. We
70
// want the register class of it.
71
InstOpRec = cast<DefInit>(DI->getArg(0))->getDef();
72
}
73
74
if (!InstOpRec->isSubClassOf("RegisterClass"))
75
return false;
76
77
if (!T.getRegisterClass(InstOpRec).contains(
78
T.getRegBank().getReg(ADI->getDef())))
79
PrintFatalError(Loc, "fixed register " + ADI->getDef()->getName() +
80
" is not a member of the " +
81
InstOpRec->getName() + " register class!");
82
83
if (Result->getArgName(AliasOpNo))
84
PrintFatalError(Loc, "result fixed register argument must "
85
"not have a name!");
86
87
ResOp = ResultOperand(ResultRecord);
88
return true;
89
}
90
91
// Handle "zero_reg" for optional def operands.
92
if (ADI && ADI->getDef()->getName() == "zero_reg") {
93
94
// Check if this is an optional def.
95
// Tied operands where the source is a sub-operand of a complex operand
96
// need to represent both operands in the alias destination instruction.
97
// Allow zero_reg for the tied portion. This can and should go away once
98
// the MC representation of things doesn't use tied operands at all.
99
// if (!InstOpRec->isSubClassOf("OptionalDefOperand"))
100
// throw TGError(Loc, "reg0 used for result that is not an "
101
// "OptionalDefOperand!");
102
103
ResOp = ResultOperand(static_cast<Record *>(nullptr));
104
return true;
105
}
106
107
// Literal integers.
108
if (IntInit *II = dyn_cast<IntInit>(Arg)) {
109
if (hasSubOps || !InstOpRec->isSubClassOf("Operand"))
110
return false;
111
// Integer arguments can't have names.
112
if (Result->getArgName(AliasOpNo))
113
PrintFatalError(Loc, "result argument #" + Twine(AliasOpNo) +
114
" must not have a name!");
115
ResOp = ResultOperand(II->getValue());
116
return true;
117
}
118
119
// Bits<n> (also used for 0bxx literals)
120
if (BitsInit *BI = dyn_cast<BitsInit>(Arg)) {
121
if (hasSubOps || !InstOpRec->isSubClassOf("Operand"))
122
return false;
123
if (!BI->isComplete())
124
return false;
125
// Convert the bits init to an integer and use that for the result.
126
IntInit *II = dyn_cast_or_null<IntInit>(
127
BI->convertInitializerTo(IntRecTy::get(BI->getRecordKeeper())));
128
if (!II)
129
return false;
130
ResOp = ResultOperand(II->getValue());
131
return true;
132
}
133
134
// If both are Operands with the same MVT, allow the conversion. It's
135
// up to the user to make sure the values are appropriate, just like
136
// for isel Pat's.
137
if (InstOpRec->isSubClassOf("Operand") && ADI &&
138
ADI->getDef()->isSubClassOf("Operand")) {
139
// FIXME: What other attributes should we check here? Identical
140
// MIOperandInfo perhaps?
141
if (InstOpRec->getValueInit("Type") != ADI->getDef()->getValueInit("Type"))
142
return false;
143
ResOp = ResultOperand(std::string(Result->getArgNameStr(AliasOpNo)),
144
ADI->getDef());
145
return true;
146
}
147
148
return false;
149
}
150
151
unsigned CodeGenInstAlias::ResultOperand::getMINumOperands() const {
152
if (!isRecord())
153
return 1;
154
155
Record *Rec = getRecord();
156
if (!Rec->isSubClassOf("Operand"))
157
return 1;
158
159
DagInit *MIOpInfo = Rec->getValueAsDag("MIOperandInfo");
160
if (MIOpInfo->getNumArgs() == 0) {
161
// Unspecified, so it defaults to 1
162
return 1;
163
}
164
165
return MIOpInfo->getNumArgs();
166
}
167
168
CodeGenInstAlias::CodeGenInstAlias(Record *R, CodeGenTarget &T) : TheDef(R) {
169
Result = R->getValueAsDag("ResultInst");
170
AsmString = std::string(R->getValueAsString("AsmString"));
171
172
// Verify that the root of the result is an instruction.
173
DefInit *DI = dyn_cast<DefInit>(Result->getOperator());
174
if (!DI || !DI->getDef()->isSubClassOf("Instruction"))
175
PrintFatalError(R->getLoc(),
176
"result of inst alias should be an instruction");
177
178
ResultInst = &T.getInstruction(DI->getDef());
179
180
// NameClass - If argument names are repeated, we need to verify they have
181
// the same class.
182
StringMap<Record *> NameClass;
183
for (unsigned i = 0, e = Result->getNumArgs(); i != e; ++i) {
184
DefInit *ADI = dyn_cast<DefInit>(Result->getArg(i));
185
if (!ADI || !Result->getArgName(i))
186
continue;
187
// Verify we don't have something like: (someinst GR16:$foo, GR32:$foo)
188
// $foo can exist multiple times in the result list, but it must have the
189
// same type.
190
Record *&Entry = NameClass[Result->getArgNameStr(i)];
191
if (Entry && Entry != ADI->getDef())
192
PrintFatalError(R->getLoc(), "result value $" + Result->getArgNameStr(i) +
193
" is both " + Entry->getName() +
194
" and " + ADI->getDef()->getName() +
195
"!");
196
Entry = ADI->getDef();
197
}
198
199
// Decode and validate the arguments of the result.
200
unsigned AliasOpNo = 0;
201
for (unsigned i = 0, e = ResultInst->Operands.size(); i != e; ++i) {
202
203
// Tied registers don't have an entry in the result dag unless they're part
204
// of a complex operand, in which case we include them anyways, as we
205
// don't have any other way to specify the whole operand.
206
if (ResultInst->Operands[i].MINumOperands == 1 &&
207
ResultInst->Operands[i].getTiedRegister() != -1) {
208
// Tied operands of different RegisterClass should be explicit within an
209
// instruction's syntax and so cannot be skipped.
210
int TiedOpNum = ResultInst->Operands[i].getTiedRegister();
211
if (ResultInst->Operands[i].Rec->getName() ==
212
ResultInst->Operands[TiedOpNum].Rec->getName())
213
continue;
214
}
215
216
if (AliasOpNo >= Result->getNumArgs())
217
PrintFatalError(R->getLoc(), "not enough arguments for instruction!");
218
219
Record *InstOpRec = ResultInst->Operands[i].Rec;
220
unsigned NumSubOps = ResultInst->Operands[i].MINumOperands;
221
ResultOperand ResOp(static_cast<int64_t>(0));
222
if (tryAliasOpMatch(Result, AliasOpNo, InstOpRec, (NumSubOps > 1),
223
R->getLoc(), T, ResOp)) {
224
// If this is a simple operand, or a complex operand with a custom match
225
// class, then we can match is verbatim.
226
if (NumSubOps == 1 || (InstOpRec->getValue("ParserMatchClass") &&
227
InstOpRec->getValueAsDef("ParserMatchClass")
228
->getValueAsString("Name") != "Imm")) {
229
ResultOperands.push_back(ResOp);
230
ResultInstOperandIndex.push_back(std::pair(i, -1));
231
++AliasOpNo;
232
233
// Otherwise, we need to match each of the suboperands individually.
234
} else {
235
DagInit *MIOI = ResultInst->Operands[i].MIOperandInfo;
236
for (unsigned SubOp = 0; SubOp != NumSubOps; ++SubOp) {
237
Record *SubRec = cast<DefInit>(MIOI->getArg(SubOp))->getDef();
238
239
// Take care to instantiate each of the suboperands with the correct
240
// nomenclature: $foo.bar
241
ResultOperands.emplace_back(
242
Result->getArgName(AliasOpNo)->getAsUnquotedString() + "." +
243
MIOI->getArgName(SubOp)->getAsUnquotedString(),
244
SubRec);
245
ResultInstOperandIndex.push_back(std::pair(i, SubOp));
246
}
247
++AliasOpNo;
248
}
249
continue;
250
}
251
252
// If the argument did not match the instruction operand, and the operand
253
// is composed of multiple suboperands, try matching the suboperands.
254
if (NumSubOps > 1) {
255
DagInit *MIOI = ResultInst->Operands[i].MIOperandInfo;
256
for (unsigned SubOp = 0; SubOp != NumSubOps; ++SubOp) {
257
if (AliasOpNo >= Result->getNumArgs())
258
PrintFatalError(R->getLoc(), "not enough arguments for instruction!");
259
Record *SubRec = cast<DefInit>(MIOI->getArg(SubOp))->getDef();
260
if (tryAliasOpMatch(Result, AliasOpNo, SubRec, false, R->getLoc(), T,
261
ResOp)) {
262
ResultOperands.push_back(ResOp);
263
ResultInstOperandIndex.push_back(std::pair(i, SubOp));
264
++AliasOpNo;
265
} else {
266
PrintFatalError(
267
R->getLoc(),
268
"result argument #" + Twine(AliasOpNo) +
269
" does not match instruction operand class " +
270
(SubOp == 0 ? InstOpRec->getName() : SubRec->getName()));
271
}
272
}
273
continue;
274
}
275
PrintFatalError(R->getLoc(),
276
"result argument #" + Twine(AliasOpNo) +
277
" does not match instruction operand class " +
278
InstOpRec->getName());
279
}
280
281
if (AliasOpNo != Result->getNumArgs())
282
PrintFatalError(R->getLoc(), "too many operands for instruction!");
283
}
284
285