aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/Target/TargetLowering.h15
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfException.cpp47
-rw-r--r--lib/Target/PowerPC/PPCISelLowering.cpp34
-rw-r--r--lib/Target/PowerPC/PPCISelLowering.h8
-rw-r--r--lib/Target/X86/X86ISelLowering.cpp43
-rw-r--r--lib/Target/X86/X86ISelLowering.h8
6 files changed, 137 insertions, 18 deletions
diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h
index 00a455c360..a899651dbd 100644
--- a/include/llvm/Target/TargetLowering.h
+++ b/include/llvm/Target/TargetLowering.h
@@ -32,6 +32,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/DebugLoc.h"
+#include "llvm/Support/Dwarf.h"
#include "llvm/Target/TargetMachine.h"
#include <climits>
#include <map>
@@ -750,7 +751,7 @@ public:
/// getPICJumpTableRelocaBase - Returns relocation base for the given PIC
/// jumptable.
virtual SDValue getPICJumpTableRelocBase(SDValue Table,
- SelectionDAG &DAG) const;
+ SelectionDAG &DAG) const;
/// isOffsetFoldingLegal - Return true if folding a constant offset
/// with the given GlobalAddress is legal. It is frequently not legal in
@@ -760,6 +761,18 @@ public:
/// getFunctionAlignment - Return the Log2 alignment of this function.
virtual unsigned getFunctionAlignment(const Function *) const = 0;
+ /// getPreferredLSDADataFormat - Return the preferred exception handling data
+ /// format for the LSDA.
+ virtual unsigned getPreferredLSDADataFormat() const {
+ return dwarf::DW_EH_PE_absptr;
+ }
+
+ /// getPreferredFDEDataFormat - Return the preferred exception handling data
+ /// format for the FDE.
+ virtual unsigned getPreferredFDEDataFormat() const {
+ return dwarf::DW_EH_PE_absptr;
+ }
+
//===--------------------------------------------------------------------===//
// TargetLowering Optimization Methods
//
diff --git a/lib/CodeGen/AsmPrinter/DwarfException.cpp b/lib/CodeGen/AsmPrinter/DwarfException.cpp
index a8d8bfd759..e32447392f 100644
--- a/lib/CodeGen/AsmPrinter/DwarfException.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfException.cpp
@@ -22,6 +22,7 @@
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetFrameInfo.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
+#include "llvm/Target/TargetLowering.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Support/Dwarf.h"
@@ -80,6 +81,7 @@ void DwarfException::EmitCIE(const Function *Personality, unsigned Index) {
EmitLabel("eh_frame_common_begin", Index);
Asm->EmitInt32((int)0);
Asm->EOL("CIE Identifier Tag");
+
Asm->EmitInt8(dwarf::DW_CIE_VERSION);
Asm->EOL("CIE Version");
@@ -91,23 +93,29 @@ void DwarfException::EmitCIE(const Function *Personality, unsigned Index) {
// Round out reader.
Asm->EmitULEB128Bytes(1);
Asm->EOL("CIE Code Alignment Factor");
+
Asm->EmitSLEB128Bytes(stackGrowth);
Asm->EOL("CIE Data Alignment Factor");
+
Asm->EmitInt8(RI->getDwarfRegNum(RI->getRARegister(), true));
Asm->EOL("CIE Return Address Column");
+ unsigned Encoding = 0;
+
// If there is a personality, we need to indicate the function's location.
if (Personality) {
Asm->EmitULEB128Bytes(7);
Asm->EOL("Augmentation Size");
if (MAI->getNeedsIndirectEncoding()) {
- Asm->EmitInt8(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4 |
- dwarf::DW_EH_PE_indirect);
- Asm->EOL("Personality (pcrel sdata4 indirect)");
+ Encoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4 |
+ dwarf::DW_EH_PE_indirect;
+ Asm->EmitInt8(Encoding);
+ Asm->EOL("Personality", Encoding);
} else {
- Asm->EmitInt8(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4);
- Asm->EOL("Personality (pcrel sdata4)");
+ Encoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
+ Asm->EmitInt8(Encoding);
+ Asm->EOL("Personality", Encoding);
}
PrintRelDirective(true);
@@ -118,17 +126,20 @@ void DwarfException::EmitCIE(const Function *Personality, unsigned Index) {
O << "-" << MAI->getPCSymbol();
Asm->EOL("Personality");
- Asm->EmitInt8(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4);
- Asm->EOL("LSDA Encoding (pcrel sdata4)");
+ Encoding = Asm->TM.getTargetLowering()->getPreferredLSDADataFormat();
+ Asm->EmitInt8(Encoding);
+ Asm->EOL("LSDA Encoding", Encoding);
- Asm->EmitInt8(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4);
- Asm->EOL("FDE Encoding (pcrel sdata4)");
+ Encoding = Asm->TM.getTargetLowering()->getPreferredFDEDataFormat();
+ Asm->EmitInt8(Encoding);
+ Asm->EOL("FDE Encoding", Encoding);
} else {
Asm->EmitULEB128Bytes(1);
Asm->EOL("Augmentation Size");
- Asm->EmitInt8(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4);
- Asm->EOL("FDE Encoding (pcrel sdata4)");
+ Encoding = Asm->TM.getTargetLowering()->getPreferredFDEDataFormat();
+ Asm->EmitInt8(Encoding);
+ Asm->EOL("FDE Encoding", Encoding);
}
// Indicate locations of general callee saved registers in frame.
@@ -152,6 +163,7 @@ void DwarfException::EmitFDE(const FunctionEHFrameInfo &EHFrameInfo) {
"Should not emit 'available externally' functions at all");
const Function *TheFunc = EHFrameInfo.function;
+ bool is4Byte = TD->getPointerSize() == sizeof(int32_t);
Asm->OutStreamer.SwitchSection(Asm->getObjFileLowering().getEHFrameSection());
@@ -195,23 +207,22 @@ void DwarfException::EmitFDE(const FunctionEHFrameInfo &EHFrameInfo) {
Asm->EOL("FDE CIE offset");
- EmitReference("eh_func_begin", EHFrameInfo.Number, true, true);
+ EmitReference("eh_func_begin", EHFrameInfo.Number, true, is4Byte);
Asm->EOL("FDE initial location");
+
EmitDifference("eh_func_end", EHFrameInfo.Number,
- "eh_func_begin", EHFrameInfo.Number, true);
+ "eh_func_begin", EHFrameInfo.Number, is4Byte);
Asm->EOL("FDE address range");
// If there is a personality and landing pads then point to the language
// specific data area in the exception table.
if (MMI->getPersonalities()[0] != NULL) {
- bool is4Byte = TD->getPointerSize() == sizeof(int32_t);
-
Asm->EmitULEB128Bytes(is4Byte ? 4 : 8);
Asm->EOL("Augmentation size");
- if (EHFrameInfo.hasLandingPads)
+ if (EHFrameInfo.hasLandingPads) {
EmitReference("exception", EHFrameInfo.Number, true, false);
- else {
+ } else {
if (is4Byte)
Asm->EmitInt32((int)0);
else
@@ -918,6 +929,8 @@ void DwarfException::EndFunction() {
MF->getFunction()));
}
+ MF = 0;
+
if (TimePassesIsEnabled)
ExceptionTimer->stopTimer();
}
diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp
index ad9bbe1d31..1f51d04859 100644
--- a/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -464,6 +464,40 @@ unsigned PPCTargetLowering::getFunctionAlignment(const Function *F) const {
return 2;
}
+/// getPreferredLSDADataFormat - Return the preferred exception handling data
+/// format for the LSDA.
+unsigned PPCTargetLowering::getPreferredLSDADataFormat() const {
+ if (getTargetMachine().getSubtarget<PPCSubtarget>().isDarwin())
+ return dwarf::DW_EH_PE_pcrel;
+
+ if (PPCSubTarget.isPPC64() ||
+ getTargetMachine().getRelocationModel() == Reloc::PIC_) {
+ unsigned DataTy =
+ (PPCSubTarget.isPPC64() ?
+ dwarf::DW_EH_PE_udata8 : dwarf::DW_EH_PE_udata4);
+ return dwarf::DW_EH_PE_pcrel | DataTy;
+ }
+
+ return dwarf::DW_EH_PE_absptr;
+}
+
+/// getPreferredFDEDataFormat - Return the preferred exception handling data
+/// format for the FDE.
+unsigned PPCTargetLowering::getPreferredFDEDataFormat() const {
+ if (getTargetMachine().getSubtarget<PPCSubtarget>().isDarwin())
+ return dwarf::DW_EH_PE_pcrel;
+
+ if (PPCSubTarget.isPPC64() ||
+ getTargetMachine().getRelocationModel() == Reloc::PIC_) {
+ unsigned DataTy =
+ (PPCSubTarget.isPPC64() ?
+ dwarf::DW_EH_PE_udata8 : dwarf::DW_EH_PE_udata4);
+ return dwarf::DW_EH_PE_pcrel | DataTy;
+ }
+
+ return dwarf::DW_EH_PE_absptr;
+}
+
//===----------------------------------------------------------------------===//
// Node matching predicates, for use by the tblgen matching code.
//===----------------------------------------------------------------------===//
diff --git a/lib/Target/PowerPC/PPCISelLowering.h b/lib/Target/PowerPC/PPCISelLowering.h
index 19fef4da0b..9e5e36ad14 100644
--- a/lib/Target/PowerPC/PPCISelLowering.h
+++ b/lib/Target/PowerPC/PPCISelLowering.h
@@ -346,6 +346,14 @@ namespace llvm {
/// getFunctionAlignment - Return the Log2 alignment of this function.
virtual unsigned getFunctionAlignment(const Function *F) const;
+ /// getPreferredLSDADataFormat - Return the preferred exception handling data
+ /// format for the LSDA.
+ virtual unsigned getPreferredLSDADataFormat() const;
+
+ /// getPreferredFDEDataFormat - Return the preferred exception handling data
+ /// format for the FDE.
+ virtual unsigned getPreferredFDEDataFormat() const;
+
private:
SDValue getFramePointerFrameIndex(SelectionDAG & DAG) const;
SDValue getReturnAddrFrameIndex(SelectionDAG & DAG) const;
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp
index 15af42e8c4..3600987f26 100644
--- a/lib/Target/X86/X86ISelLowering.cpp
+++ b/lib/Target/X86/X86ISelLowering.cpp
@@ -1055,6 +1055,49 @@ unsigned X86TargetLowering::getFunctionAlignment(const Function *F) const {
return F->hasFnAttr(Attribute::OptimizeForSize) ? 0 : 4;
}
+/// getPreferredLSDADataFormat - Return the preferred exception handling data
+/// format for the LSDA.
+unsigned X86TargetLowering::getPreferredLSDADataFormat() const {
+ if (Subtarget->isTargetDarwin())
+ return dwarf::DW_EH_PE_pcrel;
+
+ CodeModel::Model M = getTargetMachine().getCodeModel();
+
+ if (getTargetMachine().getRelocationModel() == Reloc::PIC_) {
+ if (!Subtarget->is64Bit() || M == CodeModel::Small)
+ return dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
+
+ return dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8;
+ }
+
+ if (M == CodeModel::Small)
+ return dwarf::DW_EH_PE_sdata4;
+
+ return dwarf::DW_EH_PE_absptr;
+}
+
+/// getPreferredFDEDataFormat - Return the preferred exception handling data
+/// format for the FDE.
+unsigned X86TargetLowering::getPreferredFDEDataFormat() const {
+ if (Subtarget->isTargetDarwin())
+ return dwarf::DW_EH_PE_pcrel;
+
+ CodeModel::Model M = getTargetMachine().getCodeModel();
+
+ if (getTargetMachine().getRelocationModel() == Reloc::PIC_) {
+ if (!Subtarget->is64Bit() ||
+ M == CodeModel::Small || M == CodeModel::Medium)
+ return dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
+
+ return dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8;
+ }
+
+ if (M == CodeModel::Small || M == CodeModel::Medium)
+ return dwarf::DW_EH_PE_sdata4;
+
+ return dwarf::DW_EH_PE_absptr;
+}
+
//===----------------------------------------------------------------------===//
// Return Value Calling Convention Implementation
//===----------------------------------------------------------------------===//
diff --git a/lib/Target/X86/X86ISelLowering.h b/lib/Target/X86/X86ISelLowering.h
index 1c612a13a2..64716e9d2c 100644
--- a/lib/Target/X86/X86ISelLowering.h
+++ b/lib/Target/X86/X86ISelLowering.h
@@ -560,6 +560,14 @@ namespace llvm {
/// getFunctionAlignment - Return the Log2 alignment of this function.
virtual unsigned getFunctionAlignment(const Function *F) const;
+ /// getPreferredLSDADataFormat - Return the preferred exception handling data
+ /// format for the LSDA.
+ virtual unsigned getPreferredLSDADataFormat() const;
+
+ /// getPreferredFDEDataFormat - Return the preferred exception handling data
+ /// format for the FDE.
+ virtual unsigned getPreferredFDEDataFormat() const;
+
private:
/// Subtarget - Keep a pointer to the X86Subtarget around so that we can
/// make the right decision when generating code for different targets.