#include "llvm/CodeGen/MachineJumpTableInfo.h"
#include "llvm/CodeGen/MachineLoopInfo.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
-#include "llvm/DataLayout.h"
#include "llvm/DebugInfo.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/Operator.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
-#include "llvm/Module.h"
-#include "llvm/Operator.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/MathExtras.h"
return *TM.getDataLayout();
}
+StringRef AsmPrinter::getTargetTriple() const {
+ return TM.getTargetTriple();
+}
+
/// getCurrentSection() - Return the current section we are emitting to.
const MCSection *AsmPrinter::getCurrentSection() const {
- return OutStreamer.getCurrentSection();
+ return OutStreamer.getCurrentSection().first;
}
// - pointer to mangled symbol above with initializer
unsigned PtrSize = TD->getPointerSizeInBits()/8;
OutStreamer.EmitSymbolValue(GetExternalSymbolSymbol("_tlv_bootstrap"),
- PtrSize, 0);
- OutStreamer.EmitIntValue(0, PtrSize, 0);
- OutStreamer.EmitSymbolValue(MangSym, PtrSize, 0);
+ PtrSize);
+ OutStreamer.EmitIntValue(0, PtrSize);
+ OutStreamer.EmitSymbolValue(MangSym, PtrSize);
OutStreamer.AddBlankLine();
return;
OS << AP.TM.getRegisterInfo()->getName(MI->getOperand(0).getReg());
}
- OS << '+' << MI->getOperand(1).getImm();
+ // It's only an offset if it's an immediate.
+ if (MI->getOperand(1).isImm())
+ OS << '+' << MI->getOperand(1).getImm();
// NOTE: Want this comment at start of line, don't emit with AddComment.
AP.OutStreamer.EmitRawText(OS.str());
return true;
// 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 (int Offset = MLoc.getOffset()) {
+ if (MLoc.isIndirect()) {
if (Reg < 32) {
OutStreamer.AddComment(
dwarf::OperationEncodingString(dwarf::DW_OP_breg0 + Reg));
OutStreamer.AddComment(Twine(Reg));
EmitULEB128(Reg);
}
- EmitSLEB128(Offset);
+ EmitSLEB128(MLoc.getOffset());
} else {
if (Reg < 32) {
OutStreamer.AddComment(
// Emit inter-object padding for alignment.
unsigned AlignMask = CPE.getAlignment() - 1;
unsigned NewOffset = (Offset + AlignMask) & ~AlignMask;
- OutStreamer.EmitFill(NewOffset - Offset, 0/*fillval*/, 0/*addrspace*/);
+ OutStreamer.EmitZeros(NewOffset - Offset);
Type *Ty = CPE.getType();
Offset = NewOffset + TM.getDataLayout()->getTypeAllocSize(Ty);
assert(Value && "Unknown entry kind!");
unsigned EntrySize = MJTI->getEntrySize(*TM.getDataLayout());
- OutStreamer.EmitValue(Value, EntrySize, /*addrspace*/0);
+ OutStreamer.EmitValue(Value, EntrySize);
}
bool AsmPrinter::EmitSpecialLLVMGlobal(const GlobalVariable *GV) {
if (GV->getName() == "llvm.used") {
if (MAI->hasNoDeadStrip()) // No need to emit this at all.
- EmitLLVMUsedList(GV->getInitializer());
+ EmitLLVMUsedList(cast<ConstantArray>(GV->getInitializer()));
return true;
}
return true;
}
+ if (GV->getName() == "llvm.tls_init_funcs") {
+ EmitTLSInitFuncs(cast<ConstantArray>(GV->getInitializer()));
+ return true;
+ }
+
return false;
}
/// EmitLLVMUsedList - For targets that define a MAI::UsedDirective, mark each
/// global in the specified llvm.used list for which emitUsedDirectiveFor
/// is true, as being used with this directive.
-void AsmPrinter::EmitLLVMUsedList(const Constant *List) {
+void AsmPrinter::EmitLLVMUsedList(const ConstantArray *InitList) {
// Should be an array of 'i8*'.
- const ConstantArray *InitList = dyn_cast<ConstantArray>(List);
- if (InitList == 0) return;
-
for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) {
const GlobalValue *GV =
dyn_cast<GlobalValue>(InitList->getOperand(i)->stripPointerCasts());
}
}
+/// EmitTLSInitFuncs - Emit the TLS initialization functions.
+void AsmPrinter::EmitTLSInitFuncs(const ConstantArray *InitList) {
+ const DataLayout *TD = TM.getDataLayout();
+ OutStreamer.SwitchSection(getObjFileLowering().getTLSThreadInitSection());
+ EmitAlignment(Log2_32(TD->getPointerPrefAlignment()));
+ for (unsigned I = 0, E = InitList->getNumOperands(); I != E; ++I)
+ EmitGlobalConstant(
+ dyn_cast<Constant>(InitList->getOperand(I)->stripPointerCasts()));
+}
+
//===--------------------------------------------------------------------===//
// Emission and print routines
//
/// EmitInt8 - Emit a byte directive and value.
///
void AsmPrinter::EmitInt8(int Value) const {
- OutStreamer.EmitIntValue(Value, 1, 0/*addrspace*/);
+ OutStreamer.EmitIntValue(Value, 1);
}
/// EmitInt16 - Emit a short directive and value.
///
void AsmPrinter::EmitInt16(int Value) const {
- OutStreamer.EmitIntValue(Value, 2, 0/*addrspace*/);
+ OutStreamer.EmitIntValue(Value, 2);
}
/// EmitInt32 - Emit a long directive and value.
///
void AsmPrinter::EmitInt32(int Value) const {
- OutStreamer.EmitIntValue(Value, 4, 0/*addrspace*/);
+ OutStreamer.EmitIntValue(Value, 4);
}
/// EmitLabelDifference - Emit something like ".long Hi-Lo" where the size
OutContext);
if (!MAI->hasSetDirective()) {
- OutStreamer.EmitValue(Diff, Size, 0/*AddrSpace*/);
+ OutStreamer.EmitValue(Diff, Size);
return;
}
// Otherwise, emit with .set (aka assignment).
MCSymbol *SetLabel = GetTempSymbol("set", SetCounter++);
OutStreamer.EmitAssignment(SetLabel, Diff);
- OutStreamer.EmitSymbolValue(SetLabel, Size, 0/*AddrSpace*/);
+ OutStreamer.EmitSymbolValue(SetLabel, Size);
}
/// EmitLabelOffsetDifference - Emit something like ".long Hi+Offset-Lo"
OutContext);
if (!MAI->hasSetDirective())
- OutStreamer.EmitValue(Diff, 4, 0/*AddrSpace*/);
+ OutStreamer.EmitValue(Diff, 4);
else {
// Otherwise, emit with .set (aka assignment).
MCSymbol *SetLabel = GetTempSymbol("set", SetCounter++);
OutStreamer.EmitAssignment(SetLabel, Diff);
- OutStreamer.EmitSymbolValue(SetLabel, 4, 0/*AddrSpace*/);
+ OutStreamer.EmitSymbolValue(SetLabel, 4);
}
}
MCConstantExpr::Create(Offset, OutContext),
OutContext);
- OutStreamer.EmitValue(Expr, Size, 0/*AddrSpace*/);
+ OutStreamer.EmitValue(Expr, Size);
}
static void emitGlobalConstantFP(const ConstantFP *CFP, unsigned AddrSpace,
AsmPrinter &AP) {
- if (CFP->getType()->isHalfTy()) {
- if (AP.isVerbose()) {
- SmallString<10> Str;
- CFP->getValueAPF().toString(Str);
- AP.OutStreamer.GetCommentOS() << "half " << Str << '\n';
- }
- uint64_t Val = CFP->getValueAPF().bitcastToAPInt().getZExtValue();
- AP.OutStreamer.EmitIntValue(Val, 2, AddrSpace);
- return;
- }
-
- if (CFP->getType()->isFloatTy()) {
- if (AP.isVerbose()) {
- float Val = CFP->getValueAPF().convertToFloat();
- uint64_t IntVal = CFP->getValueAPF().bitcastToAPInt().getZExtValue();
- AP.OutStreamer.GetCommentOS() << "float " << Val << '\n'
- << " (" << format("0x%x", IntVal) << ")\n";
- }
- uint64_t Val = CFP->getValueAPF().bitcastToAPInt().getZExtValue();
- AP.OutStreamer.EmitIntValue(Val, 4, AddrSpace);
- return;
- }
+ APInt API = CFP->getValueAPF().bitcastToAPInt();
- // FP Constants are printed as integer constants to avoid losing
- // precision.
- if (CFP->getType()->isDoubleTy()) {
- if (AP.isVerbose()) {
- double Val = CFP->getValueAPF().convertToDouble();
- uint64_t IntVal = CFP->getValueAPF().bitcastToAPInt().getZExtValue();
- AP.OutStreamer.GetCommentOS() << "double " << Val << '\n'
- << " (" << format("0x%lx", IntVal) << ")\n";
- }
+ // First print a comment with what we think the original floating-point value
+ // should have been.
+ if (AP.isVerbose()) {
+ SmallString<8> StrVal;
+ CFP->getValueAPF().toString(StrVal);
- uint64_t Val = CFP->getValueAPF().bitcastToAPInt().getZExtValue();
- AP.OutStreamer.EmitIntValue(Val, 8, AddrSpace);
- return;
+ CFP->getType()->print(AP.OutStreamer.GetCommentOS());
+ AP.OutStreamer.GetCommentOS() << ' ' << StrVal << '\n';
}
- if (CFP->getType()->isX86_FP80Ty()) {
- // all long double variants are printed as hex
- // API needed to prevent premature destruction
- APInt API = CFP->getValueAPF().bitcastToAPInt();
- const uint64_t *p = API.getRawData();
- if (AP.isVerbose()) {
- // Convert to double so we can print the approximate val as a comment.
- APFloat DoubleVal = CFP->getValueAPF();
- bool ignored;
- DoubleVal.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven,
- &ignored);
- AP.OutStreamer.GetCommentOS() << "x86_fp80 ~= "
- << DoubleVal.convertToDouble() << '\n';
- }
+ // Now iterate through the APInt chunks, emitting them in endian-correct
+ // order, possibly with a smaller chunk at beginning/end (e.g. for x87 80-bit
+ // floats).
+ unsigned NumBytes = API.getBitWidth() / 8;
+ unsigned TrailingBytes = NumBytes % sizeof(uint64_t);
+ const uint64_t *p = API.getRawData();
- if (AP.TM.getDataLayout()->isBigEndian()) {
- AP.OutStreamer.EmitIntValue(p[1], 2, AddrSpace);
- AP.OutStreamer.EmitIntValue(p[0], 8, AddrSpace);
- } else {
- AP.OutStreamer.EmitIntValue(p[0], 8, AddrSpace);
- AP.OutStreamer.EmitIntValue(p[1], 2, AddrSpace);
- }
+ // PPC's long double has odd notions of endianness compared to how LLVM
+ // handles it: p[0] goes first for *big* endian on PPC.
+ if (AP.TM.getDataLayout()->isBigEndian() != CFP->getType()->isPPC_FP128Ty()) {
+ int Chunk = API.getNumWords() - 1;
- // 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);
- return;
- }
+ if (TrailingBytes)
+ AP.OutStreamer.EmitIntValue(p[Chunk--], TrailingBytes, AddrSpace);
- assert(CFP->getType()->isPPC_FP128Ty() &&
- "Floating point constant type not handled");
- // All long double variants are printed as hex
- // API needed to prevent premature destruction.
- APInt API = CFP->getValueAPF().bitcastToAPInt();
- const uint64_t *p = API.getRawData();
- if (AP.TM.getDataLayout()->isBigEndian()) {
- AP.OutStreamer.EmitIntValue(p[0], 8, AddrSpace);
- AP.OutStreamer.EmitIntValue(p[1], 8, AddrSpace);
+ for (; Chunk >= 0; --Chunk)
+ AP.OutStreamer.EmitIntValue(p[Chunk], sizeof(uint64_t), AddrSpace);
} else {
- AP.OutStreamer.EmitIntValue(p[1], 8, AddrSpace);
- AP.OutStreamer.EmitIntValue(p[0], 8, AddrSpace);
+ unsigned Chunk;
+ for (Chunk = 0; Chunk < NumBytes / sizeof(uint64_t); ++Chunk)
+ AP.OutStreamer.EmitIntValue(p[Chunk], sizeof(uint64_t), AddrSpace);
+
+ if (TrailingBytes)
+ AP.OutStreamer.EmitIntValue(p[Chunk], TrailingBytes, AddrSpace);
}
+
+ // 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);
}
static void emitGlobalConstantLargeInt(const ConstantInt *CI,