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