T, Ctx, std::move(MAB), std::move(OW), std::move(CE), *STI,
Opts.RelaxAll, Opts.IncrementalLinkerCompatible,
/*DWARFMustBeAtTheEnd*/ true));
- Str.get()->InitSections(Opts.NoExecStack);
+ Str.get()->initSections(Opts.NoExecStack, *STI);
}
// When -fembed-bitcode is passed to clang_as, a 1-byte marker
/// \name MCStreamer Interface
/// @{
- void InitSections(bool NoExecStack) override;
+ void initSections(bool NoExecStack, const MCSubtargetInfo &STI) override;
void changeSection(MCSection *Section, const MCExpr *Subsection) override;
void emitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override;
void emitLabelAtPos(MCSymbol *Symbol, SMLoc Loc, MCFragment *F,
/// cannot be satisfied in this width then this fragment is ignored.
unsigned MaxBytesToEmit;
+ /// When emitting Nops some subtargets have specific nop encodings.
+ const MCSubtargetInfo *STI;
+
public:
MCAlignFragment(unsigned Alignment, int64_t Value, unsigned ValueSize,
unsigned MaxBytesToEmit, MCSection *Sec = nullptr)
unsigned getMaxBytesToEmit() const { return MaxBytesToEmit; }
bool hasEmitNops() const { return EmitNops; }
- void setEmitNops(bool Value) { EmitNops = Value; }
+ void setEmitNops(bool Value, const MCSubtargetInfo *STI) {
+ EmitNops = Value;
+ this->STI = STI;
+ }
+
+ const MCSubtargetInfo *getSubtargetInfo() const { return STI; }
static bool classof(const MCFragment *F) {
return F->getKind() == MCFragment::FT_Align;
void emitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
unsigned ValueSize = 1,
unsigned MaxBytesToEmit = 0) override;
- void emitCodeAlignment(unsigned ByteAlignment,
+ void emitCodeAlignment(unsigned ByteAlignment, const MCSubtargetInfo *STI,
unsigned MaxBytesToEmit = 0) override;
void emitValueToOffset(const MCExpr *Offset, unsigned char Value,
SMLoc Loc) override;
}
/// Create the default sections and set the initial one.
- virtual void InitSections(bool NoExecStack);
+ virtual void initSections(bool NoExecStack, const MCSubtargetInfo &STI);
MCSymbol *endSection(MCSection *Section);
///
/// \param ByteAlignment - The alignment to reach. This must be a power of
/// two on some targets.
+ /// \param STI - The MCSubtargetInfo in operation when padding is emitted.
/// \param MaxBytesToEmit - The maximum numbers of bytes to emit, or 0. If
/// the alignment cannot be reached in this many bytes, no bytes are
/// emitted.
virtual void emitCodeAlignment(unsigned ByteAlignment,
+ const MCSubtargetInfo *STI,
unsigned MaxBytesToEmit = 0);
/// Emit some number of copies of \p Value until the byte offset \p
/// \name MCStreamer interface
/// \{
- void InitSections(bool NoExecStack) override;
+ void initSections(bool NoExecStack, const MCSubtargetInfo &STI) override;
void emitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override;
void emitAssemblerFlag(MCAssemblerFlag Flag) override;
void emitThumbFunc(MCSymbol *Func) override;
const_cast<TargetLoweringObjectFile &>(getObjFileLowering())
.getModuleMetadata(M);
- OutStreamer->InitSections(false);
+ OutStreamer->initSections(false, *TM.getMCSubtargetInfo());
if (DisableDebugInfoPrinting)
MMI->setDebugInfoAvailability(false);
if (Alignment == Align(1))
return; // 1-byte aligned: no need to emit alignment.
- if (getCurrentSection()->getKind().isText())
- OutStreamer->emitCodeAlignment(Alignment.value());
- else
+ if (getCurrentSection()->getKind().isText()) {
+ const MCSubtargetInfo *STI = nullptr;
+ if (this->MF)
+ STI = &getSubtargetInfo();
+ else
+ STI = TM.getMCSubtargetInfo();
+ OutStreamer->emitCodeAlignment(Alignment.value(), STI);
+ } else
OutStreamer->emitValueToAlignment(Alignment.value());
}
// pointers. This should work for both 32-bit and 64-bit platforms.
if (FnSledIndex) {
OutStreamer->SwitchSection(FnSledIndex);
- OutStreamer->emitCodeAlignment(2 * WordSizeBytes);
+ OutStreamer->emitCodeAlignment(2 * WordSizeBytes, &getSubtargetInfo());
OutStreamer->emitSymbolValue(SledsStart, WordSizeBytes, false);
OutStreamer->emitSymbolValue(SledsEnd, WordSizeBytes, false);
OutStreamer->SwitchSection(PrevSection);
return;
Streamer.emitDataRegion(MCDR_DataRegion);
for (const ConstantPoolEntry &Entry : Entries) {
- Streamer.emitCodeAlignment(Entry.Size); // align naturally
+ Streamer.emitValueToAlignment(Entry.Size); // align naturally
Streamer.emitLabel(Entry.Label);
Streamer.emitValue(Entry.Value, Entry.Size, Entry.Loc);
}
unsigned ValueSize = 1,
unsigned MaxBytesToEmit = 0) override;
- void emitCodeAlignment(unsigned ByteAlignment,
+ void emitCodeAlignment(unsigned ByteAlignment, const MCSubtargetInfo *STI,
unsigned MaxBytesToEmit = 0) override;
void emitValueToOffset(const MCExpr *Offset,
}
void MCAsmStreamer::emitCodeAlignment(unsigned ByteAlignment,
+ const MCSubtargetInfo *STI,
unsigned MaxBytesToEmit) {
// Emit with a text fill value.
emitValueToAlignment(ByteAlignment, MAI->getTextAlignFillValue(),
DF->getContents().append(EF->getContents().begin(), EF->getContents().end());
}
-void MCELFStreamer::InitSections(bool NoExecStack) {
+void MCELFStreamer::initSections(bool NoExecStack, const MCSubtargetInfo &STI) {
MCContext &Ctx = getContext();
SwitchSection(Ctx.getObjectFileInfo()->getTextSection());
- emitCodeAlignment(Ctx.getObjectFileInfo()->getTextSectionAlignment());
+ emitCodeAlignment(Ctx.getObjectFileInfo()->getTextSectionAlignment(), &STI);
if (NoExecStack)
SwitchSection(Ctx.getAsmInfo()->getNonexecutableStackSection(Ctx));
}
void MCObjectStreamer::emitCodeAlignment(unsigned ByteAlignment,
+ const MCSubtargetInfo *STI,
unsigned MaxBytesToEmit) {
emitValueToAlignment(ByteAlignment, 0, 1, MaxBytesToEmit);
- cast<MCAlignFragment>(getCurrentFragment())->setEmitNops(true);
+ cast<MCAlignFragment>(getCurrentFragment())->setEmitNops(true, STI);
}
void MCObjectStreamer::emitValueToOffset(const MCExpr *Offset,
// Create the initial section, if requested.
if (!NoInitialTextSection)
- Out.InitSections(false);
+ Out.initSections(false, getTargetParser().getSTI());
// Prime the lexer.
Lex();
bool AsmParser::checkForValidSection() {
if (!ParsingMSInlineAsm && !getStreamer().getCurrentSectionOnly()) {
- Out.InitSections(false);
+ Out.initSections(false, getTargetParser().getSTI());
return Error(getTok().getLoc(),
"expected section directive before assembly directive");
}
bool UseCodeAlign = Section->UseCodeAlign();
if ((!HasFillExpr || Lexer.getMAI().getTextAlignFillValue() == FillExpr) &&
ValueSize == 1 && UseCodeAlign) {
- getStreamer().emitCodeAlignment(Alignment, MaxBytesToFill);
+ getStreamer().emitCodeAlignment(Alignment, &getTargetParser().getSTI(),
+ MaxBytesToFill);
} else {
// FIXME: Target specific behavior about how the "extra" bytes are filled.
getStreamer().emitValueToAlignment(Alignment, FillExpr, ValueSize,
bool MasmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
// Create the initial section, if requested.
if (!NoInitialTextSection)
- Out.InitSections(false);
+ Out.initSections(false, getTargetParser().getSTI());
// Prime the lexer.
Lex();
bool MasmParser::checkForValidSection() {
if (!ParsingMSInlineAsm && !getStreamer().getCurrentSectionOnly()) {
- Out.InitSections(false);
+ Out.initSections(false, getTargetParser().getSTI());
return Error(getTok().getLoc(),
"expected section directive before assembly directive");
}
MCSymbol *EHSymbol) {
}
-void MCStreamer::InitSections(bool NoExecStack) {
+void MCStreamer::initSections(bool NoExecStack, const MCSubtargetInfo &STI) {
SwitchSection(getContext().getObjectFileInfo()->getTextSection());
}
unsigned ValueSize,
unsigned MaxBytesToEmit) {}
void MCStreamer::emitCodeAlignment(unsigned ByteAlignment,
+ const MCSubtargetInfo *STI,
unsigned MaxBytesToEmit) {}
void MCStreamer::emitValueToOffset(const MCExpr *Offset, unsigned char Value,
SMLoc Loc) {}
DF->getContents().append(Code.begin(), Code.end());
}
-void MCWinCOFFStreamer::InitSections(bool NoExecStack) {
+void MCWinCOFFStreamer::initSections(bool NoExecStack,
+ const MCSubtargetInfo &STI) {
// FIXME: this is identical to the ELF one.
// This emulates the same behavior of GNU as. This makes it easier
// to compare the output as the major sections are in the same order.
SwitchSection(getContext().getObjectFileInfo()->getTextSection());
- emitCodeAlignment(4);
+ emitCodeAlignment(4, &STI);
SwitchSection(getContext().getObjectFileInfo()->getDataSection());
- emitCodeAlignment(4);
+ emitCodeAlignment(4, &STI);
SwitchSection(getContext().getObjectFileInfo()->getBSSSection());
- emitCodeAlignment(4);
+ emitCodeAlignment(4, &STI);
SwitchSection(getContext().getObjectFileInfo()->getTextSection());
}
// ;DATA: higher 32 bits of the address of the trampoline
// LDP X0, X30, [SP], #16 ; pop X0 and the link register from the stack
//
- OutStreamer->emitCodeAlignment(4);
+ OutStreamer->emitCodeAlignment(4, &getSubtargetInfo());
auto CurSled = OutContext.createTempSymbol("xray_sled_", true);
OutStreamer->emitLabel(CurSled);
auto Target = OutContext.createTempSymbol();
// FIXME: Ideally we could vary the LDRB index based on the padding
// between the sequence and jump table, however that relies on MCExprs
// for load indexes which are currently not supported.
- OutStreamer->emitCodeAlignment(4);
+ OutStreamer->emitCodeAlignment(4, &getSubtargetInfo());
EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::tADDhirr)
.addReg(Idx)
.addReg(Idx)
// BLX ip
// POP{ r0, lr }
//
- OutStreamer->emitCodeAlignment(4);
+ OutStreamer->emitCodeAlignment(4, &getSubtargetInfo());
auto CurSled = OutContext.createTempSymbol("xray_sled_", true);
OutStreamer->emitLabel(CurSled);
auto Target = OutContext.createTempSymbol();
return true;
if (!Section) {
- getStreamer().InitSections(false);
+ getStreamer().initSections(false, getSTI());
Section = getStreamer().getCurrentSectionOnly();
}
assert(Section && "must have section to emit alignment");
if (Section->UseCodeAlign())
- getStreamer().emitCodeAlignment(2);
+ getStreamer().emitCodeAlignment(2, &getSTI());
else
getStreamer().emitValueToAlignment(2);
const MCSection *Section = getStreamer().getCurrentSectionOnly();
assert(Section && "must have section to emit alignment");
if (Section->UseCodeAlign())
- getStreamer().emitCodeAlignment(4, 0);
+ getStreamer().emitCodeAlignment(4, &getSTI(), 0);
else
getStreamer().emitValueToAlignment(4, 0, 1, 0);
return false;
// Switch to .ARM.extab or .ARM.exidx section
SwitchSection(EHSection);
- emitCodeAlignment(4);
+ emitValueToAlignment(4, 0, 1, 0);
}
inline void ARMELFStreamer::SwitchToExTabSection(const MCSymbol &FnStart) {
MES->SwitchSection(mySection);
unsigned byteSize = is32bit ? 4 : 8;
- getStreamer().emitCodeAlignment(byteSize, byteSize);
+ getStreamer().emitCodeAlignment(byteSize, &getSTI(), byteSize);
MCSymbol *Sym;
static MCSymbol *smallData(AsmPrinter &AP, const MachineInstr &MI,
MCStreamer &OutStreamer, const MCOperand &Imm,
- int AlignSize) {
+ int AlignSize, const MCSubtargetInfo& STI) {
MCSymbol *Sym;
int64_t Value;
if (Imm.getExpr()->evaluateAsAbsolute(Value)) {
OutStreamer.emitLabel(Sym);
OutStreamer.emitSymbolAttribute(Sym, MCSA_Global);
OutStreamer.emitIntValue(Value, AlignSize);
- OutStreamer.emitCodeAlignment(AlignSize);
+ OutStreamer.emitCodeAlignment(AlignSize, &STI);
}
} else {
assert(Imm.isExpr() && "Expected expression and found none");
OutStreamer.emitLabel(Sym);
OutStreamer.emitSymbolAttribute(Sym, MCSA_Local);
OutStreamer.emitValue(Imm.getExpr(), AlignSize);
- OutStreamer.emitCodeAlignment(AlignSize);
+ OutStreamer.emitCodeAlignment(AlignSize, &STI);
}
}
return Sym;
const MCOperand &Imm = MappedInst.getOperand(1);
MCSectionSubPair Current = OutStreamer->getCurrentSection();
- MCSymbol *Sym = smallData(*this, MI, *OutStreamer, Imm, 8);
+ MCSymbol *Sym =
+ smallData(*this, MI, *OutStreamer, Imm, 8, getSubtargetInfo());
OutStreamer->SwitchSection(Current.first, Current.second);
MCInst TmpInst;
if (!OutStreamer->hasRawTextSupport()) {
MCOperand &Imm = MappedInst.getOperand(1);
MCSectionSubPair Current = OutStreamer->getCurrentSection();
- MCSymbol *Sym = smallData(*this, MI, *OutStreamer, Imm, 4);
+ MCSymbol *Sym =
+ smallData(*this, MI, *OutStreamer, Imm, 4, getSubtargetInfo());
OutStreamer->SwitchSection(Current.first, Current.second);
MCInst TmpInst;
MCOperand &Reg = MappedInst.getOperand(0);
public:
HexagonTargetStreamer(MCStreamer &S) : MCTargetStreamer(S) {}
virtual void emitCodeAlignment(unsigned ByteAlignment,
+ const MCSubtargetInfo *STI,
unsigned MaxBytesToEmit = 0){};
virtual void emitFAlign(unsigned Size, unsigned MaxBytesToEmit){};
virtual void emitCommonSymbolSorted(MCSymbol *Symbol, uint64_t Size,
if (Alignment) {
OS.SwitchSection(&Section);
if (Section.UseCodeAlign())
- OS.emitCodeAlignment(Alignment, Alignment);
+ OS.emitCodeAlignment(Alignment, &STI, Alignment);
else
OS.emitValueToAlignment(Alignment, 0, 1, Alignment);
}
// LD RA, 8(SP)
// DADDIU SP, SP, 16
//
- OutStreamer->emitCodeAlignment(4);
+ OutStreamer->emitCodeAlignment(4, &getSubtargetInfo());
auto CurSled = OutContext.createTempSymbol("xray_sled_", true);
OutStreamer->emitLabel(CurSled);
auto Target = OutContext.createTempSymbol();
// all of the nops required as part of the alignment operation. In the cases
// when no nops are added then The fragment is still created but it remains
// empty.
- emitCodeAlignment(64, 4);
+ emitCodeAlignment(64, &STI, 4);
// Emit the instruction.
// Since the previous emit created a new fragment then adding this instruction
// prefixed instruction. Align to 64 bytes if possible but add a maximum of 4
// bytes when trying to do that. If alignment requires adding more than 4
// bytes then the instruction won't be aligned.
- emitCodeAlignment(64, 4);
+ emitCodeAlignment(64, &STI, 4);
// Emit the instruction.
// Since the previous emit created a new fragment then adding this instruction
//
// Update compiler-rt/lib/xray/xray_powerpc64.cc accordingly when number
// of instructions change.
- OutStreamer->emitCodeAlignment(8);
+ OutStreamer->emitCodeAlignment(8, &getSubtargetInfo());
MCSymbol *BeginOfSled = OutContext.createTempSymbol();
OutStreamer->emitLabel(BeginOfSled);
EmitToStreamer(*OutStreamer, RetInst);
const MCSection *Section = getStreamer().getCurrentSectionOnly();
if (!Section) {
- getStreamer().InitSections(false);
+ getStreamer().initSections(false, getSTI());
Section = getStreamer().getCurrentSectionOnly();
}
if (Section->UseCodeAlign())
- getStreamer().emitCodeAlignment(2, 0);
+ getStreamer().emitCodeAlignment(2, &getSTI(), 0);
else
getStreamer().emitValueToAlignment(2, 0, 1, 0);
return false;
// First we emit the label and the jump.
auto CurSled = OutContext.createTempSymbol("xray_event_sled_", true);
OutStreamer->AddComment("# XRay Custom Event Log");
- OutStreamer->emitCodeAlignment(2);
+ OutStreamer->emitCodeAlignment(2, &getSubtargetInfo());
OutStreamer->emitLabel(CurSled);
// Use a two-byte `jmp`. This version of JMP takes an 8-bit relative offset as
// First we emit the label and the jump.
auto CurSled = OutContext.createTempSymbol("xray_typed_event_sled_", true);
OutStreamer->AddComment("# XRay Typed Event Log");
- OutStreamer->emitCodeAlignment(2);
+ OutStreamer->emitCodeAlignment(2, &getSubtargetInfo());
OutStreamer->emitLabel(CurSled);
// Use a two-byte `jmp`. This version of JMP takes an 8-bit relative offset as
// call <relative offset, 32-bits> // 5 bytes
//
auto CurSled = OutContext.createTempSymbol("xray_sled_", true);
- OutStreamer->emitCodeAlignment(2);
+ OutStreamer->emitCodeAlignment(2, &getSubtargetInfo());
OutStreamer->emitLabel(CurSled);
// Use a two-byte `jmp`. This version of JMP takes an 8-bit relative offset as
//
// This just makes sure that the alignment for the next instruction is 2.
auto CurSled = OutContext.createTempSymbol("xray_sled_", true);
- OutStreamer->emitCodeAlignment(2);
+ OutStreamer->emitCodeAlignment(2, &getSubtargetInfo());
OutStreamer->emitLabel(CurSled);
unsigned OpCode = MI.getOperand(0).getImm();
MCInst Ret;
// the PATCHABLE_FUNCTION_ENTER case, followed by the lowering of the actual
// tail call much like how we have it in PATCHABLE_RET.
auto CurSled = OutContext.createTempSymbol("xray_sled_", true);
- OutStreamer->emitCodeAlignment(2);
+ OutStreamer->emitCodeAlignment(2, &getSubtargetInfo());
OutStreamer->emitLabel(CurSled);
auto Target = OutContext.createTempSymbol();
}
// Set up initial section manually here
- Streamer.InitSections(false);
+ Streamer.initSections(false, STI);
bool ErrorOccurred = false;
MCOptions.MCIncrementalLinkerCompatible,
/*DWARFMustBeAtTheEnd*/ false));
if (NoExecStack)
- Str->InitSections(true);
+ Str->initSections(true, *STI);
}
// Use Assembler information for parsing.
}
// Set up initial section manually here
- Streamer.InitSections(false);
+ Streamer.initSections(false, STI);
bool ErrorOccurred = false;
SmallString<0> Storage;
raw_svector_ostream VecOS(Storage);
StreamerContext C = createStreamer(VecOS);
- C.Streamer->InitSections(false);
+ C.Streamer->initSections(false, *STI);
MCSection *Section = C.MOFI->getTextSection();
Section->setHasInstructions(true);
C.Streamer->SwitchSection(Section);