| //===- 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, ArrayRef<SMLoc> Loc) { | |
| if (const Record *OpRC = T.getAsRegClassLike(Op)) { | |
| if (const auto *ArgDef = dyn_cast<DefInit>(Arg)) { | |
| const Record *ArgRec = ArgDef->getDef(); | |
| // Match 'RegClass:$name', 'RegOp:$name', or RegisterByHwMode. | |
| if (const Record *ArgRC = T.getInitValueAsRegClassLike(Arg)) { | |
| if (ArgRec->isSubClassOf("RegisterByHwMode")) { | |
| // Note: constraints are validated in RegisterByHwMode ctor later. | |
| return ResultOperand::createRegister(ArgRec); | |
| } | |
| if (ArgRC->isSubClassOf("RegisterClass")) { | |
| if (!OpRC->isSubClassOf("RegisterClass") || | |
| !T.getRegisterClass(OpRC, Loc).hasSubClass( | |
| &T.getRegisterClass(ArgRC, Loc))) | |
| 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, Loc).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' but got " + | |
| Op->getName() + " instead"); | |
| } | |
| 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, | |
| R->getLoc()); | |
| 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, R->getLoc()); | |
| 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!"); | |
| } |