Preparation step for some cleanup/generalization in EH information emission:
provide TAI hook for selection of EH data emission format. Currently unused.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@47699 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/TargetAsmInfo.cpp b/lib/Target/TargetAsmInfo.cpp
index bcc2f6e..f66d0ff 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 @@
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 293836a..42e63ec 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 @@
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 @@
}
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 775ce43..9a5d142 100644
--- a/lib/Target/X86/X86TargetAsmInfo.h
+++ b/lib/Target/X86/X86TargetAsmInfo.h
@@ -25,7 +25,10 @@
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