当前位置: 首页>>代码示例>>C++>>正文


C++ AsmPrinter类代码示例

本文整理汇总了C++中AsmPrinter的典型用法代码示例。如果您正苦于以下问题:C++ AsmPrinter类的具体用法?C++ AsmPrinter怎么用?C++ AsmPrinter使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。


在下文中一共展示了AsmPrinter类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。

示例1: beginAssembly

void OcamlGCMetadataPrinter::beginAssembly(AsmPrinter &AP) {
  AP.OutStreamer.SwitchSection(AP.getObjFileLowering().getTextSection());
  EmitCamlGlobal(getModule(), AP, "code_begin");

  AP.OutStreamer.SwitchSection(AP.getObjFileLowering().getDataSection());
  EmitCamlGlobal(getModule(), AP, "data_begin");
}
开发者ID:eholk,项目名称:llvm,代码行数:7,代码来源:OcamlGCPrinter.cpp

示例2: beginAssembly

void OcamlGCMetadataPrinter::beginAssembly(Module &M, GCModuleInfo &Info,
                                           AsmPrinter &AP) {
  AP.OutStreamer->SwitchSection(AP.getObjFileLowering().getTextSection());
  EmitCamlGlobal(M, AP, "code_begin");

  AP.OutStreamer->SwitchSection(AP.getObjFileLowering().getDataSection());
  EmitCamlGlobal(M, AP, "data_begin");
}
开发者ID:CTSRD-CHERI,项目名称:cheribsd,代码行数:8,代码来源:OcamlGCPrinter.cpp

示例3: LowerPPCMachineInstrToMCInst

void llvm::LowerPPCMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI,
                                        AsmPrinter &AP, bool isDarwin) {
  OutMI.setOpcode(MI->getOpcode());
  
  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
    const MachineOperand &MO = MI->getOperand(i);
    
    MCOperand MCOp;
    switch (MO.getType()) {
    default:
      MI->dump();
      llvm_unreachable("unknown operand type");
    case MachineOperand::MO_Register:
      assert(!MO.getSubReg() && "Subregs should be eliminated!");
      assert(MO.getReg() > PPC::NoRegister &&
             MO.getReg() < PPC::NUM_TARGET_REGS &&
             "Invalid register for this target!");
      MCOp = MCOperand::createReg(MO.getReg());
      break;
    case MachineOperand::MO_Immediate:
      MCOp = MCOperand::createImm(MO.getImm());
      break;
    case MachineOperand::MO_MachineBasicBlock:
      MCOp = MCOperand::createExpr(MCSymbolRefExpr::create(
                                      MO.getMBB()->getSymbol(), AP.OutContext));
      break;
    case MachineOperand::MO_GlobalAddress:
    case MachineOperand::MO_ExternalSymbol:
      MCOp = GetSymbolRef(MO, GetSymbolFromOperand(MO, AP), AP, isDarwin);
      break;
    case MachineOperand::MO_JumpTableIndex:
      MCOp = GetSymbolRef(MO, AP.GetJTISymbol(MO.getIndex()), AP, isDarwin);
      break;
    case MachineOperand::MO_ConstantPoolIndex:
      MCOp = GetSymbolRef(MO, AP.GetCPISymbol(MO.getIndex()), AP, isDarwin);
      break;
    case MachineOperand::MO_BlockAddress:
      MCOp = GetSymbolRef(MO,AP.GetBlockAddressSymbol(MO.getBlockAddress()),AP,
                          isDarwin);
      break;
    case MachineOperand::MO_RegisterMask:
      continue;
    }
    
    OutMI.addOperand(MCOp);
  }
}
开发者ID:EdwardBetts,项目名称:expert-disco,代码行数:47,代码来源:PPCMCInstLower.cpp

示例4: emit

// Emit addresses into the section given.
void AddressPool::emit(AsmPrinter &Asm, MCSection *AddrSection) {
    if (Pool.empty())
        return;

    // Start the dwarf addr section.
    Asm.OutStreamer->SwitchSection(AddrSection);

    // Order the address pool entries by ID
    SmallVector<const MCExpr *, 64> Entries(Pool.size());

    for (const auto &I : Pool)
        Entries[I.second.Number] =
            I.second.TLS
            ? Asm.getObjFileLowering().getDebugThreadLocalSymbol(I.first)
            : MCSymbolRefExpr::Create(I.first, Asm.OutContext);

    for (const MCExpr *Entry : Entries)
        Asm.OutStreamer->EmitValue(Entry, Asm.getDataLayout().getPointerSize());
}
开发者ID:scottp101,项目名称:SPIRV-LLVM,代码行数:20,代码来源:AddressPool.cpp

示例5: finalizeList

bool DebugLocStream::finalizeList(AsmPrinter &Asm) {
  if (Lists.back().EntryOffset == Entries.size()) {
    // Empty list.  Delete it.
    Lists.pop_back();
    return false;
  }

  // Real list.  Generate a label for it.
  Lists.back().Label = Asm.createTempSymbol("debug_loc");
  return true;
}
开发者ID:alex-t,项目名称:llvm,代码行数:11,代码来源:DebugLocStream.cpp

示例6: LowerRISCVMachineOperandToMCOperand

bool llvm::LowerRISCVMachineOperandToMCOperand(const MachineOperand &MO,
                                               MCOperand &MCOp,
                                               const AsmPrinter &AP) {
  switch (MO.getType()) {
  default:
    report_fatal_error("LowerRISCVMachineInstrToMCInst: unknown operand type");
  case MachineOperand::MO_Register:
    // Ignore all implicit register operands.
    if (MO.isImplicit())
      return false;
    MCOp = MCOperand::createReg(MO.getReg());
    break;
  case MachineOperand::MO_RegisterMask:
    // Regmasks are like implicit defs.
    return false;
  case MachineOperand::MO_Immediate:
    MCOp = MCOperand::createImm(MO.getImm());
    break;
  case MachineOperand::MO_MachineBasicBlock:
    MCOp = lowerSymbolOperand(MO, MO.getMBB()->getSymbol(), AP);
    break;
  case MachineOperand::MO_GlobalAddress:
    MCOp = lowerSymbolOperand(MO, AP.getSymbol(MO.getGlobal()), AP);
    break;
  case MachineOperand::MO_BlockAddress:
    MCOp = lowerSymbolOperand(
        MO, AP.GetBlockAddressSymbol(MO.getBlockAddress()), AP);
    break;
  case MachineOperand::MO_ExternalSymbol:
    MCOp = lowerSymbolOperand(
        MO, AP.GetExternalSymbolSymbol(MO.getSymbolName()), AP);
    break;
  case MachineOperand::MO_ConstantPoolIndex:
    MCOp = lowerSymbolOperand(MO, AP.GetCPISymbol(MO.getIndex()), AP);
    break;
  }
  return true;
}
开发者ID:jvesely,项目名称:llvm,代码行数:38,代码来源:RISCVMCInstLower.cpp

示例7: LowerPPCMachineOperandToMCOperand

bool llvm::LowerPPCMachineOperandToMCOperand(const MachineOperand &MO,
                                             MCOperand &OutMO, AsmPrinter &AP,
                                             bool isDarwin) {
  switch (MO.getType()) {
  default:
    llvm_unreachable("unknown operand type");
  case MachineOperand::MO_Register:
    assert(!MO.getSubReg() && "Subregs should be eliminated!");
    assert(MO.getReg() > PPC::NoRegister &&
           MO.getReg() < PPC::NUM_TARGET_REGS &&
           "Invalid register for this target!");
    OutMO = MCOperand::createReg(MO.getReg());
    return true;
  case MachineOperand::MO_Immediate:
    OutMO = MCOperand::createImm(MO.getImm());
    return true;
  case MachineOperand::MO_MachineBasicBlock:
    OutMO = MCOperand::createExpr(
        MCSymbolRefExpr::create(MO.getMBB()->getSymbol(), AP.OutContext));
    return true;
  case MachineOperand::MO_GlobalAddress:
  case MachineOperand::MO_ExternalSymbol:
    OutMO = GetSymbolRef(MO, GetSymbolFromOperand(MO, AP), AP, isDarwin);
    return true;
  case MachineOperand::MO_JumpTableIndex:
    OutMO = GetSymbolRef(MO, AP.GetJTISymbol(MO.getIndex()), AP, isDarwin);
    return true;
  case MachineOperand::MO_ConstantPoolIndex:
    OutMO = GetSymbolRef(MO, AP.GetCPISymbol(MO.getIndex()), AP, isDarwin);
    return true;
  case MachineOperand::MO_BlockAddress:
    OutMO = GetSymbolRef(MO, AP.GetBlockAddressSymbol(MO.getBlockAddress()), AP,
                         isDarwin);
    return true;
  case MachineOperand::MO_RegisterMask:
    return false;
  }
}
开发者ID:BNieuwenhuizen,项目名称:llvm,代码行数:38,代码来源:PPCMCInstLower.cpp

示例8: getEntry

DwarfStringPool::EntryRef DwarfStringPool::getEntry(AsmPrinter &Asm,
                                                    StringRef Str) {
  auto I = Pool.insert(std::make_pair(Str, EntryTy()));
  if (I.second) {
    auto &Entry = I.first->second;
    Entry.Index = Pool.size() - 1;
    Entry.Offset = NumBytes;
    Entry.Symbol = ShouldCreateSymbols ? Asm.createTempSymbol(Prefix) : nullptr;

    NumBytes += Str.size() + 1;
    assert(NumBytes > Entry.Offset && "Unexpected overflow");
  }
  return EntryRef(*I.first);
}
开发者ID:bgabor666,项目名称:llvm,代码行数:14,代码来源:DwarfStringPool.cpp

示例9: LowerSymbolOperand

static MCOperand LowerSymbolOperand(const MachineInstr *MI,
                                    const MachineOperand &MO,
                                    AsmPrinter &AP) {

  SparcMCExpr::VariantKind Kind =
    (SparcMCExpr::VariantKind)MO.getTargetFlags();
  const MCSymbol *Symbol = nullptr;

  switch(MO.getType()) {
  default: llvm_unreachable("Unknown type in LowerSymbolOperand");
  case MachineOperand::MO_MachineBasicBlock:
    Symbol = MO.getMBB()->getSymbol();
    break;

  case MachineOperand::MO_GlobalAddress:
    Symbol = AP.getSymbol(MO.getGlobal());
    break;

  case MachineOperand::MO_BlockAddress:
    Symbol = AP.GetBlockAddressSymbol(MO.getBlockAddress());
    break;

  case MachineOperand::MO_ExternalSymbol:
    Symbol = AP.GetExternalSymbolSymbol(MO.getSymbolName());
    break;

  case MachineOperand::MO_ConstantPoolIndex:
    Symbol = AP.GetCPISymbol(MO.getIndex());
    break;
  }

  const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::Create(Symbol,
                                                         AP.OutContext);
  const SparcMCExpr *expr = SparcMCExpr::Create(Kind, MCSym,
                                                AP.OutContext);
  return MCOperand::createExpr(expr);
}
开发者ID:8l,项目名称:SPIRV-LLVM,代码行数:37,代码来源:SparcMCInstLower.cpp

示例10: finishAssembly

/// emitAssembly - Print the frametable. The ocaml frametable format is thus:
///
///   extern "C" struct align(sizeof(intptr_t)) {
///     uint16_t NumDescriptors;
///     struct align(sizeof(intptr_t)) {
///       void *ReturnAddress;
///       uint16_t FrameSize;
///       uint16_t NumLiveOffsets;
///       uint16_t LiveOffsets[NumLiveOffsets];
///     } Descriptors[NumDescriptors];
///   } caml${module}__frametable;
///
/// Note that this precludes programs from stack frames larger than 64K
/// (FrameSize and LiveOffsets would overflow). FrameTablePrinter will abort if
/// either condition is detected in a function which uses the GC.
///
void OcamlGCMetadataPrinter::finishAssembly(AsmPrinter &AP) {
  unsigned IntPtrSize = AP.TM.getTargetData()->getPointerSize();

  AP.OutStreamer.SwitchSection(AP.getObjFileLowering().getTextSection());
  EmitCamlGlobal(getModule(), AP, "code_end");

  AP.OutStreamer.SwitchSection(AP.getObjFileLowering().getDataSection());
  EmitCamlGlobal(getModule(), AP, "data_end");

  // FIXME: Why does ocaml emit this??
  AP.OutStreamer.EmitIntValue(0, IntPtrSize, 0);

  AP.OutStreamer.SwitchSection(AP.getObjFileLowering().getDataSection());
  EmitCamlGlobal(getModule(), AP, "frametable");

  for (iterator I = begin(), IE = end(); I != IE; ++I) {
    GCFunctionInfo &FI = **I;

    uint64_t FrameSize = FI.getFrameSize();
    if (FrameSize >= 1<<16) {
      // Very rude!
      report_fatal_error("Function '" + FI.getFunction().getName() +
                         "' is too large for the ocaml GC! "
                         "Frame size " + Twine(FrameSize) + ">= 65536.\n"
                         "(" + Twine(uintptr_t(&FI)) + ")");
    }

    AP.OutStreamer.AddComment("live roots for " +
                              Twine(FI.getFunction().getName()));
    AP.OutStreamer.AddBlankLine();

    for (GCFunctionInfo::iterator J = FI.begin(), JE = FI.end(); J != JE; ++J) {
      size_t LiveCount = FI.live_size(J);
      if (LiveCount >= 1<<16) {
        // Very rude!
        report_fatal_error("Function '" + FI.getFunction().getName() +
                           "' is too large for the ocaml GC! "
                           "Live root count "+Twine(LiveCount)+" >= 65536.");
      }

      AP.OutStreamer.EmitSymbolValue(J->Label, IntPtrSize, 0);
      AP.EmitInt16(FrameSize);
      AP.EmitInt16(LiveCount);

      for (GCFunctionInfo::live_iterator K = FI.live_begin(J),
                                         KE = FI.live_end(J); K != KE; ++K) {
        assert(K->StackOffset < 1<<16 &&
               "GC root stack offset is outside of fixed stack frame and out "
               "of range for ocaml GC!");

        AP.EmitInt32(K->StackOffset);
      }

      AP.EmitAlignment(IntPtrSize == 4 ? 2 : 3);
    }
  }
}
开发者ID:jhoush,项目名称:dist-llvm,代码行数:73,代码来源:OcamlGCPrinter.cpp

示例11: emit

void DwarfStringPool::emit(AsmPrinter &Asm, MCSection *StrSection,
                           MCSection *OffsetSection, bool UseRelativeOffsets) {
  if (Pool.empty())
    return;

  // Start the dwarf str section.
  Asm.OutStreamer->SwitchSection(StrSection);

  // Get all of the string pool entries and put them in an array by their ID so
  // we can sort them.
  SmallVector<const StringMapEntry<EntryTy> *, 64> Entries(Pool.size());

  for (const auto &E : Pool)
    Entries[E.getValue().Index] = &E;

  for (const auto &Entry : Entries) {
    assert(ShouldCreateSymbols == static_cast<bool>(Entry->getValue().Symbol) &&
           "Mismatch between setting and entry");

    // Emit a label for reference from debug information entries.
    if (ShouldCreateSymbols)
      Asm.OutStreamer->EmitLabel(Entry->getValue().Symbol);

    // Emit the string itself with a terminating null byte.
    Asm.OutStreamer->AddComment("string offset=" +
                                Twine(Entry->getValue().Offset));
    Asm.OutStreamer->EmitBytes(
        StringRef(Entry->getKeyData(), Entry->getKeyLength() + 1));
  }

  // If we've got an offset section go ahead and emit that now as well.
  if (OffsetSection) {
    Asm.OutStreamer->SwitchSection(OffsetSection);
    unsigned size = 4; // FIXME: DWARF64 is 8.
    for (const auto &Entry : Entries)
      if (UseRelativeOffsets)
        Asm.emitDwarfStringOffset(Entry->getValue());
      else
        Asm.OutStreamer->EmitIntValue(Entry->getValue().Offset, size);
  }
}
开发者ID:bgabor666,项目名称:llvm,代码行数:41,代码来源:DwarfStringPool.cpp

示例12: finishAssembly

void ErlangGCPrinter::finishAssembly(Module &M, GCModuleInfo &Info,
                                     AsmPrinter &AP) {
  MCStreamer &OS = *AP.OutStreamer;
  unsigned IntPtrSize = M.getDataLayout().getPointerSize();

  // Put this in a custom .note section.
  OS.SwitchSection(
      AP.getObjFileLowering().getContext().getELFSection(".note.gc",
                                                         ELF::SHT_PROGBITS, 0));

  // For each function...
  for (GCModuleInfo::FuncInfoVec::iterator FI = Info.funcinfo_begin(),
                                           IE = Info.funcinfo_end();
       FI != IE; ++FI) {
    GCFunctionInfo &MD = **FI;
    if (MD.getStrategy().getName() != getStrategy().getName())
      // this function is managed by some other GC
      continue;
    /** A compact GC layout. Emit this data structure:
     *
     * struct {
     *   int16_t PointCount;
     *   void *SafePointAddress[PointCount];
     *   int16_t StackFrameSize; (in words)
     *   int16_t StackArity;
     *   int16_t LiveCount;
     *   int16_t LiveOffsets[LiveCount];
     * } __gcmap_<FUNCTIONNAME>;
     **/

    // Align to address width.
    AP.EmitAlignment(IntPtrSize == 4 ? 2 : 3);

    // Emit PointCount.
    OS.AddComment("safe point count");
    AP.EmitInt16(MD.size());

    // And each safe point...
    for (GCFunctionInfo::iterator PI = MD.begin(), PE = MD.end(); PI != PE;
         ++PI) {
      // Emit the address of the safe point.
      OS.AddComment("safe point address");
      MCSymbol *Label = PI->Label;
      AP.EmitLabelPlusOffset(Label /*Hi*/, 0 /*Offset*/, 4 /*Size*/);
    }

    // Stack information never change in safe points! Only print info from the
    // first call-site.
    GCFunctionInfo::iterator PI = MD.begin();

    // Emit the stack frame size.
    OS.AddComment("stack frame size (in words)");
    AP.EmitInt16(MD.getFrameSize() / IntPtrSize);

    // Emit stack arity, i.e. the number of stacked arguments.
    unsigned RegisteredArgs = IntPtrSize == 4 ? 5 : 6;
    unsigned StackArity = MD.getFunction().arg_size() > RegisteredArgs
                              ? MD.getFunction().arg_size() - RegisteredArgs
                              : 0;
    OS.AddComment("stack arity");
    AP.EmitInt16(StackArity);

    // Emit the number of live roots in the function.
    OS.AddComment("live root count");
    AP.EmitInt16(MD.live_size(PI));

    // And for each live root...
    for (GCFunctionInfo::live_iterator LI = MD.live_begin(PI),
                                       LE = MD.live_end(PI);
         LI != LE; ++LI) {
      // Emit live root's offset within the stack frame.
      OS.AddComment("stack index (offset / wordsize)");
      AP.EmitInt16(LI->StackOffset / IntPtrSize);
    }
  }
}
开发者ID:bugsnag,项目名称:llvm,代码行数:76,代码来源:ErlangGCPrinter.cpp

示例13: assert

/// EmitInlineAsm - This method formats and emits the specified machine
/// instruction that is an inline asm.
void AsmPrinter::EmitInlineAsm(const MachineInstr *MI) const {
#ifndef ANDROID_TARGET_BUILD
  assert(MI->isInlineAsm() && "printInlineAsm only works on inline asms");

  unsigned NumOperands = MI->getNumOperands();

  // Count the number of register definitions to find the asm string.
  unsigned NumDefs = 0;
  for (; MI->getOperand(NumDefs).isReg() && MI->getOperand(NumDefs).isDef();
       ++NumDefs)
    assert(NumDefs != NumOperands-2 && "No asm string?");

  assert(MI->getOperand(NumDefs).isSymbol() && "No asm string?");

  // Disassemble the AsmStr, printing out the literal pieces, the operands, etc.
  const char *AsmStr = MI->getOperand(NumDefs).getSymbolName();

  // If this asmstr is empty, just print the #APP/#NOAPP markers.
  // These are useful to see where empty asm's wound up.
  if (AsmStr[0] == 0) {
    // Don't emit the comments if writing to a .o file.
    if (!OutStreamer.hasRawTextSupport()) return;

    OutStreamer.EmitRawText(Twine("\t")+MAI->getCommentString()+
                            MAI->getInlineAsmStart());
    OutStreamer.EmitRawText(Twine("\t")+MAI->getCommentString()+
                            MAI->getInlineAsmEnd());
    return;
  }

  // Emit the #APP start marker.  This has to happen even if verbose-asm isn't
  // enabled, so we use EmitRawText.
  if (OutStreamer.hasRawTextSupport())
    OutStreamer.EmitRawText(Twine("\t")+MAI->getCommentString()+
                            MAI->getInlineAsmStart());

  // Get the !srcloc metadata node if we have it, and decode the loc cookie from
  // it.
  unsigned LocCookie = 0;
  const MDNode *LocMD = 0;
  for (unsigned i = MI->getNumOperands(); i != 0; --i) {
    if (MI->getOperand(i-1).isMetadata() &&
        (LocMD = MI->getOperand(i-1).getMetadata()) &&
        LocMD->getNumOperands() != 0) {
      if (const ConstantInt *CI = dyn_cast<ConstantInt>(LocMD->getOperand(0))) {
        LocCookie = CI->getZExtValue();
        break;
      }
    }
  }

  // Emit the inline asm to a temporary string so we can emit it through
  // EmitInlineAsm.
  SmallString<256> StringData;
  raw_svector_ostream OS(StringData);

  OS << '\t';

  // The variant of the current asmprinter.
  int AsmPrinterVariant = MAI->getAssemblerDialect();

  int CurVariant = -1;            // The number of the {.|.|.} region we are in.
  const char *LastEmitted = AsmStr; // One past the last character emitted.

  while (*LastEmitted) {
    switch (*LastEmitted) {
    default: {
      // Not a special case, emit the string section literally.
      const char *LiteralEnd = LastEmitted+1;
      while (*LiteralEnd && *LiteralEnd != '{' && *LiteralEnd != '|' &&
             *LiteralEnd != '}' && *LiteralEnd != '$' && *LiteralEnd != '\n')
        ++LiteralEnd;
      if (CurVariant == -1 || CurVariant == AsmPrinterVariant)
        OS.write(LastEmitted, LiteralEnd-LastEmitted);
      LastEmitted = LiteralEnd;
      break;
    }
    case '\n':
      ++LastEmitted;   // Consume newline character.
      OS << '\n';      // Indent code with newline.
      break;
    case '$': {
      ++LastEmitted;   // Consume '$' character.
      bool Done = true;

      // Handle escapes.
      switch (*LastEmitted) {
      default: Done = false; break;
      case '$':     // $$ -> $
        if (CurVariant == -1 || CurVariant == AsmPrinterVariant)
          OS << '$';
        ++LastEmitted;  // Consume second '$' character.
        break;
      case '(':             // $( -> same as GCC's { character.
        ++LastEmitted;      // Consume '(' character.
        if (CurVariant != -1)
          report_fatal_error("Nested variants found in inline asm string: '" +
                             Twine(AsmStr) + "'");
//.........这里部分代码省略.........
开发者ID:TeamNyx,项目名称:external_llvm,代码行数:101,代码来源:AsmPrinterInlineAsm.cpp

示例14: finishAssembly

/// emitAssembly - Print the frametable. The ocaml frametable format is thus:
///
///   extern "C" struct align(sizeof(intptr_t)) {
///     uint16_t NumDescriptors;
///     struct align(sizeof(intptr_t)) {
///       void *ReturnAddress;
///       uint16_t FrameSize;
///       uint16_t NumLiveOffsets;
///       uint16_t LiveOffsets[NumLiveOffsets];
///     } Descriptors[NumDescriptors];
///   } caml${module}__frametable;
///
/// Note that this precludes programs from stack frames larger than 64K
/// (FrameSize and LiveOffsets would overflow). FrameTablePrinter will abort if
/// either condition is detected in a function which uses the GC.
///
void OcamlGCMetadataPrinter::finishAssembly(Module &M, GCModuleInfo &Info,
                                            AsmPrinter &AP) {
  unsigned IntPtrSize = M.getDataLayout().getPointerSize();

  AP.OutStreamer->SwitchSection(AP.getObjFileLowering().getTextSection());
  EmitCamlGlobal(M, AP, "code_end");

  AP.OutStreamer->SwitchSection(AP.getObjFileLowering().getDataSection());
  EmitCamlGlobal(M, AP, "data_end");

  // FIXME: Why does ocaml emit this??
  AP.OutStreamer->EmitIntValue(0, IntPtrSize);

  AP.OutStreamer->SwitchSection(AP.getObjFileLowering().getDataSection());
  EmitCamlGlobal(M, AP, "frametable");

  int NumDescriptors = 0;
  for (GCModuleInfo::FuncInfoVec::iterator I = Info.funcinfo_begin(),
                                           IE = Info.funcinfo_end();
       I != IE; ++I) {
    GCFunctionInfo &FI = **I;
    if (FI.getStrategy().getName() != getStrategy().getName())
      // this function is managed by some other GC
      continue;
    for (GCFunctionInfo::iterator J = FI.begin(), JE = FI.end(); J != JE; ++J) {
      NumDescriptors++;
    }
  }

  if (NumDescriptors >= 1 << 16) {
    // Very rude!
    report_fatal_error(" Too much descriptor for ocaml GC");
  }
  AP.emitInt16(NumDescriptors);
  AP.EmitAlignment(IntPtrSize == 4 ? 2 : 3);

  for (GCModuleInfo::FuncInfoVec::iterator I = Info.funcinfo_begin(),
                                           IE = Info.funcinfo_end();
       I != IE; ++I) {
    GCFunctionInfo &FI = **I;
    if (FI.getStrategy().getName() != getStrategy().getName())
      // this function is managed by some other GC
      continue;

    uint64_t FrameSize = FI.getFrameSize();
    if (FrameSize >= 1 << 16) {
      // Very rude!
      report_fatal_error("Function '" + FI.getFunction().getName() +
                         "' is too large for the ocaml GC! "
                         "Frame size " +
                         Twine(FrameSize) + ">= 65536.\n"
                                            "(" +
                         Twine(uintptr_t(&FI)) + ")");
    }

    AP.OutStreamer->AddComment("live roots for " +
                               Twine(FI.getFunction().getName()));
    AP.OutStreamer->AddBlankLine();

    for (GCFunctionInfo::iterator J = FI.begin(), JE = FI.end(); J != JE; ++J) {
      size_t LiveCount = FI.live_size(J);
      if (LiveCount >= 1 << 16) {
        // Very rude!
        report_fatal_error("Function '" + FI.getFunction().getName() +
                           "' is too large for the ocaml GC! "
                           "Live root count " +
                           Twine(LiveCount) + " >= 65536.");
      }

      AP.OutStreamer->EmitSymbolValue(J->Label, IntPtrSize);
      AP.emitInt16(FrameSize);
      AP.emitInt16(LiveCount);

      for (GCFunctionInfo::live_iterator K = FI.live_begin(J),
                                         KE = FI.live_end(J);
           K != KE; ++K) {
        if (K->StackOffset >= 1 << 16) {
          // Very rude!
          report_fatal_error(
              "GC root stack offset is outside of fixed stack frame and out "
              "of range for ocaml GC!");
        }
        AP.emitInt16(K->StackOffset);
      }
//.........这里部分代码省略.........
开发者ID:CTSRD-CHERI,项目名称:cheribsd,代码行数:101,代码来源:OcamlGCPrinter.cpp

示例15: finishAssembly

/// emitAssembly - Print the frametable. The ocaml frametable format is thus:
///
///   extern "C" struct align(sizeof(intptr_t)) {
///     uint16_t NumDescriptors;
///     struct align(sizeof(intptr_t)) {
///       void *ReturnAddress;
///       uint16_t FrameSize;
///       uint16_t NumLiveOffsets;
///       uint16_t LiveOffsets[NumLiveOffsets];
///     } Descriptors[NumDescriptors];
///   } caml${module}__frametable;
///
/// Note that this precludes programs from stack frames larger than 64K
/// (FrameSize and LiveOffsets would overflow). FrameTablePrinter will abort if
/// either condition is detected in a function which uses the GC.
///
void OcamlGCMetadataPrinter::finishAssembly(AsmPrinter &AP) {
  unsigned IntPtrSize = AP.TM.getTargetData()->getPointerSize();

  AP.OutStreamer.SwitchSection(AP.getObjFileLowering().getTextSection());
  EmitCamlGlobal(getModule(), AP, "code_end");

  AP.OutStreamer.SwitchSection(AP.getObjFileLowering().getDataSection());
  EmitCamlGlobal(getModule(), AP, "data_end");

  // FIXME: Why does ocaml emit this??
  AP.OutStreamer.EmitIntValue(0, IntPtrSize, 0);

  AP.OutStreamer.SwitchSection(AP.getObjFileLowering().getDataSection());
  EmitCamlGlobal(getModule(), AP, "frametable");

  int NumDescriptors = 0;
  for (iterator I = begin(), IE = end(); I != IE; ++I) {
    GCFunctionInfo &FI = **I;
    for (GCFunctionInfo::iterator J = FI.begin(), JE = FI.end(); J != JE; ++J) {
      NumDescriptors++;
    }
  }

  if (NumDescriptors >= 1<<16) {
    // Very rude!
    report_fatal_error(" Too much descriptor for ocaml GC");
  }
  AP.EmitInt16(NumDescriptors);
  AP.EmitAlignment(IntPtrSize == 4 ? 2 : 3);

  const MCRegisterInfo &MRI = AP.OutStreamer.getContext().getRegisterInfo();

  for (iterator I = begin(), IE = end(); I != IE; ++I) {
    GCFunctionInfo &FI = **I;

    uint64_t FrameSize = FI.getFrameSize();
    if (FrameSize >= 1<<16) {
      // Very rude!
      report_fatal_error("Function '" + FI.getFunction().getName() +
                         "' is too large for the ocaml GC! "
                         "Frame size " + Twine(FrameSize) + ">= 65536.\n"
                         "(" + Twine(uintptr_t(&FI)) + ")");
    }

    AP.OutStreamer.AddComment("live roots for " +
                              Twine(FI.getFunction().getName()));
    AP.OutStreamer.AddBlankLine();

    for (unsigned PI = 0, PE = FI.size(); PI != PE; ++PI) {
      size_t LiveCount = FI.live_size(PI);
      if (LiveCount >= 1<<16) {
        // Very rude!
        report_fatal_error("Function '" + FI.getFunction().getName() +
                           "' is too large for the ocaml GC! "
                           "Live root count "+Twine(LiveCount)+" >= 65536.");
      }

      GCPoint &Point = FI.getPoint(PI);
      AP.OutStreamer.EmitSymbolValue(Point.Label, IntPtrSize, 0);
      AP.EmitInt16(FrameSize);
      AP.EmitInt16(LiveCount);

      for (GCFunctionInfo::live_iterator K = FI.live_begin(PI),
                                         KE = FI.live_end(PI); K != KE; ++K) {
        if (K->isReg()) {
          AP.OutStreamer.AddComment("register root at " +
                                    Twine(MRI.getName(K->Loc.PhysReg)));
          AP.OutStreamer.AddBlankLine();
          continue;
        }
        if (K->Loc.StackOffset >= 1<<16) {
          // Very rude!
          report_fatal_error(
                 "GC root stack offset is outside of fixed stack frame and out "
                 "of range for ocaml GC!");
        }
        AP.EmitInt16(K->Loc.StackOffset);
      }

      AP.EmitAlignment(IntPtrSize == 4 ? 2 : 3);
    }
  }
}
开发者ID:eholk,项目名称:llvm,代码行数:99,代码来源:OcamlGCPrinter.cpp


注:本文中的AsmPrinter类示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。