aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Korobeynikov <asl@math.spbu.ru>2008-02-27 23:33:50 +0000
committerAnton Korobeynikov <asl@math.spbu.ru>2008-02-27 23:33:50 +0000
commitcee750fb1e25a75fd4ddae04fd0c6d8ac18fbaa9 (patch)
tree841dd4f46160869b56fbe766686abd42a67e64cc
parent0154e47ed018d4e84a1768f1c8e376af497184f0 (diff)
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
-rw-r--r--include/llvm/Target/TargetAsmInfo.h6
-rw-r--r--lib/Target/TargetAsmInfo.cpp6
-rw-r--r--lib/Target/X86/X86TargetAsmInfo.cpp66
-rw-r--r--lib/Target/X86/X86TargetAsmInfo.h3
4 files changed, 80 insertions, 1 deletions
diff --git a/include/llvm/Target/TargetAsmInfo.h b/include/llvm/Target/TargetAsmInfo.h
index f40fdb5a41..8597e40eaf 100644
--- a/include/llvm/Target/TargetAsmInfo.h
+++ b/include/llvm/Target/TargetAsmInfo.h
@@ -392,6 +392,12 @@ namespace llvm {
virtual bool 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.
+ virtual unsigned PreferredEHDataFormat(unsigned Reason, bool Global) const;
// Accessors.
//
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