summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/MC/MCAsmInfo.cpp1
-rw-r--r--llvm/lib/MC/MCAsmStreamer.cpp35
-rw-r--r--llvm/lib/MC/MCDwarf.cpp13
-rw-r--r--llvm/lib/MC/MCLoggingStreamer.cpp3
-rw-r--r--llvm/lib/MC/MCNullStreamer.cpp2
-rw-r--r--llvm/lib/MC/MCObjectStreamer.cpp2
-rw-r--r--llvm/lib/Target/PTX/PTXMCAsmStreamer.cpp5
-rw-r--r--llvm/lib/Target/PowerPC/PPCMCAsmInfo.cpp4
-rw-r--r--llvm/lib/Target/X86/X86MCAsmInfo.cpp4
9 files changed, 55 insertions, 14 deletions
diff --git a/llvm/lib/MC/MCAsmInfo.cpp b/llvm/lib/MC/MCAsmInfo.cpp
index 9cf4019e312..1bc63d03fba 100644
--- a/llvm/lib/MC/MCAsmInfo.cpp
+++ b/llvm/lib/MC/MCAsmInfo.cpp
@@ -54,6 +54,7 @@ MCAsmInfo::MCAsmInfo() {
GPRel32Directive = 0;
GlobalDirective = "\t.globl\t";
HasSetDirective = true;
+ NeedsSetToChangeDiffSize = false;
HasLCOMMDirective = false;
COMMDirectiveAlignmentIsInBytes = true;
HasDotTypeDotSizeDirective = true;
diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp
index 40a234ea85f..ab807edd9ea 100644
--- a/llvm/lib/MC/MCAsmStreamer.cpp
+++ b/llvm/lib/MC/MCAsmStreamer.cpp
@@ -44,6 +44,8 @@ class MCAsmStreamer : public MCStreamer {
unsigned IsVerboseAsm : 1;
unsigned ShowInst : 1;
+ bool needsSet(const MCExpr *Value);
+
public:
MCAsmStreamer(MCContext &Context, formatted_raw_ostream &os,
bool isLittleEndian, bool isVerboseAsm,
@@ -150,8 +152,7 @@ public:
virtual void EmitBytes(StringRef Data, unsigned AddrSpace);
- virtual void EmitValue(const MCExpr *Value, unsigned Size,unsigned AddrSpace,
- bool UseSet = false);
+ virtual void EmitValue(const MCExpr *Value, unsigned Size,unsigned AddrSpace);
virtual void EmitIntValue(uint64_t Value, unsigned Size,
unsigned AddrSpace = 0);
@@ -511,8 +512,34 @@ void MCAsmStreamer::EmitIntValue(uint64_t Value, unsigned Size,
EmitValue(MCConstantExpr::Create(Value, getContext()), Size, AddrSpace);
}
+static bool hasSymbolDifference(const MCExpr *Value) {
+ switch (Value->getKind()) {
+ case MCExpr::Target: llvm_unreachable("Can't handle target exprs yet!");
+ case MCExpr::Constant:
+ case MCExpr::SymbolRef:
+ return false;
+ case MCExpr::Unary:
+ return hasSymbolDifference(cast<MCUnaryExpr>(Value)->getSubExpr());
+ case MCExpr::Binary: {
+ const MCBinaryExpr *BE = cast<MCBinaryExpr>(Value);
+ if (BE->getOpcode() == MCBinaryExpr::Sub &&
+ BE->getLHS()->getKind() == MCExpr::SymbolRef &&
+ BE->getRHS()->getKind() == MCExpr::SymbolRef)
+ return true;
+ return hasSymbolDifference(BE->getLHS()) ||
+ hasSymbolDifference(BE->getRHS());
+ }
+ }
+ llvm_unreachable("Switch covers all cases");
+}
+
+bool MCAsmStreamer::needsSet(const MCExpr *Value) {
+ return getContext().getAsmInfo().needsSetToChangeDiffSize() &&
+ hasSymbolDifference(Value);
+}
+
void MCAsmStreamer::EmitValue(const MCExpr *Value, unsigned Size,
- unsigned AddrSpace, bool UseSet) {
+ unsigned AddrSpace) {
assert(CurSection && "Cannot emit contents before setting section!");
const char *Directive = 0;
switch (Size) {
@@ -538,7 +565,7 @@ void MCAsmStreamer::EmitValue(const MCExpr *Value, unsigned Size,
}
assert(Directive && "Invalid size for machine code value!");
- if (UseSet && MAI.hasSetDirective()) {
+ if (needsSet(Value)) {
MCSymbol *SetLabel = getContext().CreateTempSymbol();
EmitAssignment(SetLabel, Value);
OS << Directive << *SetLabel;
diff --git a/llvm/lib/MC/MCDwarf.cpp b/llvm/lib/MC/MCDwarf.cpp
index a33b0c596ba..1b1d5097042 100644
--- a/llvm/lib/MC/MCDwarf.cpp
+++ b/llvm/lib/MC/MCDwarf.cpp
@@ -213,8 +213,15 @@ void MCDwarfFileTable::Emit(MCStreamer *MCOS,
// The first 4 bytes is the total length of the information for this
// compilation unit (not including these 4 bytes for the length).
- MCOS->EmitValue(MakeStartMinusEndExpr(MCOS, LineStartSym, LineEndSym, 4),
- 4, 0, true /*UseSet*/);
+ // FIXME: We create the dummy TotalLength variable because LineEndSym points
+ // to the end of the section and the darwin assembler doesn't consider that
+ // difference an assembly time constant. It might be better for this to be
+ // proected by a flag.
+ MCSymbol *TotalLength = MCOS->getContext().CreateTempSymbol();
+ MCOS->EmitAssignment(TotalLength,
+ MakeStartMinusEndExpr(MCOS, LineStartSym, LineEndSym,
+ 4));
+ MCOS->EmitSymbolValue(TotalLength, 4, 0);
// Next 2 bytes is the Version, which is Dwarf 2.
MCOS->EmitIntValue(2, 2);
@@ -228,7 +235,7 @@ void MCDwarfFileTable::Emit(MCStreamer *MCOS,
// length of the prologue.
MCOS->EmitValue(MakeStartMinusEndExpr(MCOS, LineStartSym, ProEndSym,
(4 + 2 + 4)),
- 4, 0, true /*UseSet*/);
+ 4, 0);
// Parameters of the state machine, are next.
MCOS->EmitIntValue(DWARF2_LINE_MIN_INSN_LENGTH, 1);
diff --git a/llvm/lib/MC/MCLoggingStreamer.cpp b/llvm/lib/MC/MCLoggingStreamer.cpp
index 6cbef0b0250..134554b8006 100644
--- a/llvm/lib/MC/MCLoggingStreamer.cpp
+++ b/llvm/lib/MC/MCLoggingStreamer.cpp
@@ -154,8 +154,7 @@ public:
return Child->EmitBytes(Data, AddrSpace);
}
- virtual void EmitValue(const MCExpr *Value, unsigned Size,unsigned AddrSpace,
- bool UseSet = false){
+ virtual void EmitValue(const MCExpr *Value, unsigned Size,unsigned AddrSpace){
LogCall("EmitValue");
return Child->EmitValue(Value, Size, AddrSpace);
}
diff --git a/llvm/lib/MC/MCNullStreamer.cpp b/llvm/lib/MC/MCNullStreamer.cpp
index 86ab628e602..c8f9c636174 100644
--- a/llvm/lib/MC/MCNullStreamer.cpp
+++ b/llvm/lib/MC/MCNullStreamer.cpp
@@ -69,7 +69,7 @@ namespace {
virtual void EmitBytes(StringRef Data, unsigned AddrSpace) {}
virtual void EmitValue(const MCExpr *Value, unsigned Size,
- unsigned AddrSpace, bool UseSet = false) {}
+ unsigned AddrSpace) {}
virtual void EmitULEB128Value(const MCExpr *Value,
unsigned AddrSpace = 0) {}
virtual void EmitSLEB128Value(const MCExpr *Value,
diff --git a/llvm/lib/MC/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp
index 1538a589966..ad8fb495840 100644
--- a/llvm/lib/MC/MCObjectStreamer.cpp
+++ b/llvm/lib/MC/MCObjectStreamer.cpp
@@ -77,7 +77,7 @@ const MCExpr *MCObjectStreamer::AddValueSymbols(const MCExpr *Value) {
}
void MCObjectStreamer::EmitValue(const MCExpr *Value, unsigned Size,
- unsigned AddrSpace, bool UseSet) {
+ unsigned AddrSpace) {
assert(AddrSpace == 0 && "Address space must be 0!");
MCDataFragment *DF = getOrCreateDataFragment();
diff --git a/llvm/lib/Target/PTX/PTXMCAsmStreamer.cpp b/llvm/lib/Target/PTX/PTXMCAsmStreamer.cpp
index 8043baf8cfc..4e517ad76a2 100644
--- a/llvm/lib/Target/PTX/PTXMCAsmStreamer.cpp
+++ b/llvm/lib/Target/PTX/PTXMCAsmStreamer.cpp
@@ -147,8 +147,7 @@ public:
virtual void EmitBytes(StringRef Data, unsigned AddrSpace);
- virtual void EmitValue(const MCExpr *Value, unsigned Size,unsigned AddrSpace,
- bool UseSet = false);
+ virtual void EmitValue(const MCExpr *Value, unsigned Size,unsigned AddrSpace);
virtual void EmitULEB128Value(const MCExpr *Value, unsigned AddrSpace = 0);
virtual void EmitSLEB128Value(const MCExpr *Value, unsigned AddrSpace = 0);
virtual void EmitGPRel32Value(const MCExpr *Value);
@@ -361,7 +360,7 @@ void PTXMCAsmStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) {
}
void PTXMCAsmStreamer::EmitValue(const MCExpr *Value, unsigned Size,
- unsigned AddrSpace, bool UseSet) {
+ unsigned AddrSpace) {
assert(CurSection && "Cannot emit contents before setting section!");
const char *Directive = 0;
switch (Size) {
diff --git a/llvm/lib/Target/PowerPC/PPCMCAsmInfo.cpp b/llvm/lib/Target/PowerPC/PPCMCAsmInfo.cpp
index 3644c79d041..89c8cb664c7 100644
--- a/llvm/lib/Target/PowerPC/PPCMCAsmInfo.cpp
+++ b/llvm/lib/Target/PowerPC/PPCMCAsmInfo.cpp
@@ -21,6 +21,10 @@ PPCMCAsmInfoDarwin::PPCMCAsmInfoDarwin(bool is64Bit) {
if (!is64Bit)
Data64bitsDirective = 0; // We can't emit a 64-bit unit in PPC32 mode.
+
+ if (is64Bit)
+ NeedsSetToChangeDiffSize = true;
+
AssemblerDialect = 1; // New-Style mnemonics.
SupportsDebugInformation= true; // Debug information.
}
diff --git a/llvm/lib/Target/X86/X86MCAsmInfo.cpp b/llvm/lib/Target/X86/X86MCAsmInfo.cpp
index f45fdf5a3fb..1ac2d7e6c6d 100644
--- a/llvm/lib/Target/X86/X86MCAsmInfo.cpp
+++ b/llvm/lib/Target/X86/X86MCAsmInfo.cpp
@@ -56,6 +56,10 @@ X86MCAsmInfoDarwin::X86MCAsmInfoDarwin(const Triple &Triple) {
if (!is64Bit)
Data64bitsDirective = 0; // we can't emit a 64-bit unit
+ // FIXME: Darwin 10 doesn't need this.
+ if (is64Bit)
+ NeedsSetToChangeDiffSize = true;
+
// Use ## as a comment string so that .s files generated by llvm can go
// through the GCC preprocessor without causing an error. This is needed
// because "clang foo.s" runs the C preprocessor, which is usually reserved
OpenPOWER on IntegriCloud