aboutsummaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/AsmPrinter/AsmPrinter.cpp')
-rw-r--r--lib/CodeGen/AsmPrinter/AsmPrinter.cpp164
1 files changed, 89 insertions, 75 deletions
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 69ff329..12c3574 100644
--- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -42,6 +42,7 @@
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/Timer.h"
#include "llvm/Target/Mangler.h"
+#include "llvm/Target/TargetFrameLowering.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetLowering.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
@@ -49,9 +50,9 @@
#include "llvm/Target/TargetRegisterInfo.h"
using namespace llvm;
-static const char *DWARFGroupName = "DWARF Emission";
-static const char *DbgTimerName = "DWARF Debug Writer";
-static const char *EHTimerName = "DWARF Exception Writer";
+static const char *const DWARFGroupName = "DWARF Emission";
+static const char *const DbgTimerName = "DWARF Debug Writer";
+static const char *const EHTimerName = "DWARF Exception Writer";
STATISTIC(EmittedInsts, "Number of machine instrs printed");
@@ -97,7 +98,7 @@ AsmPrinter::AsmPrinter(TargetMachine &tm, MCStreamer &Streamer)
OutContext(Streamer.getContext()),
OutStreamer(Streamer),
LastMI(0), LastFn(0), Counter(~0U), SetCounter(0) {
- DD = 0; DE = 0; MMI = 0; LI = 0;
+ DD = 0; DE = 0; MMI = 0; LI = 0; MF = 0;
CurrentFnSym = CurrentFnSymForSize = 0;
GCMetadataPrinters = 0;
VerboseAsm = Streamer.isVerboseAsm();
@@ -154,8 +155,6 @@ void AsmPrinter::getAnalysisUsage(AnalysisUsage &AU) const {
}
bool AsmPrinter::doInitialization(Module &M) {
- OutStreamer.InitStreamer();
-
MMI = getAnalysisIfAvailable<MachineModuleInfo>();
MMI->AnalyzeModule(M);
@@ -163,6 +162,8 @@ bool AsmPrinter::doInitialization(Module &M) {
const_cast<TargetLoweringObjectFile&>(getObjFileLowering())
.Initialize(OutContext, TM);
+ OutStreamer.InitStreamer();
+
Mang = new Mangler(OutContext, &TM);
// Allow the target to emit any magic that it wants at the start of the file.
@@ -367,9 +368,10 @@ void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
MCSymbol *MangSym =
OutContext.GetOrCreateSymbol(GVSym->getName() + Twine("$tlv$init"));
- if (GVKind.isThreadBSS())
+ if (GVKind.isThreadBSS()) {
+ TheSection = getObjFileLowering().getTLSBSSSection();
OutStreamer.EmitTBSSSymbol(TheSection, MangSym, Size, 1 << AlignLog);
- else if (GVKind.isThreadData()) {
+ } else if (GVKind.isThreadData()) {
OutStreamer.SwitchSection(TheSection);
EmitAlignment(AlignLog, GV);
@@ -395,7 +397,7 @@ void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
// - pointer to mangled symbol above with initializer
unsigned PtrSize = TD->getPointerSizeInBits()/8;
OutStreamer.EmitSymbolValue(GetExternalSymbolSymbol("_tlv_bootstrap"),
- PtrSize);
+ PtrSize);
OutStreamer.EmitIntValue(0, PtrSize);
OutStreamer.EmitSymbolValue(MangSym, PtrSize);
@@ -562,10 +564,17 @@ static bool emitDebugValueComment(const MachineInstr *MI, AsmPrinter &AP) {
// cast away const; DIetc do not take const operands for some reason.
DIVariable V(const_cast<MDNode*>(MI->getOperand(2).getMetadata()));
- if (V.getContext().isSubprogram())
- OS << DISubprogram(V.getContext()).getDisplayName() << ":";
+ if (V.getContext().isSubprogram()) {
+ StringRef Name = DISubprogram(V.getContext()).getDisplayName();
+ if (!Name.empty())
+ OS << Name << ":";
+ }
OS << V.getName() << " <- ";
+ // The second operand is only an offset if it's an immediate.
+ bool Deref = MI->getOperand(0).isReg() && MI->getOperand(1).isImm();
+ int64_t Offset = Deref ? MI->getOperand(1).getImm() : 0;
+
// Register or immediate value. Register 0 means undef.
if (MI->getOperand(0).isFPImm()) {
APFloat APF = APFloat(MI->getOperand(0).getFPImm()->getValueAPF());
@@ -586,18 +595,31 @@ static bool emitDebugValueComment(const MachineInstr *MI, AsmPrinter &AP) {
} else if (MI->getOperand(0).isCImm()) {
MI->getOperand(0).getCImm()->getValue().print(OS, false /*isSigned*/);
} else {
- assert(MI->getOperand(0).isReg() && "Unknown operand type");
- if (MI->getOperand(0).getReg() == 0) {
+ unsigned Reg;
+ if (MI->getOperand(0).isReg()) {
+ Reg = MI->getOperand(0).getReg();
+ } else {
+ assert(MI->getOperand(0).isFI() && "Unknown operand type");
+ const TargetFrameLowering *TFI = AP.TM.getFrameLowering();
+ Offset += TFI->getFrameIndexReference(*AP.MF,
+ MI->getOperand(0).getIndex(), Reg);
+ Deref = true;
+ }
+ if (Reg == 0) {
// Suppress offset, it is not meaningful here.
OS << "undef";
// NOTE: Want this comment at start of line, don't emit with AddComment.
AP.OutStreamer.EmitRawText(OS.str());
return true;
}
- OS << AP.TM.getRegisterInfo()->getName(MI->getOperand(0).getReg());
+ if (Deref)
+ OS << '[';
+ OS << AP.TM.getRegisterInfo()->getName(Reg);
}
- OS << '+' << MI->getOperand(1).getImm();
+ if (Deref)
+ OS << '+' << Offset << ']';
+
// NOTE: Want this comment at start of line, don't emit with AddComment.
AP.OutStreamer.EmitRawText(OS.str());
return true;
@@ -790,16 +812,9 @@ void AsmPrinter::EmitFunctionBody() {
OutStreamer.AddBlankLine();
}
-/// getDebugValueLocation - Get location information encoded by DBG_VALUE
-/// operands.
-MachineLocation AsmPrinter::
-getDebugValueLocation(const MachineInstr *MI) const {
- // Target specific DBG_VALUE instructions are handled by each target.
- return MachineLocation();
-}
-
/// EmitDwarfRegOp - Emit dwarf register operation.
-void AsmPrinter::EmitDwarfRegOp(const MachineLocation &MLoc) const {
+void AsmPrinter::EmitDwarfRegOp(const MachineLocation &MLoc,
+ bool Indirect) const {
const TargetRegisterInfo *TRI = TM.getRegisterInfo();
int Reg = TRI->getDwarfRegNum(MLoc.getReg(), false);
@@ -817,7 +832,7 @@ void AsmPrinter::EmitDwarfRegOp(const MachineLocation &MLoc) const {
// caller might be in the middle of an dwarf expression. We should
// probably assert that Reg >= 0 once debug info generation is more mature.
- if (MLoc.isIndirect()) {
+ if (MLoc.isIndirect() || Indirect) {
if (Reg < 32) {
OutStreamer.AddComment(
dwarf::OperationEncodingString(dwarf::DW_OP_breg0 + Reg));
@@ -828,7 +843,9 @@ void AsmPrinter::EmitDwarfRegOp(const MachineLocation &MLoc) const {
OutStreamer.AddComment(Twine(Reg));
EmitULEB128(Reg);
}
- EmitSLEB128(MLoc.getOffset());
+ EmitSLEB128(!MLoc.isIndirect() ? 0 : MLoc.getOffset());
+ if (MLoc.isIndirect() && Indirect)
+ EmitInt8(dwarf::DW_OP_deref);
} else {
if (Reg < 32) {
OutStreamer.AddComment(
@@ -1400,6 +1417,10 @@ void AsmPrinter::EmitLabelOffsetDifference(const MCSymbol *Hi, uint64_t Offset,
void AsmPrinter::EmitLabelPlusOffset(const MCSymbol *Label, uint64_t Offset,
unsigned Size)
const {
+ if (MAI->needsDwarfSectionOffsetDirective() && Size == 4) { // secrel32 ONLY works for 32bits.
+ OutStreamer.EmitCOFFSecRel32(Label);
+ return;
+ }
// Emit Label+Offset (or just Label if Offset is zero)
const MCExpr *Expr = MCSymbolRefExpr::Create(Label, OutContext);
@@ -1561,8 +1582,7 @@ static const MCExpr *lowerConstant(const Constant *CV, AsmPrinter &AP) {
}
}
-static void emitGlobalConstantImpl(const Constant *C, unsigned AddrSpace,
- AsmPrinter &AP);
+static void emitGlobalConstantImpl(const Constant *C, AsmPrinter &AP);
/// isRepeatedByteSequence - Determine whether the given value is
/// composed of a repeated sequence of identical bytes and return the
@@ -1624,7 +1644,7 @@ static int isRepeatedByteSequence(const Value *V, TargetMachine &TM) {
}
static void emitGlobalConstantDataSequential(const ConstantDataSequential *CDS,
- unsigned AddrSpace,AsmPrinter &AP){
+ AsmPrinter &AP){
// See if we can aggregate this into a .fill, if so, emit it as such.
int Value = isRepeatedByteSequence(CDS, AP.TM);
@@ -1632,12 +1652,12 @@ static void emitGlobalConstantDataSequential(const ConstantDataSequential *CDS,
uint64_t Bytes = AP.TM.getDataLayout()->getTypeAllocSize(CDS->getType());
// Don't emit a 1-byte object as a .fill.
if (Bytes > 1)
- return AP.OutStreamer.EmitFill(Bytes, Value, AddrSpace);
+ return AP.OutStreamer.EmitFill(Bytes, Value);
}
// If this can be emitted with .ascii/.asciz, emit it as such.
if (CDS->isString())
- return AP.OutStreamer.EmitBytes(CDS->getAsString(), AddrSpace);
+ return AP.OutStreamer.EmitBytes(CDS->getAsString());
// Otherwise, emit the values in successive locations.
unsigned ElementByteSize = CDS->getElementByteSize();
@@ -1647,7 +1667,7 @@ static void emitGlobalConstantDataSequential(const ConstantDataSequential *CDS,
AP.OutStreamer.GetCommentOS() << format("0x%" PRIx64 "\n",
CDS->getElementAsInteger(i));
AP.OutStreamer.EmitIntValue(CDS->getElementAsInteger(i),
- ElementByteSize, AddrSpace);
+ ElementByteSize);
}
} else if (ElementByteSize == 4) {
// FP Constants are printed as integer constants to avoid losing
@@ -1662,7 +1682,7 @@ static void emitGlobalConstantDataSequential(const ConstantDataSequential *CDS,
F = CDS->getElementAsFloat(i);
if (AP.isVerbose())
AP.OutStreamer.GetCommentOS() << "float " << F << '\n';
- AP.OutStreamer.EmitIntValue(I, 4, AddrSpace);
+ AP.OutStreamer.EmitIntValue(I, 4);
}
} else {
assert(CDS->getElementType()->isDoubleTy());
@@ -1675,7 +1695,7 @@ static void emitGlobalConstantDataSequential(const ConstantDataSequential *CDS,
F = CDS->getElementAsDouble(i);
if (AP.isVerbose())
AP.OutStreamer.GetCommentOS() << "double " << F << '\n';
- AP.OutStreamer.EmitIntValue(I, 8, AddrSpace);
+ AP.OutStreamer.EmitIntValue(I, 8);
}
}
@@ -1684,41 +1704,38 @@ static void emitGlobalConstantDataSequential(const ConstantDataSequential *CDS,
unsigned EmittedSize = TD.getTypeAllocSize(CDS->getType()->getElementType()) *
CDS->getNumElements();
if (unsigned Padding = Size - EmittedSize)
- AP.OutStreamer.EmitZeros(Padding, AddrSpace);
+ AP.OutStreamer.EmitZeros(Padding);
}
-static void emitGlobalConstantArray(const ConstantArray *CA, unsigned AddrSpace,
- AsmPrinter &AP) {
+static void emitGlobalConstantArray(const ConstantArray *CA, AsmPrinter &AP) {
// See if we can aggregate some values. Make sure it can be
// represented as a series of bytes of the constant value.
int Value = isRepeatedByteSequence(CA, AP.TM);
if (Value != -1) {
uint64_t Bytes = AP.TM.getDataLayout()->getTypeAllocSize(CA->getType());
- AP.OutStreamer.EmitFill(Bytes, Value, AddrSpace);
+ AP.OutStreamer.EmitFill(Bytes, Value);
}
else {
for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i)
- emitGlobalConstantImpl(CA->getOperand(i), AddrSpace, AP);
+ emitGlobalConstantImpl(CA->getOperand(i), AP);
}
}
-static void emitGlobalConstantVector(const ConstantVector *CV,
- unsigned AddrSpace, AsmPrinter &AP) {
+static void emitGlobalConstantVector(const ConstantVector *CV, AsmPrinter &AP) {
for (unsigned i = 0, e = CV->getType()->getNumElements(); i != e; ++i)
- emitGlobalConstantImpl(CV->getOperand(i), AddrSpace, AP);
+ emitGlobalConstantImpl(CV->getOperand(i), AP);
const DataLayout &TD = *AP.TM.getDataLayout();
unsigned Size = TD.getTypeAllocSize(CV->getType());
unsigned EmittedSize = TD.getTypeAllocSize(CV->getType()->getElementType()) *
CV->getType()->getNumElements();
if (unsigned Padding = Size - EmittedSize)
- AP.OutStreamer.EmitZeros(Padding, AddrSpace);
+ AP.OutStreamer.EmitZeros(Padding);
}
-static void emitGlobalConstantStruct(const ConstantStruct *CS,
- unsigned AddrSpace, AsmPrinter &AP) {
+static void emitGlobalConstantStruct(const ConstantStruct *CS, AsmPrinter &AP) {
// Print the fields in successive locations. Pad to align if needed!
const DataLayout *TD = AP.TM.getDataLayout();
unsigned Size = TD->getTypeAllocSize(CS->getType());
@@ -1734,19 +1751,18 @@ static void emitGlobalConstantStruct(const ConstantStruct *CS,
SizeSoFar += FieldSize + PadSize;
// Now print the actual field value.
- emitGlobalConstantImpl(Field, AddrSpace, AP);
+ emitGlobalConstantImpl(Field, AP);
// Insert padding - this may include padding to increase the size of the
// current field up to the ABI size (if the struct is not packed) as well
// as padding to ensure that the next field starts at the right offset.
- AP.OutStreamer.EmitZeros(PadSize, AddrSpace);
+ AP.OutStreamer.EmitZeros(PadSize);
}
assert(SizeSoFar == Layout->getSizeInBytes() &&
"Layout of constant struct may be incorrect!");
}
-static void emitGlobalConstantFP(const ConstantFP *CFP, unsigned AddrSpace,
- AsmPrinter &AP) {
+static void emitGlobalConstantFP(const ConstantFP *CFP, AsmPrinter &AP) {
APInt API = CFP->getValueAPF().bitcastToAPInt();
// First print a comment with what we think the original floating-point value
@@ -1772,27 +1788,26 @@ static void emitGlobalConstantFP(const ConstantFP *CFP, unsigned AddrSpace,
int Chunk = API.getNumWords() - 1;
if (TrailingBytes)
- AP.OutStreamer.EmitIntValue(p[Chunk--], TrailingBytes, AddrSpace);
+ AP.OutStreamer.EmitIntValue(p[Chunk--], TrailingBytes);
for (; Chunk >= 0; --Chunk)
- AP.OutStreamer.EmitIntValue(p[Chunk], sizeof(uint64_t), AddrSpace);
+ AP.OutStreamer.EmitIntValue(p[Chunk], sizeof(uint64_t));
} else {
unsigned Chunk;
for (Chunk = 0; Chunk < NumBytes / sizeof(uint64_t); ++Chunk)
- AP.OutStreamer.EmitIntValue(p[Chunk], sizeof(uint64_t), AddrSpace);
+ AP.OutStreamer.EmitIntValue(p[Chunk], sizeof(uint64_t));
if (TrailingBytes)
- AP.OutStreamer.EmitIntValue(p[Chunk], TrailingBytes, AddrSpace);
+ AP.OutStreamer.EmitIntValue(p[Chunk], TrailingBytes);
}
// Emit the tail padding for the long double.
const DataLayout &TD = *AP.TM.getDataLayout();
AP.OutStreamer.EmitZeros(TD.getTypeAllocSize(CFP->getType()) -
- TD.getTypeStoreSize(CFP->getType()), AddrSpace);
+ TD.getTypeStoreSize(CFP->getType()));
}
-static void emitGlobalConstantLargeInt(const ConstantInt *CI,
- unsigned AddrSpace, AsmPrinter &AP) {
+static void emitGlobalConstantLargeInt(const ConstantInt *CI, AsmPrinter &AP) {
const DataLayout *TD = AP.TM.getDataLayout();
unsigned BitWidth = CI->getBitWidth();
@@ -1832,7 +1847,7 @@ static void emitGlobalConstantLargeInt(const ConstantInt *CI,
const uint64_t *RawData = Realigned.getRawData();
for (unsigned i = 0, e = BitWidth / 64; i != e; ++i) {
uint64_t Val = TD->isBigEndian() ? RawData[e - i - 1] : RawData[i];
- AP.OutStreamer.EmitIntValue(Val, 8, AddrSpace);
+ AP.OutStreamer.EmitIntValue(Val, 8);
}
if (ExtraBitsSize) {
@@ -1844,16 +1859,15 @@ static void emitGlobalConstantLargeInt(const ConstantInt *CI,
assert(Size && Size * 8 >= ExtraBitsSize &&
(ExtraBits & (((uint64_t)-1) >> (64 - ExtraBitsSize)))
== ExtraBits && "Directive too small for extra bits.");
- AP.OutStreamer.EmitIntValue(ExtraBits, Size, AddrSpace);
+ AP.OutStreamer.EmitIntValue(ExtraBits, Size);
}
}
-static void emitGlobalConstantImpl(const Constant *CV, unsigned AddrSpace,
- AsmPrinter &AP) {
+static void emitGlobalConstantImpl(const Constant *CV, AsmPrinter &AP) {
const DataLayout *TD = AP.TM.getDataLayout();
uint64_t Size = TD->getTypeAllocSize(CV->getType());
if (isa<ConstantAggregateZero>(CV) || isa<UndefValue>(CV))
- return AP.OutStreamer.EmitZeros(Size, AddrSpace);
+ return AP.OutStreamer.EmitZeros(Size);
if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {
switch (Size) {
@@ -1864,36 +1878,36 @@ static void emitGlobalConstantImpl(const Constant *CV, unsigned AddrSpace,
if (AP.isVerbose())
AP.OutStreamer.GetCommentOS() << format("0x%" PRIx64 "\n",
CI->getZExtValue());
- AP.OutStreamer.EmitIntValue(CI->getZExtValue(), Size, AddrSpace);
+ AP.OutStreamer.EmitIntValue(CI->getZExtValue(), Size);
return;
default:
- emitGlobalConstantLargeInt(CI, AddrSpace, AP);
+ emitGlobalConstantLargeInt(CI, AP);
return;
}
}
if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV))
- return emitGlobalConstantFP(CFP, AddrSpace, AP);
+ return emitGlobalConstantFP(CFP, AP);
if (isa<ConstantPointerNull>(CV)) {
- AP.OutStreamer.EmitIntValue(0, Size, AddrSpace);
+ AP.OutStreamer.EmitIntValue(0, Size);
return;
}
if (const ConstantDataSequential *CDS = dyn_cast<ConstantDataSequential>(CV))
- return emitGlobalConstantDataSequential(CDS, AddrSpace, AP);
+ return emitGlobalConstantDataSequential(CDS, AP);
if (const ConstantArray *CVA = dyn_cast<ConstantArray>(CV))
- return emitGlobalConstantArray(CVA, AddrSpace, AP);
+ return emitGlobalConstantArray(CVA, AP);
if (const ConstantStruct *CVS = dyn_cast<ConstantStruct>(CV))
- return emitGlobalConstantStruct(CVS, AddrSpace, AP);
+ return emitGlobalConstantStruct(CVS, AP);
if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV)) {
// Look through bitcasts, which might not be able to be MCExpr'ized (e.g. of
// vectors).
if (CE->getOpcode() == Instruction::BitCast)
- return emitGlobalConstantImpl(CE->getOperand(0), AddrSpace, AP);
+ return emitGlobalConstantImpl(CE->getOperand(0), AP);
if (Size > 8) {
// If the constant expression's size is greater than 64-bits, then we have
@@ -1901,27 +1915,27 @@ static void emitGlobalConstantImpl(const Constant *CV, unsigned AddrSpace,
// that way.
Constant *New = ConstantFoldConstantExpression(CE, TD);
if (New && New != CE)
- return emitGlobalConstantImpl(New, AddrSpace, AP);
+ return emitGlobalConstantImpl(New, AP);
}
}
if (const ConstantVector *V = dyn_cast<ConstantVector>(CV))
- return emitGlobalConstantVector(V, AddrSpace, AP);
+ return emitGlobalConstantVector(V, AP);
// Otherwise, it must be a ConstantExpr. Lower it to an MCExpr, then emit it
// thread the streamer with EmitValue.
- AP.OutStreamer.EmitValue(lowerConstant(CV, AP), Size, AddrSpace);
+ AP.OutStreamer.EmitValue(lowerConstant(CV, AP), Size);
}
/// EmitGlobalConstant - Print a general LLVM constant to the .s file.
-void AsmPrinter::EmitGlobalConstant(const Constant *CV, unsigned AddrSpace) {
+void AsmPrinter::EmitGlobalConstant(const Constant *CV) {
uint64_t Size = TM.getDataLayout()->getTypeAllocSize(CV->getType());
if (Size)
- emitGlobalConstantImpl(CV, AddrSpace, *this);
+ emitGlobalConstantImpl(CV, *this);
else if (MAI->hasSubsectionsViaSymbols()) {
// If the global has zero size, emit a single byte so that two labels don't
// look like they are at the same location.
- OutStreamer.EmitIntValue(0, 1, AddrSpace);
+ OutStreamer.EmitIntValue(0, 1);
}
}