Пример #1
0
void CheckOrImmMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
  OS.indent(indent) << "CheckOrImm " << Value << '\n';
}
Пример #2
0
void RecordMemRefMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
  OS.indent(indent) << "RecordMemRef\n";
}
Пример #3
0
void MoveChildMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
  OS.indent(indent) << "MoveChild " << ChildNo << '\n';
}
Пример #4
0
void DisassemblerTables::emitModRMDecision(raw_ostream &o1, raw_ostream &o2,
                                           unsigned &i1, unsigned &i2,
                                           unsigned &ModRMTableNum,
                                           ModRMDecision &decision) const {
  static uint32_t sTableNumber = 0;
  static uint32_t sEntryNumber = 1;
  ModRMDecisionType dt = getDecisionType(decision);

  if (dt == MODRM_ONEENTRY && decision.instructionIDs[0] == 0)
  {
    o2.indent(i2) << "{ /* ModRMDecision */" << "\n";
    i2++;

    o2.indent(i2) << stringForDecisionType(dt) << "," << "\n";
    o2.indent(i2) << 0 << " /* EmptyTable */\n";

    i2--;
    o2.indent(i2) << "}";
    return;
  }

  std::vector<unsigned> ModRMDecision;

  switch (dt) {
    default:
      llvm_unreachable("Unknown decision type");
    case MODRM_ONEENTRY:
      ModRMDecision.push_back(decision.instructionIDs[0]);
      break;
    case MODRM_SPLITRM:
      ModRMDecision.push_back(decision.instructionIDs[0x00]);
      ModRMDecision.push_back(decision.instructionIDs[0xc0]);
      break;
    case MODRM_SPLITREG:
      for (unsigned index = 0; index < 64; index += 8)
        ModRMDecision.push_back(decision.instructionIDs[index]);
      for (unsigned index = 0xc0; index < 256; index += 8)
        ModRMDecision.push_back(decision.instructionIDs[index]);
      break;
    case MODRM_SPLITMISC:
      for (unsigned index = 0; index < 64; index += 8)
        ModRMDecision.push_back(decision.instructionIDs[index]);
      for (unsigned index = 0xc0; index < 256; ++index)
        ModRMDecision.push_back(decision.instructionIDs[index]);
      break;
    case MODRM_FULL:
      for (unsigned index = 0; index < 256; ++index)
        ModRMDecision.push_back(decision.instructionIDs[index]);
      break;
  }

  unsigned &EntryNumber = ModRMTable[ModRMDecision];
  if (EntryNumber == 0) {
    EntryNumber = ModRMTableNum;

    ModRMTableNum += ModRMDecision.size();
    o1 << "/* Table" << EntryNumber << " */\n";
    i1++;
    for (std::vector<unsigned>::const_iterator I = ModRMDecision.begin(),
           E = ModRMDecision.end(); I != E; ++I) {
      o1.indent(i1 * 2) << format("0x%hx", *I) << ", /* "
                        << InstructionSpecifiers[*I].name << " */\n";
    }
    i1--;
  }

  o2.indent(i2) << "{ /* struct ModRMDecision */" << "\n";
  i2++;

  o2.indent(i2) << stringForDecisionType(dt) << "," << "\n";
  o2.indent(i2) << EntryNumber << " /* Table" << EntryNumber << " */\n";

  i2--;
  o2.indent(i2) << "}";

  switch (dt) {
    default:
      llvm_unreachable("Unknown decision type");
    case MODRM_ONEENTRY:
      sEntryNumber += 1;
      break;
    case MODRM_SPLITRM:
      sEntryNumber += 2;
      break;
    case MODRM_SPLITREG:
      sEntryNumber += 16;
      break;
    case MODRM_SPLITMISC:
      sEntryNumber += 8 + 64;
      break;
    case MODRM_FULL:
      sEntryNumber += 256;
      break;
  }

  // We assume that the index can fit into uint16_t.
  assert(sEntryNumber < 65536U &&
         "Index into ModRMDecision is too large for uint16_t!");

  ++sTableNumber;
}
Пример #5
0
void DisassemblerTables::emitContextTable(raw_ostream &o, unsigned &i) const {
  const unsigned int tableSize = 16384;
  o.indent(i * 2) << "static const uint8_t " CONTEXTS_STR
                     "[" << tableSize << "] = {\n";
  i++;

  for (unsigned index = 0; index < tableSize; ++index) {
    o.indent(i * 2);

    if (index & ATTR_EVEX) {
      o << "IC_EVEX";
      if (index & ATTR_EVEXL2)
        o << "_L2";
      else if (index & ATTR_EVEXL)
        o << "_L";
      if (index & ATTR_REXW)
        o << "_W";
      if (index & ATTR_OPSIZE)
        o << "_OPSIZE";
      else if (index & ATTR_XD)
        o << "_XD";
      else if (index & ATTR_XS)
        o << "_XS";
      if (index & ATTR_EVEXKZ)
        o << "_KZ";
      else if (index & ATTR_EVEXK)
        o << "_K";
      if (index & ATTR_EVEXB)
        o << "_B";
    }
    else if ((index & ATTR_VEXL) && (index & ATTR_REXW) && (index & ATTR_OPSIZE))
      o << "IC_VEX_L_W_OPSIZE";
    else if ((index & ATTR_VEXL) && (index & ATTR_REXW) && (index & ATTR_XD))
      o << "IC_VEX_L_W_XD";
    else if ((index & ATTR_VEXL) && (index & ATTR_REXW) && (index & ATTR_XS))
      o << "IC_VEX_L_W_XS";
    else if ((index & ATTR_VEXL) && (index & ATTR_REXW))
      o << "IC_VEX_L_W";
    else if ((index & ATTR_VEXL) && (index & ATTR_OPSIZE))
      o << "IC_VEX_L_OPSIZE";
    else if ((index & ATTR_VEXL) && (index & ATTR_XD))
      o << "IC_VEX_L_XD";
    else if ((index & ATTR_VEXL) && (index & ATTR_XS))
      o << "IC_VEX_L_XS";
    else if ((index & ATTR_VEX) && (index & ATTR_REXW) && (index & ATTR_OPSIZE))
      o << "IC_VEX_W_OPSIZE";
    else if ((index & ATTR_VEX) && (index & ATTR_REXW) && (index & ATTR_XD))
      o << "IC_VEX_W_XD";
    else if ((index & ATTR_VEX) && (index & ATTR_REXW) && (index & ATTR_XS))
      o << "IC_VEX_W_XS";
    else if (index & ATTR_VEXL)
      o << "IC_VEX_L";
    else if ((index & ATTR_VEX) && (index & ATTR_REXW))
      o << "IC_VEX_W";
    else if ((index & ATTR_VEX) && (index & ATTR_OPSIZE))
      o << "IC_VEX_OPSIZE";
    else if ((index & ATTR_VEX) && (index & ATTR_XD))
      o << "IC_VEX_XD";
    else if ((index & ATTR_VEX) && (index & ATTR_XS))
      o << "IC_VEX_XS";
    else if (index & ATTR_VEX)
      o << "IC_VEX";
    else if ((index & ATTR_64BIT) && (index & ATTR_REXW) && (index & ATTR_XS))
      o << "IC_64BIT_REXW_XS";
    else if ((index & ATTR_64BIT) && (index & ATTR_REXW) && (index & ATTR_XD))
      o << "IC_64BIT_REXW_XD";
    else if ((index & ATTR_64BIT) && (index & ATTR_REXW) &&
             (index & ATTR_OPSIZE))
      o << "IC_64BIT_REXW_OPSIZE";
    else if ((index & ATTR_64BIT) && (index & ATTR_XD) && (index & ATTR_OPSIZE))
      o << "IC_64BIT_XD_OPSIZE";
    else if ((index & ATTR_64BIT) && (index & ATTR_XS) && (index & ATTR_OPSIZE))
      o << "IC_64BIT_XS_OPSIZE";
    else if ((index & ATTR_64BIT) && (index & ATTR_XS))
      o << "IC_64BIT_XS";
    else if ((index & ATTR_64BIT) && (index & ATTR_XD))
      o << "IC_64BIT_XD";
    else if ((index & ATTR_64BIT) && (index & ATTR_OPSIZE))
      o << "IC_64BIT_OPSIZE";
    else if ((index & ATTR_64BIT) && (index & ATTR_ADSIZE))
      o << "IC_64BIT_ADSIZE";
    else if ((index & ATTR_64BIT) && (index & ATTR_REXW))
      o << "IC_64BIT_REXW";
    else if ((index & ATTR_64BIT))
      o << "IC_64BIT";
    else if ((index & ATTR_XS) && (index & ATTR_OPSIZE))
      o << "IC_XS_OPSIZE";
    else if ((index & ATTR_XD) && (index & ATTR_OPSIZE))
      o << "IC_XD_OPSIZE";
    else if (index & ATTR_XS)
      o << "IC_XS";
    else if (index & ATTR_XD)
      o << "IC_XD";
    else if (index & ATTR_OPSIZE)
      o << "IC_OPSIZE";
    else if (index & ATTR_ADSIZE)
      o << "IC_ADSIZE";
    else
      o << "IC";

    if (index < tableSize - 1)
      o << ",";
    else
      o << " ";

    o << " /* " << index << " */";

    o << "\n";
  }

  i--;
  o.indent(i * 2) << "};" << "\n";
}
Пример #6
0
/// EmitMatcher - Emit bytes for the specified matcher and return
/// the number of bytes emitted.
unsigned MatcherTableEmitter::
EmitMatcher(const Matcher *N, unsigned Indent, unsigned CurrentIdx,
            raw_ostream &OS) {
  OS.indent(Indent*2);

  switch (N->getKind()) {
  case Matcher::Scope: {
    const ScopeMatcher *SM = cast<ScopeMatcher>(N);
    assert(SM->getNext() == nullptr && "Shouldn't have next after scope");

    unsigned StartIdx = CurrentIdx;

    // Emit all of the children.
    for (unsigned i = 0, e = SM->getNumChildren(); i != e; ++i) {
      if (i == 0) {
        OS << "OPC_Scope, ";
        ++CurrentIdx;
      } else  {
        if (!OmitComments) {
          OS << "/*" << format_decimal(CurrentIdx, IndexWidth) << "*/";
          OS.indent(Indent*2) << "/*Scope*/ ";
        } else
          OS.indent(Indent*2);
      }

      // We need to encode the child and the offset of the failure code before
      // emitting either of them.  Handle this by buffering the output into a
      // string while we get the size.  Unfortunately, the offset of the
      // children depends on the VBR size of the child, so for large children we
      // have to iterate a bit.
      SmallString<128> TmpBuf;
      unsigned ChildSize = 0;
      unsigned VBRSize = 0;
      do {
        VBRSize = GetVBRSize(ChildSize);

        TmpBuf.clear();
        raw_svector_ostream OS(TmpBuf);
        ChildSize = EmitMatcherList(SM->getChild(i), Indent+1,
                                    CurrentIdx+VBRSize, OS);
      } while (GetVBRSize(ChildSize) != VBRSize);

      assert(ChildSize != 0 && "Should not have a zero-sized child!");

      CurrentIdx += EmitVBRValue(ChildSize, OS);
      if (!OmitComments) {
        OS << "/*->" << CurrentIdx+ChildSize << "*/";

        if (i == 0)
          OS << " // " << SM->getNumChildren() << " children in Scope";
      }

      OS << '\n' << TmpBuf;
      CurrentIdx += ChildSize;
    }

    // Emit a zero as a sentinel indicating end of 'Scope'.
    if (!OmitComments)
      OS << "/*" << format_decimal(CurrentIdx, IndexWidth) << "*/";
    OS.indent(Indent*2) << "0, ";
    if (!OmitComments)
      OS << "/*End of Scope*/";
    OS << '\n';
    return CurrentIdx - StartIdx + 1;
  }

  case Matcher::RecordNode:
    OS << "OPC_RecordNode,";
    if (!OmitComments)
      OS << " // #"
         << cast<RecordMatcher>(N)->getResultNo() << " = "
         << cast<RecordMatcher>(N)->getWhatFor();
    OS << '\n';
    return 1;

  case Matcher::RecordChild:
    OS << "OPC_RecordChild" << cast<RecordChildMatcher>(N)->getChildNo()
       << ',';
    if (!OmitComments)
      OS << " // #"
         << cast<RecordChildMatcher>(N)->getResultNo() << " = "
         << cast<RecordChildMatcher>(N)->getWhatFor();
    OS << '\n';
    return 1;

  case Matcher::RecordMemRef:
    OS << "OPC_RecordMemRef,\n";
    return 1;

  case Matcher::CaptureGlueInput:
    OS << "OPC_CaptureGlueInput,\n";
    return 1;

  case Matcher::MoveChild: {
    const auto *MCM = cast<MoveChildMatcher>(N);

    OS << "OPC_MoveChild";
    // Handle the specialized forms.
    if (MCM->getChildNo() >= 8)
      OS << ", ";
    OS << MCM->getChildNo() << ",\n";
    return (MCM->getChildNo() >= 8) ? 2 : 1;
  }

  case Matcher::MoveParent:
    OS << "OPC_MoveParent,\n";
    return 1;

  case Matcher::CheckSame:
    OS << "OPC_CheckSame, "
       << cast<CheckSameMatcher>(N)->getMatchNumber() << ",\n";
    return 2;

  case Matcher::CheckChildSame:
    OS << "OPC_CheckChild"
       << cast<CheckChildSameMatcher>(N)->getChildNo() << "Same, "
       << cast<CheckChildSameMatcher>(N)->getMatchNumber() << ",\n";
    return 2;

  case Matcher::CheckPatternPredicate: {
    StringRef Pred =cast<CheckPatternPredicateMatcher>(N)->getPredicate();
    OS << "OPC_CheckPatternPredicate, " << getPatternPredicate(Pred) << ',';
    if (!OmitComments)
      OS << " // " << Pred;
    OS << '\n';
    return 2;
  }
  case Matcher::CheckPredicate: {
    TreePredicateFn Pred = cast<CheckPredicateMatcher>(N)->getPredicate();
    unsigned OperandBytes = 0;

    if (Pred.usesOperands()) {
      unsigned NumOps = cast<CheckPredicateMatcher>(N)->getNumOperands();
      OS << "OPC_CheckPredicateWithOperands, " << NumOps << "/*#Ops*/, ";
      for (unsigned i = 0; i < NumOps; ++i)
        OS << cast<CheckPredicateMatcher>(N)->getOperandNo(i) << ", ";
      OperandBytes = 1 + NumOps;
    } else {
      OS << "OPC_CheckPredicate, ";
    }

    OS << getNodePredicate(Pred) << ',';
    if (!OmitComments)
      OS << " // " << Pred.getFnName();
    OS << '\n';
    return 2 + OperandBytes;
  }

  case Matcher::CheckOpcode:
    OS << "OPC_CheckOpcode, TARGET_VAL("
       << cast<CheckOpcodeMatcher>(N)->getOpcode().getEnumName() << "),\n";
    return 3;

  case Matcher::SwitchOpcode:
  case Matcher::SwitchType: {
    unsigned StartIdx = CurrentIdx;

    unsigned NumCases;
    if (const SwitchOpcodeMatcher *SOM = dyn_cast<SwitchOpcodeMatcher>(N)) {
      OS << "OPC_SwitchOpcode ";
      NumCases = SOM->getNumCases();
    } else {
      OS << "OPC_SwitchType ";
      NumCases = cast<SwitchTypeMatcher>(N)->getNumCases();
    }

    if (!OmitComments)
      OS << "/*" << NumCases << " cases */";
    OS << ", ";
    ++CurrentIdx;

    // For each case we emit the size, then the opcode, then the matcher.
    for (unsigned i = 0, e = NumCases; i != e; ++i) {
      const Matcher *Child;
      unsigned IdxSize;
      if (const SwitchOpcodeMatcher *SOM = dyn_cast<SwitchOpcodeMatcher>(N)) {
        Child = SOM->getCaseMatcher(i);
        IdxSize = 2;  // size of opcode in table is 2 bytes.
      } else {
        Child = cast<SwitchTypeMatcher>(N)->getCaseMatcher(i);
        IdxSize = 1;  // size of type in table is 1 byte.
      }

      // We need to encode the opcode and the offset of the case code before
      // emitting the case code.  Handle this by buffering the output into a
      // string while we get the size.  Unfortunately, the offset of the
      // children depends on the VBR size of the child, so for large children we
      // have to iterate a bit.
      SmallString<128> TmpBuf;
      unsigned ChildSize = 0;
      unsigned VBRSize = 0;
      do {
        VBRSize = GetVBRSize(ChildSize);

        TmpBuf.clear();
        raw_svector_ostream OS(TmpBuf);
        ChildSize = EmitMatcherList(Child, Indent+1, CurrentIdx+VBRSize+IdxSize,
                                    OS);
      } while (GetVBRSize(ChildSize) != VBRSize);

      assert(ChildSize != 0 && "Should not have a zero-sized child!");

      if (i != 0) {
        if (!OmitComments)
          OS << "/*" << format_decimal(CurrentIdx, IndexWidth) << "*/";
        OS.indent(Indent*2);
        if (!OmitComments)
          OS << (isa<SwitchOpcodeMatcher>(N) ?
                     "/*SwitchOpcode*/ " : "/*SwitchType*/ ");
      }

      // Emit the VBR.
      CurrentIdx += EmitVBRValue(ChildSize, OS);

      if (const SwitchOpcodeMatcher *SOM = dyn_cast<SwitchOpcodeMatcher>(N))
        OS << "TARGET_VAL(" << SOM->getCaseOpcode(i).getEnumName() << "),";
      else
        OS << getEnumName(cast<SwitchTypeMatcher>(N)->getCaseType(i)) << ',';

      CurrentIdx += IdxSize;

      if (!OmitComments)
        OS << "// ->" << CurrentIdx+ChildSize;
      OS << '\n';
      OS << TmpBuf;
      CurrentIdx += ChildSize;
    }

    // Emit the final zero to terminate the switch.
    if (!OmitComments)
      OS << "/*" << format_decimal(CurrentIdx, IndexWidth) << "*/";
    OS.indent(Indent*2) << "0,";
    if (!OmitComments)
      OS << (isa<SwitchOpcodeMatcher>(N) ?
             " // EndSwitchOpcode" : " // EndSwitchType");

    OS << '\n';
    ++CurrentIdx;
    return CurrentIdx-StartIdx;
  }

 case Matcher::CheckType:
    if (cast<CheckTypeMatcher>(N)->getResNo() == 0) {
      OS << "OPC_CheckType, "
         << getEnumName(cast<CheckTypeMatcher>(N)->getType()) << ",\n";
      return 2;
    }
    OS << "OPC_CheckTypeRes, " << cast<CheckTypeMatcher>(N)->getResNo()
       << ", " << getEnumName(cast<CheckTypeMatcher>(N)->getType()) << ",\n";
    return 3;

  case Matcher::CheckChildType:
    OS << "OPC_CheckChild"
       << cast<CheckChildTypeMatcher>(N)->getChildNo() << "Type, "
       << getEnumName(cast<CheckChildTypeMatcher>(N)->getType()) << ",\n";
    return 2;

  case Matcher::CheckInteger: {
    OS << "OPC_CheckInteger, ";
    unsigned Bytes=1+EmitVBRValue(cast<CheckIntegerMatcher>(N)->getValue(), OS);
    OS << '\n';
    return Bytes;
  }
  case Matcher::CheckChildInteger: {
    OS << "OPC_CheckChild" << cast<CheckChildIntegerMatcher>(N)->getChildNo()
       << "Integer, ";
    unsigned Bytes=1+EmitVBRValue(cast<CheckChildIntegerMatcher>(N)->getValue(),
                                  OS);
    OS << '\n';
    return Bytes;
  }
  case Matcher::CheckCondCode:
    OS << "OPC_CheckCondCode, ISD::"
       << cast<CheckCondCodeMatcher>(N)->getCondCodeName() << ",\n";
    return 2;

  case Matcher::CheckChild2CondCode:
    OS << "OPC_CheckChild2CondCode, ISD::"
       << cast<CheckChild2CondCodeMatcher>(N)->getCondCodeName() << ",\n";
    return 2;

  case Matcher::CheckValueType:
    OS << "OPC_CheckValueType, MVT::"
       << cast<CheckValueTypeMatcher>(N)->getTypeName() << ",\n";
    return 2;

  case Matcher::CheckComplexPat: {
    const CheckComplexPatMatcher *CCPM = cast<CheckComplexPatMatcher>(N);
    const ComplexPattern &Pattern = CCPM->getPattern();
    OS << "OPC_CheckComplexPat, /*CP*/" << getComplexPat(Pattern) << ", /*#*/"
       << CCPM->getMatchNumber() << ',';

    if (!OmitComments) {
      OS << " // " << Pattern.getSelectFunc();
      OS << ":$" << CCPM->getName();
      for (unsigned i = 0, e = Pattern.getNumOperands(); i != e; ++i)
        OS << " #" << CCPM->getFirstResult()+i;

      if (Pattern.hasProperty(SDNPHasChain))
        OS << " + chain result";
    }
    OS << '\n';
    return 3;
  }

  case Matcher::CheckAndImm: {
    OS << "OPC_CheckAndImm, ";
    unsigned Bytes=1+EmitVBRValue(cast<CheckAndImmMatcher>(N)->getValue(), OS);
    OS << '\n';
    return Bytes;
  }

  case Matcher::CheckOrImm: {
    OS << "OPC_CheckOrImm, ";
    unsigned Bytes = 1+EmitVBRValue(cast<CheckOrImmMatcher>(N)->getValue(), OS);
    OS << '\n';
    return Bytes;
  }

  case Matcher::CheckFoldableChainNode:
    OS << "OPC_CheckFoldableChainNode,\n";
    return 1;

  case Matcher::CheckImmAllOnesV:
    OS << "OPC_CheckImmAllOnesV,\n";
    return 1;

  case Matcher::CheckImmAllZerosV:
    OS << "OPC_CheckImmAllZerosV,\n";
    return 1;

  case Matcher::EmitInteger: {
    int64_t Val = cast<EmitIntegerMatcher>(N)->getValue();
    OS << "OPC_EmitInteger, "
       << getEnumName(cast<EmitIntegerMatcher>(N)->getVT()) << ", ";
    unsigned Bytes = 2+EmitVBRValue(Val, OS);
    OS << '\n';
    return Bytes;
  }
  case Matcher::EmitStringInteger: {
    const std::string &Val = cast<EmitStringIntegerMatcher>(N)->getValue();
    // These should always fit into one byte.
    OS << "OPC_EmitInteger, "
      << getEnumName(cast<EmitStringIntegerMatcher>(N)->getVT()) << ", "
      << Val << ",\n";
    return 3;
  }

  case Matcher::EmitRegister: {
    const EmitRegisterMatcher *Matcher = cast<EmitRegisterMatcher>(N);
    const CodeGenRegister *Reg = Matcher->getReg();
    // If the enum value of the register is larger than one byte can handle,
    // use EmitRegister2.
    if (Reg && Reg->EnumValue > 255) {
      OS << "OPC_EmitRegister2, " << getEnumName(Matcher->getVT()) << ", ";
      OS << "TARGET_VAL(" << getQualifiedName(Reg->TheDef) << "),\n";
      return 4;
    } else {
      OS << "OPC_EmitRegister, " << getEnumName(Matcher->getVT()) << ", ";
      if (Reg) {
        OS << getQualifiedName(Reg->TheDef) << ",\n";
      } else {
        OS << "0 ";
        if (!OmitComments)
          OS << "/*zero_reg*/";
        OS << ",\n";
      }
      return 3;
    }
  }

  case Matcher::EmitConvertToTarget:
    OS << "OPC_EmitConvertToTarget, "
       << cast<EmitConvertToTargetMatcher>(N)->getSlot() << ",\n";
    return 2;

  case Matcher::EmitMergeInputChains: {
    const EmitMergeInputChainsMatcher *MN =
      cast<EmitMergeInputChainsMatcher>(N);

    // Handle the specialized forms OPC_EmitMergeInputChains1_0, 1_1, and 1_2.
    if (MN->getNumNodes() == 1 && MN->getNode(0) < 3) {
      OS << "OPC_EmitMergeInputChains1_" << MN->getNode(0) << ",\n";
      return 1;
    }

    OS << "OPC_EmitMergeInputChains, " << MN->getNumNodes() << ", ";
    for (unsigned i = 0, e = MN->getNumNodes(); i != e; ++i)
      OS << MN->getNode(i) << ", ";
    OS << '\n';
    return 2+MN->getNumNodes();
  }
  case Matcher::EmitCopyToReg:
    OS << "OPC_EmitCopyToReg, "
       << cast<EmitCopyToRegMatcher>(N)->getSrcSlot() << ", "
       << getQualifiedName(cast<EmitCopyToRegMatcher>(N)->getDestPhysReg())
       << ",\n";
    return 3;
  case Matcher::EmitNodeXForm: {
    const EmitNodeXFormMatcher *XF = cast<EmitNodeXFormMatcher>(N);
    OS << "OPC_EmitNodeXForm, " << getNodeXFormID(XF->getNodeXForm()) << ", "
       << XF->getSlot() << ',';
    if (!OmitComments)
      OS << " // "<<XF->getNodeXForm()->getName();
    OS <<'\n';
    return 3;
  }

  case Matcher::EmitNode:
  case Matcher::MorphNodeTo: {
    auto NumCoveredBytes = 0;
    if (InstrumentCoverage) {
      if (const MorphNodeToMatcher *SNT = dyn_cast<MorphNodeToMatcher>(N)) {
        NumCoveredBytes = 3;
        OS << "OPC_Coverage, ";
        std::string src =
            GetPatFromTreePatternNode(SNT->getPattern().getSrcPattern());
        std::string dst =
            GetPatFromTreePatternNode(SNT->getPattern().getDstPattern());
        Record *PatRecord = SNT->getPattern().getSrcRecord();
        std::string include_src = getIncludePath(PatRecord);
        unsigned Offset =
            getPatternIdxFromTable(src + " -> " + dst, std::move(include_src));
        OS << "TARGET_VAL(" << Offset << "),\n";
        OS.indent(FullIndexWidth + Indent * 2);
      }
    }
    const EmitNodeMatcherCommon *EN = cast<EmitNodeMatcherCommon>(N);
    OS << (isa<EmitNodeMatcher>(EN) ? "OPC_EmitNode" : "OPC_MorphNodeTo");
    bool CompressVTs = EN->getNumVTs() < 3;
    if (CompressVTs)
      OS << EN->getNumVTs();

    OS << ", TARGET_VAL(" << EN->getOpcodeName() << "), 0";

    if (EN->hasChain())   OS << "|OPFL_Chain";
    if (EN->hasInFlag())  OS << "|OPFL_GlueInput";
    if (EN->hasOutFlag()) OS << "|OPFL_GlueOutput";
    if (EN->hasMemRefs()) OS << "|OPFL_MemRefs";
    if (EN->getNumFixedArityOperands() != -1)
      OS << "|OPFL_Variadic" << EN->getNumFixedArityOperands();
    OS << ",\n";

    OS.indent(FullIndexWidth + Indent*2+4);
    if (!CompressVTs) {
      OS << EN->getNumVTs();
      if (!OmitComments)
        OS << "/*#VTs*/";
      OS << ", ";
    }
    for (unsigned i = 0, e = EN->getNumVTs(); i != e; ++i)
      OS << getEnumName(EN->getVT(i)) << ", ";

    OS << EN->getNumOperands();
    if (!OmitComments)
      OS << "/*#Ops*/";
    OS << ", ";
    unsigned NumOperandBytes = 0;
    for (unsigned i = 0, e = EN->getNumOperands(); i != e; ++i)
      NumOperandBytes += EmitVBRValue(EN->getOperand(i), OS);

    if (!OmitComments) {
      // Print the result #'s for EmitNode.
      if (const EmitNodeMatcher *E = dyn_cast<EmitNodeMatcher>(EN)) {
        if (unsigned NumResults = EN->getNumVTs()) {
          OS << " // Results =";
          unsigned First = E->getFirstResultSlot();
          for (unsigned i = 0; i != NumResults; ++i)
            OS << " #" << First+i;
        }
      }
      OS << '\n';

      if (const MorphNodeToMatcher *SNT = dyn_cast<MorphNodeToMatcher>(N)) {
        OS.indent(FullIndexWidth + Indent*2) << "// Src: "
          << *SNT->getPattern().getSrcPattern() << " - Complexity = "
          << SNT->getPattern().getPatternComplexity(CGP) << '\n';
        OS.indent(FullIndexWidth + Indent*2) << "// Dst: "
          << *SNT->getPattern().getDstPattern() << '\n';
      }
    } else
      OS << '\n';

    return 5 + !CompressVTs + EN->getNumVTs() + NumOperandBytes +
           NumCoveredBytes;
  }
  case Matcher::CompleteMatch: {
    const CompleteMatchMatcher *CM = cast<CompleteMatchMatcher>(N);
    auto NumCoveredBytes = 0;
    if (InstrumentCoverage) {
      NumCoveredBytes = 3;
      OS << "OPC_Coverage, ";
      std::string src =
          GetPatFromTreePatternNode(CM->getPattern().getSrcPattern());
      std::string dst =
          GetPatFromTreePatternNode(CM->getPattern().getDstPattern());
      Record *PatRecord = CM->getPattern().getSrcRecord();
      std::string include_src = getIncludePath(PatRecord);
      unsigned Offset =
          getPatternIdxFromTable(src + " -> " + dst, std::move(include_src));
      OS << "TARGET_VAL(" << Offset << "),\n";
      OS.indent(FullIndexWidth + Indent * 2);
    }
    OS << "OPC_CompleteMatch, " << CM->getNumResults() << ", ";
    unsigned NumResultBytes = 0;
    for (unsigned i = 0, e = CM->getNumResults(); i != e; ++i)
      NumResultBytes += EmitVBRValue(CM->getResult(i), OS);
    OS << '\n';
    if (!OmitComments) {
      OS.indent(FullIndexWidth + Indent*2) << " // Src: "
        << *CM->getPattern().getSrcPattern() << " - Complexity = "
        << CM->getPattern().getPatternComplexity(CGP) << '\n';
      OS.indent(FullIndexWidth + Indent*2) << " // Dst: "
        << *CM->getPattern().getDstPattern();
    }
    OS << '\n';
    return 2 + NumResultBytes + NumCoveredBytes;
  }
  }
  llvm_unreachable("Unreachable");
}
Пример #7
0
void Module::print(raw_ostream &OS, unsigned Indent) const {
  OS.indent(Indent);
  if (IsFramework)
    OS << "framework ";
  if (IsExplicit)
    OS << "explicit ";
  OS << "module " << Name;

  if (IsSystem) {
    OS.indent(Indent + 2);
    OS << " [system]";
  }

  OS << " {\n";
  
  if (!Requires.empty()) {
    OS.indent(Indent + 2);
    OS << "requires ";
    for (unsigned I = 0, N = Requires.size(); I != N; ++I) {
      if (I)
        OS << ", ";
      OS << Requires[I];
    }
    OS << "\n";
  }
  
  if (const FileEntry *UmbrellaHeader = getUmbrellaHeader()) {
    OS.indent(Indent + 2);
    OS << "umbrella header \"";
    OS.write_escaped(UmbrellaHeader->getName());
    OS << "\"\n";
  } else if (const DirectoryEntry *UmbrellaDir = getUmbrellaDir()) {
    OS.indent(Indent + 2);
    OS << "umbrella \"";
    OS.write_escaped(UmbrellaDir->getName());
    OS << "\"\n";    
  }

  if (!ConfigMacros.empty() || ConfigMacrosExhaustive) {
    OS.indent(Indent + 2);
    OS << "config_macros ";
    if (ConfigMacrosExhaustive)
      OS << "[exhaustive]";
    for (unsigned I = 0, N = ConfigMacros.size(); I != N; ++I) {
      if (I)
        OS << ", ";
      OS << ConfigMacros[I];
    }
    OS << "\n";
  }

  for (unsigned I = 0, N = NormalHeaders.size(); I != N; ++I) {
    OS.indent(Indent + 2);
    OS << "header \"";
    OS.write_escaped(NormalHeaders[I]->getName());
    OS << "\"\n";
  }

  for (unsigned I = 0, N = ExcludedHeaders.size(); I != N; ++I) {
    OS.indent(Indent + 2);
    OS << "exclude header \"";
    OS.write_escaped(ExcludedHeaders[I]->getName());
    OS << "\"\n";
  }

  for (unsigned I = 0, N = PrivateHeaders.size(); I != N; ++I) {
    OS.indent(Indent + 2);
    OS << "private header \"";
    OS.write_escaped(PrivateHeaders[I]->getName());
    OS << "\"\n";
  }
  
  for (submodule_const_iterator MI = submodule_begin(), MIEnd = submodule_end();
       MI != MIEnd; ++MI)
    (*MI)->print(OS, Indent + 2);
  
  for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
    OS.indent(Indent + 2);
    OS << "export ";
    if (Module *Restriction = Exports[I].getPointer()) {
      OS << Restriction->getFullModuleName();
      if (Exports[I].getInt())
        OS << ".*";
    } else {
      OS << "*";
    }
    OS << "\n";
  }

  for (unsigned I = 0, N = UnresolvedExports.size(); I != N; ++I) {
    OS.indent(Indent + 2);
    OS << "export ";
    printModuleId(OS, UnresolvedExports[I].Id);
    if (UnresolvedExports[I].Wildcard) {
      if (UnresolvedExports[I].Id.empty())
        OS << "*";
      else
        OS << ".*";
    }
    OS << "\n";
  }

  for (unsigned I = 0, N = LinkLibraries.size(); I != N; ++I) {
    OS.indent(Indent + 2);
    OS << "link ";
    if (LinkLibraries[I].IsFramework)
      OS << "framework ";
    OS << "\"";
    OS.write_escaped(LinkLibraries[I].Library);
    OS << "\"";
  }

  for (unsigned I = 0, N = UnresolvedConflicts.size(); I != N; ++I) {
    OS.indent(Indent + 2);
    OS << "conflict ";
    printModuleId(OS, UnresolvedConflicts[I].Id);
    OS << ", \"";
    OS.write_escaped(UnresolvedConflicts[I].Message);
    OS << "\"\n";
  }

  for (unsigned I = 0, N = Conflicts.size(); I != N; ++I) {
    OS.indent(Indent + 2);
    OS << "conflict ";
    OS << Conflicts[I].Other->getFullModuleName();
    OS << ", \"";
    OS.write_escaped(Conflicts[I].Message);
    OS << "\"\n";
  }

  if (InferSubmodules) {
    OS.indent(Indent + 2);
    if (InferExplicitSubmodules)
      OS << "explicit ";
    OS << "module * {\n";
    if (InferExportWildcard) {
      OS.indent(Indent + 4);
      OS << "export *\n";
    }
    OS.indent(Indent + 2);
    OS << "}\n";
  }
  
  OS.indent(Indent);
  OS << "}\n";
}
Пример #8
0
void EmitCopyToRegMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
  OS.indent(indent) << "EmitCopyToReg <todo: args>\n";
}
Пример #9
0
void EmitNodeXFormMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
  OS.indent(indent) << "EmitNodeXForm " << NodeXForm->getName()
     << " Slot=" << Slot << '\n';
}
Пример #10
0
void EmitConvertToTargetMatcher::
printImpl(raw_ostream &OS, unsigned indent) const {
  OS.indent(indent) << "EmitConvertToTarget " << Slot << '\n';
}
Пример #11
0
void EmitMergeInputChainsMatcher::
printImpl(raw_ostream &OS, unsigned indent) const {
  OS.indent(indent) << "EmitMergeInputChains <todo: args>\n";
}
Пример #12
0
void EmitStringIntegerMatcher::
printImpl(raw_ostream &OS, unsigned indent) const {
  OS.indent(indent) << "EmitStringInteger " << Val << " VT=" << getEnumName(VT)
                    << '\n';
}
Пример #13
0
void CheckImmAllZerosVMatcher::printImpl(raw_ostream &OS,
                                         unsigned indent) const {
  OS.indent(indent) << "CheckAllZerosV\n";
}
Пример #14
0
void CheckFoldableChainNodeMatcher::printImpl(raw_ostream &OS,
                                              unsigned indent) const {
  OS.indent(indent) << "CheckFoldableChainNode\n";
}
Пример #15
0
void OtherPlatformAvailabilitySpec::print(raw_ostream &OS, unsigned Indent) const {
  OS.indent(Indent) << '(' << "other_constraint_availability_spec"
                    << " "
                    << ')';
}
Пример #16
0
void CompleteMatchMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
  OS.indent(indent) << "CompleteMatch <todo args>\n";
  OS.indent(indent) << "Src = " << *Pattern.getSrcPattern() << "\n";
  OS.indent(indent) << "Dst = " << *Pattern.getDstPattern() << "\n";
}
Пример #17
0
void Module::print(raw_ostream &OS, unsigned Indent) const {
  OS.indent(Indent);
  if (IsFramework)
    OS << "framework ";
  if (IsExplicit)
    OS << "explicit ";
  OS << "module " << Name;

  if (IsSystem || IsExternC) {
    OS.indent(Indent + 2);
    if (IsSystem)
      OS << " [system]";
    if (IsExternC)
      OS << " [extern_c]";
  }

  OS << " {\n";
  
  if (!Requirements.empty()) {
    OS.indent(Indent + 2);
    OS << "requires ";
    for (unsigned I = 0, N = Requirements.size(); I != N; ++I) {
      if (I)
        OS << ", ";
      if (!Requirements[I].second)
        OS << "!";
      OS << Requirements[I].first;
    }
    OS << "\n";
  }
  
  if (Header H = getUmbrellaHeader()) {
    OS.indent(Indent + 2);
    OS << "umbrella header \"";
    OS.write_escaped(H.NameAsWritten);
    OS << "\"\n";
  } else if (DirectoryName D = getUmbrellaDir()) {
    OS.indent(Indent + 2);
    OS << "umbrella \"";
    OS.write_escaped(D.NameAsWritten);
    OS << "\"\n";    
  }

  if (!ConfigMacros.empty() || ConfigMacrosExhaustive) {
    OS.indent(Indent + 2);
    OS << "config_macros ";
    if (ConfigMacrosExhaustive)
      OS << "[exhaustive]";
    for (unsigned I = 0, N = ConfigMacros.size(); I != N; ++I) {
      if (I)
        OS << ", ";
      OS << ConfigMacros[I];
    }
    OS << "\n";
  }

  struct {
    StringRef Prefix;
    HeaderKind Kind;
  } Kinds[] = {{"", HK_Normal},
               {"textual ", HK_Textual},
               {"private ", HK_Private},
               {"private textual ", HK_PrivateTextual},
               {"exclude ", HK_Excluded}};

  for (auto &K : Kinds) {
    for (auto &H : Headers[K.Kind]) {
      OS.indent(Indent + 2);
      OS << K.Prefix << "header \"";
      OS.write_escaped(H.NameAsWritten);
      OS << "\"\n";
    }
  }

  for (submodule_const_iterator MI = submodule_begin(), MIEnd = submodule_end();
       MI != MIEnd; ++MI)
    // Print inferred subframework modules so that we don't need to re-infer
    // them (requires expensive directory iteration + stat calls) when we build
    // the module. Regular inferred submodules are OK, as we need to look at all
    // those header files anyway.
    if (!(*MI)->IsInferred || (*MI)->IsFramework)
      (*MI)->print(OS, Indent + 2);
  
  for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
    OS.indent(Indent + 2);
    OS << "export ";
    if (Module *Restriction = Exports[I].getPointer()) {
      OS << Restriction->getFullModuleName();
      if (Exports[I].getInt())
        OS << ".*";
    } else {
      OS << "*";
    }
    OS << "\n";
  }

  for (unsigned I = 0, N = UnresolvedExports.size(); I != N; ++I) {
    OS.indent(Indent + 2);
    OS << "export ";
    printModuleId(OS, UnresolvedExports[I].Id);
    if (UnresolvedExports[I].Wildcard)
      OS << (UnresolvedExports[I].Id.empty() ? "*" : ".*");
    OS << "\n";
  }

  for (unsigned I = 0, N = DirectUses.size(); I != N; ++I) {
    OS.indent(Indent + 2);
    OS << "use ";
    OS << DirectUses[I]->getFullModuleName();
    OS << "\n";
  }

  for (unsigned I = 0, N = UnresolvedDirectUses.size(); I != N; ++I) {
    OS.indent(Indent + 2);
    OS << "use ";
    printModuleId(OS, UnresolvedDirectUses[I]);
    OS << "\n";
  }

  for (unsigned I = 0, N = LinkLibraries.size(); I != N; ++I) {
    OS.indent(Indent + 2);
    OS << "link ";
    if (LinkLibraries[I].IsFramework)
      OS << "framework ";
    OS << "\"";
    OS.write_escaped(LinkLibraries[I].Library);
    OS << "\"";
  }

  for (unsigned I = 0, N = UnresolvedConflicts.size(); I != N; ++I) {
    OS.indent(Indent + 2);
    OS << "conflict ";
    printModuleId(OS, UnresolvedConflicts[I].Id);
    OS << ", \"";
    OS.write_escaped(UnresolvedConflicts[I].Message);
    OS << "\"\n";
  }

  for (unsigned I = 0, N = Conflicts.size(); I != N; ++I) {
    OS.indent(Indent + 2);
    OS << "conflict ";
    OS << Conflicts[I].Other->getFullModuleName();
    OS << ", \"";
    OS.write_escaped(Conflicts[I].Message);
    OS << "\"\n";
  }

  if (InferSubmodules) {
    OS.indent(Indent + 2);
    if (InferExplicitSubmodules)
      OS << "explicit ";
    OS << "module * {\n";
    if (InferExportWildcard) {
      OS.indent(Indent + 4);
      OS << "export *\n";
    }
    OS.indent(Indent + 2);
    OS << "}\n";
  }
  
  OS.indent(Indent);
  OS << "}\n";
}
Пример #18
0
/// emitEmptyTable - Emits the modRMEmptyTable, which is used as a ID table by
///   all ModR/M decisions for instructions that are invalid for all possible
///   ModR/M byte values.
///
/// @param o        - The output stream on which to emit the table.
/// @param i        - The indentation level for that output stream.
static void emitEmptyTable(raw_ostream &o, uint32_t &i)
{
  o.indent(i * 2) << "static const InstrUID modRMEmptyTable[1] = { 0 };\n";
  o << "\n";
}
Пример #19
0
void AMDGPUInstPrinter::printLast(const MCInst *MI, unsigned OpNo,
                                  raw_ostream &O) {
  printIfSet(MI, OpNo, O.indent(25 - O.GetNumBytesInBuffer()), "*", " ");
}
Пример #20
0
void DisassemblerTables::emitModRMDecision(raw_ostream &o1,
                                           raw_ostream &o2,
                                           uint32_t &i1,
                                           uint32_t &i2,
                                           ModRMDecision &decision)
  const {
  static uint64_t sTableNumber = 0;
  uint64_t thisTableNumber = sTableNumber;
  ModRMDecisionType dt = getDecisionType(decision);
  uint16_t index;
  
  if (dt == MODRM_ONEENTRY && decision.instructionIDs[0] == 0)
  {
    o2.indent(i2) << "{ /* ModRMDecision */" << "\n";
    i2++;
    
    o2.indent(i2) << stringForDecisionType(dt) << "," << "\n";
    o2.indent(i2) << "modRMEmptyTable";
    
    i2--;
    o2.indent(i2) << "}";
    return;
  }
    
  o1.indent(i1) << "static const InstrUID modRMTable" << thisTableNumber;
    
  switch (dt) {
    default:
      llvm_unreachable("Unknown decision type");
    case MODRM_ONEENTRY:
      o1 << "[1]";
      break;
    case MODRM_SPLITRM:
      o1 << "[2]";
      break;
    case MODRM_FULL:
      o1 << "[256]";
      break;      
  }

  o1 << " = {" << "\n";
  i1++;
    
  switch (dt) {
    default:
      llvm_unreachable("Unknown decision type");
    case MODRM_ONEENTRY:
      emitOneID(o1, i1, decision.instructionIDs[0], false);
      break;
    case MODRM_SPLITRM:
      emitOneID(o1, i1, decision.instructionIDs[0x00], true); // mod = 0b00
      emitOneID(o1, i1, decision.instructionIDs[0xc0], false); // mod = 0b11
      break;
    case MODRM_FULL:
      for (index = 0; index < 256; ++index)
        emitOneID(o1, i1, decision.instructionIDs[index], index < 255);
      break;
  }
    
  i1--;
  o1.indent(i1) << "};" << "\n";
  o1 << "\n";
    
  o2.indent(i2) << "{ /* struct ModRMDecision */" << "\n";
  i2++;
    
  o2.indent(i2) << stringForDecisionType(dt) << "," << "\n";
  o2.indent(i2) << "modRMTable" << sTableNumber << "\n";
    
  i2--;
  o2.indent(i2) << "}";
    
  ++sTableNumber;
}
Пример #21
0
unsigned DeclContext::printContext(raw_ostream &OS, const unsigned indent,
                                   const bool onlyAPartialLine) const {
  unsigned Depth = 0;
  if (!onlyAPartialLine)
    if (auto *P = getParent())
      Depth = P->printContext(OS, indent);

  const char *Kind;
  switch (getContextKind()) {
  case DeclContextKind::Module:           Kind = "Module"; break;
  case DeclContextKind::FileUnit:         Kind = "FileUnit"; break;
  case DeclContextKind::SerializedLocal:  Kind = "Serialized Local"; break;
  case DeclContextKind::AbstractClosureExpr:
    Kind = "AbstractClosureExpr";
    break;
  case DeclContextKind::GenericTypeDecl:
    switch (cast<GenericTypeDecl>(this)->getKind()) {
#define DECL(ID, PARENT) \
    case DeclKind::ID: Kind = #ID "Decl"; break;
#include "swift/AST/DeclNodes.def"
    }
    break;
  case DeclContextKind::ExtensionDecl:    Kind = "ExtensionDecl"; break;
  case DeclContextKind::TopLevelCodeDecl: Kind = "TopLevelCodeDecl"; break;
  case DeclContextKind::Initializer:      Kind = "Initializer"; break;
  case DeclContextKind::AbstractFunctionDecl:
    Kind = "AbstractFunctionDecl";
    break;
  case DeclContextKind::SubscriptDecl:    Kind = "SubscriptDecl"; break;
  case DeclContextKind::EnumElementDecl:  Kind = "EnumElementDecl"; break;
  }
  OS.indent(Depth*2 + indent) << (void*)this << " " << Kind;

  switch (getContextKind()) {
  case DeclContextKind::Module:
    OS << " name=" << cast<ModuleDecl>(this)->getName();
    break;
  case DeclContextKind::FileUnit:
    switch (cast<FileUnit>(this)->getKind()) {
    case FileUnitKind::Builtin:
      OS << " Builtin";
      break;
    case FileUnitKind::Source:
      OS << " file=\"" << cast<SourceFile>(this)->getFilename() << "\"";
      break;
    case FileUnitKind::SerializedAST:
    case FileUnitKind::ClangModule:
    case FileUnitKind::DWARFModule:
      OS << " file=\"" << cast<LoadedFile>(this)->getFilename() << "\"";
      break;
    }
    break;
  case DeclContextKind::AbstractClosureExpr:
    OS << " line=" << getLineNumber(cast<AbstractClosureExpr>(this));
    OS << " : " << cast<AbstractClosureExpr>(this)->getType();
    break;
  case DeclContextKind::GenericTypeDecl:
    OS << " name=" << cast<GenericTypeDecl>(this)->getName();
    break;
  case DeclContextKind::ExtensionDecl:
    OS << " line=" << getLineNumber(cast<ExtensionDecl>(this));
    OS << " base=" << cast<ExtensionDecl>(this)->getExtendedType();
    break;
  case DeclContextKind::TopLevelCodeDecl:
    OS << " line=" << getLineNumber(cast<TopLevelCodeDecl>(this));
    break;
  case DeclContextKind::AbstractFunctionDecl: {
    auto *AFD = cast<AbstractFunctionDecl>(this);
    OS << " name=" << AFD->getFullName();
    if (AFD->hasInterfaceType())
      OS << " : " << AFD->getInterfaceType();
    else
      OS << " : (no type set)";
    break;
  }
  case DeclContextKind::SubscriptDecl: {
    auto *SD = cast<SubscriptDecl>(this);
    OS << " name=" << SD->getBaseName();
    if (SD->hasInterfaceType())
      OS << " : " << SD->getInterfaceType();
    else
      OS << " : (no type set)";
    break;
  }
  case DeclContextKind::EnumElementDecl: {
    auto *EED = cast<EnumElementDecl>(this);
    OS << " name=" << EED->getBaseName();
    if (EED->hasInterfaceType())
      OS << " : " << EED->getInterfaceType();
    else
      OS << " : (no type set)";
    break;
  }
  case DeclContextKind::Initializer:
    switch (cast<Initializer>(this)->getInitializerKind()) {
    case InitializerKind::PatternBinding: {
      auto init = cast<PatternBindingInitializer>(this);
      OS << " PatternBinding 0x" << (void*) init->getBinding()
         << " #" << init->getBindingIndex();
      break;
    }
    case InitializerKind::DefaultArgument: {
      auto init = cast<DefaultArgumentInitializer>(this);
      OS << " DefaultArgument index=" << init->getIndex();
      break;
    }
    }
    break;

  case DeclContextKind::SerializedLocal: {
    auto local = cast<SerializedLocalDeclContext>(this);
    switch (local->getLocalDeclContextKind()) {
    case LocalDeclContextKind::AbstractClosure: {
      auto serializedClosure = cast<SerializedAbstractClosureExpr>(local);
      OS << " closure : " << serializedClosure->getType();
      break;
    }
    case LocalDeclContextKind::DefaultArgumentInitializer: {
      auto init = cast<SerializedDefaultArgumentInitializer>(local);
      OS << "DefaultArgument index=" << init->getIndex();
      break;
    }
    case LocalDeclContextKind::PatternBindingInitializer: {
      auto init = cast<SerializedPatternBindingInitializer>(local);
      OS << " PatternBinding 0x" << (void*) init->getBinding()
         << " #" << init->getBindingIndex();
      break;
    }
    case LocalDeclContextKind::TopLevelCodeDecl:
      OS << " TopLevelCode";
      break;
    }
  }
  }

  if (!onlyAPartialLine)
    OS << "\n";
  return Depth + 1;
}
Пример #22
0
static void dumpAttribute(raw_ostream &OS, const DWARFDie &Die,
                          uint32_t *OffsetPtr, dwarf::Attribute Attr,
                          dwarf::Form Form, unsigned Indent,
                          DIDumpOptions DumpOpts) {
  if (!Die.isValid())
    return;
  const char BaseIndent[] = "            ";
  OS << BaseIndent;
  OS.indent(Indent+2);
  auto attrString = AttributeString(Attr);
  if (!attrString.empty())
    WithColor(OS, syntax::Attribute) << attrString;
  else
    WithColor(OS, syntax::Attribute).get() << format("DW_AT_Unknown_%x", Attr);

  if (DumpOpts.Verbose) {
    auto formString = FormEncodingString(Form);
    if (!formString.empty())
      OS << " [" << formString << ']';
    else
      OS << format(" [DW_FORM_Unknown_%x]", Form);
  }

  DWARFUnit *U = Die.getDwarfUnit();
  DWARFFormValue formValue(Form);

  if (!formValue.extractValue(U->getDebugInfoExtractor(), OffsetPtr, U))
    return;

  OS << "\t(";

  StringRef Name;
  std::string File;
  auto Color = syntax::Enumerator;
  if (Attr == DW_AT_decl_file || Attr == DW_AT_call_file) {
    Color = syntax::String;
    if (const auto *LT = U->getContext().getLineTableForUnit(U))
      if (LT->getFileNameByIndex(formValue.getAsUnsignedConstant().getValue(), U->getCompilationDir(), DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, File)) {
        File = '"' + File + '"';
        Name = File;
      }
  } else if (Optional<uint64_t> Val = formValue.getAsUnsignedConstant())
    Name = AttributeValueString(Attr, *Val);

  if (!Name.empty())
    WithColor(OS, Color) << Name;
  else if (Attr == DW_AT_decl_line || Attr == DW_AT_call_line)
    OS << *formValue.getAsUnsignedConstant();
  else if (Attr == DW_AT_location || Attr == DW_AT_frame_base ||
           Attr == DW_AT_data_member_location)
    dumpLocation(OS, formValue, U, sizeof(BaseIndent) + Indent + 4, DumpOpts);
  else
    formValue.dump(OS, DumpOpts);

  // We have dumped the attribute raw value. For some attributes
  // having both the raw value and the pretty-printed value is
  // interesting. These attributes are handled below.
  if (Attr == DW_AT_specification || Attr == DW_AT_abstract_origin) {
    if (const char *Name = Die.getAttributeValueAsReferencedDie(Attr).getName(DINameKind::LinkageName))
        OS << " \"" << Name << '\"';
  } else if (Attr == DW_AT_APPLE_property_attribute) {
    if (Optional<uint64_t> OptVal = formValue.getAsUnsignedConstant())
      dumpApplePropertyAttribute(OS, *OptVal);
  } else if (Attr == DW_AT_ranges) {
    const DWARFObject &Obj = Die.getDwarfUnit()->getContext().getDWARFObj();
    dumpRanges(Obj, OS, Die.getAddressRanges(), U->getAddressByteSize(),
               sizeof(BaseIndent) + Indent + 4, DumpOpts);
  }

  OS << ")\n";
}
Пример #23
0
void DisassemblerTables::emitInstructionInfo(raw_ostream &o,
                                             unsigned &i) const {
  unsigned NumInstructions = InstructionSpecifiers.size();

  o << "static const struct OperandSpecifier x86OperandSets[]["
    << X86_MAX_OPERANDS << "] = {\n";

  typedef std::vector<std::pair<const char *, const char *> > OperandListTy;
  std::map<OperandListTy, unsigned> OperandSets;

  unsigned OperandSetNum = 0;
  for (unsigned Index = 0; Index < NumInstructions; ++Index) {
    OperandListTy OperandList;

    for (unsigned OperandIndex = 0; OperandIndex < X86_MAX_OPERANDS;
         ++OperandIndex) {
      const char *Encoding =
        stringForOperandEncoding((OperandEncoding)InstructionSpecifiers[Index]
                                 .operands[OperandIndex].encoding);
      const char *Type =
        stringForOperandType((OperandType)InstructionSpecifiers[Index]
                             .operands[OperandIndex].type);
      OperandList.push_back(std::make_pair(Encoding, Type));
    }
    unsigned &N = OperandSets[OperandList];
    if (N != 0) continue;

    N = ++OperandSetNum;

    o << "  { /* " << (OperandSetNum - 1) << " */\n";
    for (unsigned i = 0, e = OperandList.size(); i != e; ++i) {
      o << "    { " << OperandList[i].first << ", "
        << OperandList[i].second << " },\n";
    }
    o << "  },\n";
  }
  o << "};" << "\n\n";

  o.indent(i * 2) << "static const struct InstructionSpecifier ";
  o << INSTRUCTIONS_STR "[" << InstructionSpecifiers.size() << "] = {\n";

  i++;

  for (unsigned index = 0; index < NumInstructions; ++index) {
    o.indent(i * 2) << "{ /* " << index << " */" << "\n";
    i++;

    OperandListTy OperandList;
    for (unsigned OperandIndex = 0; OperandIndex < X86_MAX_OPERANDS;
         ++OperandIndex) {
      const char *Encoding =
        stringForOperandEncoding((OperandEncoding)InstructionSpecifiers[index]
                                 .operands[OperandIndex].encoding);
      const char *Type =
        stringForOperandType((OperandType)InstructionSpecifiers[index]
                             .operands[OperandIndex].type);
      OperandList.push_back(std::make_pair(Encoding, Type));
    }
    o.indent(i * 2) << (OperandSets[OperandList] - 1) << ",\n";

    o.indent(i * 2) << "/* " << InstructionSpecifiers[index].name << " */";
    o << "\n";

    i--;
    o.indent(i * 2) << "}";

    if (index + 1 < NumInstructions)
      o << ",";

    o << "\n";
  }

  i--;
  o.indent(i * 2) << "};" << "\n";
}
Пример #24
0
void DWARFDie::dump(raw_ostream &OS, unsigned RecurseDepth, unsigned Indent,
                    DIDumpOptions DumpOpts) const {
  if (!isValid())
    return;
  DWARFDataExtractor debug_info_data = U->getDebugInfoExtractor();
  const uint32_t Offset = getOffset();
  uint32_t offset = Offset;
  if (DumpOpts.ShowChildren)
    RecurseDepth++;
  if (DumpOpts.ShowParents) {
    DumpOpts.ShowParents = false;
    Indent = dumpParentChain(getParent(), OS, Indent, DumpOpts);
  }

  if (debug_info_data.isValidOffset(offset)) {
    uint32_t abbrCode = debug_info_data.getULEB128(&offset);
    WithColor(OS, syntax::Address).get() << format("\n0x%8.8x: ", Offset);

    if (abbrCode) {
      auto AbbrevDecl = getAbbreviationDeclarationPtr();
      if (AbbrevDecl) {
        auto tagString = TagString(getTag());
        if (!tagString.empty())
          WithColor(OS, syntax::Tag).get().indent(Indent) << tagString;
        else
          WithColor(OS, syntax::Tag).get().indent(Indent)
          << format("DW_TAG_Unknown_%x", getTag());

        if (DumpOpts.Verbose)
          OS << format(" [%u] %c", abbrCode,
                       AbbrevDecl->hasChildren() ? '*' : ' ');
        OS << '\n';

        // Dump all data in the DIE for the attributes.
        for (const auto &AttrSpec : AbbrevDecl->attributes()) {
          if (AttrSpec.Form == DW_FORM_implicit_const) {
            // We are dumping .debug_info section ,
            // implicit_const attribute values are not really stored here,
            // but in .debug_abbrev section. So we just skip such attrs.
            continue;
          }
          dumpAttribute(OS, *this, &offset, AttrSpec.Attr, AttrSpec.Form,
                        Indent, DumpOpts);
        }

        DWARFDie child = getFirstChild();
        if (RecurseDepth > 0 && child) {
          while (child) {
            child.dump(OS, RecurseDepth-1, Indent+2, DumpOpts);
            child = child.getSibling();
          }
        }
      } else {
        OS << "Abbreviation code not found in 'debug_abbrev' class for code: "
        << abbrCode << '\n';
      }
    } else {
      OS.indent(Indent) << "NULL\n";
    }
  }
}
Пример #25
0
void RecordChildMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
  OS.indent(indent) << "RecordChild: " << ChildNo << '\n';
}
// Emits code to decode the singleton.  Return true if we have matched all the
// well-known bits.
bool FilterChooser::emitSingletonDecoder(raw_ostream &o, unsigned &Indentation,
                                         unsigned Opc) {
  std::vector<unsigned> StartBits;
  std::vector<unsigned> EndBits;
  std::vector<uint64_t> FieldVals;
  insn_t Insn;
  insnWithID(Insn, Opc);

  // Look for islands of undecoded bits of the singleton.
  getIslands(StartBits, EndBits, FieldVals, Insn);

  unsigned Size = StartBits.size();
  unsigned I, NumBits;

  // If we have matched all the well-known bits, just issue a return.
  if (Size == 0) {
    o.indent(Indentation) << "if (";
    if (!emitPredicateMatch(o, Indentation, Opc))
      o << "1";
    o << ") {\n";
    o.indent(Indentation) << "  MI.setOpcode(" << Opc << ");\n";
    std::vector<OperandInfo>& InsnOperands = Operands[Opc];
    for (std::vector<OperandInfo>::iterator
         I = InsnOperands.begin(), E = InsnOperands.end(); I != E; ++I) {
      // If a custom instruction decoder was specified, use that.
      if (I->numFields() == 0 && I->Decoder.size()) {
        o.indent(Indentation) << "  " << Emitter->GuardPrefix << I->Decoder
                              << "(MI, insn, Address, Decoder)" << Emitter->GuardPostfix << "\n";
        break;
      }

      emitBinaryParser(o, Indentation, *I);
    }

    o.indent(Indentation) << "  return " << Emitter->ReturnOK << "; // " << nameWithID(Opc)
                          << '\n';
    o.indent(Indentation) << "}\n"; // Closing predicate block.
    return true;
  }

  // Otherwise, there are more decodings to be done!

  // Emit code to match the island(s) for the singleton.
  o.indent(Indentation) << "// Check ";

  for (I = Size; I != 0; --I) {
    o << "Inst{" << EndBits[I-1] << '-' << StartBits[I-1] << "} ";
    if (I > 1)
      o << " && ";
    else
      o << "for singleton decoding...\n";
  }

  o.indent(Indentation) << "if (";
  if (emitPredicateMatch(o, Indentation, Opc)) {
    o << " &&\n";
    o.indent(Indentation+4);
  }

  for (I = Size; I != 0; --I) {
    NumBits = EndBits[I-1] - StartBits[I-1] + 1;
    o << "fieldFromInstruction" << BitWidth << "(insn, "
      << StartBits[I-1] << ", " << NumBits
      << ") == " << FieldVals[I-1];
    if (I > 1)
      o << " && ";
    else
      o << ") {\n";
  }
  o.indent(Indentation) << "  MI.setOpcode(" << Opc << ");\n";
  std::vector<OperandInfo>& InsnOperands = Operands[Opc];
  for (std::vector<OperandInfo>::iterator
       I = InsnOperands.begin(), E = InsnOperands.end(); I != E; ++I) {
    // If a custom instruction decoder was specified, use that.
    if (I->numFields() == 0 && I->Decoder.size()) {
      o.indent(Indentation) << "  " << Emitter->GuardPrefix << I->Decoder
                            << "(MI, insn, Address, Decoder)" << Emitter->GuardPostfix << "\n";
      break;
    }

    emitBinaryParser(o, Indentation, *I);
  }
  o.indent(Indentation) << "  return " << Emitter->ReturnOK << "; // " << nameWithID(Opc)
                        << '\n';
  o.indent(Indentation) << "}\n";

  return false;
}
Пример #27
0
void CaptureGlueInputMatcher::printImpl(raw_ostream &OS, unsigned indent) const{
  OS.indent(indent) << "CaptureGlueInput\n";
}
Пример #28
0
void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
  CodeGenTarget Target(Records);
  Record *AsmWriter = Target.getAsmWriter();

  if (!AsmWriter->getValueAsBit("isMCAsmWriter"))
    return;

  O << "\n#ifdef PRINT_ALIAS_INSTR\n";
  O << "#undef PRINT_ALIAS_INSTR\n\n";

  EmitRegIsInRegClass(O);

  // Emit the method that prints the alias instruction.
  std::string ClassName = AsmWriter->getValueAsString("AsmWriterClassName");

  std::vector<Record*> AllInstAliases =
    Records.getAllDerivedDefinitions("InstAlias");

  // Create a map from the qualified name to a list of potential matches.
  std::map<std::string, std::vector<CodeGenInstAlias*> > AliasMap;
  for (std::vector<Record*>::iterator
         I = AllInstAliases.begin(), E = AllInstAliases.end(); I != E; ++I) {
    CodeGenInstAlias *Alias = new CodeGenInstAlias(*I, Target);
    const Record *R = *I;
    if (!R->getValueAsBit("EmitAlias"))
      continue; // We were told not to emit the alias, but to emit the aliasee.
    const DagInit *DI = R->getValueAsDag("ResultInst");
    const DefInit *Op = dynamic_cast<const DefInit*>(DI->getOperator());
    AliasMap[getQualifiedName(Op->getDef())].push_back(Alias);
  }

  // A map of which conditions need to be met for each instruction operand
  // before it can be matched to the mnemonic.
  std::map<std::string, std::vector<IAPrinter*> > IAPrinterMap;

  for (std::map<std::string, std::vector<CodeGenInstAlias*> >::iterator
         I = AliasMap.begin(), E = AliasMap.end(); I != E; ++I) {
    std::vector<CodeGenInstAlias*> &Aliases = I->second;

    for (std::vector<CodeGenInstAlias*>::iterator
           II = Aliases.begin(), IE = Aliases.end(); II != IE; ++II) {
      const CodeGenInstAlias *CGA = *II;
      unsigned LastOpNo = CGA->ResultInstOperandIndex.size();
      unsigned NumResultOps =
        CountResultNumOperands(CGA->ResultInst->AsmString);

      // Don't emit the alias if it has more operands than what it's aliasing.
      if (NumResultOps < CountNumOperands(CGA->AsmString))
        continue;

      IAPrinter *IAP = new IAPrinter(CGA->Result->getAsString(),
                                     CGA->AsmString);

      std::string Cond;
      Cond = std::string("MI->getNumOperands() == ") + llvm::utostr(LastOpNo);
      IAP->addCond(Cond);

      std::map<StringRef, unsigned> OpMap;
      bool CantHandle = false;

      for (unsigned i = 0, e = LastOpNo; i != e; ++i) {
        const CodeGenInstAlias::ResultOperand &RO = CGA->ResultOperands[i];

        switch (RO.Kind) {
        case CodeGenInstAlias::ResultOperand::K_Record: {
          const Record *Rec = RO.getRecord();
          StringRef ROName = RO.getName();


          if (Rec->isSubClassOf("RegisterOperand"))
            Rec = Rec->getValueAsDef("RegClass");
          if (Rec->isSubClassOf("RegisterClass")) {
            Cond = std::string("MI->getOperand(")+llvm::utostr(i)+").isReg()";
            IAP->addCond(Cond);

            if (!IAP->isOpMapped(ROName)) {
              IAP->addOperand(ROName, i);
              Cond = std::string("regIsInRegisterClass(RC_") +
                CGA->ResultOperands[i].getRecord()->getName() +
                ", MI->getOperand(" + llvm::utostr(i) + ").getReg())";
              IAP->addCond(Cond);
            } else {
              Cond = std::string("MI->getOperand(") +
                llvm::utostr(i) + ").getReg() == MI->getOperand(" +
                llvm::utostr(IAP->getOpIndex(ROName)) + ").getReg()";
              IAP->addCond(Cond);
            }
          } else {
            assert(Rec->isSubClassOf("Operand") && "Unexpected operand!");
            // FIXME: We may need to handle these situations.
            delete IAP;
            IAP = 0;
            CantHandle = true;
            break;
          }

          break;
        }
        case CodeGenInstAlias::ResultOperand::K_Imm:
          Cond = std::string("MI->getOperand(") +
            llvm::utostr(i) + ").getImm() == " +
            llvm::utostr(CGA->ResultOperands[i].getImm());
          IAP->addCond(Cond);
          break;
        case CodeGenInstAlias::ResultOperand::K_Reg:
          // If this is zero_reg, something's playing tricks we're not
          // equipped to handle.
          if (!CGA->ResultOperands[i].getRegister()) {
            CantHandle = true;
            break;
          }

          Cond = std::string("MI->getOperand(") +
            llvm::utostr(i) + ").getReg() == " + Target.getName() +
            "::" + CGA->ResultOperands[i].getRegister()->getName();
          IAP->addCond(Cond);
          break;
        }

        if (!IAP) break;
      }

      if (CantHandle) continue;
      IAPrinterMap[I->first].push_back(IAP);
    }
  }

  std::string Header;
  raw_string_ostream HeaderO(Header);

  HeaderO << "bool " << Target.getName() << ClassName
          << "::printAliasInstr(const MCInst"
          << " *MI, raw_ostream &OS) {\n";

  std::string Cases;
  raw_string_ostream CasesO(Cases);

  for (std::map<std::string, std::vector<IAPrinter*> >::iterator
         I = IAPrinterMap.begin(), E = IAPrinterMap.end(); I != E; ++I) {
    std::vector<IAPrinter*> &IAPs = I->second;
    std::vector<IAPrinter*> UniqueIAPs;

    for (std::vector<IAPrinter*>::iterator
           II = IAPs.begin(), IE = IAPs.end(); II != IE; ++II) {
      IAPrinter *LHS = *II;
      bool IsDup = false;
      for (std::vector<IAPrinter*>::iterator
             III = IAPs.begin(), IIE = IAPs.end(); III != IIE; ++III) {
        IAPrinter *RHS = *III;
        if (LHS != RHS && *LHS == *RHS) {
          IsDup = true;
          break;
        }
      }

      if (!IsDup) UniqueIAPs.push_back(LHS);
    }

    if (UniqueIAPs.empty()) continue;

    CasesO.indent(2) << "case " << I->first << ":\n";

    for (std::vector<IAPrinter*>::iterator
           II = UniqueIAPs.begin(), IE = UniqueIAPs.end(); II != IE; ++II) {
      IAPrinter *IAP = *II;
      CasesO.indent(4);
      IAP->print(CasesO);
      CasesO << '\n';
    }

    CasesO.indent(4) << "return false;\n";
  }

  if (CasesO.str().empty()) {
    O << HeaderO.str();
    O << "  return false;\n";
    O << "}\n\n";
    O << "#endif // PRINT_ALIAS_INSTR\n";
    return;
  }

  EmitGetMapOperandNumber(O);

  O << HeaderO.str();
  O.indent(2) << "StringRef AsmString;\n";
  O.indent(2) << "SmallVector<std::pair<StringRef, unsigned>, 4> OpMap;\n";
  O.indent(2) << "switch (MI->getOpcode()) {\n";
  O.indent(2) << "default: return false;\n";
  O << CasesO.str();
  O.indent(2) << "}\n\n";

  // Code that prints the alias, replacing the operands with the ones from the
  // MCInst.
  O << "  std::pair<StringRef, StringRef> ASM = AsmString.split(' ');\n";
  O << "  OS << '\\t' << ASM.first;\n";

  O << "  if (!ASM.second.empty()) {\n";
  O << "    OS << '\\t';\n";
  O << "    for (StringRef::iterator\n";
  O << "         I = ASM.second.begin(), E = ASM.second.end(); I != E; ) {\n";
  O << "      if (*I == '$') {\n";
  O << "        StringRef::iterator Start = ++I;\n";
  O << "        while (I != E &&\n";
  O << "               ((*I >= 'a' && *I <= 'z') ||\n";
  O << "                (*I >= 'A' && *I <= 'Z') ||\n";
  O << "                (*I >= '0' && *I <= '9') ||\n";
  O << "                *I == '_'))\n";
  O << "          ++I;\n";
  O << "        StringRef Name(Start, I - Start);\n";
  O << "        printOperand(MI, getMapOperandNumber(OpMap, Name), OS);\n";
  O << "      } else {\n";
  O << "        OS << *I++;\n";
  O << "      }\n";
  O << "    }\n";
  O << "  }\n\n";
  
  O << "  return true;\n";
  O << "}\n\n";

  O << "#endif // PRINT_ALIAS_INSTR\n";
}
Пример #29
0
void MoveParentMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
  OS.indent(indent) << "MoveParent\n";
}
Пример #30
0
void CheckComplexPatMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
  OS.indent(indent) << "CheckComplexPat " << Pattern.getSelectFunc() << '\n';
}