|  | //===- 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/TableGen/Error.h" | 
|  | #include "llvm/TableGen/Record.h" | 
|  |  | 
|  | using namespace llvm; | 
|  |  | 
|  | /// tryAliasOpMatch - This is a helper function for the CodeGenInstAlias | 
|  | /// constructor.  It checks if an argument in an InstAlias pattern matches | 
|  | /// the corresponding operand of the instruction.  It returns true on a | 
|  | /// successful match, with ResOp set to the result operand to be used. | 
|  | bool CodeGenInstAlias::tryAliasOpMatch(const DagInit *Result, | 
|  | unsigned AliasOpNo, | 
|  | const Record *InstOpRec, bool hasSubOps, | 
|  | ArrayRef<SMLoc> Loc, | 
|  | const CodeGenTarget &T, | 
|  | ResultOperand &ResOp) { | 
|  | const Init *Arg = Result->getArg(AliasOpNo); | 
|  | const DefInit *ADI = dyn_cast<DefInit>(Arg); | 
|  | const Record *ResultRecord = ADI ? ADI->getDef() : nullptr; | 
|  |  | 
|  | if (ADI && ADI->getDef() == InstOpRec) { | 
|  | // If the operand is a record, it must have a name, and the record type | 
|  | // must match up with the instruction's argument type. | 
|  | if (!Result->getArgName(AliasOpNo)) | 
|  | PrintFatalError(Loc, "result argument #" + Twine(AliasOpNo) + | 
|  | " must have a name!"); | 
|  | ResOp = ResultOperand(Result->getArgNameStr(AliasOpNo).str(), ResultRecord); | 
|  | return true; | 
|  | } | 
|  |  | 
|  | // For register operands, the source register class can be a subclass | 
|  | // of the instruction register class, not just an exact match. | 
|  | if (InstOpRec->isSubClassOf("RegisterOperand")) | 
|  | InstOpRec = InstOpRec->getValueAsDef("RegClass"); | 
|  |  | 
|  | if (ADI && ADI->getDef()->isSubClassOf("RegisterOperand")) | 
|  | ADI = ADI->getDef()->getValueAsDef("RegClass")->getDefInit(); | 
|  |  | 
|  | if (ADI && ADI->getDef()->isSubClassOf("RegisterClass")) { | 
|  | if (!InstOpRec->isSubClassOf("RegisterClass")) | 
|  | return false; | 
|  | if (!T.getRegisterClass(InstOpRec).hasSubClass( | 
|  | &T.getRegisterClass(ADI->getDef()))) | 
|  | return false; | 
|  | ResOp = ResultOperand(Result->getArgNameStr(AliasOpNo).str(), ResultRecord); | 
|  | return true; | 
|  | } | 
|  |  | 
|  | // Handle explicit registers. | 
|  | if (ADI && ADI->getDef()->isSubClassOf("Register")) { | 
|  | if (InstOpRec->isSubClassOf("OptionalDefOperand")) { | 
|  | const DagInit *DI = InstOpRec->getValueAsDag("MIOperandInfo"); | 
|  | // The operand info should only have a single (register) entry. We | 
|  | // want the register class of it. | 
|  | InstOpRec = cast<DefInit>(DI->getArg(0))->getDef(); | 
|  | } | 
|  |  | 
|  | if (!InstOpRec->isSubClassOf("RegisterClass")) | 
|  | return false; | 
|  |  | 
|  | if (!T.getRegisterClass(InstOpRec).contains( | 
|  | T.getRegBank().getReg(ADI->getDef()))) | 
|  | PrintFatalError(Loc, "fixed register " + ADI->getDef()->getName() + | 
|  | " is not a member of the " + | 
|  | InstOpRec->getName() + " register class!"); | 
|  |  | 
|  | if (Result->getArgName(AliasOpNo)) | 
|  | PrintFatalError(Loc, "result fixed register argument must " | 
|  | "not have a name!"); | 
|  |  | 
|  | ResOp = ResultOperand(ResultRecord); | 
|  | return true; | 
|  | } | 
|  |  | 
|  | // Handle "zero_reg" for optional def operands. | 
|  | if (ADI && ADI->getDef()->getName() == "zero_reg") { | 
|  |  | 
|  | // Check if this is an optional def. | 
|  | // Tied operands where the source is a sub-operand of a complex operand | 
|  | // need to represent both operands in the alias destination instruction. | 
|  | // Allow zero_reg for the tied portion. This can and should go away once | 
|  | // the MC representation of things doesn't use tied operands at all. | 
|  | // if (!InstOpRec->isSubClassOf("OptionalDefOperand")) | 
|  | //  throw TGError(Loc, "reg0 used for result that is not an " | 
|  | //                "OptionalDefOperand!"); | 
|  |  | 
|  | ResOp = ResultOperand(nullptr); | 
|  | return true; | 
|  | } | 
|  |  | 
|  | // Literal integers. | 
|  | if (const IntInit *II = dyn_cast<IntInit>(Arg)) { | 
|  | if (hasSubOps || !InstOpRec->isSubClassOf("Operand")) | 
|  | return false; | 
|  | // Integer arguments can't have names. | 
|  | if (Result->getArgName(AliasOpNo)) | 
|  | PrintFatalError(Loc, "result argument #" + Twine(AliasOpNo) + | 
|  | " must not have a name!"); | 
|  | ResOp = ResultOperand(II->getValue()); | 
|  | return true; | 
|  | } | 
|  |  | 
|  | // Bits<n> (also used for 0bxx literals) | 
|  | if (const BitsInit *BI = dyn_cast<BitsInit>(Arg)) { | 
|  | if (hasSubOps || !InstOpRec->isSubClassOf("Operand")) | 
|  | return false; | 
|  | if (!BI->isComplete()) | 
|  | return false; | 
|  | // Convert the bits init to an integer and use that for the result. | 
|  | std::optional<int64_t> Value = BI->convertInitializerToInt(); | 
|  | if (!Value) | 
|  | return false; | 
|  | ResOp = ResultOperand(*Value); | 
|  | return true; | 
|  | } | 
|  |  | 
|  | // If both are Operands with the same MVT, allow the conversion. It's | 
|  | // up to the user to make sure the values are appropriate, just like | 
|  | // for isel Pat's. | 
|  | if (InstOpRec->isSubClassOf("Operand") && ADI && | 
|  | ADI->getDef()->isSubClassOf("Operand")) { | 
|  | // FIXME: What other attributes should we check here? Identical | 
|  | // MIOperandInfo perhaps? | 
|  | if (InstOpRec->getValueInit("Type") != ADI->getDef()->getValueInit("Type")) | 
|  | return false; | 
|  | ResOp = | 
|  | ResultOperand(Result->getArgNameStr(AliasOpNo).str(), ADI->getDef()); | 
|  | return true; | 
|  | } | 
|  |  | 
|  | return false; | 
|  | } | 
|  |  | 
|  | 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(); | 
|  | } | 
|  |  | 
|  | 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 AliasOpNo = 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 (AliasOpNo >= Result->getNumArgs()) | 
|  | PrintFatalError(R->getLoc(), "not enough arguments for instruction!"); | 
|  |  | 
|  | const Record *InstOpRec = OpInfo.Rec; | 
|  | unsigned NumSubOps = OpInfo.MINumOperands; | 
|  | ResultOperand ResOp(static_cast<int64_t>(0)); | 
|  | if (tryAliasOpMatch(Result, AliasOpNo, InstOpRec, (NumSubOps > 1), | 
|  | R->getLoc(), T, ResOp)) { | 
|  | // If this is a simple operand, or a complex operand with a custom match | 
|  | // class, then we can match is verbatim. | 
|  | if (NumSubOps == 1 || (InstOpRec->getValue("ParserMatchClass") && | 
|  | InstOpRec->getValueAsDef("ParserMatchClass") | 
|  | ->getValueAsString("Name") != "Imm")) { | 
|  | ResultOperands.push_back(std::move(ResOp)); | 
|  | ResultInstOperandIndex.emplace_back(OpIdx, -1); | 
|  | ++AliasOpNo; | 
|  |  | 
|  | // Otherwise, we need to match each of the suboperands individually. | 
|  | } else { | 
|  | const DagInit *MIOI = OpInfo.MIOperandInfo; | 
|  | for (unsigned SubOp = 0; SubOp != NumSubOps; ++SubOp) { | 
|  | const Record *SubRec = cast<DefInit>(MIOI->getArg(SubOp))->getDef(); | 
|  |  | 
|  | // Take care to instantiate each of the suboperands with the correct | 
|  | // nomenclature: $foo.bar | 
|  | ResultOperands.emplace_back( | 
|  | Result->getArgName(AliasOpNo)->getAsUnquotedString() + "." + | 
|  | MIOI->getArgName(SubOp)->getAsUnquotedString(), | 
|  | SubRec); | 
|  | ResultInstOperandIndex.emplace_back(OpIdx, SubOp); | 
|  | } | 
|  | ++AliasOpNo; | 
|  | } | 
|  | continue; | 
|  | } | 
|  |  | 
|  | // If the argument did not match the instruction operand, and the operand | 
|  | // is composed of multiple suboperands, try matching the suboperands. | 
|  | if (NumSubOps > 1) { | 
|  | const DagInit *MIOI = OpInfo.MIOperandInfo; | 
|  | for (unsigned SubOp = 0; SubOp != NumSubOps; ++SubOp) { | 
|  | if (AliasOpNo >= Result->getNumArgs()) | 
|  | PrintFatalError(R->getLoc(), "not enough arguments for instruction!"); | 
|  | const Record *SubRec = cast<DefInit>(MIOI->getArg(SubOp))->getDef(); | 
|  | if (tryAliasOpMatch(Result, AliasOpNo, SubRec, false, R->getLoc(), T, | 
|  | ResOp)) { | 
|  | ResultOperands.push_back(ResOp); | 
|  | ResultInstOperandIndex.emplace_back(OpIdx, SubOp); | 
|  | ++AliasOpNo; | 
|  | } else { | 
|  | PrintFatalError( | 
|  | R->getLoc(), | 
|  | "result argument #" + Twine(AliasOpNo) + | 
|  | " does not match instruction operand class " + | 
|  | (SubOp == 0 ? InstOpRec->getName() : SubRec->getName())); | 
|  | } | 
|  | } | 
|  | continue; | 
|  | } | 
|  | PrintFatalError(R->getLoc(), | 
|  | "result argument #" + Twine(AliasOpNo) + | 
|  | " does not match instruction operand class " + | 
|  | InstOpRec->getName()); | 
|  | } | 
|  |  | 
|  | if (AliasOpNo != Result->getNumArgs()) | 
|  | PrintFatalError(R->getLoc(), "too many operands for instruction!"); | 
|  | } |