| 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(const DagInit *Result, |
| 28 | unsigned AliasOpNo, |
| 29 | const Record *InstOpRec, bool hasSubOps, |
| 30 | ArrayRef<SMLoc> Loc, |
| 31 | const CodeGenTarget &T, |
| 32 | ResultOperand &ResOp) { |
| 33 | const Init *Arg = Result->getArg(Num: AliasOpNo); |
| 34 | const DefInit *ADI = dyn_cast<DefInit>(Val: Arg); |
| 35 | const Record *ResultRecord = ADI ? ADI->getDef() : nullptr; |
| 36 | |
| 37 | if (ADI && ADI->getDef() == InstOpRec) { |
| 38 | // If the operand is a record, it must have a name, and the record type |
| 39 | // must match up with the instruction's argument type. |
| 40 | if (!Result->getArgName(Num: AliasOpNo)) |
| 41 | PrintFatalError(ErrorLoc: Loc, Msg: "result argument #" + Twine(AliasOpNo) + |
| 42 | " must have a name!" ); |
| 43 | ResOp = ResultOperand(Result->getArgNameStr(Num: AliasOpNo).str(), ResultRecord); |
| 44 | return true; |
| 45 | } |
| 46 | |
| 47 | // For register operands, the source register class can be a subclass |
| 48 | // of the instruction register class, not just an exact match. |
| 49 | if (InstOpRec->isSubClassOf(Name: "RegisterOperand" )) |
| 50 | InstOpRec = InstOpRec->getValueAsDef(FieldName: "RegClass" ); |
| 51 | |
| 52 | if (ADI && ADI->getDef()->isSubClassOf(Name: "RegisterOperand" )) |
| 53 | ADI = ADI->getDef()->getValueAsDef(FieldName: "RegClass" )->getDefInit(); |
| 54 | |
| 55 | if (ADI && ADI->getDef()->isSubClassOf(Name: "RegisterClass" )) { |
| 56 | if (!InstOpRec->isSubClassOf(Name: "RegisterClass" )) |
| 57 | return false; |
| 58 | if (!T.getRegisterClass(R: InstOpRec).hasSubClass( |
| 59 | RC: &T.getRegisterClass(R: ADI->getDef()))) |
| 60 | return false; |
| 61 | ResOp = ResultOperand(Result->getArgNameStr(Num: AliasOpNo).str(), ResultRecord); |
| 62 | return true; |
| 63 | } |
| 64 | |
| 65 | // Handle explicit registers. |
| 66 | if (ADI && ADI->getDef()->isSubClassOf(Name: "Register" )) { |
| 67 | if (InstOpRec->isSubClassOf(Name: "OptionalDefOperand" )) { |
| 68 | const DagInit *DI = InstOpRec->getValueAsDag(FieldName: "MIOperandInfo" ); |
| 69 | // The operand info should only have a single (register) entry. We |
| 70 | // want the register class of it. |
| 71 | InstOpRec = cast<DefInit>(Val: DI->getArg(Num: 0))->getDef(); |
| 72 | } |
| 73 | |
| 74 | if (!InstOpRec->isSubClassOf(Name: "RegisterClass" )) |
| 75 | return false; |
| 76 | |
| 77 | if (!T.getRegisterClass(R: InstOpRec).contains( |
| 78 | T.getRegBank().getReg(ADI->getDef()))) |
| 79 | PrintFatalError(ErrorLoc: Loc, Msg: "fixed register " + ADI->getDef()->getName() + |
| 80 | " is not a member of the " + |
| 81 | InstOpRec->getName() + " register class!" ); |
| 82 | |
| 83 | if (Result->getArgName(Num: AliasOpNo)) |
| 84 | PrintFatalError(ErrorLoc: Loc, Msg: "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(nullptr); |
| 104 | return true; |
| 105 | } |
| 106 | |
| 107 | // Literal integers. |
| 108 | if (const IntInit *II = dyn_cast<IntInit>(Val: Arg)) { |
| 109 | if (hasSubOps || !InstOpRec->isSubClassOf(Name: "Operand" )) |
| 110 | return false; |
| 111 | // Integer arguments can't have names. |
| 112 | if (Result->getArgName(Num: AliasOpNo)) |
| 113 | PrintFatalError(ErrorLoc: Loc, Msg: "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 (const BitsInit *BI = dyn_cast<BitsInit>(Val: Arg)) { |
| 121 | if (hasSubOps || !InstOpRec->isSubClassOf(Name: "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 | std::optional<int64_t> Value = BI->convertInitializerToInt(); |
| 127 | if (!Value) |
| 128 | return false; |
| 129 | ResOp = ResultOperand(*Value); |
| 130 | return true; |
| 131 | } |
| 132 | |
| 133 | // If both are Operands with the same MVT, allow the conversion. It's |
| 134 | // up to the user to make sure the values are appropriate, just like |
| 135 | // for isel Pat's. |
| 136 | if (InstOpRec->isSubClassOf(Name: "Operand" ) && ADI && |
| 137 | ADI->getDef()->isSubClassOf(Name: "Operand" )) { |
| 138 | // FIXME: What other attributes should we check here? Identical |
| 139 | // MIOperandInfo perhaps? |
| 140 | if (InstOpRec->getValueInit(FieldName: "Type" ) != ADI->getDef()->getValueInit(FieldName: "Type" )) |
| 141 | return false; |
| 142 | ResOp = |
| 143 | ResultOperand(Result->getArgNameStr(Num: AliasOpNo).str(), ADI->getDef()); |
| 144 | return true; |
| 145 | } |
| 146 | |
| 147 | return false; |
| 148 | } |
| 149 | |
| 150 | unsigned CodeGenInstAlias::ResultOperand::getMINumOperands() const { |
| 151 | if (!isRecord()) |
| 152 | return 1; |
| 153 | |
| 154 | const Record *Rec = getRecord(); |
| 155 | if (!Rec->isSubClassOf(Name: "Operand" )) |
| 156 | return 1; |
| 157 | |
| 158 | const DagInit *MIOpInfo = Rec->getValueAsDag(FieldName: "MIOperandInfo" ); |
| 159 | if (MIOpInfo->getNumArgs() == 0) { |
| 160 | // Unspecified, so it defaults to 1 |
| 161 | return 1; |
| 162 | } |
| 163 | |
| 164 | return MIOpInfo->getNumArgs(); |
| 165 | } |
| 166 | |
| 167 | CodeGenInstAlias::CodeGenInstAlias(const Record *R, const CodeGenTarget &T) |
| 168 | : TheDef(R) { |
| 169 | Result = R->getValueAsDag(FieldName: "ResultInst" ); |
| 170 | AsmString = R->getValueAsString(FieldName: "AsmString" ); |
| 171 | |
| 172 | // Verify that the root of the result is an instruction. |
| 173 | const DefInit *DI = dyn_cast<DefInit>(Val: Result->getOperator()); |
| 174 | if (!DI || !DI->getDef()->isSubClassOf(Name: "Instruction" )) |
| 175 | PrintFatalError(ErrorLoc: R->getLoc(), |
| 176 | Msg: "result of inst alias should be an instruction" ); |
| 177 | |
| 178 | ResultInst = &T.getInstruction(InstRec: DI->getDef()); |
| 179 | |
| 180 | // NameClass - If argument names are repeated, we need to verify they have |
| 181 | // the same class. |
| 182 | StringMap<const Record *> NameClass; |
| 183 | for (unsigned i = 0, e = Result->getNumArgs(); i != e; ++i) { |
| 184 | const DefInit *ADI = dyn_cast<DefInit>(Val: Result->getArg(Num: i)); |
| 185 | if (!ADI || !Result->getArgName(Num: 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 | const Record *&Entry = NameClass[Result->getArgNameStr(Num: i)]; |
| 191 | if (Entry && Entry != ADI->getDef()) |
| 192 | PrintFatalError(ErrorLoc: R->getLoc(), Msg: "result value $" + Result->getArgNameStr(Num: 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 (auto [OpIdx, OpInfo] : enumerate(First&: ResultInst->Operands)) { |
| 202 | // Tied registers don't have an entry in the result dag unless they're part |
| 203 | // of a complex operand, in which case we include them anyways, as we |
| 204 | // don't have any other way to specify the whole operand. |
| 205 | if (OpInfo.MINumOperands == 1 && OpInfo.getTiedRegister() != -1) { |
| 206 | // Tied operands of different RegisterClass should be explicit within an |
| 207 | // instruction's syntax and so cannot be skipped. |
| 208 | int TiedOpNum = OpInfo.getTiedRegister(); |
| 209 | if (OpInfo.Rec->getName() == |
| 210 | ResultInst->Operands[TiedOpNum].Rec->getName()) |
| 211 | continue; |
| 212 | } |
| 213 | |
| 214 | if (AliasOpNo >= Result->getNumArgs()) |
| 215 | PrintFatalError(ErrorLoc: R->getLoc(), Msg: "not enough arguments for instruction!" ); |
| 216 | |
| 217 | const Record *InstOpRec = OpInfo.Rec; |
| 218 | unsigned NumSubOps = OpInfo.MINumOperands; |
| 219 | ResultOperand ResOp(static_cast<int64_t>(0)); |
| 220 | if (tryAliasOpMatch(Result, AliasOpNo, InstOpRec, hasSubOps: (NumSubOps > 1), |
| 221 | Loc: R->getLoc(), T, ResOp)) { |
| 222 | // If this is a simple operand, or a complex operand with a custom match |
| 223 | // class, then we can match is verbatim. |
| 224 | if (NumSubOps == 1 || (InstOpRec->getValue(Name: "ParserMatchClass" ) && |
| 225 | InstOpRec->getValueAsDef(FieldName: "ParserMatchClass" ) |
| 226 | ->getValueAsString(FieldName: "Name" ) != "Imm" )) { |
| 227 | ResultOperands.push_back(x: std::move(ResOp)); |
| 228 | ResultInstOperandIndex.emplace_back(args&: OpIdx, args: -1); |
| 229 | ++AliasOpNo; |
| 230 | |
| 231 | // Otherwise, we need to match each of the suboperands individually. |
| 232 | } else { |
| 233 | const DagInit *MIOI = OpInfo.MIOperandInfo; |
| 234 | for (unsigned SubOp = 0; SubOp != NumSubOps; ++SubOp) { |
| 235 | const Record *SubRec = cast<DefInit>(Val: MIOI->getArg(Num: SubOp))->getDef(); |
| 236 | |
| 237 | // Take care to instantiate each of the suboperands with the correct |
| 238 | // nomenclature: $foo.bar |
| 239 | ResultOperands.emplace_back( |
| 240 | args: Result->getArgName(Num: AliasOpNo)->getAsUnquotedString() + "." + |
| 241 | MIOI->getArgName(Num: SubOp)->getAsUnquotedString(), |
| 242 | args&: SubRec); |
| 243 | ResultInstOperandIndex.emplace_back(args&: OpIdx, args&: SubOp); |
| 244 | } |
| 245 | ++AliasOpNo; |
| 246 | } |
| 247 | continue; |
| 248 | } |
| 249 | |
| 250 | // If the argument did not match the instruction operand, and the operand |
| 251 | // is composed of multiple suboperands, try matching the suboperands. |
| 252 | if (NumSubOps > 1) { |
| 253 | const DagInit *MIOI = OpInfo.MIOperandInfo; |
| 254 | for (unsigned SubOp = 0; SubOp != NumSubOps; ++SubOp) { |
| 255 | if (AliasOpNo >= Result->getNumArgs()) |
| 256 | PrintFatalError(ErrorLoc: R->getLoc(), Msg: "not enough arguments for instruction!" ); |
| 257 | const Record *SubRec = cast<DefInit>(Val: MIOI->getArg(Num: SubOp))->getDef(); |
| 258 | if (tryAliasOpMatch(Result, AliasOpNo, InstOpRec: SubRec, hasSubOps: false, Loc: R->getLoc(), T, |
| 259 | ResOp)) { |
| 260 | ResultOperands.push_back(x: ResOp); |
| 261 | ResultInstOperandIndex.emplace_back(args&: OpIdx, args&: SubOp); |
| 262 | ++AliasOpNo; |
| 263 | } else { |
| 264 | PrintFatalError( |
| 265 | ErrorLoc: R->getLoc(), |
| 266 | Msg: "result argument #" + Twine(AliasOpNo) + |
| 267 | " does not match instruction operand class " + |
| 268 | (SubOp == 0 ? InstOpRec->getName() : SubRec->getName())); |
| 269 | } |
| 270 | } |
| 271 | continue; |
| 272 | } |
| 273 | PrintFatalError(ErrorLoc: R->getLoc(), |
| 274 | Msg: "result argument #" + Twine(AliasOpNo) + |
| 275 | " does not match instruction operand class " + |
| 276 | InstOpRec->getName()); |
| 277 | } |
| 278 | |
| 279 | if (AliasOpNo != Result->getNumArgs()) |
| 280 | PrintFatalError(ErrorLoc: R->getLoc(), Msg: "too many operands for instruction!" ); |
| 281 | } |
| 282 | |