Imported Upstream version 5.18.0.167

Former-commit-id: 289509151e0fee68a1b591a20c9f109c3c789d3a
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2018-10-20 08:25:10 +00:00
parent e19d552987
commit b084638f15
28489 changed files with 184 additions and 3866856 deletions

View File

@ -1,62 +0,0 @@
add_llvm_library(LLVMMC
ConstantPools.cpp
ELFObjectWriter.cpp
MCAsmBackend.cpp
MCAsmInfo.cpp
MCAsmInfoCOFF.cpp
MCAsmInfoDarwin.cpp
MCAsmInfoELF.cpp
MCAsmInfoWasm.cpp
MCAsmStreamer.cpp
MCAssembler.cpp
MCCodeEmitter.cpp
MCCodePadder.cpp
MCCodeView.cpp
MCContext.cpp
MCDwarf.cpp
MCELFObjectTargetWriter.cpp
MCELFStreamer.cpp
MCExpr.cpp
MCFragment.cpp
MCInst.cpp
MCInstPrinter.cpp
MCInstrAnalysis.cpp
MCInstrDesc.cpp
MCLabel.cpp
MCLinkerOptimizationHint.cpp
MCMachOStreamer.cpp
MCMachObjectTargetWriter.cpp
MCNullStreamer.cpp
MCObjectFileInfo.cpp
MCObjectStreamer.cpp
MCObjectWriter.cpp
MCRegisterInfo.cpp
MCSchedule.cpp
MCSection.cpp
MCSectionCOFF.cpp
MCSectionELF.cpp
MCSectionMachO.cpp
MCSectionWasm.cpp
MCStreamer.cpp
MCSubtargetInfo.cpp
MCSymbol.cpp
MCSymbolELF.cpp
MCTargetOptions.cpp
MCValue.cpp
MCWasmObjectTargetWriter.cpp
MCWasmStreamer.cpp
MCWin64EH.cpp
MCWinCOFFStreamer.cpp
MCWinEH.cpp
MachObjectWriter.cpp
StringTableBuilder.cpp
SubtargetFeature.cpp
WasmObjectWriter.cpp
WinCOFFObjectWriter.cpp
ADDITIONAL_HEADER_DIRS
${LLVM_MAIN_INCLUDE_DIR}/llvm/MC
)
add_subdirectory(MCParser)
add_subdirectory(MCDisassembler)

View File

@ -1,118 +0,0 @@
//===- ConstantPools.cpp - ConstantPool class -----------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the ConstantPool and AssemblerConstantPools classes.
//
//===----------------------------------------------------------------------===//
#include "llvm/MC/ConstantPools.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDirectives.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/Support/Casting.h"
using namespace llvm;
//
// ConstantPool implementation
//
// Emit the contents of the constant pool using the provided streamer.
void ConstantPool::emitEntries(MCStreamer &Streamer) {
if (Entries.empty())
return;
Streamer.EmitDataRegion(MCDR_DataRegion);
for (const ConstantPoolEntry &Entry : Entries) {
Streamer.EmitCodeAlignment(Entry.Size); // align naturally
Streamer.EmitLabel(Entry.Label);
Streamer.EmitValue(Entry.Value, Entry.Size, Entry.Loc);
}
Streamer.EmitDataRegion(MCDR_DataRegionEnd);
Entries.clear();
}
const MCExpr *ConstantPool::addEntry(const MCExpr *Value, MCContext &Context,
unsigned Size, SMLoc Loc) {
const MCConstantExpr *C = dyn_cast<MCConstantExpr>(Value);
// Check if there is existing entry for the same constant. If so, reuse it.
auto Itr = C ? CachedEntries.find(C->getValue()) : CachedEntries.end();
if (Itr != CachedEntries.end())
return Itr->second;
MCSymbol *CPEntryLabel = Context.createTempSymbol();
Entries.push_back(ConstantPoolEntry(CPEntryLabel, Value, Size, Loc));
const auto SymRef = MCSymbolRefExpr::create(CPEntryLabel, Context);
if (C)
CachedEntries[C->getValue()] = SymRef;
return SymRef;
}
bool ConstantPool::empty() { return Entries.empty(); }
void ConstantPool::clearCache() {
CachedEntries.clear();
}
//
// AssemblerConstantPools implementation
//
ConstantPool *AssemblerConstantPools::getConstantPool(MCSection *Section) {
ConstantPoolMapTy::iterator CP = ConstantPools.find(Section);
if (CP == ConstantPools.end())
return nullptr;
return &CP->second;
}
ConstantPool &
AssemblerConstantPools::getOrCreateConstantPool(MCSection *Section) {
return ConstantPools[Section];
}
static void emitConstantPool(MCStreamer &Streamer, MCSection *Section,
ConstantPool &CP) {
if (!CP.empty()) {
Streamer.SwitchSection(Section);
CP.emitEntries(Streamer);
}
}
void AssemblerConstantPools::emitAll(MCStreamer &Streamer) {
// Dump contents of assembler constant pools.
for (auto &CPI : ConstantPools) {
MCSection *Section = CPI.first;
ConstantPool &CP = CPI.second;
emitConstantPool(Streamer, Section, CP);
}
}
void AssemblerConstantPools::emitForCurrentSection(MCStreamer &Streamer) {
MCSection *Section = Streamer.getCurrentSectionOnly();
if (ConstantPool *CP = getConstantPool(Section)) {
emitConstantPool(Streamer, Section, *CP);
}
}
void AssemblerConstantPools::clearCacheForCurrentSection(MCStreamer &Streamer) {
MCSection *Section = Streamer.getCurrentSectionOnly();
if (ConstantPool *CP = getConstantPool(Section)) {
CP->clearCache();
}
}
const MCExpr *AssemblerConstantPools::addEntry(MCStreamer &Streamer,
const MCExpr *Expr,
unsigned Size, SMLoc Loc) {
MCSection *Section = Streamer.getCurrentSectionOnly();
return getOrCreateConstantPool(Section).addEntry(Expr, Streamer.getContext(),
Size, Loc);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,25 +0,0 @@
;===- ./lib/MC/LLVMBuild.txt -----------------------------------*- Conf -*--===;
;
; The LLVM Compiler Infrastructure
;
; This file is distributed under the University of Illinois Open Source
; License. See LICENSE.TXT for details.
;
;===------------------------------------------------------------------------===;
;
; This is an LLVMBuild description file for the components in this subdirectory.
;
; For more information on the LLVMBuild system, please see:
;
; http://llvm.org/docs/LLVMBuild.html
;
;===------------------------------------------------------------------------===;
[common]
subdirectories = MCDisassembler MCParser
[component_0]
type = Library
name = MC
parent = Libraries
required_libraries = Support

View File

@ -1,87 +0,0 @@
//===- MCAsmBackend.cpp - Target MC Assembly Backend ----------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "llvm/MC/MCAsmBackend.h"
#include "llvm/ADT/None.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/MC/MCCodePadder.h"
#include "llvm/MC/MCFixupKindInfo.h"
#include <cassert>
#include <cstddef>
#include <cstdint>
using namespace llvm;
MCAsmBackend::MCAsmBackend() : CodePadder(new MCCodePadder()) {}
MCAsmBackend::MCAsmBackend(std::unique_ptr<MCCodePadder> TargetCodePadder)
: CodePadder(std::move(TargetCodePadder)) {}
MCAsmBackend::~MCAsmBackend() = default;
Optional<MCFixupKind> MCAsmBackend::getFixupKind(StringRef Name) const {
return None;
}
const MCFixupKindInfo &MCAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
static const MCFixupKindInfo Builtins[] = {
{"FK_Data_1", 0, 8, 0},
{"FK_Data_2", 0, 16, 0},
{"FK_Data_4", 0, 32, 0},
{"FK_Data_8", 0, 64, 0},
{"FK_PCRel_1", 0, 8, MCFixupKindInfo::FKF_IsPCRel},
{"FK_PCRel_2", 0, 16, MCFixupKindInfo::FKF_IsPCRel},
{"FK_PCRel_4", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
{"FK_PCRel_8", 0, 64, MCFixupKindInfo::FKF_IsPCRel},
{"FK_GPRel_1", 0, 8, 0},
{"FK_GPRel_2", 0, 16, 0},
{"FK_GPRel_4", 0, 32, 0},
{"FK_GPRel_8", 0, 64, 0},
{"FK_DTPRel_4", 0, 32, 0},
{"FK_DTPRel_8", 0, 64, 0},
{"FK_TPRel_4", 0, 32, 0},
{"FK_TPRel_8", 0, 64, 0},
{"FK_SecRel_1", 0, 8, 0},
{"FK_SecRel_2", 0, 16, 0},
{"FK_SecRel_4", 0, 32, 0},
{"FK_SecRel_8", 0, 64, 0}};
assert((size_t)Kind <= array_lengthof(Builtins) && "Unknown fixup kind");
return Builtins[Kind];
}
bool MCAsmBackend::fixupNeedsRelaxationAdvanced(
const MCFixup &Fixup, bool Resolved, uint64_t Value,
const MCRelaxableFragment *DF, const MCAsmLayout &Layout) const {
if (!Resolved)
return true;
return fixupNeedsRelaxation(Fixup, Value, DF, Layout);
}
void MCAsmBackend::handleCodePaddingBasicBlockStart(
MCObjectStreamer *OS, const MCCodePaddingContext &Context) {
CodePadder->handleBasicBlockStart(OS, Context);
}
void MCAsmBackend::handleCodePaddingBasicBlockEnd(
const MCCodePaddingContext &Context) {
CodePadder->handleBasicBlockEnd(Context);
}
void MCAsmBackend::handleCodePaddingInstructionBegin(const MCInst &Inst) {
CodePadder->handleInstructionBegin(Inst);
}
void MCAsmBackend::handleCodePaddingInstructionEnd(const MCInst &Inst) {
CodePadder->handleInstructionEnd(Inst);
}
bool MCAsmBackend::relaxFragment(MCPaddingFragment *PF, MCAsmLayout &Layout) {
return CodePadder->relaxFragment(PF, Layout);
}

View File

@ -1,112 +0,0 @@
//===- MCAsmInfo.cpp - Asm Info -------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines target asm properties related what form asm statements
// should take.
//
//===----------------------------------------------------------------------===//
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCStreamer.h"
using namespace llvm;
MCAsmInfo::MCAsmInfo() {
SeparatorString = ";";
CommentString = "#";
LabelSuffix = ":";
PrivateGlobalPrefix = "L";
PrivateLabelPrefix = PrivateGlobalPrefix;
LinkerPrivateGlobalPrefix = "";
InlineAsmStart = "APP";
InlineAsmEnd = "NO_APP";
Code16Directive = ".code16";
Code32Directive = ".code32";
Code64Directive = ".code64";
ZeroDirective = "\t.zero\t";
AsciiDirective = "\t.ascii\t";
AscizDirective = "\t.asciz\t";
Data8bitsDirective = "\t.byte\t";
Data16bitsDirective = "\t.short\t";
Data32bitsDirective = "\t.long\t";
Data64bitsDirective = "\t.quad\t";
GlobalDirective = "\t.globl\t";
WeakDirective = "\t.weak\t";
// FIXME: Clang's logic should be synced with the logic used to initialize
// this member and the two implementations should be merged.
// For reference:
// - Solaris always enables the integrated assembler by default
// - SparcELFMCAsmInfo and X86ELFMCAsmInfo are handling this case
// - Windows always enables the integrated assembler by default
// - MCAsmInfoCOFF is handling this case, should it be MCAsmInfoMicrosoft?
// - MachO targets always enables the integrated assembler by default
// - MCAsmInfoDarwin is handling this case
// - Generic_GCC toolchains enable the integrated assembler on a per
// architecture basis.
// - The target subclasses for AArch64, ARM, and X86 handle these cases
UseIntegratedAssembler = false;
PreserveAsmComments = true;
}
MCAsmInfo::~MCAsmInfo() = default;
bool MCAsmInfo::isSectionAtomizableBySymbols(const MCSection &Section) const {
return false;
}
const MCExpr *
MCAsmInfo::getExprForPersonalitySymbol(const MCSymbol *Sym,
unsigned Encoding,
MCStreamer &Streamer) const {
return getExprForFDESymbol(Sym, Encoding, Streamer);
}
const MCExpr *
MCAsmInfo::getExprForFDESymbol(const MCSymbol *Sym,
unsigned Encoding,
MCStreamer &Streamer) const {
if (!(Encoding & dwarf::DW_EH_PE_pcrel))
return MCSymbolRefExpr::create(Sym, Streamer.getContext());
MCContext &Context = Streamer.getContext();
const MCExpr *Res = MCSymbolRefExpr::create(Sym, Context);
MCSymbol *PCSym = Context.createTempSymbol();
Streamer.EmitLabel(PCSym);
const MCExpr *PC = MCSymbolRefExpr::create(PCSym, Context);
return MCBinaryExpr::createSub(Res, PC, Context);
}
static bool isAcceptableChar(char C) {
return (C >= 'a' && C <= 'z') || (C >= 'A' && C <= 'Z') ||
(C >= '0' && C <= '9') || C == '_' || C == '$' || C == '.' || C == '@';
}
bool MCAsmInfo::isValidUnquotedName(StringRef Name) const {
if (Name.empty())
return false;
// If any of the characters in the string is an unacceptable character, force
// quotes.
for (char C : Name) {
if (!isAcceptableChar(C))
return false;
}
return true;
}
bool MCAsmInfo::shouldOmitSectionDirective(StringRef SectionName) const {
// FIXME: Does .section .bss/.data/.text work everywhere??
return SectionName == ".text" || SectionName == ".data" ||
(SectionName == ".bss" && !usesELFSectionDirectiveForBSS());
}

View File

@ -1,52 +0,0 @@
//===- MCAsmInfoCOFF.cpp - COFF asm properties ----------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines target asm properties related what form asm statements
// should take in general on COFF-based targets
//
//===----------------------------------------------------------------------===//
#include "llvm/MC/MCAsmInfoCOFF.h"
#include "llvm/MC/MCDirectives.h"
using namespace llvm;
void MCAsmInfoCOFF::anchor() {}
MCAsmInfoCOFF::MCAsmInfoCOFF() {
// MingW 4.5 and later support .comm with log2 alignment, but .lcomm uses byte
// alignment.
COMMDirectiveAlignmentIsInBytes = false;
LCOMMDirectiveAlignmentType = LCOMM::ByteAlignment;
HasDotTypeDotSizeDirective = false;
HasSingleParameterDotFile = false;
WeakRefDirective = "\t.weak\t";
HasLinkOnceDirective = true;
// Doesn't support visibility:
HiddenVisibilityAttr = HiddenDeclarationVisibilityAttr = MCSA_Invalid;
ProtectedVisibilityAttr = MCSA_Invalid;
// Set up DWARF directives
SupportsDebugInformation = true;
NeedsDwarfSectionOffsetDirective = true;
UseIntegratedAssembler = true;
// At least MSVC inline-asm does AShr.
UseLogicalShr = false;
}
void MCAsmInfoMicrosoft::anchor() {}
MCAsmInfoMicrosoft::MCAsmInfoMicrosoft() = default;
void MCAsmInfoGNUCOFF::anchor() {}
MCAsmInfoGNUCOFF::MCAsmInfoGNUCOFF() = default;

View File

@ -1,98 +0,0 @@
//===- MCAsmInfoDarwin.cpp - Darwin asm properties ------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines target asm properties related what form asm statements
// should take in general on Darwin-based targets
//
//===----------------------------------------------------------------------===//
#include "llvm/MC/MCAsmInfoDarwin.h"
#include "llvm/BinaryFormat/MachO.h"
#include "llvm/MC/MCDirectives.h"
#include "llvm/MC/MCSectionMachO.h"
using namespace llvm;
bool MCAsmInfoDarwin::isSectionAtomizableBySymbols(
const MCSection &Section) const {
const MCSectionMachO &SMO = static_cast<const MCSectionMachO &>(Section);
// Sections holding 1 byte strings are atomized based on the data they
// contain.
// Sections holding 2 byte strings require symbols in order to be atomized.
// There is no dedicated section for 4 byte strings.
if (SMO.getType() == MachO::S_CSTRING_LITERALS)
return false;
if (SMO.getSegmentName() == "__DATA" && SMO.getSectionName() == "__cfstring")
return false;
if (SMO.getSegmentName() == "__DATA" &&
SMO.getSectionName() == "__objc_classrefs")
return false;
switch (SMO.getType()) {
default:
return true;
// These sections are atomized at the element boundaries without using
// symbols.
case MachO::S_4BYTE_LITERALS:
case MachO::S_8BYTE_LITERALS:
case MachO::S_16BYTE_LITERALS:
case MachO::S_LITERAL_POINTERS:
case MachO::S_NON_LAZY_SYMBOL_POINTERS:
case MachO::S_LAZY_SYMBOL_POINTERS:
case MachO::S_THREAD_LOCAL_VARIABLE_POINTERS:
case MachO::S_MOD_INIT_FUNC_POINTERS:
case MachO::S_MOD_TERM_FUNC_POINTERS:
case MachO::S_INTERPOSING:
return false;
}
}
MCAsmInfoDarwin::MCAsmInfoDarwin() {
// Common settings for all Darwin targets.
// Syntax:
LinkerPrivateGlobalPrefix = "l";
HasSingleParameterDotFile = false;
HasSubsectionsViaSymbols = true;
AlignmentIsInBytes = false;
COMMDirectiveAlignmentIsInBytes = false;
LCOMMDirectiveAlignmentType = LCOMM::Log2Alignment;
InlineAsmStart = " InlineAsm Start";
InlineAsmEnd = " InlineAsm End";
// Directives:
HasWeakDefDirective = true;
HasWeakDefCanBeHiddenDirective = true;
WeakRefDirective = "\t.weak_reference ";
ZeroDirective = "\t.space\t"; // ".space N" emits N zeros.
HasMachoZeroFillDirective = true; // Uses .zerofill
HasMachoTBSSDirective = true; // Uses .tbss
// FIXME: Change this once MC is the system assembler.
HasAggressiveSymbolFolding = false;
HiddenVisibilityAttr = MCSA_PrivateExtern;
HiddenDeclarationVisibilityAttr = MCSA_Invalid;
// Doesn't support protected visibility.
ProtectedVisibilityAttr = MCSA_Invalid;
HasDotTypeDotSizeDirective = false;
HasNoDeadStrip = true;
HasAltEntry = true;
DwarfUsesRelocationsAcrossSections = false;
UseIntegratedAssembler = true;
SetDirectiveSuppressesReloc = true;
}

View File

@ -1,35 +0,0 @@
//===- MCAsmInfoELF.cpp - ELF asm properties ------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines target asm properties related what form asm statements
// should take in general on ELF-based targets
//
//===----------------------------------------------------------------------===//
#include "llvm/MC/MCAsmInfoELF.h"
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCSectionELF.h"
using namespace llvm;
void MCAsmInfoELF::anchor() {}
MCSection *MCAsmInfoELF::getNonexecutableStackSection(MCContext &Ctx) const {
if (!UsesNonexecutableStackSection)
return nullptr;
return Ctx.getELFSection(".note.GNU-stack", ELF::SHT_PROGBITS, 0);
}
MCAsmInfoELF::MCAsmInfoELF() {
HasIdentDirective = true;
WeakRefDirective = "\t.weak\t";
PrivateGlobalPrefix = ".L";
PrivateLabelPrefix = ".L";
}

View File

@ -1,25 +0,0 @@
//===-- MCAsmInfoWasm.cpp - Wasm asm properties -----------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines target asm properties related what form asm statements
// should take in general on Wasm-based targets
//
//===----------------------------------------------------------------------===//
#include "llvm/MC/MCAsmInfoWasm.h"
using namespace llvm;
void MCAsmInfoWasm::anchor() { }
MCAsmInfoWasm::MCAsmInfoWasm() {
HasIdentDirective = true;
WeakRefDirective = "\t.weak\t";
PrivateGlobalPrefix = ".L";
PrivateLabelPrefix = ".L";
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,16 +0,0 @@
//===- MCCodeEmitter.cpp - Instruction Encoding ---------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "llvm/MC/MCCodeEmitter.h"
using namespace llvm;
MCCodeEmitter::MCCodeEmitter() = default;
MCCodeEmitter::~MCCodeEmitter() = default;

View File

@ -1,371 +0,0 @@
//===- MCCodePadder.cpp - Target MC Code Padder ---------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "llvm/MC/MCAsmLayout.h"
#include "llvm/MC/MCCodePadder.h"
#include "llvm/MC/MCObjectStreamer.h"
#include <algorithm>
#include <limits>
#include <numeric>
using namespace llvm;
//---------------------------------------------------------------------------
// MCCodePadder
//
MCCodePadder::~MCCodePadder() {
for (auto *Policy : CodePaddingPolicies)
delete Policy;
}
bool MCCodePadder::addPolicy(MCCodePaddingPolicy *Policy) {
assert(Policy && "Policy must be valid");
return CodePaddingPolicies.insert(Policy).second;
}
void MCCodePadder::handleBasicBlockStart(MCObjectStreamer *OS,
const MCCodePaddingContext &Context) {
assert(OS != nullptr && "OS must be valid");
assert(this->OS == nullptr && "Still handling another basic block");
this->OS = OS;
ArePoliciesActive = usePoliciesForBasicBlock(Context);
bool InsertionPoint = basicBlockRequiresInsertionPoint(Context);
assert((!InsertionPoint ||
OS->getCurrentFragment()->getKind() != MCFragment::FT_Align) &&
"Cannot insert padding nops right after an alignment fragment as it "
"will ruin the alignment");
uint64_t PoliciesMask = MCPaddingFragment::PFK_None;
if (ArePoliciesActive) {
PoliciesMask = std::accumulate(
CodePaddingPolicies.begin(), CodePaddingPolicies.end(),
MCPaddingFragment::PFK_None,
[&Context](uint64_t Mask,
const MCCodePaddingPolicy *Policy) -> uint64_t {
return Policy->basicBlockRequiresPaddingFragment(Context)
? (Mask | Policy->getKindMask())
: Mask;
});
}
if (InsertionPoint || PoliciesMask != MCPaddingFragment::PFK_None) {
MCPaddingFragment *PaddingFragment = OS->getOrCreatePaddingFragment();
if (InsertionPoint)
PaddingFragment->setAsInsertionPoint();
PaddingFragment->setPaddingPoliciesMask(
PaddingFragment->getPaddingPoliciesMask() | PoliciesMask);
}
}
void MCCodePadder::handleBasicBlockEnd(const MCCodePaddingContext &Context) {
assert(this->OS != nullptr && "Not handling a basic block");
OS = nullptr;
}
void MCCodePadder::handleInstructionBegin(const MCInst &Inst) {
if (!OS)
return; // instruction was emitted outside a function
assert(CurrHandledInstFragment == nullptr && "Can't start handling an "
"instruction while still "
"handling another instruction");
bool InsertionPoint = instructionRequiresInsertionPoint(Inst);
assert((!InsertionPoint ||
OS->getCurrentFragment()->getKind() != MCFragment::FT_Align) &&
"Cannot insert padding nops right after an alignment fragment as it "
"will ruin the alignment");
uint64_t PoliciesMask = MCPaddingFragment::PFK_None;
if (ArePoliciesActive) {
PoliciesMask = std::accumulate(
CodePaddingPolicies.begin(), CodePaddingPolicies.end(),
MCPaddingFragment::PFK_None,
[&Inst](uint64_t Mask, const MCCodePaddingPolicy *Policy) -> uint64_t {
return Policy->instructionRequiresPaddingFragment(Inst)
? (Mask | Policy->getKindMask())
: Mask;
});
}
MCFragment *CurrFragment = OS->getCurrentFragment();
// CurrFragment can be a previously created MCPaddingFragment. If so, let's
// update it with the information we have, such as the instruction that it
// should point to.
bool needToUpdateCurrFragment =
CurrFragment != nullptr &&
CurrFragment->getKind() == MCFragment::FT_Padding;
if (InsertionPoint || PoliciesMask != MCPaddingFragment::PFK_None ||
needToUpdateCurrFragment) {
// temporarily holding the fragment as CurrHandledInstFragment, to be
// updated after the instruction will be written
CurrHandledInstFragment = OS->getOrCreatePaddingFragment();
if (InsertionPoint)
CurrHandledInstFragment->setAsInsertionPoint();
CurrHandledInstFragment->setPaddingPoliciesMask(
CurrHandledInstFragment->getPaddingPoliciesMask() | PoliciesMask);
}
}
void MCCodePadder::handleInstructionEnd(const MCInst &Inst) {
if (!OS)
return; // instruction was emitted outside a function
if (CurrHandledInstFragment == nullptr)
return;
MCFragment *InstFragment = OS->getCurrentFragment();
if (MCDataFragment *InstDataFragment =
dyn_cast_or_null<MCDataFragment>(InstFragment))
// Inst is a fixed size instruction and was encoded into a MCDataFragment.
// Let the fragment hold it and its size. Its size is the current size of
// the data fragment, as the padding fragment was inserted right before it
// and nothing was written yet except Inst
CurrHandledInstFragment->setInstAndInstSize(
Inst, InstDataFragment->getContents().size());
else if (MCRelaxableFragment *InstRelaxableFragment =
dyn_cast_or_null<MCRelaxableFragment>(InstFragment))
// Inst may be relaxed and its size may vary.
// Let the fragment hold the instruction and the MCRelaxableFragment
// that's holding it.
CurrHandledInstFragment->setInstAndInstFragment(Inst,
InstRelaxableFragment);
else
llvm_unreachable("After encoding an instruction current fragment must be "
"either a MCDataFragment or a MCRelaxableFragment");
CurrHandledInstFragment = nullptr;
}
MCPFRange &MCCodePadder::getJurisdiction(MCPaddingFragment *Fragment,
MCAsmLayout &Layout) {
auto JurisdictionLocation = FragmentToJurisdiction.find(Fragment);
if (JurisdictionLocation != FragmentToJurisdiction.end())
return JurisdictionLocation->second;
MCPFRange Jurisdiction;
// Forward scanning the fragments in this section, starting from the given
// fragments, and adding relevant MCPaddingFragments to the Jurisdiction
for (MCFragment *CurrFragment = Fragment; CurrFragment != nullptr;
CurrFragment = CurrFragment->getNextNode()) {
MCPaddingFragment *CurrPaddingFragment =
dyn_cast<MCPaddingFragment>(CurrFragment);
if (CurrPaddingFragment == nullptr)
continue;
if (CurrPaddingFragment != Fragment &&
CurrPaddingFragment->isInsertionPoint())
// Found next insertion point Fragment. From now on it's its jurisdiction.
break;
for (const auto *Policy : CodePaddingPolicies) {
if (CurrPaddingFragment->hasPaddingPolicy(Policy->getKindMask())) {
Jurisdiction.push_back(CurrPaddingFragment);
break;
}
}
}
auto InsertionResult =
FragmentToJurisdiction.insert(std::make_pair(Fragment, Jurisdiction));
assert(InsertionResult.second &&
"Insertion to FragmentToJurisdiction failed");
return InsertionResult.first->second;
}
uint64_t MCCodePadder::getMaxWindowSize(MCPaddingFragment *Fragment,
MCAsmLayout &Layout) {
auto MaxFragmentSizeLocation = FragmentToMaxWindowSize.find(Fragment);
if (MaxFragmentSizeLocation != FragmentToMaxWindowSize.end())
return MaxFragmentSizeLocation->second;
MCPFRange &Jurisdiction = getJurisdiction(Fragment, Layout);
uint64_t JurisdictionMask = MCPaddingFragment::PFK_None;
for (const auto *Protege : Jurisdiction)
JurisdictionMask |= Protege->getPaddingPoliciesMask();
uint64_t MaxFragmentSize = UINT64_C(0);
for (const auto *Policy : CodePaddingPolicies)
if ((JurisdictionMask & Policy->getKindMask()) !=
MCPaddingFragment::PFK_None)
MaxFragmentSize = std::max(MaxFragmentSize, Policy->getWindowSize());
auto InsertionResult =
FragmentToMaxWindowSize.insert(std::make_pair(Fragment, MaxFragmentSize));
assert(InsertionResult.second &&
"Insertion to FragmentToMaxWindowSize failed");
return InsertionResult.first->second;
}
bool MCCodePadder::relaxFragment(MCPaddingFragment *Fragment,
MCAsmLayout &Layout) {
if (!Fragment->isInsertionPoint())
return false;
uint64_t OldSize = Fragment->getSize();
uint64_t MaxWindowSize = getMaxWindowSize(Fragment, Layout);
if (MaxWindowSize == UINT64_C(0))
return false;
assert(isPowerOf2_64(MaxWindowSize) &&
"MaxWindowSize must be an integer power of 2");
uint64_t SectionAlignment = Fragment->getParent()->getAlignment();
assert(isPowerOf2_64(SectionAlignment) &&
"SectionAlignment must be an integer power of 2");
MCPFRange &Jurisdiction = getJurisdiction(Fragment, Layout);
uint64_t OptimalSize = UINT64_C(0);
double OptimalWeight = std::numeric_limits<double>::max();
uint64_t MaxFragmentSize = MaxWindowSize - UINT16_C(1);
for (uint64_t Size = UINT64_C(0); Size <= MaxFragmentSize; ++Size) {
Fragment->setSize(Size);
Layout.invalidateFragmentsFrom(Fragment);
double SizeWeight = 0.0;
// The section is guaranteed to be aligned to SectionAlignment, but that
// doesn't guarantee the exact section offset w.r.t. the policies window
// size.
// As a concrete example, the section could be aligned to 16B, but a
// policy's window size can be 32B. That means that the section actual start
// address can either be 0mod32 or 16mod32. The said policy will act
// differently for each case, so we need to take both into consideration.
for (uint64_t Offset = UINT64_C(0); Offset < MaxWindowSize;
Offset += SectionAlignment) {
double OffsetWeight = std::accumulate(
CodePaddingPolicies.begin(), CodePaddingPolicies.end(), 0.0,
[&Jurisdiction, &Offset, &Layout](
double Weight, const MCCodePaddingPolicy *Policy) -> double {
double PolicyWeight =
Policy->computeRangePenaltyWeight(Jurisdiction, Offset, Layout);
assert(PolicyWeight >= 0.0 && "A penalty weight must be positive");
return Weight + PolicyWeight;
});
SizeWeight = std::max(SizeWeight, OffsetWeight);
}
if (SizeWeight < OptimalWeight) {
OptimalWeight = SizeWeight;
OptimalSize = Size;
}
if (OptimalWeight == 0.0)
break;
}
Fragment->setSize(OptimalSize);
Layout.invalidateFragmentsFrom(Fragment);
return OldSize != OptimalSize;
}
//---------------------------------------------------------------------------
// MCCodePaddingPolicy
//
uint64_t MCCodePaddingPolicy::getNextFragmentOffset(const MCFragment *Fragment,
const MCAsmLayout &Layout) {
assert(Fragment != nullptr && "Fragment cannot be null");
MCFragment const *NextFragment = Fragment->getNextNode();
return NextFragment == nullptr
? Layout.getSectionAddressSize(Fragment->getParent())
: Layout.getFragmentOffset(NextFragment);
}
uint64_t
MCCodePaddingPolicy::getFragmentInstByte(const MCPaddingFragment *Fragment,
MCAsmLayout &Layout) const {
uint64_t InstByte = getNextFragmentOffset(Fragment, Layout);
if (InstByteIsLastByte)
InstByte += Fragment->getInstSize() - UINT64_C(1);
return InstByte;
}
uint64_t
MCCodePaddingPolicy::computeWindowEndAddress(const MCPaddingFragment *Fragment,
uint64_t Offset,
MCAsmLayout &Layout) const {
uint64_t InstByte = getFragmentInstByte(Fragment, Layout);
return alignTo(InstByte + UINT64_C(1) + Offset, WindowSize) - Offset;
}
double MCCodePaddingPolicy::computeRangePenaltyWeight(
const MCPFRange &Range, uint64_t Offset, MCAsmLayout &Layout) const {
SmallVector<MCPFRange, 8> Windows;
SmallVector<MCPFRange, 8>::iterator CurrWindowLocation = Windows.end();
for (const MCPaddingFragment *Fragment : Range) {
if (!Fragment->hasPaddingPolicy(getKindMask()))
continue;
uint64_t FragmentWindowEndAddress =
computeWindowEndAddress(Fragment, Offset, Layout);
if (CurrWindowLocation == Windows.end() ||
FragmentWindowEndAddress !=
computeWindowEndAddress(*CurrWindowLocation->begin(), Offset,
Layout)) {
// next window is starting
Windows.push_back(MCPFRange());
CurrWindowLocation = Windows.end() - 1;
}
CurrWindowLocation->push_back(Fragment);
}
if (Windows.empty())
return 0.0;
double RangeWeight = 0.0;
SmallVector<MCPFRange, 8>::iterator I = Windows.begin();
RangeWeight += computeFirstWindowPenaltyWeight(*I, Offset, Layout);
++I;
RangeWeight += std::accumulate(
I, Windows.end(), 0.0,
[this, &Layout, &Offset](double Weight, MCPFRange &Window) -> double {
return Weight += computeWindowPenaltyWeight(Window, Offset, Layout);
});
return RangeWeight;
}
double MCCodePaddingPolicy::computeFirstWindowPenaltyWeight(
const MCPFRange &Window, uint64_t Offset, MCAsmLayout &Layout) const {
if (Window.empty())
return 0.0;
uint64_t WindowEndAddress =
computeWindowEndAddress(*Window.begin(), Offset, Layout);
MCPFRange FullWindowFirstPart; // will hold all the fragments that are in the
// same window as the fragments in the given
// window but their penalty weight should not
// be added
for (const MCFragment *Fragment = (*Window.begin())->getPrevNode();
Fragment != nullptr; Fragment = Fragment->getPrevNode()) {
const MCPaddingFragment *PaddingNopFragment =
dyn_cast<MCPaddingFragment>(Fragment);
if (PaddingNopFragment == nullptr ||
!PaddingNopFragment->hasPaddingPolicy(getKindMask()))
continue;
if (WindowEndAddress !=
computeWindowEndAddress(PaddingNopFragment, Offset, Layout))
break;
FullWindowFirstPart.push_back(PaddingNopFragment);
}
std::reverse(FullWindowFirstPart.begin(), FullWindowFirstPart.end());
double FullWindowFirstPartWeight =
computeWindowPenaltyWeight(FullWindowFirstPart, Offset, Layout);
MCPFRange FullWindow(
FullWindowFirstPart); // will hold all the fragments that are in the
// same window as the fragments in the given
// window, whether their weight should be added
// or not
FullWindow.append(Window.begin(), Window.end());
double FullWindowWeight =
computeWindowPenaltyWeight(FullWindow, Offset, Layout);
assert(FullWindowWeight >= FullWindowFirstPartWeight &&
"More fragments necessarily means bigger weight");
return FullWindowWeight - FullWindowFirstPartWeight;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +0,0 @@
add_llvm_library(LLVMMCDisassembler
Disassembler.cpp
MCDisassembler.cpp
MCExternalSymbolizer.cpp
MCRelocationInfo.cpp
MCSymbolizer.cpp
)

View File

@ -1,342 +0,0 @@
//===-- lib/MC/Disassembler.cpp - Disassembler Public C Interface ---------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "Disassembler.h"
#include "llvm-c/Disassembler.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Triple.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDisassembler/MCDisassembler.h"
#include "llvm/MC/MCDisassembler/MCRelocationInfo.h"
#include "llvm/MC/MCDisassembler/MCSymbolizer.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstPrinter.h"
#include "llvm/MC/MCInstrDesc.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCInstrItineraries.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSchedule.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>
#include <cstddef>
#include <cstring>
using namespace llvm;
// LLVMCreateDisasm() creates a disassembler for the TripleName. Symbolic
// disassembly is supported by passing a block of information in the DisInfo
// parameter and specifying the TagType and callback functions as described in
// the header llvm-c/Disassembler.h . The pointer to the block and the
// functions can all be passed as NULL. If successful, this returns a
// disassembler context. If not, it returns NULL.
//
LLVMDisasmContextRef
LLVMCreateDisasmCPUFeatures(const char *TT, const char *CPU,
const char *Features, void *DisInfo, int TagType,
LLVMOpInfoCallback GetOpInfo,
LLVMSymbolLookupCallback SymbolLookUp) {
// Get the target.
std::string Error;
const Target *TheTarget = TargetRegistry::lookupTarget(TT, Error);
if (!TheTarget)
return nullptr;
const MCRegisterInfo *MRI = TheTarget->createMCRegInfo(TT);
if (!MRI)
return nullptr;
// Get the assembler info needed to setup the MCContext.
const MCAsmInfo *MAI = TheTarget->createMCAsmInfo(*MRI, TT);
if (!MAI)
return nullptr;
const MCInstrInfo *MII = TheTarget->createMCInstrInfo();
if (!MII)
return nullptr;
const MCSubtargetInfo *STI =
TheTarget->createMCSubtargetInfo(TT, CPU, Features);
if (!STI)
return nullptr;
// Set up the MCContext for creating symbols and MCExpr's.
MCContext *Ctx = new MCContext(MAI, MRI, nullptr);
if (!Ctx)
return nullptr;
// Set up disassembler.
MCDisassembler *DisAsm = TheTarget->createMCDisassembler(*STI, *Ctx);
if (!DisAsm)
return nullptr;
std::unique_ptr<MCRelocationInfo> RelInfo(
TheTarget->createMCRelocationInfo(TT, *Ctx));
if (!RelInfo)
return nullptr;
std::unique_ptr<MCSymbolizer> Symbolizer(TheTarget->createMCSymbolizer(
TT, GetOpInfo, SymbolLookUp, DisInfo, Ctx, std::move(RelInfo)));
DisAsm->setSymbolizer(std::move(Symbolizer));
// Set up the instruction printer.
int AsmPrinterVariant = MAI->getAssemblerDialect();
MCInstPrinter *IP = TheTarget->createMCInstPrinter(
Triple(TT), AsmPrinterVariant, *MAI, *MII, *MRI);
if (!IP)
return nullptr;
LLVMDisasmContext *DC =
new LLVMDisasmContext(TT, DisInfo, TagType, GetOpInfo, SymbolLookUp,
TheTarget, MAI, MRI, STI, MII, Ctx, DisAsm, IP);
if (!DC)
return nullptr;
DC->setCPU(CPU);
return DC;
}
LLVMDisasmContextRef
LLVMCreateDisasmCPU(const char *TT, const char *CPU, void *DisInfo, int TagType,
LLVMOpInfoCallback GetOpInfo,
LLVMSymbolLookupCallback SymbolLookUp) {
return LLVMCreateDisasmCPUFeatures(TT, CPU, "", DisInfo, TagType, GetOpInfo,
SymbolLookUp);
}
LLVMDisasmContextRef LLVMCreateDisasm(const char *TT, void *DisInfo,
int TagType, LLVMOpInfoCallback GetOpInfo,
LLVMSymbolLookupCallback SymbolLookUp) {
return LLVMCreateDisasmCPUFeatures(TT, "", "", DisInfo, TagType, GetOpInfo,
SymbolLookUp);
}
//
// LLVMDisasmDispose() disposes of the disassembler specified by the context.
//
void LLVMDisasmDispose(LLVMDisasmContextRef DCR){
LLVMDisasmContext *DC = static_cast<LLVMDisasmContext *>(DCR);
delete DC;
}
/// \brief Emits the comments that are stored in \p DC comment stream.
/// Each comment in the comment stream must end with a newline.
static void emitComments(LLVMDisasmContext *DC,
formatted_raw_ostream &FormattedOS) {
// Flush the stream before taking its content.
StringRef Comments = DC->CommentsToEmit.str();
// Get the default information for printing a comment.
const MCAsmInfo *MAI = DC->getAsmInfo();
StringRef CommentBegin = MAI->getCommentString();
unsigned CommentColumn = MAI->getCommentColumn();
bool IsFirst = true;
while (!Comments.empty()) {
if (!IsFirst)
FormattedOS << '\n';
// Emit a line of comments.
FormattedOS.PadToColumn(CommentColumn);
size_t Position = Comments.find('\n');
FormattedOS << CommentBegin << ' ' << Comments.substr(0, Position);
// Move after the newline character.
Comments = Comments.substr(Position+1);
IsFirst = false;
}
FormattedOS.flush();
// Tell the comment stream that the vector changed underneath it.
DC->CommentsToEmit.clear();
}
/// \brief Gets latency information for \p Inst from the itinerary
/// scheduling model, based on \p DC information.
/// \return The maximum expected latency over all the operands or -1
/// if no information is available.
static int getItineraryLatency(LLVMDisasmContext *DC, const MCInst &Inst) {
const int NoInformationAvailable = -1;
// Check if we have a CPU to get the itinerary information.
if (DC->getCPU().empty())
return NoInformationAvailable;
// Get itinerary information.
const MCSubtargetInfo *STI = DC->getSubtargetInfo();
InstrItineraryData IID = STI->getInstrItineraryForCPU(DC->getCPU());
// Get the scheduling class of the requested instruction.
const MCInstrDesc& Desc = DC->getInstrInfo()->get(Inst.getOpcode());
unsigned SCClass = Desc.getSchedClass();
int Latency = 0;
for (unsigned OpIdx = 0, OpIdxEnd = Inst.getNumOperands(); OpIdx != OpIdxEnd;
++OpIdx)
Latency = std::max(Latency, IID.getOperandCycle(SCClass, OpIdx));
return Latency;
}
/// \brief Gets latency information for \p Inst, based on \p DC information.
/// \return The maximum expected latency over all the definitions or -1
/// if no information is available.
static int getLatency(LLVMDisasmContext *DC, const MCInst &Inst) {
// Try to compute scheduling information.
const MCSubtargetInfo *STI = DC->getSubtargetInfo();
const MCSchedModel SCModel = STI->getSchedModel();
const int NoInformationAvailable = -1;
// Check if we have a scheduling model for instructions.
if (!SCModel.hasInstrSchedModel())
// Try to fall back to the itinerary model if the scheduling model doesn't
// have a scheduling table. Note the default does not have a table.
return getItineraryLatency(DC, Inst);
// Get the scheduling class of the requested instruction.
const MCInstrDesc& Desc = DC->getInstrInfo()->get(Inst.getOpcode());
unsigned SCClass = Desc.getSchedClass();
const MCSchedClassDesc *SCDesc = SCModel.getSchedClassDesc(SCClass);
// Resolving the variant SchedClass requires an MI to pass to
// SubTargetInfo::resolveSchedClass.
if (!SCDesc || !SCDesc->isValid() || SCDesc->isVariant())
return NoInformationAvailable;
// Compute output latency.
int Latency = 0;
for (unsigned DefIdx = 0, DefEnd = SCDesc->NumWriteLatencyEntries;
DefIdx != DefEnd; ++DefIdx) {
// Lookup the definition's write latency in SubtargetInfo.
const MCWriteLatencyEntry *WLEntry = STI->getWriteLatencyEntry(SCDesc,
DefIdx);
Latency = std::max(Latency, WLEntry->Cycles);
}
return Latency;
}
/// \brief Emits latency information in DC->CommentStream for \p Inst, based
/// on the information available in \p DC.
static void emitLatency(LLVMDisasmContext *DC, const MCInst &Inst) {
int Latency = getLatency(DC, Inst);
// Report only interesting latencies.
if (Latency < 2)
return;
DC->CommentStream << "Latency: " << Latency << '\n';
}
//
// LLVMDisasmInstruction() disassembles a single instruction using the
// disassembler context specified in the parameter DC. The bytes of the
// instruction are specified in the parameter Bytes, and contains at least
// BytesSize number of bytes. The instruction is at the address specified by
// the PC parameter. If a valid instruction can be disassembled its string is
// returned indirectly in OutString which whos size is specified in the
// parameter OutStringSize. This function returns the number of bytes in the
// instruction or zero if there was no valid instruction. If this function
// returns zero the caller will have to pick how many bytes they want to step
// over by printing a .byte, .long etc. to continue.
//
size_t LLVMDisasmInstruction(LLVMDisasmContextRef DCR, uint8_t *Bytes,
uint64_t BytesSize, uint64_t PC, char *OutString,
size_t OutStringSize){
LLVMDisasmContext *DC = static_cast<LLVMDisasmContext *>(DCR);
// Wrap the pointer to the Bytes, BytesSize and PC in a MemoryObject.
ArrayRef<uint8_t> Data(Bytes, BytesSize);
uint64_t Size;
MCInst Inst;
const MCDisassembler *DisAsm = DC->getDisAsm();
MCInstPrinter *IP = DC->getIP();
MCDisassembler::DecodeStatus S;
SmallVector<char, 64> InsnStr;
raw_svector_ostream Annotations(InsnStr);
S = DisAsm->getInstruction(Inst, Size, Data, PC,
/*REMOVE*/ nulls(), Annotations);
switch (S) {
case MCDisassembler::Fail:
case MCDisassembler::SoftFail:
// FIXME: Do something different for soft failure modes?
return 0;
case MCDisassembler::Success: {
StringRef AnnotationsStr = Annotations.str();
SmallVector<char, 64> InsnStr;
raw_svector_ostream OS(InsnStr);
formatted_raw_ostream FormattedOS(OS);
IP->printInst(&Inst, FormattedOS, AnnotationsStr, *DC->getSubtargetInfo());
if (DC->getOptions() & LLVMDisassembler_Option_PrintLatency)
emitLatency(DC, Inst);
emitComments(DC, FormattedOS);
assert(OutStringSize != 0 && "Output buffer cannot be zero size");
size_t OutputSize = std::min(OutStringSize-1, InsnStr.size());
std::memcpy(OutString, InsnStr.data(), OutputSize);
OutString[OutputSize] = '\0'; // Terminate string.
return Size;
}
}
llvm_unreachable("Invalid DecodeStatus!");
}
//
// LLVMSetDisasmOptions() sets the disassembler's options. It returns 1 if it
// can set all the Options and 0 otherwise.
//
int LLVMSetDisasmOptions(LLVMDisasmContextRef DCR, uint64_t Options){
if (Options & LLVMDisassembler_Option_UseMarkup){
LLVMDisasmContext *DC = static_cast<LLVMDisasmContext *>(DCR);
MCInstPrinter *IP = DC->getIP();
IP->setUseMarkup(true);
DC->addOptions(LLVMDisassembler_Option_UseMarkup);
Options &= ~LLVMDisassembler_Option_UseMarkup;
}
if (Options & LLVMDisassembler_Option_PrintImmHex){
LLVMDisasmContext *DC = static_cast<LLVMDisasmContext *>(DCR);
MCInstPrinter *IP = DC->getIP();
IP->setPrintImmHex(true);
DC->addOptions(LLVMDisassembler_Option_PrintImmHex);
Options &= ~LLVMDisassembler_Option_PrintImmHex;
}
if (Options & LLVMDisassembler_Option_AsmPrinterVariant){
LLVMDisasmContext *DC = static_cast<LLVMDisasmContext *>(DCR);
// Try to set up the new instruction printer.
const MCAsmInfo *MAI = DC->getAsmInfo();
const MCInstrInfo *MII = DC->getInstrInfo();
const MCRegisterInfo *MRI = DC->getRegisterInfo();
int AsmPrinterVariant = MAI->getAssemblerDialect();
AsmPrinterVariant = AsmPrinterVariant == 0 ? 1 : 0;
MCInstPrinter *IP = DC->getTarget()->createMCInstPrinter(
Triple(DC->getTripleName()), AsmPrinterVariant, *MAI, *MII, *MRI);
if (IP) {
DC->setIP(IP);
DC->addOptions(LLVMDisassembler_Option_AsmPrinterVariant);
Options &= ~LLVMDisassembler_Option_AsmPrinterVariant;
}
}
if (Options & LLVMDisassembler_Option_SetInstrComments) {
LLVMDisasmContext *DC = static_cast<LLVMDisasmContext *>(DCR);
MCInstPrinter *IP = DC->getIP();
IP->setCommentStream(DC->CommentStream);
DC->addOptions(LLVMDisassembler_Option_SetInstrComments);
Options &= ~LLVMDisassembler_Option_SetInstrComments;
}
if (Options & LLVMDisassembler_Option_PrintLatency) {
LLVMDisasmContext *DC = static_cast<LLVMDisasmContext *>(DCR);
DC->addOptions(LLVMDisassembler_Option_PrintLatency);
Options &= ~LLVMDisassembler_Option_PrintLatency;
}
return (Options == 0);
}

View File

@ -1,127 +0,0 @@
//===------------- Disassembler.h - LLVM Disassembler -----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the interface for the Disassembly library's disassembler
// context. The disassembler is responsible for producing strings for
// individual instructions according to a given architecture and disassembly
// syntax.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIB_MC_MCDISASSEMBLER_DISASSEMBLER_H
#define LLVM_LIB_MC_MCDISASSEMBLER_DISASSEMBLER_H
#include "llvm-c/Disassembler.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDisassembler/MCDisassembler.h"
#include "llvm/MC/MCInstPrinter.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Support/raw_ostream.h"
#include <string>
#include <utility>
namespace llvm {
class Target;
//
// This is the disassembler context returned by LLVMCreateDisasm().
//
class LLVMDisasmContext {
private:
//
// The passed parameters when the disassembler context is created.
//
// The TripleName for this disassembler.
std::string TripleName;
// The pointer to the caller's block of symbolic information.
void *DisInfo;
// The Triple specific symbolic information type returned by GetOpInfo.
int TagType;
// The function to get the symbolic information for operands.
LLVMOpInfoCallback GetOpInfo;
// The function to look up a symbol name.
LLVMSymbolLookupCallback SymbolLookUp;
//
// The objects created and saved by LLVMCreateDisasm() then used by
// LLVMDisasmInstruction().
//
// The LLVM target corresponding to the disassembler.
// FIXME: using std::unique_ptr<const llvm::Target> causes a malloc error
// when this LLVMDisasmContext is deleted.
const Target *TheTarget;
// The assembly information for the target architecture.
std::unique_ptr<const llvm::MCAsmInfo> MAI;
// The register information for the target architecture.
std::unique_ptr<const llvm::MCRegisterInfo> MRI;
// The subtarget information for the target architecture.
std::unique_ptr<const llvm::MCSubtargetInfo> MSI;
// The instruction information for the target architecture.
std::unique_ptr<const llvm::MCInstrInfo> MII;
// The assembly context for creating symbols and MCExprs.
std::unique_ptr<const llvm::MCContext> Ctx;
// The disassembler for the target architecture.
std::unique_ptr<const llvm::MCDisassembler> DisAsm;
// The instruction printer for the target architecture.
std::unique_ptr<llvm::MCInstPrinter> IP;
// The options used to set up the disassembler.
uint64_t Options;
// The CPU string.
std::string CPU;
public:
// Comment stream and backing vector.
SmallString<128> CommentsToEmit;
raw_svector_ostream CommentStream;
LLVMDisasmContext(std::string tripleName, void *disInfo, int tagType,
LLVMOpInfoCallback getOpInfo,
LLVMSymbolLookupCallback symbolLookUp,
const Target *theTarget, const MCAsmInfo *mAI,
const MCRegisterInfo *mRI, const MCSubtargetInfo *mSI,
const MCInstrInfo *mII, llvm::MCContext *ctx,
const MCDisassembler *disAsm, MCInstPrinter *iP)
: TripleName(std::move(tripleName)), DisInfo(disInfo), TagType(tagType),
GetOpInfo(getOpInfo), SymbolLookUp(symbolLookUp), TheTarget(theTarget),
Options(0), CommentStream(CommentsToEmit) {
MAI.reset(mAI);
MRI.reset(mRI);
MSI.reset(mSI);
MII.reset(mII);
Ctx.reset(ctx);
DisAsm.reset(disAsm);
IP.reset(iP);
}
const std::string &getTripleName() const { return TripleName; }
void *getDisInfo() const { return DisInfo; }
int getTagType() const { return TagType; }
LLVMOpInfoCallback getGetOpInfo() const { return GetOpInfo; }
LLVMSymbolLookupCallback getSymbolLookupCallback() const {
return SymbolLookUp;
}
const Target *getTarget() const { return TheTarget; }
const MCDisassembler *getDisAsm() const { return DisAsm.get(); }
const MCAsmInfo *getAsmInfo() const { return MAI.get(); }
const MCInstrInfo *getInstrInfo() const { return MII.get(); }
const MCRegisterInfo *getRegisterInfo() const { return MRI.get(); }
const MCSubtargetInfo *getSubtargetInfo() const { return MSI.get(); }
MCInstPrinter *getIP() { return IP.get(); }
void setIP(MCInstPrinter *NewIP) { IP.reset(NewIP); }
uint64_t getOptions() const { return Options; }
void addOptions(uint64_t Options) { this->Options |= Options; }
StringRef getCPU() const { return CPU; }
void setCPU(const char *CPU) { this->CPU = CPU; }
};
} // namespace llvm
#endif

View File

@ -1,22 +0,0 @@
;===- ./lib/MC/MCDisassembler/LLVMBuild.txt --------------------*- Conf -*--===;
;
; The LLVM Compiler Infrastructure
;
; This file is distributed under the University of Illinois Open Source
; License. See LICENSE.TXT for details.
;
;===------------------------------------------------------------------------===;
;
; This is an LLVMBuild description file for the components in this subdirectory.
;
; For more information on the LLVMBuild system, please see:
;
; http://llvm.org/docs/LLVMBuild.html
;
;===------------------------------------------------------------------------===;
[component_0]
type = Library
name = MCDisassembler
parent = MC
required_libraries = MC Support

Some files were not shown because too many files have changed in this diff Show More