summaryrefslogtreecommitdiff
path: root/lib/Target/ARM
diff options
context:
space:
mode:
authorJim Grosbach <grosbach@apple.com>2009-08-11 00:09:57 +0000
committerJim Grosbach <grosbach@apple.com>2009-08-11 00:09:57 +0000
commit1b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3 (patch)
tree55ef4dc73ff823568dc8543cbb1b4cfa77191b0b /lib/Target/ARM
parent3a1f0f6785e27eb8ede455a3583ca8c885d3911e (diff)
downloadllvm-1b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3.tar.gz
llvm-1b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3.tar.bz2
llvm-1b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3.tar.xz
SjLj based exception handling unwinding support. This patch is nasty, brutish
and short. Well, it's kinda short. Definitely nasty and brutish. The front-end generates the register/unregister calls into the SjLj runtime, call-site indices and landing pad dispatch. The back end fills in the LSDA with the call-site information provided by the front end. Catch blocks are not yet implemented. Built on Darwin and verified no llvm-core "make check" regressions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@78625 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/ARM')
-rw-r--r--lib/Target/ARM/ARMConstantPoolValue.cpp2
-rw-r--r--lib/Target/ARM/ARMConstantPoolValue.h2
-rw-r--r--lib/Target/ARM/ARMISelLowering.cpp31
-rw-r--r--lib/Target/ARM/ARMInstrInfo.td9
-rw-r--r--lib/Target/ARM/ARMTargetAsmInfo.cpp6
-rw-r--r--lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp2
6 files changed, 48 insertions, 4 deletions
diff --git a/lib/Target/ARM/ARMConstantPoolValue.cpp b/lib/Target/ARM/ARMConstantPoolValue.cpp
index a75ed3bd53..adf03e04b8 100644
--- a/lib/Target/ARM/ARMConstantPoolValue.cpp
+++ b/lib/Target/ARM/ARMConstantPoolValue.cpp
@@ -34,7 +34,7 @@ ARMConstantPoolValue::ARMConstantPoolValue(const char *s, unsigned id,
const char *Modif,
bool AddCA)
: MachineConstantPoolValue((const Type*)Type::Int32Ty),
- GV(NULL), S(s), LabelId(id), Kind(k), PCAdjust(PCAdj),
+ GV(NULL), S(strdup(s)), LabelId(id), Kind(k), PCAdjust(PCAdj),
Modifier(Modif), AddCurrentAddress(AddCA) {}
ARMConstantPoolValue::ARMConstantPoolValue(GlobalValue *gv,
diff --git a/lib/Target/ARM/ARMConstantPoolValue.h b/lib/Target/ARM/ARMConstantPoolValue.h
index fcaf2e6885..37a2c80478 100644
--- a/lib/Target/ARM/ARMConstantPoolValue.h
+++ b/lib/Target/ARM/ARMConstantPoolValue.h
@@ -53,6 +53,8 @@ public:
bool AddCurrentAddress = false);
ARMConstantPoolValue(GlobalValue *GV, ARMCP::ARMCPKind Kind,
const char *Modifier);
+ ARMConstantPoolValue();
+ ~ARMConstantPoolValue() {free((void*)S);}
GlobalValue *getGV() const { return GV; }
diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp
index aedddaa20b..61722d44fa 100644
--- a/lib/Target/ARM/ARMISelLowering.cpp
+++ b/lib/Target/ARM/ARMISelLowering.cpp
@@ -1392,6 +1392,37 @@ ARMTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) {
EVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
return DAG.getNode(ARMISD::THREAD_POINTER, dl, PtrVT);
}
+ case Intrinsic::eh_sjlj_lsda: {
+ // blah. horrible, horrible hack with the forced magic name.
+ // really need to clean this up. It belongs in the target-independent
+ // layer somehow that doesn't require the coupling with the asm
+ // printer.
+ MachineFunction &MF = DAG.getMachineFunction();
+ EVT PtrVT = getPointerTy();
+ DebugLoc dl = Op.getDebugLoc();
+ Reloc::Model RelocM = getTargetMachine().getRelocationModel();
+ SDValue CPAddr;
+ unsigned PCAdj = (RelocM != Reloc::PIC_)
+ ? 0 : (Subtarget->isThumb() ? 4 : 8);
+ ARMCP::ARMCPKind Kind = ARMCP::CPValue;
+ // Save off the LSDA name for the AsmPrinter to use when it's time
+ // to emit the table
+ std::string LSDAName = "L_lsda_";
+ LSDAName += MF.getFunction()->getName();
+ ARMConstantPoolValue *CPV =
+ new ARMConstantPoolValue(LSDAName.c_str(), ARMPCLabelIndex, Kind, PCAdj);
+ CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, 4);
+ CPAddr = DAG.getNode(ARMISD::Wrapper, dl, EVT::i32, CPAddr);
+ SDValue Result =
+ DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), CPAddr, NULL, 0);
+ SDValue Chain = Result.getValue(1);
+
+ if (RelocM == Reloc::PIC_) {
+ SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex++, EVT::i32);
+ Result = DAG.getNode(ARMISD::PIC_ADD, dl, PtrVT, Result, PICLabel);
+ }
+ return Result;
+ }
case Intrinsic::eh_sjlj_setjmp:
return DAG.getNode(ARMISD::EH_SJLJ_SETJMP, dl, EVT::i32, Op.getOperand(1));
}
diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td
index 5190492b64..4a2ce4be78 100644
--- a/lib/Target/ARM/ARMInstrInfo.td
+++ b/lib/Target/ARM/ARMInstrInfo.td
@@ -1427,9 +1427,12 @@ let Defs =
def Int_eh_sjlj_setjmp : XI<(outs), (ins GPR:$src),
AddrModeNone, SizeSpecial, IndexModeNone,
Pseudo, NoItinerary,
- "add r0, pc, #4\n\t"
- "str r0, [$src, #+4]\n\t"
- "mov r0, #0 @ eh_setjmp", "",
+ "str sp, [$src, #+8] @ eh_setjmp begin\n\t"
+ "add ip, pc, #8\n\t"
+ "str ip, [$src, #+4]\n\t"
+ "mov r0, #0\n\t"
+ "add pc, pc, #0\n\t"
+ "mov r0, #1 @ eh_setjmp end\n\t", "",
[(set R0, (ARMeh_sjlj_setjmp GPR:$src))]>;
}
diff --git a/lib/Target/ARM/ARMTargetAsmInfo.cpp b/lib/Target/ARM/ARMTargetAsmInfo.cpp
index e3348a90d4..653219bf74 100644
--- a/lib/Target/ARM/ARMTargetAsmInfo.cpp
+++ b/lib/Target/ARM/ARMTargetAsmInfo.cpp
@@ -47,6 +47,12 @@ ARMDarwinTargetAsmInfo::ARMDarwinTargetAsmInfo() {
ProtectedDirective = NULL;
HasDotTypeDotSizeDirective = false;
SupportsDebugInformation = true;
+
+ // Exceptions handling
+ ExceptionsType = ExceptionHandling::SjLj;
+ GlobalEHDirective = "\t.globl\t";
+ SupportsWeakOmittedEHFrame = false;
+ AbsoluteEHSectionOffsets = false;
}
ARMELFTargetAsmInfo::ARMELFTargetAsmInfo() {
diff --git a/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp b/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
index a909b66413..9de9af60e6 100644
--- a/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
+++ b/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
@@ -208,6 +208,8 @@ namespace {
} else {
if (GV)
Name = Mang->getMangledName(GV);
+ else if (!strncmp(ACPV->getSymbol(), "L_lsda_", 7))
+ Name = ACPV->getSymbol();
else
Name = Mang->makeNameProper(ACPV->getSymbol());
}