X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FAsmPrinter%2FAsmPrinterInlineAsm.cpp;h=567b6e3b18e32c8efc9770e439a5b4d01d865d3e;hb=667376028fc44bbcd861e6a70ff0e04b29f177d1;hp=6a21efe1f257ef2b6dd782f9018f06aec2a0d08a;hpb=04de315694d441de4dbdf52b3ff41b2fe6803646;p=oota-llvm.git diff --git a/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp b/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp index 6a21efe1f25..567b6e3b18e 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp @@ -13,32 +13,33 @@ #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/MachineModuleInfo.h" -#include "llvm/Constants.h" -#include "llvm/InlineAsm.h" -#include "llvm/LLVMContext.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/DataLayout.h" +#include "llvm/IR/InlineAsm.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/IR/Module.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/MC/MCSymbol.h" #include "llvm/MC/MCTargetAsmParser.h" -#include "llvm/Module.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/SourceMgr.h" #include "llvm/Support/TargetRegistry.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetSubtargetInfo.h" using namespace llvm; namespace { struct SrcMgrDiagInfo { const MDNode *LocInfo; - LLVMContext::DiagHandlerTy DiagHandler; + LLVMContext::InlineAsmDiagHandlerTy DiagHandler; void *DiagContext; }; } @@ -77,26 +78,32 @@ void AsmPrinter::EmitInlineAsm(StringRef Str, const MDNode *LocMDNode, 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); + emitInlineAsmEnd(TM.getSubtarget(), 0); return; } SourceMgr SrcMgr; SrcMgrDiagInfo DiagInfo; - // If the current LLVMContext has a diagnostic handler, set it in SourceMgr. + // If the current LLVMContext has an inline asm handler, set it in SourceMgr. LLVMContext &LLVMCtx = MMI->getModule()->getContext(); bool HasDiagHandler = false; - if (LLVMCtx.getDiagnosticHandler() != 0) { + if (LLVMCtx.getInlineAsmDiagnosticHandler() != 0) { // If the source manager has an issue, we arrange for srcMgrDiagHandler // to be invoked, getting DiagInfo passed into it. DiagInfo.LocInfo = LocMDNode; - DiagInfo.DiagHandler = LLVMCtx.getDiagnosticHandler(); - DiagInfo.DiagContext = LLVMCtx.getDiagnosticContext(); + DiagInfo.DiagHandler = LLVMCtx.getInlineAsmDiagnosticHandler(); + DiagInfo.DiagContext = LLVMCtx.getInlineAsmDiagnosticContext(); SrcMgr.setDiagHandler(srcMgrDiagHandler, &DiagInfo); HasDiagHandler = true; } @@ -110,20 +117,25 @@ void AsmPrinter::EmitInlineAsm(StringRef Str, const MDNode *LocMDNode, // Tell SrcMgr about this buffer, it takes ownership of the buffer. SrcMgr.AddNewSourceBuffer(Buffer, SMLoc()); - OwningPtr Parser(createMCAsmParser(SrcMgr, - OutContext, OutStreamer, - *MAI)); - - // FIXME: It would be nice if we can avoid createing a new instance of - // MCSubtargetInfo here given TargetSubtargetInfo is available. However, - // we have to watch out for asm directives which can change subtarget - // state. e.g. .code 16, .code 32. - OwningPtr - STI(TM.getTarget().createMCSubtargetInfo(TM.getTargetTriple(), - TM.getTargetCPU(), - TM.getTargetFeatureString())); - OwningPtr - TAP(TM.getTarget().createMCAsmParser(*STI, *Parser)); + std::unique_ptr 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 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; + + std::unique_ptr TAP( + TM.getTarget().createMCAsmParser(*STI, *Parser, *MII)); if (!TAP) report_fatal_error("Inline asm not supported by this streamer because" " we don't have an asm parser for this target\n"); @@ -133,6 +145,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()); if (Res && !HasDiagHandler) report_fatal_error("Error parsing inline asm\n"); } @@ -213,7 +226,7 @@ static void EmitMSInlineAsmStr(const char *AsmStr, const MachineInstr *MI, } else { unsigned OpFlags = MI->getOperand(OpNo).getImm(); ++OpNo; // Skip over the ID number. - + if (InlineAsm::isMemKind(OpFlags)) { Error = AP->PrintAsmMemoryOperand(MI, OpNo, InlineAsmVariant, /*Modifier*/ 0, OS); @@ -427,21 +440,14 @@ void AsmPrinter::EmitInlineAsm(const MachineInstr *MI) const { // If this asmstr is empty, just print the #APP/#NOAPP markers. // These are useful to see where empty asm's wound up. if (AsmStr[0] == 0) { - // Don't emit the comments if writing to a .o file. - if (!OutStreamer.hasRawTextSupport()) return; - - OutStreamer.EmitRawText(Twine("\t")+MAI->getCommentString()+ - MAI->getInlineAsmStart()); - OutStreamer.EmitRawText(Twine("\t")+MAI->getCommentString()+ - MAI->getInlineAsmEnd()); + OutStreamer.emitRawComment(MAI->getInlineAsmStart()); + OutStreamer.emitRawComment(MAI->getInlineAsmEnd()); return; } // Emit the #APP start marker. This has to happen even if verbose-asm isn't - // enabled, so we use EmitRawText. - if (OutStreamer.hasRawTextSupport()) - OutStreamer.EmitRawText(Twine("\t")+MAI->getCommentString()+ - MAI->getInlineAsmStart()); + // enabled, so we use emitRawComment. + OutStreamer.emitRawComment(MAI->getInlineAsmStart()); // Get the !srcloc metadata node if we have it, and decode the loc cookie from // it. @@ -476,10 +482,8 @@ void AsmPrinter::EmitInlineAsm(const MachineInstr *MI) const { EmitInlineAsm(OS.str(), LocMD, MI->getInlineAsmDialect()); // Emit the #NOAPP end marker. This has to happen even if verbose-asm isn't - // enabled, so we use EmitRawText. - if (OutStreamer.hasRawTextSupport()) - OutStreamer.EmitRawText(Twine("\t")+MAI->getCommentString()+ - MAI->getInlineAsmEnd()); + // enabled, so we use emitRawComment. + OutStreamer.emitRawComment(MAI->getInlineAsmEnd()); } @@ -491,8 +495,9 @@ void AsmPrinter::EmitInlineAsm(const MachineInstr *MI) const { /// for their own strange codes. void AsmPrinter::PrintSpecial(const MachineInstr *MI, raw_ostream &OS, const char *Code) const { + const DataLayout *DL = TM.getDataLayout(); if (!strcmp(Code, "private")) { - OS << MAI->getPrivateGlobalPrefix(); + OS << DL->getPrivateGlobalPrefix(); } else if (!strcmp(Code, "comment")) { OS << MAI->getCommentString(); } else if (!strcmp(Code, "uid")) { @@ -551,3 +556,5 @@ bool AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, return true; } +void AsmPrinter::emitInlineAsmEnd(const MCSubtargetInfo &StartInfo, + const MCSubtargetInfo *EndInfo) const {}