summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorrdivacky <rdivacky@FreeBSD.org>2010-04-06 15:52:58 +0000
committerrdivacky <rdivacky@FreeBSD.org>2010-04-06 15:52:58 +0000
commit5f970ec96e421f64db6b1c6509a902ea73d98cc7 (patch)
tree0dd020f28a4846707f8d60717d9b2921ea187bd8 /lib
parent62cc576dca6a6aa62c0424f0a1e93a0a679d4c8a (diff)
downloadFreeBSD-src-5f970ec96e421f64db6b1c6509a902ea73d98cc7.zip
FreeBSD-src-5f970ec96e421f64db6b1c6509a902ea73d98cc7.tar.gz
Update LLVM to r100520.
Diffstat (limited to 'lib')
-rw-r--r--lib/Analysis/IVUsers.cpp2
-rw-r--r--lib/AsmParser/Parser.cpp4
-rw-r--r--lib/CodeGen/AsmPrinter/AsmPrinter.cpp547
-rw-r--r--lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp279
-rw-r--r--lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp357
-rw-r--r--lib/CodeGen/AsmPrinter/CMakeLists.txt4
-rw-r--r--lib/CodeGen/AsmPrinter/DIE.cpp78
-rw-r--r--lib/CodeGen/AsmPrinter/DIE.h34
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfDebug.cpp532
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfDebug.h127
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfException.cpp218
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfException.h32
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfPrinter.cpp308
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfPrinter.h131
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfWriter.cpp87
-rw-r--r--lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp82
-rw-r--r--lib/CodeGen/GCMetadataPrinter.cpp6
-rw-r--r--lib/CodeGen/LLVMTargetMachine.cpp19
-rw-r--r--lib/CodeGen/MachineFunction.cpp5
-rw-r--r--lib/CodeGen/MachineFunctionAnalysis.cpp20
-rw-r--r--lib/CodeGen/MachineModuleInfo.cpp1
-rw-r--r--lib/CodeGen/MachineSink.cpp5
-rw-r--r--lib/CodeGen/PrologEpilogInserter.cpp6
-rw-r--r--lib/CodeGen/SelectionDAG/FastISel.cpp74
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeDAG.cpp1
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAG.cpp73
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp117
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h1
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp21
-rw-r--r--lib/ExecutionEngine/JIT/JITEmitter.cpp3
-rw-r--r--lib/ExecutionEngine/JIT/OProfileJITEventListener.cpp13
-rw-r--r--lib/MC/MCAsmInfo.cpp2
-rw-r--r--lib/MC/MCAsmInfoCOFF.cpp2
-rw-r--r--lib/MC/MCAsmStreamer.cpp21
-rw-r--r--lib/MC/MCParser/AsmParser.cpp6
-rw-r--r--lib/MC/MCStreamer.cpp18
-rw-r--r--lib/Support/MemoryBuffer.cpp19
-rw-r--r--lib/Support/SourceMgr.cpp10
-rw-r--r--lib/Support/regengine.inc91
-rw-r--r--lib/Support/regexec.c4
-rw-r--r--lib/Target/ARM/ARM.td18
-rw-r--r--lib/Target/ARM/ARMISelLowering.cpp9
-rw-r--r--lib/Target/ARM/ARMISelLowering.h2
-rw-r--r--lib/Target/ARM/ARMInstrFormats.td25
-rw-r--r--lib/Target/ARM/ARMMCAsmInfo.cpp1
-rw-r--r--lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp458
-rw-r--r--lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp157
-rw-r--r--lib/Target/ARM/AsmPrinter/ARMInstPrinter.h123
-rw-r--r--lib/Target/ARM/Disassembler/ARMDisassembler.cpp28
-rw-r--r--lib/Target/ARM/Disassembler/Makefile16
-rw-r--r--lib/Target/ARM/Makefile5
-rw-r--r--lib/Target/Alpha/Alpha.td6
-rw-r--r--lib/Target/Alpha/AsmPrinter/AlphaAsmPrinter.cpp64
-rw-r--r--lib/Target/Blackfin/AsmPrinter/BlackfinAsmPrinter.cpp53
-rw-r--r--lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp125
-rw-r--r--lib/Target/CellSPU/SPURegisterInfo.cpp12
-rw-r--r--lib/Target/MBlaze/AsmPrinter/MBlazeAsmPrinter.cpp192
-rw-r--r--lib/Target/MBlaze/MBlaze.td6
-rw-r--r--lib/Target/MSP430/AsmPrinter/MSP430AsmPrinter.cpp65
-rw-r--r--lib/Target/MSP430/AsmPrinter/MSP430InstPrinter.cpp13
-rw-r--r--lib/Target/MSP430/AsmPrinter/MSP430InstPrinter.h19
-rw-r--r--lib/Target/MSP430/MSP430.td9
-rw-r--r--lib/Target/MSP430/MSP430InstrFormats.td8
-rw-r--r--lib/Target/Mips/AsmPrinter/MipsAsmPrinter.cpp138
-rw-r--r--lib/Target/Mips/Mips.td5
-rw-r--r--lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.cpp121
-rw-r--r--lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.h9
-rw-r--r--lib/Target/PIC16/PIC16DebugInfo.cpp45
-rw-r--r--lib/Target/PIC16/PIC16DebugInfo.h9
-rw-r--r--lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp299
-rw-r--r--lib/Target/PowerPC/PPC.td8
-rw-r--r--lib/Target/PowerPC/PPCISelLowering.cpp2
-rw-r--r--lib/Target/PowerPC/PPCInstrFormats.td11
-rw-r--r--lib/Target/PowerPC/PPCMCAsmInfo.cpp2
-rw-r--r--lib/Target/PowerPC/PPCRegisterInfo.cpp10
-rw-r--r--lib/Target/Sparc/AsmPrinter/SparcAsmPrinter.cpp66
-rw-r--r--lib/Target/Sparc/Sparc.td6
-rw-r--r--lib/Target/Sparc/SparcMCAsmInfo.cpp1
-rw-r--r--lib/Target/SystemZ/AsmPrinter/SystemZAsmPrinter.cpp71
-rw-r--r--lib/Target/X86/AsmPrinter/X86ATTInstPrinter.cpp30
-rw-r--r--lib/Target/X86/AsmPrinter/X86ATTInstPrinter.h69
-rw-r--r--lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp120
-rw-r--r--lib/Target/X86/AsmPrinter/X86AsmPrinter.h80
-rw-r--r--lib/Target/X86/AsmPrinter/X86IntelInstPrinter.cpp30
-rw-r--r--lib/Target/X86/AsmPrinter/X86IntelInstPrinter.h71
-rw-r--r--lib/Target/X86/AsmPrinter/X86MCInstLower.cpp120
-rw-r--r--lib/Target/X86/SSEDomainFix.cpp225
-rw-r--r--lib/Target/X86/X86.td28
-rw-r--r--lib/Target/X86/X86FastISel.cpp8
-rw-r--r--lib/Target/X86/X86ISelLowering.cpp19
-rw-r--r--lib/Target/X86/X86ISelLowering.h7
-rw-r--r--lib/Target/X86/X86InstrFormats.td16
-rw-r--r--lib/Target/X86/X86InstrInfo.cpp4
-rw-r--r--lib/Target/X86/X86InstrInfo.td2
-rw-r--r--lib/Target/X86/X86MCAsmInfo.cpp1
-rw-r--r--lib/Target/X86/X86RegisterInfo.cpp35
-rw-r--r--lib/Target/XCore/AsmPrinter/XCoreAsmPrinter.cpp173
-rw-r--r--lib/Target/XCore/XCore.td5
-rw-r--r--lib/Target/XCore/XCoreISelLowering.cpp2
-rw-r--r--lib/Target/XCore/XCoreInstrInfo.cpp11
-rw-r--r--lib/Target/XCore/XCoreMCAsmInfo.cpp1
-rw-r--r--lib/Target/XCore/XCoreRegisterInfo.cpp10
-rw-r--r--lib/Transforms/InstCombine/InstCombineCalls.cpp32
-rw-r--r--lib/Transforms/Scalar/LoopUnswitch.cpp141
-rw-r--r--lib/Transforms/Scalar/MemCpyOptimizer.cpp55
-rw-r--r--lib/Transforms/Scalar/SCCP.cpp61
-rw-r--r--lib/Transforms/Scalar/ScalarReplAggregates.cpp32
-rw-r--r--lib/Transforms/Scalar/SimplifyLibCalls.cpp29
-rw-r--r--lib/Transforms/Utils/BasicBlockUtils.cpp22
-rw-r--r--lib/Transforms/Utils/BuildLibCalls.cpp43
-rw-r--r--lib/Transforms/Utils/InlineFunction.cpp11
-rw-r--r--lib/VMCore/AutoUpgrade.cpp70
-rw-r--r--lib/VMCore/LLVMContext.cpp19
-rw-r--r--lib/VMCore/LLVMContextImpl.cpp3
-rw-r--r--lib/VMCore/LLVMContextImpl.h2
-rw-r--r--lib/VMCore/Pass.cpp20
116 files changed, 3667 insertions, 3517 deletions
diff --git a/lib/Analysis/IVUsers.cpp b/lib/Analysis/IVUsers.cpp
index 98a436f..47b5d4a 100644
--- a/lib/Analysis/IVUsers.cpp
+++ b/lib/Analysis/IVUsers.cpp
@@ -142,7 +142,7 @@ static bool getSCEVStartAndStride(const SCEV *&SH, Loop *L, Loop *UseLoop,
/// the loop, resulting in reg-reg copies (if we use the pre-inc value when we
/// should use the post-inc value).
static bool IVUseShouldUsePostIncValue(Instruction *User, Instruction *IV,
- Loop *L, DominatorTree *DT) {
+ const Loop *L, DominatorTree *DT) {
// If the user is in the loop, use the preinc value.
if (L->contains(User)) return false;
diff --git a/lib/AsmParser/Parser.cpp b/lib/AsmParser/Parser.cpp
index aac4027..7280cf4 100644
--- a/lib/AsmParser/Parser.cpp
+++ b/lib/AsmParser/Parser.cpp
@@ -44,7 +44,7 @@ Module *llvm::ParseAssemblyFile(const std::string &Filename, SMDiagnostic &Err,
std::string ErrorStr;
MemoryBuffer *F = MemoryBuffer::getFileOrSTDIN(Filename.c_str(), &ErrorStr);
if (F == 0) {
- Err = SMDiagnostic("", -1, -1,
+ Err = SMDiagnostic(SMLoc(), "", -1, -1,
"Could not open input file '" + Filename + "': " +
ErrorStr, "");
return 0;
@@ -56,7 +56,7 @@ Module *llvm::ParseAssemblyFile(const std::string &Filename, SMDiagnostic &Err,
Module *llvm::ParseAssemblyString(const char *AsmString, Module *M,
SMDiagnostic &Err, LLVMContext &Context) {
MemoryBuffer *F =
- MemoryBuffer::getMemBuffer(AsmString, AsmString+strlen(AsmString),
+ MemoryBuffer::getMemBuffer(StringRef(AsmString, strlen(AsmString)),
"<string>");
return ParseAssembly(F, M, Err, Context);
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 625a2b9..c86e241 100644
--- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -13,11 +13,9 @@
#define DEBUG_TYPE "asm-printer"
#include "llvm/CodeGen/AsmPrinter.h"
-#include "llvm/Assembly/Writer.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/Constants.h"
+#include "DwarfDebug.h"
+#include "DwarfException.h"
#include "llvm/Module.h"
-#include "llvm/CodeGen/DwarfWriter.h"
#include "llvm/CodeGen/GCMetadataPrinter.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
@@ -27,50 +25,59 @@
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/Analysis/DebugInfo.h"
+#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
-#include "llvm/MC/MCAsmInfo.h"
#include "llvm/Target/Mangler.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetLowering.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
-#include "llvm/Target/TargetOptions.h"
#include "llvm/Target/TargetRegisterInfo.h"
-#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/Statistic.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Format.h"
-#include "llvm/Support/FormattedStream.h"
-#include <cerrno>
using namespace llvm;
STATISTIC(EmittedInsts, "Number of machine instrs printed");
char AsmPrinter::ID = 0;
-AsmPrinter::AsmPrinter(formatted_raw_ostream &o, TargetMachine &tm,
- MCStreamer &Streamer)
- : MachineFunctionPass(&ID), O(o),
- TM(tm), MAI(tm.getMCAsmInfo()), TRI(tm.getRegisterInfo()),
+typedef DenseMap<GCStrategy*,GCMetadataPrinter*> gcp_map_type;
+static gcp_map_type &getGCMap(void *&P) {
+ if (P == 0)
+ P = new gcp_map_type();
+ return *(gcp_map_type*)P;
+}
+
+
+AsmPrinter::AsmPrinter(TargetMachine &tm, MCStreamer &Streamer)
+ : MachineFunctionPass(&ID),
+ TM(tm), MAI(tm.getMCAsmInfo()),
OutContext(Streamer.getContext()),
OutStreamer(Streamer),
LastMI(0), LastFn(0), Counter(~0U), SetCounter(0) {
- DW = 0; MMI = 0;
+ DD = 0; DE = 0; MMI = 0; LI = 0;
+ GCMetadataPrinters = 0;
VerboseAsm = Streamer.isVerboseAsm();
}
AsmPrinter::~AsmPrinter() {
- for (gcp_iterator I = GCMetadataPrinters.begin(),
- E = GCMetadataPrinters.end(); I != E; ++I)
- delete I->second;
+ assert(DD == 0 && DE == 0 && "Debug/EH info didn't get finalized");
+
+ if (GCMetadataPrinters != 0) {
+ gcp_map_type &GCMap = getGCMap(GCMetadataPrinters);
+
+ for (gcp_map_type::iterator I = GCMap.begin(), E = GCMap.end(); I != E; ++I)
+ delete I->second;
+ delete &GCMap;
+ GCMetadataPrinters = 0;
+ }
delete &OutStreamer;
}
@@ -85,18 +92,25 @@ TargetLoweringObjectFile &AsmPrinter::getObjFileLowering() const {
return TM.getTargetLowering()->getObjFileLowering();
}
+
+/// getTargetData - Return information about data layout.
+const TargetData &AsmPrinter::getTargetData() const {
+ return *TM.getTargetData();
+}
+
/// getCurrentSection() - Return the current section we are emitting to.
const MCSection *AsmPrinter::getCurrentSection() const {
return OutStreamer.getCurrentSection();
}
+
void AsmPrinter::getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
MachineFunctionPass::getAnalysisUsage(AU);
AU.addRequired<MachineModuleInfo>();
AU.addRequired<GCModuleInfo>();
- if (VerboseAsm)
+ if (isVerbose())
AU.addRequired<MachineLoopInfo>();
}
@@ -124,17 +138,22 @@ bool AsmPrinter::doInitialization(Module &M) {
assert(MI && "AsmPrinter didn't require GCModuleInfo?");
for (GCModuleInfo::iterator I = MI->begin(), E = MI->end(); I != E; ++I)
if (GCMetadataPrinter *MP = GetOrCreateGCPrinter(*I))
- MP->beginAssembly(O, *this, *MAI);
-
- if (!M.getModuleInlineAsm().empty())
- O << MAI->getCommentString() << " Start of file scope inline assembly\n"
- << M.getModuleInlineAsm()
- << '\n' << MAI->getCommentString()
- << " End of file scope inline assembly\n";
+ MP->beginAssembly(*this);
- DW = getAnalysisIfAvailable<DwarfWriter>();
- if (DW)
- DW->BeginModule(&M, MMI, O, this, MAI);
+ // Emit module-level inline asm if it exists.
+ if (!M.getModuleInlineAsm().empty()) {
+ OutStreamer.AddComment("Start of file scope inline assembly");
+ OutStreamer.AddBlankLine();
+ EmitInlineAsm(M.getModuleInlineAsm(), 0/*no loc cookie*/);
+ OutStreamer.AddComment("End of file scope inline assembly");
+ OutStreamer.AddBlankLine();
+ }
+
+ if (MAI->doesSupportDebugInformation())
+ DD = new DwarfDebug(this, &M);
+
+ if (MAI->doesSupportExceptionHandling())
+ DE = new DwarfException(this);
return false;
}
@@ -161,7 +180,7 @@ void AsmPrinter::EmitLinkage(unsigned Linkage, MCSymbol *GVSym) const {
// .linkonce discard
// FIXME: It would be nice to use .linkonce samesize for non-common
// globals.
- O << LinkOnce;
+ OutStreamer.EmitRawText(StringRef(LinkOnce));
} else {
// .weak _foo
OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Weak);
@@ -210,7 +229,7 @@ void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
if (GVKind.isCommon() || GVKind.isBSSLocal()) {
if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
- if (VerboseAsm) {
+ if (isVerbose()) {
WriteAsOperand(OutStreamer.GetCommentOS(), GV,
/*PrintType=*/false, GV->getParent());
OutStreamer.GetCommentOS() << '\n';
@@ -263,7 +282,7 @@ void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
EmitLinkage(GV->getLinkage(), GVSym);
EmitAlignment(AlignLog, GV);
- if (VerboseAsm) {
+ if (isVerbose()) {
WriteAsOperand(OutStreamer.GetCommentOS(), GV,
/*PrintType=*/false, GV->getParent());
OutStreamer.GetCommentOS() << '\n';
@@ -297,7 +316,7 @@ void AsmPrinter::EmitFunctionHeader() {
if (MAI->hasDotTypeDotSizeDirective())
OutStreamer.EmitSymbolAttribute(CurrentFnSym, MCSA_ELF_TypeFunction);
- if (VerboseAsm) {
+ if (isVerbose()) {
WriteAsOperand(OutStreamer.GetCommentOS(), F,
/*PrintType=*/false, F->getParent());
OutStreamer.GetCommentOS() << '\n';
@@ -319,13 +338,17 @@ void AsmPrinter::EmitFunctionHeader() {
// Add some workaround for linkonce linkage on Cygwin\MinGW.
if (MAI->getLinkOnceDirective() != 0 &&
- (F->hasLinkOnceLinkage() || F->hasWeakLinkage()))
+ (F->hasLinkOnceLinkage() || F->hasWeakLinkage())) {
// FIXME: What is this?
- O << "Lllvm$workaround$fake$stub$" << *CurrentFnSym << ":\n";
+ MCSymbol *FakeStub =
+ OutContext.GetOrCreateSymbol(Twine("Lllvm$workaround$fake$stub$")+
+ CurrentFnSym->getName());
+ OutStreamer.EmitLabel(FakeStub);
+ }
// Emit pre-function debug and/or EH information.
- if (MAI->doesSupportDebugInformation() || MAI->doesSupportExceptionHandling())
- DW->BeginFunction(MF);
+ if (DE) DE->BeginFunction(MF);
+ if (DD) DD->beginFunction(MF);
}
/// EmitFunctionEntryLabel - Emit the label that is the entrypoint for the
@@ -389,6 +412,28 @@ static void EmitComments(const MachineInstr &MI, raw_ostream &CommentOS) {
}
}
+/// EmitImplicitDef - This method emits the specified machine instruction
+/// that is an implicit def.
+static void EmitImplicitDef(const MachineInstr *MI, AsmPrinter &AP) {
+ unsigned RegNo = MI->getOperand(0).getReg();
+ AP.OutStreamer.AddComment(Twine("implicit-def: ") +
+ AP.TM.getRegisterInfo()->getName(RegNo));
+ AP.OutStreamer.AddBlankLine();
+}
+
+static void EmitKill(const MachineInstr *MI, AsmPrinter &AP) {
+ std::string Str = "kill:";
+ for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
+ const MachineOperand &Op = MI->getOperand(i);
+ assert(Op.isReg() && "KILL instruction must have only register operands");
+ Str += ' ';
+ Str += AP.TM.getRegisterInfo()->getName(Op.getReg());
+ Str += (Op.isDef() ? "<def>" : "<kill>");
+ }
+ AP.OutStreamer.AddComment(Str);
+ AP.OutStreamer.AddBlankLine();
+}
+
/// EmitFunctionBody - This method emits the body and trailer for a
@@ -397,6 +442,8 @@ void AsmPrinter::EmitFunctionBody() {
// Emit target-specific gunk before the function body.
EmitFunctionBodyStart();
+ bool ShouldPrintDebugScopes = DD && MMI->hasDebugInfo();
+
// Print out code for the function.
bool HasAnyRealCode = false;
for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
@@ -411,34 +458,34 @@ void AsmPrinter::EmitFunctionBody() {
++EmittedInsts;
- // FIXME: Clean up processDebugLoc.
- processDebugLoc(II, true);
+ if (ShouldPrintDebugScopes)
+ DD->beginScope(II);
- if (VerboseAsm)
+ if (isVerbose())
EmitComments(*II, OutStreamer.GetCommentOS());
switch (II->getOpcode()) {
case TargetOpcode::DBG_LABEL:
case TargetOpcode::EH_LABEL:
case TargetOpcode::GC_LABEL:
- printLabelInst(II);
+ OutStreamer.EmitLabel(II->getOperand(0).getMCSymbol());
break;
case TargetOpcode::INLINEASM:
- printInlineAsm(II);
+ EmitInlineAsm(II);
break;
case TargetOpcode::IMPLICIT_DEF:
- printImplicitDef(II);
+ if (isVerbose()) EmitImplicitDef(II, *this);
break;
case TargetOpcode::KILL:
- printKill(II);
+ if (isVerbose()) EmitKill(II, *this);
break;
default:
EmitInstruction(II);
break;
}
- // FIXME: Clean up processDebugLoc.
- processDebugLoc(II, false);
+ if (ShouldPrintDebugScopes)
+ DD->endScope(II);
}
}
@@ -451,12 +498,25 @@ void AsmPrinter::EmitFunctionBody() {
// Emit target-specific gunk after the function body.
EmitFunctionBodyEnd();
- if (MAI->hasDotTypeDotSizeDirective())
- O << "\t.size\t" << *CurrentFnSym << ", .-" << *CurrentFnSym << '\n';
+ // If the target wants a .size directive for the size of the function, emit
+ // it.
+ if (MAI->hasDotTypeDotSizeDirective()) {
+ // Create a symbol for the end of function, so we can get the size as
+ // difference between the function label and the temp label.
+ MCSymbol *FnEndLabel = OutContext.CreateTempSymbol();
+ OutStreamer.EmitLabel(FnEndLabel);
+
+ const MCExpr *SizeExp =
+ MCBinaryExpr::CreateSub(MCSymbolRefExpr::Create(FnEndLabel, OutContext),
+ MCSymbolRefExpr::Create(CurrentFnSym, OutContext),
+ OutContext);
+ OutStreamer.EmitELFSize(CurrentFnSym, SizeExp);
+ }
// Emit post-function debug information.
- if (MAI->doesSupportDebugInformation() || MAI->doesSupportExceptionHandling())
- DW->EndFunction(MF);
+ if (DD) DD->endFunction(MF);
+ if (DE) DE->EndFunction();
+ MMI->EndFunction();
// Print out jump tables referenced by the function.
EmitJumpTableInfo();
@@ -471,9 +531,15 @@ bool AsmPrinter::doFinalization(Module &M) {
I != E; ++I)
EmitGlobalVariable(I);
- // Emit final debug information.
- if (MAI->doesSupportDebugInformation() || MAI->doesSupportExceptionHandling())
- DW->EndModule();
+ // Finalize debug and EH information.
+ if (DE) {
+ DE->EndModule();
+ delete DE; DE = 0;
+ }
+ if (DD) {
+ DD->endModule();
+ delete DD; DD = 0;
+ }
// If the target wants to know about weak references, print them all.
if (MAI->getWeakRefDirective()) {
@@ -523,7 +589,7 @@ bool AsmPrinter::doFinalization(Module &M) {
assert(MI && "AsmPrinter didn't require GCModuleInfo?");
for (GCModuleInfo::iterator I = MI->end(), E = MI->begin(); I != E; )
if (GCMetadataPrinter *MP = GetOrCreateGCPrinter(*--I))
- MP->finishAssembly(O, *this, *MAI);
+ MP->finishAssembly(*this);
// If we don't have any trampolines, then we don't require stack memory
// to be executable. Some targets have a directive to declare this.
@@ -537,7 +603,7 @@ bool AsmPrinter::doFinalization(Module &M) {
EmitEndOfAsmFile(M);
delete Mang; Mang = 0;
- DW = 0; MMI = 0;
+ MMI = 0;
OutStreamer.Finish();
return false;
@@ -548,7 +614,7 @@ void AsmPrinter::SetupMachineFunction(MachineFunction &MF) {
// Get the function symbol.
CurrentFnSym = Mang->getSymbol(MF.getFunction());
- if (VerboseAsm)
+ if (isVerbose())
LI = &getAnalysis<MachineLoopInfo>();
}
@@ -636,7 +702,7 @@ void AsmPrinter::EmitConstantPool() {
Offset = NewOffset + TM.getTargetData()->getTypeAllocSize(Ty);
// Emit the label with a comment on it.
- if (VerboseAsm) {
+ if (isVerbose()) {
OutStreamer.GetCommentOS() << "constant pool ";
WriteTypeSymbolic(OutStreamer.GetCommentOS(), CPE.getType(),
MF->getFunction()->getParent());
@@ -896,12 +962,6 @@ void AsmPrinter::EmitInt32(int Value) const {
OutStreamer.EmitIntValue(Value, 4, 0/*addrspace*/);
}
-/// EmitInt64 - Emit a long long directive and value.
-///
-void AsmPrinter::EmitInt64(uint64_t Value) const {
- OutStreamer.EmitIntValue(Value, 8, 0/*addrspace*/);
-}
-
/// EmitLabelDifference - Emit something like ".long Hi-Lo" where the size
/// in bytes of the directive is specified by Size and Hi/Lo specify the
/// labels. This implicitly uses .set if it is available.
@@ -919,9 +979,7 @@ void AsmPrinter::EmitLabelDifference(const MCSymbol *Hi, const MCSymbol *Lo,
}
// Otherwise, emit with .set (aka assignment).
- MCSymbol *SetLabel =
- OutContext.GetOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix()) +
- "set" + Twine(SetCounter++));
+ MCSymbol *SetLabel = GetTempSymbol("set", SetCounter++);
OutStreamer.EmitAssignment(SetLabel, Diff);
OutStreamer.EmitSymbolValue(SetLabel, Size, 0/*AddrSpace*/);
}
@@ -1156,7 +1214,7 @@ static void EmitGlobalConstantFP(const ConstantFP *CFP, unsigned AddrSpace,
// FP Constants are printed as integer constants to avoid losing
// precision.
if (CFP->getType()->isDoubleTy()) {
- if (AP.VerboseAsm) {
+ if (AP.isVerbose()) {
double Val = CFP->getValueAPF().convertToDouble();
AP.OutStreamer.GetCommentOS() << "double " << Val << '\n';
}
@@ -1167,7 +1225,7 @@ static void EmitGlobalConstantFP(const ConstantFP *CFP, unsigned AddrSpace,
}
if (CFP->getType()->isFloatTy()) {
- if (AP.VerboseAsm) {
+ if (AP.isVerbose()) {
float Val = CFP->getValueAPF().convertToFloat();
AP.OutStreamer.GetCommentOS() << "float " << Val << '\n';
}
@@ -1181,7 +1239,7 @@ static void EmitGlobalConstantFP(const ConstantFP *CFP, unsigned AddrSpace,
// api needed to prevent premature destruction
APInt API = CFP->getValueAPF().bitcastToAPInt();
const uint64_t *p = API.getRawData();
- if (AP.VerboseAsm) {
+ if (AP.isVerbose()) {
// Convert to double so we can print the approximate val as a comment.
APFloat DoubleVal = CFP->getValueAPF();
bool ignored;
@@ -1252,7 +1310,7 @@ void AsmPrinter::EmitGlobalConstant(const Constant *CV, unsigned AddrSpace) {
case 2:
case 4:
case 8:
- if (VerboseAsm)
+ if (isVerbose())
OutStreamer.GetCommentOS() << format("0x%llx\n", CI->getZExtValue());
OutStreamer.EmitIntValue(CI->getZExtValue(), Size, AddrSpace);
return;
@@ -1295,297 +1353,31 @@ void AsmPrinter::EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) {
llvm_unreachable("Target does not support EmitMachineConstantPoolValue");
}
-/// PrintSpecial - Print information related to the specified machine instr
-/// that is independent of the operand, and may be independent of the instr
-/// itself. This can be useful for portably encoding the comment character
-/// or other bits of target-specific knowledge into the asmstrings. The
-/// syntax used is ${:comment}. Targets can override this to add support
-/// for their own strange codes.
-void AsmPrinter::PrintSpecial(const MachineInstr *MI, const char *Code) const {
- if (!strcmp(Code, "private")) {
- O << MAI->getPrivateGlobalPrefix();
- } else if (!strcmp(Code, "comment")) {
- if (VerboseAsm)
- O << MAI->getCommentString();
- } else if (!strcmp(Code, "uid")) {
- // Comparing the address of MI isn't sufficient, because machineinstrs may
- // be allocated to the same address across functions.
- const Function *ThisF = MI->getParent()->getParent()->getFunction();
-
- // If this is a new LastFn instruction, bump the counter.
- if (LastMI != MI || LastFn != ThisF) {
- ++Counter;
- LastMI = MI;
- LastFn = ThisF;
- }
- O << Counter;
- } else {
- std::string msg;
- raw_string_ostream Msg(msg);
- Msg << "Unknown special formatter '" << Code
- << "' for machine instr: " << *MI;
- llvm_report_error(Msg.str());
- }
-}
-
-/// processDebugLoc - Processes the debug information of each machine
-/// instruction's DebugLoc.
-void AsmPrinter::processDebugLoc(const MachineInstr *MI,
- bool BeforePrintingInsn) {
- if (!MAI || !DW || !MAI->doesSupportDebugInformation()
- || !DW->ShouldEmitDwarfDebug())
- return;
-
- if (!BeforePrintingInsn)
- // After printing instruction
- DW->EndScope(MI);
- else
- DW->BeginScope(MI);
-}
-
-
-/// printInlineAsm - This method formats and prints the specified machine
-/// instruction that is an inline asm.
-void AsmPrinter::printInlineAsm(const MachineInstr *MI) const {
- unsigned NumOperands = MI->getNumOperands();
-
- // Count the number of register definitions.
- unsigned NumDefs = 0;
- for (; MI->getOperand(NumDefs).isReg() && MI->getOperand(NumDefs).isDef();
- ++NumDefs)
- assert(NumDefs != NumOperands-1 && "No asm string?");
-
- assert(MI->getOperand(NumDefs).isSymbol() && "No asm string?");
-
- // Disassemble the AsmStr, printing out the literal pieces, the operands, etc.
- const char *AsmStr = MI->getOperand(NumDefs).getSymbolName();
-
- O << '\t';
-
- // 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) {
- O << MAI->getCommentString() << MAI->getInlineAsmStart() << "\n\t";
- O << MAI->getCommentString() << MAI->getInlineAsmEnd() << '\n';
- return;
- }
-
- O << MAI->getCommentString() << MAI->getInlineAsmStart() << "\n\t";
-
- // The variant of the current asmprinter.
- int AsmPrinterVariant = MAI->getAssemblerDialect();
-
- int CurVariant = -1; // The number of the {.|.|.} region we are in.
- const char *LastEmitted = AsmStr; // One past the last character emitted.
-
- while (*LastEmitted) {
- switch (*LastEmitted) {
- default: {
- // Not a special case, emit the string section literally.
- const char *LiteralEnd = LastEmitted+1;
- while (*LiteralEnd && *LiteralEnd != '{' && *LiteralEnd != '|' &&
- *LiteralEnd != '}' && *LiteralEnd != '$' && *LiteralEnd != '\n')
- ++LiteralEnd;
- if (CurVariant == -1 || CurVariant == AsmPrinterVariant)
- O.write(LastEmitted, LiteralEnd-LastEmitted);
- LastEmitted = LiteralEnd;
- break;
- }
- case '\n':
- ++LastEmitted; // Consume newline character.
- O << '\n'; // Indent code with newline.
- break;
- case '$': {
- ++LastEmitted; // Consume '$' character.
- bool Done = true;
-
- // Handle escapes.
- switch (*LastEmitted) {
- default: Done = false; break;
- case '$': // $$ -> $
- if (CurVariant == -1 || CurVariant == AsmPrinterVariant)
- O << '$';
- ++LastEmitted; // Consume second '$' character.
- break;
- case '(': // $( -> same as GCC's { character.
- ++LastEmitted; // Consume '(' character.
- if (CurVariant != -1) {
- llvm_report_error("Nested variants found in inline asm string: '"
- + std::string(AsmStr) + "'");
- }
- CurVariant = 0; // We're in the first variant now.
- break;
- case '|':
- ++LastEmitted; // consume '|' character.
- if (CurVariant == -1)
- O << '|'; // this is gcc's behavior for | outside a variant
- else
- ++CurVariant; // We're in the next variant.
- break;
- case ')': // $) -> same as GCC's } char.
- ++LastEmitted; // consume ')' character.
- if (CurVariant == -1)
- O << '}'; // this is gcc's behavior for } outside a variant
- else
- CurVariant = -1;
- break;
- }
- if (Done) break;
-
- bool HasCurlyBraces = false;
- if (*LastEmitted == '{') { // ${variable}
- ++LastEmitted; // Consume '{' character.
- HasCurlyBraces = true;
- }
-
- // If we have ${:foo}, then this is not a real operand reference, it is a
- // "magic" string reference, just like in .td files. Arrange to call
- // PrintSpecial.
- if (HasCurlyBraces && *LastEmitted == ':') {
- ++LastEmitted;
- const char *StrStart = LastEmitted;
- const char *StrEnd = strchr(StrStart, '}');
- if (StrEnd == 0) {
- llvm_report_error("Unterminated ${:foo} operand in inline asm string: '"
- + std::string(AsmStr) + "'");
- }
-
- std::string Val(StrStart, StrEnd);
- PrintSpecial(MI, Val.c_str());
- LastEmitted = StrEnd+1;
- break;
- }
-
- const char *IDStart = LastEmitted;
- char *IDEnd;
- errno = 0;
- long Val = strtol(IDStart, &IDEnd, 10); // We only accept numbers for IDs.
- if (!isdigit(*IDStart) || (Val == 0 && errno == EINVAL)) {
- llvm_report_error("Bad $ operand number in inline asm string: '"
- + std::string(AsmStr) + "'");
- }
- LastEmitted = IDEnd;
-
- char Modifier[2] = { 0, 0 };
-
- if (HasCurlyBraces) {
- // If we have curly braces, check for a modifier character. This
- // supports syntax like ${0:u}, which correspond to "%u0" in GCC asm.
- if (*LastEmitted == ':') {
- ++LastEmitted; // Consume ':' character.
- if (*LastEmitted == 0) {
- llvm_report_error("Bad ${:} expression in inline asm string: '"
- + std::string(AsmStr) + "'");
- }
-
- Modifier[0] = *LastEmitted;
- ++LastEmitted; // Consume modifier character.
- }
-
- if (*LastEmitted != '}') {
- llvm_report_error("Bad ${} expression in inline asm string: '"
- + std::string(AsmStr) + "'");
- }
- ++LastEmitted; // Consume '}' character.
- }
-
- if ((unsigned)Val >= NumOperands-1) {
- llvm_report_error("Invalid $ operand number in inline asm string: '"
- + std::string(AsmStr) + "'");
- }
-
- // Okay, we finally have a value number. Ask the target to print this
- // operand!
- if (CurVariant == -1 || CurVariant == AsmPrinterVariant) {
- unsigned OpNo = 1;
-
- bool Error = false;
-
- // Scan to find the machine operand number for the operand.
- for (; Val; --Val) {
- if (OpNo >= MI->getNumOperands()) break;
- unsigned OpFlags = MI->getOperand(OpNo).getImm();
- OpNo += InlineAsm::getNumOperandRegisters(OpFlags) + 1;
- }
-
- if (OpNo >= MI->getNumOperands()) {
- Error = true;
- } else {
- unsigned OpFlags = MI->getOperand(OpNo).getImm();
- ++OpNo; // Skip over the ID number.
-
- if (Modifier[0] == 'l') // labels are target independent
- O << *MI->getOperand(OpNo).getMBB()->getSymbol();
- else {
- AsmPrinter *AP = const_cast<AsmPrinter*>(this);
- if ((OpFlags & 7) == 4) {
- Error = AP->PrintAsmMemoryOperand(MI, OpNo, AsmPrinterVariant,
- Modifier[0] ? Modifier : 0);
- } else {
- Error = AP->PrintAsmOperand(MI, OpNo, AsmPrinterVariant,
- Modifier[0] ? Modifier : 0);
- }
- }
- }
- if (Error) {
- std::string msg;
- raw_string_ostream Msg(msg);
- Msg << "Invalid operand found in inline asm: '" << AsmStr << "'\n";
- MI->print(Msg);
- llvm_report_error(Msg.str());
- }
- }
- break;
- }
- }
- }
- O << "\n\t" << MAI->getCommentString() << MAI->getInlineAsmEnd();
- OutStreamer.AddBlankLine();
-}
-
-/// printImplicitDef - This method prints the specified machine instruction
-/// that is an implicit def.
-void AsmPrinter::printImplicitDef(const MachineInstr *MI) const {
- if (!VerboseAsm) return;
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString() << " implicit-def: "
- << TRI->getName(MI->getOperand(0).getReg());
- OutStreamer.AddBlankLine();
+void AsmPrinter::printOffset(int64_t Offset, raw_ostream &OS) const {
+ if (Offset > 0)
+ OS << '+' << Offset;
+ else if (Offset < 0)
+ OS << Offset;
}
-void AsmPrinter::printKill(const MachineInstr *MI) const {
- if (!VerboseAsm) return;
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString() << " kill:";
- for (unsigned n = 0, e = MI->getNumOperands(); n != e; ++n) {
- const MachineOperand &op = MI->getOperand(n);
- assert(op.isReg() && "KILL instruction must have only register operands");
- O << ' ' << TRI->getName(op.getReg()) << (op.isDef() ? "<def>" : "<kill>");
- }
- OutStreamer.AddBlankLine();
-}
+//===----------------------------------------------------------------------===//
+// Symbol Lowering Routines.
+//===----------------------------------------------------------------------===//
-/// printLabel - This method prints a local label used by debug and
-/// exception handling tables.
-void AsmPrinter::printLabelInst(const MachineInstr *MI) const {
- OutStreamer.EmitLabel(MI->getOperand(0).getMCSymbol());
+/// GetTempSymbol - Return the MCSymbol corresponding to the assembler
+/// temporary label with the specified stem and unique ID.
+MCSymbol *AsmPrinter::GetTempSymbol(StringRef Name, unsigned ID) const {
+ return OutContext.GetOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix()) +
+ Name + Twine(ID));
}
-/// PrintAsmOperand - Print the specified operand of MI, an INLINEASM
-/// instruction, using the specified assembler variant. Targets should
-/// override this to format as appropriate.
-bool AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
- unsigned AsmVariant, const char *ExtraCode) {
- // Target doesn't support this yet!
- return true;
+/// GetTempSymbol - Return an assembler temporary label with the specified
+/// stem.
+MCSymbol *AsmPrinter::GetTempSymbol(StringRef Name) const {
+ return OutContext.GetOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix())+
+ Name);
}
-bool AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
- unsigned AsmVariant,
- const char *ExtraCode) {
- // Target doesn't support this yet!
- return true;
-}
MCSymbol *AsmPrinter::GetBlockAddressSymbol(const BlockAddress *BA) const {
return MMI->getAddrLabelSymbol(BA->getBasicBlock());
@@ -1663,10 +1455,10 @@ static void PrintChildLoopComment(raw_ostream &OS, const MachineLoop *Loop,
}
}
-/// PrintBasicBlockLoopComments - Pretty-print comments for basic blocks.
-static void PrintBasicBlockLoopComments(const MachineBasicBlock &MBB,
- const MachineLoopInfo *LI,
- const AsmPrinter &AP) {
+/// EmitBasicBlockLoopComments - Pretty-print comments for basic blocks.
+static void EmitBasicBlockLoopComments(const MachineBasicBlock &MBB,
+ const MachineLoopInfo *LI,
+ const AsmPrinter &AP) {
// Add loop depth information
const MachineLoop *Loop = LI->getLoopFor(&MBB);
if (Loop == 0) return;
@@ -1716,7 +1508,7 @@ void AsmPrinter::EmitBasicBlockStart(const MachineBasicBlock *MBB) const {
// the references were generated.
if (MBB->hasAddressTaken()) {
const BasicBlock *BB = MBB->getBasicBlock();
- if (VerboseAsm)
+ if (isVerbose())
OutStreamer.AddComment("Block address taken");
std::vector<MCSymbol*> Syms = MMI->getAddrLabelSymbolToEmit(BB);
@@ -1727,22 +1519,23 @@ void AsmPrinter::EmitBasicBlockStart(const MachineBasicBlock *MBB) const {
// Print the main label for the block.
if (MBB->pred_empty() || isBlockOnlyReachableByFallthrough(MBB)) {
- if (VerboseAsm) {
- // NOTE: Want this comment at start of line.
- O << MAI->getCommentString() << " BB#" << MBB->getNumber() << ':';
+ if (isVerbose() && OutStreamer.hasRawTextSupport()) {
if (const BasicBlock *BB = MBB->getBasicBlock())
if (BB->hasName())
OutStreamer.AddComment("%" + BB->getName());
- PrintBasicBlockLoopComments(*MBB, LI, *this);
- OutStreamer.AddBlankLine();
+ EmitBasicBlockLoopComments(*MBB, LI, *this);
+
+ // NOTE: Want this comment at start of line, don't emit with AddComment.
+ OutStreamer.EmitRawText(Twine(MAI->getCommentString()) + " BB#" +
+ Twine(MBB->getNumber()) + ":");
}
} else {
- if (VerboseAsm) {
+ if (isVerbose()) {
if (const BasicBlock *BB = MBB->getBasicBlock())
if (BB->hasName())
OutStreamer.AddComment("%" + BB->getName());
- PrintBasicBlockLoopComments(*MBB, LI, *this);
+ EmitBasicBlockLoopComments(*MBB, LI, *this);
}
OutStreamer.EmitLabel(MBB->getSymbol());
@@ -1766,18 +1559,11 @@ void AsmPrinter::EmitVisibility(MCSymbol *Sym, unsigned Visibility) const {
OutStreamer.EmitSymbolAttribute(Sym, Attr);
}
-void AsmPrinter::printOffset(int64_t Offset) const {
- if (Offset > 0)
- O << '+' << Offset;
- else if (Offset < 0)
- O << Offset;
-}
-
/// isBlockOnlyReachableByFallthough - Return true if the basic block has
/// exactly one predecessor and the control transfer mechanism between
/// the predecessor and this block is a fall-through.
-bool AsmPrinter::isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB)
- const {
+bool AsmPrinter::
+isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const {
// If this is a landing pad, it isn't a fall through. If it has no preds,
// then nothing falls through to it.
if (MBB->isLandingPad() || MBB->pred_empty())
@@ -1809,9 +1595,10 @@ bool AsmPrinter::isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB)
GCMetadataPrinter *AsmPrinter::GetOrCreateGCPrinter(GCStrategy *S) {
if (!S->usesMetadata())
return 0;
-
- gcp_iterator GCPI = GCMetadataPrinters.find(S);
- if (GCPI != GCMetadataPrinters.end())
+
+ gcp_map_type &GCMap = getGCMap(GCMetadataPrinters);
+ gcp_map_type::iterator GCPI = GCMap.find(S);
+ if (GCPI != GCMap.end())
return GCPI->second;
const char *Name = S->getName().c_str();
@@ -1822,7 +1609,7 @@ GCMetadataPrinter *AsmPrinter::GetOrCreateGCPrinter(GCStrategy *S) {
if (strcmp(Name, I->getName()) == 0) {
GCMetadataPrinter *GMP = I->instantiate();
GMP->S = S;
- GCMetadataPrinters.insert(std::make_pair(S, GMP));
+ GCMap.insert(std::make_pair(S, GMP));
return GMP;
}
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp b/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp
new file mode 100644
index 0000000..b310578
--- /dev/null
+++ b/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp
@@ -0,0 +1,279 @@
+//===-- AsmPrinterDwarf.cpp - AsmPrinter Dwarf Support --------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the Dwarf emissions parts of AsmPrinter.
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "asm-printer"
+#include "llvm/CodeGen/AsmPrinter.h"
+#include "llvm/CodeGen/MachineLocation.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCSection.h"
+#include "llvm/MC/MCStreamer.h"
+#include "llvm/MC/MCSymbol.h"
+#include "llvm/Target/TargetData.h"
+#include "llvm/Target/TargetFrameInfo.h"
+#include "llvm/Target/TargetLoweringObjectFile.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetRegisterInfo.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Support/Dwarf.h"
+using namespace llvm;
+
+//===----------------------------------------------------------------------===//
+// Dwarf Emission Helper Routines
+//===----------------------------------------------------------------------===//
+
+/// EmitSLEB128 - emit the specified signed leb128 value.
+void AsmPrinter::EmitSLEB128(int Value, const char *Desc) const {
+ if (isVerbose() && Desc)
+ OutStreamer.AddComment(Desc);
+
+ if (MAI->hasLEB128()) {
+ // FIXME: MCize.
+ OutStreamer.EmitRawText("\t.sleb128\t" + Twine(Value));
+ return;
+ }
+
+ // If we don't have .sleb128, emit as .bytes.
+ int Sign = Value >> (8 * sizeof(Value) - 1);
+ bool IsMore;
+
+ do {
+ unsigned char Byte = static_cast<unsigned char>(Value & 0x7f);
+ Value >>= 7;
+ IsMore = Value != Sign || ((Byte ^ Sign) & 0x40) != 0;
+ if (IsMore) Byte |= 0x80;
+ OutStreamer.EmitIntValue(Byte, 1, /*addrspace*/0);
+ } while (IsMore);
+}
+
+/// EmitULEB128 - emit the specified signed leb128 value.
+void AsmPrinter::EmitULEB128(unsigned Value, const char *Desc,
+ unsigned PadTo) const {
+ if (isVerbose() && Desc)
+ OutStreamer.AddComment(Desc);
+
+ if (MAI->hasLEB128() && PadTo == 0) {
+ // FIXME: MCize.
+ OutStreamer.EmitRawText("\t.uleb128\t" + Twine(Value));
+ return;
+ }
+
+ // If we don't have .uleb128 or we want to emit padding, emit as .bytes.
+ do {
+ unsigned char Byte = static_cast<unsigned char>(Value & 0x7f);
+ Value >>= 7;
+ if (Value || PadTo != 0) Byte |= 0x80;
+ OutStreamer.EmitIntValue(Byte, 1, /*addrspace*/0);
+ } while (Value);
+
+ if (PadTo) {
+ if (PadTo > 1)
+ OutStreamer.EmitFill(PadTo - 1, 0x80/*fillval*/, 0/*addrspace*/);
+ OutStreamer.EmitFill(1, 0/*fillval*/, 0/*addrspace*/);
+ }
+}
+
+/// EmitCFAByte - Emit a .byte 42 directive for a DW_CFA_xxx value.
+void AsmPrinter::EmitCFAByte(unsigned Val) const {
+ if (isVerbose()) {
+ if (Val >= dwarf::DW_CFA_offset && Val < dwarf::DW_CFA_offset+64)
+ OutStreamer.AddComment("DW_CFA_offset + Reg (" +
+ Twine(Val-dwarf::DW_CFA_offset) + ")");
+ else
+ OutStreamer.AddComment(dwarf::CallFrameString(Val));
+ }
+ OutStreamer.EmitIntValue(Val, 1, 0/*addrspace*/);
+}
+
+static const char *DecodeDWARFEncoding(unsigned Encoding) {
+ switch (Encoding) {
+ case dwarf::DW_EH_PE_absptr: return "absptr";
+ case dwarf::DW_EH_PE_omit: return "omit";
+ case dwarf::DW_EH_PE_pcrel: return "pcrel";
+ case dwarf::DW_EH_PE_udata4: return "udata4";
+ case dwarf::DW_EH_PE_udata8: return "udata8";
+ case dwarf::DW_EH_PE_sdata4: return "sdata4";
+ case dwarf::DW_EH_PE_sdata8: return "sdata8";
+ case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata4: return "pcrel udata4";
+ case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4: return "pcrel sdata4";
+ case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata8: return "pcrel udata8";
+ case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8: return "pcrel sdata8";
+ case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |dwarf::DW_EH_PE_udata4:
+ return "indirect pcrel udata4";
+ case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |dwarf::DW_EH_PE_sdata4:
+ return "indirect pcrel sdata4";
+ case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |dwarf::DW_EH_PE_udata8:
+ return "indirect pcrel udata8";
+ case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |dwarf::DW_EH_PE_sdata8:
+ return "indirect pcrel sdata8";
+ }
+
+ return "<unknown encoding>";
+}
+
+
+/// EmitEncodingByte - Emit a .byte 42 directive that corresponds to an
+/// encoding. If verbose assembly output is enabled, we output comments
+/// describing the encoding. Desc is an optional string saying what the
+/// encoding is specifying (e.g. "LSDA").
+void AsmPrinter::EmitEncodingByte(unsigned Val, const char *Desc) const {
+ if (isVerbose()) {
+ if (Desc != 0)
+ OutStreamer.AddComment(Twine(Desc)+" Encoding = " +
+ Twine(DecodeDWARFEncoding(Val)));
+ else
+ OutStreamer.AddComment(Twine("Encoding = ") +
+ DecodeDWARFEncoding(Val));
+ }
+
+ OutStreamer.EmitIntValue(Val, 1, 0/*addrspace*/);
+}
+
+/// GetSizeOfEncodedValue - Return the size of the encoding in bytes.
+unsigned AsmPrinter::GetSizeOfEncodedValue(unsigned Encoding) const {
+ if (Encoding == dwarf::DW_EH_PE_omit)
+ return 0;
+
+ switch (Encoding & 0x07) {
+ default: assert(0 && "Invalid encoded value.");
+ case dwarf::DW_EH_PE_absptr: return TM.getTargetData()->getPointerSize();
+ case dwarf::DW_EH_PE_udata2: return 2;
+ case dwarf::DW_EH_PE_udata4: return 4;
+ case dwarf::DW_EH_PE_udata8: return 8;
+ }
+}
+
+void AsmPrinter::EmitReference(const MCSymbol *Sym, unsigned Encoding) const {
+ const TargetLoweringObjectFile &TLOF = getObjFileLowering();
+
+ const MCExpr *Exp =
+ TLOF.getExprForDwarfReference(Sym, Mang, MMI, Encoding, OutStreamer);
+ OutStreamer.EmitValue(Exp, GetSizeOfEncodedValue(Encoding), /*addrspace*/0);
+}
+
+void AsmPrinter::EmitReference(const GlobalValue *GV, unsigned Encoding)const{
+ const TargetLoweringObjectFile &TLOF = getObjFileLowering();
+
+ const MCExpr *Exp =
+ TLOF.getExprForDwarfGlobalReference(GV, Mang, MMI, Encoding, OutStreamer);
+ OutStreamer.EmitValue(Exp, GetSizeOfEncodedValue(Encoding), /*addrspace*/0);
+}
+
+/// EmitSectionOffset - Emit the 4-byte offset of Label from the start of its
+/// section. This can be done with a special directive if the target supports
+/// it (e.g. cygwin) or by emitting it as an offset from a label at the start
+/// of the section.
+///
+/// SectionLabel is a temporary label emitted at the start of the section that
+/// Label lives in.
+void AsmPrinter::EmitSectionOffset(const MCSymbol *Label,
+ const MCSymbol *SectionLabel) const {
+ // On COFF targets, we have to emit the special .secrel32 directive.
+ if (const char *SecOffDir = MAI->getDwarfSectionOffsetDirective()) {
+ // FIXME: MCize.
+ OutStreamer.EmitRawText(SecOffDir + Twine(Label->getName()));
+ return;
+ }
+
+ // Get the section that we're referring to, based on SectionLabel.
+ const MCSection &Section = SectionLabel->getSection();
+
+ // If Label has already been emitted, verify that it is in the same section as
+ // section label for sanity.
+ assert((!Label->isInSection() || &Label->getSection() == &Section) &&
+ "Section offset using wrong section base for label");
+
+ // If the section in question will end up with an address of 0 anyway, we can
+ // just emit an absolute reference to save a relocation.
+ if (Section.isBaseAddressKnownZero()) {
+ OutStreamer.EmitSymbolValue(Label, 4, 0/*AddrSpace*/);
+ return;
+ }
+
+ // Otherwise, emit it as a label difference from the start of the section.
+ EmitLabelDifference(Label, SectionLabel, 4);
+}
+
+//===----------------------------------------------------------------------===//
+// Dwarf Lowering Routines
+//===----------------------------------------------------------------------===//
+
+
+/// EmitFrameMoves - Emit frame instructions to describe the layout of the
+/// frame.
+void AsmPrinter::EmitFrameMoves(const std::vector<MachineMove> &Moves,
+ MCSymbol *BaseLabel, bool isEH) const {
+ const TargetRegisterInfo *RI = TM.getRegisterInfo();
+
+ int stackGrowth = TM.getTargetData()->getPointerSize();
+ if (TM.getFrameInfo()->getStackGrowthDirection() !=
+ TargetFrameInfo::StackGrowsUp)
+ stackGrowth *= -1;
+
+ for (unsigned i = 0, N = Moves.size(); i < N; ++i) {
+ const MachineMove &Move = Moves[i];
+ MCSymbol *Label = Move.getLabel();
+ // Throw out move if the label is invalid.
+ if (Label && !Label->isDefined()) continue; // Not emitted, in dead code.
+
+ const MachineLocation &Dst = Move.getDestination();
+ const MachineLocation &Src = Move.getSource();
+
+ // Advance row if new location.
+ if (BaseLabel && Label) {
+ MCSymbol *ThisSym = Label;
+ if (ThisSym != BaseLabel) {
+ EmitCFAByte(dwarf::DW_CFA_advance_loc4);
+ EmitLabelDifference(ThisSym, BaseLabel, 4);
+ BaseLabel = ThisSym;
+ }
+ }
+
+ // If advancing cfa.
+ if (Dst.isReg() && Dst.getReg() == MachineLocation::VirtualFP) {
+ assert(!Src.isReg() && "Machine move not supported yet.");
+
+ if (Src.getReg() == MachineLocation::VirtualFP) {
+ EmitCFAByte(dwarf::DW_CFA_def_cfa_offset);
+ } else {
+ EmitCFAByte(dwarf::DW_CFA_def_cfa);
+ EmitULEB128(RI->getDwarfRegNum(Src.getReg(), isEH), "Register");
+ }
+
+ EmitULEB128(-Src.getOffset(), "Offset");
+ continue;
+ }
+
+ if (Src.isReg() && Src.getReg() == MachineLocation::VirtualFP) {
+ assert(Dst.isReg() && "Machine move not supported yet.");
+ EmitCFAByte(dwarf::DW_CFA_def_cfa_register);
+ EmitULEB128(RI->getDwarfRegNum(Dst.getReg(), isEH), "Register");
+ continue;
+ }
+
+ unsigned Reg = RI->getDwarfRegNum(Src.getReg(), isEH);
+ int Offset = Dst.getOffset() / stackGrowth;
+
+ if (Offset < 0) {
+ EmitCFAByte(dwarf::DW_CFA_offset_extended_sf);
+ EmitULEB128(Reg, "Reg");
+ EmitSLEB128(Offset, "Offset");
+ } else if (Reg < 64) {
+ EmitCFAByte(dwarf::DW_CFA_offset + Reg);
+ EmitULEB128(Offset, "Offset");
+ } else {
+ EmitCFAByte(dwarf::DW_CFA_offset_extended);
+ EmitULEB128(Reg, "Reg");
+ EmitULEB128(Offset, "Offset");
+ }
+ }
+}
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp b/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
new file mode 100644
index 0000000..255bcd4
--- /dev/null
+++ b/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
@@ -0,0 +1,357 @@
+//===-- AsmPrinterInlineAsm.cpp - AsmPrinter Inline Asm Handling ----------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the inline assembler pieces of the AsmPrinter class.
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "asm-printer"
+#include "llvm/CodeGen/AsmPrinter.h"
+#include "llvm/InlineAsm.h"
+#include "llvm/LLVMContext.h"
+#include "llvm/Module.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCStreamer.h"
+#include "llvm/MC/MCSymbol.h"
+#include "llvm/MC/MCParser/AsmParser.h"
+#include "llvm/Target/TargetAsmParser.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetRegistry.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace llvm;
+
+/// EmitInlineAsm - Emit a blob of inline asm to the output streamer.
+void AsmPrinter::EmitInlineAsm(StringRef Str, unsigned LocCookie) const {
+ assert(!Str.empty() && "Can't emit empty inline asm block");
+
+ // Remember if the buffer is nul terminated or not so we can avoid a copy.
+ bool isNullTerminated = Str.back() == 0;
+ if (isNullTerminated)
+ Str = Str.substr(0, Str.size()-1);
+
+ // If the output streamer is actually a .s file, just emit the blob textually.
+ // This is useful in case the asm parser doesn't handle something but the
+ // system assembler does.
+ if (OutStreamer.hasRawTextSupport()) {
+ OutStreamer.EmitRawText(Str);
+ return;
+ }
+
+ SourceMgr SrcMgr;
+
+ // If the current LLVMContext has an inline asm handler, set it in SourceMgr.
+ LLVMContext &LLVMCtx = MMI->getModule()->getContext();
+ bool HasDiagHandler = false;
+ if (void *DiagHandler = LLVMCtx.getInlineAsmDiagnosticHandler()) {
+ SrcMgr.setDiagHandler((SourceMgr::DiagHandlerTy)(intptr_t)DiagHandler,
+ LLVMCtx.getInlineAsmDiagnosticContext(), LocCookie);
+ HasDiagHandler = true;
+ }
+
+ MemoryBuffer *Buffer;
+ if (isNullTerminated)
+ Buffer = MemoryBuffer::getMemBuffer(Str, "<inline asm>");
+ else
+ Buffer = MemoryBuffer::getMemBufferCopy(Str, "<inline asm>");
+
+ // Tell SrcMgr about this buffer, it takes ownership of the buffer.
+ SrcMgr.AddNewSourceBuffer(Buffer, SMLoc());
+
+ AsmParser Parser(SrcMgr, OutContext, OutStreamer, *MAI);
+ OwningPtr<TargetAsmParser> TAP(TM.getTarget().createAsmParser(Parser));
+ if (!TAP)
+ llvm_report_error("Inline asm not supported by this streamer because"
+ " we don't have an asm parser for this target\n");
+ Parser.setTargetParser(*TAP.get());
+
+ // Don't implicitly switch to the text section before the asm.
+ int Res = Parser.Run(/*NoInitialTextSection*/ true,
+ /*NoFinalize*/ true);
+ if (Res && !HasDiagHandler)
+ llvm_report_error("Error parsing inline asm\n");
+}
+
+
+/// EmitInlineAsm - This method formats and emits the specified machine
+/// instruction that is an inline asm.
+void AsmPrinter::EmitInlineAsm(const MachineInstr *MI) const {
+ assert(MI->isInlineAsm() && "printInlineAsm only works on inline asms");
+
+ unsigned NumOperands = MI->getNumOperands();
+
+ // Count the number of register definitions to find the asm string.
+ unsigned NumDefs = 0;
+ for (; MI->getOperand(NumDefs).isReg() && MI->getOperand(NumDefs).isDef();
+ ++NumDefs)
+ assert(NumDefs != NumOperands-1 && "No asm string?");
+
+ assert(MI->getOperand(NumDefs).isSymbol() && "No asm string?");
+
+ // Disassemble the AsmStr, printing out the literal pieces, the operands, etc.
+ const char *AsmStr = MI->getOperand(NumDefs).getSymbolName();
+
+ // 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());
+ 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());
+
+ // Emit the inline asm to a temporary string so we can emit it through
+ // EmitInlineAsm.
+ SmallString<256> StringData;
+ raw_svector_ostream OS(StringData);
+
+ OS << '\t';
+
+ // The variant of the current asmprinter.
+ int AsmPrinterVariant = MAI->getAssemblerDialect();
+
+ int CurVariant = -1; // The number of the {.|.|.} region we are in.
+ const char *LastEmitted = AsmStr; // One past the last character emitted.
+
+ while (*LastEmitted) {
+ switch (*LastEmitted) {
+ default: {
+ // Not a special case, emit the string section literally.
+ const char *LiteralEnd = LastEmitted+1;
+ while (*LiteralEnd && *LiteralEnd != '{' && *LiteralEnd != '|' &&
+ *LiteralEnd != '}' && *LiteralEnd != '$' && *LiteralEnd != '\n')
+ ++LiteralEnd;
+ if (CurVariant == -1 || CurVariant == AsmPrinterVariant)
+ OS.write(LastEmitted, LiteralEnd-LastEmitted);
+ LastEmitted = LiteralEnd;
+ break;
+ }
+ case '\n':
+ ++LastEmitted; // Consume newline character.
+ OS << '\n'; // Indent code with newline.
+ break;
+ case '$': {
+ ++LastEmitted; // Consume '$' character.
+ bool Done = true;
+
+ // Handle escapes.
+ switch (*LastEmitted) {
+ default: Done = false; break;
+ case '$': // $$ -> $
+ if (CurVariant == -1 || CurVariant == AsmPrinterVariant)
+ OS << '$';
+ ++LastEmitted; // Consume second '$' character.
+ break;
+ case '(': // $( -> same as GCC's { character.
+ ++LastEmitted; // Consume '(' character.
+ if (CurVariant != -1) {
+ llvm_report_error("Nested variants found in inline asm string: '"
+ + std::string(AsmStr) + "'");
+ }
+ CurVariant = 0; // We're in the first variant now.
+ break;
+ case '|':
+ ++LastEmitted; // consume '|' character.
+ if (CurVariant == -1)
+ OS << '|'; // this is gcc's behavior for | outside a variant
+ else
+ ++CurVariant; // We're in the next variant.
+ break;
+ case ')': // $) -> same as GCC's } char.
+ ++LastEmitted; // consume ')' character.
+ if (CurVariant == -1)
+ OS << '}'; // this is gcc's behavior for } outside a variant
+ else
+ CurVariant = -1;
+ break;
+ }
+ if (Done) break;
+
+ bool HasCurlyBraces = false;
+ if (*LastEmitted == '{') { // ${variable}
+ ++LastEmitted; // Consume '{' character.
+ HasCurlyBraces = true;
+ }
+
+ // If we have ${:foo}, then this is not a real operand reference, it is a
+ // "magic" string reference, just like in .td files. Arrange to call
+ // PrintSpecial.
+ if (HasCurlyBraces && *LastEmitted == ':') {
+ ++LastEmitted;
+ const char *StrStart = LastEmitted;
+ const char *StrEnd = strchr(StrStart, '}');
+ if (StrEnd == 0)
+ llvm_report_error(Twine("Unterminated ${:foo} operand in inline asm"
+ " string: '") + Twine(AsmStr) + "'");
+
+ std::string Val(StrStart, StrEnd);
+ PrintSpecial(MI, OS, Val.c_str());
+ LastEmitted = StrEnd+1;
+ break;
+ }
+
+ const char *IDStart = LastEmitted;
+ const char *IDEnd = IDStart;
+ while (*IDEnd >= '0' && *IDEnd <= '9') ++IDEnd;
+
+ unsigned Val;
+ if (StringRef(IDStart, IDEnd-IDStart).getAsInteger(10, Val))
+ llvm_report_error("Bad $ operand number in inline asm string: '"
+ + std::string(AsmStr) + "'");
+ LastEmitted = IDEnd;
+
+ char Modifier[2] = { 0, 0 };
+
+ if (HasCurlyBraces) {
+ // If we have curly braces, check for a modifier character. This
+ // supports syntax like ${0:u}, which correspond to "%u0" in GCC asm.
+ if (*LastEmitted == ':') {
+ ++LastEmitted; // Consume ':' character.
+ if (*LastEmitted == 0)
+ llvm_report_error("Bad ${:} expression in inline asm string: '" +
+ std::string(AsmStr) + "'");
+
+ Modifier[0] = *LastEmitted;
+ ++LastEmitted; // Consume modifier character.
+ }
+
+ if (*LastEmitted != '}')
+ llvm_report_error("Bad ${} expression in inline asm string: '"
+ + std::string(AsmStr) + "'");
+ ++LastEmitted; // Consume '}' character.
+ }
+
+ if (Val >= NumOperands-1)
+ llvm_report_error("Invalid $ operand number in inline asm string: '"
+ + std::string(AsmStr) + "'");
+
+ // Okay, we finally have a value number. Ask the target to print this
+ // operand!
+ if (CurVariant == -1 || CurVariant == AsmPrinterVariant) {
+ unsigned OpNo = 1;
+
+ bool Error = false;
+
+ // Scan to find the machine operand number for the operand.
+ for (; Val; --Val) {
+ if (OpNo >= MI->getNumOperands()) break;
+ unsigned OpFlags = MI->getOperand(OpNo).getImm();
+ OpNo += InlineAsm::getNumOperandRegisters(OpFlags) + 1;
+ }
+
+ if (OpNo >= MI->getNumOperands()) {
+ Error = true;
+ } else {
+ unsigned OpFlags = MI->getOperand(OpNo).getImm();
+ ++OpNo; // Skip over the ID number.
+
+ if (Modifier[0] == 'l') // labels are target independent
+ // FIXME: What if the operand isn't an MBB, report error?
+ OS << *MI->getOperand(OpNo).getMBB()->getSymbol();
+ else {
+ AsmPrinter *AP = const_cast<AsmPrinter*>(this);
+ if ((OpFlags & 7) == 4) {
+ Error = AP->PrintAsmMemoryOperand(MI, OpNo, AsmPrinterVariant,
+ Modifier[0] ? Modifier : 0,
+ OS);
+ } else {
+ Error = AP->PrintAsmOperand(MI, OpNo, AsmPrinterVariant,
+ Modifier[0] ? Modifier : 0, OS);
+ }
+ }
+ }
+ if (Error) {
+ std::string msg;
+ raw_string_ostream Msg(msg);
+ Msg << "Invalid operand found in inline asm: '" << AsmStr << "'\n";
+ MI->print(Msg);
+ llvm_report_error(Msg.str());
+ }
+ }
+ break;
+ }
+ }
+ }
+ OS << '\n' << (char)0; // null terminate string.
+ EmitInlineAsm(OS.str(), 0/*no loc cookie*/);
+
+ // 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());
+}
+
+
+/// PrintSpecial - Print information related to the specified machine instr
+/// that is independent of the operand, and may be independent of the instr
+/// itself. This can be useful for portably encoding the comment character
+/// or other bits of target-specific knowledge into the asmstrings. The
+/// syntax used is ${:comment}. Targets can override this to add support
+/// for their own strange codes.
+void AsmPrinter::PrintSpecial(const MachineInstr *MI, raw_ostream &OS,
+ const char *Code) const {
+ if (!strcmp(Code, "private")) {
+ OS << MAI->getPrivateGlobalPrefix();
+ } else if (!strcmp(Code, "comment")) {
+ OS << MAI->getCommentString();
+ } else if (!strcmp(Code, "uid")) {
+ // Comparing the address of MI isn't sufficient, because machineinstrs may
+ // be allocated to the same address across functions.
+
+ // If this is a new LastFn instruction, bump the counter.
+ if (LastMI != MI || LastFn != getFunctionNumber()) {
+ ++Counter;
+ LastMI = MI;
+ LastFn = getFunctionNumber();
+ }
+ OS << Counter;
+ } else {
+ std::string msg;
+ raw_string_ostream Msg(msg);
+ Msg << "Unknown special formatter '" << Code
+ << "' for machine instr: " << *MI;
+ llvm_report_error(Msg.str());
+ }
+}
+
+/// PrintAsmOperand - Print the specified operand of MI, an INLINEASM
+/// instruction, using the specified assembler variant. Targets should
+/// override this to format as appropriate.
+bool AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
+ unsigned AsmVariant, const char *ExtraCode,
+ raw_ostream &O) {
+ // Target doesn't support this yet!
+ return true;
+}
+
+bool AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
+ unsigned AsmVariant,
+ const char *ExtraCode, raw_ostream &O) {
+ // Target doesn't support this yet!
+ return true;
+}
+
diff --git a/lib/CodeGen/AsmPrinter/CMakeLists.txt b/lib/CodeGen/AsmPrinter/CMakeLists.txt
index 7dc1fb5..afc482d 100644
--- a/lib/CodeGen/AsmPrinter/CMakeLists.txt
+++ b/lib/CodeGen/AsmPrinter/CMakeLists.txt
@@ -1,9 +1,9 @@
add_llvm_library(LLVMAsmPrinter
AsmPrinter.cpp
+ AsmPrinterDwarf.cpp
+ AsmPrinterInlineAsm.cpp
DIE.cpp
DwarfDebug.cpp
DwarfException.cpp
- DwarfPrinter.cpp
- DwarfWriter.cpp
OcamlGCPrinter.cpp
)
diff --git a/lib/CodeGen/AsmPrinter/DIE.cpp b/lib/CodeGen/AsmPrinter/DIE.cpp
index e0e3ff7..b2c70d5 100644
--- a/lib/CodeGen/AsmPrinter/DIE.cpp
+++ b/lib/CodeGen/AsmPrinter/DIE.cpp
@@ -12,7 +12,6 @@
//===----------------------------------------------------------------------===//
#include "DIE.h"
-#include "DwarfPrinter.h"
#include "llvm/ADT/Twine.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/MC/MCAsmInfo.h"
@@ -54,14 +53,14 @@ void DIEAbbrev::Profile(FoldingSetNodeID &ID) const {
/// Emit - Print the abbreviation using the specified asm printer.
///
-void DIEAbbrev::Emit(const DwarfPrinter *DP) const {
+void DIEAbbrev::Emit(AsmPrinter *AP) const {
// Emit its Dwarf tag type.
// FIXME: Doing work even in non-asm-verbose runs.
- DP->EmitULEB128(Tag, dwarf::TagString(Tag));
+ AP->EmitULEB128(Tag, dwarf::TagString(Tag));
// Emit whether it has children DIEs.
// FIXME: Doing work even in non-asm-verbose runs.
- DP->EmitULEB128(ChildrenFlag, dwarf::ChildrenString(ChildrenFlag));
+ AP->EmitULEB128(ChildrenFlag, dwarf::ChildrenString(ChildrenFlag));
// For each attribute description.
for (unsigned i = 0, N = Data.size(); i < N; ++i) {
@@ -69,18 +68,18 @@ void DIEAbbrev::Emit(const DwarfPrinter *DP) const {
// Emit attribute type.
// FIXME: Doing work even in non-asm-verbose runs.
- DP->EmitULEB128(AttrData.getAttribute(),
- dwarf::AttributeString(AttrData.getAttribute()));
+ AP->EmitULEB128(AttrData.getAttribute(),
+ dwarf::AttributeString(AttrData.getAttribute()));
// Emit form type.
// FIXME: Doing work even in non-asm-verbose runs.
- DP->EmitULEB128(AttrData.getForm(),
+ AP->EmitULEB128(AttrData.getForm(),
dwarf::FormEncodingString(AttrData.getForm()));
}
// Mark end of abbreviation.
- DP->EmitULEB128(0, "EOM(1)");
- DP->EmitULEB128(0, "EOM(2)");
+ AP->EmitULEB128(0, "EOM(1)");
+ AP->EmitULEB128(0, "EOM(2)");
}
#ifndef NDEBUG
@@ -188,8 +187,7 @@ void DIEValue::dump() {
/// EmitValue - Emit integer of appropriate size.
///
-void DIEInteger::EmitValue(DwarfPrinter *D, unsigned Form) const {
- const AsmPrinter *Asm = D->getAsm();
+void DIEInteger::EmitValue(AsmPrinter *Asm, unsigned Form) const {
unsigned Size = ~0U;
switch (Form) {
case dwarf::DW_FORM_flag: // Fall thru
@@ -201,8 +199,8 @@ void DIEInteger::EmitValue(DwarfPrinter *D, unsigned Form) const {
case dwarf::DW_FORM_data4: Size = 4; break;
case dwarf::DW_FORM_ref8: // Fall thru
case dwarf::DW_FORM_data8: Size = 8; break;
- case dwarf::DW_FORM_udata: D->EmitULEB128(Integer); return;
- case dwarf::DW_FORM_sdata: D->EmitSLEB128(Integer, ""); return;
+ case dwarf::DW_FORM_udata: Asm->EmitULEB128(Integer); return;
+ case dwarf::DW_FORM_sdata: Asm->EmitSLEB128(Integer); return;
default: llvm_unreachable("DIE Value form not supported yet");
}
Asm->OutStreamer.EmitIntValue(Integer, Size, 0/*addrspace*/);
@@ -210,7 +208,7 @@ void DIEInteger::EmitValue(DwarfPrinter *D, unsigned Form) const {
/// SizeOf - Determine size of integer value in bytes.
///
-unsigned DIEInteger::SizeOf(const TargetData *TD, unsigned Form) const {
+unsigned DIEInteger::SizeOf(AsmPrinter *AP, unsigned Form) const {
switch (Form) {
case dwarf::DW_FORM_flag: // Fall thru
case dwarf::DW_FORM_ref1: // Fall thru
@@ -241,10 +239,10 @@ void DIEInteger::print(raw_ostream &O) {
/// EmitValue - Emit string value.
///
-void DIEString::EmitValue(DwarfPrinter *D, unsigned Form) const {
- D->getAsm()->OutStreamer.EmitBytes(Str, /*addrspace*/0);
+void DIEString::EmitValue(AsmPrinter *AP, unsigned Form) const {
+ AP->OutStreamer.EmitBytes(Str, /*addrspace*/0);
// Emit nul terminator.
- D->getAsm()->OutStreamer.EmitIntValue(0, 1, /*addrspace*/0);
+ AP->OutStreamer.EmitIntValue(0, 1, /*addrspace*/0);
}
#ifndef NDEBUG
@@ -259,17 +257,15 @@ void DIEString::print(raw_ostream &O) {
/// EmitValue - Emit label value.
///
-void DIELabel::EmitValue(DwarfPrinter *D, unsigned Form) const {
- bool IsSmall = Form == dwarf::DW_FORM_data4;
- unsigned Size = IsSmall ? 4 : D->getTargetData()->getPointerSize();
- D->getAsm()->OutStreamer.EmitSymbolValue(Label, Size, 0/*AddrSpace*/);
+void DIELabel::EmitValue(AsmPrinter *AP, unsigned Form) const {
+ AP->OutStreamer.EmitSymbolValue(Label, SizeOf(AP, Form), 0/*AddrSpace*/);
}
/// SizeOf - Determine size of label value in bytes.
///
-unsigned DIELabel::SizeOf(const TargetData *TD, unsigned Form) const {
+unsigned DIELabel::SizeOf(AsmPrinter *AP, unsigned Form) const {
if (Form == dwarf::DW_FORM_data4) return 4;
- return TD->getPointerSize();
+ return AP->getTargetData().getPointerSize();
}
#ifndef NDEBUG
@@ -284,16 +280,15 @@ void DIELabel::print(raw_ostream &O) {
/// EmitValue - Emit delta value.
///
-void DIEDelta::EmitValue(DwarfPrinter *D, unsigned Form) const {
- bool IsSmall = Form == dwarf::DW_FORM_data4;
- D->EmitDifference(LabelHi, LabelLo, IsSmall);
+void DIEDelta::EmitValue(AsmPrinter *AP, unsigned Form) const {
+ AP->EmitLabelDifference(LabelHi, LabelLo, SizeOf(AP, Form));
}
/// SizeOf - Determine size of delta value in bytes.
///
-unsigned DIEDelta::SizeOf(const TargetData *TD, unsigned Form) const {
+unsigned DIEDelta::SizeOf(AsmPrinter *AP, unsigned Form) const {
if (Form == dwarf::DW_FORM_data4) return 4;
- return TD->getPointerSize();
+ return AP->getTargetData().getPointerSize();
}
#ifndef NDEBUG
@@ -308,8 +303,8 @@ void DIEDelta::print(raw_ostream &O) {
/// EmitValue - Emit debug information entry offset.
///
-void DIEEntry::EmitValue(DwarfPrinter *D, unsigned Form) const {
- D->getAsm()->EmitInt32(Entry->getOffset());
+void DIEEntry::EmitValue(AsmPrinter *AP, unsigned Form) const {
+ AP->EmitInt32(Entry->getOffset());
}
#ifndef NDEBUG
@@ -324,11 +319,11 @@ void DIEEntry::print(raw_ostream &O) {
/// ComputeSize - calculate the size of the block.
///
-unsigned DIEBlock::ComputeSize(const TargetData *TD) {
+unsigned DIEBlock::ComputeSize(AsmPrinter *AP) {
if (!Size) {
const SmallVector<DIEAbbrevData, 8> &AbbrevData = Abbrev.getData();
for (unsigned i = 0, N = Values.size(); i < N; ++i)
- Size += Values[i]->SizeOf(TD, AbbrevData[i].getForm());
+ Size += Values[i]->SizeOf(AP, AbbrevData[i].getForm());
}
return Size;
@@ -336,29 +331,28 @@ unsigned DIEBlock::ComputeSize(const TargetData *TD) {
/// EmitValue - Emit block data.
///
-void DIEBlock::EmitValue(DwarfPrinter *D, unsigned Form) const {
- const AsmPrinter *Asm = D->getAsm();
+void DIEBlock::EmitValue(AsmPrinter *Asm, unsigned Form) const {
switch (Form) {
- case dwarf::DW_FORM_block1: Asm->EmitInt8(Size); break;
- case dwarf::DW_FORM_block2: Asm->EmitInt16(Size); break;
- case dwarf::DW_FORM_block4: Asm->EmitInt32(Size); break;
- case dwarf::DW_FORM_block: D->EmitULEB128(Size); break;
- default: llvm_unreachable("Improper form for block"); break;
+ default: assert(0 && "Improper form for block"); break;
+ case dwarf::DW_FORM_block1: Asm->EmitInt8(Size); break;
+ case dwarf::DW_FORM_block2: Asm->EmitInt16(Size); break;
+ case dwarf::DW_FORM_block4: Asm->EmitInt32(Size); break;
+ case dwarf::DW_FORM_block: Asm->EmitULEB128(Size); break;
}
const SmallVector<DIEAbbrevData, 8> &AbbrevData = Abbrev.getData();
for (unsigned i = 0, N = Values.size(); i < N; ++i)
- Values[i]->EmitValue(D, AbbrevData[i].getForm());
+ Values[i]->EmitValue(Asm, AbbrevData[i].getForm());
}
/// SizeOf - Determine size of block data in bytes.
///
-unsigned DIEBlock::SizeOf(const TargetData *TD, unsigned Form) const {
+unsigned DIEBlock::SizeOf(AsmPrinter *AP, unsigned Form) const {
switch (Form) {
case dwarf::DW_FORM_block1: return Size + sizeof(int8_t);
case dwarf::DW_FORM_block2: return Size + sizeof(int16_t);
case dwarf::DW_FORM_block4: return Size + sizeof(int32_t);
- case dwarf::DW_FORM_block: return Size + MCAsmInfo::getULEB128Size(Size);
+ case dwarf::DW_FORM_block: return Size + MCAsmInfo::getULEB128Size(Size);
default: llvm_unreachable("Improper form for block"); break;
}
return 0;
diff --git a/lib/CodeGen/AsmPrinter/DIE.h b/lib/CodeGen/AsmPrinter/DIE.h
index 8b27ed2..454326d 100644
--- a/lib/CodeGen/AsmPrinter/DIE.h
+++ b/lib/CodeGen/AsmPrinter/DIE.h
@@ -22,8 +22,6 @@
namespace llvm {
class AsmPrinter;
- class DwarfPrinter;
- class TargetData;
class MCSymbol;
class raw_ostream;
@@ -101,7 +99,7 @@ namespace llvm {
/// Emit - Print the abbreviation using the specified asm printer.
///
- void Emit(const DwarfPrinter *DP) const;
+ void Emit(AsmPrinter *AP) const;
#ifndef NDEBUG
void print(raw_ostream &O);
@@ -221,11 +219,11 @@ namespace llvm {
/// EmitValue - Emit value via the Dwarf writer.
///
- virtual void EmitValue(DwarfPrinter *D, unsigned Form) const = 0;
+ virtual void EmitValue(AsmPrinter *AP, unsigned Form) const = 0;
/// SizeOf - Return the size of a value in bytes.
///
- virtual unsigned SizeOf(const TargetData *TD, unsigned Form) const = 0;
+ virtual unsigned SizeOf(AsmPrinter *AP, unsigned Form) const = 0;
// Implement isa/cast/dyncast.
static bool classof(const DIEValue *) { return true; }
@@ -261,11 +259,11 @@ namespace llvm {
/// EmitValue - Emit integer of appropriate size.
///
- virtual void EmitValue(DwarfPrinter *D, unsigned Form) const;
+ virtual void EmitValue(AsmPrinter *AP, unsigned Form) const;
/// SizeOf - Determine size of integer value in bytes.
///
- virtual unsigned SizeOf(const TargetData *TD, unsigned Form) const;
+ virtual unsigned SizeOf(AsmPrinter *AP, unsigned Form) const;
// Implement isa/cast/dyncast.
@@ -287,11 +285,11 @@ namespace llvm {
/// EmitValue - Emit string value.
///
- virtual void EmitValue(DwarfPrinter *D, unsigned Form) const;
+ virtual void EmitValue(AsmPrinter *AP, unsigned Form) const;
/// SizeOf - Determine size of string value in bytes.
///
- virtual unsigned SizeOf(const TargetData *, unsigned /*Form*/) const {
+ virtual unsigned SizeOf(AsmPrinter *AP, unsigned /*Form*/) const {
return Str.size() + sizeof(char); // sizeof('\0');
}
@@ -314,11 +312,11 @@ namespace llvm {
/// EmitValue - Emit label value.
///
- virtual void EmitValue(DwarfPrinter *D, unsigned Form) const;
+ virtual void EmitValue(AsmPrinter *AP, unsigned Form) const;
/// SizeOf - Determine size of label value in bytes.
///
- virtual unsigned SizeOf(const TargetData *TD, unsigned Form) const;
+ virtual unsigned SizeOf(AsmPrinter *AP, unsigned Form) const;
// Implement isa/cast/dyncast.
static bool classof(const DIELabel *) { return true; }
@@ -341,11 +339,11 @@ namespace llvm {
/// EmitValue - Emit delta value.
///
- virtual void EmitValue(DwarfPrinter *D, unsigned Form) const;
+ virtual void EmitValue(AsmPrinter *AP, unsigned Form) const;
/// SizeOf - Determine size of delta value in bytes.
///
- virtual unsigned SizeOf(const TargetData *TD, unsigned Form) const;
+ virtual unsigned SizeOf(AsmPrinter *AP, unsigned Form) const;
// Implement isa/cast/dyncast.
static bool classof(const DIEDelta *) { return true; }
@@ -369,11 +367,11 @@ namespace llvm {
/// EmitValue - Emit debug information entry offset.
///
- virtual void EmitValue(DwarfPrinter *D, unsigned Form) const;
+ virtual void EmitValue(AsmPrinter *AP, unsigned Form) const;
/// SizeOf - Determine size of debug information entry in bytes.
///
- virtual unsigned SizeOf(const TargetData *TD, unsigned Form) const {
+ virtual unsigned SizeOf(AsmPrinter *AP, unsigned Form) const {
return sizeof(int32_t);
}
@@ -398,7 +396,7 @@ namespace llvm {
/// ComputeSize - calculate the size of the block.
///
- unsigned ComputeSize(const TargetData *TD);
+ unsigned ComputeSize(AsmPrinter *AP);
/// BestForm - Choose the best form for data.
///
@@ -411,11 +409,11 @@ namespace llvm {
/// EmitValue - Emit block data.
///
- virtual void EmitValue(DwarfPrinter *D, unsigned Form) const;
+ virtual void EmitValue(AsmPrinter *AP, unsigned Form) const;
/// SizeOf - Determine size of block data in bytes.
///
- virtual unsigned SizeOf(const TargetData *TD, unsigned Form) const;
+ virtual unsigned SizeOf(AsmPrinter *AP, unsigned Form) const;
// Implement isa/cast/dyncast.
static bool classof(const DIEBlock *) { return true; }
diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index 9084456..b472d1e 100644
--- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -13,6 +13,8 @@
#define DEBUG_TYPE "dwarfdebug"
#include "DwarfDebug.h"
+#include "DIE.h"
+#include "llvm/Constants.h"
#include "llvm/Module.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
@@ -24,7 +26,9 @@
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetFrameInfo.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
+#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetRegisterInfo.h"
+#include "llvm/Analysis/DebugInfo.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/Debug.h"
@@ -269,6 +273,8 @@ public:
void dump() const;
#endif
};
+
+} // end llvm namespace
#ifndef NDEBUG
void DbgScope::dump() const {
@@ -296,16 +302,19 @@ DbgScope::~DbgScope() {
delete Variables[j];
}
-} // end llvm namespace
-
-DwarfDebug::DwarfDebug(raw_ostream &OS, AsmPrinter *A, const MCAsmInfo *T)
- : DwarfPrinter(OS, A, T), ModuleCU(0),
- AbbreviationsSet(InitAbbreviationsSetSize), Abbreviations(),
- DIEBlocks(), SectionSourceLines(), didInitial(false), shouldEmit(false),
+DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M)
+ : Asm(A), MMI(Asm->MMI), ModuleCU(0),
+ AbbreviationsSet(InitAbbreviationsSetSize),
CurrentFnDbgScope(0), DebugTimer(0) {
NextStringPoolNumber = 0;
+
+ DwarfFrameSectionSym = DwarfInfoSectionSym = DwarfAbbrevSectionSym = 0;
+ DwarfStrSectionSym = TextSectionSym = 0;
+
if (TimePassesIsEnabled)
DebugTimer = new Timer("Dwarf Debug Writer");
+
+ beginModule(M);
}
DwarfDebug::~DwarfDebug() {
for (unsigned j = 0, M = DIEBlocks.size(); j < M; ++j)
@@ -319,7 +328,7 @@ MCSymbol *DwarfDebug::getStringPoolEntry(StringRef Str) {
if (Entry.first) return Entry.first;
Entry.second = NextStringPoolNumber++;
- return Entry.first = getDWLabel("string", Entry.second);
+ return Entry.first = Asm->GetTempSymbol("string", Entry.second);
}
@@ -395,11 +404,19 @@ void DwarfDebug::addDelta(DIE *Die, unsigned Attribute, unsigned Form,
Die->addValue(Attribute, Form, Value);
}
+/// addDIEEntry - Add a DIE attribute data and value.
+///
+void DwarfDebug::addDIEEntry(DIE *Die, unsigned Attribute, unsigned Form,
+ DIE *Entry) {
+ Die->addValue(Attribute, Form, createDIEEntry(Entry));
+}
+
+
/// addBlock - Add block data.
///
void DwarfDebug::addBlock(DIE *Die, unsigned Attribute, unsigned Form,
DIEBlock *Block) {
- Block->ComputeSize(TD);
+ Block->ComputeSize(Asm);
DIEBlocks.push_back(Block); // Memoize so we can call the destructor later on.
Die->addValue(Attribute, Block->BestForm(), Block);
}
@@ -553,6 +570,7 @@ void DwarfDebug::addComplexAddress(DbgVariable *&DV, DIE *Die,
// Decode the original location, and use that as the start of the byref
// variable's location.
+ const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
unsigned Reg = RI->getDwarfRegNum(Location.getReg(), false);
DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
@@ -693,6 +711,7 @@ void DwarfDebug::addBlockByrefAddress(DbgVariable *&DV, DIE *Die,
// Decode the original location, and use that as the start of the byref
// variable's location.
+ const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
unsigned Reg = RI->getDwarfRegNum(Location.getReg(), false);
DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
@@ -748,6 +767,7 @@ void DwarfDebug::addBlockByrefAddress(DbgVariable *&DV, DIE *Die,
/// provided.
void DwarfDebug::addAddress(DIE *Die, unsigned Attribute,
const MachineLocation &Location) {
+ const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
unsigned Reg = RI->getDwarfRegNum(Location.getReg(), false);
DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
@@ -1114,7 +1134,8 @@ DIE *DwarfDebug::createMemberDIE(const DIDerivedType &DT) {
Offset -= FieldOffset;
// Maybe we need to work from the other end.
- if (TD->isLittleEndian()) Offset = FieldSize - (Offset + Size);
+ if (Asm->getTargetData().isLittleEndian())
+ Offset = FieldSize - (Offset + Size);
addUInt(MemberDie, dwarf::DW_AT_bit_offset, 0, Offset);
// Here WD_AT_data_member_location points to the anonymous
@@ -1272,7 +1293,7 @@ DbgScope *DwarfDebug::getUpdatedDbgScope(MDNode *N, const MachineInstr *MI,
if (!Parent && !InlinedAt) {
StringRef SPName = DISubprogram(N).getLinkageName();
- if (SPName == MF->getFunction()->getName())
+ if (SPName == Asm->MF->getFunction()->getName())
CurrentFnDbgScope = NScope;
}
@@ -1316,50 +1337,51 @@ DbgScope *DwarfDebug::getOrCreateAbstractScope(MDNode *N) {
/// If there are global variables in this scope then create and insert
/// DIEs for these variables.
DIE *DwarfDebug::updateSubprogramScopeDIE(MDNode *SPNode) {
- DIE *SPDie = ModuleCU->getDIE(SPNode);
- assert(SPDie && "Unable to find subprogram DIE!");
- DISubprogram SP(SPNode);
+ DIE *SPDie = ModuleCU->getDIE(SPNode);
+ assert(SPDie && "Unable to find subprogram DIE!");
+ DISubprogram SP(SPNode);
+
+ // There is not any need to generate specification DIE for a function
+ // defined at compile unit level. If a function is defined inside another
+ // function then gdb prefers the definition at top level and but does not
+ // expect specification DIE in parent function. So avoid creating
+ // specification DIE for a function defined inside a function.
+ if (SP.isDefinition() && !SP.getContext().isCompileUnit() &&
+ !SP.getContext().isFile() && !SP.getContext().isSubprogram()) {
+ addUInt(SPDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
+
+ // Add arguments.
+ DICompositeType SPTy = SP.getType();
+ DIArray Args = SPTy.getTypeArray();
+ unsigned SPTag = SPTy.getTag();
+ if (SPTag == dwarf::DW_TAG_subroutine_type)
+ for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) {
+ DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter);
+ DIType ATy = DIType(DIType(Args.getElement(i).getNode()));
+ addType(Arg, ATy);
+ if (ATy.isArtificial())
+ addUInt(Arg, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1);
+ SPDie->addChild(Arg);
+ }
+ DIE *SPDeclDie = SPDie;
+ SPDie = new DIE(dwarf::DW_TAG_subprogram);
+ addDIEEntry(SPDie, dwarf::DW_AT_specification, dwarf::DW_FORM_ref4,
+ SPDeclDie);
+ ModuleCU->addDie(SPDie);
+ }
+
+ addLabel(SPDie, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr,
+ Asm->GetTempSymbol("func_begin", Asm->getFunctionNumber()));
+ addLabel(SPDie, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr,
+ Asm->GetTempSymbol("func_end", Asm->getFunctionNumber()));
+ const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
+ MachineLocation Location(RI->getFrameRegister(*Asm->MF));
+ addAddress(SPDie, dwarf::DW_AT_frame_base, Location);
+
+ if (!DISubprogram(SPNode).isLocalToUnit())
+ addUInt(SPDie, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1);
- // There is not any need to generate specification DIE for a function
- // defined at compile unit level. If a function is defined inside another
- // function then gdb prefers the definition at top level and but does not
- // expect specification DIE in parent function. So avoid creating
- // specification DIE for a function defined inside a function.
- if (SP.isDefinition() && !SP.getContext().isCompileUnit() &&
- !SP.getContext().isFile() && !SP.getContext().isSubprogram()) {
- addUInt(SPDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
-
- // Add arguments.
- DICompositeType SPTy = SP.getType();
- DIArray Args = SPTy.getTypeArray();
- unsigned SPTag = SPTy.getTag();
- if (SPTag == dwarf::DW_TAG_subroutine_type)
- for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) {
- DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter);
- DIType ATy = DIType(DIType(Args.getElement(i).getNode()));
- addType(Arg, ATy);
- if (ATy.isArtificial())
- addUInt(Arg, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1);
- SPDie->addChild(Arg);
- }
- DIE *SPDeclDie = SPDie;
- SPDie = new DIE(dwarf::DW_TAG_subprogram);
- addDIEEntry(SPDie, dwarf::DW_AT_specification, dwarf::DW_FORM_ref4,
- SPDeclDie);
- ModuleCU->addDie(SPDie);
- }
-
- addLabel(SPDie, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr,
- getDWLabel("func_begin", SubprogramCount));
- addLabel(SPDie, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr,
- getDWLabel("func_end", SubprogramCount));
- MachineLocation Location(RI->getFrameRegister(*MF));
- addAddress(SPDie, dwarf::DW_AT_frame_base, Location);
-
- if (!DISubprogram(SPNode).isLocalToUnit())
- addUInt(SPDie, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1);
-
- return SPDie;
+ return SPDie;
}
/// constructLexicalScope - Construct new DW_TAG_lexical_block
@@ -1377,9 +1399,10 @@ DIE *DwarfDebug::constructLexicalScopeDIE(DbgScope *Scope) {
return ScopeDIE;
addLabel(ScopeDIE, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr,
- Start ? Start : getDWLabel("func_begin", SubprogramCount));
+ Start ? Start : Asm->GetTempSymbol("func_begin",
+ Asm->getFunctionNumber()));
addLabel(ScopeDIE, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr,
- End ? End : getDWLabel("func_end", SubprogramCount));
+ End ? End : Asm->GetTempSymbol("func_end",Asm->getFunctionNumber()));
return ScopeDIE;
}
@@ -1510,6 +1533,31 @@ DIE *DwarfDebug::constructVariableDIE(DbgVariable *DV, DbgScope *Scope) {
if (MCSymbol *VS = DV->getDbgValueLabel())
addLabel(VariableDie, dwarf::DW_AT_start_scope, dwarf::DW_FORM_addr,
VS);
+ } else if (DbgValueInsn->getOperand(0).getType() ==
+ MachineOperand::MO_FPImmediate) {
+ DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
+ APFloat FPImm = DbgValueInsn->getOperand(0).getFPImm()->getValueAPF();
+
+ // Get the raw data form of the floating point.
+ const APInt FltVal = FPImm.bitcastToAPInt();
+ const char *FltPtr = (const char*)FltVal.getRawData();
+
+ unsigned NumBytes = FltVal.getBitWidth() / 8; // 8 bits per byte.
+ bool LittleEndian = Asm->getTargetData().isLittleEndian();
+ int Incr = (LittleEndian ? 1 : -1);
+ int Start = (LittleEndian ? 0 : NumBytes - 1);
+ int Stop = (LittleEndian ? NumBytes : -1);
+
+ // Output the constant to DWARF one byte at a time.
+ for (; Start != Stop; Start += Incr)
+ addUInt(Block, 0, dwarf::DW_FORM_data1,
+ (unsigned char)0xFF & FltPtr[Start]);
+
+ addBlock(VariableDie, dwarf::DW_AT_const_value, 0, Block);
+
+ if (MCSymbol *VS = DV->getDbgValueLabel())
+ addLabel(VariableDie, dwarf::DW_AT_start_scope, dwarf::DW_FORM_addr,
+ VS);
} else {
//FIXME : Handle other operand types.
delete VariableDie;
@@ -1519,7 +1567,8 @@ DIE *DwarfDebug::constructVariableDIE(DbgVariable *DV, DbgScope *Scope) {
} else {
MachineLocation Location;
unsigned FrameReg;
- int Offset = RI->getFrameIndexReference(*MF, DV->getFrameIndex(),
+ const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
+ int Offset = RI->getFrameIndexReference(*Asm->MF, DV->getFrameIndex(),
FrameReg);
Location.set(FrameReg, Offset);
@@ -1667,10 +1716,9 @@ void DwarfDebug::constructCompileUnit(MDNode *N) {
addUInt(Die, dwarf::DW_AT_language, dwarf::DW_FORM_data1,
DIUnit.getLanguage());
addString(Die, dwarf::DW_AT_name, dwarf::DW_FORM_string, FN);
- addLabel(Die, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr,
- getTempLabel("text_begin"));
+ addLabel(Die, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, TextSectionSym);
addLabel(Die, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr,
- getTempLabel("text_end"));
+ Asm->GetTempSymbol("text_end"));
// DW_AT_stmt_list is a offset of line number information for this
// compile unit in debug_line section. It is always zero when only one
// compile unit is emitted in one object file.
@@ -1780,25 +1828,37 @@ void DwarfDebug::constructSubprogramDIE(MDNode *N) {
/// beginModule - Emit all Dwarf sections that should come prior to the
/// content. Create global DIEs and emit initial debug info sections.
/// This is inovked by the target AsmPrinter.
-void DwarfDebug::beginModule(Module *M, MachineModuleInfo *mmi) {
- this->M = M;
-
- if (!MAI->doesSupportDebugInformation())
- return;
-
+void DwarfDebug::beginModule(Module *M) {
TimeRegion Timer(DebugTimer);
-
+
DebugInfoFinder DbgFinder;
DbgFinder.processModule(*M);
+ bool HasDebugInfo = false;
+
+ // Scan all the compile-units to see if there are any marked as the main unit.
+ // if not, we do not generate debug info.
+ for (DebugInfoFinder::iterator I = DbgFinder.compile_unit_begin(),
+ E = DbgFinder.compile_unit_end(); I != E; ++I) {
+ if (DICompileUnit(*I).isMain()) {
+ HasDebugInfo = true;
+ break;
+ }
+ }
+
+ if (!HasDebugInfo) return;
+
+ // Tell MMI that we have debug info.
+ MMI->setDebugInfoAvailability(true);
+
+ // Emit initial sections.
+ EmitSectionLabels();
+
// Create all the compile unit DIEs.
for (DebugInfoFinder::iterator I = DbgFinder.compile_unit_begin(),
E = DbgFinder.compile_unit_end(); I != E; ++I)
constructCompileUnit(*I);
- if (!ModuleCU)
- return;
-
// Create DIEs for each subprogram.
for (DebugInfoFinder::iterator I = DbgFinder.subprogram_begin(),
E = DbgFinder.subprogram_end(); I != E; ++I)
@@ -1809,16 +1869,12 @@ void DwarfDebug::beginModule(Module *M, MachineModuleInfo *mmi) {
E = DbgFinder.global_variable_end(); I != E; ++I)
constructGlobalVariableDIE(*I);
- MMI = mmi;
- shouldEmit = true;
- MMI->setDebugInfoAvailability(true);
-
// Prime section data.
SectionMap.insert(Asm->getObjFileLowering().getTextSection());
// Print out .file directives to specify files for .loc directives. These are
// printed out early so that they precede any .loc directives.
- if (MAI->hasDotLocAndDotFile()) {
+ if (Asm->MAI->hasDotLocAndDotFile()) {
for (unsigned i = 1, e = getNumSourceIds()+1; i != e; ++i) {
// Remember source id starts at 1.
std::pair<unsigned, unsigned> Id = getSourceDirectoryAndFileIds(i);
@@ -1832,9 +1888,6 @@ void DwarfDebug::beginModule(Module *M, MachineModuleInfo *mmi) {
Asm->OutStreamer.EmitDwarfFileDirective(i, FullPath.str());
}
}
-
- // Emit initial sections
- emitInitial();
}
/// endModule - Emit all Dwarf sections that should come after the content.
@@ -1871,14 +1924,14 @@ void DwarfDebug::endModule() {
// Standard sections final addresses.
Asm->OutStreamer.SwitchSection(Asm->getObjFileLowering().getTextSection());
- Asm->OutStreamer.EmitLabel(getTempLabel("text_end"));
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("text_end"));
Asm->OutStreamer.SwitchSection(Asm->getObjFileLowering().getDataSection());
- Asm->OutStreamer.EmitLabel(getTempLabel("data_end"));
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("data_end"));
// End text sections.
for (unsigned i = 1, N = SectionMap.size(); i <= N; ++i) {
Asm->OutStreamer.SwitchSection(SectionMap[i]);
- Asm->OutStreamer.EmitLabel(getDWLabel("section_end", i));
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("section_end", i));
}
// Emit common frame information.
@@ -1975,9 +2028,7 @@ DbgVariable *DwarfDebug::findAbstractVariable(DIVariable &Var,
/// collectVariableInfo - Populate DbgScope entries with variables' info.
void DwarfDebug::collectVariableInfo() {
- if (!MMI) return;
-
- const LLVMContext &Ctx = MF->getFunction()->getContext();
+ const LLVMContext &Ctx = Asm->MF->getFunction()->getContext();
MachineModuleInfo::VariableDbgInfoMapTy &VMap = MMI->getVariableDbgInfo();
for (MachineModuleInfo::VariableDbgInfoMapTy::iterator VI = VMap.begin(),
@@ -2003,7 +2054,7 @@ void DwarfDebug::collectVariableInfo() {
}
// Collect variable information from DBG_VALUE machine instructions;
- for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
+ for (MachineFunction::const_iterator I = Asm->MF->begin(), E = Asm->MF->end();
I != E; ++I) {
for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
II != IE; ++II) {
@@ -2055,7 +2106,7 @@ void DwarfDebug::beginScope(const MachineInstr *MI) {
if (DL == PrevInstLoc)
return;
- MDNode *Scope = DL.getScope(MF->getFunction()->getContext());
+ MDNode *Scope = DL.getScope(Asm->MF->getFunction()->getContext());
// FIXME: Should only verify each scope once!
if (!DIScope(Scope).Verify())
@@ -2148,10 +2199,10 @@ bool DwarfDebug::extractScopeInformation() {
DenseMap<const MachineInstr *, unsigned> MIIndexMap;
unsigned MIIndex = 0;
- LLVMContext &Ctx = MF->getFunction()->getContext();
+ LLVMContext &Ctx = Asm->MF->getFunction()->getContext();
// Scan each instruction and create scopes. First build working set of scopes.
- for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
+ for (MachineFunction::const_iterator I = Asm->MF->begin(), E = Asm->MF->end();
I != E; ++I) {
for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
II != IE; ++II) {
@@ -2175,7 +2226,7 @@ bool DwarfDebug::extractScopeInformation() {
// Build scope hierarchy using working set of scopes.
- for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
+ for (MachineFunction::const_iterator I = Asm->MF->begin(), E = Asm->MF->end();
I != E; ++I) {
for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
II != IE; ++II) {
@@ -2243,18 +2294,17 @@ bool DwarfDebug::extractScopeInformation() {
/// beginFunction - Gather pre-function debug information. Assumes being
/// emitted immediately after the function entry point.
void DwarfDebug::beginFunction(const MachineFunction *MF) {
- this->MF = MF;
-
- if (!ShouldEmitDwarfDebug()) return;
+ if (!MMI->hasDebugInfo()) return;
+
+ TimeRegion Timer(DebugTimer);
if (!extractScopeInformation())
return;
- TimeRegion Timer(DebugTimer);
-
collectVariableInfo();
// Assumes in correct section after the entry point.
- Asm->OutStreamer.EmitLabel(getDWLabel("func_begin", ++SubprogramCount));
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("func_begin",
+ Asm->getFunctionNumber()));
// Emit label for the implicitly defined dbg.stoppoint at the start of the
// function.
@@ -2279,14 +2329,15 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) {
/// endFunction - Gather and emit post-function debug information.
///
void DwarfDebug::endFunction(const MachineFunction *MF) {
- if (!ShouldEmitDwarfDebug()) return;
- if (DbgScopeMap.empty()) return;
+ if (!MMI->hasDebugInfo() ||
+ DbgScopeMap.empty()) return;
TimeRegion Timer(DebugTimer);
if (CurrentFnDbgScope) {
// Define end label for subprogram.
- Asm->OutStreamer.EmitLabel(getDWLabel("func_end", SubprogramCount));
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("func_end",
+ Asm->getFunctionNumber()));
// Get function line info.
if (!Lines.empty()) {
@@ -2306,7 +2357,7 @@ void DwarfDebug::endFunction(const MachineFunction *MF) {
constructScopeDIE(CurrentFnDbgScope);
- DebugFrames.push_back(FunctionDebugFrameInfo(SubprogramCount,
+ DebugFrames.push_back(FunctionDebugFrameInfo(Asm->getFunctionNumber(),
MMI->getFrameMoves()));
}
@@ -2327,9 +2378,6 @@ void DwarfDebug::endFunction(const MachineFunction *MF) {
/// unique label that was emitted and which provides correspondence to
/// the source line list.
MCSymbol *DwarfDebug::recordSourceLine(unsigned Line, unsigned Col, MDNode *S) {
- if (!MMI)
- return 0;
-
TimeRegion Timer(DebugTimer);
StringRef Dir;
@@ -2404,7 +2452,7 @@ DwarfDebug::computeSizeAndOffset(DIE *Die, unsigned Offset, bool Last) {
// Size the DIE attribute values.
for (unsigned i = 0, N = Values.size(); i < N; ++i)
// Size attribute value.
- Offset += Values[i]->SizeOf(TD, AbbrevData[i].getForm());
+ Offset += Values[i]->SizeOf(Asm, AbbrevData[i].getForm());
// Size the DIE children if any.
if (!Children.empty()) {
@@ -2436,50 +2484,48 @@ void DwarfDebug::computeSizeAndOffsets() {
CompileUnitOffsets[ModuleCU] = 0;
}
-/// emitInitial - Emit initial Dwarf declarations. This is necessary for cc
-/// tools to recognize the object file contains Dwarf information.
-void DwarfDebug::emitInitial() {
- // Check to see if we already emitted intial headers.
- if (didInitial) return;
- didInitial = true;
+/// EmitSectionSym - Switch to the specified MCSection and emit an assembler
+/// temporary label to it if SymbolStem is specified.
+static MCSymbol *EmitSectionSym(AsmPrinter *Asm, const MCSection *Section,
+ const char *SymbolStem = 0) {
+ Asm->OutStreamer.SwitchSection(Section);
+ if (!SymbolStem) return 0;
+
+ MCSymbol *TmpSym = Asm->GetTempSymbol(SymbolStem);
+ Asm->OutStreamer.EmitLabel(TmpSym);
+ return TmpSym;
+}
+/// EmitSectionLabels - Emit initial Dwarf sections with a label at
+/// the start of each one.
+void DwarfDebug::EmitSectionLabels() {
const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
// Dwarf sections base addresses.
- if (MAI->doesDwarfRequireFrameSection()) {
- Asm->OutStreamer.SwitchSection(TLOF.getDwarfFrameSection());
- Asm->OutStreamer.EmitLabel(getTempLabel("section_debug_frame"));
- }
-
- Asm->OutStreamer.SwitchSection(TLOF.getDwarfInfoSection());
- Asm->OutStreamer.EmitLabel(getTempLabel("section_info"));
- Asm->OutStreamer.SwitchSection(TLOF.getDwarfAbbrevSection());
- Asm->OutStreamer.EmitLabel(getTempLabel("section_abbrev"));
- Asm->OutStreamer.SwitchSection(TLOF.getDwarfARangesSection());
- Asm->OutStreamer.EmitLabel(getTempLabel("section_aranges"));
-
- if (const MCSection *LineInfoDirective = TLOF.getDwarfMacroInfoSection()) {
- Asm->OutStreamer.SwitchSection(LineInfoDirective);
- Asm->OutStreamer.EmitLabel(getTempLabel("section_macinfo"));
- }
-
- Asm->OutStreamer.SwitchSection(TLOF.getDwarfLineSection());
- Asm->OutStreamer.EmitLabel(getTempLabel("section_line"));
- Asm->OutStreamer.SwitchSection(TLOF.getDwarfLocSection());
- Asm->OutStreamer.EmitLabel(getTempLabel("section_loc"));
- Asm->OutStreamer.SwitchSection(TLOF.getDwarfPubNamesSection());
- Asm->OutStreamer.EmitLabel(getTempLabel("section_pubnames"));
- Asm->OutStreamer.SwitchSection(TLOF.getDwarfPubTypesSection());
- Asm->OutStreamer.EmitLabel(getTempLabel("section_pubtypes"));
- Asm->OutStreamer.SwitchSection(TLOF.getDwarfStrSection());
- Asm->OutStreamer.EmitLabel(getTempLabel("section_str"));
- Asm->OutStreamer.SwitchSection(TLOF.getDwarfRangesSection());
- Asm->OutStreamer.EmitLabel(getTempLabel("section_ranges"));
-
- Asm->OutStreamer.SwitchSection(TLOF.getTextSection());
- Asm->OutStreamer.EmitLabel(getTempLabel("text_begin"));
- Asm->OutStreamer.SwitchSection(TLOF.getDataSection());
- Asm->OutStreamer.EmitLabel(getTempLabel("data_begin"));
+ if (Asm->MAI->doesDwarfRequireFrameSection()) {
+ DwarfFrameSectionSym =
+ EmitSectionSym(Asm, TLOF.getDwarfFrameSection(), "section_debug_frame");
+ }
+
+ DwarfInfoSectionSym =
+ EmitSectionSym(Asm, TLOF.getDwarfInfoSection(), "section_info");
+ DwarfAbbrevSectionSym =
+ EmitSectionSym(Asm, TLOF.getDwarfAbbrevSection(), "section_abbrev");
+ EmitSectionSym(Asm, TLOF.getDwarfARangesSection());
+
+ if (const MCSection *MacroInfo = TLOF.getDwarfMacroInfoSection())
+ EmitSectionSym(Asm, MacroInfo);
+
+ EmitSectionSym(Asm, TLOF.getDwarfLineSection());
+ EmitSectionSym(Asm, TLOF.getDwarfLocSection());
+ EmitSectionSym(Asm, TLOF.getDwarfPubNamesSection());
+ EmitSectionSym(Asm, TLOF.getDwarfPubTypesSection());
+ DwarfStrSectionSym =
+ EmitSectionSym(Asm, TLOF.getDwarfStrSection(), "section_str");
+ EmitSectionSym(Asm, TLOF.getDwarfRangesSection());
+
+ TextSectionSym = EmitSectionSym(Asm, TLOF.getTextSection(), "text_begin");
+ EmitSectionSym(Asm, TLOF.getDataSection());
}
/// emitDIE - Recusively Emits a debug information entry.
@@ -2490,12 +2536,12 @@ void DwarfDebug::emitDIE(DIE *Die) {
const DIEAbbrev *Abbrev = Abbreviations[AbbrevNumber - 1];
// Emit the code (index) for the abbreviation.
- if (Asm->VerboseAsm)
+ if (Asm->isVerbose())
Asm->OutStreamer.AddComment("Abbrev [" + Twine(AbbrevNumber) + "] 0x" +
Twine::utohexstr(Die->getOffset()) + ":0x" +
Twine::utohexstr(Die->getSize()) + " " +
dwarf::TagString(Abbrev->getTag()));
- EmitULEB128(AbbrevNumber);
+ Asm->EmitULEB128(AbbrevNumber);
const SmallVector<DIEValue*, 32> &Values = Die->getValues();
const SmallVector<DIEAbbrevData, 8> &AbbrevData = Abbrev->getData();
@@ -2506,7 +2552,7 @@ void DwarfDebug::emitDIE(DIE *Die) {
unsigned Form = AbbrevData[i].getForm();
assert(Form && "Too many attributes for DIE (check abbreviation)");
- if (Asm->VerboseAsm)
+ if (Asm->isVerbose())
Asm->OutStreamer.AddComment(dwarf::AttributeString(Attr));
switch (Attr) {
@@ -2522,7 +2568,7 @@ void DwarfDebug::emitDIE(DIE *Die) {
}
default:
// Emit an attribute using the defined form.
- Values[i]->EmitValue(this, Form);
+ Values[i]->EmitValue(Asm, Form);
break;
}
}
@@ -2534,7 +2580,7 @@ void DwarfDebug::emitDIE(DIE *Die) {
for (unsigned j = 0, M = Children.size(); j < M; ++j)
emitDIE(Children[j]);
- if (Asm->VerboseAsm)
+ if (Asm->isVerbose())
Asm->OutStreamer.AddComment("End Of Children Mark");
Asm->EmitInt8(0);
}
@@ -2549,7 +2595,8 @@ void DwarfDebug::emitDebugInfo() {
DIE *Die = ModuleCU->getCUDie();
// Emit the compile units header.
- Asm->OutStreamer.EmitLabel(getDWLabel("info_begin", ModuleCU->getID()));
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("info_begin",
+ ModuleCU->getID()));
// Emit size of content not including length itself
unsigned ContentSize = Die->getSize() +
@@ -2563,10 +2610,10 @@ void DwarfDebug::emitDebugInfo() {
Asm->OutStreamer.AddComment("DWARF version number");
Asm->EmitInt16(dwarf::DWARF_VERSION);
Asm->OutStreamer.AddComment("Offset Into Abbrev. Section");
- EmitSectionOffset(getTempLabel("abbrev_begin"),getTempLabel("section_abbrev"),
- true);
+ Asm->EmitSectionOffset(Asm->GetTempSymbol("abbrev_begin"),
+ DwarfAbbrevSectionSym);
Asm->OutStreamer.AddComment("Address Size (in bytes)");
- Asm->EmitInt8(TD->getPointerSize());
+ Asm->EmitInt8(Asm->getTargetData().getPointerSize());
emitDIE(Die);
// FIXME - extra padding for gdb bug.
@@ -2575,7 +2622,7 @@ void DwarfDebug::emitDebugInfo() {
Asm->EmitInt8(0);
Asm->EmitInt8(0);
Asm->EmitInt8(0);
- Asm->OutStreamer.EmitLabel(getDWLabel("info_end", ModuleCU->getID()));
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("info_end", ModuleCU->getID()));
}
/// emitAbbreviations - Emit the abbreviation section.
@@ -2587,7 +2634,7 @@ void DwarfDebug::emitAbbreviations() const {
Asm->OutStreamer.SwitchSection(
Asm->getObjFileLowering().getDwarfAbbrevSection());
- Asm->OutStreamer.EmitLabel(getTempLabel("abbrev_begin"));
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("abbrev_begin"));
// For each abbrevation.
for (unsigned i = 0, N = Abbreviations.size(); i < N; ++i) {
@@ -2595,16 +2642,16 @@ void DwarfDebug::emitAbbreviations() const {
const DIEAbbrev *Abbrev = Abbreviations[i];
// Emit the abbrevations code (base 1 index.)
- EmitULEB128(Abbrev->getNumber(), "Abbreviation Code");
+ Asm->EmitULEB128(Abbrev->getNumber(), "Abbreviation Code");
// Emit the abbreviations data.
- Abbrev->Emit(this);
+ Abbrev->Emit(Asm);
}
// Mark end of abbreviations.
- EmitULEB128(0, "EOM(3)");
+ Asm->EmitULEB128(0, "EOM(3)");
- Asm->OutStreamer.EmitLabel(getTempLabel("abbrev_end"));
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("abbrev_end"));
}
}
@@ -2617,14 +2664,15 @@ void DwarfDebug::emitEndOfLineMatrix(unsigned SectionEnd) {
Asm->EmitInt8(0);
Asm->OutStreamer.AddComment("Op size");
- Asm->EmitInt8(TD->getPointerSize() + 1);
+ Asm->EmitInt8(Asm->getTargetData().getPointerSize() + 1);
Asm->OutStreamer.AddComment("DW_LNE_set_address");
Asm->EmitInt8(dwarf::DW_LNE_set_address);
Asm->OutStreamer.AddComment("Section end label");
- Asm->OutStreamer.EmitSymbolValue(getDWLabel("section_end", SectionEnd),
- TD->getPointerSize(), 0/*AddrSpace*/);
+ Asm->OutStreamer.EmitSymbolValue(Asm->GetTempSymbol("section_end",SectionEnd),
+ Asm->getTargetData().getPointerSize(),
+ 0/*AddrSpace*/);
// Mark end of matrix.
Asm->OutStreamer.AddComment("DW_LNE_end_sequence");
@@ -2638,7 +2686,7 @@ void DwarfDebug::emitEndOfLineMatrix(unsigned SectionEnd) {
void DwarfDebug::emitDebugLines() {
// If the target is using .loc/.file, the assembler will be emitting the
// .debug_line table automatically.
- if (MAI->hasDotLocAndDotFile())
+ if (Asm->MAI->hasDotLocAndDotFile())
return;
// Minimum line delta, thus ranging from -10..(255-10).
@@ -2652,16 +2700,17 @@ void DwarfDebug::emitDebugLines() {
// Construct the section header.
Asm->OutStreamer.AddComment("Length of Source Line Info");
- EmitDifference(getTempLabel("line_end"), getTempLabel("line_begin"), true);
- Asm->OutStreamer.EmitLabel(getTempLabel("line_begin"));
+ Asm->EmitLabelDifference(Asm->GetTempSymbol("line_end"),
+ Asm->GetTempSymbol("line_begin"), 4);
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("line_begin"));
Asm->OutStreamer.AddComment("DWARF version number");
Asm->EmitInt16(dwarf::DWARF_VERSION);
Asm->OutStreamer.AddComment("Prolog Length");
- EmitDifference(getTempLabel("line_prolog_end"),
- getTempLabel("line_prolog_begin"), true);
- Asm->OutStreamer.EmitLabel(getTempLabel("line_prolog_begin"));
+ Asm->EmitLabelDifference(Asm->GetTempSymbol("line_prolog_end"),
+ Asm->GetTempSymbol("line_prolog_begin"), 4);
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("line_prolog_begin"));
Asm->OutStreamer.AddComment("Minimum Instruction Length");
Asm->EmitInt8(1);
@@ -2697,7 +2746,7 @@ void DwarfDebug::emitDebugLines() {
// Emit directories.
for (unsigned DI = 1, DE = getNumSourceDirectories()+1; DI != DE; ++DI) {
const std::string &Dir = getSourceDirectoryName(DI);
- if (Asm->VerboseAsm) Asm->OutStreamer.AddComment("Directory");
+ if (Asm->isVerbose()) Asm->OutStreamer.AddComment("Directory");
Asm->OutStreamer.EmitBytes(StringRef(Dir.c_str(), Dir.size()+1), 0);
}
@@ -2709,18 +2758,18 @@ void DwarfDebug::emitDebugLines() {
// Remember source id starts at 1.
std::pair<unsigned, unsigned> Id = getSourceDirectoryAndFileIds(SI);
const std::string &FN = getSourceFileName(Id.second);
- if (Asm->VerboseAsm) Asm->OutStreamer.AddComment("Source");
+ if (Asm->isVerbose()) Asm->OutStreamer.AddComment("Source");
Asm->OutStreamer.EmitBytes(StringRef(FN.c_str(), FN.size()+1), 0);
- EmitULEB128(Id.first, "Directory #");
- EmitULEB128(0, "Mod date");
- EmitULEB128(0, "File size");
+ Asm->EmitULEB128(Id.first, "Directory #");
+ Asm->EmitULEB128(0, "Mod date");
+ Asm->EmitULEB128(0, "File size");
}
Asm->OutStreamer.AddComment("End of files");
Asm->EmitInt8(0);
- Asm->OutStreamer.EmitLabel(getTempLabel("line_prolog_end"));
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("line_prolog_end"));
// A sequence for each text section.
unsigned SecSrcLinesSize = SectionSourceLines.size();
@@ -2754,13 +2803,14 @@ void DwarfDebug::emitDebugLines() {
Asm->OutStreamer.AddComment("Extended Op");
Asm->EmitInt8(0);
Asm->OutStreamer.AddComment("Op size");
- Asm->EmitInt8(TD->getPointerSize() + 1);
+ Asm->EmitInt8(Asm->getTargetData().getPointerSize() + 1);
Asm->OutStreamer.AddComment("DW_LNE_set_address");
Asm->EmitInt8(dwarf::DW_LNE_set_address);
Asm->OutStreamer.AddComment("Location label");
- Asm->OutStreamer.EmitSymbolValue(Label, TD->getPointerSize(),
+ Asm->OutStreamer.EmitSymbolValue(Label,
+ Asm->getTargetData().getPointerSize(),
0/*AddrSpace*/);
// If change of source, then switch to the new source.
@@ -2768,7 +2818,7 @@ void DwarfDebug::emitDebugLines() {
Source = LineInfo.getSourceID();
Asm->OutStreamer.AddComment("DW_LNS_set_file");
Asm->EmitInt8(dwarf::DW_LNS_set_file);
- EmitULEB128(Source, "New Source");
+ Asm->EmitULEB128(Source, "New Source");
}
// If change of line.
@@ -2789,7 +2839,7 @@ void DwarfDebug::emitDebugLines() {
// ... otherwise use long hand.
Asm->OutStreamer.AddComment("DW_LNS_advance_line");
Asm->EmitInt8(dwarf::DW_LNS_advance_line);
- EmitSLEB128(Offset, "Line Offset");
+ Asm->EmitSLEB128(Offset, "Line Offset");
Asm->OutStreamer.AddComment("DW_LNS_copy");
Asm->EmitInt8(dwarf::DW_LNS_copy);
}
@@ -2809,55 +2859,56 @@ void DwarfDebug::emitDebugLines() {
// put into it, emit an empty table.
emitEndOfLineMatrix(1);
- Asm->OutStreamer.EmitLabel(getTempLabel("line_end"));
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("line_end"));
}
/// emitCommonDebugFrame - Emit common frame info into a debug frame section.
///
void DwarfDebug::emitCommonDebugFrame() {
- if (!MAI->doesDwarfRequireFrameSection())
+ if (!Asm->MAI->doesDwarfRequireFrameSection())
return;
- int stackGrowth =
- Asm->TM.getFrameInfo()->getStackGrowthDirection() ==
- TargetFrameInfo::StackGrowsUp ?
- TD->getPointerSize() : -TD->getPointerSize();
+ int stackGrowth = Asm->getTargetData().getPointerSize();
+ if (Asm->TM.getFrameInfo()->getStackGrowthDirection() ==
+ TargetFrameInfo::StackGrowsDown)
+ stackGrowth *= -1;
// Start the dwarf frame section.
Asm->OutStreamer.SwitchSection(
Asm->getObjFileLowering().getDwarfFrameSection());
- Asm->OutStreamer.EmitLabel(getTempLabel("debug_frame_common"));
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("debug_frame_common"));
Asm->OutStreamer.AddComment("Length of Common Information Entry");
- EmitDifference(getTempLabel("debug_frame_common_end"),
- getTempLabel("debug_frame_common_begin"), true);
+ Asm->EmitLabelDifference(Asm->GetTempSymbol("debug_frame_common_end"),
+ Asm->GetTempSymbol("debug_frame_common_begin"), 4);
- Asm->OutStreamer.EmitLabel(getTempLabel("debug_frame_common_begin"));
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("debug_frame_common_begin"));
Asm->OutStreamer.AddComment("CIE Identifier Tag");
Asm->EmitInt32((int)dwarf::DW_CIE_ID);
Asm->OutStreamer.AddComment("CIE Version");
Asm->EmitInt8(dwarf::DW_CIE_VERSION);
Asm->OutStreamer.AddComment("CIE Augmentation");
Asm->OutStreamer.EmitIntValue(0, 1, /*addrspace*/0); // nul terminator.
- EmitULEB128(1, "CIE Code Alignment Factor");
- EmitSLEB128(stackGrowth, "CIE Data Alignment Factor");
+ Asm->EmitULEB128(1, "CIE Code Alignment Factor");
+ Asm->EmitSLEB128(stackGrowth, "CIE Data Alignment Factor");
Asm->OutStreamer.AddComment("CIE RA Column");
+ const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
Asm->EmitInt8(RI->getDwarfRegNum(RI->getRARegister(), false));
std::vector<MachineMove> Moves;
RI->getInitialFrameState(Moves);
- EmitFrameMoves(0, Moves, false);
+ Asm->EmitFrameMoves(Moves, 0, false);
Asm->EmitAlignment(2, 0, 0, false);
- Asm->OutStreamer.EmitLabel(getTempLabel("debug_frame_common_end"));
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("debug_frame_common_end"));
}
/// emitFunctionDebugFrame - Emit per function frame info into a debug frame
/// section.
void DwarfDebug::
emitFunctionDebugFrame(const FunctionDebugFrameInfo &DebugFrameInfo) {
- if (!MAI->doesDwarfRequireFrameSection())
+ if (!Asm->MAI->doesDwarfRequireFrameSection())
return;
// Start the dwarf frame section.
@@ -2866,27 +2917,30 @@ emitFunctionDebugFrame(const FunctionDebugFrameInfo &DebugFrameInfo) {
Asm->OutStreamer.AddComment("Length of Frame Information Entry");
MCSymbol *DebugFrameBegin =
- getDWLabel("debug_frame_begin", DebugFrameInfo.Number);
+ Asm->GetTempSymbol("debug_frame_begin", DebugFrameInfo.Number);
MCSymbol *DebugFrameEnd =
- getDWLabel("debug_frame_end", DebugFrameInfo.Number);
- EmitDifference(DebugFrameEnd, DebugFrameBegin, true);
+ Asm->GetTempSymbol("debug_frame_end", DebugFrameInfo.Number);
+ Asm->EmitLabelDifference(DebugFrameEnd, DebugFrameBegin, 4);
Asm->OutStreamer.EmitLabel(DebugFrameBegin);
Asm->OutStreamer.AddComment("FDE CIE offset");
- EmitSectionOffset(getTempLabel("debug_frame_common"),
- getTempLabel("section_debug_frame"), true);
+ Asm->EmitSectionOffset(Asm->GetTempSymbol("debug_frame_common"),
+ DwarfFrameSectionSym);
Asm->OutStreamer.AddComment("FDE initial location");
- MCSymbol *FuncBeginSym = getDWLabel("func_begin", DebugFrameInfo.Number);
+ MCSymbol *FuncBeginSym =
+ Asm->GetTempSymbol("func_begin", DebugFrameInfo.Number);
Asm->OutStreamer.EmitSymbolValue(FuncBeginSym,
- TD->getPointerSize(), 0/*AddrSpace*/);
+ Asm->getTargetData().getPointerSize(),
+ 0/*AddrSpace*/);
Asm->OutStreamer.AddComment("FDE address range");
- EmitDifference(getDWLabel("func_end", DebugFrameInfo.Number), FuncBeginSym);
+ Asm->EmitLabelDifference(Asm->GetTempSymbol("func_end",DebugFrameInfo.Number),
+ FuncBeginSym, Asm->getTargetData().getPointerSize());
- EmitFrameMoves(FuncBeginSym, DebugFrameInfo.Moves, false);
+ Asm->EmitFrameMoves(DebugFrameInfo.Moves, FuncBeginSym, false);
Asm->EmitAlignment(2, 0, 0, false);
Asm->OutStreamer.EmitLabel(DebugFrameEnd);
@@ -2900,22 +2954,24 @@ void DwarfDebug::emitDebugPubNames() {
Asm->getObjFileLowering().getDwarfPubNamesSection());
Asm->OutStreamer.AddComment("Length of Public Names Info");
- EmitDifference(getDWLabel("pubnames_end", ModuleCU->getID()),
- getDWLabel("pubnames_begin", ModuleCU->getID()), true);
+ Asm->EmitLabelDifference(
+ Asm->GetTempSymbol("pubnames_end", ModuleCU->getID()),
+ Asm->GetTempSymbol("pubnames_begin", ModuleCU->getID()), 4);
- Asm->OutStreamer.EmitLabel(getDWLabel("pubnames_begin", ModuleCU->getID()));
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("pubnames_begin",
+ ModuleCU->getID()));
Asm->OutStreamer.AddComment("DWARF Version");
Asm->EmitInt16(dwarf::DWARF_VERSION);
Asm->OutStreamer.AddComment("Offset of Compilation Unit Info");
- EmitSectionOffset(getDWLabel("info_begin", ModuleCU->getID()),
- getTempLabel("section_info"), true);
+ Asm->EmitSectionOffset(Asm->GetTempSymbol("info_begin", ModuleCU->getID()),
+ DwarfInfoSectionSym);
Asm->OutStreamer.AddComment("Compilation Unit Length");
- EmitDifference(getDWLabel("info_end", ModuleCU->getID()),
- getDWLabel("info_begin", ModuleCU->getID()),
- true);
+ Asm->EmitLabelDifference(Asm->GetTempSymbol("info_end", ModuleCU->getID()),
+ Asm->GetTempSymbol("info_begin", ModuleCU->getID()),
+ 4);
const StringMap<DIE*> &Globals = ModuleCU->getGlobals();
for (StringMap<DIE*>::const_iterator
@@ -2926,14 +2982,15 @@ void DwarfDebug::emitDebugPubNames() {
Asm->OutStreamer.AddComment("DIE offset");
Asm->EmitInt32(Entity->getOffset());
- if (Asm->VerboseAsm)
+ if (Asm->isVerbose())
Asm->OutStreamer.AddComment("External Name");
Asm->OutStreamer.EmitBytes(StringRef(Name, strlen(Name)+1), 0);
}
Asm->OutStreamer.AddComment("End Mark");
Asm->EmitInt32(0);
- Asm->OutStreamer.EmitLabel(getDWLabel("pubnames_end", ModuleCU->getID()));
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("pubnames_end",
+ ModuleCU->getID()));
}
void DwarfDebug::emitDebugPubTypes() {
@@ -2941,22 +2998,24 @@ void DwarfDebug::emitDebugPubTypes() {
Asm->OutStreamer.SwitchSection(
Asm->getObjFileLowering().getDwarfPubTypesSection());
Asm->OutStreamer.AddComment("Length of Public Types Info");
- EmitDifference(getDWLabel("pubtypes_end", ModuleCU->getID()),
- getDWLabel("pubtypes_begin", ModuleCU->getID()), true);
+ Asm->EmitLabelDifference(
+ Asm->GetTempSymbol("pubtypes_end", ModuleCU->getID()),
+ Asm->GetTempSymbol("pubtypes_begin", ModuleCU->getID()), 4);
- Asm->OutStreamer.EmitLabel(getDWLabel("pubtypes_begin", ModuleCU->getID()));
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("pubtypes_begin",
+ ModuleCU->getID()));
- if (Asm->VerboseAsm) Asm->OutStreamer.AddComment("DWARF Version");
+ if (Asm->isVerbose()) Asm->OutStreamer.AddComment("DWARF Version");
Asm->EmitInt16(dwarf::DWARF_VERSION);
Asm->OutStreamer.AddComment("Offset of Compilation ModuleCU Info");
- EmitSectionOffset(getDWLabel("info_begin", ModuleCU->getID()),
- getTempLabel("section_info"), true);
+ Asm->EmitSectionOffset(Asm->GetTempSymbol("info_begin", ModuleCU->getID()),
+ DwarfInfoSectionSym);
Asm->OutStreamer.AddComment("Compilation ModuleCU Length");
- EmitDifference(getDWLabel("info_end", ModuleCU->getID()),
- getDWLabel("info_begin", ModuleCU->getID()),
- true);
+ Asm->EmitLabelDifference(Asm->GetTempSymbol("info_end", ModuleCU->getID()),
+ Asm->GetTempSymbol("info_begin", ModuleCU->getID()),
+ 4);
const StringMap<DIE*> &Globals = ModuleCU->getGlobalTypes();
for (StringMap<DIE*>::const_iterator
@@ -2964,16 +3023,17 @@ void DwarfDebug::emitDebugPubTypes() {
const char *Name = GI->getKeyData();
DIE * Entity = GI->second;
- if (Asm->VerboseAsm) Asm->OutStreamer.AddComment("DIE offset");
+ if (Asm->isVerbose()) Asm->OutStreamer.AddComment("DIE offset");
Asm->EmitInt32(Entity->getOffset());
- if (Asm->VerboseAsm) Asm->OutStreamer.AddComment("External Name");
+ if (Asm->isVerbose()) Asm->OutStreamer.AddComment("External Name");
Asm->OutStreamer.EmitBytes(StringRef(Name, GI->getKeyLength()+1), 0);
}
Asm->OutStreamer.AddComment("End Mark");
Asm->EmitInt32(0);
- Asm->OutStreamer.EmitLabel(getDWLabel("pubtypes_end", ModuleCU->getID()));
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("pubtypes_end",
+ ModuleCU->getID()));
}
/// emitDebugStr - Emit visible names into a debug str section.
@@ -3059,7 +3119,7 @@ void DwarfDebug::emitDebugMacInfo() {
/// __debug_info section, and the low_pc is the starting address for the
/// inlining instance.
void DwarfDebug::emitDebugInlineInfo() {
- if (!MAI->doesDwarfUsesInlineInfoSection())
+ if (!Asm->MAI->doesDwarfUsesInlineInfoSection())
return;
if (!ModuleCU)
@@ -3069,15 +3129,15 @@ void DwarfDebug::emitDebugInlineInfo() {
Asm->getObjFileLowering().getDwarfDebugInlineSection());
Asm->OutStreamer.AddComment("Length of Debug Inlined Information Entry");
- EmitDifference(getDWLabel("debug_inlined_end", 1),
- getDWLabel("debug_inlined_begin", 1), true);
+ Asm->EmitLabelDifference(Asm->GetTempSymbol("debug_inlined_end", 1),
+ Asm->GetTempSymbol("debug_inlined_begin", 1), 4);
- Asm->OutStreamer.EmitLabel(getDWLabel("debug_inlined_begin", 1));
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("debug_inlined_begin", 1));
Asm->OutStreamer.AddComment("Dwarf Version");
Asm->EmitInt16(dwarf::DWARF_VERSION);
Asm->OutStreamer.AddComment("Address Size (in bytes)");
- Asm->EmitInt8(TD->getPointerSize());
+ Asm->EmitInt8(Asm->getTargetData().getPointerSize());
for (SmallVector<MDNode *, 4>::iterator I = InlinedSPNodes.begin(),
E = InlinedSPNodes.end(); I != E; ++I) {
@@ -3095,23 +3155,23 @@ void DwarfDebug::emitDebugInlineInfo() {
Asm->OutStreamer.EmitBytes(Name, 0);
Asm->OutStreamer.EmitIntValue(0, 1, 0); // nul terminator.
} else
- EmitSectionOffset(getStringPoolEntry(getRealLinkageName(LName)),
- getTempLabel("section_str"), true);
+ Asm->EmitSectionOffset(getStringPoolEntry(getRealLinkageName(LName)),
+ DwarfStrSectionSym);
Asm->OutStreamer.AddComment("Function name");
- EmitSectionOffset(getStringPoolEntry(Name), getTempLabel("section_str"),
- true);
- EmitULEB128(Labels.size(), "Inline count");
+ Asm->EmitSectionOffset(getStringPoolEntry(Name), DwarfStrSectionSym);
+ Asm->EmitULEB128(Labels.size(), "Inline count");
for (SmallVector<InlineInfoLabels, 4>::iterator LI = Labels.begin(),
LE = Labels.end(); LI != LE; ++LI) {
- if (Asm->VerboseAsm) Asm->OutStreamer.AddComment("DIE offset");
+ if (Asm->isVerbose()) Asm->OutStreamer.AddComment("DIE offset");
Asm->EmitInt32(LI->second->getOffset());
- if (Asm->VerboseAsm) Asm->OutStreamer.AddComment("low_pc");
- Asm->OutStreamer.EmitSymbolValue(LI->first, TD->getPointerSize(), 0);
+ if (Asm->isVerbose()) Asm->OutStreamer.AddComment("low_pc");
+ Asm->OutStreamer.EmitSymbolValue(LI->first,
+ Asm->getTargetData().getPointerSize(),0);
}
}
- Asm->OutStreamer.EmitLabel(getDWLabel("debug_inlined_end", 1));
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("debug_inlined_end", 1));
}
diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.h b/lib/CodeGen/AsmPrinter/DwarfDebug.h
index 03d9d99..c7baf5f 100644
--- a/lib/CodeGen/AsmPrinter/DwarfDebug.h
+++ b/lib/CodeGen/AsmPrinter/DwarfDebug.h
@@ -14,19 +14,14 @@
#ifndef CODEGEN_ASMPRINTER_DWARFDEBUG_H__
#define CODEGEN_ASMPRINTER_DWARFDEBUG_H__
-#include "DIE.h"
-#include "DwarfPrinter.h"
#include "llvm/CodeGen/AsmPrinter.h"
-#include "llvm/CodeGen/MachineLocation.h"
-#include "llvm/Analysis/DebugInfo.h"
-#include "llvm/Support/Allocator.h"
-#include "llvm/Support/raw_ostream.h"
+#include "DIE.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h"
-#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/UniqueVector.h"
-#include <string>
+#include "llvm/Support/Allocator.h"
namespace llvm {
@@ -35,9 +30,27 @@ class DbgConcreteScope;
class DbgScope;
class DbgVariable;
class MachineFrameInfo;
+class MachineLocation;
class MachineModuleInfo;
class MCAsmInfo;
class Timer;
+class DIEAbbrev;
+class DIE;
+class DIEBlock;
+class DIEEntry;
+
+class DIEnumerator;
+class DIDescriptor;
+class DIVariable;
+class DIGlobal;
+class DIGlobalVariable;
+class DISubprogram;
+class DIBasicType;
+class DIDerivedType;
+class DIType;
+class DINameSpace;
+class DISubrange;
+class DICompositeType;
//===----------------------------------------------------------------------===//
/// SrcLineInfo - This class is used to record source line correspondence.
@@ -58,7 +71,13 @@ public:
MCSymbol *getLabel() const { return Label; }
};
-class DwarfDebug : public DwarfPrinter {
+class DwarfDebug {
+ /// Asm - Target of Dwarf emission.
+ AsmPrinter *Asm;
+
+ /// MMI - Collected machine module information.
+ MachineModuleInfo *MMI;
+
//===--------------------------------------------------------------------===//
// Attributes used to construct specific Dwarf sections.
//
@@ -120,14 +139,6 @@ class DwarfDebug : public DwarfPrinter {
///
std::vector<std::vector<SrcLineInfo> > SectionSourceLines;
- /// didInitial - Flag to indicate if initial emission has been done.
- ///
- bool didInitial;
-
- /// shouldEmit - Flag to indicate if debug information should be emitted.
- ///
- bool shouldEmit;
-
// CurrentFnDbgScope - Top level scope for the current function.
//
DbgScope *CurrentFnDbgScope;
@@ -210,6 +221,14 @@ class DwarfDebug : public DwarfPrinter {
std::vector<FunctionDebugFrameInfo> DebugFrames;
+ // Section Symbols: these are assembler temporary labels that are emitted at
+ // the beginning of each supported dwarf section. These are used to form
+ // section offsets and are created by EmitSectionLabels.
+ MCSymbol *DwarfFrameSectionSym, *DwarfInfoSectionSym, *DwarfAbbrevSectionSym;
+ MCSymbol *DwarfStrSectionSym, *TextSectionSym;
+
+private:
+
/// getSourceDirectoryAndFileIds - Return the directory and file ids that
/// maps to the source id. Source id starts at 1.
std::pair<unsigned, unsigned>
@@ -273,10 +292,8 @@ class DwarfDebug : public DwarfPrinter {
/// addDIEEntry - Add a DIE attribute data and value.
///
- void addDIEEntry(DIE *Die, unsigned Attribute, unsigned Form, DIE *Entry) {
- Die->addValue(Attribute, Form, createDIEEntry(Entry));
- }
-
+ void addDIEEntry(DIE *Die, unsigned Attribute, unsigned Form, DIE *Entry);
+
/// addBlock - Add block data.
///
void addBlock(DIE *Die, unsigned Attribute, unsigned Form, DIEBlock *Block);
@@ -396,9 +413,9 @@ class DwarfDebug : public DwarfPrinter {
/// constructScopeDIE - Construct a DIE for this scope.
DIE *constructScopeDIE(DbgScope *Scope);
- /// emitInitial - Emit initial Dwarf declarations. This is necessary for cc
- /// tools to recognize the object file contains Dwarf information.
- void emitInitial();
+ /// EmitSectionLabels - Emit initial Dwarf sections with a label at
+ /// the start of each one.
+ void EmitSectionLabels();
/// emitDIE - Recusively Emits a debug information entry.
///
@@ -487,8 +504,8 @@ class DwarfDebug : public DwarfPrinter {
/// GetOrCreateSourceID - Look up the source id with the given directory and
/// source file names. If none currently exists, create a new id and insert it
- /// in the SourceIds map. This can update DirectoryNames and SourceFileNames maps
- /// as well.
+ /// in the SourceIds map. This can update DirectoryNames and SourceFileNames
+ /// maps as well.
unsigned GetOrCreateSourceID(StringRef DirName, StringRef FileName);
void constructCompileUnit(MDNode *N);
@@ -503,44 +520,17 @@ class DwarfDebug : public DwarfPrinter {
///
DIType getBlockByrefType(DIType Ty, std::string Name);
-public:
- //===--------------------------------------------------------------------===//
- // Main entry points.
- //
- DwarfDebug(raw_ostream &OS, AsmPrinter *A, const MCAsmInfo *T);
- virtual ~DwarfDebug();
-
- /// ShouldEmitDwarfDebug - Returns true if Dwarf debugging declarations should
- /// be emitted.
- bool ShouldEmitDwarfDebug() const { return shouldEmit; }
-
- /// beginModule - Emit all Dwarf sections that should come prior to the
- /// content.
- void beginModule(Module *M, MachineModuleInfo *MMI);
-
- /// endModule - Emit all Dwarf sections that should come after the content.
- ///
- void endModule();
-
- /// beginFunction - Gather pre-function debug information. Assumes being
- /// emitted immediately after the function entry point.
- void beginFunction(const MachineFunction *MF);
-
- /// endFunction - Gather and emit post-function debug information.
- ///
- void endFunction(const MachineFunction *MF);
-
/// recordSourceLine - Register a source line with debug info. Returns the
/// unique label that was emitted and which provides correspondence to
/// the source line list.
MCSymbol *recordSourceLine(unsigned Line, unsigned Col, MDNode *Scope);
-
+
/// getSourceLineCount - Return the number of source lines in the debug
/// info.
unsigned getSourceLineCount() const {
return Lines.size();
}
-
+
/// getOrCreateSourceID - Public version of GetOrCreateSourceID. This can be
/// timed. Look up the source id with the given directory and source file
/// names. If none currently exists, create a new id and insert it in the
@@ -548,13 +538,36 @@ public:
/// well.
unsigned getOrCreateSourceID(const std::string &DirName,
const std::string &FileName);
-
+
/// extractScopeInformation - Scan machine instructions in this function
/// and collect DbgScopes. Return true, if atleast one scope was found.
bool extractScopeInformation();
-
+
/// collectVariableInfo - Populate DbgScope entries with variables' info.
void collectVariableInfo();
+
+public:
+ //===--------------------------------------------------------------------===//
+ // Main entry points.
+ //
+ DwarfDebug(AsmPrinter *A, Module *M);
+ ~DwarfDebug();
+
+ /// beginModule - Emit all Dwarf sections that should come prior to the
+ /// content.
+ void beginModule(Module *M);
+
+ /// endModule - Emit all Dwarf sections that should come after the content.
+ ///
+ void endModule();
+
+ /// beginFunction - Gather pre-function debug information. Assumes being
+ /// emitted immediately after the function entry point.
+ void beginFunction(const MachineFunction *MF);
+
+ /// endFunction - Gather and emit post-function debug information.
+ ///
+ void endFunction(const MachineFunction *MF);
/// beginScope - Process beginning of a scope.
void beginScope(const MachineInstr *MI);
diff --git a/lib/CodeGen/AsmPrinter/DwarfException.cpp b/lib/CodeGen/AsmPrinter/DwarfException.cpp
index 8b616b0..72c97a4 100644
--- a/lib/CodeGen/AsmPrinter/DwarfException.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfException.cpp
@@ -13,6 +13,7 @@
#include "DwarfException.h"
#include "llvm/Module.h"
+#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
@@ -27,6 +28,7 @@
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetFrameInfo.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
+#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Support/Dwarf.h"
@@ -37,9 +39,8 @@
#include "llvm/ADT/Twine.h"
using namespace llvm;
-DwarfException::DwarfException(raw_ostream &OS, AsmPrinter *A,
- const MCAsmInfo *T)
- : DwarfPrinter(OS, A, T), shouldEmitTable(false),shouldEmitMoves(false),
+DwarfException::DwarfException(AsmPrinter *A)
+ : Asm(A), MMI(Asm->MMI), shouldEmitTable(false), shouldEmitMoves(false),
shouldEmitTableModule(false), shouldEmitMovesModule(false),
ExceptionTimer(0) {
if (TimePassesIsEnabled)
@@ -55,10 +56,10 @@ DwarfException::~DwarfException() {
/// in every non-empty .debug_frame section.
void DwarfException::EmitCIE(const Function *PersonalityFn, unsigned Index) {
// Size and sign of stack growth.
- int stackGrowth =
- Asm->TM.getFrameInfo()->getStackGrowthDirection() ==
- TargetFrameInfo::StackGrowsUp ?
- TD->getPointerSize() : -TD->getPointerSize();
+ int stackGrowth = Asm->getTargetData().getPointerSize();
+ if (Asm->TM.getFrameInfo()->getStackGrowthDirection() ==
+ TargetFrameInfo::StackGrowsDown)
+ stackGrowth *= -1;
const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
@@ -67,24 +68,25 @@ void DwarfException::EmitCIE(const Function *PersonalityFn, unsigned Index) {
MCSymbol *EHFrameSym;
if (TLOF.isFunctionEHFrameSymbolPrivate())
- EHFrameSym = getDWLabel("EH_frame", Index);
+ EHFrameSym = Asm->GetTempSymbol("EH_frame", Index);
else
EHFrameSym = Asm->OutContext.GetOrCreateSymbol(Twine("EH_frame") +
Twine(Index));
Asm->OutStreamer.EmitLabel(EHFrameSym);
- Asm->OutStreamer.EmitLabel(getDWLabel("section_eh_frame", Index));
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("section_eh_frame", Index));
// Define base labels.
- Asm->OutStreamer.EmitLabel(getDWLabel("eh_frame_common", Index));
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_frame_common", Index));
// Define the eh frame length.
Asm->OutStreamer.AddComment("Length of Common Information Entry");
- EmitDifference(getDWLabel("eh_frame_common_end", Index),
- getDWLabel("eh_frame_common_begin", Index), true);
+ Asm->EmitLabelDifference(Asm->GetTempSymbol("eh_frame_common_end", Index),
+ Asm->GetTempSymbol("eh_frame_common_begin", Index),
+ 4);
// EH frame header.
- Asm->OutStreamer.EmitLabel(getDWLabel("eh_frame_common_begin", Index));
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_frame_common_begin",Index));
Asm->OutStreamer.AddComment("CIE Identifier Tag");
Asm->OutStreamer.EmitIntValue(0, 4/*size*/, 0/*addrspace*/);
Asm->OutStreamer.AddComment("DW_CIE_VERSION");
@@ -105,7 +107,7 @@ void DwarfException::EmitCIE(const Function *PersonalityFn, unsigned Index) {
if (PersonalityFn) {
// There is a personality function.
*APtr++ = 'P';
- AugmentationSize += 1 + SizeOfEncodedValue(PerEncoding);
+ AugmentationSize += 1 + Asm->GetSizeOfEncodedValue(PerEncoding);
}
if (UsesLSDA[Index]) {
@@ -127,36 +129,39 @@ void DwarfException::EmitCIE(const Function *PersonalityFn, unsigned Index) {
Asm->OutStreamer.EmitBytes(StringRef(Augmentation, strlen(Augmentation)+1),0);
// Round out reader.
- EmitULEB128(1, "CIE Code Alignment Factor");
- EmitSLEB128(stackGrowth, "CIE Data Alignment Factor");
+ Asm->EmitULEB128(1, "CIE Code Alignment Factor");
+ Asm->EmitSLEB128(stackGrowth, "CIE Data Alignment Factor");
Asm->OutStreamer.AddComment("CIE Return Address Column");
+
+ const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
Asm->EmitInt8(RI->getDwarfRegNum(RI->getRARegister(), true));
if (Augmentation[0]) {
- EmitULEB128(AugmentationSize, "Augmentation Size");
+ Asm->EmitULEB128(AugmentationSize, "Augmentation Size");
// If there is a personality, we need to indicate the function's location.
if (PersonalityFn) {
- EmitEncodingByte(PerEncoding, "Personality");
+ Asm->EmitEncodingByte(PerEncoding, "Personality");
Asm->OutStreamer.AddComment("Personality");
- EmitReference(PersonalityFn, PerEncoding);
+ Asm->EmitReference(PersonalityFn, PerEncoding);
}
if (UsesLSDA[Index])
- EmitEncodingByte(LSDAEncoding, "LSDA");
+ Asm->EmitEncodingByte(LSDAEncoding, "LSDA");
if (FDEEncoding != dwarf::DW_EH_PE_absptr)
- EmitEncodingByte(FDEEncoding, "FDE");
+ Asm->EmitEncodingByte(FDEEncoding, "FDE");
}
// Indicate locations of general callee saved registers in frame.
std::vector<MachineMove> Moves;
RI->getInitialFrameState(Moves);
- EmitFrameMoves(0, Moves, true);
+ Asm->EmitFrameMoves(Moves, 0, true);
// On Darwin the linker honors the alignment of eh_frame, which means it must
// be 8-byte on 64-bit targets to match what gcc does. Otherwise you get
// holes which confuse readers of eh_frame.
- Asm->EmitAlignment(TD->getPointerSize() == 4 ? 2 : 3, 0, 0, false);
- Asm->OutStreamer.EmitLabel(getDWLabel("eh_frame_common_end", Index));
+ Asm->EmitAlignment(Asm->getTargetData().getPointerSize() == 4 ? 2 : 3,
+ 0, 0, false);
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_frame_common_end", Index));
}
/// EmitFDE - Emit the Frame Description Entry (FDE) for the function.
@@ -178,13 +183,13 @@ void DwarfException::EmitFDE(const FunctionEHFrameInfo &EHFrameInfo) {
Asm->OutStreamer.EmitSymbolAttribute(EHFrameInfo.FunctionEHSym,MCSA_Global);
// If corresponding function is weak definition, this should be too.
- if (TheFunc->isWeakForLinker() && MAI->getWeakDefDirective())
+ if (TheFunc->isWeakForLinker() && Asm->MAI->getWeakDefDirective())
Asm->OutStreamer.EmitSymbolAttribute(EHFrameInfo.FunctionEHSym,
MCSA_WeakDefinition);
// If corresponding function is hidden, this should be too.
if (TheFunc->hasHiddenVisibility())
- if (MCSymbolAttr HiddenAttr = MAI->getHiddenVisibilityAttr())
+ if (MCSymbolAttr HiddenAttr = Asm->MAI->getHiddenVisibilityAttr())
Asm->OutStreamer.EmitSymbolAttribute(EHFrameInfo.FunctionEHSym,
HiddenAttr);
@@ -194,14 +199,14 @@ void DwarfException::EmitFDE(const FunctionEHFrameInfo &EHFrameInfo) {
// info is to be available for non-EH uses.
if (!EHFrameInfo.hasCalls && !UnwindTablesMandatory &&
(!TheFunc->isWeakForLinker() ||
- !MAI->getWeakDefDirective() ||
+ !Asm->MAI->getWeakDefDirective() ||
TLOF.getSupportsWeakOmittedEHFrame())) {
Asm->OutStreamer.EmitAssignment(EHFrameInfo.FunctionEHSym,
MCConstantExpr::Create(0, Asm->OutContext));
// This name has no connection to the function, so it might get
// dead-stripped when the function is not, erroneously. Prohibit
// dead-stripping unconditionally.
- if (MAI->hasNoDeadStrip())
+ if (Asm->MAI->hasNoDeadStrip())
Asm->OutStreamer.EmitSymbolAttribute(EHFrameInfo.FunctionEHSym,
MCSA_NoDeadStrip);
} else {
@@ -209,52 +214,58 @@ void DwarfException::EmitFDE(const FunctionEHFrameInfo &EHFrameInfo) {
// EH frame header.
Asm->OutStreamer.AddComment("Length of Frame Information Entry");
- EmitDifference(getDWLabel("eh_frame_end", EHFrameInfo.Number),
- getDWLabel("eh_frame_begin", EHFrameInfo.Number),
- true);
+ Asm->EmitLabelDifference(
+ Asm->GetTempSymbol("eh_frame_end", EHFrameInfo.Number),
+ Asm->GetTempSymbol("eh_frame_begin", EHFrameInfo.Number), 4);
- Asm->OutStreamer.EmitLabel(getDWLabel("eh_frame_begin",EHFrameInfo.Number));
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_frame_begin",
+ EHFrameInfo.Number));
Asm->OutStreamer.AddComment("FDE CIE offset");
- EmitSectionOffset(getDWLabel("eh_frame_begin", EHFrameInfo.Number),
- getDWLabel("eh_frame_common",
- EHFrameInfo.PersonalityIndex),
- true, true);
+ Asm->EmitLabelDifference(
+ Asm->GetTempSymbol("eh_frame_begin", EHFrameInfo.Number),
+ Asm->GetTempSymbol("eh_frame_common",
+ EHFrameInfo.PersonalityIndex), 4);
- MCSymbol *EHFuncBeginSym = getDWLabel("eh_func_begin", EHFrameInfo.Number);
+ MCSymbol *EHFuncBeginSym =
+ Asm->GetTempSymbol("eh_func_begin", EHFrameInfo.Number);
Asm->OutStreamer.AddComment("FDE initial location");
- EmitReference(EHFuncBeginSym, FDEEncoding);
+ Asm->EmitReference(EHFuncBeginSym, FDEEncoding);
Asm->OutStreamer.AddComment("FDE address range");
- EmitDifference(getDWLabel("eh_func_end", EHFrameInfo.Number),EHFuncBeginSym,
- SizeOfEncodedValue(FDEEncoding) == 4);
+ Asm->EmitLabelDifference(Asm->GetTempSymbol("eh_func_end",
+ EHFrameInfo.Number),
+ EHFuncBeginSym,
+ Asm->GetSizeOfEncodedValue(FDEEncoding));
// If there is a personality and landing pads then point to the language
// specific data area in the exception table.
if (MMI->getPersonalities()[0] != NULL) {
- unsigned Size = SizeOfEncodedValue(LSDAEncoding);
+ unsigned Size = Asm->GetSizeOfEncodedValue(LSDAEncoding);
- EmitULEB128(Size, "Augmentation size");
+ Asm->EmitULEB128(Size, "Augmentation size");
Asm->OutStreamer.AddComment("Language Specific Data Area");
if (EHFrameInfo.hasLandingPads)
- EmitReference(getDWLabel("exception", EHFrameInfo.Number),LSDAEncoding);
+ Asm->EmitReference(Asm->GetTempSymbol("exception", EHFrameInfo.Number),
+ LSDAEncoding);
else
Asm->OutStreamer.EmitIntValue(0, Size/*size*/, 0/*addrspace*/);
} else {
- EmitULEB128(0, "Augmentation size");
+ Asm->EmitULEB128(0, "Augmentation size");
}
// Indicate locations of function specific callee saved registers in frame.
- EmitFrameMoves(EHFuncBeginSym, EHFrameInfo.Moves, true);
+ Asm->EmitFrameMoves(EHFrameInfo.Moves, EHFuncBeginSym, true);
// On Darwin the linker honors the alignment of eh_frame, which means it
// must be 8-byte on 64-bit targets to match what gcc does. Otherwise you
// get holes which confuse readers of eh_frame.
- Asm->EmitAlignment(TD->getPointerSize() == sizeof(int32_t) ? 2 : 3,
+ Asm->EmitAlignment(Asm->getTargetData().getPointerSize() == 4 ? 2 : 3,
0, 0, false);
- Asm->OutStreamer.EmitLabel(getDWLabel("eh_frame_end", EHFrameInfo.Number));
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_frame_end",
+ EHFrameInfo.Number));
// If the function is marked used, this table should be also. We cannot
// make the mark unconditional in this case, since retaining the table also
@@ -262,7 +273,7 @@ void DwarfException::EmitFDE(const FunctionEHFrameInfo &EHFrameInfo) {
// on unused functions (calling undefined externals) being dead-stripped to
// link correctly. Yes, there really is.
if (MMI->isUsedFunction(EHFrameInfo.function))
- if (MAI->hasNoDeadStrip())
+ if (Asm->MAI->hasNoDeadStrip())
Asm->OutStreamer.EmitSymbolAttribute(EHFrameInfo.FunctionEHSym,
MCSA_NoDeadStrip);
}
@@ -348,7 +359,7 @@ ComputeActionsTable(const SmallVectorImpl<const LandingPadInfo*> &LandingPads,
I = LandingPads.begin(), E = LandingPads.end(); I != E; ++I) {
const LandingPadInfo *LPI = *I;
const std::vector<int> &TypeIds = LPI->TypeIds;
- const unsigned NumShared = PrevLPI ? SharedTypeIds(LPI, PrevLPI) : 0;
+ unsigned NumShared = PrevLPI ? SharedTypeIds(LPI, PrevLPI) : 0;
unsigned SizeSiteActions = 0;
if (NumShared < TypeIds.size()) {
@@ -356,7 +367,7 @@ ComputeActionsTable(const SmallVectorImpl<const LandingPadInfo*> &LandingPads,
unsigned PrevAction = (unsigned)-1;
if (NumShared) {
- const unsigned SizePrevIds = PrevLPI->TypeIds.size();
+ unsigned SizePrevIds = PrevLPI->TypeIds.size();
assert(Actions.size());
PrevAction = Actions.size() - 1;
SizeAction =
@@ -465,7 +476,7 @@ ComputeCallSiteTable(SmallVectorImpl<CallSiteEntry> &CallSites,
bool PreviousIsInvoke = false;
// Visit all instructions in order of address.
- for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
+ for (MachineFunction::const_iterator I = Asm->MF->begin(), E = Asm->MF->end();
I != E; ++I) {
for (MachineBasicBlock::const_iterator MI = I->begin(), E = I->end();
MI != E; ++MI) {
@@ -496,7 +507,7 @@ ComputeCallSiteTable(SmallVectorImpl<CallSiteEntry> &CallSites,
// create a call-site entry with no landing pad for the region between the
// try-ranges.
if (SawPotentiallyThrowing &&
- MAI->getExceptionHandlingType() == ExceptionHandling::Dwarf) {
+ Asm->MAI->getExceptionHandlingType() == ExceptionHandling::Dwarf) {
CallSiteEntry Site = { LastLabel, BeginLabel, 0, 0 };
CallSites.push_back(Site);
PreviousIsInvoke = false;
@@ -519,7 +530,7 @@ ComputeCallSiteTable(SmallVectorImpl<CallSiteEntry> &CallSites,
// Try to merge with the previous call-site. SJLJ doesn't do this
if (PreviousIsInvoke &&
- MAI->getExceptionHandlingType() == ExceptionHandling::Dwarf) {
+ Asm->MAI->getExceptionHandlingType() == ExceptionHandling::Dwarf) {
CallSiteEntry &Prev = CallSites.back();
if (Site.PadLabel == Prev.PadLabel && Site.Action == Prev.Action) {
// Extend the range of the previous entry.
@@ -529,7 +540,7 @@ ComputeCallSiteTable(SmallVectorImpl<CallSiteEntry> &CallSites,
}
// Otherwise, create a new call-site.
- if (MAI->getExceptionHandlingType() == ExceptionHandling::Dwarf)
+ if (Asm->MAI->getExceptionHandlingType() == ExceptionHandling::Dwarf)
CallSites.push_back(Site);
else {
// SjLj EH must maintain the call sites in the order assigned
@@ -548,7 +559,7 @@ ComputeCallSiteTable(SmallVectorImpl<CallSiteEntry> &CallSites,
// function may throw, create a call-site entry with no landing pad for the
// region following the try-range.
if (SawPotentiallyThrowing &&
- MAI->getExceptionHandlingType() == ExceptionHandling::Dwarf) {
+ Asm->MAI->getExceptionHandlingType() == ExceptionHandling::Dwarf) {
CallSiteEntry Site = { LastLabel, 0, 0, 0 };
CallSites.push_back(Site);
}
@@ -616,18 +627,19 @@ void DwarfException::EmitExceptionTable() {
// Final tallies.
// Call sites.
- const unsigned SiteStartSize = SizeOfEncodedValue(dwarf::DW_EH_PE_udata4);
- const unsigned SiteLengthSize = SizeOfEncodedValue(dwarf::DW_EH_PE_udata4);
- const unsigned LandingPadSize = SizeOfEncodedValue(dwarf::DW_EH_PE_udata4);
- bool IsSJLJ = MAI->getExceptionHandlingType() == ExceptionHandling::SjLj;
+ bool IsSJLJ = Asm->MAI->getExceptionHandlingType() == ExceptionHandling::SjLj;
bool HaveTTData = IsSJLJ ? (!TypeInfos.empty() || !FilterIds.empty()) : true;
+
unsigned CallSiteTableLength;
-
if (IsSJLJ)
CallSiteTableLength = 0;
- else
- CallSiteTableLength = CallSites.size() *
- (SiteStartSize + SiteLengthSize + LandingPadSize);
+ else {
+ unsigned SiteStartSize = 4; // dwarf::DW_EH_PE_udata4
+ unsigned SiteLengthSize = 4; // dwarf::DW_EH_PE_udata4
+ unsigned LandingPadSize = 4; // dwarf::DW_EH_PE_udata4
+ CallSiteTableLength =
+ CallSites.size() * (SiteStartSize + SiteLengthSize + LandingPadSize);
+ }
for (unsigned i = 0, e = CallSites.size(); i < e; ++i) {
CallSiteTableLength += MCAsmInfo::getULEB128Size(CallSites[i].Action);
@@ -644,7 +656,8 @@ void DwarfException::EmitExceptionTable() {
// For SjLj exceptions, if there is no TypeInfo, then we just explicitly say
// that we're omitting that bit.
TTypeEncoding = dwarf::DW_EH_PE_omit;
- TypeFormatSize = SizeOfEncodedValue(dwarf::DW_EH_PE_absptr);
+ // dwarf::DW_EH_PE_absptr
+ TypeFormatSize = Asm->getTargetData().getPointerSize();
} else {
// Okay, we have actual filters or typeinfos to emit. As such, we need to
// pick a type encoding for them. We're about to emit a list of pointers to
@@ -674,7 +687,7 @@ void DwarfException::EmitExceptionTable() {
// in target-independent code.
//
TTypeEncoding = Asm->getObjFileLowering().getTTypeEncoding();
- TypeFormatSize = SizeOfEncodedValue(TTypeEncoding);
+ TypeFormatSize = Asm->GetSizeOfEncodedValue(TTypeEncoding);
}
// Begin the exception table.
@@ -684,16 +697,18 @@ void DwarfException::EmitExceptionTable() {
// Emit the LSDA.
MCSymbol *GCCETSym =
Asm->OutContext.GetOrCreateSymbol(Twine("GCC_except_table")+
- Twine(SubprogramCount));
+ Twine(Asm->getFunctionNumber()));
Asm->OutStreamer.EmitLabel(GCCETSym);
- Asm->OutStreamer.EmitLabel(getDWLabel("exception", SubprogramCount));
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("exception",
+ Asm->getFunctionNumber()));
if (IsSJLJ)
- Asm->OutStreamer.EmitLabel(getDWLabel("_LSDA_", Asm->getFunctionNumber()));
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("_LSDA_",
+ Asm->getFunctionNumber()));
// Emit the LSDA header.
- EmitEncodingByte(dwarf::DW_EH_PE_omit, "@LPStart");
- EmitEncodingByte(TTypeEncoding, "@TType");
+ Asm->EmitEncodingByte(dwarf::DW_EH_PE_omit, "@LPStart");
+ Asm->EmitEncodingByte(TTypeEncoding, "@TType");
// The type infos need to be aligned. GCC does this by inserting padding just
// before the type infos. However, this changes the size of the exception
@@ -730,16 +745,16 @@ void DwarfException::EmitExceptionTable() {
if (HaveTTData) {
// Account for any extra padding that will be added to the call site table
// length.
- EmitULEB128(TTypeBaseOffset, "@TType base offset", SizeAlign);
+ Asm->EmitULEB128(TTypeBaseOffset, "@TType base offset", SizeAlign);
SizeAlign = 0;
}
// SjLj Exception handling
if (IsSJLJ) {
- EmitEncodingByte(dwarf::DW_EH_PE_udata4, "Call site");
+ Asm->EmitEncodingByte(dwarf::DW_EH_PE_udata4, "Call site");
// Add extra padding if it wasn't added to the TType base offset.
- EmitULEB128(CallSiteTableLength, "Call site table length", SizeAlign);
+ Asm->EmitULEB128(CallSiteTableLength, "Call site table length", SizeAlign);
// Emit the landing pad site information.
unsigned idx = 0;
@@ -749,16 +764,16 @@ void DwarfException::EmitExceptionTable() {
// Offset of the landing pad, counted in 16-byte bundles relative to the
// @LPStart address.
- EmitULEB128(idx, "Landing pad");
+ Asm->EmitULEB128(idx, "Landing pad");
// Offset of the first associated action record, relative to the start of
// the action table. This value is biased by 1 (1 indicates the start of
// the action table), and 0 indicates that there are no actions.
- EmitULEB128(S.Action, "Action");
+ Asm->EmitULEB128(S.Action, "Action");
}
} else {
// DWARF Exception handling
- assert(MAI->getExceptionHandlingType() == ExceptionHandling::Dwarf);
+ assert(Asm->MAI->getExceptionHandlingType() == ExceptionHandling::Dwarf);
// The call-site table is a list of all call sites that may throw an
// exception (including C++ 'throw' statements) in the procedure
@@ -779,32 +794,33 @@ void DwarfException::EmitExceptionTable() {
// supposed to throw.
// Emit the landing pad call site table.
- EmitEncodingByte(dwarf::DW_EH_PE_udata4, "Call site");
+ Asm->EmitEncodingByte(dwarf::DW_EH_PE_udata4, "Call site");
// Add extra padding if it wasn't added to the TType base offset.
- EmitULEB128(CallSiteTableLength, "Call site table length", SizeAlign);
+ Asm->EmitULEB128(CallSiteTableLength, "Call site table length", SizeAlign);
for (SmallVectorImpl<CallSiteEntry>::const_iterator
I = CallSites.begin(), E = CallSites.end(); I != E; ++I) {
const CallSiteEntry &S = *I;
- MCSymbol *EHFuncBeginSym = getDWLabel("eh_func_begin", SubprogramCount);
+ MCSymbol *EHFuncBeginSym =
+ Asm->GetTempSymbol("eh_func_begin", Asm->getFunctionNumber());
MCSymbol *BeginLabel = S.BeginLabel;
if (BeginLabel == 0)
BeginLabel = EHFuncBeginSym;
MCSymbol *EndLabel = S.EndLabel;
if (EndLabel == 0)
- EndLabel = getDWLabel("eh_func_end", SubprogramCount);
+ EndLabel = Asm->GetTempSymbol("eh_func_end", Asm->getFunctionNumber());
// Offset of the call site relative to the previous call site, counted in
// number of 16-byte bundles. The first call site is counted relative to
// the start of the procedure fragment.
Asm->OutStreamer.AddComment("Region start");
- EmitSectionOffset(BeginLabel, EHFuncBeginSym, true, true);
+ Asm->EmitLabelDifference(BeginLabel, EHFuncBeginSym, 4);
Asm->OutStreamer.AddComment("Region length");
- EmitDifference(EndLabel, BeginLabel, true);
+ Asm->EmitLabelDifference(EndLabel, BeginLabel, 4);
// Offset of the landing pad, counted in 16-byte bundles relative to the
@@ -813,12 +829,12 @@ void DwarfException::EmitExceptionTable() {
if (!S.PadLabel)
Asm->OutStreamer.EmitIntValue(0, 4/*size*/, 0/*addrspace*/);
else
- EmitSectionOffset(S.PadLabel, EHFuncBeginSym, true, true);
+ Asm->EmitLabelDifference(S.PadLabel, EHFuncBeginSym, 4);
// Offset of the first associated action record, relative to the start of
// the action table. This value is biased by 1 (1 indicates the start of
// the action table), and 0 indicates that there are no actions.
- EmitULEB128(S.Action, "Action");
+ Asm->EmitULEB128(S.Action, "Action");
}
}
@@ -838,13 +854,13 @@ void DwarfException::EmitExceptionTable() {
//
// Used by the runtime to match the type of the thrown exception to the
// type of the catch clauses or the types in the exception specification.
- EmitSLEB128(Action.ValueForTypeID, " TypeInfo index");
+ Asm->EmitSLEB128(Action.ValueForTypeID, " TypeInfo index");
// Action Record
//
// Self-relative signed displacement in bytes of the next action record,
// or 0 if there is no next action record.
- EmitSLEB128(Action.NextAction, " Next action");
+ Asm->EmitSLEB128(Action.NextAction, " Next action");
}
// Emit the Catch TypeInfos.
@@ -858,9 +874,10 @@ void DwarfException::EmitExceptionTable() {
Asm->OutStreamer.AddComment("TypeInfo");
if (GV)
- EmitReference(GV, TTypeEncoding);
+ Asm->EmitReference(GV, TTypeEncoding);
else
- Asm->OutStreamer.EmitIntValue(0, SizeOfEncodedValue(TTypeEncoding), 0);
+ Asm->OutStreamer.EmitIntValue(0,Asm->GetSizeOfEncodedValue(TTypeEncoding),
+ 0);
}
// Emit the Exception Specifications.
@@ -871,7 +888,7 @@ void DwarfException::EmitExceptionTable() {
for (std::vector<unsigned>::const_iterator
I = FilterIds.begin(), E = FilterIds.end(); I < E; ++I) {
unsigned TypeID = *I;
- EmitULEB128(TypeID, TypeID != 0 ? "Exception specification" : 0);
+ Asm->EmitULEB128(TypeID, TypeID != 0 ? "Exception specification" : 0);
}
Asm->EmitAlignment(2, 0, 0, false);
@@ -880,7 +897,7 @@ void DwarfException::EmitExceptionTable() {
/// EndModule - Emit all exception information that should come after the
/// content.
void DwarfException::EndModule() {
- if (MAI->getExceptionHandlingType() != ExceptionHandling::Dwarf)
+ if (Asm->MAI->getExceptionHandlingType() != ExceptionHandling::Dwarf)
return;
if (!shouldEmitMovesModule && !shouldEmitTableModule)
@@ -901,21 +918,20 @@ void DwarfException::EndModule() {
/// BeginFunction - Gather pre-function exception information. Assumes it's
/// being emitted immediately after the function entry point.
void DwarfException::BeginFunction(const MachineFunction *MF) {
- if (!MMI || !MAI->doesSupportExceptionHandling()) return;
-
TimeRegion Timer(ExceptionTimer);
- this->MF = MF;
shouldEmitTable = shouldEmitMoves = false;
// If any landing pads survive, we need an EH table.
shouldEmitTable = !MMI->getLandingPads().empty();
// See if we need frame move info.
- shouldEmitMoves = !MF->getFunction()->doesNotThrow() || UnwindTablesMandatory;
+ shouldEmitMoves =
+ !Asm->MF->getFunction()->doesNotThrow() || UnwindTablesMandatory;
if (shouldEmitMoves || shouldEmitTable)
// Assumes in correct section after the entry point.
- Asm->OutStreamer.EmitLabel(getDWLabel("eh_func_begin", ++SubprogramCount));
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_func_begin",
+ Asm->getFunctionNumber()));
shouldEmitTableModule |= shouldEmitTable;
shouldEmitMovesModule |= shouldEmitMoves;
@@ -927,7 +943,8 @@ void DwarfException::EndFunction() {
if (!shouldEmitMoves && !shouldEmitTable) return;
TimeRegion Timer(ExceptionTimer);
- Asm->OutStreamer.EmitLabel(getDWLabel("eh_func_end", SubprogramCount));
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_func_end",
+ Asm->getFunctionNumber()));
// Record if this personality index uses a landing pad.
bool HasLandingPad = !MMI->getLandingPads().empty();
@@ -941,14 +958,15 @@ void DwarfException::EndFunction() {
const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
MCSymbol *FunctionEHSym =
- Asm->GetSymbolWithGlobalValueBase(MF->getFunction(), ".eh",
+ Asm->GetSymbolWithGlobalValueBase(Asm->MF->getFunction(), ".eh",
TLOF.isFunctionEHFrameSymbolPrivate());
// Save EH frame information
- EHFrames.push_back(FunctionEHFrameInfo(FunctionEHSym, SubprogramCount,
+ EHFrames.push_back(FunctionEHFrameInfo(FunctionEHSym,
+ Asm->getFunctionNumber(),
MMI->getPersonalityIndex(),
- MF->getFrameInfo()->hasCalls(),
+ Asm->MF->getFrameInfo()->hasCalls(),
!MMI->getLandingPads().empty(),
MMI->getFrameMoves(),
- MF->getFunction()));
+ Asm->MF->getFunction()));
}
diff --git a/lib/CodeGen/AsmPrinter/DwarfException.h b/lib/CodeGen/AsmPrinter/DwarfException.h
index 4bc4a458..f35c0b6 100644
--- a/lib/CodeGen/AsmPrinter/DwarfException.h
+++ b/lib/CodeGen/AsmPrinter/DwarfException.h
@@ -14,25 +14,34 @@
#ifndef LLVM_CODEGEN_ASMPRINTER_DWARFEXCEPTION_H
#define LLVM_CODEGEN_ASMPRINTER_DWARFEXCEPTION_H
-#include "DIE.h"
-#include "DwarfPrinter.h"
-#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/ADT/DenseMap.h"
-#include <string>
+#include <vector>
namespace llvm {
+template <typename T> class SmallVectorImpl;
struct LandingPadInfo;
class MachineModuleInfo;
+class MachineMove;
+class MachineInstr;
+class MachineFunction;
class MCAsmInfo;
class MCExpr;
+class MCSymbol;
class Timer;
-class raw_ostream;
+class Function;
+class AsmPrinter;
//===----------------------------------------------------------------------===//
/// DwarfException - Emits Dwarf exception handling directives.
///
-class DwarfException : public DwarfPrinter {
+class DwarfException {
+ /// Asm - Target of Dwarf emission.
+ AsmPrinter *Asm;
+
+ /// MMI - Collected machine module information.
+ MachineModuleInfo *MMI;
+
struct FunctionEHFrameInfo {
MCSymbol *FunctionEHSym; // L_foo.eh
unsigned Number;
@@ -166,15 +175,8 @@ public:
//===--------------------------------------------------------------------===//
// Main entry points.
//
- DwarfException(raw_ostream &OS, AsmPrinter *A, const MCAsmInfo *T);
- virtual ~DwarfException();
-
- /// BeginModule - Emit all exception information that should come prior to the
- /// content.
- void BeginModule(Module *m, MachineModuleInfo *mmi) {
- this->M = m;
- this->MMI = mmi;
- }
+ DwarfException(AsmPrinter *A);
+ ~DwarfException();
/// EndModule - Emit all exception information that should come after the
/// content.
diff --git a/lib/CodeGen/AsmPrinter/DwarfPrinter.cpp b/lib/CodeGen/AsmPrinter/DwarfPrinter.cpp
deleted file mode 100644
index 17eb2e8..0000000
--- a/lib/CodeGen/AsmPrinter/DwarfPrinter.cpp
+++ /dev/null
@@ -1,308 +0,0 @@
-//===--- lib/CodeGen/DwarfPrinter.cpp - Dwarf Printer ---------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Emit general DWARF directives.
-//
-//===----------------------------------------------------------------------===//
-
-#include "DwarfPrinter.h"
-#include "llvm/Module.h"
-#include "llvm/CodeGen/AsmPrinter.h"
-#include "llvm/CodeGen/MachineFrameInfo.h"
-#include "llvm/CodeGen/MachineFunction.h"
-#include "llvm/CodeGen/MachineModuleInfo.h"
-#include "llvm/MC/MCAsmInfo.h"
-#include "llvm/MC/MCContext.h"
-#include "llvm/MC/MCExpr.h"
-#include "llvm/MC/MCStreamer.h"
-#include "llvm/MC/MCSymbol.h"
-#include "llvm/Target/TargetData.h"
-#include "llvm/Target/TargetFrameInfo.h"
-#include "llvm/Target/TargetLoweringObjectFile.h"
-#include "llvm/Target/TargetRegisterInfo.h"
-#include "llvm/Support/Dwarf.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/ADT/SmallString.h"
-using namespace llvm;
-
-DwarfPrinter::DwarfPrinter(raw_ostream &OS, AsmPrinter *A, const MCAsmInfo *T)
-: O(OS), Asm(A), MAI(T), TD(Asm->TM.getTargetData()),
- RI(Asm->TM.getRegisterInfo()), M(NULL), MF(NULL), MMI(NULL),
- SubprogramCount(0) {}
-
-
-/// getDWLabel - Return the MCSymbol corresponding to the assembler temporary
-/// label with the specified stem and unique ID.
-MCSymbol *DwarfPrinter::getDWLabel(const char *Name, unsigned ID) const {
- // FIXME: REMOVE this. However, there is stuff in EH that passes counters in
- // here that can be zero.
-
- //assert(ID && "Should use getTempLabel if no ID");
- if (ID == 0) return getTempLabel(Name);
- return Asm->OutContext.GetOrCreateSymbol
- (Twine(MAI->getPrivateGlobalPrefix()) + Twine(Name) + Twine(ID));
-}
-
-/// getTempLabel - Return the MCSymbol corresponding to the assembler temporary
-/// label with the specified name.
-MCSymbol *DwarfPrinter::getTempLabel(const char *Name) const {
- return Asm->OutContext.GetOrCreateSymbol
- (Twine(MAI->getPrivateGlobalPrefix()) + Name);
-}
-
-
-/// SizeOfEncodedValue - Return the size of the encoding in bytes.
-unsigned DwarfPrinter::SizeOfEncodedValue(unsigned Encoding) const {
- if (Encoding == dwarf::DW_EH_PE_omit)
- return 0;
-
- switch (Encoding & 0x07) {
- case dwarf::DW_EH_PE_absptr:
- return TD->getPointerSize();
- case dwarf::DW_EH_PE_udata2:
- return 2;
- case dwarf::DW_EH_PE_udata4:
- return 4;
- case dwarf::DW_EH_PE_udata8:
- return 8;
- }
-
- assert(0 && "Invalid encoded value.");
- return 0;
-}
-
-static const char *DecodeDWARFEncoding(unsigned Encoding) {
- switch (Encoding) {
- case dwarf::DW_EH_PE_absptr: return "absptr";
- case dwarf::DW_EH_PE_omit: return "omit";
- case dwarf::DW_EH_PE_pcrel: return "pcrel";
- case dwarf::DW_EH_PE_udata4: return "udata4";
- case dwarf::DW_EH_PE_udata8: return "udata8";
- case dwarf::DW_EH_PE_sdata4: return "sdata4";
- case dwarf::DW_EH_PE_sdata8: return "sdata8";
- case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata4: return "pcrel udata4";
- case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4: return "pcrel sdata4";
- case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata8: return "pcrel udata8";
- case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8: return "pcrel sdata8";
- case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |dwarf::DW_EH_PE_udata4:
- return "indirect pcrel udata4";
- case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |dwarf::DW_EH_PE_sdata4:
- return "indirect pcrel sdata4";
- case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |dwarf::DW_EH_PE_udata8:
- return "indirect pcrel udata8";
- case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |dwarf::DW_EH_PE_sdata8:
- return "indirect pcrel sdata8";
- }
-
- return "<unknown encoding>";
-}
-
-/// EmitEncodingByte - Emit a .byte 42 directive that corresponds to an
-/// encoding. If verbose assembly output is enabled, we output comments
-/// describing the encoding. Desc is an optional string saying what the
-/// encoding is specifying (e.g. "LSDA").
-void DwarfPrinter::EmitEncodingByte(unsigned Val, const char *Desc) {
- if (Asm->VerboseAsm) {
- if (Desc != 0)
- Asm->OutStreamer.AddComment(Twine(Desc)+" Encoding = " +
- Twine(DecodeDWARFEncoding(Val)));
- else
- Asm->OutStreamer.AddComment(Twine("Encoding = ") +
- DecodeDWARFEncoding(Val));
- }
-
- Asm->OutStreamer.EmitIntValue(Val, 1, 0/*addrspace*/);
-}
-
-/// EmitCFAByte - Emit a .byte 42 directive for a DW_CFA_xxx value.
-void DwarfPrinter::EmitCFAByte(unsigned Val) {
- if (Asm->VerboseAsm) {
- if (Val >= dwarf::DW_CFA_offset && Val < dwarf::DW_CFA_offset+64)
- Asm->OutStreamer.AddComment("DW_CFA_offset + Reg (" +
- Twine(Val-dwarf::DW_CFA_offset) + ")");
- else
- Asm->OutStreamer.AddComment(dwarf::CallFrameString(Val));
- }
- Asm->OutStreamer.EmitIntValue(Val, 1, 0/*addrspace*/);
-}
-
-/// EmitSLEB128 - emit the specified signed leb128 value.
-void DwarfPrinter::EmitSLEB128(int Value, const char *Desc) const {
- if (Asm->VerboseAsm && Desc)
- Asm->OutStreamer.AddComment(Desc);
-
- if (MAI->hasLEB128()) {
- // FIXME: MCize.
- O << "\t.sleb128\t" << Value;
- Asm->OutStreamer.AddBlankLine();
- return;
- }
-
- // If we don't have .sleb128, emit as .bytes.
- int Sign = Value >> (8 * sizeof(Value) - 1);
- bool IsMore;
-
- do {
- unsigned char Byte = static_cast<unsigned char>(Value & 0x7f);
- Value >>= 7;
- IsMore = Value != Sign || ((Byte ^ Sign) & 0x40) != 0;
- if (IsMore) Byte |= 0x80;
- Asm->OutStreamer.EmitIntValue(Byte, 1, /*addrspace*/0);
- } while (IsMore);
-}
-
-/// EmitULEB128 - emit the specified signed leb128 value.
-void DwarfPrinter::EmitULEB128(unsigned Value, const char *Desc,
- unsigned PadTo) const {
- if (Asm->VerboseAsm && Desc)
- Asm->OutStreamer.AddComment(Desc);
-
- if (MAI->hasLEB128() && PadTo == 0) {
- // FIXME: MCize.
- O << "\t.uleb128\t" << Value;
- Asm->OutStreamer.AddBlankLine();
- return;
- }
-
- // If we don't have .uleb128 or we want to emit padding, emit as .bytes.
- do {
- unsigned char Byte = static_cast<unsigned char>(Value & 0x7f);
- Value >>= 7;
- if (Value || PadTo != 0) Byte |= 0x80;
- Asm->OutStreamer.EmitIntValue(Byte, 1, /*addrspace*/0);
- } while (Value);
-
- if (PadTo) {
- if (PadTo > 1)
- Asm->OutStreamer.EmitFill(PadTo - 1, 0x80/*fillval*/, 0/*addrspace*/);
- Asm->OutStreamer.EmitFill(1, 0/*fillval*/, 0/*addrspace*/);
- }
-}
-
-
-void DwarfPrinter::EmitReference(const MCSymbol *Sym, unsigned Encoding) const {
- const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
-
- const MCExpr *Exp = TLOF.getExprForDwarfReference(Sym, Asm->Mang,
- Asm->MMI, Encoding,
- Asm->OutStreamer);
- Asm->OutStreamer.EmitValue(Exp, SizeOfEncodedValue(Encoding), /*addrspace*/0);
-}
-
-void DwarfPrinter::EmitReference(const GlobalValue *GV, unsigned Encoding)const{
- const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
-
- const MCExpr *Exp =
- TLOF.getExprForDwarfGlobalReference(GV, Asm->Mang, Asm->MMI, Encoding,
- Asm->OutStreamer);
- Asm->OutStreamer.EmitValue(Exp, SizeOfEncodedValue(Encoding), /*addrspace*/0);
-}
-
-/// EmitDifference - Emit the difference between two labels. If this assembler
-/// supports .set, we emit a .set of a temporary and then use it in the .word.
-void DwarfPrinter::EmitDifference(const MCSymbol *TagHi, const MCSymbol *TagLo,
- bool IsSmall) {
- unsigned Size = IsSmall ? 4 : TD->getPointerSize();
- Asm->EmitLabelDifference(TagHi, TagLo, Size);
-}
-
-void DwarfPrinter::EmitSectionOffset(const MCSymbol *Label,
- const MCSymbol *Section,
- bool IsSmall, bool isEH) {
- bool isAbsolute;
- if (isEH)
- isAbsolute = MAI->isAbsoluteEHSectionOffsets();
- else
- isAbsolute = MAI->isAbsoluteDebugSectionOffsets();
-
- if (!isAbsolute)
- return EmitDifference(Label, Section, IsSmall);
-
- // On COFF targets, we have to emit the weird .secrel32 directive.
- if (const char *SecOffDir = MAI->getDwarfSectionOffsetDirective()) {
- // FIXME: MCize.
- Asm->O << SecOffDir << Label->getName();
- Asm->OutStreamer.AddBlankLine();
- } else {
- unsigned Size = IsSmall ? 4 : TD->getPointerSize();
- Asm->OutStreamer.EmitSymbolValue(Label, Size, 0/*AddrSpace*/);
- }
-}
-
-/// EmitFrameMoves - Emit frame instructions to describe the layout of the
-/// frame.
-void DwarfPrinter::EmitFrameMoves(MCSymbol *BaseLabel,
- const std::vector<MachineMove> &Moves,
- bool isEH) {
- int stackGrowth = TD->getPointerSize();
- if (Asm->TM.getFrameInfo()->getStackGrowthDirection() !=
- TargetFrameInfo::StackGrowsUp)
- stackGrowth *= -1;
-
- for (unsigned i = 0, N = Moves.size(); i < N; ++i) {
- const MachineMove &Move = Moves[i];
- MCSymbol *Label = Move.getLabel();
- // Throw out move if the label is invalid.
- if (Label && !Label->isDefined()) continue; // Not emitted, in dead code.
-
- const MachineLocation &Dst = Move.getDestination();
- const MachineLocation &Src = Move.getSource();
-
- // Advance row if new location.
- if (BaseLabel && Label) {
- MCSymbol *ThisSym = Label;
- if (ThisSym != BaseLabel) {
- EmitCFAByte(dwarf::DW_CFA_advance_loc4);
- EmitDifference(ThisSym, BaseLabel, true);
- BaseLabel = ThisSym;
- }
- }
-
- // If advancing cfa.
- if (Dst.isReg() && Dst.getReg() == MachineLocation::VirtualFP) {
- if (!Src.isReg()) {
- if (Src.getReg() == MachineLocation::VirtualFP) {
- EmitCFAByte(dwarf::DW_CFA_def_cfa_offset);
- } else {
- EmitCFAByte(dwarf::DW_CFA_def_cfa);
- EmitULEB128(RI->getDwarfRegNum(Src.getReg(), isEH), "Register");
- }
-
- int Offset = -Src.getOffset();
- EmitULEB128(Offset, "Offset");
- } else {
- llvm_unreachable("Machine move not supported yet.");
- }
- } else if (Src.isReg() &&
- Src.getReg() == MachineLocation::VirtualFP) {
- if (Dst.isReg()) {
- EmitCFAByte(dwarf::DW_CFA_def_cfa_register);
- EmitULEB128(RI->getDwarfRegNum(Dst.getReg(), isEH), "Register");
- } else {
- llvm_unreachable("Machine move not supported yet.");
- }
- } else {
- unsigned Reg = RI->getDwarfRegNum(Src.getReg(), isEH);
- int Offset = Dst.getOffset() / stackGrowth;
-
- if (Offset < 0) {
- EmitCFAByte(dwarf::DW_CFA_offset_extended_sf);
- EmitULEB128(Reg, "Reg");
- EmitSLEB128(Offset, "Offset");
- } else if (Reg < 64) {
- EmitCFAByte(dwarf::DW_CFA_offset + Reg);
- EmitULEB128(Offset, "Offset");
- } else {
- EmitCFAByte(dwarf::DW_CFA_offset_extended);
- EmitULEB128(Reg, "Reg");
- EmitULEB128(Offset, "Offset");
- }
- }
- }
-}
diff --git a/lib/CodeGen/AsmPrinter/DwarfPrinter.h b/lib/CodeGen/AsmPrinter/DwarfPrinter.h
deleted file mode 100644
index 0b94645..0000000
--- a/lib/CodeGen/AsmPrinter/DwarfPrinter.h
+++ /dev/null
@@ -1,131 +0,0 @@
-//===--- lib/CodeGen/DwarfPrinter.h - Dwarf Printer -------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Emit general DWARF directives.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef CODEGEN_ASMPRINTER_DWARFPRINTER_H__
-#define CODEGEN_ASMPRINTER_DWARFPRINTER_H__
-
-#include "llvm/CodeGen/MachineLocation.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/FormattedStream.h"
-#include <vector>
-
-namespace llvm {
-class AsmPrinter;
-class MachineFunction;
-class MachineModuleInfo;
-class Module;
-class MCAsmInfo;
-class TargetData;
-class TargetRegisterInfo;
-class GlobalValue;
-class MCSymbol;
-class Twine;
-
-class DwarfPrinter {
-protected:
- ~DwarfPrinter() {}
-
- //===-------------------------------------------------------------==---===//
- // Core attributes used by the DWARF printer.
- //
-
- /// O - Stream to .s file.
- raw_ostream &O;
-
- /// Asm - Target of Dwarf emission.
- AsmPrinter *Asm;
-
- /// MAI - Target asm information.
- const MCAsmInfo *MAI;
-
- /// TD - Target data.
- const TargetData *TD;
-
- /// RI - Register Information.
- const TargetRegisterInfo *RI;
-
- /// M - Current module.
- Module *M;
-
- /// MF - Current machine function.
- const MachineFunction *MF;
-
- /// MMI - Collected machine module information.
- MachineModuleInfo *MMI;
-
- /// SubprogramCount - The running count of functions being compiled.
- unsigned SubprogramCount;
-
- DwarfPrinter(raw_ostream &OS, AsmPrinter *A, const MCAsmInfo *T);
-public:
-
- //===------------------------------------------------------------------===//
- // Accessors.
- //
- const AsmPrinter *getAsm() const { return Asm; }
- MachineModuleInfo *getMMI() const { return MMI; }
- const MCAsmInfo *getMCAsmInfo() const { return MAI; }
- const TargetData *getTargetData() const { return TD; }
-
- /// getDWLabel - Return the MCSymbol corresponding to the assembler temporary
- /// label with the specified stem and unique ID.
- MCSymbol *getDWLabel(const char *Name, unsigned ID) const;
-
- /// getTempLabel - Return an assembler temporary label with the specified
- /// name.
- MCSymbol *getTempLabel(const char *Name) const;
-
- /// SizeOfEncodedValue - Return the size of the encoding in bytes.
- unsigned SizeOfEncodedValue(unsigned Encoding) const;
-
- /// EmitEncodingByte - Emit a .byte 42 directive that corresponds to an
- /// encoding. If verbose assembly output is enabled, we output comments
- /// describing the encoding. Desc is a string saying what the encoding is
- /// specifying (e.g. "LSDA").
- void EmitEncodingByte(unsigned Val, const char *Desc);
-
- /// EmitCFAByte - Emit a .byte 42 directive for a DW_CFA_xxx value.
- void EmitCFAByte(unsigned Val);
-
-
- /// EmitSLEB128 - emit the specified signed leb128 value.
- void EmitSLEB128(int Value, const char *Desc) const;
-
- /// EmitULEB128 - emit the specified unsigned leb128 value.
- void EmitULEB128(unsigned Value, const char *Desc = 0,
- unsigned PadTo = 0) const;
-
-
- /// EmitReference - Emit a reference to a label.
- ///
- void EmitReference(const MCSymbol *Sym, unsigned Encoding) const;
- void EmitReference(const GlobalValue *GV, unsigned Encoding) const;
-
- /// EmitDifference - Emit the difference between two labels.
- void EmitDifference(const MCSymbol *LabelHi, const MCSymbol *LabelLo,
- bool IsSmall = false);
-
- /// EmitSectionOffset - Emit Label-Section or use a special purpose directive
- /// to emit a section offset if the target has one.
- void EmitSectionOffset(const MCSymbol *Label, const MCSymbol *Section,
- bool IsSmall = false, bool isEH = false);
-
- /// EmitFrameMoves - Emit frame instructions to describe the layout of the
- /// frame.
- void EmitFrameMoves(MCSymbol *BaseLabel,
- const std::vector<MachineMove> &Moves, bool isEH);
-};
-
-} // end llvm namespace
-
-#endif
diff --git a/lib/CodeGen/AsmPrinter/DwarfWriter.cpp b/lib/CodeGen/AsmPrinter/DwarfWriter.cpp
deleted file mode 100644
index a2d7ab1..0000000
--- a/lib/CodeGen/AsmPrinter/DwarfWriter.cpp
+++ /dev/null
@@ -1,87 +0,0 @@
-//===-- llvm/CodeGen/DwarfWriter.cpp - Dwarf Framework --------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains support for writing dwarf info into asm files.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/CodeGen/DwarfWriter.h"
-#include "DwarfDebug.h"
-#include "DwarfException.h"
-#include "llvm/CodeGen/MachineModuleInfo.h"
-
-using namespace llvm;
-
-static RegisterPass<DwarfWriter>
-X("dwarfwriter", "DWARF Information Writer");
-char DwarfWriter::ID = 0;
-
-//===----------------------------------------------------------------------===//
-/// DwarfWriter Implementation
-///
-
-DwarfWriter::DwarfWriter()
- : ImmutablePass(&ID), DD(0), DE(0) {}
-
-DwarfWriter::~DwarfWriter() {
- delete DE;
- delete DD;
-}
-
-/// BeginModule - Emit all Dwarf sections that should come prior to the
-/// content.
-void DwarfWriter::BeginModule(Module *M,
- MachineModuleInfo *MMI,
- raw_ostream &OS, AsmPrinter *A,
- const MCAsmInfo *T) {
- DE = new DwarfException(OS, A, T);
- DD = new DwarfDebug(OS, A, T);
- DE->BeginModule(M, MMI);
- DD->beginModule(M, MMI);
-}
-
-/// EndModule - Emit all Dwarf sections that should come after the content.
-///
-void DwarfWriter::EndModule() {
- DE->EndModule();
- DD->endModule();
- delete DD; DD = 0;
- delete DE; DE = 0;
-}
-
-/// BeginFunction - Gather pre-function debug information. Assumes being
-/// emitted immediately after the function entry point.
-void DwarfWriter::BeginFunction(const MachineFunction *MF) {
- DE->BeginFunction(MF);
- DD->beginFunction(MF);
-}
-
-/// EndFunction - Gather and emit post-function debug information.
-///
-void DwarfWriter::EndFunction(const MachineFunction *MF) {
- DD->endFunction(MF);
- DE->EndFunction();
-
- if (MachineModuleInfo *MMI = DD->getMMI() ? DD->getMMI() : DE->getMMI())
- // Clear function debug information.
- MMI->EndFunction();
-}
-
-/// ShouldEmitDwarfDebug - Returns true if Dwarf debugging declarations should
-/// be emitted.
-bool DwarfWriter::ShouldEmitDwarfDebug() const {
- return DD && DD->ShouldEmitDwarfDebug();
-}
-
-void DwarfWriter::BeginScope(const MachineInstr *MI) {
- DD->beginScope(MI);
-}
-void DwarfWriter::EndScope(const MachineInstr *MI) {
- DD->endScope(MI);
-}
diff --git a/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp b/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp
index fa840e1..1db178f 100644
--- a/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp
+++ b/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp
@@ -16,11 +16,14 @@
#include "llvm/CodeGen/GCMetadataPrinter.h"
#include "llvm/Module.h"
#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MCStreamer.h"
+#include "llvm/Target/Mangler.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetMachine.h"
+#include "llvm/ADT/SmallString.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormattedStream.h"
using namespace llvm;
@@ -29,11 +32,8 @@ namespace {
class OcamlGCMetadataPrinter : public GCMetadataPrinter {
public:
- void beginAssembly(raw_ostream &OS, AsmPrinter &AP,
- const MCAsmInfo &MAI);
-
- void finishAssembly(raw_ostream &OS, AsmPrinter &AP,
- const MCAsmInfo &MAI);
+ void beginAssembly(AsmPrinter &AP);
+ void finishAssembly(AsmPrinter &AP);
};
}
@@ -43,33 +43,34 @@ Y("ocaml", "ocaml 3.10-compatible collector");
void llvm::linkOcamlGCPrinter() { }
-static void EmitCamlGlobal(const Module &M, raw_ostream &OS, AsmPrinter &AP,
- const MCAsmInfo &MAI, const char *Id) {
+static void EmitCamlGlobal(const Module &M, AsmPrinter &AP, const char *Id) {
const std::string &MId = M.getModuleIdentifier();
- std::string Mangled;
- Mangled += MAI.getGlobalPrefix();
- Mangled += "caml";
- size_t Letter = Mangled.size();
- Mangled.append(MId.begin(), std::find(MId.begin(), MId.end(), '.'));
- Mangled += "__";
- Mangled += Id;
-
+ std::string SymName;
+ SymName += "caml";
+ size_t Letter = SymName.size();
+ SymName.append(MId.begin(), std::find(MId.begin(), MId.end(), '.'));
+ SymName += "__";
+ SymName += Id;
+
// Capitalize the first letter of the module name.
- Mangled[Letter] = toupper(Mangled[Letter]);
-
- if (const char *GlobalDirective = MAI.getGlobalDirective())
- OS << GlobalDirective << Mangled << "\n";
- OS << Mangled << ":\n";
+ SymName[Letter] = toupper(SymName[Letter]);
+
+ SmallString<128> TmpStr;
+ AP.Mang->getNameWithPrefix(TmpStr, SymName);
+
+ MCSymbol *Sym = AP.OutContext.GetOrCreateSymbol(TmpStr);
+
+ AP.OutStreamer.EmitSymbolAttribute(Sym, MCSA_Global);
+ AP.OutStreamer.EmitLabel(Sym);
}
-void OcamlGCMetadataPrinter::beginAssembly(raw_ostream &OS, AsmPrinter &AP,
- const MCAsmInfo &MAI) {
+void OcamlGCMetadataPrinter::beginAssembly(AsmPrinter &AP) {
AP.OutStreamer.SwitchSection(AP.getObjFileLowering().getTextSection());
- EmitCamlGlobal(getModule(), OS, AP, MAI, "code_begin");
+ EmitCamlGlobal(getModule(), AP, "code_begin");
AP.OutStreamer.SwitchSection(AP.getObjFileLowering().getDataSection());
- EmitCamlGlobal(getModule(), OS, AP, MAI, "data_begin");
+ EmitCamlGlobal(getModule(), AP, "data_begin");
}
/// emitAssembly - Print the frametable. The ocaml frametable format is thus:
@@ -88,28 +89,20 @@ void OcamlGCMetadataPrinter::beginAssembly(raw_ostream &OS, AsmPrinter &AP,
/// (FrameSize and LiveOffsets would overflow). FrameTablePrinter will abort if
/// either condition is detected in a function which uses the GC.
///
-void OcamlGCMetadataPrinter::finishAssembly(raw_ostream &OS, AsmPrinter &AP,
- const MCAsmInfo &MAI) {
- const char *AddressDirective;
- int AddressAlignLog;
- if (AP.TM.getTargetData()->getPointerSize() == sizeof(int32_t)) {
- AddressDirective = MAI.getData32bitsDirective();
- AddressAlignLog = 2;
- } else {
- AddressDirective = MAI.getData64bitsDirective();
- AddressAlignLog = 3;
- }
+void OcamlGCMetadataPrinter::finishAssembly(AsmPrinter &AP) {
+ unsigned IntPtrSize = AP.TM.getTargetData()->getPointerSize();
AP.OutStreamer.SwitchSection(AP.getObjFileLowering().getTextSection());
- EmitCamlGlobal(getModule(), OS, AP, MAI, "code_end");
+ EmitCamlGlobal(getModule(), AP, "code_end");
AP.OutStreamer.SwitchSection(AP.getObjFileLowering().getDataSection());
- EmitCamlGlobal(getModule(), OS, AP, MAI, "data_end");
+ EmitCamlGlobal(getModule(), AP, "data_end");
- OS << AddressDirective << 0 << '\n'; // FIXME: Why does ocaml emit this??
+ // FIXME: Why does ocaml emit this??
+ AP.OutStreamer.EmitIntValue(0, IntPtrSize, 0);
AP.OutStreamer.SwitchSection(AP.getObjFileLowering().getDataSection());
- EmitCamlGlobal(getModule(), OS, AP, MAI, "frametable");
+ EmitCamlGlobal(getModule(), AP, "frametable");
for (iterator I = begin(), IE = end(); I != IE; ++I) {
GCFunctionInfo &FI = **I;
@@ -125,8 +118,9 @@ void OcamlGCMetadataPrinter::finishAssembly(raw_ostream &OS, AsmPrinter &AP,
llvm_report_error(Msg.str()); // Very rude!
}
- OS << "\t" << MAI.getCommentString() << " live roots for "
- << FI.getFunction().getName() << "\n";
+ AP.OutStreamer.AddComment("live roots for " +
+ Twine(FI.getFunction().getName()));
+ AP.OutStreamer.AddBlankLine();
for (GCFunctionInfo::iterator J = FI.begin(), JE = FI.end(); J != JE; ++J) {
size_t LiveCount = FI.live_size(J);
@@ -139,10 +133,8 @@ void OcamlGCMetadataPrinter::finishAssembly(raw_ostream &OS, AsmPrinter &AP,
llvm_report_error(Msg.str()); // Very rude!
}
- OS << AddressDirective << J->Label->getName() << '\n';
-
+ AP.OutStreamer.EmitSymbolValue(J->Label, IntPtrSize, 0);
AP.EmitInt16(FrameSize);
-
AP.EmitInt16(LiveCount);
for (GCFunctionInfo::live_iterator K = FI.live_begin(J),
@@ -154,7 +146,7 @@ void OcamlGCMetadataPrinter::finishAssembly(raw_ostream &OS, AsmPrinter &AP,
AP.EmitInt32(K->StackOffset);
}
- AP.EmitAlignment(AddressAlignLog);
+ AP.EmitAlignment(IntPtrSize == 4 ? 2 : 3);
}
}
}
diff --git a/lib/CodeGen/GCMetadataPrinter.cpp b/lib/CodeGen/GCMetadataPrinter.cpp
index 752752f..f80e9ce 100644
--- a/lib/CodeGen/GCMetadataPrinter.cpp
+++ b/lib/CodeGen/GCMetadataPrinter.cpp
@@ -18,12 +18,10 @@ GCMetadataPrinter::GCMetadataPrinter() { }
GCMetadataPrinter::~GCMetadataPrinter() { }
-void GCMetadataPrinter::beginAssembly(raw_ostream &OS, AsmPrinter &AP,
- const MCAsmInfo &MAI) {
+void GCMetadataPrinter::beginAssembly(AsmPrinter &AP) {
// Default is no action.
}
-void GCMetadataPrinter::finishAssembly(raw_ostream &OS, AsmPrinter &AP,
- const MCAsmInfo &MAI) {
+void GCMetadataPrinter::finishAssembly(AsmPrinter &AP) {
// Default is no action.
}
diff --git a/lib/CodeGen/LLVMTargetMachine.cpp b/lib/CodeGen/LLVMTargetMachine.cpp
index 75e45ef..ed57f4c 100644
--- a/lib/CodeGen/LLVMTargetMachine.cpp
+++ b/lib/CodeGen/LLVMTargetMachine.cpp
@@ -123,18 +123,15 @@ bool LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM,
const MCAsmInfo &MAI = *getMCAsmInfo();
OwningPtr<MCStreamer> AsmStreamer;
- formatted_raw_ostream *LegacyOutput;
switch (FileType) {
default: return true;
case CGFT_AssemblyFile: {
MCInstPrinter *InstPrinter =
- getTarget().createMCInstPrinter(MAI.getAssemblerDialect(), MAI, Out);
+ getTarget().createMCInstPrinter(MAI.getAssemblerDialect(), MAI);
AsmStreamer.reset(createAsmStreamer(*Context, Out,
getTargetData()->isLittleEndian(),
getVerboseAsm(), InstPrinter,
/*codeemitter*/0));
- // Set the AsmPrinter's "O" to the output file.
- LegacyOutput = &Out;
break;
}
case CGFT_ObjectFile: {
@@ -146,29 +143,17 @@ bool LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM,
return true;
AsmStreamer.reset(createMachOStreamer(*Context, *TAB, Out, MCE));
-
- // Any output to the asmprinter's "O" stream is bad and needs to be fixed,
- // force it to come out stderr.
- // FIXME: this is horrible and leaks, eventually remove the raw_ostream from
- // asmprinter.
- LegacyOutput = new formatted_raw_ostream(errs());
break;
}
case CGFT_Null:
// The Null output is intended for use for performance analysis and testing,
// not real users.
AsmStreamer.reset(createNullStreamer(*Context));
- // Any output to the asmprinter's "O" stream is bad and needs to be fixed,
- // force it to come out stderr.
- // FIXME: this is horrible and leaks, eventually remove the raw_ostream from
- // asmprinter.
- LegacyOutput = new formatted_raw_ostream(errs());
break;
}
// Create the AsmPrinter, which takes ownership of AsmStreamer if successful.
- FunctionPass *Printer =
- getTarget().createAsmPrinter(*LegacyOutput, *this, *AsmStreamer);
+ FunctionPass *Printer = getTarget().createAsmPrinter(*this, *AsmStreamer);
if (Printer == 0)
return true;
diff --git a/lib/CodeGen/MachineFunction.cpp b/lib/CodeGen/MachineFunction.cpp
index beac0c6..e4ed7db 100644
--- a/lib/CodeGen/MachineFunction.cpp
+++ b/lib/CodeGen/MachineFunction.cpp
@@ -23,6 +23,7 @@
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/MC/MCAsmInfo.h"
@@ -51,8 +52,8 @@ void ilist_traits<MachineBasicBlock>::deleteNode(MachineBasicBlock *MBB) {
}
MachineFunction::MachineFunction(Function *F, const TargetMachine &TM,
- unsigned FunctionNum, MCContext &ctx)
- : Fn(F), Target(TM), Ctx(ctx) {
+ unsigned FunctionNum, MachineModuleInfo &mmi)
+ : Fn(F), Target(TM), Ctx(mmi.getContext()), MMI(mmi) {
if (TM.getRegisterInfo())
RegInfo = new (Allocator) MachineRegisterInfo(*TM.getRegisterInfo());
else
diff --git a/lib/CodeGen/MachineFunctionAnalysis.cpp b/lib/CodeGen/MachineFunctionAnalysis.cpp
index d3f1d82..3b2eb6d 100644
--- a/lib/CodeGen/MachineFunctionAnalysis.cpp
+++ b/lib/CodeGen/MachineFunctionAnalysis.cpp
@@ -35,10 +35,23 @@ MachineFunctionAnalysis::~MachineFunctionAnalysis() {
assert(!MF && "MachineFunctionAnalysis left initialized!");
}
+void MachineFunctionAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesAll();
+ AU.addRequired<MachineModuleInfo>();
+}
+
+bool MachineFunctionAnalysis::doInitialization(Module &M) {
+ MachineModuleInfo *MMI = getAnalysisIfAvailable<MachineModuleInfo>();
+ assert(MMI && "MMI not around yet??");
+ MMI->setModule(&M);
+ NextFnNum = 1; return false;
+}
+
+
bool MachineFunctionAnalysis::runOnFunction(Function &F) {
assert(!MF && "MachineFunctionAnalysis already initialized!");
MF = new MachineFunction(&F, TM, NextFnNum++,
- getAnalysis<MachineModuleInfo>().getContext());
+ getAnalysis<MachineModuleInfo>());
return false;
}
@@ -46,8 +59,3 @@ void MachineFunctionAnalysis::releaseMemory() {
delete MF;
MF = 0;
}
-
-void MachineFunctionAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
- AU.setPreservesAll();
- AU.addRequired<MachineModuleInfo>();
-}
diff --git a/lib/CodeGen/MachineModuleInfo.cpp b/lib/CodeGen/MachineModuleInfo.cpp
index ad4f01b..f813a55 100644
--- a/lib/CodeGen/MachineModuleInfo.cpp
+++ b/lib/CodeGen/MachineModuleInfo.cpp
@@ -262,6 +262,7 @@ MachineModuleInfo::MachineModuleInfo(const MCAsmInfo &MAI)
// Always emit some info, by default "no personality" info.
Personalities.push_back(NULL);
AddrLabelSymbols = 0;
+ TheModule = 0;
}
MachineModuleInfo::MachineModuleInfo()
diff --git a/lib/CodeGen/MachineSink.cpp b/lib/CodeGen/MachineSink.cpp
index e47ba7c..e659619 100644
--- a/lib/CodeGen/MachineSink.cpp
+++ b/lib/CodeGen/MachineSink.cpp
@@ -126,6 +126,11 @@ bool MachineSinking::ProcessBlock(MachineBasicBlock &MBB) {
// Can't sink anything out of a block that has less than two successors.
if (MBB.succ_size() <= 1 || MBB.empty()) return false;
+ // Don't bother sinking code out of unreachable blocks. In addition to being
+ // unprofitable, it can also lead to infinite looping, because in an unreachable
+ // loop there may be nowhere to stop.
+ if (!DT->isReachableFromEntry(&MBB)) return false;
+
bool MadeChange = false;
// Walk the basic block bottom-up. Remember if we saw a store.
diff --git a/lib/CodeGen/PrologEpilogInserter.cpp b/lib/CodeGen/PrologEpilogInserter.cpp
index 2d54cd4..27cb566 100644
--- a/lib/CodeGen/PrologEpilogInserter.cpp
+++ b/lib/CodeGen/PrologEpilogInserter.cpp
@@ -24,7 +24,6 @@
#include "llvm/CodeGen/MachineLoopInfo.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
-#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/RegisterScavenging.h"
#include "llvm/Target/TargetMachine.h"
@@ -59,11 +58,6 @@ bool PEI::runOnMachineFunction(MachineFunction &Fn) {
FrameIndexVirtualScavenging = TRI->requiresFrameIndexScavenging(Fn);
FrameConstantRegMap.clear();
- // Get MachineModuleInfo so that we can track the construction of the
- // frame.
- if (MachineModuleInfo *MMI = getAnalysisIfAvailable<MachineModuleInfo>())
- Fn.getFrameInfo()->setMachineModuleInfo(MMI);
-
// Calculate the MaxCallFrameSize and HasCalls variables for the function's
// frame information. Also eliminates call frame pseudo instructions.
calculateCallsInformation(Fn);
diff --git a/lib/CodeGen/SelectionDAG/FastISel.cpp b/lib/CodeGen/SelectionDAG/FastISel.cpp
index d6f8a20..4bf41f2 100644
--- a/lib/CodeGen/SelectionDAG/FastISel.cpp
+++ b/lib/CodeGen/SelectionDAG/FastISel.cpp
@@ -47,7 +47,6 @@
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
-#include "llvm/CodeGen/DwarfWriter.h"
#include "llvm/Analysis/DebugInfo.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetInstrInfo.h"
@@ -326,8 +325,8 @@ bool FastISel::SelectCall(User *I) {
default: break;
case Intrinsic::dbg_declare: {
DbgDeclareInst *DI = cast<DbgDeclareInst>(I);
- if (!DIDescriptor::ValidDebugInfo(DI->getVariable(), CodeGenOpt::None)||!DW
- || !DW->ShouldEmitDwarfDebug())
+ if (!DIDescriptor::ValidDebugInfo(DI->getVariable(), CodeGenOpt::None) ||
+ !MF.getMMI().hasDebugInfo())
return true;
Value *Address = DI->getAddress();
@@ -341,7 +340,7 @@ bool FastISel::SelectCall(User *I) {
if (SI == StaticAllocaMap.end()) break; // VLAs.
int FI = SI->second;
if (!DI->getDebugLoc().isUnknown())
- MMI->setVariableDbgInfo(DI->getVariable(), FI, DI->getDebugLoc());
+ MF.getMMI().setVariableDbgInfo(DI->getVariable(), FI, DI->getDebugLoc());
// Building the map above is target independent. Generating DBG_VALUE
// inline is target dependent; do this now.
@@ -400,44 +399,39 @@ bool FastISel::SelectCall(User *I) {
switch (TLI.getOperationAction(ISD::EHSELECTION, VT)) {
default: break;
case TargetLowering::Expand: {
- if (MMI) {
- if (MBB->isLandingPad())
- AddCatchInfo(*cast<CallInst>(I), MMI, MBB);
- else {
+ if (MBB->isLandingPad())
+ AddCatchInfo(*cast<CallInst>(I), &MF.getMMI(), MBB);
+ else {
#ifndef NDEBUG
- CatchInfoLost.insert(cast<CallInst>(I));
+ CatchInfoLost.insert(cast<CallInst>(I));
#endif
- // FIXME: Mark exception selector register as live in. Hack for PR1508.
- unsigned Reg = TLI.getExceptionSelectorRegister();
- if (Reg) MBB->addLiveIn(Reg);
- }
-
+ // FIXME: Mark exception selector register as live in. Hack for PR1508.
unsigned Reg = TLI.getExceptionSelectorRegister();
- EVT SrcVT = TLI.getPointerTy();
- const TargetRegisterClass *RC = TLI.getRegClassFor(SrcVT);
- unsigned ResultReg = createResultReg(RC);
- bool InsertedCopy = TII.copyRegToReg(*MBB, MBB->end(), ResultReg, Reg,
- RC, RC);
- assert(InsertedCopy && "Can't copy address registers!");
- InsertedCopy = InsertedCopy;
-
- // Cast the register to the type of the selector.
- if (SrcVT.bitsGT(MVT::i32))
- ResultReg = FastEmit_r(SrcVT.getSimpleVT(), MVT::i32, ISD::TRUNCATE,
- ResultReg);
- else if (SrcVT.bitsLT(MVT::i32))
- ResultReg = FastEmit_r(SrcVT.getSimpleVT(), MVT::i32,
- ISD::SIGN_EXTEND, ResultReg);
- if (ResultReg == 0)
- // Unhandled operand. Halt "fast" selection and bail.
- return false;
-
- UpdateValueMap(I, ResultReg);
- } else {
- unsigned ResultReg =
- getRegForValue(Constant::getNullValue(I->getType()));
- UpdateValueMap(I, ResultReg);
+ if (Reg) MBB->addLiveIn(Reg);
}
+
+ unsigned Reg = TLI.getExceptionSelectorRegister();
+ EVT SrcVT = TLI.getPointerTy();
+ const TargetRegisterClass *RC = TLI.getRegClassFor(SrcVT);
+ unsigned ResultReg = createResultReg(RC);
+ bool InsertedCopy = TII.copyRegToReg(*MBB, MBB->end(), ResultReg, Reg,
+ RC, RC);
+ assert(InsertedCopy && "Can't copy address registers!");
+ InsertedCopy = InsertedCopy;
+
+ // Cast the register to the type of the selector.
+ if (SrcVT.bitsGT(MVT::i32))
+ ResultReg = FastEmit_r(SrcVT.getSimpleVT(), MVT::i32, ISD::TRUNCATE,
+ ResultReg);
+ else if (SrcVT.bitsLT(MVT::i32))
+ ResultReg = FastEmit_r(SrcVT.getSimpleVT(), MVT::i32,
+ ISD::SIGN_EXTEND, ResultReg);
+ if (ResultReg == 0)
+ // Unhandled operand. Halt "fast" selection and bail.
+ return false;
+
+ UpdateValueMap(I, ResultReg);
+
return true;
}
}
@@ -734,8 +728,6 @@ FastISel::SelectOperator(User *I, unsigned Opcode) {
}
FastISel::FastISel(MachineFunction &mf,
- MachineModuleInfo *mmi,
- DwarfWriter *dw,
DenseMap<const Value *, unsigned> &vm,
DenseMap<const BasicBlock *, MachineBasicBlock *> &bm,
DenseMap<const AllocaInst *, int> &am
@@ -751,8 +743,6 @@ FastISel::FastISel(MachineFunction &mf,
CatchInfoLost(cil),
#endif
MF(mf),
- MMI(mmi),
- DW(dw),
MRI(MF.getRegInfo()),
MFI(*MF.getFrameInfo()),
MCP(*MF.getConstantPool()),
diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index 63ca8e6..d35f0da 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -16,7 +16,6 @@
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
-#include "llvm/CodeGen/DwarfWriter.h"
#include "llvm/Analysis/DebugInfo.h"
#include "llvm/CodeGen/PseudoSourceValue.h"
#include "llvm/Target/TargetFrameInfo.h"
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 3643ea7..8c0554d 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -793,7 +793,7 @@ unsigned SelectionDAG::getEVTAlignment(EVT VT) const {
// EntryNode could meaningfully have debug info if we can find it...
SelectionDAG::SelectionDAG(TargetLowering &tli, FunctionLoweringInfo &fli)
- : TLI(tli), FLI(fli), DW(0),
+ : TLI(tli), FLI(fli),
EntryNode(ISD::EntryToken, DebugLoc(), getVTList(MVT::Other)),
Root(getEntryNode()), Ordering(0) {
AllNodes.push_back(&EntryNode);
@@ -801,11 +801,8 @@ SelectionDAG::SelectionDAG(TargetLowering &tli, FunctionLoweringInfo &fli)
DbgInfo = new SDDbgInfo();
}
-void SelectionDAG::init(MachineFunction &mf, MachineModuleInfo *mmi,
- DwarfWriter *dw) {
+void SelectionDAG::init(MachineFunction &mf) {
MF = &mf;
- MMI = mmi;
- DW = dw;
Context = &mf.getFunction()->getContext();
}
@@ -2258,8 +2255,7 @@ bool SelectionDAG::isVerifiedDebugInfoDesc(SDValue Op) const {
if (GA->getOffset() != 0) return false;
GlobalVariable *GV = dyn_cast<GlobalVariable>(GA->getGlobal());
if (!GV) return false;
- MachineModuleInfo *MMI = getMachineModuleInfo();
- return MMI && MMI->hasDebugInfo();
+ return MF->getMMI().hasDebugInfo();
}
@@ -3210,11 +3206,9 @@ static bool FindOptimalMemOpLowering(std::vector<EVT> &MemOps,
NonScalarIntSafe, DAG);
if (VT == MVT::Other) {
- VT = TLI.getPointerTy();
- const Type *Ty = VT.getTypeForEVT(*DAG.getContext());
- if (DstAlign >= TLI.getTargetData()->getABITypeAlignment(Ty) ||
+ if (DstAlign >= TLI.getTargetData()->getPointerPrefAlignment() ||
TLI.allowsUnalignedMemoryAccesses(VT)) {
- VT = MVT::i64;
+ VT = TLI.getPointerTy();
} else {
switch (DstAlign & 7) {
case 0: VT = MVT::i64; break;
@@ -3263,7 +3257,8 @@ static bool FindOptimalMemOpLowering(std::vector<EVT> &MemOps,
static SDValue getMemcpyLoadsAndStores(SelectionDAG &DAG, DebugLoc dl,
SDValue Chain, SDValue Dst,
SDValue Src, uint64_t Size,
- unsigned Align, bool AlwaysInline,
+ unsigned Align, bool isVol,
+ bool AlwaysInline,
const Value *DstSV, uint64_t DstSVOff,
const Value *SrcSV, uint64_t SrcSVOff) {
// Turn a memcpy of undef to nop.
@@ -3322,7 +3317,7 @@ static SDValue getMemcpyLoadsAndStores(SelectionDAG &DAG, DebugLoc dl,
Value = getMemsetStringVal(VT, dl, DAG, TLI, Str, SrcOff);
Store = DAG.getStore(Chain, dl, Value,
getMemBasePlusOffset(Dst, DstOff, DAG),
- DstSV, DstSVOff + DstOff, false, false, Align);
+ DstSV, DstSVOff + DstOff, isVol, false, Align);
} else {
// The type might not be legal for the target. This should only happen
// if the type is smaller than a legal type, as on PPC, so the right
@@ -3333,11 +3328,11 @@ static SDValue getMemcpyLoadsAndStores(SelectionDAG &DAG, DebugLoc dl,
assert(NVT.bitsGE(VT));
Value = DAG.getExtLoad(ISD::EXTLOAD, dl, NVT, Chain,
getMemBasePlusOffset(Src, SrcOff, DAG),
- SrcSV, SrcSVOff + SrcOff, VT, false, false,
+ SrcSV, SrcSVOff + SrcOff, VT, isVol, false,
MinAlign(SrcAlign, SrcOff));
Store = DAG.getTruncStore(Chain, dl, Value,
getMemBasePlusOffset(Dst, DstOff, DAG),
- DstSV, DstSVOff + DstOff, VT, false, false,
+ DstSV, DstSVOff + DstOff, VT, isVol, false,
Align);
}
OutChains.push_back(Store);
@@ -3352,7 +3347,8 @@ static SDValue getMemcpyLoadsAndStores(SelectionDAG &DAG, DebugLoc dl,
static SDValue getMemmoveLoadsAndStores(SelectionDAG &DAG, DebugLoc dl,
SDValue Chain, SDValue Dst,
SDValue Src, uint64_t Size,
- unsigned Align,bool AlwaysInline,
+ unsigned Align, bool isVol,
+ bool AlwaysInline,
const Value *DstSV, uint64_t DstSVOff,
const Value *SrcSV, uint64_t SrcSVOff) {
// Turn a memmove of undef to nop.
@@ -3403,7 +3399,7 @@ static SDValue getMemmoveLoadsAndStores(SelectionDAG &DAG, DebugLoc dl,
Value = DAG.getLoad(VT, dl, Chain,
getMemBasePlusOffset(Src, SrcOff, DAG),
- SrcSV, SrcSVOff + SrcOff, false, false, SrcAlign);
+ SrcSV, SrcSVOff + SrcOff, isVol, false, SrcAlign);
LoadValues.push_back(Value);
LoadChains.push_back(Value.getValue(1));
SrcOff += VTSize;
@@ -3418,7 +3414,7 @@ static SDValue getMemmoveLoadsAndStores(SelectionDAG &DAG, DebugLoc dl,
Store = DAG.getStore(Chain, dl, LoadValues[i],
getMemBasePlusOffset(Dst, DstOff, DAG),
- DstSV, DstSVOff + DstOff, false, false, Align);
+ DstSV, DstSVOff + DstOff, isVol, false, Align);
OutChains.push_back(Store);
DstOff += VTSize;
}
@@ -3430,7 +3426,7 @@ static SDValue getMemmoveLoadsAndStores(SelectionDAG &DAG, DebugLoc dl,
static SDValue getMemsetStores(SelectionDAG &DAG, DebugLoc dl,
SDValue Chain, SDValue Dst,
SDValue Src, uint64_t Size,
- unsigned Align,
+ unsigned Align, bool isVol,
const Value *DstSV, uint64_t DstSVOff) {
// Turn a memset of undef to nop.
if (Src.getOpcode() == ISD::UNDEF)
@@ -3472,7 +3468,7 @@ static SDValue getMemsetStores(SelectionDAG &DAG, DebugLoc dl,
SDValue Value = getMemsetValue(Src, VT, DAG, dl);
SDValue Store = DAG.getStore(Chain, dl, Value,
getMemBasePlusOffset(Dst, DstOff, DAG),
- DstSV, DstSVOff + DstOff, false, false, 0);
+ DstSV, DstSVOff + DstOff, isVol, false, 0);
OutChains.push_back(Store);
DstOff += VTSize;
}
@@ -3483,7 +3479,7 @@ static SDValue getMemsetStores(SelectionDAG &DAG, DebugLoc dl,
SDValue SelectionDAG::getMemcpy(SDValue Chain, DebugLoc dl, SDValue Dst,
SDValue Src, SDValue Size,
- unsigned Align, bool AlwaysInline,
+ unsigned Align, bool isVol, bool AlwaysInline,
const Value *DstSV, uint64_t DstSVOff,
const Value *SrcSV, uint64_t SrcSVOff) {
@@ -3497,7 +3493,7 @@ SDValue SelectionDAG::getMemcpy(SDValue Chain, DebugLoc dl, SDValue Dst,
SDValue Result = getMemcpyLoadsAndStores(*this, dl, Chain, Dst, Src,
ConstantSize->getZExtValue(),Align,
- false, DstSV, DstSVOff, SrcSV, SrcSVOff);
+ isVol, false, DstSV, DstSVOff, SrcSV, SrcSVOff);
if (Result.getNode())
return Result;
}
@@ -3506,7 +3502,7 @@ SDValue SelectionDAG::getMemcpy(SDValue Chain, DebugLoc dl, SDValue Dst,
// code. If the target chooses to do this, this is the next best.
SDValue Result =
TLI.EmitTargetCodeForMemcpy(*this, dl, Chain, Dst, Src, Size, Align,
- AlwaysInline,
+ isVol, AlwaysInline,
DstSV, DstSVOff, SrcSV, SrcSVOff);
if (Result.getNode())
return Result;
@@ -3516,10 +3512,16 @@ SDValue SelectionDAG::getMemcpy(SDValue Chain, DebugLoc dl, SDValue Dst,
if (AlwaysInline) {
assert(ConstantSize && "AlwaysInline requires a constant size!");
return getMemcpyLoadsAndStores(*this, dl, Chain, Dst, Src,
- ConstantSize->getZExtValue(), Align, true,
- DstSV, DstSVOff, SrcSV, SrcSVOff);
+ ConstantSize->getZExtValue(), Align, isVol,
+ true, DstSV, DstSVOff, SrcSV, SrcSVOff);
}
+ // FIXME: If the memcpy is volatile (isVol), lowering it to a plain libc
+ // memcpy is not guaranteed to be safe. libc memcpys aren't required to
+ // respect volatile, so they may do things like read or write memory
+ // beyond the given memory regions. But fixing this isn't easy, and most
+ // people don't care.
+
// Emit a library call.
TargetLowering::ArgListTy Args;
TargetLowering::ArgListEntry Entry;
@@ -3541,7 +3543,7 @@ SDValue SelectionDAG::getMemcpy(SDValue Chain, DebugLoc dl, SDValue Dst,
SDValue SelectionDAG::getMemmove(SDValue Chain, DebugLoc dl, SDValue Dst,
SDValue Src, SDValue Size,
- unsigned Align,
+ unsigned Align, bool isVol,
const Value *DstSV, uint64_t DstSVOff,
const Value *SrcSV, uint64_t SrcSVOff) {
@@ -3555,8 +3557,8 @@ SDValue SelectionDAG::getMemmove(SDValue Chain, DebugLoc dl, SDValue Dst,
SDValue Result =
getMemmoveLoadsAndStores(*this, dl, Chain, Dst, Src,
- ConstantSize->getZExtValue(),
- Align, false, DstSV, DstSVOff, SrcSV, SrcSVOff);
+ ConstantSize->getZExtValue(), Align, isVol,
+ false, DstSV, DstSVOff, SrcSV, SrcSVOff);
if (Result.getNode())
return Result;
}
@@ -3564,12 +3566,13 @@ SDValue SelectionDAG::getMemmove(SDValue Chain, DebugLoc dl, SDValue Dst,
// Then check to see if we should lower the memmove with target-specific
// code. If the target chooses to do this, this is the next best.
SDValue Result =
- TLI.EmitTargetCodeForMemmove(*this, dl, Chain, Dst, Src, Size, Align,
+ TLI.EmitTargetCodeForMemmove(*this, dl, Chain, Dst, Src, Size, Align, isVol,
DstSV, DstSVOff, SrcSV, SrcSVOff);
if (Result.getNode())
return Result;
// Emit a library call.
+ assert(!isVol && "library memmove does not support volatile");
TargetLowering::ArgListTy Args;
TargetLowering::ArgListEntry Entry;
Entry.Ty = TLI.getTargetData()->getIntPtrType(*getContext());
@@ -3590,7 +3593,7 @@ SDValue SelectionDAG::getMemmove(SDValue Chain, DebugLoc dl, SDValue Dst,
SDValue SelectionDAG::getMemset(SDValue Chain, DebugLoc dl, SDValue Dst,
SDValue Src, SDValue Size,
- unsigned Align,
+ unsigned Align, bool isVol,
const Value *DstSV, uint64_t DstSVOff) {
// Check to see if we should lower the memset to stores first.
@@ -3601,9 +3604,10 @@ SDValue SelectionDAG::getMemset(SDValue Chain, DebugLoc dl, SDValue Dst,
if (ConstantSize->isNullValue())
return Chain;
- SDValue Result = getMemsetStores(*this, dl, Chain, Dst, Src,
- ConstantSize->getZExtValue(),
- Align, DstSV, DstSVOff);
+ SDValue Result =
+ getMemsetStores(*this, dl, Chain, Dst, Src, ConstantSize->getZExtValue(),
+ Align, isVol, DstSV, DstSVOff);
+
if (Result.getNode())
return Result;
}
@@ -3611,12 +3615,13 @@ SDValue SelectionDAG::getMemset(SDValue Chain, DebugLoc dl, SDValue Dst,
// Then check to see if we should lower the memset with target-specific
// code. If the target chooses to do this, this is the next best.
SDValue Result =
- TLI.EmitTargetCodeForMemset(*this, dl, Chain, Dst, Src, Size, Align,
+ TLI.EmitTargetCodeForMemset(*this, dl, Chain, Dst, Src, Size, Align, isVol,
DstSV, DstSVOff);
if (Result.getNode())
return Result;
// Emit a library call.
+ assert(!isVol && "library memset does not support volatile");
const Type *IntPtrTy = TLI.getTargetData()->getIntPtrType(*getContext());
TargetLowering::ArgListTy Args;
TargetLowering::ArgListEntry Entry;
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 879bdb2..4bbb3de 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -40,7 +40,6 @@
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/PseudoSourceValue.h"
#include "llvm/CodeGen/SelectionDAG.h"
-#include "llvm/CodeGen/DwarfWriter.h"
#include "llvm/Analysis/DebugInfo.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Target/TargetData.h"
@@ -3731,28 +3730,50 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
case Intrinsic::longjmp:
return "_longjmp"+!TLI.usesUnderscoreLongJmp();
case Intrinsic::memcpy: {
+ // Assert for address < 256 since we support only user defined address
+ // spaces.
+ assert(cast<PointerType>(I.getOperand(1)->getType())->getAddressSpace()
+ < 256 &&
+ cast<PointerType>(I.getOperand(2)->getType())->getAddressSpace()
+ < 256 &&
+ "Unknown address space");
SDValue Op1 = getValue(I.getOperand(1));
SDValue Op2 = getValue(I.getOperand(2));
SDValue Op3 = getValue(I.getOperand(3));
unsigned Align = cast<ConstantInt>(I.getOperand(4))->getZExtValue();
- DAG.setRoot(DAG.getMemcpy(getRoot(), dl, Op1, Op2, Op3, Align, false,
+ bool isVol = cast<ConstantInt>(I.getOperand(5))->getZExtValue();
+ DAG.setRoot(DAG.getMemcpy(getRoot(), dl, Op1, Op2, Op3, Align, isVol, false,
I.getOperand(1), 0, I.getOperand(2), 0));
return 0;
}
case Intrinsic::memset: {
+ // Assert for address < 256 since we support only user defined address
+ // spaces.
+ assert(cast<PointerType>(I.getOperand(1)->getType())->getAddressSpace()
+ < 256 &&
+ "Unknown address space");
SDValue Op1 = getValue(I.getOperand(1));
SDValue Op2 = getValue(I.getOperand(2));
SDValue Op3 = getValue(I.getOperand(3));
unsigned Align = cast<ConstantInt>(I.getOperand(4))->getZExtValue();
- DAG.setRoot(DAG.getMemset(getRoot(), dl, Op1, Op2, Op3, Align,
+ bool isVol = cast<ConstantInt>(I.getOperand(5))->getZExtValue();
+ DAG.setRoot(DAG.getMemset(getRoot(), dl, Op1, Op2, Op3, Align, isVol,
I.getOperand(1), 0));
return 0;
}
case Intrinsic::memmove: {
+ // Assert for address < 256 since we support only user defined address
+ // spaces.
+ assert(cast<PointerType>(I.getOperand(1)->getType())->getAddressSpace()
+ < 256 &&
+ cast<PointerType>(I.getOperand(2)->getType())->getAddressSpace()
+ < 256 &&
+ "Unknown address space");
SDValue Op1 = getValue(I.getOperand(1));
SDValue Op2 = getValue(I.getOperand(2));
SDValue Op3 = getValue(I.getOperand(3));
unsigned Align = cast<ConstantInt>(I.getOperand(4))->getZExtValue();
+ bool isVol = cast<ConstantInt>(I.getOperand(5))->getZExtValue();
// If the source and destination are known to not be aliases, we can
// lower memmove as memcpy.
@@ -3761,12 +3782,12 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
Size = C->getZExtValue();
if (AA->alias(I.getOperand(1), Size, I.getOperand(2), Size) ==
AliasAnalysis::NoAlias) {
- DAG.setRoot(DAG.getMemcpy(getRoot(), dl, Op1, Op2, Op3, Align, false,
- I.getOperand(1), 0, I.getOperand(2), 0));
+ DAG.setRoot(DAG.getMemcpy(getRoot(), dl, Op1, Op2, Op3, Align, isVol,
+ false, I.getOperand(1), 0, I.getOperand(2), 0));
return 0;
}
- DAG.setRoot(DAG.getMemmove(getRoot(), dl, Op1, Op2, Op3, Align,
+ DAG.setRoot(DAG.getMemmove(getRoot(), dl, Op1, Op2, Op3, Align, isVol,
I.getOperand(1), 0, I.getOperand(2), 0));
return 0;
}
@@ -3776,9 +3797,6 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
if (OptLevel != CodeGenOpt::None)
// FIXME: Variable debug info is not supported here.
return 0;
- DwarfWriter *DW = DAG.getDwarfWriter();
- if (!DW)
- return 0;
DbgDeclareInst &DI = cast<DbgDeclareInst>(I);
if (!DIDescriptor::ValidDebugInfo(DI.getVariable(), CodeGenOpt::None))
return 0;
@@ -3799,15 +3817,12 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
return 0; // VLAs.
int FI = SI->second;
- if (MachineModuleInfo *MMI = DAG.getMachineModuleInfo())
- if (!DI.getDebugLoc().isUnknown())
- MMI->setVariableDbgInfo(Variable, FI, DI.getDebugLoc());
+ MachineModuleInfo &MMI = DAG.getMachineFunction().getMMI();
+ if (!DI.getDebugLoc().isUnknown() && MMI.hasDebugInfo())
+ MMI.setVariableDbgInfo(Variable, FI, DI.getDebugLoc());
return 0;
}
case Intrinsic::dbg_value: {
- DwarfWriter *DW = DAG.getDwarfWriter();
- if (!DW)
- return 0;
DbgValueInst &DI = cast<DbgValueInst>(I);
if (!DIDescriptor::ValidDebugInfo(DI.getVariable(), CodeGenOpt::None))
return 0;
@@ -3852,9 +3867,9 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
return 0; // VLAs.
int FI = SI->second;
- if (MachineModuleInfo *MMI = DAG.getMachineModuleInfo())
- if (!DI.getDebugLoc().isUnknown())
- MMI->setVariableDbgInfo(Variable, FI, DI.getDebugLoc());
+ MachineModuleInfo &MMI = DAG.getMachineFunction().getMMI();
+ if (!DI.getDebugLoc().isUnknown() && MMI.hasDebugInfo())
+ MMI.setVariableDbgInfo(Variable, FI, DI.getDebugLoc());
return 0;
}
case Intrinsic::eh_exception: {
@@ -3870,10 +3885,9 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
}
case Intrinsic::eh_selector: {
- MachineModuleInfo *MMI = DAG.getMachineModuleInfo();
-
+ MachineModuleInfo &MMI = DAG.getMachineFunction().getMMI();
if (CurMBB->isLandingPad())
- AddCatchInfo(I, MMI, CurMBB);
+ AddCatchInfo(I, &MMI, CurMBB);
else {
#ifndef NDEBUG
FuncInfo.CatchInfoLost.insert(&I);
@@ -3895,40 +3909,25 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
}
case Intrinsic::eh_typeid_for: {
- MachineModuleInfo *MMI = DAG.getMachineModuleInfo();
-
- if (MMI) {
- // Find the type id for the given typeinfo.
- GlobalVariable *GV = ExtractTypeInfo(I.getOperand(1));
- unsigned TypeID = MMI->getTypeIDFor(GV);
- Res = DAG.getConstant(TypeID, MVT::i32);
- } else {
- // Return something different to eh_selector.
- Res = DAG.getConstant(1, MVT::i32);
- }
-
+ // Find the type id for the given typeinfo.
+ GlobalVariable *GV = ExtractTypeInfo(I.getOperand(1));
+ unsigned TypeID = DAG.getMachineFunction().getMMI().getTypeIDFor(GV);
+ Res = DAG.getConstant(TypeID, MVT::i32);
setValue(&I, Res);
return 0;
}
case Intrinsic::eh_return_i32:
case Intrinsic::eh_return_i64:
- if (MachineModuleInfo *MMI = DAG.getMachineModuleInfo()) {
- MMI->setCallsEHReturn(true);
- DAG.setRoot(DAG.getNode(ISD::EH_RETURN, dl,
- MVT::Other,
- getControlRoot(),
- getValue(I.getOperand(1)),
- getValue(I.getOperand(2))));
- } else {
- setValue(&I, DAG.getConstant(0, TLI.getPointerTy()));
- }
-
+ DAG.getMachineFunction().getMMI().setCallsEHReturn(true);
+ DAG.setRoot(DAG.getNode(ISD::EH_RETURN, dl,
+ MVT::Other,
+ getControlRoot(),
+ getValue(I.getOperand(1)),
+ getValue(I.getOperand(2))));
return 0;
case Intrinsic::eh_unwind_init:
- if (MachineModuleInfo *MMI = DAG.getMachineModuleInfo()) {
- MMI->setCallsUnwindInit(true);
- }
+ DAG.getMachineFunction().getMMI().setCallsUnwindInit(true);
return 0;
case Intrinsic::eh_dwarf_cfa: {
EVT VT = getValue(I.getOperand(1)).getValueType();
@@ -3947,12 +3946,12 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
return 0;
}
case Intrinsic::eh_sjlj_callsite: {
- MachineModuleInfo *MMI = DAG.getMachineModuleInfo();
+ MachineModuleInfo &MMI = DAG.getMachineFunction().getMMI();
ConstantInt *CI = dyn_cast<ConstantInt>(I.getOperand(1));
assert(CI && "Non-constant call site value in eh.sjlj.callsite!");
- assert(MMI->getCurrentCallSite() == 0 && "Overlapping call sites!");
+ assert(MMI.getCurrentCallSite() == 0 && "Overlapping call sites!");
- MMI->setCurrentCallSite(CI->getZExtValue());
+ MMI.setCurrentCallSite(CI->getZExtValue());
return 0;
}
@@ -4337,7 +4336,7 @@ void SelectionDAGBuilder::LowerCallTo(CallSite CS, SDValue Callee,
const PointerType *PT = cast<PointerType>(CS.getCalledValue()->getType());
const FunctionType *FTy = cast<FunctionType>(PT->getElementType());
const Type *RetTy = FTy->getReturnType();
- MachineModuleInfo *MMI = DAG.getMachineModuleInfo();
+ MachineModuleInfo &MMI = DAG.getMachineFunction().getMMI();
MCSymbol *BeginLabel = 0;
TargetLowering::ArgListTy Args;
@@ -4395,18 +4394,18 @@ void SelectionDAGBuilder::LowerCallTo(CallSite CS, SDValue Callee,
Args.push_back(Entry);
}
- if (LandingPad && MMI) {
+ if (LandingPad) {
// Insert a label before the invoke call to mark the try range. This can be
// used to detect deletion of the invoke via the MachineModuleInfo.
- BeginLabel = MMI->getContext().CreateTempSymbol();
+ BeginLabel = MMI.getContext().CreateTempSymbol();
// For SjLj, keep track of which landing pads go with which invokes
// so as to maintain the ordering of pads in the LSDA.
- unsigned CallSiteIndex = MMI->getCurrentCallSite();
+ unsigned CallSiteIndex = MMI.getCurrentCallSite();
if (CallSiteIndex) {
- MMI->setCallSiteBeginLabel(BeginLabel, CallSiteIndex);
+ MMI.setCallSiteBeginLabel(BeginLabel, CallSiteIndex);
// Now that the call site is handled, stop tracking it.
- MMI->setCurrentCallSite(0);
+ MMI.setCurrentCallSite(0);
}
// Both PendingLoads and PendingExports must be flushed here;
@@ -4497,14 +4496,14 @@ void SelectionDAGBuilder::LowerCallTo(CallSite CS, SDValue Callee,
else
HasTailCall = true;
- if (LandingPad && MMI) {
+ if (LandingPad) {
// Insert a label at the end of the invoke call to mark the try range. This
// can be used to detect deletion of the invoke via the MachineModuleInfo.
- MCSymbol *EndLabel = MMI->getContext().CreateTempSymbol();
+ MCSymbol *EndLabel = MMI.getContext().CreateTempSymbol();
DAG.setRoot(DAG.getEHLabel(getCurDebugLoc(), getRoot(), EndLabel));
// Inform MachineModuleInfo of range.
- MMI->addInvoke(LandingPad, BeginLabel, EndLabel);
+ MMI.addInvoke(LandingPad, BeginLabel, EndLabel);
}
}
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
index 9f02772..fdcba0f 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
@@ -56,7 +56,6 @@ class InsertValueInst;
class Instruction;
class LoadInst;
class MachineBasicBlock;
-class MachineFunction;
class MachineInstr;
class MachineRegisterInfo;
class PHINode;
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index d54566b..9b137a5 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -41,7 +41,6 @@
#include "llvm/CodeGen/ScheduleHazardRecognizer.h"
#include "llvm/CodeGen/SchedulerRegistry.h"
#include "llvm/CodeGen/SelectionDAG.h"
-#include "llvm/CodeGen/DwarfWriter.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetFrameInfo.h"
@@ -303,8 +302,6 @@ void SelectionDAGISel::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addPreserved<AliasAnalysis>();
AU.addRequired<GCModuleInfo>();
AU.addPreserved<GCModuleInfo>();
- AU.addRequired<DwarfWriter>();
- AU.addPreserved<DwarfWriter>();
MachineFunctionPass::getAnalysisUsage(AU);
}
@@ -331,9 +328,7 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) {
RegInfo = &MF->getRegInfo();
DEBUG(dbgs() << "\n\n\n=== " << Fn.getName() << "\n");
- MachineModuleInfo *MMI = getAnalysisIfAvailable<MachineModuleInfo>();
- DwarfWriter *DW = getAnalysisIfAvailable<DwarfWriter>();
- CurDAG->init(*MF, MMI, DW);
+ CurDAG->init(*MF);
FuncInfo->set(Fn, *MF, EnableFastISel);
SDB->init(GFI, *AA);
@@ -342,7 +337,7 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) {
// Mark landing pad.
FuncInfo->MBBMap[Invoke->getSuccessor(1)]->setIsLandingPad();
- SelectAllBasicBlocks(Fn, *MF, MMI, DW, TII);
+ SelectAllBasicBlocks(Fn, *MF, TII);
// If the first basic block in the function has live ins that need to be
// copied into vregs, emit the copies into the top of the block before
@@ -844,15 +839,11 @@ void SelectionDAGISel::DoInstructionSelection() {
void SelectionDAGISel::SelectAllBasicBlocks(Function &Fn,
MachineFunction &MF,
- MachineModuleInfo *MMI,
- DwarfWriter *DW,
const TargetInstrInfo &TII) {
// Initialize the Fast-ISel state, if needed.
FastISel *FastIS = 0;
if (EnableFastISel)
- FastIS = TLI.createFastISel(MF, MMI, DW,
- FuncInfo->ValueMap,
- FuncInfo->MBBMap,
+ FastIS = TLI.createFastISel(MF, FuncInfo->ValueMap, FuncInfo->MBBMap,
FuncInfo->StaticAllocaMap
#ifndef NDEBUG
, FuncInfo->CatchInfoLost
@@ -888,10 +879,10 @@ void SelectionDAGISel::SelectAllBasicBlocks(Function &Fn,
}
}
- if (MMI && BB->isLandingPad()) {
+ if (BB->isLandingPad()) {
// Add a label to mark the beginning of the landing pad. Deletion of the
// landing pad can thus be detected via the MachineModuleInfo.
- MCSymbol *Label = MMI->addLandingPad(BB);
+ MCSymbol *Label = MF.getMMI().addLandingPad(BB);
const TargetInstrDesc &II = TII.get(TargetOpcode::EH_LABEL);
BuildMI(BB, SDB->getCurDebugLoc(), II).addSym(Label);
@@ -925,7 +916,7 @@ void SelectionDAGISel::SelectAllBasicBlocks(Function &Fn,
if (I == E)
// No catch info found - try to extract some from the successor.
- CopyCatchInfo(Br->getSuccessor(0), LLVMBB, MMI, *FuncInfo);
+ CopyCatchInfo(Br->getSuccessor(0), LLVMBB, &MF.getMMI(), *FuncInfo);
}
}
diff --git a/lib/ExecutionEngine/JIT/JITEmitter.cpp b/lib/ExecutionEngine/JIT/JITEmitter.cpp
index a2df2d0..7b8ab9e 100644
--- a/lib/ExecutionEngine/JIT/JITEmitter.cpp
+++ b/lib/ExecutionEngine/JIT/JITEmitter.cpp
@@ -825,7 +825,8 @@ void JITEmitter::processDebugLoc(DebugLoc DL, bool BeforePrintingInsn) {
if (!BeforePrintingInsn) return;
// FIXME: This is horribly inefficient.
- DILocation CurDLT(DL.getAsMDNode(CurFn->getContext()));
+ DILocation CurDLT(DL.getAsMDNode(
+ EmissionDetails.MF->getFunction()->getContext()));
if (CurDLT.getScope().getNode() != 0 && PrevDLT.getNode() !=CurDLT.getNode()){
JITEvent_EmittedFunctionDetails::LineStart NextLine;
diff --git a/lib/ExecutionEngine/JIT/OProfileJITEventListener.cpp b/lib/ExecutionEngine/JIT/OProfileJITEventListener.cpp
index 2baf979..9c01b73 100644
--- a/lib/ExecutionEngine/JIT/OProfileJITEventListener.cpp
+++ b/lib/ExecutionEngine/JIT/OProfileJITEventListener.cpp
@@ -19,6 +19,7 @@
#define DEBUG_TYPE "oprofile-jit-event-listener"
#include "llvm/Function.h"
#include "llvm/Metadata.h"
+#include "llvm/ADT/DenseMap.h"
#include "llvm/Analysis/DebugInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/ExecutionEngine/JITEventListener.h"
@@ -77,10 +78,10 @@ class FilenameCache {
DenseMap<AssertingVH<MDNode>, std::string> Filenames;
public:
- const char *getFilename(DIScope Scope) {
- std::string &Filename = Filenames[Scope.getNode()];
+ const char *getFilename(MDNode *Scope) {
+ std::string &Filename = Filenames[Scope];
if (Filename.empty()) {
- Filename = Scope.getFilename();
+ Filename = DIScope(Scope).getFilename();
}
return Filename.c_str();
}
@@ -91,9 +92,9 @@ static debug_line_info LineStartToOProfileFormat(
uintptr_t Address, DebugLoc Loc) {
debug_line_info Result;
Result.vma = Address;
- DILocation DILoc = MF.getDILocation(Loc);
- Result.lineno = DILoc.getLineNumber();
- Result.filename = Filenames.getFilename(DILoc.getScope());
+ Result.lineno = Loc.getLine();
+ Result.filename = Filenames.getFilename(
+ Loc.getScope(MF.getFunction()->getContext()));
DEBUG(dbgs() << "Mapping " << reinterpret_cast<void*>(Result.vma) << " to "
<< Result.filename << ":" << Result.lineno << "\n");
return Result;
diff --git a/lib/MC/MCAsmInfo.cpp b/lib/MC/MCAsmInfo.cpp
index c96ff82..f0da694 100644
--- a/lib/MC/MCAsmInfo.cpp
+++ b/lib/MC/MCAsmInfo.cpp
@@ -60,8 +60,6 @@ MCAsmInfo::MCAsmInfo() {
LinkOnceDirective = 0;
HiddenVisibilityAttr = MCSA_Hidden;
ProtectedVisibilityAttr = MCSA_Protected;
- AbsoluteDebugSectionOffsets = false;
- AbsoluteEHSectionOffsets = false;
HasLEB128 = false;
HasDotLocAndDotFile = false;
SupportsDebugInformation = false;
diff --git a/lib/MC/MCAsmInfoCOFF.cpp b/lib/MC/MCAsmInfoCOFF.cpp
index 5170206..7fc7d7a 100644
--- a/lib/MC/MCAsmInfoCOFF.cpp
+++ b/lib/MC/MCAsmInfoCOFF.cpp
@@ -31,8 +31,6 @@ MCAsmInfoCOFF::MCAsmInfoCOFF() {
// Set up DWARF directives
HasLEB128 = true; // Target asm supports leb128 directives (little-endian)
- AbsoluteDebugSectionOffsets = true;
- AbsoluteEHSectionOffsets = false;
SupportsDebugInformation = true;
DwarfSectionOffsetDirective = "\t.secrel32\t";
HasMicrosoftFastStdCallMangling = true;
diff --git a/lib/MC/MCAsmStreamer.cpp b/lib/MC/MCAsmStreamer.cpp
index 7a23aec..2c7e1c4 100644
--- a/lib/MC/MCAsmStreamer.cpp
+++ b/lib/MC/MCAsmStreamer.cpp
@@ -68,6 +68,9 @@ public:
/// isVerboseAsm - Return true if this streamer supports verbose assembly at
/// all.
virtual bool isVerboseAsm() const { return IsVerboseAsm; }
+
+ /// hasRawTextSupport - We support EmitRawText.
+ virtual bool hasRawTextSupport() const { return true; }
/// AddComment - Add a comment that can be emitted to the generated .s
/// file if applicable as a QoI issue to make the output of the compiler
@@ -145,6 +148,11 @@ public:
virtual void EmitInstruction(const MCInst &Inst);
+ /// EmitRawText - If this file is backed by a assembly streamer, this dumps
+ /// the specified string in the output .s file. This capability is
+ /// indicated by the hasRawTextSupport() predicate.
+ virtual void EmitRawText(StringRef String);
+
virtual void Finish();
/// @}
@@ -195,7 +203,6 @@ void MCAsmStreamer::EmitCommentsAndEOL() {
CommentStream.resync();
}
-
static inline int64_t truncateToSize(int64_t Value, unsigned Bytes) {
assert(Bytes && "Invalid size!");
return Value & ((uint64_t) (int64_t) -1 >> (64 - Bytes * 8));
@@ -628,12 +635,22 @@ void MCAsmStreamer::EmitInstruction(const MCInst &Inst) {
// If we have an AsmPrinter, use that to print, otherwise print the MCInst.
if (InstPrinter)
- InstPrinter->printInst(&Inst);
+ InstPrinter->printInst(&Inst, OS);
else
Inst.print(OS, &MAI);
EmitEOL();
}
+/// EmitRawText - If this file is backed by a assembly streamer, this dumps
+/// the specified string in the output .s file. This capability is
+/// indicated by the hasRawTextSupport() predicate.
+void MCAsmStreamer::EmitRawText(StringRef String) {
+ if (!String.empty() && String.back() == '\n')
+ String = String.substr(0, String.size()-1);
+ OS << String;
+ EmitEOL();
+}
+
void MCAsmStreamer::Finish() {
OS.flush();
}
diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp
index 24616b4..4e62689 100644
--- a/lib/MC/MCParser/AsmParser.cpp
+++ b/lib/MC/MCParser/AsmParser.cpp
@@ -138,7 +138,7 @@ const AsmToken &AsmParser::Lex() {
return *tok;
}
-bool AsmParser::Run(bool NoInitialTextSection) {
+bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
// Create the initial section, if requested.
//
// FIXME: Target hook & command line option for initial section.
@@ -190,7 +190,9 @@ bool AsmParser::Run(bool NoInitialTextSection) {
TheCondState.Ignore != StartingCondState.Ignore)
return TokError("unmatched .ifs or .elses");
- if (!HadError)
+ // Finalize the output stream if there are no errors and if the client wants
+ // us to.
+ if (!HadError && !NoFinalize)
Out.Finish();
return HadError;
diff --git a/lib/MC/MCStreamer.cpp b/lib/MC/MCStreamer.cpp
index 703acc4..4f484a2 100644
--- a/lib/MC/MCStreamer.cpp
+++ b/lib/MC/MCStreamer.cpp
@@ -10,6 +10,9 @@
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/Twine.h"
+#include <cstdlib>
using namespace llvm;
MCStreamer::MCStreamer(MCContext &_Context) : Context(_Context), CurSection(0) {
@@ -44,3 +47,18 @@ void MCStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue,
for (uint64_t i = 0, e = NumBytes; i != e; ++i)
EmitValue(E, 1, AddrSpace);
}
+
+/// EmitRawText - If this file is backed by a assembly streamer, this dumps
+/// the specified string in the output .s file. This capability is
+/// indicated by the hasRawTextSupport() predicate.
+void MCStreamer::EmitRawText(StringRef String) {
+ errs() << "EmitRawText called on an MCStreamer that doesn't support it, "
+ " something must not be fully mc'ized\n";
+ abort();
+}
+
+void MCStreamer::EmitRawText(const Twine &T) {
+ SmallString<128> Str;
+ T.toVector(Str);
+ EmitRawText(Str.str());
+}
diff --git a/lib/Support/MemoryBuffer.cpp b/lib/Support/MemoryBuffer.cpp
index 4f135ea..2b95089 100644
--- a/lib/Support/MemoryBuffer.cpp
+++ b/lib/Support/MemoryBuffer.cpp
@@ -71,13 +71,12 @@ namespace {
class MemoryBufferMem : public MemoryBuffer {
std::string FileID;
public:
- MemoryBufferMem(const char *Start, const char *End, StringRef FID,
- bool Copy = false)
+ MemoryBufferMem(StringRef InputData, StringRef FID, bool Copy = false)
: FileID(FID) {
if (!Copy)
- init(Start, End);
+ init(InputData.data(), InputData.data()+InputData.size());
else
- initCopyOf(Start, End);
+ initCopyOf(InputData.data(), InputData.data()+InputData.size());
}
virtual const char *getBufferIdentifier() const {
@@ -88,19 +87,17 @@ public:
/// getMemBuffer - Open the specified memory range as a MemoryBuffer. Note
/// that EndPtr[0] must be a null byte and be accessible!
-MemoryBuffer *MemoryBuffer::getMemBuffer(const char *StartPtr,
- const char *EndPtr,
+MemoryBuffer *MemoryBuffer::getMemBuffer(StringRef InputData,
const char *BufferName) {
- return new MemoryBufferMem(StartPtr, EndPtr, BufferName);
+ return new MemoryBufferMem(InputData, BufferName);
}
/// getMemBufferCopy - Open the specified memory range as a MemoryBuffer,
/// copying the contents and taking ownership of it. This has no requirements
/// on EndPtr[0].
-MemoryBuffer *MemoryBuffer::getMemBufferCopy(const char *StartPtr,
- const char *EndPtr,
+MemoryBuffer *MemoryBuffer::getMemBufferCopy(StringRef InputData,
const char *BufferName) {
- return new MemoryBufferMem(StartPtr, EndPtr, BufferName, true);
+ return new MemoryBufferMem(InputData, BufferName, true);
}
/// getNewUninitMemBuffer - Allocate a new MemoryBuffer of the specified size
@@ -112,7 +109,7 @@ MemoryBuffer *MemoryBuffer::getNewUninitMemBuffer(size_t Size,
char *Buf = (char *)malloc(Size+1);
if (!Buf) return 0;
Buf[Size] = 0;
- MemoryBufferMem *SB = new MemoryBufferMem(Buf, Buf+Size, BufferName);
+ MemoryBufferMem *SB = new MemoryBufferMem(StringRef(Buf, Size), BufferName);
// The memory for this buffer is owned by the MemoryBuffer.
SB->MustDeleteBuffer = true;
return SB;
diff --git a/lib/Support/SourceMgr.cpp b/lib/Support/SourceMgr.cpp
index 83c7964..4e7520c 100644
--- a/lib/Support/SourceMgr.cpp
+++ b/lib/Support/SourceMgr.cpp
@@ -168,13 +168,21 @@ SMDiagnostic SourceMgr::GetMessage(SMLoc Loc, const std::string &Msg,
}
PrintedMsg += Msg;
- return SMDiagnostic(CurMB->getBufferIdentifier(), FindLineNumber(Loc, CurBuf),
+ return SMDiagnostic(Loc,
+ CurMB->getBufferIdentifier(), FindLineNumber(Loc, CurBuf),
Loc.getPointer()-LineStart, PrintedMsg,
LineStr, ShowLine);
}
void SourceMgr::PrintMessage(SMLoc Loc, const std::string &Msg,
const char *Type, bool ShowLine) const {
+ // Report the message with the diagnostic handler if present.
+ if (DiagHandler) {
+ DiagHandler(GetMessage(Loc, Msg, Type, ShowLine),
+ DiagContext, DiagLocCookie);
+ return;
+ }
+
raw_ostream &OS = errs();
int CurBuf = FindBufferContainingLoc(Loc);
diff --git a/lib/Support/regengine.inc b/lib/Support/regengine.inc
index 0f27cfd..bf55543 100644
--- a/lib/Support/regengine.inc
+++ b/lib/Support/regengine.inc
@@ -72,11 +72,11 @@ struct match {
struct re_guts *g;
int eflags;
llvm_regmatch_t *pmatch; /* [nsub+1] (0 element unused) */
- char *offp; /* offsets work from here */
- char *beginp; /* start of string -- virtual NUL precedes */
- char *endp; /* end of string -- virtual NUL here */
- char *coldp; /* can be no match starting before here */
- char **lastpos; /* [nplus+1] */
+ const char *offp; /* offsets work from here */
+ const char *beginp; /* start of string -- virtual NUL precedes */
+ const char *endp; /* end of string -- virtual NUL here */
+ const char *coldp; /* can be no match starting before here */
+ const char **lastpos; /* [nplus+1] */
STATEVARS;
states st; /* current states */
states fresh; /* states for a fresh start */
@@ -84,11 +84,14 @@ struct match {
states empty; /* empty set of states */
};
-static int matcher(struct re_guts *, char *, size_t, llvm_regmatch_t[], int);
-static char *dissect(struct match *, char *, char *, sopno, sopno);
-static char *backref(struct match *, char *, char *, sopno, sopno, sopno, int);
-static char *fast(struct match *, char *, char *, sopno, sopno);
-static char *slow(struct match *, char *, char *, sopno, sopno);
+static int matcher(struct re_guts *, const char *, size_t,
+ llvm_regmatch_t[], int);
+static const char *dissect(struct match *, const char *, const char *, sopno,
+ sopno);
+static const char *backref(struct match *, const char *, const char *, sopno,
+ sopno, sopno, int);
+static const char *fast(struct match *, const char *, const char *, sopno, sopno);
+static const char *slow(struct match *, const char *, const char *, sopno, sopno);
static states step(struct re_guts *, sopno, sopno, states, int, states);
#define MAX_RECURSION 100
#define BOL (OUT+1)
@@ -125,18 +128,19 @@ static int nope = 0;
- matcher - the actual matching engine
*/
static int /* 0 success, REG_NOMATCH failure */
-matcher(struct re_guts *g, char *string, size_t nmatch, llvm_regmatch_t pmatch[],
+matcher(struct re_guts *g, const char *string, size_t nmatch,
+ llvm_regmatch_t pmatch[],
int eflags)
{
- char *endp;
+ const char *endp;
size_t i;
struct match mv;
struct match *m = &mv;
- char *dp;
+ const char *dp;
const sopno gf = g->firststate+1; /* +1 for OEND */
const sopno gl = g->laststate;
- char *start;
- char *stop;
+ const char *start;
+ const char *stop;
/* simplify the situation where possible */
if (g->cflags&REG_NOSUB)
@@ -216,7 +220,7 @@ matcher(struct re_guts *g, char *string, size_t nmatch, llvm_regmatch_t pmatch[]
dp = dissect(m, m->coldp, endp, gf, gl);
} else {
if (g->nplus > 0 && m->lastpos == NULL)
- m->lastpos = (char **)malloc((g->nplus+1) *
+ m->lastpos = (const char **)malloc((g->nplus+1) *
sizeof(char *));
if (g->nplus > 0 && m->lastpos == NULL) {
free(m->pmatch);
@@ -287,21 +291,22 @@ matcher(struct re_guts *g, char *string, size_t nmatch, llvm_regmatch_t pmatch[]
/*
- dissect - figure out what matched what, no back references
*/
-static char * /* == stop (success) always */
-dissect(struct match *m, char *start, char *stop, sopno startst, sopno stopst)
+static const char * /* == stop (success) always */
+dissect(struct match *m, const char *start, const char *stop, sopno startst,
+ sopno stopst)
{
int i;
sopno ss; /* start sop of current subRE */
sopno es; /* end sop of current subRE */
- char *sp; /* start of string matched by it */
- char *stp; /* string matched by it cannot pass here */
- char *rest; /* start of rest of string */
- char *tail; /* string unmatched by rest of RE */
+ const char *sp; /* start of string matched by it */
+ const char *stp; /* string matched by it cannot pass here */
+ const char *rest; /* start of rest of string */
+ const char *tail; /* string unmatched by rest of RE */
sopno ssub; /* start sop of subsubRE */
sopno esub; /* end sop of subsubRE */
- char *ssp; /* start of string matched by subsubRE */
- char *sep; /* end of string matched by subsubRE */
- char *oldssp; /* previous ssp */
+ const char *ssp; /* start of string matched by subsubRE */
+ const char *sep; /* end of string matched by subsubRE */
+ const char *oldssp; /* previous ssp */
AT("diss", start, stop, startst, stopst);
sp = start;
@@ -360,7 +365,7 @@ dissect(struct match *m, char *start, char *stop, sopno startst, sopno stopst)
esub = es - 1;
/* did innards match? */
if (slow(m, sp, rest, ssub, esub) != NULL) {
- char *dp = dissect(m, sp, rest, ssub, esub);
+ const char *dp = dissect(m, sp, rest, ssub, esub);
(void)dp; /* avoid warning if assertions off */
assert(dp == rest);
} else /* no */
@@ -400,7 +405,7 @@ dissect(struct match *m, char *start, char *stop, sopno startst, sopno stopst)
assert(sep == rest); /* must exhaust substring */
assert(slow(m, ssp, sep, ssub, esub) == rest);
{
- char *dp = dissect(m, ssp, sep, ssub, esub);
+ const char *dp = dissect(m, ssp, sep, ssub, esub);
(void)dp; /* avoid warning if assertions off */
assert(dp == sep);
}
@@ -438,7 +443,7 @@ dissect(struct match *m, char *start, char *stop, sopno startst, sopno stopst)
assert(OP(m->g->strip[esub]) == O_CH);
}
{
- char *dp = dissect(m, sp, rest, ssub, esub);
+ const char *dp = dissect(m, sp, rest, ssub, esub);
(void)dp; /* avoid warning if assertions off */
assert(dp == rest);
}
@@ -474,17 +479,17 @@ dissect(struct match *m, char *start, char *stop, sopno startst, sopno stopst)
/*
- backref - figure out what matched what, figuring in back references
*/
-static char * /* == stop (success) or NULL (failure) */
-backref(struct match *m, char *start, char *stop, sopno startst, sopno stopst,
- sopno lev, int rec) /* PLUS nesting level */
+static const char * /* == stop (success) or NULL (failure) */
+backref(struct match *m, const char *start, const char *stop, sopno startst,
+ sopno stopst, sopno lev, int rec) /* PLUS nesting level */
{
int i;
sopno ss; /* start sop of current subRE */
- char *sp; /* start of string matched by it */
+ const char *sp; /* start of string matched by it */
sopno ssub; /* start sop of subsubRE */
sopno esub; /* end sop of subsubRE */
- char *ssp; /* start of string matched by subsubRE */
- char *dp;
+ const char *ssp; /* start of string matched by subsubRE */
+ const char *dp;
size_t len;
int hard;
sop s;
@@ -674,18 +679,19 @@ backref(struct match *m, char *start, char *stop, sopno startst, sopno stopst,
/*
- fast - step through the string at top speed
*/
-static char * /* where tentative match ended, or NULL */
-fast(struct match *m, char *start, char *stop, sopno startst, sopno stopst)
+static const char * /* where tentative match ended, or NULL */
+fast(struct match *m, const char *start, const char *stop, sopno startst,
+ sopno stopst)
{
states st = m->st;
states fresh = m->fresh;
states tmp = m->tmp;
- char *p = start;
+ const char *p = start;
int c = (start == m->beginp) ? OUT : *(start-1);
int lastc; /* previous c */
int flagch;
int i;
- char *coldp; /* last p after which no match was underway */
+ const char *coldp; /* last p after which no match was underway */
CLEAR(st);
SET1(st, startst);
@@ -758,18 +764,19 @@ fast(struct match *m, char *start, char *stop, sopno startst, sopno stopst)
/*
- slow - step through the string more deliberately
*/
-static char * /* where it ended */
-slow(struct match *m, char *start, char *stop, sopno startst, sopno stopst)
+static const char * /* where it ended */
+slow(struct match *m, const char *start, const char *stop, sopno startst,
+ sopno stopst)
{
states st = m->st;
states empty = m->empty;
states tmp = m->tmp;
- char *p = start;
+ const char *p = start;
int c = (start == m->beginp) ? OUT : *(start-1);
int lastc; /* previous c */
int flagch;
int i;
- char *matchp; /* last p at which a match ended */
+ const char *matchp; /* last p at which a match ended */
AT("slow", start, stop, startst, stopst);
CLEAR(st);
diff --git a/lib/Support/regexec.c b/lib/Support/regexec.c
index 7d70f6e..41fb2ea 100644
--- a/lib/Support/regexec.c
+++ b/lib/Support/regexec.c
@@ -155,7 +155,7 @@ llvm_regexec(const llvm_regex_t *preg, const char *string, size_t nmatch,
eflags = GOODFLAGS(eflags);
if (g->nstates <= (long)(CHAR_BIT*sizeof(states1)) && !(eflags&REG_LARGE))
- return(smatcher(g, (char *)string, nmatch, pmatch, eflags));
+ return(smatcher(g, string, nmatch, pmatch, eflags));
else
- return(lmatcher(g, (char *)string, nmatch, pmatch, eflags));
+ return(lmatcher(g, string, nmatch, pmatch, eflags));
}
diff --git a/lib/Target/ARM/ARM.td b/lib/Target/ARM/ARM.td
index 6486a60..8d9c622 100644
--- a/lib/Target/ARM/ARM.td
+++ b/lib/Target/ARM/ARM.td
@@ -140,23 +140,7 @@ include "ARMCallingConv.td"
include "ARMInstrInfo.td"
-def ARMInstrInfo : InstrInfo {
- // Define how we want to layout our target-specific information field.
- let TSFlagsFields = ["AddrModeBits",
- "SizeFlag",
- "IndexModeBits",
- "Form",
- "isUnaryDataProc",
- "canXformTo16Bit",
- "Dom"];
- let TSFlagsShifts = [0,
- 4,
- 7,
- 9,
- 15,
- 16,
- 17];
-}
+def ARMInstrInfo : InstrInfo;
//===----------------------------------------------------------------------===//
// Declare the target which we are implementing
diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp
index b6c81f6..77fb0c3 100644
--- a/lib/Target/ARM/ARMISelLowering.cpp
+++ b/lib/Target/ARM/ARMISelLowering.cpp
@@ -861,7 +861,8 @@ CreateCopyOfByValArgument(SDValue Src, SDValue Dst, SDValue Chain,
DebugLoc dl) {
SDValue SizeNode = DAG.getConstant(Flags.getByValSize(), MVT::i32);
return DAG.getMemcpy(Chain, dl, Dst, Src, SizeNode, Flags.getByValAlign(),
- /*AlwaysInline=*/false, NULL, 0, NULL, 0);
+ /*isVolatile=*/false, /*AlwaysInline=*/false,
+ NULL, 0, NULL, 0);
}
/// LowerMemOpCallTo - Store the argument to the stack.
@@ -2053,7 +2054,7 @@ ARMTargetLowering::EmitTargetCodeForMemcpy(SelectionDAG &DAG, DebugLoc dl,
SDValue Chain,
SDValue Dst, SDValue Src,
SDValue Size, unsigned Align,
- bool AlwaysInline,
+ bool isVolatile, bool AlwaysInline,
const Value *DstSV, uint64_t DstSVOff,
const Value *SrcSV, uint64_t SrcSVOff){
// Do repeated 4-byte loads and stores. To be improved.
@@ -2089,7 +2090,7 @@ ARMTargetLowering::EmitTargetCodeForMemcpy(SelectionDAG &DAG, DebugLoc dl,
Loads[i] = DAG.getLoad(VT, dl, Chain,
DAG.getNode(ISD::ADD, dl, MVT::i32, Src,
DAG.getConstant(SrcOff, MVT::i32)),
- SrcSV, SrcSVOff + SrcOff, false, false, 0);
+ SrcSV, SrcSVOff + SrcOff, isVolatile, false, 0);
TFOps[i] = Loads[i].getValue(1);
SrcOff += VTSize;
}
@@ -2100,7 +2101,7 @@ ARMTargetLowering::EmitTargetCodeForMemcpy(SelectionDAG &DAG, DebugLoc dl,
TFOps[i] = DAG.getStore(Chain, dl, Loads[i],
DAG.getNode(ISD::ADD, dl, MVT::i32, Dst,
DAG.getConstant(DstOff, MVT::i32)),
- DstSV, DstSVOff + DstOff, false, false, 0);
+ DstSV, DstSVOff + DstOff, isVolatile, false, 0);
DstOff += VTSize;
}
Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &TFOps[0], i);
diff --git a/lib/Target/ARM/ARMISelLowering.h b/lib/Target/ARM/ARMISelLowering.h
index f8f8adc..fa33ad3 100644
--- a/lib/Target/ARM/ARMISelLowering.h
+++ b/lib/Target/ARM/ARMISelLowering.h
@@ -305,7 +305,7 @@ namespace llvm {
SDValue Chain,
SDValue Dst, SDValue Src,
SDValue Size, unsigned Align,
- bool AlwaysInline,
+ bool isVolatile, bool AlwaysInline,
const Value *DstSV, uint64_t DstSVOff,
const Value *SrcSV, uint64_t SrcSVOff);
SDValue LowerCallResult(SDValue Chain, SDValue InFlag,
diff --git a/lib/Target/ARM/ARMInstrFormats.td b/lib/Target/ARM/ARMInstrFormats.td
index 4427e50..b466d0d 100644
--- a/lib/Target/ARM/ARMInstrFormats.td
+++ b/lib/Target/ARM/ARMInstrFormats.td
@@ -185,28 +185,25 @@ class InstTemplate<AddrMode am, SizeFlagVal sz, IndexMode im,
: Instruction {
let Namespace = "ARM";
- // TSFlagsFields
AddrMode AM = am;
- bits<4> AddrModeBits = AM.Value;
-
SizeFlagVal SZ = sz;
- bits<3> SizeFlag = SZ.Value;
-
IndexMode IM = im;
bits<2> IndexModeBits = IM.Value;
-
Format F = f;
bits<6> Form = F.Value;
-
Domain D = d;
- bits<2> Dom = D.Value;
-
- //
- // Attributes specific to ARM instructions...
- //
bit isUnaryDataProc = 0;
bit canXformTo16Bit = 0;
+ // The layout of TSFlags should be kept in sync with ARMBaseInstrInfo.h.
+ let TSFlags{3-0} = AM.Value;
+ let TSFlags{6-4} = SZ.Value;
+ let TSFlags{8-7} = IndexModeBits;
+ let TSFlags{14-9} = Form;
+ let TSFlags{15} = isUnaryDataProc;
+ let TSFlags{16} = canXformTo16Bit;
+ let TSFlags{18-17} = D.Value;
+
let Constraints = cstr;
let Itinerary = itin;
}
@@ -1317,7 +1314,7 @@ class ADI5<bits<4> opcod1, bits<2> opcod2, dag oops, dag iops,
let Inst{11-8} = 0b1011;
// 64-bit loads & stores operate on both NEON and VFP pipelines.
- let Dom = VFPNeonDomain.Value;
+ let D = VFPNeonDomain;
}
class ASI5<bits<4> opcod1, bits<2> opcod2, dag oops, dag iops,
@@ -1341,7 +1338,7 @@ class AXDI5<dag oops, dag iops, IndexMode im, InstrItinClass itin,
let Inst{11-8} = 0b1011;
// 64-bit loads & stores operate on both NEON and VFP pipelines.
- let Dom = VFPNeonDomain.Value;
+ let D = VFPNeonDomain;
}
class AXSI5<dag oops, dag iops, IndexMode im, InstrItinClass itin,
diff --git a/lib/Target/ARM/ARMMCAsmInfo.cpp b/lib/Target/ARM/ARMMCAsmInfo.cpp
index 20197e4..53edfca 100644
--- a/lib/Target/ARM/ARMMCAsmInfo.cpp
+++ b/lib/Target/ARM/ARMMCAsmInfo.cpp
@@ -58,7 +58,6 @@ ARMELFMCAsmInfo::ARMELFMCAsmInfo() {
CommentString = "@";
HasLEB128 = true;
- AbsoluteDebugSectionOffsets = true;
PrivateGlobalPrefix = ".L";
WeakRefDirective = "\t.weak\t";
HasLCOMMDirective = true;
diff --git a/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp b/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
index ba736e3..15c5294 100644
--- a/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
+++ b/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
@@ -26,7 +26,6 @@
#include "llvm/Type.h"
#include "llvm/Assembly/Writer.h"
#include "llvm/CodeGen/AsmPrinter.h"
-#include "llvm/CodeGen/DwarfWriter.h"
#include "llvm/CodeGen/MachineModuleInfoImpls.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h"
@@ -46,11 +45,9 @@
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
-#include "llvm/ADT/StringSet.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/FormattedStream.h"
-#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/raw_ostream.h"
#include <cctype>
using namespace llvm;
@@ -74,9 +71,8 @@ namespace {
const MachineConstantPool *MCP;
public:
- explicit ARMAsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
- MCStreamer &Streamer)
- : AsmPrinter(O, TM, Streamer), AFI(NULL), MCP(NULL) {
+ explicit ARMAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
+ : AsmPrinter(TM, Streamer), AFI(NULL), MCP(NULL) {
Subtarget = &TM.getSubtarget<ARMSubtarget>();
}
@@ -87,80 +83,123 @@ namespace {
void printInstructionThroughMCStreamer(const MachineInstr *MI);
- void printOperand(const MachineInstr *MI, int OpNum,
+ void printOperand(const MachineInstr *MI, int OpNum, raw_ostream &O,
const char *Modifier = 0);
- void printSOImmOperand(const MachineInstr *MI, int OpNum);
- void printSOImm2PartOperand(const MachineInstr *MI, int OpNum);
- void printSORegOperand(const MachineInstr *MI, int OpNum);
- void printAddrMode2Operand(const MachineInstr *MI, int OpNum);
- void printAddrMode2OffsetOperand(const MachineInstr *MI, int OpNum);
- void printAddrMode3Operand(const MachineInstr *MI, int OpNum);
- void printAddrMode3OffsetOperand(const MachineInstr *MI, int OpNum);
- void printAddrMode4Operand(const MachineInstr *MI, int OpNum,
+ void printSOImmOperand(const MachineInstr *MI, int OpNum, raw_ostream &O);
+ void printSOImm2PartOperand(const MachineInstr *MI, int OpNum,
+ raw_ostream &O);
+ void printSORegOperand(const MachineInstr *MI, int OpNum,
+ raw_ostream &O);
+ void printAddrMode2Operand(const MachineInstr *MI, int OpNum,
+ raw_ostream &O);
+ void printAddrMode2OffsetOperand(const MachineInstr *MI, int OpNum,
+ raw_ostream &O);
+ void printAddrMode3Operand(const MachineInstr *MI, int OpNum,
+ raw_ostream &O);
+ void printAddrMode3OffsetOperand(const MachineInstr *MI, int OpNum,
+ raw_ostream &O);
+ void printAddrMode4Operand(const MachineInstr *MI, int OpNum,raw_ostream &O,
const char *Modifier = 0);
- void printAddrMode5Operand(const MachineInstr *MI, int OpNum,
+ void printAddrMode5Operand(const MachineInstr *MI, int OpNum,raw_ostream &O,
const char *Modifier = 0);
- void printAddrMode6Operand(const MachineInstr *MI, int OpNum);
- void printAddrMode6OffsetOperand(const MachineInstr *MI, int OpNum);
+ void printAddrMode6Operand(const MachineInstr *MI, int OpNum,
+ raw_ostream &O);
+ void printAddrMode6OffsetOperand(const MachineInstr *MI, int OpNum,
+ raw_ostream &O);
void printAddrModePCOperand(const MachineInstr *MI, int OpNum,
+ raw_ostream &O,
const char *Modifier = 0);
- void printBitfieldInvMaskImmOperand (const MachineInstr *MI, int OpNum);
-
- void printThumbS4ImmOperand(const MachineInstr *MI, int OpNum);
- void printThumbITMask(const MachineInstr *MI, int OpNum);
- void printThumbAddrModeRROperand(const MachineInstr *MI, int OpNum);
+ void printBitfieldInvMaskImmOperand (const MachineInstr *MI, int OpNum,
+ raw_ostream &O);
+
+ void printThumbS4ImmOperand(const MachineInstr *MI, int OpNum,
+ raw_ostream &O);
+ void printThumbITMask(const MachineInstr *MI, int OpNum, raw_ostream &O);
+ void printThumbAddrModeRROperand(const MachineInstr *MI, int OpNum,
+ raw_ostream &O);
void printThumbAddrModeRI5Operand(const MachineInstr *MI, int OpNum,
+ raw_ostream &O,
unsigned Scale);
- void printThumbAddrModeS1Operand(const MachineInstr *MI, int OpNum);
- void printThumbAddrModeS2Operand(const MachineInstr *MI, int OpNum);
- void printThumbAddrModeS4Operand(const MachineInstr *MI, int OpNum);
- void printThumbAddrModeSPOperand(const MachineInstr *MI, int OpNum);
-
- void printT2SOOperand(const MachineInstr *MI, int OpNum);
- void printT2AddrModeImm12Operand(const MachineInstr *MI, int OpNum);
- void printT2AddrModeImm8Operand(const MachineInstr *MI, int OpNum);
- void printT2AddrModeImm8s4Operand(const MachineInstr *MI, int OpNum);
- void printT2AddrModeImm8OffsetOperand(const MachineInstr *MI, int OpNum);
- void printT2AddrModeImm8s4OffsetOperand(const MachineInstr *MI, int OpNum) {}
- void printT2AddrModeSoRegOperand(const MachineInstr *MI, int OpNum);
-
- void printCPSOptionOperand(const MachineInstr *MI, int OpNum) {}
- void printMSRMaskOperand(const MachineInstr *MI, int OpNum) {}
- void printNegZeroOperand(const MachineInstr *MI, int OpNum) {}
- void printPredicateOperand(const MachineInstr *MI, int OpNum);
- void printMandatoryPredicateOperand(const MachineInstr *MI, int OpNum);
- void printSBitModifierOperand(const MachineInstr *MI, int OpNum);
- void printPCLabel(const MachineInstr *MI, int OpNum);
- void printRegisterList(const MachineInstr *MI, int OpNum);
+ void printThumbAddrModeS1Operand(const MachineInstr *MI, int OpNum,
+ raw_ostream &O);
+ void printThumbAddrModeS2Operand(const MachineInstr *MI, int OpNum,
+ raw_ostream &O);
+ void printThumbAddrModeS4Operand(const MachineInstr *MI, int OpNum,
+ raw_ostream &O);
+ void printThumbAddrModeSPOperand(const MachineInstr *MI, int OpNum,
+ raw_ostream &O);
+
+ void printT2SOOperand(const MachineInstr *MI, int OpNum, raw_ostream &O);
+ void printT2AddrModeImm12Operand(const MachineInstr *MI, int OpNum,
+ raw_ostream &O);
+ void printT2AddrModeImm8Operand(const MachineInstr *MI, int OpNum,
+ raw_ostream &O);
+ void printT2AddrModeImm8s4Operand(const MachineInstr *MI, int OpNum,
+ raw_ostream &O);
+ void printT2AddrModeImm8OffsetOperand(const MachineInstr *MI, int OpNum,
+ raw_ostream &O);
+ void printT2AddrModeImm8s4OffsetOperand(const MachineInstr *MI, int OpNum,
+ raw_ostream &O) {}
+ void printT2AddrModeSoRegOperand(const MachineInstr *MI, int OpNum,
+ raw_ostream &O);
+
+ void printCPSOptionOperand(const MachineInstr *MI, int OpNum,
+ raw_ostream &O) {}
+ void printMSRMaskOperand(const MachineInstr *MI, int OpNum,
+ raw_ostream &O) {}
+ void printNegZeroOperand(const MachineInstr *MI, int OpNum,
+ raw_ostream &O) {}
+ void printPredicateOperand(const MachineInstr *MI, int OpNum,
+ raw_ostream &O);
+ void printMandatoryPredicateOperand(const MachineInstr *MI, int OpNum,
+ raw_ostream &O);
+ void printSBitModifierOperand(const MachineInstr *MI, int OpNum,
+ raw_ostream &O);
+ void printPCLabel(const MachineInstr *MI, int OpNum,
+ raw_ostream &O);
+ void printRegisterList(const MachineInstr *MI, int OpNum,
+ raw_ostream &O);
void printCPInstOperand(const MachineInstr *MI, int OpNum,
+ raw_ostream &O,
const char *Modifier);
- void printJTBlockOperand(const MachineInstr *MI, int OpNum);
- void printJT2BlockOperand(const MachineInstr *MI, int OpNum);
- void printTBAddrMode(const MachineInstr *MI, int OpNum);
- void printNoHashImmediate(const MachineInstr *MI, int OpNum);
- void printVFPf32ImmOperand(const MachineInstr *MI, int OpNum);
- void printVFPf64ImmOperand(const MachineInstr *MI, int OpNum);
-
- void printHex8ImmOperand(const MachineInstr *MI, int OpNum) {
+ void printJTBlockOperand(const MachineInstr *MI, int OpNum,
+ raw_ostream &O);
+ void printJT2BlockOperand(const MachineInstr *MI, int OpNum,
+ raw_ostream &O);
+ void printTBAddrMode(const MachineInstr *MI, int OpNum,
+ raw_ostream &O);
+ void printNoHashImmediate(const MachineInstr *MI, int OpNum,
+ raw_ostream &O);
+ void printVFPf32ImmOperand(const MachineInstr *MI, int OpNum,
+ raw_ostream &O);
+ void printVFPf64ImmOperand(const MachineInstr *MI, int OpNum,
+ raw_ostream &O);
+
+ void printHex8ImmOperand(const MachineInstr *MI, int OpNum,
+ raw_ostream &O) {
O << "#0x" << utohexstr(MI->getOperand(OpNum).getImm() & 0xff);
}
- void printHex16ImmOperand(const MachineInstr *MI, int OpNum) {
+ void printHex16ImmOperand(const MachineInstr *MI, int OpNum,
+ raw_ostream &O) {
O << "#0x" << utohexstr(MI->getOperand(OpNum).getImm() & 0xffff);
}
- void printHex32ImmOperand(const MachineInstr *MI, int OpNum) {
+ void printHex32ImmOperand(const MachineInstr *MI, int OpNum,
+ raw_ostream &O) {
O << "#0x" << utohexstr(MI->getOperand(OpNum).getImm() & 0xffffffff);
}
- void printHex64ImmOperand(const MachineInstr *MI, int OpNum) {
+ void printHex64ImmOperand(const MachineInstr *MI, int OpNum,
+ raw_ostream &O) {
O << "#0x" << utohexstr(MI->getOperand(OpNum).getImm());
}
virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
- unsigned AsmVariant, const char *ExtraCode);
+ unsigned AsmVariant, const char *ExtraCode,
+ raw_ostream &O);
virtual bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum,
unsigned AsmVariant,
- const char *ExtraCode);
+ const char *ExtraCode, raw_ostream &O);
- void printInstruction(const MachineInstr *MI); // autogenerated.
+ void printInstruction(const MachineInstr *MI, raw_ostream &O); // autogen
static const char *getRegisterName(unsigned RegNo);
virtual void EmitInstruction(const MachineInstr *MI);
@@ -178,6 +217,14 @@ namespace {
/// EmitMachineConstantPoolValue - Print a machine constantpool value to
/// the .s file.
virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) {
+ SmallString<128> Str;
+ raw_svector_ostream OS(Str);
+ EmitMachineConstantPoolValue(MCPV, OS);
+ OutStreamer.EmitRawText(OS.str());
+ }
+
+ void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV,
+ raw_ostream &O) {
switch (TM.getTargetData()->getTypeAllocSize(MCPV->getType())) {
case 1: O << MAI->getData8bitsDirective(0); break;
case 2: O << MAI->getData16bitsDirective(0); break;
@@ -186,14 +233,11 @@ namespace {
}
ARMConstantPoolValue *ACPV = static_cast<ARMConstantPoolValue*>(MCPV);
- SmallString<128> TmpNameStr;
if (ACPV->isLSDA()) {
- raw_svector_ostream(TmpNameStr) << MAI->getPrivateGlobalPrefix() <<
- "_LSDA_" << getFunctionNumber();
- O << TmpNameStr.str();
+ O << MAI->getPrivateGlobalPrefix() << "_LSDA_" << getFunctionNumber();
} else if (ACPV->isBlockAddress()) {
- O << GetBlockAddressSymbol(ACPV->getBlockAddress())->getName();
+ O << *GetBlockAddressSymbol(ACPV->getBlockAddress());
} else if (ACPV->isGlobalValue()) {
GlobalValue *GV = ACPV->getGV();
bool isIndirect = Subtarget->isTargetDarwin() &&
@@ -228,14 +272,6 @@ namespace {
O << "-.";
O << ')';
}
- OutStreamer.AddBlankLine();
- }
-
- void getAnalysisUsage(AnalysisUsage &AU) const {
- AsmPrinter::getAnalysisUsage(AU);
- AU.setPreservesAll();
- AU.addRequired<MachineModuleInfo>();
- AU.addRequired<DwarfWriter>();
}
};
} // end of anonymous namespace
@@ -244,11 +280,17 @@ namespace {
void ARMAsmPrinter::EmitFunctionEntryLabel() {
if (AFI->isThumbFunction()) {
- O << "\t.code\t16\n";
- O << "\t.thumb_func";
- if (Subtarget->isTargetDarwin())
- O << '\t' << *CurrentFnSym;
- O << '\n';
+ OutStreamer.EmitRawText(StringRef("\t.code\t16"));
+ if (!Subtarget->isTargetDarwin())
+ OutStreamer.EmitRawText(StringRef("\t.thumb_func"));
+ else {
+ // This needs to emit to a temporary string to get properly quoted
+ // MCSymbols when they have spaces in them.
+ SmallString<128> Tmp;
+ raw_svector_ostream OS(Tmp);
+ OS << "\t.thumb_func\t" << *CurrentFnSym;
+ OutStreamer.EmitRawText(OS.str());
+ }
}
OutStreamer.EmitLabel(CurrentFnSym);
@@ -265,7 +307,7 @@ bool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
}
void ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
- const char *Modifier) {
+ raw_ostream &O, const char *Modifier) {
const MachineOperand &MO = MI->getOperand(OpNum);
unsigned TF = MO.getTargetFlags();
@@ -276,15 +318,16 @@ void ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
unsigned Reg = MO.getReg();
assert(TargetRegisterInfo::isPhysicalRegister(Reg));
if (Modifier && strcmp(Modifier, "dregpair") == 0) {
- unsigned DRegLo = TRI->getSubReg(Reg, 5); // arm_dsubreg_0
- unsigned DRegHi = TRI->getSubReg(Reg, 6); // arm_dsubreg_1
+ unsigned DRegLo = TM.getRegisterInfo()->getSubReg(Reg, 5);// arm_dsubreg_0
+ unsigned DRegHi = TM.getRegisterInfo()->getSubReg(Reg, 6);// arm_dsubreg_1
O << '{'
<< getRegisterName(DRegLo) << ',' << getRegisterName(DRegHi)
<< '}';
} else if (Modifier && strcmp(Modifier, "lane") == 0) {
unsigned RegNum = ARMRegisterInfo::getRegisterNumbering(Reg);
- unsigned DReg = TRI->getMatchingSuperReg(Reg, RegNum & 1 ? 2 : 1,
- &ARM::DPR_VFP2RegClass);
+ unsigned DReg =
+ TM.getRegisterInfo()->getMatchingSuperReg(Reg, RegNum & 1 ? 2 : 1,
+ &ARM::DPR_VFP2RegClass);
O << getRegisterName(DReg) << '[' << (RegNum & 1) << ']';
} else {
assert(!MO.getSubReg() && "Subregs should be eliminated!");
@@ -319,7 +362,7 @@ void ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
O << ":upper16:";
O << *Mang->getSymbol(GV);
- printOffset(MO.getOffset());
+ printOffset(MO.getOffset(), O);
if (isCallOp && Subtarget->isTargetELF() &&
TM.getRelocationModel() == Reloc::PIC_)
@@ -344,7 +387,7 @@ void ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
}
}
-static void printSOImm(formatted_raw_ostream &O, int64_t V, bool VerboseAsm,
+static void printSOImm(raw_ostream &O, int64_t V, bool VerboseAsm,
const MCAsmInfo *MAI) {
// Break it up into two parts that make up a shifter immediate.
V = ARM_AM::getSOImmVal(V);
@@ -359,8 +402,7 @@ static void printSOImm(formatted_raw_ostream &O, int64_t V, bool VerboseAsm,
O << "#" << Imm << ", " << Rot;
// Pretty printed version.
if (VerboseAsm) {
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString() << ' ';
+ O << "\t" << MAI->getCommentString() << ' ';
O << (int)ARM_AM::rotr32(Imm, Rot);
}
} else {
@@ -370,28 +412,30 @@ static void printSOImm(formatted_raw_ostream &O, int64_t V, bool VerboseAsm,
/// printSOImmOperand - SOImm is 4-bit rotate amount in bits 8-11 with 8-bit
/// immediate in bits 0-7.
-void ARMAsmPrinter::printSOImmOperand(const MachineInstr *MI, int OpNum) {
+void ARMAsmPrinter::printSOImmOperand(const MachineInstr *MI, int OpNum,
+ raw_ostream &O) {
const MachineOperand &MO = MI->getOperand(OpNum);
assert(MO.isImm() && "Not a valid so_imm value!");
- printSOImm(O, MO.getImm(), VerboseAsm, MAI);
+ printSOImm(O, MO.getImm(), isVerbose(), MAI);
}
/// printSOImm2PartOperand - SOImm is broken into two pieces using a 'mov'
/// followed by an 'orr' to materialize.
-void ARMAsmPrinter::printSOImm2PartOperand(const MachineInstr *MI, int OpNum) {
+void ARMAsmPrinter::printSOImm2PartOperand(const MachineInstr *MI, int OpNum,
+ raw_ostream &O) {
const MachineOperand &MO = MI->getOperand(OpNum);
assert(MO.isImm() && "Not a valid so_imm value!");
unsigned V1 = ARM_AM::getSOImmTwoPartFirst(MO.getImm());
unsigned V2 = ARM_AM::getSOImmTwoPartSecond(MO.getImm());
- printSOImm(O, V1, VerboseAsm, MAI);
+ printSOImm(O, V1, isVerbose(), MAI);
O << "\n\torr";
- printPredicateOperand(MI, 2);
+ printPredicateOperand(MI, 2, O);
O << "\t";
- printOperand(MI, 0);
+ printOperand(MI, 0, O);
O << ", ";
- printOperand(MI, 0);
+ printOperand(MI, 0, O);
O << ", ";
- printSOImm(O, V2, VerboseAsm, MAI);
+ printSOImm(O, V2, isVerbose(), MAI);
}
// so_reg is a 4-operand unit corresponding to register forms of the A5.1
@@ -399,7 +443,8 @@ void ARMAsmPrinter::printSOImm2PartOperand(const MachineInstr *MI, int OpNum) {
// REG 0 0 - e.g. R5
// REG REG 0,SH_OPC - e.g. R5, ROR R3
// REG 0 IMM,SH_OPC - e.g. R5, LSL #3
-void ARMAsmPrinter::printSORegOperand(const MachineInstr *MI, int Op) {
+void ARMAsmPrinter::printSORegOperand(const MachineInstr *MI, int Op,
+ raw_ostream &O) {
const MachineOperand &MO1 = MI->getOperand(Op);
const MachineOperand &MO2 = MI->getOperand(Op+1);
const MachineOperand &MO3 = MI->getOperand(Op+2);
@@ -419,13 +464,14 @@ void ARMAsmPrinter::printSORegOperand(const MachineInstr *MI, int Op) {
}
}
-void ARMAsmPrinter::printAddrMode2Operand(const MachineInstr *MI, int Op) {
+void ARMAsmPrinter::printAddrMode2Operand(const MachineInstr *MI, int Op,
+ raw_ostream &O) {
const MachineOperand &MO1 = MI->getOperand(Op);
const MachineOperand &MO2 = MI->getOperand(Op+1);
const MachineOperand &MO3 = MI->getOperand(Op+2);
if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
- printOperand(MI, Op);
+ printOperand(MI, Op, O);
return;
}
@@ -451,7 +497,8 @@ void ARMAsmPrinter::printAddrMode2Operand(const MachineInstr *MI, int Op) {
O << "]";
}
-void ARMAsmPrinter::printAddrMode2OffsetOperand(const MachineInstr *MI, int Op){
+void ARMAsmPrinter::printAddrMode2OffsetOperand(const MachineInstr *MI, int Op,
+ raw_ostream &O) {
const MachineOperand &MO1 = MI->getOperand(Op);
const MachineOperand &MO2 = MI->getOperand(Op+1);
@@ -473,7 +520,8 @@ void ARMAsmPrinter::printAddrMode2OffsetOperand(const MachineInstr *MI, int Op){
<< " #" << ShImm;
}
-void ARMAsmPrinter::printAddrMode3Operand(const MachineInstr *MI, int Op) {
+void ARMAsmPrinter::printAddrMode3Operand(const MachineInstr *MI, int Op,
+ raw_ostream &O) {
const MachineOperand &MO1 = MI->getOperand(Op);
const MachineOperand &MO2 = MI->getOperand(Op+1);
const MachineOperand &MO3 = MI->getOperand(Op+2);
@@ -496,7 +544,8 @@ void ARMAsmPrinter::printAddrMode3Operand(const MachineInstr *MI, int Op) {
O << "]";
}
-void ARMAsmPrinter::printAddrMode3OffsetOperand(const MachineInstr *MI, int Op){
+void ARMAsmPrinter::printAddrMode3OffsetOperand(const MachineInstr *MI, int Op,
+ raw_ostream &O){
const MachineOperand &MO1 = MI->getOperand(Op);
const MachineOperand &MO2 = MI->getOperand(Op+1);
@@ -514,6 +563,7 @@ void ARMAsmPrinter::printAddrMode3OffsetOperand(const MachineInstr *MI, int Op){
}
void ARMAsmPrinter::printAddrMode4Operand(const MachineInstr *MI, int Op,
+ raw_ostream &O,
const char *Modifier) {
const MachineOperand &MO2 = MI->getOperand(Op+1);
ARM_AM::AMSubMode Mode = ARM_AM::getAM4SubMode(MO2.getImm());
@@ -524,17 +574,18 @@ void ARMAsmPrinter::printAddrMode4Operand(const MachineInstr *MI, int Op,
if (Mode == ARM_AM::ia)
O << ".w";
} else {
- printOperand(MI, Op);
+ printOperand(MI, Op, O);
}
}
void ARMAsmPrinter::printAddrMode5Operand(const MachineInstr *MI, int Op,
+ raw_ostream &O,
const char *Modifier) {
const MachineOperand &MO1 = MI->getOperand(Op);
const MachineOperand &MO2 = MI->getOperand(Op+1);
if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
- printOperand(MI, Op);
+ printOperand(MI, Op, O);
return;
}
@@ -560,7 +611,8 @@ void ARMAsmPrinter::printAddrMode5Operand(const MachineInstr *MI, int Op,
O << "]";
}
-void ARMAsmPrinter::printAddrMode6Operand(const MachineInstr *MI, int Op) {
+void ARMAsmPrinter::printAddrMode6Operand(const MachineInstr *MI, int Op,
+ raw_ostream &O) {
const MachineOperand &MO1 = MI->getOperand(Op);
const MachineOperand &MO2 = MI->getOperand(Op+1);
@@ -572,7 +624,8 @@ void ARMAsmPrinter::printAddrMode6Operand(const MachineInstr *MI, int Op) {
O << "]";
}
-void ARMAsmPrinter::printAddrMode6OffsetOperand(const MachineInstr *MI, int Op){
+void ARMAsmPrinter::printAddrMode6OffsetOperand(const MachineInstr *MI, int Op,
+ raw_ostream &O){
const MachineOperand &MO = MI->getOperand(Op);
if (MO.getReg() == 0)
O << "!";
@@ -581,9 +634,10 @@ void ARMAsmPrinter::printAddrMode6OffsetOperand(const MachineInstr *MI, int Op){
}
void ARMAsmPrinter::printAddrModePCOperand(const MachineInstr *MI, int Op,
+ raw_ostream &O,
const char *Modifier) {
if (Modifier && strcmp(Modifier, "label") == 0) {
- printPCLabel(MI, Op+1);
+ printPCLabel(MI, Op+1, O);
return;
}
@@ -593,7 +647,8 @@ void ARMAsmPrinter::printAddrModePCOperand(const MachineInstr *MI, int Op,
}
void
-ARMAsmPrinter::printBitfieldInvMaskImmOperand(const MachineInstr *MI, int Op) {
+ARMAsmPrinter::printBitfieldInvMaskImmOperand(const MachineInstr *MI, int Op,
+ raw_ostream &O) {
const MachineOperand &MO = MI->getOperand(Op);
uint32_t v = ~MO.getImm();
int32_t lsb = CountTrailingZeros_32(v);
@@ -604,12 +659,14 @@ ARMAsmPrinter::printBitfieldInvMaskImmOperand(const MachineInstr *MI, int Op) {
//===--------------------------------------------------------------------===//
-void ARMAsmPrinter::printThumbS4ImmOperand(const MachineInstr *MI, int Op) {
+void ARMAsmPrinter::printThumbS4ImmOperand(const MachineInstr *MI, int Op,
+ raw_ostream &O) {
O << "#" << MI->getOperand(Op).getImm() * 4;
}
void
-ARMAsmPrinter::printThumbITMask(const MachineInstr *MI, int Op) {
+ARMAsmPrinter::printThumbITMask(const MachineInstr *MI, int Op,
+ raw_ostream &O) {
// (3 - the number of trailing zeros) is the number of then / else.
unsigned Mask = MI->getOperand(Op).getImm();
unsigned CondBit0 = Mask >> 4 & 1;
@@ -625,7 +682,8 @@ ARMAsmPrinter::printThumbITMask(const MachineInstr *MI, int Op) {
}
void
-ARMAsmPrinter::printThumbAddrModeRROperand(const MachineInstr *MI, int Op) {
+ARMAsmPrinter::printThumbAddrModeRROperand(const MachineInstr *MI, int Op,
+ raw_ostream &O) {
const MachineOperand &MO1 = MI->getOperand(Op);
const MachineOperand &MO2 = MI->getOperand(Op+1);
O << "[" << getRegisterName(MO1.getReg());
@@ -634,13 +692,14 @@ ARMAsmPrinter::printThumbAddrModeRROperand(const MachineInstr *MI, int Op) {
void
ARMAsmPrinter::printThumbAddrModeRI5Operand(const MachineInstr *MI, int Op,
+ raw_ostream &O,
unsigned Scale) {
const MachineOperand &MO1 = MI->getOperand(Op);
const MachineOperand &MO2 = MI->getOperand(Op+1);
const MachineOperand &MO3 = MI->getOperand(Op+2);
if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
- printOperand(MI, Op);
+ printOperand(MI, Op, O);
return;
}
@@ -653,19 +712,23 @@ ARMAsmPrinter::printThumbAddrModeRI5Operand(const MachineInstr *MI, int Op,
}
void
-ARMAsmPrinter::printThumbAddrModeS1Operand(const MachineInstr *MI, int Op) {
- printThumbAddrModeRI5Operand(MI, Op, 1);
+ARMAsmPrinter::printThumbAddrModeS1Operand(const MachineInstr *MI, int Op,
+ raw_ostream &O) {
+ printThumbAddrModeRI5Operand(MI, Op, O, 1);
}
void
-ARMAsmPrinter::printThumbAddrModeS2Operand(const MachineInstr *MI, int Op) {
- printThumbAddrModeRI5Operand(MI, Op, 2);
+ARMAsmPrinter::printThumbAddrModeS2Operand(const MachineInstr *MI, int Op,
+ raw_ostream &O) {
+ printThumbAddrModeRI5Operand(MI, Op, O, 2);
}
void
-ARMAsmPrinter::printThumbAddrModeS4Operand(const MachineInstr *MI, int Op) {
- printThumbAddrModeRI5Operand(MI, Op, 4);
+ARMAsmPrinter::printThumbAddrModeS4Operand(const MachineInstr *MI, int Op,
+ raw_ostream &O) {
+ printThumbAddrModeRI5Operand(MI, Op, O, 4);
}
-void ARMAsmPrinter::printThumbAddrModeSPOperand(const MachineInstr *MI,int Op) {
+void ARMAsmPrinter::printThumbAddrModeSPOperand(const MachineInstr *MI,int Op,
+ raw_ostream &O) {
const MachineOperand &MO1 = MI->getOperand(Op);
const MachineOperand &MO2 = MI->getOperand(Op+1);
O << "[" << getRegisterName(MO1.getReg());
@@ -680,7 +743,8 @@ void ARMAsmPrinter::printThumbAddrModeSPOperand(const MachineInstr *MI,int Op) {
// register with shift forms.
// REG 0 0 - e.g. R5
// REG IMM, SH_OPC - e.g. R5, LSL #3
-void ARMAsmPrinter::printT2SOOperand(const MachineInstr *MI, int OpNum) {
+void ARMAsmPrinter::printT2SOOperand(const MachineInstr *MI, int OpNum,
+ raw_ostream &O) {
const MachineOperand &MO1 = MI->getOperand(OpNum);
const MachineOperand &MO2 = MI->getOperand(OpNum+1);
@@ -698,7 +762,8 @@ void ARMAsmPrinter::printT2SOOperand(const MachineInstr *MI, int OpNum) {
}
void ARMAsmPrinter::printT2AddrModeImm12Operand(const MachineInstr *MI,
- int OpNum) {
+ int OpNum,
+ raw_ostream &O) {
const MachineOperand &MO1 = MI->getOperand(OpNum);
const MachineOperand &MO2 = MI->getOperand(OpNum+1);
@@ -711,7 +776,8 @@ void ARMAsmPrinter::printT2AddrModeImm12Operand(const MachineInstr *MI,
}
void ARMAsmPrinter::printT2AddrModeImm8Operand(const MachineInstr *MI,
- int OpNum) {
+ int OpNum,
+ raw_ostream &O) {
const MachineOperand &MO1 = MI->getOperand(OpNum);
const MachineOperand &MO2 = MI->getOperand(OpNum+1);
@@ -727,7 +793,8 @@ void ARMAsmPrinter::printT2AddrModeImm8Operand(const MachineInstr *MI,
}
void ARMAsmPrinter::printT2AddrModeImm8s4Operand(const MachineInstr *MI,
- int OpNum) {
+ int OpNum,
+ raw_ostream &O) {
const MachineOperand &MO1 = MI->getOperand(OpNum);
const MachineOperand &MO2 = MI->getOperand(OpNum+1);
@@ -743,7 +810,8 @@ void ARMAsmPrinter::printT2AddrModeImm8s4Operand(const MachineInstr *MI,
}
void ARMAsmPrinter::printT2AddrModeImm8OffsetOperand(const MachineInstr *MI,
- int OpNum) {
+ int OpNum,
+ raw_ostream &O) {
const MachineOperand &MO1 = MI->getOperand(OpNum);
int32_t OffImm = (int32_t)MO1.getImm();
// Don't print +0.
@@ -754,7 +822,8 @@ void ARMAsmPrinter::printT2AddrModeImm8OffsetOperand(const MachineInstr *MI,
}
void ARMAsmPrinter::printT2AddrModeSoRegOperand(const MachineInstr *MI,
- int OpNum) {
+ int OpNum,
+ raw_ostream &O) {
const MachineOperand &MO1 = MI->getOperand(OpNum);
const MachineOperand &MO2 = MI->getOperand(OpNum+1);
const MachineOperand &MO3 = MI->getOperand(OpNum+2);
@@ -775,19 +844,22 @@ void ARMAsmPrinter::printT2AddrModeSoRegOperand(const MachineInstr *MI,
//===--------------------------------------------------------------------===//
-void ARMAsmPrinter::printPredicateOperand(const MachineInstr *MI, int OpNum) {
+void ARMAsmPrinter::printPredicateOperand(const MachineInstr *MI, int OpNum,
+ raw_ostream &O) {
ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(OpNum).getImm();
if (CC != ARMCC::AL)
O << ARMCondCodeToString(CC);
}
void ARMAsmPrinter::printMandatoryPredicateOperand(const MachineInstr *MI,
- int OpNum) {
+ int OpNum,
+ raw_ostream &O) {
ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(OpNum).getImm();
O << ARMCondCodeToString(CC);
}
-void ARMAsmPrinter::printSBitModifierOperand(const MachineInstr *MI, int OpNum){
+void ARMAsmPrinter::printSBitModifierOperand(const MachineInstr *MI, int OpNum,
+ raw_ostream &O){
unsigned Reg = MI->getOperand(OpNum).getReg();
if (Reg) {
assert(Reg == ARM::CPSR && "Expect ARM CPSR register!");
@@ -795,25 +867,27 @@ void ARMAsmPrinter::printSBitModifierOperand(const MachineInstr *MI, int OpNum){
}
}
-void ARMAsmPrinter::printPCLabel(const MachineInstr *MI, int OpNum) {
+void ARMAsmPrinter::printPCLabel(const MachineInstr *MI, int OpNum,
+ raw_ostream &O) {
int Id = (int)MI->getOperand(OpNum).getImm();
O << MAI->getPrivateGlobalPrefix()
<< "PC" << getFunctionNumber() << "_" << Id;
}
-void ARMAsmPrinter::printRegisterList(const MachineInstr *MI, int OpNum) {
+void ARMAsmPrinter::printRegisterList(const MachineInstr *MI, int OpNum,
+ raw_ostream &O) {
O << "{";
for (unsigned i = OpNum, e = MI->getNumOperands(); i != e; ++i) {
if (MI->getOperand(i).isImplicit())
continue;
if ((int)i != OpNum) O << ", ";
- printOperand(MI, i);
+ printOperand(MI, i, O);
}
O << "}";
}
void ARMAsmPrinter::printCPInstOperand(const MachineInstr *MI, int OpNum,
- const char *Modifier) {
+ raw_ostream &O, const char *Modifier) {
assert(Modifier && "This operand only works with a modifier!");
// There are two aspects to a CONSTANTPOOL_ENTRY operand, the label and the
// data itself.
@@ -852,7 +926,8 @@ GetARMJTIPICJumpTableLabel2(unsigned uid, unsigned uid2) const {
return OutContext.GetOrCreateSymbol(Name.str());
}
-void ARMAsmPrinter::printJTBlockOperand(const MachineInstr *MI, int OpNum) {
+void ARMAsmPrinter::printJTBlockOperand(const MachineInstr *MI, int OpNum,
+ raw_ostream &O) {
assert(!Subtarget->isThumb2() && "Thumb2 should use double-jump jumptables!");
const MachineOperand &MO1 = MI->getOperand(OpNum);
@@ -860,7 +935,9 @@ void ARMAsmPrinter::printJTBlockOperand(const MachineInstr *MI, int OpNum) {
unsigned JTI = MO1.getIndex();
MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm());
- OutStreamer.EmitLabel(JTISymbol);
+ // Can't use EmitLabel until instprinter happens, label comes out in the wrong
+ // order.
+ O << *JTISymbol << ":\n";
const char *JTEntryDirective = MAI->getData32bitsDirective();
@@ -892,13 +969,17 @@ void ARMAsmPrinter::printJTBlockOperand(const MachineInstr *MI, int OpNum) {
}
}
-void ARMAsmPrinter::printJT2BlockOperand(const MachineInstr *MI, int OpNum) {
+void ARMAsmPrinter::printJT2BlockOperand(const MachineInstr *MI, int OpNum,
+ raw_ostream &O) {
const MachineOperand &MO1 = MI->getOperand(OpNum);
const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id
unsigned JTI = MO1.getIndex();
MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm());
- OutStreamer.EmitLabel(JTISymbol);
+
+ // Can't use EmitLabel until instprinter happens, label comes out in the wrong
+ // order.
+ O << *JTISymbol << ":\n";
const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
@@ -924,48 +1005,44 @@ void ARMAsmPrinter::printJT2BlockOperand(const MachineInstr *MI, int OpNum) {
if (i != e-1)
O << '\n';
}
-
- // Make sure the instruction that follows TBB is 2-byte aligned.
- // FIXME: Constant island pass should insert an "ALIGN" instruction instead.
- if (ByteOffset && (JTBBs.size() & 1)) {
- O << '\n';
- EmitAlignment(1);
- }
}
-void ARMAsmPrinter::printTBAddrMode(const MachineInstr *MI, int OpNum) {
+void ARMAsmPrinter::printTBAddrMode(const MachineInstr *MI, int OpNum,
+ raw_ostream &O) {
O << "[pc, " << getRegisterName(MI->getOperand(OpNum).getReg());
if (MI->getOpcode() == ARM::t2TBH)
O << ", lsl #1";
O << ']';
}
-void ARMAsmPrinter::printNoHashImmediate(const MachineInstr *MI, int OpNum) {
+void ARMAsmPrinter::printNoHashImmediate(const MachineInstr *MI, int OpNum,
+ raw_ostream &O) {
O << MI->getOperand(OpNum).getImm();
}
-void ARMAsmPrinter::printVFPf32ImmOperand(const MachineInstr *MI, int OpNum) {
+void ARMAsmPrinter::printVFPf32ImmOperand(const MachineInstr *MI, int OpNum,
+ raw_ostream &O) {
const ConstantFP *FP = MI->getOperand(OpNum).getFPImm();
O << '#' << FP->getValueAPF().convertToFloat();
- if (VerboseAsm) {
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString() << ' ';
+ if (isVerbose()) {
+ O << "\t\t" << MAI->getCommentString() << ' ';
WriteAsOperand(O, FP, /*PrintType=*/false);
}
}
-void ARMAsmPrinter::printVFPf64ImmOperand(const MachineInstr *MI, int OpNum) {
+void ARMAsmPrinter::printVFPf64ImmOperand(const MachineInstr *MI, int OpNum,
+ raw_ostream &O) {
const ConstantFP *FP = MI->getOperand(OpNum).getFPImm();
O << '#' << FP->getValueAPF().convertToDouble();
- if (VerboseAsm) {
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString() << ' ';
+ if (isVerbose()) {
+ O << "\t\t" << MAI->getCommentString() << ' ';
WriteAsOperand(O, FP, /*PrintType=*/false);
}
}
bool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
- unsigned AsmVariant, const char *ExtraCode){
+ unsigned AsmVariant, const char *ExtraCode,
+ raw_ostream &O) {
// Does this asm operand have a single letter operand modifier?
if (ExtraCode && ExtraCode[0]) {
if (ExtraCode[1] != 0) return true; // Unknown modifier.
@@ -981,11 +1058,11 @@ bool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
case 'c': // Don't print "#" before an immediate operand.
if (!MI->getOperand(OpNum).isImm())
return true;
- printNoHashImmediate(MI, OpNum);
+ printNoHashImmediate(MI, OpNum, O);
return false;
case 'P': // Print a VFP double precision register.
case 'q': // Print a NEON quad precision register.
- printOperand(MI, OpNum);
+ printOperand(MI, OpNum, O);
return false;
case 'Q':
if (TM.getTargetData()->isLittleEndian())
@@ -1005,13 +1082,14 @@ bool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
}
}
- printOperand(MI, OpNum);
+ printOperand(MI, OpNum, O);
return false;
}
bool ARMAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
unsigned OpNum, unsigned AsmVariant,
- const char *ExtraCode) {
+ const char *ExtraCode,
+ raw_ostream &O) {
if (ExtraCode && ExtraCode[0])
return true; // Unknown modifier.
@@ -1024,14 +1102,21 @@ bool ARMAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
if (EnableMCInst) {
printInstructionThroughMCStreamer(MI);
- } else {
- int Opc = MI->getOpcode();
- if (Opc == ARM::CONSTPOOL_ENTRY)
- EmitAlignment(2);
-
- printInstruction(MI);
- OutStreamer.AddBlankLine();
+ return;
}
+
+ if (MI->getOpcode() == ARM::CONSTPOOL_ENTRY)
+ EmitAlignment(2);
+
+ SmallString<128> Str;
+ raw_svector_ostream OS(Str);
+ printInstruction(MI, OS);
+ OutStreamer.EmitRawText(OS.str());
+
+ // Make sure the instruction that follows TBB is 2-byte aligned.
+ // FIXME: Constant island pass should insert an "ALIGN" instruction instead.
+ if (MI->getOpcode() == ARM::t2TBB)
+ EmitAlignment(1);
}
void ARMAsmPrinter::EmitStartOfAsmFile(Module &M) {
@@ -1066,38 +1151,48 @@ void ARMAsmPrinter::EmitStartOfAsmFile(Module &M) {
}
// Use unified assembler syntax.
- O << "\t.syntax unified\n";
+ OutStreamer.EmitRawText(StringRef("\t.syntax unified"));
// Emit ARM Build Attributes
if (Subtarget->isTargetELF()) {
// CPU Type
std::string CPUString = Subtarget->getCPUString();
if (CPUString != "generic")
- O << "\t.cpu " << CPUString << '\n';
+ OutStreamer.EmitRawText("\t.cpu " + Twine(CPUString));
// FIXME: Emit FPU type
if (Subtarget->hasVFP2())
- O << "\t.eabi_attribute " << ARMBuildAttrs::VFP_arch << ", 2\n";
+ OutStreamer.EmitRawText("\t.eabi_attribute " +
+ Twine(ARMBuildAttrs::VFP_arch) + ", 2");
// Signal various FP modes.
- if (!UnsafeFPMath)
- O << "\t.eabi_attribute " << ARMBuildAttrs::ABI_FP_denormal << ", 1\n"
- << "\t.eabi_attribute " << ARMBuildAttrs::ABI_FP_exceptions << ", 1\n";
-
+ if (!UnsafeFPMath) {
+ OutStreamer.EmitRawText("\t.eabi_attribute " +
+ Twine(ARMBuildAttrs::ABI_FP_denormal) + ", 1");
+ OutStreamer.EmitRawText("\t.eabi_attribute " +
+ Twine(ARMBuildAttrs::ABI_FP_exceptions) + ", 1");
+ }
+
if (FiniteOnlyFPMath())
- O << "\t.eabi_attribute " << ARMBuildAttrs::ABI_FP_number_model << ", 1\n";
+ OutStreamer.EmitRawText("\t.eabi_attribute " +
+ Twine(ARMBuildAttrs::ABI_FP_number_model)+ ", 1");
else
- O << "\t.eabi_attribute " << ARMBuildAttrs::ABI_FP_number_model << ", 3\n";
+ OutStreamer.EmitRawText("\t.eabi_attribute " +
+ Twine(ARMBuildAttrs::ABI_FP_number_model)+ ", 3");
// 8-bytes alignment stuff.
- O << "\t.eabi_attribute " << ARMBuildAttrs::ABI_align8_needed << ", 1\n"
- << "\t.eabi_attribute " << ARMBuildAttrs::ABI_align8_preserved << ", 1\n";
+ OutStreamer.EmitRawText("\t.eabi_attribute " +
+ Twine(ARMBuildAttrs::ABI_align8_needed) + ", 1");
+ OutStreamer.EmitRawText("\t.eabi_attribute " +
+ Twine(ARMBuildAttrs::ABI_align8_preserved) + ", 1");
// Hard float. Use both S and D registers and conform to AAPCS-VFP.
- if (Subtarget->isAAPCS_ABI() && FloatABIType == FloatABI::Hard)
- O << "\t.eabi_attribute " << ARMBuildAttrs::ABI_HardFP_use << ", 3\n"
- << "\t.eabi_attribute " << ARMBuildAttrs::ABI_VFP_args << ", 1\n";
-
+ if (Subtarget->isAAPCS_ABI() && FloatABIType == FloatABI::Hard) {
+ OutStreamer.EmitRawText("\t.eabi_attribute " +
+ Twine(ARMBuildAttrs::ABI_HardFP_use) + ", 3");
+ OutStreamer.EmitRawText("\t.eabi_attribute " +
+ Twine(ARMBuildAttrs::ABI_VFP_args) + ", 1");
+ }
// FIXME: Should we signal R9 usage?
}
}
@@ -1111,8 +1206,6 @@ void ARMAsmPrinter::EmitEndOfAsmFile(Module &M) {
MachineModuleInfoMachO &MMIMacho =
MMI->getObjFileInfo<MachineModuleInfoMachO>();
- O << '\n';
-
// Output non-lazy-pointers for external and common global variables.
MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetGVStubList();
@@ -1308,10 +1401,9 @@ void ARMAsmPrinter::printInstructionThroughMCStreamer(const MachineInstr *MI) {
static MCInstPrinter *createARMMCInstPrinter(const Target &T,
unsigned SyntaxVariant,
- const MCAsmInfo &MAI,
- raw_ostream &O) {
+ const MCAsmInfo &MAI) {
if (SyntaxVariant == 0)
- return new ARMInstPrinter(O, MAI, false);
+ return new ARMInstPrinter(MAI, false);
return 0;
}
diff --git a/lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp b/lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp
index 30763a9..ef5ead6 100644
--- a/lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp
+++ b/lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp
@@ -98,7 +98,7 @@ static unsigned NextReg(unsigned Reg) {
}
}
-void ARMInstPrinter::printInst(const MCInst *MI) {
+void ARMInstPrinter::printInst(const MCInst *MI, raw_ostream &O) {
// Check for MOVs and print canonical forms, instead.
if (MI->getOpcode() == ARM::MOVs) {
const MCOperand &Dst = MI->getOperand(0);
@@ -107,8 +107,8 @@ void ARMInstPrinter::printInst(const MCInst *MI) {
const MCOperand &MO3 = MI->getOperand(3);
O << '\t' << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO3.getImm()));
- printSBitModifierOperand(MI, 6);
- printPredicateOperand(MI, 4);
+ printSBitModifierOperand(MI, 6, O);
+ printPredicateOperand(MI, 4, O);
O << '\t' << getRegisterName(Dst.getReg())
<< ", " << getRegisterName(MO1.getReg());
@@ -133,9 +133,9 @@ void ARMInstPrinter::printInst(const MCInst *MI) {
const MCOperand &MO1 = MI->getOperand(2);
if (ARM_AM::getAM4SubMode(MO1.getImm()) == ARM_AM::db) {
O << '\t' << "push";
- printPredicateOperand(MI, 3);
+ printPredicateOperand(MI, 3, O);
O << '\t';
- printRegisterList(MI, 5);
+ printRegisterList(MI, 5, O);
return;
}
}
@@ -146,9 +146,9 @@ void ARMInstPrinter::printInst(const MCInst *MI) {
const MCOperand &MO1 = MI->getOperand(2);
if (ARM_AM::getAM4SubMode(MO1.getImm()) == ARM_AM::ia) {
O << '\t' << "pop";
- printPredicateOperand(MI, 3);
+ printPredicateOperand(MI, 3, O);
O << '\t';
- printRegisterList(MI, 5);
+ printRegisterList(MI, 5, O);
return;
}
}
@@ -159,9 +159,9 @@ void ARMInstPrinter::printInst(const MCInst *MI) {
const MCOperand &MO1 = MI->getOperand(2);
if (ARM_AM::getAM5SubMode(MO1.getImm()) == ARM_AM::db) {
O << '\t' << "vpush";
- printPredicateOperand(MI, 3);
+ printPredicateOperand(MI, 3, O);
O << '\t';
- printRegisterList(MI, 5);
+ printRegisterList(MI, 5, O);
return;
}
}
@@ -172,18 +172,18 @@ void ARMInstPrinter::printInst(const MCInst *MI) {
const MCOperand &MO1 = MI->getOperand(2);
if (ARM_AM::getAM5SubMode(MO1.getImm()) == ARM_AM::ia) {
O << '\t' << "vpop";
- printPredicateOperand(MI, 3);
+ printPredicateOperand(MI, 3, O);
O << '\t';
- printRegisterList(MI, 5);
+ printRegisterList(MI, 5, O);
return;
}
}
- printInstruction(MI);
+ printInstruction(MI, O);
}
void ARMInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
- const char *Modifier) {
+ raw_ostream &O, const char *Modifier) {
const MCOperand &Op = MI->getOperand(OpNo);
if (Op.isReg()) {
unsigned Reg = Op.getReg();
@@ -247,7 +247,8 @@ static void printSOImm(raw_ostream &O, int64_t V, bool VerboseAsm,
/// printSOImmOperand - SOImm is 4-bit rotate amount in bits 8-11 with 8-bit
/// immediate in bits 0-7.
-void ARMInstPrinter::printSOImmOperand(const MCInst *MI, unsigned OpNum) {
+void ARMInstPrinter::printSOImmOperand(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O) {
const MCOperand &MO = MI->getOperand(OpNum);
assert(MO.isImm() && "Not a valid so_imm value!");
printSOImm(O, MO.getImm(), VerboseAsm, &MAI);
@@ -255,7 +256,8 @@ void ARMInstPrinter::printSOImmOperand(const MCInst *MI, unsigned OpNum) {
/// printSOImm2PartOperand - SOImm is broken into two pieces using a 'mov'
/// followed by an 'orr' to materialize.
-void ARMInstPrinter::printSOImm2PartOperand(const MCInst *MI, unsigned OpNum) {
+void ARMInstPrinter::printSOImm2PartOperand(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O) {
// FIXME: REMOVE this method.
abort();
}
@@ -265,7 +267,8 @@ void ARMInstPrinter::printSOImm2PartOperand(const MCInst *MI, unsigned OpNum) {
// REG 0 0 - e.g. R5
// REG REG 0,SH_OPC - e.g. R5, ROR R3
// REG 0 IMM,SH_OPC - e.g. R5, LSL #3
-void ARMInstPrinter::printSORegOperand(const MCInst *MI, unsigned OpNum) {
+void ARMInstPrinter::printSORegOperand(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O) {
const MCOperand &MO1 = MI->getOperand(OpNum);
const MCOperand &MO2 = MI->getOperand(OpNum+1);
const MCOperand &MO3 = MI->getOperand(OpNum+2);
@@ -286,13 +289,14 @@ void ARMInstPrinter::printSORegOperand(const MCInst *MI, unsigned OpNum) {
}
-void ARMInstPrinter::printAddrMode2Operand(const MCInst *MI, unsigned Op) {
+void ARMInstPrinter::printAddrMode2Operand(const MCInst *MI, unsigned Op,
+ raw_ostream &O) {
const MCOperand &MO1 = MI->getOperand(Op);
const MCOperand &MO2 = MI->getOperand(Op+1);
const MCOperand &MO3 = MI->getOperand(Op+2);
if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
- printOperand(MI, Op);
+ printOperand(MI, Op, O);
return;
}
@@ -319,7 +323,8 @@ void ARMInstPrinter::printAddrMode2Operand(const MCInst *MI, unsigned Op) {
}
void ARMInstPrinter::printAddrMode2OffsetOperand(const MCInst *MI,
- unsigned OpNum) {
+ unsigned OpNum,
+ raw_ostream &O) {
const MCOperand &MO1 = MI->getOperand(OpNum);
const MCOperand &MO2 = MI->getOperand(OpNum+1);
@@ -341,7 +346,8 @@ void ARMInstPrinter::printAddrMode2OffsetOperand(const MCInst *MI,
<< " #" << ShImm;
}
-void ARMInstPrinter::printAddrMode3Operand(const MCInst *MI, unsigned OpNum) {
+void ARMInstPrinter::printAddrMode3Operand(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O) {
const MCOperand &MO1 = MI->getOperand(OpNum);
const MCOperand &MO2 = MI->getOperand(OpNum+1);
const MCOperand &MO3 = MI->getOperand(OpNum+2);
@@ -362,7 +368,8 @@ void ARMInstPrinter::printAddrMode3Operand(const MCInst *MI, unsigned OpNum) {
}
void ARMInstPrinter::printAddrMode3OffsetOperand(const MCInst *MI,
- unsigned OpNum) {
+ unsigned OpNum,
+ raw_ostream &O) {
const MCOperand &MO1 = MI->getOperand(OpNum);
const MCOperand &MO2 = MI->getOperand(OpNum+1);
@@ -381,6 +388,7 @@ void ARMInstPrinter::printAddrMode3OffsetOperand(const MCInst *MI,
void ARMInstPrinter::printAddrMode4Operand(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O,
const char *Modifier) {
const MCOperand &MO2 = MI->getOperand(OpNum+1);
ARM_AM::AMSubMode Mode = ARM_AM::getAM4SubMode(MO2.getImm());
@@ -391,17 +399,18 @@ void ARMInstPrinter::printAddrMode4Operand(const MCInst *MI, unsigned OpNum,
if (Mode == ARM_AM::ia)
O << ".w";
} else {
- printOperand(MI, OpNum);
+ printOperand(MI, OpNum, O);
}
}
void ARMInstPrinter::printAddrMode5Operand(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O,
const char *Modifier) {
const MCOperand &MO1 = MI->getOperand(OpNum);
const MCOperand &MO2 = MI->getOperand(OpNum+1);
if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
- printOperand(MI, OpNum);
+ printOperand(MI, OpNum, O);
return;
}
@@ -425,7 +434,8 @@ void ARMInstPrinter::printAddrMode5Operand(const MCInst *MI, unsigned OpNum,
O << "]";
}
-void ARMInstPrinter::printAddrMode6Operand(const MCInst *MI, unsigned OpNum) {
+void ARMInstPrinter::printAddrMode6Operand(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O) {
const MCOperand &MO1 = MI->getOperand(OpNum);
const MCOperand &MO2 = MI->getOperand(OpNum+1);
@@ -438,7 +448,8 @@ void ARMInstPrinter::printAddrMode6Operand(const MCInst *MI, unsigned OpNum) {
}
void ARMInstPrinter::printAddrMode6OffsetOperand(const MCInst *MI,
- unsigned OpNum) {
+ unsigned OpNum,
+ raw_ostream &O) {
const MCOperand &MO = MI->getOperand(OpNum);
if (MO.getReg() == 0)
O << "!";
@@ -447,12 +458,14 @@ void ARMInstPrinter::printAddrMode6OffsetOperand(const MCInst *MI,
}
void ARMInstPrinter::printAddrModePCOperand(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O,
const char *Modifier) {
assert(0 && "FIXME: Implement printAddrModePCOperand");
}
void ARMInstPrinter::printBitfieldInvMaskImmOperand (const MCInst *MI,
- unsigned OpNum) {
+ unsigned OpNum,
+ raw_ostream &O) {
const MCOperand &MO = MI->getOperand(OpNum);
uint32_t v = ~MO.getImm();
int32_t lsb = CountTrailingZeros_32(v);
@@ -461,7 +474,8 @@ void ARMInstPrinter::printBitfieldInvMaskImmOperand (const MCInst *MI,
O << '#' << lsb << ", #" << width;
}
-void ARMInstPrinter::printRegisterList(const MCInst *MI, unsigned OpNum) {
+void ARMInstPrinter::printRegisterList(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O) {
O << "{";
for (unsigned i = OpNum, e = MI->getNumOperands(); i != e; ++i) {
if (i != OpNum) O << ", ";
@@ -470,7 +484,8 @@ void ARMInstPrinter::printRegisterList(const MCInst *MI, unsigned OpNum) {
O << "}";
}
-void ARMInstPrinter::printCPSOptionOperand(const MCInst *MI, unsigned OpNum) {
+void ARMInstPrinter::printCPSOptionOperand(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O) {
const MCOperand &Op = MI->getOperand(OpNum);
unsigned option = Op.getImm();
unsigned mode = option & 31;
@@ -492,7 +507,8 @@ void ARMInstPrinter::printCPSOptionOperand(const MCInst *MI, unsigned OpNum) {
O << '#' << mode;
}
-void ARMInstPrinter::printMSRMaskOperand(const MCInst *MI, unsigned OpNum) {
+void ARMInstPrinter::printMSRMaskOperand(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O) {
const MCOperand &Op = MI->getOperand(OpNum);
unsigned Mask = Op.getImm();
if (Mask) {
@@ -504,7 +520,8 @@ void ARMInstPrinter::printMSRMaskOperand(const MCInst *MI, unsigned OpNum) {
}
}
-void ARMInstPrinter::printNegZeroOperand(const MCInst *MI, unsigned OpNum){
+void ARMInstPrinter::printNegZeroOperand(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O) {
const MCOperand &Op = MI->getOperand(OpNum);
O << '#';
if (Op.getImm() < 0)
@@ -513,19 +530,22 @@ void ARMInstPrinter::printNegZeroOperand(const MCInst *MI, unsigned OpNum){
O << Op.getImm();
}
-void ARMInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNum) {
+void ARMInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O) {
ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(OpNum).getImm();
if (CC != ARMCC::AL)
O << ARMCondCodeToString(CC);
}
void ARMInstPrinter::printMandatoryPredicateOperand(const MCInst *MI,
- unsigned OpNum) {
+ unsigned OpNum,
+ raw_ostream &O) {
ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(OpNum).getImm();
O << ARMCondCodeToString(CC);
}
-void ARMInstPrinter::printSBitModifierOperand(const MCInst *MI, unsigned OpNum){
+void ARMInstPrinter::printSBitModifierOperand(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O) {
if (MI->getOperand(OpNum).getReg()) {
assert(MI->getOperand(OpNum).getReg() == ARM::CPSR &&
"Expect ARM CPSR register!");
@@ -536,26 +556,31 @@ void ARMInstPrinter::printSBitModifierOperand(const MCInst *MI, unsigned OpNum){
void ARMInstPrinter::printCPInstOperand(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O,
const char *Modifier) {
// FIXME: remove this.
abort();
}
-void ARMInstPrinter::printNoHashImmediate(const MCInst *MI, unsigned OpNum) {
+void ARMInstPrinter::printNoHashImmediate(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O) {
O << MI->getOperand(OpNum).getImm();
}
-void ARMInstPrinter::printPCLabel(const MCInst *MI, unsigned OpNum) {
+void ARMInstPrinter::printPCLabel(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O) {
// FIXME: remove this.
abort();
}
-void ARMInstPrinter::printThumbS4ImmOperand(const MCInst *MI, unsigned OpNum) {
+void ARMInstPrinter::printThumbS4ImmOperand(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O) {
O << "#" << MI->getOperand(OpNum).getImm() * 4;
}
-void ARMInstPrinter::printThumbITMask(const MCInst *MI, unsigned OpNum) {
+void ARMInstPrinter::printThumbITMask(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O) {
// (3 - the number of trailing zeros) is the number of then / else.
unsigned Mask = MI->getOperand(OpNum).getImm();
unsigned CondBit0 = Mask >> 4 & 1;
@@ -570,8 +595,8 @@ void ARMInstPrinter::printThumbITMask(const MCInst *MI, unsigned OpNum) {
}
}
-void ARMInstPrinter::printThumbAddrModeRROperand(const MCInst *MI, unsigned Op)
-{
+void ARMInstPrinter::printThumbAddrModeRROperand(const MCInst *MI, unsigned Op,
+ raw_ostream &O) {
const MCOperand &MO1 = MI->getOperand(Op);
const MCOperand &MO2 = MI->getOperand(Op+1);
O << "[" << getRegisterName(MO1.getReg());
@@ -579,13 +604,14 @@ void ARMInstPrinter::printThumbAddrModeRROperand(const MCInst *MI, unsigned Op)
}
void ARMInstPrinter::printThumbAddrModeRI5Operand(const MCInst *MI, unsigned Op,
+ raw_ostream &O,
unsigned Scale) {
const MCOperand &MO1 = MI->getOperand(Op);
const MCOperand &MO2 = MI->getOperand(Op+1);
const MCOperand &MO3 = MI->getOperand(Op+2);
if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
- printOperand(MI, Op);
+ printOperand(MI, Op, O);
return;
}
@@ -597,22 +623,23 @@ void ARMInstPrinter::printThumbAddrModeRI5Operand(const MCInst *MI, unsigned Op,
O << "]";
}
-void ARMInstPrinter::printThumbAddrModeS1Operand(const MCInst *MI, unsigned Op)
-{
- printThumbAddrModeRI5Operand(MI, Op, 1);
+void ARMInstPrinter::printThumbAddrModeS1Operand(const MCInst *MI, unsigned Op,
+ raw_ostream &O) {
+ printThumbAddrModeRI5Operand(MI, Op, O, 1);
}
-void ARMInstPrinter::printThumbAddrModeS2Operand(const MCInst *MI, unsigned Op)
-{
- printThumbAddrModeRI5Operand(MI, Op, 2);
+void ARMInstPrinter::printThumbAddrModeS2Operand(const MCInst *MI, unsigned Op,
+ raw_ostream &O) {
+ printThumbAddrModeRI5Operand(MI, Op, O, 2);
}
-void ARMInstPrinter::printThumbAddrModeS4Operand(const MCInst *MI, unsigned Op)
-{
- printThumbAddrModeRI5Operand(MI, Op, 4);
+void ARMInstPrinter::printThumbAddrModeS4Operand(const MCInst *MI, unsigned Op,
+ raw_ostream &O) {
+ printThumbAddrModeRI5Operand(MI, Op, O, 4);
}
-void ARMInstPrinter::printThumbAddrModeSPOperand(const MCInst *MI,unsigned Op) {
+void ARMInstPrinter::printThumbAddrModeSPOperand(const MCInst *MI, unsigned Op,
+ raw_ostream &O) {
const MCOperand &MO1 = MI->getOperand(Op);
const MCOperand &MO2 = MI->getOperand(Op+1);
O << "[" << getRegisterName(MO1.getReg());
@@ -621,7 +648,8 @@ void ARMInstPrinter::printThumbAddrModeSPOperand(const MCInst *MI,unsigned Op) {
O << "]";
}
-void ARMInstPrinter::printTBAddrMode(const MCInst *MI, unsigned OpNum) {
+void ARMInstPrinter::printTBAddrMode(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O) {
O << "[pc, " << getRegisterName(MI->getOperand(OpNum).getReg());
if (MI->getOpcode() == ARM::t2TBH)
O << ", lsl #1";
@@ -632,7 +660,8 @@ void ARMInstPrinter::printTBAddrMode(const MCInst *MI, unsigned OpNum) {
// register with shift forms.
// REG 0 0 - e.g. R5
// REG IMM, SH_OPC - e.g. R5, LSL #3
-void ARMInstPrinter::printT2SOOperand(const MCInst *MI, unsigned OpNum) {
+void ARMInstPrinter::printT2SOOperand(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O) {
const MCOperand &MO1 = MI->getOperand(OpNum);
const MCOperand &MO2 = MI->getOperand(OpNum+1);
@@ -649,7 +678,8 @@ void ARMInstPrinter::printT2SOOperand(const MCInst *MI, unsigned OpNum) {
}
void ARMInstPrinter::printT2AddrModeImm12Operand(const MCInst *MI,
- unsigned OpNum) {
+ unsigned OpNum,
+ raw_ostream &O) {
const MCOperand &MO1 = MI->getOperand(OpNum);
const MCOperand &MO2 = MI->getOperand(OpNum+1);
@@ -662,7 +692,8 @@ void ARMInstPrinter::printT2AddrModeImm12Operand(const MCInst *MI,
}
void ARMInstPrinter::printT2AddrModeImm8Operand(const MCInst *MI,
- unsigned OpNum) {
+ unsigned OpNum,
+ raw_ostream &O) {
const MCOperand &MO1 = MI->getOperand(OpNum);
const MCOperand &MO2 = MI->getOperand(OpNum+1);
@@ -678,7 +709,8 @@ void ARMInstPrinter::printT2AddrModeImm8Operand(const MCInst *MI,
}
void ARMInstPrinter::printT2AddrModeImm8s4Operand(const MCInst *MI,
- unsigned OpNum) {
+ unsigned OpNum,
+ raw_ostream &O) {
const MCOperand &MO1 = MI->getOperand(OpNum);
const MCOperand &MO2 = MI->getOperand(OpNum+1);
@@ -694,7 +726,8 @@ void ARMInstPrinter::printT2AddrModeImm8s4Operand(const MCInst *MI,
}
void ARMInstPrinter::printT2AddrModeImm8OffsetOperand(const MCInst *MI,
- unsigned OpNum) {
+ unsigned OpNum,
+ raw_ostream &O) {
const MCOperand &MO1 = MI->getOperand(OpNum);
int32_t OffImm = (int32_t)MO1.getImm();
// Don't print +0.
@@ -705,7 +738,8 @@ void ARMInstPrinter::printT2AddrModeImm8OffsetOperand(const MCInst *MI,
}
void ARMInstPrinter::printT2AddrModeImm8s4OffsetOperand(const MCInst *MI,
- unsigned OpNum) {
+ unsigned OpNum,
+ raw_ostream &O) {
const MCOperand &MO1 = MI->getOperand(OpNum);
int32_t OffImm = (int32_t)MO1.getImm() / 4;
// Don't print +0.
@@ -716,7 +750,8 @@ void ARMInstPrinter::printT2AddrModeImm8s4OffsetOperand(const MCInst *MI,
}
void ARMInstPrinter::printT2AddrModeSoRegOperand(const MCInst *MI,
- unsigned OpNum) {
+ unsigned OpNum,
+ raw_ostream &O) {
const MCOperand &MO1 = MI->getOperand(OpNum);
const MCOperand &MO2 = MI->getOperand(OpNum+1);
const MCOperand &MO3 = MI->getOperand(OpNum+2);
@@ -734,11 +769,13 @@ void ARMInstPrinter::printT2AddrModeSoRegOperand(const MCInst *MI,
O << "]";
}
-void ARMInstPrinter::printVFPf32ImmOperand(const MCInst *MI, unsigned OpNum) {
+void ARMInstPrinter::printVFPf32ImmOperand(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O) {
O << '#' << MI->getOperand(OpNum).getImm();
}
-void ARMInstPrinter::printVFPf64ImmOperand(const MCInst *MI, unsigned OpNum) {
+void ARMInstPrinter::printVFPf64ImmOperand(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O) {
O << '#' << MI->getOperand(OpNum).getImm();
}
diff --git a/lib/Target/ARM/AsmPrinter/ARMInstPrinter.h b/lib/Target/ARM/AsmPrinter/ARMInstPrinter.h
index d41b5df..dd006fc 100644
--- a/lib/Target/ARM/AsmPrinter/ARMInstPrinter.h
+++ b/lib/Target/ARM/AsmPrinter/ARMInstPrinter.h
@@ -22,79 +22,96 @@ namespace llvm {
class ARMInstPrinter : public MCInstPrinter {
bool VerboseAsm;
public:
- ARMInstPrinter(raw_ostream &O, const MCAsmInfo &MAI, bool verboseAsm)
- : MCInstPrinter(O, MAI), VerboseAsm(verboseAsm) {}
+ ARMInstPrinter(const MCAsmInfo &MAI, bool verboseAsm)
+ : MCInstPrinter(MAI), VerboseAsm(verboseAsm) {}
- virtual void printInst(const MCInst *MI);
+ virtual void printInst(const MCInst *MI, raw_ostream &O);
// Autogenerated by tblgen.
- void printInstruction(const MCInst *MI);
+ void printInstruction(const MCInst *MI, raw_ostream &O);
static const char *getRegisterName(unsigned RegNo);
- void printOperand(const MCInst *MI, unsigned OpNo,
+ void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O,
const char *Modifier = 0);
- void printSOImmOperand(const MCInst *MI, unsigned OpNum);
- void printSOImm2PartOperand(const MCInst *MI, unsigned OpNum);
+ void printSOImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
+ void printSOImm2PartOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
- void printSORegOperand(const MCInst *MI, unsigned OpNum);
- void printAddrMode2Operand(const MCInst *MI, unsigned OpNum);
- void printAddrMode2OffsetOperand(const MCInst *MI, unsigned OpNum);
- void printAddrMode3Operand(const MCInst *MI, unsigned OpNum);
- void printAddrMode3OffsetOperand(const MCInst *MI, unsigned OpNum);
- void printAddrMode4Operand(const MCInst *MI, unsigned OpNum,
+ void printSORegOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
+ void printAddrMode2Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
+ void printAddrMode2OffsetOperand(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O);
+ void printAddrMode3Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
+ void printAddrMode3OffsetOperand(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O);
+ void printAddrMode4Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O,
const char *Modifier = 0);
- void printAddrMode5Operand(const MCInst *MI, unsigned OpNum,
+ void printAddrMode5Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O,
const char *Modifier = 0);
- void printAddrMode6Operand(const MCInst *MI, unsigned OpNum);
- void printAddrMode6OffsetOperand(const MCInst *MI, unsigned OpNum);
- void printAddrModePCOperand(const MCInst *MI, unsigned OpNum,
+ void printAddrMode6Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
+ void printAddrMode6OffsetOperand(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O);
+ void printAddrModePCOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O,
const char *Modifier = 0);
- void printBitfieldInvMaskImmOperand(const MCInst *MI, unsigned OpNum);
+ void printBitfieldInvMaskImmOperand(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O);
- void printThumbS4ImmOperand(const MCInst *MI, unsigned OpNum);
- void printThumbITMask(const MCInst *MI, unsigned OpNum);
- void printThumbAddrModeRROperand(const MCInst *MI, unsigned OpNum);
+ void printThumbS4ImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
+ void printThumbITMask(const MCInst *MI, unsigned OpNum, raw_ostream &O);
+ void printThumbAddrModeRROperand(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O);
void printThumbAddrModeRI5Operand(const MCInst *MI, unsigned OpNum,
- unsigned Scale);
- void printThumbAddrModeS1Operand(const MCInst *MI, unsigned OpNum);
- void printThumbAddrModeS2Operand(const MCInst *MI, unsigned OpNum);
- void printThumbAddrModeS4Operand(const MCInst *MI, unsigned OpNum);
- void printThumbAddrModeSPOperand(const MCInst *MI, unsigned OpNum);
+ raw_ostream &O, unsigned Scale);
+ void printThumbAddrModeS1Operand(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O);
+ void printThumbAddrModeS2Operand(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O);
+ void printThumbAddrModeS4Operand(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O);
+ void printThumbAddrModeSPOperand(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O);
- void printT2SOOperand(const MCInst *MI, unsigned OpNum);
- void printT2AddrModeImm12Operand(const MCInst *MI, unsigned OpNum);
- void printT2AddrModeImm8Operand(const MCInst *MI, unsigned OpNum);
- void printT2AddrModeImm8s4Operand(const MCInst *MI, unsigned OpNum);
- void printT2AddrModeImm8OffsetOperand(const MCInst *MI, unsigned OpNum);
- void printT2AddrModeImm8s4OffsetOperand(const MCInst *MI, unsigned OpNum);
- void printT2AddrModeSoRegOperand(const MCInst *MI, unsigned OpNum);
+ void printT2SOOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
+ void printT2AddrModeImm12Operand(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O);
+ void printT2AddrModeImm8Operand(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O);
+ void printT2AddrModeImm8s4Operand(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O);
+ void printT2AddrModeImm8OffsetOperand(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O);
+ void printT2AddrModeImm8s4OffsetOperand(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O);
+ void printT2AddrModeSoRegOperand(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O);
- void printCPSOptionOperand(const MCInst *MI, unsigned OpNum);
- void printMSRMaskOperand(const MCInst *MI, unsigned OpNum);
- void printNegZeroOperand(const MCInst *MI, unsigned OpNum);
- void printPredicateOperand(const MCInst *MI, unsigned OpNum);
- void printMandatoryPredicateOperand(const MCInst *MI, unsigned OpNum);
- void printSBitModifierOperand(const MCInst *MI, unsigned OpNum);
- void printRegisterList(const MCInst *MI, unsigned OpNum);
- void printCPInstOperand(const MCInst *MI, unsigned OpNum,
+ void printCPSOptionOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
+ void printMSRMaskOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
+ void printNegZeroOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
+ void printPredicateOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
+ void printMandatoryPredicateOperand(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O);
+ void printSBitModifierOperand(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O);
+ void printRegisterList(const MCInst *MI, unsigned OpNum, raw_ostream &O);
+ void printCPInstOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O,
const char *Modifier);
- void printJTBlockOperand(const MCInst *MI, unsigned OpNum) {}
- void printJT2BlockOperand(const MCInst *MI, unsigned OpNum) {}
- void printTBAddrMode(const MCInst *MI, unsigned OpNum);
- void printNoHashImmediate(const MCInst *MI, unsigned OpNum);
- void printVFPf32ImmOperand(const MCInst *MI, unsigned OpNum);
- void printVFPf64ImmOperand(const MCInst *MI, unsigned OpNum);
- void printHex8ImmOperand(const MCInst *MI, int OpNum) {}
- void printHex16ImmOperand(const MCInst *MI, int OpNum) {}
- void printHex32ImmOperand(const MCInst *MI, int OpNum) {}
- void printHex64ImmOperand(const MCInst *MI, int OpNum) {}
+ void printJTBlockOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O) {}
+ void printJT2BlockOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O) {}
+ void printTBAddrMode(const MCInst *MI, unsigned OpNum, raw_ostream &O);
+ void printNoHashImmediate(const MCInst *MI, unsigned OpNum, raw_ostream &O);
+ void printVFPf32ImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
+ void printVFPf64ImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
+ void printHex8ImmOperand(const MCInst *MI, int OpNum, raw_ostream &O) {}
+ void printHex16ImmOperand(const MCInst *MI, int OpNum, raw_ostream &O) {}
+ void printHex32ImmOperand(const MCInst *MI, int OpNum, raw_ostream &O) {}
+ void printHex64ImmOperand(const MCInst *MI, int OpNum, raw_ostream &O) {}
- void printPCLabel(const MCInst *MI, unsigned OpNum);
+ void printPCLabel(const MCInst *MI, unsigned OpNum, raw_ostream &O);
// FIXME: Implement.
- void PrintSpecial(const MCInst *MI, const char *Kind) {}
+ void PrintSpecial(const MCInst *MI, raw_ostream &O, const char *Kind) {}
};
}
diff --git a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
index 0431340..47c3104 100644
--- a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
+++ b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
@@ -380,11 +380,18 @@ bool ARMDisassembler::getInstruction(MCInst &MI,
raw_ostream &os) const {
// The machine instruction.
uint32_t insn;
+ uint8_t bytes[4];
// We want to read exactly 4 bytes of data.
- if (Region.readBytes(Address, 4, (uint8_t*)&insn, NULL) == -1)
+ if (Region.readBytes(Address, 4, (uint8_t*)bytes, NULL) == -1)
return false;
+ // Encoded as a small-endian 32-bit word in the stream.
+ insn = (bytes[3] << 24) |
+ (bytes[2] << 16) |
+ (bytes[1] << 8) |
+ (bytes[0] << 0);
+
unsigned Opcode = decodeARMInstruction(insn);
ARMFormat Format = ARMFormats[Opcode];
Size = 4;
@@ -414,9 +421,15 @@ bool ThumbDisassembler::getInstruction(MCInst &MI,
const MemoryObject &Region,
uint64_t Address,
raw_ostream &os) const {
- // The machine instruction.
+ // The Thumb instruction stream is a sequence of halhwords.
+
+ // This represents the first halfword as well as the machine instruction
+ // passed to decodeThumbInstruction(). For 16-bit Thumb instruction, the top
+ // halfword of insn is 0x00 0x00; otherwise, the first halfword is moved to
+ // the top half followed by the second halfword.
uint32_t insn = 0;
- uint32_t insn1 = 0;
+ // Possible second halfword.
+ uint16_t insn1 = 0;
// A6.1 Thumb instruction set encoding
//
@@ -429,9 +442,12 @@ bool ThumbDisassembler::getInstruction(MCInst &MI,
// Otherwise, the halfword is a 16-bit instruction.
// Read 2 bytes of data first.
- if (Region.readBytes(Address, 2, (uint8_t*)&insn, NULL) == -1)
+ uint8_t bytes[2];
+ if (Region.readBytes(Address, 2, (uint8_t*)bytes, NULL) == -1)
return false;
+ // Encoded as a small-endian 16-bit halfword in the stream.
+ insn = (bytes[1] << 8) | bytes[0];
unsigned bits15_11 = slice(insn, 15, 11);
bool IsThumb2 = false;
@@ -439,8 +455,10 @@ bool ThumbDisassembler::getInstruction(MCInst &MI,
// { 0b11101 /* 0x1D */, 0b11110 /* 0x1E */, ob11111 /* 0x1F */ }.
if (bits15_11 == 0x1D || bits15_11 == 0x1E || bits15_11 == 0x1F) {
IsThumb2 = true;
- if (Region.readBytes(Address + 2, 2, (uint8_t*)&insn1, NULL) == -1)
+ if (Region.readBytes(Address + 2, 2, (uint8_t*)bytes, NULL) == -1)
return false;
+ // Encoded as a small-endian 16-bit halfword in the stream.
+ insn1 = (bytes[1] << 8) | bytes[0];
insn = (insn << 16 | insn1);
}
diff --git a/lib/Target/ARM/Disassembler/Makefile b/lib/Target/ARM/Disassembler/Makefile
deleted file mode 100644
index 031b6ac..0000000
--- a/lib/Target/ARM/Disassembler/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-##===- lib/Target/ARM/Disassembler/Makefile ----------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../../..
-LIBRARYNAME = LLVMARMDisassembler
-
-# Hack: we need to include 'main' arm target directory to grab private headers
-CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
diff --git a/lib/Target/ARM/Makefile b/lib/Target/ARM/Makefile
index b7ed14a..a8dd38c 100644
--- a/lib/Target/ARM/Makefile
+++ b/lib/Target/ARM/Makefile
@@ -16,9 +16,8 @@ BUILT_SOURCES = ARMGenRegisterInfo.h.inc ARMGenRegisterNames.inc \
ARMGenRegisterInfo.inc ARMGenInstrNames.inc \
ARMGenInstrInfo.inc ARMGenAsmWriter.inc \
ARMGenDAGISel.inc ARMGenSubtarget.inc \
- ARMGenCodeEmitter.inc ARMGenCallingConv.inc \
- ARMGenDecoderTables.inc
+ ARMGenCodeEmitter.inc ARMGenCallingConv.inc
-DIRS = AsmPrinter AsmParser Disassembler TargetInfo
+DIRS = AsmPrinter AsmParser TargetInfo
include $(LEVEL)/Makefile.common
diff --git a/lib/Target/Alpha/Alpha.td b/lib/Target/Alpha/Alpha.td
index 6efdf55..4508eda 100644
--- a/lib/Target/Alpha/Alpha.td
+++ b/lib/Target/Alpha/Alpha.td
@@ -47,11 +47,7 @@ include "AlphaSchedule.td"
include "AlphaInstrInfo.td"
-def AlphaInstrInfo : InstrInfo {
- // Define how we want to layout our target-specific information field.
- // let TSFlagsFields = [];
- // let TSFlagsShifts = [];
-}
+def AlphaInstrInfo : InstrInfo;
//===----------------------------------------------------------------------===//
// Alpha Processor Definitions
diff --git a/lib/Target/Alpha/AsmPrinter/AlphaAsmPrinter.cpp b/lib/Target/Alpha/AsmPrinter/AlphaAsmPrinter.cpp
index 093cf05..2a1f5559 100644
--- a/lib/Target/Alpha/AsmPrinter/AlphaAsmPrinter.cpp
+++ b/lib/Target/Alpha/AsmPrinter/AlphaAsmPrinter.cpp
@@ -20,7 +20,6 @@
#include "llvm/Type.h"
#include "llvm/Assembly/Writer.h"
#include "llvm/CodeGen/AsmPrinter.h"
-#include "llvm/CodeGen/DwarfWriter.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCSymbol.h"
@@ -28,8 +27,8 @@
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetRegistry.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/FormattedStream.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/raw_ostream.h"
using namespace llvm;
namespace {
@@ -37,40 +36,42 @@ namespace {
/// Unique incrementer for label values for referencing Global values.
///
- explicit AlphaAsmPrinter(formatted_raw_ostream &o, TargetMachine &tm,
- MCStreamer &Streamer)
- : AsmPrinter(o, tm, Streamer) {}
+ explicit AlphaAsmPrinter(TargetMachine &tm, MCStreamer &Streamer)
+ : AsmPrinter(tm, Streamer) {}
virtual const char *getPassName() const {
return "Alpha Assembly Printer";
}
- void printInstruction(const MachineInstr *MI);
+ void printInstruction(const MachineInstr *MI, raw_ostream &O);
void EmitInstruction(const MachineInstr *MI) {
- printInstruction(MI);
- OutStreamer.AddBlankLine();
+ SmallString<128> Str;
+ raw_svector_ostream OS(Str);
+ printInstruction(MI, OS);
+ OutStreamer.EmitRawText(OS.str());
}
static const char *getRegisterName(unsigned RegNo);
- void printOp(const MachineOperand &MO, bool IsCallOp = false);
- void printOperand(const MachineInstr *MI, int opNum);
- void printBaseOffsetPair(const MachineInstr *MI, int i, bool brackets=true);
+ void printOp(const MachineOperand &MO, raw_ostream &O);
+ void printOperand(const MachineInstr *MI, int opNum, raw_ostream &O);
+ void printBaseOffsetPair(const MachineInstr *MI, int i, raw_ostream &O,
+ bool brackets=true);
virtual void EmitFunctionBodyStart();
virtual void EmitFunctionBodyEnd();
void EmitStartOfAsmFile(Module &M);
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
- unsigned AsmVariant, const char *ExtraCode);
+ unsigned AsmVariant, const char *ExtraCode,
+ raw_ostream &O);
bool PrintAsmMemoryOperand(const MachineInstr *MI,
- unsigned OpNo,
- unsigned AsmVariant,
- const char *ExtraCode);
+ unsigned OpNo, unsigned AsmVariant,
+ const char *ExtraCode, raw_ostream &O);
};
} // end of anonymous namespace
#include "AlphaGenAsmWriter.inc"
-void AlphaAsmPrinter::printOperand(const MachineInstr *MI, int opNum)
-{
+void AlphaAsmPrinter::printOperand(const MachineInstr *MI, int opNum,
+ raw_ostream &O) {
const MachineOperand &MO = MI->getOperand(opNum);
if (MO.getType() == MachineOperand::MO_Register) {
assert(TargetRegisterInfo::isPhysicalRegister(MO.getReg()) &&
@@ -80,12 +81,12 @@ void AlphaAsmPrinter::printOperand(const MachineInstr *MI, int opNum)
O << MO.getImm();
assert(MO.getImm() < (1 << 30));
} else {
- printOp(MO);
+ printOp(MO, O);
}
}
-void AlphaAsmPrinter::printOp(const MachineOperand &MO, bool IsCallOp) {
+void AlphaAsmPrinter::printOp(const MachineOperand &MO, raw_ostream &O) {
switch (MO.getType()) {
case MachineOperand::MO_Register:
O << getRegisterName(MO.getReg());
@@ -126,40 +127,37 @@ void AlphaAsmPrinter::printOp(const MachineOperand &MO, bool IsCallOp) {
/// EmitFunctionBodyStart - Targets can override this to emit stuff before
/// the first basic block in the function.
void AlphaAsmPrinter::EmitFunctionBodyStart() {
- O << "\t.ent " << *CurrentFnSym << "\n";
+ OutStreamer.EmitRawText("\t.ent " + Twine(CurrentFnSym->getName()));
}
/// EmitFunctionBodyEnd - Targets can override this to emit stuff after
/// the last basic block in the function.
void AlphaAsmPrinter::EmitFunctionBodyEnd() {
- O << "\t.end " << *CurrentFnSym << "\n";
+ OutStreamer.EmitRawText("\t.end " + Twine(CurrentFnSym->getName()));
}
void AlphaAsmPrinter::EmitStartOfAsmFile(Module &M) {
- if (TM.getSubtarget<AlphaSubtarget>().hasCT())
- O << "\t.arch ev6\n"; //This might need to be ev67, so leave this test here
- else
- O << "\t.arch ev6\n";
- O << "\t.set noat\n";
+ OutStreamer.EmitRawText(StringRef("\t.arch ev6"));
+ OutStreamer.EmitRawText(StringRef("\t.set noat"));
}
/// PrintAsmOperand - Print out an operand for an inline asm expression.
///
bool AlphaAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
unsigned AsmVariant,
- const char *ExtraCode) {
- printOperand(MI, OpNo);
+ const char *ExtraCode, raw_ostream &O) {
+ printOperand(MI, OpNo, O);
return false;
}
bool AlphaAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
- unsigned OpNo,
- unsigned AsmVariant,
- const char *ExtraCode) {
+ unsigned OpNo, unsigned AsmVariant,
+ const char *ExtraCode,
+ raw_ostream &O) {
if (ExtraCode && ExtraCode[0])
return true; // Unknown modifier.
O << "0(";
- printOperand(MI, OpNo);
+ printOperand(MI, OpNo, O);
O << ")";
return false;
}
diff --git a/lib/Target/Blackfin/AsmPrinter/BlackfinAsmPrinter.cpp b/lib/Target/Blackfin/AsmPrinter/BlackfinAsmPrinter.cpp
index 1c6d841..6ba258b 100644
--- a/lib/Target/Blackfin/AsmPrinter/BlackfinAsmPrinter.cpp
+++ b/lib/Target/Blackfin/AsmPrinter/BlackfinAsmPrinter.cpp
@@ -19,7 +19,6 @@
#include "llvm/DerivedTypes.h"
#include "llvm/Module.h"
#include "llvm/CodeGen/AsmPrinter.h"
-#include "llvm/CodeGen/DwarfWriter.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineInstr.h"
@@ -33,33 +32,36 @@
#include "llvm/Target/TargetRegistry.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/FormattedStream.h"
+#include "llvm/Support/raw_ostream.h"
using namespace llvm;
namespace {
class BlackfinAsmPrinter : public AsmPrinter {
public:
- BlackfinAsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
- MCStreamer &Streamer)
- : AsmPrinter(O, TM, Streamer) {}
+ BlackfinAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
+ : AsmPrinter(TM, Streamer) {}
virtual const char *getPassName() const {
return "Blackfin Assembly Printer";
}
- void printOperand(const MachineInstr *MI, int opNum);
- void printMemoryOperand(const MachineInstr *MI, int opNum);
- void printInstruction(const MachineInstr *MI); // autogenerated.
+ void printOperand(const MachineInstr *MI, int opNum, raw_ostream &O);
+ void printMemoryOperand(const MachineInstr *MI, int opNum, raw_ostream &O);
+ void printInstruction(const MachineInstr *MI, raw_ostream &O);// autogen'd.
static const char *getRegisterName(unsigned RegNo);
void EmitInstruction(const MachineInstr *MI) {
- printInstruction(MI);
- OutStreamer.AddBlankLine();
+ SmallString<128> Str;
+ raw_svector_ostream OS(Str);
+ printInstruction(MI, OS);
+ OutStreamer.EmitRawText(OS.str());
}
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
- unsigned AsmVariant, const char *ExtraCode);
+ unsigned AsmVariant, const char *ExtraCode,
+ raw_ostream &O);
bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
- unsigned AsmVariant, const char *ExtraCode);
+ unsigned AsmVariant, const char *ExtraCode,
+ raw_ostream &O);
};
} // end of anonymous namespace
@@ -69,8 +71,9 @@ extern "C" void LLVMInitializeBlackfinAsmPrinter() {
RegisterAsmPrinter<BlackfinAsmPrinter> X(TheBlackfinTarget);
}
-void BlackfinAsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
- const MachineOperand &MO = MI->getOperand (opNum);
+void BlackfinAsmPrinter::printOperand(const MachineInstr *MI, int opNum,
+ raw_ostream &O) {
+ const MachineOperand &MO = MI->getOperand(opNum);
switch (MO.getType()) {
case MachineOperand::MO_Register:
assert(TargetRegisterInfo::isPhysicalRegister(MO.getReg()) &&
@@ -86,7 +89,7 @@ void BlackfinAsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
return;
case MachineOperand::MO_GlobalAddress:
O << *Mang->getSymbol(MO.getGlobal());
- printOffset(MO.getOffset());
+ printOffset(MO.getOffset(), O);
break;
case MachineOperand::MO_ExternalSymbol:
O << *GetExternalSymbolSymbol(MO.getSymbolName());
@@ -105,22 +108,23 @@ void BlackfinAsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
}
}
-void BlackfinAsmPrinter::printMemoryOperand(const MachineInstr *MI, int opNum) {
- printOperand(MI, opNum);
+void BlackfinAsmPrinter::printMemoryOperand(const MachineInstr *MI, int opNum,
+ raw_ostream &O) {
+ printOperand(MI, opNum, O);
if (MI->getOperand(opNum+1).isImm() && MI->getOperand(opNum+1).getImm() == 0)
return;
O << " + ";
- printOperand(MI, opNum+1);
+ printOperand(MI, opNum+1, O);
}
/// PrintAsmOperand - Print out an operand for an inline asm expression.
///
bool BlackfinAsmPrinter::PrintAsmOperand(const MachineInstr *MI,
- unsigned OpNo,
- unsigned AsmVariant,
- const char *ExtraCode) {
+ unsigned OpNo, unsigned AsmVariant,
+ const char *ExtraCode,
+ raw_ostream &O) {
if (ExtraCode && ExtraCode[0]) {
if (ExtraCode[1] != 0) return true; // Unknown modifier.
@@ -131,7 +135,7 @@ bool BlackfinAsmPrinter::PrintAsmOperand(const MachineInstr *MI,
}
}
- printOperand(MI, OpNo);
+ printOperand(MI, OpNo, O);
return false;
}
@@ -139,12 +143,13 @@ bool BlackfinAsmPrinter::PrintAsmOperand(const MachineInstr *MI,
bool BlackfinAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
unsigned OpNo,
unsigned AsmVariant,
- const char *ExtraCode) {
+ const char *ExtraCode,
+ raw_ostream &O) {
if (ExtraCode && ExtraCode[0])
return true; // Unknown modifier
O << '[';
- printOperand(MI, OpNo);
+ printOperand(MI, OpNo, O);
O << ']';
return false;
diff --git a/lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp b/lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp
index 857ddcf..0ef36e5 100644
--- a/lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp
+++ b/lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp
@@ -30,17 +30,17 @@
#include "llvm/Target/TargetOptions.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Target/TargetRegistry.h"
+#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/FormattedStream.h"
+#include "llvm/Support/raw_ostream.h"
using namespace llvm;
namespace {
class SPUAsmPrinter : public AsmPrinter {
public:
- explicit SPUAsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
- MCStreamer &Streamer) :
- AsmPrinter(O, TM, Streamer) {}
+ explicit SPUAsmPrinter(TargetMachine &TM, MCStreamer &Streamer) :
+ AsmPrinter(TM, Streamer) {}
virtual const char *getPassName() const {
return "STI CBEA SPU Assembly Printer";
@@ -52,44 +52,48 @@ namespace {
/// printInstruction - This method is automatically generated by tablegen
/// from the instruction set description.
- void printInstruction(const MachineInstr *MI);
+ void printInstruction(const MachineInstr *MI, raw_ostream &OS);
static const char *getRegisterName(unsigned RegNo);
void EmitInstruction(const MachineInstr *MI) {
- printInstruction(MI);
- OutStreamer.AddBlankLine();
+ SmallString<128> Str;
+ raw_svector_ostream OS(Str);
+ printInstruction(MI, OS);
+ OutStreamer.EmitRawText(OS.str());
}
- void printOp(const MachineOperand &MO);
+ void printOp(const MachineOperand &MO, raw_ostream &OS);
/// printRegister - Print register according to target requirements.
///
- void printRegister(const MachineOperand &MO, bool R0AsZero) {
+ void printRegister(const MachineOperand &MO, bool R0AsZero, raw_ostream &O){
unsigned RegNo = MO.getReg();
assert(TargetRegisterInfo::isPhysicalRegister(RegNo) &&
"Not physreg??");
O << getRegisterName(RegNo);
}
- void printOperand(const MachineInstr *MI, unsigned OpNo) {
+ void printOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) {
const MachineOperand &MO = MI->getOperand(OpNo);
if (MO.isReg()) {
O << getRegisterName(MO.getReg());
} else if (MO.isImm()) {
O << MO.getImm();
} else {
- printOp(MO);
+ printOp(MO, O);
}
}
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
- unsigned AsmVariant, const char *ExtraCode);
+ unsigned AsmVariant, const char *ExtraCode,
+ raw_ostream &O);
bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
- unsigned AsmVariant, const char *ExtraCode);
+ unsigned AsmVariant, const char *ExtraCode,
+ raw_ostream &O);
void
- printS7ImmOperand(const MachineInstr *MI, unsigned OpNo)
+ printS7ImmOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O)
{
int value = MI->getOperand(OpNo).getImm();
value = (value << (32 - 7)) >> (32 - 7);
@@ -100,7 +104,7 @@ namespace {
}
void
- printU7ImmOperand(const MachineInstr *MI, unsigned OpNo)
+ printU7ImmOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O)
{
unsigned int value = MI->getOperand(OpNo).getImm();
assert(value < (1 << 8) && "Invalid u7 argument");
@@ -108,45 +112,45 @@ namespace {
}
void
- printShufAddr(const MachineInstr *MI, unsigned OpNo)
+ printShufAddr(const MachineInstr *MI, unsigned OpNo, raw_ostream &O)
{
char value = MI->getOperand(OpNo).getImm();
O << (int) value;
O << "(";
- printOperand(MI, OpNo+1);
+ printOperand(MI, OpNo+1, O);
O << ")";
}
void
- printS16ImmOperand(const MachineInstr *MI, unsigned OpNo)
+ printS16ImmOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O)
{
O << (short) MI->getOperand(OpNo).getImm();
}
void
- printU16ImmOperand(const MachineInstr *MI, unsigned OpNo)
+ printU16ImmOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O)
{
O << (unsigned short)MI->getOperand(OpNo).getImm();
}
void
- printU32ImmOperand(const MachineInstr *MI, unsigned OpNo)
+ printU32ImmOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O)
{
O << (unsigned)MI->getOperand(OpNo).getImm();
}
void
- printMemRegReg(const MachineInstr *MI, unsigned OpNo) {
+ printMemRegReg(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) {
// When used as the base register, r0 reads constant zero rather than
// the value contained in the register. For this reason, the darwin
// assembler requires that we print r0 as 0 (no r) when used as the base.
const MachineOperand &MO = MI->getOperand(OpNo);
O << getRegisterName(MO.getReg()) << ", ";
- printOperand(MI, OpNo+1);
+ printOperand(MI, OpNo+1, O);
}
void
- printU18ImmOperand(const MachineInstr *MI, unsigned OpNo)
+ printU18ImmOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O)
{
unsigned int value = MI->getOperand(OpNo).getImm();
assert(value <= (1 << 19) - 1 && "Invalid u18 argument");
@@ -154,7 +158,7 @@ namespace {
}
void
- printS10ImmOperand(const MachineInstr *MI, unsigned OpNo)
+ printS10ImmOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O)
{
short value = (short) (((int) MI->getOperand(OpNo).getImm() << 16)
>> 16);
@@ -164,7 +168,7 @@ namespace {
}
void
- printU10ImmOperand(const MachineInstr *MI, unsigned OpNo)
+ printU10ImmOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O)
{
short value = (short) (((int) MI->getOperand(OpNo).getImm() << 16)
>> 16);
@@ -173,7 +177,7 @@ namespace {
}
void
- printDFormAddr(const MachineInstr *MI, unsigned OpNo)
+ printDFormAddr(const MachineInstr *MI, unsigned OpNo, raw_ostream &O)
{
assert(MI->getOperand(OpNo).isImm() &&
"printDFormAddr first operand is not immediate");
@@ -182,18 +186,18 @@ namespace {
assert((value16 >= -(1 << (9+4)) && value16 <= (1 << (9+4)) - 1)
&& "Invalid dform s10 offset argument");
O << (value16 & ~0xf) << "(";
- printOperand(MI, OpNo+1);
+ printOperand(MI, OpNo+1, O);
O << ")";
}
void
- printAddr256K(const MachineInstr *MI, unsigned OpNo)
+ printAddr256K(const MachineInstr *MI, unsigned OpNo, raw_ostream &O)
{
/* Note: operand 1 is an offset or symbol name. */
if (MI->getOperand(OpNo).isImm()) {
- printS16ImmOperand(MI, OpNo);
+ printS16ImmOperand(MI, OpNo, O);
} else {
- printOp(MI->getOperand(OpNo));
+ printOp(MI->getOperand(OpNo), O);
if (MI->getOperand(OpNo+1).isImm()) {
int displ = int(MI->getOperand(OpNo+1).getImm());
if (displ > 0)
@@ -204,50 +208,51 @@ namespace {
}
}
- void printCallOperand(const MachineInstr *MI, unsigned OpNo) {
- printOp(MI->getOperand(OpNo));
+ void printCallOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) {
+ printOp(MI->getOperand(OpNo), O);
}
- void printPCRelativeOperand(const MachineInstr *MI, unsigned OpNo) {
+ void printPCRelativeOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) {
// Used to generate a ".-<target>", but it turns out that the assembler
// really wants the target.
//
// N.B.: This operand is used for call targets. Branch hints are another
// animal entirely.
- printOp(MI->getOperand(OpNo));
+ printOp(MI->getOperand(OpNo), O);
}
- void printHBROperand(const MachineInstr *MI, unsigned OpNo) {
+ void printHBROperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) {
// HBR operands are generated in front of branches, hence, the
// program counter plus the target.
O << ".+";
- printOp(MI->getOperand(OpNo));
+ printOp(MI->getOperand(OpNo), O);
}
- void printSymbolHi(const MachineInstr *MI, unsigned OpNo) {
+ void printSymbolHi(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) {
if (MI->getOperand(OpNo).isImm()) {
- printS16ImmOperand(MI, OpNo);
+ printS16ImmOperand(MI, OpNo, O);
} else {
- printOp(MI->getOperand(OpNo));
+ printOp(MI->getOperand(OpNo), O);
O << "@h";
}
}
- void printSymbolLo(const MachineInstr *MI, unsigned OpNo) {
+ void printSymbolLo(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) {
if (MI->getOperand(OpNo).isImm()) {
- printS16ImmOperand(MI, OpNo);
+ printS16ImmOperand(MI, OpNo, O);
} else {
- printOp(MI->getOperand(OpNo));
+ printOp(MI->getOperand(OpNo), O);
O << "@l";
}
}
/// Print local store address
- void printSymbolLSA(const MachineInstr *MI, unsigned OpNo) {
- printOp(MI->getOperand(OpNo));
+ void printSymbolLSA(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) {
+ printOp(MI->getOperand(OpNo), O);
}
- void printROTHNeg7Imm(const MachineInstr *MI, unsigned OpNo) {
+ void printROTHNeg7Imm(const MachineInstr *MI, unsigned OpNo,
+ raw_ostream &O) {
if (MI->getOperand(OpNo).isImm()) {
int value = (int) MI->getOperand(OpNo).getImm();
assert((value >= 0 && value < 16)
@@ -258,15 +263,13 @@ namespace {
}
}
- void printROTNeg7Imm(const MachineInstr *MI, unsigned OpNo) {
- if (MI->getOperand(OpNo).isImm()) {
- int value = (int) MI->getOperand(OpNo).getImm();
- assert((value >= 0 && value <= 32)
- && "Invalid negated immediate rotate 7-bit argument");
- O << -value;
- } else {
- llvm_unreachable("Invalid/non-immediate rotate amount in printRotateNeg7Imm");
- }
+ void printROTNeg7Imm(const MachineInstr *MI, unsigned OpNo, raw_ostream &O){
+ assert(MI->getOperand(OpNo).isImm() &&
+ "Invalid/non-immediate rotate amount in printRotateNeg7Imm");
+ int value = (int) MI->getOperand(OpNo).getImm();
+ assert((value >= 0 && value <= 32)
+ && "Invalid negated immediate rotate 7-bit argument");
+ O << -value;
}
};
} // end of anonymous namespace
@@ -274,7 +277,7 @@ namespace {
// Include the auto-generated portion of the assembly writer
#include "SPUGenAsmWriter.inc"
-void SPUAsmPrinter::printOp(const MachineOperand &MO) {
+void SPUAsmPrinter::printOp(const MachineOperand &MO, raw_ostream &O) {
switch (MO.getType()) {
case MachineOperand::MO_Immediate:
llvm_report_error("printOp() does not handle immediate values");
@@ -323,7 +326,7 @@ void SPUAsmPrinter::printOp(const MachineOperand &MO) {
///
bool SPUAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
unsigned AsmVariant,
- const char *ExtraCode) {
+ const char *ExtraCode, raw_ostream &O) {
// Does this asm operand have a single letter operand modifier?
if (ExtraCode && ExtraCode[0]) {
if (ExtraCode[1] != 0) return true; // Unknown modifier.
@@ -341,17 +344,17 @@ bool SPUAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
}
}
- printOperand(MI, OpNo);
+ printOperand(MI, OpNo, O);
return false;
}
bool SPUAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
- unsigned OpNo,
- unsigned AsmVariant,
- const char *ExtraCode) {
+ unsigned OpNo, unsigned AsmVariant,
+ const char *ExtraCode,
+ raw_ostream &O) {
if (ExtraCode && ExtraCode[0])
return true; // Unknown modifier.
- printMemRegReg(MI, OpNo);
+ printMemRegReg(MI, OpNo, O);
return false;
}
diff --git a/lib/Target/CellSPU/SPURegisterInfo.cpp b/lib/Target/CellSPU/SPURegisterInfo.cpp
index ad034eb..ffac581 100644
--- a/lib/Target/CellSPU/SPURegisterInfo.cpp
+++ b/lib/Target/CellSPU/SPURegisterInfo.cpp
@@ -451,11 +451,11 @@ void SPURegisterInfo::emitPrologue(MachineFunction &MF) const
MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB
MachineBasicBlock::iterator MBBI = MBB.begin();
MachineFrameInfo *MFI = MF.getFrameInfo();
- MachineModuleInfo *MMI = MFI->getMachineModuleInfo();
+ MachineModuleInfo &MMI = MF.getMMI();
DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
// Prepare for debug frame info.
- bool hasDebugInfo = MMI && MMI->hasDebugInfo();
+ bool hasDebugInfo = MMI.hasDebugInfo();
MCSymbol *FrameLabel = 0;
// Move MBBI back to the beginning of the function.
@@ -473,7 +473,7 @@ void SPURegisterInfo::emitPrologue(MachineFunction &MF) const
FrameSize = -(FrameSize + SPUFrameInfo::minStackSize());
if (hasDebugInfo) {
// Mark effective beginning of when frame pointer becomes valid.
- FrameLabel = MMI->getContext().CreateTempSymbol();
+ FrameLabel = MMI.getContext().CreateTempSymbol();
BuildMI(MBB, MBBI, dl, TII.get(SPU::DBG_LABEL)).addSym(FrameLabel);
}
@@ -516,7 +516,7 @@ void SPURegisterInfo::emitPrologue(MachineFunction &MF) const
}
if (hasDebugInfo) {
- std::vector<MachineMove> &Moves = MMI->getFrameMoves();
+ std::vector<MachineMove> &Moves = MMI.getFrameMoves();
// Show update of SP.
MachineLocation SPDst(MachineLocation::VirtualFP);
@@ -535,7 +535,7 @@ void SPURegisterInfo::emitPrologue(MachineFunction &MF) const
}
// Mark effective beginning of when frame pointer is ready.
- MCSymbol *ReadyLabel = MMI->getContext().CreateTempSymbol();
+ MCSymbol *ReadyLabel = MMI.getContext().CreateTempSymbol();
BuildMI(MBB, MBBI, dl, TII.get(SPU::DBG_LABEL)).addSym(ReadyLabel);
MachineLocation FPDst(SPU::R1);
@@ -552,7 +552,7 @@ void SPURegisterInfo::emitPrologue(MachineFunction &MF) const
// Insert terminator label
BuildMI(MBB, MBBI, dl, TII.get(SPU::DBG_LABEL))
- .addSym(MMI->getContext().CreateTempSymbol());
+ .addSym(MMI.getContext().CreateTempSymbol());
}
}
}
diff --git a/lib/Target/MBlaze/AsmPrinter/MBlazeAsmPrinter.cpp b/lib/Target/MBlaze/AsmPrinter/MBlazeAsmPrinter.cpp
index ee2c7c8..b1df926 100644
--- a/lib/Target/MBlaze/AsmPrinter/MBlazeAsmPrinter.cpp
+++ b/lib/Target/MBlaze/AsmPrinter/MBlazeAsmPrinter.cpp
@@ -23,7 +23,6 @@
#include "llvm/DerivedTypes.h"
#include "llvm/Module.h"
#include "llvm/CodeGen/AsmPrinter.h"
-#include "llvm/CodeGen/DwarfWriter.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
@@ -37,13 +36,10 @@
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Target/TargetRegistry.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/FormattedStream.h"
-#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/raw_ostream.h"
#include <cctype>
using namespace llvm;
@@ -52,9 +48,8 @@ namespace {
class MBlazeAsmPrinter : public AsmPrinter {
const MBlazeSubtarget *Subtarget;
public:
- explicit MBlazeAsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
- MCStreamer &Streamer)
- : AsmPrinter(O, TM, Streamer) {
+ explicit MBlazeAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
+ : AsmPrinter(TM, Streamer) {
Subtarget = &TM.getSubtarget<MBlazeSubtarget>();
}
@@ -63,31 +58,32 @@ namespace {
}
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
- unsigned AsmVariant, const char *ExtraCode);
- void printOperand(const MachineInstr *MI, int opNum);
- void printUnsignedImm(const MachineInstr *MI, int opNum);
- void printFSLImm(const MachineInstr *MI, int opNum);
- void printMemOperand(const MachineInstr *MI, int opNum,
+ unsigned AsmVariant, const char *ExtraCode,
+ raw_ostream &O);
+ void printOperand(const MachineInstr *MI, int opNum, raw_ostream &O);
+ void printUnsignedImm(const MachineInstr *MI, int opNum, raw_ostream &O);
+ void printFSLImm(const MachineInstr *MI, int opNum, raw_ostream &O);
+ void printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O,
const char *Modifier = 0);
- void printFCCOperand(const MachineInstr *MI, int opNum,
+ void printFCCOperand(const MachineInstr *MI, int opNum, raw_ostream &O,
const char *Modifier = 0);
- void printSavedRegsBitmask();
- void printHex32(unsigned int Value);
+ void printSavedRegsBitmask(raw_ostream &OS);
const char *emitCurrentABIString();
void emitFrameDirective();
- void printInstruction(const MachineInstr *MI); // autogenerated.
+ void printInstruction(const MachineInstr *MI, raw_ostream &O);
void EmitInstruction(const MachineInstr *MI) {
- printInstruction(MI);
- O << '\n';
+ SmallString<128> Str;
+ raw_svector_ostream OS(Str);
+ printInstruction(MI, OS);
+ OutStreamer.EmitRawText(OS.str());
}
virtual void EmitFunctionBodyStart();
virtual void EmitFunctionBodyEnd();
static const char *getRegisterName(unsigned RegNo);
virtual void EmitFunctionEntryLabel();
- void EmitStartOfAsmFile(Module &M);
};
} // end of anonymous namespace
@@ -128,9 +124,17 @@ namespace {
// Mask directives
//===----------------------------------------------------------------------===//
+// Print a 32 bit hex number with all numbers.
+static void printHex32(unsigned int Value, raw_ostream &O) {
+ O << "0x";
+ for (int i = 7; i >= 0; i--)
+ O << utohexstr((Value & (0xF << (i*4))) >> (i*4));
+}
+
+
// Create a bitmask with all callee saved registers for CPU or Floating Point
// registers. For CPU registers consider RA, GP and FP for saving if necessary.
-void MBlazeAsmPrinter::printSavedRegsBitmask() {
+void MBlazeAsmPrinter::printSavedRegsBitmask(raw_ostream &O) {
const TargetRegisterInfo &RI = *TM.getRegisterInfo();
const MBlazeFunctionInfo *MBlazeFI = MF->getInfo<MBlazeFunctionInfo>();
@@ -156,15 +160,8 @@ void MBlazeAsmPrinter::printSavedRegsBitmask() {
getRegisterNumbering(RI.getRARegister()));
// Print CPUBitmask
- O << "\t.mask \t"; printHex32(CPUBitmask); O << ','
- << MBlazeFI->getCPUTopSavedRegOff() << '\n';
-}
-
-// Print a 32 bit hex number with all numbers.
-void MBlazeAsmPrinter::printHex32(unsigned int Value) {
- O << "0x";
- for (int i = 7; i >= 0; i--)
- O << utohexstr( (Value & (0xF << (i*4))) >> (i*4) );
+ O << "\t.mask \t"; printHex32(CPUBitmask, O);
+ O << ',' << MBlazeFI->getCPUTopSavedRegOff() << '\n';
}
//===----------------------------------------------------------------------===//
@@ -180,122 +177,127 @@ void MBlazeAsmPrinter::emitFrameDirective() {
unsigned stackSize = MF->getFrameInfo()->getStackSize();
- O << "\t.frame\t" << getRegisterName(stackReg)
- << ',' << stackSize << ','
- << getRegisterName(returnReg)
- << '\n';
+ OutStreamer.EmitRawText("\t.frame\t" + Twine(getRegisterName(stackReg)) +
+ "," + Twine(stackSize) + "," +
+ Twine(getRegisterName(returnReg)));
}
void MBlazeAsmPrinter::EmitFunctionEntryLabel() {
- O << "\t.ent\t" << *CurrentFnSym << '\n';
- OutStreamer.EmitLabel(CurrentFnSym);
+ OutStreamer.EmitRawText("\t.ent\t" + Twine(CurrentFnSym->getName()));
+ OutStreamer.EmitLabel(CurrentFnSym);
}
/// EmitFunctionBodyStart - Targets can override this to emit stuff before
/// the first basic block in the function.
void MBlazeAsmPrinter::EmitFunctionBodyStart() {
emitFrameDirective();
- printSavedRegsBitmask();
+
+ SmallString<128> Str;
+ raw_svector_ostream OS(Str);
+ printSavedRegsBitmask(OS);
+ OutStreamer.EmitRawText(OS.str());
}
/// EmitFunctionBodyEnd - Targets can override this to emit stuff after
/// the last basic block in the function.
void MBlazeAsmPrinter::EmitFunctionBodyEnd() {
- O << "\t.end\t" << *CurrentFnSym << '\n';
+ OutStreamer.EmitRawText("\t.end\t" + Twine(CurrentFnSym->getName()));
}
// Print out an operand for an inline asm expression.
bool MBlazeAsmPrinter::
PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
- unsigned AsmVariant,const char *ExtraCode){
+ unsigned AsmVariant,const char *ExtraCode, raw_ostream &O) {
// Does this asm operand have a single letter operand modifier?
if (ExtraCode && ExtraCode[0])
return true; // Unknown modifier.
- printOperand(MI, OpNo);
+ printOperand(MI, OpNo, O);
return false;
}
-void MBlazeAsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
+void MBlazeAsmPrinter::printOperand(const MachineInstr *MI, int opNum,
+ raw_ostream &O) {
const MachineOperand &MO = MI->getOperand(opNum);
switch (MO.getType()) {
- case MachineOperand::MO_Register:
- O << getRegisterName(MO.getReg());
- break;
-
- case MachineOperand::MO_Immediate:
- O << (int)MO.getImm();
- break;
-
- case MachineOperand::MO_FPImmediate: {
- const ConstantFP* fp = MO.getFPImm();
- printHex32(fp->getValueAPF().bitcastToAPInt().getZExtValue());
- O << ";\t# immediate = " << *fp;
- break;
- }
-
- case MachineOperand::MO_MachineBasicBlock:
- O << *MO.getMBB()->getSymbol();
- return;
-
- case MachineOperand::MO_GlobalAddress:
- O << *Mang->getSymbol(MO.getGlobal());
- break;
-
- case MachineOperand::MO_ExternalSymbol:
- O << *GetExternalSymbolSymbol(MO.getSymbolName());
- break;
-
- case MachineOperand::MO_JumpTableIndex:
- O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
- << '_' << MO.getIndex();
- break;
-
- case MachineOperand::MO_ConstantPoolIndex:
- O << MAI->getPrivateGlobalPrefix() << "CPI"
- << getFunctionNumber() << "_" << MO.getIndex();
- if (MO.getOffset())
- O << "+" << MO.getOffset();
- break;
-
- default:
- llvm_unreachable("<unknown operand type>");
+ case MachineOperand::MO_Register:
+ O << getRegisterName(MO.getReg());
+ break;
+
+ case MachineOperand::MO_Immediate:
+ O << (int)MO.getImm();
+ break;
+
+ case MachineOperand::MO_FPImmediate: {
+ const ConstantFP *fp = MO.getFPImm();
+ printHex32(fp->getValueAPF().bitcastToAPInt().getZExtValue(), O);
+ O << ";\t# immediate = " << *fp;
+ break;
+ }
+
+ case MachineOperand::MO_MachineBasicBlock:
+ O << *MO.getMBB()->getSymbol();
+ return;
+
+ case MachineOperand::MO_GlobalAddress:
+ O << *Mang->getSymbol(MO.getGlobal());
+ break;
+
+ case MachineOperand::MO_ExternalSymbol:
+ O << *GetExternalSymbolSymbol(MO.getSymbolName());
+ break;
+
+ case MachineOperand::MO_JumpTableIndex:
+ O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
+ << '_' << MO.getIndex();
+ break;
+
+ case MachineOperand::MO_ConstantPoolIndex:
+ O << MAI->getPrivateGlobalPrefix() << "CPI"
+ << getFunctionNumber() << "_" << MO.getIndex();
+ if (MO.getOffset())
+ O << "+" << MO.getOffset();
+ break;
+
+ default:
+ llvm_unreachable("<unknown operand type>");
}
}
-void MBlazeAsmPrinter::printUnsignedImm(const MachineInstr *MI, int opNum) {
+void MBlazeAsmPrinter::printUnsignedImm(const MachineInstr *MI, int opNum,
+ raw_ostream &O) {
const MachineOperand &MO = MI->getOperand(opNum);
if (MO.getType() == MachineOperand::MO_Immediate)
O << (unsigned int)MO.getImm();
else
- printOperand(MI, opNum);
+ printOperand(MI, opNum, O);
}
-void MBlazeAsmPrinter::printFSLImm(const MachineInstr *MI, int opNum) {
+void MBlazeAsmPrinter::printFSLImm(const MachineInstr *MI, int opNum,
+ raw_ostream &O) {
const MachineOperand &MO = MI->getOperand(opNum);
if (MO.getType() == MachineOperand::MO_Immediate)
O << "rfsl" << (unsigned int)MO.getImm();
else
- printOperand(MI, opNum);
+ printOperand(MI, opNum, O);
}
void MBlazeAsmPrinter::
-printMemOperand(const MachineInstr *MI, int opNum, const char *Modifier) {
- printOperand(MI, opNum+1);
+printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O,
+ const char *Modifier) {
+ printOperand(MI, opNum+1, O);
O << ", ";
- printOperand(MI, opNum);
+ printOperand(MI, opNum, O);
}
void MBlazeAsmPrinter::
-printFCCOperand(const MachineInstr *MI, int opNum, const char *Modifier) {
+printFCCOperand(const MachineInstr *MI, int opNum, raw_ostream &O,
+ const char *Modifier) {
const MachineOperand& MO = MI->getOperand(opNum);
O << MBlaze::MBlazeFCCToString((MBlaze::CondCode)MO.getImm());
}
-void MBlazeAsmPrinter::EmitStartOfAsmFile(Module &M) {
-}
-
// Force static initialization.
extern "C" void LLVMInitializeMBlazeAsmPrinter() {
RegisterAsmPrinter<MBlazeAsmPrinter> X(TheMBlazeTarget);
diff --git a/lib/Target/MBlaze/MBlaze.td b/lib/Target/MBlaze/MBlaze.td
index 1679752..482ddd3 100644
--- a/lib/Target/MBlaze/MBlaze.td
+++ b/lib/Target/MBlaze/MBlaze.td
@@ -25,11 +25,7 @@ include "MBlazeIntrinsics.td"
include "MBlazeInstrInfo.td"
include "MBlazeCallingConv.td"
-def MBlazeInstrInfo : InstrInfo {
- let TSFlagsFields = [];
- let TSFlagsShifts = [];
-}
-
+def MBlazeInstrInfo : InstrInfo;
//===----------------------------------------------------------------------===//
// Microblaze Subtarget features //
diff --git a/lib/Target/MSP430/AsmPrinter/MSP430AsmPrinter.cpp b/lib/Target/MSP430/AsmPrinter/MSP430AsmPrinter.cpp
index 04ac6f1..56f72bb 100644
--- a/lib/Target/MSP430/AsmPrinter/MSP430AsmPrinter.cpp
+++ b/lib/Target/MSP430/AsmPrinter/MSP430AsmPrinter.cpp
@@ -24,7 +24,6 @@
#include "llvm/Module.h"
#include "llvm/Assembly/Writer.h"
#include "llvm/CodeGen/AsmPrinter.h"
-#include "llvm/CodeGen/DwarfWriter.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineConstantPool.h"
@@ -36,50 +35,36 @@
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetRegistry.h"
-#include "llvm/Support/FormattedStream.h"
+#include "llvm/Support/raw_ostream.h"
using namespace llvm;
namespace {
class MSP430AsmPrinter : public AsmPrinter {
public:
- MSP430AsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
- MCStreamer &Streamer)
- : AsmPrinter(O, TM, Streamer) {}
+ MSP430AsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
+ : AsmPrinter(TM, Streamer) {}
virtual const char *getPassName() const {
return "MSP430 Assembly Printer";
}
- void printMCInst(const MCInst *MI) {
- MSP430InstPrinter(O, *MAI).printInstruction(MI);
- }
void printOperand(const MachineInstr *MI, int OpNum,
- const char* Modifier = 0);
- void printPCRelImmOperand(const MachineInstr *MI, int OpNum) {
- printOperand(MI, OpNum);
- }
+ raw_ostream &O, const char* Modifier = 0);
void printSrcMemOperand(const MachineInstr *MI, int OpNum,
- const char* Modifier = 0);
- void printCCOperand(const MachineInstr *MI, int OpNum);
- void printMachineInstruction(const MachineInstr * MI);
+ raw_ostream &O);
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
- unsigned AsmVariant,
- const char *ExtraCode);
+ unsigned AsmVariant, const char *ExtraCode,
+ raw_ostream &O);
bool PrintAsmMemoryOperand(const MachineInstr *MI,
unsigned OpNo, unsigned AsmVariant,
- const char *ExtraCode);
+ const char *ExtraCode, raw_ostream &O);
void EmitInstruction(const MachineInstr *MI);
-
- void getAnalysisUsage(AnalysisUsage &AU) const {
- AsmPrinter::getAnalysisUsage(AU);
- AU.setPreservesAll();
- }
};
} // end of anonymous namespace
void MSP430AsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
- const char* Modifier) {
+ raw_ostream &O, const char *Modifier) {
const MachineOperand &MO = MI->getOperand(OpNum);
switch (MO.getType()) {
default: assert(0 && "Not implemented yet!");
@@ -126,7 +111,7 @@ void MSP430AsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
}
void MSP430AsmPrinter::printSrcMemOperand(const MachineInstr *MI, int OpNum,
- const char* Modifier) {
+ raw_ostream &O) {
const MachineOperand &Base = MI->getOperand(OpNum);
const MachineOperand &Disp = MI->getOperand(OpNum+1);
@@ -135,48 +120,37 @@ void MSP430AsmPrinter::printSrcMemOperand(const MachineInstr *MI, int OpNum,
// Imm here is in fact global address - print extra modifier.
if (Disp.isImm() && !Base.getReg())
O << '&';
- printOperand(MI, OpNum+1, "nohash");
+ printOperand(MI, OpNum+1, O, "nohash");
// Print register base field
if (Base.getReg()) {
O << '(';
- printOperand(MI, OpNum);
+ printOperand(MI, OpNum, O);
O << ')';
}
}
-void MSP430AsmPrinter::printCCOperand(const MachineInstr *MI, int OpNum) {
- switch (MI->getOperand(OpNum).getImm()) {
- default: assert(0 && "Unknown cond");
- case MSP430CC::COND_E: O << "eq"; break;
- case MSP430CC::COND_NE: O << "ne"; break;
- case MSP430CC::COND_HS: O << "hs"; break;
- case MSP430CC::COND_LO: O << "lo"; break;
- case MSP430CC::COND_GE: O << "ge"; break;
- case MSP430CC::COND_L: O << 'l'; break;
- }
-}
-
/// PrintAsmOperand - Print out an operand for an inline asm expression.
///
bool MSP430AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
unsigned AsmVariant,
- const char *ExtraCode) {
+ const char *ExtraCode, raw_ostream &O) {
// Does this asm operand have a single letter operand modifier?
if (ExtraCode && ExtraCode[0])
return true; // Unknown modifier.
- printOperand(MI, OpNo);
+ printOperand(MI, OpNo, O);
return false;
}
bool MSP430AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
unsigned OpNo, unsigned AsmVariant,
- const char *ExtraCode) {
+ const char *ExtraCode,
+ raw_ostream &O) {
if (ExtraCode && ExtraCode[0]) {
return true; // Unknown modifier.
}
- printSrcMemOperand(MI, OpNo);
+ printSrcMemOperand(MI, OpNo, O);
return false;
}
@@ -191,10 +165,9 @@ void MSP430AsmPrinter::EmitInstruction(const MachineInstr *MI) {
static MCInstPrinter *createMSP430MCInstPrinter(const Target &T,
unsigned SyntaxVariant,
- const MCAsmInfo &MAI,
- raw_ostream &O) {
+ const MCAsmInfo &MAI) {
if (SyntaxVariant == 0)
- return new MSP430InstPrinter(O, MAI);
+ return new MSP430InstPrinter(MAI);
return 0;
}
diff --git a/lib/Target/MSP430/AsmPrinter/MSP430InstPrinter.cpp b/lib/Target/MSP430/AsmPrinter/MSP430InstPrinter.cpp
index d7636e6..c15d408 100644
--- a/lib/Target/MSP430/AsmPrinter/MSP430InstPrinter.cpp
+++ b/lib/Target/MSP430/AsmPrinter/MSP430InstPrinter.cpp
@@ -28,11 +28,12 @@ using namespace llvm;
#include "MSP430GenAsmWriter.inc"
#undef MachineInstr
-void MSP430InstPrinter::printInst(const MCInst *MI) {
- printInstruction(MI);
+void MSP430InstPrinter::printInst(const MCInst *MI, raw_ostream &O) {
+ printInstruction(MI, O);
}
-void MSP430InstPrinter::printPCRelImmOperand(const MCInst *MI, unsigned OpNo) {
+void MSP430InstPrinter::printPCRelImmOperand(const MCInst *MI, unsigned OpNo,
+ raw_ostream &O) {
const MCOperand &Op = MI->getOperand(OpNo);
if (Op.isImm())
O << Op.getImm();
@@ -43,7 +44,7 @@ void MSP430InstPrinter::printPCRelImmOperand(const MCInst *MI, unsigned OpNo) {
}
void MSP430InstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
- const char *Modifier) {
+ raw_ostream &O, const char *Modifier) {
assert((Modifier == 0 || Modifier[0] == 0) && "No modifiers supported");
const MCOperand &Op = MI->getOperand(OpNo);
if (Op.isReg()) {
@@ -57,6 +58,7 @@ void MSP430InstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
}
void MSP430InstPrinter::printSrcMemOperand(const MCInst *MI, unsigned OpNo,
+ raw_ostream &O,
const char *Modifier) {
const MCOperand &Base = MI->getOperand(OpNo);
const MCOperand &Disp = MI->getOperand(OpNo+1);
@@ -84,7 +86,8 @@ void MSP430InstPrinter::printSrcMemOperand(const MCInst *MI, unsigned OpNo,
O << '(' << getRegisterName(Base.getReg()) << ')';
}
-void MSP430InstPrinter::printCCOperand(const MCInst *MI, unsigned OpNo) {
+void MSP430InstPrinter::printCCOperand(const MCInst *MI, unsigned OpNo,
+ raw_ostream &O) {
unsigned CC = MI->getOperand(OpNo).getImm();
switch (CC) {
diff --git a/lib/Target/MSP430/AsmPrinter/MSP430InstPrinter.h b/lib/Target/MSP430/AsmPrinter/MSP430InstPrinter.h
index 2fac800..f0e1ce2 100644
--- a/lib/Target/MSP430/AsmPrinter/MSP430InstPrinter.h
+++ b/lib/Target/MSP430/AsmPrinter/MSP430InstPrinter.h
@@ -16,29 +16,26 @@
#include "llvm/MC/MCInstPrinter.h"
-namespace llvm
-{
-
+namespace llvm {
class MCOperand;
class MSP430InstPrinter : public MCInstPrinter {
public:
- MSP430InstPrinter(raw_ostream &O, const MCAsmInfo &MAI) :
- MCInstPrinter(O, MAI){
+ MSP430InstPrinter(const MCAsmInfo &MAI) : MCInstPrinter(MAI) {
}
- virtual void printInst(const MCInst *MI);
+ virtual void printInst(const MCInst *MI, raw_ostream &O);
// Autogenerated by tblgen.
- void printInstruction(const MCInst *MI);
+ void printInstruction(const MCInst *MI, raw_ostream &O);
static const char *getRegisterName(unsigned RegNo);
- void printOperand(const MCInst *MI, unsigned OpNo,
+ void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O,
const char *Modifier = 0);
- void printPCRelImmOperand(const MCInst *MI, unsigned OpNo);
- void printSrcMemOperand(const MCInst *MI, unsigned OpNo,
+ void printPCRelImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
+ void printSrcMemOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O,
const char *Modifier = 0);
- void printCCOperand(const MCInst *MI, unsigned OpNo);
+ void printCCOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
};
}
diff --git a/lib/Target/MSP430/MSP430.td b/lib/Target/MSP430/MSP430.td
index fe533d3..0f08e3d 100644
--- a/lib/Target/MSP430/MSP430.td
+++ b/lib/Target/MSP430/MSP430.td
@@ -48,14 +48,7 @@ include "MSP430CallingConv.td"
include "MSP430InstrInfo.td"
-def MSP430InstrInfo : InstrInfo {
- // Define how we want to layout our TargetSpecific information field... This
- // should be kept up-to-date with the fields in the MSP430InstrInfo.h file.
- let TSFlagsFields = ["FormBits",
- "Size"];
- let TSFlagsShifts = [0,
- 2];
-}
+def MSP430InstrInfo : InstrInfo;
def MSP430InstPrinter : AsmWriter {
string AsmWriterClassName = "InstPrinter";
diff --git a/lib/Target/MSP430/MSP430InstrFormats.td b/lib/Target/MSP430/MSP430InstrFormats.td
index 4ccc7df..73aef1f 100644
--- a/lib/Target/MSP430/MSP430InstrFormats.td
+++ b/lib/Target/MSP430/MSP430InstrFormats.td
@@ -61,10 +61,12 @@ class MSP430Inst<dag outs, dag ins, SizeVal sz, Format f,
dag InOperandList = ins;
Format Form = f;
- bits<2> FormBits = Form.Value;
-
SizeVal Sz = sz;
- bits<3> Size = Sz.Value;
+
+ // Define how we want to layout our TargetSpecific information field... This
+ // should be kept up-to-date with the fields in the MSP430InstrInfo.h file.
+ let TSFlags{1-0} = Form.Value;
+ let TSFlags{4-2} = Sz.Value;
let AsmString = asmstr;
}
diff --git a/lib/Target/Mips/AsmPrinter/MipsAsmPrinter.cpp b/lib/Target/Mips/AsmPrinter/MipsAsmPrinter.cpp
index 2a2d9dc..6974371 100644
--- a/lib/Target/Mips/AsmPrinter/MipsAsmPrinter.cpp
+++ b/lib/Target/Mips/AsmPrinter/MipsAsmPrinter.cpp
@@ -13,17 +13,12 @@
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "mips-asm-printer"
-
#include "Mips.h"
#include "MipsSubtarget.h"
#include "MipsInstrInfo.h"
#include "MipsTargetMachine.h"
#include "MipsMachineFunction.h"
-#include "llvm/Constants.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/Module.h"
#include "llvm/CodeGen/AsmPrinter.h"
-#include "llvm/CodeGen/DwarfWriter.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
@@ -37,22 +32,18 @@
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Target/TargetRegistry.h"
-#include "llvm/Support/ErrorHandling.h"
+#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/FormattedStream.h"
-#include "llvm/Support/MathExtras.h"
-#include <cctype>
+#include "llvm/ADT/Twine.h"
+#include "llvm/Support/raw_ostream.h"
using namespace llvm;
namespace {
class MipsAsmPrinter : public AsmPrinter {
const MipsSubtarget *Subtarget;
public:
- explicit MipsAsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
- MCStreamer &Streamer)
- : AsmPrinter(O, TM, Streamer) {
+ explicit MipsAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
+ : AsmPrinter(TM, Streamer) {
Subtarget = &TM.getSubtarget<MipsSubtarget>();
}
@@ -61,23 +52,26 @@ namespace {
}
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
- unsigned AsmVariant, const char *ExtraCode);
- void printOperand(const MachineInstr *MI, int opNum);
- void printUnsignedImm(const MachineInstr *MI, int opNum);
- void printMemOperand(const MachineInstr *MI, int opNum,
+ unsigned AsmVariant, const char *ExtraCode,
+ raw_ostream &O);
+ void printOperand(const MachineInstr *MI, int opNum, raw_ostream &O);
+ void printUnsignedImm(const MachineInstr *MI, int opNum, raw_ostream &O);
+ void printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O,
const char *Modifier = 0);
- void printFCCOperand(const MachineInstr *MI, int opNum,
+ void printFCCOperand(const MachineInstr *MI, int opNum, raw_ostream &O,
const char *Modifier = 0);
- void printSavedRegsBitmask();
- void printHex32(unsigned int Value);
+ void printSavedRegsBitmask(raw_ostream &O);
+ void printHex32(unsigned int Value, raw_ostream &O);
- const char *emitCurrentABIString();
+ const char *getCurrentABIString() const;
void emitFrameDirective();
- void printInstruction(const MachineInstr *MI); // autogenerated.
+ void printInstruction(const MachineInstr *MI, raw_ostream &O); // autogen'd.
void EmitInstruction(const MachineInstr *MI) {
- printInstruction(MI);
- OutStreamer.AddBlankLine();
+ SmallString<128> Str;
+ raw_svector_ostream OS(Str);
+ printInstruction(MI, OS);
+ OutStreamer.EmitRawText(OS.str());
}
virtual void EmitFunctionBodyStart();
virtual void EmitFunctionBodyEnd();
@@ -127,7 +121,7 @@ namespace {
// Create a bitmask with all callee saved registers for CPU or Floating Point
// registers. For CPU registers consider RA, GP and FP for saving if necessary.
-void MipsAsmPrinter::printSavedRegsBitmask() {
+void MipsAsmPrinter::printSavedRegsBitmask(raw_ostream &O) {
const TargetRegisterInfo &RI = *TM.getRegisterInfo();
const MipsFunctionInfo *MipsFI = MF->getInfo<MipsFunctionInfo>();
@@ -156,21 +150,19 @@ void MipsAsmPrinter::printSavedRegsBitmask() {
getRegisterNumbering(RI.getRARegister()));
// Print CPUBitmask
- O << "\t.mask \t"; printHex32(CPUBitmask); O << ','
- << MipsFI->getCPUTopSavedRegOff() << '\n';
+ O << "\t.mask \t"; printHex32(CPUBitmask, O);
+ O << ',' << MipsFI->getCPUTopSavedRegOff() << '\n';
// Print FPUBitmask
- O << "\t.fmask\t"; printHex32(FPUBitmask); O << ","
+ O << "\t.fmask\t"; printHex32(FPUBitmask, O); O << ","
<< MipsFI->getFPUTopSavedRegOff() << '\n';
}
// Print a 32 bit hex number with all numbers.
-void MipsAsmPrinter::
-printHex32(unsigned int Value)
-{
+void MipsAsmPrinter::printHex32(unsigned Value, raw_ostream &O) {
O << "0x";
for (int i = 7; i >= 0; i--)
- O << utohexstr( (Value & (0xF << (i*4))) >> (i*4) );
+ O << utohexstr((Value & (0xF << (i*4))) >> (i*4));
}
//===----------------------------------------------------------------------===//
@@ -185,22 +177,21 @@ void MipsAsmPrinter::emitFrameDirective() {
unsigned returnReg = RI.getRARegister();
unsigned stackSize = MF->getFrameInfo()->getStackSize();
-
- O << "\t.frame\t" << '$' << LowercaseString(getRegisterName(stackReg))
- << ',' << stackSize << ','
- << '$' << LowercaseString(getRegisterName(returnReg))
- << '\n';
+ OutStreamer.EmitRawText("\t.frame\t$" +
+ Twine(LowercaseString(getRegisterName(stackReg))) +
+ "," + Twine(stackSize) + ",$" +
+ Twine(LowercaseString(getRegisterName(returnReg))));
}
/// Emit Set directives.
-const char *MipsAsmPrinter::emitCurrentABIString() {
- switch(Subtarget->getTargetABI()) {
- case MipsSubtarget::O32: return "abi32";
- case MipsSubtarget::O64: return "abiO64";
- case MipsSubtarget::N32: return "abiN32";
- case MipsSubtarget::N64: return "abi64";
- case MipsSubtarget::EABI: return "eabi32"; // TODO: handle eabi64
- default: break;
+const char *MipsAsmPrinter::getCurrentABIString() const {
+ switch (Subtarget->getTargetABI()) {
+ case MipsSubtarget::O32: return "abi32";
+ case MipsSubtarget::O64: return "abiO64";
+ case MipsSubtarget::N32: return "abiN32";
+ case MipsSubtarget::N64: return "abi64";
+ case MipsSubtarget::EABI: return "eabi32"; // TODO: handle eabi64
+ default: break;
}
llvm_unreachable("Unknown Mips ABI");
@@ -208,7 +199,7 @@ const char *MipsAsmPrinter::emitCurrentABIString() {
}
void MipsAsmPrinter::EmitFunctionEntryLabel() {
- O << "\t.ent\t" << *CurrentFnSym << '\n';
+ OutStreamer.EmitRawText("\t.ent\t" + Twine(CurrentFnSym->getName()));
OutStreamer.EmitLabel(CurrentFnSym);
}
@@ -216,7 +207,11 @@ void MipsAsmPrinter::EmitFunctionEntryLabel() {
/// the first basic block in the function.
void MipsAsmPrinter::EmitFunctionBodyStart() {
emitFrameDirective();
- printSavedRegsBitmask();
+
+ SmallString<128> Str;
+ raw_svector_ostream OS(Str);
+ printSavedRegsBitmask(OS);
+ OutStreamer.EmitRawText(OS.str());
}
/// EmitFunctionBodyEnd - Targets can override this to emit stuff after
@@ -225,25 +220,26 @@ void MipsAsmPrinter::EmitFunctionBodyEnd() {
// There are instruction for this macros, but they must
// always be at the function end, and we can't emit and
// break with BB logic.
- O << "\t.set\tmacro\n";
- O << "\t.set\treorder\n";
-
- O << "\t.end\t" << *CurrentFnSym << '\n';
+ OutStreamer.EmitRawText(StringRef("\t.set\tmacro"));
+ OutStreamer.EmitRawText(StringRef("\t.set\treorder"));
+ OutStreamer.EmitRawText("\t.end\t" + Twine(CurrentFnSym->getName()));
}
// Print out an operand for an inline asm expression.
bool MipsAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
- unsigned AsmVariant,const char *ExtraCode){
+ unsigned AsmVariant,const char *ExtraCode,
+ raw_ostream &O) {
// Does this asm operand have a single letter operand modifier?
if (ExtraCode && ExtraCode[0])
return true; // Unknown modifier.
- printOperand(MI, OpNo);
+ printOperand(MI, OpNo, O);
return false;
}
-void MipsAsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
+void MipsAsmPrinter::printOperand(const MachineInstr *MI, int opNum,
+ raw_ostream &O) {
const MachineOperand &MO = MI->getOperand(opNum);
bool closeP = false;
@@ -307,36 +303,39 @@ void MipsAsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
if (closeP) O << ")";
}
-void MipsAsmPrinter::printUnsignedImm(const MachineInstr *MI, int opNum) {
+void MipsAsmPrinter::printUnsignedImm(const MachineInstr *MI, int opNum,
+ raw_ostream &O) {
const MachineOperand &MO = MI->getOperand(opNum);
if (MO.getType() == MachineOperand::MO_Immediate)
O << (unsigned short int)MO.getImm();
else
- printOperand(MI, opNum);
+ printOperand(MI, opNum, O);
}
void MipsAsmPrinter::
-printMemOperand(const MachineInstr *MI, int opNum, const char *Modifier) {
+printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O,
+ const char *Modifier) {
// when using stack locations for not load/store instructions
// print the same way as all normal 3 operand instructions.
if (Modifier && !strcmp(Modifier, "stackloc")) {
- printOperand(MI, opNum+1);
+ printOperand(MI, opNum+1, O);
O << ", ";
- printOperand(MI, opNum);
+ printOperand(MI, opNum, O);
return;
}
// Load/Store memory operands -- imm($reg)
// If PIC target the target is loaded as the
// pattern lw $25,%call16($28)
- printOperand(MI, opNum);
+ printOperand(MI, opNum, O);
O << "(";
- printOperand(MI, opNum+1);
+ printOperand(MI, opNum+1, O);
O << ")";
}
void MipsAsmPrinter::
-printFCCOperand(const MachineInstr *MI, int opNum, const char *Modifier) {
+printFCCOperand(const MachineInstr *MI, int opNum, raw_ostream &O,
+ const char *Modifier) {
const MachineOperand& MO = MI->getOperand(opNum);
O << Mips::MipsFCCToString((Mips::CondCode)MO.getImm());
}
@@ -345,15 +344,18 @@ void MipsAsmPrinter::EmitStartOfAsmFile(Module &M) {
// FIXME: Use SwitchSection.
// Tell the assembler which ABI we are using
- O << "\t.section .mdebug." << emitCurrentABIString() << '\n';
+ OutStreamer.EmitRawText("\t.section .mdebug." + Twine(getCurrentABIString()));
// TODO: handle O64 ABI
- if (Subtarget->isABI_EABI())
- O << "\t.section .gcc_compiled_long" <<
- (Subtarget->isGP32bit() ? "32" : "64") << '\n';
+ if (Subtarget->isABI_EABI()) {
+ if (Subtarget->isGP32bit())
+ OutStreamer.EmitRawText(StringRef("\t.section .gcc_compiled_long32"));
+ else
+ OutStreamer.EmitRawText(StringRef("\t.section .gcc_compiled_long64"));
+ }
// return to previous section
- O << "\t.previous" << '\n';
+ OutStreamer.EmitRawText(StringRef("\t.previous"));
}
// Force static initialization.
diff --git a/lib/Target/Mips/Mips.td b/lib/Target/Mips/Mips.td
index 79a78d8..aa036ae 100644
--- a/lib/Target/Mips/Mips.td
+++ b/lib/Target/Mips/Mips.td
@@ -24,10 +24,7 @@ include "MipsSchedule.td"
include "MipsInstrInfo.td"
include "MipsCallingConv.td"
-def MipsInstrInfo : InstrInfo {
- let TSFlagsFields = [];
- let TSFlagsShifts = [];
-}
+def MipsInstrInfo : InstrInfo;
//===----------------------------------------------------------------------===//
// Mips Subtarget features //
diff --git a/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.cpp b/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.cpp
index 1001d29..c46db46 100644
--- a/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.cpp
+++ b/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.cpp
@@ -19,9 +19,7 @@
#include "llvm/DerivedTypes.h"
#include "llvm/Function.h"
#include "llvm/Module.h"
-#include "llvm/CodeGen/DwarfWriter.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
-#include "llvm/CodeGen/DwarfWriter.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
@@ -29,23 +27,26 @@
#include "llvm/Target/TargetRegistry.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/FormattedStream.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/ADT/SmallString.h"
#include <cstring>
using namespace llvm;
#include "PIC16GenAsmWriter.inc"
-PIC16AsmPrinter::PIC16AsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
- MCStreamer &Streamer)
-: AsmPrinter(O, TM, Streamer), DbgInfo(O, TM.getMCAsmInfo()) {
+PIC16AsmPrinter::PIC16AsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
+: AsmPrinter(TM, Streamer), DbgInfo(Streamer, TM.getMCAsmInfo()) {
PTLI = static_cast<PIC16TargetLowering*>(TM.getTargetLowering());
PMAI = static_cast<const PIC16MCAsmInfo*>(TM.getMCAsmInfo());
PTOF = (PIC16TargetObjectFile *)&PTLI->getObjFileLowering();
}
void PIC16AsmPrinter::EmitInstruction(const MachineInstr *MI) {
- printInstruction(MI);
- OutStreamer.AddBlankLine();
+ SmallString<128> Str;
+ raw_svector_ostream OS(Str);
+ printInstruction(MI, OS);
+
+ OutStreamer.EmitRawText(OS.str());
}
static int getFunctionColor(const Function *F) {
@@ -111,33 +112,33 @@ bool PIC16AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
PAN::isISR(F->getSection()));
// Start the Code Section.
- O << "\n";
OutStreamer.SwitchSection(fCodeSection);
// Emit the frame address of the function at the beginning of code.
- O << "\tretlw low(" << PAN::getFrameLabel(CurrentFnSym->getName()) << ")\n";
- O << "\tretlw high(" << PAN::getFrameLabel(CurrentFnSym->getName()) << ")\n";
+ OutStreamer.EmitRawText("\tretlw low(" +
+ Twine(PAN::getFrameLabel(CurrentFnSym->getName())) +
+ ")");
+ OutStreamer.EmitRawText("\tretlw high(" +
+ Twine(PAN::getFrameLabel(CurrentFnSym->getName())) +
+ ")");
// Emit function start label.
- O << *CurrentFnSym << ":\n";
+ OutStreamer.EmitLabel(CurrentFnSym);
DebugLoc CurDL;
- O << "\n";
// Print out code for the function.
for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
I != E; ++I) {
// Print a label for the basic block.
- if (I != MF.begin()) {
+ if (I != MF.begin())
EmitBasicBlockStart(I);
- }
// Print a basic block.
for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
II != E; ++II) {
-
// Emit the line directive if source line changed.
- const DebugLoc DL = II->getDebugLoc();
+ DebugLoc DL = II->getDebugLoc();
if (!DL.isUnknown() && DL != CurDL) {
DbgInfo.ChangeDebugLoc(MF, DL);
CurDL = DL;
@@ -156,7 +157,8 @@ bool PIC16AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
// printOperand - print operand of insn.
-void PIC16AsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
+void PIC16AsmPrinter::printOperand(const MachineInstr *MI, int opNum,
+ raw_ostream &O) {
const MachineOperand &MO = MI->getOperand(opNum);
const Function *F = MI->getParent()->getParent()->getFunction();
@@ -167,9 +169,7 @@ void PIC16AsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
std::string RegName = getRegisterName(MO.getReg());
if ((MI->getOpcode() == PIC16::load_indirect) ||
(MI->getOpcode() == PIC16::store_indirect))
- {
RegName.replace (0, 3, "INDF");
- }
O << RegName;
}
return;
@@ -216,7 +216,8 @@ void PIC16AsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
/// printCCOperand - Print the cond code operand.
///
-void PIC16AsmPrinter::printCCOperand(const MachineInstr *MI, int opNum) {
+void PIC16AsmPrinter::printCCOperand(const MachineInstr *MI, int opNum,
+ raw_ostream &O) {
int CC = (int)MI->getOperand(opNum).getImm();
O << PIC16CondCodeToString((PIC16CC::CondCodes)CC);
}
@@ -228,13 +229,15 @@ void PIC16AsmPrinter::printLibcallDecls() {
// If no libcalls used, return.
if (LibcallDecls.empty()) return;
- O << MAI->getCommentString() << "External decls for libcalls - BEGIN." <<"\n";
+ OutStreamer.AddComment("External decls for libcalls - BEGIN");
+ OutStreamer.AddBlankLine();
for (std::set<std::string>::const_iterator I = LibcallDecls.begin(),
- E = LibcallDecls.end(); I != E; I++) {
- O << MAI->getExternDirective() << *I << "\n";
- }
- O << MAI->getCommentString() << "External decls for libcalls - END." <<"\n";
+ E = LibcallDecls.end(); I != E; I++)
+ OutStreamer.EmitRawText(MAI->getExternDirective() + Twine(*I));
+
+ OutStreamer.AddComment("External decls for libcalls - END");
+ OutStreamer.AddBlankLine();
}
/// doInitialization - Perform Module level initializations here.
@@ -245,8 +248,8 @@ bool PIC16AsmPrinter::doInitialization(Module &M) {
bool Result = AsmPrinter::doInitialization(M);
// Every asmbly contains these std headers.
- O << "\n#include p16f1xxx.inc";
- O << "\n#include stdmacros.inc";
+ OutStreamer.EmitRawText(StringRef("\n#include p16f1xxx.inc"));
+ OutStreamer.EmitRawText(StringRef("#include stdmacros.inc"));
// Set the section names for all globals.
for (Module::global_iterator I = M.global_begin(), E = M.global_end();
@@ -289,7 +292,8 @@ bool PIC16AsmPrinter::doInitialization(Module &M) {
///
void PIC16AsmPrinter::EmitFunctionDecls(Module &M) {
// Emit declarations for external functions.
- O <<"\n"<<MAI->getCommentString() << "Function Declarations - BEGIN." <<"\n";
+ OutStreamer.AddComment("Function Declarations - BEGIN");
+ OutStreamer.AddBlankLine();
for (Module::iterator I = M.begin(), E = M.end(); I != E; I++) {
if (I->isIntrinsic() || I->getName() == "@abort")
continue;
@@ -312,12 +316,16 @@ void PIC16AsmPrinter::EmitFunctionDecls(Module &M) {
const char *directive = I->isDeclaration() ? MAI->getExternDirective() :
MAI->getGlobalDirective();
- O << directive << Sym->getName() << "\n";
- O << directive << PAN::getRetvalLabel(Sym->getName()) << "\n";
- O << directive << PAN::getArgsLabel(Sym->getName()) << "\n";
+ OutStreamer.EmitRawText(directive + Twine(Sym->getName()));
+ OutStreamer.EmitRawText(directive +
+ Twine(PAN::getRetvalLabel(Sym->getName())));
+ OutStreamer.EmitRawText(directive +
+ Twine(PAN::getArgsLabel(Sym->getName())));
}
- O << MAI->getCommentString() << "Function Declarations - END." <<"\n";
+ OutStreamer.AddComment("Function Declarations - END");
+ OutStreamer.AddBlankLine();
+
}
// Emit variables imported from other Modules.
@@ -325,10 +333,14 @@ void PIC16AsmPrinter::EmitUndefinedVars(Module &M) {
std::vector<const GlobalVariable*> Items = ExternalVarDecls;
if (!Items.size()) return;
- O << "\n" << MAI->getCommentString() << "Imported Variables - BEGIN" << "\n";
+ OutStreamer.AddComment("Imported Variables - BEGIN");
+ OutStreamer.AddBlankLine();
for (unsigned j = 0; j < Items.size(); j++)
- O << MAI->getExternDirective() << *Mang->getSymbol(Items[j]) << "\n";
- O << MAI->getCommentString() << "Imported Variables - END" << "\n";
+ OutStreamer.EmitRawText(MAI->getExternDirective() +
+ Twine(Mang->getSymbol(Items[j])->getName()));
+
+ OutStreamer.AddComment("Imported Variables - END");
+ OutStreamer.AddBlankLine();
}
// Emit variables defined in this module and are available to other modules.
@@ -336,10 +348,14 @@ void PIC16AsmPrinter::EmitDefinedVars(Module &M) {
std::vector<const GlobalVariable*> Items = ExternalVarDefs;
if (!Items.size()) return;
- O << "\n" << MAI->getCommentString() << "Exported Variables - BEGIN" << "\n";
+ OutStreamer.AddComment("Exported Variables - BEGIN");
+ OutStreamer.AddBlankLine();
+
for (unsigned j = 0; j < Items.size(); j++)
- O << MAI->getGlobalDirective() << *Mang->getSymbol(Items[j]) << "\n";
- O << MAI->getCommentString() << "Exported Variables - END" << "\n";
+ OutStreamer.EmitRawText(MAI->getGlobalDirective() +
+ Twine(Mang->getSymbol(Items[j])->getName()));
+ OutStreamer.AddComment("Exported Variables - END");
+ OutStreamer.AddBlankLine();
}
// Emit initialized data placed in ROM.
@@ -356,7 +372,7 @@ bool PIC16AsmPrinter::doFinalization(Module &M) {
EmitAllAutos(M);
printLibcallDecls();
DbgInfo.EndModule(M);
- O << "\n\t" << "END\n";
+ OutStreamer.EmitRawText(StringRef("\tEND"));
return AsmPrinter::doFinalization(M);
}
@@ -364,7 +380,6 @@ void PIC16AsmPrinter::EmitFunctionFrame(MachineFunction &MF) {
const Function *F = MF.getFunction();
const TargetData *TD = TM.getTargetData();
// Emit the data section name.
- O << "\n";
PIC16Section *fPDataSection =
const_cast<PIC16Section *>(getObjFileLowering().
@@ -374,7 +389,8 @@ void PIC16AsmPrinter::EmitFunctionFrame(MachineFunction &MF) {
OutStreamer.SwitchSection(fPDataSection);
// Emit function frame label
- O << PAN::getFrameLabel(CurrentFnSym->getName()) << ":\n";
+ OutStreamer.EmitRawText(PAN::getFrameLabel(CurrentFnSym->getName()) +
+ Twine(":"));
const Type *RetType = F->getReturnType();
unsigned RetSize = 0;
@@ -386,10 +402,11 @@ void PIC16AsmPrinter::EmitFunctionFrame(MachineFunction &MF) {
// we will need to avoid printing a global directive for Retval label
// in emitExternandGloblas.
if(RetSize > 0)
- O << PAN::getRetvalLabel(CurrentFnSym->getName())
- << " RES " << RetSize << "\n";
+ OutStreamer.EmitRawText(PAN::getRetvalLabel(CurrentFnSym->getName()) +
+ Twine(" RES ") + Twine(RetSize));
else
- O << PAN::getRetvalLabel(CurrentFnSym->getName()) << ": \n";
+ OutStreamer.EmitRawText(PAN::getRetvalLabel(CurrentFnSym->getName()) +
+ Twine(":"));
// Emit variable to hold the space for function arguments
unsigned ArgSize = 0;
@@ -399,13 +416,14 @@ void PIC16AsmPrinter::EmitFunctionFrame(MachineFunction &MF) {
ArgSize += TD->getTypeAllocSize(Ty);
}
- O << PAN::getArgsLabel(CurrentFnSym->getName()) << " RES " << ArgSize << "\n";
+ OutStreamer.EmitRawText(PAN::getArgsLabel(CurrentFnSym->getName()) +
+ Twine(" RES ") + Twine(ArgSize));
// Emit temporary space
int TempSize = PTLI->GetTmpSize();
if (TempSize > 0)
- O << PAN::getTempdataLabel(CurrentFnSym->getName()) << " RES "
- << TempSize << '\n';
+ OutStreamer.EmitRawText(PAN::getTempdataLabel(CurrentFnSym->getName()) +
+ Twine(" RES ") + Twine(TempSize));
}
@@ -417,7 +435,7 @@ void PIC16AsmPrinter::EmitInitializedDataSection(const PIC16Section *S) {
for (unsigned j = 0; j < Items.size(); j++) {
Constant *C = Items[j]->getInitializer();
int AddrSpace = Items[j]->getType()->getAddressSpace();
- O << *Mang->getSymbol(Items[j]);
+ OutStreamer.EmitRawText(Mang->getSymbol(Items[j])->getName());
EmitGlobalConstant(C, AddrSpace);
}
}
@@ -436,7 +454,8 @@ EmitUninitializedDataSection(const PIC16Section *S) {
Constant *C = Items[j]->getInitializer();
const Type *Ty = C->getType();
unsigned Size = TD->getTypeAllocSize(Ty);
- O << *Mang->getSymbol(Items[j]) << " RES " << Size << "\n";
+ OutStreamer.EmitRawText(Mang->getSymbol(Items[j])->getName() +
+ Twine(" RES ") + Twine(Size));
}
}
@@ -484,7 +503,7 @@ EmitSectionList(Module &M, const std::vector<PIC16Section *> &SList) {
// Exclude llvm specific metadata sections.
if (SList[i]->getName().find("llvm.") != std::string::npos)
continue;
- O << "\n";
+ OutStreamer.AddBlankLine();
EmitSingleSection(SList[i]);
}
}
diff --git a/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.h b/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.h
index 8063fcc..e27778f 100644
--- a/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.h
+++ b/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.h
@@ -31,8 +31,7 @@
namespace llvm {
class VISIBILITY_HIDDEN PIC16AsmPrinter : public AsmPrinter {
public:
- explicit PIC16AsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
- MCStreamer &Streamer);
+ explicit PIC16AsmPrinter(TargetMachine &TM, MCStreamer &Streamer);
private:
virtual const char *getPassName() const {
return "PIC16 Assembly Printer";
@@ -43,9 +42,9 @@ namespace llvm {
}
bool runOnMachineFunction(MachineFunction &F);
- void printOperand(const MachineInstr *MI, int opNum);
- void printCCOperand(const MachineInstr *MI, int opNum);
- void printInstruction(const MachineInstr *MI); // definition autogenerated.
+ void printOperand(const MachineInstr *MI, int opNum, raw_ostream &O);
+ void printCCOperand(const MachineInstr *MI, int opNum, raw_ostream &O);
+ void printInstruction(const MachineInstr *MI, raw_ostream &O);
static const char *getRegisterName(unsigned RegNo);
void EmitInstruction(const MachineInstr *MI);
diff --git a/lib/Target/PIC16/PIC16DebugInfo.cpp b/lib/Target/PIC16/PIC16DebugInfo.cpp
index a223540..5d86329 100644
--- a/lib/Target/PIC16/PIC16DebugInfo.cpp
+++ b/lib/Target/PIC16/PIC16DebugInfo.cpp
@@ -18,10 +18,10 @@
#include "llvm/GlobalVariable.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCStreamer.h"
#include "llvm/Support/DebugLoc.h"
-#include "llvm/Support/FormattedStream.h"
#include "llvm/ADT/SmallString.h"
-
+#include "llvm/ADT/StringExtras.h"
using namespace llvm;
/// PopulateDebugInfo - Populate the TypeNo, Aux[] and TagName from Ty.
@@ -267,7 +267,8 @@ void PIC16DbgInfo::ChangeDebugLoc(const MachineFunction &MF,
///
void PIC16DbgInfo::SwitchToLine(unsigned Line, bool IsInBeginFunction) {
if (CurLine == Line) return;
- if (!IsInBeginFunction) O << "\n\t.line " << Line << "\n";
+ if (!IsInBeginFunction)
+ OS.EmitRawText("\n\t.line " + Twine(Line));
CurLine = Line;
}
@@ -286,7 +287,7 @@ void PIC16DbgInfo::EndFunction(const MachineFunction &MF) {
void PIC16DbgInfo::EndModule(Module &M) {
if (! EmitDebugDirectives) return;
EmitVarDebugInfo(M);
- if (CurFile != "") O << "\n\t.eof";
+ if (CurFile != "") OS.EmitRawText(StringRef("\n\t.eof"));
}
/// EmitCompositeTypeElements - Emit debug information for members of a
@@ -410,22 +411,26 @@ void PIC16DbgInfo::EmitFunctEndDI(const Function *F, unsigned Line) {
///
void PIC16DbgInfo::EmitAuxEntry(const std::string VarName, int Aux[], int Num,
std::string TagName) {
- O << "\n\t.dim " << VarName << ", 1" ;
+ std::string Tmp;
// TagName is emitted in case of structure/union objects.
- if (TagName != "")
- O << ", " << TagName;
+ if (!TagName.empty()) Tmp += ", " + TagName;
+
for (int i = 0; i<Num; i++)
- O << "," << (Aux[i] && 0xff);
+ Tmp += "," + utostr(Aux[i] && 0xff);
+
+ OS.EmitRawText("\n\t.dim " + Twine(VarName) + ", 1" + Tmp);
}
/// EmitSymbol - Emit .def for a symbol. Value is offset for the member.
///
-void PIC16DbgInfo::EmitSymbol(std::string Name, short Class, unsigned short
- Type, unsigned long Value) {
- O << "\n\t" << ".def "<< Name << ", type = " << Type << ", class = "
- << Class;
+void PIC16DbgInfo::EmitSymbol(std::string Name, short Class,
+ unsigned short Type, unsigned long Value) {
+ std::string Tmp;
if (Value > 0)
- O << ", value = " << Value;
+ Tmp = ", value = " + utostr(Value);
+
+ OS.EmitRawText("\n\t.def " + Twine(Name) + ", type = " + utostr(Type) +
+ ", class = " + utostr(Class) + Tmp);
}
/// EmitVarDebugInfo - Emit debug information for all variables.
@@ -447,14 +452,13 @@ void PIC16DbgInfo::EmitVarDebugInfo(Module &M) {
PopulateDebugInfo(Ty, TypeNo, HasAux, Aux, TagName);
// Emit debug info only if type information is availaible.
if (TypeNo != PIC16Dbg::T_NULL) {
- O << "\n\t.type " << VarName << ", " << TypeNo;
+ OS.EmitRawText("\t.type " + Twine(VarName) + ", " + Twine(TypeNo));
short ClassNo = getStorageClass(DIGV);
- O << "\n\t.class " << VarName << ", " << ClassNo;
- if (HasAux)
+ OS.EmitRawText("\t.class " + Twine(VarName) + ", " + Twine(ClassNo));
+ if (HasAux)
EmitAuxEntry(VarName, Aux, PIC16Dbg::AuxSize, TagName);
}
}
- O << "\n";
}
/// SwitchToCU - Switch to a new compilation unit.
@@ -470,8 +474,9 @@ void PIC16DbgInfo::SwitchToCU(MDNode *CU) {
if ( FilePath == CurFile ) return;
// Else, close the current one and start a new.
- if (CurFile != "") O << "\n\t.eof";
- O << "\n\t.file\t\"" << FilePath << "\"\n" ;
+ if (CurFile != "")
+ OS.EmitRawText(StringRef("\t.eof"));
+ OS.EmitRawText("\n\t.file\t\"" + Twine(FilePath) + "\"");
CurFile = FilePath;
CurLine = 0;
}
@@ -480,6 +485,6 @@ void PIC16DbgInfo::SwitchToCU(MDNode *CU) {
///
void PIC16DbgInfo::EmitEOF() {
if (CurFile != "")
- O << "\n\t.EOF";
+ OS.EmitRawText(StringRef("\t.EOF"));
}
diff --git a/lib/Target/PIC16/PIC16DebugInfo.h b/lib/Target/PIC16/PIC16DebugInfo.h
index 54e27c7..031dcf0 100644
--- a/lib/Target/PIC16/PIC16DebugInfo.h
+++ b/lib/Target/PIC16/PIC16DebugInfo.h
@@ -20,6 +20,8 @@
namespace llvm {
class MachineFunction;
class DebugLoc;
+ class MCStreamer;
+
namespace PIC16Dbg {
enum VarType {
T_NULL,
@@ -88,10 +90,8 @@ namespace llvm {
};
}
- class formatted_raw_ostream;
-
class PIC16DbgInfo {
- formatted_raw_ostream &O;
+ MCStreamer &OS;
const MCAsmInfo *MAI;
std::string CurFile;
unsigned CurLine;
@@ -101,8 +101,7 @@ namespace llvm {
bool EmitDebugDirectives;
public:
- PIC16DbgInfo(formatted_raw_ostream &o, const MCAsmInfo *T)
- : O(o), MAI(T) {
+ PIC16DbgInfo(MCStreamer &os, const MCAsmInfo *T) : OS(os), MAI(T) {
CurFile = "";
CurLine = 0;
EmitDebugDirectives = false;
diff --git a/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp b/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp
index 5adefd3..6056564 100644
--- a/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp
+++ b/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp
@@ -26,7 +26,6 @@
#include "llvm/Module.h"
#include "llvm/Assembly/Writer.h"
#include "llvm/CodeGen/AsmPrinter.h"
-#include "llvm/CodeGen/DwarfWriter.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
@@ -44,10 +43,8 @@
#include "llvm/Target/TargetOptions.h"
#include "llvm/Target/TargetRegistry.h"
#include "llvm/Support/MathExtras.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/FormattedStream.h"
+#include "llvm/Support/raw_ostream.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/ADT/SmallString.h"
@@ -56,13 +53,12 @@ using namespace llvm;
namespace {
class PPCAsmPrinter : public AsmPrinter {
protected:
- DenseMap<const MCSymbol*, const MCSymbol*> TOC;
+ DenseMap<MCSymbol*, MCSymbol*> TOC;
const PPCSubtarget &Subtarget;
uint64_t LabelID;
public:
- explicit PPCAsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
- MCStreamer &Streamer)
- : AsmPrinter(O, TM, Streamer),
+ explicit PPCAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
+ : AsmPrinter(TM, Streamer),
Subtarget(TM.getSubtarget<PPCSubtarget>()), LabelID(0) {}
virtual const char *getPassName() const {
@@ -92,12 +88,12 @@ namespace {
/// from the instruction set description. This method returns true if the
/// machine instruction was sufficiently described to print it, otherwise it
/// returns false.
- void printInstruction(const MachineInstr *MI);
+ void printInstruction(const MachineInstr *MI, raw_ostream &O);
static const char *getRegisterName(unsigned RegNo);
virtual void EmitInstruction(const MachineInstr *MI);
- void printOp(const MachineOperand &MO);
+ void printOp(const MachineOperand &MO, raw_ostream &O);
/// stripRegisterPrefix - This method strips the character prefix from a
/// register name so that only the number is left. Used by for linux asm.
@@ -114,7 +110,7 @@ namespace {
/// printRegister - Print register according to target requirements.
///
- void printRegister(const MachineOperand &MO, bool R0AsZero) {
+ void printRegister(const MachineOperand &MO, bool R0AsZero, raw_ostream &O){
unsigned RegNo = MO.getReg();
assert(TargetRegisterInfo::isPhysicalRegister(RegNo) && "Not physreg??");
@@ -131,66 +127,76 @@ namespace {
O << RegName;
}
- void printOperand(const MachineInstr *MI, unsigned OpNo) {
+ void printOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) {
const MachineOperand &MO = MI->getOperand(OpNo);
if (MO.isReg()) {
- printRegister(MO, false);
+ printRegister(MO, false, O);
} else if (MO.isImm()) {
O << MO.getImm();
} else {
- printOp(MO);
+ printOp(MO, O);
}
}
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
- unsigned AsmVariant, const char *ExtraCode);
+ unsigned AsmVariant, const char *ExtraCode,
+ raw_ostream &O);
bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
- unsigned AsmVariant, const char *ExtraCode);
+ unsigned AsmVariant, const char *ExtraCode,
+ raw_ostream &O);
- void printS5ImmOperand(const MachineInstr *MI, unsigned OpNo) {
+ void printS5ImmOperand(const MachineInstr *MI, unsigned OpNo,
+ raw_ostream &O) {
char value = MI->getOperand(OpNo).getImm();
value = (value << (32-5)) >> (32-5);
O << (int)value;
}
- void printU5ImmOperand(const MachineInstr *MI, unsigned OpNo) {
+ void printU5ImmOperand(const MachineInstr *MI, unsigned OpNo,
+ raw_ostream &O) {
unsigned char value = MI->getOperand(OpNo).getImm();
assert(value <= 31 && "Invalid u5imm argument!");
O << (unsigned int)value;
}
- void printU6ImmOperand(const MachineInstr *MI, unsigned OpNo) {
+ void printU6ImmOperand(const MachineInstr *MI, unsigned OpNo,
+ raw_ostream &O) {
unsigned char value = MI->getOperand(OpNo).getImm();
assert(value <= 63 && "Invalid u6imm argument!");
O << (unsigned int)value;
}
- void printS16ImmOperand(const MachineInstr *MI, unsigned OpNo) {
+ void printS16ImmOperand(const MachineInstr *MI, unsigned OpNo,
+ raw_ostream &O) {
O << (short)MI->getOperand(OpNo).getImm();
}
- void printU16ImmOperand(const MachineInstr *MI, unsigned OpNo) {
+ void printU16ImmOperand(const MachineInstr *MI, unsigned OpNo,
+ raw_ostream &O) {
O << (unsigned short)MI->getOperand(OpNo).getImm();
}
- void printS16X4ImmOperand(const MachineInstr *MI, unsigned OpNo) {
+ void printS16X4ImmOperand(const MachineInstr *MI, unsigned OpNo,
+ raw_ostream &O) {
if (MI->getOperand(OpNo).isImm()) {
O << (short)(MI->getOperand(OpNo).getImm()*4);
} else {
O << "lo16(";
- printOp(MI->getOperand(OpNo));
+ printOp(MI->getOperand(OpNo), O);
if (TM.getRelocationModel() == Reloc::PIC_)
O << "-\"L" << getFunctionNumber() << "$pb\")";
else
O << ')';
}
}
- void printBranchOperand(const MachineInstr *MI, unsigned OpNo) {
+ void printBranchOperand(const MachineInstr *MI, unsigned OpNo,
+ raw_ostream &O) {
// Branches can take an immediate operand. This is used by the branch
// selection pass to print $+8, an eight byte displacement from the PC.
if (MI->getOperand(OpNo).isImm()) {
O << "$+" << MI->getOperand(OpNo).getImm()*4;
} else {
- printOp(MI->getOperand(OpNo));
+ printOp(MI->getOperand(OpNo), O);
}
}
- void printCallOperand(const MachineInstr *MI, unsigned OpNo) {
+ void printCallOperand(const MachineInstr *MI, unsigned OpNo,
+ raw_ostream &O) {
const MachineOperand &MO = MI->getOperand(OpNo);
if (TM.getRelocationModel() != Reloc::Static) {
if (MO.getType() == MachineOperand::MO_GlobalAddress) {
@@ -223,21 +229,22 @@ namespace {
}
}
- printOp(MI->getOperand(OpNo));
+ printOp(MI->getOperand(OpNo), O);
}
- void printAbsAddrOperand(const MachineInstr *MI, unsigned OpNo) {
+ void printAbsAddrOperand(const MachineInstr *MI, unsigned OpNo,
+ raw_ostream &O) {
O << (int)MI->getOperand(OpNo).getImm()*4;
}
- void printPICLabel(const MachineInstr *MI, unsigned OpNo) {
+ void printPICLabel(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) {
O << "\"L" << getFunctionNumber() << "$pb\"\n";
O << "\"L" << getFunctionNumber() << "$pb\":";
}
- void printSymbolHi(const MachineInstr *MI, unsigned OpNo) {
+ void printSymbolHi(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) {
if (MI->getOperand(OpNo).isImm()) {
- printS16ImmOperand(MI, OpNo);
+ printS16ImmOperand(MI, OpNo, O);
} else {
if (Subtarget.isDarwin()) O << "ha16(";
- printOp(MI->getOperand(OpNo));
+ printOp(MI->getOperand(OpNo), O);
if (TM.getRelocationModel() == Reloc::PIC_)
O << "-\"L" << getFunctionNumber() << "$pb\"";
if (Subtarget.isDarwin())
@@ -246,12 +253,12 @@ namespace {
O << "@ha";
}
}
- void printSymbolLo(const MachineInstr *MI, unsigned OpNo) {
+ void printSymbolLo(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) {
if (MI->getOperand(OpNo).isImm()) {
- printS16ImmOperand(MI, OpNo);
+ printS16ImmOperand(MI, OpNo, O);
} else {
if (Subtarget.isDarwin()) O << "lo16(";
- printOp(MI->getOperand(OpNo));
+ printOp(MI->getOperand(OpNo), O);
if (TM.getRelocationModel() == Reloc::PIC_)
O << "-\"L" << getFunctionNumber() << "$pb\"";
if (Subtarget.isDarwin())
@@ -260,53 +267,55 @@ namespace {
O << "@l";
}
}
- void printcrbitm(const MachineInstr *MI, unsigned OpNo) {
+ void printcrbitm(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) {
unsigned CCReg = MI->getOperand(OpNo).getReg();
unsigned RegNo = enumRegToMachineReg(CCReg);
O << (0x80 >> RegNo);
}
// The new addressing mode printers.
- void printMemRegImm(const MachineInstr *MI, unsigned OpNo) {
- printSymbolLo(MI, OpNo);
+ void printMemRegImm(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) {
+ printSymbolLo(MI, OpNo, O);
O << '(';
if (MI->getOperand(OpNo+1).isReg() &&
MI->getOperand(OpNo+1).getReg() == PPC::R0)
O << "0";
else
- printOperand(MI, OpNo+1);
+ printOperand(MI, OpNo+1, O);
O << ')';
}
- void printMemRegImmShifted(const MachineInstr *MI, unsigned OpNo) {
+ void printMemRegImmShifted(const MachineInstr *MI, unsigned OpNo,
+ raw_ostream &O) {
if (MI->getOperand(OpNo).isImm())
- printS16X4ImmOperand(MI, OpNo);
+ printS16X4ImmOperand(MI, OpNo, O);
else
- printSymbolLo(MI, OpNo);
+ printSymbolLo(MI, OpNo, O);
O << '(';
if (MI->getOperand(OpNo+1).isReg() &&
MI->getOperand(OpNo+1).getReg() == PPC::R0)
O << "0";
else
- printOperand(MI, OpNo+1);
+ printOperand(MI, OpNo+1, O);
O << ')';
}
- void printMemRegReg(const MachineInstr *MI, unsigned OpNo) {
+ void printMemRegReg(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) {
// When used as the base register, r0 reads constant zero rather than
// the value contained in the register. For this reason, the darwin
// assembler requires that we print r0 as 0 (no r) when used as the base.
const MachineOperand &MO = MI->getOperand(OpNo);
- printRegister(MO, true);
+ printRegister(MO, true, O);
O << ", ";
- printOperand(MI, OpNo+1);
+ printOperand(MI, OpNo+1, O);
}
- void printTOCEntryLabel(const MachineInstr *MI, unsigned OpNo) {
+ void printTOCEntryLabel(const MachineInstr *MI, unsigned OpNo,
+ raw_ostream &O) {
const MachineOperand &MO = MI->getOperand(OpNo);
assert(MO.getType() == MachineOperand::MO_GlobalAddress);
- const MCSymbol *Sym = Mang->getSymbol(MO.getGlobal());
+ MCSymbol *Sym = Mang->getSymbol(MO.getGlobal());
// Map symbol -> label of TOC entry.
- const MCSymbol *&TOCEntry = TOC[Sym];
+ MCSymbol *&TOCEntry = TOC[Sym];
if (TOCEntry == 0)
TOCEntry = OutContext.
GetOrCreateSymbol(StringRef(MAI->getPrivateGlobalPrefix()) +
@@ -316,15 +325,14 @@ namespace {
}
void printPredicateOperand(const MachineInstr *MI, unsigned OpNo,
- const char *Modifier);
+ raw_ostream &O, const char *Modifier);
};
/// PPCLinuxAsmPrinter - PowerPC assembly printer, customized for Linux
class PPCLinuxAsmPrinter : public PPCAsmPrinter {
public:
- explicit PPCLinuxAsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
- MCStreamer &Streamer)
- : PPCAsmPrinter(O, TM, Streamer) {}
+ explicit PPCLinuxAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
+ : PPCAsmPrinter(TM, Streamer) {}
virtual const char *getPassName() const {
return "Linux PPC Assembly Printer";
@@ -333,23 +341,14 @@ namespace {
bool doFinalization(Module &M);
virtual void EmitFunctionEntryLabel();
-
- void getAnalysisUsage(AnalysisUsage &AU) const {
- AU.setPreservesAll();
- AU.addRequired<MachineModuleInfo>();
- AU.addRequired<DwarfWriter>();
- PPCAsmPrinter::getAnalysisUsage(AU);
- }
};
/// PPCDarwinAsmPrinter - PowerPC assembly printer, customized for Darwin/Mac
/// OS X
class PPCDarwinAsmPrinter : public PPCAsmPrinter {
- formatted_raw_ostream &OS;
public:
- explicit PPCDarwinAsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
- MCStreamer &Streamer)
- : PPCAsmPrinter(O, TM, Streamer), OS(O) {}
+ explicit PPCDarwinAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
+ : PPCAsmPrinter(TM, Streamer) {}
virtual const char *getPassName() const {
return "Darwin PPC Assembly Printer";
@@ -359,20 +358,13 @@ namespace {
void EmitStartOfAsmFile(Module &M);
void EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs);
-
- void getAnalysisUsage(AnalysisUsage &AU) const {
- AU.setPreservesAll();
- AU.addRequired<MachineModuleInfo>();
- AU.addRequired<DwarfWriter>();
- PPCAsmPrinter::getAnalysisUsage(AU);
- }
};
} // end of anonymous namespace
// Include the auto-generated portion of the assembly writer
#include "PPCGenAsmWriter.inc"
-void PPCAsmPrinter::printOp(const MachineOperand &MO) {
+void PPCAsmPrinter::printOp(const MachineOperand &MO, raw_ostream &O) {
switch (MO.getType()) {
case MachineOperand::MO_Immediate:
llvm_unreachable("printOp() does not handle immediate values");
@@ -446,7 +438,7 @@ void PPCAsmPrinter::printOp(const MachineOperand &MO) {
O << *SymToPrint;
- printOffset(MO.getOffset());
+ printOffset(MO.getOffset(), O);
return;
}
@@ -460,7 +452,7 @@ void PPCAsmPrinter::printOp(const MachineOperand &MO) {
///
bool PPCAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
unsigned AsmVariant,
- const char *ExtraCode) {
+ const char *ExtraCode, raw_ostream &O) {
// Does this asm operand have a single letter operand modifier?
if (ExtraCode && ExtraCode[0]) {
if (ExtraCode[1] != 0) return true; // Unknown modifier.
@@ -469,7 +461,7 @@ bool PPCAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
default: return true; // Unknown modifier.
case 'c': // Don't print "$" before a global var name or constant.
// PPC never has a prefix.
- printOperand(MI, OpNo);
+ printOperand(MI, OpNo, O);
return false;
case 'L': // Write second word of DImode reference.
// Verify that this operand has two consecutive registers.
@@ -488,7 +480,7 @@ bool PPCAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
}
}
- printOperand(MI, OpNo);
+ printOperand(MI, OpNo, O);
return false;
}
@@ -498,18 +490,19 @@ bool PPCAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
bool PPCAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
unsigned AsmVariant,
- const char *ExtraCode) {
+ const char *ExtraCode,
+ raw_ostream &O) {
if (ExtraCode && ExtraCode[0])
return true; // Unknown modifier.
assert (MI->getOperand(OpNo).isReg());
O << "0(";
- printOperand(MI, OpNo);
+ printOperand(MI, OpNo, O);
O << ")";
return false;
}
void PPCAsmPrinter::printPredicateOperand(const MachineInstr *MI, unsigned OpNo,
- const char *Modifier) {
+ raw_ostream &O, const char *Modifier){
assert(Modifier && "Must specify 'cc' or 'reg' as predicate op modifier!");
unsigned Code = MI->getOperand(OpNo).getImm();
if (!strcmp(Modifier, "cc")) {
@@ -530,7 +523,7 @@ void PPCAsmPrinter::printPredicateOperand(const MachineInstr *MI, unsigned OpNo,
"Need to specify 'cc' or 'reg' as predicate op modifier!");
// Don't print the register for 'always'.
if (Code == PPC::PRED_ALWAYS) return;
- printOperand(MI, OpNo+1);
+ printOperand(MI, OpNo+1, O);
}
}
@@ -539,6 +532,9 @@ void PPCAsmPrinter::printPredicateOperand(const MachineInstr *MI, unsigned OpNo,
/// the current output stream.
///
void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
+ SmallString<128> Str;
+ raw_svector_ostream O(Str);
+
// Check for slwi/srwi mnemonics.
if (MI->getOpcode() == PPC::RLWINM) {
unsigned char SH = MI->getOperand(2).getImm();
@@ -553,11 +549,11 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
SH = 32-SH;
}
if (useSubstituteMnemonic) {
- printOperand(MI, 0);
+ printOperand(MI, 0, O);
O << ", ";
- printOperand(MI, 1);
+ printOperand(MI, 1, O);
O << ", " << (unsigned int)SH;
- OutStreamer.AddBlankLine();
+ OutStreamer.EmitRawText(O.str());
return;
}
}
@@ -565,10 +561,10 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
if ((MI->getOpcode() == PPC::OR || MI->getOpcode() == PPC::OR8) &&
MI->getOperand(1).getReg() == MI->getOperand(2).getReg()) {
O << "\tmr ";
- printOperand(MI, 0);
+ printOperand(MI, 0, O);
O << ", ";
- printOperand(MI, 1);
- OutStreamer.AddBlankLine();
+ printOperand(MI, 1, O);
+ OutStreamer.EmitRawText(O.str());
return;
}
@@ -578,17 +574,17 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
// rldicr RA, RS, SH, 63-SH == sldi RA, RS, SH
if (63-SH == ME) {
O << "\tsldi ";
- printOperand(MI, 0);
+ printOperand(MI, 0, O);
O << ", ";
- printOperand(MI, 1);
+ printOperand(MI, 1, O);
O << ", " << (unsigned int)SH;
- OutStreamer.AddBlankLine();
+ OutStreamer.EmitRawText(O.str());
return;
}
}
- printInstruction(MI);
- OutStreamer.AddBlankLine();
+ printInstruction(MI, O);
+ OutStreamer.EmitRawText(O.str());
}
void PPCLinuxAsmPrinter::EmitFunctionEntryLabel() {
@@ -597,12 +593,13 @@ void PPCLinuxAsmPrinter::EmitFunctionEntryLabel() {
// Emit an official procedure descriptor.
// FIXME 64-bit SVR4: Use MCSection here!
- O << "\t.section\t\".opd\",\"aw\"\n";
- O << "\t.align 3\n";
+ OutStreamer.EmitRawText(StringRef("\t.section\t\".opd\",\"aw\""));
+ OutStreamer.EmitRawText(StringRef("\t.align 3"));
OutStreamer.EmitLabel(CurrentFnSym);
- O << "\t.quad .L." << *CurrentFnSym << ",.TOC.@tocbase\n";
- O << "\t.previous\n";
- O << ".L." << *CurrentFnSym << ":\n";
+ OutStreamer.EmitRawText("\t.quad .L." + Twine(CurrentFnSym->getName()) +
+ ",.TOC.@tocbase");
+ OutStreamer.EmitRawText(StringRef("\t.previous"));
+ OutStreamer.EmitRawText(".L." + Twine(CurrentFnSym->getName()) + ":");
}
@@ -613,13 +610,14 @@ bool PPCLinuxAsmPrinter::doFinalization(Module &M) {
if (isPPC64 && !TOC.empty()) {
// FIXME 64-bit SVR4: Use MCSection here?
- O << "\t.section\t\".toc\",\"aw\"\n";
+ OutStreamer.EmitRawText(StringRef("\t.section\t\".toc\",\"aw\""));
// FIXME: This is nondeterminstic!
- for (DenseMap<const MCSymbol*, const MCSymbol*>::iterator I = TOC.begin(),
+ for (DenseMap<MCSymbol*, MCSymbol*>::iterator I = TOC.begin(),
E = TOC.end(); I != E; ++I) {
- O << *I->second << ":\n";
- O << "\t.tc " << *I->first << "[TC]," << *I->first << '\n';
+ OutStreamer.EmitLabel(I->second);
+ OutStreamer.EmitRawText("\t.tc " + Twine(I->first->getName()) +
+ "[TC]," + I->first->getName());
}
}
@@ -647,7 +645,7 @@ void PPCDarwinAsmPrinter::EmitStartOfAsmFile(Module &M) {
if (Subtarget.isPPC64() && Directive < PPC::DIR_970)
Directive = PPC::DIR_64;
assert(Directive <= PPC::DIR_64 && "Directive out of range.");
- O << "\t.machine " << CPUDirectives[Directive] << '\n';
+ OutStreamer.EmitRawText("\t.machine " + Twine(CPUDirectives[Directive]));
// Prime text sections so they are adjacent. This reduces the likelihood a
// large data or debug section causes a branch to exceed 16M limit.
@@ -670,14 +668,14 @@ void PPCDarwinAsmPrinter::EmitStartOfAsmFile(Module &M) {
OutStreamer.SwitchSection(getObjFileLowering().getTextSection());
}
-static const MCSymbol *GetLazyPtr(const MCSymbol *Sym, MCContext &Ctx) {
+static MCSymbol *GetLazyPtr(MCSymbol *Sym, MCContext &Ctx) {
// Remove $stub suffix, add $lazy_ptr.
SmallString<128> TmpStr(Sym->getName().begin(), Sym->getName().end()-5);
TmpStr += "$lazy_ptr";
return Ctx.GetOrCreateSymbol(TmpStr.str());
}
-static const MCSymbol *GetAnonSym(const MCSymbol *Sym, MCContext &Ctx) {
+static MCSymbol *GetAnonSym(MCSymbol *Sym, MCContext &Ctx) {
// Add $tmp suffix to $stub, yielding $stub$tmp.
SmallString<128> TmpStr(Sym->getName().begin(), Sym->getName().end());
TmpStr += "$tmp";
@@ -705,31 +703,41 @@ EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs) {
OutStreamer.SwitchSection(StubSection);
EmitAlignment(4);
- const MCSymbol *Stub = Stubs[i].first;
- const MCSymbol *RawSym = Stubs[i].second.getPointer();
- const MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext);
- const MCSymbol *AnonSymbol = GetAnonSym(Stub, OutContext);
+ MCSymbol *Stub = Stubs[i].first;
+ MCSymbol *RawSym = Stubs[i].second.getPointer();
+ MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext);
+ MCSymbol *AnonSymbol = GetAnonSym(Stub, OutContext);
- O << *Stub << ":\n";
- O << "\t.indirect_symbol " << *RawSym << '\n';
- O << "\tmflr r0\n";
- O << "\tbcl 20,31," << *AnonSymbol << '\n';
- O << *AnonSymbol << ":\n";
- O << "\tmflr r11\n";
- O << "\taddis r11,r11,ha16(" << *LazyPtr << '-' << *AnonSymbol
- << ")\n";
- O << "\tmtlr r0\n";
- O << (isPPC64 ? "\tldu" : "\tlwzu") << " r12,lo16(" << *LazyPtr
- << '-' << *AnonSymbol << ")(r11)\n";
- O << "\tmtctr r12\n";
- O << "\tbctr\n";
+ OutStreamer.EmitLabel(Stub);
+ OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
+ // FIXME: MCize this.
+ OutStreamer.EmitRawText(StringRef("\tmflr r0"));
+ OutStreamer.EmitRawText("\tbcl 20,31," + Twine(AnonSymbol->getName()));
+ OutStreamer.EmitLabel(AnonSymbol);
+ OutStreamer.EmitRawText(StringRef("\tmflr r11"));
+ OutStreamer.EmitRawText("\taddis r11,r11,ha16("+Twine(LazyPtr->getName())+
+ "-" + AnonSymbol->getName() + ")");
+ OutStreamer.EmitRawText(StringRef("\tmtlr r0"));
+
+ if (isPPC64)
+ OutStreamer.EmitRawText("\tldu r12,lo16(" + Twine(LazyPtr->getName()) +
+ "-" + AnonSymbol->getName() + ")(r11)");
+ else
+ OutStreamer.EmitRawText("\tlwzu r12,lo16(" + Twine(LazyPtr->getName()) +
+ "-" + AnonSymbol->getName() + ")(r11)");
+ OutStreamer.EmitRawText(StringRef("\tmtctr r12"));
+ OutStreamer.EmitRawText(StringRef("\tbctr"));
OutStreamer.SwitchSection(LSPSection);
- O << *LazyPtr << ":\n";
- O << "\t.indirect_symbol " << *RawSym << '\n';
- O << (isPPC64 ? "\t.quad" : "\t.long") << " dyld_stub_binding_helper\n";
+ OutStreamer.EmitLabel(LazyPtr);
+ OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
+
+ if (isPPC64)
+ OutStreamer.EmitRawText(StringRef("\t.quad dyld_stub_binding_helper"));
+ else
+ OutStreamer.EmitRawText(StringRef("\t.long dyld_stub_binding_helper"));
}
- O << '\n';
+ OutStreamer.AddBlankLine();
return;
}
@@ -739,26 +747,34 @@ EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs) {
MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
16, SectionKind::getText());
for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
- const MCSymbol *Stub = Stubs[i].first;
- const MCSymbol *RawSym = Stubs[i].second.getPointer();
- const MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext);
+ MCSymbol *Stub = Stubs[i].first;
+ MCSymbol *RawSym = Stubs[i].second.getPointer();
+ MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext);
OutStreamer.SwitchSection(StubSection);
EmitAlignment(4);
- O << *Stub << ":\n";
- O << "\t.indirect_symbol " << *RawSym << '\n';
- O << "\tlis r11,ha16(" << *LazyPtr << ")\n";
- O << (isPPC64 ? "\tldu" : "\tlwzu") << " r12,lo16(" << *LazyPtr
- << ")(r11)\n";
- O << "\tmtctr r12\n";
- O << "\tbctr\n";
+ OutStreamer.EmitLabel(Stub);
+ OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
+ OutStreamer.EmitRawText("\tlis r11,ha16(" + Twine(LazyPtr->getName()) +")");
+ if (isPPC64)
+ OutStreamer.EmitRawText("\tldu r12,lo16(" + Twine(LazyPtr->getName()) +
+ ")(r11)");
+ else
+ OutStreamer.EmitRawText("\tlwzu r12,lo16(" + Twine(LazyPtr->getName()) +
+ ")(r11)");
+ OutStreamer.EmitRawText(StringRef("\tmtctr r12"));
+ OutStreamer.EmitRawText(StringRef("\tbctr"));
OutStreamer.SwitchSection(LSPSection);
- O << *LazyPtr << ":\n";
- O << "\t.indirect_symbol " << *RawSym << '\n';
- O << (isPPC64 ? "\t.quad" : "\t.long") << " dyld_stub_binding_helper\n";
+ OutStreamer.EmitLabel(LazyPtr);
+ OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
+
+ if (isPPC64)
+ OutStreamer.EmitRawText(StringRef("\t.quad dyld_stub_binding_helper"));
+ else
+ OutStreamer.EmitRawText(StringRef("\t.long dyld_stub_binding_helper"));
}
- O << '\n';
+ OutStreamer.AddBlankLine();
}
@@ -858,14 +874,13 @@ bool PPCDarwinAsmPrinter::doFinalization(Module &M) {
/// for a MachineFunction to the given output stream, in a format that the
/// Darwin assembler can deal with.
///
-static AsmPrinter *createPPCAsmPrinterPass(formatted_raw_ostream &o,
- TargetMachine &tm,
+static AsmPrinter *createPPCAsmPrinterPass(TargetMachine &tm,
MCStreamer &Streamer) {
const PPCSubtarget *Subtarget = &tm.getSubtarget<PPCSubtarget>();
if (Subtarget->isDarwin())
- return new PPCDarwinAsmPrinter(o, tm, Streamer);
- return new PPCLinuxAsmPrinter(o, tm, Streamer);
+ return new PPCDarwinAsmPrinter(tm, Streamer);
+ return new PPCLinuxAsmPrinter(tm, Streamer);
}
// Force static initialization.
diff --git a/lib/Target/PowerPC/PPC.td b/lib/Target/PowerPC/PPC.td
index 08f5bb4..27644b2 100644
--- a/lib/Target/PowerPC/PPC.td
+++ b/lib/Target/PowerPC/PPC.td
@@ -96,14 +96,6 @@ def : Processor<"ppc64", G5Itineraries,
include "PPCCallingConv.td"
def PPCInstrInfo : InstrInfo {
- // Define how we want to layout our TargetSpecific information field... This
- // should be kept up-to-date with the fields in the PPCInstrInfo.h file.
- let TSFlagsFields = ["PPC970_First",
- "PPC970_Single",
- "PPC970_Cracked",
- "PPC970_Unit"];
- let TSFlagsShifts = [0, 1, 2, 3];
-
let isLittleEndianEncoding = 1;
}
diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp
index dda530e..9cd01be 100644
--- a/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -2392,7 +2392,7 @@ CreateCopyOfByValArgument(SDValue Src, SDValue Dst, SDValue Chain,
DebugLoc dl) {
SDValue SizeNode = DAG.getConstant(Flags.getByValSize(), MVT::i32);
return DAG.getMemcpy(Chain, dl, Dst, Src, SizeNode, Flags.getByValAlign(),
- false, NULL, 0, NULL, 0);
+ false, false, NULL, 0, NULL, 0);
}
/// LowerMemOpCallTo - Store the argument to the stack or remember it in case of
diff --git a/lib/Target/PowerPC/PPCInstrFormats.td b/lib/Target/PowerPC/PPCInstrFormats.td
index 54cebcd..4357bdc 100644
--- a/lib/Target/PowerPC/PPCInstrFormats.td
+++ b/lib/Target/PowerPC/PPCInstrFormats.td
@@ -23,13 +23,18 @@ class I<bits<6> opcode, dag OOL, dag IOL, string asmstr, InstrItinClass itin>
let InOperandList = IOL;
let AsmString = asmstr;
let Itinerary = itin;
-
- /// These fields correspond to the fields in PPCInstrInfo.h. Any changes to
- /// these must be reflected there! See comments there for what these are.
+
bits<1> PPC970_First = 0;
bits<1> PPC970_Single = 0;
bits<1> PPC970_Cracked = 0;
bits<3> PPC970_Unit = 0;
+
+ /// These fields correspond to the fields in PPCInstrInfo.h. Any changes to
+ /// these must be reflected there! See comments there for what these are.
+ let TSFlags{0} = PPC970_First;
+ let TSFlags{1} = PPC970_Single;
+ let TSFlags{2} = PPC970_Cracked;
+ let TSFlags{5-3} = PPC970_Unit;
}
class PPC970_DGroup_First { bits<1> PPC970_First = 1; }
diff --git a/lib/Target/PowerPC/PPCMCAsmInfo.cpp b/lib/Target/PowerPC/PPCMCAsmInfo.cpp
index b37aee8..3644c79 100644
--- a/lib/Target/PowerPC/PPCMCAsmInfo.cpp
+++ b/lib/Target/PowerPC/PPCMCAsmInfo.cpp
@@ -38,7 +38,6 @@ PPCLinuxMCAsmInfo::PPCLinuxMCAsmInfo(bool is64Bit) {
UsesELFSectionDirectiveForBSS = true;
// Debug Information
- AbsoluteDebugSectionOffsets = true;
SupportsDebugInformation = true;
PCSymbol = ".";
@@ -49,7 +48,6 @@ PPCLinuxMCAsmInfo::PPCLinuxMCAsmInfo(bool is64Bit) {
// Exceptions handling
if (!is64Bit)
ExceptionsType = ExceptionHandling::Dwarf;
- AbsoluteEHSectionOffsets = false;
ZeroDirective = "\t.space\t";
Data64bitsDirective = is64Bit ? "\t.quad\t" : 0;
diff --git a/lib/Target/PowerPC/PPCRegisterInfo.cpp b/lib/Target/PowerPC/PPCRegisterInfo.cpp
index 9363aa8..52d87cd 100644
--- a/lib/Target/PowerPC/PPCRegisterInfo.cpp
+++ b/lib/Target/PowerPC/PPCRegisterInfo.cpp
@@ -1280,9 +1280,9 @@ PPCRegisterInfo::emitPrologue(MachineFunction &MF) const {
MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB
MachineBasicBlock::iterator MBBI = MBB.begin();
MachineFrameInfo *MFI = MF.getFrameInfo();
- MachineModuleInfo *MMI = MFI->getMachineModuleInfo();
+ MachineModuleInfo &MMI = MF.getMMI();
DebugLoc dl;
- bool needsFrameMoves = (MMI && MMI->hasDebugInfo()) ||
+ bool needsFrameMoves = MMI.hasDebugInfo() ||
!MF.getFunction()->doesNotThrow() ||
UnwindTablesMandatory;
@@ -1442,13 +1442,13 @@ PPCRegisterInfo::emitPrologue(MachineFunction &MF) const {
}
}
- std::vector<MachineMove> &Moves = MMI->getFrameMoves();
+ std::vector<MachineMove> &Moves = MMI.getFrameMoves();
// Add the "machine moves" for the instructions we generated above, but in
// reverse order.
if (needsFrameMoves) {
// Mark effective beginning of when frame pointer becomes valid.
- FrameLabel = MMI->getContext().CreateTempSymbol();
+ FrameLabel = MMI.getContext().CreateTempSymbol();
BuildMI(MBB, MBBI, dl, TII.get(PPC::DBG_LABEL)).addSym(FrameLabel);
// Show update of SP.
@@ -1489,7 +1489,7 @@ PPCRegisterInfo::emitPrologue(MachineFunction &MF) const {
}
if (needsFrameMoves) {
- ReadyLabel = MMI->getContext().CreateTempSymbol();
+ ReadyLabel = MMI.getContext().CreateTempSymbol();
// Mark effective beginning of when frame pointer is ready.
BuildMI(MBB, MBBI, dl, TII.get(PPC::DBG_LABEL)).addSym(ReadyLabel);
diff --git a/lib/Target/Sparc/AsmPrinter/SparcAsmPrinter.cpp b/lib/Target/Sparc/AsmPrinter/SparcAsmPrinter.cpp
index 3e40dbb..ab948bb 100644
--- a/lib/Target/Sparc/AsmPrinter/SparcAsmPrinter.cpp
+++ b/lib/Target/Sparc/AsmPrinter/SparcAsmPrinter.cpp
@@ -23,39 +23,43 @@
#include "llvm/MC/MCSymbol.h"
#include "llvm/Target/Mangler.h"
#include "llvm/Target/TargetRegistry.h"
+#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
-#include "llvm/Support/FormattedStream.h"
+#include "llvm/Support/raw_ostream.h"
using namespace llvm;
namespace {
class SparcAsmPrinter : public AsmPrinter {
public:
- explicit SparcAsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
- MCStreamer &Streamer)
- : AsmPrinter(O, TM, Streamer) {}
+ explicit SparcAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
+ : AsmPrinter(TM, Streamer) {}
virtual const char *getPassName() const {
return "Sparc Assembly Printer";
}
- void printOperand(const MachineInstr *MI, int opNum);
- void printMemOperand(const MachineInstr *MI, int opNum,
+ void printOperand(const MachineInstr *MI, int opNum, raw_ostream &OS);
+ void printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &OS,
const char *Modifier = 0);
- void printCCOperand(const MachineInstr *MI, int opNum);
+ void printCCOperand(const MachineInstr *MI, int opNum, raw_ostream &OS);
virtual void EmitInstruction(const MachineInstr *MI) {
- printInstruction(MI);
- OutStreamer.AddBlankLine();
+ SmallString<128> Str;
+ raw_svector_ostream OS(Str);
+ printInstruction(MI, OS);
+ OutStreamer.EmitRawText(OS.str());
}
- void printInstruction(const MachineInstr *MI); // autogenerated.
+ void printInstruction(const MachineInstr *MI, raw_ostream &OS);// autogen'd.
static const char *getRegisterName(unsigned RegNo);
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
- unsigned AsmVariant, const char *ExtraCode);
+ unsigned AsmVariant, const char *ExtraCode,
+ raw_ostream &O);
bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
- unsigned AsmVariant, const char *ExtraCode);
+ unsigned AsmVariant, const char *ExtraCode,
+ raw_ostream &O);
- bool printGetPCX(const MachineInstr *MI, unsigned OpNo);
+ bool printGetPCX(const MachineInstr *MI, unsigned OpNo, raw_ostream &OS);
virtual bool isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB)
const;
@@ -64,7 +68,8 @@ namespace {
#include "SparcGenAsmWriter.inc"
-void SparcAsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
+void SparcAsmPrinter::printOperand(const MachineInstr *MI, int opNum,
+ raw_ostream &O) {
const MachineOperand &MO = MI->getOperand (opNum);
bool CloseParen = false;
if (MI->getOpcode() == SP::SETHIi && !MO.isReg() && !MO.isImm()) {
@@ -103,13 +108,13 @@ void SparcAsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
}
void SparcAsmPrinter::printMemOperand(const MachineInstr *MI, int opNum,
- const char *Modifier) {
- printOperand(MI, opNum);
+ raw_ostream &O, const char *Modifier) {
+ printOperand(MI, opNum, O);
// If this is an ADD operand, emit it like normal operands.
if (Modifier && !strcmp(Modifier, "arith")) {
O << ", ";
- printOperand(MI, opNum+1);
+ printOperand(MI, opNum+1, O);
return;
}
@@ -124,14 +129,15 @@ void SparcAsmPrinter::printMemOperand(const MachineInstr *MI, int opNum,
if (MI->getOperand(opNum+1).isGlobal() ||
MI->getOperand(opNum+1).isCPI()) {
O << "%lo(";
- printOperand(MI, opNum+1);
+ printOperand(MI, opNum+1, O);
O << ")";
} else {
- printOperand(MI, opNum+1);
+ printOperand(MI, opNum+1, O);
}
}
-bool SparcAsmPrinter::printGetPCX(const MachineInstr *MI, unsigned opNum) {
+bool SparcAsmPrinter::printGetPCX(const MachineInstr *MI, unsigned opNum,
+ raw_ostream &O) {
std::string operand = "";
const MachineOperand &MO = MI->getOperand(opNum);
switch (MO.getType()) {
@@ -155,14 +161,15 @@ bool SparcAsmPrinter::printGetPCX(const MachineInstr *MI, unsigned opNum) {
O << ".LLGETPC" << mfNum << '_' << bbNum << ":\n" ;
O << "\tor\t" << operand
- << ", %lo(_GLOBAL_OFFSET_TABLE_+(.-.LLGETPCH" << mfNum << '_' << bbNum << ")), "
- << operand << '\n';
+ << ", %lo(_GLOBAL_OFFSET_TABLE_+(.-.LLGETPCH" << mfNum << '_' << bbNum
+ << ")), " << operand << '\n';
O << "\tadd\t" << operand << ", %o7, " << operand << '\n';
return true;
}
-void SparcAsmPrinter::printCCOperand(const MachineInstr *MI, int opNum) {
+void SparcAsmPrinter::printCCOperand(const MachineInstr *MI, int opNum,
+ raw_ostream &O) {
int CC = (int)MI->getOperand(opNum).getImm();
O << SPARCCondCodeToString((SPCC::CondCodes)CC);
}
@@ -171,7 +178,8 @@ void SparcAsmPrinter::printCCOperand(const MachineInstr *MI, int opNum) {
///
bool SparcAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
unsigned AsmVariant,
- const char *ExtraCode) {
+ const char *ExtraCode,
+ raw_ostream &O) {
if (ExtraCode && ExtraCode[0]) {
if (ExtraCode[1] != 0) return true; // Unknown modifier.
@@ -182,20 +190,20 @@ bool SparcAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
}
}
- printOperand(MI, OpNo);
+ printOperand(MI, OpNo, O);
return false;
}
bool SparcAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
- unsigned OpNo,
- unsigned AsmVariant,
- const char *ExtraCode) {
+ unsigned OpNo, unsigned AsmVariant,
+ const char *ExtraCode,
+ raw_ostream &O) {
if (ExtraCode && ExtraCode[0])
return true; // Unknown modifier
O << '[';
- printMemOperand(MI, OpNo);
+ printMemOperand(MI, OpNo, O);
O << ']';
return false;
diff --git a/lib/Target/Sparc/Sparc.td b/lib/Target/Sparc/Sparc.td
index 53ea8f4..925d782 100644
--- a/lib/Target/Sparc/Sparc.td
+++ b/lib/Target/Sparc/Sparc.td
@@ -38,11 +38,7 @@ include "SparcRegisterInfo.td"
include "SparcCallingConv.td"
include "SparcInstrInfo.td"
-def SparcInstrInfo : InstrInfo {
- // Define how we want to layout our target-specific information field.
- let TSFlagsFields = [];
- let TSFlagsShifts = [];
-}
+def SparcInstrInfo : InstrInfo;
//===----------------------------------------------------------------------===//
// SPARC processors supported.
diff --git a/lib/Target/Sparc/SparcMCAsmInfo.cpp b/lib/Target/Sparc/SparcMCAsmInfo.cpp
index 53a9bde..535c6f7 100644
--- a/lib/Target/Sparc/SparcMCAsmInfo.cpp
+++ b/lib/Target/Sparc/SparcMCAsmInfo.cpp
@@ -22,7 +22,6 @@ SparcELFMCAsmInfo::SparcELFMCAsmInfo(const Target &T, const StringRef &TT) {
ZeroDirective = "\t.skip\t";
CommentString = "!";
HasLEB128 = true;
- AbsoluteDebugSectionOffsets = true;
SupportsDebugInformation = true;
SunStyleELFSectionSwitchSyntax = true;
diff --git a/lib/Target/SystemZ/AsmPrinter/SystemZAsmPrinter.cpp b/lib/Target/SystemZ/AsmPrinter/SystemZAsmPrinter.cpp
index b29dfcd..07cfb2c 100644
--- a/lib/Target/SystemZ/AsmPrinter/SystemZAsmPrinter.cpp
+++ b/lib/Target/SystemZ/AsmPrinter/SystemZAsmPrinter.cpp
@@ -21,11 +21,9 @@
#include "llvm/Module.h"
#include "llvm/Assembly/Writer.h"
#include "llvm/CodeGen/AsmPrinter.h"
-#include "llvm/CodeGen/DwarfWriter.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineConstantPool.h"
-#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCSymbol.h"
@@ -33,56 +31,52 @@
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetRegistry.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/FormattedStream.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/raw_ostream.h"
using namespace llvm;
namespace {
class SystemZAsmPrinter : public AsmPrinter {
public:
- SystemZAsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
- MCStreamer &Streamer)
- : AsmPrinter(O, TM, Streamer) {}
+ SystemZAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
+ : AsmPrinter(TM, Streamer) {}
virtual const char *getPassName() const {
return "SystemZ Assembly Printer";
}
- void printOperand(const MachineInstr *MI, int OpNum,
+ void printOperand(const MachineInstr *MI, int OpNum, raw_ostream &O,
const char* Modifier = 0);
- void printPCRelImmOperand(const MachineInstr *MI, int OpNum);
- void printRIAddrOperand(const MachineInstr *MI, int OpNum,
+ void printPCRelImmOperand(const MachineInstr *MI, int OpNum, raw_ostream &O);
+ void printRIAddrOperand(const MachineInstr *MI, int OpNum, raw_ostream &O,
const char* Modifier = 0);
- void printRRIAddrOperand(const MachineInstr *MI, int OpNum,
+ void printRRIAddrOperand(const MachineInstr *MI, int OpNum, raw_ostream &O,
const char* Modifier = 0);
- void printS16ImmOperand(const MachineInstr *MI, int OpNum) {
+ void printS16ImmOperand(const MachineInstr *MI, int OpNum, raw_ostream &O) {
O << (int16_t)MI->getOperand(OpNum).getImm();
}
- void printS32ImmOperand(const MachineInstr *MI, int OpNum) {
+ void printS32ImmOperand(const MachineInstr *MI, int OpNum, raw_ostream &O) {
O << (int32_t)MI->getOperand(OpNum).getImm();
}
- void printInstruction(const MachineInstr *MI); // autogenerated.
+ void printInstruction(const MachineInstr *MI, raw_ostream &O);
static const char *getRegisterName(unsigned RegNo);
void EmitInstruction(const MachineInstr *MI);
-
- void getAnalysisUsage(AnalysisUsage &AU) const {
- AsmPrinter::getAnalysisUsage(AU);
- AU.setPreservesAll();
- }
};
} // end of anonymous namespace
#include "SystemZGenAsmWriter.inc"
void SystemZAsmPrinter::EmitInstruction(const MachineInstr *MI) {
- // Call the autogenerated instruction printer routines.
- printInstruction(MI);
- OutStreamer.AddBlankLine();
+ SmallString<128> Str;
+ raw_svector_ostream OS(Str);
+ printInstruction(MI, OS);
+ OutStreamer.EmitRawText(OS.str());
}
-void SystemZAsmPrinter::printPCRelImmOperand(const MachineInstr *MI, int OpNum){
+void SystemZAsmPrinter::printPCRelImmOperand(const MachineInstr *MI, int OpNum,
+ raw_ostream &O) {
const MachineOperand &MO = MI->getOperand(OpNum);
switch (MO.getType()) {
case MachineOperand::MO_Immediate:
@@ -101,7 +95,7 @@ void SystemZAsmPrinter::printPCRelImmOperand(const MachineInstr *MI, int OpNum){
!GV->hasLocalLinkage())
O << "@PLT";
- printOffset(MO.getOffset());
+ printOffset(MO.getOffset(), O);
return;
}
case MachineOperand::MO_ExternalSymbol: {
@@ -121,7 +115,7 @@ void SystemZAsmPrinter::printPCRelImmOperand(const MachineInstr *MI, int OpNum){
void SystemZAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
- const char* Modifier) {
+ raw_ostream &O, const char *Modifier) {
const MachineOperand &MO = MI->getOperand(OpNum);
switch (MO.getType()) {
case MachineOperand::MO_Register: {
@@ -130,9 +124,9 @@ void SystemZAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
unsigned Reg = MO.getReg();
if (Modifier && strncmp(Modifier, "subreg", 6) == 0) {
if (strncmp(Modifier + 7, "even", 4) == 0)
- Reg = TRI->getSubReg(Reg, SystemZ::SUBREG_EVEN);
+ Reg = TM.getRegisterInfo()->getSubReg(Reg, SystemZ::SUBREG_EVEN);
else if (strncmp(Modifier + 7, "odd", 3) == 0)
- Reg = TRI->getSubReg(Reg, SystemZ::SUBREG_ODD);
+ Reg = TM.getRegisterInfo()->getSubReg(Reg, SystemZ::SUBREG_ODD);
else
assert(0 && "Invalid subreg modifier");
}
@@ -155,7 +149,7 @@ void SystemZAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
O << MAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << '_'
<< MO.getIndex();
- printOffset(MO.getOffset());
+ printOffset(MO.getOffset(), O);
break;
case MachineOperand::MO_GlobalAddress:
O << *Mang->getSymbol(MO.getGlobal());
@@ -169,47 +163,48 @@ void SystemZAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
}
switch (MO.getTargetFlags()) {
- default:
- llvm_unreachable("Unknown target flag on GV operand");
+ default: assert(0 && "Unknown target flag on GV operand");
case SystemZII::MO_NO_FLAG:
break;
case SystemZII::MO_GOTENT: O << "@GOTENT"; break;
case SystemZII::MO_PLT: O << "@PLT"; break;
}
- printOffset(MO.getOffset());
+ printOffset(MO.getOffset(), O);
}
void SystemZAsmPrinter::printRIAddrOperand(const MachineInstr *MI, int OpNum,
- const char* Modifier) {
+ raw_ostream &O,
+ const char *Modifier) {
const MachineOperand &Base = MI->getOperand(OpNum);
// Print displacement operand.
- printOperand(MI, OpNum+1);
+ printOperand(MI, OpNum+1, O);
// Print base operand (if any)
if (Base.getReg()) {
O << '(';
- printOperand(MI, OpNum);
+ printOperand(MI, OpNum, O);
O << ')';
}
}
void SystemZAsmPrinter::printRRIAddrOperand(const MachineInstr *MI, int OpNum,
- const char* Modifier) {
+ raw_ostream &O,
+ const char *Modifier) {
const MachineOperand &Base = MI->getOperand(OpNum);
const MachineOperand &Index = MI->getOperand(OpNum+2);
// Print displacement operand.
- printOperand(MI, OpNum+1);
+ printOperand(MI, OpNum+1, O);
// Print base operand (if any)
if (Base.getReg()) {
O << '(';
- printOperand(MI, OpNum);
+ printOperand(MI, OpNum, O);
if (Index.getReg()) {
O << ',';
- printOperand(MI, OpNum+2);
+ printOperand(MI, OpNum+2, O);
}
O << ')';
} else
diff --git a/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.cpp b/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.cpp
index 734a545..0b64cb4 100644
--- a/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.cpp
+++ b/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.cpp
@@ -29,15 +29,18 @@ using namespace llvm;
#include "X86GenAsmWriter.inc"
#undef MachineInstr
-void X86ATTInstPrinter::printInst(const MCInst *MI) { printInstruction(MI); }
+void X86ATTInstPrinter::printInst(const MCInst *MI, raw_ostream &OS) {
+ printInstruction(MI, OS);
+}
StringRef X86ATTInstPrinter::getOpcodeName(unsigned Opcode) const {
return getInstructionName(Opcode);
}
-void X86ATTInstPrinter::printSSECC(const MCInst *MI, unsigned Op) {
+void X86ATTInstPrinter::printSSECC(const MCInst *MI, unsigned Op,
+ raw_ostream &O) {
switch (MI->getOperand(Op).getImm()) {
- default: llvm_unreachable("Invalid ssecc argument!");
+ default: assert(0 && "Invalid ssecc argument!");
case 0: O << "eq"; break;
case 1: O << "lt"; break;
case 2: O << "le"; break;
@@ -53,7 +56,8 @@ void X86ATTInstPrinter::printSSECC(const MCInst *MI, unsigned Op) {
/// being encoded as a pc-relative value (e.g. for jumps and calls). These
/// print slightly differently than normal immediates. For example, a $ is not
/// emitted.
-void X86ATTInstPrinter::print_pcrel_imm(const MCInst *MI, unsigned OpNo) {
+void X86ATTInstPrinter::print_pcrel_imm(const MCInst *MI, unsigned OpNo,
+ raw_ostream &O) {
const MCOperand &Op = MI->getOperand(OpNo);
if (Op.isImm())
// Print this as a signed 32-bit value.
@@ -64,8 +68,8 @@ void X86ATTInstPrinter::print_pcrel_imm(const MCInst *MI, unsigned OpNo) {
}
}
-void X86ATTInstPrinter::printOperand(const MCInst *MI, unsigned OpNo) {
-
+void X86ATTInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
+ raw_ostream &O) {
const MCOperand &Op = MI->getOperand(OpNo);
if (Op.isReg()) {
O << '%' << getRegisterName(Op.getReg());
@@ -81,7 +85,8 @@ void X86ATTInstPrinter::printOperand(const MCInst *MI, unsigned OpNo) {
}
}
-void X86ATTInstPrinter::printLeaMemReference(const MCInst *MI, unsigned Op) {
+void X86ATTInstPrinter::printLeaMemReference(const MCInst *MI, unsigned Op,
+ raw_ostream &O) {
const MCOperand &BaseReg = MI->getOperand(Op);
const MCOperand &IndexReg = MI->getOperand(Op+2);
const MCOperand &DispSpec = MI->getOperand(Op+3);
@@ -98,11 +103,11 @@ void X86ATTInstPrinter::printLeaMemReference(const MCInst *MI, unsigned Op) {
if (IndexReg.getReg() || BaseReg.getReg()) {
O << '(';
if (BaseReg.getReg())
- printOperand(MI, Op);
+ printOperand(MI, Op, O);
if (IndexReg.getReg()) {
O << ',';
- printOperand(MI, Op+2);
+ printOperand(MI, Op+2, O);
unsigned ScaleVal = MI->getOperand(Op+1).getImm();
if (ScaleVal != 1)
O << ',' << ScaleVal;
@@ -111,11 +116,12 @@ void X86ATTInstPrinter::printLeaMemReference(const MCInst *MI, unsigned Op) {
}
}
-void X86ATTInstPrinter::printMemReference(const MCInst *MI, unsigned Op) {
+void X86ATTInstPrinter::printMemReference(const MCInst *MI, unsigned Op,
+ raw_ostream &O) {
// If this has a segment register, print it.
if (MI->getOperand(Op+4).getReg()) {
- printOperand(MI, Op+4);
+ printOperand(MI, Op+4, O);
O << ':';
}
- printLeaMemReference(MI, Op);
+ printLeaMemReference(MI, Op, O);
}
diff --git a/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.h b/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.h
index d109a07..8d5d508 100644
--- a/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.h
+++ b/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.h
@@ -21,63 +21,62 @@ namespace llvm {
class X86ATTInstPrinter : public MCInstPrinter {
public:
- X86ATTInstPrinter(raw_ostream &O, const MCAsmInfo &MAI)
- : MCInstPrinter(O, MAI) {}
+ X86ATTInstPrinter(const MCAsmInfo &MAI) : MCInstPrinter(MAI) {}
- virtual void printInst(const MCInst *MI);
+ virtual void printInst(const MCInst *MI, raw_ostream &OS);
virtual StringRef getOpcodeName(unsigned Opcode) const;
// Autogenerated by tblgen.
- void printInstruction(const MCInst *MI);
+ void printInstruction(const MCInst *MI, raw_ostream &OS);
static const char *getRegisterName(unsigned RegNo);
static const char *getInstructionName(unsigned Opcode);
- void printOperand(const MCInst *MI, unsigned OpNo);
- void printMemReference(const MCInst *MI, unsigned Op);
- void printLeaMemReference(const MCInst *MI, unsigned Op);
- void printSSECC(const MCInst *MI, unsigned Op);
- void print_pcrel_imm(const MCInst *MI, unsigned OpNo);
+ void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &OS);
+ void printMemReference(const MCInst *MI, unsigned Op, raw_ostream &OS);
+ void printLeaMemReference(const MCInst *MI, unsigned Op, raw_ostream &OS);
+ void printSSECC(const MCInst *MI, unsigned Op, raw_ostream &OS);
+ void print_pcrel_imm(const MCInst *MI, unsigned OpNo, raw_ostream &OS);
- void printopaquemem(const MCInst *MI, unsigned OpNo) {
- printMemReference(MI, OpNo);
+ void printopaquemem(const MCInst *MI, unsigned OpNo, raw_ostream &O) {
+ printMemReference(MI, OpNo, O);
}
- void printi8mem(const MCInst *MI, unsigned OpNo) {
- printMemReference(MI, OpNo);
+ void printi8mem(const MCInst *MI, unsigned OpNo, raw_ostream &O) {
+ printMemReference(MI, OpNo, O);
}
- void printi16mem(const MCInst *MI, unsigned OpNo) {
- printMemReference(MI, OpNo);
+ void printi16mem(const MCInst *MI, unsigned OpNo, raw_ostream &O) {
+ printMemReference(MI, OpNo, O);
}
- void printi32mem(const MCInst *MI, unsigned OpNo) {
- printMemReference(MI, OpNo);
+ void printi32mem(const MCInst *MI, unsigned OpNo, raw_ostream &O) {
+ printMemReference(MI, OpNo, O);
}
- void printi64mem(const MCInst *MI, unsigned OpNo) {
- printMemReference(MI, OpNo);
+ void printi64mem(const MCInst *MI, unsigned OpNo, raw_ostream &O) {
+ printMemReference(MI, OpNo, O);
}
- void printi128mem(const MCInst *MI, unsigned OpNo) {
- printMemReference(MI, OpNo);
+ void printi128mem(const MCInst *MI, unsigned OpNo, raw_ostream &O) {
+ printMemReference(MI, OpNo, O);
}
- void printf32mem(const MCInst *MI, unsigned OpNo) {
- printMemReference(MI, OpNo);
+ void printf32mem(const MCInst *MI, unsigned OpNo, raw_ostream &O) {
+ printMemReference(MI, OpNo, O);
}
- void printf64mem(const MCInst *MI, unsigned OpNo) {
- printMemReference(MI, OpNo);
+ void printf64mem(const MCInst *MI, unsigned OpNo, raw_ostream &O) {
+ printMemReference(MI, OpNo, O);
}
- void printf80mem(const MCInst *MI, unsigned OpNo) {
- printMemReference(MI, OpNo);
+ void printf80mem(const MCInst *MI, unsigned OpNo, raw_ostream &O) {
+ printMemReference(MI, OpNo, O);
}
- void printf128mem(const MCInst *MI, unsigned OpNo) {
- printMemReference(MI, OpNo);
+ void printf128mem(const MCInst *MI, unsigned OpNo, raw_ostream &O) {
+ printMemReference(MI, OpNo, O);
}
- void printlea32mem(const MCInst *MI, unsigned OpNo) {
- printLeaMemReference(MI, OpNo);
+ void printlea32mem(const MCInst *MI, unsigned OpNo, raw_ostream &O) {
+ printLeaMemReference(MI, OpNo, O);
}
- void printlea64mem(const MCInst *MI, unsigned OpNo) {
- printLeaMemReference(MI, OpNo);
+ void printlea64mem(const MCInst *MI, unsigned OpNo, raw_ostream &O) {
+ printLeaMemReference(MI, OpNo, O);
}
- void printlea64_32mem(const MCInst *MI, unsigned OpNo) {
- printLeaMemReference(MI, OpNo);
+ void printlea64_32mem(const MCInst *MI, unsigned OpNo, raw_ostream &O) {
+ printLeaMemReference(MI, OpNo, O);
}
};
diff --git a/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp b/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp
index 66bb914..f592396 100644
--- a/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp
+++ b/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp
@@ -36,7 +36,6 @@
#include "llvm/CodeGen/MachineModuleInfoImpls.h"
#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/FormattedStream.h"
#include "llvm/Target/Mangler.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Target/TargetRegistry.h"
@@ -47,7 +46,7 @@ using namespace llvm;
// Primitive Helper Functions.
//===----------------------------------------------------------------------===//
-void X86AsmPrinter::PrintPICBaseSymbol() const {
+void X86AsmPrinter::PrintPICBaseSymbol(raw_ostream &O) const {
const TargetLowering *TLI = TM.getTargetLowering();
O << *static_cast<const X86TargetLowering*>(TLI)->getPICBaseSymbol(MF,
OutContext);
@@ -60,10 +59,11 @@ bool X86AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
if (Subtarget->isTargetCOFF()) {
const Function *F = MF.getFunction();
- O << "\t.def\t " << *CurrentFnSym << ";\t.scl\t" <<
- (F->hasInternalLinkage() ? COFF::C_STAT : COFF::C_EXT)
- << ";\t.type\t" << (COFF::DT_FCN << COFF::N_BTSHFT)
- << ";\t.endef\n";
+ OutStreamer.EmitRawText("\t.def\t " + Twine(CurrentFnSym->getName()) +
+ ";\t.scl\t" +
+ Twine(F->hasInternalLinkage() ? COFF::C_STAT : COFF::C_EXT) +
+ ";\t.type\t" + Twine(COFF::DT_FCN << COFF::N_BTSHFT)
+ + ";\t.endef");
}
// Have common code print out the function header with linkage info etc.
@@ -79,7 +79,8 @@ bool X86AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
/// printSymbolOperand - Print a raw symbol reference operand. This handles
/// jump tables, constant pools, global address and external symbols, all of
/// which print to a label with various suffixes for relocation types etc.
-void X86AsmPrinter::printSymbolOperand(const MachineOperand &MO) {
+void X86AsmPrinter::printSymbolOperand(const MachineOperand &MO,
+ raw_ostream &O) {
switch (MO.getType()) {
default: llvm_unreachable("unknown symbol type!");
case MachineOperand::MO_JumpTableIndex:
@@ -87,7 +88,7 @@ void X86AsmPrinter::printSymbolOperand(const MachineOperand &MO) {
break;
case MachineOperand::MO_ConstantPoolIndex:
O << *GetCPISymbol(MO.getIndex());
- printOffset(MO.getOffset());
+ printOffset(MO.getOffset(), O);
break;
case MachineOperand::MO_GlobalAddress: {
const GlobalValue *GV = MO.getGlobal();
@@ -136,7 +137,7 @@ void X86AsmPrinter::printSymbolOperand(const MachineOperand &MO) {
O << *GVSym;
else
O << '(' << *GVSym << ')';
- printOffset(MO.getOffset());
+ printOffset(MO.getOffset(), O);
break;
}
case MachineOperand::MO_ExternalSymbol: {
@@ -182,14 +183,14 @@ void X86AsmPrinter::printSymbolOperand(const MachineOperand &MO) {
break;
case X86II::MO_GOT_ABSOLUTE_ADDRESS:
O << " + [.-";
- PrintPICBaseSymbol();
+ PrintPICBaseSymbol(O);
O << ']';
break;
case X86II::MO_PIC_BASE_OFFSET:
case X86II::MO_DARWIN_NONLAZY_PIC_BASE:
case X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE:
O << '-';
- PrintPICBaseSymbol();
+ PrintPICBaseSymbol(O);
break;
case X86II::MO_TLSGD: O << "@TLSGD"; break;
case X86II::MO_GOTTPOFF: O << "@GOTTPOFF"; break;
@@ -206,7 +207,8 @@ void X86AsmPrinter::printSymbolOperand(const MachineOperand &MO) {
/// print_pcrel_imm - This is used to print an immediate value that ends up
/// being encoded as a pc-relative value. These print slightly differently, for
/// example, a $ is not emitted.
-void X86AsmPrinter::print_pcrel_imm(const MachineInstr *MI, unsigned OpNo) {
+void X86AsmPrinter::print_pcrel_imm(const MachineInstr *MI, unsigned OpNo,
+ raw_ostream &O) {
const MachineOperand &MO = MI->getOperand(OpNo);
switch (MO.getType()) {
default: llvm_unreachable("Unknown pcrel immediate operand");
@@ -218,14 +220,14 @@ void X86AsmPrinter::print_pcrel_imm(const MachineInstr *MI, unsigned OpNo) {
return;
case MachineOperand::MO_GlobalAddress:
case MachineOperand::MO_ExternalSymbol:
- printSymbolOperand(MO);
+ printSymbolOperand(MO, O);
return;
}
}
void X86AsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
- const char *Modifier) {
+ raw_ostream &O, const char *Modifier) {
const MachineOperand &MO = MI->getOperand(OpNo);
switch (MO.getType()) {
default: llvm_unreachable("unknown operand type!");
@@ -251,13 +253,14 @@ void X86AsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
case MachineOperand::MO_GlobalAddress:
case MachineOperand::MO_ExternalSymbol: {
O << '$';
- printSymbolOperand(MO);
+ printSymbolOperand(MO, O);
break;
}
}
}
-void X86AsmPrinter::printSSECC(const MachineInstr *MI, unsigned Op) {
+void X86AsmPrinter::printSSECC(const MachineInstr *MI, unsigned Op,
+ raw_ostream &O) {
unsigned char value = MI->getOperand(Op).getImm();
assert(value <= 7 && "Invalid ssecc argument!");
switch (value) {
@@ -273,7 +276,7 @@ void X86AsmPrinter::printSSECC(const MachineInstr *MI, unsigned Op) {
}
void X86AsmPrinter::printLeaMemReference(const MachineInstr *MI, unsigned Op,
- const char *Modifier) {
+ raw_ostream &O, const char *Modifier) {
const MachineOperand &BaseReg = MI->getOperand(Op);
const MachineOperand &IndexReg = MI->getOperand(Op+2);
const MachineOperand &DispSpec = MI->getOperand(Op+3);
@@ -294,7 +297,7 @@ void X86AsmPrinter::printLeaMemReference(const MachineInstr *MI, unsigned Op,
} else {
assert(DispSpec.isGlobal() || DispSpec.isCPI() ||
DispSpec.isJTI() || DispSpec.isSymbol());
- printSymbolOperand(MI->getOperand(Op+3));
+ printSymbolOperand(MI->getOperand(Op+3), O);
}
if (HasParenPart) {
@@ -303,11 +306,11 @@ void X86AsmPrinter::printLeaMemReference(const MachineInstr *MI, unsigned Op,
O << '(';
if (HasBaseReg)
- printOperand(MI, Op, Modifier);
+ printOperand(MI, Op, O, Modifier);
if (IndexReg.getReg()) {
O << ',';
- printOperand(MI, Op+2, Modifier);
+ printOperand(MI, Op+2, O, Modifier);
unsigned ScaleVal = MI->getOperand(Op+1).getImm();
if (ScaleVal != 1)
O << ',' << ScaleVal;
@@ -317,24 +320,26 @@ void X86AsmPrinter::printLeaMemReference(const MachineInstr *MI, unsigned Op,
}
void X86AsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op,
- const char *Modifier) {
+ raw_ostream &O, const char *Modifier) {
assert(isMem(MI, Op) && "Invalid memory reference!");
const MachineOperand &Segment = MI->getOperand(Op+4);
if (Segment.getReg()) {
- printOperand(MI, Op+4, Modifier);
+ printOperand(MI, Op+4, O, Modifier);
O << ':';
}
- printLeaMemReference(MI, Op, Modifier);
+ printLeaMemReference(MI, Op, O, Modifier);
}
-void X86AsmPrinter::printPICLabel(const MachineInstr *MI, unsigned Op) {
- PrintPICBaseSymbol();
+void X86AsmPrinter::printPICLabel(const MachineInstr *MI, unsigned Op,
+ raw_ostream &O) {
+ PrintPICBaseSymbol(O);
O << '\n';
- PrintPICBaseSymbol();
+ PrintPICBaseSymbol(O);
O << ':';
}
-bool X86AsmPrinter::printAsmMRegister(const MachineOperand &MO, char Mode) {
+bool X86AsmPrinter::printAsmMRegister(const MachineOperand &MO, char Mode,
+ raw_ostream &O) {
unsigned Reg = MO.getReg();
switch (Mode) {
default: return true; // Unknown mode.
@@ -363,7 +368,7 @@ bool X86AsmPrinter::printAsmMRegister(const MachineOperand &MO, char Mode) {
///
bool X86AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
unsigned AsmVariant,
- const char *ExtraCode) {
+ const char *ExtraCode, raw_ostream &O) {
// Does this asm operand have a single letter operand modifier?
if (ExtraCode && ExtraCode[0]) {
if (ExtraCode[1] != 0) return true; // Unknown modifier.
@@ -378,12 +383,12 @@ bool X86AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
return false;
}
if (MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isSymbol()) {
- printSymbolOperand(MO);
+ printSymbolOperand(MO, O);
return false;
}
if (MO.isReg()) {
O << '(';
- printOperand(MI, OpNo);
+ printOperand(MI, OpNo, O);
O << ')';
return false;
}
@@ -393,15 +398,15 @@ bool X86AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
if (MO.isImm())
O << MO.getImm();
else if (MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isSymbol())
- printSymbolOperand(MO);
+ printSymbolOperand(MO, O);
else
- printOperand(MI, OpNo);
+ printOperand(MI, OpNo, O);
return false;
case 'A': // Print '*' before a register (it must be a register)
if (MO.isReg()) {
O << '*';
- printOperand(MI, OpNo);
+ printOperand(MI, OpNo, O);
return false;
}
return true;
@@ -412,12 +417,12 @@ bool X86AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
case 'k': // Print SImode register
case 'q': // Print DImode register
if (MO.isReg())
- return printAsmMRegister(MO, ExtraCode[0]);
- printOperand(MI, OpNo);
+ return printAsmMRegister(MO, ExtraCode[0], O);
+ printOperand(MI, OpNo, O);
return false;
case 'P': // This is the operand of a call, treat specially.
- print_pcrel_imm(MI, OpNo);
+ print_pcrel_imm(MI, OpNo, O);
return false;
case 'n': // Negate the immediate or print a '-' before the operand.
@@ -431,13 +436,14 @@ bool X86AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
}
}
- printOperand(MI, OpNo);
+ printOperand(MI, OpNo, O);
return false;
}
bool X86AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
unsigned OpNo, unsigned AsmVariant,
- const char *ExtraCode) {
+ const char *ExtraCode,
+ raw_ostream &O) {
if (ExtraCode && ExtraCode[0]) {
if (ExtraCode[1] != 0) return true; // Unknown modifier.
@@ -451,11 +457,11 @@ bool X86AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
// These only apply to registers, ignore on mem.
break;
case 'P': // Don't print @PLT, but do print as memory.
- printMemReference(MI, OpNo, "no-rip");
+ printMemReference(MI, OpNo, O, "no-rip");
return false;
}
}
- printMemReference(MI, OpNo);
+ printMemReference(MI, OpNo, O);
return false;
}
@@ -570,10 +576,11 @@ void X86AsmPrinter::EmitEndOfAsmFile(Module &M) {
// Emit type information for external functions
for (X86COFFMachineModuleInfo::stub_iterator I = COFFMMI.stub_begin(),
E = COFFMMI.stub_end(); I != E; ++I) {
- O << "\t.def\t " << I->getKeyData()
- << ";\t.scl\t" << COFF::C_EXT
- << ";\t.type\t" << (COFF::DT_FCN << COFF::N_BTSHFT)
- << ";\t.endef\n";
+ OutStreamer.EmitRawText("\t.def\t " + Twine(I->getKeyData()) +
+ ";\t.scl\t" + Twine(COFF::C_EXT) +
+ ";\t.type\t" +
+ Twine(COFF::DT_FCN << COFF::N_BTSHFT) +
+ ";\t.endef");
}
if (Subtarget->isTargetCygMing()) {
@@ -598,10 +605,13 @@ void X86AsmPrinter::EmitEndOfAsmFile(Module &M) {
true,
SectionKind::getMetadata()));
for (unsigned i = 0, e = DLLExportedGlobals.size(); i != e; ++i)
- O << "\t.ascii \" -export:" << *DLLExportedGlobals[i] << ",data\"\n";
+ OutStreamer.EmitRawText("\t.ascii \" -export:" +
+ Twine(DLLExportedGlobals[i]->getName()) +
+ ",data\"");
for (unsigned i = 0, e = DLLExportedFns.size(); i != e; ++i)
- O << "\t.ascii \" -export:" << *DLLExportedFns[i] << "\"\n";
+ OutStreamer.EmitRawText("\t.ascii \" -export:" +
+ Twine(DLLExportedFns[i]->getName()) + "\"");
}
}
}
@@ -618,12 +628,11 @@ void X86AsmPrinter::EmitEndOfAsmFile(Module &M) {
OutStreamer.SwitchSection(TLOFELF.getDataRelSection());
const TargetData *TD = TM.getTargetData();
- for (unsigned i = 0, e = Stubs.size(); i != e; ++i)
- O << *Stubs[i].first << ":\n"
- << (TD->getPointerSize() == 8 ?
- MAI->getData64bitsDirective() : MAI->getData32bitsDirective())
- << *Stubs[i].second.getPointer() << '\n';
-
+ for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
+ OutStreamer.EmitLabel(Stubs[i].first);
+ OutStreamer.EmitSymbolValue(Stubs[i].second.getPointer(),
+ TD->getPointerSize(), 0);
+ }
Stubs.clear();
}
}
@@ -636,12 +645,11 @@ void X86AsmPrinter::EmitEndOfAsmFile(Module &M) {
static MCInstPrinter *createX86MCInstPrinter(const Target &T,
unsigned SyntaxVariant,
- const MCAsmInfo &MAI,
- raw_ostream &O) {
+ const MCAsmInfo &MAI) {
if (SyntaxVariant == 0)
- return new X86ATTInstPrinter(O, MAI);
+ return new X86ATTInstPrinter(MAI);
if (SyntaxVariant == 1)
- return new X86IntelInstPrinter(O, MAI);
+ return new X86IntelInstPrinter(MAI);
return 0;
}
diff --git a/lib/Target/X86/AsmPrinter/X86AsmPrinter.h b/lib/Target/X86/AsmPrinter/X86AsmPrinter.h
index 28c25f9..ee59289 100644
--- a/lib/Target/X86/AsmPrinter/X86AsmPrinter.h
+++ b/lib/Target/X86/AsmPrinter/X86AsmPrinter.h
@@ -19,7 +19,6 @@
#include "../X86TargetMachine.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/CodeGen/AsmPrinter.h"
-#include "llvm/CodeGen/DwarfWriter.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/Support/Compiler.h"
@@ -35,9 +34,8 @@ class MCSymbol;
class VISIBILITY_HIDDEN X86AsmPrinter : public AsmPrinter {
const X86Subtarget *Subtarget;
public:
- explicit X86AsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
- MCStreamer &Streamer)
- : AsmPrinter(O, TM, Streamer) {
+ explicit X86AsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
+ : AsmPrinter(TM, Streamer) {
Subtarget = &TM.getSubtarget<X86Subtarget>();
}
@@ -47,85 +45,41 @@ class VISIBILITY_HIDDEN X86AsmPrinter : public AsmPrinter {
const X86Subtarget &getSubtarget() const { return *Subtarget; }
- void getAnalysisUsage(AnalysisUsage &AU) const {
- AU.setPreservesAll();
- AU.addRequired<MachineModuleInfo>();
- AU.addRequired<DwarfWriter>();
- AsmPrinter::getAnalysisUsage(AU);
- }
-
virtual void EmitStartOfAsmFile(Module &M);
virtual void EmitEndOfAsmFile(Module &M);
virtual void EmitInstruction(const MachineInstr *MI);
- void printSymbolOperand(const MachineOperand &MO);
+ void printSymbolOperand(const MachineOperand &MO, raw_ostream &O);
// These methods are used by the tablegen'erated instruction printer.
- void printOperand(const MachineInstr *MI, unsigned OpNo,
+ void printOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O,
const char *Modifier = 0);
- void print_pcrel_imm(const MachineInstr *MI, unsigned OpNo);
-
- void printopaquemem(const MachineInstr *MI, unsigned OpNo) {
- printMemReference(MI, OpNo);
- }
-
- void printi8mem(const MachineInstr *MI, unsigned OpNo) {
- printMemReference(MI, OpNo);
- }
- void printi16mem(const MachineInstr *MI, unsigned OpNo) {
- printMemReference(MI, OpNo);
- }
- void printi32mem(const MachineInstr *MI, unsigned OpNo) {
- printMemReference(MI, OpNo);
- }
- void printi64mem(const MachineInstr *MI, unsigned OpNo) {
- printMemReference(MI, OpNo);
- }
- void printi128mem(const MachineInstr *MI, unsigned OpNo) {
- printMemReference(MI, OpNo);
- }
- void printf32mem(const MachineInstr *MI, unsigned OpNo) {
- printMemReference(MI, OpNo);
- }
- void printf64mem(const MachineInstr *MI, unsigned OpNo) {
- printMemReference(MI, OpNo);
- }
- void printf80mem(const MachineInstr *MI, unsigned OpNo) {
- printMemReference(MI, OpNo);
- }
- void printf128mem(const MachineInstr *MI, unsigned OpNo) {
- printMemReference(MI, OpNo);
- }
- void printlea32mem(const MachineInstr *MI, unsigned OpNo) {
- printLeaMemReference(MI, OpNo);
- }
- void printlea64mem(const MachineInstr *MI, unsigned OpNo) {
- printLeaMemReference(MI, OpNo);
- }
- void printlea64_32mem(const MachineInstr *MI, unsigned OpNo) {
- printLeaMemReference(MI, OpNo, "subreg64");
- }
+ void print_pcrel_imm(const MachineInstr *MI, unsigned OpNo, raw_ostream &O);
- bool printAsmMRegister(const MachineOperand &MO, char Mode);
+ bool printAsmMRegister(const MachineOperand &MO, char Mode, raw_ostream &O);
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
- unsigned AsmVariant, const char *ExtraCode);
+ unsigned AsmVariant, const char *ExtraCode,
+ raw_ostream &OS);
bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
- unsigned AsmVariant, const char *ExtraCode);
+ unsigned AsmVariant, const char *ExtraCode,
+ raw_ostream &OS);
void printMachineInstruction(const MachineInstr *MI);
- void printSSECC(const MachineInstr *MI, unsigned Op);
- void printMemReference(const MachineInstr *MI, unsigned Op,
+ void printSSECC(const MachineInstr *MI, unsigned Op, raw_ostream &O);
+ void printMemReference(const MachineInstr *MI, unsigned Op, raw_ostream &O,
const char *Modifier=NULL);
- void printLeaMemReference(const MachineInstr *MI, unsigned Op,
+ void printLeaMemReference(const MachineInstr *MI, unsigned Op, raw_ostream &O,
const char *Modifier=NULL);
- void printPICLabel(const MachineInstr *MI, unsigned Op);
+ void printPICLabel(const MachineInstr *MI, unsigned Op, raw_ostream &O);
- void PrintPICBaseSymbol() const;
+ void PrintPICBaseSymbol(raw_ostream &O) const;
bool runOnMachineFunction(MachineFunction &F);
+
+ void PrintDebugValueComment(const MachineInstr *MI, raw_ostream &OS);
};
} // end namespace llvm
diff --git a/lib/Target/X86/AsmPrinter/X86IntelInstPrinter.cpp b/lib/Target/X86/AsmPrinter/X86IntelInstPrinter.cpp
index 610beb5..7e0a9bb 100644
--- a/lib/Target/X86/AsmPrinter/X86IntelInstPrinter.cpp
+++ b/lib/Target/X86/AsmPrinter/X86IntelInstPrinter.cpp
@@ -28,14 +28,17 @@ using namespace llvm;
#include "X86GenAsmWriter1.inc"
#undef MachineInstr
-void X86IntelInstPrinter::printInst(const MCInst *MI) { printInstruction(MI); }
+void X86IntelInstPrinter::printInst(const MCInst *MI, raw_ostream &OS) {
+ printInstruction(MI, OS);
+}
StringRef X86IntelInstPrinter::getOpcodeName(unsigned Opcode) const {
return getInstructionName(Opcode);
}
-void X86IntelInstPrinter::printSSECC(const MCInst *MI, unsigned Op) {
+void X86IntelInstPrinter::printSSECC(const MCInst *MI, unsigned Op,
+ raw_ostream &O) {
switch (MI->getOperand(Op).getImm()) {
- default: llvm_unreachable("Invalid ssecc argument!");
+ default: assert(0 && "Invalid ssecc argument!");
case 0: O << "eq"; break;
case 1: O << "lt"; break;
case 2: O << "le"; break;
@@ -49,7 +52,8 @@ void X86IntelInstPrinter::printSSECC(const MCInst *MI, unsigned Op) {
/// print_pcrel_imm - This is used to print an immediate value that ends up
/// being encoded as a pc-relative value.
-void X86IntelInstPrinter::print_pcrel_imm(const MCInst *MI, unsigned OpNo) {
+void X86IntelInstPrinter::print_pcrel_imm(const MCInst *MI, unsigned OpNo,
+ raw_ostream &O) {
const MCOperand &Op = MI->getOperand(OpNo);
if (Op.isImm())
O << Op.getImm();
@@ -65,9 +69,7 @@ static void PrintRegName(raw_ostream &O, StringRef RegName) {
}
void X86IntelInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
- const char *Modifier) {
- assert(Modifier == 0 && "Modifiers should not be used");
-
+ raw_ostream &O) {
const MCOperand &Op = MI->getOperand(OpNo);
if (Op.isReg()) {
PrintRegName(O, getRegisterName(Op.getReg()));
@@ -79,7 +81,8 @@ void X86IntelInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
}
}
-void X86IntelInstPrinter::printLeaMemReference(const MCInst *MI, unsigned Op) {
+void X86IntelInstPrinter::printLeaMemReference(const MCInst *MI, unsigned Op,
+ raw_ostream &O) {
const MCOperand &BaseReg = MI->getOperand(Op);
unsigned ScaleVal = MI->getOperand(Op+1).getImm();
const MCOperand &IndexReg = MI->getOperand(Op+2);
@@ -89,7 +92,7 @@ void X86IntelInstPrinter::printLeaMemReference(const MCInst *MI, unsigned Op) {
bool NeedPlus = false;
if (BaseReg.getReg()) {
- printOperand(MI, Op);
+ printOperand(MI, Op, O);
NeedPlus = true;
}
@@ -97,7 +100,7 @@ void X86IntelInstPrinter::printLeaMemReference(const MCInst *MI, unsigned Op) {
if (NeedPlus) O << " + ";
if (ScaleVal != 1)
O << ScaleVal << '*';
- printOperand(MI, Op+2);
+ printOperand(MI, Op+2, O);
NeedPlus = true;
}
@@ -124,11 +127,12 @@ void X86IntelInstPrinter::printLeaMemReference(const MCInst *MI, unsigned Op) {
O << ']';
}
-void X86IntelInstPrinter::printMemReference(const MCInst *MI, unsigned Op) {
+void X86IntelInstPrinter::printMemReference(const MCInst *MI, unsigned Op,
+ raw_ostream &O) {
// If this has a segment register, print it.
if (MI->getOperand(Op+4).getReg()) {
- printOperand(MI, Op+4);
+ printOperand(MI, Op+4, O);
O << ':';
}
- printLeaMemReference(MI, Op);
+ printLeaMemReference(MI, Op, O);
}
diff --git a/lib/Target/X86/AsmPrinter/X86IntelInstPrinter.h b/lib/Target/X86/AsmPrinter/X86IntelInstPrinter.h
index 545bf84..a0beeb2 100644
--- a/lib/Target/X86/AsmPrinter/X86IntelInstPrinter.h
+++ b/lib/Target/X86/AsmPrinter/X86IntelInstPrinter.h
@@ -22,77 +22,76 @@ namespace llvm {
class X86IntelInstPrinter : public MCInstPrinter {
public:
- X86IntelInstPrinter(raw_ostream &O, const MCAsmInfo &MAI)
- : MCInstPrinter(O, MAI) {}
+ X86IntelInstPrinter(const MCAsmInfo &MAI)
+ : MCInstPrinter(MAI) {}
- virtual void printInst(const MCInst *MI);
+ virtual void printInst(const MCInst *MI, raw_ostream &OS);
virtual StringRef getOpcodeName(unsigned Opcode) const;
// Autogenerated by tblgen.
- void printInstruction(const MCInst *MI);
+ void printInstruction(const MCInst *MI, raw_ostream &O);
static const char *getRegisterName(unsigned RegNo);
static const char *getInstructionName(unsigned Opcode);
- void printOperand(const MCInst *MI, unsigned OpNo,
- const char *Modifier = 0);
- void printMemReference(const MCInst *MI, unsigned Op);
- void printLeaMemReference(const MCInst *MI, unsigned Op);
- void printSSECC(const MCInst *MI, unsigned Op);
- void print_pcrel_imm(const MCInst *MI, unsigned OpNo);
+ void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
+ void printMemReference(const MCInst *MI, unsigned Op, raw_ostream &O);
+ void printLeaMemReference(const MCInst *MI, unsigned Op, raw_ostream &O);
+ void printSSECC(const MCInst *MI, unsigned Op, raw_ostream &O);
+ void print_pcrel_imm(const MCInst *MI, unsigned OpNo, raw_ostream &O);
- void printopaquemem(const MCInst *MI, unsigned OpNo) {
+ void printopaquemem(const MCInst *MI, unsigned OpNo, raw_ostream &O) {
O << "OPAQUE PTR ";
- printMemReference(MI, OpNo);
+ printMemReference(MI, OpNo, O);
}
- void printi8mem(const MCInst *MI, unsigned OpNo) {
+ void printi8mem(const MCInst *MI, unsigned OpNo, raw_ostream &O) {
O << "BYTE PTR ";
- printMemReference(MI, OpNo);
+ printMemReference(MI, OpNo, O);
}
- void printi16mem(const MCInst *MI, unsigned OpNo) {
+ void printi16mem(const MCInst *MI, unsigned OpNo, raw_ostream &O) {
O << "WORD PTR ";
- printMemReference(MI, OpNo);
+ printMemReference(MI, OpNo, O);
}
- void printi32mem(const MCInst *MI, unsigned OpNo) {
+ void printi32mem(const MCInst *MI, unsigned OpNo, raw_ostream &O) {
O << "DWORD PTR ";
- printMemReference(MI, OpNo);
+ printMemReference(MI, OpNo, O);
}
- void printi64mem(const MCInst *MI, unsigned OpNo) {
+ void printi64mem(const MCInst *MI, unsigned OpNo, raw_ostream &O) {
O << "QWORD PTR ";
- printMemReference(MI, OpNo);
+ printMemReference(MI, OpNo, O);
}
- void printi128mem(const MCInst *MI, unsigned OpNo) {
+ void printi128mem(const MCInst *MI, unsigned OpNo, raw_ostream &O) {
O << "XMMWORD PTR ";
- printMemReference(MI, OpNo);
+ printMemReference(MI, OpNo, O);
}
- void printf32mem(const MCInst *MI, unsigned OpNo) {
+ void printf32mem(const MCInst *MI, unsigned OpNo, raw_ostream &O) {
O << "DWORD PTR ";
- printMemReference(MI, OpNo);
+ printMemReference(MI, OpNo, O);
}
- void printf64mem(const MCInst *MI, unsigned OpNo) {
+ void printf64mem(const MCInst *MI, unsigned OpNo, raw_ostream &O) {
O << "QWORD PTR ";
- printMemReference(MI, OpNo);
+ printMemReference(MI, OpNo, O);
}
- void printf80mem(const MCInst *MI, unsigned OpNo) {
+ void printf80mem(const MCInst *MI, unsigned OpNo, raw_ostream &O) {
O << "XWORD PTR ";
- printMemReference(MI, OpNo);
+ printMemReference(MI, OpNo, O);
}
- void printf128mem(const MCInst *MI, unsigned OpNo) {
+ void printf128mem(const MCInst *MI, unsigned OpNo, raw_ostream &O) {
O << "XMMWORD PTR ";
- printMemReference(MI, OpNo);
+ printMemReference(MI, OpNo, O);
}
- void printlea32mem(const MCInst *MI, unsigned OpNo) {
+ void printlea32mem(const MCInst *MI, unsigned OpNo, raw_ostream &O) {
O << "DWORD PTR ";
- printLeaMemReference(MI, OpNo);
+ printLeaMemReference(MI, OpNo, O);
}
- void printlea64mem(const MCInst *MI, unsigned OpNo) {
+ void printlea64mem(const MCInst *MI, unsigned OpNo, raw_ostream &O) {
O << "QWORD PTR ";
- printLeaMemReference(MI, OpNo);
+ printLeaMemReference(MI, OpNo, O);
}
- void printlea64_32mem(const MCInst *MI, unsigned OpNo) {
+ void printlea64_32mem(const MCInst *MI, unsigned OpNo, raw_ostream &O) {
O << "QWORD PTR ";
- printLeaMemReference(MI, OpNo);
+ printLeaMemReference(MI, OpNo, O);
}
};
diff --git a/lib/Target/X86/AsmPrinter/X86MCInstLower.cpp b/lib/Target/X86/AsmPrinter/X86MCInstLower.cpp
index c851ca3..a290eb0 100644
--- a/lib/Target/X86/AsmPrinter/X86MCInstLower.cpp
+++ b/lib/Target/X86/AsmPrinter/X86MCInstLower.cpp
@@ -326,70 +326,76 @@ void X86MCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
}
}
+void X86AsmPrinter::PrintDebugValueComment(const MachineInstr *MI,
+ raw_ostream &O) {
+ // FIXME: if this is implemented for another target before it goes
+ // away completely, the common part should be moved into AsmPrinter.
+ O << '\t' << MAI->getCommentString() << "DEBUG_VALUE: ";
+ unsigned NOps = MI->getNumOperands();
+ // cast away const; DIetc do not take const operands for some reason.
+ DIVariable V((MDNode*)(MI->getOperand(NOps-1).getMetadata()));
+ O << V.getName();
+ O << " <- ";
+ if (NOps==3) {
+ // Register or immediate value. Register 0 means undef.
+ assert(MI->getOperand(0).isReg() ||
+ MI->getOperand(0).isImm() ||
+ MI->getOperand(0).isFPImm());
+ if (MI->getOperand(0).isReg() && MI->getOperand(0).getReg() == 0) {
+ // Suppress offset in this case, it is not meaningful.
+ O << "undef";
+ OutStreamer.AddBlankLine();
+ return;
+ }
+
+ if (MI->getOperand(0).isFPImm()) {
+ // This is more naturally done in printOperand, but since the only use
+ // of such an operand is in this comment and that is temporary (and it's
+ // ugly), we prefer to keep this localized.
+ // The include of Type.h may be removable when this code is.
+ if (MI->getOperand(0).getFPImm()->getType()->isFloatTy() ||
+ MI->getOperand(0).getFPImm()->getType()->isDoubleTy())
+ MI->getOperand(0).print(O, &TM);
+ else {
+ // There is no good way to print long double. Convert a copy to
+ // double. Ah well, it's only a comment.
+ bool ignored;
+ APFloat APF = APFloat(MI->getOperand(0).getFPImm()->getValueAPF());
+ APF.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven,
+ &ignored);
+ O << "(long double) " << APF.convertToDouble();
+ }
+ } else
+ printOperand(MI, 0, O);
+ } else {
+ if (MI->getOperand(0).isReg() && MI->getOperand(0).getReg() == 0) {
+ // Suppress offset in this case, it is not meaningful.
+ O << "undef";
+ OutStreamer.AddBlankLine();
+ return;
+ }
+ // Frame address. Currently handles register +- offset only.
+ assert(MI->getOperand(0).isReg() && MI->getOperand(3).isImm());
+ O << '['; printOperand(MI, 0, O); O << '+'; printOperand(MI, 3, O);
+ O << ']';
+ }
+ O << "+";
+ printOperand(MI, NOps-2, O);
+}
void X86AsmPrinter::EmitInstruction(const MachineInstr *MI) {
X86MCInstLower MCInstLowering(OutContext, Mang, *this);
switch (MI->getOpcode()) {
- case TargetOpcode::DBG_VALUE: {
- // FIXME: if this is implemented for another target before it goes
- // away completely, the common part should be moved into AsmPrinter.
- if (!VerboseAsm)
- return;
- O << '\t' << MAI->getCommentString() << "DEBUG_VALUE: ";
- unsigned NOps = MI->getNumOperands();
- // cast away const; DIetc do not take const operands for some reason.
- DIVariable V((MDNode*)(MI->getOperand(NOps-1).getMetadata()));
- O << V.getName();
- O << " <- ";
- if (NOps==3) {
- // Register or immediate value. Register 0 means undef.
- assert(MI->getOperand(0).getType()==MachineOperand::MO_Register ||
- MI->getOperand(0).getType()==MachineOperand::MO_Immediate ||
- MI->getOperand(0).getType()==MachineOperand::MO_FPImmediate);
- if (MI->getOperand(0).getType()==MachineOperand::MO_Register &&
- MI->getOperand(0).getReg()==0) {
- // Suppress offset in this case, it is not meaningful.
- O << "undef";
- OutStreamer.AddBlankLine();
- return;
- } else if (MI->getOperand(0).getType()==MachineOperand::MO_FPImmediate) {
- // This is more naturally done in printOperand, but since the only use
- // of such an operand is in this comment and that is temporary (and it's
- // ugly), we prefer to keep this localized.
- // The include of Type.h may be removable when this code is.
- if (MI->getOperand(0).getFPImm()->getType()->isFloatTy() ||
- MI->getOperand(0).getFPImm()->getType()->isDoubleTy())
- MI->getOperand(0).print(O, &TM);
- else {
- // There is no good way to print long double. Convert a copy to
- // double. Ah well, it's only a comment.
- bool ignored;
- APFloat APF = APFloat(MI->getOperand(0).getFPImm()->getValueAPF());
- APF.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven,
- &ignored);
- O << "(long double) " << APF.convertToDouble();
- }
- } else
- printOperand(MI, 0);
- } else {
- if (MI->getOperand(0).getType()==MachineOperand::MO_Register &&
- MI->getOperand(0).getReg()==0) {
- // Suppress offset in this case, it is not meaningful.
- O << "undef";
- OutStreamer.AddBlankLine();
- return;
- }
- // Frame address. Currently handles register +- offset only.
- assert(MI->getOperand(0).getType()==MachineOperand::MO_Register);
- assert(MI->getOperand(3).getType()==MachineOperand::MO_Immediate);
- O << '['; printOperand(MI, 0); O << '+'; printOperand(MI, 3); O << ']';
+ case TargetOpcode::DBG_VALUE:
+ if (isVerbose() && OutStreamer.hasRawTextSupport()) {
+ std::string TmpStr;
+ raw_string_ostream OS(TmpStr);
+ PrintDebugValueComment(MI, OS);
+ OutStreamer.EmitRawText(StringRef(OS.str()));
}
- O << "+";
- printOperand(MI, NOps-2);
- OutStreamer.AddBlankLine();
return;
- }
+
case X86::MOVPC32r: {
MCInst TmpInst;
// This is a pseudo op for a two instruction sequence with a label, which
diff --git a/lib/Target/X86/SSEDomainFix.cpp b/lib/Target/X86/SSEDomainFix.cpp
index 395ab57..4b54676 100644
--- a/lib/Target/X86/SSEDomainFix.cpp
+++ b/lib/Target/X86/SSEDomainFix.cpp
@@ -23,49 +23,11 @@
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/ADT/DepthFirstIterator.h"
+#include "llvm/Support/Allocator.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
-namespace {
-
-/// Allocate objects from a pool, allow objects to be recycled, and provide a
-/// way of deleting everything.
-template<typename T, unsigned PageSize = 64>
-class PoolAllocator {
- std::vector<T*> Pages, Avail;
-public:
- ~PoolAllocator() { Clear(); }
-
- T* Alloc() {
- if (Avail.empty()) {
- T *p = new T[PageSize];
- Pages.push_back(p);
- Avail.reserve(PageSize);
- for (unsigned n = 0; n != PageSize; ++n)
- Avail.push_back(p+n);
- }
- T *p = Avail.back();
- Avail.pop_back();
- return p;
- }
-
- // Allow object to be reallocated. It won't be reconstructed.
- void Recycle(T *p) {
- p->clear();
- Avail.push_back(p);
- }
-
- // Destroy all objects, make sure there are no external pointers to them.
- void Clear() {
- Avail.clear();
- while (!Pages.empty()) {
- delete[] Pages.back();
- Pages.pop_back();
- }
- }
-};
-
/// A DomainValue is a bit like LiveIntervals' ValNo, but it also keeps track
/// of execution domains.
///
@@ -81,14 +43,15 @@ public:
/// domain, but if we were forced to pay the penalty of a domain crossing, we
/// keep track of the fact the the register is now available in multiple
/// domains.
+namespace {
struct DomainValue {
// Basic reference counting.
unsigned Refs;
- // Available domains. For an open DomainValue, it is the still possible
- // domains for collapsing. For a collapsed DomainValue it is the domains where
- // the register is available for free.
- unsigned Mask;
+ // Bitmask of available domains. For an open DomainValue, it is the still
+ // possible domains for collapsing. For a collapsed DomainValue it is the
+ // domains where the register is available for free.
+ unsigned AvailableDomains;
// Position of the last defining instruction.
unsigned Dist;
@@ -96,38 +59,51 @@ struct DomainValue {
// Twiddleable instructions using or defining these registers.
SmallVector<MachineInstr*, 8> Instrs;
- // Collapsed DomainValue have no instructions to twiddle - it simply keeps
+ // A collapsed DomainValue has no instructions to twiddle - it simply keeps
// track of the domains where the registers are already available.
- bool collapsed() const { return Instrs.empty(); }
+ bool isCollapsed() const { return Instrs.empty(); }
- // Is any domain in mask available?
- bool compat(unsigned mask) const {
- return Mask & mask;
+ // Is domain available?
+ bool hasDomain(unsigned domain) const {
+ return AvailableDomains & (1u << domain);
}
// Mark domain as available.
- void add(unsigned domain) {
- Mask |= 1u << domain;
+ void addDomain(unsigned domain) {
+ AvailableDomains |= 1u << domain;
+ }
+
+ // Restrict to a single domain available.
+ void setSingleDomain(unsigned domain) {
+ AvailableDomains = 1u << domain;
+ }
+
+ // Return bitmask of domains that are available and in mask.
+ unsigned getCommonDomains(unsigned mask) const {
+ return AvailableDomains & mask;
}
- // First domain available in mask.
- unsigned firstDomain() const {
- return CountTrailingZeros_32(Mask);
+ // First domain available.
+ unsigned getFirstDomain() const {
+ return CountTrailingZeros_32(AvailableDomains);
}
DomainValue() { clear(); }
void clear() {
- Refs = Mask = Dist = 0;
+ Refs = AvailableDomains = Dist = 0;
Instrs.clear();
}
};
+}
static const unsigned NumRegs = 16;
+namespace {
class SSEDomainFixPass : public MachineFunctionPass {
static char ID;
- PoolAllocator<DomainValue> Pool;
+ SpecificBumpPtrAllocator<DomainValue> Allocator;
+ SmallVector<DomainValue*,16> Avail;
MachineFunction *MF;
const X86InstrInfo *TII;
@@ -156,6 +132,10 @@ private:
// Register mapping.
int RegIndex(unsigned Reg);
+ // DomainValue allocation.
+ DomainValue *Alloc(int domain = -1);
+ void Recycle(DomainValue*);
+
// LiveRegs manipulations.
void SetLiveReg(int rx, DomainValue *DV);
void Kill(int rx);
@@ -182,17 +162,35 @@ int SSEDomainFixPass::RegIndex(unsigned reg) {
return reg < NumRegs ? reg : -1;
}
+DomainValue *SSEDomainFixPass::Alloc(int domain) {
+ DomainValue *dv = Avail.empty() ?
+ new(Allocator.Allocate()) DomainValue :
+ Avail.pop_back_val();
+ dv->Dist = Distance;
+ if (domain >= 0)
+ dv->addDomain(domain);
+ return dv;
+}
+
+void SSEDomainFixPass::Recycle(DomainValue *dv) {
+ assert(dv && "Cannot recycle NULL");
+ dv->clear();
+ Avail.push_back(dv);
+}
+
/// Set LiveRegs[rx] = dv, updating reference counts.
void SSEDomainFixPass::SetLiveReg(int rx, DomainValue *dv) {
assert(unsigned(rx) < NumRegs && "Invalid index");
- if (!LiveRegs)
- LiveRegs = (DomainValue**)calloc(sizeof(DomainValue*), NumRegs);
+ if (!LiveRegs) {
+ LiveRegs = new DomainValue*[NumRegs];
+ std::fill(LiveRegs, LiveRegs+NumRegs, (DomainValue*)0);
+ }
if (LiveRegs[rx] == dv)
return;
if (LiveRegs[rx]) {
assert(LiveRegs[rx]->Refs && "Bad refcount");
- if (--LiveRegs[rx]->Refs == 0) Pool.Recycle(LiveRegs[rx]);
+ if (--LiveRegs[rx]->Refs == 0) Recycle(LiveRegs[rx]);
}
LiveRegs[rx] = dv;
if (dv) ++dv->Refs;
@@ -205,8 +203,8 @@ void SSEDomainFixPass::Kill(int rx) {
// Before killing the last reference to an open DomainValue, collapse it to
// the first available domain.
- if (LiveRegs[rx]->Refs == 1 && !LiveRegs[rx]->collapsed())
- Collapse(LiveRegs[rx], LiveRegs[rx]->firstDomain());
+ if (LiveRegs[rx]->Refs == 1 && !LiveRegs[rx]->isCollapsed())
+ Collapse(LiveRegs[rx], LiveRegs[rx]->getFirstDomain());
else
SetLiveReg(rx, 0);
}
@@ -216,54 +214,45 @@ void SSEDomainFixPass::Force(int rx, unsigned domain) {
assert(unsigned(rx) < NumRegs && "Invalid index");
DomainValue *dv;
if (LiveRegs && (dv = LiveRegs[rx])) {
- if (dv->collapsed())
- dv->add(domain);
+ if (dv->isCollapsed())
+ dv->addDomain(domain);
else
Collapse(dv, domain);
} else {
// Set up basic collapsed DomainValue.
- dv = Pool.Alloc();
- dv->Dist = Distance;
- dv->add(domain);
- SetLiveReg(rx, dv);
+ SetLiveReg(rx, Alloc(domain));
}
}
/// Collapse open DomainValue into given domain. If there are multiple
/// registers using dv, they each get a unique collapsed DomainValue.
void SSEDomainFixPass::Collapse(DomainValue *dv, unsigned domain) {
- assert(dv->compat(1u << domain) && "Cannot collapse");
+ assert(dv->hasDomain(domain) && "Cannot collapse");
// Collapse all the instructions.
- while (!dv->Instrs.empty()) {
- MachineInstr *mi = dv->Instrs.back();
- TII->SetSSEDomain(mi, domain);
- dv->Instrs.pop_back();
- }
- dv->Mask = 1u << domain;
+ while (!dv->Instrs.empty())
+ TII->SetSSEDomain(dv->Instrs.pop_back_val(), domain);
+ dv->setSingleDomain(domain);
// If there are multiple users, give them new, unique DomainValues.
- if (LiveRegs && dv->Refs > 1) {
+ if (LiveRegs && dv->Refs > 1)
for (unsigned rx = 0; rx != NumRegs; ++rx)
- if (LiveRegs[rx] == dv) {
- DomainValue *dv2 = Pool.Alloc();
- dv2->Dist = Distance;
- dv2->add(domain);
- SetLiveReg(rx, dv2);
- }
- }
+ if (LiveRegs[rx] == dv)
+ SetLiveReg(rx, Alloc(domain));
}
/// Merge - All instructions and registers in B are moved to A, and B is
/// released.
bool SSEDomainFixPass::Merge(DomainValue *A, DomainValue *B) {
- assert(!A->collapsed() && "Cannot merge into collapsed");
- assert(!B->collapsed() && "Cannot merge from collapsed");
+ assert(!A->isCollapsed() && "Cannot merge into collapsed");
+ assert(!B->isCollapsed() && "Cannot merge from collapsed");
if (A == B)
return true;
- if (!A->compat(B->Mask))
+ // Restrict to the domains that A and B have in common.
+ unsigned common = A->getCommonDomains(B->AvailableDomains);
+ if (!common)
return false;
- A->Mask &= B->Mask;
+ A->AvailableDomains = common;
A->Dist = std::max(A->Dist, B->Dist);
A->Instrs.append(B->Instrs.begin(), B->Instrs.end());
for (unsigned rx = 0; rx != NumRegs; ++rx)
@@ -290,18 +279,18 @@ void SSEDomainFixPass::enterBasicBlock() {
}
// We have a live DomainValue from more than one predecessor.
- if (LiveRegs[rx]->collapsed()) {
+ if (LiveRegs[rx]->isCollapsed()) {
// We are already collapsed, but predecessor is not. Force him.
- if (!pdv->collapsed())
- Collapse(pdv, LiveRegs[rx]->firstDomain());
+ if (!pdv->isCollapsed())
+ Collapse(pdv, LiveRegs[rx]->getFirstDomain());
continue;
}
-
+
// Currently open, merge in predecessor.
- if (!pdv->collapsed())
+ if (!pdv->isCollapsed())
Merge(LiveRegs[rx], pdv);
else
- Collapse(LiveRegs[rx], pdv->firstDomain());
+ Collapse(LiveRegs[rx], pdv->getFirstDomain());
}
}
}
@@ -332,8 +321,11 @@ void SSEDomainFixPass::visitHardInstr(MachineInstr *mi, unsigned domain) {
// A soft instruction can be changed to work in other domains given by mask.
void SSEDomainFixPass::visitSoftInstr(MachineInstr *mi, unsigned mask) {
+ // Bitmask of available domains for this instruction after taking collapsed
+ // operands into account.
+ unsigned available = mask;
+
// Scan the explicit use operands for incoming domains.
- unsigned collmask = mask;
SmallVector<int, 4> used;
if (LiveRegs)
for (unsigned i = mi->getDesc().getNumDefs(),
@@ -343,33 +335,40 @@ void SSEDomainFixPass::visitSoftInstr(MachineInstr *mi, unsigned mask) {
int rx = RegIndex(mo.getReg());
if (rx < 0) continue;
if (DomainValue *dv = LiveRegs[rx]) {
+ // Bitmask of domains that dv and available have in common.
+ unsigned common = dv->getCommonDomains(available);
// Is it possible to use this collapsed register for free?
- if (dv->collapsed()) {
- if (unsigned m = collmask & dv->Mask)
- collmask = m;
- } else if (dv->compat(collmask))
+ if (dv->isCollapsed()) {
+ // Restrict available domains to the ones in common with the operand.
+ // If there are no common domains, we must pay the cross-domain
+ // penalty for this operand.
+ if (common) available = common;
+ } else if (common)
+ // Open DomainValue is compatible, save it for merging.
used.push_back(rx);
else
+ // Open DomainValue is not compatible with instruction. It is useless
+ // now.
Kill(rx);
}
}
// If the collapsed operands force a single domain, propagate the collapse.
- if (isPowerOf2_32(collmask)) {
- unsigned domain = CountTrailingZeros_32(collmask);
+ if (isPowerOf2_32(available)) {
+ unsigned domain = CountTrailingZeros_32(available);
TII->SetSSEDomain(mi, domain);
visitHardInstr(mi, domain);
return;
}
- // Kill off any remaining uses that don't match collmask, and build a list of
- // incoming DomainValue that we want to merge.
+ // Kill off any remaining uses that don't match available, and build a list of
+ // incoming DomainValues that we want to merge.
SmallVector<DomainValue*,4> doms;
for (SmallVector<int, 4>::iterator i=used.begin(), e=used.end(); i!=e; ++i) {
int rx = *i;
DomainValue *dv = LiveRegs[rx];
// This useless DomainValue could have been missed above.
- if (!dv->compat(collmask)) {
+ if (!dv->getCommonDomains(available)) {
Kill(*i);
continue;
}
@@ -388,28 +387,29 @@ void SSEDomainFixPass::visitSoftInstr(MachineInstr *mi, unsigned mask) {
doms.push_back(dv);
}
- // doms are now sorted in order of appearance. Try to merge them all, giving
- // priority to the latest ones.
+ // doms are now sorted in order of appearance. Try to merge them all, giving
+ // priority to the latest ones.
DomainValue *dv = 0;
while (!doms.empty()) {
if (!dv) {
dv = doms.pop_back_val();
continue;
}
-
- DomainValue *ThisDV = doms.pop_back_val();
- if (Merge(dv, ThisDV)) continue;
-
+
+ DomainValue *latest = doms.pop_back_val();
+ if (Merge(dv, latest)) continue;
+
+ // If latest didn't merge, it is useless now. Kill all registers using it.
for (SmallVector<int,4>::iterator i=used.begin(), e=used.end(); i != e; ++i)
- if (LiveRegs[*i] == ThisDV)
+ if (LiveRegs[*i] == latest)
Kill(*i);
}
// dv is the DomainValue we are going to use for this instruction.
if (!dv)
- dv = Pool.Alloc();
+ dv = Alloc();
dv->Dist = Distance;
- dv->Mask = collmask;
+ dv->AvailableDomains = available;
dv->Instrs.push_back(mi);
// Finally set all defs and non-collapsed uses to dv.
@@ -487,9 +487,10 @@ bool SSEDomainFixPass::runOnMachineFunction(MachineFunction &mf) {
// DomainValues?
for (LiveOutMap::const_iterator i = LiveOuts.begin(), e = LiveOuts.end();
i != e; ++i)
- free(i->second);
+ delete[] i->second;
LiveOuts.clear();
- Pool.Clear();
+ Avail.clear();
+ Allocator.DestroyAll();
return false;
}
diff --git a/lib/Target/X86/X86.td b/lib/Target/X86/X86.td
index 89cc84f..ec86fc2 100644
--- a/lib/Target/X86/X86.td
+++ b/lib/Target/X86/X86.td
@@ -164,33 +164,7 @@ include "X86RegisterInfo.td"
include "X86InstrInfo.td"
-def X86InstrInfo : InstrInfo {
-
- // Define how we want to layout our TargetSpecific information field... This
- // should be kept up-to-date with the fields in the X86InstrInfo.h file.
- let TSFlagsFields = ["FormBits",
- "hasOpSizePrefix",
- "hasAdSizePrefix",
- "Prefix",
- "hasREX_WPrefix",
- "ImmT.Value",
- "FPForm.Value",
- "hasLockPrefix",
- "SegOvrBits",
- "ExeDomain.Value",
- "Opcode"];
- let TSFlagsShifts = [0,
- 6,
- 7,
- 8,
- 12,
- 13,
- 16,
- 19,
- 20,
- 22,
- 24];
-}
+def X86InstrInfo : InstrInfo;
//===----------------------------------------------------------------------===//
// Calling Conventions
diff --git a/lib/Target/X86/X86FastISel.cpp b/lib/Target/X86/X86FastISel.cpp
index c69eeb3..7849b51 100644
--- a/lib/Target/X86/X86FastISel.cpp
+++ b/lib/Target/X86/X86FastISel.cpp
@@ -54,8 +54,6 @@ class X86FastISel : public FastISel {
public:
explicit X86FastISel(MachineFunction &mf,
- MachineModuleInfo *mmi,
- DwarfWriter *dw,
DenseMap<const Value *, unsigned> &vm,
DenseMap<const BasicBlock *, MachineBasicBlock *> &bm,
DenseMap<const AllocaInst *, int> &am
@@ -63,7 +61,7 @@ public:
, SmallSet<Instruction*, 8> &cil
#endif
)
- : FastISel(mf, mmi, dw, vm, bm, am
+ : FastISel(mf, vm, bm, am
#ifndef NDEBUG
, cil
#endif
@@ -1753,8 +1751,6 @@ unsigned X86FastISel::TargetMaterializeAlloca(AllocaInst *C) {
namespace llvm {
llvm::FastISel *X86::createFastISel(MachineFunction &mf,
- MachineModuleInfo *mmi,
- DwarfWriter *dw,
DenseMap<const Value *, unsigned> &vm,
DenseMap<const BasicBlock *, MachineBasicBlock *> &bm,
DenseMap<const AllocaInst *, int> &am
@@ -1762,7 +1758,7 @@ namespace llvm {
, SmallSet<Instruction*, 8> &cil
#endif
) {
- return new X86FastISel(mf, mmi, dw, vm, bm, am
+ return new X86FastISel(mf, vm, bm, am
#ifndef NDEBUG
, cil
#endif
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp
index 527e19b..64702f1 100644
--- a/lib/Target/X86/X86ISelLowering.cpp
+++ b/lib/Target/X86/X86ISelLowering.cpp
@@ -1434,7 +1434,8 @@ CreateCopyOfByValArgument(SDValue Src, SDValue Dst, SDValue Chain,
DebugLoc dl) {
SDValue SizeNode = DAG.getConstant(Flags.getByValSize(), MVT::i32);
return DAG.getMemcpy(Chain, dl, Dst, Src, SizeNode, Flags.getByValAlign(),
- /*AlwaysInline=*/true, NULL, 0, NULL, 0);
+ /*isVolatile*/false, /*AlwaysInline=*/true,
+ NULL, 0, NULL, 0);
}
/// IsTailCallConvention - Return true if the calling convention is one that
@@ -2397,8 +2398,7 @@ X86TargetLowering::IsEligibleForTailCallOptimization(SDValue Callee,
}
FastISel *
-X86TargetLowering::createFastISel(MachineFunction &mf, MachineModuleInfo *mmo,
- DwarfWriter *dw,
+X86TargetLowering::createFastISel(MachineFunction &mf,
DenseMap<const Value *, unsigned> &vm,
DenseMap<const BasicBlock*, MachineBasicBlock*> &bm,
DenseMap<const AllocaInst *, int> &am
@@ -2406,7 +2406,7 @@ X86TargetLowering::createFastISel(MachineFunction &mf, MachineModuleInfo *mmo,
, SmallSet<Instruction*, 8> &cil
#endif
) {
- return X86::createFastISel(mf, mmo, dw, vm, bm, am
+ return X86::createFastISel(mf, vm, bm, am
#ifndef NDEBUG
, cil
#endif
@@ -6548,6 +6548,7 @@ X86TargetLowering::EmitTargetCodeForMemset(SelectionDAG &DAG, DebugLoc dl,
SDValue Chain,
SDValue Dst, SDValue Src,
SDValue Size, unsigned Align,
+ bool isVolatile,
const Value *DstSV,
uint64_t DstSVOff) {
ConstantSDNode *ConstantSize = dyn_cast<ConstantSDNode>(Size);
@@ -6676,7 +6677,7 @@ X86TargetLowering::EmitTargetCodeForMemset(SelectionDAG &DAG, DebugLoc dl,
DAG.getConstant(Offset, AddrVT)),
Src,
DAG.getConstant(BytesLeft, SizeVT),
- Align, DstSV, DstSVOff + Offset);
+ Align, isVolatile, DstSV, DstSVOff + Offset);
}
// TODO: Use a Tokenfactor, as in memcpy, instead of a single chain.
@@ -6687,7 +6688,7 @@ SDValue
X86TargetLowering::EmitTargetCodeForMemcpy(SelectionDAG &DAG, DebugLoc dl,
SDValue Chain, SDValue Dst, SDValue Src,
SDValue Size, unsigned Align,
- bool AlwaysInline,
+ bool isVolatile, bool AlwaysInline,
const Value *DstSV, uint64_t DstSVOff,
const Value *SrcSV, uint64_t SrcSVOff) {
// This requires the copy size to be a constant, preferrably
@@ -6746,7 +6747,7 @@ X86TargetLowering::EmitTargetCodeForMemcpy(SelectionDAG &DAG, DebugLoc dl,
DAG.getNode(ISD::ADD, dl, SrcVT, Src,
DAG.getConstant(Offset, SrcVT)),
DAG.getConstant(BytesLeft, SizeVT),
- Align, AlwaysInline,
+ Align, isVolatile, AlwaysInline,
DstSV, DstSVOff + Offset,
SrcSV, SrcSVOff + Offset));
}
@@ -6829,8 +6830,8 @@ SDValue X86TargetLowering::LowerVACOPY(SDValue Op, SelectionDAG &DAG) {
DebugLoc dl = Op.getDebugLoc();
return DAG.getMemcpy(Chain, dl, DstPtr, SrcPtr,
- DAG.getIntPtrConstant(24), 8, false,
- DstSV, 0, SrcSV, 0);
+ DAG.getIntPtrConstant(24), 8, /*isVolatile*/false,
+ false, DstSV, 0, SrcSV, 0);
}
SDValue
diff --git a/lib/Target/X86/X86ISelLowering.h b/lib/Target/X86/X86ISelLowering.h
index 2c2a5fb..1026480 100644
--- a/lib/Target/X86/X86ISelLowering.h
+++ b/lib/Target/X86/X86ISelLowering.h
@@ -575,7 +575,6 @@ namespace llvm {
/// or null if the target does not support "fast" ISel.
virtual FastISel *
createFastISel(MachineFunction &mf,
- MachineModuleInfo *mmi, DwarfWriter *dw,
DenseMap<const Value *, unsigned> &,
DenseMap<const BasicBlock *, MachineBasicBlock *> &,
DenseMap<const AllocaInst *, int> &
@@ -741,12 +740,13 @@ namespace llvm {
SDValue Chain,
SDValue Dst, SDValue Src,
SDValue Size, unsigned Align,
+ bool isVolatile,
const Value *DstSV, uint64_t DstSVOff);
SDValue EmitTargetCodeForMemcpy(SelectionDAG &DAG, DebugLoc dl,
SDValue Chain,
SDValue Dst, SDValue Src,
SDValue Size, unsigned Align,
- bool AlwaysInline,
+ bool isVolatile, bool AlwaysInline,
const Value *DstSV, uint64_t DstSVOff,
const Value *SrcSV, uint64_t SrcSVOff);
@@ -756,7 +756,7 @@ namespace llvm {
/// block, the number of args, and whether or not the second arg is
/// in memory or not.
MachineBasicBlock *EmitPCMP(MachineInstr *BInstr, MachineBasicBlock *BB,
- unsigned argNum, bool inMem) const;
+ unsigned argNum, bool inMem) const;
/// Utility function to emit atomic bitwise operations (and, or, xor).
/// It takes the bitwise instruction to expand, the associated machine basic
@@ -815,7 +815,6 @@ namespace llvm {
namespace X86 {
FastISel *createFastISel(MachineFunction &mf,
- MachineModuleInfo *mmi, DwarfWriter *dw,
DenseMap<const Value *, unsigned> &,
DenseMap<const BasicBlock *, MachineBasicBlock *> &,
DenseMap<const AllocaInst *, int> &
diff --git a/lib/Target/X86/X86InstrFormats.td b/lib/Target/X86/X86InstrFormats.td
index cbe4c82..c4522f3 100644
--- a/lib/Target/X86/X86InstrFormats.td
+++ b/lib/Target/X86/X86InstrFormats.td
@@ -128,6 +128,19 @@ class X86Inst<bits<8> opcod, Format f, ImmType i, dag outs, dag ins,
bit hasLockPrefix = 0; // Does this inst have a 0xF0 prefix?
bits<2> SegOvrBits = 0; // Segment override prefix.
Domain ExeDomain = d;
+
+ // TSFlags layout should be kept in sync with X86InstrInfo.h.
+ let TSFlags{5-0} = FormBits;
+ let TSFlags{6} = hasOpSizePrefix;
+ let TSFlags{7} = hasAdSizePrefix;
+ let TSFlags{11-8} = Prefix;
+ let TSFlags{12} = hasREX_WPrefix;
+ let TSFlags{15-13} = ImmT.Value;
+ let TSFlags{18-16} = FPForm.Value;
+ let TSFlags{19} = hasLockPrefix;
+ let TSFlags{21-20} = SegOvrBits;
+ let TSFlags{23-22} = ExeDomain.Value;
+ let TSFlags{31-24} = Opcode;
}
class I<bits<8> o, Format f, dag outs, dag ins, string asm,
@@ -314,8 +327,7 @@ class SS42AI<bits<8> o, Format F, dag outs, dag ins, string asm,
// AES Instruction Templates:
//
// AES8I
-// FIXME: Verify these, they appear to use the same encoding as the SSE4.2 T8
-// and TA encodings.
+// These use the same encoding as the SSE4.2 T8 and TA encodings.
class AES8I<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag>pattern>
: I<o, F, outs, ins, asm, pattern, SSEPackedInt>, T8,
diff --git a/lib/Target/X86/X86InstrInfo.cpp b/lib/Target/X86/X86InstrInfo.cpp
index fcb9947..ccb7b05 100644
--- a/lib/Target/X86/X86InstrInfo.cpp
+++ b/lib/Target/X86/X86InstrInfo.cpp
@@ -2961,10 +2961,6 @@ X86InstrInfo::areLoadsFromSameBasePtr(SDNode *Load1, SDNode *Load2,
Load1->getOperand(2) == Load2->getOperand(2)) {
if (cast<ConstantSDNode>(Load1->getOperand(1))->getZExtValue() != 1)
return false;
- SDValue Op2 = Load1->getOperand(2);
- if (!isa<RegisterSDNode>(Op2) ||
- cast<RegisterSDNode>(Op2)->getReg() != 0)
- return 0;
// Now let's examine the displacements.
if (isa<ConstantSDNode>(Load1->getOperand(3)) &&
diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td
index 65b7ec0..940b439 100644
--- a/lib/Target/X86/X86InstrInfo.td
+++ b/lib/Target/X86/X86InstrInfo.td
@@ -2707,7 +2707,7 @@ let isCodeGenOnly = 1 in {
"add{b}\t{$src2, $dst|$dst, $src2}", []>;
def ADD16rr_alt: I<0x03, MRMSrcReg,(outs GR16:$dst),(ins GR16:$src1, GR16:$src2),
"add{w}\t{$src2, $dst|$dst, $src2}", []>, OpSize;
- def ADD32rr_alt: I<0x03, MRMSrcReg,(outs GR16:$dst),(ins GR16:$src1, GR16:$src2),
+ def ADD32rr_alt: I<0x03, MRMSrcReg,(outs GR32:$dst),(ins GR32:$src1, GR32:$src2),
"add{l}\t{$src2, $dst|$dst, $src2}", []>;
}
diff --git a/lib/Target/X86/X86MCAsmInfo.cpp b/lib/Target/X86/X86MCAsmInfo.cpp
index 1afabc9..d257ee3 100644
--- a/lib/Target/X86/X86MCAsmInfo.cpp
+++ b/lib/Target/X86/X86MCAsmInfo.cpp
@@ -84,7 +84,6 @@ X86ELFMCAsmInfo::X86ELFMCAsmInfo(const Triple &T) {
HasLEB128 = true; // Target asm supports leb128 directives (little-endian)
// Debug Information
- AbsoluteDebugSectionOffsets = true;
SupportsDebugInformation = true;
// Exceptions handling
diff --git a/lib/Target/X86/X86RegisterInfo.cpp b/lib/Target/X86/X86RegisterInfo.cpp
index 3238cce..32f28a5 100644
--- a/lib/Target/X86/X86RegisterInfo.cpp
+++ b/lib/Target/X86/X86RegisterInfo.cpp
@@ -297,9 +297,7 @@ X86RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
bool ghcCall = false;
if (MF) {
- const MachineFrameInfo *MFI = MF->getFrameInfo();
- const MachineModuleInfo *MMI = MFI->getMachineModuleInfo();
- callsEHReturn = (MMI ? MMI->callsEHReturn() : false);
+ callsEHReturn = MF->getMMI().callsEHReturn();
const Function *F = MF->getFunction();
ghcCall = (F ? F->getCallingConv() == CallingConv::GHC : false);
}
@@ -348,12 +346,8 @@ X86RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
const TargetRegisterClass* const*
X86RegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const {
bool callsEHReturn = false;
-
- if (MF) {
- const MachineFrameInfo *MFI = MF->getFrameInfo();
- const MachineModuleInfo *MMI = MFI->getMachineModuleInfo();
- callsEHReturn = (MMI ? MMI->callsEHReturn() : false);
- }
+ if (MF)
+ callsEHReturn = MF->getMMI().callsEHReturn();
static const TargetRegisterClass * const CalleeSavedRegClasses32Bit[] = {
&X86::GR32RegClass, &X86::GR32RegClass,
@@ -443,14 +437,14 @@ BitVector X86RegisterInfo::getReservedRegs(const MachineFunction &MF) const {
/// or if frame pointer elimination is disabled.
bool X86RegisterInfo::hasFP(const MachineFunction &MF) const {
const MachineFrameInfo *MFI = MF.getFrameInfo();
- const MachineModuleInfo *MMI = MFI->getMachineModuleInfo();
+ const MachineModuleInfo &MMI = MF.getMMI();
return (NoFramePointerElim ||
needsStackRealignment(MF) ||
MFI->hasVarSizedObjects() ||
MFI->isFrameAddressTaken() ||
MF.getInfo<X86MachineFunctionInfo>()->getForceFramePointer() ||
- (MMI && MMI->callsUnwindInit()));
+ MMI.callsUnwindInit());
}
bool X86RegisterInfo::canRealignStack(const MachineFunction &MF) const {
@@ -800,14 +794,13 @@ void X86RegisterInfo::emitCalleeSavedFrameMoves(MachineFunction &MF,
MCSymbol *Label,
unsigned FramePtr) const {
MachineFrameInfo *MFI = MF.getFrameInfo();
- MachineModuleInfo *MMI = MFI->getMachineModuleInfo();
- if (!MMI) return;
+ MachineModuleInfo &MMI = MF.getMMI();
// Add callee saved registers to move list.
const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
if (CSI.empty()) return;
- std::vector<MachineMove> &Moves = MMI->getFrameMoves();
+ std::vector<MachineMove> &Moves = MMI.getFrameMoves();
const TargetData *TD = MF.getTarget().getTargetData();
bool HasFP = hasFP(MF);
@@ -874,9 +867,9 @@ void X86RegisterInfo::emitPrologue(MachineFunction &MF) const {
MachineFrameInfo *MFI = MF.getFrameInfo();
const Function *Fn = MF.getFunction();
const X86Subtarget *Subtarget = &MF.getTarget().getSubtarget<X86Subtarget>();
- MachineModuleInfo *MMI = MFI->getMachineModuleInfo();
+ MachineModuleInfo &MMI = MF.getMMI();
X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>();
- bool needsFrameMoves = (MMI && MMI->hasDebugInfo()) ||
+ bool needsFrameMoves = MMI.hasDebugInfo() ||
!Fn->doesNotThrow() || UnwindTablesMandatory;
uint64_t MaxAlign = MFI->getMaxAlignment(); // Desired stack alignment.
uint64_t StackSize = MFI->getStackSize(); // Number of bytes to allocate.
@@ -935,7 +928,7 @@ void X86RegisterInfo::emitPrologue(MachineFunction &MF) const {
// REG < 64 => DW_CFA_offset + Reg
// ELSE => DW_CFA_offset_extended
- std::vector<MachineMove> &Moves = MMI->getFrameMoves();
+ std::vector<MachineMove> &Moves = MMI.getFrameMoves();
const TargetData *TD = MF.getTarget().getTargetData();
uint64_t NumBytes = 0;
int stackGrowth = -TD->getPointerSize();
@@ -959,7 +952,7 @@ void X86RegisterInfo::emitPrologue(MachineFunction &MF) const {
if (needsFrameMoves) {
// Mark the place where EBP/RBP was saved.
- MCSymbol *FrameLabel = MMI->getContext().CreateTempSymbol();
+ MCSymbol *FrameLabel = MMI.getContext().CreateTempSymbol();
BuildMI(MBB, MBBI, DL, TII.get(X86::DBG_LABEL)).addSym(FrameLabel);
// Define the current CFA rule to use the provided offset.
@@ -987,7 +980,7 @@ void X86RegisterInfo::emitPrologue(MachineFunction &MF) const {
if (needsFrameMoves) {
// Mark effective beginning of when frame pointer becomes valid.
- MCSymbol *FrameLabel = MMI->getContext().CreateTempSymbol();
+ MCSymbol *FrameLabel = MMI.getContext().CreateTempSymbol();
BuildMI(MBB, MBBI, DL, TII.get(X86::DBG_LABEL)).addSym(FrameLabel);
// Define the current CFA to use the EBP/RBP register.
@@ -1027,7 +1020,7 @@ void X86RegisterInfo::emitPrologue(MachineFunction &MF) const {
if (!HasFP && needsFrameMoves) {
// Mark callee-saved push instruction.
- MCSymbol *Label = MMI->getContext().CreateTempSymbol();
+ MCSymbol *Label = MMI.getContext().CreateTempSymbol();
BuildMI(MBB, MBBI, DL, TII.get(X86::DBG_LABEL)).addSym(Label);
// Define the current CFA rule to use the provided offset.
@@ -1099,7 +1092,7 @@ void X86RegisterInfo::emitPrologue(MachineFunction &MF) const {
if ((NumBytes || PushedRegs) && needsFrameMoves) {
// Mark end of stack pointer adjustment.
- MCSymbol *Label = MMI->getContext().CreateTempSymbol();
+ MCSymbol *Label = MMI.getContext().CreateTempSymbol();
BuildMI(MBB, MBBI, DL, TII.get(X86::DBG_LABEL)).addSym(Label);
if (!HasFP && NumBytes) {
diff --git a/lib/Target/XCore/AsmPrinter/XCoreAsmPrinter.cpp b/lib/Target/XCore/AsmPrinter/XCoreAsmPrinter.cpp
index c882338..5801b40 100644
--- a/lib/Target/XCore/AsmPrinter/XCoreAsmPrinter.cpp
+++ b/lib/Target/XCore/AsmPrinter/XCoreAsmPrinter.cpp
@@ -22,7 +22,6 @@
#include "llvm/DerivedTypes.h"
#include "llvm/Module.h"
#include "llvm/CodeGen/AsmPrinter.h"
-#include "llvm/CodeGen/DwarfWriter.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineConstantPool.h"
@@ -34,11 +33,11 @@
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetRegistry.h"
+#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/FormattedStream.h"
-#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cctype>
using namespace llvm;
@@ -53,68 +52,53 @@ namespace {
class XCoreAsmPrinter : public AsmPrinter {
const XCoreSubtarget &Subtarget;
public:
- explicit XCoreAsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
- MCStreamer &Streamer)
- : AsmPrinter(O, TM, Streamer),
- Subtarget(TM.getSubtarget<XCoreSubtarget>()) {}
+ explicit XCoreAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
+ : AsmPrinter(TM, Streamer), Subtarget(TM.getSubtarget<XCoreSubtarget>()){}
virtual const char *getPassName() const {
return "XCore Assembly Printer";
}
- void printMemOperand(const MachineInstr *MI, int opNum);
- void printInlineJT(const MachineInstr *MI, int opNum,
+ void printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O);
+ void printInlineJT(const MachineInstr *MI, int opNum, raw_ostream &O,
const std::string &directive = ".jmptable");
- void printInlineJT32(const MachineInstr *MI, int opNum) {
- printInlineJT(MI, opNum, ".jmptable32");
+ void printInlineJT32(const MachineInstr *MI, int opNum, raw_ostream &O) {
+ printInlineJT(MI, opNum, O, ".jmptable32");
}
- void printOperand(const MachineInstr *MI, int opNum);
+ void printOperand(const MachineInstr *MI, int opNum, raw_ostream &O);
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
- unsigned AsmVariant, const char *ExtraCode);
+ unsigned AsmVariant, const char *ExtraCode,
+ raw_ostream &O);
- void emitGlobalDirective(const MCSymbol *Sym);
-
- void emitArrayBound(const MCSymbol *Sym, const GlobalVariable *GV);
+ void emitArrayBound(MCSymbol *Sym, const GlobalVariable *GV);
virtual void EmitGlobalVariable(const GlobalVariable *GV);
- void emitFunctionStart(MachineFunction &MF);
-
- void printInstruction(const MachineInstr *MI); // autogenerated.
+ void printInstruction(const MachineInstr *MI, raw_ostream &O); // autogen'd.
static const char *getRegisterName(unsigned RegNo);
- bool runOnMachineFunction(MachineFunction &MF);
+ void EmitFunctionEntryLabel();
void EmitInstruction(const MachineInstr *MI);
void EmitFunctionBodyEnd();
-
- void getAnalysisUsage(AnalysisUsage &AU) const {
- AsmPrinter::getAnalysisUsage(AU);
- AU.setPreservesAll();
- AU.addRequired<MachineModuleInfo>();
- AU.addRequired<DwarfWriter>();
- }
};
} // end of anonymous namespace
#include "XCoreGenAsmWriter.inc"
-void XCoreAsmPrinter::emitGlobalDirective(const MCSymbol *Sym) {
- O << MAI->getGlobalDirective() << *Sym << "\n";
-}
-
-void XCoreAsmPrinter::emitArrayBound(const MCSymbol *Sym,
- const GlobalVariable *GV) {
+void XCoreAsmPrinter::emitArrayBound(MCSymbol *Sym, const GlobalVariable *GV) {
assert(((GV->hasExternalLinkage() ||
GV->hasWeakLinkage()) ||
GV->hasLinkOnceLinkage()) && "Unexpected linkage");
if (const ArrayType *ATy = dyn_cast<ArrayType>(
cast<PointerType>(GV->getType())->getElementType())) {
- O << MAI->getGlobalDirective() << *Sym;
- O << ".globound" << "\n";
- O << "\t.set\t" << *Sym;
- O << ".globound" << "," << ATy->getNumElements() << "\n";
+ OutStreamer.EmitSymbolAttribute(Sym, MCSA_Global);
+ // FIXME: MCStreamerize.
+ OutStreamer.EmitRawText(StringRef(".globound"));
+ OutStreamer.EmitRawText("\t.set\t" + Twine(Sym->getName()));
+ OutStreamer.EmitRawText(".globound," + Twine(ATy->getNumElements()));
if (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage()) {
// TODO Use COMDAT groups for LinkOnceLinkage
- O << MAI->getWeakDefDirective() << *Sym << ".globound" << "\n";
+ OutStreamer.EmitRawText(MAI->getWeakDefDirective() +Twine(Sym->getName())+
+ ".globound");
}
}
}
@@ -134,7 +118,8 @@ void XCoreAsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
unsigned Align = (unsigned)TD->getPreferredTypeAlignmentShift(C->getType());
// Mark the start of the global
- O << "\t.cc_top " << *GVSym << ".data," << *GVSym << "\n";
+ OutStreamer.EmitRawText("\t.cc_top " + Twine(GVSym->getName()) + ".data," +
+ GVSym->getName());
switch (GV->getLinkage()) {
case GlobalValue::AppendingLinkage:
@@ -145,10 +130,11 @@ void XCoreAsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
case GlobalValue::WeakODRLinkage:
case GlobalValue::ExternalLinkage:
emitArrayBound(GVSym, GV);
- emitGlobalDirective(GVSym);
+ OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Global);
+
// TODO Use COMDAT groups for LinkOnceLinkage
if (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage())
- O << MAI->getWeakDefDirective() << *GVSym << "\n";
+ OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Weak);
// FALL THROUGH
case GlobalValue::InternalLinkage:
case GlobalValue::PrivateLinkage:
@@ -169,10 +155,11 @@ void XCoreAsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
Size *= MaxThreads;
}
if (MAI->hasDotTypeDotSizeDirective()) {
- O << "\t.type " << *GVSym << ",@object\n";
- O << "\t.size " << *GVSym << "," << Size << "\n";
+ OutStreamer.EmitSymbolAttribute(GVSym, MCSA_ELF_TypeObject);
+ OutStreamer.EmitRawText("\t.size " + Twine(GVSym->getName()) + "," +
+ Twine(Size));
}
- O << *GVSym << ":\n";
+ OutStreamer.EmitLabel(GVSym);
EmitGlobalConstant(C);
if (GV->isThreadLocal()) {
@@ -185,87 +172,38 @@ void XCoreAsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
OutStreamer.EmitZeros(4 - Size, 0);
// Mark the end of the global
- O << "\t.cc_bottom " << *GVSym << ".data\n";
+ OutStreamer.EmitRawText("\t.cc_bottom " + Twine(GVSym->getName()) + ".data");
}
-/// Emit the directives on the start of functions
-void XCoreAsmPrinter::emitFunctionStart(MachineFunction &MF) {
- // Print out the label for the function.
- const Function *F = MF.getFunction();
-
- OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(F, Mang, TM));
-
- // Mark the start of the function
- O << "\t.cc_top " << *CurrentFnSym << ".function," << *CurrentFnSym << "\n";
-
- switch (F->getLinkage()) {
- default: llvm_unreachable("Unknown linkage type!");
- case Function::InternalLinkage: // Symbols default to internal.
- case Function::PrivateLinkage:
- case Function::LinkerPrivateLinkage:
- break;
- case Function::ExternalLinkage:
- emitGlobalDirective(CurrentFnSym);
- break;
- case Function::LinkOnceAnyLinkage:
- case Function::LinkOnceODRLinkage:
- case Function::WeakAnyLinkage:
- case Function::WeakODRLinkage:
- // TODO Use COMDAT groups for LinkOnceLinkage
- O << MAI->getGlobalDirective() << *CurrentFnSym << "\n";
- O << MAI->getWeakDefDirective() << *CurrentFnSym << "\n";
- break;
- }
- // (1 << 1) byte aligned
- EmitAlignment(MF.getAlignment(), F, 1);
- if (MAI->hasDotTypeDotSizeDirective())
- O << "\t.type " << *CurrentFnSym << ",@function\n";
-
- O << *CurrentFnSym << ":\n";
-}
-
-
/// EmitFunctionBodyEnd - Targets can override this to emit stuff after
/// the last basic block in the function.
void XCoreAsmPrinter::EmitFunctionBodyEnd() {
// Emit function end directives
- O << "\t.cc_bottom " << *CurrentFnSym << ".function\n";
+ OutStreamer.EmitRawText("\t.cc_bottom " + Twine(CurrentFnSym->getName()) +
+ ".function");
}
-/// runOnMachineFunction - This uses the printMachineInstruction()
-/// method to print assembly for each instruction.
-///
-bool XCoreAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
- SetupMachineFunction(MF);
-
- // Print out constants referenced by the function
- EmitConstantPool();
-
- // Emit the function start directives
- emitFunctionStart(MF);
-
- // Emit pre-function debug information.
- DW->BeginFunction(&MF);
-
- EmitFunctionBody();
- return false;
+void XCoreAsmPrinter::EmitFunctionEntryLabel() {
+ // Mark the start of the function
+ OutStreamer.EmitRawText("\t.cc_top " + Twine(CurrentFnSym->getName()) +
+ ".function," + CurrentFnSym->getName());
+ OutStreamer.EmitLabel(CurrentFnSym);
}
-void XCoreAsmPrinter::printMemOperand(const MachineInstr *MI, int opNum)
-{
- printOperand(MI, opNum);
+void XCoreAsmPrinter::printMemOperand(const MachineInstr *MI, int opNum,
+ raw_ostream &O) {
+ printOperand(MI, opNum, O);
- if (MI->getOperand(opNum+1).isImm()
- && MI->getOperand(opNum+1).getImm() == 0)
+ if (MI->getOperand(opNum+1).isImm() && MI->getOperand(opNum+1).getImm() == 0)
return;
O << "+";
- printOperand(MI, opNum+1);
+ printOperand(MI, opNum+1, O);
}
void XCoreAsmPrinter::
-printInlineJT(const MachineInstr *MI, int opNum, const std::string &directive)
-{
+printInlineJT(const MachineInstr *MI, int opNum, raw_ostream &O,
+ const std::string &directive) {
unsigned JTI = MI->getOperand(opNum).getIndex();
const MachineFunction *MF = MI->getParent()->getParent();
const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
@@ -280,7 +218,8 @@ printInlineJT(const MachineInstr *MI, int opNum, const std::string &directive)
}
}
-void XCoreAsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
+void XCoreAsmPrinter::printOperand(const MachineInstr *MI, int opNum,
+ raw_ostream &O) {
const MachineOperand &MO = MI->getOperand(opNum);
switch (MO.getType()) {
case MachineOperand::MO_Register:
@@ -317,23 +256,25 @@ void XCoreAsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
/// PrintAsmOperand - Print out an operand for an inline asm expression.
///
bool XCoreAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
- unsigned AsmVariant,
- const char *ExtraCode) {
- printOperand(MI, OpNo);
+ unsigned AsmVariant,const char *ExtraCode,
+ raw_ostream &O) {
+ printOperand(MI, OpNo, O);
return false;
}
void XCoreAsmPrinter::EmitInstruction(const MachineInstr *MI) {
+ SmallString<128> Str;
+ raw_svector_ostream O(Str);
+
// Check for mov mnemonic
unsigned src, dst, srcSR, dstSR;
if (TM.getInstrInfo()->isMoveInstr(*MI, src, dst, srcSR, dstSR)) {
O << "\tmov " << getRegisterName(dst) << ", ";
O << getRegisterName(src);
- OutStreamer.AddBlankLine();
- return;
+ } else {
+ printInstruction(MI, O);
}
- printInstruction(MI);
- OutStreamer.AddBlankLine();
+ OutStreamer.EmitRawText(O.str());
}
// Force static initialization.
diff --git a/lib/Target/XCore/XCore.td b/lib/Target/XCore/XCore.td
index b07445d..3840189 100644
--- a/lib/Target/XCore/XCore.td
+++ b/lib/Target/XCore/XCore.td
@@ -24,10 +24,7 @@ include "XCoreRegisterInfo.td"
include "XCoreInstrInfo.td"
include "XCoreCallingConv.td"
-def XCoreInstrInfo : InstrInfo {
- let TSFlagsFields = [];
- let TSFlagsShifts = [];
-}
+def XCoreInstrInfo : InstrInfo;
//===----------------------------------------------------------------------===//
// XCore processors supported.
diff --git a/lib/Target/XCore/XCoreISelLowering.cpp b/lib/Target/XCore/XCoreISelLowering.cpp
index bf1a457..27e5233 100644
--- a/lib/Target/XCore/XCoreISelLowering.cpp
+++ b/lib/Target/XCore/XCoreISelLowering.cpp
@@ -1443,7 +1443,7 @@ SDValue XCoreTargetLowering::PerformDAGCombine(SDNode *N,
return DAG.getMemmove(Chain, dl, ST->getBasePtr(),
LD->getBasePtr(),
DAG.getConstant(StoreBits/8, MVT::i32),
- Alignment, ST->getSrcValue(),
+ Alignment, false, ST->getSrcValue(),
ST->getSrcValueOffset(), LD->getSrcValue(),
LD->getSrcValueOffset());
}
diff --git a/lib/Target/XCore/XCoreInstrInfo.cpp b/lib/Target/XCore/XCoreInstrInfo.cpp
index ae3f16c..c983112 100644
--- a/lib/Target/XCore/XCoreInstrInfo.cpp
+++ b/lib/Target/XCore/XCoreInstrInfo.cpp
@@ -14,12 +14,12 @@
#include "XCoreMachineFunctionInfo.h"
#include "XCoreInstrInfo.h"
#include "XCore.h"
-#include "llvm/ADT/STLExtras.h"
+#include "llvm/MC/MCContext.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineLocation.h"
-#include "llvm/CodeGen/MachineModuleInfo.h"
#include "XCoreGenInstrInfo.inc"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
@@ -419,14 +419,11 @@ void XCoreInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
bool XCoreInstrInfo::spillCalleeSavedRegisters(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI,
- const std::vector<CalleeSavedInfo> &CSI) const
-{
+ const std::vector<CalleeSavedInfo> &CSI) const {
if (CSI.empty()) {
return true;
}
MachineFunction *MF = MBB.getParent();
- const MachineFrameInfo *MFI = MF->getFrameInfo();
- MachineModuleInfo *MMI = MFI->getMachineModuleInfo();
XCoreFunctionInfo *XFI = MF->getInfo<XCoreFunctionInfo>();
bool emitFrameMoves = XCoreRegisterInfo::needsFrameMoves(*MF);
@@ -442,7 +439,7 @@ bool XCoreInstrInfo::spillCalleeSavedRegisters(MachineBasicBlock &MBB,
storeRegToStackSlot(MBB, MI, it->getReg(), true,
it->getFrameIdx(), it->getRegClass());
if (emitFrameMoves) {
- MCSymbol *SaveLabel = MMI->getContext().CreateTempSymbol();
+ MCSymbol *SaveLabel = MF->getContext().CreateTempSymbol();
BuildMI(MBB, MI, DL, get(XCore::DBG_LABEL)).addSym(SaveLabel);
XFI->getSpillLabels().push_back(std::make_pair(SaveLabel, *it));
}
diff --git a/lib/Target/XCore/XCoreMCAsmInfo.cpp b/lib/Target/XCore/XCoreMCAsmInfo.cpp
index bf78575..5f6feae 100644
--- a/lib/Target/XCore/XCoreMCAsmInfo.cpp
+++ b/lib/Target/XCore/XCoreMCAsmInfo.cpp
@@ -25,6 +25,5 @@ XCoreMCAsmInfo::XCoreMCAsmInfo(const Target &T, const StringRef &TT) {
// Debug
HasLEB128 = true;
- AbsoluteDebugSectionOffsets = true;
}
diff --git a/lib/Target/XCore/XCoreRegisterInfo.cpp b/lib/Target/XCore/XCoreRegisterInfo.cpp
index 1631e73..ab71d05 100644
--- a/lib/Target/XCore/XCoreRegisterInfo.cpp
+++ b/lib/Target/XCore/XCoreRegisterInfo.cpp
@@ -67,12 +67,8 @@ unsigned XCoreRegisterInfo::getNumArgRegs(const MachineFunction *MF)
return array_lengthof(XCore_ArgRegs);
}
-bool XCoreRegisterInfo::needsFrameMoves(const MachineFunction &MF)
-{
- const MachineFrameInfo *MFI = MF.getFrameInfo();
- MachineModuleInfo *MMI = MFI->getMachineModuleInfo();
- return (MMI && MMI->hasDebugInfo()) ||
- !MF.getFunction()->doesNotThrow() ||
+bool XCoreRegisterInfo::needsFrameMoves(const MachineFunction &MF) {
+ return MF.getMMI().hasDebugInfo() || !MF.getFunction()->doesNotThrow() ||
UnwindTablesMandatory;
}
@@ -412,7 +408,7 @@ void XCoreRegisterInfo::emitPrologue(MachineFunction &MF) const {
MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB
MachineBasicBlock::iterator MBBI = MBB.begin();
MachineFrameInfo *MFI = MF.getFrameInfo();
- MachineModuleInfo *MMI = MFI->getMachineModuleInfo();
+ MachineModuleInfo *MMI = &MF.getMMI();
XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>();
DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
diff --git a/lib/Transforms/InstCombine/InstCombineCalls.cpp b/lib/Transforms/InstCombine/InstCombineCalls.cpp
index 76c815d..e025b05 100644
--- a/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -136,8 +136,14 @@ Instruction *InstCombiner::SimplifyMemTransfer(MemIntrinsic *MI) {
return 0; // If not 1/2/4/8 bytes, exit.
// Use an integer load+store unless we can find something better.
- Type *NewPtrTy =
- PointerType::getUnqual(IntegerType::get(MI->getContext(), Size<<3));
+ unsigned SrcAddrSp =
+ cast<PointerType>(MI->getOperand(2)->getType())->getAddressSpace();
+ unsigned DstAddrSp =
+ cast<PointerType>(MI->getOperand(1)->getType())->getAddressSpace();
+
+ const IntegerType* IntType = IntegerType::get(MI->getContext(), Size<<3);
+ Type *NewSrcPtrTy = PointerType::get(IntType, SrcAddrSp);
+ Type *NewDstPtrTy = PointerType::get(IntType, DstAddrSp);
// Memcpy forces the use of i8* for the source and destination. That means
// that if you're using memcpy to move one double around, you'll get a cast
@@ -167,8 +173,10 @@ Instruction *InstCombiner::SimplifyMemTransfer(MemIntrinsic *MI) {
break;
}
- if (SrcETy->isSingleValueType())
- NewPtrTy = PointerType::getUnqual(SrcETy);
+ if (SrcETy->isSingleValueType()) {
+ NewSrcPtrTy = PointerType::get(SrcETy, SrcAddrSp);
+ NewDstPtrTy = PointerType::get(SrcETy, DstAddrSp);
+ }
}
}
@@ -178,11 +186,12 @@ Instruction *InstCombiner::SimplifyMemTransfer(MemIntrinsic *MI) {
SrcAlign = std::max(SrcAlign, CopyAlign);
DstAlign = std::max(DstAlign, CopyAlign);
- Value *Src = Builder->CreateBitCast(MI->getOperand(2), NewPtrTy);
- Value *Dest = Builder->CreateBitCast(MI->getOperand(1), NewPtrTy);
- Instruction *L = new LoadInst(Src, "tmp", false, SrcAlign);
+ Value *Src = Builder->CreateBitCast(MI->getOperand(2), NewSrcPtrTy);
+ Value *Dest = Builder->CreateBitCast(MI->getOperand(1), NewDstPtrTy);
+ Instruction *L = new LoadInst(Src, "tmp", MI->isVolatile(), SrcAlign);
InsertNewInstBefore(L, *MI);
- InsertNewInstBefore(new StoreInst(L, Dest, false, DstAlign), *MI);
+ InsertNewInstBefore(new StoreInst(L, Dest, MI->isVolatile(), DstAlign),
+ *MI);
// Set the size of the copy to 0, it will be deleted on the next iteration.
MI->setOperand(3, Constant::getNullValue(MemOpLength->getType()));
@@ -275,10 +284,11 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
if (GVSrc->isConstant()) {
Module *M = CI.getParent()->getParent()->getParent();
Intrinsic::ID MemCpyID = Intrinsic::memcpy;
- const Type *Tys[1];
- Tys[0] = CI.getOperand(3)->getType();
+ const Type *Tys[3] = { CI.getOperand(1)->getType(),
+ CI.getOperand(2)->getType(),
+ CI.getOperand(3)->getType() };
CI.setOperand(0,
- Intrinsic::getDeclaration(M, MemCpyID, Tys, 1));
+ Intrinsic::getDeclaration(M, MemCpyID, Tys, 3));
Changed = true;
}
}
diff --git a/lib/Transforms/Scalar/LoopUnswitch.cpp b/lib/Transforms/Scalar/LoopUnswitch.cpp
index 27fd2ef..3918738 100644
--- a/lib/Transforms/Scalar/LoopUnswitch.cpp
+++ b/lib/Transforms/Scalar/LoopUnswitch.cpp
@@ -231,8 +231,7 @@ bool LoopUnswitch::processCurrentLoop() {
// block that is branching on a loop-invariant condition, we can unswitch this
// loop.
for (Loop::block_iterator I = currentLoop->block_begin(),
- E = currentLoop->block_end();
- I != E; ++I) {
+ E = currentLoop->block_end(); I != E; ++I) {
TerminatorInst *TI = (*I)->getTerminator();
if (BranchInst *BI = dyn_cast<BranchInst>(TI)) {
// If this isn't branching on an invariant condition, we can't unswitch
@@ -474,7 +473,6 @@ static inline void RemapInstruction(Instruction *I,
static Loop *CloneLoop(Loop *L, Loop *PL, DenseMap<const Value*, Value*> &VM,
LoopInfo *LI, LPPassManager *LPM) {
Loop *New = new Loop();
-
LPM->insertLoop(New, PL);
// Add all of the blocks in L to the new loop.
@@ -565,8 +563,7 @@ void LoopUnswitch::UnswitchTrivialCondition(Loop *L, Value *Cond,
/// SplitExitEdges - Split all of the edges from inside the loop to their exit
/// blocks. Update the appropriate Phi nodes as we do so.
void LoopUnswitch::SplitExitEdges(Loop *L,
- const SmallVector<BasicBlock *, 8> &ExitBlocks)
-{
+ const SmallVector<BasicBlock *, 8> &ExitBlocks){
for (unsigned i = 0, e = ExitBlocks.size(); i != e; ++i) {
BasicBlock *ExitBlock = ExitBlocks[i];
@@ -619,15 +616,15 @@ void LoopUnswitch::UnswitchNontrivialCondition(Value *LIC, Constant *Val,
NewBlocks.reserve(LoopBlocks.size());
DenseMap<const Value*, Value*> ValueMap;
for (unsigned i = 0, e = LoopBlocks.size(); i != e; ++i) {
- BasicBlock *New = CloneBasicBlock(LoopBlocks[i], ValueMap, ".us", F);
- NewBlocks.push_back(New);
- ValueMap[LoopBlocks[i]] = New; // Keep the BB mapping.
- LPM->cloneBasicBlockSimpleAnalysis(LoopBlocks[i], New, L);
+ BasicBlock *NewBB = CloneBasicBlock(LoopBlocks[i], ValueMap, ".us", F);
+ NewBlocks.push_back(NewBB);
+ ValueMap[LoopBlocks[i]] = NewBB; // Keep the BB mapping.
+ LPM->cloneBasicBlockSimpleAnalysis(LoopBlocks[i], NewBB, L);
}
// Splice the newly inserted blocks into the function right before the
// original preheader.
- F->getBasicBlockList().splice(LoopBlocks[0], F->getBasicBlockList(),
+ F->getBasicBlockList().splice(NewPreheader, F->getBasicBlockList(),
NewBlocks[0], F->end());
// Now we create the new Loop object for the versioned loop.
@@ -652,8 +649,8 @@ void LoopUnswitch::UnswitchNontrivialCondition(Value *LIC, Constant *Val,
// If the successor of the exit block had PHI nodes, add an entry for
// NewExit.
PHINode *PN;
- for (BasicBlock::iterator I = ExitSucc->begin();
- (PN = dyn_cast<PHINode>(I)); ++I) {
+ for (BasicBlock::iterator I = ExitSucc->begin(); isa<PHINode>(I); ++I) {
+ PN = cast<PHINode>(I);
Value *V = PN->getIncomingValueForBlock(ExitBlocks[i]);
DenseMap<const Value *, Value*>::iterator It = ValueMap.find(V);
if (It != ValueMap.end()) V = It->second;
@@ -682,7 +679,7 @@ void LoopUnswitch::UnswitchNontrivialCondition(Value *LIC, Constant *Val,
// Now we rewrite the original code to know that the condition is true and the
// new code to know that the condition is false.
- RewriteLoopBodyWithConditionConstant(L , LIC, Val, false);
+ RewriteLoopBodyWithConditionConstant(L, LIC, Val, false);
// It's possible that simplifying one loop could cause the other to be
// deleted. If so, don't simplify it.
@@ -884,65 +881,66 @@ void LoopUnswitch::RewriteLoopBodyWithConditionConstant(Loop *L, Value *LIC,
U->replaceUsesOfWith(LIC, Replacement);
Worklist.push_back(U);
}
- } else {
- // Otherwise, we don't know the precise value of LIC, but we do know that it
- // is certainly NOT "Val". As such, simplify any uses in the loop that we
- // can. This case occurs when we unswitch switch statements.
- for (unsigned i = 0, e = Users.size(); i != e; ++i)
- if (Instruction *U = cast<Instruction>(Users[i])) {
- if (!L->contains(U))
- continue;
+ SimplifyCode(Worklist, L);
+ return;
+ }
+
+ // Otherwise, we don't know the precise value of LIC, but we do know that it
+ // is certainly NOT "Val". As such, simplify any uses in the loop that we
+ // can. This case occurs when we unswitch switch statements.
+ for (unsigned i = 0, e = Users.size(); i != e; ++i) {
+ Instruction *U = cast<Instruction>(Users[i]);
+ if (!L->contains(U))
+ continue;
- Worklist.push_back(U);
+ Worklist.push_back(U);
- // If we know that LIC is not Val, use this info to simplify code.
- if (SwitchInst *SI = dyn_cast<SwitchInst>(U)) {
- for (unsigned i = 1, e = SI->getNumCases(); i != e; ++i) {
- if (SI->getCaseValue(i) == Val) {
- // Found a dead case value. Don't remove PHI nodes in the
- // successor if they become single-entry, those PHI nodes may
- // be in the Users list.
-
- // FIXME: This is a hack. We need to keep the successor around
- // and hooked up so as to preserve the loop structure, because
- // trying to update it is complicated. So instead we preserve the
- // loop structure and put the block on a dead code path.
- BasicBlock *Switch = SI->getParent();
- SplitEdge(Switch, SI->getSuccessor(i), this);
- // Compute the successors instead of relying on the return value
- // of SplitEdge, since it may have split the switch successor
- // after PHI nodes.
- BasicBlock *NewSISucc = SI->getSuccessor(i);
- BasicBlock *OldSISucc = *succ_begin(NewSISucc);
- // Create an "unreachable" destination.
- BasicBlock *Abort = BasicBlock::Create(Context, "us-unreachable",
- Switch->getParent(),
- OldSISucc);
- new UnreachableInst(Context, Abort);
- // Force the new case destination to branch to the "unreachable"
- // block while maintaining a (dead) CFG edge to the old block.
- NewSISucc->getTerminator()->eraseFromParent();
- BranchInst::Create(Abort, OldSISucc,
- ConstantInt::getTrue(Context), NewSISucc);
- // Release the PHI operands for this edge.
- for (BasicBlock::iterator II = NewSISucc->begin();
- PHINode *PN = dyn_cast<PHINode>(II); ++II)
- PN->setIncomingValue(PN->getBasicBlockIndex(Switch),
- UndefValue::get(PN->getType()));
- // Tell the domtree about the new block. We don't fully update the
- // domtree here -- instead we force it to do a full recomputation
- // after the pass is complete -- but we do need to inform it of
- // new blocks.
- if (DT)
- DT->addNewBlock(Abort, NewSISucc);
- break;
- }
- }
- }
+ // TODO: We could do other simplifications, for example, turning
+ // 'icmp eq LIC, Val' -> false.
+
+ // If we know that LIC is not Val, use this info to simplify code.
+ SwitchInst *SI = dyn_cast<SwitchInst>(U);
+ if (SI == 0 || !isa<ConstantInt>(Val)) continue;
+
+ unsigned DeadCase = SI->findCaseValue(cast<ConstantInt>(Val));
+ if (DeadCase == 0) continue; // Default case is live for multiple values.
+
+ // Found a dead case value. Don't remove PHI nodes in the
+ // successor if they become single-entry, those PHI nodes may
+ // be in the Users list.
- // TODO: We could do other simplifications, for example, turning
- // LIC == Val -> false.
- }
+ // FIXME: This is a hack. We need to keep the successor around
+ // and hooked up so as to preserve the loop structure, because
+ // trying to update it is complicated. So instead we preserve the
+ // loop structure and put the block on a dead code path.
+ BasicBlock *Switch = SI->getParent();
+ SplitEdge(Switch, SI->getSuccessor(DeadCase), this);
+ // Compute the successors instead of relying on the return value
+ // of SplitEdge, since it may have split the switch successor
+ // after PHI nodes.
+ BasicBlock *NewSISucc = SI->getSuccessor(DeadCase);
+ BasicBlock *OldSISucc = *succ_begin(NewSISucc);
+ // Create an "unreachable" destination.
+ BasicBlock *Abort = BasicBlock::Create(Context, "us-unreachable",
+ Switch->getParent(),
+ OldSISucc);
+ new UnreachableInst(Context, Abort);
+ // Force the new case destination to branch to the "unreachable"
+ // block while maintaining a (dead) CFG edge to the old block.
+ NewSISucc->getTerminator()->eraseFromParent();
+ BranchInst::Create(Abort, OldSISucc,
+ ConstantInt::getTrue(Context), NewSISucc);
+ // Release the PHI operands for this edge.
+ for (BasicBlock::iterator II = NewSISucc->begin();
+ PHINode *PN = dyn_cast<PHINode>(II); ++II)
+ PN->setIncomingValue(PN->getBasicBlockIndex(Switch),
+ UndefValue::get(PN->getType()));
+ // Tell the domtree about the new block. We don't fully update the
+ // domtree here -- instead we force it to do a full recomputation
+ // after the pass is complete -- but we do need to inform it of
+ // new blocks.
+ if (DT)
+ DT->addNewBlock(Abort, NewSISucc);
}
SimplifyCode(Worklist, L);
@@ -1054,7 +1052,10 @@ void LoopUnswitch::SimplifyCode(std::vector<Instruction*> &Worklist, Loop *L) {
LPM->deleteSimpleAnalysisValue(Succ, L);
Succ->eraseFromParent();
++NumSimplify;
- } else if (ConstantInt *CB = dyn_cast<ConstantInt>(BI->getCondition())){
+ break;
+ }
+
+ if (ConstantInt *CB = dyn_cast<ConstantInt>(BI->getCondition())){
// Conditional branch. Turn it into an unconditional branch, then
// remove dead blocks.
break; // FIXME: Enable.
diff --git a/lib/Transforms/Scalar/MemCpyOptimizer.cpp b/lib/Transforms/Scalar/MemCpyOptimizer.cpp
index 62e2977..3b305ae 100644
--- a/lib/Transforms/Scalar/MemCpyOptimizer.cpp
+++ b/lib/Transforms/Scalar/MemCpyOptimizer.cpp
@@ -413,7 +413,6 @@ bool MemCpyOpt::processStore(StoreInst *SI, BasicBlock::iterator &BBI) {
// interesting as a small compile-time optimization.
Ranges.addStore(0, SI);
- Function *MemSetF = 0;
// Now that we have full information about ranges, loop over the ranges and
// emit memset's for anything big enough to be worthwhile.
@@ -433,29 +432,40 @@ bool MemCpyOpt::processStore(StoreInst *SI, BasicBlock::iterator &BBI) {
// memset block. This ensure that the memset is dominated by any addressing
// instruction needed by the start of the block.
BasicBlock::iterator InsertPt = BI;
-
- if (MemSetF == 0) {
- const Type *Ty = Type::getInt64Ty(Context);
- MemSetF = Intrinsic::getDeclaration(M, Intrinsic::memset, &Ty, 1);
- }
-
+
// Get the starting pointer of the block.
StartPtr = Range.StartPtr;
-
+
+ // Determine alignment
+ unsigned Alignment = Range.Alignment;
+ if (Alignment == 0) {
+ const Type *EltType =
+ cast<PointerType>(StartPtr->getType())->getElementType();
+ Alignment = TD->getABITypeAlignment(EltType);
+ }
+
// Cast the start ptr to be i8* as memset requires.
- const Type *i8Ptr = Type::getInt8PtrTy(Context);
- if (StartPtr->getType() != i8Ptr)
+ const PointerType* StartPTy = cast<PointerType>(StartPtr->getType());
+ const PointerType *i8Ptr = Type::getInt8PtrTy(Context,
+ StartPTy->getAddressSpace());
+ if (StartPTy!= i8Ptr)
StartPtr = new BitCastInst(StartPtr, i8Ptr, StartPtr->getName(),
InsertPt);
-
+
Value *Ops[] = {
StartPtr, ByteVal, // Start, value
// size
ConstantInt::get(Type::getInt64Ty(Context), Range.End-Range.Start),
// align
- ConstantInt::get(Type::getInt32Ty(Context), Range.Alignment)
+ ConstantInt::get(Type::getInt32Ty(Context), Alignment),
+ // volatile
+ ConstantInt::get(Type::getInt1Ty(Context), 0),
};
- Value *C = CallInst::Create(MemSetF, Ops, Ops+4, "", InsertPt);
+ const Type *Tys[] = { Ops[0]->getType(), Ops[2]->getType() };
+
+ Function *MemSetF = Intrinsic::getDeclaration(M, Intrinsic::memset, Tys, 2);
+
+ Value *C = CallInst::Create(MemSetF, Ops, Ops+5, "", InsertPt);
DEBUG(dbgs() << "Replace stores:\n";
for (unsigned i = 0, e = Range.TheStores.size(); i != e; ++i)
dbgs() << *Range.TheStores[i];
@@ -680,16 +690,19 @@ bool MemCpyOpt::processMemCpy(MemCpyInst *M) {
return false;
// If all checks passed, then we can transform these memcpy's
- const Type *Ty = M->getLength()->getType();
+ const Type *ArgTys[3] = { M->getRawDest()->getType(),
+ MDep->getRawSource()->getType(),
+ M->getLength()->getType() };
Function *MemCpyFun = Intrinsic::getDeclaration(
M->getParent()->getParent()->getParent(),
- M->getIntrinsicID(), &Ty, 1);
+ M->getIntrinsicID(), ArgTys, 3);
- Value *Args[4] = {
- M->getRawDest(), MDep->getRawSource(), M->getLength(), M->getAlignmentCst()
+ Value *Args[5] = {
+ M->getRawDest(), MDep->getRawSource(), M->getLength(),
+ M->getAlignmentCst(), M->getVolatileCst()
};
- CallInst *C = CallInst::Create(MemCpyFun, Args, Args+4, "", M);
+ CallInst *C = CallInst::Create(MemCpyFun, Args, Args+5, "", M);
// If C and M don't interfere, then this is a valid transformation. If they
@@ -728,8 +741,10 @@ bool MemCpyOpt::processMemMove(MemMoveInst *M) {
// If not, then we know we can transform this.
Module *Mod = M->getParent()->getParent()->getParent();
- const Type *Ty = M->getLength()->getType();
- M->setOperand(0, Intrinsic::getDeclaration(Mod, Intrinsic::memcpy, &Ty, 1));
+ const Type *ArgTys[3] = { M->getRawDest()->getType(),
+ M->getRawSource()->getType(),
+ M->getLength()->getType() };
+ M->setOperand(0,Intrinsic::getDeclaration(Mod, Intrinsic::memcpy, ArgTys, 3));
// MemDep may have over conservative information about this instruction, just
// conservatively flush it from the cache.
diff --git a/lib/Transforms/Scalar/SCCP.cpp b/lib/Transforms/Scalar/SCCP.cpp
index 546b7b6..4f09bee 100644
--- a/lib/Transforms/Scalar/SCCP.cpp
+++ b/lib/Transforms/Scalar/SCCP.cpp
@@ -1521,45 +1521,48 @@ bool SCCPSolver::ResolvedUndefsIn(Function &F) {
}
}
+ // Check to see if we have a branch or switch on an undefined value. If so
+ // we force the branch to go one way or the other to make the successor
+ // values live. It doesn't really matter which way we force it.
TerminatorInst *TI = BB->getTerminator();
if (BranchInst *BI = dyn_cast<BranchInst>(TI)) {
if (!BI->isConditional()) continue;
if (!getValueState(BI->getCondition()).isUndefined())
continue;
- } else if (SwitchInst *SI = dyn_cast<SwitchInst>(TI)) {
+
+ // If the input to SCCP is actually branch on undef, fix the undef to
+ // false.
+ if (isa<UndefValue>(BI->getCondition())) {
+ BI->setCondition(ConstantInt::getFalse(BI->getContext()));
+ markEdgeExecutable(BB, TI->getSuccessor(1));
+ return true;
+ }
+
+ // Otherwise, it is a branch on a symbolic value which is currently
+ // considered to be undef. Handle this by forcing the input value to the
+ // branch to false.
+ markForcedConstant(BI->getCondition(),
+ ConstantInt::getFalse(TI->getContext()));
+ return true;
+ }
+
+ if (SwitchInst *SI = dyn_cast<SwitchInst>(TI)) {
if (SI->getNumSuccessors() < 2) // no cases
continue;
if (!getValueState(SI->getCondition()).isUndefined())
continue;
- } else {
- continue;
- }
-
- // If the edge to the second successor isn't thought to be feasible yet,
- // mark it so now. We pick the second one so that this goes to some
- // enumerated value in a switch instead of going to the default destination.
- if (KnownFeasibleEdges.count(Edge(BB, TI->getSuccessor(1))))
- continue;
-
- // Otherwise, it isn't already thought to be feasible. Mark it as such now
- // and return. This will make other blocks reachable, which will allow new
- // values to be discovered and existing ones to be moved in the lattice.
- markEdgeExecutable(BB, TI->getSuccessor(1));
-
- // This must be a conditional branch of switch on undef. At this point,
- // force the old terminator to branch to the first successor. This is
- // required because we are now influencing the dataflow of the function with
- // the assumption that this edge is taken. If we leave the branch condition
- // as undef, then further analysis could think the undef went another way
- // leading to an inconsistent set of conclusions.
- if (BranchInst *BI = dyn_cast<BranchInst>(TI)) {
- BI->setCondition(ConstantInt::getFalse(BI->getContext()));
- } else {
- SwitchInst *SI = cast<SwitchInst>(TI);
- SI->setCondition(SI->getCaseValue(1));
+
+ // If the input to SCCP is actually switch on undef, fix the undef to
+ // the first constant.
+ if (isa<UndefValue>(SI->getCondition())) {
+ SI->setCondition(SI->getCaseValue(1));
+ markEdgeExecutable(BB, TI->getSuccessor(1));
+ return true;
+ }
+
+ markForcedConstant(SI->getCondition(), SI->getCaseValue(1));
+ return true;
}
-
- return true;
}
return false;
diff --git a/lib/Transforms/Scalar/ScalarReplAggregates.cpp b/lib/Transforms/Scalar/ScalarReplAggregates.cpp
index bbe6270..6211beb 100644
--- a/lib/Transforms/Scalar/ScalarReplAggregates.cpp
+++ b/lib/Transforms/Scalar/ScalarReplAggregates.cpp
@@ -858,8 +858,17 @@ void SROA::RewriteMemIntrinUserOfAlloca(MemIntrinsic *MI, Instruction *Inst,
EltPtr = new BitCastInst(EltPtr, BytePtrTy, EltPtr->getName(), MI);
// Cast the other pointer (if we have one) to BytePtrTy.
- if (OtherElt && OtherElt->getType() != BytePtrTy)
- OtherElt = new BitCastInst(OtherElt, BytePtrTy, OtherElt->getName(), MI);
+ if (OtherElt && OtherElt->getType() != BytePtrTy) {
+ // Preserve address space of OtherElt
+ const PointerType* OtherPTy = cast<PointerType>(OtherElt->getType());
+ const PointerType* PTy = cast<PointerType>(BytePtrTy);
+ if (OtherPTy->getElementType() != PTy->getElementType()) {
+ Type *NewOtherPTy = PointerType::get(PTy->getElementType(),
+ OtherPTy->getAddressSpace());
+ OtherElt = new BitCastInst(OtherElt, NewOtherPTy,
+ OtherElt->getNameStr(), MI);
+ }
+ }
unsigned EltSize = TD->getTypeAllocSize(EltTy);
@@ -870,17 +879,28 @@ void SROA::RewriteMemIntrinUserOfAlloca(MemIntrinsic *MI, Instruction *Inst,
SROADest ? OtherElt : EltPtr, // Src ptr
ConstantInt::get(MI->getOperand(3)->getType(), EltSize), // Size
// Align
- ConstantInt::get(Type::getInt32Ty(MI->getContext()), OtherEltAlign)
+ ConstantInt::get(Type::getInt32Ty(MI->getContext()), OtherEltAlign),
+ MI->getVolatileCst()
};
- CallInst::Create(TheFn, Ops, Ops + 4, "", MI);
+ // In case we fold the address space overloaded memcpy of A to B
+ // with memcpy of B to C, change the function to be a memcpy of A to C.
+ const Type *Tys[] = { Ops[0]->getType(), Ops[1]->getType(),
+ Ops[2]->getType() };
+ Module *M = MI->getParent()->getParent()->getParent();
+ TheFn = Intrinsic::getDeclaration(M, MI->getIntrinsicID(), Tys, 3);
+ CallInst::Create(TheFn, Ops, Ops + 5, "", MI);
} else {
assert(isa<MemSetInst>(MI));
Value *Ops[] = {
EltPtr, MI->getOperand(2), // Dest, Value,
ConstantInt::get(MI->getOperand(3)->getType(), EltSize), // Size
- Zero // Align
+ Zero, // Align
+ ConstantInt::get(Type::getInt1Ty(MI->getContext()), 0) // isVolatile
};
- CallInst::Create(TheFn, Ops, Ops + 4, "", MI);
+ const Type *Tys[] = { Ops[0]->getType(), Ops[2]->getType() };
+ Module *M = MI->getParent()->getParent()->getParent();
+ TheFn = Intrinsic::getDeclaration(M, Intrinsic::memset, Tys, 2);
+ CallInst::Create(TheFn, Ops, Ops + 5, "", MI);
}
}
DeadInsts.push_back(MI);
diff --git a/lib/Transforms/Scalar/SimplifyLibCalls.cpp b/lib/Transforms/Scalar/SimplifyLibCalls.cpp
index 5941ea6..b053cfc 100644
--- a/lib/Transforms/Scalar/SimplifyLibCalls.cpp
+++ b/lib/Transforms/Scalar/SimplifyLibCalls.cpp
@@ -142,7 +142,8 @@ struct StrCatOpt : public LibCallOptimization {
// We have enough information to now generate the memcpy call to do the
// concatenation for us. Make a memcpy to copy the nul byte with align = 1.
EmitMemCpy(CpyDst, Src,
- ConstantInt::get(TD->getIntPtrType(*Context), Len+1), 1, B, TD);
+ ConstantInt::get(TD->getIntPtrType(*Context), Len+1),
+ 1, false, B, TD);
}
};
@@ -383,7 +384,8 @@ struct StrCpyOpt : public LibCallOptimization {
CI->getOperand(3), B, TD);
else
EmitMemCpy(Dst, Src,
- ConstantInt::get(TD->getIntPtrType(*Context), Len), 1, B, TD);
+ ConstantInt::get(TD->getIntPtrType(*Context), Len),
+ 1, false, B, TD);
return Dst;
}
};
@@ -411,8 +413,8 @@ struct StrNCpyOpt : public LibCallOptimization {
if (SrcLen == 0) {
// strncpy(x, "", y) -> memset(x, '\0', y, 1)
- EmitMemSet(Dst, ConstantInt::get(Type::getInt8Ty(*Context), '\0'), LenOp,
- B, TD);
+ EmitMemSet(Dst, ConstantInt::get(Type::getInt8Ty(*Context), '\0'),
+ LenOp, false, B, TD);
return Dst;
}
@@ -432,7 +434,8 @@ struct StrNCpyOpt : public LibCallOptimization {
// strncpy(x, s, c) -> memcpy(x, s, c, 1) [s and c are constant]
EmitMemCpy(Dst, Src,
- ConstantInt::get(TD->getIntPtrType(*Context), Len), 1, B, TD);
+ ConstantInt::get(TD->getIntPtrType(*Context), Len),
+ 1, false, B, TD);
return Dst;
}
@@ -593,7 +596,7 @@ struct MemCpyOpt : public LibCallOptimization {
// memcpy(x, y, n) -> llvm.memcpy(x, y, n, 1)
EmitMemCpy(CI->getOperand(1), CI->getOperand(2),
- CI->getOperand(3), 1, B, TD);
+ CI->getOperand(3), 1, false, B, TD);
return CI->getOperand(1);
}
};
@@ -615,7 +618,7 @@ struct MemMoveOpt : public LibCallOptimization {
// memmove(x, y, n) -> llvm.memmove(x, y, n, 1)
EmitMemMove(CI->getOperand(1), CI->getOperand(2),
- CI->getOperand(3), 1, B, TD);
+ CI->getOperand(3), 1, false, B, TD);
return CI->getOperand(1);
}
};
@@ -637,8 +640,8 @@ struct MemSetOpt : public LibCallOptimization {
// memset(p, v, n) -> llvm.memset(p, v, n, 1)
Value *Val = B.CreateIntCast(CI->getOperand(2), Type::getInt8Ty(*Context),
- false);
- EmitMemSet(CI->getOperand(1), Val, CI->getOperand(3), B, TD);
+ false);
+ EmitMemSet(CI->getOperand(1), Val, CI->getOperand(3), false, B, TD);
return CI->getOperand(1);
}
};
@@ -999,7 +1002,7 @@ struct SPrintFOpt : public LibCallOptimization {
// sprintf(str, fmt) -> llvm.memcpy(str, fmt, strlen(fmt)+1, 1)
EmitMemCpy(CI->getOperand(1), CI->getOperand(2), // Copy the nul byte.
ConstantInt::get(TD->getIntPtrType(*Context),
- FormatStr.size()+1), 1, B, TD);
+ FormatStr.size()+1), 1, false, B, TD);
return ConstantInt::get(CI->getType(), FormatStr.size());
}
@@ -1013,11 +1016,11 @@ struct SPrintFOpt : public LibCallOptimization {
// sprintf(dst, "%c", chr) --> *(i8*)dst = chr; *((i8*)dst+1) = 0
if (!CI->getOperand(3)->getType()->isIntegerTy()) return 0;
Value *V = B.CreateTrunc(CI->getOperand(3),
- Type::getInt8Ty(*Context), "char");
+ Type::getInt8Ty(*Context), "char");
Value *Ptr = CastToCStr(CI->getOperand(1), B);
B.CreateStore(V, Ptr);
Ptr = B.CreateGEP(Ptr, ConstantInt::get(Type::getInt32Ty(*Context), 1),
- "nul");
+ "nul");
B.CreateStore(Constant::getNullValue(Type::getInt8Ty(*Context)), Ptr);
return ConstantInt::get(CI->getType(), 1);
@@ -1034,7 +1037,7 @@ struct SPrintFOpt : public LibCallOptimization {
Value *IncLen = B.CreateAdd(Len,
ConstantInt::get(Len->getType(), 1),
"leninc");
- EmitMemCpy(CI->getOperand(1), CI->getOperand(3), IncLen, 1, B, TD);
+ EmitMemCpy(CI->getOperand(1), CI->getOperand(3), IncLen, 1, false, B, TD);
// The sprintf result is the unincremented number of bytes in the string.
return B.CreateIntCast(Len, CI->getType(), false);
diff --git a/lib/Transforms/Utils/BasicBlockUtils.cpp b/lib/Transforms/Utils/BasicBlockUtils.cpp
index 1f62dab..2f1ae00 100644
--- a/lib/Transforms/Utils/BasicBlockUtils.cpp
+++ b/lib/Transforms/Utils/BasicBlockUtils.cpp
@@ -336,21 +336,19 @@ BasicBlock *llvm::SplitBlock(BasicBlock *Old, Instruction *SplitPt, Pass *P) {
if (Loop *L = LI->getLoopFor(Old))
L->addBasicBlockToLoop(New, LI->getBase());
- if (DominatorTree *DT = P->getAnalysisIfAvailable<DominatorTree>())
- {
- // Old dominates New. New node domiantes all other nodes dominated by Old.
- DomTreeNode *OldNode = DT->getNode(Old);
- std::vector<DomTreeNode *> Children;
- for (DomTreeNode::iterator I = OldNode->begin(), E = OldNode->end();
- I != E; ++I)
- Children.push_back(*I);
-
- DomTreeNode *NewNode = DT->addNewBlock(New,Old);
-
+ if (DominatorTree *DT = P->getAnalysisIfAvailable<DominatorTree>()) {
+ // Old dominates New. New node domiantes all other nodes dominated by Old.
+ DomTreeNode *OldNode = DT->getNode(Old);
+ std::vector<DomTreeNode *> Children;
+ for (DomTreeNode::iterator I = OldNode->begin(), E = OldNode->end();
+ I != E; ++I)
+ Children.push_back(*I);
+
+ DomTreeNode *NewNode = DT->addNewBlock(New,Old);
for (std::vector<DomTreeNode *>::iterator I = Children.begin(),
E = Children.end(); I != E; ++I)
DT->changeImmediateDominator(*I, NewNode);
- }
+ }
if (DominanceFrontier *DF = P->getAnalysisIfAvailable<DominanceFrontier>())
DF->splitBlock(Old);
diff --git a/lib/Transforms/Utils/BuildLibCalls.cpp b/lib/Transforms/Utils/BuildLibCalls.cpp
index 0afccf4..fff8179 100644
--- a/lib/Transforms/Utils/BuildLibCalls.cpp
+++ b/lib/Transforms/Utils/BuildLibCalls.cpp
@@ -109,15 +109,16 @@ Value *llvm::EmitStrNCpy(Value *Dst, Value *Src, Value *Len,
/// EmitMemCpy - Emit a call to the memcpy function to the builder. This always
/// expects that Len has type 'intptr_t' and Dst/Src are pointers.
-Value *llvm::EmitMemCpy(Value *Dst, Value *Src, Value *Len,
- unsigned Align, IRBuilder<> &B, const TargetData *TD) {
+Value *llvm::EmitMemCpy(Value *Dst, Value *Src, Value *Len, unsigned Align,
+ bool isVolatile, IRBuilder<> &B, const TargetData *TD) {
Module *M = B.GetInsertBlock()->getParent()->getParent();
- const Type *Ty = Len->getType();
- Value *MemCpy = Intrinsic::getDeclaration(M, Intrinsic::memcpy, &Ty, 1);
+ const Type *ArgTys[3] = { Dst->getType(), Src->getType(), Len->getType() };
+ Value *MemCpy = Intrinsic::getDeclaration(M, Intrinsic::memcpy, ArgTys, 3);
Dst = CastToCStr(Dst, B);
Src = CastToCStr(Src, B);
- return B.CreateCall4(MemCpy, Dst, Src, Len,
- ConstantInt::get(B.getInt32Ty(), Align));
+ return B.CreateCall5(MemCpy, Dst, Src, Len,
+ ConstantInt::get(B.getInt32Ty(), Align),
+ ConstantInt::get(B.getInt1Ty(), isVolatile));
}
/// EmitMemCpyChk - Emit a call to the __memcpy_chk function to the builder.
@@ -146,16 +147,18 @@ Value *llvm::EmitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize,
/// EmitMemMove - Emit a call to the memmove function to the builder. This
/// always expects that the size has type 'intptr_t' and Dst/Src are pointers.
-Value *llvm::EmitMemMove(Value *Dst, Value *Src, Value *Len,
- unsigned Align, IRBuilder<> &B, const TargetData *TD) {
+Value *llvm::EmitMemMove(Value *Dst, Value *Src, Value *Len, unsigned Align,
+ bool isVolatile, IRBuilder<> &B, const TargetData *TD) {
Module *M = B.GetInsertBlock()->getParent()->getParent();
LLVMContext &Context = B.GetInsertBlock()->getContext();
- const Type *Ty = TD->getIntPtrType(Context);
- Value *MemMove = Intrinsic::getDeclaration(M, Intrinsic::memmove, &Ty, 1);
+ const Type *ArgTys[3] = { Dst->getType(), Src->getType(),
+ TD->getIntPtrType(Context) };
+ Value *MemMove = Intrinsic::getDeclaration(M, Intrinsic::memmove, ArgTys, 3);
Dst = CastToCStr(Dst, B);
Src = CastToCStr(Src, B);
Value *A = ConstantInt::get(B.getInt32Ty(), Align);
- return B.CreateCall4(MemMove, Dst, Src, Len, A);
+ Value *Vol = ConstantInt::get(B.getInt1Ty(), isVolatile);
+ return B.CreateCall5(MemMove, Dst, Src, Len, A, Vol);
}
/// EmitMemChr - Emit a call to the memchr function. This assumes that Ptr is
@@ -206,15 +209,15 @@ Value *llvm::EmitMemCmp(Value *Ptr1, Value *Ptr2,
}
/// EmitMemSet - Emit a call to the memset function
-Value *llvm::EmitMemSet(Value *Dst, Value *Val,
- Value *Len, IRBuilder<> &B, const TargetData *TD) {
+Value *llvm::EmitMemSet(Value *Dst, Value *Val, Value *Len, bool isVolatile,
+ IRBuilder<> &B, const TargetData *TD) {
Module *M = B.GetInsertBlock()->getParent()->getParent();
Intrinsic::ID IID = Intrinsic::memset;
- const Type *Tys[1];
- Tys[0] = Len->getType();
- Value *MemSet = Intrinsic::getDeclaration(M, IID, Tys, 1);
+ const Type *Tys[2] = { Dst->getType(), Len->getType() };
+ Value *MemSet = Intrinsic::getDeclaration(M, IID, Tys, 2);
Value *Align = ConstantInt::get(B.getInt32Ty(), 1);
- return B.CreateCall4(MemSet, CastToCStr(Dst, B), Val, Len, Align);
+ Value *Vol = ConstantInt::get(B.getInt1Ty(), isVolatile);
+ return B.CreateCall5(MemSet, CastToCStr(Dst, B), Val, Len, Align, Vol);
}
/// EmitUnaryFloatFnCall - Emit a call to the unary function named 'Name' (e.g.
@@ -381,7 +384,7 @@ bool SimplifyFortifiedLibCalls::fold(CallInst *CI, const TargetData *TD) {
if (Name == "__memcpy_chk") {
if (isFoldable(4, 3, false)) {
EmitMemCpy(CI->getOperand(1), CI->getOperand(2), CI->getOperand(3),
- 1, B, TD);
+ 1, false, B, TD);
replaceCall(CI->getOperand(1));
return true;
}
@@ -396,7 +399,7 @@ bool SimplifyFortifiedLibCalls::fold(CallInst *CI, const TargetData *TD) {
if (Name == "__memmove_chk") {
if (isFoldable(4, 3, false)) {
EmitMemMove(CI->getOperand(1), CI->getOperand(2), CI->getOperand(3),
- 1, B, TD);
+ 1, false, B, TD);
replaceCall(CI->getOperand(1));
return true;
}
@@ -407,7 +410,7 @@ bool SimplifyFortifiedLibCalls::fold(CallInst *CI, const TargetData *TD) {
if (isFoldable(4, 3, false)) {
Value *Val = B.CreateIntCast(CI->getOperand(2), B.getInt8Ty(),
false);
- EmitMemSet(CI->getOperand(1), Val, CI->getOperand(3), B, TD);
+ EmitMemSet(CI->getOperand(1), Val, CI->getOperand(3), false, B, TD);
replaceCall(CI->getOperand(1));
return true;
}
diff --git a/lib/Transforms/Utils/InlineFunction.cpp b/lib/Transforms/Utils/InlineFunction.cpp
index 17f8827..75c9ccd 100644
--- a/lib/Transforms/Utils/InlineFunction.cpp
+++ b/lib/Transforms/Utils/InlineFunction.cpp
@@ -297,10 +297,10 @@ bool llvm::InlineFunction(CallSite CS, CallGraph *CG, const TargetData *TD,
I->getName(),
&*Caller->begin()->begin());
// Emit a memcpy.
- const Type *Tys[] = { Type::getInt64Ty(Context) };
+ const Type *Tys[3] = {VoidPtrTy, VoidPtrTy, Type::getInt64Ty(Context)};
Function *MemCpyFn = Intrinsic::getDeclaration(Caller->getParent(),
Intrinsic::memcpy,
- Tys, 1);
+ Tys, 3);
Value *DestCast = new BitCastInst(NewAlloca, VoidPtrTy, "tmp", TheCall);
Value *SrcCast = new BitCastInst(*AI, VoidPtrTy, "tmp", TheCall);
@@ -309,17 +309,18 @@ bool llvm::InlineFunction(CallSite CS, CallGraph *CG, const TargetData *TD,
Size = ConstantExpr::getSizeOf(AggTy);
else
Size = ConstantInt::get(Type::getInt64Ty(Context),
- TD->getTypeStoreSize(AggTy));
+ TD->getTypeStoreSize(AggTy));
// Always generate a memcpy of alignment 1 here because we don't know
// the alignment of the src pointer. Other optimizations can infer
// better alignment.
Value *CallArgs[] = {
DestCast, SrcCast, Size,
- ConstantInt::get(Type::getInt32Ty(Context), 1)
+ ConstantInt::get(Type::getInt32Ty(Context), 1),
+ ConstantInt::get(Type::getInt1Ty(Context), 0)
};
CallInst *TheMemCpy =
- CallInst::Create(MemCpyFn, CallArgs, CallArgs+4, "", TheCall);
+ CallInst::Create(MemCpyFn, CallArgs, CallArgs+5, "", TheCall);
// If we have a call graph, update it.
if (CG) {
diff --git a/lib/VMCore/AutoUpgrade.cpp b/lib/VMCore/AutoUpgrade.cpp
index b9aa5c3..4d06b66 100644
--- a/lib/VMCore/AutoUpgrade.cpp
+++ b/lib/VMCore/AutoUpgrade.cpp
@@ -145,6 +145,54 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
}
break;
+ case 'm': {
+ // This upgrades the llvm.memcpy, llvm.memmove, and llvm.memset to the
+ // new format that allows overloading the pointer for different address
+ // space (e.g., llvm.memcpy.i16 => llvm.memcpy.p0i8.p0i8.i16)
+ const char* NewFnName = NULL;
+ if (Name.compare(5,8,"memcpy.i",8) == 0) {
+ if (Name[13] == '8')
+ NewFnName = "llvm.memcpy.p0i8.p0i8.i8";
+ else if (Name.compare(13,2,"16") == 0)
+ NewFnName = "llvm.memcpy.p0i8.p0i8.i16";
+ else if (Name.compare(13,2,"32") == 0)
+ NewFnName = "llvm.memcpy.p0i8.p0i8.i32";
+ else if (Name.compare(13,2,"64") == 0)
+ NewFnName = "llvm.memcpy.p0i8.p0i8.i64";
+ } else if (Name.compare(5,9,"memmove.i",9) == 0) {
+ if (Name[14] == '8')
+ NewFnName = "llvm.memmove.p0i8.p0i8.i8";
+ else if (Name.compare(14,2,"16") == 0)
+ NewFnName = "llvm.memmove.p0i8.p0i8.i16";
+ else if (Name.compare(14,2,"32") == 0)
+ NewFnName = "llvm.memmove.p0i8.p0i8.i32";
+ else if (Name.compare(14,2,"64") == 0)
+ NewFnName = "llvm.memmove.p0i8.p0i8.i64";
+ }
+ else if (Name.compare(5,8,"memset.i",8) == 0) {
+ if (Name[13] == '8')
+ NewFnName = "llvm.memset.p0i8.i8";
+ else if (Name.compare(13,2,"16") == 0)
+ NewFnName = "llvm.memset.p0i8.i16";
+ else if (Name.compare(13,2,"32") == 0)
+ NewFnName = "llvm.memset.p0i8.i32";
+ else if (Name.compare(13,2,"64") == 0)
+ NewFnName = "llvm.memset.p0i8.i64";
+ }
+ if (NewFnName) {
+ const FunctionType *FTy = F->getFunctionType();
+ NewFn = cast<Function>(M->getOrInsertFunction(NewFnName,
+ FTy->getReturnType(),
+ FTy->getParamType(0),
+ FTy->getParamType(1),
+ FTy->getParamType(2),
+ FTy->getParamType(3),
+ Type::getInt1Ty(F->getContext()),
+ (Type *)0));
+ return true;
+ }
+ break;
+ }
case 'p':
// This upgrades the llvm.part.select overloaded intrinsic names to only
// use one type specifier in the name. We only care about the old format
@@ -472,6 +520,28 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
CI->eraseFromParent();
}
break;
+ case Intrinsic::memcpy:
+ case Intrinsic::memmove:
+ case Intrinsic::memset: {
+ // Add isVolatile
+ const llvm::Type *I1Ty = llvm::Type::getInt1Ty(CI->getContext());
+ Value *Operands[5] = { CI->getOperand(1), CI->getOperand(2),
+ CI->getOperand(3), CI->getOperand(4),
+ llvm::ConstantInt::get(I1Ty, 0) };
+ CallInst *NewCI = CallInst::Create(NewFn, Operands, Operands+5,
+ CI->getName(), CI);
+ NewCI->setTailCall(CI->isTailCall());
+ NewCI->setCallingConv(CI->getCallingConv());
+ // Handle any uses of the old CallInst.
+ if (!CI->use_empty())
+ // Replace all uses of the old call with the new cast which has the
+ // correct type.
+ CI->replaceAllUsesWith(NewCI);
+
+ // Clean up the old call now that it has been completely upgraded.
+ CI->eraseFromParent();
+ break;
+ }
}
}
diff --git a/lib/VMCore/LLVMContext.cpp b/lib/VMCore/LLVMContext.cpp
index 2a870ec..3244f28 100644
--- a/lib/VMCore/LLVMContext.cpp
+++ b/lib/VMCore/LLVMContext.cpp
@@ -33,6 +33,23 @@ LLVMContext::LLVMContext() : pImpl(new LLVMContextImpl(*this)) {
}
LLVMContext::~LLVMContext() { delete pImpl; }
+void LLVMContext::setInlineAsmDiagnosticHandler(void *DiagHandler,
+ void *DiagContext) {
+ pImpl->InlineAsmDiagHandler = DiagHandler;
+ pImpl->InlineAsmDiagContext = DiagContext;
+}
+
+/// getInlineAsmDiagnosticHandler - Return the diagnostic handler set by
+/// setInlineAsmDiagnosticHandler.
+void *LLVMContext::getInlineAsmDiagnosticHandler() const {
+ return pImpl->InlineAsmDiagHandler;
+}
+
+/// getInlineAsmDiagnosticContext - Return the diagnostic context set by
+/// setInlineAsmDiagnosticHandler.
+void *LLVMContext::getInlineAsmDiagnosticContext() const {
+ return pImpl->InlineAsmDiagContext;
+}
#ifndef NDEBUG
/// isValidName - Return true if Name is a valid custom metadata handler name.
@@ -73,5 +90,3 @@ void LLVMContext::getMDKindNames(SmallVectorImpl<StringRef> &Names) const {
// MD Handlers are numbered from 1.
Names[I->second] = I->first();
}
-
-
diff --git a/lib/VMCore/LLVMContextImpl.cpp b/lib/VMCore/LLVMContextImpl.cpp
index b4553dd..e71157f 100644
--- a/lib/VMCore/LLVMContextImpl.cpp
+++ b/lib/VMCore/LLVMContextImpl.cpp
@@ -30,6 +30,9 @@ LLVMContextImpl::LLVMContextImpl(LLVMContext &C)
Int32Ty(C, 32),
Int64Ty(C, 64),
AlwaysOpaqueTy(new OpaqueType(C)) {
+ InlineAsmDiagHandler = 0;
+ InlineAsmDiagContext = 0;
+
// Make sure the AlwaysOpaqueTy stays alive as long as the Context.
AlwaysOpaqueTy->addRef();
OpaqueTypes.insert(AlwaysOpaqueTy);
diff --git a/lib/VMCore/LLVMContextImpl.h b/lib/VMCore/LLVMContextImpl.h
index d4ebf80..4876f5d 100644
--- a/lib/VMCore/LLVMContextImpl.h
+++ b/lib/VMCore/LLVMContextImpl.h
@@ -115,6 +115,8 @@ public:
class LLVMContextImpl {
public:
+ void *InlineAsmDiagHandler, *InlineAsmDiagContext;
+
typedef DenseMap<DenseMapAPIntKeyInfo::KeyTy, ConstantInt*,
DenseMapAPIntKeyInfo> IntMapTy;
IntMapTy IntConstants;
diff --git a/lib/VMCore/Pass.cpp b/lib/VMCore/Pass.cpp
index 6093750..6b941f3 100644
--- a/lib/VMCore/Pass.cpp
+++ b/lib/VMCore/Pass.cpp
@@ -294,13 +294,8 @@ public:
static std::vector<PassRegistrationListener*> *Listeners = 0;
static sys::SmartMutex<true> ListenersLock;
-// FIXME: This should use ManagedStatic to manage the pass registrar.
-// Unfortunately, we can't do this, because passes are registered with static
-// ctors, and having llvm_shutdown clear this map prevents successful
-// ressurection after llvm_shutdown is run.
+static PassRegistrar *PassRegistrarObj = 0;
static PassRegistrar *getPassRegistrar() {
- static PassRegistrar *PassRegistrarObj = 0;
-
// Use double-checked locking to safely initialize the registrar when
// we're running in multithreaded mode.
PassRegistrar* tmp = PassRegistrarObj;
@@ -323,6 +318,19 @@ static PassRegistrar *getPassRegistrar() {
return PassRegistrarObj;
}
+// FIXME: We use ManagedCleanup to erase the pass registrar on shutdown.
+// Unfortunately, passes are registered with static ctors, and having
+// llvm_shutdown clear this map prevents successful ressurection after
+// llvm_shutdown is run. Ideally we should find a solution so that we don't
+// leak the map, AND can still resurrect after shutdown.
+void cleanupPassRegistrar(void*) {
+ if (PassRegistrarObj) {
+ delete PassRegistrarObj;
+ PassRegistrarObj = 0;
+ }
+}
+ManagedCleanup<&cleanupPassRegistrar> registrarCleanup;
+
// getPassInfo - Return the PassInfo data structure that corresponds to this
// pass...
const PassInfo *Pass::getPassInfo() const {
OpenPOWER on IntegriCloud