aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/llvm/MC/MCAsmInfo.h8
-rw-r--r--include/llvm/MC/MCObjectStreamer.h3
-rw-r--r--include/llvm/MC/MCStreamer.h2
-rw-r--r--lib/MC/MCAsmInfo.cpp1
-rw-r--r--lib/MC/MCAsmStreamer.cpp35
-rw-r--r--lib/MC/MCDwarf.cpp13
-rw-r--r--lib/MC/MCLoggingStreamer.cpp3
-rw-r--r--lib/MC/MCNullStreamer.cpp2
-rw-r--r--lib/MC/MCObjectStreamer.cpp2
-rw-r--r--lib/Target/PTX/PTXMCAsmStreamer.cpp5
-rw-r--r--lib/Target/PowerPC/PPCMCAsmInfo.cpp4
-rw-r--r--lib/Target/X86/X86MCAsmInfo.cpp4
-rw-r--r--test/MC/MachO/empty-dwarf-lines.s2
13 files changed, 66 insertions, 18 deletions
diff --git a/include/llvm/MC/MCAsmInfo.h b/include/llvm/MC/MCAsmInfo.h
index d53318c..0e6c4e7 100644
--- a/include/llvm/MC/MCAsmInfo.h
+++ b/include/llvm/MC/MCAsmInfo.h
@@ -197,6 +197,13 @@ namespace llvm {
/// HasSetDirective - True if the assembler supports the .set directive.
bool HasSetDirective; // Defaults to true.
+ /// NeedsSetToChangeDiffSize - True if the assembler requires that we do
+ /// Lc = a - b
+ /// .long Lc
+ /// instead of doing
+ /// .long a - b
+ bool NeedsSetToChangeDiffSize; // Defaults to false.
+
/// HasLCOMMDirective - This is true if the target supports the .lcomm
/// directive.
bool HasLCOMMDirective; // Defaults to false.
@@ -400,6 +407,7 @@ namespace llvm {
return ExternDirective;
}
bool hasSetDirective() const { return HasSetDirective; }
+ bool needsSetToChangeDiffSize() const { return NeedsSetToChangeDiffSize; }
bool hasLCOMMDirective() const { return HasLCOMMDirective; }
bool hasDotTypeDotSizeDirective() const {return HasDotTypeDotSizeDirective;}
bool getCOMMDirectiveAlignmentIsInBytes() const {
diff --git a/include/llvm/MC/MCObjectStreamer.h b/include/llvm/MC/MCObjectStreamer.h
index a3f532d..d130ba4 100644
--- a/include/llvm/MC/MCObjectStreamer.h
+++ b/include/llvm/MC/MCObjectStreamer.h
@@ -60,8 +60,7 @@ public:
/// @{
virtual void EmitLabel(MCSymbol *Symbol);
- 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 EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol);
diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h
index 16646c9..d89ee9a 100644
--- a/include/llvm/MC/MCStreamer.h
+++ b/include/llvm/MC/MCStreamer.h
@@ -242,7 +242,7 @@ namespace llvm {
/// @param Size - The size of the integer (in bytes) to emit. This must
/// match a native machine width.
virtual void EmitValue(const MCExpr *Value, unsigned Size,
- unsigned AddrSpace = 0, bool UseSet = false) = 0;
+ unsigned AddrSpace = 0) = 0;
/// EmitIntValue - Special case of EmitValue that avoids the client having
/// to pass in a MCExpr for constant integers.
diff --git a/lib/MC/MCAsmInfo.cpp b/lib/MC/MCAsmInfo.cpp
index 9cf4019..1bc63d0 100644
--- a/lib/MC/MCAsmInfo.cpp
+++ b/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/lib/MC/MCAsmStreamer.cpp b/lib/MC/MCAsmStreamer.cpp
index 40a234e..ab807ed 100644
--- a/lib/MC/MCAsmStreamer.cpp
+++ b/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/lib/MC/MCDwarf.cpp b/lib/MC/MCDwarf.cpp
index a33b0c5..1b1d509 100644
--- a/lib/MC/MCDwarf.cpp
+++ b/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/lib/MC/MCLoggingStreamer.cpp b/lib/MC/MCLoggingStreamer.cpp
index 6cbef0b..134554b 100644
--- a/lib/MC/MCLoggingStreamer.cpp
+++ b/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/lib/MC/MCNullStreamer.cpp b/lib/MC/MCNullStreamer.cpp
index 86ab628..c8f9c63 100644
--- a/lib/MC/MCNullStreamer.cpp
+++ b/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/lib/MC/MCObjectStreamer.cpp b/lib/MC/MCObjectStreamer.cpp
index 1538a58..ad8fb49 100644
--- a/lib/MC/MCObjectStreamer.cpp
+++ b/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/lib/Target/PTX/PTXMCAsmStreamer.cpp b/lib/Target/PTX/PTXMCAsmStreamer.cpp
index 8043baf..4e517ad 100644
--- a/lib/Target/PTX/PTXMCAsmStreamer.cpp
+++ b/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/lib/Target/PowerPC/PPCMCAsmInfo.cpp b/lib/Target/PowerPC/PPCMCAsmInfo.cpp
index 3644c79..89c8cb6 100644
--- a/lib/Target/PowerPC/PPCMCAsmInfo.cpp
+++ b/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/lib/Target/X86/X86MCAsmInfo.cpp b/lib/Target/X86/X86MCAsmInfo.cpp
index f45fdf5..1ac2d7e 100644
--- a/lib/Target/X86/X86MCAsmInfo.cpp
+++ b/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
diff --git a/test/MC/MachO/empty-dwarf-lines.s b/test/MC/MachO/empty-dwarf-lines.s
index 29ef218..8d06d73 100644
--- a/test/MC/MachO/empty-dwarf-lines.s
+++ b/test/MC/MachO/empty-dwarf-lines.s
@@ -17,7 +17,7 @@ _c:
// CHECK-NEXT: ('offset', 452)
// CHECK-NEXT: ('alignment', 0)
// CHECK-NEXT: ('reloc_offset', 496)
-// CHECK-NEXT: ('num_reloc', 4)
+// CHECK-NEXT: ('num_reloc', 2)
// CHECK-NEXT: ('flags', 0x2000000)
// CHECK-NEXT: ('reserved1', 0)
// CHECK-NEXT: ('reserved2', 0)