//
//===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "asm-printer"
#include "llvm/CodeGen/AsmPrinter.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/Twine.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/Target/TargetSubtargetInfo.h"
using namespace llvm;
+#define DEBUG_TYPE "asm-printer"
+
namespace {
struct SrcMgrDiagInfo {
const MDNode *LocInfo;
if (isNullTerminated)
Str = Str.substr(0, Str.size()-1);
- // If the output streamer is actually a .s file, just emit the blob textually.
+ // If the output streamer does not have mature MC support or the integrated
+ // assembler has been disabled, just emit the blob textually.
+ // Otherwise parse the asm and emit it via MC support.
// This is useful in case the asm parser doesn't handle something but the
// system assembler does.
- if (OutStreamer.hasRawTextSupport()) {
+ const MCAsmInfo *MCAI = TM.getMCAsmInfo();
+ assert(MCAI && "No MCAsmInfo");
+ if (!MCAI->useIntegratedAssembler() &&
+ !OutStreamer.isIntegratedAssemblerRequired()) {
OutStreamer.EmitRawText(Str);
- OutStreamer.EmitInlineAsmEnd(TM.getSubtarget<MCSubtargetInfo>(), 0);
+ emitInlineAsmEnd(TM.getSubtarget<MCSubtargetInfo>(), nullptr);
return;
}
// If the current LLVMContext has an inline asm handler, set it in SourceMgr.
LLVMContext &LLVMCtx = MMI->getModule()->getContext();
bool HasDiagHandler = false;
- if (LLVMCtx.getInlineAsmDiagnosticHandler() != 0) {
+ if (LLVMCtx.getInlineAsmDiagnosticHandler() != nullptr) {
// If the source manager has an issue, we arrange for srcMgrDiagHandler
// to be invoked, getting DiagInfo passed into it.
DiagInfo.LocInfo = LocMDNode;
// Tell SrcMgr about this buffer, it takes ownership of the buffer.
SrcMgr.AddNewSourceBuffer(Buffer, SMLoc());
- OwningPtr<MCAsmParser> Parser(createMCAsmParser(SrcMgr,
- OutContext, OutStreamer,
- *MAI));
-
- // Reuse the existing Subtarget, because the AsmParser may need to
- // modify it. For example, when switching between ARM and
- // Thumb mode.
- MCSubtargetInfo* STI =
- const_cast<MCSubtargetInfo*>(&TM.getSubtarget<MCSubtargetInfo>());
-
- // Preserve a copy of the original STI because the parser may modify it.
- // The target can restore the original state in EmitInlineAsmEnd().
+ 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
+ // emitInlineAsmEnd().
MCSubtargetInfo STIOrig = *STI;
- OwningPtr<MCTargetAsmParser>
- TAP(TM.getTarget().createMCAsmParser(*STI, *Parser, *MII));
+ MCTargetOptions MCOptions;
+ if (MF)
+ MCOptions = MF->getTarget().Options.MCOptions;
+ std::unique_ptr<MCTargetAsmParser> TAP(
+ TM.getTarget().createMCAsmParser(*STI, *Parser, *MII, 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");
// Don't implicitly switch to the text section before the asm.
int Res = Parser->Run(/*NoInitialTextSection*/ true,
/*NoFinalize*/ true);
- OutStreamer.EmitInlineAsmEnd(STIOrig, STI);
+ emitInlineAsmEnd(STIOrig, STI.get());
if (Res && !HasDiagHandler)
report_fatal_error("Error parsing inline asm\n");
}
if (InlineAsm::isMemKind(OpFlags)) {
Error = AP->PrintAsmMemoryOperand(MI, OpNo, InlineAsmVariant,
- /*Modifier*/ 0, OS);
+ /*Modifier*/ nullptr, OS);
} else {
Error = AP->PrintAsmOperand(MI, OpNo, InlineAsmVariant,
- /*Modifier*/ 0, OS);
+ /*Modifier*/ nullptr, OS);
}
}
if (Error) {
++LastEmitted;
const char *StrStart = LastEmitted;
const char *StrEnd = strchr(StrStart, '}');
- if (StrEnd == 0)
+ if (!StrEnd)
report_fatal_error("Unterminated ${:foo} operand in inline asm"
" string: '" + Twine(AsmStr) + "'");
else {
if (InlineAsm::isMemKind(OpFlags)) {
Error = AP->PrintAsmMemoryOperand(MI, OpNo, InlineAsmVariant,
- Modifier[0] ? Modifier : 0,
+ Modifier[0] ? Modifier : nullptr,
OS);
} else {
Error = AP->PrintAsmOperand(MI, OpNo, InlineAsmVariant,
- Modifier[0] ? Modifier : 0, OS);
+ Modifier[0] ? Modifier : nullptr, OS);
}
}
}
// Get the !srcloc metadata node if we have it, and decode the loc cookie from
// it.
unsigned LocCookie = 0;
- const MDNode *LocMD = 0;
+ const MDNode *LocMD = nullptr;
for (unsigned i = MI->getNumOperands(); i != 0; --i) {
if (MI->getOperand(i-1).isMetadata() &&
(LocMD = MI->getOperand(i-1).getMetadata()) &&
return true;
}
+void AsmPrinter::emitInlineAsmEnd(const MCSubtargetInfo &StartInfo,
+ const MCSubtargetInfo *EndInfo) const {}