1 //===-- ARMSjLjLoweringPass.cpp - ARM SjLj Lowering Pass ------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file contains a pass that lowers the SjLj exception handling into
11 // machine instructions.
13 //===----------------------------------------------------------------------===//
15 #define DEBUG_TYPE "arm-sjlj-lowering"
17 #include "llvm/Function.h"
18 #include "llvm/CodeGen/MachineFrameInfo.h"
19 #include "llvm/CodeGen/MachineFunction.h"
20 #include "llvm/CodeGen/MachineFunctionPass.h"
21 #include "llvm/Target/TargetData.h"
22 #include "llvm/Target/TargetLowering.h"
23 #include "llvm/Support/CommandLine.h"
26 // Hidden options for the new EH stuff.
28 EnableNewSjLjEHPrepare("enable-new-sjlj-eh", cl::Hidden,
29 cl::desc("Use the new SjLj EH preparation pass"));
33 class ARMSjLjLowering : public MachineFunctionPass {
39 const TargetLowering *TLI;
40 const TargetInstrInfo *TII;
41 const TargetRegisterInfo *TRI;
43 /// createFunctionContext - Create the function context on the stack. This
44 /// returns the nonnegative identifier representing it in the FrameInfo.
45 int createFunctionContext();
49 ARMSjLjLowering() : MachineFunctionPass(ID) {}
51 virtual bool runOnMachineFunction(MachineFunction &mf);
53 virtual const char *getPassName() const {
54 return "ARM setjmp/longjmp exception handling lowering pass";
58 char ARMSjLjLowering::ID = 0;
60 } // end anonymous namespace
62 FunctionPass *llvm::createARMSjLjLoweringPass() {
63 return new ARMSjLjLowering();
66 bool ARMSjLjLowering::runOnMachineFunction(MachineFunction &mf) {
67 if (!EnableNewSjLjEHPrepare) return false;
70 Fn = MF->getFunction();
71 Context = &Fn->getContext();
72 TLI = MF->getTarget().getTargetLowering();
73 TII = MF->getTarget().getInstrInfo();
74 TRI = MF->getTarget().getRegisterInfo();
76 int FrameIdx = createFunctionContext(); (void)FrameIdx;
81 /// createFunctionContext - Create the function context on the stack.
82 int ARMSjLjLowering::createFunctionContext() {
83 // struct _Unwind_FunctionContext {
84 // // next function in stack of handlers.
85 // struct _Unwind_FunctionContext *prev;
87 // // set by calling function before registering to be the landing pad.
88 // uintptr_t resumeLocation;
90 // // set by personality handler to be parameters passed to landing pad
92 // uintptr_t resumeParameters[4];
94 // // set by calling function before registering
95 // __personality_routine personality; // arm offset=24
97 // uintptr_t lsda // arm offset=28
99 // // variable length array, contains registers to restore
100 // // 0 = r7, 1 = pc, 2 = sp
101 // void *jbuf[]; // 5 for GCC compatibility.
103 Type *VoidPtrTy = Type::getInt8PtrTy(*Context);
104 Type *Int32Ty = Type::getInt32Ty(*Context);
106 StructType::get(VoidPtrTy, // prev
107 Int32Ty, // resumeLocation
108 ArrayType::get(Int32Ty, 4), // resumeParameters
109 VoidPtrTy, // personality
111 ArrayType::get(VoidPtrTy, 5), // jbuf
114 uint64_t TySize = TLI->getTargetData()->getTypeAllocSize(FunctionCtxTy);
115 unsigned Align = TLI->getTargetData()->getPrefTypeAlignment(FunctionCtxTy);
117 return MF->getFrameInfo()->CreateStackObject(TySize, Align, false, false);