diff --git a/include/llvm/Target/TargetAsmBackend.h b/include/llvm/Target/TargetAsmBackend.h index dfdabdb7fa3..35e768cabd0 100644 --- a/include/llvm/Target/TargetAsmBackend.h +++ b/include/llvm/Target/TargetAsmBackend.h @@ -28,6 +28,28 @@ public: const Target &getTarget() const { return TheTarget; } + /// hasAbsolutizedSet - Check whether this target "absolutizes" + /// assignments. That is, given code like: + /// a: + /// ... + /// b: + /// tmp = a - b + /// .long tmp + /// will the value of 'tmp' be a relocatable expression, or the assembly time + /// value of L0 - L1. This distinction is only relevant for platforms that + /// support scattered symbols, since in the absence of scattered symbols (a - + /// b) cannot change after assembly. + virtual bool hasAbsolutizedSet() const { return false; } + + /// hasScatteredSymbols - Check whether this target supports scattered + /// symbols. If so, the assembler should assume that atoms can be scattered by + /// the linker. In particular, this means that the offsets between symbols + /// which are in distinct atoms is not known at link time, and the assembler + /// must generate fixups and relocations appropriately. + /// + /// Note that the assembler currently does not reason about atoms, instead it + /// assumes all temporary symbols reside in the "current atom". + virtual bool hasScatteredSymbols() const { return false; } }; } // End llvm namespace diff --git a/lib/Target/X86/X86AsmBackend.cpp b/lib/Target/X86/X86AsmBackend.cpp index 2eda7b59860..88cc2c734bc 100644 --- a/lib/Target/X86/X86AsmBackend.cpp +++ b/lib/Target/X86/X86AsmBackend.cpp @@ -21,14 +21,34 @@ public: : TargetAsmBackend(T) {} }; +class DarwinX86AsmBackend : public X86AsmBackend { +public: + DarwinX86AsmBackend(const Target &T) + : X86AsmBackend(T) {} + + virtual bool hasAbsolutizedSet() const { return true; } + + virtual bool hasScatteredSymbols() const { return true; } +}; + } TargetAsmBackend *llvm::createX86_32AsmBackend(const Target &T, const std::string &TT) { - return new X86AsmBackend(T); + switch (Triple(TT).getOS()) { + case Triple::Darwin: + return new DarwinX86AsmBackend(T); + default: + return new X86AsmBackend(T); + } } TargetAsmBackend *llvm::createX86_64AsmBackend(const Target &T, const std::string &TT) { - return new X86AsmBackend(T); + switch (Triple(TT).getOS()) { + case Triple::Darwin: + return new DarwinX86AsmBackend(T); + default: + return new X86AsmBackend(T); + } }