diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Target/TargetAsmInfo.cpp | 6 | ||||
-rw-r--r-- | lib/Target/X86/X86TargetAsmInfo.cpp | 66 | ||||
-rw-r--r-- | lib/Target/X86/X86TargetAsmInfo.h | 3 |
3 files changed, 74 insertions, 1 deletions
diff --git a/lib/Target/TargetAsmInfo.cpp b/lib/Target/TargetAsmInfo.cpp index bcc2f6e085..f66d0ffbed 100644 --- a/lib/Target/TargetAsmInfo.cpp +++ b/lib/Target/TargetAsmInfo.cpp @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Target/TargetAsmInfo.h" +#include "llvm/Support/Dwarf.h" #include <cctype> #include <cstring> @@ -134,3 +135,8 @@ unsigned TargetAsmInfo::getInlineAsmLength(const char *Str) const { return Length; } +unsigned TargetAsmInfo::PreferredEHDataFormat(unsigned Reason, + bool Global) const { + return dwarf::DW_EH_PE_absptr; +} + diff --git a/lib/Target/X86/X86TargetAsmInfo.cpp b/lib/Target/X86/X86TargetAsmInfo.cpp index 293836a06e..42e63ecba3 100644 --- a/lib/Target/X86/X86TargetAsmInfo.cpp +++ b/lib/Target/X86/X86TargetAsmInfo.cpp @@ -20,7 +20,10 @@ #include "llvm/Intrinsics.h" #include "llvm/Module.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/Support/Dwarf.h" + using namespace llvm; +using namespace llvm::dwarf; static const char* x86_asm_table[] = {"{si}", "S", "{di}", "D", @@ -35,7 +38,8 @@ static const char* x86_asm_table[] = {"{si}", "S", X86TargetAsmInfo::X86TargetAsmInfo(const X86TargetMachine &TM) { const X86Subtarget *Subtarget = &TM.getSubtarget<X86Subtarget>(); - + X86TM = &TM; + // FIXME - Should be simplified. AsmTransCBE = x86_asm_table; @@ -303,3 +307,63 @@ bool X86TargetAsmInfo::ExpandInlineAsm(CallInst *CI) const { } return false; } + +/// PreferredEHDataFormat - This hook allows the target to select data +/// format used for encoding pointers in exception handling data. Reason is +/// 0 for data, 1 for code labels, 2 for function pointers. Global is true +/// if the symbol can be relocated. +unsigned X86TargetAsmInfo::PreferredEHDataFormat(unsigned Reason, + bool Global) const { + const X86Subtarget *Subtarget = &X86TM->getSubtarget<X86Subtarget>(); + + switch (Subtarget->TargetType) { + case X86Subtarget::isDarwin: + if (Reason == 2 && Global) + return (DW_EH_PE_pcrel | DW_EH_PE_indirect | DW_EH_PE_sdata4); + else if (Reason == 1 || !Global) + return DW_EH_PE_pcrel; + else + return DW_EH_PE_absptr; + + case X86Subtarget::isELF: + case X86Subtarget::isCygwin: + case X86Subtarget::isMingw: { + CodeModel::Model CM = X86TM->getCodeModel(); + + if (X86TM->getRelocationModel() == Reloc::PIC_) { + unsigned Format = 0; + + if (!Subtarget->is64Bit()) + // 32 bit targets always encode pointers as 4 bytes + Format = DW_EH_PE_sdata4; + else { + // 64 bit targets encode pointers in 4 bytes iff: + // - code model is small OR + // - code model is medium and we're emitting externally visible symbols or + // any code symbols + if (CM == CodeModel::Small || + (CM == CodeModel::Medium && (Global || Reason))) + Format = DW_EH_PE_sdata4; + else + Format = DW_EH_PE_sdata8; + } + + if (Global) + Format |= DW_EH_PE_indirect; + + return (Format | DW_EH_PE_pcrel); + } else { + if (Subtarget->is64Bit() && + (CM == CodeModel::Small || + (CM == CodeModel::Medium && Reason))) + return DW_EH_PE_udata4; + else + return DW_EH_PE_absptr; + } + } + + default: + return TargetAsmInfo::PreferredEHDataFormat(Reason, Global); + } +} + diff --git a/lib/Target/X86/X86TargetAsmInfo.h b/lib/Target/X86/X86TargetAsmInfo.h index 775ce43330..9a5d1423f6 100644 --- a/lib/Target/X86/X86TargetAsmInfo.h +++ b/lib/Target/X86/X86TargetAsmInfo.h @@ -25,7 +25,10 @@ namespace llvm { explicit X86TargetAsmInfo(const X86TargetMachine &TM); virtual bool ExpandInlineAsm(CallInst *CI) const; + virtual unsigned PreferredEHDataFormat(unsigned Reason, bool Global) const; + private: + const X86TargetMachine* X86TM; bool LowerToBSwap(CallInst *CI) const; }; } // namespace llvm |