aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2010-12-04 03:21:47 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2010-12-04 03:21:47 +0000
commit5d4918dbd116b0b5e561c431b1ea527ee1b9302a (patch)
tree3c50fff76598829d12b03b798194dcc6f0ab039d /lib
parent9ad8221bcb26643ae5837d7f27b41610eeec98a7 (diff)
downloadexternal_llvm-5d4918dbd116b0b5e561c431b1ea527ee1b9302a.zip
external_llvm-5d4918dbd116b0b5e561c431b1ea527ee1b9302a.tar.gz
external_llvm-5d4918dbd116b0b5e561c431b1ea527ee1b9302a.tar.bz2
There are two reasons why we might want to use
foo = a - b .long foo instead of just .long a - b First, on darwin9 64 bits the assembler produces the wrong result. Second, if "a" is the end of the section all darwin assemblers (9, 10 and mc) will not consider a - b to be a constant but will if the dummy foo is created. Split how we handle these cases. The first one is something MC should take care of. The second one has to be handled by the caller. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@120889 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-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
9 files changed, 55 insertions, 14 deletions
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