void BTFTypeFuncProto::emitType(MCStreamer &OS) { BTFTypeBase::emitType(OS); for (const auto &Param : Parameters) { OS.EmitIntValue(Param.NameOff, 4); OS.EmitIntValue(Param.Type, 4); } }
void BTFTypeEnum::emitType(MCStreamer &OS) { BTFTypeBase::emitType(OS); for (const auto &Enum : EnumValues) { OS.EmitIntValue(Enum.NameOff, 4); OS.EmitIntValue(Enum.Val, 4); } }
/// Emit a BTF common type. void BTFTypeBase::emitType(MCStreamer &OS) { OS.AddComment(std::string(BTFKindStr[Kind]) + "(id = " + std::to_string(Id) + ")"); OS.EmitIntValue(BTFType.NameOff, 4); OS.AddComment("0x" + Twine::utohexstr(BTFType.Info)); OS.EmitIntValue(BTFType.Info, 4); OS.EmitIntValue(BTFType.Size, 4); }
void BTFTypeStruct::emitType(MCStreamer &OS) { BTFTypeBase::emitType(OS); for (const auto &Member : Members) { OS.EmitIntValue(Member.NameOff, 4); OS.EmitIntValue(Member.Type, 4); OS.AddComment("0x" + Twine::utohexstr(Member.Offset)); OS.EmitIntValue(Member.Offset, 4); } }
/// emitModuleFlags - Emit the module flags that specify the garbage collection /// information. void TargetLoweringObjectFileMachO:: emitModuleFlags(MCStreamer &Streamer, ArrayRef<Module::ModuleFlagEntry> ModuleFlags, Mangler *Mang, const TargetMachine &TM) const { unsigned VersionVal = 0; unsigned ImageInfoFlags = 0; StringRef SectionVal; for (ArrayRef<Module::ModuleFlagEntry>::iterator i = ModuleFlags.begin(), e = ModuleFlags.end(); i != e; ++i) { const Module::ModuleFlagEntry &MFE = *i; // Ignore flags with 'Require' behavior. if (MFE.Behavior == Module::Require) continue; StringRef Key = MFE.Key->getString(); Value *Val = MFE.Val; if (Key == "Objective-C Image Info Version") VersionVal = cast<ConstantInt>(Val)->getZExtValue(); else if (Key == "Objective-C Garbage Collection" || Key == "Objective-C GC Only" || Key == "Objective-C Is Simulated") ImageInfoFlags |= cast<ConstantInt>(Val)->getZExtValue(); else if (Key == "Objective-C Image Info Section") SectionVal = cast<MDString>(Val)->getString(); } // The section is mandatory. If we don't have it, then we don't have GC info. if (SectionVal.empty()) return; StringRef Segment, Section; unsigned TAA = 0, StubSize = 0; bool TAAParsed; std::string ErrorCode = MCSectionMachO::ParseSectionSpecifier(SectionVal, Segment, Section, TAA, TAAParsed, StubSize); if (!ErrorCode.empty()) // If invalid, report the error with report_fatal_error. report_fatal_error("Invalid section specifier '" + Section + "': " + ErrorCode + "."); // Get the section. const MCSectionMachO *S = getContext().getMachOSection(Segment, Section, TAA, StubSize, SectionKind::getDataNoRel()); Streamer.SwitchSection(S); Streamer.EmitLabel(getContext(). GetOrCreateSymbol(StringRef("L_OBJC_IMAGE_INFO"))); Streamer.EmitIntValue(VersionVal, 4); Streamer.EmitIntValue(ImageInfoFlags, 4); Streamer.AddBlankLine(); }
static void writeIndexTable(MCStreamer &Out, ArrayRef<unsigned> ContributionOffsets, const MapVector<uint64_t, UnitIndexEntry> &IndexEntries, uint32_t DWARFUnitIndex::Entry::SectionContribution::*Field) { for (const auto &E : IndexEntries) for (size_t i = 0; i != array_lengthof(E.second.Contributions); ++i) if (ContributionOffsets[i]) Out.EmitIntValue(E.second.Contributions[i].*Field, 4); }
void TargetLoweringObjectFileELF::emitModuleMetadata( MCStreamer &Streamer, Module &M, const TargetMachine &TM) const { unsigned Version = 0; unsigned Flags = 0; StringRef Section; GetObjCImageInfo(M, Version, Flags, Section); if (Section.empty()) return; auto &C = getContext(); auto *S = C.getELFSection(Section, ELF::SHT_PROGBITS, ELF::SHF_ALLOC); Streamer.SwitchSection(S); Streamer.EmitLabel(C.getOrCreateSymbol(StringRef("OBJC_IMAGE_INFO"))); Streamer.EmitIntValue(Version, 4); Streamer.EmitIntValue(Flags, 4); Streamer.AddBlankLine(); }
void TargetLoweringObjectFileMachO::emitModuleMetadata( MCStreamer &Streamer, Module &M, const TargetMachine &TM) const { // Emit the linker options if present. if (auto *LinkerOptions = M.getNamedMetadata("llvm.linker.options")) { for (const auto &Option : LinkerOptions->operands()) { SmallVector<std::string, 4> StrOptions; for (const auto &Piece : cast<MDNode>(Option)->operands()) StrOptions.push_back(cast<MDString>(Piece)->getString()); Streamer.EmitLinkerOptions(StrOptions); } } unsigned VersionVal = 0; unsigned ImageInfoFlags = 0; StringRef SectionVal; GetObjCImageInfo(M, VersionVal, ImageInfoFlags, SectionVal); // The section is mandatory. If we don't have it, then we don't have GC info. if (SectionVal.empty()) return; StringRef Segment, Section; unsigned TAA = 0, StubSize = 0; bool TAAParsed; std::string ErrorCode = MCSectionMachO::ParseSectionSpecifier(SectionVal, Segment, Section, TAA, TAAParsed, StubSize); if (!ErrorCode.empty()) // If invalid, report the error with report_fatal_error. report_fatal_error("Invalid section specifier '" + Section + "': " + ErrorCode + "."); // Get the section. MCSectionMachO *S = getContext().getMachOSection( Segment, Section, TAA, StubSize, SectionKind::getData()); Streamer.SwitchSection(S); Streamer.EmitLabel(getContext(). getOrCreateSymbol(StringRef("L_OBJC_IMAGE_INFO"))); Streamer.EmitIntValue(VersionVal, 4); Streamer.EmitIntValue(ImageInfoFlags, 4); Streamer.AddBlankLine(); }
static void EmitUnwindCode(MCStreamer &streamer, MCSymbol *begin, MCWin64EHInstruction &inst) { uint8_t b1, b2; uint16_t w; b2 = (inst.getOperation() & 0x0F); switch (inst.getOperation()) { case Win64EH::UOP_PushNonVol: EmitAbsDifference(streamer, inst.getLabel(), begin); b2 |= (inst.getRegister() & 0x0F) << 4; streamer.EmitIntValue(b2, 1); break; case Win64EH::UOP_AllocLarge: EmitAbsDifference(streamer, inst.getLabel(), begin); if (inst.getSize() > 512*1024-8) { b2 |= 0x10; streamer.EmitIntValue(b2, 1); w = inst.getSize() & 0xFFF8; streamer.EmitIntValue(w, 2); w = inst.getSize() >> 16; } else {
static void writeIndex(MCStreamer &Out, MCSection *Section, ArrayRef<unsigned> ContributionOffsets, const MapVector<uint64_t, UnitIndexEntry> &IndexEntries) { if (IndexEntries.empty()) return; unsigned Columns = 0; for (auto &C : ContributionOffsets) if (C) ++Columns; std::vector<unsigned> Buckets(NextPowerOf2(3 * IndexEntries.size() / 2)); uint64_t Mask = Buckets.size() - 1; size_t i = 0; for (const auto &P : IndexEntries) { auto S = P.first; auto H = S & Mask; auto HP = ((S >> 32) & Mask) | 1; while (Buckets[H]) { assert(S != IndexEntries.begin()[Buckets[H] - 1].first && "Duplicate unit"); H = (H + HP) & Mask; } Buckets[H] = i + 1; ++i; } Out.SwitchSection(Section); Out.EmitIntValue(2, 4); // Version Out.EmitIntValue(Columns, 4); // Columns Out.EmitIntValue(IndexEntries.size(), 4); // Num Units Out.EmitIntValue(Buckets.size(), 4); // Num Buckets // Write the signatures. for (const auto &I : Buckets) Out.EmitIntValue(I ? IndexEntries.begin()[I - 1].first : 0, 8); // Write the indexes. for (const auto &I : Buckets) Out.EmitIntValue(I, 4); // Write the column headers (which sections will appear in the table) for (size_t i = 0; i != ContributionOffsets.size(); ++i) if (ContributionOffsets[i]) Out.EmitIntValue(i + DW_SECT_INFO, 4); // Write the offsets. writeIndexTable(Out, ContributionOffsets, IndexEntries, &DWARFUnitIndex::Entry::SectionContribution::Offset); // Write the lengths. writeIndexTable(Out, ContributionOffsets, IndexEntries, &DWARFUnitIndex::Entry::SectionContribution::Length); }
// Integrated assembler version void MipsReginfo::emitMipsReginfoSectionCG(MCStreamer &OS, const TargetLoweringObjectFile &TLOF, const MipsSubtarget &MST) const { if (OS.hasRawTextSupport()) return; const MipsTargetObjectFile &TLOFELF = static_cast<const MipsTargetObjectFile &>(TLOF); OS.SwitchSection(TLOFELF.getReginfoSection()); // .reginfo if (MST.isABI_O32()) { OS.EmitIntValue(0, 4); // ri_gprmask OS.EmitIntValue(0, 4); // ri_cpr[0]mask OS.EmitIntValue(0, 4); // ri_cpr[1]mask OS.EmitIntValue(0, 4); // ri_cpr[2]mask OS.EmitIntValue(0, 4); // ri_cpr[3]mask OS.EmitIntValue(0, 4); // ri_gp_value } // .MIPS.options else if (MST.isABI_N64()) { OS.EmitIntValue(1, 1); // kind OS.EmitIntValue(40, 1); // size OS.EmitIntValue(0, 2); // section OS.EmitIntValue(0, 4); // info OS.EmitIntValue(0, 4); // ri_gprmask OS.EmitIntValue(0, 4); // pad OS.EmitIntValue(0, 4); // ri_cpr[0]mask OS.EmitIntValue(0, 4); // ri_cpr[1]mask OS.EmitIntValue(0, 4); // ri_cpr[2]mask OS.EmitIntValue(0, 4); // ri_cpr[3]mask OS.EmitIntValue(0, 8); // ri_gp_value } else llvm_unreachable("Unsupported abi for reginfo"); }
void TargetLoweringObjectFileCOFF::emitModuleMetadata( MCStreamer &Streamer, Module &M, const TargetMachine &TM) const { if (NamedMDNode *LinkerOptions = M.getNamedMetadata("llvm.linker.options")) { // Emit the linker options to the linker .drectve section. According to the // spec, this section is a space-separated string containing flags for // linker. MCSection *Sec = getDrectveSection(); Streamer.SwitchSection(Sec); for (const auto &Option : LinkerOptions->operands()) { for (const auto &Piece : cast<MDNode>(Option)->operands()) { // Lead with a space for consistency with our dllexport implementation. std::string Directive(" "); Directive.append(cast<MDString>(Piece)->getString()); Streamer.EmitBytes(Directive); } } } unsigned Version = 0; unsigned Flags = 0; StringRef Section; GetObjCImageInfo(M, Version, Flags, Section); if (Section.empty()) return; auto &C = getContext(); auto *S = C.getCOFFSection( Section, COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | COFF::IMAGE_SCN_MEM_READ, SectionKind::getReadOnly()); Streamer.SwitchSection(S); Streamer.EmitLabel(C.getOrCreateSymbol(StringRef("OBJC_IMAGE_INFO"))); Streamer.EmitIntValue(Version, 4); Streamer.EmitIntValue(Flags, 4); Streamer.AddBlankLine(); }
static std::error_code writeStringsAndOffsets(MCStreamer &Out, StringMap<uint32_t> &Strings, uint32_t &StringOffset, MCSection *StrSection, MCSection *StrOffsetSection, StringRef CurStrSection, StringRef CurStrOffsetSection) { // Could possibly produce an error or warning if one of these was non-null but // the other was null. if (CurStrSection.empty() || CurStrOffsetSection.empty()) return std::error_code(); DenseMap<uint32_t, uint32_t> OffsetRemapping; DataExtractor Data(CurStrSection, true, 0); uint32_t LocalOffset = 0; uint32_t PrevOffset = 0; while (const char *s = Data.getCStr(&LocalOffset)) { StringRef Str(s, LocalOffset - PrevOffset - 1); auto Pair = Strings.insert(std::make_pair(Str, StringOffset)); if (Pair.second) { Out.SwitchSection(StrSection); Out.EmitBytes( StringRef(Pair.first->getKeyData(), Pair.first->getKeyLength() + 1)); StringOffset += Str.size() + 1; } OffsetRemapping[PrevOffset] = Pair.first->second; PrevOffset = LocalOffset; } Data = DataExtractor(CurStrOffsetSection, true, 0); Out.SwitchSection(StrOffsetSection); uint32_t Offset = 0; uint64_t Size = CurStrOffsetSection.size(); while (Offset < Size) { auto OldOffset = Data.getU32(&Offset); auto NewOffset = OffsetRemapping[OldOffset]; Out.EmitIntValue(NewOffset, 4); } return std::error_code(); }
static void emitNonLazySymbolPointer(MCStreamer &OutStreamer, MCSymbol *StubLabel, MachineModuleInfoImpl::StubValueTy &MCSym) { // L_foo$stub: OutStreamer.EmitLabel(StubLabel); // .indirect_symbol _foo OutStreamer.EmitSymbolAttribute(MCSym.getPointer(), MCSA_IndirectSymbol); if (MCSym.getInt()) // External to current translation unit. OutStreamer.EmitIntValue(0, 4/*size*/); else // Internal to current translation unit. // // When we place the LSDA into the TEXT section, the type info // pointers need to be indirect and pc-rel. We accomplish this by // using NLPs; however, sometimes the types are local to the file. // We need to fill in the value for the NLP in those cases. OutStreamer.EmitValue( MCSymbolRefExpr::create(MCSym.getPointer(), OutStreamer.getContext()), 4 /*size*/); }
void BTFTypeInt::emitType(MCStreamer &OS) { BTFTypeBase::emitType(OS); OS.AddComment("0x" + Twine::utohexstr(IntVal)); OS.EmitIntValue(IntVal, 4); }
/// emitModuleFlags - Perform code emission for module flags. void TargetLoweringObjectFileMachO:: emitModuleFlags(MCStreamer &Streamer, ArrayRef<Module::ModuleFlagEntry> ModuleFlags, Mangler &Mang, const TargetMachine &TM) const { unsigned VersionVal = 0; unsigned ImageInfoFlags = 0; MDNode *LinkerOptions = nullptr; StringRef SectionVal; for (ArrayRef<Module::ModuleFlagEntry>::iterator i = ModuleFlags.begin(), e = ModuleFlags.end(); i != e; ++i) { const Module::ModuleFlagEntry &MFE = *i; // Ignore flags with 'Require' behavior. if (MFE.Behavior == Module::Require) continue; StringRef Key = MFE.Key->getString(); Metadata *Val = MFE.Val; if (Key == "Objective-C Image Info Version") { VersionVal = mdconst::extract<ConstantInt>(Val)->getZExtValue(); } else if (Key == "Objective-C Garbage Collection" || Key == "Objective-C GC Only" || Key == "Objective-C Is Simulated" || Key == "Objective-C Image Swift Version") { ImageInfoFlags |= mdconst::extract<ConstantInt>(Val)->getZExtValue(); } else if (Key == "Objective-C Image Info Section") { SectionVal = cast<MDString>(Val)->getString(); } else if (Key == "Linker Options") { LinkerOptions = cast<MDNode>(Val); } } // Emit the linker options if present. if (LinkerOptions) { for (unsigned i = 0, e = LinkerOptions->getNumOperands(); i != e; ++i) { MDNode *MDOptions = cast<MDNode>(LinkerOptions->getOperand(i)); SmallVector<std::string, 4> StrOptions; // Convert to strings. for (unsigned ii = 0, ie = MDOptions->getNumOperands(); ii != ie; ++ii) { MDString *MDOption = cast<MDString>(MDOptions->getOperand(ii)); StrOptions.push_back(MDOption->getString()); } Streamer.EmitLinkerOptions(StrOptions); } } // The section is mandatory. If we don't have it, then we don't have GC info. if (SectionVal.empty()) return; StringRef Segment, Section; unsigned TAA = 0, StubSize = 0; bool TAAParsed; std::string ErrorCode = MCSectionMachO::ParseSectionSpecifier(SectionVal, Segment, Section, TAA, TAAParsed, StubSize); if (!ErrorCode.empty()) // If invalid, report the error with report_fatal_error. report_fatal_error("Invalid section specifier '" + Section + "': " + ErrorCode + "."); // Get the section. const MCSectionMachO *S = getContext().getMachOSection(Segment, Section, TAA, StubSize, SectionKind::getDataNoRel()); Streamer.SwitchSection(S); Streamer.EmitLabel(getContext(). GetOrCreateSymbol(StringRef("L_OBJC_IMAGE_INFO"))); Streamer.EmitIntValue(VersionVal, 4); Streamer.EmitIntValue(ImageInfoFlags, 4); Streamer.AddBlankLine(); }
void BTFTypeArray::emitType(MCStreamer &OS) { BTFTypeBase::emitType(OS); OS.EmitIntValue(ArrayInfo.ElemType, 4); OS.EmitIntValue(ArrayInfo.IndexType, 4); OS.EmitIntValue(ArrayInfo.Nelems, 4); }
static std::error_code write(MCStreamer &Out, ArrayRef<std::string> Inputs) { const auto &MCOFI = *Out.getContext().getObjectFileInfo(); MCSection *const StrSection = MCOFI.getDwarfStrDWOSection(); MCSection *const StrOffsetSection = MCOFI.getDwarfStrOffDWOSection(); const StringMap<std::pair<MCSection *, DWARFSectionKind>> KnownSections = { {"debug_info.dwo", {MCOFI.getDwarfInfoDWOSection(), DW_SECT_INFO}}, {"debug_types.dwo", {MCOFI.getDwarfTypesDWOSection(), DW_SECT_TYPES}}, {"debug_str_offsets.dwo", {StrOffsetSection, DW_SECT_STR_OFFSETS}}, {"debug_str.dwo", {StrSection, static_cast<DWARFSectionKind>(0)}}, {"debug_loc.dwo", {MCOFI.getDwarfLocDWOSection(), DW_SECT_LOC}}, {"debug_abbrev.dwo", {MCOFI.getDwarfAbbrevDWOSection(), DW_SECT_ABBREV}}}; struct UnitIndexEntry { uint64_t Signature; DWARFUnitIndex::Entry::SectionContribution Contributions[8]; }; std::vector<UnitIndexEntry> IndexEntries; StringMap<uint32_t> Strings; uint32_t StringOffset = 0; uint64_t UnitIndex = 0; uint32_t ContributionOffsets[8] = {}; for (const auto &Input : Inputs) { auto ErrOrObj = object::ObjectFile::createObjectFile(Input); if (!ErrOrObj) return ErrOrObj.getError(); IndexEntries.emplace_back(); UnitIndexEntry &CurEntry = IndexEntries.back(); CurEntry.Signature = UnitIndex++; StringRef CurStrSection; StringRef CurStrOffsetSection; for (const auto &Section : ErrOrObj->getBinary()->sections()) { StringRef Name; if (std::error_code Err = Section.getName(Name)) return Err; auto SectionPair = KnownSections.find(Name.substr(Name.find_first_not_of("._"))); if (SectionPair == KnownSections.end()) continue; StringRef Contents; if (auto Err = Section.getContents(Contents)) return Err; if (DWARFSectionKind Kind = SectionPair->second.second) { auto Index = Kind - DW_SECT_INFO; CurEntry.Contributions[Index].Offset = ContributionOffsets[Index]; ContributionOffsets[Index] += (CurEntry.Contributions[Index].Length = Contents.size()); } MCSection *OutSection = SectionPair->second.first; if (OutSection == StrOffsetSection) CurStrOffsetSection = Contents; else if (OutSection == StrSection) CurStrSection = Contents; else { Out.SwitchSection(OutSection); Out.EmitBytes(Contents); } } if (auto Err = writeStringsAndOffsets(Out, Strings, StringOffset, StrSection, StrOffsetSection, CurStrSection, CurStrOffsetSection)) return Err; } Out.SwitchSection(MCOFI.getDwarfCUIndexSection()); Out.EmitIntValue(2, 4); // Version Out.EmitIntValue(8, 4); // Columns Out.EmitIntValue(IndexEntries.size(), 4); // Num Units // FIXME: This is not the right number of buckets for a real hash. Out.EmitIntValue(IndexEntries.size(), 4); // Num Buckets // Write the signatures. for (const auto &E : IndexEntries) Out.EmitIntValue(E.Signature, 8); // Write the indexes. for (size_t i = 0; i != IndexEntries.size(); ++i) Out.EmitIntValue(i + 1, 4); // Write the column headers (which sections will appear in the table) for (size_t i = 1; i != 9; ++i) Out.EmitIntValue(i, 4); // Write the offsets. for (const auto &E : IndexEntries) for (const auto &C : E.Contributions) Out.EmitIntValue(C.Offset, 4); // Write the lengths. for (const auto &E : IndexEntries) for (const auto &C : E.Contributions) Out.EmitIntValue(C.Length, 4); return std::error_code(); }
void EmitCFIInstruction(MCStreamer &Streamer, const MCCFIInstruction &Instr, int &CFAOffset, int DataAlignmentFactor) { // Same as MCDwarf::EmitCFIInstruction () // FIXME: Unify int dataAlignmentFactor = DataAlignmentFactor; bool VerboseAsm = Streamer.isVerboseAsm(); switch (Instr.getOperation()) { case MCCFIInstruction::OpWindowSave: { Streamer.EmitIntValue(dwarf::DW_CFA_GNU_window_save, 1); return; } case MCCFIInstruction::OpUndefined: { unsigned Reg = Instr.getRegister(); if (VerboseAsm) { Streamer.AddComment("DW_CFA_undefined"); Streamer.AddComment(Twine("Reg ") + Twine(Reg)); } Streamer.EmitIntValue(dwarf::DW_CFA_undefined, 1); Streamer.EmitULEB128IntValue(Reg); return; } case MCCFIInstruction::OpAdjustCfaOffset: case MCCFIInstruction::OpDefCfaOffset: { const bool IsRelative = Instr.getOperation() == MCCFIInstruction::OpAdjustCfaOffset; if (VerboseAsm) Streamer.AddComment("DW_CFA_def_cfa_offset"); Streamer.EmitIntValue(dwarf::DW_CFA_def_cfa_offset, 1); if (IsRelative) CFAOffset += Instr.getOffset(); else // The backends pass in a negative value, // then createDefCfaOffset () negates it CFAOffset = Instr.getOffset(); if (VerboseAsm) Streamer.AddComment(Twine("Offset " + Twine(CFAOffset))); Streamer.EmitULEB128IntValue(CFAOffset); return; } case MCCFIInstruction::OpDefCfa: { if (VerboseAsm) Streamer.AddComment("DW_CFA_def_cfa"); Streamer.EmitIntValue(dwarf::DW_CFA_def_cfa, 1); if (VerboseAsm) Streamer.AddComment(Twine("Reg ") + Twine(Instr.getRegister())); Streamer.EmitULEB128IntValue(Instr.getRegister()); // Backends pass a negative value to createDefCfa () which // negates it back CFAOffset = Instr.getOffset(); if (VerboseAsm) Streamer.AddComment(Twine("Offset " + Twine(CFAOffset))); Streamer.EmitULEB128IntValue(CFAOffset); return; } case MCCFIInstruction::OpDefCfaRegister: { if (VerboseAsm) Streamer.AddComment("DW_CFA_def_cfa_register"); Streamer.EmitIntValue(dwarf::DW_CFA_def_cfa_register, 1); if (VerboseAsm) Streamer.AddComment(Twine("Reg ") + Twine(Instr.getRegister())); Streamer.EmitULEB128IntValue(Instr.getRegister()); return; } case MCCFIInstruction::OpOffset: case MCCFIInstruction::OpRelOffset: { const bool IsRelative = Instr.getOperation() == MCCFIInstruction::OpRelOffset; unsigned Reg = Instr.getRegister(); int Offset = Instr.getOffset(); if (IsRelative) Offset -= CFAOffset; Offset = Offset / dataAlignmentFactor; if (Offset < 0) { if (VerboseAsm) Streamer.AddComment("DW_CFA_offset_extended_sf"); Streamer.EmitIntValue(dwarf::DW_CFA_offset_extended_sf, 1); if (VerboseAsm) Streamer.AddComment(Twine("Reg ") + Twine(Reg)); Streamer.EmitULEB128IntValue(Reg); if (VerboseAsm) Streamer.AddComment(Twine("Offset ") + Twine(Offset)); Streamer.EmitSLEB128IntValue(Offset); } else if (Reg < 64) { if (VerboseAsm) Streamer.AddComment(Twine("DW_CFA_offset + Reg(") + Twine(Reg) + ")"); Streamer.EmitIntValue(dwarf::DW_CFA_offset + Reg, 1); if (VerboseAsm) Streamer.AddComment(Twine("Offset ") + Twine(Offset)); Streamer.EmitULEB128IntValue(Offset); } else { if (VerboseAsm) Streamer.AddComment("DW_CFA_offset_extended"); Streamer.EmitIntValue(dwarf::DW_CFA_offset_extended, 1); if (VerboseAsm) Streamer.AddComment(Twine("Reg ") + Twine(Reg)); Streamer.EmitULEB128IntValue(Reg); if (VerboseAsm) Streamer.AddComment(Twine("Offset ") + Twine(Offset)); Streamer.EmitULEB128IntValue(Offset); } return; } case MCCFIInstruction::OpRememberState: if (VerboseAsm) Streamer.AddComment("DW_CFA_remember_state"); Streamer.EmitIntValue(dwarf::DW_CFA_remember_state, 1); return; case MCCFIInstruction::OpRestoreState: if (VerboseAsm) Streamer.AddComment("DW_CFA_restore_state"); Streamer.EmitIntValue(dwarf::DW_CFA_restore_state, 1); return; case MCCFIInstruction::OpSameValue: { unsigned Reg = Instr.getRegister(); if (VerboseAsm) Streamer.AddComment("DW_CFA_same_value"); Streamer.EmitIntValue(dwarf::DW_CFA_same_value, 1); if (VerboseAsm) Streamer.AddComment(Twine("Reg ") + Twine(Reg)); Streamer.EmitULEB128IntValue(Reg); return; } case MCCFIInstruction::OpRestore: { unsigned Reg = Instr.getRegister(); if (VerboseAsm) { Streamer.AddComment("DW_CFA_restore"); Streamer.AddComment(Twine("Reg ") + Twine(Reg)); } Streamer.EmitIntValue(dwarf::DW_CFA_restore | Reg, 1); return; } case MCCFIInstruction::OpEscape: if (VerboseAsm) Streamer.AddComment("Escape bytes"); Streamer.EmitBytes(Instr.getValues()); return; case MCCFIInstruction::OpRegister: llvm_unreachable("Unhandled case in switch"); return; } llvm_unreachable("Unhandled case in switch"); }
static void EncodeTypes(MCStreamer &Streamer, ArrayRef<MVT> Types) { Streamer.EmitIntValue(Types.size(), sizeof(uint64_t)); for (MVT Type : Types) Streamer.EmitIntValue(Type.SimpleTy, sizeof(uint64_t)); }