mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 19:52:54 +01:00
[AsmPrinter] Use the per-function subtarget to emit inline asm instructions that
are not at the file level. Previously, the default subtarget created from the target triple was used to emit inline asm instructions. Compilation would fail in cases where the feature bits necessary to assemble an inline asm instruction in a function weren't set. llvm-svn: 232392
This commit is contained in:
parent
356f802585
commit
5581d69ed8
@ -504,7 +504,8 @@ private:
|
||||
|
||||
/// Emit a blob of inline asm to the output streamer.
|
||||
void
|
||||
EmitInlineAsm(StringRef Str, const MDNode *LocMDNode = nullptr,
|
||||
EmitInlineAsm(StringRef Str, const MCSubtargetInfo &STI,
|
||||
const MDNode *LocMDNode = nullptr,
|
||||
InlineAsm::AsmDialect AsmDialect = InlineAsm::AD_ATT) const;
|
||||
|
||||
/// This method formats and emits the specified machine instruction that is an
|
||||
|
@ -221,9 +221,13 @@ bool AsmPrinter::doInitialization(Module &M) {
|
||||
|
||||
// Emit module-level inline asm if it exists.
|
||||
if (!M.getModuleInlineAsm().empty()) {
|
||||
// We're at the module level. Construct MCSubtarget from the default CPU
|
||||
// and target triple.
|
||||
std::unique_ptr<MCSubtargetInfo> STI(TM.getTarget().createMCSubtargetInfo(
|
||||
TM.getTargetTriple(), TM.getTargetCPU(), TM.getTargetFeatureString()));
|
||||
OutStreamer.AddComment("Start of file scope inline assembly");
|
||||
OutStreamer.AddBlankLine();
|
||||
EmitInlineAsm(M.getModuleInlineAsm()+"\n");
|
||||
EmitInlineAsm(M.getModuleInlineAsm()+"\n", *STI);
|
||||
OutStreamer.AddComment("End of file scope inline assembly");
|
||||
OutStreamer.AddBlankLine();
|
||||
}
|
||||
|
@ -73,7 +73,8 @@ static void srcMgrDiagHandler(const SMDiagnostic &Diag, void *diagInfo) {
|
||||
}
|
||||
|
||||
/// EmitInlineAsm - Emit a blob of inline asm to the output streamer.
|
||||
void AsmPrinter::EmitInlineAsm(StringRef Str, const MDNode *LocMDNode,
|
||||
void AsmPrinter::EmitInlineAsm(StringRef Str, const MCSubtargetInfo &STI,
|
||||
const MDNode *LocMDNode,
|
||||
InlineAsm::AsmDialect Dialect) const {
|
||||
assert(!Str.empty() && "Can't emit empty inline asm block");
|
||||
|
||||
@ -93,17 +94,7 @@ void AsmPrinter::EmitInlineAsm(StringRef Str, const MDNode *LocMDNode,
|
||||
!OutStreamer.isIntegratedAssemblerRequired()) {
|
||||
emitInlineAsmStart();
|
||||
OutStreamer.EmitRawText(Str);
|
||||
// If we have a machine function then grab the MCSubtarget off of that,
|
||||
// otherwise we're at the module level and want to construct one from
|
||||
// the default CPU and target triple.
|
||||
if (MF) {
|
||||
emitInlineAsmEnd(MF->getSubtarget<MCSubtargetInfo>(), nullptr);
|
||||
} else {
|
||||
std::unique_ptr<MCSubtargetInfo> STI(TM.getTarget().createMCSubtargetInfo(
|
||||
TM.getTargetTriple(), TM.getTargetCPU(),
|
||||
TM.getTargetFeatureString()));
|
||||
emitInlineAsmEnd(*STI, nullptr);
|
||||
}
|
||||
emitInlineAsmEnd(STI, nullptr);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -135,19 +126,11 @@ void AsmPrinter::EmitInlineAsm(StringRef Str, const MDNode *LocMDNode,
|
||||
std::unique_ptr<MCAsmParser> Parser(
|
||||
createMCAsmParser(SrcMgr, OutContext, OutStreamer, *MAI));
|
||||
|
||||
// Initialize the parser with a fresh subtarget info. It is better to use a
|
||||
// new STI here because the parser may modify it and we do not want those
|
||||
// modifications to persist after parsing the inlineasm. The modifications
|
||||
// made by the parser will be seen by the code emitters because it passes
|
||||
// the current STI down to the EncodeInstruction() method.
|
||||
std::unique_ptr<MCSubtargetInfo> STI(TM.getTarget().createMCSubtargetInfo(
|
||||
TM.getTargetTriple(), TM.getTargetCPU(), TM.getTargetFeatureString()));
|
||||
|
||||
// Preserve a copy of the original STI because the parser may modify it. For
|
||||
// example, when switching between arm and thumb mode. If the target needs to
|
||||
// emit code to return to the original state it can do so in
|
||||
// Create a temporary copy of the original STI because the parser may modify
|
||||
// it. For example, when switching between arm and thumb mode. If the target
|
||||
// needs to emit code to return to the original state it can do so in
|
||||
// emitInlineAsmEnd().
|
||||
MCSubtargetInfo STIOrig = *STI;
|
||||
MCSubtargetInfo TmpSTI = STI;
|
||||
|
||||
// We create a new MCInstrInfo here since we might be at the module level
|
||||
// and not have a MachineFunction to initialize the TargetInstrInfo from and
|
||||
@ -155,7 +138,7 @@ void AsmPrinter::EmitInlineAsm(StringRef Str, const MDNode *LocMDNode,
|
||||
// because it's not subtarget dependent.
|
||||
std::unique_ptr<MCInstrInfo> MII(TM.getTarget().createMCInstrInfo());
|
||||
std::unique_ptr<MCTargetAsmParser> TAP(TM.getTarget().createMCAsmParser(
|
||||
*STI, *Parser, *MII, TM.Options.MCOptions));
|
||||
TmpSTI, *Parser, *MII, TM.Options.MCOptions));
|
||||
if (!TAP)
|
||||
report_fatal_error("Inline asm not supported by this streamer because"
|
||||
" we don't have an asm parser for this target\n");
|
||||
@ -170,7 +153,7 @@ void AsmPrinter::EmitInlineAsm(StringRef Str, const MDNode *LocMDNode,
|
||||
// Don't implicitly switch to the text section before the asm.
|
||||
int Res = Parser->Run(/*NoInitialTextSection*/ true,
|
||||
/*NoFinalize*/ true);
|
||||
emitInlineAsmEnd(STIOrig, STI.get());
|
||||
emitInlineAsmEnd(STI, &TmpSTI);
|
||||
if (Res && !HasDiagHandler)
|
||||
report_fatal_error("Error parsing inline asm\n");
|
||||
}
|
||||
@ -505,7 +488,7 @@ void AsmPrinter::EmitInlineAsm(const MachineInstr *MI) const {
|
||||
else
|
||||
EmitMSInlineAsmStr(AsmStr, MI, MMI, InlineAsmVariant, AP, LocCookie, OS);
|
||||
|
||||
EmitInlineAsm(OS.str(), LocMD, MI->getInlineAsmDialect());
|
||||
EmitInlineAsm(OS.str(), getSubtargetInfo(), LocMD, MI->getInlineAsmDialect());
|
||||
|
||||
// Emit the #NOAPP end marker. This has to happen even if verbose-asm isn't
|
||||
// enabled, so we use emitRawComment.
|
||||
|
Loading…
Reference in New Issue
Block a user