brintos

brintos / llvm-project-archived public Read only

0
0
Text · 15.8 KiB · e9c2d93 Raw
439 lines · cpp
1//===----------------------------------------------------------------------===//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#include "InstructionEncoding.h"10#include "CodeGenInstruction.h"11#include "VarLenCodeEmitterGen.h"12#include "llvm/Support/FormatVariadic.h"13#include "llvm/TableGen/Error.h"14 15using namespace llvm;16 17std::pair<std::string, bool>18InstructionEncoding::findOperandDecoderMethod(const Record *Record) {19  std::string Decoder;20 21  const RecordVal *DecoderString = Record->getValue("DecoderMethod");22  const StringInit *String =23      DecoderString ? dyn_cast<StringInit>(DecoderString->getValue()) : nullptr;24  if (String) {25    Decoder = String->getValue().str();26    if (!Decoder.empty())27      return {Decoder, false};28  }29 30  if (Record->isSubClassOf("RegisterOperand"))31    // Allows use of a DecoderMethod in referenced RegisterClass if set.32    return findOperandDecoderMethod(Record->getValueAsDef("RegClass"));33 34  if (Record->isSubClassOf("RegisterClass")) {35    Decoder = "Decode" + Record->getName().str() + "RegisterClass";36  } else if (Record->isSubClassOf("RegClassByHwMode")) {37    Decoder = "Decode" + Record->getName().str() + "RegClassByHwMode";38  }39 40  return {Decoder, true};41}42 43OperandInfo InstructionEncoding::getOpInfo(const Record *TypeRecord) {44  const RecordVal *HasCompleteDecoderVal =45      TypeRecord->getValue("hasCompleteDecoder");46  const BitInit *HasCompleteDecoderBit =47      HasCompleteDecoderVal48          ? dyn_cast<BitInit>(HasCompleteDecoderVal->getValue())49          : nullptr;50  bool HasCompleteDecoder =51      HasCompleteDecoderBit ? HasCompleteDecoderBit->getValue() : true;52 53  return OperandInfo(findOperandDecoderMethod(TypeRecord).first,54                     HasCompleteDecoder);55}56 57void InstructionEncoding::parseVarLenEncoding(const VarLenInst &VLI) {58  InstBits = KnownBits(VLI.size());59  SoftFailMask = APInt(VLI.size(), 0);60 61  // Parse Inst field.62  unsigned I = 0;63  for (const EncodingSegment &S : VLI) {64    if (const auto *SegmentBits = dyn_cast<BitsInit>(S.Value)) {65      for (const Init *V : SegmentBits->getBits()) {66        if (const auto *B = dyn_cast<BitInit>(V)) {67          if (B->getValue())68            InstBits.One.setBit(I);69          else70            InstBits.Zero.setBit(I);71        }72        ++I;73      }74    } else if (const auto *B = dyn_cast<BitInit>(S.Value)) {75      if (B->getValue())76        InstBits.One.setBit(I);77      else78        InstBits.Zero.setBit(I);79      ++I;80    } else {81      I += S.BitWidth;82    }83  }84  assert(I == VLI.size());85}86 87void InstructionEncoding::parseFixedLenEncoding(88    const BitsInit &RecordInstBits) {89  // For fixed length instructions, sometimes the `Inst` field specifies more90  // bits than the actual size of the instruction, which is specified in `Size`.91  // In such cases, we do some basic validation and drop the upper bits.92  unsigned BitWidth = EncodingDef->getValueAsInt("Size") * 8;93  unsigned InstNumBits = RecordInstBits.getNumBits();94 95  // Returns true if all bits in `Bits` are zero or unset.96  auto CheckAllZeroOrUnset = [&](ArrayRef<const Init *> Bits,97                                 const RecordVal *Field) {98    bool AllZeroOrUnset = llvm::all_of(Bits, [](const Init *Bit) {99      if (const auto *BI = dyn_cast<BitInit>(Bit))100        return !BI->getValue();101      return isa<UnsetInit>(Bit);102    });103    if (AllZeroOrUnset)104      return;105    PrintNote([Field](raw_ostream &OS) { Field->print(OS); });106    PrintFatalError(EncodingDef, Twine(Name) + ": Size is " + Twine(BitWidth) +107                                     " bits, but " + Field->getName() +108                                     " bits beyond that are    not zero/unset");109  };110 111  if (InstNumBits < BitWidth)112    PrintFatalError(EncodingDef, Twine(Name) + ": Size is " + Twine(BitWidth) +113                                     " bits, but Inst specifies only " +114                                     Twine(InstNumBits) + " bits");115 116  if (InstNumBits > BitWidth) {117    // Ensure that all the bits beyond 'Size' are 0 or unset (i.e., carry no118    // actual encoding).119    ArrayRef<const Init *> UpperBits =120        RecordInstBits.getBits().drop_front(BitWidth);121    const RecordVal *InstField = EncodingDef->getValue("Inst");122    CheckAllZeroOrUnset(UpperBits, InstField);123  }124 125  ArrayRef<const Init *> ActiveInstBits =126      RecordInstBits.getBits().take_front(BitWidth);127  InstBits = KnownBits(BitWidth);128  SoftFailMask = APInt(BitWidth, 0);129 130  // Parse Inst field.131  for (auto [I, V] : enumerate(ActiveInstBits)) {132    if (const auto *B = dyn_cast<BitInit>(V)) {133      if (B->getValue())134        InstBits.One.setBit(I);135      else136        InstBits.Zero.setBit(I);137    }138  }139 140  // Parse SoftFail field.141  const RecordVal *SoftFailField = EncodingDef->getValue("SoftFail");142  if (!SoftFailField)143    return;144 145  const auto *SFBits = dyn_cast<BitsInit>(SoftFailField->getValue());146  if (!SFBits || SFBits->getNumBits() != InstNumBits) {147    PrintNote(EncodingDef->getLoc(), "in record");148    PrintFatalError(SoftFailField,149                    formatv("SoftFail field, if defined, must be "150                            "of the same type as Inst, which is bits<{}>",151                            InstNumBits));152  }153 154  if (InstNumBits > BitWidth) {155    // Ensure that all upper bits of `SoftFail` are 0 or unset.156    ArrayRef<const Init *> UpperBits = SFBits->getBits().drop_front(BitWidth);157    CheckAllZeroOrUnset(UpperBits, SoftFailField);158  }159 160  ArrayRef<const Init *> ActiveSFBits = SFBits->getBits().take_front(BitWidth);161  for (auto [I, V] : enumerate(ActiveSFBits)) {162    if (const auto *B = dyn_cast<BitInit>(V); B && B->getValue()) {163      if (!InstBits.Zero[I] && !InstBits.One[I]) {164        PrintNote(EncodingDef->getLoc(), "in record");165        PrintError(SoftFailField,166                   formatv("SoftFail{{{0}} = 1 requires Inst{{{0}} "167                           "to be fully defined (0 or 1, not '?')",168                           I));169      }170      SoftFailMask.setBit(I);171    }172  }173}174 175void InstructionEncoding::parseVarLenOperands(const VarLenInst &VLI) {176  SmallVector<int> TiedTo;177 178  for (const auto &[Idx, Op] : enumerate(Inst->Operands)) {179    if (Op.MIOperandInfo && Op.MIOperandInfo->getNumArgs() > 0)180      for (auto *Arg : Op.MIOperandInfo->getArgs())181        Operands.push_back(getOpInfo(cast<DefInit>(Arg)->getDef()));182    else183      Operands.push_back(getOpInfo(Op.Rec));184 185    int TiedReg = Op.getTiedRegister();186    TiedTo.push_back(-1);187    if (TiedReg != -1) {188      TiedTo[Idx] = TiedReg;189      TiedTo[TiedReg] = Idx;190    }191  }192 193  unsigned CurrBitPos = 0;194  for (const auto &EncodingSegment : VLI) {195    unsigned Offset = 0;196    StringRef OpName;197 198    if (const StringInit *SI = dyn_cast<StringInit>(EncodingSegment.Value)) {199      OpName = SI->getValue();200    } else if (const DagInit *DI = dyn_cast<DagInit>(EncodingSegment.Value)) {201      OpName = cast<StringInit>(DI->getArg(0))->getValue();202      Offset = cast<IntInit>(DI->getArg(2))->getValue();203    }204 205    if (!OpName.empty()) {206      auto OpSubOpPair = Inst->Operands.parseOperandName(OpName);207      unsigned OpIdx = Inst->Operands.getFlattenedOperandNumber(OpSubOpPair);208      Operands[OpIdx].addField(CurrBitPos, EncodingSegment.BitWidth, Offset);209      if (!EncodingSegment.CustomDecoder.empty())210        Operands[OpIdx].Decoder = EncodingSegment.CustomDecoder.str();211 212      int TiedReg = TiedTo[OpSubOpPair.first];213      if (TiedReg != -1) {214        unsigned OpIdx = Inst->Operands.getFlattenedOperandNumber(215            {TiedReg, OpSubOpPair.second});216        Operands[OpIdx].addField(CurrBitPos, EncodingSegment.BitWidth, Offset);217      }218    }219 220    CurrBitPos += EncodingSegment.BitWidth;221  }222}223 224static void debugDumpRecord(const Record &Rec) {225  // Dump the record, so we can see what's going on.226  PrintNote([&Rec](raw_ostream &OS) {227    OS << "Dumping record for previous error:\n";228    OS << Rec;229  });230}231 232/// For an operand field named OpName: populate OpInfo.InitValue with the233/// constant-valued bit values, and OpInfo.Fields with the ranges of bits to234/// insert from the decoded instruction.235static void addOneOperandFields(const Record *EncodingDef,236                                const BitsInit &InstBits,237                                std::map<StringRef, StringRef> &TiedNames,238                                const Record *OpRec, StringRef OpName,239                                OperandInfo &OpInfo) {240  OpInfo.Name = OpName;241 242  // Find a field with the operand's name.243  const RecordVal *OpEncodingField = EncodingDef->getValue(OpName);244 245  // If there is no such field, try tied operand's name.246  if (!OpEncodingField) {247    if (auto I = TiedNames.find(OpName); I != TiedNames.end())248      OpEncodingField = EncodingDef->getValue(I->second);249 250    // If still no luck, we're done with this operand.251    if (!OpEncodingField) {252      OpInfo.HasNoEncoding = true;253      return;254    }255  }256 257  // Some or all bits of the operand may be required to be 0 or 1 depending258  // on the instruction's encoding. Collect those bits.259  if (const auto *OpBit = dyn_cast<BitInit>(OpEncodingField->getValue())) {260    OpInfo.InitValue = OpBit->getValue();261    return;262  }263  if (const auto *OpBits = dyn_cast<BitsInit>(OpEncodingField->getValue())) {264    if (OpBits->getNumBits() == 0) {265      if (OpInfo.Decoder.empty()) {266        PrintError(EncodingDef->getLoc(), "operand '" + OpName + "' of type '" +267                                              OpRec->getName() +268                                              "' must have a decoder method");269      }270      return;271    }272    for (unsigned I = 0; I < OpBits->getNumBits(); ++I) {273      if (const auto *OpBit = dyn_cast<BitInit>(OpBits->getBit(I)))274        OpInfo.InitValue = OpInfo.InitValue.value_or(0) |275                           static_cast<uint64_t>(OpBit->getValue()) << I;276    }277  }278 279  // Find out where the variable bits of the operand are encoded. The bits don't280  // have to be consecutive or in ascending order. For example, an operand could281  // be encoded as follows:282  //283  //  7    6      5      4    3    2      1    0284  // {1, op{5}, op{2}, op{1}, 0, op{4}, op{3}, ?}285  //286  // In this example the operand is encoded in three segments:287  //288  //           Base Width Offset289  // op{2...1}   4    2     1290  // op{4...3}   1    2     3291  // op{5}       6    1     5292  //293  for (unsigned I = 0, J = 0; I != InstBits.getNumBits(); I = J) {294    const VarInit *Var;295    unsigned Offset = 0;296    for (; J != InstBits.getNumBits(); ++J) {297      const Init *BitJ = InstBits.getBit(J);298      if (const auto *VBI = dyn_cast<VarBitInit>(BitJ)) {299        Var = dyn_cast<VarInit>(VBI->getBitVar());300        if (I == J)301          Offset = VBI->getBitNum();302        else if (VBI->getBitNum() != Offset + J - I)303          break;304      } else {305        Var = dyn_cast<VarInit>(BitJ);306      }307      if (!Var ||308          (Var->getName() != OpName && Var->getName() != TiedNames[OpName]))309        break;310    }311    if (I == J)312      ++J;313    else314      OpInfo.addField(I, J - I, Offset);315  }316 317  if (!OpInfo.InitValue && OpInfo.fields().empty()) {318    // We found a field in InstructionEncoding record that corresponds to the319    // named operand, but that field has no constant bits and doesn't contribute320    // to the Inst field. For now, treat that field as if it didn't exist.321    // TODO: Remove along with IgnoreNonDecodableOperands.322    OpInfo.HasNoEncoding = true;323  }324}325 326void InstructionEncoding::parseFixedLenOperands(const BitsInit &Bits) {327  // Search for tied operands, so that we can correctly instantiate328  // operands that are not explicitly represented in the encoding.329  std::map<StringRef, StringRef> TiedNames;330  for (const auto &Op : Inst->Operands) {331    for (const auto &[J, CI] : enumerate(Op.Constraints)) {332      if (!CI.isTied())333        continue;334      std::pair<unsigned, unsigned> SO =335          Inst->Operands.getSubOperandNumber(CI.getTiedOperand());336      StringRef TiedName = Inst->Operands[SO.first].SubOpNames[SO.second];337      if (TiedName.empty())338        TiedName = Inst->Operands[SO.first].Name;339      StringRef MyName = Op.SubOpNames[J];340      if (MyName.empty())341        MyName = Op.Name;342 343      TiedNames[MyName] = TiedName;344      TiedNames[TiedName] = MyName;345    }346  }347 348  // For each operand, see if we can figure out where it is encoded.349  for (const CGIOperandList::OperandInfo &Op : Inst->Operands) {350    // Lookup the decoder method and construct a new OperandInfo to hold our351    // result.352    OperandInfo OpInfo = getOpInfo(Op.Rec);353 354    // If we have named sub-operands...355    if (Op.MIOperandInfo && !Op.SubOpNames[0].empty()) {356      // Then there should not be a custom decoder specified on the top-level357      // type.358      if (!OpInfo.Decoder.empty()) {359        PrintError(EncodingDef,360                   "DecoderEmitter: operand \"" + Op.Name + "\" has type \"" +361                       Op.Rec->getName() +362                       "\" with a custom DecoderMethod, but also named "363                       "sub-operands.");364        continue;365      }366 367      // Decode each of the sub-ops separately.368      for (auto [SubOpName, SubOp] :369           zip_equal(Op.SubOpNames, Op.MIOperandInfo->getArgs())) {370        const Record *SubOpRec = cast<DefInit>(SubOp)->getDef();371        OperandInfo SubOpInfo = getOpInfo(SubOpRec);372        addOneOperandFields(EncodingDef, Bits, TiedNames, SubOpRec, SubOpName,373                            SubOpInfo);374        Operands.push_back(std::move(SubOpInfo));375      }376      continue;377    }378 379    // Otherwise, if we have an operand with sub-operands, but they aren't380    // named...381    if (Op.MIOperandInfo && OpInfo.Decoder.empty()) {382      // If we have sub-ops, we'd better have a custom decoder.383      // (Otherwise we don't know how to populate them properly...)384      if (Op.MIOperandInfo->getNumArgs()) {385        PrintError(EncodingDef,386                   "DecoderEmitter: operand \"" + Op.Name +387                       "\" has non-empty MIOperandInfo, but doesn't "388                       "have a custom decoder!");389        debugDumpRecord(*EncodingDef);390        continue;391      }392    }393 394    addOneOperandFields(EncodingDef, Bits, TiedNames, Op.Rec, Op.Name, OpInfo);395    Operands.push_back(std::move(OpInfo));396  }397}398 399InstructionEncoding::InstructionEncoding(const Record *EncodingDef,400                                         const CodeGenInstruction *Inst)401    : EncodingDef(EncodingDef), Inst(Inst) {402  const Record *InstDef = Inst->TheDef;403 404  // Give this encoding a name.405  if (EncodingDef != InstDef)406    Name = (EncodingDef->getName() + Twine(':')).str();407  Name.append(InstDef->getName());408 409  DecoderNamespace = EncodingDef->getValueAsString("DecoderNamespace");410  DecoderMethod = EncodingDef->getValueAsString("DecoderMethod");411  if (!DecoderMethod.empty())412    HasCompleteDecoder = EncodingDef->getValueAsBit("hasCompleteDecoder");413 414  const RecordVal *InstField = EncodingDef->getValue("Inst");415  if (const auto *DI = dyn_cast<DagInit>(InstField->getValue())) {416    VarLenInst VLI(DI, InstField);417    parseVarLenEncoding(VLI);418    // If the encoding has a custom decoder, don't bother parsing the operands.419    if (DecoderMethod.empty())420      parseVarLenOperands(VLI);421  } else {422    const auto *BI = cast<BitsInit>(InstField->getValue());423    parseFixedLenEncoding(*BI);424    // If the encoding has a custom decoder, don't bother parsing the operands.425    if (DecoderMethod.empty())426      parseFixedLenOperands(*BI);427  }428 429  if (DecoderMethod.empty()) {430    // A generated decoder is always successful if none of the operand431    // decoders can fail (all are always successful).432    HasCompleteDecoder = all_of(Operands, [](const OperandInfo &Op) {433      // By default, a generated operand decoder is assumed to always succeed.434      // This can be overridden by the user.435      return Op.Decoder.empty() || Op.HasCompleteDecoder;436    });437  }438}439