Path: blob/main/contrib/llvm-project/llvm/utils/TableGen/Common/CodeGenInstAlias.cpp
35290 views
//===- CodeGenInstAlias.cpp - CodeGen InstAlias Class Wrapper -------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file implements the CodeGenInstAlias class.9//10//===----------------------------------------------------------------------===//1112#include "CodeGenInstAlias.h"13#include "CodeGenInstruction.h"14#include "CodeGenRegisters.h"15#include "CodeGenTarget.h"16#include "llvm/ADT/StringMap.h"17#include "llvm/TableGen/Error.h"18#include "llvm/TableGen/Record.h"1920using namespace llvm;2122/// tryAliasOpMatch - This is a helper function for the CodeGenInstAlias23/// constructor. It checks if an argument in an InstAlias pattern matches24/// the corresponding operand of the instruction. It returns true on a25/// successful match, with ResOp set to the result operand to be used.26bool CodeGenInstAlias::tryAliasOpMatch(DagInit *Result, unsigned AliasOpNo,27Record *InstOpRec, bool hasSubOps,28ArrayRef<SMLoc> Loc, CodeGenTarget &T,29ResultOperand &ResOp) {30Init *Arg = Result->getArg(AliasOpNo);31DefInit *ADI = dyn_cast<DefInit>(Arg);32Record *ResultRecord = ADI ? ADI->getDef() : nullptr;3334if (ADI && ADI->getDef() == InstOpRec) {35// If the operand is a record, it must have a name, and the record type36// must match up with the instruction's argument type.37if (!Result->getArgName(AliasOpNo))38PrintFatalError(Loc, "result argument #" + Twine(AliasOpNo) +39" must have a name!");40ResOp = ResultOperand(std::string(Result->getArgNameStr(AliasOpNo)),41ResultRecord);42return true;43}4445// For register operands, the source register class can be a subclass46// of the instruction register class, not just an exact match.47if (InstOpRec->isSubClassOf("RegisterOperand"))48InstOpRec = InstOpRec->getValueAsDef("RegClass");4950if (ADI && ADI->getDef()->isSubClassOf("RegisterOperand"))51ADI = ADI->getDef()->getValueAsDef("RegClass")->getDefInit();5253if (ADI && ADI->getDef()->isSubClassOf("RegisterClass")) {54if (!InstOpRec->isSubClassOf("RegisterClass"))55return false;56if (!T.getRegisterClass(InstOpRec).hasSubClass(57&T.getRegisterClass(ADI->getDef())))58return false;59ResOp = ResultOperand(std::string(Result->getArgNameStr(AliasOpNo)),60ResultRecord);61return true;62}6364// Handle explicit registers.65if (ADI && ADI->getDef()->isSubClassOf("Register")) {66if (InstOpRec->isSubClassOf("OptionalDefOperand")) {67DagInit *DI = InstOpRec->getValueAsDag("MIOperandInfo");68// The operand info should only have a single (register) entry. We69// want the register class of it.70InstOpRec = cast<DefInit>(DI->getArg(0))->getDef();71}7273if (!InstOpRec->isSubClassOf("RegisterClass"))74return false;7576if (!T.getRegisterClass(InstOpRec).contains(77T.getRegBank().getReg(ADI->getDef())))78PrintFatalError(Loc, "fixed register " + ADI->getDef()->getName() +79" is not a member of the " +80InstOpRec->getName() + " register class!");8182if (Result->getArgName(AliasOpNo))83PrintFatalError(Loc, "result fixed register argument must "84"not have a name!");8586ResOp = ResultOperand(ResultRecord);87return true;88}8990// Handle "zero_reg" for optional def operands.91if (ADI && ADI->getDef()->getName() == "zero_reg") {9293// Check if this is an optional def.94// Tied operands where the source is a sub-operand of a complex operand95// need to represent both operands in the alias destination instruction.96// Allow zero_reg for the tied portion. This can and should go away once97// the MC representation of things doesn't use tied operands at all.98// if (!InstOpRec->isSubClassOf("OptionalDefOperand"))99// throw TGError(Loc, "reg0 used for result that is not an "100// "OptionalDefOperand!");101102ResOp = ResultOperand(static_cast<Record *>(nullptr));103return true;104}105106// Literal integers.107if (IntInit *II = dyn_cast<IntInit>(Arg)) {108if (hasSubOps || !InstOpRec->isSubClassOf("Operand"))109return false;110// Integer arguments can't have names.111if (Result->getArgName(AliasOpNo))112PrintFatalError(Loc, "result argument #" + Twine(AliasOpNo) +113" must not have a name!");114ResOp = ResultOperand(II->getValue());115return true;116}117118// Bits<n> (also used for 0bxx literals)119if (BitsInit *BI = dyn_cast<BitsInit>(Arg)) {120if (hasSubOps || !InstOpRec->isSubClassOf("Operand"))121return false;122if (!BI->isComplete())123return false;124// Convert the bits init to an integer and use that for the result.125IntInit *II = dyn_cast_or_null<IntInit>(126BI->convertInitializerTo(IntRecTy::get(BI->getRecordKeeper())));127if (!II)128return false;129ResOp = ResultOperand(II->getValue());130return true;131}132133// If both are Operands with the same MVT, allow the conversion. It's134// up to the user to make sure the values are appropriate, just like135// for isel Pat's.136if (InstOpRec->isSubClassOf("Operand") && ADI &&137ADI->getDef()->isSubClassOf("Operand")) {138// FIXME: What other attributes should we check here? Identical139// MIOperandInfo perhaps?140if (InstOpRec->getValueInit("Type") != ADI->getDef()->getValueInit("Type"))141return false;142ResOp = ResultOperand(std::string(Result->getArgNameStr(AliasOpNo)),143ADI->getDef());144return true;145}146147return false;148}149150unsigned CodeGenInstAlias::ResultOperand::getMINumOperands() const {151if (!isRecord())152return 1;153154Record *Rec = getRecord();155if (!Rec->isSubClassOf("Operand"))156return 1;157158DagInit *MIOpInfo = Rec->getValueAsDag("MIOperandInfo");159if (MIOpInfo->getNumArgs() == 0) {160// Unspecified, so it defaults to 1161return 1;162}163164return MIOpInfo->getNumArgs();165}166167CodeGenInstAlias::CodeGenInstAlias(Record *R, CodeGenTarget &T) : TheDef(R) {168Result = R->getValueAsDag("ResultInst");169AsmString = std::string(R->getValueAsString("AsmString"));170171// Verify that the root of the result is an instruction.172DefInit *DI = dyn_cast<DefInit>(Result->getOperator());173if (!DI || !DI->getDef()->isSubClassOf("Instruction"))174PrintFatalError(R->getLoc(),175"result of inst alias should be an instruction");176177ResultInst = &T.getInstruction(DI->getDef());178179// NameClass - If argument names are repeated, we need to verify they have180// the same class.181StringMap<Record *> NameClass;182for (unsigned i = 0, e = Result->getNumArgs(); i != e; ++i) {183DefInit *ADI = dyn_cast<DefInit>(Result->getArg(i));184if (!ADI || !Result->getArgName(i))185continue;186// Verify we don't have something like: (someinst GR16:$foo, GR32:$foo)187// $foo can exist multiple times in the result list, but it must have the188// same type.189Record *&Entry = NameClass[Result->getArgNameStr(i)];190if (Entry && Entry != ADI->getDef())191PrintFatalError(R->getLoc(), "result value $" + Result->getArgNameStr(i) +192" is both " + Entry->getName() +193" and " + ADI->getDef()->getName() +194"!");195Entry = ADI->getDef();196}197198// Decode and validate the arguments of the result.199unsigned AliasOpNo = 0;200for (unsigned i = 0, e = ResultInst->Operands.size(); i != e; ++i) {201202// Tied registers don't have an entry in the result dag unless they're part203// of a complex operand, in which case we include them anyways, as we204// don't have any other way to specify the whole operand.205if (ResultInst->Operands[i].MINumOperands == 1 &&206ResultInst->Operands[i].getTiedRegister() != -1) {207// Tied operands of different RegisterClass should be explicit within an208// instruction's syntax and so cannot be skipped.209int TiedOpNum = ResultInst->Operands[i].getTiedRegister();210if (ResultInst->Operands[i].Rec->getName() ==211ResultInst->Operands[TiedOpNum].Rec->getName())212continue;213}214215if (AliasOpNo >= Result->getNumArgs())216PrintFatalError(R->getLoc(), "not enough arguments for instruction!");217218Record *InstOpRec = ResultInst->Operands[i].Rec;219unsigned NumSubOps = ResultInst->Operands[i].MINumOperands;220ResultOperand ResOp(static_cast<int64_t>(0));221if (tryAliasOpMatch(Result, AliasOpNo, InstOpRec, (NumSubOps > 1),222R->getLoc(), T, ResOp)) {223// If this is a simple operand, or a complex operand with a custom match224// class, then we can match is verbatim.225if (NumSubOps == 1 || (InstOpRec->getValue("ParserMatchClass") &&226InstOpRec->getValueAsDef("ParserMatchClass")227->getValueAsString("Name") != "Imm")) {228ResultOperands.push_back(ResOp);229ResultInstOperandIndex.push_back(std::pair(i, -1));230++AliasOpNo;231232// Otherwise, we need to match each of the suboperands individually.233} else {234DagInit *MIOI = ResultInst->Operands[i].MIOperandInfo;235for (unsigned SubOp = 0; SubOp != NumSubOps; ++SubOp) {236Record *SubRec = cast<DefInit>(MIOI->getArg(SubOp))->getDef();237238// Take care to instantiate each of the suboperands with the correct239// nomenclature: $foo.bar240ResultOperands.emplace_back(241Result->getArgName(AliasOpNo)->getAsUnquotedString() + "." +242MIOI->getArgName(SubOp)->getAsUnquotedString(),243SubRec);244ResultInstOperandIndex.push_back(std::pair(i, SubOp));245}246++AliasOpNo;247}248continue;249}250251// If the argument did not match the instruction operand, and the operand252// is composed of multiple suboperands, try matching the suboperands.253if (NumSubOps > 1) {254DagInit *MIOI = ResultInst->Operands[i].MIOperandInfo;255for (unsigned SubOp = 0; SubOp != NumSubOps; ++SubOp) {256if (AliasOpNo >= Result->getNumArgs())257PrintFatalError(R->getLoc(), "not enough arguments for instruction!");258Record *SubRec = cast<DefInit>(MIOI->getArg(SubOp))->getDef();259if (tryAliasOpMatch(Result, AliasOpNo, SubRec, false, R->getLoc(), T,260ResOp)) {261ResultOperands.push_back(ResOp);262ResultInstOperandIndex.push_back(std::pair(i, SubOp));263++AliasOpNo;264} else {265PrintFatalError(266R->getLoc(),267"result argument #" + Twine(AliasOpNo) +268" does not match instruction operand class " +269(SubOp == 0 ? InstOpRec->getName() : SubRec->getName()));270}271}272continue;273}274PrintFatalError(R->getLoc(),275"result argument #" + Twine(AliasOpNo) +276" does not match instruction operand class " +277InstOpRec->getName());278}279280if (AliasOpNo != Result->getNumArgs())281PrintFatalError(R->getLoc(), "too many operands for instruction!");282}283284285