| 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 | |
| 22 | using namespace llvm; |
| 23 | |
| 24 | unsigned 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 | |
| 41 | using ResultOperand = CodeGenInstAlias::ResultOperand; |
| 42 | |
| 43 | static Expected<ResultOperand> |
| 44 | matchSimpleOperand(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 | |
| 121 | static 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 | |
| 134 | CodeGenInstAlias::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 | |