1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
|
//===- CodeGenInstAlias.cpp - CodeGen InstAlias Class Wrapper -------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements the CodeGenInstAlias class.
//
//===----------------------------------------------------------------------===//
#include "CodeGenInstAlias.h"
#include "CodeGenInstruction.h"
#include "CodeGenRegisters.h"
#include "CodeGenTarget.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/Support/Error.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h"
using namespace llvm;
unsigned CodeGenInstAlias::ResultOperand::getMINumOperands() const {
if (!isRecord())
return 1;
const Record *Rec = getRecord();
if (!Rec->isSubClassOf("Operand"))
return 1;
const DagInit *MIOpInfo = Rec->getValueAsDag("MIOperandInfo");
if (MIOpInfo->getNumArgs() == 0) {
// Unspecified, so it defaults to 1
return 1;
}
return MIOpInfo->getNumArgs();
}
using ResultOperand = CodeGenInstAlias::ResultOperand;
static Expected<ResultOperand> matchSimpleOperand(const Init *Arg,
const StringInit *ArgName,
const Record *Op,
const CodeGenTarget &T) {
if (Op->isSubClassOf("RegisterClass") ||
Op->isSubClassOf("RegisterOperand")) {
const Record *OpRC =
Op->isSubClassOf("RegisterClass") ? Op : Op->getValueAsDef("RegClass");
if (const auto *ArgDef = dyn_cast<DefInit>(Arg)) {
const Record *ArgRec = ArgDef->getDef();
// Match 'RegClass:$name' or 'RegOp:$name'.
if (const Record *ArgRC = T.getInitValueAsRegClassLike(Arg)) {
if (ArgRC->isSubClassOf("RegisterClass")) {
if (!T.getRegisterClass(OpRC).hasSubClass(&T.getRegisterClass(ArgRC)))
return createStringError(
"argument register class" + ArgRC->getName() +
" is not a subclass of operand register class " +
OpRC->getName());
if (!ArgName)
return createStringError(
"register class argument must have a name");
}
// TODO: Verify RegClassByHwMode usage
return ResultOperand::createRecord(ArgName->getAsUnquotedString(),
ArgRec);
}
// Match 'Reg'.
if (ArgRec->isSubClassOf("Register")) {
if (!T.getRegisterClass(OpRC).contains(T.getRegBank().getReg(ArgRec)))
return createStringError(
"register argument " + ArgRec->getName() +
" is not a member of operand register class " + OpRC->getName());
if (ArgName)
return createStringError("register argument must not have a name");
return ResultOperand::createRegister(ArgRec);
}
// Match 'zero_reg'.
if (ArgRec->getName() == "zero_reg") {
if (ArgName)
return createStringError("register argument must not have a name");
return ResultOperand::createRegister(nullptr);
}
}
return createStringError("argument must be a subclass of RegisterClass, "
"RegisterOperand, or zero_reg");
}
if (Op->isSubClassOf("Operand")) {
// Match integer or bits.
if (const auto *ArgInt = dyn_cast_or_null<IntInit>(
Arg->convertInitializerTo(IntRecTy::get(Arg->getRecordKeeper())))) {
if (ArgName)
return createStringError("integer argument must not have a name");
return ResultOperand::createImmediate(ArgInt->getValue());
}
// Match a subclass of Operand.
if (const auto *ArgDef = dyn_cast<DefInit>(Arg);
ArgDef && ArgDef->getDef()->isSubClassOf("Operand")) {
if (!ArgName)
return createStringError("argument must have a name");
return ResultOperand::createRecord(ArgName->getAsUnquotedString(),
ArgDef->getDef());
}
return createStringError("argument must be a subclass of Operand");
}
llvm_unreachable("Unknown operand kind");
}
static Expected<ResultOperand> matchComplexOperand(const Init *Arg,
const StringInit *ArgName,
const Record *Op) {
assert(Op->isSubClassOf("Operand"));
const auto *ArgDef = dyn_cast<DefInit>(Arg);
if (!ArgDef || !ArgDef->getDef()->isSubClassOf("Operand"))
return createStringError("argument must be a subclass of Operand");
if (!ArgName)
return createStringError("argument must have a name");
return ResultOperand::createRecord(ArgName->getAsUnquotedString(),
ArgDef->getDef());
}
CodeGenInstAlias::CodeGenInstAlias(const Record *R, const CodeGenTarget &T)
: TheDef(R) {
Result = R->getValueAsDag("ResultInst");
AsmString = R->getValueAsString("AsmString");
// Verify that the root of the result is an instruction.
const DefInit *DI = dyn_cast<DefInit>(Result->getOperator());
if (!DI || !DI->getDef()->isSubClassOf("Instruction"))
PrintFatalError(R->getLoc(),
"result of inst alias should be an instruction");
ResultInst = &T.getInstruction(DI->getDef());
// NameClass - If argument names are repeated, we need to verify they have
// the same class.
StringMap<const Record *> NameClass;
for (unsigned i = 0, e = Result->getNumArgs(); i != e; ++i) {
const DefInit *ADI = dyn_cast<DefInit>(Result->getArg(i));
if (!ADI || !Result->getArgName(i))
continue;
// Verify we don't have something like: (someinst GR16:$foo, GR32:$foo)
// $foo can exist multiple times in the result list, but it must have the
// same type.
const Record *&Entry = NameClass[Result->getArgNameStr(i)];
if (Entry && Entry != ADI->getDef())
PrintFatalError(R->getLoc(), "result value $" + Result->getArgNameStr(i) +
" is both " + Entry->getName() +
" and " + ADI->getDef()->getName() +
"!");
Entry = ADI->getDef();
}
// Decode and validate the arguments of the result.
unsigned ArgIdx = 0;
for (auto [OpIdx, OpInfo] : enumerate(ResultInst->Operands)) {
// Tied registers don't have an entry in the result dag unless they're part
// of a complex operand, in which case we include them anyways, as we
// don't have any other way to specify the whole operand.
if (OpInfo.MINumOperands == 1 && OpInfo.getTiedRegister() != -1) {
// Tied operands of different RegisterClass should be explicit within an
// instruction's syntax and so cannot be skipped.
int TiedOpNum = OpInfo.getTiedRegister();
if (OpInfo.Rec->getName() ==
ResultInst->Operands[TiedOpNum].Rec->getName())
continue;
}
if (ArgIdx >= Result->getNumArgs())
PrintFatalError(R->getLoc(), "not enough arguments for instruction!");
const Record *Op = OpInfo.Rec;
if (Op->isSubClassOf("Operand") && !OpInfo.MIOperandInfo->arg_empty()) {
// Complex operand (a subclass of Operand with non-empty MIOperandInfo).
// The argument can be a DAG or a subclass of Operand.
if (auto *ArgDag = dyn_cast<DagInit>(Result->getArg(ArgIdx))) {
// The argument is a DAG. The operator must be the name of the operand.
if (auto *Operator = dyn_cast<DefInit>(ArgDag->getOperator());
!Operator || Operator->getDef()->getName() != Op->getName())
PrintFatalError(R, "argument #" + Twine(ArgIdx) +
" operator must be " + Op->getName());
// The number of sub-arguments and the number of sub-operands
// must match exactly.
unsigned NumSubOps = OpInfo.MIOperandInfo->getNumArgs();
unsigned NumSubArgs = ArgDag->getNumArgs();
if (NumSubArgs != NumSubOps)
PrintFatalError(R, "argument #" + Twine(ArgIdx) +
" must have exactly " + Twine(NumSubOps) +
" sub-arguments");
// Match sub-operands individually.
for (unsigned SubOpIdx = 0; SubOpIdx != NumSubOps; ++SubOpIdx) {
const Record *SubOp =
cast<DefInit>(OpInfo.MIOperandInfo->getArg(SubOpIdx))->getDef();
Expected<ResultOperand> ResOpOrErr = matchSimpleOperand(
ArgDag->getArg(SubOpIdx), ArgDag->getArgName(SubOpIdx), SubOp, T);
if (!ResOpOrErr)
PrintFatalError(R, "in argument #" + Twine(ArgIdx) + "." +
Twine(SubOpIdx) + ": " +
toString(ResOpOrErr.takeError()));
ResultOperands.push_back(*ResOpOrErr);
ResultInstOperandIndex.emplace_back(OpIdx, SubOpIdx);
}
} else {
// Match complex operand as a whole.
Expected<ResultOperand> ResOpOrErr = matchComplexOperand(
Result->getArg(ArgIdx), Result->getArgName(ArgIdx), Op);
if (!ResOpOrErr)
PrintFatalError(R, "in argument #" + Twine(ArgIdx) + ": " +
toString(ResOpOrErr.takeError()));
ResultOperands.push_back(*ResOpOrErr);
ResultInstOperandIndex.emplace_back(OpIdx, -1);
}
} else {
// Simple operand (RegisterClass, RegisterOperand or Operand with empty
// MIOperandInfo).
Expected<ResultOperand> ResOpOrErr = matchSimpleOperand(
Result->getArg(ArgIdx), Result->getArgName(ArgIdx), Op, T);
if (!ResOpOrErr)
PrintFatalError(R, "in argument #" + Twine(ArgIdx) + ": " +
toString(ResOpOrErr.takeError()));
ResultOperands.push_back(*ResOpOrErr);
ResultInstOperandIndex.emplace_back(OpIdx, -1);
}
ArgIdx++;
}
if (ArgIdx != Result->getNumArgs())
PrintFatalError(R->getLoc(), "too many operands for instruction!");
}
|