From cee750fb1e25a75fd4ddae04fd0c6d8ac18fbaa9 Mon Sep 17 00:00:00 2001 From: Anton Korobeynikov Date: Wed, 27 Feb 2008 23:33:50 +0000 Subject: [PATCH] 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 --- include/llvm/Target/TargetAsmInfo.h | 6 +++ lib/Target/TargetAsmInfo.cpp | 6 +++ lib/Target/X86/X86TargetAsmInfo.cpp | 66 ++++++++++++++++++++++++++++- lib/Target/X86/X86TargetAsmInfo.h | 3 ++ 4 files changed, 80 insertions(+), 1 deletion(-) diff --git a/include/llvm/Target/TargetAsmInfo.h b/include/llvm/Target/TargetAsmInfo.h index f40fdb5a414..8597e40eaf7 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 bcc2f6e085d..f66d0ffbed0 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 #include @@ -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 293836a06e8..42e63ecba34 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(); - + 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(); + + 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 775ce433308..9a5d1423f64 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 -- 2.34.1