brintos

brintos / llvm-project-archived public Read only

0
0
Text · 9.9 KiB · 6c1a3e9 Raw
242 lines · cpp
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-exception6//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 22using namespace llvm;23 24unsigned CodeGenInstAlias::ResultOperand::getMINumOperands() const {25  if (!isRecord())26    return 1;27 28  const Record *Rec = getRecord();29  if (!Rec->isSubClassOf("Operand"))30    return 1;31 32  const DagInit *MIOpInfo = Rec->getValueAsDag("MIOperandInfo");33  if (MIOpInfo->getNumArgs() == 0) {34    // Unspecified, so it defaults to 135    return 1;36  }37 38  return MIOpInfo->getNumArgs();39}40 41using ResultOperand = CodeGenInstAlias::ResultOperand;42 43static Expected<ResultOperand> matchSimpleOperand(const Init *Arg,44                                                  const StringInit *ArgName,45                                                  const Record *Op,46                                                  const CodeGenTarget &T) {47  if (Op->isSubClassOf("RegisterClass") ||48      Op->isSubClassOf("RegisterOperand")) {49    const Record *OpRC =50        Op->isSubClassOf("RegisterClass") ? Op : Op->getValueAsDef("RegClass");51 52    if (const auto *ArgDef = dyn_cast<DefInit>(Arg)) {53      const Record *ArgRec = ArgDef->getDef();54 55      // Match 'RegClass:$name' or 'RegOp:$name'.56      if (const Record *ArgRC = T.getInitValueAsRegClassLike(Arg)) {57        if (ArgRC->isSubClassOf("RegisterClass")) {58          if (!T.getRegisterClass(OpRC).hasSubClass(&T.getRegisterClass(ArgRC)))59            return createStringError(60                "argument register class" + ArgRC->getName() +61                " is not a subclass of operand register class " +62                OpRC->getName());63          if (!ArgName)64            return createStringError(65                "register class argument must have a name");66        }67 68        // TODO: Verify RegClassByHwMode usage69 70        return ResultOperand::createRecord(ArgName->getAsUnquotedString(),71                                           ArgRec);72      }73 74      // Match 'Reg'.75      if (ArgRec->isSubClassOf("Register")) {76        if (!T.getRegisterClass(OpRC).contains(T.getRegBank().getReg(ArgRec)))77          return createStringError(78              "register argument " + ArgRec->getName() +79              " is not a member of operand register class " + OpRC->getName());80        if (ArgName)81          return createStringError("register argument must not have a name");82        return ResultOperand::createRegister(ArgRec);83      }84 85      // Match 'zero_reg'.86      if (ArgRec->getName() == "zero_reg") {87        if (ArgName)88          return createStringError("register argument must not have a name");89        return ResultOperand::createRegister(nullptr);90      }91    }92 93    return createStringError("argument must be a subclass of RegisterClass, "94                             "RegisterOperand, or zero_reg");95  }96 97  if (Op->isSubClassOf("Operand")) {98    // Match integer or bits.99    if (const auto *ArgInt = dyn_cast_or_null<IntInit>(100            Arg->convertInitializerTo(IntRecTy::get(Arg->getRecordKeeper())))) {101      if (ArgName)102        return createStringError("integer argument must not have a name");103      return ResultOperand::createImmediate(ArgInt->getValue());104    }105 106    // Match a subclass of Operand.107    if (const auto *ArgDef = dyn_cast<DefInit>(Arg);108        ArgDef && ArgDef->getDef()->isSubClassOf("Operand")) {109      if (!ArgName)110        return createStringError("argument must have a name");111      return ResultOperand::createRecord(ArgName->getAsUnquotedString(),112                                         ArgDef->getDef());113    }114 115    return createStringError("argument must be a subclass of Operand");116  }117 118  llvm_unreachable("Unknown operand kind");119}120 121static 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>(Arg);126  if (!ArgDef || !ArgDef->getDef()->isSubClassOf("Operand"))127    return createStringError("argument must be a subclass of Operand");128  if (!ArgName)129    return createStringError("argument must have a name");130  return ResultOperand::createRecord(ArgName->getAsUnquotedString(),131                                     ArgDef->getDef());132}133 134CodeGenInstAlias::CodeGenInstAlias(const Record *R, const CodeGenTarget &T)135    : TheDef(R) {136  Result = R->getValueAsDag("ResultInst");137  AsmString = R->getValueAsString("AsmString");138 139  // Verify that the root of the result is an instruction.140  const DefInit *DI = dyn_cast<DefInit>(Result->getOperator());141  if (!DI || !DI->getDef()->isSubClassOf("Instruction"))142    PrintFatalError(R->getLoc(),143                    "result of inst alias should be an instruction");144 145  ResultInst = &T.getInstruction(DI->getDef());146 147  // NameClass - If argument names are repeated, we need to verify they have148  // 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>(Result->getArg(i));152    if (!ADI || !Result->getArgName(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 the156    // same type.157    const Record *&Entry = NameClass[Result->getArgNameStr(i)];158    if (Entry && Entry != ADI->getDef())159      PrintFatalError(R->getLoc(), "result value $" + Result->getArgNameStr(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(ResultInst->Operands)) {169    // Tied registers don't have an entry in the result dag unless they're part170    // of a complex operand, in which case we include them anyways, as we171    // 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 an174      // 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(R->getLoc(), "not enough arguments for instruction!");183 184    const Record *Op = OpInfo.Rec;185    if (Op->isSubClassOf("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>(Result->getArg(ArgIdx))) {189        // The argument is a DAG. The operator must be the name of the operand.190        if (auto *Operator = dyn_cast<DefInit>(ArgDag->getOperator());191            !Operator || Operator->getDef()->getName() != Op->getName())192          PrintFatalError(R, "argument #" + Twine(ArgIdx) +193                                 " operator must be " + Op->getName());194        // The number of sub-arguments and the number of sub-operands195        // must match exactly.196        unsigned NumSubOps = OpInfo.MIOperandInfo->getNumArgs();197        unsigned NumSubArgs = ArgDag->getNumArgs();198        if (NumSubArgs != NumSubOps)199          PrintFatalError(R, "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>(OpInfo.MIOperandInfo->getArg(SubOpIdx))->getDef();206          Expected<ResultOperand> ResOpOrErr = matchSimpleOperand(207              ArgDag->getArg(SubOpIdx), ArgDag->getArgName(SubOpIdx), SubOp, T);208          if (!ResOpOrErr)209            PrintFatalError(R, "in argument #" + Twine(ArgIdx) + "." +210                                   Twine(SubOpIdx) + ": " +211                                   toString(ResOpOrErr.takeError()));212          ResultOperands.push_back(*ResOpOrErr);213          ResultInstOperandIndex.emplace_back(OpIdx, SubOpIdx);214        }215      } else {216        // Match complex operand as a whole.217        Expected<ResultOperand> ResOpOrErr = matchComplexOperand(218            Result->getArg(ArgIdx), Result->getArgName(ArgIdx), Op);219        if (!ResOpOrErr)220          PrintFatalError(R, "in argument #" + Twine(ArgIdx) + ": " +221                                 toString(ResOpOrErr.takeError()));222        ResultOperands.push_back(*ResOpOrErr);223        ResultInstOperandIndex.emplace_back(OpIdx, -1);224      }225    } else {226      // Simple operand (RegisterClass, RegisterOperand or Operand with empty227      // MIOperandInfo).228      Expected<ResultOperand> ResOpOrErr = matchSimpleOperand(229          Result->getArg(ArgIdx), Result->getArgName(ArgIdx), Op, T);230      if (!ResOpOrErr)231        PrintFatalError(R, "in argument #" + Twine(ArgIdx) + ": " +232                               toString(ResOpOrErr.takeError()));233      ResultOperands.push_back(*ResOpOrErr);234      ResultInstOperandIndex.emplace_back(OpIdx, -1);235    }236    ArgIdx++;237  }238 239  if (ArgIdx != Result->getNumArgs())240    PrintFatalError(R->getLoc(), "too many operands for instruction!");241}242