summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVenkatraman Govindaraju <venkatra@cs.wisc.edu>2013-09-26 15:11:00 +0000
committerVenkatraman Govindaraju <venkatra@cs.wisc.edu>2013-09-26 15:11:00 +0000
commit30ec8a3658b1f06bb94d392c55feb7f107517bf8 (patch)
treeb5d40acafb8c504c81cbc3b49222b8a2c533d44e
parent83ba58e5f0a5afbb23d7d2092d817accded4455a (diff)
downloadllvm-30ec8a3658b1f06bb94d392c55feb7f107517bf8.tar.gz
llvm-30ec8a3658b1f06bb94d392c55feb7f107517bf8.tar.bz2
llvm-30ec8a3658b1f06bb94d392c55feb7f107517bf8.tar.xz
[Sparc] Implements exception handling in SPARC with DwarfCFI.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191432 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp3
-rw-r--r--lib/Target/Sparc/MCTargetDesc/SparcMCAsmInfo.cpp2
-rw-r--r--lib/Target/Sparc/SparcFrameLowering.cpp19
-rw-r--r--lib/Target/Sparc/SparcISelLowering.cpp6
-rw-r--r--test/CodeGen/SPARC/exception.ll112
5 files changed, 138 insertions, 4 deletions
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp b/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp
index c48445f4d4..b92f49cfae 100644
--- a/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp
+++ b/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp
@@ -185,6 +185,9 @@ void AsmPrinter::emitCFIInstruction(const MCCFIInstruction &Inst) const {
case MCCFIInstruction::OpOffset:
OutStreamer.EmitCFIOffset(Inst.getRegister(), Inst.getOffset());
break;
+ case MCCFIInstruction::OpRegister:
+ OutStreamer.EmitCFIRegister(Inst.getRegister(), Inst.getRegister2());
+ break;
case MCCFIInstruction::OpWindowSave:
OutStreamer.EmitCFIWindowSave();
break;
diff --git a/lib/Target/Sparc/MCTargetDesc/SparcMCAsmInfo.cpp b/lib/Target/Sparc/MCTargetDesc/SparcMCAsmInfo.cpp
index 45cfe033bb..06b1df6dbf 100644
--- a/lib/Target/Sparc/MCTargetDesc/SparcMCAsmInfo.cpp
+++ b/lib/Target/Sparc/MCTargetDesc/SparcMCAsmInfo.cpp
@@ -36,6 +36,8 @@ SparcELFMCAsmInfo::SparcELFMCAsmInfo(StringRef TT) {
HasLEB128 = true;
SupportsDebugInformation = true;
+ ExceptionsType = ExceptionHandling::DwarfCFI;
+
SunStyleELFSectionSwitchSyntax = true;
UsesELFSectionDirectiveForBSS = true;
diff --git a/lib/Target/Sparc/SparcFrameLowering.cpp b/lib/Target/Sparc/SparcFrameLowering.cpp
index 536e466ca3..1f9cac54b8 100644
--- a/lib/Target/Sparc/SparcFrameLowering.cpp
+++ b/lib/Target/Sparc/SparcFrameLowering.cpp
@@ -70,6 +70,25 @@ void SparcFrameLowering::emitPrologue(MachineFunction &MF) const {
BuildMI(MBB, MBBI, dl, TII.get(SAVErr), SP::O6)
.addReg(SP::O6).addReg(SP::G1);
}
+ MachineModuleInfo &MMI = MF.getMMI();
+ const MCRegisterInfo *MRI = MMI.getContext().getRegisterInfo();
+ MCSymbol *FrameLabel = MMI.getContext().CreateTempSymbol();
+ BuildMI(MBB, MBBI, dl, TII.get(SP::PROLOG_LABEL)).addSym(FrameLabel);
+
+ unsigned regFP = MRI->getDwarfRegNum(SP::I6, true);
+
+ // Emit ".cfi_def_cfa_register 30".
+ MMI.addFrameInst(MCCFIInstruction::createDefCfaRegister(FrameLabel,
+ regFP));
+ // Emit ".cfi_window_save".
+ MMI.addFrameInst(MCCFIInstruction::createWindowSave(FrameLabel));
+
+ unsigned regInRA = MRI->getDwarfRegNum(SP::I7, true);
+ unsigned regOutRA = MRI->getDwarfRegNum(SP::O7, true);
+ // Emit ".cfi_register 15, 31".
+ MMI.addFrameInst(MCCFIInstruction::createRegister(FrameLabel,
+ regOutRA,
+ regInRA));
}
void SparcFrameLowering::
diff --git a/lib/Target/Sparc/SparcISelLowering.cpp b/lib/Target/Sparc/SparcISelLowering.cpp
index 86bac7e3d8..cdba998244 100644
--- a/lib/Target/Sparc/SparcISelLowering.cpp
+++ b/lib/Target/Sparc/SparcISelLowering.cpp
@@ -1432,8 +1432,6 @@ SparcTargetLowering::SparcTargetLowering(TargetMachine &TM)
setOperationAction(ISD::UMUL_LOHI, MVT::i32, Expand);
setOperationAction(ISD::SMUL_LOHI, MVT::i32, Expand);
- setOperationAction(ISD::EH_LABEL, MVT::Other, Expand);
-
// VASTART needs to be custom lowered to use the VarArgsFrameIndex.
setOperationAction(ISD::VASTART , MVT::Other, Custom);
// VAARG needs to be lowered to not do unaligned accesses for doubles.
@@ -1446,8 +1444,8 @@ SparcTargetLowering::SparcTargetLowering(TargetMachine &TM)
setOperationAction(ISD::STACKRESTORE , MVT::Other, Expand);
setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32 , Custom);
- // No debug info support yet.
- setOperationAction(ISD::EH_LABEL, MVT::Other, Expand);
+ setExceptionPointerRegister(SP::I0);
+ setExceptionSelectorRegister(SP::I1);
setStackPointerRegisterToSaveRestore(SP::O6);
diff --git a/test/CodeGen/SPARC/exception.ll b/test/CodeGen/SPARC/exception.ll
new file mode 100644
index 0000000000..cb5b6e5c11
--- /dev/null
+++ b/test/CodeGen/SPARC/exception.ll
@@ -0,0 +1,112 @@
+; RUN: llc < %s -march=sparc | FileCheck %s
+
+
+%struct.__fundamental_type_info_pseudo = type { %struct.__type_info_pseudo }
+%struct.__type_info_pseudo = type { i8*, i8* }
+
+@_ZTIi = external constant %struct.__fundamental_type_info_pseudo
+@_ZTIf = external constant %struct.__fundamental_type_info_pseudo
+@.cst = linker_private unnamed_addr constant [12 x i8] c"catched int\00", align 64
+@.cst1 = linker_private unnamed_addr constant [14 x i8] c"catched float\00", align 64
+
+; CHECK-LABEL: main:
+; CHECK: .cfi_startproc
+; CHECK: .cfi_def_cfa_register 30
+; CHECK: .cfi_window_save
+; CHECK: .cfi_register 15, 31
+
+; CHECK: call __cxa_throw
+; CHECK: call __cxa_throw
+
+; CHECK: call __cxa_begin_catch
+; CHECK: call __cxa_end_catch
+
+; CHECK: call __cxa_begin_catch
+; CHECK: call __cxa_end_catch
+
+; CHECK: .cfi_endproc
+
+define i32 @main(i32 %argc, i8** nocapture readnone %argv) unnamed_addr #0 {
+entry:
+ %0 = icmp eq i32 %argc, 2
+ %1 = tail call i8* @__cxa_allocate_exception(i32 4) #1
+ br i1 %0, label %"3", label %"4"
+
+"3": ; preds = %entry
+ %2 = bitcast i8* %1 to i32*
+ store i32 0, i32* %2, align 4
+ invoke void @__cxa_throw(i8* %1, i8* bitcast (%struct.__fundamental_type_info_pseudo* @_ZTIi to i8*), void (i8*)* null) #2
+ to label %3 unwind label %"8"
+
+; <label>:3 ; preds = %"3"
+ unreachable
+
+"4": ; preds = %entry
+ %4 = bitcast i8* %1 to float*
+ store float 1.000000e+00, float* %4, align 4
+
+
+ invoke void @__cxa_throw(i8* %1, i8* bitcast (%struct.__fundamental_type_info_pseudo* @_ZTIf to i8*), void (i8*)* null) #2
+ to label %5 unwind label %"8"
+
+; <label>:5 ; preds = %"4"
+ unreachable
+
+"5": ; preds = %"13", %"11"
+ %6 = phi i32 [ 2, %"13" ], [ 0, %"11" ]
+ ret i32 %6
+
+"8": ; preds = %"4", %"3"
+ %exc = landingpad { i8*, i32 } personality i32 (i32, i64, i8*, i8*)* @__gxx_personality_v0
+ catch %struct.__fundamental_type_info_pseudo* @_ZTIi
+ catch %struct.__fundamental_type_info_pseudo* @_ZTIf
+ %exc_ptr12 = extractvalue { i8*, i32 } %exc, 0
+ %filter13 = extractvalue { i8*, i32 } %exc, 1
+ %typeid = tail call i32 @llvm.eh.typeid.for(i8* bitcast (%struct.__fundamental_type_info_pseudo* @_ZTIi to i8*))
+ %7 = icmp eq i32 %filter13, %typeid
+ br i1 %7, label %"11", label %8
+
+; <label>:8 ; preds = %"8"
+ %typeid8 = tail call i32 @llvm.eh.typeid.for(i8* bitcast (%struct.__fundamental_type_info_pseudo* @_ZTIf to i8*))
+ %9 = icmp eq i32 %filter13, %typeid8
+ br i1 %9, label %"13", label %"9"
+
+"9": ; preds = %8
+ resume { i8*, i32 } %exc
+
+"11": ; preds = %"8"
+ %10 = tail call i8* @__cxa_begin_catch(i8* %exc_ptr12) #1
+ %11 = tail call i32 @puts(i8* getelementptr inbounds ([12 x i8]* @.cst, i32 0, i32 0))
+ tail call void @__cxa_end_catch() #1
+ br label %"5"
+
+"13": ; preds = %8
+ %12 = tail call i8* @__cxa_begin_catch(i8* %exc_ptr12) #1
+ %13 = tail call i32 @puts(i8* getelementptr inbounds ([14 x i8]* @.cst1, i32 0, i32 0))
+ tail call void @__cxa_end_catch() #1
+ br label %"5"
+}
+
+; Function Attrs: nounwind
+declare i8* @__cxa_allocate_exception(i32) #1
+
+; Function Attrs: noreturn
+declare void @__cxa_throw(i8*, i8*, void (i8*)*) #2
+
+declare void @__cxa_end_catch()
+
+; Function Attrs: nounwind readnone
+declare i32 @llvm.eh.typeid.for(i8*) #3
+
+; Function Attrs: nounwind
+declare i8* @__cxa_begin_catch(i8*) #1
+
+; Function Attrs: nounwind
+declare i32 @puts(i8* nocapture readonly) #1
+
+declare i32 @__gxx_personality_v0(i32, i64, i8*, i8*)
+
+attributes #0 = { "no-frame-pointer-elim-non-leaf"="false" }
+attributes #1 = { nounwind }
+attributes #2 = { noreturn }
+attributes #3 = { nounwind readnone }