#include "MCTargetDesc/X86BaseInfo.h"
#include "MCTargetDesc/X86EncodingOptimization.h"
#include "MCTargetDesc/X86FixupKinds.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/BinaryFormat/MachO.h"
#include "llvm/MC/MCAsmBackend.h"
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDwarf.h"
#include "llvm/MC/MCELFObjectWriter.h"
#include "llvm/MC/MCELFStreamer.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCFixupKindInfo.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCMachObjectWriter.h"
#include "llvm/MC/MCObjectStreamer.h"
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSectionMachO.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/MCValue.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
usingnamespacellvm;
namespace {
class X86AlignBranchKind { … };
X86AlignBranchKind X86AlignBranchKindLoc;
cl::opt<unsigned> X86AlignBranchBoundary(
"x86-align-branch-boundary", cl::init(0),
cl::desc(
"Control how the assembler should align branches with NOP. If the "
"boundary's size is not 0, it should be a power of 2 and no less "
"than 32. Branches will be aligned to prevent from being across or "
"against the boundary of specified size. The default value 0 does not "
"align branches."));
cl::opt<X86AlignBranchKind, true, cl::parser<std::string>> X86AlignBranch(
"x86-align-branch",
cl::desc(
"Specify types of branches to align (plus separated list of types):"
"\njcc indicates conditional jumps"
"\nfused indicates fused conditional jumps"
"\njmp indicates direct unconditional jumps"
"\ncall indicates direct and indirect calls"
"\nret indicates rets"
"\nindirect indicates indirect unconditional jumps"),
cl::location(X86AlignBranchKindLoc));
cl::opt<bool> X86AlignBranchWithin32BBoundaries(
"x86-branches-within-32B-boundaries", cl::init(false),
cl::desc(
"Align selected instructions to mitigate negative performance impact "
"of Intel's micro code update for errata skx102. May break "
"assumptions about labels corresponding to particular instructions, "
"and should be used with caution."));
cl::opt<unsigned> X86PadMaxPrefixSize(
"x86-pad-max-prefix-size", cl::init(0),
cl::desc("Maximum number of prefixes to use for padding"));
cl::opt<bool> X86PadForAlign(
"x86-pad-for-align", cl::init(false), cl::Hidden,
cl::desc("Pad previous instructions to implement align directives"));
cl::opt<bool> X86PadForBranchAlign(
"x86-pad-for-branch-align", cl::init(true), cl::Hidden,
cl::desc("Pad previous instructions to implement branch alignment"));
class X86AsmBackend : public MCAsmBackend { … };
}
static bool isRelaxableBranch(unsigned Opcode) { … }
static unsigned getRelaxedOpcodeBranch(unsigned Opcode,
bool Is16BitMode = false) { … }
static unsigned getRelaxedOpcode(const MCInst &MI, bool Is16BitMode) { … }
static X86::CondCode getCondFromBranch(const MCInst &MI,
const MCInstrInfo &MCII) { … }
static X86::SecondMacroFusionInstKind
classifySecondInstInMacroFusion(const MCInst &MI, const MCInstrInfo &MCII) { … }
static bool isRIPRelative(const MCInst &MI, const MCInstrInfo &MCII) { … }
static bool isPrefix(unsigned Opcode, const MCInstrInfo &MCII) { … }
static bool isFirstMacroFusibleInst(const MCInst &Inst,
const MCInstrInfo &MCII) { … }
uint8_t X86AsmBackend::determinePaddingPrefix(const MCInst &Inst) const { … }
bool X86AsmBackend::isMacroFused(const MCInst &Cmp, const MCInst &Jcc) const { … }
static bool hasVariantSymbol(const MCInst &MI) { … }
bool X86AsmBackend::allowAutoPadding() const { … }
bool X86AsmBackend::allowEnhancedRelaxation() const { … }
static bool mayHaveInterruptDelaySlot(unsigned InstOpcode) { … }
static bool
isRightAfterData(MCFragment *CurrentFragment,
const std::pair<MCFragment *, size_t> &PrevInstPosition) { … }
static size_t getSizeForInstFragment(const MCFragment *F) { … }
bool X86AsmBackend::canPadInst(const MCInst &Inst, MCObjectStreamer &OS) const { … }
bool X86AsmBackend::canPadBranches(MCObjectStreamer &OS) const { … }
bool X86AsmBackend::needAlign(const MCInst &Inst) const { … }
void X86AsmBackend::emitInstructionBegin(MCObjectStreamer &OS,
const MCInst &Inst, const MCSubtargetInfo &STI) { … }
void X86AsmBackend::emitInstructionEnd(MCObjectStreamer &OS,
const MCInst &Inst) { … }
std::optional<MCFixupKind> X86AsmBackend::getFixupKind(StringRef Name) const { … }
const MCFixupKindInfo &X86AsmBackend::getFixupKindInfo(MCFixupKind Kind) const { … }
bool X86AsmBackend::shouldForceRelocation(const MCAssembler &,
const MCFixup &Fixup, const MCValue &,
const MCSubtargetInfo *STI) { … }
static unsigned getFixupKindSize(unsigned Kind) { … }
void X86AsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
const MCValue &Target,
MutableArrayRef<char> Data,
uint64_t Value, bool IsResolved,
const MCSubtargetInfo *STI) const { … }
bool X86AsmBackend::mayNeedRelaxation(const MCInst &MI,
const MCSubtargetInfo &STI) const { … }
bool X86AsmBackend::fixupNeedsRelaxation(const MCFixup &Fixup,
uint64_t Value) const { … }
void X86AsmBackend::relaxInstruction(MCInst &Inst,
const MCSubtargetInfo &STI) const { … }
bool X86AsmBackend::padInstructionViaPrefix(MCRelaxableFragment &RF,
MCCodeEmitter &Emitter,
unsigned &RemainingSize) const { … }
bool X86AsmBackend::padInstructionViaRelaxation(MCRelaxableFragment &RF,
MCCodeEmitter &Emitter,
unsigned &RemainingSize) const { … }
bool X86AsmBackend::padInstructionEncoding(MCRelaxableFragment &RF,
MCCodeEmitter &Emitter,
unsigned &RemainingSize) const { … }
void X86AsmBackend::finishLayout(MCAssembler const &Asm) const { … }
unsigned X86AsmBackend::getMaximumNopSize(const MCSubtargetInfo &STI) const { … }
bool X86AsmBackend::writeNopData(raw_ostream &OS, uint64_t Count,
const MCSubtargetInfo *STI) const { … }
namespace {
class ELFX86AsmBackend : public X86AsmBackend { … };
class ELFX86_32AsmBackend : public ELFX86AsmBackend { … };
class ELFX86_X32AsmBackend : public ELFX86AsmBackend { … };
class ELFX86_IAMCUAsmBackend : public ELFX86AsmBackend { … };
class ELFX86_64AsmBackend : public ELFX86AsmBackend { … };
class WindowsX86AsmBackend : public X86AsmBackend { … };
namespace CU {
enum CompactUnwindEncodings { … };
}
class DarwinX86AsmBackend : public X86AsmBackend { … };
}
MCAsmBackend *llvm::createX86_32AsmBackend(const Target &T,
const MCSubtargetInfo &STI,
const MCRegisterInfo &MRI,
const MCTargetOptions &Options) { … }
MCAsmBackend *llvm::createX86_64AsmBackend(const Target &T,
const MCSubtargetInfo &STI,
const MCRegisterInfo &MRI,
const MCTargetOptions &Options) { … }
namespace {
class X86ELFStreamer : public MCELFStreamer { … };
}
void X86_MC::emitInstruction(MCObjectStreamer &S, const MCInst &Inst,
const MCSubtargetInfo &STI) { … }
void X86ELFStreamer::emitInstruction(const MCInst &Inst,
const MCSubtargetInfo &STI) { … }
MCStreamer *llvm::createX86ELFStreamer(const Triple &T, MCContext &Context,
std::unique_ptr<MCAsmBackend> &&MAB,
std::unique_ptr<MCObjectWriter> &&MOW,
std::unique_ptr<MCCodeEmitter> &&MCE) { … }